Create a new libsubid

Closes #154

Currently this has three functions: one which returns the
list of subuid ranges for a user, one returning the subgids,
and one which frees the ranges lists.

I might be mistaken about what -disable-man means;  some of
the code suggests it means just don't re-generate them, but
not totally ignore them.  But that doesn't seem to really work,
so let's just ignore man/ when -disable-man.

Remove --disable-shared.  I'm not sure why it was there, but it stems
from long, long ago, and I suspect it comes from some ancient
toolchain bug.

Create a tests/run_some, a shorter version of run_all.  I'll
slowly add tests to this as I verify they work, then I can
work on fixing the once which don't.

Also, don't touch man/ if not -enable-man.

Changelog:
	Apr 22: change the subid list api as recomended by Dan Walsh.
	Apr 23: implement get_subid_owner
	Apr 24: implement range add/release
	Apr 25: finish tests and rebase
	May 10: make @owner const

Signed-off-by: Serge Hallyn <serge@hallyn.com>
This commit is contained in:
Serge Hallyn
2020-04-18 18:03:54 -05:00
parent 43a917cce5
commit 0a7888b1fa
31 changed files with 1105 additions and 17 deletions

4
src/.gitignore vendored
View File

@@ -33,3 +33,7 @@
/userdel
/usermod
/vipw
/get_subid_owners
/list_subid_ranges
/new_subid_range
/free_subid_range

View File

@@ -156,4 +156,64 @@ if FCAPS
setcap cap_setuid+ep $(DESTDIR)$(ubindir)/newuidmap
setcap cap_setgid+ep $(DESTDIR)$(ubindir)/newgidmap
endif
noinst_PROGRAMS += list_subid_ranges \
get_subid_owners \
new_subid_range \
free_subid_range
MISCLIBS = \
$(LIBAUDIT) \
$(LIBSELINUX) \
$(LIBSEMANAGE) \
$(LIBCRYPT_NOPAM) \
$(LIBSKEY) \
$(LIBMD) \
$(LIBECONF) \
$(LIBCRYPT) \
$(LIBTCB)
list_subid_ranges_LDADD = \
$(top_builddir)/lib/libshadow.la \
$(top_builddir)/libmisc/libmisc.a \
$(top_builddir)/libsubid/libsubid.la \
$(MISCLIBS)
list_subid_ranges_CPPFLAGS = \
-I$(top_srcdir)/lib \
-I$(top_srcdir)/libmisc \
-I$(top_srcdir)/libsubid
get_subid_owners_LDADD = \
$(top_builddir)/lib/libshadow.la \
$(top_builddir)/libmisc/libmisc.a \
$(top_builddir)/libsubid/libsubid.la \
$(MISCLIBS)
get_subid_owners_CPPFLAGS = \
-I$(top_srcdir)/lib \
-I$(top_srcdir)/libmisc \
-I$(top_srcdir)/libsubid
new_subid_range_CPPFLAGS = \
-I$(top_srcdir)/lib \
-I$(top_srcdir)/libmisc \
-I$(top_srcdir)/libsubid
new_subid_range_LDADD = \
$(top_builddir)/lib/libshadow.la \
$(top_builddir)/libmisc/libmisc.a \
$(top_builddir)/libsubid/libsubid.la \
$(MISCLIBS)
free_subid_range_CPPFLAGS = \
-I$(top_srcdir)/lib \
-I$(top_srcdir)/libmisc \
-I$(top_srcdir)/libsubid
free_subid_range_LDADD = \
$(top_builddir)/lib/libshadow.la \
$(top_builddir)/libmisc/libmisc.a \
$(top_builddir)/libsubid/libsubid.la \
$(MISCLIBS)
endif

50
src/free_subid_range.c Normal file
View File

@@ -0,0 +1,50 @@
#include <stdio.h>
#include <unistd.h>
#include "api.h"
#include "stdlib.h"
#include "prototypes.h"
/* Test program for the subid freeing routine */
const char *Prog;
void usage(void)
{
fprintf(stderr, "Usage: %s [-g] user start count\n", Prog);
fprintf(stderr, " Release a user's subuid (or with -g, subgid) range\n");
exit(EXIT_FAILURE);
}
int main(int argc, char *argv[])
{
int c;
bool ok;
struct subordinate_range range;
bool group = false; // get subuids by default
Prog = Basename (argv[0]);
while ((c = getopt(argc, argv, "g")) != EOF) {
switch(c) {
case 'g': group = true; break;
default: usage();
}
}
argv = &argv[optind];
argc = argc - optind;
if (argc < 3)
usage();
range.owner = argv[0];
range.start = atoi(argv[1]);
range.count = atoi(argv[2]);
if (group)
ok = free_subgid_range(&range);
else
ok = free_subuid_range(&range);
if (!ok) {
fprintf(stderr, "Failed freeing id range\n");
exit(EXIT_FAILURE);
}
return 0;
}

