Browse Source

Add support to handle password files in directories other than /etc

OPENBSD_2_2
niklas 27 years ago
parent
commit
58f7db1ec4
4 changed files with 117 additions and 29 deletions
  1. +3
    -1
      src/lib/libutil/Makefile
  2. +91
    -27
      src/lib/libutil/passwd.c
  3. +20
    -0
      src/lib/libutil/pw_init.3
  4. +3
    -1
      src/lib/libutil/util.h

+ 3
- 1
src/lib/libutil/Makefile View File

@ -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 $ # $NetBSD: Makefile,v 1.8 1996/05/16 07:03:28 thorpej Exp $
LIB= util LIB= util
@ -16,6 +16,8 @@ MLINKS+=login.3 logout.3
MLINKS+=login.3 logwtmp.3 MLINKS+=login.3 logwtmp.3
MLINKS+=openpty.3 login_tty.3 MLINKS+=openpty.3 login_tty.3
MLINKS+=openpty.3 forkpty.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_edit.3
MLINKS+=pw_init.3 pw_prompt.3 MLINKS+=pw_init.3 pw_prompt.3
MLINKS+=pw_init.3 pw_copy.3 MLINKS+=pw_init.3 pw_copy.3


+ 91
- 27
src/lib/libutil/passwd.c View File

