]> granicus.if.org Git - shadow/commitdiff
* NEWS, configure.in, libmisc/copydir.c, man/useradd.8.xml,
authornekral-guest <nekral-guest@5a98b0ae-9ef6-0310-add3-de5d479b70d7>
Tue, 30 Mar 2010 21:01:27 +0000 (21:01 +0000)
committernekral-guest <nekral-guest@5a98b0ae-9ef6-0310-add3-de5d479b70d7>
Tue, 30 Mar 2010 21:01:27 +0000 (21:01 +0000)
man/usermod.8.xml, src/Makefile.am: Added support for ACLs and
Extended Attributes.

ChangeLog
NEWS
TODO
configure.in
libmisc/copydir.c
man/useradd.8.xml
man/usermod.8.xml
src/Makefile.am

index bd1a867585840e259079dac5b30c9c691adee5a6..fbb3765395c685d16449eae2b7aea0be1e0d4546 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+2010-03-30  Nicolas François  <nicolas.francois@centraliens.net>
+
+       * NEWS, configure.in, libmisc/copydir.c, man/useradd.8.xml,
+       man/usermod.8.xml, src/Makefile.am: Added support for ACLs and
+       Extended Attributes.
+
 2010-03-30  Nicolas François  <nicolas.francois@centraliens.net>
 
        * libmisc/copydir.c: Document the sections closed by #endif
