diff --git a/src/chfn.c b/src/chfn.c index 9043212a1..adb5caf15 100644 --- a/src/chfn.c +++ b/src/chfn.c @@ -34,7 +34,7 @@ #include "shadowlog.h" #include "string/sprintf.h" #include "string/strtcpy.h" - +#include "chkname.h" /* * Global variables. @@ -648,11 +648,17 @@ int main (int argc, char **argv) * name, or the name getlogin() returns. */ if (optind < argc) { - user = argv[optind]; + if (!is_valid_user_name (argv[optind])) { + fprintf (stderr, _("%s: Provided user name is not a valid name\n"), Prog); + fail_exit (E_NOPERM); + } + user = xstrdup (argv[optind]); + pw = xgetpwnam (user); if (NULL == pw) { fprintf (stderr, _("%s: user '%s' does not exist\n"), Prog, user); + free (user); fail_exit (E_NOPERM); } } else { @@ -665,6 +671,7 @@ int main (int argc, char **argv) (unsigned long) getuid ())); fail_exit (E_NOPERM); } + user = xstrdup (pw->pw_name); } @@ -708,6 +715,8 @@ int main (int argc, char **argv) SYSLOG ((LOG_INFO, "changed user '%s' information", user)); + free (user); + nscd_flush_cache ("passwd"); sssd_flush_cache (SSSD_DB_PASSWD); diff --git a/src/chsh.c b/src/chsh.c index c4918c1b1..fea9cbcdc 100644 --- a/src/chsh.c +++ b/src/chsh.c @@ -32,6 +32,7 @@ #include "exitcodes.h" #include "shadowlog.h" #include "string/strtcpy.h" +#include "chkname.h" #ifndef SHELLS_FILE #define SHELLS_FILE "/etc/shells" @@ -498,11 +499,17 @@ int main (int argc, char **argv) * name, or the name getlogin() returns. */ if (optind < argc) { - user = argv[optind]; + if (!is_valid_user_name (argv[optind])) { + fprintf (stderr, _("%s: Provided user name is not a valid name\n"), Prog); + fail_exit (E_NOPERM); + } + user = xstrdup (argv[optind]); + pw = xgetpwnam (user); if (NULL == pw) { fprintf (stderr, _("%s: user '%s' does not exist\n"), Prog, user); + free (user); fail_exit (1); } } else { @@ -515,6 +522,7 @@ int main (int argc, char **argv) (unsigned long) getuid ())); fail_exit (1); } + user = xstrdup (pw->pw_name); } @@ -569,6 +577,8 @@ int main (int argc, char **argv) SYSLOG ((LOG_INFO, "changed user '%s' shell to '%s'", user, loginsh)); + free (user); + nscd_flush_cache ("passwd"); sssd_flush_cache (SSSD_DB_PASSWD); diff --git a/src/newgrp.c b/src/newgrp.c index 1b3d76b83..74bb661f2 100644 --- a/src/newgrp.c +++ b/src/newgrp.c @@ -26,7 +26,7 @@ #include "exitcodes.h" #include "shadowlog.h" #include "string/sprintf.h" - +#include "chkname.h" /* * Global variables @@ -482,7 +482,13 @@ int main (int argc, char **argv) * not "newgrp". */ if ((argc > 0) && (argv[0][0] != '-')) { - group = argv[0]; + if (!is_valid_group_name (argv[optind])) { + fprintf ( + stderr, _("%s: provided group is not a valid group name\n"), + Prog); + goto failure; + } + group = xstrdup (argv[optind]); argc--; argv++; } else { @@ -513,7 +519,13 @@ int main (int argc, char **argv) usage (); goto failure; } else if (argv[0] != NULL) { - group = argv[0]; + if (!is_valid_group_name (argv[optind])) { + fprintf ( + stderr, _("%s: provided group is not a valid group name\n"), + Prog); + goto failure; + } + group = xstrdup (argv[optind]); } else { /* * get the group file entry for her login group id. @@ -531,7 +543,7 @@ int main (int argc, char **argv) (unsigned long) pwd->pw_gid)); goto failure; } else { - group = grp->gr_name; + group = xstrdup (grp->gr_name); } } } @@ -567,6 +579,7 @@ int main (int argc, char **argv) "changing", NULL, getuid (), 0); } #endif + free (group); exit (EXIT_FAILURE); } #endif /* HAVE_SETGROUPS */ @@ -722,6 +735,7 @@ int main (int argc, char **argv) audit_logger (AUDIT_CHGRP_ID, Prog, audit_buf, NULL, getuid (), 0); #endif + free (group); exit (EXIT_FAILURE); } @@ -732,6 +746,7 @@ int main (int argc, char **argv) audit_logger (AUDIT_CHGRP_ID, Prog, audit_buf, NULL, getuid (), 0); #endif + free (group); exit (EXIT_FAILURE); } @@ -748,6 +763,7 @@ int main (int argc, char **argv) audit_buf, NULL, getuid (), 0); #endif perror (SHELL); + free (group); exit ((errno == ENOENT) ? E_CMD_NOTFOUND : E_CMD_NOEXEC); } @@ -818,6 +834,7 @@ int main (int argc, char **argv) * the previous environment which should be the user's login shell. */ err = shell (prog, initflag ? NULL : progbase, newenvp); + free (group); exit ((err == ENOENT) ? E_CMD_NOTFOUND : E_CMD_NOEXEC); /*@notreached@*/ failure: @@ -843,6 +860,7 @@ int main (int argc, char **argv) "changing", NULL, getuid (), 0); } #endif + free (group); exit (EXIT_FAILURE); } diff --git a/src/passwd.c b/src/passwd.c index 2999a3c88..a43aaa315 100644 --- a/src/passwd.c +++ b/src/passwd.c @@ -35,8 +35,7 @@ #include "shadowlog.h" #include "string/strtcpy.h" #include "time/day_to_str.h" - - +#include "chkname.h" /* * exit status values @@ -907,7 +906,11 @@ int main (int argc, char **argv) } myname = xstrdup (pw->pw_name); if (optind < argc) { - name = argv[optind]; + if (!is_valid_user_name (argv[optind])) { + fprintf (stderr, _("%s: Provided user name is not a valid name\n"), Prog); + fail_exit (E_NOPERM); + } + name = xstrdup (argv[optind]); } else { name = myname; } @@ -931,6 +934,7 @@ int main (int argc, char **argv) (void) fprintf (stderr, _("%s: Permission denied.\n"), Prog); + free (name); exit (E_NOPERM); } prefix_setpwent (); @@ -938,6 +942,7 @@ int main (int argc, char **argv) print_status (pw); } prefix_endpwent (); + free (name); exit (E_SUCCESS); } #if 0 @@ -971,6 +976,7 @@ int main (int argc, char **argv) if (anyflag && !amroot) { (void) fprintf (stderr, _("%s: Permission denied.\n"), Prog); + free (name); exit (E_NOPERM); } @@ -979,6 +985,7 @@ int main (int argc, char **argv) (void) fprintf (stderr, _("%s: user '%s' does not exist\n"), Prog, name); + free (name); exit (E_NOPERM); } #ifdef WITH_SELINUX @@ -991,6 +998,7 @@ int main (int argc, char **argv) (void) fprintf(stderr, _("%s: root is not authorized by SELinux to change the password of %s\n"), Prog, name); + free (name); exit (E_NOPERM); } #endif /* WITH_SELINUX */ @@ -1007,11 +1015,13 @@ int main (int argc, char **argv) "can't view or modify password information for %s", name)); closelog (); + free (name); exit (E_NOPERM); } if (Sflg) { print_status (pw); + free (name); exit (E_SUCCESS); } if (!use_pam) @@ -1025,6 +1035,7 @@ int main (int argc, char **argv) (void) fprintf (stderr, _("%s: Permission denied.\n"), Prog); + free (name); exit (E_NOPERM); } sp = pwd_to_spwd (pw); @@ -1056,6 +1067,7 @@ int main (int argc, char **argv) _("The password for %s is unchanged.\n"), name); closelog (); + free (name); exit (E_NOPERM); } do_update_pwd = true; @@ -1079,6 +1091,7 @@ int main (int argc, char **argv) if (sflg) { cp = agetpass_stdin (); if (cp == NULL) { + free (name); exit (E_FAILURE); } do_pam_passwd_non_interactive ("passwd", name, cp); @@ -1086,6 +1099,7 @@ int main (int argc, char **argv) } else { do_pam_passwd (name, qflg, kflg); } + free (name); exit (E_SUCCESS); } #endif /* USE_PAM */ @@ -1093,6 +1107,7 @@ int main (int argc, char **argv) (void) fputs (_("Cannot change ID to root.\n"), stderr); SYSLOG ((LOG_ERR, "can't setuid(0)")); closelog (); + free (name); exit (E_NOPERM); } if (spw_file_present ()) { @@ -1106,6 +1121,8 @@ int main (int argc, char **argv) sssd_flush_cache (SSSD_DB_PASSWD | SSSD_DB_GROUP); SYSLOG ((LOG_INFO, "password for '%s' changed by '%s'", name, myname)); + + free (name); closelog (); if (!qflg) { if (!anyflag) {