add UNLEASHED_OBJ to unleashed.mk
[unleashed/tickless.git] / usr / src / cmd / oamuser / user / funcs.c
blob0fd85313b3f0a8d93de5f727a1076ef653b561df
1 /*
2 * CDDL HEADER START
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]
19 * CDDL HEADER END
22 * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
23 * Copyright (c) 2013 RackTop Systems.
26 #include <stdio.h>
27 #include <stdlib.h>
28 #include <strings.h>
29 #include <auth_attr.h>
30 #include <prof_attr.h>
31 #include <user_attr.h>
32 #include <project.h>
33 #include <secdb.h>
34 #include <pwd.h>
35 #include <unistd.h>
36 #include <priv.h>
37 #include <errno.h>
38 #include <ctype.h>
39 #include <nss.h>
40 #include <bsm/libbsm.h>
41 #include "funcs.h"
42 #include "messages.h"
43 #undef GROUP
44 #include "userdefs.h"
46 typedef struct ua_key {
47 const char *key;
48 const char *(*check)(const char *);
49 const char *errstr;
50 char *newvalue;
51 } ua_key_t;
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 *);
76 int nkeys;
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.
100 void
101 change_key(const char *key, char *value)
103 int i;
104 const char *res;
106 if (key == NULL) {
107 key = value;
108 value = strchr(value, '=');
109 /* Bad value */
110 if (value == NULL) {
111 errmsg(M_INVALID_VALUE);
112 exit(EX_BADARG);
114 *value++ = '\0';
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);
122 exit(EX_BADARG);
125 if (keys[i].check != NULL &&
126 (res = keys[i].check(value)) != NULL) {
127 errmsg(M_INVALID, res, keys[i].errstr);
128 exit(EX_BADARG);
130 keys[i].newvalue = value;
131 nkeys++;
132 return;
135 errmsg(M_INVALID_KEY, key);
136 exit(EX_BADARG);
140 * Add the keys to the argument vector.
142 void
143 addkey_args(char **argv, int *index)
145 int i;
147 for (i = 0; i < NKEYS; i++) {
148 const char *key = keys[i].key;
149 char *val = keys[i].newvalue;
150 size_t len;
151 char *arg;
153 if (val == NULL)
154 continue;
156 len = strlen(key) + strlen(val) + 2;
157 arg = malloc(len);
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.
170 char *
171 getsetdefval(const char *key, char *dflt)
173 int i;
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);
179 else
180 return (keys[i].newvalue = dflt);
182 return (NULL);
185 char *
186 getusertype(char *cmdname)
188 static char usertype[MAX_TYPE_LENGTH];
189 char *cmd;
191 if ((cmd = strrchr(cmdname, '/')))
192 ++cmd;
193 else
194 cmd = 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);
200 else
201 strcpy(usertype, USERATTR_TYPE_NONADMIN_KW);
203 return (usertype);
207 is_role(char *usertype)
209 if (strcmp(usertype, USERATTR_TYPE_NONADMIN_KW) == 0)
210 return (1);
211 /* not a role */
212 return (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
222 static const char *
223 check_auth(const char *auths)
225 char *authname;
226 authattr_t *result;
227 char *tmp;
228 struct passwd *pw;
229 int have_grant = 0;
231 tmp = strdup(auths);
232 if (tmp == NULL) {
233 errmsg(M_NOSPACE);
234 exit(EX_FAILURE);
237 authname = strtok(tmp, AUTH_SEP);
238 pw = getpwuid(getuid());
239 if (pw == NULL) {
240 return (authname);
243 while (authname != NULL) {
244 char *suffix;
245 char *authtoks;
247 /* Check if user has been granted this authorization */
248 if (!chkauthattr(authname, pw->pw_name))
249 return (authname);
251 /* Remove named object after slash */
252 if ((suffix = index(authname, KV_OBJECTCHAR)) != NULL)
253 *suffix = '\0';
255 /* Find the suffix */
256 if ((suffix = rindex(authname, '.')) == NULL)
257 return (authname);
259 /* Check for existence in auth_attr */
260 suffix++;
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);
266 return (authname);
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);
275 have_grant = 0;
276 while ((suffix = rindex(authtoks, '.')) &&
277 !have_grant) {
278 strcpy(suffix, ".grant");
279 if (chkauthattr(authtoks, pw->pw_name))
280 have_grant = 1;
281 else
282 *suffix = '\0';
284 if (!have_grant)
285 return (authname);
287 authname = strtok(NULL, AUTH_SEP);
289 free(tmp);
290 return (NULL);
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
300 static const char *
301 check_prof(const char *profs)
303 char *profname;
304 profattr_t *result;
305 char *tmp;
307 tmp = strdup(profs);
308 if (tmp == NULL) {
309 errmsg(M_NOSPACE);
310 exit(EX_FAILURE);
313 profname = strtok(tmp, PROF_SEP);
314 while (profname != NULL) {
315 result = getprofnam(profname);
316 if (result == NULL) {
317 /* can't find the profile */
318 return (profname);
320 free_profattr(result);
321 profname = strtok(NULL, PROF_SEP);
323 free(tmp);
324 return (NULL);
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
335 static const char *
336 check_role(const char *roles)
338 char *rolename;
339 userattr_t *result;
340 char *utype;
341 char *tmp;
343 tmp = strdup(roles);
344 if (tmp == NULL) {
345 errmsg(M_NOSPACE);
346 exit(EX_FAILURE);
349 rolename = strtok(tmp, ROLE_SEP);
350 while (rolename != NULL) {
351 result = getusernam(rolename);
352 if (result == NULL) {
353 /* can't find the rolename */
354 return (rolename);
356 /* Now, make sure it is a role */
357 utype = kva_match(result->attr, USERATTR_TYPE_KW);
358 if (utype == NULL) {
359 /* no user type defined. not a role */
360 free_userattr(result);
361 return (rolename);
363 if (strcmp(utype, USERATTR_TYPE_NONADMIN_KW) != 0) {
364 free_userattr(result);
365 return (rolename);
367 free_userattr(result);
368 rolename = strtok(NULL, ROLE_SEP);
370 free(tmp);
371 return (NULL);
374 static const char *
375 check_proj(const char *proj)
377 if (getprojidbyname(proj) < 0) {
378 return (proj);
379 } else {
380 return (NULL);
384 static const char *
385 check_privset(const char *pset)
387 priv_set_t *tmp;
388 const char *res;
390 tmp = priv_str_to_set(pset, ",", &res);
392 if (tmp != NULL) {
393 res = NULL;
394 priv_freeset(tmp);
395 } else if (res == NULL)
396 res = strerror(errno);
398 return (res);
401 static const char *
402 check_type(const char *type)
404 if (strcmp(type, USERATTR_TYPE_NONADMIN_KW) != 0 &&
405 strcmp(type, USERATTR_TYPE_NORMAL_KW) != 0)
406 return (type);
408 return (NULL);
411 static const char *
412 check_lock_after_retries(const char *keyval)
414 if (keyval != NULL) {
415 if ((strcasecmp(keyval, "no") != 0) &&
416 (strcasecmp(keyval, "yes") != 0) &&
417 (*keyval != '\0')) {
418 return (keyval);
421 return (NULL);
424 static const char *
425 check_auditflags(const char *auditflags)
427 au_mask_t mask;
428 char *flags;
429 char *last = NULL;
430 char *err = "NULL";
432 /* if deleting audit_flags */
433 if (*auditflags == '\0') {
434 return (NULL);
437 if ((flags = _strdup_null((char *)auditflags)) == NULL) {
438 errmsg(M_NOSPACE);
439 exit(EX_FAILURE);
442 if (!__chkflags(_strtok_escape(flags, KV_AUDIT_DELIMIT, &last), &mask,
443 B_FALSE, &err)) {
444 (void) snprintf(auditerr, sizeof (auditerr),
445 "always mask \"%s\"", err);
446 free(flags);
447 return (auditerr);
449 if (!__chkflags(_strtok_escape(NULL, KV_AUDIT_DELIMIT, &last), &mask,
450 B_FALSE, &err)) {
451 (void) snprintf(auditerr, sizeof (auditerr),
452 "never mask \"%s\"", err);
453 free(flags);
454 return (auditerr);
456 if (last != NULL) {
457 (void) snprintf(auditerr, sizeof (auditerr), "\"%s\"",
458 auditflags);
459 free(flags);
460 return (auditerr);
462 free(flags);
464 return (NULL);