diff options
Diffstat (limited to 'src/libnsss')
-rw-r--r-- | src/libnsss/deps-lib/nsss | 1 | ||||
-rw-r--r-- | src/libnsss/nsss_unix_getgrouplist.c | 43 | ||||
-rw-r--r-- | src/libnsss/nsss_unix_grp_getlist.c | 54 |
3 files changed, 98 insertions, 0 deletions
diff --git a/src/libnsss/deps-lib/nsss b/src/libnsss/deps-lib/nsss index 5c2630c..97f3518 100644 --- a/src/libnsss/deps-lib/nsss +++ b/src/libnsss/deps-lib/nsss @@ -91,6 +91,7 @@ nsss_unix_getspent.o nsss_unix_getspent_r.o nsss_unix_getspnam.o nsss_unix_getspnam_r.o +nsss_unix_getgrouplist.o nsss_unix_grp_get.o nsss_unix_grp_getbygid.o nsss_unix_grp_getbyname.o diff --git a/src/libnsss/nsss_unix_getgrouplist.c b/src/libnsss/nsss_unix_getgrouplist.c new file mode 100644 index 0000000..e9a11ab --- /dev/null +++ b/src/libnsss/nsss_unix_getgrouplist.c @@ -0,0 +1,43 @@ +/* ISC license. */ + +#include <string.h> +#include <unistd.h> +#include <errno.h> +#include <limits.h> + +#include <skalibs/stralloc.h> +#include <skalibs/genalloc.h> +#include <skalibs/skamisc.h> + +#include <nsss/grp-def.h> +#include <nsss/grp-unix.h> +#include <nsss/nsss-unix.h> +#include "nsss-unix-internal.h" + +int nsss_unix_getgrouplist (char const *user, gid_t gid, gid_t *gids, int *ngids) +{ + nsss_unix_t a = NSSS_UNIX_ZERO ; + stralloc sa = STRALLOC_ZERO ; + genalloc ga = GENALLOC_ZERO ; /* char * */ + int e = errno ; + size_t r = 0 ; + size_t n ; + if (*ngids < 0) return (errno = EINVAL, -1) ; + n = *ngids ; + if (!nsss_unix_grp_start(&a)) return -1 ; + if (!nsss_unix_grp_getlist(&a, gids, n, &r, &sa, &ga, user)) return -1 ; + nsss_unix_grp_end(&a) ; + if (r > INT_MAX) return (errno = EMSGSIZE, -1) ; + if (r > n) return (*ngids = (int)r, errno = ENOBUFS, -1) ; + for (size_t i = 0 ; i < r ; i++) + if (gid == gids[i]) goto ok ; + r++ ; + if (r > INT_MAX) return (errno = EMSGSIZE, -1) ; + if (r > n) return (*ngids = (int)r, errno = ENOBUFS, -1) ; + memmove(gids + 1, gids, (r-1) * sizeof(gid_t)) ; + gids[0] = gid ; + ok: + *ngids = (int)r ; + errno = e ; + return (int)n ; +} diff --git a/src/libnsss/nsss_unix_grp_getlist.c b/src/libnsss/nsss_unix_grp_getlist.c new file mode 100644 index 0000000..9885a03 --- /dev/null +++ b/src/libnsss/nsss_unix_grp_getlist.c @@ -0,0 +1,54 @@ +/* ISC license. */ + +#include <string.h> +#include <errno.h> + +#include <skalibs/stralloc.h> +#include <skalibs/genalloc.h> + +#include <nsss/grp-unix.h> +#include <nsss/nsss-unix.h> + +int nsss_unix_grp_getlist (nsss_unix_t *a, gid_t *gids, size_t n, size_t *r, stralloc *sa, genalloc *ga, char const *user) +{ + int e = errno ; + int sawasnull = !sa->s ; + int gawasnull = !genalloc_s(char *, ga) ; + size_t sabase = sa->len ; + size_t gabase = genalloc_len(char *, ga) ; + size_t m = 0 ; + + for (;;) + { + struct group *gr ; + sa->len = sabase ; + genalloc_setlen(char *, ga, gabase) ; + errno = 0 ; + if (!nsss_unix_grp_get(a, gr, sa, ga)) + { + if (errno) goto err ; + else break ; + } + for (char **p = gr->gr_mem ; *p ; p++) + if (!strcmp(user, *p)) + { + if (m < n) gids[m] = gr->gr_gid ; + m++ ; + break ; + } + } + + if (gawasnull) genalloc_free(char *, &ga) ; + else genalloc_setlen(char *, ga, gabase) ; + if (sawasnull) stralloc_free(&sa) ; + else sa->len = sabase ; + *r = m ; + return 1 ; + + err: + if (gawasnull) genalloc_free(char *, &ga) ; + else genalloc_setlen(char *, ga, gabase) ; + if (sawasnull) stralloc_free(&sa) ; + else sa->len = sabase ; + return 0 ; +} |