diff --git a/NEWS b/NEWS
index a4a0b29353ccf1a6bc02fcfe0d8f84ecfabf4b07..d90d7991886b702548d3eb8a3dc4961fa1b2f1df 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -7,6 +7,9 @@ shadow-4.1.4.2 -> shadow-4.1.5                                  UNRELEASED
     zero) when explicitly requested (e.g. with --help).
   * initial support for tcb (http://openwall.com/tcb/) for useradd,
     userdel, usermod, chage, pwck, vipw.
+  * Added support for ACLs and Extended Attributes in useradd and usermod.
+    Support shall be enabled with the new --with-acl or --with-attr
+    configure options.
 
 -chpasswd
   * PAM enabled versions: restore the -e option to allow restoring
diff --git a/TODO b/TODO
index 1e68387d5b3da5149823f7abd437ada2c453c27b..24917a10ca0257c58c4ccf5640665b49466d2eca 100644 (file)
--- a/TODO
+++ b/TODO
@@ -120,4 +120,7 @@ ALL:
 
 - su
   - add a login.defs configuration parameter to add variables to keep in
-    the environment with "su -l" (TERM/TERMCOLOR/...
+    the environment with "su -l" (TERM/TERMCOLOR/...)
+
+- vipw
+  - set ACT and XATTR on the temporary file (and backups?)
index 584ce7b54992085c07af3dc966a7f9afbf8cc59a..3aa84d5de51237e9a9867d63c506eda9b5a62595 100644 (file)
@@ -33,7 +33,8 @@ AC_HEADER_STDBOOL
 AC_CHECK_HEADERS(errno.h fcntl.h limits.h unistd.h sys/time.h utmp.h \
        utmpx.h termios.h termio.h sgtty.h sys/ioctl.h syslog.h paths.h \
        utime.h ulimit.h sys/resource.h gshadow.h lastlog.h \
-       locale.h rpc/key_prot.h netdb.h)
+       locale.h rpc/key_prot.h netdb.h acl/libacl.h attr/libattr.h
+       attr/error_context.h)
 
 dnl shadow now uses the libc's shadow implementation
 AC_CHECK_HEADER([shadow.h],,[AC_MSG_ERROR([You need a libc with shadow.h])])
@@ -246,6 +247,10 @@ AC_ARG_WITH(libpam,
 AC_ARG_WITH(selinux,
        [AC_HELP_STRING([--with-selinux], [use SELinux support @<:@default=yes if found@:>@])],
        [with_selinux=$withval], [with_selinux=maybe])
+AC_ARG_WITH(acl,
+       [AC_HELP_STRING([--with-acl], [use ACL support @<:@default=yes if found@:>@])],
+       [AC_HELP_STRING([--with-attr], [use Extended Attribute support @<:@default=yes if found@:>@])],
+       [with_attr=$withval], [with_attr=maybe])
 AC_ARG_WITH(skey,
        [AC_HELP_STRING([--with-skey], [use S/Key support @<:@default=no@:>@])],
        [with_skey=$withval], [with_skey=no])
@@ -319,6 +324,58 @@ AC_SUBST(LIBCRYPT)
 AC_CHECK_LIB(crypt, crypt, [LIBCRYPT=-lcrypt],
        [AC_MSG_ERROR([crypt() not found])])
 
+AC_SUBST(LIBACL)
+if test "$with_acl" != "no"; then
+       AC_CHECK_HEADERS(acl/libacl.h attr/error_context.h, [acl_header="yes"], [acl_header="no"])
+       if test "$acl_header$with_acl" = "noyes" ; then
+               AC_MSG_ERROR([acl/libacl.h or attr/error_context.h is missing])
+       elif test "$acl_header" = "yes" ; then
+               AC_CHECK_LIB(acl, perm_copy_file,
+                            [AC_CHECK_LIB(acl, perm_copy_fd,
+                                          [acl_lib="yes"],
+                                          [acl_lib="no"])],
+                            [acl_lib="no"])
+               if test "$acl_lib$with_acl" = "noyes" ; then
+                       AC_MSG_ERROR([libacl not found])
+               elif test "$acl_lib" = "no" ; then
+                       with_acl="no"
+               else
+                       AC_DEFINE(WITH_ACL, 1,
+                                 [Build shadow with ACL support])
+                       LIBACL="-lacl"
+                       with_acl="yes"
+               fi
+       else
+               with_acl="no"
+       fi
+fi
+
+AC_SUBST(LIBATTR)
+if test "$with_attr" != "no"; then
+       AC_CHECK_HEADERS(attr/libattr.h attr/error_context.h, [attr_header="yes"], [attr_header="no"])
+       if test "$attr_header$with_attr" = "noyes" ; then
+               AC_MSG_ERROR([attr/libattr.h or attr/error_context.h is missing])
+       elif test "$attr_header" = "yes" ; then
+               AC_CHECK_LIB(attr, attr_copy_file,
+                            [AC_CHECK_LIB(attr, attr_copy_fd,
+                                          [attr_lib="yes"],
+                                          [attr_lib="no"])],
+                            [attr_lib="no"])
+               if test "$attr_lib$with_attr" = "noyes" ; then
+                       AC_MSG_ERROR([libattr not found])
+               elif test "$attr_lib" = "no" ; then
+                       with_attr="no"
+               else
+                       AC_DEFINE(WITH_ATTR, 1,
+                                 [Build shadow with Extended Attributes support])
+                       LIBACL="-lattr"
+                       with_attr="yes"
+               fi
+       else
+               with_attr="no"
+       fi
+fi
+
 AC_SUBST(LIBAUDIT)
 if test "$with_audit" != "no"; then
        AC_CHECK_HEADER(libaudit.h, [audit_header="yes"], [audit_header="no"])
@@ -565,6 +622,8 @@ if test "$with_libpam" = "yes"; then
 echo " suid account management tools:  $enable_acct_tools_setuid"
 fi
 echo " SELinux support:                $with_selinux"
+echo " ACL support:                    $with_acl"
+echo " Extended Attributes support:    $with_attr"
 echo " tcb support (incomplete):       $with_tcb"
 echo " shadow group support:           $enable_shadowgrp"
 echo " S/Key support:                  $with_skey"
index 51578a5bdf297e1e677bb0f16e12f5de0602d266..c48e7c5d2bba027b70e2bbc713aee33df2c9dd5c 100644 (file)
 #ifdef WITH_SELINUX
 #include <selinux/selinux.h>
 #endif                         /* WITH_SELINUX */
+#if defined(WITH_ACL) || defined(WITH_ATTR)
+#include <attr/error_context.h>
+#endif                         /* WITH_ACL || WITH_ATTR */
+#ifdef WITH_ACL
+#include <acl/libacl.h>
+#endif                         /* WITH_ACL */
+#ifdef WITH_ATTR
+#include <attr/libattr.h>
+#endif                         /* WITH_ATTR */
+
 static /*@null@*/const char *src_orig;
 static /*@null@*/const char *dst_orig;
 
@@ -70,7 +80,7 @@ static int copy_symlink (const char *src, const char *dst,
 #endif                         /* S_IFLNK */
 static int copy_hardlink (const char *src, const char *dst,
                           struct link_name *lp);
-static int copy_special (const char *dst,
+static int copy_special (const char *src, const char *dst,
                          const struct stat *statp, const struct timeval mt[],
                          long int uid, long int gid);
 static int copy_file (const char *src, const char *dst,
@@ -119,6 +129,25 @@ int selinux_file_context (const char *dst_name)
 }
 #endif                         /* WITH_SELINUX */
 
+#if defined(WITH_ACL) || defined(WITH_ATTR)
+void error (struct error_context *ctx, const char *fmt, ...)
+{
+       va_list ap;
+
+       va_start (ap, fmt);
+       (void) fprintf (stderr, _("%s: "), Prog);
+       if (vfprintf (stderr, fmt, ap) != 0) {
+               (void) fputs (_(": "), stderr);
+       }
+       (void) fprintf (stderr, "%s\n", strerror (errno));
+       va_end (ap);
+}
+
+struct error_context ctx = {
+       error
+};
+#endif                         /* WITH_ACL || WITH_ATTR */
+
 /*
  * remove_link - delete a link from the linked list
  */
@@ -369,7 +398,7 @@ static int copy_entry (const char *src, const char *dst,
                 */
 
                else if (!S_ISREG (sb.st_mode)) {
-                       err = copy_special (dst, &sb, mt, uid, gid);
+                       err = copy_special (src, dst, &sb, mt, uid, gid);
                }
 
                /*
@@ -413,7 +442,21 @@ static int copy_dir (const char *src, const char *dst,
            || (chown (dst,
                       (uid == - 1) ? statp->st_uid : (uid_t) uid,
                       (gid == - 1) ? statp->st_gid : (gid_t) gid) != 0)
+#ifdef WITH_ACL
+           || (perm_copy_file (src, dst, &ctx) != 0)
+#else                          /* !WITH_ACL */
            || (chmod (dst, statp->st_mode) != 0)
+#endif                         /* !WITH_ACL */
+#ifdef WITH_ATTR
+       /*
+        * If the third parameter is NULL, all extended attributes
+        * except those that define Access Control Lists are copied.
+        * ACLs are excluded by default because copying them between
+        * file systems with and without ACL support needs some
+        * additional logic so that no unexpected permissions result.
+        */
+           || (attr_copy_file (src, dst, NULL, &ctx) != 0)
+#endif                         /* WITH_ATTR */
            || (copy_tree (src, dst, uid, gid) != 0)
            || (utimes (dst, mt) != 0)) {
                err = -1;
@@ -514,6 +557,13 @@ static int copy_symlink (const char *src, const char *dst,
            || (lchown (dst,
                        (uid == -1) ? statp->st_uid : (uid_t) uid,
                        (gid == -1) ? statp->st_gid : (gid_t) gid) != 0)) {
+               /* FIXME: there are no modes on symlinks, right?
+                *        ACL could be copied, but this would be much more
+                *        complex than calling perm_copy_file.
+                *        Ditto for Extended Attributes.
+                *        We currently only document that ACL and Extended
+                *        Attributes are not copied.
+                */
                free (oldlink);
                return -1;
        }
@@ -542,7 +592,7 @@ static int copy_symlink (const char *src, const char *dst,
 static int copy_hardlink (const char *src, const char *dst,
                           struct link_name *lp)
 {
-       /* TODO: selinux needed? */
+       /* TODO: selinux, ACL, Extended Attributes needed? */
 
        if (link (lp->ln_name, dst) != 0) {
                return -1;
@@ -574,7 +624,7 @@ static int copy_hardlink (const char *src, const char *dst,
  *
  *     Return 0 on success, -1 on error.
  */
-static int copy_special (const char *dst,
+static int copy_special (const char *src, const char *dst,
                          const struct stat *statp, const struct timeval mt[],
                          long int uid, long int gid)
 {
@@ -588,7 +638,21 @@ static int copy_special (const char *dst,
            || (chown (dst,
                       (uid == -1) ? statp->st_uid : (uid_t) uid,
                       (gid == -1) ? statp->st_gid : (gid_t) gid) != 0)
+#ifdef WITH_ACL
+           || (perm_copy_file (src, dst, &ctx) != 0)
+#else                          /* !WITH_ACL */
            || (chmod (dst, statp->st_mode & 07777) != 0)
+#endif                         /* !WITH_ACL */
+#ifdef WITH_ATTR
+       /*
+        * If the third parameter is NULL, all extended attributes
+        * except those that define Access Control Lists are copied.
+        * ACLs are excluded by default because copying them between
+        * file systems with and without ACL support needs some
+        * additional logic so that no unexpected permissions result.
+        */
+           || (attr_copy_file (src, dst, NULL, &ctx) != 0)
+#endif                         /* WITH_ATTR */
            || (utimes (dst, mt) != 0)) {
                err = -1;
        }
@@ -628,7 +692,22 @@ static int copy_file (const char *src, const char *dst,
            || (fchown (ofd,
                        (uid == -1) ? statp->st_uid : (uid_t) uid,
                        (gid == -1) ? statp->st_gid : (gid_t) gid) != 0)
-           || (fchmod (ofd, statp->st_mode & 07777) != 0)) {
+#ifdef WITH_ACL
+           || (perm_copy_fd (src, ifd, dst, ofd, &ctx) != 0)
+#else                          /* !WITH_ACL */
+           || (fchmod (ofd, statp->st_mode & 07777) != 0)
+#endif                         /* !WITH_ACL */
+#ifdef WITH_ATTR
+       /*
+        * If the third parameter is NULL, all extended attributes
+        * except those that define Access Control Lists are copied.
+        * ACLs are excluded by default because copying them between
+        * file systems with and without ACL support needs some
+        * additional logic so that no unexpected permissions result.
+        */
+           || (attr_copy_fd (src, ifd, dst, ofd, NULL, &ctx) != 0)
+#endif                         /* WITH_ATTR */
+          ) {
                (void) close (ifd);
                return -1;
        }
index b2c4ea3646d4c0877d1156b8288031f61dd17a19..eb3adeb7a0f3352eff259791bd0368a3a000360f 100644 (file)
            <filename>/etc/default/useradd</filename> or, by default,
            <filename>/etc/skel</filename>.
          </para>
+         <para>
+           If possible, the ACLs and extended attributes are copied.
+         </para>
        </listitem>
       </varlistentry>
       <varlistentry>
index f24995742356ef55aaff8fea2a275af402d3e6fc..0a948630f4f1fb419f06f2de8ad2cdc3b5fa0b66 100644 (file)
            This option is only valid in combination with the
            <option>-d</option> (or <option>--home</option>) option.
          </para>
+         <para>
+           <command>usermod</command> will try to adapt the ownership of the
+           files and to copy the modes, ACL and extended attributes, but
+           manual changes might be needed afterwards.
+         </para>
        </listitem>
       </varlistentry>
       <varlistentry>
index 9bfd6ec07372ca4107cc7f70f5655c3d8e736b2f..8ca53cb4e4232161f1a578e5944ae5eb4af2dad8 100644 (file)
@@ -106,9 +106,9 @@ su_SOURCES     = \
        suauth.c
 su_LDADD       = $(LDADD) $(LIBPAM) $(LIBCRYPT_NOPAM) $(LIBSKEY) $(LIBMD)
 sulogin_LDADD  = $(LDADD) $(LIBCRYPT)
-useradd_LDADD  = $(LDADD) $(LIBPAM_SUID) $(LIBAUDIT) $(LIBSELINUX)
+useradd_LDADD  = $(LDADD) $(LIBPAM_SUID) $(LIBAUDIT) $(LIBSELINUX) $(LIBACL)
 userdel_LDADD  = $(LDADD) $(LIBPAM_SUID) $(LIBAUDIT) $(LIBSELINUX)
-usermod_LDADD  = $(LDADD) $(LIBPAM_SUID) $(LIBAUDIT) $(LIBSELINUX)
+usermod_LDADD  = $(LDADD) $(LIBPAM_SUID) $(LIBAUDIT) $(LIBSELINUX) $(LIBACL)
 vipw_LDADD     = $(LDADD) $(LIBSELINUX)
 
 install-am: all-am