]> granicus.if.org Git - shadow/blobdiff - src/pwck.c
2010-03-18 Paweł Hajdan, Jr. <phajdan.jr@gentoo.org>
[shadow] / src / pwck.c
index badb3b26d1b44bc90232cc328507f149397163e2..a66eb847e4aa01eb2358780f66298523364e4d85 100644 (file)
@@ -47,6 +47,9 @@
 #include "shadowio.h"
 #include "getdef.h"
 #include "nscd.h"
+#ifdef WITH_TCB
+#include "tcbfuncs.h"
+#endif
 
 /*
  * Exit codes
@@ -72,6 +75,9 @@ static bool use_system_spw_file = true;
 
 static bool is_shadow = false;
 
+static bool pw_opened  = false;
+static bool spw_opened = false;
+
 static bool pw_locked  = false;
 static bool spw_locked = false;
 
@@ -154,7 +160,7 @@ static void process_flags (int argc, char **argv)
        }
 
        if (sort_mode && read_only) {
-               fprintf (stderr, _("%s: -s and -r are incompatibile\n"), Prog);
+               fprintf (stderr, _("%s: -s and -r are incompatible\n"), Prog);
                exit (E_USAGE);
        }
 
@@ -192,6 +198,11 @@ static void process_flags (int argc, char **argv)
  */
 static void open_files (void)
 {
+       bool use_tcb = false;
+#ifdef WITH_TCB
+       use_tcb = getdef_bool("USE_TCB");
+#endif
+
        /*
         * Lock the files if we aren't in "read-only" mode
         */
@@ -203,11 +214,11 @@ static void open_files (void)
                        fail_exit (E_CANTLOCK);
                }
                pw_locked = true;
-               if (is_shadow) {
+               if (is_shadow && !use_tcb) {
                        if (spw_lock () == 0) {
                                fprintf (stderr,
                                         _("%s: cannot lock %s; try again later.\n"),
-                                        Prog, spw_file);
+                                        Prog, spw_dbname());
                                fail_exit (E_CANTLOCK);
                        }
                        spw_locked = true;
@@ -226,13 +237,17 @@ static void open_files (void)
                }
                fail_exit (E_CANTOPEN);
        }
