Blame SOURCES/Handle-extra-large-NSS-entries.patch

a86470
From 43992c5d7b138a11339a725242863b5d001d21bb Mon Sep 17 00:00:00 2001
a86470
From: Simo Sorce <simo@redhat.com>
a86470
Date: Tue, 3 Oct 2017 12:31:02 -0400
a86470
Subject: [PATCH] Handle extra large NSS entries
a86470
a86470
Signed-off-by: Simo Sorce <simo@redhat.com>
a86470
Reviewed-by: Robbie Harwood <rharwood@redhat.com>
a86470
a86470
Closes #152
a86470
a86470
(cherry picked from commit 9813eb46c6c415a933c5edf5076fd0a8e39c86b2)
a86470
[rharwood@redhat.com: conflicts due to no lex/yacc stuff yet]
a86470
---
a86470
 src/Makefile.am       |  2 +-
a1faee
 src/mod_auth_gssapi.c | 26 ++++++-----------
a86470
 src/mod_auth_gssapi.h |  2 ++
a1faee
 src/util.c            | 66 +++++++++++++++++++++++++++++++++++++++++++
a86470
 4 files changed, 78 insertions(+), 18 deletions(-)
a86470
 create mode 100644 src/util.c
a86470
a86470
diff --git a/src/Makefile.am b/src/Makefile.am
a86470
index 0605261..d8dd3ec 100644
a86470
--- a/src/Makefile.am
a86470
+++ b/src/Makefile.am
a86470
@@ -8,7 +8,7 @@ dist_noinst_HEADERS = \
a86470
     mod_auth_gssapi.h crypto.h sessions.h environ.h
a86470
 
a86470
 mod_auth_gssapi_la_SOURCES = \
a86470
-    mod_auth_gssapi.c crypto.c sessions.c environ.c
a86470
+    mod_auth_gssapi.c crypto.c sessions.c environ.c util.c
a86470
 mod_auth_gssapi_la_CFLAGS = \
a86470
     $(MAG_CFLAGS)
a86470
 mod_auth_gssapi_la_LIBADD = \
a86470
diff --git a/src/mod_auth_gssapi.c b/src/mod_auth_gssapi.c
a86470
index 74962d1..c2dd039 100644
a86470
--- a/src/mod_auth_gssapi.c
a86470
+++ b/src/mod_auth_gssapi.c
a86470
@@ -1476,7 +1476,7 @@ static const char *mag_deleg_ccache_dir(cmd_parms *parms, void *mconfig,
a86470
 #define CCMODE "mode:"
a86470
 #define CCUID "uid:"
a86470
 #define CCGID "gid:"
a86470
-#define NSS_BUF_LEN 2048 /* just use a uid/gid number if not big enough */
a86470
+
a86470
 static const char *mag_deleg_ccache_perms(cmd_parms *parms, void *mconfig,
a86470
                                           const char *w)
a86470
 {
a86470
@@ -1510,15 +1510,11 @@ static const char *mag_deleg_ccache_perms(cmd_parms *parms, void *mconfig,
a86470
                 cfg->deleg_ccache_uid = 0;
a86470
             }
a86470
         } else {
a86470
-            struct passwd pwd, *user;
a86470
-            char buf[NSS_BUF_LEN];
a86470
-            int ret = getpwnam_r(p, &pwd, buf, NSS_BUF_LEN, &user);
a86470
-            if ((ret != 0) || user != &pwd) {
a86470
+            int ret = mag_get_user_uid(p, &cfg->deleg_ccache_uid);
a86470
+            if (ret != 0) {
a86470
                 ap_log_error(APLOG_MARK, APLOG_ERR, 0, parms->server,
a86470
-                             "Invalid GssapiDelegCcachePerms uid value [%s]",
a86470
-                             p);
a86470
-            } else {
a86470
-                cfg->deleg_ccache_uid = user->pw_uid;
a86470
+                    "Invalid GssapiDelegCcachePerms uid value [%s](%s)",
a86470
+                    p, strerror(ret));
a86470
             }
a86470
         }
a86470
     } else if (strncmp(w, CCGID, sizeof(CCGID) - 1) == 0) {
a86470
@@ -1535,15 +1531,11 @@ static const char *mag_deleg_ccache_perms(cmd_parms *parms, void *mconfig,
a86470
                 cfg->deleg_ccache_gid = 0;
a86470
             }
a86470
         } else {
a86470
-            struct group grp, *group;
a86470
-            char buf[NSS_BUF_LEN];
a86470
-            int ret = getgrnam_r(p, &grp, buf, NSS_BUF_LEN, &group);
a86470
-            if ((ret != 0) || group != &grp) {
a86470
+            int ret = mag_get_group_gid(p, &cfg->deleg_ccache_gid);
a86470
+            if (ret != 0) {
a86470
                 ap_log_error(APLOG_MARK, APLOG_ERR, 0, parms->server,
a86470
-                             "Invalid GssapiDelegCcachePerms gid value [%s]",
a86470
-                             p);
a86470
-            } else {
a86470
-                cfg->deleg_ccache_gid = group->gr_gid;
a86470
+                    "Invalid GssapiDelegCcachePerms gid value [%s](%s)",
a86470
+                    p, strerror(ret));
a86470
             }
a86470
         }