40
src/get_subid_owners.c Normal file
View File

@@ -0,0 +1,40 @@
#include <stdio.h>
#include "api.h"
#include "stdlib.h"
#include "prototypes.h"
const char *Prog;
void usage(void)
{
fprintf(stderr, "Usage: [-g] %s subuid\n", Prog);
fprintf(stderr, " list uids who own the given subuid\n");
fprintf(stderr, " pass -g to query a subgid\n");
exit(EXIT_FAILURE);
}
int main(int argc, char *argv[])
{
int i, n;
uid_t *uids;
Prog = Basename (argv[0]);
if (argc < 2) {
usage();
}
if (argc == 3 && strcmp(argv[1], "-g") == 0)
n = get_subgid_owners(atoi(argv[2]), &uids);
else if (argc == 2 && strcmp(argv[1], "-h") == 0)
usage();
else
n = get_subuid_owners(atoi(argv[1]), &uids);
if (n < 0) {
fprintf(stderr, "No owners found\n");
exit(1);
}
for (i = 0; i < n; i++) {
printf("%d\n", uids[i]);
}
free(uids);
return 0;
}

41
src/list_subid_ranges.c Normal file
View File

@@ -0,0 +1,41 @@
#include <stdio.h>
#include "api.h"
#include "stdlib.h"
#include "prototypes.h"
const char *Prog;
void usage(void)
{
fprintf(stderr, "Usage: %s [-g] user\n", Prog);
fprintf(stderr, " list subuid ranges for user\n");
fprintf(stderr, " pass -g to list subgid ranges\n");
exit(EXIT_FAILURE);
}
int main(int argc, char *argv[])
{
int i;
struct subordinate_range **ranges;
Prog = Basename (argv[0]);
if (argc < 2) {
usage();
}
if (argc == 3 && strcmp(argv[1], "-g") == 0)
ranges = get_subgid_ranges(argv[2]);
else if (argc == 2 && strcmp(argv[1], "-h") == 0)
usage();
else
ranges = get_subuid_ranges(argv[1]);
if (!ranges) {
fprintf(stderr, "Error fetching ranges\n");
exit(1);
}
for (i = 0; ranges[i]; i++) {
printf("%d: %s %lu %lu\n", i, ranges[i]->owner,
ranges[i]->start, ranges[i]->count);
}
subid_free_ranges(ranges);
return 0;
}

57
src/new_subid_range.c Normal file
View File

@@ -0,0 +1,57 @@
#include <stdio.h>
#include <unistd.h>
#include "api.h"
#include "stdlib.h"
#include "prototypes.h"
/* Test program for the subid creation routine */
const char *Prog;
void usage(void)
{
fprintf(stderr, "Usage: %s [-g] [-n] user count\n", Prog);
fprintf(stderr, " Find a subuid (or with -g, subgid) range for user\n");
fprintf(stderr, " If -n is given, a new range will be created even if one exists\n");
fprintf(stderr, " count defaults to 65536\n");
exit(EXIT_FAILURE);
}
int main(int argc, char *argv[])
{
int c;
struct subordinate_range range;
bool makenew = false; // reuse existing by default
bool group = false; // get subuids by default
bool ok;
Prog = Basename (argv[0]);
while ((c = getopt(argc, argv, "gn")) != EOF) {
switch(c) {
case 'n': makenew = true; break;
case 'g': group = true; break;
default: usage();
}
}
argv = &argv[optind];
argc = argc - optind;
if (argc == 0)
usage();
range.owner = argv[0];
range.start = 0;
range.count = 65536;
if (argc > 1)
range.count = atoi(argv[1]);
if (group)
ok = grant_subgid_range(&range, !makenew);
else
ok = grant_subuid_range(&range, !makenew);
if (!ok) {
fprintf(stderr, "Failed creating new id range\n");
exit(EXIT_FAILURE);
}
printf("Subuid range %lu:%lu\n", range.start, range.count);
return 0;
}