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