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