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>
41 #include <tsol/label.h>
47 typedef struct ua_key
{
49 const char *(*check
)(const char *);
54 static const char role
[] = "role name";
55 static const char prof
[] = "profile name";
56 static const char proj
[] = "project name";
57 static const char priv
[] = "privilege set";
58 static const char auth
[] = "authorization";
59 static const char type
[] = "user type";
60 static const char lock
[] = "lock_after_retries value";
61 static const char label
[] = "label";
62 static const char idlecmd
[] = "idlecmd value";
63 static const char idletime
[] = "idletime value";
64 static const char auditflags
[] = "audit mask";
65 static char auditerr
[256];
68 static const char *check_auth(const char *);
69 static const char *check_prof(const char *);
70 static const char *check_role(const char *);
71 static const char *check_proj(const char *);
72 static const char *check_privset(const char *);
73 static const char *check_type(const char *);
74 static const char *check_lock_after_retries(const char *);
75 static const char *check_label(const char *);
76 static const char *check_idlecmd(const char *);
77 static const char *check_idletime(const char *);
78 static const char *check_auditflags(const char *);
82 static ua_key_t keys
[] = {
83 /* First entry is always set correctly in main() */
84 { USERATTR_TYPE_KW
, check_type
, type
},
85 { USERATTR_AUTHS_KW
, check_auth
, auth
},
86 { USERATTR_PROFILES_KW
, check_prof
, prof
},
87 { USERATTR_ROLES_KW
, check_role
, role
},
88 { USERATTR_DEFAULTPROJ_KW
, check_proj
, proj
},
89 { USERATTR_LIMPRIV_KW
, check_privset
, priv
},
90 { USERATTR_DFLTPRIV_KW
, check_privset
, priv
},
91 { USERATTR_LOCK_AFTER_RETRIES_KW
, check_lock_after_retries
, lock
},
92 { USERATTR_CLEARANCE
, check_label
, label
},
93 { USERATTR_MINLABEL
, check_label
, label
},
94 { USERATTR_IDLECMD_KW
, check_idlecmd
, idlecmd
},
95 { USERATTR_IDLETIME_KW
, check_idletime
, idletime
},
96 { USERATTR_AUDIT_FLAGS_KW
, check_auditflags
, auditflags
},
99 #define NKEYS (sizeof (keys)/sizeof (ua_key_t))
102 * Change a key, there are three different call sequences:
104 * key, value - key with option letter, value.
105 * NULL, value - -K key=value option.
109 change_key(const char *key
, char *value
)
116 value
= strchr(value
, '=');
119 errmsg(M_INVALID_VALUE
);
125 for (i
= 0; i
< NKEYS
; i
++) {
126 if (strcmp(key
, keys
[i
].key
) == 0) {
127 if (keys
[i
].newvalue
!= NULL
) {
128 /* Can't set a value twice */
129 errmsg(M_REDEFINED_KEY
, key
);
133 if (keys
[i
].check
!= NULL
&&
134 (res
= keys
[i
].check(value
)) != NULL
) {
135 errmsg(M_INVALID
, res
, keys
[i
].errstr
);
138 keys
[i
].newvalue
= value
;
143 errmsg(M_INVALID_KEY
, key
);
148 * Add the keys to the argument vector.
151 addkey_args(char **argv
, int *index
)
155 for (i
= 0; i
< NKEYS
; i
++) {
156 const char *key
= keys
[i
].key
;
157 char *val
= keys
[i
].newvalue
;
164 len
= strlen(key
) + strlen(val
) + 2;
167 (void) snprintf(arg
, len
, "%s=%s", key
, val
);
168 argv
[(*index
)++] = "-K";
169 argv
[(*index
)++] = arg
;
174 * Propose a default value for a key and get the actual value back.
175 * If the proposed default value is NULL, return the actual value set.
176 * The key argument is the user_attr key.
179 getsetdefval(const char *key
, char *dflt
)
183 for (i
= 0; i
< NKEYS
; i
++)
184 if (strcmp(keys
[i
].key
, key
) == 0) {
185 if (keys
[i
].newvalue
!= NULL
)
186 return (keys
[i
].newvalue
);
188 return (keys
[i
].newvalue
= dflt
);
194 getusertype(char *cmdname
)
196 static char usertype
[MAX_TYPE_LENGTH
];
199 if ((cmd
= strrchr(cmdname
, '/')))
204 /* get user type based on the program name */
205 if (strncmp(cmd
, CMD_PREFIX_USER
,
206 strlen(CMD_PREFIX_USER
)) == 0)
207 strcpy(usertype
, USERATTR_TYPE_NORMAL_KW
);
209 strcpy(usertype
, USERATTR_TYPE_NONADMIN_KW
);
215 is_role(char *usertype
)
217 if (strcmp(usertype
, USERATTR_TYPE_NONADMIN_KW
) == 0)
224 * Verifies the provided list of authorizations are all valid.
226 * Returns NULL if all authorization names are valid.
227 * Otherwise, returns the invalid authorization name
231 check_auth(const char *auths
)
245 authname
= strtok(tmp
, AUTH_SEP
);
246 pw
= getpwuid(getuid());
251 while (authname
!= NULL
) {
255 /* Check if user has been granted this authorization */
256 if (!chkauthattr(authname
, pw
->pw_name
))
259 /* Remove named object after slash */
260 if ((suffix
= index(authname
, KV_OBJECTCHAR
)) != NULL
)
263 /* Find the suffix */
264 if ((suffix
= rindex(authname
, '.')) == NULL
)
267 /* Check for existence in auth_attr */
269 if (strcmp(suffix
, KV_WILDCARD
)) { /* Not a wildcard */
270 result
= getauthnam(authname
);
271 if (result
== NULL
) {
272 /* can't find the auth */
273 free_authattr(result
);
276 free_authattr(result
);
279 /* Check if user can delegate this authorization */
280 if (strcmp(suffix
, "grant")) { /* Not a grant option */
281 authtoks
= malloc(strlen(authname
) + sizeof ("grant"));
282 strcpy(authtoks
, authname
);
284 while ((suffix
= rindex(authtoks
, '.')) &&
286 strcpy(suffix
, ".grant");
287 if (chkauthattr(authtoks
, pw
->pw_name
))
295 authname
= strtok(NULL
, AUTH_SEP
);
302 * Verifies the provided list of profile names are valid.
304 * Returns NULL if all profile names are valid.
305 * Otherwise, returns the invalid profile name
309 check_prof(const char *profs
)
321 profname
= strtok(tmp
, PROF_SEP
);
322 while (profname
!= NULL
) {
323 result
= getprofnam(profname
);
324 if (result
== NULL
) {
325 /* can't find the profile */
328 free_profattr(result
);
329 profname
= strtok(NULL
, PROF_SEP
);
337 * Verifies the provided list of role names are valid.
339 * Returns NULL if all role names are valid.
340 * Otherwise, returns the invalid role name
344 check_role(const char *roles
)
357 rolename
= strtok(tmp
, ROLE_SEP
);
358 while (rolename
!= NULL
) {
359 result
= getusernam(rolename
);
360 if (result
== NULL
) {
361 /* can't find the rolename */
364 /* Now, make sure it is a role */
365 utype
= kva_match(result
->attr
, USERATTR_TYPE_KW
);
367 /* no user type defined. not a role */
368 free_userattr(result
);
371 if (strcmp(utype
, USERATTR_TYPE_NONADMIN_KW
) != 0) {
372 free_userattr(result
);
375 free_userattr(result
);
376 rolename
= strtok(NULL
, ROLE_SEP
);
383 check_proj(const char *proj
)
385 if (getprojidbyname(proj
) < 0) {
393 check_privset(const char *pset
)
398 tmp
= priv_str_to_set(pset
, ",", &res
);
403 } else if (res
== NULL
)
404 res
= strerror(errno
);
410 check_type(const char *type
)
412 if (strcmp(type
, USERATTR_TYPE_NONADMIN_KW
) != 0 &&
413 strcmp(type
, USERATTR_TYPE_NORMAL_KW
) != 0)
420 check_lock_after_retries(const char *keyval
)
422 if (keyval
!= NULL
) {
423 if ((strcasecmp(keyval
, "no") != 0) &&
424 (strcasecmp(keyval
, "yes") != 0) &&
433 check_label(const char *labelstr
)
436 m_label_t
*lbl
= NULL
;
438 if (!is_system_labeled())
441 err
= str_to_label(labelstr
, &lbl
, MAC_LABEL
, L_NO_CORRECTION
, NULL
);
451 check_idlecmd(const char *cmd
)
453 if ((strcmp(cmd
, USERATTR_IDLECMD_LOCK_KW
) != 0) &&
454 (strcmp(cmd
, USERATTR_IDLECMD_LOGOUT_KW
) != 0)) {
462 check_idletime(const char *time
)
465 unsigned char *up
= (unsigned char *)time
;
478 check_auditflags(const char *auditflags
)
485 /* if deleting audit_flags */
486 if (*auditflags
== '\0') {
490 if ((flags
= _strdup_null((char *)auditflags
)) == NULL
) {
495 if (!__chkflags(_strtok_escape(flags
, KV_AUDIT_DELIMIT
, &last
), &mask
,
497 (void) snprintf(auditerr
, sizeof (auditerr
),
498 "always mask \"%s\"", err
);
502 if (!__chkflags(_strtok_escape(NULL
, KV_AUDIT_DELIMIT
, &last
), &mask
,
504 (void) snprintf(auditerr
, sizeof (auditerr
),
505 "never mask \"%s\"", err
);
510 (void) snprintf(auditerr
, sizeof (auditerr
), "\"%s\"",