- print(fp, pw);
- (void)fflush(fp);
-
- /*
- * give the file to the real user; setuid permissions
- * are discarded in edit()
- */
- (void)fchown(fd, getuid(), getgid());
-
- for (rval = 0;;) {
- (void)fstat(fd, &begin);
- if (edit(tfile)) {
- (void)fprintf(stderr, "chpass: edit failed; ");
- break;
- }
- (void)fstat(fd, &end);
- if (begin.st_mtime == end.st_mtime) {
- (void)fprintf(stderr, "chpass: no changes made; ");
- break;
- }
- (void)rewind(fp);
- if (check(fp, pw)) {
- rval = 1;
- break;
- }
- (void)fflush(stderr);
- if (prompt())
- break;
- }
- (void)fclose(fp);
- (void)unlink(tfile);
- return(rval);
-}
-
-check(fp, pw)
- FILE *fp;
- struct passwd *pw;
-{
- register struct entry *ep;
- register char *p;
- static char buf[1024];
-
- while (fgets(buf, sizeof(buf), fp)) {
- if (!buf[0] || buf[0] == '#')
- continue;
- if (!(p = index(buf, '\n'))) {
- (void)fprintf(stderr, "chpass: line too long.\n");
- return(0);
- }
- *p = '\0';
- for (ep = list;; ++ep) {
- if (!ep->prompt) {
- (void)fprintf(stderr,
- "chpass: unrecognized field.\n");
- return(0);
- }
- if (!strncasecmp(buf, ep->prompt, ep->len)) {
- if (ep->restricted && uid)
- break;
- if (!(p = index(buf, ':'))) {
- (void)fprintf(stderr,
- "chpass: line corrupted.\n");
- return(0);
- }
- while (isspace(*++p));
- if (ep->except && strpbrk(p, ep->except)) {
- (void)fprintf(stderr,
- "chpass: illegal character in the \"%s\" field.\n",
- ep->prompt);
- return(0);
- }
- if ((ep->func)(p, pw, ep))
- return(0);
- break;
- }
- }
- }
- /*
- * special checks...
- *
- * there has to be a limit on the size of the gecos fields,
- * otherwise getpwent(3) can choke.
- * ``if I swallow anything evil, put your fingers down my throat...''
- * -- The Who
- */
- if (strlen(list[E_NAME].save) + strlen(list[E_BPHONE].save) +
- strlen(list[E_HPHONE].save) + strlen(list[E_LOCATE].save)
- > 512) {
- (void)fprintf(stderr, "chpass: gecos field too large.\n");
- exit(1);
- }
- (void)sprintf(pw->pw_gecos = buf, "%s,%s,%s,%s",
- list[E_NAME].save, list[E_LOCATE].save, list[E_BPHONE].save,
- list[E_HPHONE].save);
- return(1);
-}
-
-copy(pw, fp)
- struct passwd *pw;
- FILE *fp;
-{
- register int done;
- register char *p;
- char buf[1024];
-
- for (done = 0; fgets(buf, sizeof(buf), stdin);) {
- /* skip lines that are too big */
- if (!index(buf, '\n')) {
- (void)fprintf(stderr, "chpass: line too long; ");
- return(0);
- }
- if (done) {
- (void)fprintf(fp, "%s", buf);
- continue;
- }
- if (!(p = index(buf, ':'))) {
- (void)fprintf(stderr, "chpass: corrupted entry; ");
- return(0);
- }
- *p = '\0';
- if (strcmp(buf, pw->pw_name)) {
- *p = ':';
- (void)fprintf(fp, "%s", buf);
- continue;
- }
- (void)fprintf(fp, "%s:%s:%d:%d:%s:%ld:%ld:%s:%s:%s\n",
- pw->pw_name, pw->pw_passwd, pw->pw_uid, pw->pw_gid,
- pw->pw_class, pw->pw_change, pw->pw_expire, pw->pw_gecos,
- pw->pw_dir, pw->pw_shell);
- done = 1;
- }
- if (!done)
- (void)fprintf(fp, "%s:%s:%d:%d:%s:%ld:%ld:%s:%s:%s\n",
- pw->pw_name, pw->pw_passwd, pw->pw_uid, pw->pw_gid,
- pw->pw_class, pw->pw_change, pw->pw_expire, pw->pw_gecos,
- pw->pw_dir, pw->pw_shell);
- return(1);
-}
-
-makedb(file)
- char *file;
-{
- int status, pid, w;
-
- if (!(pid = vfork())) {
- execl(_PATH_MKPASSWD, "mkpasswd", "-p", file, NULL);
- _exit(127);
- }
- while ((w = wait(&status)) != pid && w != -1);
- return(w == -1 || status);
-}
-
-edit(file)
- char *file;
-{
- int status, pid, w;
- char *p, *editor, *getenv();
-
- if (editor = getenv("EDITOR")) {
- if (p = rindex(editor, '/'))
- ++p;
- else
- p = editor;
- }
- else
- p = editor = "vi";
- if (!(pid = vfork())) {
- (void)setgid(getgid());
- (void)setuid(getuid());
- execlp(editor, p, file, NULL);
- _exit(127);
- }
- while ((w = wait(&status)) != pid && w != -1);
- return(w == -1 || status);
-}
-
-loadpw(arg, pw)
- char *arg;
- register struct passwd *pw;
-{
- register char *cp;
- long atol();
- char *strsep();
-
- pw->pw_name = strsep(arg, ":");
- pw->pw_passwd = strsep((char *)NULL, ":");
- if (!(cp = strsep((char *)NULL, ":")))
- goto bad;
- pw->pw_uid = atoi(cp);
- if (!(cp = strsep((char *)NULL, ":")))
- goto bad;
- pw->pw_gid = atoi(cp);
- pw->pw_class = strsep((char *)NULL, ":");
- if (!(cp = strsep((char *)NULL, ":")))
- goto bad;
- pw->pw_change = atol(cp);
- if (!(cp = strsep((char *)NULL, ":")))
- goto bad;
- pw->pw_expire = atol(cp);
- pw->pw_gecos = strsep((char *)NULL, ":");
- pw->pw_dir = strsep((char *)NULL, ":");
- pw->pw_shell = strsep((char *)NULL, ":");
- if (!pw->pw_shell || strsep((char *)NULL, ":")) {
-bad: (void)fprintf(stderr, "chpass: bad password list.\n");
- exit(1);
- }