4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
22 * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
23 * Copyright (c) 2013 RackTop Systems.
29 #include <auth_attr.h>
30 #include <prof_attr.h>
31 #include <user_attr.h>
40 #include <bsm/libbsm.h>
46 typedef struct ua_key
{
48 const char *(*check
)(const char *);
53 static const char role
[] = "role name";
54 static const char prof
[] = "profile name";
55 static const char proj
[] = "project name";
56 static const char priv
[] = "privilege set";
57 static const char auth
[] = "authorization";
58 static const char type
[] = "user type";
59 static const char lock
[] = "lock_after_retries value";
60 static const char label
[] = "label";
61 static const char idlecmd
[] = "idlecmd value";
62 static const char idletime
[] = "idletime value";
63 static const char auditflags
[] = "audit mask";
64 static char auditerr
[256];
67 static const char *check_auth(const char *);
68 static const char *check_prof(const char *);
69 static const char *check_role(const char *);
70 static const char *check_proj(const char *);
71 static const char *check_privset(const char *);
72 static const char *check_type(const char *);
73 static const char *check_lock_after_retries(const char *);
74 static const char *check_auditflags(const char *);
78 static ua_key_t keys
[] = {
79 /* First entry is always set correctly in main() */
80 { USERATTR_TYPE_KW
, check_type
, type
},
81 { USERATTR_AUTHS_KW
, check_auth
, auth
},
82 { USERATTR_PROFILES_KW
, check_prof
, prof
},
83 { USERATTR_ROLES_KW
, check_role
, role
},
84 { USERATTR_DEFAULTPROJ_KW
, check_proj
, proj
},
85 { USERATTR_LIMPRIV_KW
, check_privset
, priv
},
86 { USERATTR_DFLTPRIV_KW
, check_privset
, priv
},
87 { USERATTR_LOCK_AFTER_RETRIES_KW
, check_lock_after_retries
, lock
},
88 { USERATTR_AUDIT_FLAGS_KW
, check_auditflags
, auditflags
},
91 #define NKEYS (sizeof (keys)/sizeof (ua_key_t))
94 * Change a key, there are three different call sequences:
96 * key, value - key with option letter, value.
97 * NULL, value - -K key=value option.
101 change_key(const char *key
, char *value
)
108 value
= strchr(value
, '=');
111 errmsg(M_INVALID_VALUE
);
117 for (i
= 0; i
< NKEYS
; i
++) {
118 if (strcmp(key
, keys
[i
].key
) == 0) {
119 if (keys
[i
].newvalue
!= NULL
) {
120 /* Can't set a value twice */
121 errmsg(M_REDEFINED_KEY
, key
);
125 if (keys
[i
].check
!= NULL
&&
126 (res
= keys
[i
].check(value
)) != NULL
) {
127 errmsg(M_INVALID
, res
, keys
[i
].errstr
);
130 keys
[i
].newvalue
= value
;
135 errmsg(M_INVALID_KEY
, key
);
140 * Add the keys to the argument vector.
143 addkey_args(char **argv
, int *index
)
147 for (i
= 0; i
< NKEYS
; i
++) {
148 const char *key
= keys
[i
].key
;
149 char *val
= keys
[i
].newvalue
;
156 len
= strlen(key
) + strlen(val
) + 2;
159 (void) snprintf(arg
, len
, "%s=%s", key
, val
);
160 argv
[(*index
)++] = "-K";
161 argv
[(*index
)++] = arg
;
166 * Propose a default value for a key and get the actual value back.
167 * If the proposed default value is NULL, return the actual value set.
168 * The key argument is the user_attr key.
171 getsetdefval(const char *key
, char *dflt
)
175 for (i
= 0; i
< NKEYS
; i
++)
176 if (strcmp(keys
[i
].key
, key
) == 0) {
177 if (keys
[i
].newvalue
!= NULL
)
178 return (keys
[i
].newvalue
);
180 return (keys
[i
].newvalue
= dflt
);
186 getusertype(char *cmdname
)
188 static char usertype
[MAX_TYPE_LENGTH
];
191 if ((cmd
= strrchr(cmdname
, '/')))
196 /* get user type based on the program name */
197 if (strncmp(cmd
, CMD_PREFIX_USER
,
198 strlen(CMD_PREFIX_USER
)) == 0)
199 strcpy(usertype
, USERATTR_TYPE_NORMAL_KW
);
201 strcpy(usertype
, USERATTR_TYPE_NONADMIN_KW
);
207 is_role(char *usertype
)
209 if (strcmp(usertype
, USERATTR_TYPE_NONADMIN_KW
) == 0)
216 * Verifies the provided list of authorizations are all valid.
218 * Returns NULL if all authorization names are valid.
219 * Otherwise, returns the invalid authorization name
223 check_auth(const char *auths
)
237 authname
= strtok(tmp
, AUTH_SEP
);
238 pw
= getpwuid(getuid());
243 while (authname
!= NULL
) {
247 /* Check if user has been granted this authorization */
248 if (!chkauthattr(authname
, pw
->pw_name
))
251 /* Remove named object after slash */
252 if ((suffix
= index(authname
, KV_OBJECTCHAR
)) != NULL
)
255 /* Find the suffix */
256 if ((suffix
= rindex(authname
, '.')) == NULL
)
259 /* Check for existence in auth_attr */
261 if (strcmp(suffix
, KV_WILDCARD
)) { /* Not a wildcard */
262 result
= getauthnam(authname
);
263 if (result
== NULL
) {
264 /* can't find the auth */
265 free_authattr(result
);
268 free_authattr(result
);
271 /* Check if user can delegate this authorization */
272 if (strcmp(suffix
, "grant")) { /* Not a grant option */
273 authtoks
= malloc(strlen(authname
) + sizeof ("grant"));
274 strcpy(authtoks
, authname
);
276 while ((suffix
= rindex(authtoks
, '.')) &&
278 strcpy(suffix
, ".grant");
279 if (chkauthattr(authtoks
, pw
->pw_name
))
287 authname
= strtok(NULL
, AUTH_SEP
);
294 * Verifies the provided list of profile names are valid.
296 * Returns NULL if all profile names are valid.
297 * Otherwise, returns the invalid profile name
301 check_prof(const char *profs
)
313 profname
= strtok(tmp
, PROF_SEP
);
314 while (profname
!= NULL
) {
315 result
= getprofnam(profname
);
316 if (result
== NULL
) {
317 /* can't find the profile */
320 free_profattr(result
);
321 profname
= strtok(NULL
, PROF_SEP
);
329 * Verifies the provided list of role names are valid.
331 * Returns NULL if all role names are valid.
332 * Otherwise, returns the invalid role name
336 check_role(const char *roles
)
349 rolename
= strtok(tmp
, ROLE_SEP
);
350 while (rolename
!= NULL
) {
351 result
= getusernam(rolename
);
352 if (result
== NULL
) {
353 /* can't find the rolename */
356 /* Now, make sure it is a role */
357 utype
= kva_match(result
->attr
, USERATTR_TYPE_KW
);
359 /* no user type defined. not a role */
360 free_userattr(result
);
363 if (strcmp(utype
, USERATTR_TYPE_NONADMIN_KW
) != 0) {
364 free_userattr(result
);
367 free_userattr(result
);
368 rolename
= strtok(NULL
, ROLE_SEP
);
375 check_proj(const char *proj
)
377 if (getprojidbyname(proj
) < 0) {
385 check_privset(const char *pset
)
390 tmp
= priv_str_to_set(pset
, ",", &res
);
395 } else if (res
== NULL
)
396 res
= strerror(errno
);
402 check_type(const char *type
)
404 if (strcmp(type
, USERATTR_TYPE_NONADMIN_KW
) != 0 &&
405 strcmp(type
, USERATTR_TYPE_NORMAL_KW
) != 0)
412 check_lock_after_retries(const char *keyval
)
414 if (keyval
!= NULL
) {
415 if ((strcasecmp(keyval
, "no") != 0) &&
416 (strcasecmp(keyval
, "yes") != 0) &&
425 check_auditflags(const char *auditflags
)
432 /* if deleting audit_flags */
433 if (*auditflags
== '\0') {
437 if ((flags
= _strdup_null((char *)auditflags
)) == NULL
) {
442 if (!__chkflags(_strtok_escape(flags
, KV_AUDIT_DELIMIT
, &last
), &mask
,
444 (void) snprintf(auditerr
, sizeof (auditerr
),
445 "always mask \"%s\"", err
);
449 if (!__chkflags(_strtok_escape(NULL
, KV_AUDIT_DELIMIT
, &last
), &mask
,
451 (void) snprintf(auditerr
, sizeof (auditerr
),
452 "never mask \"%s\"", err
);
457 (void) snprintf(auditerr
, sizeof (auditerr
), "\"%s\"",