Blob Blame History Raw
From c31065ecc0793e836066035d0c692b050b5f6f55 Mon Sep 17 00:00:00 2001
From: Nikolai Kondrashov <Nikolai.Kondrashov@redhat.com>
Date: Wed, 29 Mar 2017 16:07:52 +0300
Subject: [PATCH 03/93] NSS: Move shell options to common responder
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

Move all the shell-related options from the NSS responder context to the
common responder context, so they can be used by other responders for
retrieving original user shell, when it is overrided for session
recording.

Reviewed-by: Pavel Březina <pbrezina@redhat.com>
---
 src/responder/common/responder.h        |   7 +++
 src/responder/common/responder_common.c | 100 ++++++++++++++++++++++++++++++++
 src/responder/nss/nss_private.h         |   6 --
 src/responder/nss/nss_protocol_pwent.c  |  42 +++++++-------
 src/responder/nss/nsssrv.c              |  99 -------------------------------
 5 files changed, 128 insertions(+), 126 deletions(-)

diff --git a/src/responder/common/responder.h b/src/responder/common/responder.h
index b0e3e05b9d0f7890fda3a2596b8ffc5a7ec2d205..7a998967f2761b1c813a866f34cf78d549ede1b9 100644
--- a/src/responder/common/responder.h
+++ b/src/responder/common/responder.h
@@ -139,6 +139,13 @@ struct resp_ctx {
     char *default_domain;
     char override_space;
 
+    char **allowed_shells;
+    char *override_shell;
+    char **vetoed_shells;
+    char **etc_shells;
+    char *shell_fallback;
+    char *default_shell;
+
     uint32_t cache_req_num;
 
     void *pvt_ctx;
diff --git a/src/responder/common/responder_common.c b/src/responder/common/responder_common.c
index 74c424c7bae5de3b900261cb9f958ee4414403dd..edf6a34bda9730f32fac503ae88951390da51612 100644
--- a/src/responder/common/responder_common.c
+++ b/src/responder/common/responder_common.c
@@ -50,6 +50,9 @@
 #include <systemd/sd-daemon.h>
 #endif
 
+#define SHELL_REALLOC_INCREMENT 5
+#define SHELL_REALLOC_MAX       50
+
 static errno_t set_close_on_exec(int fd)
 {
     int v;
@@ -1062,6 +1065,72 @@ done:
     return ret;
 }
 
+static errno_t sss_get_etc_shells(TALLOC_CTX *mem_ctx, char ***_shells)
+{
+    int i = 0;
+    char *sh;
+    char **shells = NULL;
+    TALLOC_CTX *tmp_ctx;
+    errno_t ret;
+    int size;
+
+    tmp_ctx = talloc_new(NULL);
+    if (!tmp_ctx) return ENOMEM;
+
+    shells = talloc_array(tmp_ctx, char *, SHELL_REALLOC_INCREMENT);
+    if (!shells) {
+        ret = ENOMEM;
+        goto done;
+    }
+    size = SHELL_REALLOC_INCREMENT;
+
+    setusershell();
+    while ((sh = getusershell())) {
+        shells[i] = talloc_strdup(shells, sh);
+        if (!shells[i]) {
+            endusershell();
+            ret = ENOMEM;
+            goto done;
+        }
+        DEBUG(SSSDBG_TRACE_FUNC, "Found shell %s in /etc/shells\n", shells[i]);
+        i++;
+
+        if (i == size) {
+            size += SHELL_REALLOC_INCREMENT;
+            if (size > SHELL_REALLOC_MAX) {
+                DEBUG(SSSDBG_FATAL_FAILURE,
+                      "Reached maximum number of shells [%d]. "
+                          "Users may be denied access. "
+                          "Please check /etc/shells for sanity\n",
+                          SHELL_REALLOC_MAX);
+                break;
+            }
+            shells = talloc_realloc(NULL, shells, char *,
+                                    size);
+            if (!shells) {
+                ret = ENOMEM;
+                goto done;
+            }
+        }
+    }
+    endusershell();
+
+    if (i + 1 < size) {
+        shells = talloc_realloc(NULL, shells, char *, i + 1);
+        if (!shells) {
+            ret = ENOMEM;
+            goto done;
+        }
+    }
+    shells[i] = NULL;
+
+    *_shells = talloc_move(mem_ctx, &shells);
+    ret = EOK;
+done:
+    talloc_zfree(tmp_ctx);
+    return ret;
+}
+
 int sss_process_init(TALLOC_CTX *mem_ctx,
                      struct tevent_context *ev,
                      struct confdb_ctx *cdb,
@@ -1201,6 +1270,37 @@ int sss_process_init(TALLOC_CTX *mem_ctx,
               ret, sss_strerror(ret));
     }
 
+    /* Read shell settings */
+    ret = confdb_get_string(cdb, rctx, CONFDB_NSS_CONF_ENTRY,
+                            CONFDB_NSS_OVERRIDE_SHELL, NULL,
+                            &rctx->override_shell);
+    if (ret != EOK && ret != ENOENT) goto fail;
+
+    ret = confdb_get_string_as_list(cdb, rctx, CONFDB_NSS_CONF_ENTRY,
+                                    CONFDB_NSS_ALLOWED_SHELL,
+                                    &rctx->allowed_shells);
+    if (ret != EOK && ret != ENOENT) goto fail;
+
+    ret = confdb_get_string_as_list(cdb, rctx, CONFDB_NSS_CONF_ENTRY,
+                                    CONFDB_NSS_VETOED_SHELL,
+                                    &rctx->vetoed_shells);
+    if (ret != EOK && ret != ENOENT) goto fail;
+
+    ret = sss_get_etc_shells(rctx, &rctx->etc_shells);
+    if (ret != EOK) goto fail;
+
+    ret = confdb_get_string(cdb, rctx, CONFDB_NSS_CONF_ENTRY,
+                            CONFDB_NSS_SHELL_FALLBACK,
+                            CONFDB_DEFAULT_SHELL_FALLBACK,
+                            &rctx->shell_fallback);
+    if (ret != EOK) goto fail;
+
+    ret = confdb_get_string(cdb, rctx, CONFDB_NSS_CONF_ENTRY,
+                            CONFDB_NSS_DEFAULT_SHELL,
+                            NULL,
+                            &rctx->default_shell);
+    if (ret != EOK) goto fail;
+
     ret = sss_monitor_init(rctx, rctx->ev, monitor_intf,
                            svc_name, svc_version, MT_SVC_SERVICE,
                            rctx, &rctx->last_request_time,
diff --git a/src/responder/nss/nss_private.h b/src/responder/nss/nss_private.h
index 13de83226177bbaa8b8237e3e27b7e72da369194..a0b573d6ecba2d8ba6f55db0adcd7ee29cbec991 100644
--- a/src/responder/nss/nss_private.h
+++ b/src/responder/nss/nss_private.h
@@ -74,12 +74,6 @@ struct nss_ctx {
     char *override_homedir;
     char *fallback_homedir;
     char *homedir_substr;
-    char **allowed_shells;
-    char *override_shell;
-    char **vetoed_shells;
-    char **etc_shells;
-    char *shell_fallback;
-    char *default_shell;
     const char **extra_attributes;
 
     /* Enumeration. */
diff --git a/src/responder/nss/nss_protocol_pwent.c b/src/responder/nss/nss_protocol_pwent.c
index b355d4fc90397f51e82545e56940be850f144d49..cb11ea3d493370552fa5a97fd4ffe2108ff34026 100644
--- a/src/responder/nss/nss_protocol_pwent.c
+++ b/src/responder/nss/nss_protocol_pwent.c
@@ -121,7 +121,7 @@ nss_get_homedir(TALLOC_CTX *mem_ctx,
 
 static const char *
 nss_get_shell_override(struct ldb_message *msg,
-                       struct nss_ctx *nss_ctx,
+                       struct resp_ctx *rctx,
                        struct sss_domain_info *domain)
 {
     const char *shell;
@@ -131,8 +131,8 @@ nss_get_shell_override(struct ldb_message *msg,
      * the server for the login shell. */
     if (domain->override_shell) {
         return domain->override_shell;
-    } else if (nss_ctx->override_shell) {
-        return nss_ctx->override_shell;
+    } else if (rctx->override_shell) {
+        return rctx->override_shell;
     }
 
     shell = sss_view_ldb_msg_find_attr_as_string(domain, msg, SYSDB_SHELL,
@@ -141,56 +141,56 @@ nss_get_shell_override(struct ldb_message *msg,
         /* Check whether there is a default shell specified */
         if (domain->default_shell) {
             return domain->default_shell;
-        } else if (nss_ctx->default_shell) {
-            return nss_ctx->default_shell;
+        } else if (rctx->default_shell) {
+            return rctx->default_shell;
         }
 
         return "";
     }
 
-    if (nss_ctx->allowed_shells == NULL && nss_ctx->vetoed_shells == NULL) {
+    if (rctx->allowed_shells == NULL && rctx->vetoed_shells == NULL) {
         return shell;
     }
 
-    if (nss_ctx->vetoed_shells) {
-        for (i = 0; nss_ctx->vetoed_shells[i]; i++) {
-            if (strcmp(nss_ctx->vetoed_shells[i], shell) == 0) {
+    if (rctx->vetoed_shells) {
+        for (i = 0; rctx->vetoed_shells[i]; i++) {
+            if (strcmp(rctx->vetoed_shells[i], shell) == 0) {
                 DEBUG(SSSDBG_FUNC_DATA,
                       "The shell '%s' is vetoed. Using fallback.\n",
                       shell);
-                return nss_ctx->shell_fallback;
+                return rctx->shell_fallback;
             }
         }
     }
 
-    if (nss_ctx->etc_shells) {
-        for (i = 0; nss_ctx->etc_shells[i]; i++) {
-            if (strcmp(shell, nss_ctx->etc_shells[i]) == 0) {
+    if (rctx->etc_shells) {
+        for (i = 0; rctx->etc_shells[i]; i++) {
+            if (strcmp(shell, rctx->etc_shells[i]) == 0) {
                 DEBUG(SSSDBG_TRACE_ALL,
                       "Shell %s found in /etc/shells\n", shell);
                 break;
             }
         }
 
-        if (nss_ctx->etc_shells[i]) {
+        if (rctx->etc_shells[i]) {
             DEBUG(SSSDBG_TRACE_ALL, "Using original shell '%s'\n", shell);
             return shell;
         }
     }
 
-    if (nss_ctx->allowed_shells) {
-        if (strcmp(nss_ctx->allowed_shells[0], "*") == 0) {
+    if (rctx->allowed_shells) {
+        if (strcmp(rctx->allowed_shells[0], "*") == 0) {
             DEBUG(SSSDBG_FUNC_DATA,
                   "The shell '%s' is allowed but does not exist. "
                   "Using fallback\n", shell);
-            return nss_ctx->shell_fallback;
+            return rctx->shell_fallback;
         } else {
-            for (i = 0; nss_ctx->allowed_shells[i]; i++) {
-                if (strcmp(nss_ctx->allowed_shells[i], shell) == 0) {
+            for (i = 0; rctx->allowed_shells[i]; i++) {
+                if (strcmp(rctx->allowed_shells[i], shell) == 0) {
                     DEBUG(SSSDBG_FUNC_DATA,
                           "The shell '%s' is allowed but does not exist. "
                           "Using fallback\n", shell);
-                    return nss_ctx->shell_fallback;
+                    return rctx->shell_fallback;
                 }
             }
         }
@@ -239,7 +239,7 @@ nss_get_pwent(TALLOC_CTX *mem_ctx,
     gecos = sss_view_ldb_msg_find_attr_as_string(domain, msg, SYSDB_GECOS,
                                                  NULL);
     homedir = nss_get_homedir(mem_ctx, nss_ctx, domain, msg, name, upn, uid);
-    shell = nss_get_shell_override(msg, nss_ctx, domain);
+    shell = nss_get_shell_override(msg, nss_ctx->rctx, domain);
 
     /* Convert to sized strings. */
     ret = sized_output_name(mem_ctx, nss_ctx->rctx, name, domain, _name);
diff --git a/src/responder/nss/nsssrv.c b/src/responder/nss/nsssrv.c
index 644e94188c0dabdeef6631814ed5e3326cd7d1a1..d67b9fac8d770d113560e41b259e2d5edd219343 100644
--- a/src/responder/nss/nsssrv.c
+++ b/src/responder/nss/nsssrv.c
@@ -52,9 +52,6 @@
 #define DEFAULT_PWFIELD "*"
 #define DEFAULT_NSS_FD_LIMIT 8192
 
-#define SHELL_REALLOC_INCREMENT 5
-#define SHELL_REALLOC_MAX       50
-
 static int nss_clear_memcache(struct sbus_request *dbus_req, void *data);
 static int nss_clear_netgroup_hash_table(struct sbus_request *dbus_req, void *data);
 
@@ -150,72 +147,6 @@ static int nss_clear_netgroup_hash_table(struct sbus_request *dbus_req, void *da
     return sbus_request_return_and_finish(dbus_req, DBUS_TYPE_INVALID);
 }
 
-static errno_t nss_get_etc_shells(TALLOC_CTX *mem_ctx, char ***_shells)
-{
-    int i = 0;
-    char *sh;
-    char **shells = NULL;
-    TALLOC_CTX *tmp_ctx;
-    errno_t ret;
-    int size;
-
-    tmp_ctx = talloc_new(NULL);
-    if (!tmp_ctx) return ENOMEM;
-
-    shells = talloc_array(tmp_ctx, char *, SHELL_REALLOC_INCREMENT);
-    if (!shells) {
-        ret = ENOMEM;
-        goto done;
-    }
-    size = SHELL_REALLOC_INCREMENT;
-
-    setusershell();
-    while ((sh = getusershell())) {
-        shells[i] = talloc_strdup(shells, sh);
-        if (!shells[i]) {
-            endusershell();
-            ret = ENOMEM;
-            goto done;
-        }
-        DEBUG(SSSDBG_TRACE_FUNC, "Found shell %s in /etc/shells\n", shells[i]);
-        i++;
-
-        if (i == size) {
-            size += SHELL_REALLOC_INCREMENT;
-            if (size > SHELL_REALLOC_MAX) {
-                DEBUG(SSSDBG_FATAL_FAILURE,
-                      "Reached maximum number of shells [%d]. "
-                          "Users may be denied access. "
-                          "Please check /etc/shells for sanity\n",
-                          SHELL_REALLOC_MAX);
-                break;
-            }
-            shells = talloc_realloc(NULL, shells, char *,
-                                    size);
-            if (!shells) {
-                ret = ENOMEM;
-                goto done;
-            }
-        }
-    }
-    endusershell();
-
-    if (i + 1 < size) {
-        shells = talloc_realloc(NULL, shells, char *, i + 1);
-        if (!shells) {
-            ret = ENOMEM;
-            goto done;
-        }
-    }
-    shells[i] = NULL;
-
-    *_shells = talloc_move(mem_ctx, &shells);
-    ret = EOK;
-done:
-    talloc_zfree(tmp_ctx);
-    return ret;
-}
-
 static int nss_get_config(struct nss_ctx *nctx,
                           struct confdb_ctx *cdb)
 {
@@ -264,36 +195,6 @@ static int nss_get_config(struct nss_ctx *nctx,
                             &nctx->fallback_homedir);
     if (ret != EOK) goto done;
 
-    ret = confdb_get_string(cdb, nctx, CONFDB_NSS_CONF_ENTRY,
-                            CONFDB_NSS_OVERRIDE_SHELL, NULL,
-                            &nctx->override_shell);
-    if (ret != EOK && ret != ENOENT) goto done;
-
-    ret = confdb_get_string_as_list(cdb, nctx, CONFDB_NSS_CONF_ENTRY,
-                                    CONFDB_NSS_ALLOWED_SHELL,
-                                    &nctx->allowed_shells);
-    if (ret != EOK && ret != ENOENT) goto done;
-
-    ret = confdb_get_string_as_list(cdb, nctx, CONFDB_NSS_CONF_ENTRY,
-                                    CONFDB_NSS_VETOED_SHELL,
-                                    &nctx->vetoed_shells);
-    if (ret != EOK && ret != ENOENT) goto done;
-
-    ret = nss_get_etc_shells(nctx, &nctx->etc_shells);
-    if (ret != EOK) goto done;
-
-    ret = confdb_get_string(cdb, nctx, CONFDB_NSS_CONF_ENTRY,
-                            CONFDB_NSS_SHELL_FALLBACK,
-                            CONFDB_DEFAULT_SHELL_FALLBACK,
-                            &nctx->shell_fallback);
-    if (ret != EOK) goto done;
-
-    ret = confdb_get_string(cdb, nctx, CONFDB_NSS_CONF_ENTRY,
-                            CONFDB_NSS_DEFAULT_SHELL,
-                            NULL,
-                            &nctx->default_shell);
-    if (ret != EOK) goto done;
-
     ret = confdb_get_string(cdb, nctx, CONFDB_NSS_CONF_ENTRY,
                             CONFDB_NSS_HOMEDIR_SUBSTRING,
                             CONFDB_DEFAULT_HOMEDIR_SUBSTRING,
-- 
2.14.1