summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/libutil/Makefile4
-rw-r--r--lib/libutil/passwd.c118
-rw-r--r--lib/libutil/pw_init.320
-rw-r--r--lib/libutil/util.h4
4 files changed, 117 insertions, 29 deletions
diff --git a/lib/libutil/Makefile b/lib/libutil/Makefile
index d03c964ad1b..4f6c215bc7c 100644
--- a/lib/libutil/Makefile
+++ b/lib/libutil/Makefile
@@ -1,4 +1,4 @@
-# $OpenBSD: Makefile,v 1.13 1997/04/27 20:56:18 millert Exp $
+# $OpenBSD: Makefile,v 1.14 1997/06/17 10:10:41 niklas Exp $
# $NetBSD: Makefile,v 1.8 1996/05/16 07:03:28 thorpej Exp $
LIB= util
@@ -16,6 +16,8 @@ MLINKS+=login.3 logout.3
MLINKS+=login.3 logwtmp.3
MLINKS+=openpty.3 login_tty.3
MLINKS+=openpty.3 forkpty.3
+MLINKS+=pw_init.3 pw_setdir.3
+MLINKS+=pw_init.3 pw_file.3
MLINKS+=pw_init.3 pw_edit.3
MLINKS+=pw_init.3 pw_prompt.3
MLINKS+=pw_init.3 pw_copy.3
diff --git a/lib/libutil/passwd.c b/lib/libutil/passwd.c
index e7ed1758891..91f15e624e4 100644
--- a/lib/libutil/passwd.c
+++ b/lib/libutil/passwd.c
@@ -1,4 +1,5 @@
-/* $OpenBSD: passwd.c,v 1.9 1997/04/10 20:05:49 provos Exp $ */
+/* $OpenBSD: passwd.c,v 1.10 1997/06/17 10:10:42 niklas Exp $ */
+
/*
* Copyright (c) 1987, 1993, 1994, 1995
* The Regents of the University of California. All rights reserved.
@@ -33,7 +34,7 @@
*/
#if defined(LIBC_SCCS) && !defined(lint)
-static char rcsid[] = "$NetBSD: passwd.c,v 1.1.4.1 1996/06/02 19:48:31 ghudson Exp $";
+static char rcsid[] = "$OpenBSD: passwd.c,v 1.10 1997/06/17 10:10:42 niklas Exp $";
#endif /* LIBC_SCCS and not lint */
#include <sys/types.h>
@@ -65,6 +66,10 @@ static const char options[NUM_OPTIONS][2][80] =
{"ypcipher", "old"}
};
+static char pw_defdir[] = "/etc";
+static char *pw_dir = pw_defdir;
+static char *pw_lck;
+
/* Removes trailers. */
static void
remove_trailing_space(line)
@@ -121,12 +126,31 @@ pw_default(option)
return NULL;
}
-/* Retrieve password information from the /etc/passwd.conf file,
+char *
+pw_file(nm)
+ const char *nm;
+{
+ const char *p = strrchr(nm, '/');
+ char *new_nm;
+
+ if (p)
+ p++;
+ else
+ p = nm;
+ new_nm = malloc(strlen(pw_dir) + strlen(p) + 2);
+ if (!new_nm)
+ return NULL;
+ sprintf(new_nm, "%s/%s", pw_dir, p);
+ return new_nm;
+}
+
+
+/*
+ * Retrieve password information from the /etc/passwd.conf file,
* at the moment this is only for choosing the cipher to use.
* It could easily be used for other authentication methods as
* well.
*/
-
void
pw_getconf(data, max, key, option)
char *data;
@@ -143,14 +167,18 @@ pw_getconf(data, max, key, option)
result[0] = '\0';
- if ((fp = fopen(_PATH_PASSWDCONF, "r")) == NULL) {
- if((p=(char *)pw_default(option))) {
+ p = pw_file(_PATH_PASSWDCONF);
+ if (!p || (fp = fopen(p, "r")) == NULL) {
+ if (p)
+ free(p);
+ if((p = (char *)pw_default(option))) {
strncpy(data, p, max - 1);
data[max - 1] = '\0';
} else
data[0] = '\0';
return;
}
+ free(p);
while (!found && (got || read_line(fp, line, LINE_MAX))) {
got = 0;
@@ -193,6 +221,26 @@ pw_getconf(data, max, key, option)
data[max - 1] = '\0';
}
+
+void
+pw_setdir(dir)
+ const char *dir;
+{
+ char *p;
+
+ if (strcmp (dir, pw_dir) == 0)
+ return;
+ if (pw_dir != pw_defdir)
+ free(pw_dir);
+ pw_dir = strdup(dir);
+ if (pw_lck) {
+ p = pw_file(pw_lck);
+ free(pw_lck);
+ pw_lck = p;
+ }
+}
+
+
int
pw_lock(retries)
int retries;
@@ -200,16 +248,17 @@ pw_lock(retries)
int i, fd;
mode_t old_mode;
+ if (!pw_lck)
+ return (-1);
/* Acquire the lock file. */
old_mode = umask(0);
- fd = open(_PATH_MASTERPASSWD_LOCK, O_WRONLY|O_CREAT|O_EXCL, 0600);
+ fd = open(pw_lck, O_WRONLY|O_CREAT|O_EXCL, 0600);
for (i = 0; i < retries && fd < 0 && errno == EEXIST; i++) {
sleep(1);
- fd = open(_PATH_MASTERPASSWD_LOCK, O_WRONLY|O_CREAT|O_EXCL,
- 0600);
+ fd = open(pw_lck, O_WRONLY|O_CREAT|O_EXCL, 0600);
}
umask(old_mode);
- return(fd);
+ return (fd);
}
int
@@ -217,23 +266,25 @@ pw_mkdb()
{
int pstat;
pid_t pid;
+ char *lock;
pid = vfork();
if (pid == 0) {
- execl(_PATH_PWD_MKDB, "pwd_mkdb", "-p",
- _PATH_MASTERPASSWD_LOCK, NULL);
+ if (pw_lck)
+ execl(_PATH_PWD_MKDB, "pwd_mkdb", "-p", "-d", pw_dir,
+ pw_lck, NULL);
_exit(1);
}
pid = waitpid(pid, &pstat, 0);
if (pid == -1 || !WIFEXITED(pstat) || WEXITSTATUS(pstat) != 0)
- return(-1);
- return(0);
+ return (-1);
+ return (0);
}
int
pw_abort()
{
- return(unlink(_PATH_MASTERPASSWD_LOCK));
+ return (pw_lck ? unlink(pw_lck) : -1);
}
/* Everything below this point is intended for the convenience of programs
@@ -276,6 +327,9 @@ pw_init()
(void)signal(SIGQUIT, SIG_IGN);
(void)signal(SIGTERM, SIG_IGN);
(void)signal(SIGCONT, pw_cont);
+
+ if (!pw_lck)
+ pw_lck = pw_file(_PATH_MASTERPASSWD_LOCK);
}
void
@@ -287,8 +341,12 @@ pw_edit(notsetuid, filename)
char *p, *editor;
char *argp[] = {"sh", "-c", NULL, NULL};
- if (!filename)
- filename = _PATH_MASTERPASSWD_LOCK;
+ if (!filename) {
+ filename = pw_lck;
+ if (!filename)
+ return;
+ }
+
if (!(editor = getenv("EDITOR")))
editor = _PATH_VI;
@@ -345,18 +403,21 @@ pw_copy(ffd, tfd, pw)
int ffd, tfd;
struct passwd *pw;
{
- FILE *from, *to;
- int done;
- char *p, buf[8192];
+ FILE *from, *to;
+ int done;
+ char *p, buf[8192];
+ char *master = pw_file(_PATH_MASTERPASSWD);
+ if (!master)
+ pw_error(NULL, 0, 1);
if (!(from = fdopen(ffd, "r")))
- pw_error(_PATH_MASTERPASSWD, 1, 1);
+ pw_error(master, 1, 1);
if (!(to = fdopen(tfd, "w")))
- pw_error(_PATH_MASTERPASSWD_LOCK, 1, 1);
+ pw_error(pw_lck ? pw_lck : NULL, pw_lck ? 1 : 0, 1);
for (done = 0; fgets(buf, sizeof(buf), from);) {
if (!strchr(buf, '\n')) {
- warnx("%s: line too long", _PATH_MASTERPASSWD);
+ warnx("%s: line too long", master);
pw_error(NULL, 0, 1);
}
if (done) {
@@ -366,7 +427,7 @@ pw_copy(ffd, tfd, pw)
continue;
}
if (!(p = strchr(buf, ':'))) {
- warnx("%s: corrupted entry", _PATH_MASTERPASSWD);
+ warnx("%s: corrupted entry", master);
pw_error(NULL, 0, 1);
}
*p = '\0';
@@ -392,7 +453,8 @@ pw_copy(ffd, tfd, pw)
pw->pw_dir, pw->pw_shell);
if (ferror(to))
-err: pw_error(NULL, 1, 1);
+err:
+ pw_error(NULL, 0, 1);
(void)fclose(to);
}
@@ -492,10 +554,12 @@ pw_error(name, err, eval)
const char *name;
int err, eval;
{
+ char *master = pw_file(_PATH_MASTERPASSWD);
+
if (err)
warn(name);
-
- warnx("%s: unchanged", _PATH_MASTERPASSWD);
+ if (master)
+ warnx("%s: unchanged", master);
pw_abort();
exit(eval);
}
diff --git a/lib/libutil/pw_init.3 b/lib/libutil/pw_init.3
index 0de0b1a16c2..6d0ac205ea3 100644
--- a/lib/libutil/pw_init.3
+++ b/lib/libutil/pw_init.3
@@ -38,6 +38,8 @@
.Os
.Sh NAME
.Nm pw_init ,
+.Nm pw_setdir ,
+.Nm pw_file ,
.Nm pw_edit ,
.Nm pw_prompt ,
.Nm pw_copy ,
@@ -50,6 +52,10 @@
.Ft void
.Fn pw_init
.Ft void
+.Fn pw_setdir "const char *directory"
+.Ft char *
+.Fn pw_file "const char *filename"
+.Ft void
.Fn pw_edit "int notsetuid" "const char *filename"
.Ft void
.Fn pw_prompt
@@ -73,6 +79,20 @@ contents of the passwd database into a world-readable file), and
disabling most signals.
.Pp
The
+.Fn pw_setdir
+function sets an alternative directory where the rest of the functions looks
+for password-related files. Use this if you are writing utilities that should
+be able to handle password files outside of /etc.
+.Pp
+The
+.Fn pw_file
+function transforms filenames so that they end up in the directory specified
+to the latest
+.Fn pw_setdir
+call. The rule is that all directories are stripped off the given name and
+only the filename is appended to the directory.
+.Pp
+The
.Fn pw_edit
function runs an editor (named by the environment variable EDITOR, or
.Pa /usr/bin/vi
diff --git a/lib/libutil/util.h b/lib/libutil/util.h
index 6c2f4a304a9..acadd530050 100644
--- a/lib/libutil/util.h
+++ b/lib/libutil/util.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: util.h,v 1.5 1997/02/16 19:59:23 provos Exp $ */
+/* $OpenBSD: util.h,v 1.6 1997/06/17 10:10:43 niklas Exp $ */
/* $NetBSD: util.h,v 1.2 1996/05/16 07:00:22 thorpej Exp $ */
/*-
@@ -57,6 +57,8 @@ int login_tty __P((int));
int logout __P((const char *));
void logwtmp __P((const char *, const char *, const char *));
int opendev __P((char *, int, int, char **));
+void pw_setdir __P((const char *));
+char *pw_file __P((const char *));
int pw_lock __P((int retries));
int pw_mkdb __P((void));
int pw_abort __P((void));