1d6f907dcSJoerg Wunsch /*- 2ad7cf975SJoerg Wunsch * Copyright (C) 1996 3ad7cf975SJoerg Wunsch * David L. Nugent. All rights reserved. 4d6f907dcSJoerg Wunsch * 5d6f907dcSJoerg Wunsch * Redistribution and use in source and binary forms, with or without 6d6f907dcSJoerg Wunsch * modification, are permitted provided that the following conditions 7d6f907dcSJoerg Wunsch * are met: 8d6f907dcSJoerg Wunsch * 1. Redistributions of source code must retain the above copyright 9ad7cf975SJoerg Wunsch * notice, this list of conditions and the following disclaimer. 10d6f907dcSJoerg Wunsch * 2. Redistributions in binary form must reproduce the above copyright 11d6f907dcSJoerg Wunsch * notice, this list of conditions and the following disclaimer in the 12d6f907dcSJoerg Wunsch * documentation and/or other materials provided with the distribution. 13d6f907dcSJoerg Wunsch * 14ad7cf975SJoerg Wunsch * THIS SOFTWARE IS PROVIDED BY DAVID L. NUGENT AND CONTRIBUTORS ``AS IS'' AND 15d6f907dcSJoerg Wunsch * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16d6f907dcSJoerg Wunsch * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17ad7cf975SJoerg Wunsch * ARE DISCLAIMED. IN NO EVENT SHALL DAVID L. NUGENT OR CONTRIBUTORS BE LIABLE 18d6f907dcSJoerg Wunsch * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19d6f907dcSJoerg Wunsch * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20d6f907dcSJoerg Wunsch * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21d6f907dcSJoerg Wunsch * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22d6f907dcSJoerg Wunsch * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23d6f907dcSJoerg Wunsch * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24d6f907dcSJoerg Wunsch * SUCH DAMAGE. 25d6f907dcSJoerg Wunsch */ 26d6f907dcSJoerg Wunsch 271dcc6ec7SPhilippe Charnier #ifndef lint 281dcc6ec7SPhilippe Charnier static const char rcsid[] = 2997d92980SPeter Wemm "$FreeBSD$"; 301dcc6ec7SPhilippe Charnier #endif /* not lint */ 311dcc6ec7SPhilippe Charnier 321dcc6ec7SPhilippe Charnier #include <err.h> 335e91a8acSNate Williams #include <fcntl.h> 34e7161f36SAndrey A. Chernov #include <locale.h> 35f1d684faSDavid Nugent #include <paths.h> 362cc63cd1SBaptiste Daroussin #include <stdbool.h> 37f1d684faSDavid Nugent #include <sys/wait.h> 385f12594aSDavid Nugent #include "pw.h" 39d6f907dcSJoerg Wunsch 402399cd14SDavid Nugent const char *Modes[] = { 412399cd14SDavid Nugent "add", "del", "mod", "show", "next", 422399cd14SDavid Nugent NULL}; 43d6f907dcSJoerg Wunsch const char *Which[] = {"user", "group", NULL}; 4448aee7f3SJoerg Wunsch static const char *Combo1[] = { 4548aee7f3SJoerg Wunsch "useradd", "userdel", "usermod", "usershow", "usernext", 462399cd14SDavid Nugent "lock", "unlock", 4748aee7f3SJoerg Wunsch "groupadd", "groupdel", "groupmod", "groupshow", "groupnext", 48d6f907dcSJoerg Wunsch NULL}; 4948aee7f3SJoerg Wunsch static const char *Combo2[] = { 5048aee7f3SJoerg Wunsch "adduser", "deluser", "moduser", "showuser", "nextuser", 512399cd14SDavid Nugent "lock", "unlock", 5248aee7f3SJoerg Wunsch "addgroup", "delgroup", "modgroup", "showgroup", "nextgroup", 53d6f907dcSJoerg Wunsch NULL}; 54d6f907dcSJoerg Wunsch 555f12594aSDavid Nugent struct pwf PWF = 565f12594aSDavid Nugent { 57ac72be28SBaptiste Daroussin PWF_REGULAR, 585f12594aSDavid Nugent setpwent, 595f12594aSDavid Nugent endpwent, 605f12594aSDavid Nugent getpwent, 615f12594aSDavid Nugent getpwuid, 625f12594aSDavid Nugent getpwnam, 635f12594aSDavid Nugent setgrent, 645f12594aSDavid Nugent endgrent, 655f12594aSDavid Nugent getgrent, 665f12594aSDavid Nugent getgrgid, 675f12594aSDavid Nugent getgrnam, 685f12594aSDavid Nugent 695f12594aSDavid Nugent }; 705f12594aSDavid Nugent struct pwf VPWF = 715f12594aSDavid Nugent { 72ac72be28SBaptiste Daroussin PWF_ALT, 735f12594aSDavid Nugent vsetpwent, 745f12594aSDavid Nugent vendpwent, 755f12594aSDavid Nugent vgetpwent, 765f12594aSDavid Nugent vgetpwuid, 775f12594aSDavid Nugent vgetpwnam, 785f12594aSDavid Nugent vsetgrent, 795f12594aSDavid Nugent vendgrent, 805f12594aSDavid Nugent vgetgrent, 815f12594aSDavid Nugent vgetgrgid, 825f12594aSDavid Nugent vgetgrnam, 835f12594aSDavid Nugent }; 845f12594aSDavid Nugent 85*d2d022b9SBaptiste Daroussin static int (*cmdfunc[W_NUM][M_NUM])(int argc, char **argv, char *_name) = { 86*d2d022b9SBaptiste Daroussin { /* user */ 87*d2d022b9SBaptiste Daroussin pw_user_add, 88*d2d022b9SBaptiste Daroussin pw_user_del, 89*d2d022b9SBaptiste Daroussin pw_user_mod, 90*d2d022b9SBaptiste Daroussin pw_user_show, 91*d2d022b9SBaptiste Daroussin pw_user_next, 92*d2d022b9SBaptiste Daroussin pw_user_lock, 93*d2d022b9SBaptiste Daroussin pw_user_unlock, 94*d2d022b9SBaptiste Daroussin }, 95*d2d022b9SBaptiste Daroussin { /* group */ 96*d2d022b9SBaptiste Daroussin pw_group_add, 97*d2d022b9SBaptiste Daroussin pw_group_del, 98*d2d022b9SBaptiste Daroussin pw_group_mod, 99*d2d022b9SBaptiste Daroussin pw_group_show, 100*d2d022b9SBaptiste Daroussin pw_group_next, 101*d2d022b9SBaptiste Daroussin } 102*d2d022b9SBaptiste Daroussin }; 1032cc63cd1SBaptiste Daroussin 104*d2d022b9SBaptiste Daroussin struct pwconf conf; 105d6f907dcSJoerg Wunsch 106d6f907dcSJoerg Wunsch static int getindex(const char *words[], const char *word); 107d6f907dcSJoerg Wunsch static void cmdhelp(int mode, int which); 108d6f907dcSJoerg Wunsch 109d6f907dcSJoerg Wunsch int 110d6f907dcSJoerg Wunsch main(int argc, char *argv[]) 111d6f907dcSJoerg Wunsch { 112*d2d022b9SBaptiste Daroussin int mode = -1, which = -1, tmp; 11390edef4fSBaptiste Daroussin struct stat st; 114*d2d022b9SBaptiste Daroussin char arg, *arg1; 11582a3c75aSBaptiste Daroussin bool relocated, nis; 116d6f907dcSJoerg Wunsch 117*d2d022b9SBaptiste Daroussin arg1 = NULL; 11882a3c75aSBaptiste Daroussin relocated = nis = false; 119bbe09b2eSBaptiste Daroussin memset(&conf, 0, sizeof(conf)); 12065730d93SBaptiste Daroussin strlcpy(conf.rootdir, "/", sizeof(conf.rootdir)); 1212cc63cd1SBaptiste Daroussin strlcpy(conf.etcpath, _PATH_PWD, sizeof(conf.etcpath)); 12211621f96SBaptiste Daroussin conf.fd = -1; 123a70fbf7eSBaptiste Daroussin conf.checkduplicate = true; 1242cc63cd1SBaptiste Daroussin 125*d2d022b9SBaptiste Daroussin setlocale(LC_ALL, ""); 126e7161f36SAndrey A. Chernov 127d6f907dcSJoerg Wunsch /* 128d6f907dcSJoerg Wunsch * Break off the first couple of words to determine what exactly 129d6f907dcSJoerg Wunsch * we're being asked to do 130d6f907dcSJoerg Wunsch */ 1315f12594aSDavid Nugent while (argc > 1) { 1325f12594aSDavid Nugent if (*argv[1] == '-') { 1335f12594aSDavid Nugent /* 1345f12594aSDavid Nugent * Special case, allow pw -V<dir> <operation> [args] for scripts etc. 1355f12594aSDavid Nugent */ 136ac72be28SBaptiste Daroussin arg = argv[1][1]; 137ac72be28SBaptiste Daroussin if (arg == 'V' || arg == 'R') { 1382cc63cd1SBaptiste Daroussin if (relocated) 1392cc63cd1SBaptiste Daroussin errx(EXIT_FAILURE, "Both '-R' and '-V' " 1402cc63cd1SBaptiste Daroussin "specified, only one accepted"); 1412cc63cd1SBaptiste Daroussin relocated = true; 1425f12594aSDavid Nugent optarg = &argv[1][2]; 1435f12594aSDavid Nugent if (*optarg == '\0') { 14490edef4fSBaptiste Daroussin if (stat(argv[2], &st) != 0) 14590edef4fSBaptiste Daroussin errx(EX_OSFILE, \ 14690edef4fSBaptiste Daroussin "no such directory `%s'", 14790edef4fSBaptiste Daroussin argv[2]); 14890edef4fSBaptiste Daroussin if (!S_ISDIR(st.st_mode)) 14990edef4fSBaptiste Daroussin errx(EX_OSFILE, "`%s' not a " 15090edef4fSBaptiste Daroussin "directory", argv[2]); 1515f12594aSDavid Nugent optarg = argv[2]; 1525f12594aSDavid Nugent ++argv; 1535f12594aSDavid Nugent --argc; 1545f12594aSDavid Nugent } 1552cc63cd1SBaptiste Daroussin memcpy(&PWF, &VPWF, sizeof PWF); 1562cc63cd1SBaptiste Daroussin if (arg == 'R') { 1572cc63cd1SBaptiste Daroussin strlcpy(conf.rootdir, optarg, 1582cc63cd1SBaptiste Daroussin sizeof(conf.rootdir)); 1592cc63cd1SBaptiste Daroussin PWF._altdir = PWF_ROOTDIR; 1602cc63cd1SBaptiste Daroussin } 1612cc63cd1SBaptiste Daroussin snprintf(conf.etcpath, sizeof(conf.etcpath), 1622cc63cd1SBaptiste Daroussin "%s%s", optarg, arg == 'R' ? "/etc" : ""); 163e3921b27SDavid Nugent } else 1645f12594aSDavid Nugent break; 1655f12594aSDavid Nugent } 166c4e667b9SDavid Nugent else if (mode == -1 && (tmp = getindex(Modes, argv[1])) != -1) 167d6f907dcSJoerg Wunsch mode = tmp; 168c4e667b9SDavid Nugent else if (which == -1 && (tmp = getindex(Which, argv[1])) != -1) 169d6f907dcSJoerg Wunsch which = tmp; 170c4e667b9SDavid Nugent else if ((mode == -1 && which == -1) && 171c4e667b9SDavid Nugent ((tmp = getindex(Combo1, argv[1])) != -1 || 172c4e667b9SDavid Nugent (tmp = getindex(Combo2, argv[1])) != -1)) { 173d6f907dcSJoerg Wunsch which = tmp / M_NUM; 174d6f907dcSJoerg Wunsch mode = tmp % M_NUM; 175c4e667b9SDavid Nugent } else if (strcmp(argv[1], "help") == 0 && argv[2] == NULL) 176d6f907dcSJoerg Wunsch cmdhelp(mode, which); 177*d2d022b9SBaptiste Daroussin else if (which != -1 && mode != -1) 178*d2d022b9SBaptiste Daroussin arg1 = argv[1]; 179*d2d022b9SBaptiste Daroussin else 1801dcc6ec7SPhilippe Charnier errx(EX_USAGE, "unknown keyword `%s'", argv[1]); 181d6f907dcSJoerg Wunsch ++argv; 182d6f907dcSJoerg Wunsch --argc; 183d6f907dcSJoerg Wunsch } 184d6f907dcSJoerg Wunsch 185d6f907dcSJoerg Wunsch /* 186d6f907dcSJoerg Wunsch * Bail out unless the user is specific! 187d6f907dcSJoerg Wunsch */ 188d6f907dcSJoerg Wunsch if (mode == -1 || which == -1) 189d6f907dcSJoerg Wunsch cmdhelp(mode, which); 190d6f907dcSJoerg Wunsch 19165730d93SBaptiste Daroussin conf.rootfd = open(conf.rootdir, O_DIRECTORY|O_CLOEXEC); 19265730d93SBaptiste Daroussin if (conf.rootfd == -1) 19365730d93SBaptiste Daroussin errx(EXIT_FAILURE, "Unable to open '%s'", conf.rootdir); 194d6f907dcSJoerg Wunsch 195*d2d022b9SBaptiste Daroussin return (cmdfunc[which][mode](argc, argv, arg1)); 196d6f907dcSJoerg Wunsch } 197d6f907dcSJoerg Wunsch 1985e91a8acSNate Williams 199d6f907dcSJoerg Wunsch static int 200d6f907dcSJoerg Wunsch getindex(const char *words[], const char *word) 201d6f907dcSJoerg Wunsch { 202d6f907dcSJoerg Wunsch int i = 0; 203d6f907dcSJoerg Wunsch 204d6f907dcSJoerg Wunsch while (words[i]) { 205d6f907dcSJoerg Wunsch if (strcmp(words[i], word) == 0) 206*d2d022b9SBaptiste Daroussin return (i); 207d6f907dcSJoerg Wunsch i++; 208d6f907dcSJoerg Wunsch } 209*d2d022b9SBaptiste Daroussin return (-1); 210d6f907dcSJoerg Wunsch } 211d6f907dcSJoerg Wunsch 212d6f907dcSJoerg Wunsch 213d6f907dcSJoerg Wunsch /* 214d6f907dcSJoerg Wunsch * This is probably an overkill for a cmdline help system, but it reflects 215d6f907dcSJoerg Wunsch * the complexity of the command line. 216d6f907dcSJoerg Wunsch */ 217d6f907dcSJoerg Wunsch 218d6f907dcSJoerg Wunsch static void 219d6f907dcSJoerg Wunsch cmdhelp(int mode, int which) 220d6f907dcSJoerg Wunsch { 221d6f907dcSJoerg Wunsch if (which == -1) 2222399cd14SDavid Nugent fprintf(stderr, "usage:\n pw [user|group|lock|unlock] [add|del|mod|show|next] [help|switches/values]\n"); 223d6f907dcSJoerg Wunsch else if (mode == -1) 2242399cd14SDavid Nugent fprintf(stderr, "usage:\n pw %s [add|del|mod|show|next] [help|switches/values]\n", Which[which]); 225d6f907dcSJoerg Wunsch else { 226d6f907dcSJoerg Wunsch 227d6f907dcSJoerg Wunsch /* 228d6f907dcSJoerg Wunsch * We need to give mode specific help 229d6f907dcSJoerg Wunsch */ 230d6f907dcSJoerg Wunsch static const char *help[W_NUM][M_NUM] = 231d6f907dcSJoerg Wunsch { 232d6f907dcSJoerg Wunsch { 2331dcc6ec7SPhilippe Charnier "usage: pw useradd [name] [switches]\n" 2345f12594aSDavid Nugent "\t-V etcdir alternate /etc location\n" 235ac72be28SBaptiste Daroussin "\t-R rootir alternate root directory\n" 236d6f907dcSJoerg Wunsch "\t-C config configuration file\n" 237d6f907dcSJoerg Wunsch "\t-q quiet operation\n" 238d6f907dcSJoerg Wunsch " Adding users:\n" 239d6f907dcSJoerg Wunsch "\t-n name login name\n" 240d6f907dcSJoerg Wunsch "\t-u uid user id\n" 241d6f907dcSJoerg Wunsch "\t-c comment user name/comment\n" 242d6f907dcSJoerg Wunsch "\t-d directory home directory\n" 243d6f907dcSJoerg Wunsch "\t-e date account expiry date\n" 244d6f907dcSJoerg Wunsch "\t-p date password expiry date\n" 245d6f907dcSJoerg Wunsch "\t-g grp initial group\n" 246d6f907dcSJoerg Wunsch "\t-G grp1,grp2 additional groups\n" 247d6f907dcSJoerg Wunsch "\t-m [ -k dir ] create and set up home\n" 2481dd634b0SLukas Ertl "\t-M mode home directory permissions\n" 249d6f907dcSJoerg Wunsch "\t-s shell name of login shell\n" 250d6f907dcSJoerg Wunsch "\t-o duplicate uid ok\n" 251d6f907dcSJoerg Wunsch "\t-L class user class\n" 252d6f907dcSJoerg Wunsch "\t-h fd read password on fd\n" 25387d6b5caSIan Dowse "\t-H fd read encrypted password on fd\n" 254f1d684faSDavid Nugent "\t-Y update NIS maps\n" 25548aee7f3SJoerg Wunsch "\t-N no update\n" 256d6f907dcSJoerg Wunsch " Setting defaults:\n" 2575f12594aSDavid Nugent "\t-V etcdir alternate /etc location\n" 258ac72be28SBaptiste Daroussin "\t-R rootir alternate root directory\n" 259d6f907dcSJoerg Wunsch "\t-D set user defaults\n" 260d6f907dcSJoerg Wunsch "\t-b dir default home root dir\n" 261d6f907dcSJoerg Wunsch "\t-e period default expiry period\n" 262d6f907dcSJoerg Wunsch "\t-p period default password change period\n" 263d6f907dcSJoerg Wunsch "\t-g group default group\n" 264d6f907dcSJoerg Wunsch "\t-G grp1,grp2 additional groups\n" 265d6f907dcSJoerg Wunsch "\t-L class default user class\n" 266d6f907dcSJoerg Wunsch "\t-k dir default home skeleton\n" 26785204142SLukas Ertl "\t-M mode home directory permissions\n" 268d6f907dcSJoerg Wunsch "\t-u min,max set min,max uids\n" 269d6f907dcSJoerg Wunsch "\t-i min,max set min,max gids\n" 270d6f907dcSJoerg Wunsch "\t-w method set default password method\n" 271f1d684faSDavid Nugent "\t-s shell default shell\n" 272f1d684faSDavid Nugent "\t-y path set NIS passwd file path\n", 2731dcc6ec7SPhilippe Charnier "usage: pw userdel [uid|name] [switches]\n" 2745f12594aSDavid Nugent "\t-V etcdir alternate /etc location\n" 275ac72be28SBaptiste Daroussin "\t-R rootir alternate root directory\n" 276d6f907dcSJoerg Wunsch "\t-n name login name\n" 277d6f907dcSJoerg Wunsch "\t-u uid user id\n" 278f1d684faSDavid Nugent "\t-Y update NIS maps\n" 279*d2d022b9SBaptiste Daroussin "\t-y path set NIS passwd file path\n" 280d6f907dcSJoerg Wunsch "\t-r remove home & contents\n", 2811dcc6ec7SPhilippe Charnier "usage: pw usermod [uid|name] [switches]\n" 2825f12594aSDavid Nugent "\t-V etcdir alternate /etc location\n" 283ac72be28SBaptiste Daroussin "\t-R rootir alternate root directory\n" 284d6f907dcSJoerg Wunsch "\t-C config configuration file\n" 285d6f907dcSJoerg Wunsch "\t-q quiet operation\n" 286d6f907dcSJoerg Wunsch "\t-F force add if no user\n" 287d6f907dcSJoerg Wunsch "\t-n name login name\n" 288d6f907dcSJoerg Wunsch "\t-u uid user id\n" 289d6f907dcSJoerg Wunsch "\t-c comment user name/comment\n" 290d6f907dcSJoerg Wunsch "\t-d directory home directory\n" 291d6f907dcSJoerg Wunsch "\t-e date account expiry date\n" 292d6f907dcSJoerg Wunsch "\t-p date password expiry date\n" 293d6f907dcSJoerg Wunsch "\t-g grp initial group\n" 294d6f907dcSJoerg Wunsch "\t-G grp1,grp2 additional groups\n" 295d6f907dcSJoerg Wunsch "\t-l name new login name\n" 296d6f907dcSJoerg Wunsch "\t-L class user class\n" 297d6f907dcSJoerg Wunsch "\t-m [ -k dir ] create and set up home\n" 2981dd634b0SLukas Ertl "\t-M mode home directory permissions\n" 299d6f907dcSJoerg Wunsch "\t-s shell name of login shell\n" 30048aee7f3SJoerg Wunsch "\t-w method set new password using method\n" 30148aee7f3SJoerg Wunsch "\t-h fd read password on fd\n" 30287d6b5caSIan Dowse "\t-H fd read encrypted password on fd\n" 303f1d684faSDavid Nugent "\t-Y update NIS maps\n" 304*d2d022b9SBaptiste Daroussin "\t-y path set NIS passwd file path\n" 30548aee7f3SJoerg Wunsch "\t-N no update\n", 3061dcc6ec7SPhilippe Charnier "usage: pw usershow [uid|name] [switches]\n" 3075f12594aSDavid Nugent "\t-V etcdir alternate /etc location\n" 308ac72be28SBaptiste Daroussin "\t-R rootir alternate root directory\n" 309d6f907dcSJoerg Wunsch "\t-n name login name\n" 310d6f907dcSJoerg Wunsch "\t-u uid user id\n" 311d6f907dcSJoerg Wunsch "\t-F force print\n" 31248aee7f3SJoerg Wunsch "\t-P prettier format\n" 313f3522722SDavid Nugent "\t-a print all users\n" 314f3522722SDavid Nugent "\t-7 print in v7 format\n", 3151dcc6ec7SPhilippe Charnier "usage: pw usernext [switches]\n" 3165f12594aSDavid Nugent "\t-V etcdir alternate /etc location\n" 317ac72be28SBaptiste Daroussin "\t-R rootir alternate root directory\n" 3183bfc59e8SBaptiste Daroussin "\t-C config configuration file\n" 3193bfc59e8SBaptiste Daroussin "\t-q quiet operation\n", 320ed6fd55aSDima Dorfman "usage pw: lock [switches]\n" 321ed6fd55aSDima Dorfman "\t-V etcdir alternate /etc locations\n" 322ed6fd55aSDima Dorfman "\t-C config configuration file\n" 323ed6fd55aSDima Dorfman "\t-q quiet operation\n", 324ed6fd55aSDima Dorfman "usage pw: unlock [switches]\n" 325ed6fd55aSDima Dorfman "\t-V etcdir alternate /etc locations\n" 326ed6fd55aSDima Dorfman "\t-C config configuration file\n" 327ed6fd55aSDima Dorfman "\t-q quiet operation\n" 328d6f907dcSJoerg Wunsch }, 329d6f907dcSJoerg Wunsch { 3301dcc6ec7SPhilippe Charnier "usage: pw groupadd [group|gid] [switches]\n" 3315f12594aSDavid Nugent "\t-V etcdir alternate /etc location\n" 332ac72be28SBaptiste Daroussin "\t-R rootir alternate root directory\n" 333d6f907dcSJoerg Wunsch "\t-C config configuration file\n" 334d6f907dcSJoerg Wunsch "\t-q quiet operation\n" 335d6f907dcSJoerg Wunsch "\t-n group group name\n" 336d6f907dcSJoerg Wunsch "\t-g gid group id\n" 33748aee7f3SJoerg Wunsch "\t-M usr1,usr2 add users as group members\n" 33848aee7f3SJoerg Wunsch "\t-o duplicate gid ok\n" 339f1d684faSDavid Nugent "\t-Y update NIS maps\n" 34048aee7f3SJoerg Wunsch "\t-N no update\n", 3411dcc6ec7SPhilippe Charnier "usage: pw groupdel [group|gid] [switches]\n" 3425f12594aSDavid Nugent "\t-V etcdir alternate /etc location\n" 343ac72be28SBaptiste Daroussin "\t-R rootir alternate root directory\n" 344d6f907dcSJoerg Wunsch "\t-n name group name\n" 345f1d684faSDavid Nugent "\t-g gid group id\n" 346f1d684faSDavid Nugent "\t-Y update NIS maps\n", 3471dcc6ec7SPhilippe Charnier "usage: pw groupmod [group|gid] [switches]\n" 3485f12594aSDavid Nugent "\t-V etcdir alternate /etc location\n" 349ac72be28SBaptiste Daroussin "\t-R rootir alternate root directory\n" 350d6f907dcSJoerg Wunsch "\t-C config configuration file\n" 351d6f907dcSJoerg Wunsch "\t-q quiet operation\n" 352d6f907dcSJoerg Wunsch "\t-F force add if not exists\n" 353d6f907dcSJoerg Wunsch "\t-n name group name\n" 354d6f907dcSJoerg Wunsch "\t-g gid group id\n" 35548aee7f3SJoerg Wunsch "\t-M usr1,usr2 replaces users as group members\n" 35648aee7f3SJoerg Wunsch "\t-m usr1,usr2 add users as group members\n" 357bc991a6dSSean Farley "\t-d usr1,usr2 delete users as group members\n" 35848aee7f3SJoerg Wunsch "\t-l name new group name\n" 359f1d684faSDavid Nugent "\t-Y update NIS maps\n" 36048aee7f3SJoerg Wunsch "\t-N no update\n", 3611dcc6ec7SPhilippe Charnier "usage: pw groupshow [group|gid] [switches]\n" 3625f12594aSDavid Nugent "\t-V etcdir alternate /etc location\n" 363ac72be28SBaptiste Daroussin "\t-R rootir alternate root directory\n" 364d6f907dcSJoerg Wunsch "\t-n name group name\n" 365d6f907dcSJoerg Wunsch "\t-g gid group id\n" 366d6f907dcSJoerg Wunsch "\t-F force print\n" 36748aee7f3SJoerg Wunsch "\t-P prettier format\n" 36848aee7f3SJoerg Wunsch "\t-a print all accounting groups\n", 3691dcc6ec7SPhilippe Charnier "usage: pw groupnext [switches]\n" 3705f12594aSDavid Nugent "\t-V etcdir alternate /etc location\n" 371ac72be28SBaptiste Daroussin "\t-R rootir alternate root directory\n" 37248aee7f3SJoerg Wunsch "\t-C config configuration file\n" 3733bfc59e8SBaptiste Daroussin "\t-q quiet operation\n" 374d6f907dcSJoerg Wunsch } 375d6f907dcSJoerg Wunsch }; 376d6f907dcSJoerg Wunsch 377cab0fb4eSKris Kennaway fprintf(stderr, "%s", help[which][mode]); 378d6f907dcSJoerg Wunsch } 37948aee7f3SJoerg Wunsch exit(EXIT_FAILURE); 380d6f907dcSJoerg Wunsch } 381