summaryrefslogtreecommitdiff
path: root/libexec/rpc.yppasswdd/yppasswdd_mkpw.c
diff options
context:
space:
mode:
authorNiklas Hallqvist <niklas@cvs.openbsd.org>1997-06-17 10:13:15 +0000
committerNiklas Hallqvist <niklas@cvs.openbsd.org>1997-06-17 10:13:15 +0000
commit4fa365e5f68d2c3c6707044db9557cc80667ebe7 (patch)
treef28c89956c0a3617aa7cdf18b1f1133be83c7e10 /libexec/rpc.yppasswdd/yppasswdd_mkpw.c
parent1e5d8b4f0d89c2f7dff323f6dacc2d5c47c7d54e (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.c168
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);
}
-*/