a86470
     } else {
a86470
diff --git a/src/mod_auth_gssapi.h b/src/mod_auth_gssapi.h
a86470
index 159d6b7..2ea52a3 100644
a86470
--- a/src/mod_auth_gssapi.h
a86470
+++ b/src/mod_auth_gssapi.h
a86470
@@ -138,3 +138,5 @@ struct mag_conn {
a86470
 struct mag_conn *mag_new_conn_ctx(apr_pool_t *pool);
a86470
 const char *mag_str_auth_type(int auth_type);
a86470
 char *mag_error(apr_pool_t *pool, const char *msg, uint32_t maj, uint32_t min);
a86470
+int mag_get_user_uid(const char *name, uid_t *uid);
a86470
+int mag_get_group_gid(const char *name, gid_t *gid);
a86470
diff --git a/src/util.c b/src/util.c
a86470
new file mode 100644
a86470
index 0000000..6b2a4a0
a86470
--- /dev/null
a86470
+++ b/src/util.c
a86470
@@ -0,0 +1,66 @@
a86470
+/* Copyright (C) 2017 mod_auth_gssapi contributors - See COPYING for (C) terms */
a86470
+
a86470
+#include "mod_auth_gssapi.h"
a86470
+
a86470
+#define NSS_BUF_MIN 1024
a86470
+#define NSS_BUF_MAX 1024*1024
a86470
+static char *get_buf(char *cur, size_t *len)
a86470
+{
a86470
+    if (*len == 0) {
a86470
+        *len = NSS_BUF_MIN;
a86470
+    } else {
a86470
+        *len *= 2;
a86470
+    }
a86470
+    if (*len > NSS_BUF_MAX) {
a86470
+        *len = 0; /* will free the buf and return NULL */
a86470
+    }
a86470
+    return realloc(cur, *len);
a86470
+}
a86470
+
a86470
+int mag_get_user_uid(const char *name, uid_t *uid)
a86470
+{
a86470
+    struct passwd pwd, *user;
a86470
+    size_t buflen = 0;
a86470
+    char *buf = NULL;
a86470
+    int ret;
a86470
+
a86470
+    do {
a86470
+        buf = get_buf(buf, &buflen);
a86470
+        if (buf == NULL || buflen == 0) {
a86470
+            ret = ENOMEM;
a86470
+            break;
a86470
+        }
a86470
+        ret = getpwnam_r(name, &pwd, buf, buflen, &user);
a86470
+    } while (ret == ERANGE);
a86470
+    if (ret != 0 || user != &pwd) {
a86470
+        ret = (ret == 0) ? EINVAL : ret;
a86470
+    } else {
a86470
+        *uid = user->pw_uid;
a86470
+    }
a86470
+    free(buf);
a86470
+    return ret;
a86470
+}
a86470
+
a86470
+int mag_get_group_gid(const char *name, gid_t *gid)
a86470
+{
a86470
+    struct group grp, *group;
a86470
+    size_t buflen = 0;
a86470
+    char *buf = NULL;
a86470
+    int ret;
a86470
+
a86470
+    do {
a86470
+        buf = get_buf(buf, &buflen);
a86470
+        if (buf == NULL || buflen == 0) {
a86470
+            ret = ENOMEM;
a86470
+            break;
a86470
+        }
a86470
+        ret = getgrnam_r(name, &grp, buf, buflen, &group);
a86470
+    } while (ret == ERANGE);
a86470
+    if (ret != 0 || group != &grp) {
a86470
+        ret = (ret == 0) ? EINVAL : ret;
a86470
+    } else {
a86470
+        *gid = group->gr_gid;
a86470
+    }
a86470
+    free(buf);
a86470
+    return ret;
a86470
+}