#include <string.h>
#include <pwd.h>
#include <grp.h>
+#include <stdlib.h>
#include "../src/nss_utils.h"
# 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,
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);
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 = {
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,
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;
}