upstream merge
This commit is contained in:
@@ -154,7 +154,7 @@ static /*@noreturn@*/void usage (int status)
|
||||
(void) fputs (_(" -l, --list show account aging information\n"), usageout);
|
||||
(void) fputs (_(" -m, --mindays MIN_DAYS set minimum number of days before password\n"
|
||||
" change to MIN_DAYS\n"), usageout);
|
||||
(void) fputs (_(" -M, --maxdays MAX_DAYS set maximim number of days before password\n"
|
||||
(void) fputs (_(" -M, --maxdays MAX_DAYS set maximum number of days before password\n"
|
||||
" change to MAX_DAYS\n"), usageout);
|
||||
(void) fputs (_(" -R, --root CHROOT_DIR directory to chroot into\n"), usageout);
|
||||
(void) fputs (_(" -W, --warndays WARN_DAYS set expiration warning days to WARN_DAYS\n"), usageout);
|
||||
@@ -780,7 +780,7 @@ static void get_defaults (/*@null@*/const struct spwd *sp)
|
||||
* -E set account expiration date (*)
|
||||
* -I set password inactive after expiration (*)
|
||||
* -l show account aging information
|
||||
* -M set maximim number of days before password change (*)
|
||||
* -M set maximum number of days before password change (*)
|
||||
* -m set minimum number of days before password change (*)
|
||||
* -W set expiration warning days (*)
|
||||
*
|
||||
|
@@ -552,7 +552,7 @@ int main (int argc, char **argv)
|
||||
if (NULL != sp) {
|
||||
newsp = *sp;
|
||||
newsp.sp_pwdp = cp;
|
||||
newsp.sp_lstchg = (long) time ((time_t *)NULL) / SCALE;
|
||||
newsp.sp_lstchg = (long) gettime () / SCALE;
|
||||
if (0 == newsp.sp_lstchg) {
|
||||
/* Better disable aging than requiring a
|
||||
* password change */
|
||||
|
@@ -66,6 +66,11 @@
|
||||
#define E_NOTFOUND 6 /* specified group doesn't exist */
|
||||
#define E_NAME_IN_USE 9 /* group name already in use */
|
||||
#define E_GRP_UPDATE 10 /* can't update group file */
|
||||
#define E_CLEANUP_SERVICE 11 /* can't setup cleanup service */
|
||||
#define E_PAM_USERNAME 12 /* can't determine your username for use with pam */
|
||||
#define E_PAM_ERROR 13 /* pam returned an error, see Syslog facility id groupmod */
|
||||
|
||||
|
||||
/*
|
||||
* Global variables
|
||||
*/
|
||||
@@ -763,7 +768,7 @@ int main (int argc, char **argv)
|
||||
fprintf (stderr,
|
||||
_("%s: Cannot setup cleanup service.\n"),
|
||||
Prog);
|
||||
exit (1);
|
||||
exit (E_CLEANUP_SERVICE);
|
||||
}
|
||||
|
||||
process_flags (argc, argv);
|
||||
@@ -777,7 +782,7 @@ int main (int argc, char **argv)
|
||||
fprintf (stderr,
|
||||
_("%s: Cannot determine your user name.\n"),
|
||||
Prog);
|
||||
exit (1);
|
||||
exit (E_PAM_USERNAME);
|
||||
}
|
||||
|
||||
retval = pam_start ("groupmod", pampw->pw_name, &conv, &pamh);
|
||||
@@ -798,7 +803,7 @@ int main (int argc, char **argv)
|
||||
if (NULL != pamh) {
|
||||
(void) pam_end (pamh, retval);
|
||||
}
|
||||
exit (1);
|
||||
exit (E_PAM_ERROR);
|
||||
}
|
||||
(void) pam_end (pamh, retval);
|
||||
#endif /* USE_PAM */
|
||||
|
75
src/newgrp.c
75
src/newgrp.c
@@ -83,16 +83,30 @@ static void usage (void)
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* find_matching_group - search all groups of a given group id for
|
||||
* membership of a given username
|
||||
*/
|
||||
static /*@null@*/struct group *find_matching_group (const char *name, gid_t gid)
|
||||
static bool ingroup(const char *name, struct group *gr)
|
||||
{
|
||||
struct group *gr;
|
||||
char **look;
|
||||
bool notfound = true;
|
||||
|
||||
look = gr->gr_mem;
|
||||
while (*look && notfound)
|
||||
notfound = strcmp (*look++, name);
|
||||
|
||||
return !notfound;
|
||||
}
|
||||
|
||||
/*
|
||||
* find_matching_group - search all groups of a gr's group id for
|
||||
* membership of a given username
|
||||
* but check gr itself first
|
||||
*/
|
||||
static /*@null@*/struct group *find_matching_group (const char *name, struct group *gr)
|
||||
{
|
||||
gid_t gid = gr->gr_gid;
|
||||
|
||||
if (ingroup(name, gr))
|
||||
return gr;
|
||||
|
||||
setgrent ();
|
||||
while ((gr = getgrent ()) != NULL) {
|
||||
if (gr->gr_gid != gid) {
|
||||
@@ -103,14 +117,8 @@ static /*@null@*/struct group *find_matching_group (const char *name, gid_t gid)
|
||||
* A group with matching GID was found.
|
||||
* Test for membership of 'name'.
|
||||
*/
|
||||
look = gr->gr_mem;
|
||||
while ((NULL != *look) && notfound) {
|
||||
notfound = (strcmp (*look, name) != 0);
|
||||
look++;
|
||||
}
|
||||
if (!notfound) {
|
||||
if (ingroup(name, gr))
|
||||
break;
|
||||
}
|
||||
}
|
||||
endgrent ();
|
||||
return gr;
|
||||
@@ -387,6 +395,7 @@ int main (int argc, char **argv)
|
||||
{
|
||||
bool initflag = false;
|
||||
int i;
|
||||
bool is_member = false;
|
||||
bool cflag = false;
|
||||
int err = 0;
|
||||
gid_t gid;
|
||||
@@ -625,22 +634,36 @@ int main (int argc, char **argv)
|
||||
goto failure;
|
||||
}
|
||||
|
||||
#ifdef HAVE_SETGROUPS
|
||||
/* when using pam_group, she will not be listed in the groups
|
||||
* database. However getgroups() will return the group. So
|
||||
* if she is listed there already it is ok to grant membership.
|
||||
*/
|
||||
for (i = 0; i < ngroups; i++) {
|
||||
if (grp->gr_gid == grouplist[i]) {
|
||||
is_member = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
#endif /* HAVE_SETGROUPS */
|
||||
/*
|
||||
* For splitted groups (due to limitations of NIS), check all
|
||||
* groups of the same GID like the requested group for
|
||||
* membership of the current user.
|
||||
*/
|
||||
grp = find_matching_group (name, grp->gr_gid);
|
||||
if (NULL == grp) {
|
||||
/*
|
||||
* No matching group found. As we already know that
|
||||
* the group exists, this happens only in the case
|
||||
* of a requested group where the user is not member.
|
||||
*
|
||||
* Re-read the group entry for further processing.
|
||||
*/
|
||||
grp = xgetgrnam (group);
|
||||
assert (NULL != grp);
|
||||
if (!is_member) {
|
||||
grp = find_matching_group (name, grp);
|
||||
if (NULL == grp) {
|
||||
/*
|
||||
* No matching group found. As we already know that
|
||||
* the group exists, this happens only in the case
|
||||
* of a requested group where the user is not member.
|
||||
*
|
||||
* Re-read the group entry for further processing.
|
||||
*/
|
||||
grp = xgetgrnam (group);
|
||||
assert (NULL != grp);
|
||||
}
|
||||
}
|
||||
#ifdef SHADOWGRP
|
||||
sgrp = getsgnam (group);
|
||||
@@ -653,7 +676,9 @@ int main (int argc, char **argv)
|
||||
/*
|
||||
* Check if the user is allowed to access this group.
|
||||
*/
|
||||
check_perms (grp, pwd, group);
|
||||
if (!is_member) {
|
||||
check_perms (grp, pwd, group);
|
||||
}
|
||||
|
||||
/*
|
||||
* all successful validations pass through this point. The group id
|
||||
|
@@ -496,7 +496,7 @@ static int add_passwd (struct passwd *pwd, const char *password)
|
||||
}
|
||||
spent.sp_pwdp = cp;
|
||||
}
|
||||
spent.sp_lstchg = (long) time ((time_t *) 0) / SCALE;
|
||||
spent.sp_lstchg = (long) gettime () / SCALE;
|
||||
if (0 == spent.sp_lstchg) {
|
||||
/* Better disable aging than requiring a password
|
||||
* change */
|
||||
@@ -553,7 +553,7 @@ static int add_passwd (struct passwd *pwd, const char *password)
|
||||
*/
|
||||
spent.sp_pwdp = "!";
|
||||
#endif
|
||||
spent.sp_lstchg = (long) time ((time_t *) 0) / SCALE;
|
||||
spent.sp_lstchg = (long) gettime () / SCALE;
|
||||
if (0 == spent.sp_lstchg) {
|
||||
/* Better disable aging than requiring a password change */
|
||||
spent.sp_lstchg = -1;
|
||||
|
@@ -668,7 +668,7 @@ static void update_shadow (void)
|
||||
}
|
||||
#ifndef USE_PAM
|
||||
if (do_update_age) {
|
||||
nsp->sp_lstchg = (long) time ((time_t *) 0) / SCALE;
|
||||
nsp->sp_lstchg = (long) gettime () / SCALE;
|
||||
if (0 == nsp->sp_lstchg) {
|
||||
/* Better disable aging than requiring a password
|
||||
* change */
|
||||
|
2
src/su.c
2
src/su.c
@@ -379,7 +379,7 @@ static void prepare_pam_close_session (void)
|
||||
/* wake child when resumed */
|
||||
kill (pid, SIGCONT);
|
||||
stop = false;
|
||||
} else {
|
||||
} else if ( (pid_t)-1 != pid) {
|
||||
pid_child = 0;
|
||||
}
|
||||
} while (!stop);
|
||||
|
@@ -882,7 +882,7 @@ static void new_spent (struct spwd *spent)
|
||||
memzero (spent, sizeof *spent);
|
||||
spent->sp_namp = (char *) user_name;
|
||||
spent->sp_pwdp = (char *) user_pass;
|
||||
spent->sp_lstchg = (long) time ((time_t *) 0) / SCALE;
|
||||
spent->sp_lstchg = (long) gettime () / SCALE;
|
||||
if (0 == spent->sp_lstchg) {
|
||||
/* Better disable aging than requiring a password change */
|
||||
spent->sp_lstchg = -1;
|
||||
|
@@ -97,6 +97,7 @@ static char *user_home;
|
||||
static bool fflg = false;
|
||||
static bool rflg = false;
|
||||
static bool Zflg = false;
|
||||
static bool Rflg = false;
|
||||
|
||||
static bool is_shadow_pwd;
|
||||
|
||||
@@ -1048,6 +1049,7 @@ int main (int argc, char **argv)
|
||||
rflg = true;
|
||||
break;
|
||||
case 'R': /* no-op, handled in process_root_flag () */
|
||||
Rflg = true;
|
||||
break;
|
||||
case 'P': /* no-op, handled in process_prefix_flag () */
|
||||
break;
|
||||
@@ -1130,9 +1132,12 @@ int main (int argc, char **argv)
|
||||
*/
|
||||
user_name = argv[argc - 1];
|
||||
{
|
||||
struct passwd *pwd;
|
||||
pwd = prefix_getpwnam (user_name); /* local, no need for xgetpwnam */
|
||||
const struct passwd *pwd;
|
||||
|
||||
pw_open(O_RDONLY);
|
||||
pwd = pw_locate (user_name); /* we care only about local users */
|
||||
if (NULL == pwd) {
|
||||
pw_close();
|
||||
fprintf (stderr, _("%s: user '%s' does not exist\n"),
|
||||
Prog, user_name);
|
||||
#ifdef WITH_AUDIT
|
||||
@@ -1157,6 +1162,7 @@ int main (int argc, char **argv)
|
||||
else {
|
||||
user_home = xstrdup (pwd->pw_dir);
|
||||
}
|
||||
pw_close();
|
||||
}
|
||||
#ifdef WITH_TCB
|
||||
if (shadowtcb_set_user (user_name) == SHADOWTCB_FAILURE) {
|
||||
@@ -1188,7 +1194,7 @@ int main (int argc, char **argv)
|
||||
* Note: This is a best effort basis. The user may log in between,
|
||||
* a cron job may be started on her behalf, etc.
|
||||
*/
|
||||
if ((prefix[0] == '\0') && user_busy (user_name, user_id) != 0) {
|
||||
if ((prefix[0] == '\0') && !Rflg && user_busy (user_name, user_id) != 0) {
|
||||
if (!fflg) {
|
||||
#ifdef WITH_AUDIT
|
||||
audit_logger (AUDIT_DEL_USER, Prog,
|
||||
|
@@ -416,7 +416,7 @@ static /*@noreturn@*/void usage (int status)
|
||||
(void) fputs (_(" -G, --groups GROUPS new list of supplementary GROUPS\n"), usageout);
|
||||
(void) fputs (_(" -a, --append append the user to the supplemental GROUPS\n"
|
||||
" mentioned by the -G option without removing\n"
|
||||
" him/her from other groups\n"), usageout);
|
||||
" the user from other groups\n"), usageout);
|
||||
(void) fputs (_(" -h, --help display this help message and exit\n"), usageout);
|
||||
(void) fputs (_(" -l, --login NEW_LOGIN new value of the login name\n"), usageout);
|
||||
(void) fputs (_(" -L, --lock lock the user account\n"), usageout);
|
||||
@@ -647,7 +647,7 @@ static void new_spent (struct spwd *spent)
|
||||
spent->sp_pwdp = new_pw_passwd (spent->sp_pwdp);
|
||||
|
||||
if (pflg) {
|
||||
spent->sp_lstchg = (long) time ((time_t *) 0) / SCALE;
|
||||
spent->sp_lstchg = (long) gettime () / SCALE;
|
||||
if (0 == spent->sp_lstchg) {
|
||||
/* Better disable aging than requiring a password
|
||||
* change. */
|
||||
@@ -1704,7 +1704,7 @@ static void usr_update (void)
|
||||
spent.sp_pwdp = xstrdup (pwent.pw_passwd);
|
||||
pwent.pw_passwd = xstrdup (SHADOW_PASSWD_STRING);
|
||||
|
||||
spent.sp_lstchg = (long) time ((time_t *) 0) / SCALE;
|
||||
spent.sp_lstchg = (long) gettime () / SCALE;
|
||||
if (0 == spent.sp_lstchg) {
|
||||
/* Better disable aging than
|
||||
* requiring a password change */
|
||||
|
Reference in New Issue
Block a user