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>
2020-04-19 04:33:54 +05:30
|
|
|
#include <sys/types.h>
|
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 <stdbool.h>
|
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>
2020-04-19 04:33:54 +05:30
|
|
|
|
|
|
|
#ifndef SUBID_RANGE_DEFINED
|
|
|
|
#define SUBID_RANGE_DEFINED 1
|
|
|
|
struct subordinate_range {
|
|
|
|
const char *owner;
|
|
|
|
unsigned long start;
|
|
|
|
unsigned long count;
|
|
|
|
};
|
|
|
|
|
|
|
|
enum subid_type {
|
|
|
|
ID_TYPE_UID = 1,
|
|
|
|
ID_TYPE_GID = 2
|
|
|
|
};
|
|
|
|
|
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
|
|
|
enum subid_status {
|
|
|
|
SUBID_STATUS_SUCCESS = 0,
|
|
|
|
SUBID_STATUS_UNKNOWN_USER = 1,
|
|
|
|
SUBID_STATUS_ERROR_CONN = 2,
|
|
|
|
SUBID_STATUS_ERROR = 3,
|
|
|
|
};
|
|
|
|
|
2021-05-09 04:12:14 +05:30
|
|
|
/*
|
|
|
|
* libsubid_init: initialize libsubid
|
|
|
|
*
|
|
|
|
* @progname: Name to display as program. If NULL, then "(libsubid)" will be
|
|
|
|
* shown in error messages.
|
|
|
|
* @logfd: Open file pointer to pass error messages to. If NULL, then
|
|
|
|
* /dev/null will be opened and messages will be sent there. The
|
|
|
|
* default if libsubid_init() is not called is stderr (2).
|
|
|
|
*
|
|
|
|
* This function does not need to be called. If not called, then the defaults
|
|
|
|
* will be used.
|
|
|
|
*
|
|
|
|
* Returns false if an error occurred.
|
|
|
|
*/
|
|
|
|
bool libsubid_init(const char *progname, FILE *logfd);
|
|
|
|
|
2021-04-15 20:22:29 +05:30
|
|
|
/*
|
|
|
|
* get_subuid_ranges: return a list of UID ranges for a user
|
|
|
|
*
|
|
|
|
* @owner: username being queried
|
|
|
|
* @ranges: a pointer to a subordinate range ** in which the result will be
|
|
|
|
* returned.
|
|
|
|
*
|
|
|
|
* returns: number of ranges found, ir < 0 on error.
|
|
|
|
*/
|
|
|
|
int get_subuid_ranges(const char *owner, struct subordinate_range ***ranges);
|
|
|
|
|
|
|
|
/*
|
|
|
|
* get_subgid_ranges: return a list of GID ranges for a user
|
|
|
|
*
|
|
|
|
* @owner: username being queried
|
|
|
|
* @ranges: a pointer to a subordinate range ** in which the result will be
|
|
|
|
* returned.
|
|
|
|
*
|
|
|
|
* returns: number of ranges found, ir < 0 on error.
|
|
|
|
*/
|
|
|
|
int get_subgid_ranges(const char *owner, struct subordinate_range ***ranges);
|
|
|
|
|
|
|
|
/*
|
|
|
|
* subid_free_ranges: free an array of subordinate_ranges returned by either
|
|
|
|
* get_subuid_ranges() or get_subgid_ranges().
|
|
|
|
*
|
|
|
|
* @ranges: the ranges to free
|
|
|
|
* @count: the number of ranges in @ranges
|
|
|
|
*/
|
|
|
|
void subid_free_ranges(struct subordinate_range **ranges, int count);
|
|
|
|
|
|
|
|
/*
|
|
|
|
* get_subuid_owners: return a list of uids to which the given uid has been
|
|
|
|
* delegated.
|
|
|
|
*
|
|
|
|
* @uid: The subuid being queried
|
|
|
|
* @owners: a pointer to an array of uids into which the results are placed.
|
|
|
|
* The returned array must be freed by the caller.
|
|
|
|
*
|
|
|
|
* Returns the number of uids returned, or < 0 on error.
|
|
|
|
*/
|
|
|
|
int get_subuid_owners(uid_t uid, uid_t **owner);
|
|
|
|
|
|
|
|
/*
|
|
|
|
* get_subgid_owners: return a list of uids to which the given gid has been
|
|
|
|
* delegated.
|
|
|
|
*
|
|
|
|
* @uid: The subgid being queried
|
|
|
|
* @owners: a pointer to an array of uids into which the results are placed.
|
|
|
|
* The returned array must be freed by the caller.
|
|
|
|
*
|
|
|
|
* Returns the number of uids returned, or < 0 on error.
|
|
|
|
*/
|
|
|
|
int get_subgid_owners(gid_t gid, uid_t **owner);
|
|
|
|
|
|
|
|
/*
|
|
|
|
* grant_subuid_range: assign a subuid range to a user
|
|
|
|
*
|
|
|
|
* @range: pointer to a struct subordinate_range detailing the UID range
|
|
|
|
* to allocate. ->owner must be the username, and ->count must be
|
|
|
|
* filled in. ->start is ignored, and will contain the start
|
|
|
|
* of the newly allocated range, upon success.
|
|
|
|
*
|
|
|
|
* Returns true if the delegation succeeded, false otherwise. If true,
|
|
|
|
* then the range from (range->start, range->start + range->count) will
|
|
|
|
* be delegated to range->owner.
|
|
|
|
*/
|
|
|
|
bool grant_subuid_range(struct subordinate_range *range, bool reuse);
|
|
|
|
|
|
|
|
/*
|
|
|
|
* grant_subsid_range: assign a subgid range to a user
|
|
|
|
*
|
|
|
|
* @range: pointer to a struct subordinate_range detailing the GID range
|
|
|
|
* to allocate. ->owner must be the username, and ->count must be
|
|
|
|
* filled in. ->start is ignored, and will contain the start
|
|
|
|
* of the newly allocated range, upon success.
|
|
|
|
*
|
|
|
|
* Returns true if the delegation succeeded, false otherwise. If true,
|
|
|
|
* then the range from (range->start, range->start + range->count) will
|
|
|
|
* be delegated to range->owner.
|
|
|
|
*/
|
|
|
|
bool grant_subgid_range(struct subordinate_range *range, bool reuse);
|
|
|
|
|
|
|
|
/*
|
|
|
|
* ungrant_subuid_range: remove a subuid allocation.
|
|
|
|
*
|
|
|
|
* @range: pointer to a struct subordinate_range detailing the UID allocation
|
|
|
|
* to remove.
|
|
|
|
*
|
|
|
|
* Returns true if successful, false if it failed, for instance if the
|
|
|
|
* delegation did not exist.
|
|
|
|
*/
|
|
|
|
bool ungrant_subuid_range(struct subordinate_range *range);
|
|
|
|
|
|
|
|
/*
|
|
|
|
* ungrant_subuid_range: remove a subgid allocation.
|
|
|
|
*
|
|
|
|
* @range: pointer to a struct subordinate_range detailing the GID allocation
|
|
|
|
* to remove.
|
|
|
|
*
|
|
|
|
* Returns true if successful, false if it failed, for instance if the
|
|
|
|
* delegation did not exist.
|
|
|
|
*/
|
|
|
|
bool ungrant_subgid_range(struct subordinate_range *range);
|
|
|
|
|
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>
2020-04-19 04:33:54 +05:30
|
|
|
#define SUBID_NFIELDS 3
|
|
|
|
#endif
|