* NEWS, src/userdel.c: Report errors to remove the user's mailbox.
* NEWS, src/userdel.c: When USERGROUPS_ENAB is enabled, remove the user's group when the user was the only member. This is still not complete, as the user could have been specified twice in the members. * NEWS, src/userdel.c: Do not fail when -r is used and the home directory does not exist.
This commit is contained in:
parent
738ebc04b9
commit
604c7d72d9
12
ChangeLog
12
ChangeLog
@ -1,4 +1,14 @@
|
|||||||
2009-05-21 Nicolas François <nicolas.francois@centraliens.net>
|
2009-05-22 Nicolas François <nicolas.francois@centraliens.net>
|
||||||
|
|
||||||
|
* NEWS, src/userdel.c: Report errors to remove the user's mailbox.
|
||||||
|
* NEWS, src/userdel.c: When USERGROUPS_ENAB is enabled, remove the
|
||||||
|
user's group when the user was the only member. This is still not
|
||||||
|
complete, as the user could have been specified twice in the
|
||||||
|
members.
|
||||||
|
* NEWS, src/userdel.c: Do not fail when -r is used and the home
|
||||||
|
directory does not exist.
|
||||||
|
|
||||||
|
2009-05-22 Nicolas François <nicolas.francois@centraliens.net>
|
||||||
|
|
||||||
* libmisc/copydir.c: Added warning for relative symlinks.
|
* libmisc/copydir.c: Added warning for relative symlinks.
|
||||||
* libmisc/copydir.c (remove_tree): There is no need to check if
|
* libmisc/copydir.c (remove_tree): There is no need to check if
|
||||||
|
4
NEWS
4
NEWS
@ -10,6 +10,10 @@ shadow-4.1.4 -> shadow-4.1.4.1 UNRELEASED
|
|||||||
the user is running some processes.
|
the user is running some processes.
|
||||||
* If not on Linux, continue to search for an utmp record, but make sure
|
* If not on Linux, continue to search for an utmp record, but make sure
|
||||||
the process recorded in the utmp entry is still running.
|
the process recorded in the utmp entry is still running.
|
||||||
|
* Report failures to remove the user's mailbox
|
||||||
|
* When USERGROUPS_ENAB is enabled, remove the user's group when the
|
||||||
|
user was the only member.
|
||||||
|
* Do not fail when -r is used and the home directory does not exist.
|
||||||
- usermod
|
- usermod
|
||||||
* Check if the user is busy when the user's UID, name or home directory
|
* Check if the user is busy when the user's UID, name or home directory
|
||||||
is changed.
|
is changed.
|
||||||
|
@ -106,7 +106,7 @@ static void user_cancel (const char *);
|
|||||||
static bool path_prefix (const char *, const char *);
|
static bool path_prefix (const char *, const char *);
|
||||||
#endif
|
#endif
|
||||||
static int is_owner (uid_t, const char *);
|
static int is_owner (uid_t, const char *);
|
||||||
static void remove_mailbox (void);
|
static int remove_mailbox (void);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* usage - display usage message and exit
|
* usage - display usage message and exit
|
||||||
@ -196,11 +196,16 @@ static void update_groups (void)
|
|||||||
* we've removed their name from all the groups above, so
|
* we've removed their name from all the groups above, so
|
||||||
* now if they have a group with the same name as their
|
* now if they have a group with the same name as their
|
||||||
* user name, with no members, we delete it.
|
* user name, with no members, we delete it.
|
||||||
|
* FIXME: below, the check for grp->gr_mem[0] is not sufficient.
|
||||||
|
* We should retrieve the group with gr_locate and check
|
||||||
|
* that gr_mem is empty.
|
||||||
*/
|
*/
|
||||||
grp = xgetgrnam (user_name);
|
grp = xgetgrnam (user_name);
|
||||||
if ( (NULL != grp)
|
if ( (NULL != grp)
|
||||||
&& getdef_bool ("USERGROUPS_ENAB")
|
&& getdef_bool ("USERGROUPS_ENAB")
|
||||||
&& (NULL == grp->gr_mem[0])) {
|
&& ( (NULL == grp->gr_mem[0])
|
||||||
|
|| ( (NULL == grp->gr_mem[1])
|
||||||
|
&& (strcmp (grp->gr_mem[0], user_name) == 0)))) {
|
||||||
|
|
||||||
pwd = NULL;
|
pwd = NULL;
|
||||||
if (!fflg) {
|
if (!fflg) {
|
||||||
@ -615,21 +620,36 @@ static bool path_prefix (const char *s1, const char *s2)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/*
|
||||||
|
* is_owner - Check if path is owned by uid
|
||||||
|
*
|
||||||
|
* Return
|
||||||
|
* 1: path exists and is owned by uid
|
||||||
|
* 0: path is not owned by uid, or a failure occured
|
||||||
|
* -1: path does not exist
|
||||||
|
*/
|
||||||
static int is_owner (uid_t uid, const char *path)
|
static int is_owner (uid_t uid, const char *path)
|
||||||
{
|
{
|
||||||
struct stat st;
|
struct stat st;
|
||||||
|
|
||||||
|
errno = 0;
|
||||||
if (stat (path, &st) != 0) {
|
if (stat (path, &st) != 0) {
|
||||||
|
if ((ENOENT == errno) || (ENOTDIR == errno)) {
|
||||||
|
/* The file or directory does not exist */
|
||||||
return -1;
|
return -1;
|
||||||
|
} else {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
return (st.st_uid == uid);
|
return (st.st_uid == uid);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void remove_mailbox (void)
|
static int remove_mailbox (void)
|
||||||
{
|
{
|
||||||
const char *maildir;
|
const char *maildir;
|
||||||
char mailfile[1024];
|
char mailfile[1024];
|
||||||
int i;
|
int i;
|
||||||
|
int errors = 0;
|
||||||
|
|
||||||
maildir = getdef_str ("MAIL_DIR");
|
maildir = getdef_str ("MAIL_DIR");
|
||||||
#ifdef MAIL_SPOOL_DIR
|
#ifdef MAIL_SPOOL_DIR
|
||||||
@ -638,12 +658,14 @@ static void remove_mailbox (void)
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
if (NULL == maildir) {
|
if (NULL == maildir) {
|
||||||
return;
|
return 0;
|
||||||
}
|
}
|
||||||
snprintf (mailfile, sizeof mailfile, "%s/%s", maildir, user_name);
|
snprintf (mailfile, sizeof mailfile, "%s/%s", maildir, user_name);
|
||||||
if (fflg) {
|
if (fflg) {
|
||||||
if (unlink (mailfile) != 0) {
|
if (unlink (mailfile) != 0) {
|
||||||
fprintf (stderr, _("%s: warning: can't remove %s: %s"), Prog, mailfile, strerror (errno));
|
fprintf (stderr,
|
||||||
|
_("%s: warning: can't remove %s: %s\n"),
|
||||||
|
Prog, mailfile, strerror (errno));
|
||||||
SYSLOG ((LOG_ERR, "Cannot remove %s: %s", mailfile, strerror (errno)));
|
SYSLOG ((LOG_ERR, "Cannot remove %s: %s", mailfile, strerror (errno)));
|
||||||
#ifdef WITH_AUDIT
|
#ifdef WITH_AUDIT
|
||||||
audit_logger (AUDIT_DEL_USER, Prog,
|
audit_logger (AUDIT_DEL_USER, Prog,
|
||||||
@ -651,6 +673,7 @@ static void remove_mailbox (void)
|
|||||||
user_name, (unsigned int) user_id,
|
user_name, (unsigned int) user_id,
|
||||||
SHADOW_AUDIT_FAILURE);
|
SHADOW_AUDIT_FAILURE);
|
||||||
#endif
|
#endif
|
||||||
|
errors = 1;
|
||||||
/* continue */
|
/* continue */
|
||||||
}
|
}
|
||||||
#ifdef WITH_AUDIT
|
#ifdef WITH_AUDIT
|
||||||
@ -662,26 +685,30 @@ static void remove_mailbox (void)
|
|||||||
SHADOW_AUDIT_SUCCESS);
|
SHADOW_AUDIT_SUCCESS);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
return;
|
return errors;
|
||||||
}
|
}
|
||||||
i = is_owner (user_id, mailfile);
|
i = is_owner (user_id, mailfile);
|
||||||
if (i == 0) {
|
if (i == 0) {
|
||||||
fprintf (stderr,
|
fprintf (stderr,
|
||||||
_("%s: %s not owned by %s, not removing\n"),
|
_("%s: %s not owned by %s, not removing\n"),
|
||||||
Prog, mailfile, user_name);
|
Prog, mailfile, user_name);
|
||||||
SYSLOG ((LOG_ERR, "%s not owned by %s, not removed", mailfile, strerror (errno)));
|
SYSLOG ((LOG_ERR,
|
||||||
|
"%s not owned by %s, not removed",
|
||||||
|
mailfile, strerror (errno)));
|
||||||
#ifdef WITH_AUDIT
|
#ifdef WITH_AUDIT
|
||||||
audit_logger (AUDIT_DEL_USER, Prog,
|
audit_logger (AUDIT_DEL_USER, Prog,
|
||||||
"deleting mail file",
|
"deleting mail file",
|
||||||
user_name, (unsigned int) user_id,
|
user_name, (unsigned int) user_id,
|
||||||
SHADOW_AUDIT_FAILURE);
|
SHADOW_AUDIT_FAILURE);
|
||||||
#endif
|
#endif
|
||||||
return;
|
return 1;
|
||||||
} else if (i == -1) {
|
} else if (i == -1) {
|
||||||
return; /* mailbox doesn't exist */
|
return 0; /* mailbox doesn't exist */
|
||||||
}
|
}
|
||||||
if (unlink (mailfile) != 0) {
|
if (unlink (mailfile) != 0) {
|
||||||
fprintf (stderr, _("%s: warning: can't remove %s: %s"), Prog, mailfile, strerror (errno));
|
fprintf (stderr,
|
||||||
|
_("%s: warning: can't remove %s: %s\n"),
|
||||||
|
Prog, mailfile, strerror (errno));
|
||||||
SYSLOG ((LOG_ERR, "Cannot remove %s: %s", mailfile, strerror (errno)));
|
SYSLOG ((LOG_ERR, "Cannot remove %s: %s", mailfile, strerror (errno)));
|
||||||
#ifdef WITH_AUDIT
|
#ifdef WITH_AUDIT
|
||||||
audit_logger (AUDIT_DEL_USER, Prog,
|
audit_logger (AUDIT_DEL_USER, Prog,
|
||||||
@ -689,6 +716,7 @@ static void remove_mailbox (void)
|
|||||||
user_name, (unsigned int) user_id,
|
user_name, (unsigned int) user_id,
|
||||||
SHADOW_AUDIT_FAILURE);
|
SHADOW_AUDIT_FAILURE);
|
||||||
#endif
|
#endif
|
||||||
|
errors = 1;
|
||||||
/* continue */
|
/* continue */
|
||||||
}
|
}
|
||||||
#ifdef WITH_AUDIT
|
#ifdef WITH_AUDIT
|
||||||
@ -700,6 +728,7 @@ static void remove_mailbox (void)
|
|||||||
SHADOW_AUDIT_SUCCESS);
|
SHADOW_AUDIT_SUCCESS);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
return errors;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -868,9 +897,16 @@ int main (int argc, char **argv)
|
|||||||
update_groups ();
|
update_groups ();
|
||||||
|
|
||||||
if (rflg) {
|
if (rflg) {
|
||||||
remove_mailbox ();
|
errors += remove_mailbox ();
|
||||||
}
|
}
|
||||||
if (rflg && !fflg && (is_owner (user_id, user_home) == 0)) {
|
if (rflg) {
|
||||||
|
int home_owned = is_owner (user_id, user_home);
|
||||||
|
if (-1 == home_owned) {
|
||||||
|
fprintf (stderr,
|
||||||
|
_("%s: %s home directory (%s) not found\n"),
|
||||||
|
Prog, user_name, user_home);
|
||||||
|
rflg = 0;
|
||||||
|
} else if ((0 == home_owned) && !fflg) {
|
||||||
fprintf (stderr,
|
fprintf (stderr,
|
||||||
_("%s: %s not owned by %s, not removing\n"),
|
_("%s: %s not owned by %s, not removing\n"),
|
||||||
Prog, user_home, user_name);
|
Prog, user_home, user_name);
|
||||||
@ -878,6 +914,7 @@ int main (int argc, char **argv)
|
|||||||
errors++;
|
errors++;
|
||||||
/* continue */
|
/* continue */
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef EXTRA_CHECK_HOME_DIR
|
#ifdef EXTRA_CHECK_HOME_DIR
|
||||||
/* This may be slow, the above should be good enough. */
|
/* This may be slow, the above should be good enough. */
|
||||||
|
Loading…
x
Reference in New Issue
Block a user