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