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