diff options
author | Todd C. Miller <millert@cvs.openbsd.org> | 2002-07-31 22:08:43 +0000 |
---|---|---|
committer | Todd C. Miller <millert@cvs.openbsd.org> | 2002-07-31 22:08:43 +0000 |
commit | a307fd5af8a64e548d9c1607e22f1849dd79a745 (patch) | |
tree | a050683deae2ff2aab7ee452990347a929371e78 /usr.bin | |
parent | 245837def3aec0ed575c4e9fc1522d98ca2142fc (diff) |
When I got removed the use of atexit() I missed the fact that edit()
calls pw_error() which in turn calls exit(). Now edit() returns
its status so the temp file gets cleaned up nicely if the user makes
no changes or if an error occurred. Problem noticed by deraadt@
Diffstat (limited to 'usr.bin')
-rw-r--r-- | usr.bin/chpass/chpass.c | 19 | ||||
-rw-r--r-- | usr.bin/chpass/chpass.h | 9 | ||||
-rw-r--r-- | usr.bin/chpass/edit.c | 13 |
3 files changed, 30 insertions, 11 deletions
diff --git a/usr.bin/chpass/chpass.c b/usr.bin/chpass/chpass.c index 38e8d960b46..dfa33686041 100644 --- a/usr.bin/chpass/chpass.c +++ b/usr.bin/chpass/chpass.c @@ -1,4 +1,4 @@ -/* $OpenBSD: chpass.c,v 1.25 2002/06/27 22:02:08 deraadt Exp $ */ +/* $OpenBSD: chpass.c,v 1.26 2002/07/31 22:08:41 millert Exp $ */ /* $NetBSD: chpass.c,v 1.8 1996/05/15 21:50:43 jtc Exp $ */ /*- @@ -44,7 +44,7 @@ static char copyright[] = #if 0 static char sccsid[] = "@(#)chpass.c 8.4 (Berkeley) 4/2/94"; #else -static char rcsid[] = "$OpenBSD: chpass.c,v 1.25 2002/06/27 22:02:08 deraadt Exp $"; +static char rcsid[] = "$OpenBSD: chpass.c,v 1.26 2002/07/31 22:08:41 millert Exp $"; #endif #endif /* not lint */ @@ -178,14 +178,27 @@ main(int argc, char *argv[]) /* Edit the user passwd information if requested. */ if (op == EDITENTRY) { char tempname[] = __CONCAT(_PATH_VARTMP,"pw.XXXXXXXX"); + int edit_status; dfd = mkstemp(tempname); if (dfd == -1 || fcntl(dfd, F_SETFD, 1) == -1) pw_error(tempname, 1, 1); display(tempname, dfd, pw); - edit(tempname, pw); + edit_status = edit(tempname, pw); close(dfd); unlink(tempname); + + switch (edit_status) { + case EDIT_OK: + break; + case EDIT_NOCHANGE: + pw_error(NULL, 0, 0); + break; + case EDIT_ERROR: + default: + pw_error(tempname, 1, 1); + break; + } } /* Drop user's real uid and block all signals to avoid a DoS. */ diff --git a/usr.bin/chpass/chpass.h b/usr.bin/chpass/chpass.h index 0be09522559..ec0f17d4d2b 100644 --- a/usr.bin/chpass/chpass.h +++ b/usr.bin/chpass/chpass.h @@ -1,4 +1,4 @@ -/* $OpenBSD: chpass.h,v 1.6 2002/06/27 22:02:08 deraadt Exp $ */ +/* $OpenBSD: chpass.h,v 1.7 2002/07/31 22:08:42 millert Exp $ */ /* $NetBSD: chpass.h,v 1.4 1996/05/15 21:50:44 jtc Exp $ */ /* @@ -51,12 +51,17 @@ typedef struct _entry { #define E_NAME 7 #define E_SHELL 12 +/* edit() return values. */ +#define EDIT_OK 0 +#define EDIT_NOCHANGE 1 +#define EDIT_ERROR -1 + extern ENTRY list[]; extern uid_t uid; int atot(char *, time_t *); void display(char *, int, struct passwd *); -void edit(char *, struct passwd *); +int edit(char *, struct passwd *); char *ok_shell(char *); int p_change(char *, struct passwd *, ENTRY *); int p_class(char *, struct passwd *, ENTRY *); diff --git a/usr.bin/chpass/edit.c b/usr.bin/chpass/edit.c index d62dcd1fb12..28dcf1074bf 100644 --- a/usr.bin/chpass/edit.c +++ b/usr.bin/chpass/edit.c @@ -1,4 +1,4 @@ -/* $OpenBSD: edit.c,v 1.22 2002/06/27 19:02:40 deraadt Exp $ */ +/* $OpenBSD: edit.c,v 1.23 2002/07/31 22:08:42 millert Exp $ */ /* $NetBSD: edit.c,v 1.6 1996/05/15 21:50:45 jtc Exp $ */ /*- @@ -38,7 +38,7 @@ #if 0 static char sccsid[] = "@(#)edit.c 8.3 (Berkeley) 4/2/94"; #else -static char rcsid[] = "$OpenBSD: edit.c,v 1.22 2002/06/27 19:02:40 deraadt Exp $"; +static char rcsid[] = "$OpenBSD: edit.c,v 1.23 2002/07/31 22:08:42 millert Exp $"; #endif #endif /* not lint */ @@ -58,7 +58,7 @@ static char rcsid[] = "$OpenBSD: edit.c,v 1.22 2002/06/27 19:02:40 deraadt Exp $ #include "chpass.h" -void +int edit(tempname, pw) char *tempname; struct passwd *pw; @@ -67,19 +67,20 @@ edit(tempname, pw) for (;;) { if (lstat(tempname, &begin) == -1 || S_ISLNK(begin.st_mode)) - pw_error(tempname, 1, 1); + return (EDIT_ERROR); pw_edit(1, tempname); if (lstat(tempname, &end) == -1 || S_ISLNK(end.st_mode)) - pw_error(tempname, 1, 1); + return (EDIT_ERROR); if (begin.st_mtime == end.st_mtime && begin.st_size == end.st_size) { warnx("no changes made"); - pw_error(NULL, 0, 0); + return (EDIT_NOCHANGE); } if (verify(tempname, pw)) break; pw_prompt(); } + return(EDIT_OK); } /* |