* NEWS, src/groupmems.c, man/groupmems.8.xml: Added support for

shadow groups.
	* src/groupmems.c: Use fail_exit() instead of exit().
This commit is contained in:
nekral-guest 2008-08-31 17:29:34 +00:00
parent 190a6e7687
commit 87b56b19fb
4 changed files with 183 additions and 3 deletions

View File

@ -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> 2008-08-29 Nicolas François <nicolas.francois@centraliens.net>
* src/groupmems.c: The grp structure returned by gr_locate is a * src/groupmems.c: The grp structure returned by gr_locate is a

1
NEWS
View File

@ -20,6 +20,7 @@ shadow-4.1.2.1 -> shadow-4.1.3 UNRELEASED
* Added syslog support. * Added syslog support.
* Use the groupmems PAM service name instead of groupmod. * Use the groupmems PAM service name instead of groupmod.
* Fix segmentation faults when adding or removing users from a group. * Fix segmentation faults when adding or removing users from a group.
* Added support for shadow groups.
- newusers - newusers
* Implement the -r, --system option. * Implement the -r, --system option.
- passwd - passwd

View File

@ -53,12 +53,27 @@
<term><option>-a</option> <replaceable>user_name</replaceable></term> <term><option>-a</option> <replaceable>user_name</replaceable></term>
<listitem> <listitem>
<para>Add a new user to the group membership list.</para> <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> </listitem>
</varlistentry> </varlistentry>
<varlistentry> <varlistentry>
<term><option>-d</option> <replaceable>user_name</replaceable></term> <term><option>-d</option> <replaceable>user_name</replaceable></term>
<listitem> <listitem>
<para>Delete a user from the group membership list.</para> <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> </listitem>
</varlistentry> </varlistentry>
<varlistentry> <varlistentry>
@ -79,6 +94,11 @@
<term><option>-p</option></term> <term><option>-p</option></term>
<listitem> <listitem>
<para>Purge all users from the group membership list.</para> <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> </listitem>
</varlistentry> </varlistentry>
</variablelist> </variablelist>

View File

@ -44,6 +44,9 @@
#include "defines.h" #include "defines.h"
#include "prototypes.h" #include "prototypes.h"
#include "groupio.h" #include "groupio.h"
#ifdef SHADOWGRP
#include "sgroupio.h"
#endif
/* Exit Status Values */ /* Exit Status Values */
@ -69,6 +72,12 @@ static bool list = false;
static int exclusive = 0; static int exclusive = 0;
static char *Prog; static char *Prog;
static bool gr_locked = false; 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 */ /* local function prototypes */
static char *whoami (void); static char *whoami (void);
@ -121,11 +130,60 @@ static void add_user (const char *user,
fprintf (stderr, fprintf (stderr,
_("%s: Out of memory. Cannot update %s.\n"), _("%s: Out of memory. Cannot update %s.\n"),
Prog, gr_dbname ()); Prog, gr_dbname ());
exit (13); fail_exit (13);
} }
/* Add the user to the /etc/group group */ /* Add the user to the /etc/group group */
newgrp->gr_mem = add_list (newgrp->gr_mem, user); 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) { if (gr_update (newgrp) == 0) {
fprintf (stderr, fprintf (stderr,
_("%s: failed to prepare the new %s entry '%s'\n"), _("%s: failed to prepare the new %s entry '%s'\n"),
@ -155,11 +213,61 @@ static void remove_user (const char *user,
fprintf (stderr, fprintf (stderr,
_("%s: Out of memory. Cannot update %s.\n"), _("%s: Out of memory. Cannot update %s.\n"),
Prog, gr_dbname ()); Prog, gr_dbname ());
exit (13); fail_exit (13);
} }
/* Remove the user from the /etc/group group */ /* Remove the user from the /etc/group group */
newgrp->gr_mem = del_list (newgrp->gr_mem, user); 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) { if (gr_update (newgrp) == 0) {
fprintf (stderr, fprintf (stderr,
_("%s: failed to prepare the new %s entry '%s'\n"), _("%s: failed to prepare the new %s entry '%s'\n"),
@ -179,11 +287,56 @@ static void purge_members (const struct group *grp)
fprintf (stderr, fprintf (stderr,
_("%s: Out of memory. Cannot update %s.\n"), _("%s: Out of memory. Cannot update %s.\n"),
Prog, gr_dbname ()); Prog, gr_dbname ());
exit (13); fail_exit (13);
} }
/* Remove all the members of the /etc/group group */ /* Remove all the members of the /etc/group group */
newgrp->gr_mem[0] = NULL; 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) { if (gr_update (newgrp) == 0) {
fprintf (stderr, fprintf (stderr,
_("%s: failed to prepare the new %s entry '%s'\n"), _("%s: failed to prepare the new %s entry '%s'\n"),