Date: Fri, 7 Sep 2001 15:34:37 -0700 (PDT) From: alan@batie.org To: FreeBSD-gnats-submit@freebsd.org Subject: bin/30424: Generalization of vipw to lock pwdb while being edited by a script Message-ID: <200109072234.f87MYbi56103@aggie.rdrop.com>
next in thread | raw e-mail | index | archive | help
>Number: 30424 >Category: bin >Synopsis: Generalization of vipw to lock pwdb while being edited by a script >Confidential: no >Severity: non-critical >Priority: medium >Responsible: freebsd-bugs >State: open >Quarter: >Keywords: >Date-Required: >Class: change-request >Submitter-Id: current-users >Arrival-Date: Fri Sep 07 15:40:01 PDT 2001 >Closed-Date: >Last-Modified: >Originator: Alan Batie >Release: FreeBSD 4.3-STABLE i386 >Organization: RainDrop Laboratories >Environment: System: FreeBSD aggie.rdrop.com 4.3-STABLE FreeBSD 4.3-STABLE #3: Wed Sep 5 13:36:38 PDT 2001 root@aggie.rdrop.com:/usr/src/freebsd/sys/compile/AGORA i386 >Description: I have scripts to update accounts, and need to have the password file locked while they run to avoid having a user change their password at the same time and losing one of the updates. Since vipw already does most of what needs to be done, I've modified it so that when invoked as "pw_lock", instead of running vi, it runs the specified command, but still does all the locking and database updating. >How-To-Repeat: N/A >Fix: *** vipw.c.orig Tue Oct 31 23:06:55 2000 --- vipw.c Mon Nov 6 19:10:09 2000 *************** *** 57,65 **** --- 57,69 ---- #include "pw_util.h" + #define PROG_VIPW "vipw" + #define PROG_PWLOCK "pw_lock" + extern char *mppath; extern char *masterpasswd; char *tempname; + char *progname; void copyfile __P((int, int)); static void usage __P((void)); *************** *** 73,78 **** --- 77,90 ---- struct stat begin, end; int ch; + /* Strip the path, if present, from the program name */ + progname = strrchr(argv[0], '/'); + if (progname == NULL) { + progname = argv[0]; + } else { + progname++; /* Skip past the '/' */ + } + while ((ch = getopt(argc, argv, "d:")) != -1) switch (ch) { case 'd': *************** *** 97,104 **** argc -= optind; argv += optind; ! if (argc != 0) usage(); pw_init(); pfd = pw_lock(); --- 109,117 ---- argc -= optind; argv += optind; ! if (argc != 0 && strcmp(progname, PROG_VIPW) == 0) { usage(); + } pw_init(); pfd = pw_lock(); *************** *** 111,117 **** for (;;) { if (stat(tempname, &begin)) pw_error(tempname, 1, 1); ! pw_edit(0); if (stat(tempname, &end)) pw_error(tempname, 1, 1); if (begin.st_mtime == end.st_mtime) { --- 124,137 ---- for (;;) { if (stat(tempname, &begin)) pw_error(tempname, 1, 1); ! if (strcmp(progname, PROG_VIPW) == 0) { ! pw_edit(0); ! } else if (strcmp(progname, PROG_PWLOCK) == 0) { ! pw_runcmd(argv); ! } else { ! warnx("Unknown invocation mode '%s'", progname); ! pw_error((char *)NULL, 0, 0); ! } if (stat(tempname, &end)) pw_error(tempname, 1, 1); if (begin.st_mtime == end.st_mtime) { *** pw_util.h.org Sun Nov 5 12:10:42 2000 --- pw_util.h Sun Nov 5 12:28:21 2000 *************** *** 40,42 **** --- 40,43 ---- int pw_mkdb __P((char *)); void pw_prompt __P((void)); int pw_tmp __P((void)); + int pw_runcmd __P((char **argv)); *** pw_util.c.org Sun Nov 5 12:08:15 2000 --- pw_util.c Mon Nov 6 19:24:53 2000 *************** *** 260,262 **** --- 260,290 ---- (void)unlink(tempname); exit(eval); } + + int + pw_runcmd(char **argv) + { + union wait pstat; + pid_t pid; + char *progname; + + /* Strip the path, if present, from the program name */ + progname = strrchr(argv[0], '/'); + if (progname == NULL) { + progname = argv[0]; + } else { + progname++; /* Skip past the '/' */ + } + + if (!(pid = vfork())) { + execl(argv[0], progname, tempname, (char *)NULL); + warn("Command '%s' failed", argv[0]); + pw_error((char *)NULL, 0, 0); + } + pid = waitpid(pid, (int *)&pstat, 0); + if (pid == -1 || pstat.w_status) { + return(0); + } + (void)printf("%s: done\n", argv[0]); + return(1); + } *** Makefile.orig Fri Sep 7 15:08:10 2001 --- Makefile Fri Sep 7 15:08:54 2001 *************** *** 2,7 **** --- 2,8 ---- # $FreeBSD: src/usr.sbin/vipw/Makefile,v 1.2.14.1 2001/04/25 12:11:09 ru Exp $ PROG= vipw + LINKS= ${BINDIR}/vipw ${BINDIR}/pw_lock SRCS= pw_util.c vipw.c MAN= vipw.8 *** vipw.8.orig Fri Sep 7 15:10:22 2001 --- vipw.8 Fri Sep 7 15:22:57 2001 *************** *** 41,46 **** --- 41,48 ---- .Sh SYNOPSIS .Nm .Op Fl d Ar directory + .Nm pw_lock + .Ar command arg ... .Sh DESCRIPTION .Nm Vipw edits the password file after setting the appropriate locks, *************** *** 83,88 **** --- 85,95 ---- at very large sites could take several minutes. Until this update is completed, the password file is unavailable for other updates and the new information is not available to programs. + .Pp + If invoked as + .Nm pw_lock + , the user database is locked, the command is run, and then the user + database is updated as above. .Sh ENVIRONMENT If the following environment variable exists it will be utilized by .Nm : >Release-Note: >Audit-Trail: >Unformatted: To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-bugs" in the body of the message
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200109072234.f87MYbi56103>