| /* groupadd.c - create a new group |
| * |
| * Copyright 2013 Ashwini Kumar <ak.ashwini@gmail.com> |
| * Copyright 2013 Kyungwan Han <asura321@gmail.com> |
| * |
| * See http://refspecs.linuxfoundation.org/LSB_4.1.0/LSB-Core-generic/LSB-Core-generic/groupadd.html |
| |
| USE_GROUPADD(NEWTOY(groupadd, "<1>2g#<0S", TOYFLAG_NEEDROOT|TOYFLAG_SBIN)) |
| USE_GROUPADD(OLDTOY(addgroup, groupadd, TOYFLAG_NEEDROOT|TOYFLAG_SBIN)) |
| |
| config GROUPADD |
| bool "groupadd" |
| default n |
| help |
| usage: groupadd [-S] [-g GID] [USER] GROUP |
| |
| Add a group or add a user to a group |
| |
| -g GID Group id |
| -S Create a system group |
| */ |
| |
| #define FOR_groupadd |
| #include "toys.h" |
| |
| #define GROUP_PATH "/etc/group" |
| #define SECURE_GROUP_PATH "/etc/gshadow" |
| |
| GLOBALS( |
| long gid; |
| ) |
| |
| /* Add a new group to the system, if GID is given then that is validated |
| * to be free, else a free GID is choosen by self. |
| * SYSTEM IDs are considered in the range 100 ... 999 |
| * update_group(), updates the entries in /etc/group, /etc/gshadow files |
| */ |
| static void new_group() |
| { |
| char *entry = NULL; |
| |
| if (toys.optflags & FLAG_g) { |
| if (TT.gid > INT_MAX) error_exit("gid should be less than '%d' ", INT_MAX); |
| if (getgrgid(TT.gid)) error_exit("group '%ld' is in use", TT.gid); |
| } else { |
| if (toys.optflags & FLAG_S) TT.gid = CFG_TOYBOX_UID_SYS; |
| else TT.gid = CFG_TOYBOX_UID_USR; |
| //find unused gid |
| while (getgrgid(TT.gid)) TT.gid++; |
| } |
| |
| entry = xmprintf("%s:%s:%d:", *toys.optargs, "x", TT.gid); |
| update_password(GROUP_PATH, *toys.optargs, entry); |
| free(entry); |
| entry = xmprintf("%s:%s::", *toys.optargs, "!"); |
| update_password(SECURE_GROUP_PATH, *toys.optargs, entry); |
| free(entry); |
| } |
| |
| void groupadd_main(void) |
| { |
| struct group *grp = NULL; |
| char *entry = NULL; |
| |
| if (toys.optflags && toys.optc == 2) |
| help_exit("options, user and group can't be together"); |
| |
| if (toys.optc == 2) { //add user to group |
| //toys.optargs[0]- user, toys.optargs[1] - group |
| xgetpwnam(*toys.optargs); |
| if (!(grp = getgrnam(toys.optargs[1]))) |
| error_exit("group '%s' does not exist", toys.optargs[1]); |
| if (!grp->gr_mem) entry = xmprintf("%s", *toys.optargs); |
| else { |
| int i; |
| |
| for (i = 0; grp->gr_mem[i]; i++) |
| if (!strcmp(grp->gr_mem[i], *toys.optargs)) return; |
| |
| entry = xstrdup(""); |
| for (i=0; grp->gr_mem[i]; i++) { |
| entry = xrealloc(entry, strlen(entry) + strlen(grp->gr_mem[i]) + 2); |
| strcat(entry, grp->gr_mem[i]); |
| strcat(entry, ","); |
| } |
| entry = xrealloc(entry, strlen(entry) + strlen(*toys.optargs) + 1); |
| strcat(entry, *toys.optargs); |
| } |
| update_password(GROUP_PATH, grp->gr_name, entry); |
| update_password(SECURE_GROUP_PATH, grp->gr_name, entry); |
| free(entry); |
| } else { //new group to be created |
| char *s = *toys.optargs; |
| |
| /* investigate the group to be created */ |
| if (getgrnam(s)) error_exit("'%s' in use", s); |
| if (s[strcspn(s, ":/\n")] || strlen(s) > LOGIN_NAME_MAX) |
| error_exit("bad name"); |
| new_group(); |
| } |
| } |