usermod: check only local groups with -G option

Check only local groups when adding new supplementary groups to a user

Resolves: https://bugzilla.redhat.com/show_bug.cgi?id=1727236
This commit is contained in:
ikerexxe 2020-03-27 14:23:02 +01:00
parent 125a5dc309
commit 140510de9d

View File

@ -183,6 +183,7 @@ static bool sub_gid_locked = false;
static void date_to_str (/*@unique@*//*@out@*/char *buf, size_t maxsize, static void date_to_str (/*@unique@*//*@out@*/char *buf, size_t maxsize,
long int date); long int date);
static int get_groups (char *); static int get_groups (char *);
static struct group * get_local_group (char * grp_name);
static /*@noreturn@*/void usage (int status); static /*@noreturn@*/void usage (int status);
static void new_pwent (struct passwd *); static void new_pwent (struct passwd *);
static void new_spent (struct spwd *); static void new_spent (struct spwd *);
@ -196,7 +197,9 @@ static void grp_update (void);
static void process_flags (int, char **); static void process_flags (int, char **);
static void close_files (void); static void close_files (void);
static void close_group_files (void);
static void open_files (void); static void open_files (void);
static void open_group_files (void);
static void usr_update (void); static void usr_update (void);
static void move_home (void); static void move_home (void);
static void update_lastlog (void); static void update_lastlog (void);
@ -253,6 +256,11 @@ static int get_groups (char *list)
return 0; return 0;
} }
/*
* Open the group files
*/
open_group_files ();
/* /*
* So long as there is some data to be converted, strip off each * So long as there is some data to be converted, strip off each
* name and look it up. A mix of numerical and string values for * name and look it up. A mix of numerical and string values for
@ -272,7 +280,7 @@ static int get_groups (char *list)
* Names starting with digits are treated as numerical GID * Names starting with digits are treated as numerical GID
* values, otherwise the string is looked up as is. * values, otherwise the string is looked up as is.
*/ */
grp = prefix_getgr_nam_gid (list); grp = get_local_group (list);
/* /*
* There must be a match, either by GID value or by * There must be a match, either by GID value or by
@ -322,6 +330,8 @@ static int get_groups (char *list)
gr_free ((struct group *)grp); gr_free ((struct group *)grp);
} while (NULL != list); } while (NULL != list);
close_group_files ();
user_groups[ngroups] = (char *) 0; user_groups[ngroups] = (char *) 0;
/* /*
@ -334,6 +344,44 @@ static int get_groups (char *list)
return 0; return 0;
} }
/*
* get_local_group - checks if a given group name exists locally
*
* get_local_group() checks if a given group name exists locally.
* If the name exists the group information is returned, otherwise NULL is
* returned.
*/
static struct group * get_local_group(char * grp_name)
{
const struct group *grp;
struct group *result_grp = NULL;
long long int gid;
char *endptr;
gid = strtoll (grp_name, &endptr, 10);
if ( ('\0' != *grp_name)
&& ('\0' == *endptr)
&& (ERANGE != errno)
&& (gid == (gid_t)gid)) {
grp = gr_locate_gid ((gid_t) gid);
}
else {
grp = gr_locate(grp_name);
}
if (grp != NULL) {
result_grp = __gr_dup (grp);
if (NULL == result_grp) {
fprintf (stderr,
_("%s: Out of memory. Cannot find group '%s'.\n"),
Prog, grp_name);
fail_exit (E_GRP_UPDATE);
}
}
return result_grp;
}
#ifdef ENABLE_SUBIDS #ifdef ENABLE_SUBIDS
struct ulong_range struct ulong_range
{ {
@ -1447,50 +1495,7 @@ static void close_files (void)
} }
if (Gflg || lflg) { if (Gflg || lflg) {
if (gr_close () == 0) { close_group_files ();
fprintf (stderr,
_("%s: failure while writing changes to %s\n"),
Prog, gr_dbname ());
SYSLOG ((LOG_ERR,
"failure while writing changes to %s",
gr_dbname ()));
fail_exit (E_GRP_UPDATE);
}
#ifdef SHADOWGRP
if (is_shadow_grp) {
if (sgr_close () == 0) {
fprintf (stderr,
_("%s: failure while writing changes to %s\n"),
Prog, sgr_dbname ());
SYSLOG ((LOG_ERR,
"failure while writing changes to %s",
sgr_dbname ()));
fail_exit (E_GRP_UPDATE);
}
}
#endif
#ifdef SHADOWGRP
if (is_shadow_grp) {
if (sgr_unlock () == 0) {
fprintf (stderr,
_("%s: failed to unlock %s\n"),
Prog, sgr_dbname ());
SYSLOG ((LOG_ERR,
"failed to unlock %s",
sgr_dbname ()));
/* continue */
}
}
#endif
if (gr_unlock () == 0) {
fprintf (stderr,
_("%s: failed to unlock %s\n"),
Prog, gr_dbname ());
SYSLOG ((LOG_ERR,
"failed to unlock %s",
gr_dbname ()));
/* continue */
}
} }
if (is_shadow_pwd) { if (is_shadow_pwd) {
@ -1559,6 +1564,60 @@ static void close_files (void)
#endif #endif
} }
/*
* close_group_files - close all of the files that were opened
*
* close_group_files() closes all of the files that were opened related
* with groups. This causes any modified entries to be written out.
*/
static void close_group_files (void)
{
if (gr_close () == 0) {
fprintf (stderr,
_("%s: failure while writing changes to %s\n"),
Prog, gr_dbname ());
SYSLOG ((LOG_ERR,
"failure while writing changes to %s",
gr_dbname ()));
fail_exit (E_GRP_UPDATE);
}
#ifdef SHADOWGRP
if (is_shadow_grp) {
if (sgr_close () == 0) {
fprintf (stderr,
_("%s: failure while writing changes to %s\n"),
Prog, sgr_dbname ());
SYSLOG ((LOG_ERR,
"failure while writing changes to %s",
sgr_dbname ()));
fail_exit (E_GRP_UPDATE);
}
}
#endif
#ifdef SHADOWGRP
if (is_shadow_grp) {
if (sgr_unlock () == 0) {
fprintf (stderr,
_("%s: failed to unlock %s\n"),
Prog, sgr_dbname ());
SYSLOG ((LOG_ERR,
"failed to unlock %s",
sgr_dbname ()));
/* continue */
}
}
#endif
if (gr_unlock () == 0) {
fprintf (stderr,
_("%s: failed to unlock %s\n"),
Prog, gr_dbname ());
SYSLOG ((LOG_ERR,
"failed to unlock %s",
gr_dbname ()));
/* continue */
}
}
/* /*
* open_files - lock and open the password files * open_files - lock and open the password files
* *
@ -1594,38 +1653,7 @@ static void open_files (void)
} }
if (Gflg || lflg) { if (Gflg || lflg) {
/* open_group_files ();
* Lock and open the group file. This will load all of the
* group entries.
*/
if (gr_lock () == 0) {
fprintf (stderr,
_("%s: cannot lock %s; try again later.\n"),
Prog, gr_dbname ());
fail_exit (E_GRP_UPDATE);
}
gr_locked = true;
if (gr_open (O_CREAT | O_RDWR) == 0) {
fprintf (stderr,
_("%s: cannot open %s\n"),
Prog, gr_dbname ());
fail_exit (E_GRP_UPDATE);
}
#ifdef SHADOWGRP
if (is_shadow_grp && (sgr_lock () == 0)) {
fprintf (stderr,
_("%s: cannot lock %s; try again later.\n"),
Prog, sgr_dbname ());
fail_exit (E_GRP_UPDATE);
}
sgr_locked = true;
if (is_shadow_grp && (sgr_open (O_CREAT | O_RDWR) == 0)) {
fprintf (stderr,
_("%s: cannot open %s\n"),
Prog, sgr_dbname ());
fail_exit (E_GRP_UPDATE);
}
#endif
} }
#ifdef ENABLE_SUBIDS #ifdef ENABLE_SUBIDS
if (vflg || Vflg) { if (vflg || Vflg) {
@ -1661,6 +1689,44 @@ static void open_files (void)
#endif /* ENABLE_SUBIDS */ #endif /* ENABLE_SUBIDS */
} }
/*
* open_group_files - lock and open the group files
*
* open_group_files() loads all of the group entries.
*/
static void open_group_files (void)
{
if (gr_lock () == 0) {
fprintf (stderr,
_("%s: cannot lock %s; try again later.\n"),
Prog, gr_dbname ());
fail_exit (E_GRP_UPDATE);
}
gr_locked = true;
if (gr_open (O_CREAT | O_RDWR) == 0) {
fprintf (stderr,
_("%s: cannot open %s\n"),
Prog, gr_dbname ());
fail_exit (E_GRP_UPDATE);
}
#ifdef SHADOWGRP
if (is_shadow_grp && (sgr_lock () == 0)) {
fprintf (stderr,
_("%s: cannot lock %s; try again later.\n"),
Prog, sgr_dbname ());
fail_exit (E_GRP_UPDATE);
}
sgr_locked = true;
if (is_shadow_grp && (sgr_open (O_CREAT | O_RDWR) == 0)) {
fprintf (stderr,
_("%s: cannot open %s\n"),
Prog, sgr_dbname ());
fail_exit (E_GRP_UPDATE);
}
#endif
}
/* /*
* usr_update - create the user entries * usr_update - create the user entries
* *