commit b39751498ad3ec5727559e33c3fa0d541bc21025
parent 4aec1a1705a634555089db8b948f4a9ba8eda9ac
Author: sin <sin@2f30.org>
Date: Sat, 7 Mar 2015 17:52:16 +0000
Add GRBYNAME support
Diffstat:
M | backend.c | | | 11 | +++++++++++ |
M | dummy.c | | | 17 | ++++++++++++++++- |
M | req.c | | | 67 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
M | waffle.h | | | 7 | +++++-- |
4 files changed, 99 insertions(+), 3 deletions(-)
diff --git a/backend.c b/backend.c
@@ -58,3 +58,14 @@ backends_pwbyuid(const char *key, struct passwd *pw)
return 0;
return -1;
}
+
+int
+backends_grbyname(const char *key, struct group *gr)
+{
+ size_t i;
+
+ for (i = 0; i < LEN(backends); i++)
+ if (!backends[i].ops->grbyname(key, gr))
+ return 0;
+ return -1;
+}
diff --git a/dummy.c b/dummy.c
@@ -42,9 +42,24 @@ dummy_pwbyuid(uid_t uid, struct passwd *pw)
return 0;
}
+static int
+dummy_grbyname(const char *name, struct group *gr)
+{
+ static char *mem[] = { "group1", "group2", NULL };
+
+ if (strcmp(name, "dummy"))
+ return -1;
+ gr->gr_name = "dummy";
+ gr->gr_passwd = "passwd";
+ gr->gr_gid = 1337;
+ gr->gr_mem = mem;
+ return 0;
+}
+
struct backend_ops dummy_ops = {
.init = dummy_init,
.term = dummy_term,
.pwbyname = dummy_pwbyname,
- .pwbyuid = dummy_pwbyuid
+ .pwbyuid = dummy_pwbyuid,
+ .grbyname = dummy_grbyname,
};
diff --git a/req.c b/req.c
@@ -97,10 +97,72 @@ replypwd(int clifd, struct passwd *pwd)
return (size_t)n != len ? -1 : 0;
}
+static int
+replygr(int clifd, struct group *gr)
+{
+ struct nscdgrp header;
+ char *buf;
+ int32_t *lengths;
+ size_t memsize = 0, i, len, offset;
+ ssize_t n;
+
+ header.version = NSCDVERSION;
+ header.found = gr ? 1 : 0;
+ header.namelen = gr ? strlen(gr->gr_name) + 1 : 0;
+ header.passwdlen = gr ? strlen(gr->gr_passwd) + 1 : 0;
+ header.gid = gr ? gr->gr_gid : -1;
+ if (gr) {
+ for (i = 0; gr->gr_mem[i]; i++)
+ memsize += strlen(gr->gr_mem[i]) + 1;
+ header.memcnt = i;
+ } else {
+ header.memcnt = 0;
+ }
+
+ len = sizeof(header) +
+ header.namelen +
+ header.passwdlen +
+ header.memcnt * 4 +
+ memsize;
+
+ buf = malloc(len);
+ if (!buf)
+ return -1;
+
+ if (!gr) {
+ memcpy(buf, &header, sizeof(header));
+ } else {
+ memcpy(buf, &header, sizeof(header));
+ offset = sizeof(header);
+
+ lengths = (int32_t *)&buf[offset];
+ for (i = 0; i < header.memcnt; i++)
+ lengths[i] = strlen(gr->gr_mem[i]) + 1;
+ offset += header.memcnt * 4;
+
+ memcpy(buf + offset, gr->gr_name, header.namelen);
+ offset += header.namelen;
+
+ memcpy(buf + offset, gr->gr_passwd, header.passwdlen);
+ offset += header.passwdlen;
+
+ for (i = 0; i < header.memcnt; i++) {
+ memcpy(buf + offset, gr->gr_mem[i],
+ strlen(gr->gr_mem[i]) + 1);
+ offset += lengths[i];
+ }
+ }
+
+ n = write(clifd, buf, len);
+ free(buf);
+ return (size_t)n != len ? -1 : 0;
+}
+
int
process_req(int clifd, struct nscdreq *req, char *key)
{
struct passwd pwd;
+ struct group gr;
switch (req->type) {
case GETPWBYNAME:
@@ -113,6 +175,11 @@ process_req(int clifd, struct nscdreq *req, char *key)
return replypwd(clifd, &pwd);
else
return replypwd(clifd, NULL);
+ case GETGRBYNAME:
+ if (!backends_grbyname(key, &gr))
+ return replygr(clifd, &gr);
+ else
+ return replygr(clifd, NULL);
}
if (debug)
diff --git a/waffle.h b/waffle.h
@@ -1,4 +1,5 @@
#include <sys/types.h>
+#include <grp.h>
#include <pwd.h>
#include "proto.h"
@@ -7,8 +8,9 @@
struct backend_ops {
int (*init)(void);
void (*term)(void);
- int (*pwbyname)(const char *name, struct passwd *pw);
- int (*pwbyuid)(uid_t uid, struct passwd *pw);
+ int (*pwbyname)(const char *, struct passwd *);
+ int (*pwbyuid)(uid_t, struct passwd *);
+ int (*grbyname)(const char *, struct group *);
};
/* nscd.c */
@@ -25,3 +27,4 @@ int backends_init(void);
void backends_term(void);
int backends_pwbyname(const char *, struct passwd *);
int backends_pwbyuid(const char *, struct passwd *);
+int backends_grbyname(const char *, struct group *);