summaryrefslogtreecommitdiff
path: root/server
diff options
context:
space:
mode:
authorRemi Ferrand <remi.ferrand@cc.in2p3.fr>2014-03-31 15:18:54 +0200
committerRuss Allbery <rra@stanford.edu>2014-06-16 10:56:13 -0700
commitf92a381dbdaf753a90235a9f1e33b193a752c1c4 (patch)
tree8a3f52c0c471d2a08baad2811513adbb8a203dc0 /server
parentb6b2009aa32869a2a988ba458b45b044264cfd78 (diff)
Add ACL scheme for checking that user belongs to nss group
* Add documentation for *unxgrp* ACL scheme * Add *unxgrp* in supported ACL scheme in usage message * Add test suite for acl-unxgrp Change-Id: I7ed3008953e7751c02d81323e3c08cc9dddb9e49 Reviewed-on: https://gerrit.stanford.edu/1492 Reviewed-by: Russ Allbery <rra@stanford.edu> Tested-by: Russ Allbery <rra@stanford.edu>
Diffstat (limited to 'server')
-rw-r--r--server/config.c83
-rw-r--r--server/remctld.c3
2 files changed, 86 insertions, 0 deletions
diff --git a/server/config.c b/server/config.c
index f6d7608..85bd795 100644
--- a/server/config.c
+++ b/server/config.c
@@ -27,6 +27,11 @@
# include <regex.h>
#endif
#include <sys/stat.h>
+#ifdef HAVE_GETGRNAM_R
+# include <sys/types.h>
+# include <grp.h>
+# include <unistd.h>
+#endif
#include <server/internal.h>
#include <util/macros.h>
@@ -885,6 +890,79 @@ acl_check_regex(const char *user, const char *data, const char *file,
}
#endif /* HAVE_REGCOMP */
+#ifdef HAVE_GETGRNAM_R
+static enum config_status
+acl_check_unxgrp (const char *user, const char *data, const char *file,
+ int lineno)
+{
+ struct group grp;
+ struct group *tempgrp = NULL;
+ int status = -1;
+ enum config_status result = CONFIG_ERROR;
+ long buf_len = -1;
+ char *buf = NULL;
+ size_t buf_sz = 1024;
+
+ memset(&grp, 0x0, sizeof(grp));
+
+ buf_len = sysconf(_SC_GETGR_R_SIZE_MAX);
+ if (buf_len > 0) {
+ buf_sz = (size_t) buf_sz;
+ }
+
+ buf = (char *) xmalloc(sizeof(char) * buf_sz);
+ memset(buf, 0x0, buf_sz);
+
+ do {
+ status = getgrnam_r(data, &grp, buf, buf_sz, &tempgrp);
+ if (status != 0 && status != EINTR) {
+ warn("%s:%d: resolving unix group '%s' failed with status %d", file,
+ lineno, data, status);
+ result = CONFIG_ERROR;
+ goto die;
+ }
+ } while (status == EINTR);
+
+ /* No group matching */
+ if (tempgrp == NULL) {
+ result = CONFIG_NOMATCH;
+ }
+ else {
+ /* Sanitize and search for match in group members */
+ char *cur_member = grp.gr_mem[0];
+ char *p_user = user;
+ int i = 0;
+ char *sanitized_user = NULL;
+
+ /* Sanitize username, remove instances and REALM */
+ sanitized_user = xmalloc(sizeof(char)* strlen(user));
+ memset(sanitized_user, 0x0, strlen(user));
+
+ while (p_user != NULL && *p_user != '\0') {
+ if (*p_user == '\x40' || *p_user == '\x2F')
+ break;
+ sanitized_user[i++] = *p_user;
+ p_user += 1;
+ }
+
+ /* Check if sanitized user is within group members */
+ i = 0;
+ while (cur_member != NULL && *cur_member != '\0') {
+ if (strcmp(cur_member, sanitized_user) == 0) {
+ result = CONFIG_SUCCESS;
+ goto die;
+ }
+ cur_member = grp.gr_mem[++i];
+ }
+
+ result = CONFIG_NOMATCH;
+ }
+
+die:
+ return result;
+}
+#endif /* HAVE_GETGRNAM_R */
+
/*
* The table relating ACL scheme names to functions. The first two ACL
* schemes must remain in their current slots or the index constants set at
@@ -909,6 +987,11 @@ static const struct acl_scheme schemes[] = {
#else
{ "regex", NULL },
#endif
+#ifdef HAVE_GETGRNAM_R
+ { "unxgrp", acl_check_unxgrp },
+#else
+ { "unxgrp", NULL },
+#endif
{ NULL, NULL }
};
diff --git a/server/remctld.c b/server/remctld.c
index 2fde503..3209b1e 100644
--- a/server/remctld.c
+++ b/server/remctld.c
@@ -107,6 +107,9 @@ usage(int status)
#ifdef HAVE_REGCOMP
fprintf(output, ", regex");
#endif
+#ifdef HAVE_GETGRNAM_R
+ fprintf(output, ", unxgrp");
+#endif
fprintf(output, "\n");
exit(status);
}