diff options
author | Niklas Hallqvist <niklas@cvs.openbsd.org> | 1997-06-17 10:13:15 +0000 |
---|---|---|
committer | Niklas Hallqvist <niklas@cvs.openbsd.org> | 1997-06-17 10:13:15 +0000 |
commit | 4fa365e5f68d2c3c6707044db9557cc80667ebe7 (patch) | |
tree | f28c89956c0a3617aa7cdf18b1f1133be83c7e10 /libexec/rpc.yppasswdd/yppasswdd_mkpw.c | |
parent | 1e5d8b4f0d89c2f7dff323f6dacc2d5c47c7d54e (diff) |
Add a -d flag which takes the directory where the YP password files are.
This change makes it possible to separate the host's passwords from the ones
served to YP clients.
Diffstat (limited to 'libexec/rpc.yppasswdd/yppasswdd_mkpw.c')
-rw-r--r-- | libexec/rpc.yppasswdd/yppasswdd_mkpw.c | 168 |
1 files changed, 113 insertions, 55 deletions
diff --git a/libexec/rpc.yppasswdd/yppasswdd_mkpw.c b/libexec/rpc.yppasswdd/yppasswdd_mkpw.c index fdcb84d082f..7c0b9c2567d 100644 --- a/libexec/rpc.yppasswdd/yppasswdd_mkpw.c +++ b/libexec/rpc.yppasswdd/yppasswdd_mkpw.c @@ -30,25 +30,30 @@ */ #ifndef LINT -static char rcsid[] = "$Id: yppasswdd_mkpw.c,v 1.12 1997/02/18 23:38:58 provos Exp $"; +static char rcsid[] = "$Id: yppasswdd_mkpw.c,v 1.13 1997/06/17 10:13:14 niklas Exp $"; #endif +#include <sys/param.h> #include <sys/types.h> #include <sys/stat.h> #include <stdio.h> #include <fcntl.h> #include <rpc/rpc.h> #include <rpcsvc/yppasswd.h> +#include <db.h> #include <pwd.h> #include <stdlib.h> #include <unistd.h> #include <util.h> +#include <string.h> +#include <syslog.h> extern int noshell; extern int nogecos; extern int nopw; extern int make; extern char make_arg[]; +extern char *dir; int badchars(base) @@ -71,27 +76,96 @@ badchars(base) } int +subst(s, from, to) + char *s; + char from, to; +{ + int n = 0; + + while (*s) { + if (*s == from) { + *s = to; + n++; + } + s++; + } + return (n); +} + +int make_passwd(argp) yppasswd *argp; { - struct passwd *pw; + struct passwd pw; int pfd, tfd; - char buf[10], *p; - int alen; + char buf[10], *bp = NULL, *p, *t; + int n; + ssize_t cnt; + size_t resid; + struct stat st; + char *master; - pw = getpwnam(argp->newpw.pw_name); - if (!pw) - return (1); - - if (strcmp(crypt(argp->oldpass, pw->pw_passwd), pw->pw_passwd) != 0) + pw_init(); + if (dir) + pw_setdir(dir); + master = pw_file(_PATH_MASTERPASSWD); + if (!master) return (1); + pfd = open(master, O_RDONLY); + if (pfd < 0) + goto fail; + if (fstat(pfd, &st)) + goto fail; + p = bp = malloc((resid = st.st_size) + 1); + do { + cnt = read(pfd, p, resid); + if (cnt < 0) + goto fail; + p += cnt; + resid -= cnt; + } while (resid > 0); + close(pfd); + pfd = -1; + *p = '\0'; /* Buf oflow prevention */ + + p = bp; + subst(p, '\n', '\0'); + for (n = 1; p < bp + st.st_size; n++, p = t) { + t = strchr(p, '\0') + 1; + cnt = subst(p, ':', '\0'); + if (cnt != 9) { + syslog(LOG_WARNING, "bad entry at line %d of %s", n, + master); + continue; + } + + if (strcmp(p, argp->newpw.pw_name) == 0) + break; + } + if (p >= bp + st.st_size) + goto fail; + +#define EXPAND(e) e = p; while (*p++); + EXPAND(pw.pw_name); + EXPAND(pw.pw_passwd); + pw.pw_uid = atoi(p); EXPAND(t); + pw.pw_gid = atoi(p); EXPAND(t); + EXPAND(pw.pw_class); + pw.pw_change = (time_t)atol(p); EXPAND(t); + pw.pw_expire = (time_t)atol(p); EXPAND(t); + EXPAND(pw.pw_gecos); + EXPAND(pw.pw_dir); + EXPAND(pw.pw_shell); + + if (strcmp(crypt(argp->oldpass, pw.pw_passwd), pw.pw_passwd) != 0) + goto fail; if (!nopw && badchars(argp->newpw.pw_passwd)) - return (1); + goto fail; if (!nogecos && badchars(argp->newpw.pw_gecos)) - return (1); + goto fail; if (!nogecos && badchars(argp->newpw.pw_shell)) - return (1); + goto fail; /* * Get the new password. Reset passwd change time to zero; when @@ -99,64 +173,48 @@ make_passwd(argp) * class and reset the timer. */ if (!nopw) { - pw->pw_passwd = argp->newpw.pw_passwd; - pw->pw_change = 0; + pw.pw_passwd = argp->newpw.pw_passwd; + pw.pw_change = 0; } if (!nogecos) - pw->pw_gecos = argp->newpw.pw_gecos; + pw.pw_gecos = argp->newpw.pw_gecos; if (!noshell) - pw->pw_shell = argp->newpw.pw_shell; + pw.pw_shell = argp->newpw.pw_shell; - for (alen = 0, p = pw->pw_gecos; *p; p++) + for (n = 0, p = pw.pw_gecos; *p; p++) if (*p == '&') - alen = alen + strlen(pw->pw_name) - 1; - if (strlen(pw->pw_name) + 1 + strlen(pw->pw_passwd) + 1 + - strlen((sprintf(buf, "%d", pw->pw_uid), buf)) + 1 + - strlen((sprintf(buf, "%d", pw->pw_gid), buf)) + 1 + - strlen(pw->pw_gecos) + alen + 1 + strlen(pw->pw_dir) + 1 + - strlen(pw->pw_shell) >= 1023) { - return (1); + n = n + strlen(pw.pw_name) - 1; + if (strlen(pw.pw_name) + 1 + strlen(pw.pw_passwd) + 1 + + strlen((sprintf(buf, "%d", pw.pw_uid), buf)) + 1 + + strlen((sprintf(buf, "%d", pw.pw_gid), buf)) + 1 + + strlen(pw.pw_gecos) + n + 1 + strlen(pw.pw_dir) + 1 + + strlen(pw.pw_shell) >= 1023) + goto fail; + + pfd = open(master, O_RDONLY, 0); + if (pfd < 0) { + syslog(LOG_ERR, "cannot open %s", master); + goto fail; } - pfd = open(_PATH_MASTERPASSWD, O_RDONLY, 0); - if (pfd < 0) - pw_error(_PATH_MASTERPASSWD, 1, 1); - - pw_init(); tfd = pw_lock(0); - - pw_copy(pfd, tfd, pw); + pw_copy(pfd, tfd, &pw); pw_mkdb(); + free(bp); if (fork() == 0) { chdir("/var/yp"); - (void) umask(022); + (void)umask(022); system(make_arg); exit(0); } return (0); -} -/* -int -do_mkdb() -{ - int pstat; - pid_t pid; - - (void)printf("%s: rebuilding the database...\n", progname); - (void)fflush(stdout); - if (!(pid = vfork())) { - execl(_PATH_PWD_MKDB, "pwd_mkdb", "-p", tempname, NULL); - warn(_PATH_PWD_MKDB); - warnx("%s: unchanged", _PATH_MASTERPASSWD); - pw_abort(); - _exit(1); - } - pid = waitpid(pid, &pstat, 0); - if (pid == -1 || !WIFEXITED(pstat) || WEXITSTATUS(pstat) != 0) - return(0); - (void)printf("%s: done\n", progname); - return(1); +fail: + if (bp) + free(bp); + if (pfd >= 0) + close(pfd); + free(master); + return (1); } -*/ |