From d7fa77f03b90e1568d840da7d8f8af8012cb43c8 Mon Sep 17 00:00:00 2001 From: nekral-guest Date: Wed, 16 Feb 2011 20:32:16 +0000 Subject: [PATCH] * lib/groupio.c, lib/sgroupio.c, lib/shadowio.c, lib/pwio.c: Check entry validity before commits to databases. * libmisc/fields.c, libmisc/Makefile.am, lib/fields.c, lib/Makefile.am, po/POTFILES.in: fields.c moved from libmisc to lib. --- ChangeLog | 8 ++++++++ lib/Makefile.am | 1 + {libmisc => lib}/fields.c | 4 ++++ lib/groupio.c | 17 +++++++++++++++++ lib/pwio.c | 11 +++++++++++ lib/sgroupio.c | 26 ++++++++++++++++++++++++++ lib/shadowio.c | 6 ++++++ libmisc/Makefile.am | 1 - libmisc/user_busy.c | 15 ++++++++++++--- po/POTFILES.in | 2 +- 10 files changed, 86 insertions(+), 5 deletions(-) rename {libmisc => lib}/fields.c (99%) diff --git a/ChangeLog b/ChangeLog index 2b562632..06a9a997 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,11 @@ +2010-02-15 Nicolas François + + * lib/groupio.c, lib/sgroupio.c, lib/shadowio.c, lib/pwio.c: Check + entry validity before commits to databases. + * libmisc/fields.c, libmisc/Makefile.am, lib/fields.c, + lib/Makefile.am, po/POTFILES.in: fields.c moved from libmisc to + lib. + 2010-02-13 Nicolas François * NEWS, src/chfn.c, src/chsh.c: Fix CVE-2011-0721: forbid \n in diff --git a/lib/Makefile.am b/lib/Makefile.am index ee7ec6ee..a04623cd 100644 --- a/lib/Makefile.am +++ b/lib/Makefile.am @@ -14,6 +14,7 @@ libshadow_la_SOURCES = \ encrypt.c \ exitcodes.h \ faillog.h \ + fields.c \ fputsx.c \ getdef.c \ getdef.h \ diff --git a/libmisc/fields.c b/lib/fields.c similarity index 99% rename from libmisc/fields.c rename to lib/fields.c index a673659d..12377dc4 100644 --- a/libmisc/fields.c +++ b/lib/fields.c @@ -54,6 +54,10 @@ int valid_field (const char *field, const char *illegal) const char *cp; int err = 0; + if (NULL == cp) { + return -1; + } + /* For each character of field, search if it appears in the list * of illegal characters. */ for (cp = field; '\0' != *cp; cp++) { diff --git a/lib/groupio.c b/lib/groupio.c index e6fa69a1..109c5886 100644 --- a/lib/groupio.c +++ b/lib/groupio.c @@ -80,6 +80,23 @@ static int group_put (const void *ent, FILE * file) { const struct group *gr = ent; + if ( (NULL == gr) + || (valid_field (gr->gr_name, ":\n") == -1) + || (valid_field (gr->gr_passwd, ":\n") == -1) + || (gr->gr_gid == (gid_t)-1)) { + return -1; + } + + /* FIXME: fail also if gr->gr_mem == NULL ?*/ + if (NULL != gr->gr_mem) { + size_t i; + for (i = 0; NULL != gr->gr_mem[i]; i++) { + if (valid_field (gr->gr_mem[i], ",:\n") == -1) { + return -1; + } + } + } + return (putgrent (gr, file) == -1) ? -1 : 0; } diff --git a/lib/pwio.c b/lib/pwio.c index fc6d8af4..793c2e5a 100644 --- a/lib/pwio.c +++ b/lib/pwio.c @@ -72,6 +72,17 @@ static int passwd_put (const void *ent, FILE * file) { const struct passwd *pw = ent; + if ( (NULL == pw) + || (valid_field (pw->pw_name, ":\n") == -1) + || (valid_field (pw->pw_passwd, ":\n") == -1) + || (pw->pw_uid == (uid_t)-1) + || (pw->pw_gid == (gid_t)-1) + || (valid_field (pw->pw_gecos, ":\n") == -1) + || (valid_field (pw->pw_dir, ":\n") == -1) + || (valid_field (pw->pw_shell, ":\n") == -1)) { + return -1; + } + return (putpwent (pw, file) == -1) ? -1 : 0; } diff --git a/lib/sgroupio.c b/lib/sgroupio.c index 836fc276..35238331 100644 --- a/lib/sgroupio.c +++ b/lib/sgroupio.c @@ -169,6 +169,32 @@ static int gshadow_put (const void *ent, FILE * file) { const struct sgrp *sg = ent; + if ( (NULL == sg) + || (valid_field (sg->sg_name, ":\n") == -1) + || (valid_field (sg->sg_passwd, ":\n") == -1)) { + return -1; + } + + /* FIXME: fail also if sg->sg_adm == NULL ?*/ + if (NULL != sg->sg_adm) { + size_t i; + for (i = 0; NULL != sg->sg_adm[i]; i++) { + if (valid_field (sg->sg_adm[i], ",:\n") == -1) { + return -1; + } + } + } + + /* FIXME: fail also if sg->sg_mem == NULL ?*/ + if (NULL != sg->sg_mem) { + size_t i; + for (i = 0; NULL != sg->sg_mem[i]; i++) { + if (valid_field (sg->sg_mem[i], ",:\n") == -1) { + return -1; + } + } + } + return (putsgent (sg, file) == -1) ? -1 : 0; } diff --git a/lib/shadowio.c b/lib/shadowio.c index aec90cd9..2930e65d 100644 --- a/lib/shadowio.c +++ b/lib/shadowio.c @@ -76,6 +76,12 @@ static int shadow_put (const void *ent, FILE * file) { const struct spwd *sp = ent; + if ( (NULL == sp) + || (valid_field (sp->sp_namp, ":\n") == -1) + || (valid_field (sp->sp_pwdp, ":\n") == -1)) { + return -1; + } + return (putspent (sp, file) == -1) ? -1 : 0; } diff --git a/libmisc/Makefile.am b/libmisc/Makefile.am index fa254749..a8afc177 100644 --- a/libmisc/Makefile.am +++ b/libmisc/Makefile.am @@ -23,7 +23,6 @@ libmisc_a_SOURCES = \ env.c \ failure.c \ failure.h \ - fields.c \ find_new_gid.c \ find_new_uid.c \ getdate.h \ diff --git a/libmisc/user_busy.c b/libmisc/user_busy.c index ff626b04..168f9d55 100644 --- a/libmisc/user_busy.c +++ b/libmisc/user_busy.c @@ -43,7 +43,7 @@ #ifdef __linux__ static int check_status (const char *sname, uid_t uid); -static int user_busy_processes (uid_t uid); +static int user_busy_processes (const char *name, uid_t uid); #else /* !__linux__ */ static int user_busy_utmp (const char *name); #endif /* !__linux__ */ @@ -58,7 +58,7 @@ int user_busy (const char *name, uid_t uid) */ #ifdef __linux__ /* On Linux, directly parse /proc */ - return user_busy_processes (uid); + return user_busy_processes (name, uid); #else /* !__linux__ */ /* If we cannot rely on /proc, check is there is a record in utmp * indicating that the user is still logged in */ @@ -91,6 +91,9 @@ static int user_busy_utmp (const char *name) continue; } + fprintf (stderr, + _("%s: user %s is currently logged in\n"), + Prog, name); return 1; } @@ -137,7 +140,7 @@ static int check_status (const char *sname, uid_t uid) return 0; } -static int user_busy_processes (uid_t uid) +static int user_busy_processes (const char *name, uid_t uid) { DIR *proc; struct dirent *ent; @@ -195,6 +198,9 @@ static int user_busy_processes (uid_t uid) if (check_status (tmp_d_name, uid) != 0) { (void) closedir (proc); + fprintf (stderr, + _("%s: user %s is currently used by process %d\n"), + Prog, name, pid); return 1; } @@ -212,6 +218,9 @@ static int user_busy_processes (uid_t uid) } if (check_status (task_path+6, uid) != 0) { (void) closedir (proc); + fprintf (stderr, + _("%s: user %s is currently used by process %d\n"), + Prog, name, pid); return 1; } } diff --git a/po/POTFILES.in b/po/POTFILES.in index 6cb3cdb5..065333e5 100644 --- a/po/POTFILES.in +++ b/po/POTFILES.in @@ -2,6 +2,7 @@ lib/commonio.c lib/encrypt.c +lib/fields.c lib/fputsx.c lib/getdef.c lib/get_gid.c @@ -40,7 +41,6 @@ libmisc/copydir.c libmisc/entry.c libmisc/env.c libmisc/failure.c -libmisc/fields.c libmisc/find_new_gid.c libmisc/find_new_uid.c libmisc/getgr_nam_gid.c