summaryrefslogtreecommitdiff
path: root/src/responder
diff options
context:
space:
mode:
authorJakub Hrozek <jhrozek@redhat.com>2011-05-17 16:49:19 +0200
committerStephen Gallagher <sgallagh@redhat.com>2011-05-20 05:49:25 -0400
commit068dbee9ca7bf5b37330eff91c94ae10f288d09f (patch)
treea11f08234e2b6043aa13826d59d999550f9da980 /src/responder
parentd9d716b547d256c03df97b0ff8282349a0f365ad (diff)
downloadsssd-068dbee9ca7bf5b37330eff91c94ae10f288d09f.tar.gz
sssd-068dbee9ca7bf5b37330eff91c94ae10f288d09f.tar.bz2
sssd-068dbee9ca7bf5b37330eff91c94ae10f288d09f.zip
Add new options to override shell value
https://fedorahosted.org/sssd/ticket/742
Diffstat (limited to 'src/responder')
-rw-r--r--src/responder/nss/nsssrv.c82
-rw-r--r--src/responder/nss/nsssrv.h3
-rw-r--r--src/responder/nss/nsssrv_cmd.c39
3 files changed, 123 insertions, 1 deletions
diff --git a/src/responder/nss/nsssrv.c b/src/responder/nss/nsssrv.c
index a5323bd7..b9d548e4 100644
--- a/src/responder/nss/nsssrv.c
+++ b/src/responder/nss/nsssrv.c
@@ -48,6 +48,9 @@
#define DEFAULT_PWFIELD "*"
+#define SHELL_REALLOC_INCREMENT 5
+#define SHELL_REALLOC_MAX 50
+
struct sbus_method monitor_nss_methods[] = {
{ MON_CLI_METHOD_PING, monitor_common_pong },
{ MON_CLI_METHOD_RES_INIT, monitor_common_res_init },
@@ -63,6 +66,71 @@ struct sbus_interface monitor_nss_interface = {
NULL
};
+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(6, ("Found shell %s in /etc/shells\n", shells[i]));
+ i++;
+
+ if (i == size) {
+ size += SHELL_REALLOC_INCREMENT;
+ if (size > SHELL_REALLOC_MAX) {
+ DEBUG(0, ("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 resp_ctx *rctx,
struct confdb_ctx *cdb)
@@ -115,6 +183,20 @@ static int nss_get_config(struct nss_ctx *nctx,
&nctx->override_homedir);
if (ret != EOK) 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 = 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 = 0;
done:
talloc_free(tmpctx);
diff --git a/src/responder/nss/nsssrv.h b/src/responder/nss/nsssrv.h
index e3e774f9..f9aff566 100644
--- a/src/responder/nss/nsssrv.h
+++ b/src/responder/nss/nsssrv.h
@@ -59,6 +59,9 @@ struct nss_ctx {
char *pwfield;
char *override_homedir;
+ char **allowed_shells;
+ char **etc_shells;
+ char *shell_fallback;
};
struct nss_packet;
diff --git a/src/responder/nss/nsssrv_cmd.c b/src/responder/nss/nsssrv_cmd.c
index 4386da71..e698b5ec 100644
--- a/src/responder/nss/nsssrv_cmd.c
+++ b/src/responder/nss/nsssrv_cmd.c
@@ -305,6 +305,43 @@ static const char *get_homedir_override(TALLOC_CTX *mem_ctx,
ldb_msg_find_attr_as_string(msg, SYSDB_HOMEDIR, NULL));
}
+static const char *get_shell_override(TALLOC_CTX *mem_ctx,
+ struct ldb_message *msg,
+ struct nss_ctx *nctx)
+{
+ const char *user_shell;
+ int i;
+
+ user_shell = ldb_msg_find_attr_as_string(msg, SYSDB_SHELL, NULL);
+ if (!user_shell) return NULL;
+ if (!nctx->allowed_shells) return talloc_strdup(mem_ctx, user_shell);
+
+ for (i=0; nctx->etc_shells[i]; i++) {
+ if (strcmp(user_shell, nctx->etc_shells[i]) == 0) {
+ DEBUG(9, ("Shell %s found in /etc/shells\n",
+ nctx->etc_shells[i]));
+ break;
+ }
+ }
+
+ if (nctx->etc_shells[i]) {
+ DEBUG(9, ("Using original shell '%s'\n", user_shell));
+ return talloc_strdup(mem_ctx, user_shell);
+ }
+
+ for (i=0; nctx->allowed_shells[i]; i++) {
+ if (strcmp(nctx->allowed_shells[i], user_shell) == 0) {
+ DEBUG(5, ("The shell '%s' is allowed but does not exist. "
+ "Using fallback\n", user_shell));
+ return talloc_strdup(mem_ctx, nctx->shell_fallback);
+ }
+ }
+
+ DEBUG(5, ("The shell '%s' is not allowed and does not exist.\n",
+ user_shell));
+ return talloc_strdup(mem_ctx, NOLOGIN_SHELL);
+}
+
static int fill_pwent(struct sss_packet *packet,
struct sss_domain_info *dom,
struct nss_ctx *nctx,
@@ -373,7 +410,7 @@ static int fill_pwent(struct sss_packet *packet,
gecos = ldb_msg_find_attr_as_string(msg, SYSDB_GECOS, NULL);
homedir = get_homedir_override(tmp_ctx, msg, nctx, dom, name, uid);
- shell = ldb_msg_find_attr_as_string(msg, SYSDB_SHELL, NULL);
+ shell = get_shell_override(tmp_ctx, msg, nctx);
if (!gecos) gecos = "";
if (!homedir) homedir = "/";