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> 36f1d684faSDavid Nugent #include <sys/wait.h> 375f12594aSDavid Nugent #include "pw.h" 38d6f907dcSJoerg Wunsch 39923dc0b2SDavid Nugent #if !defined(_PATH_YP) 40923dc0b2SDavid Nugent #define _PATH_YP "/var/yp/" 41923dc0b2SDavid Nugent #endif 422399cd14SDavid Nugent const char *Modes[] = { 432399cd14SDavid Nugent "add", "del", "mod", "show", "next", 442399cd14SDavid Nugent NULL}; 45d6f907dcSJoerg Wunsch const char *Which[] = {"user", "group", NULL}; 4648aee7f3SJoerg Wunsch static const char *Combo1[] = { 4748aee7f3SJoerg Wunsch "useradd", "userdel", "usermod", "usershow", "usernext", 482399cd14SDavid Nugent "lock", "unlock", 4948aee7f3SJoerg Wunsch "groupadd", "groupdel", "groupmod", "groupshow", "groupnext", 50d6f907dcSJoerg Wunsch NULL}; 5148aee7f3SJoerg Wunsch static const char *Combo2[] = { 5248aee7f3SJoerg Wunsch "adduser", "deluser", "moduser", "showuser", "nextuser", 532399cd14SDavid Nugent "lock", "unlock", 5448aee7f3SJoerg Wunsch "addgroup", "delgroup", "modgroup", "showgroup", "nextgroup", 55d6f907dcSJoerg Wunsch NULL}; 56d6f907dcSJoerg Wunsch 575f12594aSDavid Nugent struct pwf PWF = 585f12594aSDavid Nugent { 595f12594aSDavid Nugent 0, 605f12594aSDavid Nugent setpwent, 615f12594aSDavid Nugent endpwent, 625f12594aSDavid Nugent getpwent, 635f12594aSDavid Nugent getpwuid, 645f12594aSDavid Nugent getpwnam, 655f12594aSDavid Nugent pwdb, 665f12594aSDavid Nugent setgrent, 675f12594aSDavid Nugent endgrent, 685f12594aSDavid Nugent getgrent, 695f12594aSDavid Nugent getgrgid, 705f12594aSDavid Nugent getgrnam, 715f12594aSDavid Nugent grdb 725f12594aSDavid Nugent 735f12594aSDavid Nugent }; 745f12594aSDavid Nugent struct pwf VPWF = 755f12594aSDavid Nugent { 765f12594aSDavid Nugent 1, 775f12594aSDavid Nugent vsetpwent, 785f12594aSDavid Nugent vendpwent, 795f12594aSDavid Nugent vgetpwent, 805f12594aSDavid Nugent vgetpwuid, 815f12594aSDavid Nugent vgetpwnam, 825f12594aSDavid Nugent vpwdb, 835f12594aSDavid Nugent vsetgrent, 845f12594aSDavid Nugent vendgrent, 855f12594aSDavid Nugent vgetgrent, 865f12594aSDavid Nugent vgetgrgid, 875f12594aSDavid Nugent vgetgrnam, 885f12594aSDavid Nugent vgrdb 895f12594aSDavid Nugent }; 905f12594aSDavid Nugent 91d6f907dcSJoerg Wunsch static struct cargs arglist; 92d6f907dcSJoerg Wunsch 93d6f907dcSJoerg Wunsch static int getindex(const char *words[], const char *word); 94d6f907dcSJoerg Wunsch static void cmdhelp(int mode, int which); 95d6f907dcSJoerg Wunsch 96d6f907dcSJoerg Wunsch 97d6f907dcSJoerg Wunsch int 98d6f907dcSJoerg Wunsch main(int argc, char *argv[]) 99d6f907dcSJoerg Wunsch { 100d6f907dcSJoerg Wunsch int ch; 101d6f907dcSJoerg Wunsch int mode = -1; 102d6f907dcSJoerg Wunsch int which = -1; 1035f12594aSDavid Nugent char *config = NULL; 104d6f907dcSJoerg Wunsch struct userconf *cnf; 105d6f907dcSJoerg Wunsch 106d6f907dcSJoerg Wunsch static const char *opts[W_NUM][M_NUM] = 107d6f907dcSJoerg Wunsch { 10848aee7f3SJoerg Wunsch { /* user */ 109eebbeceeSLukas Ertl "V:C:qn:u:c:d:e:p:g:G:mM:k:s:oL:i:w:h:H:Db:NPy:Y", 110e3921b27SDavid Nugent "V:C:qn:u:rY", 111eebbeceeSLukas Ertl "V:C:qn:u:c:d:e:p:g:G:mM:l:k:s:w:L:h:H:FNPY", 112f3522722SDavid Nugent "V:C:qn:u:FPa7", 1132399cd14SDavid Nugent "V:C:q", 1142399cd14SDavid Nugent "V:C:q", 115e3921b27SDavid Nugent "V:C:q" 11648aee7f3SJoerg Wunsch }, 11748aee7f3SJoerg Wunsch { /* grp */ 11804cfd91bSMaxim Konovalov "V:C:qn:g:h:H:M:opNPY", 119e3921b27SDavid Nugent "V:C:qn:g:Y", 120bc991a6dSSean Farley "V:C:qn:d:g:l:h:H:FM:m:NPY", 121e3921b27SDavid Nugent "V:C:qn:g:FPa", 122e3921b27SDavid Nugent "V:C:q" 12348aee7f3SJoerg Wunsch } 124d6f907dcSJoerg Wunsch }; 125d6f907dcSJoerg Wunsch 126d6f907dcSJoerg Wunsch static int (*funcs[W_NUM]) (struct userconf * _cnf, int _mode, struct cargs * _args) = 127d6f907dcSJoerg Wunsch { /* Request handlers */ 128d6f907dcSJoerg Wunsch pw_user, 129d6f907dcSJoerg Wunsch pw_group 130d6f907dcSJoerg Wunsch }; 131d6f907dcSJoerg Wunsch 132d6f907dcSJoerg Wunsch LIST_INIT(&arglist); 133d6f907dcSJoerg Wunsch 13439610c72SAndrey A. Chernov (void)setlocale(LC_ALL, ""); 135e7161f36SAndrey A. Chernov 136d6f907dcSJoerg Wunsch /* 137d6f907dcSJoerg Wunsch * Break off the first couple of words to determine what exactly 138d6f907dcSJoerg Wunsch * we're being asked to do 139d6f907dcSJoerg Wunsch */ 1405f12594aSDavid Nugent while (argc > 1) { 141d6f907dcSJoerg Wunsch int tmp; 142d6f907dcSJoerg Wunsch 1435f12594aSDavid Nugent if (*argv[1] == '-') { 1445f12594aSDavid Nugent /* 1455f12594aSDavid Nugent * Special case, allow pw -V<dir> <operation> [args] for scripts etc. 1465f12594aSDavid Nugent */ 1475f12594aSDavid Nugent if (argv[1][1] == 'V') { 1485f12594aSDavid Nugent optarg = &argv[1][2]; 1495f12594aSDavid Nugent if (*optarg == '\0') { 1505f12594aSDavid Nugent optarg = argv[2]; 1515f12594aSDavid Nugent ++argv; 1525f12594aSDavid Nugent --argc; 1535f12594aSDavid Nugent } 1545f12594aSDavid Nugent addarg(&arglist, 'V', optarg); 155e3921b27SDavid Nugent } else 1565f12594aSDavid Nugent break; 1575f12594aSDavid Nugent } 158c4e667b9SDavid Nugent else if (mode == -1 && (tmp = getindex(Modes, argv[1])) != -1) 159d6f907dcSJoerg Wunsch mode = tmp; 160c4e667b9SDavid Nugent else if (which == -1 && (tmp = getindex(Which, argv[1])) != -1) 161d6f907dcSJoerg Wunsch which = tmp; 162c4e667b9SDavid Nugent else if ((mode == -1 && which == -1) && 163c4e667b9SDavid Nugent ((tmp = getindex(Combo1, argv[1])) != -1 || 164c4e667b9SDavid Nugent (tmp = getindex(Combo2, argv[1])) != -1)) { 165d6f907dcSJoerg Wunsch which = tmp / M_NUM; 166d6f907dcSJoerg Wunsch mode = tmp % M_NUM; 167c4e667b9SDavid Nugent } else if (strcmp(argv[1], "help") == 0 && argv[2] == NULL) 168d6f907dcSJoerg Wunsch cmdhelp(mode, which); 1697291e217SDavid Nugent else if (which != -1 && mode != -1) 170d6f907dcSJoerg Wunsch addarg(&arglist, 'n', argv[1]); 171d6f907dcSJoerg Wunsch else 1721dcc6ec7SPhilippe Charnier errx(EX_USAGE, "unknown keyword `%s'", argv[1]); 173d6f907dcSJoerg Wunsch ++argv; 174d6f907dcSJoerg Wunsch --argc; 175d6f907dcSJoerg Wunsch } 176d6f907dcSJoerg Wunsch 177d6f907dcSJoerg Wunsch /* 178d6f907dcSJoerg Wunsch * Bail out unless the user is specific! 179d6f907dcSJoerg Wunsch */ 180d6f907dcSJoerg Wunsch if (mode == -1 || which == -1) 181d6f907dcSJoerg Wunsch cmdhelp(mode, which); 182d6f907dcSJoerg Wunsch 183d6f907dcSJoerg Wunsch /* 184d6f907dcSJoerg Wunsch * We know which mode we're in and what we're about to do, so now 185d6f907dcSJoerg Wunsch * let's dispatch the remaining command line args in a genric way. 186d6f907dcSJoerg Wunsch */ 187d6f907dcSJoerg Wunsch optarg = NULL; 188d6f907dcSJoerg Wunsch 189d6f907dcSJoerg Wunsch while ((ch = getopt(argc, argv, opts[which][mode])) != -1) { 190d6f907dcSJoerg Wunsch if (ch == '?') 191923dc0b2SDavid Nugent errx(EX_USAGE, "unknown switch"); 192d6f907dcSJoerg Wunsch else 193d6f907dcSJoerg Wunsch addarg(&arglist, ch, optarg); 194d6f907dcSJoerg Wunsch optarg = NULL; 195d6f907dcSJoerg Wunsch } 196d6f907dcSJoerg Wunsch 197d6f907dcSJoerg Wunsch /* 19848aee7f3SJoerg Wunsch * Must be root to attempt an update 19948aee7f3SJoerg Wunsch */ 200fa7e83d4SDavid Nugent if (geteuid() != 0 && mode != M_PRINT && mode != M_NEXT && getarg(&arglist, 'N')==NULL) 2011dcc6ec7SPhilippe Charnier errx(EX_NOPERM, "you must be root to run this program"); 20248aee7f3SJoerg Wunsch 20348aee7f3SJoerg Wunsch /* 204d6f907dcSJoerg Wunsch * We should immediately look for the -q 'quiet' switch so that we 205d6f907dcSJoerg Wunsch * don't bother with extraneous errors 206d6f907dcSJoerg Wunsch */ 207d6f907dcSJoerg Wunsch if (getarg(&arglist, 'q') != NULL) 2081a37aa56SDavid E. O'Brien freopen(_PATH_DEVNULL, "w", stderr); 209d6f907dcSJoerg Wunsch 210d6f907dcSJoerg Wunsch /* 2115f12594aSDavid Nugent * Set our base working path if not overridden 2125f12594aSDavid Nugent */ 2135f12594aSDavid Nugent 2145f12594aSDavid Nugent config = getarg(&arglist, 'C') ? getarg(&arglist, 'C')->val : NULL; 2155f12594aSDavid Nugent 2165f12594aSDavid Nugent if (getarg(&arglist, 'V') != NULL) { 2175f12594aSDavid Nugent char * etcpath = getarg(&arglist, 'V')->val; 2185f12594aSDavid Nugent if (*etcpath) { 2195f12594aSDavid Nugent if (config == NULL) { /* Only override config location if -C not specified */ 2205f12594aSDavid Nugent config = malloc(MAXPATHLEN); 2215f12594aSDavid Nugent snprintf(config, MAXPATHLEN, "%s/pw.conf", etcpath); 2225f12594aSDavid Nugent } 2235f12594aSDavid Nugent memcpy(&PWF, &VPWF, sizeof PWF); 2245f12594aSDavid Nugent setpwdir(etcpath); 2255f12594aSDavid Nugent setgrdir(etcpath); 2265f12594aSDavid Nugent } 2275f12594aSDavid Nugent } 2285f12594aSDavid Nugent 2295f12594aSDavid Nugent /* 230d6f907dcSJoerg Wunsch * Now, let's do the common initialisation 231d6f907dcSJoerg Wunsch */ 2325f12594aSDavid Nugent cnf = read_userconfig(config); 2335e91a8acSNate Williams 234f1d684faSDavid Nugent ch = funcs[which] (cnf, mode, &arglist); 235f1d684faSDavid Nugent 236f1d684faSDavid Nugent /* 237f1d684faSDavid Nugent * If everything went ok, and we've been asked to update 238f1d684faSDavid Nugent * the NIS maps, then do it now 239f1d684faSDavid Nugent */ 240f1d684faSDavid Nugent if (ch == EXIT_SUCCESS && getarg(&arglist, 'Y') != NULL) { 241f1d684faSDavid Nugent pid_t pid; 242f1d684faSDavid Nugent 243f1d684faSDavid Nugent fflush(NULL); 244f1d684faSDavid Nugent if (chdir(_PATH_YP) == -1) 2451dcc6ec7SPhilippe Charnier warn("chdir(" _PATH_YP ")"); 246f1d684faSDavid Nugent else if ((pid = fork()) == -1) 2471dcc6ec7SPhilippe Charnier warn("fork()"); 248f1d684faSDavid Nugent else if (pid == 0) { 249f1d684faSDavid Nugent /* Is make anywhere else? */ 2507bc6d015SBrian Somers execlp("/usr/bin/make", "make", (char *)NULL); 251f1d684faSDavid Nugent _exit(1); 252f1d684faSDavid Nugent } else { 253f1d684faSDavid Nugent int i; 254f1d684faSDavid Nugent waitpid(pid, &i, 0); 255f1d684faSDavid Nugent if ((i = WEXITSTATUS(i)) != 0) 2561dcc6ec7SPhilippe Charnier errx(ch, "make exited with status %d", i); 257f1d684faSDavid Nugent else 258f1d684faSDavid Nugent pw_log(cnf, mode, which, "NIS maps updated"); 259f1d684faSDavid Nugent } 260f1d684faSDavid Nugent } 261f1d684faSDavid Nugent return ch; 262d6f907dcSJoerg Wunsch } 263d6f907dcSJoerg Wunsch 2645e91a8acSNate Williams 265d6f907dcSJoerg Wunsch static int 266d6f907dcSJoerg Wunsch getindex(const char *words[], const char *word) 267d6f907dcSJoerg Wunsch { 268d6f907dcSJoerg Wunsch int i = 0; 269d6f907dcSJoerg Wunsch 270d6f907dcSJoerg Wunsch while (words[i]) { 271d6f907dcSJoerg Wunsch if (strcmp(words[i], word) == 0) 272d6f907dcSJoerg Wunsch return i; 273d6f907dcSJoerg Wunsch i++; 274d6f907dcSJoerg Wunsch } 275d6f907dcSJoerg Wunsch return -1; 276d6f907dcSJoerg Wunsch } 277d6f907dcSJoerg Wunsch 278d6f907dcSJoerg Wunsch 279d6f907dcSJoerg Wunsch /* 280d6f907dcSJoerg Wunsch * This is probably an overkill for a cmdline help system, but it reflects 281d6f907dcSJoerg Wunsch * the complexity of the command line. 282d6f907dcSJoerg Wunsch */ 283d6f907dcSJoerg Wunsch 284d6f907dcSJoerg Wunsch static void 285d6f907dcSJoerg Wunsch cmdhelp(int mode, int which) 286d6f907dcSJoerg Wunsch { 287d6f907dcSJoerg Wunsch if (which == -1) 2882399cd14SDavid Nugent fprintf(stderr, "usage:\n pw [user|group|lock|unlock] [add|del|mod|show|next] [help|switches/values]\n"); 289d6f907dcSJoerg Wunsch else if (mode == -1) 2902399cd14SDavid Nugent fprintf(stderr, "usage:\n pw %s [add|del|mod|show|next] [help|switches/values]\n", Which[which]); 291d6f907dcSJoerg Wunsch else { 292d6f907dcSJoerg Wunsch 293d6f907dcSJoerg Wunsch /* 294d6f907dcSJoerg Wunsch * We need to give mode specific help 295d6f907dcSJoerg Wunsch */ 296d6f907dcSJoerg Wunsch static const char *help[W_NUM][M_NUM] = 297d6f907dcSJoerg Wunsch { 298d6f907dcSJoerg Wunsch { 2991dcc6ec7SPhilippe Charnier "usage: pw useradd [name] [switches]\n" 3005f12594aSDavid Nugent "\t-V etcdir alternate /etc location\n" 301d6f907dcSJoerg Wunsch "\t-C config configuration file\n" 302d6f907dcSJoerg Wunsch "\t-q quiet operation\n" 303d6f907dcSJoerg Wunsch " Adding users:\n" 304d6f907dcSJoerg Wunsch "\t-n name login name\n" 305d6f907dcSJoerg Wunsch "\t-u uid user id\n" 306d6f907dcSJoerg Wunsch "\t-c comment user name/comment\n" 307d6f907dcSJoerg Wunsch "\t-d directory home directory\n" 308d6f907dcSJoerg Wunsch "\t-e date account expiry date\n" 309d6f907dcSJoerg Wunsch "\t-p date password expiry date\n" 310d6f907dcSJoerg Wunsch "\t-g grp initial group\n" 311d6f907dcSJoerg Wunsch "\t-G grp1,grp2 additional groups\n" 312d6f907dcSJoerg Wunsch "\t-m [ -k dir ] create and set up home\n" 3131dd634b0SLukas Ertl "\t-M mode home directory permissions\n" 314d6f907dcSJoerg Wunsch "\t-s shell name of login shell\n" 315d6f907dcSJoerg Wunsch "\t-o duplicate uid ok\n" 316d6f907dcSJoerg Wunsch "\t-L class user class\n" 317d6f907dcSJoerg Wunsch "\t-h fd read password on fd\n" 31887d6b5caSIan Dowse "\t-H fd read encrypted password on fd\n" 319f1d684faSDavid Nugent "\t-Y update NIS maps\n" 32048aee7f3SJoerg Wunsch "\t-N no update\n" 321d6f907dcSJoerg Wunsch " Setting defaults:\n" 3225f12594aSDavid Nugent "\t-V etcdir alternate /etc location\n" 323d6f907dcSJoerg Wunsch "\t-D set user defaults\n" 324d6f907dcSJoerg Wunsch "\t-b dir default home root dir\n" 325d6f907dcSJoerg Wunsch "\t-e period default expiry period\n" 326d6f907dcSJoerg Wunsch "\t-p period default password change period\n" 327d6f907dcSJoerg Wunsch "\t-g group default group\n" 328d6f907dcSJoerg Wunsch "\t-G grp1,grp2 additional groups\n" 329d6f907dcSJoerg Wunsch "\t-L class default user class\n" 330d6f907dcSJoerg Wunsch "\t-k dir default home skeleton\n" 33185204142SLukas Ertl "\t-M mode home directory permissions\n" 332d6f907dcSJoerg Wunsch "\t-u min,max set min,max uids\n" 333d6f907dcSJoerg Wunsch "\t-i min,max set min,max gids\n" 334d6f907dcSJoerg Wunsch "\t-w method set default password method\n" 335f1d684faSDavid Nugent "\t-s shell default shell\n" 336f1d684faSDavid Nugent "\t-y path set NIS passwd file path\n", 3371dcc6ec7SPhilippe Charnier "usage: pw userdel [uid|name] [switches]\n" 3385f12594aSDavid Nugent "\t-V etcdir alternate /etc location\n" 339d6f907dcSJoerg Wunsch "\t-n name login name\n" 340d6f907dcSJoerg Wunsch "\t-u uid user id\n" 341f1d684faSDavid Nugent "\t-Y update NIS maps\n" 342d6f907dcSJoerg Wunsch "\t-r remove home & contents\n", 3431dcc6ec7SPhilippe Charnier "usage: pw usermod [uid|name] [switches]\n" 3445f12594aSDavid Nugent "\t-V etcdir alternate /etc location\n" 345d6f907dcSJoerg Wunsch "\t-C config configuration file\n" 346d6f907dcSJoerg Wunsch "\t-q quiet operation\n" 347d6f907dcSJoerg Wunsch "\t-F force add if no user\n" 348d6f907dcSJoerg Wunsch "\t-n name login name\n" 349d6f907dcSJoerg Wunsch "\t-u uid user id\n" 350d6f907dcSJoerg Wunsch "\t-c comment user name/comment\n" 351d6f907dcSJoerg Wunsch "\t-d directory home directory\n" 352d6f907dcSJoerg Wunsch "\t-e date account expiry date\n" 353d6f907dcSJoerg Wunsch "\t-p date password expiry date\n" 354d6f907dcSJoerg Wunsch "\t-g grp initial group\n" 355d6f907dcSJoerg Wunsch "\t-G grp1,grp2 additional groups\n" 356d6f907dcSJoerg Wunsch "\t-l name new login name\n" 357d6f907dcSJoerg Wunsch "\t-L class user class\n" 358d6f907dcSJoerg Wunsch "\t-m [ -k dir ] create and set up home\n" 3591dd634b0SLukas Ertl "\t-M mode home directory permissions\n" 360d6f907dcSJoerg Wunsch "\t-s shell name of login shell\n" 36148aee7f3SJoerg Wunsch "\t-w method set new password using method\n" 36248aee7f3SJoerg Wunsch "\t-h fd read password on fd\n" 36387d6b5caSIan Dowse "\t-H fd read encrypted password on fd\n" 364f1d684faSDavid Nugent "\t-Y update NIS maps\n" 36548aee7f3SJoerg Wunsch "\t-N no update\n", 3661dcc6ec7SPhilippe Charnier "usage: pw usershow [uid|name] [switches]\n" 3675f12594aSDavid Nugent "\t-V etcdir alternate /etc location\n" 368d6f907dcSJoerg Wunsch "\t-n name login name\n" 369d6f907dcSJoerg Wunsch "\t-u uid user id\n" 370d6f907dcSJoerg Wunsch "\t-F force print\n" 37148aee7f3SJoerg Wunsch "\t-P prettier format\n" 372f3522722SDavid Nugent "\t-a print all users\n" 373f3522722SDavid Nugent "\t-7 print in v7 format\n", 3741dcc6ec7SPhilippe Charnier "usage: pw usernext [switches]\n" 3755f12594aSDavid Nugent "\t-V etcdir alternate /etc location\n" 37648aee7f3SJoerg Wunsch "\t-C config configuration file\n" 377ed6fd55aSDima Dorfman "\t-q quiet operation\n", 378ed6fd55aSDima Dorfman "usage pw: lock [switches]\n" 379ed6fd55aSDima Dorfman "\t-V etcdir alternate /etc locations\n" 380ed6fd55aSDima Dorfman "\t-C config configuration file\n" 381ed6fd55aSDima Dorfman "\t-q quiet operation\n", 382ed6fd55aSDima Dorfman "usage pw: unlock [switches]\n" 383ed6fd55aSDima Dorfman "\t-V etcdir alternate /etc locations\n" 384ed6fd55aSDima Dorfman "\t-C config configuration file\n" 385ed6fd55aSDima Dorfman "\t-q quiet operation\n" 386d6f907dcSJoerg Wunsch }, 387d6f907dcSJoerg Wunsch { 3881dcc6ec7SPhilippe Charnier "usage: pw groupadd [group|gid] [switches]\n" 3895f12594aSDavid Nugent "\t-V etcdir alternate /etc location\n" 390d6f907dcSJoerg Wunsch "\t-C config configuration file\n" 391d6f907dcSJoerg Wunsch "\t-q quiet operation\n" 392d6f907dcSJoerg Wunsch "\t-n group group name\n" 393d6f907dcSJoerg Wunsch "\t-g gid group id\n" 39448aee7f3SJoerg Wunsch "\t-M usr1,usr2 add users as group members\n" 39548aee7f3SJoerg Wunsch "\t-o duplicate gid ok\n" 396f1d684faSDavid Nugent "\t-Y update NIS maps\n" 39748aee7f3SJoerg Wunsch "\t-N no update\n", 3981dcc6ec7SPhilippe Charnier "usage: pw groupdel [group|gid] [switches]\n" 3995f12594aSDavid Nugent "\t-V etcdir alternate /etc location\n" 400d6f907dcSJoerg Wunsch "\t-n name group name\n" 401f1d684faSDavid Nugent "\t-g gid group id\n" 402f1d684faSDavid Nugent "\t-Y update NIS maps\n", 4031dcc6ec7SPhilippe Charnier "usage: pw groupmod [group|gid] [switches]\n" 4045f12594aSDavid Nugent "\t-V etcdir alternate /etc location\n" 405d6f907dcSJoerg Wunsch "\t-C config configuration file\n" 406d6f907dcSJoerg Wunsch "\t-q quiet operation\n" 407d6f907dcSJoerg Wunsch "\t-F force add if not exists\n" 408d6f907dcSJoerg Wunsch "\t-n name group name\n" 409d6f907dcSJoerg Wunsch "\t-g gid group id\n" 41048aee7f3SJoerg Wunsch "\t-M usr1,usr2 replaces users as group members\n" 41148aee7f3SJoerg Wunsch "\t-m usr1,usr2 add users as group members\n" 412bc991a6dSSean Farley "\t-d usr1,usr2 delete users as group members\n" 41348aee7f3SJoerg Wunsch "\t-l name new group name\n" 414f1d684faSDavid Nugent "\t-Y update NIS maps\n" 41548aee7f3SJoerg Wunsch "\t-N no update\n", 4161dcc6ec7SPhilippe Charnier "usage: pw groupshow [group|gid] [switches]\n" 4175f12594aSDavid Nugent "\t-V etcdir alternate /etc location\n" 418d6f907dcSJoerg Wunsch "\t-n name group name\n" 419d6f907dcSJoerg Wunsch "\t-g gid group id\n" 420d6f907dcSJoerg Wunsch "\t-F force print\n" 42148aee7f3SJoerg Wunsch "\t-P prettier format\n" 42248aee7f3SJoerg Wunsch "\t-a print all accounting groups\n", 4231dcc6ec7SPhilippe Charnier "usage: pw groupnext [switches]\n" 4245f12594aSDavid Nugent "\t-V etcdir alternate /etc location\n" 42548aee7f3SJoerg Wunsch "\t-C config configuration file\n" 426ed6fd55aSDima Dorfman "\t-q quiet operation\n" 427d6f907dcSJoerg Wunsch } 428d6f907dcSJoerg Wunsch }; 429d6f907dcSJoerg Wunsch 430cab0fb4eSKris Kennaway fprintf(stderr, "%s", help[which][mode]); 431d6f907dcSJoerg Wunsch } 43248aee7f3SJoerg Wunsch exit(EXIT_FAILURE); 433d6f907dcSJoerg Wunsch } 434d6f907dcSJoerg Wunsch 435d6f907dcSJoerg Wunsch struct carg * 436d6f907dcSJoerg Wunsch getarg(struct cargs * _args, int ch) 437d6f907dcSJoerg Wunsch { 438d0d78e13SBen Smithurst struct carg *c = LIST_FIRST(_args); 439d6f907dcSJoerg Wunsch 440d6f907dcSJoerg Wunsch while (c != NULL && c->ch != ch) 441d0d78e13SBen Smithurst c = LIST_NEXT(c, list); 442d6f907dcSJoerg Wunsch return c; 443d6f907dcSJoerg Wunsch } 444d6f907dcSJoerg Wunsch 445d6f907dcSJoerg Wunsch struct carg * 446d6f907dcSJoerg Wunsch addarg(struct cargs * _args, int ch, char *argstr) 447d6f907dcSJoerg Wunsch { 448d6f907dcSJoerg Wunsch struct carg *ca = malloc(sizeof(struct carg)); 449d6f907dcSJoerg Wunsch 450d6f907dcSJoerg Wunsch if (ca == NULL) 4511dcc6ec7SPhilippe Charnier errx(EX_OSERR, "out of memory"); 452d6f907dcSJoerg Wunsch ca->ch = ch; 453d6f907dcSJoerg Wunsch ca->val = argstr; 454d6f907dcSJoerg Wunsch LIST_INSERT_HEAD(_args, ca, list); 455d6f907dcSJoerg Wunsch return ca; 456d6f907dcSJoerg Wunsch } 457