subids: support nsswitch
Closes #154
When starting any operation to do with subuid delegation, check
nsswitch for a module to use. If none is specified, then use
the traditional /etc/subuid and /etc/subgid files.
Currently only one module is supported, and there is no fallback
to the files on errors. Several possibilities could be considered:
1. in case of connection error, fall back to files
2. in case of unknown user, also fall back to files
etc...
When non-files nss module is used, functions to edit the range
are not supported. It may make sense to support it, but it also
may make sense to require another tool to be used.
libsubordinateio also uses the nss_ helpers. This is how for instance
lxc could easily be converted to supporting nsswitch.
Add a set of test cases, including a dummy libsubid_zzz module. This
hardcodes values such that:
'ubuntu' gets 200000 - 300000
'user1' gets 100000 - 165536
'error' emulates an nss module error
'unknown' emulates a user unknown to the nss module
'conn' emulates a connection error ot the nss module
Changes to libsubid:
Change the list_owner_ranges api: return a count instead of making the array
null terminated.
This is a breaking change, so bump the libsubid abi major number.
Rename free_subuid_range and free_subgid_range to ungrant_subuid_range,
because otherwise it's confusing with free_subid_ranges which frees
memory.
Run libsubid tests in jenkins
Switch argument order in find_subid_owners
Move the db locking into subordinateio.c
Signed-off-by: Serge Hallyn <serge@hallyn.com>
2021-02-01 05:08:20 +05:30
|
|
|
#include <stdio.h>
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <dlfcn.h>
|
|
|
|
#include <stdbool.h>
|
|
|
|
#include <string.h>
|
|
|
|
#include <strings.h>
|
|
|
|
#include <ctype.h>
|
|
|
|
#include <stdatomic.h>
|
|
|
|
#include "prototypes.h"
|
|
|
|
#include "../libsubid/subid.h"
|
|
|
|
|
|
|
|
#define NSSWITCH "/etc/nsswitch.conf"
|
|
|
|
|
|
|
|
// NSS plugin handling for subids
|
|
|
|
// If nsswitch has a line like
|
|
|
|
// subid: sssd
|
|
|
|
// then sssd will be consulted for subids. Unlike normal NSS dbs,
|
|
|
|
// only one db is supported at a time. That's open to debate, but
|
|
|
|
// the subids are a pretty limited resource, and local files seem
|
|
|
|
// bound to step on any other allocations leading to insecure
|
|
|
|
// conditions.
|
|
|
|
static atomic_flag nss_init_started;
|
|
|
|
static atomic_bool nss_init_completed;
|
|
|
|
|
|
|
|
static struct subid_nss_ops *subid_nss;
|
|
|
|
|
|
|
|
bool nss_is_initialized() {
|
|
|
|
return atomic_load(&nss_init_completed);
|
|
|
|
}
|
|
|
|
|
|
|
|
void nss_exit() {
|
|
|
|
if (nss_is_initialized() && subid_nss) {
|
|
|
|
dlclose(subid_nss->handle);
|
|
|
|
free(subid_nss);
|
|
|
|
subid_nss = NULL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// nsswitch_path is an argument only to support testing.
|
|
|
|
void nss_init(char *nsswitch_path) {
|
|
|
|
FILE *nssfp = NULL;
|
|
|
|
char *line = NULL, *p, *token, *saveptr;
|
|
|
|
size_t len = 0;
|
|
|
|
|
|
|
|
if (atomic_flag_test_and_set(&nss_init_started)) {
|
|
|
|
// Another thread has started nss_init, wait for it to complete
|
|
|
|
while (!atomic_load(&nss_init_completed))
|
|
|
|
usleep(100);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!nsswitch_path)
|
|
|
|
nsswitch_path = NSSWITCH;
|
|
|
|
|
|
|
|
// read nsswitch.conf to check for a line like:
|
|
|
|
// subid: files
|
|
|
|
nssfp = fopen(nsswitch_path, "r");
|
|
|
|
if (!nssfp) {
|
2021-05-09 04:12:14 +05:30
|
|
|
fprintf(shadow_logfd, "Failed opening %s: %m", nsswitch_path);
|
subids: support nsswitch
Closes #154
When starting any operation to do with subuid delegation, check
nsswitch for a module to use. If none is specified, then use
the traditional /etc/subuid and /etc/subgid files.
Currently only one module is supported, and there is no fallback
to the files on errors. Several possibilities could be considered:
1. in case of connection error, fall back to files
2. in case of unknown user, also fall back to files
etc...
When non-files nss module is used, functions to edit the range
are not supported. It may make sense to support it, but it also
may make sense to require another tool to be used.
libsubordinateio also uses the nss_ helpers. This is how for instance
lxc could easily be converted to supporting nsswitch.
Add a set of test cases, including a dummy libsubid_zzz module. This
hardcodes values such that:
'ubuntu' gets 200000 - 300000
'user1' gets 100000 - 165536
'error' emulates an nss module error
'unknown' emulates a user unknown to the nss module
'conn' emulates a connection error ot the nss module
Changes to libsubid:
Change the list_owner_ranges api: return a count instead of making the array
null terminated.
This is a breaking change, so bump the libsubid abi major number.
Rename free_subuid_range and free_subgid_range to ungrant_subuid_range,
because otherwise it's confusing with free_subid_ranges which frees
memory.
Run libsubid tests in jenkins
Switch argument order in find_subid_owners
Move the db locking into subordinateio.c
Signed-off-by: Serge Hallyn <serge@hallyn.com>
2021-02-01 05:08:20 +05:30
|
|
|
atomic_store(&nss_init_completed, true);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
while ((getline(&line, &len, nssfp)) != -1) {
|
|
|
|
if (line[0] == '\0' || line[0] == '#')
|
|
|
|
continue;
|
|
|
|
if (strlen(line) < 8)
|
|
|
|
continue;
|
|
|
|
if (strncasecmp(line, "subid:", 6) != 0)
|
|
|
|
continue;
|
|
|
|
p = &line[6];
|
|
|
|
while ((*p) && isspace(*p))
|
|
|
|
p++;
|
|
|
|
if (!*p)
|
|
|
|
continue;
|
|
|
|
for (token = strtok_r(p, " \n\t", &saveptr);
|
|
|
|
token;
|
|
|
|
token = strtok_r(NULL, " \n\t", &saveptr)) {
|
|
|
|
char libname[65];
|
|
|
|
void *h;
|
|
|
|
if (strcmp(token, "files") == 0) {
|
|
|
|
subid_nss = NULL;
|
|
|
|
goto done;
|
|
|
|
}
|
|
|
|
if (strlen(token) > 50) {
|
2021-05-09 04:12:14 +05:30
|
|
|
fprintf(shadow_logfd, "Subid NSS module name too long (longer than 50 characters): %s\n", token);
|
|
|
|
fprintf(shadow_logfd, "Using files\n");
|
subids: support nsswitch
Closes #154
When starting any operation to do with subuid delegation, check
nsswitch for a module to use. If none is specified, then use
the traditional /etc/subuid and /etc/subgid files.
Currently only one module is supported, and there is no fallback
to the files on errors. Several possibilities could be considered:
1. in case of connection error, fall back to files
2. in case of unknown user, also fall back to files
etc...
When non-files nss module is used, functions to edit the range
are not supported. It may make sense to support it, but it also
may make sense to require another tool to be used.
libsubordinateio also uses the nss_ helpers. This is how for instance
lxc could easily be converted to supporting nsswitch.
Add a set of test cases, including a dummy libsubid_zzz module. This
hardcodes values such that:
'ubuntu' gets 200000 - 300000
'user1' gets 100000 - 165536
'error' emulates an nss module error
'unknown' emulates a user unknown to the nss module
'conn' emulates a connection error ot the nss module
Changes to libsubid:
Change the list_owner_ranges api: return a count instead of making the array
null terminated.
This is a breaking change, so bump the libsubid abi major number.
Rename free_subuid_range and free_subgid_range to ungrant_subuid_range,
because otherwise it's confusing with free_subid_ranges which frees
memory.
Run libsubid tests in jenkins
Switch argument order in find_subid_owners
Move the db locking into subordinateio.c
Signed-off-by: Serge Hallyn <serge@hallyn.com>
2021-02-01 05:08:20 +05:30
|
|
|
subid_nss = NULL;
|
|
|
|
goto done;
|
|
|
|
}
|
|
|
|
snprintf(libname, 64, "libsubid_%s.so", token);
|
|
|
|
h = dlopen(libname, RTLD_LAZY);
|
|
|
|
if (!h) {
|
2021-05-09 04:12:14 +05:30
|
|
|
fprintf(shadow_logfd, "Error opening %s: %s\n", libname, dlerror());
|
|
|
|
fprintf(shadow_logfd, "Using files\n");
|
subids: support nsswitch
Closes #154
When starting any operation to do with subuid delegation, check
nsswitch for a module to use. If none is specified, then use
the traditional /etc/subuid and /etc/subgid files.
Currently only one module is supported, and there is no fallback
to the files on errors. Several possibilities could be considered:
1. in case of connection error, fall back to files
2. in case of unknown user, also fall back to files
etc...
When non-files nss module is used, functions to edit the range
are not supported. It may make sense to support it, but it also
may make sense to require another tool to be used.
libsubordinateio also uses the nss_ helpers. This is how for instance
lxc could easily be converted to supporting nsswitch.
Add a set of test cases, including a dummy libsubid_zzz module. This
hardcodes values such that:
'ubuntu' gets 200000 - 300000
'user1' gets 100000 - 165536
'error' emulates an nss module error
'unknown' emulates a user unknown to the nss module
'conn' emulates a connection error ot the nss module
Changes to libsubid:
Change the list_owner_ranges api: return a count instead of making the array
null terminated.
This is a breaking change, so bump the libsubid abi major number.
Rename free_subuid_range and free_subgid_range to ungrant_subuid_range,
because otherwise it's confusing with free_subid_ranges which frees
memory.
Run libsubid tests in jenkins
Switch argument order in find_subid_owners
Move the db locking into subordinateio.c
Signed-off-by: Serge Hallyn <serge@hallyn.com>
2021-02-01 05:08:20 +05:30
|
|
|
subid_nss = NULL;
|
|
|
|
goto done;
|
|
|
|
}
|
|
|
|
subid_nss = malloc(sizeof(*subid_nss));
|
|
|
|
if (!subid_nss) {
|
|
|
|
dlclose(h);
|
|
|
|
goto done;
|
|
|
|
}
|
|
|
|
subid_nss->has_range = dlsym(h, "shadow_subid_has_range");
|
|
|
|
if (!subid_nss->has_range) {
|
2021-05-09 04:12:14 +05:30
|
|
|
fprintf(shadow_logfd, "%s did not provide @has_range@\n", libname);
|
subids: support nsswitch
Closes #154
When starting any operation to do with subuid delegation, check
nsswitch for a module to use. If none is specified, then use
the traditional /etc/subuid and /etc/subgid files.
Currently only one module is supported, and there is no fallback
to the files on errors. Several possibilities could be considered:
1. in case of connection error, fall back to files
2. in case of unknown user, also fall back to files
etc...
When non-files nss module is used, functions to edit the range
are not supported. It may make sense to support it, but it also
may make sense to require another tool to be used.
libsubordinateio also uses the nss_ helpers. This is how for instance
lxc could easily be converted to supporting nsswitch.
Add a set of test cases, including a dummy libsubid_zzz module. This
hardcodes values such that:
'ubuntu' gets 200000 - 300000
'user1' gets 100000 - 165536
'error' emulates an nss module error
'unknown' emulates a user unknown to the nss module
'conn' emulates a connection error ot the nss module
Changes to libsubid:
Change the list_owner_ranges api: return a count instead of making the array
null terminated.
This is a breaking change, so bump the libsubid abi major number.
Rename free_subuid_range and free_subgid_range to ungrant_subuid_range,
because otherwise it's confusing with free_subid_ranges which frees
memory.
Run libsubid tests in jenkins
Switch argument order in find_subid_owners
Move the db locking into subordinateio.c
Signed-off-by: Serge Hallyn <serge@hallyn.com>
2021-02-01 05:08:20 +05:30
|
|
|
dlclose(h);
|
|
|
|
free(subid_nss);
|
|
|
|
subid_nss = NULL;
|
|
|
|
goto done;
|
|
|
|
}
|
|
|
|
subid_nss->list_owner_ranges = dlsym(h, "shadow_subid_list_owner_ranges");
|
|
|
|
if (!subid_nss->list_owner_ranges) {
|
2021-05-09 04:12:14 +05:30
|
|
|
fprintf(shadow_logfd, "%s did not provide @list_owner_ranges@\n", libname);
|
subids: support nsswitch
Closes #154
When starting any operation to do with subuid delegation, check
nsswitch for a module to use. If none is specified, then use
the traditional /etc/subuid and /etc/subgid files.
Currently only one module is supported, and there is no fallback
to the files on errors. Several possibilities could be considered:
1. in case of connection error, fall back to files
2. in case of unknown user, also fall back to files
etc...
When non-files nss module is used, functions to edit the range
are not supported. It may make sense to support it, but it also
may make sense to require another tool to be used.
libsubordinateio also uses the nss_ helpers. This is how for instance
lxc could easily be converted to supporting nsswitch.
Add a set of test cases, including a dummy libsubid_zzz module. This
hardcodes values such that:
'ubuntu' gets 200000 - 300000
'user1' gets 100000 - 165536
'error' emulates an nss module error
'unknown' emulates a user unknown to the nss module
'conn' emulates a connection error ot the nss module
Changes to libsubid:
Change the list_owner_ranges api: return a count instead of making the array
null terminated.
This is a breaking change, so bump the libsubid abi major number.
Rename free_subuid_range and free_subgid_range to ungrant_subuid_range,
because otherwise it's confusing with free_subid_ranges which frees
memory.
Run libsubid tests in jenkins
Switch argument order in find_subid_owners
Move the db locking into subordinateio.c
Signed-off-by: Serge Hallyn <serge@hallyn.com>
2021-02-01 05:08:20 +05:30
|
|
|
dlclose(h);
|
|
|
|
free(subid_nss);
|
|
|
|
subid_nss = NULL;
|
|
|
|
goto done;
|
|
|
|
}
|
|
|
|
subid_nss->find_subid_owners = dlsym(h, "shadow_subid_find_subid_owners");
|
|
|
|
if (!subid_nss->find_subid_owners) {
|
2021-05-09 04:12:14 +05:30
|
|
|
fprintf(shadow_logfd, "%s did not provide @find_subid_owners@\n", libname);
|
subids: support nsswitch
Closes #154
When starting any operation to do with subuid delegation, check
nsswitch for a module to use. If none is specified, then use
the traditional /etc/subuid and /etc/subgid files.
Currently only one module is supported, and there is no fallback
to the files on errors. Several possibilities could be considered:
1. in case of connection error, fall back to files
2. in case of unknown user, also fall back to files
etc...
When non-files nss module is used, functions to edit the range
are not supported. It may make sense to support it, but it also
may make sense to require another tool to be used.
libsubordinateio also uses the nss_ helpers. This is how for instance
lxc could easily be converted to supporting nsswitch.
Add a set of test cases, including a dummy libsubid_zzz module. This
hardcodes values such that:
'ubuntu' gets 200000 - 300000
'user1' gets 100000 - 165536
'error' emulates an nss module error
'unknown' emulates a user unknown to the nss module
'conn' emulates a connection error ot the nss module
Changes to libsubid:
Change the list_owner_ranges api: return a count instead of making the array
null terminated.
This is a breaking change, so bump the libsubid abi major number.
Rename free_subuid_range and free_subgid_range to ungrant_subuid_range,
because otherwise it's confusing with free_subid_ranges which frees
memory.
Run libsubid tests in jenkins
Switch argument order in find_subid_owners
Move the db locking into subordinateio.c
Signed-off-by: Serge Hallyn <serge@hallyn.com>
2021-02-01 05:08:20 +05:30
|
|
|
dlclose(h);
|
|
|
|
free(subid_nss);
|
|
|
|
subid_nss = NULL;
|
|
|
|
goto done;
|
|
|
|
}
|
|
|
|
subid_nss->handle = h;
|
|
|
|
goto done;
|
|
|
|
}
|
2021-05-09 04:12:14 +05:30
|
|
|
fprintf(shadow_logfd, "No usable subid NSS module found, using files\n");
|
subids: support nsswitch
Closes #154
When starting any operation to do with subuid delegation, check
nsswitch for a module to use. If none is specified, then use
the traditional /etc/subuid and /etc/subgid files.
Currently only one module is supported, and there is no fallback
to the files on errors. Several possibilities could be considered:
1. in case of connection error, fall back to files
2. in case of unknown user, also fall back to files
etc...
When non-files nss module is used, functions to edit the range
are not supported. It may make sense to support it, but it also
may make sense to require another tool to be used.
libsubordinateio also uses the nss_ helpers. This is how for instance
lxc could easily be converted to supporting nsswitch.
Add a set of test cases, including a dummy libsubid_zzz module. This
hardcodes values such that:
'ubuntu' gets 200000 - 300000
'user1' gets 100000 - 165536
'error' emulates an nss module error
'unknown' emulates a user unknown to the nss module
'conn' emulates a connection error ot the nss module
Changes to libsubid:
Change the list_owner_ranges api: return a count instead of making the array
null terminated.
This is a breaking change, so bump the libsubid abi major number.
Rename free_subuid_range and free_subgid_range to ungrant_subuid_range,
because otherwise it's confusing with free_subid_ranges which frees
memory.
Run libsubid tests in jenkins
Switch argument order in find_subid_owners
Move the db locking into subordinateio.c
Signed-off-by: Serge Hallyn <serge@hallyn.com>
2021-02-01 05:08:20 +05:30
|
|
|
// subid_nss has to be null here, but to ease reviews:
|
|
|
|
free(subid_nss);
|
|
|
|
subid_nss = NULL;
|
|
|
|
goto done;
|
|
|
|
}
|
|
|
|
|
|
|
|
done:
|
|
|
|
atomic_store(&nss_init_completed, true);
|
|
|
|
free(line);
|
|
|
|
if (nssfp) {
|
|
|
|
atexit(nss_exit);
|
|
|
|
fclose(nssfp);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
struct subid_nss_ops *get_subid_nss_handle() {
|
|
|
|
nss_init(NULL);
|
|
|
|
return subid_nss;
|
|
|
|
}
|