* src/usermod.c (fail_exit): Add static variables pw_locked,
spw_locked, gr_locked, and sgr_locked to indicate which files must be unlocked. * src/usermod.c (open_files, close_files): Open and close the group files as well as the passwd files. This permit to check if the group files modification are allowed before writing the passwd files. * src/usermod.c (grp_update, update_gshadow, update_group): Do not return a status code, but call fail_exit() in case of error. The group files are no more opened and closed in update_gshadow() and update_group(). * src/usermod.c (main): move the call to grp_update between open_files and close_files. * src/usermod.c: Differentiate failure to add a group entry and failure to add a shadow group entry.
This commit is contained in:
parent
326074388c
commit
24e742d202
18
ChangeLog
18
ChangeLog
@ -1,3 +1,21 @@
|
|||||||
|
2007-11-17 Nicolas François <nicolas.francois@centraliens.net>
|
||||||
|
|
||||||
|
* src/usermod.c (fail_exit): Add static variables pw_locked,
|
||||||
|
spw_locked, gr_locked, and sgr_locked to indicate which files must
|
||||||
|
be unlocked.
|
||||||
|
* src/usermod.c (open_files, close_files): Open and close the
|
||||||
|
group files as well as the passwd files. This permit to check if
|
||||||
|
the group files modification are allowed before writing the passwd
|
||||||
|
files.
|
||||||
|
* src/usermod.c (grp_update, update_gshadow, update_group): Do not
|
||||||
|
return a status code, but call fail_exit() in case of error. The
|
||||||
|
group files are no more opened and closed in update_gshadow() and
|
||||||
|
update_group().
|
||||||
|
* src/usermod.c (main): move the call to grp_update between
|
||||||
|
open_files and close_files.
|
||||||
|
* src/usermod.c: Differentiate failure to add a group entry and
|
||||||
|
failure to add a shadow group entry.
|
||||||
|
|
||||||
2007-11-17 Nicolas François <nicolas.francois@centraliens.net>
|
2007-11-17 Nicolas François <nicolas.francois@centraliens.net>
|
||||||
|
|
||||||
* src/userdel.c: Differentiate failure to update a group entry and
|
* src/userdel.c: Differentiate failure to update a group entry and
|
||||||
|
2
NEWS
2
NEWS
@ -28,6 +28,8 @@ shadow-4.0.18.1 -> shadow-4.0.18.2 UNRELEASED
|
|||||||
- userdel: Abort if an error is detected while updating the passwd or group
|
- userdel: Abort if an error is detected while updating the passwd or group
|
||||||
databases. The passwd or group files will not be written.
|
databases. The passwd or group files will not be written.
|
||||||
- usermod: Update the group database before flushing the nscd caches.
|
- usermod: Update the group database before flushing the nscd caches.
|
||||||
|
- usermod: Make sure the group modifications will be allowed before
|
||||||
|
writing the passwd files.
|
||||||
|
|
||||||
shadow-4.0.18.1 -> shadow-4.0.18.2 28-10-2007
|
shadow-4.0.18.1 -> shadow-4.0.18.2 28-10-2007
|
||||||
|
|
||||||
|
179
src/usermod.c
179
src/usermod.c
@ -105,7 +105,7 @@ static long user_newinactive; /* Audit */
|
|||||||
static char *Prog;
|
static char *Prog;
|
||||||
|
|
||||||
static int
|
static int
|
||||||
aflg = 0, /* append to existing secondary group set */
|
aflg = 0, /* append to existing secondary group set */
|
||||||
cflg = 0, /* new comment (GECOS) field */
|
cflg = 0, /* new comment (GECOS) field */
|
||||||
dflg = 0, /* new home directory */
|
dflg = 0, /* new home directory */
|
||||||
eflg = 0, /* days since 1970-01-01 when account becomes expired */
|
eflg = 0, /* days since 1970-01-01 when account becomes expired */
|
||||||
@ -127,6 +127,13 @@ static int is_shadow_pwd;
|
|||||||
static int is_shadow_grp;
|
static int is_shadow_grp;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
static int pw_locked = 0;
|
||||||
|
static int spw_locked = 0;
|
||||||
|
static int gr_locked = 0;
|
||||||
|
#ifdef SHADOWGRP
|
||||||
|
static int sgr_locked = 0;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
/* local function prototypes */
|
/* local function prototypes */
|
||||||
static int get_groups (char *);
|
static int get_groups (char *);
|
||||||
@ -135,12 +142,12 @@ static void new_pwent (struct passwd *);
|
|||||||
|
|
||||||
static void new_spent (struct spwd *);
|
static void new_spent (struct spwd *);
|
||||||
static void fail_exit (int);
|
static void fail_exit (int);
|
||||||
static int update_group (void);
|
static void update_group (void);
|
||||||
|
|
||||||
#ifdef SHADOWGRP
|
#ifdef SHADOWGRP
|
||||||
static int update_gshadow (void);
|
static void update_gshadow (void);
|
||||||
#endif
|
#endif
|
||||||
static int grp_update (void);
|
static void grp_update (void);
|
||||||
|
|
||||||
static long get_number (const char *);
|
static long get_number (const char *);
|
||||||
static uid_t get_id (const char *);
|
static uid_t get_id (const char *);
|
||||||
@ -514,14 +521,17 @@ static void new_spent (struct spwd *spent)
|
|||||||
*/
|
*/
|
||||||
static void fail_exit (int code)
|
static void fail_exit (int code)
|
||||||
{
|
{
|
||||||
(void) gr_unlock ();
|
if (gr_locked)
|
||||||
|
gr_unlock ();
|
||||||
#ifdef SHADOWGRP
|
#ifdef SHADOWGRP
|
||||||
if (is_shadow_grp)
|
if (sgr_locked)
|
||||||
sgr_unlock ();
|
sgr_unlock ();
|
||||||
#endif
|
#endif
|
||||||
if (is_shadow_pwd)
|
if (spw_locked)
|
||||||
spw_unlock ();
|
spw_unlock ();
|
||||||
(void) pw_unlock ();
|
if (pw_locked)
|
||||||
|
pw_unlock ();
|
||||||
|
|
||||||
#ifdef WITH_AUDIT
|
#ifdef WITH_AUDIT
|
||||||
audit_logger (AUDIT_USER_CHAUTHTOK, Prog, "modifying account",
|
audit_logger (AUDIT_USER_CHAUTHTOK, Prog, "modifying account",
|
||||||
user_name, -1, 0);
|
user_name, -1, 0);
|
||||||
@ -530,7 +540,7 @@ static void fail_exit (int code)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
static int update_group (void)
|
static void update_group (void)
|
||||||
{
|
{
|
||||||
int is_member;
|
int is_member;
|
||||||
int was_member;
|
int was_member;
|
||||||
@ -538,22 +548,6 @@ static int update_group (void)
|
|||||||
const struct group *grp;
|
const struct group *grp;
|
||||||
struct group *ngrp;
|
struct group *ngrp;
|
||||||
|
|
||||||
/*
|
|
||||||
* Lock and open the group file. This will load all of the group
|
|
||||||
* entries.
|
|
||||||
*/
|
|
||||||
if (!gr_lock ()) {
|
|
||||||
fprintf (stderr, _("%s: error locking group file\n"), Prog);
|
|
||||||
SYSLOG ((LOG_ERR, "error locking group file"));
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
if (!gr_open (O_RDWR)) {
|
|
||||||
fprintf (stderr, _("%s: error opening group file\n"), Prog);
|
|
||||||
SYSLOG ((LOG_ERR, "error opening group file"));
|
|
||||||
gr_unlock ();
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
changed = 0;
|
changed = 0;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -576,8 +570,7 @@ static int update_group (void)
|
|||||||
fprintf (stderr,
|
fprintf (stderr,
|
||||||
_("%s: Out of memory. Cannot update the group database.\n"),
|
_("%s: Out of memory. Cannot update the group database.\n"),
|
||||||
Prog);
|
Prog);
|
||||||
gr_unlock ();
|
fail_exit (E_GRP_UPDATE);
|
||||||
return -1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (was_member && (!Gflg || is_member)) {
|
if (was_member && (!Gflg || is_member)) {
|
||||||
@ -627,23 +620,16 @@ static int update_group (void)
|
|||||||
if (!gr_update (ngrp)) {
|
if (!gr_update (ngrp)) {
|
||||||
fprintf (stderr,
|
fprintf (stderr,
|
||||||
_("%s: error adding new group entry\n"), Prog);
|
_("%s: error adding new group entry\n"), Prog);
|
||||||
SYSLOG ((LOG_ERR, "error adding group entry"));
|
SYSLOG ((LOG_ERR, "error adding new group entry"));
|
||||||
gr_unlock ();
|
fail_exit (E_GRP_UPDATE);
|
||||||
return -1;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!gr_close ()) {
|
|
||||||
fprintf (stderr, _("%s: cannot rewrite group file\n"), Prog);
|
|
||||||
gr_unlock ();
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
gr_unlock ();
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef SHADOWGRP
|
#ifdef SHADOWGRP
|
||||||
static int update_gshadow (void)
|
static void update_gshadow (void)
|
||||||
{
|
{
|
||||||
int is_member;
|
int is_member;
|
||||||
int was_member;
|
int was_member;
|
||||||
@ -652,20 +638,6 @@ static int update_gshadow (void)
|
|||||||
const struct sgrp *sgrp;
|
const struct sgrp *sgrp;
|
||||||
struct sgrp *nsgrp;
|
struct sgrp *nsgrp;
|
||||||
|
|
||||||
if (!sgr_lock ()) {
|
|
||||||
fprintf (stderr,
|
|
||||||
_("%s: error locking shadow group file\n"), Prog);
|
|
||||||
SYSLOG ((LOG_ERR, "error locking shadow group file"));
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
if (!sgr_open (O_RDWR)) {
|
|
||||||
fprintf (stderr,
|
|
||||||
_("%s: error opening shadow group file\n"), Prog);
|
|
||||||
SYSLOG ((LOG_ERR, "error opening shadow group file"));
|
|
||||||
sgr_unlock ();
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
changed = 0;
|
changed = 0;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -698,8 +670,7 @@ static int update_gshadow (void)
|
|||||||
fprintf (stderr,
|
fprintf (stderr,
|
||||||
_("%s: Out of memory. Cannot update the shadow group database.\n"),
|
_("%s: Out of memory. Cannot update the shadow group database.\n"),
|
||||||
Prog);
|
Prog);
|
||||||
sgr_unlock ();
|
fail_exit (E_GRP_UPDATE);
|
||||||
return -1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (was_admin && lflg) {
|
if (was_admin && lflg) {
|
||||||
@ -767,21 +738,11 @@ static int update_gshadow (void)
|
|||||||
*/
|
*/
|
||||||
if (!sgr_update (nsgrp)) {
|
if (!sgr_update (nsgrp)) {
|
||||||
fprintf (stderr,
|
fprintf (stderr,
|
||||||
_("%s: error adding new group entry\n"), Prog);
|
_("%s: error adding new shadow group entry\n"), Prog);
|
||||||
SYSLOG ((LOG_ERR, "error adding shadow group entry"));
|
SYSLOG ((LOG_ERR, "error adding shadow group entry"));
|
||||||
sgr_unlock ();
|
fail_exit (E_GRP_UPDATE);
|
||||||
return -1;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!sgr_close ()) {
|
|
||||||
fprintf (stderr,
|
|
||||||
_("%s: cannot rewrite shadow group file\n"), Prog);
|
|
||||||
sgr_unlock ();
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
sgr_unlock ();
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
#endif /* SHADOWGRP */
|
#endif /* SHADOWGRP */
|
||||||
|
|
||||||
@ -791,16 +752,13 @@ static int update_gshadow (void)
|
|||||||
* grp_update() takes the secondary group set given in user_groups and
|
* grp_update() takes the secondary group set given in user_groups and
|
||||||
* adds the user to each group given by that set.
|
* adds the user to each group given by that set.
|
||||||
*/
|
*/
|
||||||
static int grp_update (void)
|
static void grp_update (void)
|
||||||
{
|
{
|
||||||
int ret;
|
update_group ();
|
||||||
|
|
||||||
ret = update_group ();
|
|
||||||
#ifdef SHADOWGRP
|
#ifdef SHADOWGRP
|
||||||
if (!ret && is_shadow_grp)
|
if (is_shadow_grp)
|
||||||
ret = update_gshadow ();
|
update_gshadow ();
|
||||||
#endif
|
#endif
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static long get_number (const char *numstr)
|
static long get_number (const char *numstr)
|
||||||
@ -1138,9 +1096,34 @@ static void close_files (void)
|
|||||||
_("%s: cannot rewrite shadow password file\n"), Prog);
|
_("%s: cannot rewrite shadow password file\n"), Prog);
|
||||||
fail_exit (E_PW_UPDATE);
|
fail_exit (E_PW_UPDATE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (Gflg || lflg) {
|
||||||
|
if (!gr_close ()) {
|
||||||
|
fprintf (stderr, _("%s: cannot rewrite group file\n"),
|
||||||
|
Prog);
|
||||||
|
fail_exit (E_GRP_UPDATE);
|
||||||
|
}
|
||||||
|
#ifdef SHADOWGRP
|
||||||
|
if (is_shadow_grp && !sgr_close ()) {
|
||||||
|
fprintf (stderr,
|
||||||
|
_("%s: cannot rewrite shadow group file\n"),
|
||||||
|
Prog);
|
||||||
|
fail_exit (E_GRP_UPDATE);
|
||||||
|
}
|
||||||
|
if (is_shadow_grp)
|
||||||
|
sgr_unlock ();
|
||||||
|
#endif
|
||||||
|
gr_unlock ();
|
||||||
|
}
|
||||||
|
|
||||||
if (is_shadow_pwd)
|
if (is_shadow_pwd)
|
||||||
spw_unlock ();
|
spw_unlock ();
|
||||||
(void) pw_unlock ();
|
pw_unlock ();
|
||||||
|
|
||||||
|
pw_locked = 0;
|
||||||
|
spw_locked = 0;
|
||||||
|
gr_locked = 0;
|
||||||
|
sgr_locked = 0;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Close the DBM and/or flat files
|
* Close the DBM and/or flat files
|
||||||
@ -1162,8 +1145,9 @@ static void open_files (void)
|
|||||||
{
|
{
|
||||||
if (!pw_lock ()) {
|
if (!pw_lock ()) {
|
||||||
fprintf (stderr, _("%s: unable to lock password file\n"), Prog);
|
fprintf (stderr, _("%s: unable to lock password file\n"), Prog);
|
||||||
exit (E_PW_UPDATE);
|
fail_exit (E_PW_UPDATE);
|
||||||
}
|
}
|
||||||
|
pw_locked = 1;
|
||||||
if (!pw_open (O_RDWR)) {
|
if (!pw_open (O_RDWR)) {
|
||||||
fprintf (stderr, _("%s: unable to open password file\n"), Prog);
|
fprintf (stderr, _("%s: unable to open password file\n"), Prog);
|
||||||
fail_exit (E_PW_UPDATE);
|
fail_exit (E_PW_UPDATE);
|
||||||
@ -1173,11 +1157,48 @@ static void open_files (void)
|
|||||||
_("%s: cannot lock shadow password file\n"), Prog);
|
_("%s: cannot lock shadow password file\n"), Prog);
|
||||||
fail_exit (E_PW_UPDATE);
|
fail_exit (E_PW_UPDATE);
|
||||||
}
|
}
|
||||||
|
spw_locked = 1;
|
||||||
if (is_shadow_pwd && !spw_open (O_RDWR)) {
|
if (is_shadow_pwd && !spw_open (O_RDWR)) {
|
||||||
fprintf (stderr,
|
fprintf (stderr,
|
||||||
_("%s: cannot open shadow password file\n"), Prog);
|
_("%s: cannot open shadow password file\n"), Prog);
|
||||||
fail_exit (E_PW_UPDATE);
|
fail_exit (E_PW_UPDATE);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (Gflg || lflg) {
|
||||||
|
/*
|
||||||
|
* Lock and open the group file. This will load all of the
|
||||||
|
* group entries.
|
||||||
|
*/
|
||||||
|
if (!gr_lock ()) {
|
||||||
|
fprintf (stderr, _("%s: error locking group file\n"),
|
||||||
|
Prog);
|
||||||
|
fail_exit (E_GRP_UPDATE);
|
||||||
|
}
|
||||||
|
gr_locked = 1;
|
||||||
|
if (!gr_open (O_RDWR)) {
|
||||||
|
fprintf (stderr, _("%s: error opening group file\n"),
|
||||||
|
Prog);
|
||||||
|
fail_exit (E_GRP_UPDATE);
|
||||||
|
}
|
||||||
|
#ifdef SHADOWGRP
|
||||||
|
if (is_shadow_grp && !sgr_lock ()) {
|
||||||
|
fprintf (stderr,
|
||||||
|
_("%s: error locking shadow group file\n"),
|
||||||
|
Prog);
|
||||||
|
fail_exit (E_GRP_UPDATE);
|
||||||
|
}
|
||||||
|
sgr_locked = 1;
|
||||||
|
if (is_shadow_grp && !sgr_open (O_RDWR)) {
|
||||||
|
fprintf (stderr,
|
||||||
|
_("%s: error opening shadow group file\n"),
|
||||||
|
Prog);
|
||||||
|
fail_exit (E_GRP_UPDATE);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -1454,8 +1475,6 @@ static void move_mailbox (void)
|
|||||||
*/
|
*/
|
||||||
int main (int argc, char **argv)
|
int main (int argc, char **argv)
|
||||||
{
|
{
|
||||||
int grp_err = 0;
|
|
||||||
|
|
||||||
#ifdef USE_PAM
|
#ifdef USE_PAM
|
||||||
pam_handle_t *pamh = NULL;
|
pam_handle_t *pamh = NULL;
|
||||||
struct passwd *pampw;
|
struct passwd *pampw;
|
||||||
@ -1526,10 +1545,9 @@ int main (int argc, char **argv)
|
|||||||
*/
|
*/
|
||||||
open_files ();
|
open_files ();
|
||||||
usr_update ();
|
usr_update ();
|
||||||
close_files ();
|
|
||||||
|
|
||||||
if (Gflg || lflg)
|
if (Gflg || lflg)
|
||||||
grp_err = grp_update ();
|
grp_update ();
|
||||||
|
close_files ();
|
||||||
|
|
||||||
nscd_flush_cache ("passwd");
|
nscd_flush_cache ("passwd");
|
||||||
nscd_flush_cache ("group");
|
nscd_flush_cache ("group");
|
||||||
@ -1554,9 +1572,6 @@ int main (int argc, char **argv)
|
|||||||
user_gid, gflg ? user_newgid : user_gid);
|
user_gid, gflg ? user_newgid : user_gid);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (grp_err)
|
|
||||||
exit (E_GRP_UPDATE);
|
|
||||||
|
|
||||||
#ifdef USE_PAM
|
#ifdef USE_PAM
|
||||||
if (retval == PAM_SUCCESS)
|
if (retval == PAM_SUCCESS)
|
||||||
pam_end (pamh, PAM_SUCCESS);
|
pam_end (pamh, PAM_SUCCESS);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user