2N/A * The contents of this file are subject to the terms of the 2N/A * Common Development and Distribution License (the "License"). 2N/A * You may not use this file except in compliance with the License. 2N/A * See the License for the specific language governing permissions 2N/A * and limitations under the License. 2N/A * When distributing Covered Code, include this CDDL HEADER in each 2N/A * If applicable, add the following below this CDDL HEADER, with the 2N/A * fields enclosed by brackets "[]" replaced with your own identifying 2N/A * information: Portions Copyright [yyyy] [name of copyright owner] 2N/A * Copyright (c) 2003, 2012, Oracle and/or its affiliates. All rights reserved. 2N/A * Constant info per dir_dev_access() invocation 2N/A * Revoke all access to a device node and make sure that there are 2N/A * no interposed streams devices attached. Must be called before a 2N/A * device is actually opened. 2N/A * When fdetach is called, the underlying device node is revealed; it 2N/A * will have the previous owner and that owner can re-attach; so we 2N/A * retry until we win. 2N/A * Ignore non-existent devices. 2N/A * don't fdetach block devices, as it will unmount them 2N/A "failed to chown device %s: %s\n",
2N/A * If the file system returned ENOSYS, we know that it 2N/A * doesn't support ACLs, therefore, we must assume that 2N/A * there were no ACLs to remove in the first place. 2N/A "failed to set acl on device %s: %s\n",
2N/A "failed to chmod device %s: %s\n",
2N/A /* may be null in which case we fall back to DINFOCPYONE */ 2N/A *
ptr =
'\0';
/* handle comments */ 2N/A continue;
/* ignore blank lines */ 2N/A err = -
1;
/* invalid entry, skip */ 2N/A ": line %d, invalid entry -- %s\n",
2N/A /* convert string to octal value */ 2N/A err = -
1;
/* invalid mode, skip */ 2N/A ": line %d, invalid mode -- %s\n",
2N/A err = -
1;
/* empty device list, skip */ 2N/A ": line %d, empty device list -- %s\n",
2N/A /* include line from logindevperm for additional parsing */ 2N/A * returns 0 if resolved, -1 otherwise. 2N/A * devpath: Absolute path to /dev link 2N/A * devfs_path: Returns malloced string: /devices path w/out "/devices" 2N/A * if the link contents is not a minor node assume 2N/A * that link contents is really a pointer to another 2N/A * link, and if so recurse and read its link contents. 2N/A /* absolute path, starting with /dev */ 2N/A /* relative path, prefix devpath */ 2N/A * Use the cached devinfo snapshot to match the devfs device 2N/A * path and return the driver name for the node. 2N/A /* first try the cached snapshot */ 2N/A /* fall back to looking up this node directly */ 2N/A * check a logindevperm line for a driver list and match this against 2N/A * the driver of the minor node 2N/A * returns 0 if no drivers were specified or a driver match 2N/A * get path and truncate on : to take a snapshot 2N/A * There's nothing reasonable we can do with a name service failure 2N/A * so we just drive on as if the lookup had not found a match. 2N/A * This function is recursive. We start with "/" and the rest of the pathname 2N/A * in left_to_do argument, and we walk the entire pathname which may contain 2N/A * regular expressions or '*' for each directory name or basename. 2N/A * Determine if the search needs to be performed via finddev, 2N/A * which returns only persisted names in the global /dev, or 2N/A * readdir, for paths other than /dev and non-global zones. 2N/A * This use of finddev avoids triggering potential implicit 2N/A * reconfig for names managed by logindevperm but not present 2N/A * ENOENT errors are expected errors when there are 2N/A * dangling /dev device links. Ignore them silently 2N/A /* finally check the driver matches */ 2N/A * if the owner of device has been 2N/A * login, the ownership and mode 2N/A * should be set already. in 2N/A * this case, do not set the 2N/A /* we are done, set the permissions */ 2N/A /* transform pattern into ^pattern$ for exact match */ 2N/A * recurse but adjust what is still left to do 2N/A (*
ferror)(
"di_devperm_login: NULL tty device\n");
2N/A * this should never happen, but if it does set 2N/A * group to tty's traditional value. 2N/A /* set the login console device permission */ 2N/A /* set the device permissions */ 2N/A * this should never happen, but if it does set user 2N/A * and group to root's traditional values. 2N/A * Tokens are separated by ' ', '\t', ':', '=', '&', '|', ';', '\n', or '\0' 2N/A while (*
cp ==
' ' || *
cp ==
'\t') {
2N/A cp++;
/* skip leading spaces */ 2N/A while (*
cp !=
'\0' && *
cp !=
'\n' && *
cp !=
' ' && *
cp !=
'\t' &&
2N/A cp++;
/* point to next character */ 2N/A * If terminating character is a space or tab, look ahead to see if 2N/A * there's another terminator that's not a space or a tab. 2N/A * (This code handles trailing spaces.) 2N/A *
cp++ =
'\0';
/* terminate token, point to next */ 2N/A * get a decimal octal or hex number. Handle '~' for one's complement. 2N/A if (c ==
'x' || c ==
'X') {
2N/A if (c >=
'0' && c <=
'7') {
2N/A /* invalid number */ 2N/A if (c >=
'0' && c <=
'9') {
2N/A /* invalid number */ 2N/A if (c >=
'a' && c <=
'f') {
2N/A }
else if (c >=
'A' && c <=
'F') {
2N/A }
else if (c >=
'0' && c <=
'9') {
2N/A /* invalid number */ 2N/A /* cut off comments starting with '#' */ 2N/A /* ignore comment or blank lines */ 2N/A }
else if (t ==
'\n' || t ==
'\0') {
2N/A if (t ==
'\n' || t ==
'\0') {
2N/A if (t ==
'\n' || t ==
'\0') {
/* no owner or group */ 2N/A }
else if (t ==
'\n' || t ==
'\0') {
/* no group */ 2N/A * We only want the minor perm entry for a 2N/A * the named driver. The driver name is the 2N/A * minor in the clone case. 2N/A * Compute the uid's and gid's here - there are 2N/A * are devices to be stat(2)ed. And almost every 2N/A * device is 'root sys'. See 1135520. 2N/A * Free mperm list of entries 2N/A * Load all minor perm entries into the kernel 2N/A * Done at boot time via devfsadm 2N/A * is_blank() returns 1 (true) if a line specified is composed of 2N/A * whitespace characters only. otherwise, it returns 0 (false). 2N/A * Note. the argument (line) must be null-terminated.