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 2005 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 <unistd.h> 47 #include <strings.h> 48 #include "users.h" 49 #include "messages.h" 50 #include "funcs.h" 51 52 /******************************************************************************* 53 * userdel [-r] login 54 * 55 * This command deletes user logins. Arguments are: 56 * 57 * -r - when given, this option removes home directory & its contents 58 * 59 * login - a string of printable chars except colon (:) 60 ******************************************************************************/ 61 62 extern int check_perm(), isbusy(); 63 extern int rm_files(), call_passmgmt(), edit_group(); 64 65 static char *logname; /* login name to delete */ 66 static char *nargv[20]; /* arguments for execvp of passmgmt */ 67 68 char *cmdname; 69 70 int 71 main(int argc, char **argv) 72 { 73 int ch, ret = 0, rflag = 0, argindex, tries; 74 struct passwd *pstruct; 75 struct stat statbuf; 76 #ifndef att 77 FILE *pwf; /* fille ptr for opened passwd file */ 78 #endif 79 char *usertype = NULL; 80 int rc; 81 82 cmdname = argv[0]; 83 84 if( geteuid() != 0 ) { 85 errmsg( M_PERM_DENIED ); 86 exit( EX_NO_PERM ); 87 } 88 89 opterr = 0; /* no print errors from getopt */ 90 usertype = getusertype(argv[0]); 91 92 while( (ch = getopt(argc, argv, "r")) != EOF ) { 93 switch(ch) { 94 case 'r': 95 rflag++; 96 break; 97 case '?': 98 if (is_role(usertype)) 99 errmsg( M_DRUSAGE ); 100 else 101 errmsg( M_DUSAGE ); 102 exit( EX_SYNTAX ); 103 } 104 } 105 106 if( optind != argc - 1 ) { 107 if (is_role(usertype)) 108 errmsg( M_DRUSAGE ); 109 else 110 errmsg( M_DUSAGE ); 111 exit( EX_SYNTAX ); 112 } 113 114 logname = argv[optind]; 115 116 #ifdef att 117 pstruct = getpwnam(logname); 118 #else 119 /* 120 * Do this with fgetpwent to make sure we are only looking on local 121 * system (since passmgmt only works on local system). 122 */ 123 if ((pwf = fopen("/etc/passwd", "r")) == NULL) { 124 errmsg( M_OOPS, "open", "/etc/passwd"); 125 exit(EX_FAILURE); 126 } 127 while ((pstruct = fgetpwent(pwf)) != NULL) 128 if (strcmp(pstruct->pw_name, logname) == 0) 129 break; 130 131 fclose(pwf); 132 #endif 133 134 if (pstruct == NULL) { 135 errmsg( M_EXIST, logname ); 136 exit( EX_NAME_NOT_EXIST ); 137 } 138 139 if( isbusy(logname) ) { 140 errmsg( M_BUSY, logname, "remove" ); 141 exit( EX_BUSY ); 142 } 143 144 /* that's it for validations - now do the work */ 145 /* set up arguments to passmgmt in nargv array */ 146 nargv[0] = "passmgmt"; 147 nargv[1] = "-d"; /* delete */ 148 argindex = 2; /* next argument */ 149 150 /* finally - login name */ 151 nargv[argindex++] = logname; 152 153 /* set the last to null */ 154 nargv[argindex++] = NULL; 155 156 /* remove home directory */ 157 if( rflag ) { 158 /* Check Permissions */ 159 if( stat( pstruct->pw_dir, &statbuf ) ) { 160 errmsg(M_OOPS, "find status about home directory", 161 strerror(errno)); 162 exit( EX_HOMEDIR ); 163 } 164 165 if( check_perm( statbuf, pstruct->pw_uid, pstruct->pw_gid, 166 S_IWOTH|S_IXOTH ) != 0 ) { 167 errmsg( M_NO_PERM, logname, pstruct->pw_dir ); 168 exit( EX_HOMEDIR ); 169 } 170 171 if( rm_files(pstruct->pw_dir, logname) != EX_SUCCESS ) 172 exit( EX_HOMEDIR ); 173 } 174 175 /* now call passmgmt */ 176 ret = PEX_FAILED; 177 for( tries = 3; ret != PEX_SUCCESS && tries--; ) { 178 switch( ret = call_passmgmt( nargv ) ) { 179 case PEX_SUCCESS: 180 ret = edit_group( logname, (char *)0, (int **)0, 1 ); 181 if( ret != EX_SUCCESS ) 182 errmsg( M_UPDATE, "deleted" ); 183 break; 184 185 case PEX_BUSY: 186 break; 187 188 case PEX_HOSED_FILES: 189 errmsg( M_HOSED_FILES ); 190 exit( EX_INCONSISTENT ); 191 break; 192 193 case PEX_SYNTAX: 194 case PEX_BADARG: 195 /* should NEVER occur that passmgmt usage is wrong */ 196 if (is_role(usertype)) 197 errmsg( M_DRUSAGE ); 198 else 199 errmsg( M_DUSAGE ); 200 exit( EX_SYNTAX ); 201 break; 202 203 case PEX_BADUID: 204 /* uid is used - shouldn't happen but print message anyway */ 205 errmsg( M_UID_USED, pstruct->pw_uid ); 206 exit( EX_ID_EXISTS ); 207 break; 208 209 case PEX_BADNAME: 210 /* invalid loname */ 211 errmsg( M_USED, logname); 212 exit( EX_NAME_EXISTS ); 213 break; 214 215 default: 216 errmsg( M_UPDATE, "deleted" ); 217 exit( ret ); 218 break; 219 } 220 } 221 if( tries == 0 ) 222 errmsg( M_UPDATE, "deleted" ); 223 224 /* 225 * Now, remove this user from all project entries 226 */ 227 228 rc = edit_project(logname, (char *)0, (projid_t **)0, 1); 229 if (rc != EX_SUCCESS) { 230 errmsg(M_UPDATE, "modified"); 231 exit(rc); 232 } 233 234 exit( ret ); 235 /*NOTREACHED*/ 236 } 237