summaryrefslogtreecommitdiff
path: root/src/libnsss
diff options
context:
space:
mode:
Diffstat (limited to 'src/libnsss')
-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
9 files changed, 198 insertions, 41 deletions
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 ;
}