#include <sys/types.h>
#include <sys/stat.h>
#include <stdio.h>
#include <ctype.h>
#include <limits.h>
#include <pwd.h>
#include <project.h>
#include <string.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <userdefs.h>
#include <stdlib.h>
#include <errno.h>
#include <unistd.h>
#include <strings.h>
#include "users.h"
#include "messages.h"
#include "funcs.h"
extern int check_perm(), isbusy(), get_default_zfs_flags();
extern int rm_files(), call_passmgmt(), edit_group();
static char *logname;
static char *nargv[20];
char *cmdname;
int
main(int argc, char **argv)
{
int ch, ret = 0, rflag = 0;
int zfs_flags = 0, argindex, tries;
struct passwd *pstruct;
struct stat statbuf;
#ifndef att
FILE *pwf;
#endif
char *usertype = NULL;
int rc;
cmdname = argv[0];
if (geteuid() != 0) {
errmsg(M_PERM_DENIED);
exit(EX_NO_PERM);
}
opterr = 0;
usertype = getusertype(argv[0]);
while ((ch = getopt(argc, argv, "r")) != EOF) {
switch (ch) {
case 'r':
rflag++;
break;
case '?':
if (is_role(usertype))
errmsg(M_DRUSAGE);
else
errmsg(M_DUSAGE);
exit(EX_SYNTAX);
}
}
if (optind != argc - 1) {
if (is_role(usertype))
errmsg(M_DRUSAGE);
else
errmsg(M_DUSAGE);
exit(EX_SYNTAX);
}
logname = argv[optind];
#ifdef att
pstruct = getpwnam(logname);
#else
if ((pwf = fopen("/etc/passwd", "r")) == NULL) {
errmsg(M_OOPS, "open", "/etc/passwd");
exit(EX_FAILURE);
}
while ((pstruct = fgetpwent(pwf)) != NULL)
if (strcmp(pstruct->pw_name, logname) == 0)
break;
fclose(pwf);
#endif
if (pstruct == NULL) {
errmsg(M_EXIST, logname);
exit(EX_NAME_NOT_EXIST);
}
if (isbusy(logname)) {
errmsg(M_BUSY, logname, "remove");
exit(EX_BUSY);
}
nargv[0] = PASSMGMT;
nargv[1] = "-d";
argindex = 2;
nargv[argindex++] = logname;
nargv[argindex++] = NULL;
if (rflag) {
if (stat(pstruct->pw_dir, &statbuf)) {
errmsg(M_OOPS, "find status about home directory",
strerror(errno));
exit(EX_HOMEDIR);
}
if (check_perm(statbuf, pstruct->pw_uid, pstruct->pw_gid,
S_IWOTH|S_IXOTH) != 0) {
errmsg(M_NO_PERM, logname, pstruct->pw_dir);
exit(EX_HOMEDIR);
}
zfs_flags = get_default_zfs_flags();
if (rm_files(pstruct->pw_dir, logname, zfs_flags) != EX_SUCCESS)
exit(EX_HOMEDIR);
}
ret = PEX_FAILED;
for (tries = 3; ret != PEX_SUCCESS && tries--; ) {
switch (ret = call_passmgmt(nargv)) {
case PEX_SUCCESS:
ret = edit_group(logname, (char *)0, (int **)0, 1);
if (ret != EX_SUCCESS)
errmsg(M_UPDATE, "deleted");
break;
case PEX_BUSY:
break;
case PEX_HOSED_FILES:
errmsg(M_HOSED_FILES);
exit(EX_INCONSISTENT);
break;
case PEX_SYNTAX:
case PEX_BADARG:
if (is_role(usertype))
errmsg(M_DRUSAGE);
else
errmsg(M_DUSAGE);
exit(EX_SYNTAX);
break;
case PEX_BADUID:
errmsg(M_UID_USED, pstruct->pw_uid);
exit(EX_ID_EXISTS);
break;
case PEX_BADNAME:
errmsg(M_USED, logname);
exit(EX_NAME_EXISTS);
break;
default:
errmsg(M_UPDATE, "deleted");
exit(ret);
break;
}
}
if (tries == 0)
errmsg(M_UPDATE, "deleted");
rc = edit_project(logname, (char *)0, (projid_t **)0, 1);
if (rc != EX_SUCCESS) {
errmsg(M_UPDATE, "modified");
exit(rc);
}
exit(ret);
}