summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorLaurent Bercot <ska-skaware@skarnet.org>2019-09-21 21:17:34 +0000
committerLaurent Bercot <ska-skaware@skarnet.org>2019-09-21 21:17:34 +0000
commit426039bdd70a5502d56fbc2a9dcde5817b145c1c (patch)
treed796c9013d131297819b9d7637bea628d9c117d7 /src
parentce150eb99b4af0f509e86c0e077abb5203253049 (diff)
downloadnsss-426039bdd70a5502d56fbc2a9dcde5817b145c1c.tar.xz
Add getgrouplist() support (stubbed in nsssd-nslcd)
Diffstat (limited to 'src')
-rw-r--r--src/include/nsss/grp-unix.h1
-rw-r--r--src/include/nsss/nsss-switch.h4
-rw-r--r--src/include/nsss/nsss-unix.h2
-rw-r--r--src/include/nsss/nsssd.h1
-rw-r--r--src/libnsss/deps-lib/nsss7
-rw-r--r--src/libnsss/nsss-internal.h2
-rw-r--r--src/libnsss/nsss_all_getgrouplist.c35
-rw-r--r--src/libnsss/nsss_grouplist_adjust.c24
-rw-r--r--src/libnsss/nsss_switch_getgrouplist.c30
-rw-r--r--src/libnsss/nsss_switch_grp_getlist.c66
-rw-r--r--src/libnsss/nsss_unix_getgrouplist.c34
-rw-r--r--src/libnsss/nsss_unix_getgrouplist_preadjust.c22
-rw-r--r--src/libnsss/nsss_unix_grp_getlist.c19
-rw-r--r--src/nsssd/nsssd-nslcd.c11
-rw-r--r--src/nsssd/nsssd-unix.c6
-rw-r--r--src/nsssd/nsssd_main.c50
16 files changed, 270 insertions, 44 deletions
diff --git a/src/include/nsss/grp-unix.h b/src/include/nsss/grp-unix.h
index 3b198c0..862fbf2 100644
--- a/src/include/nsss/grp-unix.h
+++ b/src/include/nsss/grp-unix.h
@@ -17,5 +17,6 @@ extern struct group *nsss_unix_getgrnam (char const *) ;
extern int nsss_unix_getgrgid_r (gid_t, struct group *, char *, size_t, struct group **) ;
extern int nsss_unix_getgrnam_r (char const *, struct group *, char *, size_t, struct group **) ;
extern int nsss_unix_getgrouplist (char const *, gid_t, gid_t *, int *) ;
+extern int nsss_unix_getgrouplist_preadjust (char const *, gid_t *, size_t, size_t *) ;
#endif
diff --git a/src/include/nsss/nsss-switch.h b/src/include/nsss/nsss-switch.h
index 9e1a850..1f40f7c 100644
--- a/src/include/nsss/nsss-switch.h
+++ b/src/include/nsss/nsss-switch.h
@@ -79,8 +79,8 @@ extern int nsss_switch_grp_getbyname (nsss_switch_t *, struct group *, stralloc
#define nsss_switch_grp_getbyname_g(a, b, sa, ga, name, deadline) nsss_switch_grp_getbyname(a, b, sa, ga, name, (deadline), &STAMP)
extern int nsss_switch_grp_getbygid (nsss_switch_t *, struct group *, stralloc *, genalloc *, gid_t, tain_t const *, tain_t *) ;
#define nsss_switch_grp_getbygid_g(a, b, sa, ga, g, deadline) nsss_switch_grp_getbygid(a, b, sa, ga, g, (deadline), &STAMP)
-extern int nsss_switch_grp_getlist (nsss_switch_t *, char const *, gid_t, genalloc *, tain_t const *, tain_t *) ;
-#define nsss_switch_grp_getlist_g(a, user, g, ga, deadline) nsss_switch_grp_getlist(a, user, g, ga, (deadline), &STAMP)
+extern int nsss_switch_grp_getlist (nsss_switch_t *, char const *, gid_t *, size_t, size_t *, stralloc *, tain_t const *, tain_t *) ;
+#define nsss_switch_grp_getlist_g(a, user, gids, n, r, sa, deadline) nsss_switch_grp_getlist(a, user, gids, n, r, sa, (deadline), &STAMP)
/* Shadow */
diff --git a/src/include/nsss/nsss-unix.h b/src/include/nsss/nsss-unix.h
index dfb0bde..e48eaec 100644
--- a/src/include/nsss/nsss-unix.h
+++ b/src/include/nsss/nsss-unix.h
@@ -48,7 +48,7 @@ extern int nsss_unix_pwd_getbyuid (nsss_unix_t *, struct passwd *, stralloc *, u
extern int nsss_unix_grp_get (nsss_unix_t *, struct group *, stralloc *, genalloc *) ;
extern int nsss_unix_grp_getbyname (nsss_unix_t *, struct group *, stralloc *, genalloc *, char const *) ;
extern int nsss_unix_grp_getbygid (nsss_unix_t *, struct group *, stralloc *, genalloc *, gid_t) ;
-extern int nsss_unix_grp_getlist (nsss_unix_t *, gid_t *, size_t, size_t *, stralloc *, genalloc *, char const *) ;
+extern int nsss_unix_grp_getlist (nsss_unix_t *, char const *, gid_t *, size_t, size_t *, stralloc *, genalloc *) ;
/* Shadow */
diff --git a/src/include/nsss/nsssd.h b/src/include/nsss/nsssd.h
index 7649873..b21e6d2 100644
--- a/src/include/nsss/nsssd.h
+++ b/src/include/nsss/nsssd.h
@@ -73,6 +73,7 @@ extern int nsssd_grp_rewind (void *) ;
extern int nsssd_grp_get (void *, struct group *) ;
extern int nsssd_grp_getbygid (void *, struct group *, gid_t) ;
extern int nsssd_grp_getbyname (void *, struct group *, char const *) ;
+extern int nsssd_grp_getlist (void *, char const *, gid_t *, size_t, size_t *) ;
extern void nsssd_grp_end (void *) ;
extern int nsssd_shadow_start (void *) ;
diff --git a/src/libnsss/deps-lib/nsss b/src/libnsss/deps-lib/nsss
index 1886bdf..e00084e 100644
--- a/src/libnsss/deps-lib/nsss
+++ b/src/libnsss/deps-lib/nsss
@@ -8,6 +8,7 @@ nsss_all_getgrgid.o
nsss_all_getgrgid_r.o
nsss_all_getgrnam.o
nsss_all_getgrnam_r.o
+nsss_all_getgrouplist.o
nsss_all_getpwent.o
nsss_all_getpwent_r.o
nsss_all_getpwnam.o
@@ -23,6 +24,7 @@ nsss_all_setpwent.o
nsss_all_setspent.o
nsss_grp_copy.o
nsss_grp_here.o
+nsss_grouplist_adjust.o
nsss_pwd_copy.o
nsss_pwd_here.o
nsss_shadow_copy.o
@@ -37,6 +39,7 @@ nsss_switch_getgrgid.o
nsss_switch_getgrgid_r.o
nsss_switch_getgrnam.o
nsss_switch_getgrnam_r.o
+nsss_switch_getgrouplist.o
nsss_switch_getpwent.o
nsss_switch_getpwent_r.o
nsss_switch_getpwnam.o
@@ -51,6 +54,7 @@ nsss_switch_grp_end.o
nsss_switch_grp_get.o
nsss_switch_grp_getbygid.o
nsss_switch_grp_getbyname.o
+nsss_switch_grp_getlist.o
nsss_switch_grp_read.o
nsss_switch_grp_rewind.o
nsss_switch_here.o
@@ -81,6 +85,8 @@ nsss_unix_getgrgid.o
nsss_unix_getgrgid_r.o
nsss_unix_getgrnam.o
nsss_unix_getgrnam_r.o
+nsss_unix_getgrouplist.o
+nsss_unix_getgrouplist_preadjust.o
nsss_unix_getpwent.o
nsss_unix_getpwent_r.o
nsss_unix_getpwnam.o
@@ -91,7 +97,6 @@ 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-internal.h b/src/libnsss/nsss-internal.h
index f9dbeb3..a67b5f7 100644
--- a/src/libnsss/nsss-internal.h
+++ b/src/libnsss/nsss-internal.h
@@ -24,7 +24,7 @@ extern struct group nsss_grp_here ;
extern stralloc nsss_grp_sa_here ;
extern genalloc nsss_grp_ga_here ;
extern int nsss_grp_copy (struct group *, char *, size_t, struct group const *, char const *, size_t, char *const *, size_t) ;
-
+extern int nsss_grouplist_adjust (size_t, size_t, gid_t, gid_t *, int *, int) ;
/* Shadow */
diff --git a/src/libnsss/nsss_all_getgrouplist.c b/src/libnsss/nsss_all_getgrouplist.c
new file mode 100644
index 0000000..0560ba7
--- /dev/null
+++ b/src/libnsss/nsss_all_getgrouplist.c
@@ -0,0 +1,35 @@
+/* ISC license. */
+
+#include <stddef.h>
+#include <errno.h>
+
+#include <skalibs/stralloc.h>
+
+#include <nsss/config.h>
+#include <nsss/grp-unix.h>
+#include <nsss/nsss-switch.h>
+#include <nsss/grp-all.h>
+#include "nsss-internal.h"
+
+int nsss_all_getgrouplist (char const *user, gid_t gid, gid_t *gids, int *ngids)
+{
+ stralloc sa = STRALLOC_ZERO ;
+ int e = errno ;
+ size_t r = 0 ;
+ size_t n ;
+ nsss_switch_t a = NSSS_SWITCH_ZERO ;
+ if (*ngids < 0) return (errno = EINVAL, -1) ;
+ n = *ngids ;
+ if (!nsss_switch_start(&a, NSSS_SWITCH_GRP, NSSS_NSSSD_PATH, 0, 0)) goto fallback ;
+ if (!nsss_switch_grp_getlist(&a, user, gids, n, &r, &sa, 0, 0))
+ {
+ nsss_switch_end(&a, NSSS_SWITCH_GRP) ;
+ return -1 ;
+ }
+ nsss_switch_end(&a, NSSS_SWITCH_GRP) ;
+ return nsss_grouplist_adjust(n, r, gid, gids, ngids, e) ;
+
+ fallback:
+ errno = e ;
+ return nsss_unix_getgrouplist(user, gid, gids, ngids) ;
+}
diff --git a/src/libnsss/nsss_grouplist_adjust.c b/src/libnsss/nsss_grouplist_adjust.c
new file mode 100644
index 0000000..fda4882
--- /dev/null
+++ b/src/libnsss/nsss_grouplist_adjust.c
@@ -0,0 +1,24 @@
+/* ISC license. */
+
+#include <string.h>
+#include <errno.h>
+#include <limits.h>
+
+#include <nsss/grp-def.h>
+#include "nsss-internal.h"
+
+int nsss_grouplist_adjust (size_t n, size_t r, gid_t gid, gid_t *gids, int *ngids, int e)
+{
+ 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_switch_getgrouplist.c b/src/libnsss/nsss_switch_getgrouplist.c
new file mode 100644
index 0000000..73d3fe0
--- /dev/null
+++ b/src/libnsss/nsss_switch_getgrouplist.c
@@ -0,0 +1,30 @@
+/* ISC license. */
+
+#include <stddef.h>
+#include <errno.h>
+
+#include <skalibs/stralloc.h>
+
+#include <nsss/config.h>
+#include <nsss/nsss-switch.h>
+#include <nsss/grp-switch.h>
+#include "nsss-internal.h"
+
+int nsss_switch_getgrouplist (char const *user, gid_t gid, gid_t *gids, int *ngids)
+{
+ stralloc sa = STRALLOC_ZERO ;
+ int e = errno ;
+ size_t r = 0 ;
+ size_t n ;
+ nsss_switch_t a = NSSS_SWITCH_ZERO ;
+ if (*ngids < 0) return (errno = EINVAL, -1) ;
+ n = *ngids ;
+ if (!nsss_switch_start(&a, NSSS_SWITCH_GRP, NSSS_NSSSD_PATH, 0, 0)) return -1 ;
+ if (!nsss_switch_grp_getlist(&a, user, gids, n, &r, &sa, 0, 0))
+ {
+ nsss_switch_end(&a, NSSS_SWITCH_GRP) ;
+ return -1 ;
+ }
+ nsss_switch_end(&a, NSSS_SWITCH_GRP) ;
+ return nsss_grouplist_adjust(n, r, gid, gids, ngids, e) ;
+}
diff --git a/src/libnsss/nsss_switch_grp_getlist.c b/src/libnsss/nsss_switch_grp_getlist.c
new file mode 100644
index 0000000..70e4486
--- /dev/null
+++ b/src/libnsss/nsss_switch_grp_getlist.c
@@ -0,0 +1,66 @@
+/* ISC license. */
+
+#include <string.h>
+#include <sys/uio.h>
+#include <errno.h>
+
+#include <skalibs/posixishard.h>
+#include <skalibs/uint32.h>
+#include <skalibs/uint64.h>
+#include <skalibs/types.h>
+#include <skalibs/buffer.h>
+#include <skalibs/stralloc.h>
+#include <skalibs/unix-timed.h>
+
+#include <nsss/nsss-switch.h>
+
+ /*
+ Expects:
+ 8 bytes: n
+ 8 bytes: r
+ min(n, r) * sizeof(gid_t) bytes: the list of gids
+ */
+
+static int nsss_switch_grouplist_read (buffer *b, size_t n, size_t *r, gid_t *gids, stralloc *sa, tain_t const *deadline, tain_t *stamp)
+{
+ size_t rr ;
+ uint64_t res ;
+ char buf[8] ;
+ if (!buffer_timed_get(b, buf, 8, deadline, stamp)) return 0 ;
+ uint64_unpack_big(buf, &res) ;
+ if (res != n) return (errno = EPROTO, 0) ;
+ if (!buffer_timed_get(b, buf, 8, deadline, stamp)) return 0 ;
+ uint64_unpack_big(buf, &res) ;
+ rr = res ;
+ if (res > n) res = n ;
+ if (res)
+ {
+ int sawasnull = !sa->s ;
+ size_t sabase = sa->len ;
+ if (!stralloc_readyplus(sa, res * sizeof(gid_t))) return 0 ;
+ if (!buffer_timed_get(b, sa->s + sabase, res * sizeof(gid_t), deadline, stamp))
+ {
+ if (sawasnull) stralloc_free(sa) ; else sa->len = sabase ;
+ return 0 ;
+ }
+ for (size_t i = 0 ; i < res ; i++)
+ gid_unpack_big(sa->s + sabase + i * sizeof(gid_t), gids + i) ;
+ if (sawasnull) stralloc_free(sa) ; else sa->len = sabase ;
+ }
+ *r = rr ;
+ return 1 ;
+}
+
+int nsss_switch_grp_getlist (nsss_switch_t *a, char const *user, gid_t *gids, size_t n, size_t *r, stralloc *sa, tain_t const *deadline, tain_t *stamp)
+{
+ char buf[13] = { NSSS_SWITCH_GRP_GETLIST } ;
+ size_t len = strlen(user) ;
+ struct iovec v[2] = { { .iov_base = buf, .iov_len = 13 }, { .iov_base = (char *)user, .iov_len = len + 1 } } ;
+ if (len > NSSS_SWITCH_NAME_MAXLEN - 1) return (errno = EINVAL, 0) ;
+ uint64_pack_big(buf + 1, n) ;
+ uint32_pack_big(buf + 9, len + 1) ;
+ if (!ipc_timed_sendv(buffer_fd(&a->b), v, 2, deadline, stamp)) return 0 ;
+ if (!buffer_timed_get(&a->b, &buf[0], 1, deadline, stamp)) return 0 ;
+ if (buf[0]) return (errno = buf[0], 0) ;
+ return nsss_switch_grouplist_read(&a->b, n, r, gids, sa, deadline, stamp) ;
+}
diff --git a/src/libnsss/nsss_unix_getgrouplist.c b/src/libnsss/nsss_unix_getgrouplist.c
index e9a11ab..83a8aeb 100644
--- a/src/libnsss/nsss_unix_getgrouplist.c
+++ b/src/libnsss/nsss_unix_getgrouplist.c
@@ -1,43 +1,19 @@
/* ISC license. */
-#include <string.h>
-#include <unistd.h>
+#include <stddef.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"
+#include <nsss/grp-unix.h>
+#include "nsss-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 ;
+ if (!nsss_unix_getgrouplist_preadjust(user, gids, n, &r)) return -1 ;
+ return nsss_grouplist_adjust(n, r, gid, gids, ngids, e) ;
}
diff --git a/src/libnsss/nsss_unix_getgrouplist_preadjust.c b/src/libnsss/nsss_unix_getgrouplist_preadjust.c
new file mode 100644
index 0000000..a0dc236
--- /dev/null
+++ b/src/libnsss/nsss_unix_getgrouplist_preadjust.c
@@ -0,0 +1,22 @@
+/* ISC license. */
+
+#include <skalibs/stralloc.h>
+#include <skalibs/genalloc.h>
+
+#include <nsss/nsss-unix.h>
+#include <nsss/grp-unix.h>
+
+int nsss_unix_getgrouplist_preadjust (char const *user, gid_t *gids, size_t n, size_t *r)
+{
+ stralloc sa = STRALLOC_ZERO ;
+ genalloc ga = GENALLOC_ZERO ; /* char * */
+ nsss_unix_t a = NSSS_UNIX_ZERO ;
+ if (!nsss_unix_grp_start(&a)) return 0 ;
+ if (!nsss_unix_grp_getlist(&a, user, gids, n, r, &sa, &ga))
+ {
+ nsss_unix_grp_end(&a) ;
+ return 0 ;
+ }
+ nsss_unix_grp_end(&a) ;
+ return 1 ;
+}
diff --git a/src/libnsss/nsss_unix_grp_getlist.c b/src/libnsss/nsss_unix_grp_getlist.c
index 9885a03..65a9117 100644
--- a/src/libnsss/nsss_unix_grp_getlist.c
+++ b/src/libnsss/nsss_unix_grp_getlist.c
@@ -9,9 +9,8 @@
#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 nsss_unix_grp_getlist (nsss_unix_t *a, char const *user, gid_t *gids, size_t n, size_t *r, stralloc *sa, genalloc *ga)
{
- int e = errno ;
int sawasnull = !sa->s ;
int gawasnull = !genalloc_s(char *, ga) ;
size_t sabase = sa->len ;
@@ -20,35 +19,35 @@ int nsss_unix_grp_getlist (nsss_unix_t *a, gid_t *gids, size_t n, size_t *r, str
for (;;)
{
- struct group *gr ;
+ struct group gr ;
sa->len = sabase ;
genalloc_setlen(char *, ga, gabase) ;
errno = 0 ;
- if (!nsss_unix_grp_get(a, gr, sa, ga))
+ if (!nsss_unix_grp_get(a, &gr, sa, ga))
{
if (errno) goto err ;
else break ;
}
- for (char **p = gr->gr_mem ; *p ; p++)
+ for (char **p = gr.gr_mem ; *p ; p++)
if (!strcmp(user, *p))
{
- if (m < n) gids[m] = gr->gr_gid ;
+ if (m < n) gids[m] = gr.gr_gid ;
m++ ;
break ;
}
}
- if (gawasnull) genalloc_free(char *, &ga) ;
+ if (gawasnull) genalloc_free(char *, ga) ;
else genalloc_setlen(char *, ga, gabase) ;
- if (sawasnull) stralloc_free(&sa) ;
+ if (sawasnull) stralloc_free(sa) ;
else sa->len = sabase ;
*r = m ;
return 1 ;
err:
- if (gawasnull) genalloc_free(char *, &ga) ;
+ if (gawasnull) genalloc_free(char *, ga) ;
else genalloc_setlen(char *, ga, gabase) ;
- if (sawasnull) stralloc_free(&sa) ;
+ if (sawasnull) stralloc_free(sa) ;
else sa->len = sabase ;
return 0 ;
}
diff --git a/src/nsssd/nsssd-nslcd.c b/src/nsssd/nsssd-nslcd.c
index 8f43ac9..47fb61d 100644
--- a/src/nsssd/nsssd-nslcd.c
+++ b/src/nsssd/nsssd-nslcd.c
@@ -467,6 +467,17 @@ int nsssd_grp_getbyname (void *handle, struct group *gr, char const *name)
return 0 ;
}
+int nsssd_grp_getlist (void *handle, char const *user, gid_t *gids, size_t n, size_t *r)
+{
+ /* TODO: find a sane way of implementing getgrouplist() over nslcd */
+ (void)handle ;
+ (void)user ;
+ (void)gids ;
+ (void)n ;
+ (void)r ;
+ return (errno = ENOSYS, 0) ;
+}
+
void nsssd_grp_end (void *handle)
{
}
diff --git a/src/nsssd/nsssd-unix.c b/src/nsssd/nsssd-unix.c
index e158c9f..6cbb3f2 100644
--- a/src/nsssd/nsssd-unix.c
+++ b/src/nsssd/nsssd-unix.c
@@ -115,6 +115,12 @@ int nsssd_grp_getbyname (void *handle, struct group *gr, char const *name)
return 1 ;
}
+int nsssd_grp_getlist (void *handle, char const *user, gid_t *gids, size_t n, size_t *r)
+{
+ (void)handle ;
+ return nsss_unix_getgrouplist_preadjust(user, gids, n, r) ;
+}
+
void nsssd_grp_end (void *handle)
{
nsss_unix_endgrent() ;
diff --git a/src/nsssd/nsssd_main.c b/src/nsssd/nsssd_main.c
index 133a813..2f4c625 100644
--- a/src/nsssd/nsssd_main.c
+++ b/src/nsssd/nsssd_main.c
@@ -11,6 +11,7 @@
#include <skalibs/types.h>
#include <skalibs/buffer.h>
#include <skalibs/strerr2.h>
+#include <skalibs/genalloc.h>
#include <skalibs/tai.h>
#include <skalibs/djbunix.h>
#include <skalibs/unix-timed.h>
@@ -309,6 +310,54 @@ static inline void do_grgid (void *a)
print_gr(&gr) ;
}
+static inline void do_grlist (void *a)
+{
+ uint64_t n ;
+ uint32_t len ;
+ char buf[12] ;
+ get0(buf, 12) ;
+ uint64_unpack_big(buf, &n) ;
+ uint32_unpack_big(buf + 8, &len) ;
+ if (!len || len > NSSS_SWITCH_NAME_MAXLEN - 1)
+ {
+ answer(EPROTO) ;
+ return ;
+ }
+ {
+ genalloc ga = GENALLOC_ZERO ;
+ size_t r ;
+ char user[len] ;
+ get0(user, len) ;
+ if (user[len-1])
+ {
+ answer(EPROTO) ;
+ return ;
+ }
+ if (!genalloc_ready(gid_t, &ga, n))
+ {
+ answer(errno) ;
+ return ;
+ }
+ if (!nsssd_grp_getlist(a, user, genalloc_s(gid_t, &ga), n, &r))
+ {
+ genalloc_free(gid_t, &ga) ;
+ answer(errno) ;
+ return ;
+ }
+ put1("", 1) ;
+ uint64_pack_big(buf, n) ; put1(buf, 8) ;
+ uint64_pack_big(buf, r) ; put1(buf, 8) ;
+ if (r > n) r = n ;
+ for (size_t i = 0 ; i < r ; i++)
+ {
+ gid_pack_big(buf, genalloc_s(gid_t, &ga)[i]) ;
+ put1(buf, sizeof(gid_t)) ;
+ }
+ genalloc_free(gid_t, &ga) ;
+ }
+ flush1() ;
+}
+
static inline void do_spend (void *a)
{
nsssd_shadow_end(a) ;
@@ -429,6 +478,7 @@ int nsssd_main (char const *const *argv, char const *const *envp)
case NSSS_SWITCH_GRP_GET : do_grget(a) ; break ;
case NSSS_SWITCH_GRP_GETBYNAME : do_grnam(a) ; break ;
case NSSS_SWITCH_GRP_GETBYGID : do_grgid(a) ; break ;
+ case NSSS_SWITCH_GRP_GETLIST : do_grlist(a) ; break ;
case NSSS_SWITCH_SHADOW_END : do_spend(a) ; break ;
case NSSS_SWITCH_SHADOW_REWIND : do_sprewind(a) ; break ;
case NSSS_SWITCH_SHADOW_GET : do_spget(a) ; break ;