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 40923dc0b2SDavid Nugent #if !defined(_PATH_YP) 41923dc0b2SDavid Nugent #define _PATH_YP "/var/yp/" 42923dc0b2SDavid Nugent #endif 432399cd14SDavid Nugent const char *Modes[] = { 442399cd14SDavid Nugent "add", "del", "mod", "show", "next", 452399cd14SDavid Nugent NULL}; 46d6f907dcSJoerg Wunsch const char *Which[] = {"user", "group", NULL}; 4748aee7f3SJoerg Wunsch static const char *Combo1[] = { 4848aee7f3SJoerg Wunsch "useradd", "userdel", "usermod", "usershow", "usernext", 492399cd14SDavid Nugent "lock", "unlock", 5048aee7f3SJoerg Wunsch "groupadd", "groupdel", "groupmod", "groupshow", "groupnext", 51d6f907dcSJoerg Wunsch NULL}; 5248aee7f3SJoerg Wunsch static const char *Combo2[] = { 5348aee7f3SJoerg Wunsch "adduser", "deluser", "moduser", "showuser", "nextuser", 542399cd14SDavid Nugent "lock", "unlock", 5548aee7f3SJoerg Wunsch "addgroup", "delgroup", "modgroup", "showgroup", "nextgroup", 56d6f907dcSJoerg Wunsch NULL}; 57d6f907dcSJoerg Wunsch 585f12594aSDavid Nugent struct pwf PWF = 595f12594aSDavid Nugent { 60ac72be28SBaptiste Daroussin PWF_REGULAR, 615f12594aSDavid Nugent setpwent, 625f12594aSDavid Nugent endpwent, 635f12594aSDavid Nugent getpwent, 645f12594aSDavid Nugent getpwuid, 655f12594aSDavid Nugent getpwnam, 665f12594aSDavid Nugent setgrent, 675f12594aSDavid Nugent endgrent, 685f12594aSDavid Nugent getgrent, 695f12594aSDavid Nugent getgrgid, 705f12594aSDavid Nugent getgrnam, 715f12594aSDavid Nugent 725f12594aSDavid Nugent }; 735f12594aSDavid Nugent struct pwf VPWF = 745f12594aSDavid Nugent { 75ac72be28SBaptiste Daroussin PWF_ALT, 765f12594aSDavid Nugent vsetpwent, 775f12594aSDavid Nugent vendpwent, 785f12594aSDavid Nugent vgetpwent, 795f12594aSDavid Nugent vgetpwuid, 805f12594aSDavid Nugent vgetpwnam, 815f12594aSDavid Nugent vsetgrent, 825f12594aSDavid Nugent vendgrent, 835f12594aSDavid Nugent vgetgrent, 845f12594aSDavid Nugent vgetgrgid, 855f12594aSDavid Nugent vgetgrnam, 865f12594aSDavid Nugent }; 875f12594aSDavid Nugent 882cc63cd1SBaptiste Daroussin struct pwconf conf; 892cc63cd1SBaptiste Daroussin 90d6f907dcSJoerg Wunsch static struct cargs arglist; 91d6f907dcSJoerg Wunsch 92d6f907dcSJoerg Wunsch static int getindex(const char *words[], const char *word); 93d6f907dcSJoerg Wunsch static void cmdhelp(int mode, int which); 94d6f907dcSJoerg Wunsch 95d6f907dcSJoerg Wunsch 96d6f907dcSJoerg Wunsch int 97d6f907dcSJoerg Wunsch main(int argc, char *argv[]) 98d6f907dcSJoerg Wunsch { 99d6f907dcSJoerg Wunsch int ch; 100d6f907dcSJoerg Wunsch int mode = -1; 101d6f907dcSJoerg Wunsch int which = -1; 1025f12594aSDavid Nugent char *config = NULL; 10390edef4fSBaptiste Daroussin struct stat st; 104ac72be28SBaptiste Daroussin char arg; 105*82a3c75aSBaptiste Daroussin bool relocated, nis; 106d6f907dcSJoerg Wunsch 107d6f907dcSJoerg Wunsch static const char *opts[W_NUM][M_NUM] = 108d6f907dcSJoerg Wunsch { 10948aee7f3SJoerg Wunsch { /* user */ 110ac72be28SBaptiste Daroussin "R:V:C:qn:u:c:d:e:p:g:G:mM:k:s:oL:i:w:h:H:Db:NPy:Y", 111ac72be28SBaptiste Daroussin "R:V:C:qn:u:rY", 112ac72be28SBaptiste Daroussin "R:V:C:qn:u:c:d:e:p:g:G:mM:l:k:s:w:L:h:H:FNPY", 113ac72be28SBaptiste Daroussin "R:V:C:qn:u:FPa7", 114ac72be28SBaptiste Daroussin "R:V:C:q", 115ac72be28SBaptiste Daroussin "R:V:C:q", 116ac72be28SBaptiste Daroussin "R:V:C:q" 11748aee7f3SJoerg Wunsch }, 11848aee7f3SJoerg Wunsch { /* grp */ 119ac72be28SBaptiste Daroussin "R:V:C:qn:g:h:H:M:opNPY", 120ac72be28SBaptiste Daroussin "R:V:C:qn:g:Y", 121ac72be28SBaptiste Daroussin "R:V:C:qn:d:g:l:h:H:FM:m:NPY", 122ac72be28SBaptiste Daroussin "R:V:C:qn:g:FPa", 123ac72be28SBaptiste Daroussin "R:V:C:q" 12448aee7f3SJoerg Wunsch } 125d6f907dcSJoerg Wunsch }; 126d6f907dcSJoerg Wunsch 1272cc63cd1SBaptiste Daroussin static int (*funcs[W_NUM]) (int _mode, struct cargs * _args) = 128d6f907dcSJoerg Wunsch { /* Request handlers */ 129d6f907dcSJoerg Wunsch pw_user, 130d6f907dcSJoerg Wunsch pw_group 131d6f907dcSJoerg Wunsch }; 132d6f907dcSJoerg Wunsch 133*82a3c75aSBaptiste Daroussin relocated = nis = false; 1342cc63cd1SBaptiste Daroussin conf.rootdir[0] = '\0'; 1352cc63cd1SBaptiste Daroussin strlcpy(conf.etcpath, _PATH_PWD, sizeof(conf.etcpath)); 1362cc63cd1SBaptiste Daroussin 137d6f907dcSJoerg Wunsch LIST_INIT(&arglist); 138d6f907dcSJoerg Wunsch 13939610c72SAndrey A. Chernov (void)setlocale(LC_ALL, ""); 140e7161f36SAndrey A. Chernov 141d6f907dcSJoerg Wunsch /* 142d6f907dcSJoerg Wunsch * Break off the first couple of words to determine what exactly 143d6f907dcSJoerg Wunsch * we're being asked to do 144d6f907dcSJoerg Wunsch */ 1455f12594aSDavid Nugent while (argc > 1) { 146d6f907dcSJoerg Wunsch int tmp; 147d6f907dcSJoerg Wunsch 1485f12594aSDavid Nugent if (*argv[1] == '-') { 1495f12594aSDavid Nugent /* 1505f12594aSDavid Nugent * Special case, allow pw -V<dir> <operation> [args] for scripts etc. 1515f12594aSDavid Nugent */ 152ac72be28SBaptiste Daroussin arg = argv[1][1]; 153ac72be28SBaptiste Daroussin if (arg == 'V' || arg == 'R') { 1542cc63cd1SBaptiste Daroussin if (relocated) 1552cc63cd1SBaptiste Daroussin errx(EXIT_FAILURE, "Both '-R' and '-V' " 1562cc63cd1SBaptiste Daroussin "specified, only one accepted"); 1572cc63cd1SBaptiste Daroussin relocated = true; 1585f12594aSDavid Nugent optarg = &argv[1][2]; 1595f12594aSDavid Nugent if (*optarg == '\0') { 16090edef4fSBaptiste Daroussin if (stat(argv[2], &st) != 0) 16190edef4fSBaptiste Daroussin errx(EX_OSFILE, \ 16290edef4fSBaptiste Daroussin "no such directory `%s'", 16390edef4fSBaptiste Daroussin argv[2]); 16490edef4fSBaptiste Daroussin if (!S_ISDIR(st.st_mode)) 16590edef4fSBaptiste Daroussin errx(EX_OSFILE, "`%s' not a " 16690edef4fSBaptiste Daroussin "directory", argv[2]); 1675f12594aSDavid Nugent optarg = argv[2]; 1685f12594aSDavid Nugent ++argv; 1695f12594aSDavid Nugent --argc; 1705f12594aSDavid Nugent } 1712cc63cd1SBaptiste Daroussin memcpy(&PWF, &VPWF, sizeof PWF); 1722cc63cd1SBaptiste Daroussin if (arg == 'R') { 1732cc63cd1SBaptiste Daroussin strlcpy(conf.rootdir, optarg, 1742cc63cd1SBaptiste Daroussin sizeof(conf.rootdir)); 1752cc63cd1SBaptiste Daroussin PWF._altdir = PWF_ROOTDIR; 1762cc63cd1SBaptiste Daroussin } 1772cc63cd1SBaptiste Daroussin snprintf(conf.etcpath, sizeof(conf.etcpath), 1782cc63cd1SBaptiste Daroussin "%s%s", optarg, arg == 'R' ? "/etc" : ""); 179e3921b27SDavid Nugent } else 1805f12594aSDavid Nugent break; 1815f12594aSDavid Nugent } 182c4e667b9SDavid Nugent else if (mode == -1 && (tmp = getindex(Modes, argv[1])) != -1) 183d6f907dcSJoerg Wunsch mode = tmp; 184c4e667b9SDavid Nugent else if (which == -1 && (tmp = getindex(Which, argv[1])) != -1) 185d6f907dcSJoerg Wunsch which = tmp; 186c4e667b9SDavid Nugent else if ((mode == -1 && which == -1) && 187c4e667b9SDavid Nugent ((tmp = getindex(Combo1, argv[1])) != -1 || 188c4e667b9SDavid Nugent (tmp = getindex(Combo2, argv[1])) != -1)) { 189d6f907dcSJoerg Wunsch which = tmp / M_NUM; 190d6f907dcSJoerg Wunsch mode = tmp % M_NUM; 191c4e667b9SDavid Nugent } else if (strcmp(argv[1], "help") == 0 && argv[2] == NULL) 192d6f907dcSJoerg Wunsch cmdhelp(mode, which); 1937291e217SDavid Nugent else if (which != -1 && mode != -1) 194d6f907dcSJoerg Wunsch addarg(&arglist, 'n', argv[1]); 195d6f907dcSJoerg Wunsch else 1961dcc6ec7SPhilippe Charnier errx(EX_USAGE, "unknown keyword `%s'", argv[1]); 197d6f907dcSJoerg Wunsch ++argv; 198d6f907dcSJoerg Wunsch --argc; 199d6f907dcSJoerg Wunsch } 200d6f907dcSJoerg Wunsch 201d6f907dcSJoerg Wunsch /* 202d6f907dcSJoerg Wunsch * Bail out unless the user is specific! 203d6f907dcSJoerg Wunsch */ 204d6f907dcSJoerg Wunsch if (mode == -1 || which == -1) 205d6f907dcSJoerg Wunsch cmdhelp(mode, which); 206d6f907dcSJoerg Wunsch 207d6f907dcSJoerg Wunsch /* 208d6f907dcSJoerg Wunsch * We know which mode we're in and what we're about to do, so now 209d6f907dcSJoerg Wunsch * let's dispatch the remaining command line args in a genric way. 210d6f907dcSJoerg Wunsch */ 211d6f907dcSJoerg Wunsch optarg = NULL; 212d6f907dcSJoerg Wunsch 213d6f907dcSJoerg Wunsch while ((ch = getopt(argc, argv, opts[which][mode])) != -1) { 214*82a3c75aSBaptiste Daroussin switch (ch) { 215*82a3c75aSBaptiste Daroussin case '?': 216923dc0b2SDavid Nugent errx(EX_USAGE, "unknown switch"); 217*82a3c75aSBaptiste Daroussin break; 218*82a3c75aSBaptiste Daroussin case 'C': 219*82a3c75aSBaptiste Daroussin config = optarg; 220*82a3c75aSBaptiste Daroussin break; 221*82a3c75aSBaptiste Daroussin case 'Y': 222*82a3c75aSBaptiste Daroussin nis = true; 223*82a3c75aSBaptiste Daroussin break; 224*82a3c75aSBaptiste Daroussin default: 225d6f907dcSJoerg Wunsch addarg(&arglist, ch, optarg); 226*82a3c75aSBaptiste Daroussin break; 227*82a3c75aSBaptiste Daroussin } 228d6f907dcSJoerg Wunsch optarg = NULL; 229d6f907dcSJoerg Wunsch } 230d6f907dcSJoerg Wunsch 231d6f907dcSJoerg Wunsch /* 23248aee7f3SJoerg Wunsch * Must be root to attempt an update 23348aee7f3SJoerg Wunsch */ 234fa7e83d4SDavid Nugent if (geteuid() != 0 && mode != M_PRINT && mode != M_NEXT && getarg(&arglist, 'N')==NULL) 2351dcc6ec7SPhilippe Charnier errx(EX_NOPERM, "you must be root to run this program"); 23648aee7f3SJoerg Wunsch 23748aee7f3SJoerg Wunsch /* 238d6f907dcSJoerg Wunsch * We should immediately look for the -q 'quiet' switch so that we 239d6f907dcSJoerg Wunsch * don't bother with extraneous errors 240d6f907dcSJoerg Wunsch */ 241d6f907dcSJoerg Wunsch if (getarg(&arglist, 'q') != NULL) 2421a37aa56SDavid E. O'Brien freopen(_PATH_DEVNULL, "w", stderr); 243d6f907dcSJoerg Wunsch 244d6f907dcSJoerg Wunsch /* 2455f12594aSDavid Nugent * Set our base working path if not overridden 2465f12594aSDavid Nugent */ 2475f12594aSDavid Nugent 2485f12594aSDavid Nugent if (config == NULL) { /* Only override config location if -C not specified */ 2492cc63cd1SBaptiste Daroussin asprintf(&config, "%s/pw.conf", conf.etcpath); 25019741915SBaptiste Daroussin if (config == NULL) 25119741915SBaptiste Daroussin errx(EX_OSERR, "out of memory"); 2525f12594aSDavid Nugent } 2535f12594aSDavid Nugent 2545f12594aSDavid Nugent /* 255d6f907dcSJoerg Wunsch * Now, let's do the common initialisation 256d6f907dcSJoerg Wunsch */ 2572cc63cd1SBaptiste Daroussin conf.userconf = read_userconfig(config); 2585e91a8acSNate Williams 2592cc63cd1SBaptiste Daroussin ch = funcs[which] (mode, &arglist); 260f1d684faSDavid Nugent 261f1d684faSDavid Nugent /* 262f1d684faSDavid Nugent * If everything went ok, and we've been asked to update 263f1d684faSDavid Nugent * the NIS maps, then do it now 264f1d684faSDavid Nugent */ 265*82a3c75aSBaptiste Daroussin if (ch == EXIT_SUCCESS && nis) { 266f1d684faSDavid Nugent pid_t pid; 267f1d684faSDavid Nugent 268f1d684faSDavid Nugent fflush(NULL); 269f1d684faSDavid Nugent if (chdir(_PATH_YP) == -1) 2701dcc6ec7SPhilippe Charnier warn("chdir(" _PATH_YP ")"); 271f1d684faSDavid Nugent else if ((pid = fork()) == -1) 2721dcc6ec7SPhilippe Charnier warn("fork()"); 273f1d684faSDavid Nugent else if (pid == 0) { 274f1d684faSDavid Nugent /* Is make anywhere else? */ 2757bc6d015SBrian Somers execlp("/usr/bin/make", "make", (char *)NULL); 276f1d684faSDavid Nugent _exit(1); 277f1d684faSDavid Nugent } else { 278f1d684faSDavid Nugent int i; 279f1d684faSDavid Nugent waitpid(pid, &i, 0); 280f1d684faSDavid Nugent if ((i = WEXITSTATUS(i)) != 0) 2811dcc6ec7SPhilippe Charnier errx(ch, "make exited with status %d", i); 282f1d684faSDavid Nugent else 2832cc63cd1SBaptiste Daroussin pw_log(conf.userconf, mode, which, "NIS maps updated"); 284f1d684faSDavid Nugent } 285f1d684faSDavid Nugent } 286f1d684faSDavid Nugent return ch; 287d6f907dcSJoerg Wunsch } 288d6f907dcSJoerg Wunsch 2895e91a8acSNate Williams 290d6f907dcSJoerg Wunsch static int 291d6f907dcSJoerg Wunsch getindex(const char *words[], const char *word) 292d6f907dcSJoerg Wunsch { 293d6f907dcSJoerg Wunsch int i = 0; 294d6f907dcSJoerg Wunsch 295d6f907dcSJoerg Wunsch while (words[i]) { 296d6f907dcSJoerg Wunsch if (strcmp(words[i], word) == 0) 297d6f907dcSJoerg Wunsch return i; 298d6f907dcSJoerg Wunsch i++; 299d6f907dcSJoerg Wunsch } 300d6f907dcSJoerg Wunsch return -1; 301d6f907dcSJoerg Wunsch } 302d6f907dcSJoerg Wunsch 303d6f907dcSJoerg Wunsch 304d6f907dcSJoerg Wunsch /* 305d6f907dcSJoerg Wunsch * This is probably an overkill for a cmdline help system, but it reflects 306d6f907dcSJoerg Wunsch * the complexity of the command line. 307d6f907dcSJoerg Wunsch */ 308d6f907dcSJoerg Wunsch 309d6f907dcSJoerg Wunsch static void 310d6f907dcSJoerg Wunsch cmdhelp(int mode, int which) 311d6f907dcSJoerg Wunsch { 312d6f907dcSJoerg Wunsch if (which == -1) 3132399cd14SDavid Nugent fprintf(stderr, "usage:\n pw [user|group|lock|unlock] [add|del|mod|show|next] [help|switches/values]\n"); 314d6f907dcSJoerg Wunsch else if (mode == -1) 3152399cd14SDavid Nugent fprintf(stderr, "usage:\n pw %s [add|del|mod|show|next] [help|switches/values]\n", Which[which]); 316d6f907dcSJoerg Wunsch else { 317d6f907dcSJoerg Wunsch 318d6f907dcSJoerg Wunsch /* 319d6f907dcSJoerg Wunsch * We need to give mode specific help 320d6f907dcSJoerg Wunsch */ 321d6f907dcSJoerg Wunsch static const char *help[W_NUM][M_NUM] = 322d6f907dcSJoerg Wunsch { 323d6f907dcSJoerg Wunsch { 3241dcc6ec7SPhilippe Charnier "usage: pw useradd [name] [switches]\n" 3255f12594aSDavid Nugent "\t-V etcdir alternate /etc location\n" 326ac72be28SBaptiste Daroussin "\t-R rootir alternate root directory\n" 327d6f907dcSJoerg Wunsch "\t-C config configuration file\n" 328d6f907dcSJoerg Wunsch "\t-q quiet operation\n" 329d6f907dcSJoerg Wunsch " Adding users:\n" 330d6f907dcSJoerg Wunsch "\t-n name login name\n" 331d6f907dcSJoerg Wunsch "\t-u uid user id\n" 332d6f907dcSJoerg Wunsch "\t-c comment user name/comment\n" 333d6f907dcSJoerg Wunsch "\t-d directory home directory\n" 334d6f907dcSJoerg Wunsch "\t-e date account expiry date\n" 335d6f907dcSJoerg Wunsch "\t-p date password expiry date\n" 336d6f907dcSJoerg Wunsch "\t-g grp initial group\n" 337d6f907dcSJoerg Wunsch "\t-G grp1,grp2 additional groups\n" 338d6f907dcSJoerg Wunsch "\t-m [ -k dir ] create and set up home\n" 3391dd634b0SLukas Ertl "\t-M mode home directory permissions\n" 340d6f907dcSJoerg Wunsch "\t-s shell name of login shell\n" 341d6f907dcSJoerg Wunsch "\t-o duplicate uid ok\n" 342d6f907dcSJoerg Wunsch "\t-L class user class\n" 343d6f907dcSJoerg Wunsch "\t-h fd read password on fd\n" 34487d6b5caSIan Dowse "\t-H fd read encrypted password on fd\n" 345f1d684faSDavid Nugent "\t-Y update NIS maps\n" 34648aee7f3SJoerg Wunsch "\t-N no update\n" 347d6f907dcSJoerg Wunsch " Setting defaults:\n" 3485f12594aSDavid Nugent "\t-V etcdir alternate /etc location\n" 349ac72be28SBaptiste Daroussin "\t-R rootir alternate root directory\n" 350d6f907dcSJoerg Wunsch "\t-D set user defaults\n" 351d6f907dcSJoerg Wunsch "\t-b dir default home root dir\n" 352d6f907dcSJoerg Wunsch "\t-e period default expiry period\n" 353d6f907dcSJoerg Wunsch "\t-p period default password change period\n" 354d6f907dcSJoerg Wunsch "\t-g group default group\n" 355d6f907dcSJoerg Wunsch "\t-G grp1,grp2 additional groups\n" 356d6f907dcSJoerg Wunsch "\t-L class default user class\n" 357d6f907dcSJoerg Wunsch "\t-k dir default home skeleton\n" 35885204142SLukas Ertl "\t-M mode home directory permissions\n" 359d6f907dcSJoerg Wunsch "\t-u min,max set min,max uids\n" 360d6f907dcSJoerg Wunsch "\t-i min,max set min,max gids\n" 361d6f907dcSJoerg Wunsch "\t-w method set default password method\n" 362f1d684faSDavid Nugent "\t-s shell default shell\n" 363f1d684faSDavid Nugent "\t-y path set NIS passwd file path\n", 3641dcc6ec7SPhilippe Charnier "usage: pw userdel [uid|name] [switches]\n" 3655f12594aSDavid Nugent "\t-V etcdir alternate /etc location\n" 366ac72be28SBaptiste Daroussin "\t-R rootir alternate root directory\n" 367d6f907dcSJoerg Wunsch "\t-n name login name\n" 368d6f907dcSJoerg Wunsch "\t-u uid user id\n" 369f1d684faSDavid Nugent "\t-Y update NIS maps\n" 370d6f907dcSJoerg Wunsch "\t-r remove home & contents\n", 3711dcc6ec7SPhilippe Charnier "usage: pw usermod [uid|name] [switches]\n" 3725f12594aSDavid Nugent "\t-V etcdir alternate /etc location\n" 373ac72be28SBaptiste Daroussin "\t-R rootir alternate root directory\n" 374d6f907dcSJoerg Wunsch "\t-C config configuration file\n" 375d6f907dcSJoerg Wunsch "\t-q quiet operation\n" 376d6f907dcSJoerg Wunsch "\t-F force add if no user\n" 377d6f907dcSJoerg Wunsch "\t-n name login name\n" 378d6f907dcSJoerg Wunsch "\t-u uid user id\n" 379d6f907dcSJoerg Wunsch "\t-c comment user name/comment\n" 380d6f907dcSJoerg Wunsch "\t-d directory home directory\n" 381d6f907dcSJoerg Wunsch "\t-e date account expiry date\n" 382d6f907dcSJoerg Wunsch "\t-p date password expiry date\n" 383d6f907dcSJoerg Wunsch "\t-g grp initial group\n" 384d6f907dcSJoerg Wunsch "\t-G grp1,grp2 additional groups\n" 385d6f907dcSJoerg Wunsch "\t-l name new login name\n" 386d6f907dcSJoerg Wunsch "\t-L class user class\n" 387d6f907dcSJoerg Wunsch "\t-m [ -k dir ] create and set up home\n" 3881dd634b0SLukas Ertl "\t-M mode home directory permissions\n" 389d6f907dcSJoerg Wunsch "\t-s shell name of login shell\n" 39048aee7f3SJoerg Wunsch "\t-w method set new password using method\n" 39148aee7f3SJoerg Wunsch "\t-h fd read password on fd\n" 39287d6b5caSIan Dowse "\t-H fd read encrypted password on fd\n" 393f1d684faSDavid Nugent "\t-Y update NIS maps\n" 39448aee7f3SJoerg Wunsch "\t-N no update\n", 3951dcc6ec7SPhilippe Charnier "usage: pw usershow [uid|name] [switches]\n" 3965f12594aSDavid Nugent "\t-V etcdir alternate /etc location\n" 397ac72be28SBaptiste Daroussin "\t-R rootir alternate root directory\n" 398d6f907dcSJoerg Wunsch "\t-n name login name\n" 399d6f907dcSJoerg Wunsch "\t-u uid user id\n" 400d6f907dcSJoerg Wunsch "\t-F force print\n" 40148aee7f3SJoerg Wunsch "\t-P prettier format\n" 402f3522722SDavid Nugent "\t-a print all users\n" 403f3522722SDavid Nugent "\t-7 print in v7 format\n", 4041dcc6ec7SPhilippe Charnier "usage: pw usernext [switches]\n" 4055f12594aSDavid Nugent "\t-V etcdir alternate /etc location\n" 406ac72be28SBaptiste Daroussin "\t-R rootir alternate root directory\n" 40748aee7f3SJoerg Wunsch "\t-C config configuration file\n" 408ed6fd55aSDima Dorfman "\t-q quiet operation\n", 409ed6fd55aSDima Dorfman "usage pw: lock [switches]\n" 410ed6fd55aSDima Dorfman "\t-V etcdir alternate /etc locations\n" 411ed6fd55aSDima Dorfman "\t-C config configuration file\n" 412ed6fd55aSDima Dorfman "\t-q quiet operation\n", 413ed6fd55aSDima Dorfman "usage pw: unlock [switches]\n" 414ed6fd55aSDima Dorfman "\t-V etcdir alternate /etc locations\n" 415ed6fd55aSDima Dorfman "\t-C config configuration file\n" 416ed6fd55aSDima Dorfman "\t-q quiet operation\n" 417d6f907dcSJoerg Wunsch }, 418d6f907dcSJoerg Wunsch { 4191dcc6ec7SPhilippe Charnier "usage: pw groupadd [group|gid] [switches]\n" 4205f12594aSDavid Nugent "\t-V etcdir alternate /etc location\n" 421ac72be28SBaptiste Daroussin "\t-R rootir alternate root directory\n" 422d6f907dcSJoerg Wunsch "\t-C config configuration file\n" 423d6f907dcSJoerg Wunsch "\t-q quiet operation\n" 424d6f907dcSJoerg Wunsch "\t-n group group name\n" 425d6f907dcSJoerg Wunsch "\t-g gid group id\n" 42648aee7f3SJoerg Wunsch "\t-M usr1,usr2 add users as group members\n" 42748aee7f3SJoerg Wunsch "\t-o duplicate gid ok\n" 428f1d684faSDavid Nugent "\t-Y update NIS maps\n" 42948aee7f3SJoerg Wunsch "\t-N no update\n", 4301dcc6ec7SPhilippe Charnier "usage: pw groupdel [group|gid] [switches]\n" 4315f12594aSDavid Nugent "\t-V etcdir alternate /etc location\n" 432ac72be28SBaptiste Daroussin "\t-R rootir alternate root directory\n" 433d6f907dcSJoerg Wunsch "\t-n name group name\n" 434f1d684faSDavid Nugent "\t-g gid group id\n" 435f1d684faSDavid Nugent "\t-Y update NIS maps\n", 4361dcc6ec7SPhilippe Charnier "usage: pw groupmod [group|gid] [switches]\n" 4375f12594aSDavid Nugent "\t-V etcdir alternate /etc location\n" 438ac72be28SBaptiste Daroussin "\t-R rootir alternate root directory\n" 439d6f907dcSJoerg Wunsch "\t-C config configuration file\n" 440d6f907dcSJoerg Wunsch "\t-q quiet operation\n" 441d6f907dcSJoerg Wunsch "\t-F force add if not exists\n" 442d6f907dcSJoerg Wunsch "\t-n name group name\n" 443d6f907dcSJoerg Wunsch "\t-g gid group id\n" 44448aee7f3SJoerg Wunsch "\t-M usr1,usr2 replaces users as group members\n" 44548aee7f3SJoerg Wunsch "\t-m usr1,usr2 add users as group members\n" 446bc991a6dSSean Farley "\t-d usr1,usr2 delete users as group members\n" 44748aee7f3SJoerg Wunsch "\t-l name new group name\n" 448f1d684faSDavid Nugent "\t-Y update NIS maps\n" 44948aee7f3SJoerg Wunsch "\t-N no update\n", 4501dcc6ec7SPhilippe Charnier "usage: pw groupshow [group|gid] [switches]\n" 4515f12594aSDavid Nugent "\t-V etcdir alternate /etc location\n" 452ac72be28SBaptiste Daroussin "\t-R rootir alternate root directory\n" 453d6f907dcSJoerg Wunsch "\t-n name group name\n" 454d6f907dcSJoerg Wunsch "\t-g gid group id\n" 455d6f907dcSJoerg Wunsch "\t-F force print\n" 45648aee7f3SJoerg Wunsch "\t-P prettier format\n" 45748aee7f3SJoerg Wunsch "\t-a print all accounting groups\n", 4581dcc6ec7SPhilippe Charnier "usage: pw groupnext [switches]\n" 4595f12594aSDavid Nugent "\t-V etcdir alternate /etc location\n" 460ac72be28SBaptiste Daroussin "\t-R rootir alternate root directory\n" 46148aee7f3SJoerg Wunsch "\t-C config configuration file\n" 462ed6fd55aSDima Dorfman "\t-q quiet operation\n" 463d6f907dcSJoerg Wunsch } 464d6f907dcSJoerg Wunsch }; 465d6f907dcSJoerg Wunsch 466cab0fb4eSKris Kennaway fprintf(stderr, "%s", help[which][mode]); 467d6f907dcSJoerg Wunsch } 46848aee7f3SJoerg Wunsch exit(EXIT_FAILURE); 469d6f907dcSJoerg Wunsch } 470d6f907dcSJoerg Wunsch 471d6f907dcSJoerg Wunsch struct carg * 472d6f907dcSJoerg Wunsch getarg(struct cargs * _args, int ch) 473d6f907dcSJoerg Wunsch { 474d0d78e13SBen Smithurst struct carg *c = LIST_FIRST(_args); 475d6f907dcSJoerg Wunsch 476d6f907dcSJoerg Wunsch while (c != NULL && c->ch != ch) 477d0d78e13SBen Smithurst c = LIST_NEXT(c, list); 478d6f907dcSJoerg Wunsch return c; 479d6f907dcSJoerg Wunsch } 480d6f907dcSJoerg Wunsch 481d6f907dcSJoerg Wunsch struct carg * 482d6f907dcSJoerg Wunsch addarg(struct cargs * _args, int ch, char *argstr) 483d6f907dcSJoerg Wunsch { 484d6f907dcSJoerg Wunsch struct carg *ca = malloc(sizeof(struct carg)); 485d6f907dcSJoerg Wunsch 486d6f907dcSJoerg Wunsch if (ca == NULL) 4871dcc6ec7SPhilippe Charnier errx(EX_OSERR, "out of memory"); 488d6f907dcSJoerg Wunsch ca->ch = ch; 489d6f907dcSJoerg Wunsch ca->val = argstr; 490d6f907dcSJoerg Wunsch LIST_INSERT_HEAD(_args, ca, list); 491d6f907dcSJoerg Wunsch return ca; 492d6f907dcSJoerg Wunsch } 493