xref: /onnv-gate/usr/src/cmd/oamuser/user/funcs.c (revision 12788:c71b0e8f856c)
10Sstevel@tonic-gate /*
20Sstevel@tonic-gate  * CDDL HEADER START
30Sstevel@tonic-gate  *
40Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
52657Srica  * Common Development and Distribution License (the "License").
62657Srica  * You may not use this file except in compliance with the License.
70Sstevel@tonic-gate  *
80Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
90Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
100Sstevel@tonic-gate  * See the License for the specific language governing permissions
110Sstevel@tonic-gate  * and limitations under the License.
120Sstevel@tonic-gate  *
130Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
140Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
150Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
160Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
170Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
180Sstevel@tonic-gate  *
190Sstevel@tonic-gate  * CDDL HEADER END
200Sstevel@tonic-gate  */
210Sstevel@tonic-gate /*
2212582SGlenn.Faden@Sun.COM  * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
230Sstevel@tonic-gate  */
240Sstevel@tonic-gate 
250Sstevel@tonic-gate #include <stdio.h>
260Sstevel@tonic-gate #include <stdlib.h>
270Sstevel@tonic-gate #include <strings.h>
280Sstevel@tonic-gate #include <auth_attr.h>
290Sstevel@tonic-gate #include <prof_attr.h>
300Sstevel@tonic-gate #include <user_attr.h>
310Sstevel@tonic-gate #include <project.h>
320Sstevel@tonic-gate #include <secdb.h>
330Sstevel@tonic-gate #include <pwd.h>
340Sstevel@tonic-gate #include <unistd.h>
350Sstevel@tonic-gate #include <priv.h>
360Sstevel@tonic-gate #include <errno.h>
372657Srica #include <ctype.h>
38*12788Sgary.winiger@oracle.com #include <nss.h>
39*12788Sgary.winiger@oracle.com #include <bsm/libbsm.h>
402657Srica #include <tsol/label.h>
410Sstevel@tonic-gate #include "funcs.h"
420Sstevel@tonic-gate #include "messages.h"
43*12788Sgary.winiger@oracle.com #undef	GROUP
440Sstevel@tonic-gate #include "userdefs.h"
450Sstevel@tonic-gate 
460Sstevel@tonic-gate typedef struct ua_key {
470Sstevel@tonic-gate 	const char	*key;
480Sstevel@tonic-gate 	const char	*(*check)(const char *);
490Sstevel@tonic-gate 	const char	*errstr;
500Sstevel@tonic-gate 	char		*newvalue;
510Sstevel@tonic-gate } ua_key_t;
520Sstevel@tonic-gate 
530Sstevel@tonic-gate static const char role[] = "role name";
540Sstevel@tonic-gate static const char prof[] = "profile name";
550Sstevel@tonic-gate static const char proj[] = "project name";
560Sstevel@tonic-gate static const char priv[] = "privilege set";
570Sstevel@tonic-gate static const char auth[] = "authorization";
580Sstevel@tonic-gate static const char type[] = "user type";
590Sstevel@tonic-gate static const char lock[] = "lock_after_retries value";
602657Srica static const char label[] = "label";
612657Srica static const char idlecmd[] = "idlecmd value";
622657Srica static const char idletime[] = "idletime value";
63*12788Sgary.winiger@oracle.com static const char auditflags[] = "audit mask";
64*12788Sgary.winiger@oracle.com static char	  auditerr[256];
650Sstevel@tonic-gate 
660Sstevel@tonic-gate 
670Sstevel@tonic-gate static const char *check_auth(const char *);
680Sstevel@tonic-gate static const char *check_prof(const char *);
690Sstevel@tonic-gate static const char *check_role(const char *);
700Sstevel@tonic-gate static const char *check_proj(const char *);
710Sstevel@tonic-gate static const char *check_privset(const char *);
720Sstevel@tonic-gate static const char *check_type(const char *);
730Sstevel@tonic-gate static const char *check_lock_after_retries(const char *);
742657Srica static const char *check_label(const char *);
752657Srica static const char *check_idlecmd(const char *);
762657Srica static const char *check_idletime(const char *);
77*12788Sgary.winiger@oracle.com static const char *check_auditflags(const char *);
780Sstevel@tonic-gate 
790Sstevel@tonic-gate int nkeys;
800Sstevel@tonic-gate 
810Sstevel@tonic-gate static ua_key_t keys[] = {
820Sstevel@tonic-gate 	/* First entry is always set correctly in main() */
830Sstevel@tonic-gate 	{ USERATTR_TYPE_KW,	check_type,	type },
840Sstevel@tonic-gate 	{ USERATTR_AUTHS_KW,	check_auth,	auth },
850Sstevel@tonic-gate 	{ USERATTR_PROFILES_KW,	check_prof,	prof },
860Sstevel@tonic-gate 	{ USERATTR_ROLES_KW,	check_role,	role },
870Sstevel@tonic-gate 	{ USERATTR_DEFAULTPROJ_KW,	check_proj,	proj },
880Sstevel@tonic-gate 	{ USERATTR_LIMPRIV_KW,	check_privset,	priv },
890Sstevel@tonic-gate 	{ USERATTR_DFLTPRIV_KW,	check_privset,	priv },
900Sstevel@tonic-gate 	{ USERATTR_LOCK_AFTER_RETRIES_KW, check_lock_after_retries,  lock },
912657Srica 	{ USERATTR_CLEARANCE,	check_label,	label },
922657Srica 	{ USERATTR_MINLABEL,	check_label,	label },
932657Srica 	{ USERATTR_IDLECMD_KW,	check_idlecmd,	idlecmd },
942657Srica 	{ USERATTR_IDLETIME_KW,	check_idletime,	idletime },
95*12788Sgary.winiger@oracle.com 	{ USERATTR_AUDIT_FLAGS_KW, check_auditflags, auditflags },
960Sstevel@tonic-gate };
970Sstevel@tonic-gate 
980Sstevel@tonic-gate #define	NKEYS	(sizeof (keys)/sizeof (ua_key_t))
990Sstevel@tonic-gate 
1000Sstevel@tonic-gate /*
1010Sstevel@tonic-gate  * Change a key, there are three different call sequences:
1020Sstevel@tonic-gate  *
1030Sstevel@tonic-gate  *		key, value	- key with option letter, value.
1040Sstevel@tonic-gate  *		NULL, value	- -K key=value option.
1050Sstevel@tonic-gate  */
1060Sstevel@tonic-gate 
1070Sstevel@tonic-gate void
change_key(const char * key,char * value)1080Sstevel@tonic-gate change_key(const char *key, char *value)
1090Sstevel@tonic-gate {
1100Sstevel@tonic-gate 	int i;
1110Sstevel@tonic-gate 	const char *res;
1120Sstevel@tonic-gate 
1130Sstevel@tonic-gate 	if (key == NULL) {
1140Sstevel@tonic-gate 		key = value;
1150Sstevel@tonic-gate 		value = strchr(value, '=');
1160Sstevel@tonic-gate 		/* Bad value */
1170Sstevel@tonic-gate 		if (value == NULL) {
1180Sstevel@tonic-gate 			errmsg(M_INVALID_VALUE);
1190Sstevel@tonic-gate 			exit(EX_BADARG);
1200Sstevel@tonic-gate 		}
1210Sstevel@tonic-gate 		*value++ = '\0';
1220Sstevel@tonic-gate 	}
1230Sstevel@tonic-gate 
1240Sstevel@tonic-gate 	for (i = 0; i < NKEYS; i++) {
1250Sstevel@tonic-gate 		if (strcmp(key, keys[i].key) == 0) {
1260Sstevel@tonic-gate 			if (keys[i].newvalue != NULL) {
1270Sstevel@tonic-gate 				/* Can't set a value twice */
1280Sstevel@tonic-gate 				errmsg(M_REDEFINED_KEY, key);
1290Sstevel@tonic-gate 				exit(EX_BADARG);
1300Sstevel@tonic-gate 			}
1310Sstevel@tonic-gate 
1320Sstevel@tonic-gate 			if (keys[i].check != NULL &&
1330Sstevel@tonic-gate 			    (res = keys[i].check(value)) != NULL) {
1340Sstevel@tonic-gate 				errmsg(M_INVALID, res, keys[i].errstr);
1350Sstevel@tonic-gate 				exit(EX_BADARG);
1360Sstevel@tonic-gate 			}
1370Sstevel@tonic-gate 			keys[i].newvalue = value;
1380Sstevel@tonic-gate 			nkeys++;
1390Sstevel@tonic-gate 			return;
1400Sstevel@tonic-gate 		}
1410Sstevel@tonic-gate 	}
1420Sstevel@tonic-gate 	errmsg(M_INVALID_KEY, key);
1430Sstevel@tonic-gate 	exit(EX_BADARG);
1440Sstevel@tonic-gate }
1450Sstevel@tonic-gate 
1460Sstevel@tonic-gate /*
1470Sstevel@tonic-gate  * Add the keys to the argument vector.
1480Sstevel@tonic-gate  */
1490Sstevel@tonic-gate void
addkey_args(char ** argv,int * index)1500Sstevel@tonic-gate addkey_args(char **argv, int *index)
1510Sstevel@tonic-gate {
1520Sstevel@tonic-gate 	int i;
1530Sstevel@tonic-gate 
1540Sstevel@tonic-gate 	for (i = 0; i < NKEYS; i++) {
1550Sstevel@tonic-gate 		const char *key = keys[i].key;
1560Sstevel@tonic-gate 		char *val = keys[i].newvalue;
1570Sstevel@tonic-gate 		size_t len;
1580Sstevel@tonic-gate 		char *arg;
1590Sstevel@tonic-gate 
1600Sstevel@tonic-gate 		if (val == NULL)
1610Sstevel@tonic-gate 			continue;
1620Sstevel@tonic-gate 
1630Sstevel@tonic-gate 		len = strlen(key) + strlen(val) + 2;
1640Sstevel@tonic-gate 		arg = malloc(len);
1650Sstevel@tonic-gate 
1660Sstevel@tonic-gate 		(void) snprintf(arg, len, "%s=%s", key, val);
1670Sstevel@tonic-gate 		argv[(*index)++] = "-K";
1680Sstevel@tonic-gate 		argv[(*index)++] = arg;
1690Sstevel@tonic-gate 	}
1700Sstevel@tonic-gate }
1710Sstevel@tonic-gate 
1720Sstevel@tonic-gate /*
1730Sstevel@tonic-gate  * Propose a default value for a key and get the actual value back.
1740Sstevel@tonic-gate  * If the proposed default value is NULL, return the actual value set.
1750Sstevel@tonic-gate  * The key argument is the user_attr key.
1760Sstevel@tonic-gate  */
1770Sstevel@tonic-gate char *
getsetdefval(const char * key,char * dflt)1780Sstevel@tonic-gate getsetdefval(const char *key, char *dflt)
1790Sstevel@tonic-gate {
1800Sstevel@tonic-gate 	int i;
1810Sstevel@tonic-gate 
1820Sstevel@tonic-gate 	for (i = 0; i < NKEYS; i++)
1830Sstevel@tonic-gate 		if (strcmp(keys[i].key, key) == 0)
1840Sstevel@tonic-gate 			if (keys[i].newvalue != NULL)
1850Sstevel@tonic-gate 				return (keys[i].newvalue);
1860Sstevel@tonic-gate 			else
1870Sstevel@tonic-gate 				return (keys[i].newvalue = dflt);
1880Sstevel@tonic-gate 	return (NULL);
1890Sstevel@tonic-gate }
1900Sstevel@tonic-gate 
1910Sstevel@tonic-gate char *
getusertype(char * cmdname)1920Sstevel@tonic-gate getusertype(char *cmdname)
1930Sstevel@tonic-gate {
1940Sstevel@tonic-gate 	static char usertype[MAX_TYPE_LENGTH];
1950Sstevel@tonic-gate 	char *cmd;
1960Sstevel@tonic-gate 
1970Sstevel@tonic-gate 	if (cmd = strrchr(cmdname, '/'))
1980Sstevel@tonic-gate 		++cmd;
1990Sstevel@tonic-gate 	else
2000Sstevel@tonic-gate 		cmd = cmdname;
2010Sstevel@tonic-gate 
2020Sstevel@tonic-gate 	/* get user type based on the program name */
2030Sstevel@tonic-gate 	if (strncmp(cmd, CMD_PREFIX_USER,
2040Sstevel@tonic-gate 	    strlen(CMD_PREFIX_USER)) == 0)
2050Sstevel@tonic-gate 		strcpy(usertype, USERATTR_TYPE_NORMAL_KW);
2060Sstevel@tonic-gate 	else
2070Sstevel@tonic-gate 		strcpy(usertype, USERATTR_TYPE_NONADMIN_KW);
2080Sstevel@tonic-gate 
2090Sstevel@tonic-gate 	return (usertype);
2100Sstevel@tonic-gate }
2110Sstevel@tonic-gate 
2120Sstevel@tonic-gate int
is_role(char * usertype)2130Sstevel@tonic-gate is_role(char *usertype)
2140Sstevel@tonic-gate {
2150Sstevel@tonic-gate 	if (strcmp(usertype, USERATTR_TYPE_NONADMIN_KW) == 0)
2160Sstevel@tonic-gate 		return (1);
2170Sstevel@tonic-gate 	/* not a role */
2180Sstevel@tonic-gate 	return (0);
2190Sstevel@tonic-gate }
2200Sstevel@tonic-gate 
2210Sstevel@tonic-gate /*
2220Sstevel@tonic-gate  * Verifies the provided list of authorizations are all valid.
2230Sstevel@tonic-gate  *
2240Sstevel@tonic-gate  * Returns NULL if all authorization names are valid.
2250Sstevel@tonic-gate  * Otherwise, returns the invalid authorization name
2260Sstevel@tonic-gate  *
2270Sstevel@tonic-gate  */
2280Sstevel@tonic-gate static const char *
check_auth(const char * auths)2290Sstevel@tonic-gate check_auth(const char *auths)
2300Sstevel@tonic-gate {
2310Sstevel@tonic-gate 	char *authname;
2320Sstevel@tonic-gate 	authattr_t *result;
2330Sstevel@tonic-gate 	char *tmp;
2340Sstevel@tonic-gate 	struct passwd   *pw;
2350Sstevel@tonic-gate 	int have_grant = 0;
2360Sstevel@tonic-gate 
2370Sstevel@tonic-gate 	tmp = strdup(auths);
23812578SGlenn.Faden@Sun.COM 	if (tmp == NULL) {
23912578SGlenn.Faden@Sun.COM 		errmsg(M_NOSPACE);
24012578SGlenn.Faden@Sun.COM 		exit(EX_FAILURE);
24112578SGlenn.Faden@Sun.COM 	}
2420Sstevel@tonic-gate 
2430Sstevel@tonic-gate 	authname = strtok(tmp, AUTH_SEP);
2440Sstevel@tonic-gate 	pw = getpwuid(getuid());
2450Sstevel@tonic-gate 	if (pw == NULL) {
2460Sstevel@tonic-gate 		return (authname);
2470Sstevel@tonic-gate 	}
2480Sstevel@tonic-gate 
2490Sstevel@tonic-gate 	while (authname != NULL) {
2500Sstevel@tonic-gate 		char *suffix;
2510Sstevel@tonic-gate 		char *authtoks;
2520Sstevel@tonic-gate 
25312578SGlenn.Faden@Sun.COM 		/* Check if user has been granted this authorization */
25412578SGlenn.Faden@Sun.COM 		if (!chkauthattr(authname, pw->pw_name))
25512578SGlenn.Faden@Sun.COM 			return (authname);
25612578SGlenn.Faden@Sun.COM 
25712578SGlenn.Faden@Sun.COM 		/* Remove named object after slash */
25812578SGlenn.Faden@Sun.COM 		if ((suffix = index(authname, KV_OBJECTCHAR)) != NULL)
25912578SGlenn.Faden@Sun.COM 			*suffix = '\0';
26012578SGlenn.Faden@Sun.COM 
2610Sstevel@tonic-gate 		/* Find the suffix */
2620Sstevel@tonic-gate 		if ((suffix = rindex(authname, '.')) == NULL)
2630Sstevel@tonic-gate 			return (authname);
2640Sstevel@tonic-gate 
2650Sstevel@tonic-gate 		/* Check for existence in auth_attr */
2660Sstevel@tonic-gate 		suffix++;
2670Sstevel@tonic-gate 		if (strcmp(suffix, KV_WILDCARD)) { /* Not a wildcard */
2680Sstevel@tonic-gate 			result = getauthnam(authname);
2690Sstevel@tonic-gate 			if (result == NULL) {
2700Sstevel@tonic-gate 			/* can't find the auth */
2710Sstevel@tonic-gate 				free_authattr(result);
2720Sstevel@tonic-gate 				return (authname);
2730Sstevel@tonic-gate 			}
2740Sstevel@tonic-gate 			free_authattr(result);
2750Sstevel@tonic-gate 		}
2760Sstevel@tonic-gate 
2770Sstevel@tonic-gate 		/* Check if user can delegate this authorization */
2780Sstevel@tonic-gate 		if (strcmp(suffix, "grant")) { /* Not a grant option */
2790Sstevel@tonic-gate 			authtoks = malloc(strlen(authname) + sizeof ("grant"));
2800Sstevel@tonic-gate 			strcpy(authtoks, authname);
2810Sstevel@tonic-gate 			have_grant = 0;
2820Sstevel@tonic-gate 			while ((suffix = rindex(authtoks, '.')) &&
2830Sstevel@tonic-gate 			    !have_grant) {
2840Sstevel@tonic-gate 				strcpy(suffix, ".grant");
2850Sstevel@tonic-gate 				if (chkauthattr(authtoks, pw->pw_name))
2860Sstevel@tonic-gate 					have_grant = 1;
2870Sstevel@tonic-gate 				else
2880Sstevel@tonic-gate 					*suffix = '\0';
2890Sstevel@tonic-gate 			}
2900Sstevel@tonic-gate 			if (!have_grant)
2910Sstevel@tonic-gate 				return (authname);
2920Sstevel@tonic-gate 		}
2930Sstevel@tonic-gate 		authname = strtok(NULL, AUTH_SEP);
2940Sstevel@tonic-gate 	}
29512578SGlenn.Faden@Sun.COM 	free(tmp);
2960Sstevel@tonic-gate 	return (NULL);
2970Sstevel@tonic-gate }
2980Sstevel@tonic-gate 
2990Sstevel@tonic-gate /*
3000Sstevel@tonic-gate  * Verifies the provided list of profile names are valid.
3010Sstevel@tonic-gate  *
3020Sstevel@tonic-gate  * Returns NULL if all profile names are valid.
3030Sstevel@tonic-gate  * Otherwise, returns the invalid profile name
3040Sstevel@tonic-gate  *
3050Sstevel@tonic-gate  */
3060Sstevel@tonic-gate static const char *
check_prof(const char * profs)3070Sstevel@tonic-gate check_prof(const char *profs)
3080Sstevel@tonic-gate {
3090Sstevel@tonic-gate 	char *profname;
3100Sstevel@tonic-gate 	profattr_t *result;
3110Sstevel@tonic-gate 	char *tmp;
3120Sstevel@tonic-gate 
3130Sstevel@tonic-gate 	tmp = strdup(profs);
31412578SGlenn.Faden@Sun.COM 	if (tmp == NULL) {
31512578SGlenn.Faden@Sun.COM 		errmsg(M_NOSPACE);
31612578SGlenn.Faden@Sun.COM 		exit(EX_FAILURE);
31712578SGlenn.Faden@Sun.COM 	}
3180Sstevel@tonic-gate 
3190Sstevel@tonic-gate 	profname = strtok(tmp, PROF_SEP);
3200Sstevel@tonic-gate 	while (profname != NULL) {
3210Sstevel@tonic-gate 		result = getprofnam(profname);
3220Sstevel@tonic-gate 		if (result == NULL) {
3230Sstevel@tonic-gate 		/* can't find the profile */
3240Sstevel@tonic-gate 			return (profname);
3250Sstevel@tonic-gate 		}
3260Sstevel@tonic-gate 		free_profattr(result);
3270Sstevel@tonic-gate 		profname = strtok(NULL, PROF_SEP);
3280Sstevel@tonic-gate 	}
32912578SGlenn.Faden@Sun.COM 	free(tmp);
3300Sstevel@tonic-gate 	return (NULL);
3310Sstevel@tonic-gate }
3320Sstevel@tonic-gate 
3330Sstevel@tonic-gate 
3340Sstevel@tonic-gate /*
3350Sstevel@tonic-gate  * Verifies the provided list of role names are valid.
3360Sstevel@tonic-gate  *
3370Sstevel@tonic-gate  * Returns NULL if all role names are valid.
3380Sstevel@tonic-gate  * Otherwise, returns the invalid role name
3390Sstevel@tonic-gate  *
3400Sstevel@tonic-gate  */
3410Sstevel@tonic-gate static const char *
check_role(const char * roles)3420Sstevel@tonic-gate check_role(const char *roles)
3430Sstevel@tonic-gate {
3440Sstevel@tonic-gate 	char *rolename;
3450Sstevel@tonic-gate 	userattr_t *result;
3460Sstevel@tonic-gate 	char *utype;
3470Sstevel@tonic-gate 	char *tmp;
3480Sstevel@tonic-gate 
3490Sstevel@tonic-gate 	tmp = strdup(roles);
35012578SGlenn.Faden@Sun.COM 	if (tmp == NULL) {
35112578SGlenn.Faden@Sun.COM 		errmsg(M_NOSPACE);
35212578SGlenn.Faden@Sun.COM 		exit(EX_FAILURE);
35312578SGlenn.Faden@Sun.COM 	}
3540Sstevel@tonic-gate 
3550Sstevel@tonic-gate 	rolename = strtok(tmp, ROLE_SEP);
3560Sstevel@tonic-gate 	while (rolename != NULL) {
3570Sstevel@tonic-gate 		result = getusernam(rolename);
3580Sstevel@tonic-gate 		if (result == NULL) {
3590Sstevel@tonic-gate 		/* can't find the rolename */
3600Sstevel@tonic-gate 			return (rolename);
3610Sstevel@tonic-gate 		}
3620Sstevel@tonic-gate 		/* Now, make sure it is a role */
3630Sstevel@tonic-gate 		utype = kva_match(result->attr, USERATTR_TYPE_KW);
3640Sstevel@tonic-gate 		if (utype == NULL) {
3650Sstevel@tonic-gate 			/* no user type defined. not a role */
3660Sstevel@tonic-gate 			free_userattr(result);
3670Sstevel@tonic-gate 			return (rolename);
3680Sstevel@tonic-gate 		}
3690Sstevel@tonic-gate 		if (strcmp(utype, USERATTR_TYPE_NONADMIN_KW) != 0) {
3700Sstevel@tonic-gate 			free_userattr(result);
3710Sstevel@tonic-gate 			return (rolename);
3720Sstevel@tonic-gate 		}
3730Sstevel@tonic-gate 		free_userattr(result);
3740Sstevel@tonic-gate 		rolename = strtok(NULL, ROLE_SEP);
3750Sstevel@tonic-gate 	}
37612578SGlenn.Faden@Sun.COM 	free(tmp);
3770Sstevel@tonic-gate 	return (NULL);
3780Sstevel@tonic-gate }
3790Sstevel@tonic-gate 
3800Sstevel@tonic-gate static const char *
check_proj(const char * proj)3810Sstevel@tonic-gate check_proj(const char *proj)
3820Sstevel@tonic-gate {
3830Sstevel@tonic-gate 	if (getprojidbyname(proj) < 0) {
3840Sstevel@tonic-gate 		return (proj);
3850Sstevel@tonic-gate 	} else {
3860Sstevel@tonic-gate 		return (NULL);
3870Sstevel@tonic-gate 	}
3880Sstevel@tonic-gate }
3890Sstevel@tonic-gate 
3900Sstevel@tonic-gate static const char *
check_privset(const char * pset)3910Sstevel@tonic-gate check_privset(const char *pset)
3920Sstevel@tonic-gate {
3930Sstevel@tonic-gate 	priv_set_t *tmp;
3940Sstevel@tonic-gate 	const char *res;
3950Sstevel@tonic-gate 
3960Sstevel@tonic-gate 	tmp = priv_str_to_set(pset, ",", &res);
3970Sstevel@tonic-gate 
3980Sstevel@tonic-gate 	if (tmp != NULL) {
3990Sstevel@tonic-gate 		res = NULL;
4000Sstevel@tonic-gate 		priv_freeset(tmp);
4010Sstevel@tonic-gate 	} else if (res == NULL)
4020Sstevel@tonic-gate 		res = strerror(errno);
4030Sstevel@tonic-gate 
4040Sstevel@tonic-gate 	return (res);
4050Sstevel@tonic-gate }
4060Sstevel@tonic-gate 
4070Sstevel@tonic-gate static const char *
check_type(const char * type)4080Sstevel@tonic-gate check_type(const char *type)
4090Sstevel@tonic-gate {
4100Sstevel@tonic-gate 	if (strcmp(type, USERATTR_TYPE_NONADMIN_KW) != 0 &&
4110Sstevel@tonic-gate 	    strcmp(type, USERATTR_TYPE_NORMAL_KW) != 0)
4120Sstevel@tonic-gate 		return (type);
4130Sstevel@tonic-gate 
4140Sstevel@tonic-gate 	return (NULL);
4150Sstevel@tonic-gate }
4160Sstevel@tonic-gate 
4170Sstevel@tonic-gate static const char *
check_lock_after_retries(const char * keyval)4180Sstevel@tonic-gate check_lock_after_retries(const char *keyval)
4190Sstevel@tonic-gate {
4200Sstevel@tonic-gate 	if (keyval != NULL) {
4210Sstevel@tonic-gate 		if ((strcasecmp(keyval, "no") != 0) &&
4220Sstevel@tonic-gate 		    (strcasecmp(keyval, "yes") != 0) &&
4230Sstevel@tonic-gate 		    (*keyval != '\0'))   {
4240Sstevel@tonic-gate 			return (keyval);
4250Sstevel@tonic-gate 		}
4260Sstevel@tonic-gate 	}
4270Sstevel@tonic-gate 	return (NULL);
4280Sstevel@tonic-gate }
4292657Srica 
4302657Srica static const char *
check_label(const char * labelstr)4312657Srica check_label(const char *labelstr)
4322657Srica {
4332657Srica 	int	err;
4342657Srica 	m_label_t *lbl = NULL;
4352657Srica 
4362657Srica 	if (!is_system_labeled())
4372657Srica 		return (NULL);
4382657Srica 
4392657Srica 	err = str_to_label(labelstr, &lbl, MAC_LABEL, L_NO_CORRECTION, NULL);
4402657Srica 	m_label_free(lbl);
4412657Srica 
4422657Srica 	if (err == -1)
4432657Srica 		return (labelstr);
4442657Srica 
4452657Srica 	return (NULL);
4462657Srica }
4472657Srica 
4482657Srica static const char *
check_idlecmd(const char * cmd)4492657Srica check_idlecmd(const char *cmd)
4502657Srica {
4512657Srica 	if ((strcmp(cmd, USERATTR_IDLECMD_LOCK_KW) != 0) &&
4522657Srica 	    (strcmp(cmd, USERATTR_IDLECMD_LOGOUT_KW) != 0)) {
4532657Srica 		return (cmd);
4542657Srica 	}
4552657Srica 
4562657Srica 	return (NULL);
4572657Srica }
4582657Srica 
4592657Srica static const char *
check_idletime(const char * time)4602657Srica check_idletime(const char *time)
4612657Srica {
4622657Srica 	int		c;
4632657Srica 	unsigned char	*up = (unsigned char *)time;
4642657Srica 
4652657Srica 	c = *up;
4662657Srica 	while (c != '\0') {
4672657Srica 		if (!isdigit(c))
4682657Srica 			return (time);
4692657Srica 		c = *++up;
4702657Srica 	}
4712657Srica 
4722657Srica 	return (NULL);
4732657Srica }
474*12788Sgary.winiger@oracle.com 
475*12788Sgary.winiger@oracle.com static const char *
check_auditflags(const char * auditflags)476*12788Sgary.winiger@oracle.com check_auditflags(const char *auditflags)
477*12788Sgary.winiger@oracle.com {
478*12788Sgary.winiger@oracle.com 	au_mask_t mask;
479*12788Sgary.winiger@oracle.com 	char	*flags;
480*12788Sgary.winiger@oracle.com 	char	*last = NULL;
481*12788Sgary.winiger@oracle.com 	char	*err = "NULL";
482*12788Sgary.winiger@oracle.com 
483*12788Sgary.winiger@oracle.com 	/* if deleting audit_flags */
484*12788Sgary.winiger@oracle.com 	if (*auditflags == '\0') {
485*12788Sgary.winiger@oracle.com 		return (NULL);
486*12788Sgary.winiger@oracle.com 	}
487*12788Sgary.winiger@oracle.com 
488*12788Sgary.winiger@oracle.com 	if ((flags = _strdup_null((char *)auditflags)) == NULL) {
489*12788Sgary.winiger@oracle.com 		errmsg(M_NOSPACE);
490*12788Sgary.winiger@oracle.com 		exit(EX_FAILURE);
491*12788Sgary.winiger@oracle.com 	}
492*12788Sgary.winiger@oracle.com 
493*12788Sgary.winiger@oracle.com 	if (!__chkflags(_strtok_escape(flags, KV_AUDIT_DELIMIT, &last), &mask,
494*12788Sgary.winiger@oracle.com 	    B_FALSE, &err)) {
495*12788Sgary.winiger@oracle.com 		(void) snprintf(auditerr, sizeof (auditerr),
496*12788Sgary.winiger@oracle.com 		    "always mask \"%s\"", err);
497*12788Sgary.winiger@oracle.com 		free(flags);
498*12788Sgary.winiger@oracle.com 		return (auditerr);
499*12788Sgary.winiger@oracle.com 	}
500*12788Sgary.winiger@oracle.com 	if (!__chkflags(_strtok_escape(NULL, KV_AUDIT_DELIMIT, &last), &mask,
501*12788Sgary.winiger@oracle.com 	    B_FALSE, &err)) {
502*12788Sgary.winiger@oracle.com 		(void) snprintf(auditerr, sizeof (auditerr),
503*12788Sgary.winiger@oracle.com 		    "never mask \"%s\"", err);
504*12788Sgary.winiger@oracle.com 		free(flags);
505*12788Sgary.winiger@oracle.com 		return (auditerr);
506*12788Sgary.winiger@oracle.com 	}
507*12788Sgary.winiger@oracle.com 	if (last != NULL) {
508*12788Sgary.winiger@oracle.com 		(void) snprintf(auditerr, sizeof (auditerr), "\"%s\"",
509*12788Sgary.winiger@oracle.com 		    auditflags);
510*12788Sgary.winiger@oracle.com 		free(flags);
511*12788Sgary.winiger@oracle.com 		return (auditerr);
512*12788Sgary.winiger@oracle.com 	}
513*12788Sgary.winiger@oracle.com 	free(flags);
514*12788Sgary.winiger@oracle.com 
515*12788Sgary.winiger@oracle.com 	return (NULL);
516*12788Sgary.winiger@oracle.com }
517