-       if (is_shadow && (spw_open (read_only ? O_RDONLY : O_RDWR) == 0)) {
-               fprintf (stderr, _("%s: cannot open %s\n"),
-                        Prog, spw_file);
-               if (use_system_spw_file) {
-                       SYSLOG ((LOG_WARN, "cannot open %s", spw_file));
+       pw_opened = true;
+       if (is_shadow && !use_tcb) {
+               if (spw_open (read_only ? O_RDONLY : O_RDWR) == 0) {
+                       fprintf (stderr, _("%s: cannot open %s\n"),
+                                Prog, spw_dbname());
+                       if (use_system_spw_file) {
+                               SYSLOG ((LOG_WARN, "cannot open %s", spw_dbname()));
+                       }
+                       fail_exit (E_CANTOPEN);
                }
-               fail_exit (E_CANTOPEN);
+               spw_opened = true;
        }
 }
 
@@ -250,18 +265,20 @@ static void close_files (bool changed)
         * changes to the files.
         */
        if (changed) {
-               if (pw_close () == 0) {
+               if (pw_opened && pw_close () == 0) {
                        fprintf (stderr, _("%s: failure while writing changes to %s\n"),
                                 Prog, pwd_file);
                        SYSLOG ((LOG_ERR, "failure while writing changes to %s", pwd_file));
                        fail_exit (E_CANTUPDATE);
                }
-               if (is_shadow && (spw_close () == 0)) {
+               pw_opened = false;
+               if (is_shadow && spw_opened && (spw_close () == 0)) {
                        fprintf (stderr, _("%s: failure while writing changes to %s\n"),
-                                Prog, spw_file);
-                       SYSLOG ((LOG_ERR, "failure while writing changes to %s", spw_file));
+                                Prog, spw_dbname());
+                       SYSLOG ((LOG_ERR, "failure while writing changes to %s", spw_dbname()));
                        fail_exit (E_CANTUPDATE);
                }
+               spw_opened = false;
        }
 
        /*
@@ -450,12 +467,49 @@ static void check_pw_file (int *errors, bool *changed)
                 */
 
                if (is_shadow) {
+#ifdef WITH_TCB
+                       if (getdef_bool("USE_TCB")) {
+                               if (!shadowtcb_set_user (pwd->pw_name)) {
+                                       printf(_("no tcb directory for %s\n"), pwd->pw_name);
+                                       printf(_("create tcb directory for %s?"), pwd->pw_name);
+                                       *errors += 1;
+                                       if (yes_or_no (read_only)) {
+                                               if (!shadowtcb_create(pwd->pw_name, pwd->pw_uid)) {
+                                                       *errors += 1;
+                                                       printf(_("failed to create tcb directory for %s\n"), pwd->pw_name);
+                                                       continue;
+                                               }
+                                       } else {
+                                               continue;
+                                       }
+                               }
+                               if (spw_lock () == 0) {
+                                       *errors += 1;
+                                       fprintf (stderr,
+                                               _("%s: cannot lock %s.\n"),
+                                               Prog, spw_dbname());
+                                       continue;
+                               }
+                               spw_locked = true;
+                               if (spw_open (read_only ? O_RDONLY : O_RDWR) == 0) {
+                                       fprintf (stderr, _("%s: cannot open %s\n"),
+                                                Prog, spw_dbname());
+                                       *errors += 1;
+                                       if (spw_unlock () == 0) {
+                                               fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, spw_dbname ());
+                                               SYSLOG ((LOG_ERR, "failed to unlock %s", spw_dbname ()));
+                                       }
+                                       continue;
+                               }
+                               spw_opened = true;
+                       }
+#endif
                        spw = (struct spwd *) spw_locate (pwd->pw_name);
                        if (NULL == spw) {
                                printf (_("no matching password file entry in %s\n"),
-                                       spw_file);
+                                       spw_dbname());
                                printf (_("add user '%s' in %s? "),
-                                       pwd->pw_name, spw_file);
+                                       pwd->pw_name, spw_dbname());
                                *errors += 1;
                                if (yes_or_no (read_only)) {
                                        struct spwd sp;
@@ -494,11 +548,37 @@ static void check_pw_file (int *errors, bool *changed)
                                                fprintf (stderr,
                                                         _("%s: failed to prepare the new %s entry '%s'\n"),
                                                         Prog, pw_dbname (), pw.pw_name);
-                                               exit (E_CANTUPDATE);
+                                               fail_exit (E_CANTUPDATE);
                                        }
                                }
+                       } else {
+                               /* The passwd entry has a shadow counterpart.
+                                * Make sure no passwords are in passwd.
+                                */
+                               if (strcmp (pwd->pw_passwd, SHADOW_PASSWD_STRING) != 0) {
+                                       printf (_("user %s has an entry in %s, but its password field in %s is not set to 'x'\n"),
+                                               pwd->pw_name, spw_dbname(), pwd_file);
+                                       *errors += 1;
+                               }
+                       }
+               }
+#ifdef WITH_TCB
+               if (getdef_bool("USE_TCB") && spw_locked) {
+                       if (spw_opened && spw_close () == 0) {
+                               fprintf (stderr, _("%s: failure while writing changes to %s\n"),
+                                        Prog, spw_dbname());
+                               SYSLOG ((LOG_ERR, "failure while writing changes to %s", spw_dbname()));
+                       } else {
+                               spw_opened = false;
+                       }
+                       if (spw_unlock () == 0) {
+                               fprintf (stderr, _("%s: failed to unlock %s\n"), Prog, spw_dbname ());
+                               SYSLOG ((LOG_ERR, "failed to unlock %s", spw_dbname ()));
+                       } else {
+                               spw_locked = false;
                        }
                }
+#endif
        }
 }