You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
117 lines
3.1 KiB
117 lines
3.1 KiB
4 months ago
|
/* userdel.c - delete a user
|
||
|
*
|
||
|
* Copyright 2014 Ashwini Kumar <ak.ashwini1981@gmail.com>
|
||
|
*
|
||
|
* See http://refspecs.linuxfoundation.org/LSB_4.1.0/LSB-Core-generic/LSB-Core-generic/userdel.html
|
||
|
|
||
|
USE_USERDEL(NEWTOY(userdel, "<1>1r", TOYFLAG_NEEDROOT|TOYFLAG_SBIN))
|
||
|
USE_USERDEL(OLDTOY(deluser, userdel, TOYFLAG_NEEDROOT|TOYFLAG_SBIN))
|
||
|
|
||
|
config USERDEL
|
||
|
bool "userdel"
|
||
|
default n
|
||
|
help
|
||
|
usage: userdel [-r] USER
|
||
|
usage: deluser [-r] USER
|
||
|
|
||
|
Delete USER from the SYSTEM
|
||
|
|
||
|
-r remove home directory
|
||
|
*/
|
||
|
|
||
|
#define FOR_userdel
|
||
|
#include "toys.h"
|
||
|
|
||
|
static void update_groupfiles(char *filename, char* username)
|
||
|
{
|
||
|
char *filenamesfx = NULL, *sfx = NULL, *line = NULL;
|
||
|
FILE *exfp, *newfp;
|
||
|
int ulen = strlen(username);
|
||
|
struct flock lock;
|
||
|
|
||
|
filenamesfx = xmprintf("%s+", filename);
|
||
|
sfx = strchr(filenamesfx, '+');
|
||
|
exfp = xfopen(filename, "r+");
|
||
|
|
||
|
*sfx = '-';
|
||
|
unlink(filenamesfx);
|
||
|
if (link(filename, filenamesfx)) error_msg("Can't create backup file");
|
||
|
|
||
|
*sfx = '+';
|
||
|
lock.l_type = F_WRLCK;
|
||
|
lock.l_whence = SEEK_SET;
|
||
|
lock.l_start = lock.l_len = 0;
|
||
|
|
||
|
if (fcntl(fileno(exfp), F_SETLK, &lock) < 0)
|
||
|
perror_msg("Couldn't lock file %s",filename);
|
||
|
|
||
|
lock.l_type = F_UNLCK; //unlocking at a later stage
|
||
|
|
||
|
newfp = xfopen(filenamesfx, "w+");
|
||
|
|
||
|
while ((line = get_line(fileno(exfp))) != NULL){
|
||
|
sprintf(toybuf, "%s:",username);
|
||
|
if (!strncmp(line, toybuf, ulen+1)) goto LOOP;
|
||
|
else {
|
||
|
char *n, *p = strrchr(line, ':');
|
||
|
|
||
|
if (p && *++p && (n = strstr(p, username))) {
|
||
|
do {
|
||
|
if (n[ulen] == ',') {
|
||
|
*n = '\0';
|
||
|
n += ulen + 1;
|
||
|
fprintf(newfp, "%s%s\n", line, n);
|
||
|
break;
|
||
|
} else if (!n[ulen]) {
|
||
|
if (n[-1] == ',') n[-1] = *n = '\0';
|
||
|
if (n[-1] == ':') *n = '\0';
|
||
|
fprintf(newfp, "%s%s\n", line, n);
|
||
|
break;
|
||
|
} else n += ulen;
|
||
|
} while (*n && (n=strstr(n, username)));
|
||
|
if (!n) fprintf(newfp, "%s\n", line);
|
||
|
} else fprintf(newfp, "%s\n", line);
|
||
|
}
|
||
|
LOOP:
|
||
|
free(line);
|
||
|
}
|
||
|
fcntl(fileno(exfp), F_SETLK, &lock);
|
||
|
fclose(exfp);
|
||
|
errno = 0;
|
||
|
fflush(newfp);
|
||
|
fsync(fileno(newfp));
|
||
|
fclose(newfp);
|
||
|
rename(filenamesfx, filename);
|
||
|
if (errno){
|
||
|
perror_msg("File Writing/Saving failed: ");
|
||
|
unlink(filenamesfx);
|
||
|
}
|
||
|
free(filenamesfx);
|
||
|
}
|
||
|
|
||
|
void userdel_main(void)
|
||
|
{
|
||
|
struct passwd *pwd = NULL;
|
||
|
|
||
|
pwd = xgetpwnam(*toys.optargs);
|
||
|
update_password("/etc/passwd", pwd->pw_name, NULL);
|
||
|
update_password("/etc/shadow", pwd->pw_name, NULL);
|
||
|
|
||
|
// delete the group named USER, and remove user from group.
|
||
|
// could update_password() be used for this?
|
||
|
// not a good idea, as update_passwd() updates one entry at a time
|
||
|
// in this case it will be modifying the files as many times the
|
||
|
// USER appears in group database files. So the customized version
|
||
|
// of update_passwd() is here.
|
||
|
update_groupfiles("/etc/group", *toys.optargs);
|
||
|
update_groupfiles("/etc/gshadow", *toys.optargs);
|
||
|
|
||
|
if (toys.optflags & FLAG_r) {
|
||
|
char *arg[] = {"rm", "-fr", pwd->pw_dir, NULL, NULL};
|
||
|
|
||
|
sprintf(toybuf, "/var/spool/mail/%s",pwd->pw_name);
|
||
|
arg[3] = toybuf;
|
||
|
xexec(arg);
|
||
|
}
|
||
|
}
|