]> granicus.if.org Git - shadow/commitdiff
* NEWS, src/groupmems.c, man/groupmems.8.xml: Added support for
authornekral-guest <nekral-guest@5a98b0ae-9ef6-0310-add3-de5d479b70d7>
Sun, 31 Aug 2008 17:29:34 +0000 (17:29 +0000)
committernekral-guest <nekral-guest@5a98b0ae-9ef6-0310-add3-de5d479b70d7>
Sun, 31 Aug 2008 17:29:34 +0000 (17:29 +0000)
shadow groups.
* src/groupmems.c: Use fail_exit() instead of exit().

ChangeLog
NEWS
man/groupmems.8.xml
src/groupmems.c

index e17737280eafad7efab07dcff30986133ba34856..a2a0274a916c56ea7823db5f353877f75bcbb42e 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,9 @@
+2008-08-29  Nicolas François  <nicolas.francois@centraliens.net>
+
+       * NEWS, src/groupmems.c, man/groupmems.8.xml: Added support for
+       shadow groups.
+       * src/groupmems.c: Use fail_exit() instead of exit().
+
 2008-08-29  Nicolas François  <nicolas.francois@centraliens.net>
 
        * src/groupmems.c: The grp structure returned by gr_locate is a
diff --git a/NEWS b/NEWS
index f8289067bd4cedaa887c011b5cd8cff977614a11..92f5e37b799a356f5b0f7c6291ae222cdbdb2b8d 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -20,6 +20,7 @@ shadow-4.1.2.1 -> shadow-4.1.3                                                UNRELEASED
   * Added syslog support.
   * Use the groupmems PAM service name instead of groupmod.
   * Fix segmentation faults when adding or removing users from a group.
+  * Added support for shadow groups.
 - newusers
   * Implement the -r, --system option.
 - passwd
index c6d582331516656f28c5fd845c4631cd2f017961..935dc6574f0d1a46c09a759bd5c14c1d9309ad67 100644 (file)
        <term><option>-a</option> <replaceable>user_name</replaceable></term>
        <listitem>
          <para>Add a new user to the group membership list.</para>
+         <para condition="gshadow">
+           If the <filename>/etc/gshadow</filename> file exist, and the
+           group has no entry in the <filename>/etc/gshadow</filename>
+           file, a new entry will be created.
+         </para>
        </listitem>
       </varlistentry>
       <varlistentry>
        <term><option>-d</option> <replaceable>user_name</replaceable></term>
        <listitem>
          <para>Delete a user from the group membership list.</para>
+         <para condition="gshadow">
+           If the <filename>/etc/gshadow</filename> file exist, the user
+           will be removed from the list of members and administrators of
+           the group.
+         </para>
+         <para condition="gshadow">
+           If the <filename>/etc/gshadow</filename> file exist, and the
+           group has no entry in the <filename>/etc/gshadow</filename>
+           file, a new entry will be created.
+         </para>
        </listitem>
       </varlistentry>
       <varlistentry>
        <term><option>-p</option></term>
        <listitem>
          <para>Purge all users from the group membership list.</para>
+         <para condition="gshadow">
+           If the <filename>/etc/gshadow</filename> file exist, and the
+           group has no entry in the <filename>/etc/gshadow</filename>
+           file, a new entry will be created.
+         </para>
        </listitem>
       </varlistentry>
     </variablelist>
index a33330036dd7bfa7f2c447c47cb4459dfd8ba305..a8e4f7fbddf40b6526e2b89dbe87c58309e01839 100644 (file)
@@ -44,6 +44,9 @@
 #include "defines.h"
 #include "prototypes.h"
 #include "groupio.h"
+#ifdef SHADOWGRP
+#include "sgroupio.h"
+#endif
 
 /* Exit Status Values */
 
@@ -69,6 +72,12 @@ static bool list = false;
 static int exclusive = 0;
 static char *Prog;
 static bool gr_locked = false;
+#ifdef SHADOWGRP
+/* Indicate if shadow groups are enabled on the system
+ * (/etc/gshadow present) */
+static bool is_shadowgrp;
+static bool sgr_locked = false;
+#endif
 
 /* local function prototypes */
 static char *whoami (void);
@@ -121,11 +130,60 @@ static void add_user (const char *user,
                fprintf (stderr,
                         _("%s: Out of memory. Cannot update %s.\n"),
                         Prog, gr_dbname ());
-               exit (13);
+               fail_exit (13);
        }
 
        /* Add the user to the /etc/group group */
        newgrp->gr_mem = add_list (newgrp->gr_mem, user);
