17c478bd9Sstevel@tonic-gate /*
27c478bd9Sstevel@tonic-gate * CDDL HEADER START
37c478bd9Sstevel@tonic-gate *
47c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the
5f48205beScasper * Common Development and Distribution License (the "License").
6f48205beScasper * You may not use this file except in compliance with the License.
77c478bd9Sstevel@tonic-gate *
87c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
97c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing.
107c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions
117c478bd9Sstevel@tonic-gate * and limitations under the License.
127c478bd9Sstevel@tonic-gate *
137c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each
147c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
157c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the
167c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying
177c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner]
187c478bd9Sstevel@tonic-gate *
197c478bd9Sstevel@tonic-gate * CDDL HEADER END
207c478bd9Sstevel@tonic-gate */
217c478bd9Sstevel@tonic-gate /*
220a1278f2SGary Mills * Copyright (c) 2013 Gary Mills
230a1278f2SGary Mills *
24c651b32eSJohn Sonnenschein * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
257c478bd9Sstevel@tonic-gate * Use is subject to license terms.
267c478bd9Sstevel@tonic-gate */
277c478bd9Sstevel@tonic-gate
287c478bd9Sstevel@tonic-gate /* Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T */
297c478bd9Sstevel@tonic-gate /* All Rights Reserved */
307c478bd9Sstevel@tonic-gate
31a7fe1d5bSAndy Stormont /*
32a7fe1d5bSAndy Stormont * Copyright (c) 2013 RackTop Systems.
33a7fe1d5bSAndy Stormont */
347c478bd9Sstevel@tonic-gate
357c478bd9Sstevel@tonic-gate #include <sys/types.h>
367c478bd9Sstevel@tonic-gate #include <sys/stat.h>
377c478bd9Sstevel@tonic-gate #include <sys/param.h>
387c478bd9Sstevel@tonic-gate #include <stdio.h>
397c478bd9Sstevel@tonic-gate #include <stdlib.h>
407c478bd9Sstevel@tonic-gate #include <ctype.h>
417c478bd9Sstevel@tonic-gate #include <limits.h>
427c478bd9Sstevel@tonic-gate #include <string.h>
437c478bd9Sstevel@tonic-gate #include <userdefs.h>
447c478bd9Sstevel@tonic-gate #include <user_attr.h>
457c478bd9Sstevel@tonic-gate #include <nss_dbdefs.h>
467c478bd9Sstevel@tonic-gate #include <errno.h>
477c478bd9Sstevel@tonic-gate #include <project.h>
487c478bd9Sstevel@tonic-gate #include "users.h"
497c478bd9Sstevel@tonic-gate #include "messages.h"
507c478bd9Sstevel@tonic-gate #include "funcs.h"
517c478bd9Sstevel@tonic-gate
527c478bd9Sstevel@tonic-gate /*
53*7fc68ddfSAlbert Lee * usermod [-u uid [-o] | -g group | -G group [[,group]...]
54*7fc68ddfSAlbert Lee * | -d dir [-m [-z|Z]]
557c478bd9Sstevel@tonic-gate * | -s shell | -c comment | -l new_logname]
567c478bd9Sstevel@tonic-gate * | -f inactive | -e expire ]
577c478bd9Sstevel@tonic-gate * [ -A authorization [, authorization ...]]
587c478bd9Sstevel@tonic-gate * [ -P profile [, profile ...]]
597c478bd9Sstevel@tonic-gate * [ -R role [, role ...]]
607c478bd9Sstevel@tonic-gate * [ -K key=value ]
617c478bd9Sstevel@tonic-gate * [ -p project [, project]] login
627c478bd9Sstevel@tonic-gate *
637c478bd9Sstevel@tonic-gate * This command adds new user logins to the system. Arguments are:
647c478bd9Sstevel@tonic-gate *
657c478bd9Sstevel@tonic-gate * uid - an integer less than MAXUID
667c478bd9Sstevel@tonic-gate * group - an existing group's integer ID or char string name
677c478bd9Sstevel@tonic-gate * dir - a directory
687c478bd9Sstevel@tonic-gate * shell - a program to be used as a shell
697c478bd9Sstevel@tonic-gate * comment - any text string
707c478bd9Sstevel@tonic-gate * skel_dir - a directory
717c478bd9Sstevel@tonic-gate * base_dir - a directory
727c478bd9Sstevel@tonic-gate * rid - an integer less than 2**16 (USHORT)
737c478bd9Sstevel@tonic-gate * login - a string of printable chars except colon (:)
747c478bd9Sstevel@tonic-gate * inactive - number of days a login maybe inactive before it is locked
757c478bd9Sstevel@tonic-gate * expire - date when a login is no longer valid
767c478bd9Sstevel@tonic-gate * authorization - One or more comma separated authorizations defined
777c478bd9Sstevel@tonic-gate * in auth_attr(4).
787c478bd9Sstevel@tonic-gate * profile - One or more comma separated execution profiles defined
797c478bd9Sstevel@tonic-gate * in prof_attr(4)
807c478bd9Sstevel@tonic-gate * role - One or more comma-separated role names defined in user_attr(4)
817c478bd9Sstevel@tonic-gate * key=value - One or more -K options each specifying a valid user_attr(4)
827c478bd9Sstevel@tonic-gate * attribute.
837c478bd9Sstevel@tonic-gate *
847c478bd9Sstevel@tonic-gate */
857c478bd9Sstevel@tonic-gate
86*7fc68ddfSAlbert Lee extern int **valid_lgroup(), isbusy(), get_default_zfs_flags();
877c478bd9Sstevel@tonic-gate extern int valid_uid(), check_perm(), create_home(), move_dir();
887c478bd9Sstevel@tonic-gate extern int valid_expire(), edit_group(), call_passmgmt();
897c478bd9Sstevel@tonic-gate extern projid_t **valid_lproject();
907c478bd9Sstevel@tonic-gate
917c478bd9Sstevel@tonic-gate static uid_t uid; /* new uid */
927c478bd9Sstevel@tonic-gate static gid_t gid; /* gid of new login */
937c478bd9Sstevel@tonic-gate static char *new_logname = NULL; /* new login name with -l option */
947c478bd9Sstevel@tonic-gate static char *uidstr = NULL; /* uid from command line */
957c478bd9Sstevel@tonic-gate static char *group = NULL; /* group from command line */
967c478bd9Sstevel@tonic-gate static char *grps = NULL; /* multi groups from command line */
977c478bd9Sstevel@tonic-gate static char *dir = NULL; /* home dir from command line */
987c478bd9Sstevel@tonic-gate static char *shell = NULL; /* shell from command line */
997c478bd9Sstevel@tonic-gate static char *comment = NULL; /* comment from command line */
1007c478bd9Sstevel@tonic-gate static char *logname = NULL; /* login name to add */
1017c478bd9Sstevel@tonic-gate static char *inactstr = NULL; /* inactive from command line */
1027c478bd9Sstevel@tonic-gate static char *expire = NULL; /* expiration date from command line */
1037c478bd9Sstevel@tonic-gate static char *projects = NULL; /* project ids from command line */
1047c478bd9Sstevel@tonic-gate static char *usertype;
1057c478bd9Sstevel@tonic-gate
1067c478bd9Sstevel@tonic-gate char *cmdname;
1077c478bd9Sstevel@tonic-gate static char gidstring[32], uidstring[32];
1087c478bd9Sstevel@tonic-gate char inactstring[10];
1097c478bd9Sstevel@tonic-gate
1107c478bd9Sstevel@tonic-gate char *
strcpmalloc(str)1117c478bd9Sstevel@tonic-gate strcpmalloc(str)
1127c478bd9Sstevel@tonic-gate char *str;
1137c478bd9Sstevel@tonic-gate {
1147c478bd9Sstevel@tonic-gate if (str == NULL)
1157c478bd9Sstevel@tonic-gate return (NULL);
1167c478bd9Sstevel@tonic-gate
1177c478bd9Sstevel@tonic-gate return (strdup(str));
1187c478bd9Sstevel@tonic-gate }
1197c478bd9Sstevel@tonic-gate struct passwd *
passwd_cpmalloc(opw)1207c478bd9Sstevel@tonic-gate passwd_cpmalloc(opw)
1217c478bd9Sstevel@tonic-gate struct passwd *opw;
1227c478bd9Sstevel@tonic-gate {
1237c478bd9Sstevel@tonic-gate struct passwd *npw;
1247c478bd9Sstevel@tonic-gate
1257c478bd9Sstevel@tonic-gate if (opw == NULL)
1267c478bd9Sstevel@tonic-gate return (NULL);
1277c478bd9Sstevel@tonic-gate
1287c478bd9Sstevel@tonic-gate
1297c478bd9Sstevel@tonic-gate npw = malloc(sizeof (struct passwd));
1307c478bd9Sstevel@tonic-gate
1317c478bd9Sstevel@tonic-gate npw->pw_name = strcpmalloc(opw->pw_name);
1327c478bd9Sstevel@tonic-gate npw->pw_passwd = strcpmalloc(opw->pw_passwd);
1337c478bd9Sstevel@tonic-gate npw->pw_uid = opw->pw_uid;
1347c478bd9Sstevel@tonic-gate npw->pw_gid = opw->pw_gid;
1357c478bd9Sstevel@tonic-gate npw->pw_age = strcpmalloc(opw->pw_age);
1367c478bd9Sstevel@tonic-gate npw->pw_comment = strcpmalloc(opw->pw_comment);
1377c478bd9Sstevel@tonic-gate npw->pw_gecos = strcpmalloc(opw->pw_gecos);
1387c478bd9Sstevel@tonic-gate npw->pw_dir = strcpmalloc(opw->pw_dir);
1397c478bd9Sstevel@tonic-gate npw->pw_shell = strcpmalloc(opw->pw_shell);
1407c478bd9Sstevel@tonic-gate
1417c478bd9Sstevel@tonic-gate return (npw);
1427c478bd9Sstevel@tonic-gate }
1437c478bd9Sstevel@tonic-gate
1447c478bd9Sstevel@tonic-gate int
main(argc,argv)1457c478bd9Sstevel@tonic-gate main(argc, argv)
1467c478bd9Sstevel@tonic-gate int argc;
1477c478bd9Sstevel@tonic-gate char **argv;
1487c478bd9Sstevel@tonic-gate {
149*7fc68ddfSAlbert Lee int ch, ret = EX_SUCCESS, call_pass = 0, oflag = 0, zfs_flags = 0;
150*7fc68ddfSAlbert Lee int tries, mflag = 0, inact, **gidlist, flag = 0, zflag = 0, Zflag = 0;
1517c478bd9Sstevel@tonic-gate boolean_t fail_if_busy = B_FALSE;
1527c478bd9Sstevel@tonic-gate char *ptr;
1537c478bd9Sstevel@tonic-gate struct passwd *pstruct; /* password struct for login */
1547c478bd9Sstevel@tonic-gate struct passwd *pw;
1557c478bd9Sstevel@tonic-gate struct group *g_ptr; /* validated group from -g */
1567c478bd9Sstevel@tonic-gate struct stat statbuf; /* status buffer for stat */
1577c478bd9Sstevel@tonic-gate #ifndef att
1587c478bd9Sstevel@tonic-gate FILE *pwf; /* fille ptr for opened passwd file */
1597c478bd9Sstevel@tonic-gate #endif
1607c478bd9Sstevel@tonic-gate int warning;
1617c478bd9Sstevel@tonic-gate projid_t **projlist;
1627c478bd9Sstevel@tonic-gate char **nargv; /* arguments for execvp of passmgmt */
1637c478bd9Sstevel@tonic-gate int argindex; /* argument index into nargv */
1647c478bd9Sstevel@tonic-gate userattr_t *ua;
1657c478bd9Sstevel@tonic-gate char *val;
1667c478bd9Sstevel@tonic-gate int isrole; /* current account is role */
1677c478bd9Sstevel@tonic-gate
1687c478bd9Sstevel@tonic-gate cmdname = argv[0];
1697c478bd9Sstevel@tonic-gate
1707c478bd9Sstevel@tonic-gate if (geteuid() != 0) {
1717c478bd9Sstevel@tonic-gate errmsg(M_PERM_DENIED);
1727c478bd9Sstevel@tonic-gate exit(EX_NO_PERM);
1737c478bd9Sstevel@tonic-gate }
1747c478bd9Sstevel@tonic-gate
1757c478bd9Sstevel@tonic-gate opterr = 0; /* no print errors from getopt */
1767c478bd9Sstevel@tonic-gate /* get user type based on the program name */
1777c478bd9Sstevel@tonic-gate usertype = getusertype(argv[0]);
1787c478bd9Sstevel@tonic-gate
1797c478bd9Sstevel@tonic-gate while ((ch = getopt(argc, argv,
180*7fc68ddfSAlbert Lee "c:d:e:f:G:g:l:mzZop:s:u:A:P:R:K:")) != EOF)
1817c478bd9Sstevel@tonic-gate switch (ch) {
1827c478bd9Sstevel@tonic-gate case 'c':
1837c478bd9Sstevel@tonic-gate comment = optarg;
1847c478bd9Sstevel@tonic-gate flag++;
1857c478bd9Sstevel@tonic-gate break;
1867c478bd9Sstevel@tonic-gate case 'd':
1877c478bd9Sstevel@tonic-gate dir = optarg;
1887c478bd9Sstevel@tonic-gate fail_if_busy = B_TRUE;
1897c478bd9Sstevel@tonic-gate flag++;
1907c478bd9Sstevel@tonic-gate break;
1917c478bd9Sstevel@tonic-gate case 'e':
1927c478bd9Sstevel@tonic-gate expire = optarg;
1937c478bd9Sstevel@tonic-gate flag++;
1947c478bd9Sstevel@tonic-gate break;
1957c478bd9Sstevel@tonic-gate case 'f':
1967c478bd9Sstevel@tonic-gate inactstr = optarg;
1977c478bd9Sstevel@tonic-gate flag++;
1987c478bd9Sstevel@tonic-gate break;
1997c478bd9Sstevel@tonic-gate case 'G':
2007c478bd9Sstevel@tonic-gate grps = optarg;
2017c478bd9Sstevel@tonic-gate flag++;
2027c478bd9Sstevel@tonic-gate break;
2037c478bd9Sstevel@tonic-gate case 'g':
2047c478bd9Sstevel@tonic-gate group = optarg;
2057c478bd9Sstevel@tonic-gate fail_if_busy = B_TRUE;
2067c478bd9Sstevel@tonic-gate flag++;
2077c478bd9Sstevel@tonic-gate break;
2087c478bd9Sstevel@tonic-gate case 'l':
2097c478bd9Sstevel@tonic-gate new_logname = optarg;
2107c478bd9Sstevel@tonic-gate fail_if_busy = B_TRUE;
2117c478bd9Sstevel@tonic-gate flag++;
2127c478bd9Sstevel@tonic-gate break;
2137c478bd9Sstevel@tonic-gate case 'm':
2147c478bd9Sstevel@tonic-gate mflag++;
2157c478bd9Sstevel@tonic-gate flag++;
2167c478bd9Sstevel@tonic-gate fail_if_busy = B_TRUE;
2177c478bd9Sstevel@tonic-gate break;
2187c478bd9Sstevel@tonic-gate case 'o':
2197c478bd9Sstevel@tonic-gate oflag++;
2207c478bd9Sstevel@tonic-gate flag++;
2217c478bd9Sstevel@tonic-gate fail_if_busy = B_TRUE;
2227c478bd9Sstevel@tonic-gate break;
2237c478bd9Sstevel@tonic-gate case 'p':
2247c478bd9Sstevel@tonic-gate projects = optarg;
2257c478bd9Sstevel@tonic-gate flag++;
2267c478bd9Sstevel@tonic-gate break;
2277c478bd9Sstevel@tonic-gate case 's':
2287c478bd9Sstevel@tonic-gate shell = optarg;
2297c478bd9Sstevel@tonic-gate flag++;
2307c478bd9Sstevel@tonic-gate break;
2317c478bd9Sstevel@tonic-gate case 'u':
2327c478bd9Sstevel@tonic-gate uidstr = optarg;
2337c478bd9Sstevel@tonic-gate flag++;
2347c478bd9Sstevel@tonic-gate fail_if_busy = B_TRUE;
2357c478bd9Sstevel@tonic-gate break;
236*7fc68ddfSAlbert Lee case 'Z':
237*7fc68ddfSAlbert Lee Zflag++;
238*7fc68ddfSAlbert Lee break;
239*7fc68ddfSAlbert Lee case 'z':
240*7fc68ddfSAlbert Lee zflag++;
241*7fc68ddfSAlbert Lee break;
2427c478bd9Sstevel@tonic-gate case 'A':
2437c478bd9Sstevel@tonic-gate change_key(USERATTR_AUTHS_KW, optarg);
2447c478bd9Sstevel@tonic-gate flag++;
2457c478bd9Sstevel@tonic-gate break;
2467c478bd9Sstevel@tonic-gate case 'P':
2477c478bd9Sstevel@tonic-gate change_key(USERATTR_PROFILES_KW, optarg);
2487c478bd9Sstevel@tonic-gate flag++;
2497c478bd9Sstevel@tonic-gate break;
2507c478bd9Sstevel@tonic-gate case 'R':
2517c478bd9Sstevel@tonic-gate change_key(USERATTR_ROLES_KW, optarg);
2527c478bd9Sstevel@tonic-gate flag++;
2537c478bd9Sstevel@tonic-gate break;
2547c478bd9Sstevel@tonic-gate case 'K':
2557c478bd9Sstevel@tonic-gate change_key(NULL, optarg);
2567c478bd9Sstevel@tonic-gate flag++;
2577c478bd9Sstevel@tonic-gate break;
2587c478bd9Sstevel@tonic-gate default:
2597c478bd9Sstevel@tonic-gate case '?':
2607c478bd9Sstevel@tonic-gate if (is_role(usertype))
2617c478bd9Sstevel@tonic-gate errmsg(M_MRUSAGE);
2627c478bd9Sstevel@tonic-gate else
2637c478bd9Sstevel@tonic-gate errmsg(M_MUSAGE);
2647c478bd9Sstevel@tonic-gate exit(EX_SYNTAX);
2657c478bd9Sstevel@tonic-gate }
2667c478bd9Sstevel@tonic-gate
267*7fc68ddfSAlbert Lee if (((!mflag) && (zflag || Zflag)) || (zflag && Zflag) ||
268*7fc68ddfSAlbert Lee (mflag > 1 && (zflag || Zflag))) {
269*7fc68ddfSAlbert Lee if (is_role(usertype))
270*7fc68ddfSAlbert Lee errmsg(M_ARUSAGE);
271*7fc68ddfSAlbert Lee else
272*7fc68ddfSAlbert Lee errmsg(M_AUSAGE);
273*7fc68ddfSAlbert Lee exit(EX_SYNTAX);
274*7fc68ddfSAlbert Lee }
275*7fc68ddfSAlbert Lee
276*7fc68ddfSAlbert Lee
2777c478bd9Sstevel@tonic-gate if (optind != argc - 1 || flag == 0) {
2787c478bd9Sstevel@tonic-gate if (is_role(usertype))
2797c478bd9Sstevel@tonic-gate errmsg(M_MRUSAGE);
2807c478bd9Sstevel@tonic-gate else
2817c478bd9Sstevel@tonic-gate errmsg(M_MUSAGE);
2827c478bd9Sstevel@tonic-gate exit(EX_SYNTAX);
2837c478bd9Sstevel@tonic-gate }
2847c478bd9Sstevel@tonic-gate
2857c478bd9Sstevel@tonic-gate if ((!uidstr && oflag) || (mflag && !dir)) {
2867c478bd9Sstevel@tonic-gate if (is_role(usertype))
2877c478bd9Sstevel@tonic-gate errmsg(M_MRUSAGE);
2887c478bd9Sstevel@tonic-gate else
2897c478bd9Sstevel@tonic-gate errmsg(M_MUSAGE);
2907c478bd9Sstevel@tonic-gate exit(EX_SYNTAX);
2917c478bd9Sstevel@tonic-gate }
2927c478bd9Sstevel@tonic-gate
2937c478bd9Sstevel@tonic-gate logname = argv[optind];
2947c478bd9Sstevel@tonic-gate
2957c478bd9Sstevel@tonic-gate /* Determine whether the account is a role or not */
2967c478bd9Sstevel@tonic-gate if ((ua = getusernam(logname)) == NULL ||
2977c478bd9Sstevel@tonic-gate (val = kva_match(ua->attr, USERATTR_TYPE_KW)) == NULL ||
2987c478bd9Sstevel@tonic-gate strcmp(val, USERATTR_TYPE_NONADMIN_KW) != 0)
2997c478bd9Sstevel@tonic-gate isrole = 0;
3007c478bd9Sstevel@tonic-gate else
3017c478bd9Sstevel@tonic-gate isrole = 1;
3027c478bd9Sstevel@tonic-gate
3037c478bd9Sstevel@tonic-gate /* Verify that rolemod is used for roles and usermod for users */
3047c478bd9Sstevel@tonic-gate if (isrole != is_role(usertype)) {
3057c478bd9Sstevel@tonic-gate if (isrole)
3067c478bd9Sstevel@tonic-gate errmsg(M_ISROLE);
3077c478bd9Sstevel@tonic-gate else
3087c478bd9Sstevel@tonic-gate errmsg(M_ISUSER);
3097c478bd9Sstevel@tonic-gate exit(EX_SYNTAX);
3107c478bd9Sstevel@tonic-gate }
3117c478bd9Sstevel@tonic-gate
3127c478bd9Sstevel@tonic-gate /* Set the usertype key; defaults to the commandline */
3137c478bd9Sstevel@tonic-gate usertype = getsetdefval(USERATTR_TYPE_KW, usertype);
3147c478bd9Sstevel@tonic-gate
3157c478bd9Sstevel@tonic-gate if (is_role(usertype)) {
3167c478bd9Sstevel@tonic-gate /* Roles can't have roles */
3177c478bd9Sstevel@tonic-gate if (getsetdefval(USERATTR_ROLES_KW, NULL) != NULL) {
3187c478bd9Sstevel@tonic-gate errmsg(M_MRUSAGE);
3197c478bd9Sstevel@tonic-gate exit(EX_SYNTAX);
3207c478bd9Sstevel@tonic-gate }
3217c478bd9Sstevel@tonic-gate /* If it was an ordinary user, delete its roles */
3227c478bd9Sstevel@tonic-gate if (!isrole)
3237c478bd9Sstevel@tonic-gate change_key(USERATTR_ROLES_KW, "");
3247c478bd9Sstevel@tonic-gate }
3257c478bd9Sstevel@tonic-gate
3267c478bd9Sstevel@tonic-gate #ifdef att
3277c478bd9Sstevel@tonic-gate pw = getpwnam(logname);
3287c478bd9Sstevel@tonic-gate #else
3297c478bd9Sstevel@tonic-gate /*
3307c478bd9Sstevel@tonic-gate * Do this with fgetpwent to make sure we are only looking on local
3317c478bd9Sstevel@tonic-gate * system (since passmgmt only works on local system).
3327c478bd9Sstevel@tonic-gate */
3337c478bd9Sstevel@tonic-gate if ((pwf = fopen("/etc/passwd", "r")) == NULL) {
3347c478bd9Sstevel@tonic-gate errmsg(M_OOPS, "open", "/etc/passwd");
3357c478bd9Sstevel@tonic-gate exit(EX_FAILURE);
3367c478bd9Sstevel@tonic-gate }
3377c478bd9Sstevel@tonic-gate while ((pw = fgetpwent(pwf)) != NULL)
3387c478bd9Sstevel@tonic-gate if (strcmp(pw->pw_name, logname) == 0)
3397c478bd9Sstevel@tonic-gate break;
3407c478bd9Sstevel@tonic-gate
3417c478bd9Sstevel@tonic-gate fclose(pwf);
3427c478bd9Sstevel@tonic-gate #endif
3437c478bd9Sstevel@tonic-gate
3447c478bd9Sstevel@tonic-gate if (pw == NULL) {
3457c478bd9Sstevel@tonic-gate char pwdb[NSS_BUFLEN_PASSWD];
3467c478bd9Sstevel@tonic-gate struct passwd pwd;
3477c478bd9Sstevel@tonic-gate
3487c478bd9Sstevel@tonic-gate if (getpwnam_r(logname, &pwd, pwdb, sizeof (pwdb)) == NULL) {
3497c478bd9Sstevel@tonic-gate /* This user does not exist. */
3507c478bd9Sstevel@tonic-gate errmsg(M_EXIST, logname);
3517c478bd9Sstevel@tonic-gate exit(EX_NAME_NOT_EXIST);
3527c478bd9Sstevel@tonic-gate } else {
3537c478bd9Sstevel@tonic-gate /* This user exists in non-local name service. */
3547c478bd9Sstevel@tonic-gate errmsg(M_NONLOCAL, logname);
3557c478bd9Sstevel@tonic-gate exit(EX_NOT_LOCAL);
3567c478bd9Sstevel@tonic-gate }
3577c478bd9Sstevel@tonic-gate }
3587c478bd9Sstevel@tonic-gate
3597c478bd9Sstevel@tonic-gate pstruct = passwd_cpmalloc(pw);
3607c478bd9Sstevel@tonic-gate
3617c478bd9Sstevel@tonic-gate /*
3627c478bd9Sstevel@tonic-gate * We can't modify a logged in user if any of the following
3637c478bd9Sstevel@tonic-gate * are being changed:
3647c478bd9Sstevel@tonic-gate * uid (-u & -o), group (-g), home dir (-m), loginname (-l).
3657c478bd9Sstevel@tonic-gate * If none of those are specified it is okay to go ahead
3667c478bd9Sstevel@tonic-gate * some types of changes only take effect on next login, some
3677c478bd9Sstevel@tonic-gate * like authorisations and profiles take effect instantly.
3687c478bd9Sstevel@tonic-gate * One might think that -K type=role should require that the
3697c478bd9Sstevel@tonic-gate * user not be logged in, however this would make it very
3707c478bd9Sstevel@tonic-gate * difficult to make the root account a role using this command.
3717c478bd9Sstevel@tonic-gate */
3727c478bd9Sstevel@tonic-gate if (isbusy(logname)) {
3737c478bd9Sstevel@tonic-gate if (fail_if_busy) {
3747c478bd9Sstevel@tonic-gate errmsg(M_BUSY, logname, "change");
3757c478bd9Sstevel@tonic-gate exit(EX_BUSY);
3767c478bd9Sstevel@tonic-gate }
3777c478bd9Sstevel@tonic-gate warningmsg(WARN_LOGGED_IN, logname);
3787c478bd9Sstevel@tonic-gate }
3797c478bd9Sstevel@tonic-gate
3807c478bd9Sstevel@tonic-gate if (new_logname && strcmp(new_logname, logname)) {
3817c478bd9Sstevel@tonic-gate switch (valid_login(new_logname, (struct passwd **)NULL,
3827c478bd9Sstevel@tonic-gate &warning)) {
3837c478bd9Sstevel@tonic-gate case INVALID:
3847c478bd9Sstevel@tonic-gate errmsg(M_INVALID, new_logname, "login name");
3857c478bd9Sstevel@tonic-gate exit(EX_BADARG);
3867c478bd9Sstevel@tonic-gate /*NOTREACHED*/
3877c478bd9Sstevel@tonic-gate
3887c478bd9Sstevel@tonic-gate case NOTUNIQUE:
3897c478bd9Sstevel@tonic-gate errmsg(M_USED, new_logname);
3907c478bd9Sstevel@tonic-gate exit(EX_NAME_EXISTS);
3917c478bd9Sstevel@tonic-gate /*NOTREACHED*/
3920a1278f2SGary Mills
3930a1278f2SGary Mills case LONGNAME:
3940a1278f2SGary Mills errmsg(M_TOO_LONG, new_logname);
3950a1278f2SGary Mills exit(EX_BADARG);
3960a1278f2SGary Mills /*NOTREACHED*/
3970a1278f2SGary Mills
3987c478bd9Sstevel@tonic-gate default:
3997c478bd9Sstevel@tonic-gate call_pass = 1;
4007c478bd9Sstevel@tonic-gate break;
4017c478bd9Sstevel@tonic-gate }
4027c478bd9Sstevel@tonic-gate if (warning)
4037c478bd9Sstevel@tonic-gate warningmsg(warning, logname);
4047c478bd9Sstevel@tonic-gate }
4057c478bd9Sstevel@tonic-gate
4067c478bd9Sstevel@tonic-gate if (uidstr) {
4077c478bd9Sstevel@tonic-gate /* convert uidstr to integer */
4087c478bd9Sstevel@tonic-gate errno = 0;
4097c478bd9Sstevel@tonic-gate uid = (uid_t)strtol(uidstr, &ptr, (int)10);
4107c478bd9Sstevel@tonic-gate if (*ptr || errno == ERANGE) {
4117c478bd9Sstevel@tonic-gate errmsg(M_INVALID, uidstr, "user id");
4127c478bd9Sstevel@tonic-gate exit(EX_BADARG);
4137c478bd9Sstevel@tonic-gate }
4147c478bd9Sstevel@tonic-gate
4157c478bd9Sstevel@tonic-gate if (uid != pstruct->pw_uid) {
4167c478bd9Sstevel@tonic-gate switch (valid_uid(uid, NULL)) {
4177c478bd9Sstevel@tonic-gate case NOTUNIQUE:
4187c478bd9Sstevel@tonic-gate if (!oflag) {
4197c478bd9Sstevel@tonic-gate /* override not specified */
4207c478bd9Sstevel@tonic-gate errmsg(M_UID_USED, uid);
4217c478bd9Sstevel@tonic-gate exit(EX_ID_EXISTS);
4227c478bd9Sstevel@tonic-gate }
4237c478bd9Sstevel@tonic-gate break;
4247c478bd9Sstevel@tonic-gate case RESERVED:
4257c478bd9Sstevel@tonic-gate errmsg(M_RESERVED, uid);
4267c478bd9Sstevel@tonic-gate break;
4277c478bd9Sstevel@tonic-gate case TOOBIG:
4287c478bd9Sstevel@tonic-gate errmsg(M_TOOBIG, "uid", uid);
4297c478bd9Sstevel@tonic-gate exit(EX_BADARG);
4307c478bd9Sstevel@tonic-gate break;
4317c478bd9Sstevel@tonic-gate }
4327c478bd9Sstevel@tonic-gate
4337c478bd9Sstevel@tonic-gate call_pass = 1;
4347c478bd9Sstevel@tonic-gate
4357c478bd9Sstevel@tonic-gate } else {
4367c478bd9Sstevel@tonic-gate /* uid's the same, so don't change anything */
4377c478bd9Sstevel@tonic-gate uidstr = NULL;
4387c478bd9Sstevel@tonic-gate oflag = 0;
4397c478bd9Sstevel@tonic-gate }
4407c478bd9Sstevel@tonic-gate
4417c478bd9Sstevel@tonic-gate } else uid = pstruct->pw_uid;
4427c478bd9Sstevel@tonic-gate
4437c478bd9Sstevel@tonic-gate if (group) {
4447c478bd9Sstevel@tonic-gate switch (valid_group(group, &g_ptr, &warning)) {
4457c478bd9Sstevel@tonic-gate case INVALID:
4467c478bd9Sstevel@tonic-gate errmsg(M_INVALID, group, "group id");
4477c478bd9Sstevel@tonic-gate exit(EX_BADARG);
4487c478bd9Sstevel@tonic-gate /*NOTREACHED*/
4497c478bd9Sstevel@tonic-gate case TOOBIG:
4507c478bd9Sstevel@tonic-gate errmsg(M_TOOBIG, "gid", group);
4517c478bd9Sstevel@tonic-gate exit(EX_BADARG);
4527c478bd9Sstevel@tonic-gate /*NOTREACHED*/
4537c478bd9Sstevel@tonic-gate case UNIQUE:
4547c478bd9Sstevel@tonic-gate errmsg(M_GRP_NOTUSED, group);
4557c478bd9Sstevel@tonic-gate exit(EX_NAME_NOT_EXIST);
4567c478bd9Sstevel@tonic-gate /*NOTREACHED*/
4577c478bd9Sstevel@tonic-gate case RESERVED:
4587c478bd9Sstevel@tonic-gate gid = (gid_t)strtol(group, &ptr, (int)10);
4597c478bd9Sstevel@tonic-gate errmsg(M_RESERVED_GID, gid);
4607c478bd9Sstevel@tonic-gate break;
4617c478bd9Sstevel@tonic-gate }
4627c478bd9Sstevel@tonic-gate if (warning)
4637c478bd9Sstevel@tonic-gate warningmsg(warning, group);
4647c478bd9Sstevel@tonic-gate
4657c478bd9Sstevel@tonic-gate if (g_ptr != NULL)
4667c478bd9Sstevel@tonic-gate gid = g_ptr->gr_gid;
4677c478bd9Sstevel@tonic-gate else
4687c478bd9Sstevel@tonic-gate gid = pstruct->pw_gid;
4697c478bd9Sstevel@tonic-gate
4707c478bd9Sstevel@tonic-gate /* call passmgmt if gid is different, else ignore group */
4717c478bd9Sstevel@tonic-gate if (gid != pstruct->pw_gid)
4727c478bd9Sstevel@tonic-gate call_pass = 1;
4737c478bd9Sstevel@tonic-gate else group = NULL;
4747c478bd9Sstevel@tonic-gate
4757c478bd9Sstevel@tonic-gate } else gid = pstruct->pw_gid;
4767c478bd9Sstevel@tonic-gate
4777c478bd9Sstevel@tonic-gate if (grps && *grps) {
4787c478bd9Sstevel@tonic-gate if (!(gidlist = valid_lgroup(grps, gid)))
4797c478bd9Sstevel@tonic-gate exit(EX_BADARG);
4807c478bd9Sstevel@tonic-gate } else
4817c478bd9Sstevel@tonic-gate gidlist = (int **)0;
4827c478bd9Sstevel@tonic-gate
4837c478bd9Sstevel@tonic-gate if (projects && *projects) {
4847c478bd9Sstevel@tonic-gate if (! (projlist = valid_lproject(projects)))
4857c478bd9Sstevel@tonic-gate exit(EX_BADARG);
4867c478bd9Sstevel@tonic-gate } else
4877c478bd9Sstevel@tonic-gate projlist = (projid_t **)0;
4887c478bd9Sstevel@tonic-gate
4897c478bd9Sstevel@tonic-gate if (dir) {
4907c478bd9Sstevel@tonic-gate if (REL_PATH(dir)) {
4917c478bd9Sstevel@tonic-gate errmsg(M_RELPATH, dir);
4927c478bd9Sstevel@tonic-gate exit(EX_BADARG);
4937c478bd9Sstevel@tonic-gate }
4947c478bd9Sstevel@tonic-gate if (strcmp(pstruct->pw_dir, dir) == 0) {
4957c478bd9Sstevel@tonic-gate /* home directory is the same so ignore dflag & mflag */
4967c478bd9Sstevel@tonic-gate dir = NULL;
4977c478bd9Sstevel@tonic-gate mflag = 0;
4987c478bd9Sstevel@tonic-gate } else call_pass = 1;
4997c478bd9Sstevel@tonic-gate }
5007c478bd9Sstevel@tonic-gate
5017c478bd9Sstevel@tonic-gate if (mflag) {
5027c478bd9Sstevel@tonic-gate if (stat(dir, &statbuf) == 0) {
5037c478bd9Sstevel@tonic-gate /* Home directory exists */
5047c478bd9Sstevel@tonic-gate if (check_perm(statbuf, pstruct->pw_uid,
5057c478bd9Sstevel@tonic-gate pstruct->pw_gid, S_IWOTH|S_IXOTH) != 0) {
5067c478bd9Sstevel@tonic-gate errmsg(M_NO_PERM, logname, dir);
5077c478bd9Sstevel@tonic-gate exit(EX_NO_PERM);
5087c478bd9Sstevel@tonic-gate }
5097c478bd9Sstevel@tonic-gate
510*7fc68ddfSAlbert Lee } else {
511*7fc68ddfSAlbert Lee zfs_flags = get_default_zfs_flags();
512*7fc68ddfSAlbert Lee if (zflag || mflag > 1)
513*7fc68ddfSAlbert Lee zfs_flags |= MANAGE_ZFS;
514*7fc68ddfSAlbert Lee else if (Zflag)
515*7fc68ddfSAlbert Lee zfs_flags &= ~MANAGE_ZFS;
516*7fc68ddfSAlbert Lee ret = create_home(dir, NULL, uid, gid, zfs_flags);
517*7fc68ddfSAlbert Lee }
5187c478bd9Sstevel@tonic-gate
5197c478bd9Sstevel@tonic-gate if (ret == EX_SUCCESS)
520*7fc68ddfSAlbert Lee ret = move_dir(pstruct->pw_dir, dir,
521*7fc68ddfSAlbert Lee logname, zfs_flags);
5227c478bd9Sstevel@tonic-gate
5237c478bd9Sstevel@tonic-gate if (ret != EX_SUCCESS)
5247c478bd9Sstevel@tonic-gate exit(ret);
5257c478bd9Sstevel@tonic-gate }
5267c478bd9Sstevel@tonic-gate
5277c478bd9Sstevel@tonic-gate if (shell) {
5287c478bd9Sstevel@tonic-gate if (REL_PATH(shell)) {
5297c478bd9Sstevel@tonic-gate errmsg(M_RELPATH, shell);
5307c478bd9Sstevel@tonic-gate exit(EX_BADARG);
5317c478bd9Sstevel@tonic-gate }
5327c478bd9Sstevel@tonic-gate if (strcmp(pstruct->pw_shell, shell) == 0) {
5337c478bd9Sstevel@tonic-gate /* ignore s option if shell is not different */
5347c478bd9Sstevel@tonic-gate shell = NULL;
5357c478bd9Sstevel@tonic-gate } else {
5367c478bd9Sstevel@tonic-gate if (stat(shell, &statbuf) < 0 ||
5377c478bd9Sstevel@tonic-gate (statbuf.st_mode & S_IFMT) != S_IFREG ||
5387c478bd9Sstevel@tonic-gate (statbuf.st_mode & 0555) != 0555) {
5397c478bd9Sstevel@tonic-gate
5407c478bd9Sstevel@tonic-gate errmsg(M_INVALID, shell, "shell");
5417c478bd9Sstevel@tonic-gate exit(EX_BADARG);
5427c478bd9Sstevel@tonic-gate }
5437c478bd9Sstevel@tonic-gate
5447c478bd9Sstevel@tonic-gate call_pass = 1;
5457c478bd9Sstevel@tonic-gate }
5467c478bd9Sstevel@tonic-gate }
5477c478bd9Sstevel@tonic-gate
548a7fe1d5bSAndy Stormont if (comment) {
5497c478bd9Sstevel@tonic-gate /* ignore comment if comment is not changed */
5507c478bd9Sstevel@tonic-gate if (strcmp(pstruct->pw_comment, comment))
5517c478bd9Sstevel@tonic-gate call_pass = 1;
5527c478bd9Sstevel@tonic-gate else
5537c478bd9Sstevel@tonic-gate comment = NULL;
554a7fe1d5bSAndy Stormont }
5557c478bd9Sstevel@tonic-gate
5567c478bd9Sstevel@tonic-gate /* inactive string is a positive integer */
5577c478bd9Sstevel@tonic-gate if (inactstr) {
5587c478bd9Sstevel@tonic-gate /* convert inactstr to integer */
5597c478bd9Sstevel@tonic-gate inact = (int)strtol(inactstr, &ptr, 10);
5607c478bd9Sstevel@tonic-gate if (*ptr || inact < 0) {
5617c478bd9Sstevel@tonic-gate errmsg(M_INVALID, inactstr, "inactivity period");
5627c478bd9Sstevel@tonic-gate exit(EX_BADARG);
5637c478bd9Sstevel@tonic-gate }
5647c478bd9Sstevel@tonic-gate call_pass = 1;
5657c478bd9Sstevel@tonic-gate }
5667c478bd9Sstevel@tonic-gate
5677c478bd9Sstevel@tonic-gate /* expiration string is a date, newer than today */
5687c478bd9Sstevel@tonic-gate if (expire) {
5697c478bd9Sstevel@tonic-gate if (*expire &&
5707c478bd9Sstevel@tonic-gate valid_expire(expire, (time_t *)0) == INVALID) {
5717c478bd9Sstevel@tonic-gate errmsg(M_INVALID, expire, "expiration date");
5727c478bd9Sstevel@tonic-gate exit(EX_BADARG);
5737c478bd9Sstevel@tonic-gate }
5747c478bd9Sstevel@tonic-gate call_pass = 1;
5757c478bd9Sstevel@tonic-gate }
5767c478bd9Sstevel@tonic-gate
5777c478bd9Sstevel@tonic-gate if (nkeys > 0)
5787c478bd9Sstevel@tonic-gate call_pass = 1;
5797c478bd9Sstevel@tonic-gate
5807c478bd9Sstevel@tonic-gate /* that's it for validations - now do the work */
5817c478bd9Sstevel@tonic-gate
5827c478bd9Sstevel@tonic-gate if (grps) {
5837c478bd9Sstevel@tonic-gate /* redefine login's supplentary group memberships */
5847c478bd9Sstevel@tonic-gate ret = edit_group(logname, new_logname, gidlist, 1);
5857c478bd9Sstevel@tonic-gate if (ret != EX_SUCCESS) {
5867c478bd9Sstevel@tonic-gate errmsg(M_UPDATE, "modified");
5877c478bd9Sstevel@tonic-gate exit(ret);
5887c478bd9Sstevel@tonic-gate }
5897c478bd9Sstevel@tonic-gate }
5907c478bd9Sstevel@tonic-gate if (projects) {
5917c478bd9Sstevel@tonic-gate ret = edit_project(logname, (char *)NULL, projlist, 0);
5927c478bd9Sstevel@tonic-gate if (ret != EX_SUCCESS) {
5937c478bd9Sstevel@tonic-gate errmsg(M_UPDATE, "modified");
5947c478bd9Sstevel@tonic-gate exit(ret);
5957c478bd9Sstevel@tonic-gate }
5967c478bd9Sstevel@tonic-gate }
5977c478bd9Sstevel@tonic-gate
5987c478bd9Sstevel@tonic-gate
5997c478bd9Sstevel@tonic-gate if (!call_pass) exit(ret);
6007c478bd9Sstevel@tonic-gate
6017c478bd9Sstevel@tonic-gate /* only get to here if need to call passmgmt */
6027c478bd9Sstevel@tonic-gate /* set up arguments to passmgmt in nargv array */
6037c478bd9Sstevel@tonic-gate nargv = malloc((30 + nkeys * 2) * sizeof (char *));
6047c478bd9Sstevel@tonic-gate
6057c478bd9Sstevel@tonic-gate argindex = 0;
606c651b32eSJohn Sonnenschein nargv[argindex++] = PASSMGMT;
6077c478bd9Sstevel@tonic-gate nargv[argindex++] = "-m"; /* modify */
6087c478bd9Sstevel@tonic-gate
6097c478bd9Sstevel@tonic-gate if (comment) { /* comment */
6107c478bd9Sstevel@tonic-gate nargv[argindex++] = "-c";
6117c478bd9Sstevel@tonic-gate nargv[argindex++] = comment;
6127c478bd9Sstevel@tonic-gate }
6137c478bd9Sstevel@tonic-gate
6147c478bd9Sstevel@tonic-gate if (dir) {
6157c478bd9Sstevel@tonic-gate /* flags for home directory */
6167c478bd9Sstevel@tonic-gate nargv[argindex++] = "-h";
6177c478bd9Sstevel@tonic-gate nargv[argindex++] = dir;
6187c478bd9Sstevel@tonic-gate }
6197c478bd9Sstevel@tonic-gate
6207c478bd9Sstevel@tonic-gate if (group) {
6217c478bd9Sstevel@tonic-gate /* set gid flag */
6227c478bd9Sstevel@tonic-gate nargv[argindex++] = "-g";
623f48205beScasper (void) sprintf(gidstring, "%u", gid);
6247c478bd9Sstevel@tonic-gate nargv[argindex++] = gidstring;
6257c478bd9Sstevel@tonic-gate }
6267c478bd9Sstevel@tonic-gate
6277c478bd9Sstevel@tonic-gate if (shell) { /* shell */
6287c478bd9Sstevel@tonic-gate nargv[argindex++] = "-s";
6297c478bd9Sstevel@tonic-gate nargv[argindex++] = shell;
6307c478bd9Sstevel@tonic-gate }
6317c478bd9Sstevel@tonic-gate
6327c478bd9Sstevel@tonic-gate if (inactstr) {
6337c478bd9Sstevel@tonic-gate nargv[argindex++] = "-f";
6347c478bd9Sstevel@tonic-gate nargv[argindex++] = inactstr;
6357c478bd9Sstevel@tonic-gate }
6367c478bd9Sstevel@tonic-gate
6377c478bd9Sstevel@tonic-gate if (expire) {
6387c478bd9Sstevel@tonic-gate nargv[argindex++] = "-e";
6397c478bd9Sstevel@tonic-gate nargv[argindex++] = expire;
6407c478bd9Sstevel@tonic-gate }
6417c478bd9Sstevel@tonic-gate
6427c478bd9Sstevel@tonic-gate if (uidstr) { /* set uid flag */
6437c478bd9Sstevel@tonic-gate nargv[argindex++] = "-u";
644f48205beScasper (void) sprintf(uidstring, "%u", uid);
6457c478bd9Sstevel@tonic-gate nargv[argindex++] = uidstring;
6467c478bd9Sstevel@tonic-gate }
6477c478bd9Sstevel@tonic-gate
6487c478bd9Sstevel@tonic-gate if (oflag) nargv[argindex++] = "-o";
6497c478bd9Sstevel@tonic-gate
6507c478bd9Sstevel@tonic-gate if (new_logname) { /* redefine login name */
6517c478bd9Sstevel@tonic-gate nargv[argindex++] = "-l";
6527c478bd9Sstevel@tonic-gate nargv[argindex++] = new_logname;
6537c478bd9Sstevel@tonic-gate }
6547c478bd9Sstevel@tonic-gate
6557c478bd9Sstevel@tonic-gate if (nkeys > 0)
6567c478bd9Sstevel@tonic-gate addkey_args(nargv, &argindex);
6577c478bd9Sstevel@tonic-gate
6587c478bd9Sstevel@tonic-gate /* finally - login name */
6597c478bd9Sstevel@tonic-gate nargv[argindex++] = logname;
6607c478bd9Sstevel@tonic-gate
6617c478bd9Sstevel@tonic-gate /* set the last to null */
6627c478bd9Sstevel@tonic-gate nargv[argindex++] = NULL;
6637c478bd9Sstevel@tonic-gate
6647c478bd9Sstevel@tonic-gate /* now call passmgmt */
6657c478bd9Sstevel@tonic-gate ret = PEX_FAILED;
6667c478bd9Sstevel@tonic-gate for (tries = 3; ret != PEX_SUCCESS && tries--; ) {
6677c478bd9Sstevel@tonic-gate switch (ret = call_passmgmt(nargv)) {
6687c478bd9Sstevel@tonic-gate case PEX_SUCCESS:
6697c478bd9Sstevel@tonic-gate case PEX_BUSY:
6707c478bd9Sstevel@tonic-gate break;
6717c478bd9Sstevel@tonic-gate
6727c478bd9Sstevel@tonic-gate case PEX_HOSED_FILES:
6737c478bd9Sstevel@tonic-gate errmsg(M_HOSED_FILES);
6747c478bd9Sstevel@tonic-gate exit(EX_INCONSISTENT);
6757c478bd9Sstevel@tonic-gate break;
6767c478bd9Sstevel@tonic-gate
6777c478bd9Sstevel@tonic-gate case PEX_SYNTAX:
6787c478bd9Sstevel@tonic-gate case PEX_BADARG:
6797c478bd9Sstevel@tonic-gate /* should NEVER occur that passmgmt usage is wrong */
6807c478bd9Sstevel@tonic-gate if (is_role(usertype))
6817c478bd9Sstevel@tonic-gate errmsg(M_MRUSAGE);
6827c478bd9Sstevel@tonic-gate else
6837c478bd9Sstevel@tonic-gate errmsg(M_MUSAGE);
6847c478bd9Sstevel@tonic-gate exit(EX_SYNTAX);
6857c478bd9Sstevel@tonic-gate break;
6867c478bd9Sstevel@tonic-gate
6877c478bd9Sstevel@tonic-gate case PEX_BADUID:
6887c478bd9Sstevel@tonic-gate /* uid in use - shouldn't happen print message anyway */
6897c478bd9Sstevel@tonic-gate errmsg(M_UID_USED, uid);
6907c478bd9Sstevel@tonic-gate exit(EX_ID_EXISTS);
6917c478bd9Sstevel@tonic-gate break;
6927c478bd9Sstevel@tonic-gate
6937c478bd9Sstevel@tonic-gate case PEX_BADNAME:
6947c478bd9Sstevel@tonic-gate /* invalid loname */
6957c478bd9Sstevel@tonic-gate errmsg(M_USED, logname);
6967c478bd9Sstevel@tonic-gate exit(EX_NAME_EXISTS);
6977c478bd9Sstevel@tonic-gate break;
6987c478bd9Sstevel@tonic-gate
6997c478bd9Sstevel@tonic-gate default:
7007c478bd9Sstevel@tonic-gate errmsg(M_UPDATE, "modified");
7017c478bd9Sstevel@tonic-gate exit(ret);
7027c478bd9Sstevel@tonic-gate break;
7037c478bd9Sstevel@tonic-gate }
7047c478bd9Sstevel@tonic-gate }
7057c478bd9Sstevel@tonic-gate if (tries == 0) {
7067c478bd9Sstevel@tonic-gate errmsg(M_UPDATE, "modified");
7077c478bd9Sstevel@tonic-gate }
7087c478bd9Sstevel@tonic-gate
7097c478bd9Sstevel@tonic-gate exit(ret);
7107c478bd9Sstevel@tonic-gate /*NOTREACHED*/
7117c478bd9Sstevel@tonic-gate }
712