Print this page
Add libuserdefs and use in cmd/{oamuser,passwd}
Split |
Close |
Expand all |
Collapse all |
--- old/usr/src/cmd/oamuser/user/funcs.c
+++ new/usr/src/cmd/oamuser/user/funcs.c
1 1 /*
2 2 * CDDL HEADER START
3 3 *
4 4 * The contents of this file are subject to the terms of the
5 5 * Common Development and Distribution License (the "License").
6 6 * You may not use this file except in compliance with the License.
7 7 *
8 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 9 * or http://www.opensolaris.org/os/licensing.
10 10 * See the License for the specific language governing permissions
11 11 * and limitations under the License.
12 12 *
13 13 * When distributing Covered Code, include this CDDL HEADER in each
14 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 15 * If applicable, add the following below this CDDL HEADER, with the
16 16 * fields enclosed by brackets "[]" replaced with your own identifying
17 17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 18 *
19 19 * CDDL HEADER END
20 20 */
21 21 /*
22 22 * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
23 23 * Copyright (c) 2013 RackTop Systems.
24 24 */
25 25
26 26 #include <stdio.h>
27 27 #include <stdlib.h>
28 28 #include <strings.h>
29 29 #include <auth_attr.h>
30 30 #include <prof_attr.h>
31 31 #include <user_attr.h>
32 32 #include <project.h>
33 33 #include <secdb.h>
34 34 #include <pwd.h>
35 35 #include <unistd.h>
36 36 #include <priv.h>
37 37 #include <errno.h>
38 38 #include <ctype.h>
39 39 #include <nss.h>
40 40 #include <bsm/libbsm.h>
41 41 #include <tsol/label.h>
42 42 #include "funcs.h"
43 43 #include "messages.h"
44 44 #undef GROUP
45 45 #include "userdefs.h"
46 46
47 47 typedef struct ua_key {
48 48 const char *key;
49 49 const char *(*check)(const char *);
50 50 const char *errstr;
51 51 char *newvalue;
52 52 } ua_key_t;
53 53
54 54 static const char role[] = "role name";
55 55 static const char prof[] = "profile name";
56 56 static const char proj[] = "project name";
57 57 static const char priv[] = "privilege set";
58 58 static const char auth[] = "authorization";
59 59 static const char type[] = "user type";
60 60 static const char lock[] = "lock_after_retries value";
61 61 static const char label[] = "label";
62 62 static const char idlecmd[] = "idlecmd value";
63 63 static const char idletime[] = "idletime value";
64 64 static const char auditflags[] = "audit mask";
65 65 static char auditerr[256];
66 66
67 67
68 68 static const char *check_auth(const char *);
69 69 static const char *check_prof(const char *);
70 70 static const char *check_role(const char *);
71 71 static const char *check_proj(const char *);
72 72 static const char *check_privset(const char *);
73 73 static const char *check_type(const char *);
74 74 static const char *check_lock_after_retries(const char *);
75 75 static const char *check_label(const char *);
76 76 static const char *check_idlecmd(const char *);
77 77 static const char *check_idletime(const char *);
78 78 static const char *check_auditflags(const char *);
79 79
80 80 int nkeys;
81 81
82 82 static ua_key_t keys[] = {
83 83 /* First entry is always set correctly in main() */
84 84 { USERATTR_TYPE_KW, check_type, type },
85 85 { USERATTR_AUTHS_KW, check_auth, auth },
86 86 { USERATTR_PROFILES_KW, check_prof, prof },
87 87 { USERATTR_ROLES_KW, check_role, role },
88 88 { USERATTR_DEFAULTPROJ_KW, check_proj, proj },
89 89 { USERATTR_LIMPRIV_KW, check_privset, priv },
90 90 { USERATTR_DFLTPRIV_KW, check_privset, priv },
↓ open down ↓ |
90 lines elided |
↑ open up ↑ |
91 91 { USERATTR_LOCK_AFTER_RETRIES_KW, check_lock_after_retries, lock },
92 92 { USERATTR_CLEARANCE, check_label, label },
93 93 { USERATTR_MINLABEL, check_label, label },
94 94 { USERATTR_IDLECMD_KW, check_idlecmd, idlecmd },
95 95 { USERATTR_IDLETIME_KW, check_idletime, idletime },
96 96 { USERATTR_AUDIT_FLAGS_KW, check_auditflags, auditflags },
97 97 };
98 98
99 99 #define NKEYS (sizeof (keys)/sizeof (ua_key_t))
100 100
101 +/* Import default keys for ordinary useradd */
102 +void
103 +import_def(struct userdefs *ud)
104 +{
105 + int i;
106 +
107 + /* Don't import the user type (skip i = 0) */
108 + for (i = 1; i < NKEYS; i++) {
109 + if (keys[i].newvalue == NULL)
110 + keys[i].newvalue =
111 + userdef_get_by_uakey(ud, keys[i].key);
112 + }
113 +}
114 +
115 +/* Export command line keys to defaults for useradd -D */
116 +void
117 +update_def(struct userdefs *ud)
118 +{
119 + int i;
120 +
121 + for (i = 0; i < NKEYS; i++) {
122 + if (keys[i].newvalue != NULL)
123 + userdef_set_by_uakey(ud, keys[i].key,
124 + keys[i].newvalue);
125 + }
126 +}
127 +
101 128 /*
102 129 * Change a key, there are three different call sequences:
103 130 *
104 131 * key, value - key with option letter, value.
105 132 * NULL, value - -K key=value option.
106 133 */
107 134
108 135 void
109 136 change_key(const char *key, char *value)
110 137 {
111 138 int i;
112 139 const char *res;
113 140
114 141 if (key == NULL) {
115 142 key = value;
116 143 value = strchr(value, '=');
117 144 /* Bad value */
118 145 if (value == NULL) {
119 146 errmsg(M_INVALID_VALUE);
120 147 exit(EX_BADARG);
121 148 }
122 149 *value++ = '\0';
123 150 }
124 151
125 152 for (i = 0; i < NKEYS; i++) {
126 153 if (strcmp(key, keys[i].key) == 0) {
127 154 if (keys[i].newvalue != NULL) {
128 155 /* Can't set a value twice */
129 156 errmsg(M_REDEFINED_KEY, key);
130 157 exit(EX_BADARG);
131 158 }
132 159
133 160 if (keys[i].check != NULL &&
134 161 (res = keys[i].check(value)) != NULL) {
135 162 errmsg(M_INVALID, res, keys[i].errstr);
136 163 exit(EX_BADARG);
137 164 }
138 165 keys[i].newvalue = value;
139 166 nkeys++;
140 167 return;
141 168 }
142 169 }
143 170 errmsg(M_INVALID_KEY, key);
144 171 exit(EX_BADARG);
145 172 }
146 173
147 174 /*
148 175 * Add the keys to the argument vector.
149 176 */
150 177 void
151 178 addkey_args(char **argv, int *index)
152 179 {
153 180 int i;
154 181
155 182 for (i = 0; i < NKEYS; i++) {
156 183 const char *key = keys[i].key;
157 184 char *val = keys[i].newvalue;
158 185 size_t len;
159 186 char *arg;
160 187
161 188 if (val == NULL)
162 189 continue;
163 190
164 191 len = strlen(key) + strlen(val) + 2;
165 192 arg = malloc(len);
166 193
167 194 (void) snprintf(arg, len, "%s=%s", key, val);
168 195 argv[(*index)++] = "-K";
169 196 argv[(*index)++] = arg;
170 197 }
171 198 }
172 199
173 200 /*
174 201 * Propose a default value for a key and get the actual value back.
175 202 * If the proposed default value is NULL, return the actual value set.
176 203 * The key argument is the user_attr key.
177 204 */
178 205 char *
179 206 getsetdefval(const char *key, char *dflt)
180 207 {
181 208 int i;
182 209
183 210 for (i = 0; i < NKEYS; i++)
184 211 if (strcmp(keys[i].key, key) == 0) {
185 212 if (keys[i].newvalue != NULL)
186 213 return (keys[i].newvalue);
187 214 else
188 215 return (keys[i].newvalue = dflt);
189 216 }
190 217 return (NULL);
191 218 }
192 219
193 220 char *
194 221 getusertype(char *cmdname)
195 222 {
196 223 static char usertype[MAX_TYPE_LENGTH];
197 224 char *cmd;
198 225
199 226 if ((cmd = strrchr(cmdname, '/')))
200 227 ++cmd;
201 228 else
202 229 cmd = cmdname;
203 230
204 231 /* get user type based on the program name */
205 232 if (strncmp(cmd, CMD_PREFIX_USER,
206 233 strlen(CMD_PREFIX_USER)) == 0)
207 234 strcpy(usertype, USERATTR_TYPE_NORMAL_KW);
208 235 else
209 236 strcpy(usertype, USERATTR_TYPE_NONADMIN_KW);
210 237
211 238 return (usertype);
212 239 }
213 240
214 241 int
215 242 is_role(char *usertype)
216 243 {
217 244 if (strcmp(usertype, USERATTR_TYPE_NONADMIN_KW) == 0)
218 245 return (1);
219 246 /* not a role */
220 247 return (0);
221 248 }
222 249
223 250 /*
224 251 * Verifies the provided list of authorizations are all valid.
225 252 *
226 253 * Returns NULL if all authorization names are valid.
227 254 * Otherwise, returns the invalid authorization name
228 255 *
229 256 */
230 257 static const char *
231 258 check_auth(const char *auths)
232 259 {
233 260 char *authname;
234 261 authattr_t *result;
235 262 char *tmp;
236 263 struct passwd *pw;
237 264 int have_grant = 0;
238 265
239 266 tmp = strdup(auths);
240 267 if (tmp == NULL) {
241 268 errmsg(M_NOSPACE);
242 269 exit(EX_FAILURE);
243 270 }
244 271
245 272 authname = strtok(tmp, AUTH_SEP);
246 273 pw = getpwuid(getuid());
247 274 if (pw == NULL) {
248 275 return (authname);
249 276 }
250 277
251 278 while (authname != NULL) {
252 279 char *suffix;
253 280 char *authtoks;
254 281
255 282 /* Check if user has been granted this authorization */
256 283 if (!chkauthattr(authname, pw->pw_name))
257 284 return (authname);
258 285
259 286 /* Remove named object after slash */
260 287 if ((suffix = index(authname, KV_OBJECTCHAR)) != NULL)
261 288 *suffix = '\0';
262 289
263 290 /* Find the suffix */
264 291 if ((suffix = rindex(authname, '.')) == NULL)
265 292 return (authname);
266 293
267 294 /* Check for existence in auth_attr */
268 295 suffix++;
269 296 if (strcmp(suffix, KV_WILDCARD)) { /* Not a wildcard */
270 297 result = getauthnam(authname);
271 298 if (result == NULL) {
272 299 /* can't find the auth */
273 300 free_authattr(result);
274 301 return (authname);
275 302 }
276 303 free_authattr(result);
277 304 }
278 305
279 306 /* Check if user can delegate this authorization */
280 307 if (strcmp(suffix, "grant")) { /* Not a grant option */
281 308 authtoks = malloc(strlen(authname) + sizeof ("grant"));
282 309 strcpy(authtoks, authname);
283 310 have_grant = 0;
284 311 while ((suffix = rindex(authtoks, '.')) &&
285 312 !have_grant) {
286 313 strcpy(suffix, ".grant");
287 314 if (chkauthattr(authtoks, pw->pw_name))
288 315 have_grant = 1;
289 316 else
290 317 *suffix = '\0';
291 318 }
292 319 if (!have_grant)
293 320 return (authname);
294 321 }
295 322 authname = strtok(NULL, AUTH_SEP);
296 323 }
297 324 free(tmp);
298 325 return (NULL);
299 326 }
300 327
301 328 /*
302 329 * Verifies the provided list of profile names are valid.
303 330 *
304 331 * Returns NULL if all profile names are valid.
305 332 * Otherwise, returns the invalid profile name
306 333 *
307 334 */
308 335 static const char *
309 336 check_prof(const char *profs)
310 337 {
311 338 char *profname;
312 339 profattr_t *result;
313 340 char *tmp;
314 341
315 342 tmp = strdup(profs);
316 343 if (tmp == NULL) {
317 344 errmsg(M_NOSPACE);
318 345 exit(EX_FAILURE);
319 346 }
320 347
321 348 profname = strtok(tmp, PROF_SEP);
322 349 while (profname != NULL) {
323 350 result = getprofnam(profname);
324 351 if (result == NULL) {
325 352 /* can't find the profile */
326 353 return (profname);
327 354 }
328 355 free_profattr(result);
329 356 profname = strtok(NULL, PROF_SEP);
330 357 }
331 358 free(tmp);
332 359 return (NULL);
333 360 }
334 361
335 362
336 363 /*
337 364 * Verifies the provided list of role names are valid.
338 365 *
339 366 * Returns NULL if all role names are valid.
340 367 * Otherwise, returns the invalid role name
341 368 *
342 369 */
343 370 static const char *
344 371 check_role(const char *roles)
345 372 {
346 373 char *rolename;
347 374 userattr_t *result;
348 375 char *utype;
349 376 char *tmp;
350 377
351 378 tmp = strdup(roles);
352 379 if (tmp == NULL) {
353 380 errmsg(M_NOSPACE);
354 381 exit(EX_FAILURE);
355 382 }
356 383
357 384 rolename = strtok(tmp, ROLE_SEP);
358 385 while (rolename != NULL) {
359 386 result = getusernam(rolename);
360 387 if (result == NULL) {
361 388 /* can't find the rolename */
362 389 return (rolename);
363 390 }
364 391 /* Now, make sure it is a role */
365 392 utype = kva_match(result->attr, USERATTR_TYPE_KW);
366 393 if (utype == NULL) {
367 394 /* no user type defined. not a role */
368 395 free_userattr(result);
369 396 return (rolename);
370 397 }
371 398 if (strcmp(utype, USERATTR_TYPE_NONADMIN_KW) != 0) {
372 399 free_userattr(result);
373 400 return (rolename);
374 401 }
375 402 free_userattr(result);
376 403 rolename = strtok(NULL, ROLE_SEP);
377 404 }
378 405 free(tmp);
379 406 return (NULL);
380 407 }
381 408
382 409 static const char *
383 410 check_proj(const char *proj)
384 411 {
385 412 if (getprojidbyname(proj) < 0) {
386 413 return (proj);
387 414 } else {
388 415 return (NULL);
389 416 }
390 417 }
391 418
392 419 static const char *
393 420 check_privset(const char *pset)
394 421 {
395 422 priv_set_t *tmp;
396 423 const char *res;
397 424
398 425 tmp = priv_str_to_set(pset, ",", &res);
399 426
400 427 if (tmp != NULL) {
401 428 res = NULL;
402 429 priv_freeset(tmp);
403 430 } else if (res == NULL)
404 431 res = strerror(errno);
405 432
406 433 return (res);
407 434 }
408 435
409 436 static const char *
410 437 check_type(const char *type)
411 438 {
412 439 if (strcmp(type, USERATTR_TYPE_NONADMIN_KW) != 0 &&
413 440 strcmp(type, USERATTR_TYPE_NORMAL_KW) != 0)
414 441 return (type);
415 442
416 443 return (NULL);
417 444 }
418 445
419 446 static const char *
420 447 check_lock_after_retries(const char *keyval)
421 448 {
422 449 if (keyval != NULL) {
423 450 if ((strcasecmp(keyval, "no") != 0) &&
424 451 (strcasecmp(keyval, "yes") != 0) &&
425 452 (*keyval != '\0')) {
426 453 return (keyval);
427 454 }
428 455 }
429 456 return (NULL);
430 457 }
431 458
432 459 static const char *
433 460 check_label(const char *labelstr)
434 461 {
435 462 int err;
436 463 m_label_t *lbl = NULL;
437 464
438 465 if (!is_system_labeled())
439 466 return (NULL);
440 467
441 468 err = str_to_label(labelstr, &lbl, MAC_LABEL, L_NO_CORRECTION, NULL);
442 469 m_label_free(lbl);
443 470
444 471 if (err == -1)
445 472 return (labelstr);
446 473
447 474 return (NULL);
448 475 }
449 476
450 477 static const char *
451 478 check_idlecmd(const char *cmd)
452 479 {
453 480 if ((strcmp(cmd, USERATTR_IDLECMD_LOCK_KW) != 0) &&
454 481 (strcmp(cmd, USERATTR_IDLECMD_LOGOUT_KW) != 0)) {
455 482 return (cmd);
456 483 }
457 484
458 485 return (NULL);
459 486 }
460 487
461 488 static const char *
462 489 check_idletime(const char *time)
463 490 {
464 491 int c;
465 492 unsigned char *up = (unsigned char *)time;
466 493
467 494 c = *up;
468 495 while (c != '\0') {
469 496 if (!isdigit(c))
470 497 return (time);
471 498 c = *++up;
472 499 }
473 500
474 501 return (NULL);
475 502 }
476 503
477 504 static const char *
478 505 check_auditflags(const char *auditflags)
479 506 {
480 507 au_mask_t mask;
481 508 char *flags;
482 509 char *last = NULL;
483 510 char *err = "NULL";
484 511
485 512 /* if deleting audit_flags */
486 513 if (*auditflags == '\0') {
487 514 return (NULL);
488 515 }
489 516
490 517 if ((flags = _strdup_null((char *)auditflags)) == NULL) {
491 518 errmsg(M_NOSPACE);
492 519 exit(EX_FAILURE);
493 520 }
494 521
495 522 if (!__chkflags(_strtok_escape(flags, KV_AUDIT_DELIMIT, &last), &mask,
496 523 B_FALSE, &err)) {
497 524 (void) snprintf(auditerr, sizeof (auditerr),
498 525 "always mask \"%s\"", err);
499 526 free(flags);
500 527 return (auditerr);
501 528 }
502 529 if (!__chkflags(_strtok_escape(NULL, KV_AUDIT_DELIMIT, &last), &mask,
503 530 B_FALSE, &err)) {
504 531 (void) snprintf(auditerr, sizeof (auditerr),
505 532 "never mask \"%s\"", err);
506 533 free(flags);
507 534 return (auditerr);
508 535 }
509 536 if (last != NULL) {
510 537 (void) snprintf(auditerr, sizeof (auditerr), "\"%s\"",
511 538 auditflags);
512 539 free(flags);
513 540 return (auditerr);
514 541 }
515 542 free(flags);
516 543
517 544 return (NULL);
518 545 }
↓ open down ↓ |
408 lines elided |
↑ open up ↑ |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX