waffle

user and group backend daemon
git clone git://git.2f30.org/waffle
Log | Files | Refs | LICENSE

commit b39751498ad3ec5727559e33c3fa0d541bc21025
parent 4aec1a1705a634555089db8b948f4a9ba8eda9ac
Author: sin <sin@2f30.org>
Date:   Sat,  7 Mar 2015 17:52:16 +0000

Add GRBYNAME support

Diffstat:
Mbackend.c | 11+++++++++++
Mdummy.c | 17++++++++++++++++-
Mreq.c | 67+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Mwaffle.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 *);