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