xref: /aosp_15_r20/external/toybox/toys/pending/userdel.c (revision cf5a6c84e2b8763fc1a7db14496fd4742913b199)
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