Browse Source

Change pw_copy(3) to take a 3rd arguement, the existing passwd entry.

This allows an application to only update a password entry if it is
in the state it expects.  Additionally, if the old passwd struct
is specified the new one may have a different pw_name field since
matching is done on the original.  Adapted from FreeBSD.
OPENBSD_3_6
millert 20 years ago
parent
commit
d0d2e5a2ff
4 changed files with 49 additions and 13 deletions
  1. +31
    -6
      src/lib/libutil/passwd.c
  2. +15
    -4
      src/lib/libutil/pw_init.3
  3. +1
    -1
      src/lib/libutil/shlib_version
  4. +2
    -2
      src/lib/libutil/util.h

+ 31
- 6
src/lib/libutil/passwd.c View File

@ -1,4 +1,4 @@
/* $OpenBSD: passwd.c,v 1.42 2003/06/26 16:34:42 deraadt Exp $ */
/* $OpenBSD: passwd.c,v 1.43 2004/04/20 23:20:07 millert Exp $ */
/* /*
* Copyright (c) 1987, 1993, 1994, 1995 * Copyright (c) 1987, 1993, 1994, 1995
@ -30,7 +30,7 @@
*/ */
#if defined(LIBC_SCCS) && !defined(lint) #if defined(LIBC_SCCS) && !defined(lint)
static const char rcsid[] = "$OpenBSD: passwd.c,v 1.42 2003/06/26 16:34:42 deraadt Exp $";
static const char rcsid[] = "$OpenBSD: passwd.c,v 1.43 2004/04/20 23:20:07 millert Exp $";
#endif /* LIBC_SCCS and not lint */ #endif /* LIBC_SCCS and not lint */
#include <sys/types.h> #include <sys/types.h>
@ -422,12 +422,27 @@ pw_prompt(void)
pw_error(NULL, 0, 0); pw_error(NULL, 0, 0);
} }
static int
pw_equal(const struct passwd *pw1, const struct passwd *pw2)
{
return (strcmp(pw1->pw_name, pw2->pw_name) == 0 &&
pw1->pw_uid == pw2->pw_uid &&
pw1->pw_gid == pw2->pw_gid &&
strcmp(pw1->pw_class, pw2->pw_class) == 0 &&
pw1->pw_change == pw2->pw_change &&
pw1->pw_expire == pw2->pw_expire &&
strcmp(pw1->pw_gecos, pw2->pw_gecos) == 0 &&
strcmp(pw1->pw_dir, pw2->pw_dir) == 0 &&
strcmp(pw1->pw_shell, pw2->pw_shell) == 0);
}
void void
pw_copy(int ffd, int tfd, struct passwd *pw)
pw_copy(int ffd, int tfd, const struct passwd *pw, const struct passwd *opw)
{ {
struct passwd tpw;
FILE *from, *to; FILE *from, *to;
int done; int done;
char *p, buf[8192];
char *p, *ep, buf[8192];
char *master = pw_file(_PATH_MASTERPASSWD); char *master = pw_file(_PATH_MASTERPASSWD);
if (!master) if (!master)
@ -438,7 +453,7 @@ pw_copy(int ffd, int tfd, struct passwd *pw)
pw_error(pw_lck ? pw_lck : NULL, pw_lck ? 1 : 0, 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 ((ep = strchr(buf, '\n')) == NULL) {
warnx("%s: line too long", master); warnx("%s: line too long", master);
pw_error(NULL, 0, 1); pw_error(NULL, 0, 1);
} }
@ -453,13 +468,23 @@ pw_copy(int ffd, int tfd, struct passwd *pw)
pw_error(NULL, 0, 1); pw_error(NULL, 0, 1);
} }
*p = '\0'; *p = '\0';
if (strcmp(buf, pw->pw_name)) {
if (strcmp(buf, opw ? opw->pw_name : pw->pw_name)) {
*p = ':'; *p = ':';
(void)fprintf(to, "%s", buf); (void)fprintf(to, "%s", buf);
if (ferror(to)) if (ferror(to))
goto err; goto err;
continue; continue;
} }
if (opw != NULL) {
*p = ':';
*ep = '\0';
if (!pw_scan(buf, &tpw, NULL))
pw_error(NULL, 0, 1);
if (!pw_equal(&tpw, opw)) {
warnx("%s: inconsistent entry", master);
pw_error(NULL, 0, 1);
}
}
(void)fprintf(to, "%s:%s:%u:%u:%s:%d:%d:%s:%s:%s\n", (void)fprintf(to, "%s:%s:%u:%u:%s:%d:%d:%s:%s:%s\n",
pw->pw_name, pw->pw_passwd, (u_int)pw->pw_uid, pw->pw_name, pw->pw_passwd, (u_int)pw->pw_uid,
(u_int)pw->pw_gid, pw->pw_class, pw->pw_change, (u_int)pw->pw_gid, pw->pw_class, pw->pw_change,


+ 15
- 4
src/lib/libutil/pw_init.3 View File

@ -1,4 +1,4 @@
.\" $OpenBSD: pw_init.3,v 1.7 2003/06/02 20:18:42 millert Exp $
.\" $OpenBSD: pw_init.3,v 1.8 2004/04/20 23:20:07 millert Exp $
.\" .\"
.\" Copyright (c) 1995 .\" Copyright (c) 1995
.\" The Regents of the University of California. All rights reserved. .\" The Regents of the University of California. All rights reserved.
@ -58,7 +58,7 @@
.Ft void .Ft void
.Fn pw_prompt .Fn pw_prompt
.Ft void .Ft void
.Fn pw_copy "int ffd" "int tfd" "struct passwd *pw"
.Fn pw_copy "int ffd" "int tfd" "const struct passwd *pw" "const struct passwd *opw"
.Ft int .Ft int
.Fn pw_scan "char *bp" "struct passwd *pw" "int *flags" .Fn pw_scan "char *bp" "struct passwd *pw" "int *flags"
.Ft void .Ft void
@ -125,9 +125,20 @@ function reads a passwd file from
.Fa ffd .Fa ffd
and writes it to and writes it to
.Fa tfd , .Fa tfd ,
updating the entry corresponding to pw->pw_name with the information
in
updating the entry corresponding to pw-\*(Gtpw_name
with the information in
.Fa pw . .Fa pw .
If
.Fa opw
is not NULL, opw-\*(Gtpw_name will be used for matching instead.
Additionally, if the existing entry does not match
.Fa opw ,
the operation is aborted.
The use of
.Fa opw
allows the caller to change the user name in an entry as well as
guarantee that the entry being replaced has not changed in the
meantime.
.Pp .Pp
The The
.Fn pw_scan .Fn pw_scan


+ 1
- 1
src/lib/libutil/shlib_version View File

@ -1,2 +1,2 @@
major=9
major=10
minor=0 minor=0

+ 2
- 2
src/lib/libutil/util.h View File

@ -1,4 +1,4 @@
/* $OpenBSD: util.h,v 1.24 2003/06/02 20:18:42 millert Exp $ */
/* $OpenBSD: util.h,v 1.25 2004/04/20 23:20:07 millert 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 $ */
/*- /*-
@ -97,7 +97,7 @@ int pw_abort(void);
void pw_init(void); void pw_init(void);
void pw_edit(int, const char *); void pw_edit(int, const char *);
void pw_prompt(void); void pw_prompt(void);
void pw_copy(int, int, struct passwd *);
void pw_copy(int, int, const struct passwd *, const struct passwd *);
void pw_getconf(char *, size_t, const char *, const char *); void pw_getconf(char *, size_t, const char *, const char *);
int pw_scan(char *, struct passwd *, int *); int pw_scan(char *, struct passwd *, int *);
void pw_error(const char *, int, int); void pw_error(const char *, int, int);


Loading…
Cancel
Save