+
+#ifdef SHADOWGRP
+       if (is_shadowgrp) {
+               const struct sgrp *sg = sgr_locate (newgrp->gr_name);
+               struct sgrp *newsg;
+
+               if (NULL == sg) {
+                       /* Create a shadow group based on this group */
+                       static struct sgrp sgrent;
+                       sgrent.sg_name = xstrdup (newgrp->gr_name);
+                       sgrent.sg_mem = dup_list (newgrp->gr_mem);
+                       sgrent.sg_adm = (char **) xmalloc (sizeof (char *));
+#ifdef FIRST_MEMBER_IS_ADMIN
+                       if (sgrent.sg_mem[0]) {
+                               sgrent.sg_adm[0] = xstrdup (sgrent.sg_mem[0]);
+                               sgrent.sg_adm[1] = NULL;
+                       } else
+#endif
+                       {
+                               sgrent.sg_adm[0] = NULL;
+                       }
+
+                       /* Move any password to gshadow */
+                       sgrent.sg_passwd = newgrp->gr_passwd;
+                       newgrp->gr_passwd = SHADOW_PASSWD_STRING;
+
+                       newsg = &sgrent;
+               } else {
+                       newsg = __sgr_dup (sg);
+                       if (NULL == newsg) {
+                               fprintf (stderr,
+                                        _("%s: Out of memory. Cannot update %s.\n"),
+                                        Prog, sgr_dbname ());
+                               fail_exit (13);
+                       }
+                       /* Add the user to the members */
+                       newsg->sg_mem = add_list (newsg->sg_mem, user);
+                       /* Do not touch the administrators */
+               }
+
+               if (sgr_update (newsg) == 0) {
+                       fprintf (stderr,
+                                _("%s: failed to prepare the new %s entry '%s'\n"),
+                                Prog, sgr_dbname (), newsg->sg_name);
+                       fail_exit (13);
+               }
+       }
+#endif
+
        if (gr_update (newgrp) == 0) {
                fprintf (stderr,
                         _("%s: failed to prepare the new %s entry '%s'\n"),
@@ -155,11 +213,61 @@ static void remove_user (const char *user,
                fprintf (stderr,
                         _("%s: Out of memory. Cannot update %s.\n"),
                         Prog, gr_dbname ());
-               exit (13);
+               fail_exit (13);
        }
 
        /* Remove the user from the /etc/group group */
        newgrp->gr_mem = del_list (newgrp->gr_mem, user);
+
+#ifdef SHADOWGRP
+       if (is_shadowgrp) {
+               const struct sgrp *sg = sgr_locate (newgrp->gr_name);
+               struct sgrp *newsg;
+
+               if (NULL == sg) {
+                       /* Create a shadow group based on this group */
+                       static struct sgrp sgrent;
+                       sgrent.sg_name = xstrdup (newgrp->gr_name);
+                       sgrent.sg_mem = dup_list (newgrp->gr_mem);
+                       sgrent.sg_adm = (char **) xmalloc (sizeof (char *));
+#ifdef FIRST_MEMBER_IS_ADMIN
+                       if (sgrent.sg_mem[0]) {
+                               sgrent.sg_adm[0] = xstrdup (sgrent.sg_mem[0]);
+                               sgrent.sg_adm[1] = NULL;
+                       } else
+#endif
+                       {
+                               sgrent.sg_adm[0] = NULL;
+                       }
+
+                       /* Move any password to gshadow */
+                       sgrent.sg_passwd = newgrp->gr_passwd;
+                       newgrp->gr_passwd = SHADOW_PASSWD_STRING;
+
+                       newsg = &sgrent;
+               } else {
+                       newsg = __sgr_dup (sg);
+                       if (NULL == newsg) {
+                               fprintf (stderr,
+                                        _("%s: Out of memory. Cannot update %s.\n"),
+                                        Prog, sgr_dbname ());
+                               fail_exit (13);
+                       }
+                       /* Remove the user from the members */
+                       newsg->sg_mem = del_list (newsg->sg_mem, user);
+                       /* Remove the user from the administrators */
+                       newsg->sg_adm = del_list (newsg->sg_adm, user);
+               }
+
+               if (sgr_update (newsg) == 0) {
+                       fprintf (stderr,
+                                _("%s: failed to prepare the new %s entry '%s'\n"),
+                                Prog, sgr_dbname (), newsg->sg_name);
+                       fail_exit (13);
+               }
+       }
+#endif
+
        if (gr_update (newgrp) == 0) {
                fprintf (stderr,
                         _("%s: failed to prepare the new %s entry '%s'\n"),
@@ -179,11 +287,56 @@ static void purge_members (const struct group *grp)
                fprintf (stderr,
                         _("%s: Out of memory. Cannot update %s.\n"),
                         Prog, gr_dbname ());
-               exit (13);
+               fail_exit (13);
        }
 
        /* Remove all the members of the /etc/group group */
        newgrp->gr_mem[0] = NULL;
+
+#ifdef SHADOWGRP
+       if (is_shadowgrp) {
+               const struct sgrp *sg = sgr_locate (newgrp->gr_name);
+               struct sgrp *newsg;
+
+               if (NULL == sg) {
+                       /* Create a shadow group based on this group */
+                       static struct sgrp sgrent;
+                       sgrent.sg_name = xstrdup (newgrp->gr_name);
+                       sgrent.sg_mem = (char **) xmalloc (sizeof (char *));
+                       sgrent.sg_mem[0] = NULL;
+                       sgrent.sg_adm = (char **) xmalloc (sizeof (char *));
+                       sgrent.sg_adm[0] = NULL;
+
+                       /* Move any password to gshadow */
+                       sgrent.sg_passwd = newgrp->gr_passwd;
+                       newgrp->gr_passwd = xstrdup(SHADOW_PASSWD_STRING);
+
+                       newsg = &sgrent;
+               } else {
+                       newsg = __sgr_dup (sg);
+                       if (NULL == newsg) {
+                               fprintf (stderr,
+                                        _("%s: Out of memory. Cannot update %s.\n"),
+                                        Prog, sgr_dbname ());
+                               fail_exit (13);
+                       }
+                       /* Remove all the members of the /etc/gshadow
+                        * group */
+                       newsg->sg_mem[0] = NULL;
+                       /* Remove all the administrators of the
+                        * /etc/gshadow group */
+                       newsg->sg_adm[0] = NULL;
+               }
+
+               if (sgr_update (newsg) == 0) {
+                       fprintf (stderr,
+                                _("%s: failed to prepare the new %s entry '%s'\n"),
+                                Prog, sgr_dbname (), newsg->sg_name);
+                       fail_exit (13);
+               }
+       }
+#endif
+
        if (gr_update (newgrp) == 0) {
                fprintf (stderr,
                         _("%s: failed to prepare the new %s entry '%s'\n"),