xref: /illumos-gate/usr/src/cmd/oamuser/user/userdel.c (revision 7c478bd9)
1*7c478bd9Sstevel@tonic-gate /*
2*7c478bd9Sstevel@tonic-gate  * CDDL HEADER START
3*7c478bd9Sstevel@tonic-gate  *
4*7c478bd9Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
5*7c478bd9Sstevel@tonic-gate  * Common Development and Distribution License, Version 1.0 only
6*7c478bd9Sstevel@tonic-gate  * (the "License").  You may not use this file except in compliance
7*7c478bd9Sstevel@tonic-gate  * with the License.
8*7c478bd9Sstevel@tonic-gate  *
9*7c478bd9Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10*7c478bd9Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
11*7c478bd9Sstevel@tonic-gate  * See the License for the specific language governing permissions
12*7c478bd9Sstevel@tonic-gate  * and limitations under the License.
13*7c478bd9Sstevel@tonic-gate  *
14*7c478bd9Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
15*7c478bd9Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16*7c478bd9Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
17*7c478bd9Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
18*7c478bd9Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
19*7c478bd9Sstevel@tonic-gate  *
20*7c478bd9Sstevel@tonic-gate  * CDDL HEADER END
21*7c478bd9Sstevel@tonic-gate  */
22*7c478bd9Sstevel@tonic-gate /*	Copyright (c) 1984, 1986, 1987, 1988, 1989 AT&T	*/
23*7c478bd9Sstevel@tonic-gate /*	  All Rights Reserved  	*/
24*7c478bd9Sstevel@tonic-gate 
25*7c478bd9Sstevel@tonic-gate 
26*7c478bd9Sstevel@tonic-gate /*
27*7c478bd9Sstevel@tonic-gate  * Copyright 2004 Sun Microsystems, Inc.  All rights reserved.
28*7c478bd9Sstevel@tonic-gate  * Use is subject to license terms.
29*7c478bd9Sstevel@tonic-gate  */
30*7c478bd9Sstevel@tonic-gate 
31*7c478bd9Sstevel@tonic-gate #pragma ident	"%Z%%M%	%I%	%E% SMI"
32*7c478bd9Sstevel@tonic-gate 
33*7c478bd9Sstevel@tonic-gate #include <sys/types.h>
34*7c478bd9Sstevel@tonic-gate #include <sys/stat.h>
35*7c478bd9Sstevel@tonic-gate #include <stdio.h>
36*7c478bd9Sstevel@tonic-gate #include <ctype.h>
37*7c478bd9Sstevel@tonic-gate #include <limits.h>
38*7c478bd9Sstevel@tonic-gate #include <pwd.h>
39*7c478bd9Sstevel@tonic-gate #include <project.h>
40*7c478bd9Sstevel@tonic-gate #include <string.h>
41*7c478bd9Sstevel@tonic-gate #include <sys/types.h>
42*7c478bd9Sstevel@tonic-gate #include <sys/stat.h>
43*7c478bd9Sstevel@tonic-gate #include <userdefs.h>
44*7c478bd9Sstevel@tonic-gate #include <stdlib.h>
45*7c478bd9Sstevel@tonic-gate #include <errno.h>
46*7c478bd9Sstevel@tonic-gate #include "users.h"
47*7c478bd9Sstevel@tonic-gate #include "messages.h"
48*7c478bd9Sstevel@tonic-gate #include "funcs.h"
49*7c478bd9Sstevel@tonic-gate 
50*7c478bd9Sstevel@tonic-gate /*******************************************************************************
51*7c478bd9Sstevel@tonic-gate  *  userdel [-r] login
52*7c478bd9Sstevel@tonic-gate  *
53*7c478bd9Sstevel@tonic-gate  *	This command deletes user logins.  Arguments are:
54*7c478bd9Sstevel@tonic-gate  *
55*7c478bd9Sstevel@tonic-gate  *	-r - when given, this option removes home directory & its contents
56*7c478bd9Sstevel@tonic-gate  *
57*7c478bd9Sstevel@tonic-gate  *	login - a string of printable chars except colon (:)
58*7c478bd9Sstevel@tonic-gate  ******************************************************************************/
59*7c478bd9Sstevel@tonic-gate 
60*7c478bd9Sstevel@tonic-gate extern char *prerrno();
61*7c478bd9Sstevel@tonic-gate extern int check_perm(), isbusy();
62*7c478bd9Sstevel@tonic-gate extern int rm_files(), call_passmgmt(), edit_group();
63*7c478bd9Sstevel@tonic-gate 
64*7c478bd9Sstevel@tonic-gate extern char *optarg;		/* used by getopt */
65*7c478bd9Sstevel@tonic-gate extern int optind, opterr;	/* used by getopt */
66*7c478bd9Sstevel@tonic-gate 
67*7c478bd9Sstevel@tonic-gate static char *logname;			/* login name to delete */
68*7c478bd9Sstevel@tonic-gate static char *nargv[20];		/* arguments for execvp of passmgmt */
69*7c478bd9Sstevel@tonic-gate 
70*7c478bd9Sstevel@tonic-gate char *cmdname;
71*7c478bd9Sstevel@tonic-gate 
72*7c478bd9Sstevel@tonic-gate int
73*7c478bd9Sstevel@tonic-gate main(int argc, char **argv)
74*7c478bd9Sstevel@tonic-gate {
75*7c478bd9Sstevel@tonic-gate 	int ch, ret = 0, rflag = 0, argindex, tries;
76*7c478bd9Sstevel@tonic-gate 	struct passwd *pstruct;
77*7c478bd9Sstevel@tonic-gate 	struct stat statbuf;
78*7c478bd9Sstevel@tonic-gate #ifndef att
79*7c478bd9Sstevel@tonic-gate 	FILE *pwf;		/* fille ptr for opened passwd file */
80*7c478bd9Sstevel@tonic-gate #endif
81*7c478bd9Sstevel@tonic-gate 	char *usertype = NULL;
82*7c478bd9Sstevel@tonic-gate 	int rc;
83*7c478bd9Sstevel@tonic-gate 
84*7c478bd9Sstevel@tonic-gate 	cmdname = argv[0];
85*7c478bd9Sstevel@tonic-gate 
86*7c478bd9Sstevel@tonic-gate 	if( geteuid() != 0 ) {
87*7c478bd9Sstevel@tonic-gate 		errmsg( M_PERM_DENIED );
88*7c478bd9Sstevel@tonic-gate 		exit( EX_NO_PERM );
89*7c478bd9Sstevel@tonic-gate 	}
90*7c478bd9Sstevel@tonic-gate 
91*7c478bd9Sstevel@tonic-gate 	opterr = 0;			/* no print errors from getopt */
92*7c478bd9Sstevel@tonic-gate 	usertype = getusertype(argv[0]);
93*7c478bd9Sstevel@tonic-gate 
94*7c478bd9Sstevel@tonic-gate 	while( (ch = getopt(argc, argv, "r")) != EOF ) {
95*7c478bd9Sstevel@tonic-gate 		switch(ch) {
96*7c478bd9Sstevel@tonic-gate 			case 'r':
97*7c478bd9Sstevel@tonic-gate 				rflag++;
98*7c478bd9Sstevel@tonic-gate 				break;
99*7c478bd9Sstevel@tonic-gate 			case '?':
100*7c478bd9Sstevel@tonic-gate 				if (is_role(usertype))
101*7c478bd9Sstevel@tonic-gate 					errmsg( M_DRUSAGE );
102*7c478bd9Sstevel@tonic-gate 				else
103*7c478bd9Sstevel@tonic-gate 					errmsg( M_DUSAGE );
104*7c478bd9Sstevel@tonic-gate 				exit( EX_SYNTAX );
105*7c478bd9Sstevel@tonic-gate 		}
106*7c478bd9Sstevel@tonic-gate 	}
107*7c478bd9Sstevel@tonic-gate 
108*7c478bd9Sstevel@tonic-gate 	if( optind != argc - 1 ) {
109*7c478bd9Sstevel@tonic-gate 		if (is_role(usertype))
110*7c478bd9Sstevel@tonic-gate 			errmsg( M_DRUSAGE );
111*7c478bd9Sstevel@tonic-gate 		else
112*7c478bd9Sstevel@tonic-gate 			errmsg( M_DUSAGE );
113*7c478bd9Sstevel@tonic-gate 		exit( EX_SYNTAX );
114*7c478bd9Sstevel@tonic-gate 	}
115*7c478bd9Sstevel@tonic-gate 
116*7c478bd9Sstevel@tonic-gate 	logname = argv[optind];
117*7c478bd9Sstevel@tonic-gate 
118*7c478bd9Sstevel@tonic-gate #ifdef att
119*7c478bd9Sstevel@tonic-gate 	pstruct = getpwnam(logname);
120*7c478bd9Sstevel@tonic-gate #else
121*7c478bd9Sstevel@tonic-gate 	/*
122*7c478bd9Sstevel@tonic-gate 	 * Do this with fgetpwent to make sure we are only looking on local
123*7c478bd9Sstevel@tonic-gate 	 * system (since passmgmt only works on local system).
124*7c478bd9Sstevel@tonic-gate 	 */
125*7c478bd9Sstevel@tonic-gate 	if ((pwf = fopen("/etc/passwd", "r")) == NULL) {
126*7c478bd9Sstevel@tonic-gate 		errmsg( M_OOPS, "open", "/etc/passwd");
127*7c478bd9Sstevel@tonic-gate 		exit(EX_FAILURE);
128*7c478bd9Sstevel@tonic-gate 	}
129*7c478bd9Sstevel@tonic-gate 	while ((pstruct = fgetpwent(pwf)) != NULL)
130*7c478bd9Sstevel@tonic-gate 		if (strcmp(pstruct->pw_name, logname) == 0)
131*7c478bd9Sstevel@tonic-gate 			break;
132*7c478bd9Sstevel@tonic-gate 
133*7c478bd9Sstevel@tonic-gate 	fclose(pwf);
134*7c478bd9Sstevel@tonic-gate #endif
135*7c478bd9Sstevel@tonic-gate 
136*7c478bd9Sstevel@tonic-gate 	if (pstruct == NULL) {
137*7c478bd9Sstevel@tonic-gate 		errmsg( M_EXIST, logname );
138*7c478bd9Sstevel@tonic-gate 		exit( EX_NAME_NOT_EXIST );
139*7c478bd9Sstevel@tonic-gate 	}
140*7c478bd9Sstevel@tonic-gate 
141*7c478bd9Sstevel@tonic-gate 	if( isbusy(logname) ) {
142*7c478bd9Sstevel@tonic-gate 		errmsg( M_BUSY, logname, "remove" );
143*7c478bd9Sstevel@tonic-gate 		exit( EX_BUSY );
144*7c478bd9Sstevel@tonic-gate 	}
145*7c478bd9Sstevel@tonic-gate 
146*7c478bd9Sstevel@tonic-gate 	/* that's it for validations - now do the work */
147*7c478bd9Sstevel@tonic-gate 	/* set up arguments to  passmgmt in nargv array */
148*7c478bd9Sstevel@tonic-gate 	nargv[0] = "passmgmt";
149*7c478bd9Sstevel@tonic-gate 	nargv[1] = "-d";	/* delete */
150*7c478bd9Sstevel@tonic-gate 	argindex = 2;		/* next argument */
151*7c478bd9Sstevel@tonic-gate 
152*7c478bd9Sstevel@tonic-gate 	/* finally - login name */
153*7c478bd9Sstevel@tonic-gate 	nargv[argindex++] = logname;
154*7c478bd9Sstevel@tonic-gate 
155*7c478bd9Sstevel@tonic-gate 	/* set the last to null */
156*7c478bd9Sstevel@tonic-gate 	nargv[argindex++] = NULL;
157*7c478bd9Sstevel@tonic-gate 
158*7c478bd9Sstevel@tonic-gate 	/* remove home directory */
159*7c478bd9Sstevel@tonic-gate 	if( rflag ) {
160*7c478bd9Sstevel@tonic-gate 		/* Check Permissions */
161*7c478bd9Sstevel@tonic-gate 		if( stat( pstruct->pw_dir, &statbuf ) ) {
162*7c478bd9Sstevel@tonic-gate 			errmsg( M_OOPS, "find status about home directory",
163*7c478bd9Sstevel@tonic-gate 				prerrno( errno ) );
164*7c478bd9Sstevel@tonic-gate 			exit( EX_HOMEDIR );
165*7c478bd9Sstevel@tonic-gate 		}
166*7c478bd9Sstevel@tonic-gate 
167*7c478bd9Sstevel@tonic-gate 		if( check_perm( statbuf, pstruct->pw_uid, pstruct->pw_gid,
168*7c478bd9Sstevel@tonic-gate 		    S_IWOTH|S_IXOTH ) != 0 ) {
169*7c478bd9Sstevel@tonic-gate 			errmsg( M_NO_PERM, logname, pstruct->pw_dir );
170*7c478bd9Sstevel@tonic-gate 			exit( EX_HOMEDIR );
171*7c478bd9Sstevel@tonic-gate 		}
172*7c478bd9Sstevel@tonic-gate 
173*7c478bd9Sstevel@tonic-gate 		if( rm_files(pstruct->pw_dir, logname) != EX_SUCCESS )
174*7c478bd9Sstevel@tonic-gate 			exit( EX_HOMEDIR );
175*7c478bd9Sstevel@tonic-gate 	}
176*7c478bd9Sstevel@tonic-gate 
177*7c478bd9Sstevel@tonic-gate 	/* now call passmgmt */
178*7c478bd9Sstevel@tonic-gate 	ret = PEX_FAILED;
179*7c478bd9Sstevel@tonic-gate 	for( tries = 3; ret != PEX_SUCCESS && tries--; ) {
180*7c478bd9Sstevel@tonic-gate 		switch( ret = call_passmgmt( nargv ) ) {
181*7c478bd9Sstevel@tonic-gate 		case PEX_SUCCESS:
182*7c478bd9Sstevel@tonic-gate 			ret = edit_group( logname, (char *)0, (int **)0, 1 );
183*7c478bd9Sstevel@tonic-gate 			if( ret != EX_SUCCESS )
184*7c478bd9Sstevel@tonic-gate 				errmsg( M_UPDATE, "deleted" );
185*7c478bd9Sstevel@tonic-gate 			break;
186*7c478bd9Sstevel@tonic-gate 
187*7c478bd9Sstevel@tonic-gate 		case PEX_BUSY:
188*7c478bd9Sstevel@tonic-gate 			break;
189*7c478bd9Sstevel@tonic-gate 
190*7c478bd9Sstevel@tonic-gate 		case PEX_HOSED_FILES:
191*7c478bd9Sstevel@tonic-gate 			errmsg( M_HOSED_FILES );
192*7c478bd9Sstevel@tonic-gate 			exit( EX_INCONSISTENT );
193*7c478bd9Sstevel@tonic-gate 			break;
194*7c478bd9Sstevel@tonic-gate 
195*7c478bd9Sstevel@tonic-gate 		case PEX_SYNTAX:
196*7c478bd9Sstevel@tonic-gate 		case PEX_BADARG:
197*7c478bd9Sstevel@tonic-gate 			/* should NEVER occur that passmgmt usage is wrong */
198*7c478bd9Sstevel@tonic-gate 			if (is_role(usertype))
199*7c478bd9Sstevel@tonic-gate 				errmsg( M_DRUSAGE );
200*7c478bd9Sstevel@tonic-gate 			else
201*7c478bd9Sstevel@tonic-gate 				errmsg( M_DUSAGE );
202*7c478bd9Sstevel@tonic-gate 			exit( EX_SYNTAX );
203*7c478bd9Sstevel@tonic-gate 			break;
204*7c478bd9Sstevel@tonic-gate 
205*7c478bd9Sstevel@tonic-gate 		case PEX_BADUID:
206*7c478bd9Sstevel@tonic-gate 			/* uid is used - shouldn't happen but print message anyway */
207*7c478bd9Sstevel@tonic-gate 			errmsg( M_UID_USED, pstruct->pw_uid );
208*7c478bd9Sstevel@tonic-gate 			exit( EX_ID_EXISTS );
209*7c478bd9Sstevel@tonic-gate 			break;
210*7c478bd9Sstevel@tonic-gate 
211*7c478bd9Sstevel@tonic-gate 		case PEX_BADNAME:
212*7c478bd9Sstevel@tonic-gate 			/* invalid loname */
213*7c478bd9Sstevel@tonic-gate 			errmsg( M_USED, logname);
214*7c478bd9Sstevel@tonic-gate 			exit( EX_NAME_EXISTS );
215*7c478bd9Sstevel@tonic-gate 			break;
216*7c478bd9Sstevel@tonic-gate 
217*7c478bd9Sstevel@tonic-gate 		default:
218*7c478bd9Sstevel@tonic-gate 			errmsg( M_UPDATE, "deleted" );
219*7c478bd9Sstevel@tonic-gate 			exit( ret );
220*7c478bd9Sstevel@tonic-gate 			break;
221*7c478bd9Sstevel@tonic-gate 		}
222*7c478bd9Sstevel@tonic-gate 	}
223*7c478bd9Sstevel@tonic-gate 	if( tries == 0 )
224*7c478bd9Sstevel@tonic-gate 		errmsg( M_UPDATE, "deleted" );
225*7c478bd9Sstevel@tonic-gate 
226*7c478bd9Sstevel@tonic-gate /*
227*7c478bd9Sstevel@tonic-gate  * Now, remove this user from all project entries
228*7c478bd9Sstevel@tonic-gate  */
229*7c478bd9Sstevel@tonic-gate 
230*7c478bd9Sstevel@tonic-gate 	rc = edit_project(logname, (char *)0, (projid_t **)0, 1);
231*7c478bd9Sstevel@tonic-gate 	if (rc != EX_SUCCESS) {
232*7c478bd9Sstevel@tonic-gate 		errmsg(M_UPDATE, "modified");
233*7c478bd9Sstevel@tonic-gate 		exit(rc);
234*7c478bd9Sstevel@tonic-gate 	}
235*7c478bd9Sstevel@tonic-gate 
236*7c478bd9Sstevel@tonic-gate 	exit( ret );
237*7c478bd9Sstevel@tonic-gate 	/*NOTREACHED*/
238*7c478bd9Sstevel@tonic-gate }
239