diff --git a/configure.ac b/configure.ac index 8be142df..d75ba3f1 100644 --- a/configure.ac +++ b/configure.ac @@ -253,6 +253,9 @@ AC_ARG_WITH(audit, AC_ARG_WITH(libpam, [AC_HELP_STRING([--with-libpam], [use libpam for PAM support @<:@default=yes if found@:>@])], [with_libpam=$withval], [with_libpam=maybe]) +AC_ARG_WITH(btrfs, + [AC_HELP_STRING([--with-btrfs], [add BtrFS support @<:@default=yes if found@:>@])], + [with_selinux=$withval], [with_selinux=maybe]) AC_ARG_WITH(selinux, [AC_HELP_STRING([--with-selinux], [use SELinux support @<:@default=yes if found@:>@])], [with_selinux=$withval], [with_selinux=maybe]) @@ -459,6 +462,20 @@ if test "$with_libcrack" = "yes"; then AC_DEFINE(HAVE_LIBCRACK_PW, 1, [Defined if it includes *Pw functions.])) fi +if test "$with_btrfs" != "no"; then + AC_CHECK_HEADERS([sys/statfs.h linux/magic.h linux/btrfs_tree.h], \ + [btrfs_headers="yes"], [btrfs_headers="no"]) + if test "$btrfs_headers$with_btrfs" = "noyes" ; then + AC_MSG_ERROR([One of sys/statfs.h linux/magic.h linux/btrfs_tree.h is missing]) + fi + + if test "$btrfs_headers" = "yes" ; then + AC_DEFINE(WITH_BTRFS, 1, [Build shadow with BtrFS support]) + with_btrfs="yes" + fi +fi +AM_CONDITIONAL(WITH_BTRFS, test x$with_btrfs = xyes) + AC_SUBST(LIBSELINUX) AC_SUBST(LIBSEMANAGE) if test "$with_selinux" != "no"; then @@ -691,6 +708,7 @@ if test "$with_libpam" = "yes"; then echo " suid account management tools: $enable_acct_tools_setuid" fi echo " SELinux support: $with_selinux" +echo " BtrFS support: $with_btrfs" echo " ACL support: $with_acl" echo " Extended Attributes support: $with_attr" echo " tcb support (incomplete): $with_tcb" diff --git a/lib/prototypes.h b/lib/prototypes.h index 9e4f73cd..24825f60 100644 --- a/lib/prototypes.h +++ b/lib/prototypes.h @@ -73,10 +73,12 @@ extern int expire (const struct passwd *, /*@null@*/const struct spwd *); extern int isexpired (const struct passwd *, /*@null@*/const struct spwd *); /* btrfs.c */ +#ifdef WITH_BTRFS extern int btrfs_create_subvolume(const char *path); extern int btrfs_remove_subvolume(const char *path); extern int btrfs_is_subvolume(const char *path); extern int is_btrfs(const char *path); +#endif /* basename() renamed to Basename() to avoid libc name space confusion */ /* basename.c */ diff --git a/libmisc/Makefile.am b/libmisc/Makefile.am index a95392ea..9aed980f 100644 --- a/libmisc/Makefile.am +++ b/libmisc/Makefile.am @@ -10,7 +10,6 @@ libmisc_a_SOURCES = \ age.c \ audit_help.c \ basename.c \ - btrfs.c \ chkname.c \ chkname.h \ chowndir.c \ @@ -73,3 +72,8 @@ libmisc_a_SOURCES = \ xgetspnam.c \ xmalloc.c \ yesno.c + +if WITH_BTRFS +libmisc_a_SOURCES += btrfs.c +endif + diff --git a/src/useradd.c b/src/useradd.c index bb426bf4..bdd7fe8c 100644 --- a/src/useradd.c +++ b/src/useradd.c @@ -823,7 +823,9 @@ static void usage (int status) Prog, Prog, Prog); (void) fputs (_(" -b, --base-dir BASE_DIR base directory for the home directory of the\n" " new account\n"), usageout); +#ifdef WITH_BTRFS (void) fputs (_(" --btrfs-subvolume-home use BTRFS subvolume for home directory\n"), usageout); +#endif (void) fputs (_(" -c, --comment COMMENT GECOS field of the new account\n"), usageout); (void) fputs (_(" -d, --home-dir HOME_DIR home directory of the new account\n"), usageout); (void) fputs (_(" -D, --defaults print or change default useradd configuration\n"), usageout); @@ -1104,7 +1106,9 @@ static void process_flags (int argc, char **argv) int c; static struct option long_options[] = { {"base-dir", required_argument, NULL, 'b'}, +#ifdef WITH_BTRFS {"btrfs-subvolume-home", no_argument, NULL, 200}, +#endif {"comment", required_argument, NULL, 'c'}, {"home-dir", required_argument, NULL, 'd'}, {"defaults", no_argument, NULL, 'D'}, @@ -2083,6 +2087,7 @@ static void create_home (void) subvolume but no BTRFS. The paths cound be different by the trailing slash */ +#if WITH_BTRFS if (subvolflg && (strlen(prefix_user_home) - (int)strlen(path)) <= 1) { char *btrfs_check = strdup(path); @@ -2107,7 +2112,9 @@ static void create_home (void) fail_exit (E_HOMEDIR); } } - else if (mkdir (path, 0) != 0) { + else +#endif + if (mkdir (path, 0) != 0) { fprintf (stderr, _("%s: cannot create directory %s\n"), Prog, path); diff --git a/src/userdel.c b/src/userdel.c index 00369133..7be46e8d 100644 --- a/src/userdel.c +++ b/src/userdel.c @@ -1272,6 +1272,7 @@ int main (int argc, char **argv) #endif /* EXTRA_CHECK_HOME_DIR */ if (rflg) { +#ifdef WITH_BTRFS int is_subvolume = btrfs_is_subvolume (user_home); if (is_subvolume < 0) { errors++; @@ -1286,7 +1287,9 @@ int main (int argc, char **argv) /* continue */ } } - else if (remove_tree (user_home, true) != 0) { + else +#endif + if (remove_tree (user_home, true) != 0) { fprintf (stderr, _("%s: error removing directory %s\n"), Prog, user_home); diff --git a/src/usermod.c b/src/usermod.c index 3c2a0844..c3718864 100644 --- a/src/usermod.c +++ b/src/usermod.c @@ -1819,12 +1819,14 @@ static void move_home (void) return; } else { if (EXDEV == errno) { +#ifdef WITH_BTRFS if (btrfs_is_subvolume (prefix_user_home) > 0) { fprintf (stderr, _("%s: error: cannot move subvolume from %s to %s - different device\n"), Prog, prefix_user_home, prefix_user_newhome); fail_exit (E_HOMEDIR); } +#endif if (copy_tree (prefix_user_home, prefix_user_newhome, true, true,