]> granicus.if.org Git - shadow/commitdiff
Create parent dirs for useradd -m
authorMichael Vetter <jubalh@iodoru.org>
Tue, 15 May 2018 15:25:52 +0000 (17:25 +0200)
committerMichael Vetter <jubalh@iodoru.org>
Tue, 15 May 2018 15:30:34 +0000 (17:30 +0200)
Equivalent of `mkdir -p`. It will create all parent directories.
Example: `useradd -d /home2/testu1 -m testu1`

Based on https://github.com/shadow-maint/shadow/pull/2 by Thorsten Kukuk
and Thorsten Behrens which was Code from pwdutils 3.2.2 with slight adaptations.

Adapted to so it applies to current code.

src/useradd.c

index e721e52be3943f7c201ac90463d4c5b49696ef21..ca90f076ab2f1e26de24b218a84b66a923e14fd8 100644 (file)
@@ -2018,6 +2018,19 @@ static void usr_update (void)
 static void create_home (void)
 {
        if (access (prefix_user_home, F_OK) != 0) {
+               char path[strlen (prefix_user_home) + 2];
+               char *bhome, *cp;
+
+               path[0] = '\0';
+               bhome = strdup (prefix_user_home);
+               if (!bhome) {
+                       fprintf (stderr,
+                                                       _("%s: error while duplicating string %s\n"),
+                                                       Prog, user_home);
+                       fail_exit (E_HOMEDIR);
+               }
+               ++bhome;
+
 #ifdef WITH_SELINUX
                if (set_selinux_file_context (prefix_user_home) != 0) {
                        fprintf (stderr,
@@ -2026,19 +2039,42 @@ static void create_home (void)
                        fail_exit (E_HOMEDIR);
                }
 #endif
-               /* XXX - create missing parent directories.  --marekm */
-               if (mkdir (prefix_user_home, 0) != 0) {
+
+               /* Check for every part of the path, if the directory
+                  exists. If not, create it with permissions 755 and
+                  owner root:root.
+                */
+               cp = strtok (bhome, "/");
+               while (cp) {
+                       strcat (path, "/");
+                       strcat (path, cp);
+                       if (access (path, F_OK) != 0) {
+                               if (mkdir (path, 0) != 0) {
                        fprintf (stderr,
-                                _("%s: cannot create directory %s\n"),
-                                Prog, prefix_user_home);
+                                                       _("%s: cannot create directory %s\n"),
+                                                       Prog, path);
 #ifdef WITH_AUDIT
                        audit_logger (AUDIT_ADD_USER, Prog,
-                                     "adding home directory",
-                                     user_name, (unsigned int) user_id,
-                                     SHADOW_AUDIT_FAILURE);
+                                                                               "adding home directory",
+                                                                               user_name, (unsigned int) user_id,
+                                                                               SHADOW_AUDIT_FAILURE);
 #endif
                        fail_exit (E_HOMEDIR);
                }
+                               if (chown (path, 0, 0) < 0) {
+                                       fprintf (stderr,
+                                                                       _("%s: warning: chown on `%s' failed: %m\n"),
+                                                                       Prog, path);
+                               }
+                               if (chmod (path, 0755) < 0) {
+                                       fprintf (stderr,
+                                                                       _("%s: warning: chmod on `%s' failed: %m\n"),
+                                                                       Prog, path);
+                               }
+                       }
+                       cp = strtok (NULL, "/");
+               }
+
                (void) chown (prefix_user_home, user_id, user_gid);
                chmod (prefix_user_home,
                       0777 & ~getdef_num ("UMASK", GETDEF_DEFAULT_UMASK));