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 8 USE_GROUPADD(NEWTOY(groupadd, "<1>2g#<0S", TOYFLAG_NEEDROOT|TOYFLAG_SBIN)) 9 USE_GROUPADD(OLDTOY(addgroup, groupadd, TOYFLAG_NEEDROOT|TOYFLAG_SBIN)) 10 11 config 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 29 GLOBALS( 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 */ 38 static void new_group() 39 { 40 char *entry = NULL; 41 42 if (toys.optflags & FLAG_g) { 43 if (TT.gid > INT_MAX) error_exit("gid should be less than '%d' ", INT_MAX); 44 if (getgrgid(TT.gid)) error_exit("group '%ld' is in use", TT.gid); 45 } else { 46 if (toys.optflags & FLAG_S) TT.gid = CFG_TOYBOX_UID_SYS; 47 else TT.gid = CFG_TOYBOX_UID_USR; 48 //find unused gid 49 while (getgrgid(TT.gid)) TT.gid++; 50 } 51 52 entry = xmprintf("%s:%s:%d:", *toys.optargs, "x", TT.gid); 53 update_password(GROUP_PATH, *toys.optargs, entry); 54 free(entry); 55 entry = xmprintf("%s:%s::", *toys.optargs, "!"); 56 update_password(SECURE_GROUP_PATH, *toys.optargs, entry); 57 free(entry); 58 } 59 60 void groupadd_main(void) 61 { 62 struct group *grp = NULL; 63 char *entry = NULL; 64 65 if (toys.optflags && toys.optc == 2) 66 help_exit("options, user and group can't be together"); 67 68 if (toys.optc == 2) { //add user to group 69 //toys.optargs[0]- user, toys.optargs[1] - group 70 xgetpwnam(*toys.optargs); 71 if (!(grp = getgrnam(toys.optargs[1]))) 72 error_exit("group '%s' does not exist", toys.optargs[1]); 73 if (!grp->gr_mem) entry = xmprintf("%s", *toys.optargs); 74 else { 75 int i; 76 77 for (i = 0; grp->gr_mem[i]; i++) 78 if (!strcmp(grp->gr_mem[i], *toys.optargs)) return; 79 80 entry = xstrdup(""); 81 for (i=0; grp->gr_mem[i]; i++) { 82 entry = xrealloc(entry, strlen(entry) + strlen(grp->gr_mem[i]) + 2); 83 strcat(entry, grp->gr_mem[i]); 84 strcat(entry, ","); 85 } 86 entry = xrealloc(entry, strlen(entry) + strlen(*toys.optargs) + 1); 87 strcat(entry, *toys.optargs); 88 } 89 update_password(GROUP_PATH, grp->gr_name, entry); 90 update_password(SECURE_GROUP_PATH, grp->gr_name, entry); 91 free(entry); 92 } else { //new group to be created 93 char *s = *toys.optargs; 94 95 /* investigate the group to be created */ 96 if (getgrnam(s)) error_exit("'%s' in use", s); 97 if (s[strcspn(s, ":/\n")] || strlen(s) > LOGIN_NAME_MAX) 98 error_exit("bad name"); 99 new_group(); 100 } 101 } 102