summaryrefslogtreecommitdiff
path: root/src/nsssd
diff options
context:
space:
mode:
Diffstat (limited to 'src/nsssd')
-rw-r--r--src/nsssd/nsssd-nslcd.c11
-rw-r--r--src/nsssd/nsssd-unix.c6
-rw-r--r--src/nsssd/nsssd_main.c50
3 files changed, 67 insertions, 0 deletions
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 ;