1*cf5a6c84SAndroid Build Coastguard Worker /* userdel.c - delete a user
2*cf5a6c84SAndroid Build Coastguard Worker *
3*cf5a6c84SAndroid Build Coastguard Worker * Copyright 2014 Ashwini Kumar <[email protected]>
4*cf5a6c84SAndroid Build Coastguard Worker *
5*cf5a6c84SAndroid Build Coastguard Worker * See http://refspecs.linuxfoundation.org/LSB_4.1.0/LSB-Core-generic/LSB-Core-generic/userdel.html
6*cf5a6c84SAndroid Build Coastguard Worker
7*cf5a6c84SAndroid Build Coastguard Worker USE_USERDEL(NEWTOY(userdel, "<1>1r", TOYFLAG_NEEDROOT|TOYFLAG_SBIN))
8*cf5a6c84SAndroid Build Coastguard Worker USE_USERDEL(OLDTOY(deluser, userdel, TOYFLAG_NEEDROOT|TOYFLAG_SBIN))
9*cf5a6c84SAndroid Build Coastguard Worker
10*cf5a6c84SAndroid Build Coastguard Worker config USERDEL
11*cf5a6c84SAndroid Build Coastguard Worker bool "userdel"
12*cf5a6c84SAndroid Build Coastguard Worker default n
13*cf5a6c84SAndroid Build Coastguard Worker help
14*cf5a6c84SAndroid Build Coastguard Worker usage: userdel [-r] USER
15*cf5a6c84SAndroid Build Coastguard Worker usage: deluser [-r] USER
16*cf5a6c84SAndroid Build Coastguard Worker
17*cf5a6c84SAndroid Build Coastguard Worker Delete USER from the SYSTEM
18*cf5a6c84SAndroid Build Coastguard Worker
19*cf5a6c84SAndroid Build Coastguard Worker -r remove home directory
20*cf5a6c84SAndroid Build Coastguard Worker */
21*cf5a6c84SAndroid Build Coastguard Worker
22*cf5a6c84SAndroid Build Coastguard Worker #define FOR_userdel
23*cf5a6c84SAndroid Build Coastguard Worker #include "toys.h"
24*cf5a6c84SAndroid Build Coastguard Worker
update_groupfiles(char * filename,char * username)25*cf5a6c84SAndroid Build Coastguard Worker static void update_groupfiles(char *filename, char* username)
26*cf5a6c84SAndroid Build Coastguard Worker {
27*cf5a6c84SAndroid Build Coastguard Worker char *filenamesfx = NULL, *sfx = NULL, *line = NULL;
28*cf5a6c84SAndroid Build Coastguard Worker FILE *exfp, *newfp;
29*cf5a6c84SAndroid Build Coastguard Worker int ulen = strlen(username);
30*cf5a6c84SAndroid Build Coastguard Worker size_t allocated_length = 0;
31*cf5a6c84SAndroid Build Coastguard Worker struct flock lock;
32*cf5a6c84SAndroid Build Coastguard Worker
33*cf5a6c84SAndroid Build Coastguard Worker filenamesfx = xmprintf("%s+", filename);
34*cf5a6c84SAndroid Build Coastguard Worker sfx = strchr(filenamesfx, '+');
35*cf5a6c84SAndroid Build Coastguard Worker exfp = xfopen(filename, "r+");
36*cf5a6c84SAndroid Build Coastguard Worker
37*cf5a6c84SAndroid Build Coastguard Worker *sfx = '-';
38*cf5a6c84SAndroid Build Coastguard Worker unlink(filenamesfx);
39*cf5a6c84SAndroid Build Coastguard Worker if (link(filename, filenamesfx)) error_msg("Can't create backup file");
40*cf5a6c84SAndroid Build Coastguard Worker
41*cf5a6c84SAndroid Build Coastguard Worker *sfx = '+';
42*cf5a6c84SAndroid Build Coastguard Worker lock.l_type = F_WRLCK;
43*cf5a6c84SAndroid Build Coastguard Worker lock.l_whence = SEEK_SET;
44*cf5a6c84SAndroid Build Coastguard Worker lock.l_start = lock.l_len = 0;
45*cf5a6c84SAndroid Build Coastguard Worker
46*cf5a6c84SAndroid Build Coastguard Worker if (fcntl(fileno(exfp), F_SETLK, &lock) < 0)
47*cf5a6c84SAndroid Build Coastguard Worker perror_msg("Couldn't lock file %s",filename);
48*cf5a6c84SAndroid Build Coastguard Worker
49*cf5a6c84SAndroid Build Coastguard Worker lock.l_type = F_UNLCK; //unlocking at a later stage
50*cf5a6c84SAndroid Build Coastguard Worker
51*cf5a6c84SAndroid Build Coastguard Worker newfp = xfopen(filenamesfx, "w+");
52*cf5a6c84SAndroid Build Coastguard Worker
53*cf5a6c84SAndroid Build Coastguard Worker while (getline(&line, &allocated_length, exfp) > 0) {
54*cf5a6c84SAndroid Build Coastguard Worker sprintf(toybuf, "%s:",username);
55*cf5a6c84SAndroid Build Coastguard Worker if (strncmp(line, toybuf, ulen+1)) {
56*cf5a6c84SAndroid Build Coastguard Worker char *n, *p = strrchr(line, ':');
57*cf5a6c84SAndroid Build Coastguard Worker
58*cf5a6c84SAndroid Build Coastguard Worker if (p && *++p && (n = strstr(p, username))) {
59*cf5a6c84SAndroid Build Coastguard Worker do {
60*cf5a6c84SAndroid Build Coastguard Worker if (n[ulen] == ',') {
61*cf5a6c84SAndroid Build Coastguard Worker *n = '\0';
62*cf5a6c84SAndroid Build Coastguard Worker n += ulen + 1;
63*cf5a6c84SAndroid Build Coastguard Worker fprintf(newfp, "%s%s\n", line, n);
64*cf5a6c84SAndroid Build Coastguard Worker break;
65*cf5a6c84SAndroid Build Coastguard Worker } else if (!n[ulen]) {
66*cf5a6c84SAndroid Build Coastguard Worker if (n[-1] == ',') n[-1] = *n = '\0';
67*cf5a6c84SAndroid Build Coastguard Worker if (n[-1] == ':') *n = '\0';
68*cf5a6c84SAndroid Build Coastguard Worker fprintf(newfp, "%s%s\n", line, n);
69*cf5a6c84SAndroid Build Coastguard Worker break;
70*cf5a6c84SAndroid Build Coastguard Worker } else n += ulen;
71*cf5a6c84SAndroid Build Coastguard Worker } while (*n && (n=strstr(n, username)));
72*cf5a6c84SAndroid Build Coastguard Worker if (!n) fprintf(newfp, "%s\n", line);
73*cf5a6c84SAndroid Build Coastguard Worker } else fprintf(newfp, "%s\n", line);
74*cf5a6c84SAndroid Build Coastguard Worker }
75*cf5a6c84SAndroid Build Coastguard Worker }
76*cf5a6c84SAndroid Build Coastguard Worker free(line);
77*cf5a6c84SAndroid Build Coastguard Worker fcntl(fileno(exfp), F_SETLK, &lock);
78*cf5a6c84SAndroid Build Coastguard Worker fclose(exfp);
79*cf5a6c84SAndroid Build Coastguard Worker errno = 0;
80*cf5a6c84SAndroid Build Coastguard Worker fflush(newfp);
81*cf5a6c84SAndroid Build Coastguard Worker fsync(fileno(newfp));
82*cf5a6c84SAndroid Build Coastguard Worker fclose(newfp);
83*cf5a6c84SAndroid Build Coastguard Worker rename(filenamesfx, filename);
84*cf5a6c84SAndroid Build Coastguard Worker if (errno){
85*cf5a6c84SAndroid Build Coastguard Worker perror_msg("File Writing/Saving failed: ");
86*cf5a6c84SAndroid Build Coastguard Worker unlink(filenamesfx);
87*cf5a6c84SAndroid Build Coastguard Worker }
88*cf5a6c84SAndroid Build Coastguard Worker free(filenamesfx);
89*cf5a6c84SAndroid Build Coastguard Worker }
90*cf5a6c84SAndroid Build Coastguard Worker
userdel_main(void)91*cf5a6c84SAndroid Build Coastguard Worker void userdel_main(void)
92*cf5a6c84SAndroid Build Coastguard Worker {
93*cf5a6c84SAndroid Build Coastguard Worker struct passwd *pwd = xgetpwnam(*toys.optargs);
94*cf5a6c84SAndroid Build Coastguard Worker
95*cf5a6c84SAndroid Build Coastguard Worker update_password("/etc/passwd", pwd->pw_name, 0, 0);
96*cf5a6c84SAndroid Build Coastguard Worker update_password("/etc/shadow", pwd->pw_name, 0, 0);
97*cf5a6c84SAndroid Build Coastguard Worker
98*cf5a6c84SAndroid Build Coastguard Worker // delete the group named USER, and remove user from group.
99*cf5a6c84SAndroid Build Coastguard Worker // could update_password() be used for this?
100*cf5a6c84SAndroid Build Coastguard Worker // not a good idea, as update_passwd() updates one entry at a time
101*cf5a6c84SAndroid Build Coastguard Worker // in this case it will be modifying the files as many times the
102*cf5a6c84SAndroid Build Coastguard Worker // USER appears in group database files. So the customized version
103*cf5a6c84SAndroid Build Coastguard Worker // of update_passwd() is here.
104*cf5a6c84SAndroid Build Coastguard Worker update_groupfiles("/etc/group", *toys.optargs);
105*cf5a6c84SAndroid Build Coastguard Worker update_groupfiles("/etc/gshadow", *toys.optargs);
106*cf5a6c84SAndroid Build Coastguard Worker
107*cf5a6c84SAndroid Build Coastguard Worker if (FLAG(r)) {
108*cf5a6c84SAndroid Build Coastguard Worker char *arg[] = {"rm", "-fr", pwd->pw_dir, NULL, NULL};
109*cf5a6c84SAndroid Build Coastguard Worker
110*cf5a6c84SAndroid Build Coastguard Worker sprintf(toybuf, "/var/spool/mail/%s",pwd->pw_name);
111*cf5a6c84SAndroid Build Coastguard Worker arg[3] = toybuf;
112*cf5a6c84SAndroid Build Coastguard Worker xexec(arg);
113*cf5a6c84SAndroid Build Coastguard Worker }
114*cf5a6c84SAndroid Build Coastguard Worker }
115