Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

newsubgid: add deny_setgroups option to /etc/subgid #99

Open
wants to merge 5 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
3 changes: 2 additions & 1 deletion lib/Makefile.am
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@

AUTOMAKE_OPTIONS = 1.0 foreign

DEFS =
DEFS =

noinst_LTLIBRARIES = libshadow.la

libshadow_la_LIBADD = ../libmisc/libmisc.la
libshadow_la_LDFLAGS = -version-info 0:0:0

libshadow_la_SOURCES = \
Expand Down
2 changes: 2 additions & 0 deletions lib/prototypes.h
Original file line number Diff line number Diff line change
Expand Up @@ -229,8 +229,10 @@ extern void setup_limits (const struct passwd *);
extern /*@only@*/ /*@out@*/char **add_list (/*@returned@*/ /*@only@*/char **, const char *);
extern /*@only@*/ /*@out@*/char **del_list (/*@returned@*/ /*@only@*/char **, const char *);
extern /*@only@*/ /*@out@*/char **dup_list (char *const *);
extern /*@only@*/ /*@out@*/void free_list (char *const *);
extern bool is_on_list (char *const *list, const char *member);
extern /*@only@*/char **comma_to_list (const char *);
extern /*@only@*/char *comma_from_list (char *const *);

/* log.c */
extern void dolastlog (
Expand Down
76 changes: 52 additions & 24 deletions lib/subordinateio.c
Original file line number Diff line number Diff line change
Expand Up @@ -18,9 +18,11 @@ struct subordinate_range {
const char *owner;
unsigned long start;
unsigned long count;
char **options;
};

#define NFIELDS 3
#define NFIELDS_MIN 3
#define NFIELDS_MAX 4

/*
* subordinate_dup: create a duplicate range
Expand All @@ -46,6 +48,7 @@ static /*@null@*/ /*@only@*/void *subordinate_dup (const void *ent)
}
range->start = rangeent->start;
range->count = rangeent->count;
range->options = dup_list(rangeent->options);

return range;
}
Expand All @@ -58,8 +61,9 @@ static /*@null@*/ /*@only@*/void *subordinate_dup (const void *ent)
static void subordinate_free (/*@out@*/ /*@only@*/void *ent)
{
struct subordinate_range *rangeent = ent;

free ((void *)(rangeent->owner));
free_list(rangeent->options);
free (rangeent);
}