@ -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 * Copyright (c) 1987, 1993, 1994, 1995
* The Regents of the University of California. All rights reserved. * The Regents of the University of California. All rights reserved.
@ -33,7 +34,7 @@
*/ */
#if defined(LIBC_SCCS) && !defined(lint) #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 */ #endif /* LIBC_SCCS and not lint */
#include <sys/types.h> #include <sys/types.h>
@ -65,6 +66,10 @@ static const char options[NUM_OPTIONS][2][80] =
{"ypcipher", "old"} {"ypcipher", "old"}
}; };
static char pw_defdir[] = "/etc";
static char *pw_dir = pw_defdir;
static char *pw_lck;
/* Removes trailers. */ /* Removes trailers. */
static void static void
remove_trailing_space(line) remove_trailing_space(line)
@ -121,12 +126,31 @@ pw_default(option)
return NULL; 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. * at the moment this is only for choosing the cipher to use.
* It could easily be used for other authentication methods as * It could easily be used for other authentication methods as
* well. * well.
*/ */
void void
pw_getconf(data, max, key, option) pw_getconf(data, max, key, option)
char *data; char *data;
@ -143,14 +167,18 @@ pw_getconf(data, max, key, option)
result[0] = '\0'; 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); strncpy(data, p, max - 1);
data[max - 1] = '\0'; data[max - 1] = '\0';
} else } else
data[0] = '\0'; data[0] = '\0';
return; return;
} }
free(p);
while (!found && (got || read_line(fp, line, LINE_MAX))) { while (!found && (got || read_line(fp, line, LINE_MAX))) {
got = 0; got = 0;
@ -193,6 +221,26 @@ pw_getconf(data, max, key, option)
data[max - 1] = '\0'; 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 int
pw_lock(retries) pw_lock(retries)
int retries; int retries;
@ -200,16 +248,17 @@ pw_lock(retries)
int i, fd; int i, fd;
mode_t old_mode; mode_t old_mode;
if (!pw_lck)
return (-1);
/* Acquire the lock file. */ /* Acquire the lock file. */
old_mode = umask(0); 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++) { for (i = 0; i < retries && fd < 0 && errno == EEXIST; i++) {
sleep(1); 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); umask(old_mode);
return(fd);
return (fd);
} }
int int
@ -217,23 +266,25 @@ pw_mkdb()
{ {
int pstat; int pstat;
pid_t pid; pid_t pid;
char *lock;
pid = vfork(); pid = vfork();
if (pid == 0) { 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); _exit(1);
} }
pid = waitpid(pid, &pstat, 0); pid = waitpid(pid, &pstat, 0);
if (pid == -1 || !WIFEXITED(pstat) || WEXITSTATUS(pstat) != 0) if (pid == -1 || !WIFEXITED(pstat) || WEXITSTATUS(pstat) != 0)
return(-1);
return(0);
return (-1);
return (0);
} }
int int
pw_abort() 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 /* Everything below this point is intended for the convenience of programs
@ -276,6 +327,9 @@ pw_init()
(void)signal(SIGQUIT, SIG_IGN); (void)signal(SIGQUIT, SIG_IGN);
(void)signal(SIGTERM, SIG_IGN); (void)signal(SIGTERM, SIG_IGN);
(void)signal(SIGCONT, pw_cont); (void)signal(SIGCONT, pw_cont);
if (!pw_lck)
pw_lck = pw_file(_PATH_MASTERPASSWD_LOCK);
} }
void void
@ -287,8 +341,12 @@ pw_edit(notsetuid, filename)
char *p, *editor; char *p, *editor;
char *argp[] = {"sh", "-c", NULL, NULL}; char *argp[] = {"sh", "-c", NULL, NULL};
if (!filename)
filename = _PATH_MASTERPASSWD_LOCK;
if (!filename) {
filename = pw_lck;
if (!filename)
return;
}
if (!(editor = getenv("EDITOR"))) if (!(editor = getenv("EDITOR")))
editor = _PATH_VI; editor = _PATH_VI;
@ -345,18 +403,21 @@ pw_copy(ffd, tfd, pw)
int ffd, tfd; int ffd, tfd;
struct passwd *pw; 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"))) if (!(from = fdopen(ffd, "r")))
pw_error(_PATH_MASTERPASSWD, 1, 1);
pw_error(master, 1, 1);
if (!(to = fdopen(tfd, "w"))) 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);) { for (done = 0; fgets(buf, sizeof(buf), from);) {
if (!strchr(buf, '\n')) { if (!strchr(buf, '\n')) {
warnx("%s: line too long", _PATH_MASTERPASSWD);
warnx("%s: line too long", master);
pw_error(NULL, 0, 1); pw_error(NULL, 0, 1);
} }
if (done) { if (done) {
@ -366,7 +427,7 @@ pw_copy(ffd, tfd, pw)
continue; continue;
} }
if (!(p = strchr(buf, ':'))) { if (!(p = strchr(buf, ':'))) {
warnx("%s: corrupted entry", _PATH_MASTERPASSWD);
warnx("%s: corrupted entry", master);
pw_error(NULL, 0, 1); pw_error(NULL, 0, 1);
} }
*p = '\0'; *p = '\0';
@ -392,7 +453,8 @@ pw_copy(ffd, tfd, pw)
pw->pw_dir, pw->pw_shell); pw->pw_dir, pw->pw_shell);
if (ferror(to)) if (ferror(to))
err: pw_error(NULL, 1, 1);
err:
pw_error(NULL, 0, 1);
(void)fclose(to); (void)fclose(to);
} }
@ -492,10 +554,12 @@ pw_error(name, err, eval)
const char *name; const char *name;
int err, eval; int err, eval;
{ {
char *master = pw_file(_PATH_MASTERPASSWD);
if (err) if (err)
warn(name); warn(name);
warnx("%s: unchanged", _PATH_MASTERPASSWD);
if (master)
warnx("%s: unchanged", master);
pw_abort(); pw_abort();
exit(eval); exit(eval);
} }

+ 20
- 0
src/lib/libutil/pw_init.3 View File

@ -38,6 +38,8 @@
.Os .Os
.Sh NAME .Sh NAME
.Nm pw_init , .Nm pw_init ,
.Nm pw_setdir ,
.Nm pw_file ,
.Nm pw_edit , .Nm pw_edit ,
.Nm pw_prompt , .Nm pw_prompt ,
.Nm pw_copy , .Nm pw_copy ,
@ -50,6 +52,10 @@
.Ft void .Ft void
.Fn pw_init .Fn pw_init
.Ft void .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" .Fn pw_edit "int notsetuid" "const char *filename"
.Ft void .Ft void
.Fn pw_prompt .Fn pw_prompt
@ -73,6 +79,20 @@ contents of the passwd database into a world-readable file), and
disabling most signals. disabling most signals.
.Pp .Pp
The 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 .Fn pw_edit
function runs an editor (named by the environment variable EDITOR, or function runs an editor (named by the environment variable EDITOR, or
.Pa /usr/bin/vi .Pa /usr/bin/vi


+ 3
- 1
src/lib/libutil/util.h View File

@ -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 $ */ /* $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 *)); int logout __P((const char *));
void logwtmp __P((const char *, const char *, const char *)); void logwtmp __P((const char *, const char *, const char *));
int opendev __P((char *, int, int, 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_lock __P((int retries));
int pw_mkdb __P((void)); int pw_mkdb __P((void));
int pw_abort __P((void)); int pw_abort __P((void));


Loading…
Cancel
Save