xref: /onnv-gate/usr/src/cmd/oamuser/user/funcs.c (revision 12582:4a05f6f7bc8c)
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 /*
22*12582SGlenn.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>
382657Srica #include <tsol/label.h>
390Sstevel@tonic-gate #include "funcs.h"
400Sstevel@tonic-gate #include "messages.h"
410Sstevel@tonic-gate #include "userdefs.h"
420Sstevel@tonic-gate 
430Sstevel@tonic-gate typedef struct ua_key {
440Sstevel@tonic-gate 	const char	*key;
450Sstevel@tonic-gate 	const char	*(*check)(const char *);
460Sstevel@tonic-gate 	const char	*errstr;
470Sstevel@tonic-gate 	char		*newvalue;
480Sstevel@tonic-gate } ua_key_t;
490Sstevel@tonic-gate 
500Sstevel@tonic-gate static const char role[] = "role name";
510Sstevel@tonic-gate static const char prof[] = "profile name";
520Sstevel@tonic-gate static const char proj[] = "project name";
530Sstevel@tonic-gate static const char priv[] = "privilege set";
540Sstevel@tonic-gate static const char auth[] = "authorization";
550Sstevel@tonic-gate static const char type[] = "user type";
560Sstevel@tonic-gate static const char lock[] = "lock_after_retries value";
572657Srica static const char label[] = "label";
582657Srica static const char idlecmd[] = "idlecmd value";
592657Srica static const char idletime[] = "idletime value";
600Sstevel@tonic-gate 
610Sstevel@tonic-gate 
620Sstevel@tonic-gate static const char *check_auth(const char *);
630Sstevel@tonic-gate static const char *check_prof(const char *);
640Sstevel@tonic-gate static const char *check_role(const char *);
650Sstevel@tonic-gate static const char *check_proj(const char *);
660Sstevel@tonic-gate static const char *check_privset(const char *);
670Sstevel@tonic-gate static const char *check_type(const char *);
680Sstevel@tonic-gate static const char *check_lock_after_retries(const char *);
692657Srica static const char *check_label(const char *);
702657Srica static const char *check_idlecmd(const char *);
712657Srica static const char *check_idletime(const char *);
720Sstevel@tonic-gate 
730Sstevel@tonic-gate int nkeys;
740Sstevel@tonic-gate 
750Sstevel@tonic-gate static ua_key_t keys[] = {
760Sstevel@tonic-gate 	/* First entry is always set correctly in main() */
770Sstevel@tonic-gate 	{ USERATTR_TYPE_KW,	check_type,	type },
780Sstevel@tonic-gate 	{ USERATTR_AUTHS_KW,	check_auth,	auth },
790Sstevel@tonic-gate 	{ USERATTR_PROFILES_KW,	check_prof,	prof },
800Sstevel@tonic-gate 	{ USERATTR_ROLES_KW,	check_role,	role },
810Sstevel@tonic-gate 	{ USERATTR_DEFAULTPROJ_KW,	check_proj,	proj },
820Sstevel@tonic-gate 	{ USERATTR_LIMPRIV_KW,	check_privset,	priv },
830Sstevel@tonic-gate 	{ USERATTR_DFLTPRIV_KW,	check_privset,	priv },
840Sstevel@tonic-gate 	{ USERATTR_LOCK_AFTER_RETRIES_KW, check_lock_after_retries,  lock },
852657Srica 	{ USERATTR_CLEARANCE,	check_label,	label },
862657Srica 	{ USERATTR_MINLABEL,	check_label,	label },
872657Srica 	{ USERATTR_IDLECMD_KW,	check_idlecmd,	idlecmd },
882657Srica 	{ USERATTR_IDLETIME_KW,	check_idletime,	idletime },
890Sstevel@tonic-gate };
900Sstevel@tonic-gate 
910Sstevel@tonic-gate #define	NKEYS	(sizeof (keys)/sizeof (ua_key_t))
920Sstevel@tonic-gate 
930Sstevel@tonic-gate /*
940Sstevel@tonic-gate  * Change a key, there are three different call sequences:
950Sstevel@tonic-gate  *
960Sstevel@tonic-gate  *		key, value	- key with option letter, value.
970Sstevel@tonic-gate  *		NULL, value	- -K key=value option.
980Sstevel@tonic-gate  */
990Sstevel@tonic-gate 
1000Sstevel@tonic-gate void
1010Sstevel@tonic-gate change_key(const char *key, char *value)
1020Sstevel@tonic-gate {
1030Sstevel@tonic-gate 	int i;
1040Sstevel@tonic-gate 	const char *res;
1050Sstevel@tonic-gate 
1060Sstevel@tonic-gate 	if (key == NULL) {
1070Sstevel@tonic-gate 		key = value;
1080Sstevel@tonic-gate 		value = strchr(value, '=');
1090Sstevel@tonic-gate 		/* Bad value */
1100Sstevel@tonic-gate 		if (value == NULL) {
1110Sstevel@tonic-gate 			errmsg(M_INVALID_VALUE);
1120Sstevel@tonic-gate 			exit(EX_BADARG);
1130Sstevel@tonic-gate 		}
1140Sstevel@tonic-gate 		*value++ = '\0';
1150Sstevel@tonic-gate 	}
1160Sstevel@tonic-gate 
1170Sstevel@tonic-gate 	for (i = 0; i < NKEYS; i++) {
1180Sstevel@tonic-gate 		if (strcmp(key, keys[i].key) == 0) {
1190Sstevel@tonic-gate 			if (keys[i].newvalue != NULL) {
1200Sstevel@tonic-gate 				/* Can't set a value twice */
1210Sstevel@tonic-gate 				errmsg(M_REDEFINED_KEY, key);
1220Sstevel@tonic-gate 				exit(EX_BADARG);
1230Sstevel@tonic-gate 			}
1240Sstevel@tonic-gate 
1250Sstevel@tonic-gate 			if (keys[i].check != NULL &&
1260Sstevel@tonic-gate 			    (res = keys[i].check(value)) != NULL) {
1270Sstevel@tonic-gate 				errmsg(M_INVALID, res, keys[i].errstr);
1280Sstevel@tonic-gate 				exit(EX_BADARG);
1290Sstevel@tonic-gate 			}
1300Sstevel@tonic-gate 			keys[i].newvalue = value;
1310Sstevel@tonic-gate 			nkeys++;
1320Sstevel@tonic-gate 			return;
1330Sstevel@tonic-gate 		}
1340Sstevel@tonic-gate 	}
1350Sstevel@tonic-gate 	errmsg(M_INVALID_KEY, key);
1360Sstevel@tonic-gate 	exit(EX_BADARG);
1370Sstevel@tonic-gate }
1380Sstevel@tonic-gate 
1390Sstevel@tonic-gate /*
1400Sstevel@tonic-gate  * Add the keys to the argument vector.
1410Sstevel@tonic-gate  */
1420Sstevel@tonic-gate void
1430Sstevel@tonic-gate addkey_args(char **argv, int *index)
1440Sstevel@tonic-gate {
1450Sstevel@tonic-gate 	int i;
1460Sstevel@tonic-gate 
1470Sstevel@tonic-gate 	for (i = 0; i < NKEYS; i++) {
1480Sstevel@tonic-gate 		const char *key = keys[i].key;
1490Sstevel@tonic-gate 		char *val = keys[i].newvalue;
1500Sstevel@tonic-gate 		size_t len;
1510Sstevel@tonic-gate 		char *arg;
1520Sstevel@tonic-gate 
1530Sstevel@tonic-gate 		if (val == NULL)
1540Sstevel@tonic-gate 			continue;
1550Sstevel@tonic-gate 
1560Sstevel@tonic-gate 		len = strlen(key) + strlen(val) + 2;
1570Sstevel@tonic-gate 		arg = malloc(len);
1580Sstevel@tonic-gate 
1590Sstevel@tonic-gate 		(void) snprintf(arg, len, "%s=%s", key, val);
1600Sstevel@tonic-gate 		argv[(*index)++] = "-K";
1610Sstevel@tonic-gate 		argv[(*index)++] = arg;
1620Sstevel@tonic-gate 	}
1630Sstevel@tonic-gate }
1640Sstevel@tonic-gate 
1650Sstevel@tonic-gate /*
1660Sstevel@tonic-gate  * Propose a default value for a key and get the actual value back.
1670Sstevel@tonic-gate  * If the proposed default value is NULL, return the actual value set.
1680Sstevel@tonic-gate  * The key argument is the user_attr key.
1690Sstevel@tonic-gate  */
1700Sstevel@tonic-gate char *
1710Sstevel@tonic-gate getsetdefval(const char *key, char *dflt)
1720Sstevel@tonic-gate {
1730Sstevel@tonic-gate 	int i;
1740Sstevel@tonic-gate 
1750Sstevel@tonic-gate 	for (i = 0; i < NKEYS; i++)
1760Sstevel@tonic-gate 		if (strcmp(keys[i].key, key) == 0)
1770Sstevel@tonic-gate 			if (keys[i].newvalue != NULL)
1780Sstevel@tonic-gate 				return (keys[i].newvalue);
1790Sstevel@tonic-gate 			else
1800Sstevel@tonic-gate 				return (keys[i].newvalue = dflt);
1810Sstevel@tonic-gate 	return (NULL);
1820Sstevel@tonic-gate }
1830Sstevel@tonic-gate 
1840Sstevel@tonic-gate char *
1850Sstevel@tonic-gate getusertype(char *cmdname)
1860Sstevel@tonic-gate {
1870Sstevel@tonic-gate 	static char usertype[MAX_TYPE_LENGTH];
1880Sstevel@tonic-gate 	char *cmd;
1890Sstevel@tonic-gate 
1900Sstevel@tonic-gate 	if (cmd = strrchr(cmdname, '/'))
1910Sstevel@tonic-gate 		++cmd;
1920Sstevel@tonic-gate 	else
1930Sstevel@tonic-gate 		cmd = cmdname;
1940Sstevel@tonic-gate 
1950Sstevel@tonic-gate 	/* get user type based on the program name */
1960Sstevel@tonic-gate 	if (strncmp(cmd, CMD_PREFIX_USER,
1970Sstevel@tonic-gate 	    strlen(CMD_PREFIX_USER)) == 0)
1980Sstevel@tonic-gate 		strcpy(usertype, USERATTR_TYPE_NORMAL_KW);
1990Sstevel@tonic-gate 	else
2000Sstevel@tonic-gate 		strcpy(usertype, USERATTR_TYPE_NONADMIN_KW);
2010Sstevel@tonic-gate 
2020Sstevel@tonic-gate 	return (usertype);
2030Sstevel@tonic-gate }
2040Sstevel@tonic-gate 
2050Sstevel@tonic-gate int
2060Sstevel@tonic-gate is_role(char *usertype)
2070Sstevel@tonic-gate {
2080Sstevel@tonic-gate 	if (strcmp(usertype, USERATTR_TYPE_NONADMIN_KW) == 0)
2090Sstevel@tonic-gate 		return (1);
2100Sstevel@tonic-gate 	/* not a role */
2110Sstevel@tonic-gate 	return (0);
2120Sstevel@tonic-gate }
2130Sstevel@tonic-gate 
2140Sstevel@tonic-gate /*
2150Sstevel@tonic-gate  * Verifies the provided list of authorizations are all valid.
2160Sstevel@tonic-gate  *
2170Sstevel@tonic-gate  * Returns NULL if all authorization names are valid.
2180Sstevel@tonic-gate  * Otherwise, returns the invalid authorization name
2190Sstevel@tonic-gate  *
2200Sstevel@tonic-gate  */
2210Sstevel@tonic-gate static const char *
2220Sstevel@tonic-gate check_auth(const char *auths)
2230Sstevel@tonic-gate {
2240Sstevel@tonic-gate 	char *authname;
2250Sstevel@tonic-gate 	authattr_t *result;
2260Sstevel@tonic-gate 	char *tmp;
2270Sstevel@tonic-gate 	struct passwd   *pw;
2280Sstevel@tonic-gate 	int have_grant = 0;
2290Sstevel@tonic-gate 
2300Sstevel@tonic-gate 	tmp = strdup(auths);
23112578SGlenn.Faden@Sun.COM 	if (tmp == NULL) {
23212578SGlenn.Faden@Sun.COM 		errmsg(M_NOSPACE);
23312578SGlenn.Faden@Sun.COM 		exit(EX_FAILURE);
23412578SGlenn.Faden@Sun.COM 	}
2350Sstevel@tonic-gate 
2360Sstevel@tonic-gate 	authname = strtok(tmp, AUTH_SEP);
2370Sstevel@tonic-gate 	pw = getpwuid(getuid());
2380Sstevel@tonic-gate 	if (pw == NULL) {
2390Sstevel@tonic-gate 		return (authname);
2400Sstevel@tonic-gate 	}
2410Sstevel@tonic-gate 
2420Sstevel@tonic-gate 	while (authname != NULL) {
2430Sstevel@tonic-gate 		char *suffix;
2440Sstevel@tonic-gate 		char *authtoks;
2450Sstevel@tonic-gate 
24612578SGlenn.Faden@Sun.COM 		/* Check if user has been granted this authorization */
24712578SGlenn.Faden@Sun.COM 		if (!chkauthattr(authname, pw->pw_name))
24812578SGlenn.Faden@Sun.COM 			return (authname);
24912578SGlenn.Faden@Sun.COM 
25012578SGlenn.Faden@Sun.COM 		/* Remove named object after slash */
25112578SGlenn.Faden@Sun.COM 		if ((suffix = index(authname, KV_OBJECTCHAR)) != NULL)
25212578SGlenn.Faden@Sun.COM 			*suffix = '\0';
25312578SGlenn.Faden@Sun.COM 
2540Sstevel@tonic-gate 		/* Find the suffix */
2550Sstevel@tonic-gate 		if ((suffix = rindex(authname, '.')) == NULL)
2560Sstevel@tonic-gate 			return (authname);
2570Sstevel@tonic-gate 
2580Sstevel@tonic-gate 		/* Check for existence in auth_attr */
2590Sstevel@tonic-gate 		suffix++;
2600Sstevel@tonic-gate 		if (strcmp(suffix, KV_WILDCARD)) { /* Not a wildcard */
2610Sstevel@tonic-gate 			result = getauthnam(authname);
2620Sstevel@tonic-gate 			if (result == NULL) {
2630Sstevel@tonic-gate 			/* can't find the auth */
2640Sstevel@tonic-gate 				free_authattr(result);
2650Sstevel@tonic-gate 				return (authname);
2660Sstevel@tonic-gate 			}
2670Sstevel@tonic-gate 			free_authattr(result);
2680Sstevel@tonic-gate 		}
2690Sstevel@tonic-gate 
2700Sstevel@tonic-gate 		/* Check if user can delegate this authorization */
2710Sstevel@tonic-gate 		if (strcmp(suffix, "grant")) { /* Not a grant option */
2720Sstevel@tonic-gate 			authtoks = malloc(strlen(authname) + sizeof ("grant"));
2730Sstevel@tonic-gate 			strcpy(authtoks, authname);
2740Sstevel@tonic-gate 			have_grant = 0;
2750Sstevel@tonic-gate 			while ((suffix = rindex(authtoks, '.')) &&
2760Sstevel@tonic-gate 			    !have_grant) {
2770Sstevel@tonic-gate 				strcpy(suffix, ".grant");
2780Sstevel@tonic-gate 				if (chkauthattr(authtoks, pw->pw_name))
2790Sstevel@tonic-gate 					have_grant = 1;
2800Sstevel@tonic-gate 				else
2810Sstevel@tonic-gate 					*suffix = '\0';
2820Sstevel@tonic-gate 			}
2830Sstevel@tonic-gate 			if (!have_grant)
2840Sstevel@tonic-gate 				return (authname);
2850Sstevel@tonic-gate 		}
2860Sstevel@tonic-gate 		authname = strtok(NULL, AUTH_SEP);
2870Sstevel@tonic-gate 	}
28812578SGlenn.Faden@Sun.COM 	free(tmp);
2890Sstevel@tonic-gate 	return (NULL);
2900Sstevel@tonic-gate }
2910Sstevel@tonic-gate 
2920Sstevel@tonic-gate /*
2930Sstevel@tonic-gate  * Verifies the provided list of profile names are valid.
2940Sstevel@tonic-gate  *
2950Sstevel@tonic-gate  * Returns NULL if all profile names are valid.
2960Sstevel@tonic-gate  * Otherwise, returns the invalid profile name
2970Sstevel@tonic-gate  *
2980Sstevel@tonic-gate  */
2990Sstevel@tonic-gate static const char *
3000Sstevel@tonic-gate check_prof(const char *profs)
3010Sstevel@tonic-gate {
3020Sstevel@tonic-gate 	char *profname;
3030Sstevel@tonic-gate 	profattr_t *result;
3040Sstevel@tonic-gate 	char *tmp;
3050Sstevel@tonic-gate 
3060Sstevel@tonic-gate 	tmp = strdup(profs);
30712578SGlenn.Faden@Sun.COM 	if (tmp == NULL) {
30812578SGlenn.Faden@Sun.COM 		errmsg(M_NOSPACE);
30912578SGlenn.Faden@Sun.COM 		exit(EX_FAILURE);
31012578SGlenn.Faden@Sun.COM 	}
3110Sstevel@tonic-gate 
3120Sstevel@tonic-gate 	profname = strtok(tmp, PROF_SEP);
3130Sstevel@tonic-gate 	while (profname != NULL) {
3140Sstevel@tonic-gate 		result = getprofnam(profname);
3150Sstevel@tonic-gate 		if (result == NULL) {
3160Sstevel@tonic-gate 		/* can't find the profile */
3170Sstevel@tonic-gate 			return (profname);
3180Sstevel@tonic-gate 		}
3190Sstevel@tonic-gate 		free_profattr(result);
3200Sstevel@tonic-gate 		profname = strtok(NULL, PROF_SEP);
3210Sstevel@tonic-gate 	}
32212578SGlenn.Faden@Sun.COM 	free(tmp);
3230Sstevel@tonic-gate 	return (NULL);
3240Sstevel@tonic-gate }
3250Sstevel@tonic-gate 
3260Sstevel@tonic-gate 
3270Sstevel@tonic-gate /*
3280Sstevel@tonic-gate  * Verifies the provided list of role names are valid.
3290Sstevel@tonic-gate  *
3300Sstevel@tonic-gate  * Returns NULL if all role names are valid.
3310Sstevel@tonic-gate  * Otherwise, returns the invalid role name
3320Sstevel@tonic-gate  *
3330Sstevel@tonic-gate  */
3340Sstevel@tonic-gate static const char *
3350Sstevel@tonic-gate check_role(const char *roles)
3360Sstevel@tonic-gate {
3370Sstevel@tonic-gate 	char *rolename;
3380Sstevel@tonic-gate 	userattr_t *result;
3390Sstevel@tonic-gate 	char *utype;
3400Sstevel@tonic-gate 	char *tmp;
3410Sstevel@tonic-gate 
3420Sstevel@tonic-gate 	tmp = strdup(roles);
34312578SGlenn.Faden@Sun.COM 	if (tmp == NULL) {
34412578SGlenn.Faden@Sun.COM 		errmsg(M_NOSPACE);
34512578SGlenn.Faden@Sun.COM 		exit(EX_FAILURE);
34612578SGlenn.Faden@Sun.COM 	}
3470Sstevel@tonic-gate 
3480Sstevel@tonic-gate 	rolename = strtok(tmp, ROLE_SEP);
3490Sstevel@tonic-gate 	while (rolename != NULL) {
3500Sstevel@tonic-gate 		result = getusernam(rolename);
3510Sstevel@tonic-gate 		if (result == NULL) {
3520Sstevel@tonic-gate 		/* can't find the rolename */
3530Sstevel@tonic-gate 			return (rolename);
3540Sstevel@tonic-gate 		}
3550Sstevel@tonic-gate 		/* Now, make sure it is a role */
3560Sstevel@tonic-gate 		utype = kva_match(result->attr, USERATTR_TYPE_KW);
3570Sstevel@tonic-gate 		if (utype == NULL) {
3580Sstevel@tonic-gate 			/* no user type defined. not a role */
3590Sstevel@tonic-gate 			free_userattr(result);
3600Sstevel@tonic-gate 			return (rolename);
3610Sstevel@tonic-gate 		}
3620Sstevel@tonic-gate 		if (strcmp(utype, USERATTR_TYPE_NONADMIN_KW) != 0) {
3630Sstevel@tonic-gate 			free_userattr(result);
3640Sstevel@tonic-gate 			return (rolename);
3650Sstevel@tonic-gate 		}
3660Sstevel@tonic-gate 		free_userattr(result);
3670Sstevel@tonic-gate 		rolename = strtok(NULL, ROLE_SEP);
3680Sstevel@tonic-gate 	}
36912578SGlenn.Faden@Sun.COM 	free(tmp);
3700Sstevel@tonic-gate 	return (NULL);
3710Sstevel@tonic-gate }
3720Sstevel@tonic-gate 
3730Sstevel@tonic-gate static const char *
3740Sstevel@tonic-gate check_proj(const char *proj)
3750Sstevel@tonic-gate {
3760Sstevel@tonic-gate 	if (getprojidbyname(proj) < 0) {
3770Sstevel@tonic-gate 		return (proj);
3780Sstevel@tonic-gate 	} else {
3790Sstevel@tonic-gate 		return (NULL);
3800Sstevel@tonic-gate 	}
3810Sstevel@tonic-gate }
3820Sstevel@tonic-gate 
3830Sstevel@tonic-gate static const char *
3840Sstevel@tonic-gate check_privset(const char *pset)
3850Sstevel@tonic-gate {
3860Sstevel@tonic-gate 	priv_set_t *tmp;
3870Sstevel@tonic-gate 	const char *res;
3880Sstevel@tonic-gate 
3890Sstevel@tonic-gate 	tmp = priv_str_to_set(pset, ",", &res);
3900Sstevel@tonic-gate 
3910Sstevel@tonic-gate 	if (tmp != NULL) {
3920Sstevel@tonic-gate 		res = NULL;
3930Sstevel@tonic-gate 		priv_freeset(tmp);
3940Sstevel@tonic-gate 	} else if (res == NULL)
3950Sstevel@tonic-gate 		res = strerror(errno);
3960Sstevel@tonic-gate 
3970Sstevel@tonic-gate 	return (res);
3980Sstevel@tonic-gate }
3990Sstevel@tonic-gate 
4000Sstevel@tonic-gate static const char *
4010Sstevel@tonic-gate check_type(const char *type)
4020Sstevel@tonic-gate {
4030Sstevel@tonic-gate 	if (strcmp(type, USERATTR_TYPE_NONADMIN_KW) != 0 &&
4040Sstevel@tonic-gate 	    strcmp(type, USERATTR_TYPE_NORMAL_KW) != 0)
4050Sstevel@tonic-gate 		return (type);
4060Sstevel@tonic-gate 
4070Sstevel@tonic-gate 	return (NULL);
4080Sstevel@tonic-gate }
4090Sstevel@tonic-gate 
4100Sstevel@tonic-gate static const char *
4110Sstevel@tonic-gate check_lock_after_retries(const char *keyval)
4120Sstevel@tonic-gate {
4130Sstevel@tonic-gate 	if (keyval != NULL) {
4140Sstevel@tonic-gate 		if ((strcasecmp(keyval, "no") != 0) &&
4150Sstevel@tonic-gate 		    (strcasecmp(keyval, "yes") != 0) &&
4160Sstevel@tonic-gate 		    (*keyval != '\0'))   {
4170Sstevel@tonic-gate 			return (keyval);
4180Sstevel@tonic-gate 		}
4190Sstevel@tonic-gate 	}
4200Sstevel@tonic-gate 	return (NULL);
4210Sstevel@tonic-gate }
4222657Srica 
4232657Srica static const char *
4242657Srica check_label(const char *labelstr)
4252657Srica {
4262657Srica 	int	err;
4272657Srica 	m_label_t *lbl = NULL;
4282657Srica 
4292657Srica 	if (!is_system_labeled())
4302657Srica 		return (NULL);
4312657Srica 
4322657Srica 	err = str_to_label(labelstr, &lbl, MAC_LABEL, L_NO_CORRECTION, NULL);
4332657Srica 	m_label_free(lbl);
4342657Srica 
4352657Srica 	if (err == -1)
4362657Srica 		return (labelstr);
4372657Srica 
4382657Srica 	return (NULL);
4392657Srica }
4402657Srica 
4412657Srica static const char *
4422657Srica check_idlecmd(const char *cmd)
4432657Srica {
4442657Srica 	if ((strcmp(cmd, USERATTR_IDLECMD_LOCK_KW) != 0) &&
4452657Srica 	    (strcmp(cmd, USERATTR_IDLECMD_LOGOUT_KW) != 0)) {
4462657Srica 		return (cmd);
4472657Srica 	}
4482657Srica 
4492657Srica 	return (NULL);
4502657Srica }
4512657Srica 
4522657Srica static const char *
4532657Srica check_idletime(const char *time)
4542657Srica {
4552657Srica 	int		c;
4562657Srica 	unsigned char	*up = (unsigned char *)time;
4572657Srica 
4582657Srica 	c = *up;
4592657Srica 	while (c != '\0') {
4602657Srica 		if (!isdigit(c))
4612657Srica 			return (time);
4622657Srica 		c = *++up;
4632657Srica 	}
4642657Srica 
4652657Srica 	return (NULL);
4662657Srica }
467