tests: Implement _nss_nwrap_initgroups_dyn(), _nss_nwrap_getgrent_r(), _nss_nwrap_get...
authorPavel Filipenský <pfilipensky@samba.org>
Mon, 16 Jan 2023 20:27:05 +0000 (21:27 +0100)
committerAndreas Schneider <asn@samba.org>
Tue, 24 Jan 2023 08:56:35 +0000 (09:56 +0100)
Signed-off-by: Pavel Filipenský <pfilipensky@samba.org>
Reviewed-by: Andreas Schneider <asn@samba.org>
tests/nss_nwrap.c

index df0f4ab8d81b31068fd7ba37384a57a80402b289..a11b1649f33330b98b509646b11c85fa37ccde20 100644 (file)
@@ -7,6 +7,7 @@
 #include <string.h>
 #include <pwd.h>
 #include <grp.h>
+#include <stdlib.h>
 
 #include "../src/nss_utils.h"
 
@@ -31,6 +32,14 @@ typedef nss_status_t NSS_STATUS;
 # error "No nsswitch support detected"
 #endif
 
+#ifndef discard_const
+#define discard_const(ptr) ((void *)((uintptr_t)(ptr)))
+#endif
+
+#ifndef discard_const_p
+#define discard_const_p(type, ptr) ((type *)discard_const(ptr))
+#endif
+
 NSS_STATUS _nss_nwrap_setpwent(void);
 NSS_STATUS _nss_nwrap_endpwent(void);
 NSS_STATUS _nss_nwrap_getpwent_r(struct passwd *result, char *buffer,
@@ -41,12 +50,20 @@ NSS_STATUS _nss_nwrap_getpwnam_r(const char *name, struct passwd *result,
                                   char *buffer, size_t buflen, int *errnop);
 NSS_STATUS _nss_nwrap_setgrent(void);
 NSS_STATUS _nss_nwrap_endgrent(void);
-NSS_STATUS _nss_nwrap_getgrent_r(struct group *result, char *buffer,
-                                size_t buflen, int *errnop);
-NSS_STATUS _nss_nwrap_getgrnam_r(const char *name, struct group *result,
-                                char *buffer, size_t buflen, int *errnop);
-NSS_STATUS _nss_nwrap_getgrgid_r(gid_t gid, struct group *result, char *buffer,
-                                size_t buflen, int *errnop);
+NSS_STATUS _nss_nwrap_getgrent_r(struct group *result,
+                                char *buffer,
+                                size_t buflen,
+                                struct group **grdstp);
+NSS_STATUS _nss_nwrap_getgrnam_r(const char *name,
+                                struct group *result,
+                                char *buffer,
+                                size_t buflen,
+                                struct group **grdstp);
+NSS_STATUS _nss_nwrap_getgrgid_r(gid_t gid,
+                                struct group *result,
+                                char *buffer,
+                                size_t buflen,
+                                struct group **grdstp);
 NSS_STATUS _nss_nwrap_initgroups_dyn(char *user, gid_t group, long int *start,
                                     long int *size, gid_t **groups,
                                     long int limit, int *errnop);
@@ -135,6 +152,7 @@ NSS_STATUS _nss_nwrap_getpwent_r(struct passwd *result, char *buffer,
 NSS_STATUS _nss_nwrap_getpwuid_r(uid_t uid, struct passwd *result,
                                 char *buffer, size_t buflen, int *errnop)
 {
+       (void)errnop; /* unused */
        if (uid == 424242) {
                char buf[] = "hanswurst\0secret\0\0/home/hanswurst\0/bin/false";
                const struct passwd src = {
@@ -167,50 +185,116 @@ NSS_STATUS _nss_nwrap_getpwnam_r(const char *name, struct passwd *result,
 
        return NSS_STATUS_UNAVAIL;
 }
+static int grent_idx = 0;
 
 NSS_STATUS _nss_nwrap_setgrent(void)
 {
-       return NSS_STATUS_UNAVAIL;
+       grent_idx = 0;
+       return NSS_STATUS_SUCCESS;
 }
 
 NSS_STATUS _nss_nwrap_endgrent(void)
 {
-       return NSS_STATUS_UNAVAIL;
+       grent_idx = 0;
+       return NSS_STATUS_SUCCESS;
 }
 
-NSS_STATUS _nss_nwrap_getgrent_r(struct group *result, char *buffer,
-                                size_t buflen, int *errnop)
+static const struct group gr0 = {
+       .gr_name = discard_const_p(char, "wb_group_0"),
+       .gr_passwd = discard_const_p(char, "x"),
+       .gr_gid = 100010,
+       .gr_mem = (char *[]) {
+               discard_const_p(char, "alice"),
+               discard_const_p(char, "bob"),
+               NULL
+       },
+};
+static const struct group gr1 = {
+       .gr_name = discard_const_p(char, "wb_group_1"),
+       .gr_passwd = discard_const_p(char, "x"),
+       .gr_gid = 100011,
+       .gr_mem = (char *[]) {
+               discard_const_p(char, "alice"),
+               discard_const_p(char, "bob"),
+               NULL
+       },
+};
+static const struct group gr2 = {
+       .gr_name = discard_const_p(char, "wb_group_2"),
+       .gr_passwd = discard_const_p(char, "x"),
+       .gr_gid = 100012,
+       .gr_mem = (char *[]) {
+               discard_const_p(char, "alice"),
+               NULL
+       },
+};
+
+NSS_STATUS _nss_nwrap_getgrent_r(struct group *result,
+                                char *buffer,
+                                size_t buflen,
+                                struct group **grdstp)
 {
-       (void) result;
-       (void) buffer;
-       (void) buflen;
-       (void) errnop;
-
-       return NSS_STATUS_UNAVAIL;
+       switch (grent_idx) {
+               int ret;
+       case 0:
+               ret = nwrap_gr_copy_r(&gr0, result, buffer, buflen, grdstp);
+               grent_idx++;
+               return ret == 0 ? NSS_STATUS_SUCCESS : NSS_STATUS_TRYAGAIN;
+       case 1:
+               ret = nwrap_gr_copy_r(&gr1, result, buffer, buflen, grdstp);
+               grent_idx++;
+               return ret == 0 ? NSS_STATUS_SUCCESS : NSS_STATUS_TRYAGAIN;
+       case 2:
+               ret = nwrap_gr_copy_r(&gr2, result, buffer, buflen, grdstp);
+               grent_idx++;
+               return ret == 0 ? NSS_STATUS_SUCCESS : NSS_STATUS_TRYAGAIN;
+       default:
+               return NSS_STATUS_NOTFOUND;
+       }
 }
 
-NSS_STATUS _nss_nwrap_getgrnam_r(const char *name, struct group *result,
-                                char *buffer, size_t buflen, int *errnop)
+NSS_STATUS _nss_nwrap_getgrnam_r(const char *name,
+                                struct group *result,
+                                char *buffer,
+                                size_t buflen,
+                                struct group **grdstp)
 {
-       (void) name;
-       (void) result;
-       (void) buffer;
-       (void) buflen;
-       (void) errnop;
-
-       return NSS_STATUS_UNAVAIL;
+       int ret;
+
+       if (strcmp(name, "wb_group_0") == 0) {
+               ret = nwrap_gr_copy_r(&gr0, result, buffer, buflen, grdstp);
+               return ret == 0 ? NSS_STATUS_SUCCESS : NSS_STATUS_TRYAGAIN;
+       } else if (strcmp(name, "wb_group_1") == 0) {
+               ret = nwrap_gr_copy_r(&gr1, result, buffer, buflen, grdstp);
+               return ret == 0 ? NSS_STATUS_SUCCESS : NSS_STATUS_TRYAGAIN;
+       } else if (strcmp(name, "wb_group_2") == 0) {
+               ret = nwrap_gr_copy_r(&gr2, result, buffer, buflen, grdstp);
+               return ret == 0 ? NSS_STATUS_SUCCESS : NSS_STATUS_TRYAGAIN;
+       } else {
+               return NSS_STATUS_NOTFOUND;
+       }
 }
 
-NSS_STATUS _nss_nwrap_getgrgid_r(gid_t gid, struct group *result, char *buffer,
-                                size_t buflen, int *errnop)
+NSS_STATUS _nss_nwrap_getgrgid_r(gid_t gid,
+                                struct group *result,
+                                char *buffer,
+                                size_t buflen,
+                                struct group **grdstp)
 {
-       (void) gid;
-       (void) result;
-       (void) buffer;
-       (void) buflen;
-       (void) errnop;
-
-       return NSS_STATUS_UNAVAIL;
+       int ret;
+       switch (gid) {
+       case 100010:
+               ret = nwrap_gr_copy_r(&gr0, result, buffer, buflen, grdstp);
+               return ret == 0 ? NSS_STATUS_SUCCESS : NSS_STATUS_TRYAGAIN;
+       case 100011:
+               ret = nwrap_gr_copy_r(&gr1, result, buffer, buflen, grdstp);
+               return ret == 0 ? NSS_STATUS_SUCCESS : NSS_STATUS_TRYAGAIN;
+       case 100012:
+               ret = nwrap_gr_copy_r(&gr2, result, buffer, buflen, grdstp);
+               return ret == 0 ? NSS_STATUS_SUCCESS : NSS_STATUS_TRYAGAIN;
+       default:
+               return NSS_STATUS_NOTFOUND;
+       }
 }
 
 NSS_STATUS _nss_nwrap_initgroups_dyn(char *user, gid_t group, long int *start,
@@ -218,13 +302,40 @@ NSS_STATUS _nss_nwrap_initgroups_dyn(char *user, gid_t group, long int *start,
                                     long int limit, int *errnop)
 {
        (void) user;
-       (void) group;
-       (void) start;
-       (void) size;
-       (void) groups;
+       (void)group;
        (void) limit;
        (void) errnop;
 
-       return NSS_STATUS_UNAVAIL;
+       if (!(strcmp(user, "alice") == 0 || strcmp(user, "bob") == 0)) {
+               return NSS_STATUS_SUCCESS;
+       }
+
+       if (*start + 4 >= *size) {
+               long int newsize;
+               gid_t *newgroups;
+
+               newsize = *size + 4;
+               if (limit > 0) {
+                       if (newsize > limit) {
+                               return NSS_STATUS_NOTFOUND;
+                       }
+               }
+
+               newgroups =
+                       (gid_t *)realloc((*groups), newsize * sizeof(**groups));
+               if (!newgroups) {
+                       *errnop = ENOMEM;
+                       return NSS_STATUS_NOTFOUND;
+               }
+               *groups = newgroups;
+               *size = newsize;
+       }
+
+       (*groups)[(*start)++] = 100010;
+       (*groups)[(*start)++] = 100011;
+       if (strcmp(user, "alice") == 0) {
+               (*groups)[(*start)++] = 100012;
+       }
+       return NSS_STATUS_SUCCESS;
 }