Expand All @@ -76,9 +80,9 @@ static void *subordinate_parse (const char *line)
{
static struct subordinate_range range;
static char rangebuf[1024];
int i;
int i, j;
char *cp;
char *fields[NFIELDS];
char *fields[NFIELDS_MAX];

/*
* Copy the string to a temporary buffer so the substrings can
Expand All @@ -93,7 +97,7 @@ static void *subordinate_parse (const char *line)
* field. The fields are converted into NUL terminated strings.
*/

for (cp = rangebuf, i = 0; (i < NFIELDS) && (NULL != cp); i++) {
for (cp = rangebuf, i = 0; (i < NFIELDS_MAX) && (NULL != cp); i++) {
fields[i] = cp;
while (('\0' != *cp) && (':' != *cp)) {
cp++;
Expand All @@ -108,16 +112,23 @@ static void *subordinate_parse (const char *line)
}

/*
* There must be exactly NFIELDS colon separated fields or
* the entry is invalid. Also, fields must be non-blank.
* There must be at least NFIELDS_MIN and at most NFIELDS_MAX colon
* separated fields or the entry is invalid. The first NFIELDS_MIN fields
* must be non-blank.
*/
if (i != NFIELDS || *fields[0] == '\0' || *fields[1] == '\0' || *fields[2] == '\0')
if (i < NFIELDS_MIN || i > NFIELDS_MAX)
return NULL;
for (j = 0; j < NFIELDS_MIN; j++)
if (*fields[j] == '\0')
return NULL;

range.owner = fields[0];
if (getulong (fields[1], &range.start) == 0)
return NULL;
if (getulong (fields[2], &range.count) == 0)
return NULL;
if (i >= 4)
range.options = comma_to_list(fields[3]);

return &range;
}
Expand All @@ -133,11 +144,15 @@ static void *subordinate_parse (const char *line)
static int subordinate_put (const void *ent, FILE * file)
{
const struct subordinate_range *range = ent;
char *options = comma_from_list(range->options);

return fprintf(file, "%s:%lu:%lu\n",
range->owner,
range->start,
range->count) < 0 ? -1 : 0;
int n = fprintf(file, "%s:%lu:%lu:%s\n",
range->owner,
range->start,
range->count,
options ?: "");
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

iiuc this is a gnu extension, probably not safe for shadow to use, so please make it options ? options : ""

free(options);
return n < 0 ? -1 : 0;
}

static struct commonio_ops subordinate_ops = {
Expand Down Expand Up @@ -285,38 +300,41 @@ static const struct subordinate_range *find_range(struct commonio_db *db,
}

/*
* have_range: check whether @owner is authorized to use the range
* (@start .. @start+@count-1).
* get_range: check whether @owner is authorized to use the range
* (@start .. @start+@count-1) and return the first matching range.
* @db: database to check
* @owner: owning uid being queried
* @start: start of range
* @count: number of uids in range
*
* Returns true if @owner is authorized to use the range, false otherwise.
* Returns the corresponding subordinate_range if @owner is authorized to use
* the range, NULL otherwise.
*/
static bool have_range(struct commonio_db *db,
const char *owner, unsigned long start, unsigned long count)
static const struct subordinate_range *get_range(struct commonio_db *db,
const char *owner,
unsigned long start,
unsigned long count)
{
const struct subordinate_range *range;
unsigned long end;

if (count == 0)
return false;
return NULL;

end = start + count - 1;
range = find_range (db, owner, start);
while (range) {
unsigned long last;
unsigned long last;

last = range->start + range->count - 1;
if (last >= (start + count - 1))
return true;
return range;

count = end - last;
start = last + 1;
range = find_range(db, owner, start);
}
return false;
return NULL;
}

/*
Expand Down Expand Up @@ -430,7 +448,7 @@ static int add_range(struct commonio_db *db,
range.count = count;

/* See if the range is already present */
if (have_range(db, owner, start, count))
if (get_range(db, owner, start, count))
return 1;

/* Otherwise append the range */
Expand Down Expand Up @@ -585,7 +603,12 @@ bool sub_uid_assigned(const char *owner)

bool have_sub_uids(const char *owner, uid_t start, unsigned long count)
{
return have_range (&subordinate_uid_db, owner, start, count);
return NULL != get_range (&subordinate_uid_db, owner, start, count);
}

char **sub_uid_options(const char *owner, uid_t start, unsigned long count)
{
return dup_list(get_range(&subordinate_uid_db, owner, start, count)->options);
}

int sub_uid_add (const char *owner, uid_t start, unsigned long count)
Expand Down Expand Up @@ -661,7 +684,12 @@ int sub_gid_open (int mode)

bool have_sub_gids(const char *owner, gid_t start, unsigned long count)
{
return have_range(&subordinate_gid_db, owner, start, count);
return NULL != get_range (&subordinate_gid_db, owner, start, count);
}

char **sub_gid_options(const char *owner, gid_t start, unsigned long count)
{
return dup_list(get_range(&subordinate_gid_db, owner, start, count)->options);
}

bool sub_gid_assigned(const char *owner)
Expand Down
2 changes: 2 additions & 0 deletions lib/subordinateio.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@

extern int sub_uid_close(void);
extern bool have_sub_uids(const char *owner, uid_t start, unsigned long count);
extern char **sub_uid_options(const char *owner, uid_t start, unsigned long count);
extern bool sub_uid_file_present (void);
extern bool sub_uid_assigned(const char *owner);
extern int sub_uid_lock (void);
Expand All @@ -26,6 +27,7 @@ extern uid_t sub_uid_find_free_range(uid_t min, uid_t max, unsigned long count);

extern int sub_gid_close(void);
extern bool have_sub_gids(const char *owner, gid_t start, unsigned long count);
extern char **sub_gid_options(const char *owner, uid_t start, unsigned long count);
extern bool sub_gid_file_present (void);
extern bool sub_gid_assigned(const char *owner);
extern int sub_gid_lock (void);
Expand Down
4 changes: 2 additions & 2 deletions libmisc/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@ EXTRA_DIST = .indent.pro xgetXXbyYY.c

AM_CPPFLAGS = -I$(top_srcdir)/lib

noinst_LIBRARIES = libmisc.a
noinst_LTLIBRARIES = libmisc.la

libmisc_a_SOURCES = \
libmisc_la_SOURCES = \
addgrps.c \
age.c \
audit_help.c \
Expand Down
2 changes: 1 addition & 1 deletion src/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -68,7 +68,7 @@ endif

LDADD = $(INTLLIBS) \
$(LIBTCB) \
$(top_builddir)/libmisc/libmisc.a \
$(top_builddir)/libmisc/libmisc.la \
$(top_builddir)/lib/libshadow.la

if ACCT_TOOLS_SETUID
Expand Down