groupadd.c revision 59d85e2bb065a3bdc27868acb7a65f89d872c7fa
1/* groupadd.c - create a new group 2 * 3 * Copyright 2013 Ashwini Kumar <ak.ashwini@gmail.com> 4 * Copyright 2013 Kyungwan Han <asura321@gmail.com> 5 * 6 * See http://refspecs.linuxfoundation.org/LSB_4.1.0/LSB-Core-generic/LSB-Core-generic/groupadd.html 7 8USE_GROUPADD(NEWTOY(groupadd, "<1>2g#<0S", TOYFLAG_NEEDROOT|TOYFLAG_SBIN)) 9USE_GROUPADD(OLDTOY(addgroup, groupadd, OPTSTR_groupadd, TOYFLAG_NEEDROOT|TOYFLAG_SBIN)) 10 11config GROUPADD 12 bool "groupadd" 13 default n 14 help 15 usage: groupadd [-S] [-g GID] [USER] GROUP 16 17 Add a group or add a user to a group 18 19 -g GID Group id 20 -S Create a system group 21*/ 22 23#define FOR_groupadd 24#include "toys.h" 25 26#define GROUP_PATH "/etc/group" 27#define SECURE_GROUP_PATH "/etc/gshadow" 28 29GLOBALS( 30 long gid; 31) 32 33/* Add a new group to the system, if GID is given then that is validated 34 * to be free, else a free GID is choosen by self. 35 * SYSTEM IDs are considered in the range 100 ... 999 36 * update_group(), updates the entries in /etc/group, /etc/gshadow files 37 */ 38static void new_group() 39{ 40 char *entry = NULL; 41 int max = INT_MAX; 42 43 if (toys.optflags & FLAG_g) { 44 if (TT.gid > INT_MAX) error_exit("gid should be less than '%d' ", INT_MAX); 45 if (getgrgid(TT.gid)) error_exit("group '%ld' is in use", TT.gid); 46 } else { 47 if (toys.optflags & FLAG_S) { 48 TT.gid = SYS_FIRST_ID; 49 max = SYS_LAST_ID; 50 } else { 51 TT.gid = SYS_LAST_ID + 1; //i.e. starting from 1000 52 max = 60000; // as per config file on Linux desktop 53 } 54 //find unused gid 55 while (TT.gid <= max) { 56 if (!getgrgid(TT.gid)) break; 57 if (TT.gid == max) error_exit("no more free gids left"); 58 TT.gid++; 59 } 60 } 61 62 entry = xmprintf("%s:%s:%d:", *toys.optargs, "x", TT.gid); 63 update_password(GROUP_PATH, *toys.optargs, entry); 64 free(entry); 65 entry = xmprintf("%s:%s::", *toys.optargs, "!"); 66 update_password(SECURE_GROUP_PATH, *toys.optargs, entry); 67 free(entry); 68} 69 70void groupadd_main(void) 71{ 72 struct group *grp = NULL; 73 char *entry = NULL; 74 75 if (toys.optflags && toys.optc == 2) { 76 toys.exithelp = 1; 77 error_exit("options, user and group can't be together"); 78 } 79 80 if (toys.optc == 2) { //add user to group 81 //toys.optargs[0]- user, toys.optargs[1] - group 82 xgetpwnam(*toys.optargs); 83 if (!(grp = getgrnam(toys.optargs[1]))) 84 error_exit("group '%s' does not exist", toys.optargs[1]); 85 if (!grp->gr_mem) entry = xmprintf("%s", *toys.optargs); 86 else { 87 int i; 88 89 for (i = 0; grp->gr_mem[i]; i++) 90 if (!strcmp(grp->gr_mem[i], *toys.optargs)) return; 91 92 entry = xstrdup(""); 93 for (i=0; grp->gr_mem[i]; i++) { 94 entry = xrealloc(entry, strlen(entry) + strlen(grp->gr_mem[i]) + 2); 95 strcat(entry, grp->gr_mem[i]); 96 strcat(entry, ","); 97 } 98 entry = xrealloc(entry, strlen(entry) + strlen(*toys.optargs) + 1); 99 strcat(entry, *toys.optargs); 100 } 101 update_password(GROUP_PATH, grp->gr_name, entry); 102 update_password(SECURE_GROUP_PATH, grp->gr_name, entry); 103 free(entry); 104 } else { //new group to be created 105 /* investigate the group to be created */ 106 if ((grp = getgrnam(*toys.optargs))) 107 error_exit("group '%s' is in use", *toys.optargs); 108 setlocale(LC_ALL, "C"); 109 is_valid_username(*toys.optargs); 110 new_group(); 111 } 112} 113