[SSSD] [PATCH] New option code for krb5 and ipa auth
Sumit Bose
sbose at redhat.com
Wed Oct 21 18:15:18 UTC 2009
On Tue, Oct 20, 2009 at 07:20:51PM -0400, Simo Sorce wrote:
>
> On Tue, 2009-10-20 at 14:24 +0200, Sumit Bose wrote:
> > + dummy = dp_opt_get_cstring(opts, KRB5_CHANGEPW_PRINC);
> > + if (strchr(dummy, '@') == NULL) {
> > + value = talloc_asprintf(opts, "%s@%s", dummy, realm);
> > + if (value == NULL) {
> > + DEBUG(7, ("talloc_asprintf failed.\n"));
> > + return ENOMEM;
> > + }
>
> Same here too.
> Please always check what you get back.
>
> Simo.
>
ok, I've added checks where needed. New patches are attached.
bye,
Sumit
-------------- next part --------------
>From 0a2a6e9d52d1e90ff62876bcb479b0ad602ef931 Mon Sep 17 00:00:00 2001
From: Sumit Bose <sbose at redhat.com>
Date: Tue, 20 Oct 2009 10:49:40 +0200
Subject: [PATCH 1/3] update krb5 option handling to new option scheme
---
server/Makefile.am | 11 ++-
server/providers/krb5/krb5_auth.c | 62 +++++++++-----
server/providers/krb5/krb5_auth.h | 8 +--
server/providers/krb5/krb5_child.c | 41 +++++++++-
server/providers/krb5/krb5_common.c | 155 +++++++++++++++++++++++++++++++++++
server/providers/krb5/krb5_common.h | 20 +++++
server/providers/krb5/krb5_init.c | 86 +------------------
server/providers/krb5/krb5_utils.c | 26 ++++---
server/tests/krb5_utils-tests.c | 16 +++-
9 files changed, 294 insertions(+), 131 deletions(-)
create mode 100644 server/providers/krb5/krb5_common.c
diff --git a/server/Makefile.am b/server/Makefile.am
index 81f438d..480d57d 100644
--- a/server/Makefile.am
+++ b/server/Makefile.am
@@ -388,14 +388,16 @@ strtonum_tests_LDADD = \
$(CHECK_LIBS)
krb5_utils_tests_SOURCES = \
- $(SSSD_DEBUG_OBJ) \
tests/krb5_utils-tests.c \
- providers/krb5/krb5_utils.c
+ providers/krb5/krb5_utils.c \
+ providers/krb5/krb5_common.c \
+ providers/data_provider_opts.c \
+ $(SSSD_UTIL_OBJ)
krb5_utils_tests_CFLAGS = \
$(CHECK_CFLAGS)
krb5_utils_tests_LDADD = \
- $(CHECK_LIBS) \
- $(TALLOC_LIBS)
+ $(SSSD_LIBS)\
+ $(CHECK_LIBS)
check_and_open_tests_SOURCES = \
$(SSSD_DEBUG_OBJ) \
@@ -461,6 +463,7 @@ libsss_proxy_la_LDFLAGS = \
libsss_krb5_la_SOURCES = \
providers/krb5/krb5_utils.c \
providers/krb5/krb5_auth.c \
+ providers/krb5/krb5_common.c \
providers/krb5/krb5_init.c
libsss_krb5_la_CFLAGS = \
$(AM_CFLAGS) \
diff --git a/server/providers/krb5/krb5_auth.c b/server/providers/krb5/krb5_auth.c
index 1e689d9..1d699a8 100644
--- a/server/providers/krb5/krb5_auth.c
+++ b/server/providers/krb5/krb5_auth.c
@@ -210,7 +210,10 @@ static errno_t activate_child_timeout_handler(struct krb5child_req *kr)
struct timeval tv;
tv = tevent_timeval_current();
- tv = tevent_timeval_add(&tv, kr->krb5_ctx->auth_timeout, 0);
+ tv = tevent_timeval_add(&tv,
+ dp_opt_get_int(kr->krb5_ctx->opts,
+ KRB5_AUTH_TIMEOUT),
+ 0);
kr->timeout_handler = tevent_add_timer(kr->req->be_ctx->ev, kr, tv,
krb5_child_timeout, kr);
if (kr->timeout_handler == NULL) {
@@ -278,7 +281,10 @@ static errno_t krb5_setup(struct be_req *req, struct krb5child_req **krb5_req,
kr->krb5_ctx = krb5_ctx;
kr->homedir = homedir;
- kr->ccname = expand_ccname_template(kr, kr, krb5_ctx->ccname_template);
+ kr->ccname = expand_ccname_template(kr, kr,
+ dp_opt_get_cstring(krb5_ctx->opts,
+ KRB5_CCNAME_TMPL)
+ );
if (kr->ccname == NULL) {
DEBUG(1, ("expand_ccname_template failed.\n"));
err = EINVAL;
@@ -736,6 +742,7 @@ static void get_user_upn_done(void *pvt, int err, struct ldb_result *res)
struct pam_data *pd;
int pam_status=PAM_SYSTEM_ERR;
const char *homedir = NULL;
+ const char *dummy;
pd = talloc_get_type(be_req->req_data, struct pam_data);
krb5_ctx = get_krb5_ctx(be_req);
@@ -760,9 +767,9 @@ static void get_user_upn_done(void *pvt, int err, struct ldb_result *res)
pd->upn = ldb_msg_find_attr_as_string(res->msgs[0], SYSDB_UPN, NULL);
if (pd->upn == NULL) {
/* NOTE: this is a hack, works only in some environments */
- if (krb5_ctx->realm != NULL) {
- pd->upn = talloc_asprintf(be_req, "%s@%s", pd->user,
- krb5_ctx->realm);
+ dummy = dp_opt_get_cstring(krb5_ctx->opts, KRB5_REALM);
+ if (dummy != NULL) {
+ pd->upn = talloc_asprintf(be_req, "%s@%s", pd->user, dummy);
if (pd->upn == NULL) {
DEBUG(1, ("failed to build simple upn.\n"));
}
@@ -829,6 +836,7 @@ static void krb5_pam_handler_done(struct tevent_req *req)
char *password = NULL;
char *env = NULL;
int dp_err = DP_ERR_FATAL;
+ const char *dummy;
pd->pam_status = PAM_SYSTEM_ERR;
talloc_free(kr);
@@ -877,26 +885,34 @@ static void krb5_pam_handler_done(struct tevent_req *req)
}
if (*msg_status == PAM_SUCCESS && pd->cmd == SSS_PAM_AUTHENTICATE) {
- env = talloc_asprintf(pd, "%s=%s", SSSD_KRB5_REALM, krb5_ctx->realm);
- if (env == NULL) {
- DEBUG(1, ("talloc_asprintf failed.\n"));
- goto done;
- }
- ret = pam_add_response(pd, PAM_ENV_ITEM, strlen(env)+1, (uint8_t *) env);
- if (ret != EOK) {
- DEBUG(1, ("pam_add_response failed.\n"));
- goto done;
+ dummy = dp_opt_get_cstring(krb5_ctx->opts, KRB5_REALM);
+ if (dummy != NULL) {
+ env = talloc_asprintf(pd, "%s=%s", SSSD_KRB5_REALM, dummy);
+ if (env == NULL) {
+ DEBUG(1, ("talloc_asprintf failed.\n"));
+ goto done;
+ }
+ ret = pam_add_response(pd, PAM_ENV_ITEM, strlen(env)+1,
+ (uint8_t *) env);
+ if (ret != EOK) {
+ DEBUG(1, ("pam_add_response failed.\n"));
+ goto done;
+ }
}
- env = talloc_asprintf(pd, "%s=%s", SSSD_KRB5_KDC, krb5_ctx->kdcip);
- if (env == NULL) {
- DEBUG(1, ("talloc_asprintf failed.\n"));
- goto done;
- }
- ret = pam_add_response(pd, PAM_ENV_ITEM, strlen(env)+1, (uint8_t *) env);
- if (ret != EOK) {
- DEBUG(1, ("pam_add_response failed.\n"));
- goto done;
+ dummy = dp_opt_get_cstring(krb5_ctx->opts, KRB5_KDC);
+ if (dummy != NULL) {
+ env = talloc_asprintf(pd, "%s=%s", SSSD_KRB5_KDC, dummy);
+ if (env == NULL) {
+ DEBUG(1, ("talloc_asprintf failed.\n"));
+ goto done;
+ }
+ ret = pam_add_response(pd, PAM_ENV_ITEM, strlen(env)+1,
+ (uint8_t *) env);
+ if (ret != EOK) {
+ DEBUG(1, ("pam_add_response failed.\n"));
+ goto done;
+ }
}
}
diff --git a/server/providers/krb5/krb5_auth.h b/server/providers/krb5/krb5_auth.h
index 9e9142c..95647e3 100644
--- a/server/providers/krb5/krb5_auth.h
+++ b/server/providers/krb5/krb5_auth.h
@@ -74,13 +74,7 @@ struct krb5_ctx {
char* k4_cache_name;
action_type action;
-
- char *kdcip;
- char *realm;
- char *changepw_principle;
- char *ccache_dir;
- char *ccname_template;
- int auth_timeout;
+ struct dp_option *opts;
int child_debug_fd;
};
diff --git a/server/providers/krb5/krb5_child.c b/server/providers/krb5/krb5_child.c
index 4e681b9..e67ff88 100644
--- a/server/providers/krb5/krb5_child.c
+++ b/server/providers/krb5/krb5_child.c
@@ -36,6 +36,41 @@
#define IN_BUF_SIZE 512
+struct krb5_child_ctx {
+ /* opts taken from kinit */
+ /* in seconds */
+ krb5_deltat starttime;
+ krb5_deltat lifetime;
+ krb5_deltat rlife;
+
+ int forwardable;
+ int proxiable;
+ int addresses;
+
+ int not_forwardable;
+ int not_proxiable;
+ int no_addresses;
+
+ int verbose;
+
+ char* principal_name;
+ char* service_name;
+ char* keytab_name;
+ char* k5_cache_name;
+ char* k4_cache_name;
+
+ action_type action;
+
+ char *kdcip;
+ char *realm;
+ char *changepw_principle;
+ char *ccache_dir;
+ char *ccname_template;
+ int auth_timeout;
+
+ int child_debug_fd;
+};
+
struct krb5_req {
krb5_context ctx;
krb5_ccache cc;
@@ -49,7 +84,7 @@ struct krb5_req {
struct be_req *req;
struct pam_data *pd;
- struct krb5_ctx *krb5_ctx;
+ struct krb5_child_ctx *krb5_ctx;
errno_t (*child_req)(int fd, struct krb5_req *kr);
char *ccname;
@@ -522,7 +557,7 @@ static int krb5_cleanup(void *ptr)
krb5_free_context(kr->ctx);
if (kr->krb5_ctx != NULL) {
- memset(kr->krb5_ctx, 0, sizeof(struct krb5_ctx));
+ memset(kr->krb5_ctx, 0, sizeof(struct krb5_child_ctx));
}
memset(kr, 0, sizeof(struct krb5_req));
@@ -543,7 +578,7 @@ static int krb5_setup(struct pam_data *pd, const char *user_princ_str,
}
talloc_set_destructor((TALLOC_CTX *) kr, krb5_cleanup);
- kr->krb5_ctx = talloc_zero(kr, struct krb5_ctx);
+ kr->krb5_ctx = talloc_zero(kr, struct krb5_child_ctx);
if (kr->krb5_ctx == NULL) {
DEBUG(1, ("talloc failed.\n"));
kerr = ENOMEM;
diff --git a/server/providers/krb5/krb5_common.c b/server/providers/krb5/krb5_common.c
new file mode 100644
index 0000000..a9d00ef
--- /dev/null
+++ b/server/providers/krb5/krb5_common.c
@@ -0,0 +1,155 @@
+/*
+ SSSD
+
+ Kerberos Provider Common Functions
+
+ Authors:
+ Sumit Bose <sbose at redhat.com>
+
+ Copyright (C) 2008-2009 Red Hat
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+
+#include "providers/dp_backend.h"
+#include "providers/krb5/krb5_common.h"
+
+struct dp_option default_krb5_opts[] = {
+ { "krb5_kdcip", DP_OPT_STRING, NULL_STRING, NULL_STRING },
+ { "krb5_realm", DP_OPT_STRING, NULL_STRING, NULL_STRING },
+ { "krb5_ccachedir", DP_OPT_STRING, { "/tmp" }, NULL_STRING },
+ { "krb5_ccname_tmpl", DP_OPT_STRING, { "FILE:%d/krb5cc_%U_XXXXXX" }, NULL_STRING},
+ { "krb5_changepw_principle", DP_OPT_STRING, { "kadmin/changepw" }, NULL_STRING },
+ { "krb5_auth_timeout", DP_OPT_NUMBER, { .number = 15 }, NULL_NUMBER },
+};
+
+errno_t check_and_export_options(struct dp_option *opts,
+ struct sss_domain_info *dom)
+{
+ int ret;
+ char *value;
+ const char *realm;
+ const char *dummy;
+ struct stat stat_buf;
+
+ dummy = dp_opt_get_cstring(opts, KRB5_KDC);
+ if (dummy == NULL) {
+ DEBUG(1, ("No KDC configured, "
+ "using kerberos defaults from /etc/krb5.conf"));
+ } else {
+ ret = setenv(SSSD_KRB5_KDC, dummy, 1);
+ if (ret != EOK) {
+ DEBUG(2, ("setenv %s failed, authentication might fail.\n",
+ SSSD_KRB5_KDC));
+ }
+ }
+
+ realm = dp_opt_get_cstring(opts, KRB5_REALM);
+ if (realm == NULL) {
+ ret = dp_opt_set_string(opts, KRB5_REALM, dom->name);
+ if (ret != EOK) {
+ DEBUG(1, ("dp_opt_set_string failed.\n"));
+ return ret;
+ }
+ realm = dom->name;
+ }
+ ret = setenv(SSSD_KRB5_REALM, realm, 1);
+ if (ret != EOK) {
+ DEBUG(2, ("setenv %s failed, authentication might fail.\n",
+ SSSD_KRB5_REALM));
+ }
+
+ dummy = dp_opt_get_cstring(opts, KRB5_CCACHEDIR);
+ ret = lstat(dummy, &stat_buf);
+ if (ret != EOK) {
+ DEBUG(1, ("lstat for [%s] failed: [%d][%s].\n", dummy, errno,
+ strerror(errno)));
+ return ret;
+ }
+ if ( !S_ISDIR(stat_buf.st_mode) ) {
+ DEBUG(1, ("Value of krb5ccache_dir [%s] is not a directory.\n", dummy));
+ return EINVAL;
+ }
+
+ dummy = dp_opt_get_cstring(opts, KRB5_CCNAME_TMPL);
+ if (dummy == NULL) {
+ DEBUG(1, ("Missing credential cache name template.\n"));
+ return EINVAL;
+ }
+ if (dummy[0] != '/' && strncmp(dummy, "FILE:", 5) != 0) {
+ DEBUG(1, ("Currently only file based credential caches are supported "
+ "and krb5ccname_template must start with '/' or 'FILE:'\n"));
+ return EINVAL;
+ }
+
+ dummy = dp_opt_get_cstring(opts, KRB5_CHANGEPW_PRINC);
+ if (dummy == NULL) {
+ DEBUG(1, ("Missing change password principle.\n"));
+ return EINVAL;
+ }
+ if (strchr(dummy, '@') == NULL) {
+ value = talloc_asprintf(opts, "%s@%s", dummy, realm);
+ if (value == NULL) {
+ DEBUG(7, ("talloc_asprintf failed.\n"));
+ return ENOMEM;
+ }
+ ret = dp_opt_set_string(opts, KRB5_CHANGEPW_PRINC, value);
+ if (ret != EOK) {
+ DEBUG(1, ("dp_opt_set_string failed.\n"));
+ return ret;
+ }
+ dummy = value;
+ }
+
+ ret = setenv(SSSD_KRB5_CHANGEPW_PRINCIPLE, dummy, 1);
+ if (ret != EOK) {
+ DEBUG(2, ("setenv %s failed, password change might fail.\n",
+ SSSD_KRB5_CHANGEPW_PRINCIPLE));
+ }
+
+ return EOK;
+}
+
+errno_t krb5_get_options(TALLOC_CTX *memctx, struct confdb_ctx *cdb,
+ const char *conf_path, struct dp_option **_opts)
+{
+ int ret;
+ struct dp_option *opts;
+
+ opts = talloc_zero(memctx, struct dp_option);
+ if (opts == NULL) {
+ DEBUG(1, ("talloc_zero failed.\n"));
+ return ENOMEM;
+ }
+
+ ret = dp_get_options(opts, cdb, conf_path, default_krb5_opts,
+ KRB5_OPTS, &opts);
+ if (ret != EOK) {
+ DEBUG(1, ("dp_get_options failed.\n"));
+ goto done;
+ }
+
+ *_opts = opts;
+ ret = EOK;
+
+done:
+ if (ret != EOK) {
+ talloc_zfree(opts);
+ }
+
+ return ret;
+}
diff --git a/server/providers/krb5/krb5_common.h b/server/providers/krb5/krb5_common.h
index 64e4360..5d784a5 100644
--- a/server/providers/krb5/krb5_common.h
+++ b/server/providers/krb5/krb5_common.h
@@ -34,7 +34,27 @@
#include <krb5.h>
#endif
+#include "providers/dp_backend.h"
+#include "util/util.h"
+
#define SSSD_KRB5_KDC "SSSD_KRB5_KDC"
#define SSSD_KRB5_REALM "SSSD_KRB5_REALM"
+#define SSSD_KRB5_CHANGEPW_PRINCIPLE "SSSD_KRB5_CHANGEPW_PRINCIPLE"
+
+enum krb5_opts {
+ KRB5_KDC = 0,
+ KRB5_REALM,
+ KRB5_CCACHEDIR,
+ KRB5_CCNAME_TMPL,
+ KRB5_CHANGEPW_PRINC,
+ KRB5_AUTH_TIMEOUT,
+
+ KRB5_OPTS
+};
+
+errno_t check_and_export_options(struct dp_option *opts,
+ struct sss_domain_info *dom);
+errno_t krb5_get_options(TALLOC_CTX *memctx, struct confdb_ctx *cdb,
+ const char *conf_path, struct dp_option **_opts);
#endif /* __KRB5_COMMON_H__ */
diff --git a/server/providers/krb5/krb5_init.c b/server/providers/krb5/krb5_init.c
index 676d078..26cf5e3 100644
--- a/server/providers/krb5/krb5_init.c
+++ b/server/providers/krb5/krb5_init.c
@@ -27,6 +27,7 @@
#include <fcntl.h>
#include <sys/stat.h>
#include "providers/krb5/krb5_auth.h"
+#include "providers/krb5/krb5_common.h"
struct bet_ops krb5_auth_ops = {
.handler = krb5_pam_handler,
@@ -43,11 +44,8 @@ int sssm_krb5_auth_init(struct be_ctx *bectx,
void **pvt_auth_data)
{
struct krb5_ctx *ctx = NULL;
- char *value = NULL;
- int int_value;
int ret;
struct tevent_signal *sige;
- struct stat stat_buf;
unsigned v;
FILE *debug_filep;
@@ -59,91 +57,17 @@ int sssm_krb5_auth_init(struct be_ctx *bectx,
ctx->action = INIT_PW;
- ret = confdb_get_string(bectx->cdb, ctx, bectx->conf_path,
- CONFDB_KRB5_KDCIP, NULL, &value);
- if (ret != EOK) goto fail;
- if (value == NULL) {
- DEBUG(2, ("Missing krb5KDCIP, authentication might fail.\n"));
- } else {
- ret = setenv(SSSD_KRB5_KDC, value, 1);
- if (ret != EOK) {
- DEBUG(2, ("setenv %s failed, authentication might fail.\n",
- SSSD_KRB5_KDC));
- }
- }
- ctx->kdcip = value;
-
- ret = confdb_get_string(bectx->cdb, ctx, bectx->conf_path,
- CONFDB_KRB5_REALM, NULL, &value);
- if (ret != EOK) goto fail;
- if (value == NULL) {
- DEBUG(4, ("Missing krb5REALM authentication might fail.\n"));
- } else {
- ret = setenv(SSSD_KRB5_REALM, value, 1);
- if (ret != EOK) {
- DEBUG(2, ("setenv %s failed, authentication might fail.\n",
- SSSD_KRB5_REALM));
- }
- }
- ctx->realm = value;
-
- ret = confdb_get_string(bectx->cdb, ctx, bectx->conf_path,
- CONFDB_KRB5_CCACHEDIR, "/tmp", &value);
- if (ret != EOK) goto fail;
- ret = lstat(value, &stat_buf);
+ ret = krb5_get_options(ctx, bectx->cdb, bectx->conf_path, &ctx->opts);
if (ret != EOK) {
- DEBUG(1, ("lstat for [%s] failed: [%d][%s].\n", value, errno,
- strerror(errno)));
- goto fail;
- }
- if ( !S_ISDIR(stat_buf.st_mode) ) {
- DEBUG(1, ("Value of krb5ccache_dir [%s] is not a directory.\n", value));
+ DEBUG(1, ("krb5_get_options failed.\n"));
goto fail;
}
- ctx->ccache_dir = value;
-
- ret = confdb_get_string(bectx->cdb, ctx, bectx->conf_path,
- CONFDB_KRB5_CCNAME_TMPL,
- "FILE:%d/krb5cc_%U_XXXXXX",
- &value);
- if (ret != EOK) goto fail;
- if (value[0] != '/' && strncmp(value, "FILE:", 5) != 0) {
- DEBUG(1, ("Currently only file based credential caches are supported "
- "and krb5ccname_template must start with '/' or 'FILE:'\n"));
- goto fail;
- }
- ctx->ccname_template = value;
-
- ret = confdb_get_string(bectx->cdb, ctx, bectx->conf_path,
- CONFDB_KRB5_CHANGEPW_PRINC,
- "kadmin/changepw",
- &value);
- if (ret != EOK) goto fail;
- if (strchr(value, '@') == NULL) {
- value = talloc_asprintf_append(value, "@%s", ctx->realm);
- if (value == NULL) {
- DEBUG(7, ("talloc_asprintf_append failed.\n"));
- goto fail;
- }
- }
- ctx->changepw_principle = value;
- ret = setenv(SSSD_KRB5_CHANGEPW_PRINCIPLE, ctx->changepw_principle, 1);
+ ret = check_and_export_options(ctx->opts, bectx->domain);
if (ret != EOK) {
- DEBUG(2, ("setenv %s failed, password change might fail.\n",
- SSSD_KRB5_CHANGEPW_PRINCIPLE));
- }
-
- ret = confdb_get_int(bectx->cdb, ctx, bectx->conf_path,
- CONFDB_KRB5_AUTH_TIMEOUT, 15, &int_value);
- if (ret != EOK) goto fail;
- if (int_value <= 0) {
- DEBUG(4, ("krb5auth_timeout has to be a positive value.\n"));
+ DEBUG(1, ("check_and_export_options failed.\n"));
goto fail;
}
- ctx->auth_timeout = int_value;
-
-/* TODO: set options */
sige = tevent_add_signal(bectx->ev, ctx, SIGCHLD, SA_SIGINFO,
krb5_child_sig_handler, NULL);
diff --git a/server/providers/krb5/krb5_utils.c b/server/providers/krb5/krb5_utils.c
index 68254ab..489030a 100644
--- a/server/providers/krb5/krb5_utils.c
+++ b/server/providers/krb5/krb5_utils.c
@@ -35,6 +35,12 @@ char *expand_ccname_template(TALLOC_CTX *mem_ctx, struct krb5child_req *kr,
char *p;
char *n;
char *result = NULL;
+ const char *dummy;
+
+ if (template == NULL) {
+ DEBUG(1, ("Missing template.\n"));
+ return NULL;
+ }
copy = talloc_strdup(mem_ctx, template);
if (copy == NULL) {
@@ -78,7 +84,7 @@ char *expand_ccname_template(TALLOC_CTX *mem_ctx, struct krb5child_req *kr,
break;
case 'p':
if (kr->pd->upn == NULL) {
- DEBUG(1, ("Cannot expand user principal name template "
+ DEBUG(1, ("Cannot expand user principle name template "
"because upn is empty.\n"));
return NULL;
}
@@ -88,13 +94,12 @@ char *expand_ccname_template(TALLOC_CTX *mem_ctx, struct krb5child_req *kr,
result = talloc_asprintf_append(result, "%s%%", p);
break;
case 'r':
- if (kr->krb5_ctx->realm == NULL) {
- DEBUG(1, ("Cannot expand realm template "
- "because value is not available.\n"));
+ dummy = dp_opt_get_string(kr->krb5_ctx->opts, KRB5_REALM);
+ if (dummy == NULL) {
+ DEBUG(1, ("Missing kerberos realm.\n"));
return NULL;
}
- result = talloc_asprintf_append(result, "%s%s", p,
- kr->krb5_ctx->realm);
+ result = talloc_asprintf_append(result, "%s%s", p, dummy);
break;
case 'h':
if (kr->homedir == NULL) {
@@ -105,13 +110,12 @@ char *expand_ccname_template(TALLOC_CTX *mem_ctx, struct krb5child_req *kr,
result = talloc_asprintf_append(result, "%s%s", p, kr->homedir);
break;
case 'd':
- if (kr->krb5_ctx->ccache_dir == NULL) {
- DEBUG(1, ("Cannot expand ccache directory template "
- "because value is not available.\n"));
+ dummy = dp_opt_get_string(kr->krb5_ctx->opts, KRB5_CCACHEDIR);
+ if (dummy == NULL) {
+ DEBUG(1, ("Missing credential cache directory.\n"));
return NULL;
}
- result = talloc_asprintf_append(result, "%s%s", p,
- kr->krb5_ctx->ccache_dir);
+ result = talloc_asprintf_append(result, "%s%s", p, dummy);
break;
case 'P':
if (kr->pd->cli_pid == 0) {
diff --git a/server/tests/krb5_utils-tests.c b/server/tests/krb5_utils-tests.c
index 1ebebe6..aed1c3c 100644
--- a/server/tests/krb5_utils-tests.c
+++ b/server/tests/krb5_utils-tests.c
@@ -38,12 +38,15 @@
#define CCACHE_DIR "/var/tmp"
#define PID "4321"
+extern struct dp_option default_krb5_opts[];
+
TALLOC_CTX *tmp_ctx = NULL;
struct krb5child_req *kr;
void setup_talloc_context(void)
{
int ret;
+ int i;
struct pam_data *pd;
struct krb5_ctx *krb5_ctx;
fail_unless(tmp_ctx == NULL, "Talloc context already initialized.");
@@ -64,8 +67,17 @@ void setup_talloc_context(void)
pd->upn = PRINCIPLE_NAME;
pd->cli_pid = atoi(PID);
- krb5_ctx->realm = REALM;
- krb5_ctx->ccache_dir = CCACHE_DIR;
+ krb5_ctx->opts = talloc_zero_array(tmp_ctx, struct dp_option, KRB5_OPTS);
+ fail_unless(krb5_ctx->opts != NULL, "Cannot created options.");
+ for (i = 0; i < KRB5_OPTS; i++) {
+ krb5_ctx->opts[i].opt_name = default_krb5_opts[i].opt_name;
+ krb5_ctx->opts[i].type = default_krb5_opts[i].type;
+ krb5_ctx->opts[i].def_val = default_krb5_opts[i].def_val;
+ }
+ ret = dp_opt_set_string(krb5_ctx->opts, KRB5_REALM, REALM);
+ fail_unless(ret == EOK, "Failed to set Realm");
+ ret = dp_opt_set_string(krb5_ctx->opts, KRB5_CCACHEDIR, CCACHE_DIR);
+ fail_unless(ret == EOK, "Failed to set Ccache dir");
kr->homedir = HOME_DIRECTORY;
--
1.6.2.5
-------------- next part --------------
>From aa05c255acce57902630c80b7c1fd4c5de86515a Mon Sep 17 00:00:00 2001
From: Sumit Bose <sbose at redhat.com>
Date: Tue, 20 Oct 2009 12:56:26 +0200
Subject: [PATCH 2/3] update ipa auth options to new option scheme
---
server/Makefile.am | 1 +
server/providers/ipa/ipa_common.c | 79 +++++++++++++++++++
server/providers/ipa/ipa_common.h | 7 ++
server/providers/ipa/ipa_init.c | 157 +++++++++++--------------------------
4 files changed, 134 insertions(+), 110 deletions(-)
diff --git a/server/Makefile.am b/server/Makefile.am
index 480d57d..e115058 100644
--- a/server/Makefile.am
+++ b/server/Makefile.am
@@ -484,6 +484,7 @@ libsss_ipa_la_SOURCES = \
providers/ldap/sdap.c \
util/sss_ldap.c \
providers/krb5/krb5_utils.c \
+ providers/krb5/krb5_common.c \
providers/krb5/krb5_auth.c
libsss_ipa_la_CFLAGS = \
$(AM_CFLAGS) \
diff --git a/server/providers/ipa/ipa_common.c b/server/providers/ipa/ipa_common.c
index 799ac2f..6dba10c 100644
--- a/server/providers/ipa/ipa_common.c
+++ b/server/providers/ipa/ipa_common.c
@@ -104,6 +104,15 @@ struct sdap_id_map ipa_group_map[] = {
{ "ldap_group_modify_timestamp", "modifyTimestamp", SYSDB_ORIG_MODSTAMP, NULL }
};
+struct dp_option ipa_def_krb5_opts[] = {
+ { "krb5_kdcip", DP_OPT_STRING, NULL_STRING, NULL_STRING },
+ { "krb5_realm", DP_OPT_STRING, NULL_STRING, NULL_STRING },
+ { "krb5_ccachedir", DP_OPT_STRING, { "/tmp" }, NULL_STRING },
+ { "krb5_ccname_tmpl", DP_OPT_STRING, { "FILE:%d/krb5cc_%U_XXXXXX" }, NULL_STRING},
+ { "krb5_changepw_princ", DP_OPT_STRING, { "kadmin/changepw" }, NULL_STRING },
+ { "krb5_auth_timeout", DP_OPT_NUMBER, { .number = 15 }, NULL_NUMBER },
+};
+
int domain_to_basedn(TALLOC_CTX *memctx, const char *domain, char **basedn)
{
const char *s;
@@ -317,3 +326,73 @@ done:
return ret;
}
+/* the following preprocessor code is used to keep track of
+ * the options in the krb5 module, so that if they change and ipa
+ * is not updated correspondingly this will trigger a build error */
+#if KRB5_OPTS > 6
+#error There are krb5 options not accounted for
+#endif
+
+int ipa_get_auth_options(TALLOC_CTX *memctx,
+ struct confdb_ctx *cdb,
+ const char *conf_path,
+ struct ipa_options *ipa_opts,
+ struct dp_option **_opts)
+{
+ int ret;
+ int i;
+ TALLOC_CTX *tmpctx;
+ struct dp_option *opts;
+ char *value;
+
+ tmpctx = talloc_new(memctx);
+ if (!tmpctx) {
+ return ENOMEM;
+ }
+
+ opts = talloc_zero(memctx, struct dp_option);
+ if (opts == NULL) {
+ ret = ENOMEM;
+ goto done;
+ }
+
+ ret = dp_copy_options(ipa_opts, ipa_def_krb5_opts,
+ KRB5_OPTS, &opts);
+ if (ret != EOK) {
+ goto done;
+ }
+
+ value = dp_opt_get_string(ipa_opts->basic, IPA_SERVER);
+ if (!value) {
+ ret = ENOMEM;
+ goto done;
+ }
+ ret = dp_opt_set_string(opts, KRB5_KDC, value);
+ if (ret != EOK) {
+ goto done;
+ }
+
+
+ value = dp_opt_get_string(ipa_opts->basic, IPA_DOMAIN);
+ if (!value) {
+ ret = ENOMEM;
+ goto done;
+ }
+ for (i = 0; value[i]; i++) {
+ value[i] = toupper(value[i]);
+ }
+ ret = dp_opt_set_string(opts, KRB5_REALM, value);
+ if (ret != EOK) {
+ goto done;
+ }
+
+ *_opts = opts;
+ ret = EOK;
+
+done:
+ talloc_zfree(tmpctx);
+ if (ret != EOK) {
+ talloc_zfree(opts);
+ }
+ return ret;
+}
diff --git a/server/providers/ipa/ipa_common.h b/server/providers/ipa/ipa_common.h
index 80f5294..f7d3ab8 100644
--- a/server/providers/ipa/ipa_common.h
+++ b/server/providers/ipa/ipa_common.h
@@ -25,6 +25,7 @@
#include "util/util.h"
#include "confdb/confdb.h"
#include "providers/ldap/ldap_common.h"
+#include "providers/krb5/krb5_common.h"
enum ipa_basic_opt {
IPA_DOMAIN = 0,
@@ -58,4 +59,10 @@ int ipa_get_id_options(TALLOC_CTX *memctx,
struct ipa_options *ipa_opts,
struct sdap_options **_opts);
+int ipa_get_auth_options(TALLOC_CTX *memctx,
+ struct confdb_ctx *cdb,
+ const char *conf_path,
+ struct ipa_options *ipa_opts,
+ struct dp_option **_opts);
+
#endif /* _IPA_COMMON_H_ */
diff --git a/server/providers/ipa/ipa_init.c b/server/providers/ipa/ipa_init.c
index 9cdcf4b..0c2eb2a 100644
--- a/server/providers/ipa/ipa_init.c
+++ b/server/providers/ipa/ipa_init.c
@@ -25,6 +25,8 @@
#include <sys/types.h>
#include <unistd.h>
#include <sys/stat.h>
+#include <fcntl.h>
+
#include "providers/ipa/ipa_common.h"
#include "providers/krb5/krb5_auth.h"
@@ -100,141 +102,76 @@ done:
int sssm_ipa_auth_init(struct be_ctx *bectx,
struct bet_ops **ops,
- void **pvt_auth_data)
+ void **pvt_data)
{
struct krb5_ctx *ctx = NULL;
- struct tevent_signal *sige;
- struct stat stat_buf;
- char *value = NULL;
- int int_value;
int ret;
+ struct tevent_signal *sige;
+ unsigned v;
+ FILE *debug_filep;
+
+ if (!ipa_options) {
+ ipa_get_options(bectx, bectx->cdb,
+ bectx->conf_path,
+ bectx->domain, &ipa_options);
+ }
+ if (!ipa_options) {
+ return ENOMEM;
+ }
ctx = talloc_zero(bectx, struct krb5_ctx);
if (!ctx) {
- DEBUG(1, ("talloc failed.\n"));
return ENOMEM;
}
- ctx->action = INIT_PW;
-
- ret = confdb_get_string(bectx->cdb, ctx, bectx->conf_path,
- CONFDB_KRB5_KDCIP, NULL, &value);
+ ret = ipa_get_auth_options(ctx, bectx->cdb,
+ bectx->conf_path,
+ ipa_options, &ctx->opts);
if (ret != EOK) {
- goto fail;
+ goto done;
}
- if (value == NULL) {
- DEBUG(2, ("Missing krb5KDCIP, authentication might fail.\n"));
- } else {
- ret = setenv(SSSD_KRB5_KDC, value, 1);
- if (ret != EOK) {
- DEBUG(2, ("setenv %s failed, authentication might fail.\n",
- SSSD_KRB5_KDC));
- }
+ ret = check_and_export_options(ctx->opts, bectx->domain);
+ if (ret != EOK) {
+ DEBUG(1, ("check_and_export_opts failed.\n"));
+ goto done;
}
- ctx->kdcip = value;
- ret = confdb_get_string(bectx->cdb, ctx, bectx->conf_path,
- CONFDB_KRB5_REALM, NULL, &value);
- if (ret != EOK) {
- goto fail;
+ sige = tevent_add_signal(bectx->ev, ctx, SIGCHLD, SA_SIGINFO,
+ krb5_child_sig_handler, NULL);
+ if (sige == NULL) {
+ DEBUG(1, ("tevent_add_signal failed.\n"));
+ ret = ENOMEM;
+ goto done;
}
- if (value == NULL) {
- DEBUG(4, ("Missing krb5REALM authentication might fail.\n"));
- } else {
- ret = setenv(SSSD_KRB5_REALM, value, 1);
+ if (debug_to_file != 0) {
+ ret = open_debug_file_ex("krb5_child", &debug_filep);
if (ret != EOK) {
- DEBUG(2, ("setenv %s failed, authentication might fail.\n",
- SSSD_KRB5_REALM));
+ DEBUG(0, ("Error setting up logging (%d) [%s]\n",
+ ret, strerror(ret)));
+ goto done;
}
- }
- ctx->realm = value;
- ret = confdb_get_string(bectx->cdb, ctx, bectx->conf_path,
- CONFDB_KRB5_CCACHEDIR, "/tmp", &value);
- if (ret != EOK) {
- goto fail;
- }
-
- ret = lstat(value, &stat_buf);
- if (ret != EOK) {
- DEBUG(1, ("lstat for [%s] failed: [%d][%s].\n",
- value, errno, strerror(errno)));
- goto fail;
- }
- if (!S_ISDIR(stat_buf.st_mode)) {
- DEBUG(1, ("Value of krb5ccache_dir [%s] is not a directory.\n",
- value));
- goto fail;
- }
- ctx->ccache_dir = value;
-
- ret = confdb_get_string(bectx->cdb, ctx, bectx->conf_path,
- CONFDB_KRB5_CCNAME_TMPL,
- "FILE:%d/krb5cc_%U_XXXXXX",
- &value);
- if (ret != EOK) {
- goto fail;
- }
-
- if (value[0] != '/' && strncmp(value, "FILE:", 5) != 0) {
- DEBUG(1, ("Currently only file based credential caches are supported "
- "and krb5ccname_template must start with '/' or 'FILE:'\n"));
- goto fail;
- }
- ctx->ccname_template = value;
-
- ret = confdb_get_string(bectx->cdb, ctx, bectx->conf_path,
- CONFDB_KRB5_CHANGEPW_PRINC,
- "kadmin/changepw",
- &value);
- if (ret != EOK) {
- goto fail;
- }
-
- if (strchr(value, '@') == NULL) {
- value = talloc_asprintf_append(value, "@%s", ctx->realm);
- if (value == NULL) {
- DEBUG(7, ("talloc_asprintf_append failed.\n"));
- goto fail;
+ ctx->child_debug_fd = fileno(debug_filep);
+ if (ctx->child_debug_fd == -1) {
+ DEBUG(0, ("fileno failed [%d][%s]\n", errno, strerror(errno)));
+ ret = errno;
+ goto done;
}
- }
- ctx->changepw_principle = value;
-
- ret = setenv(SSSD_KRB5_CHANGEPW_PRINCIPLE, ctx->changepw_principle, 1);
- if (ret != EOK) {
- DEBUG(2, ("setenv %s failed, password change might fail.\n",
- SSSD_KRB5_CHANGEPW_PRINCIPLE));
- }
-
- ret = confdb_get_int(bectx->cdb, ctx, bectx->conf_path,
- CONFDB_KRB5_AUTH_TIMEOUT, 15, &int_value);
- if (ret != EOK) {
- goto fail;
- }
- if (int_value <= 0) {
- DEBUG(4, ("krb5auth_timeout has to be a positive value.\n"));
- goto fail;
- }
- ctx->auth_timeout = int_value;
-
-/* TODO: set options */
- sige = tevent_add_signal(bectx->ev, ctx, SIGCHLD, SA_SIGINFO,
- krb5_child_sig_handler, NULL);
- if (sige == NULL) {
- DEBUG(1, ("tevent_add_signal failed.\n"));
- ret = ENOMEM;
- goto fail;
+ v = fcntl(ctx->child_debug_fd, F_GETFD, 0);
+ fcntl(ctx->child_debug_fd, F_SETFD, v & ~FD_CLOEXEC);
}
*ops = &ipa_auth_ops;
- *pvt_auth_data = ctx;
- return EOK;
+ *pvt_data = ctx;
+ ret = EOK;
-fail:
- talloc_free(ctx);
+done:
+ if (ret != EOK) {
+ talloc_free(ctx);
+ }
return ret;
}
--
1.6.2.5
-------------- next part --------------
>From 74a30ed29a11459f191f2149d8fbce4718b76cc5 Mon Sep 17 00:00:00 2001
From: Sumit Bose <sbose at redhat.com>
Date: Tue, 20 Oct 2009 13:10:01 +0200
Subject: [PATCH 3/3] fix a compiler warning about redefinition of DEBUG
---
server/krb5_plugin/sssd_krb5_locator_plugin.c | 34 ++++++++++++++-----------
1 files changed, 19 insertions(+), 15 deletions(-)
diff --git a/server/krb5_plugin/sssd_krb5_locator_plugin.c b/server/krb5_plugin/sssd_krb5_locator_plugin.c
index fc5f426..a30586c 100644
--- a/server/krb5_plugin/sssd_krb5_locator_plugin.c
+++ b/server/krb5_plugin/sssd_krb5_locator_plugin.c
@@ -35,7 +35,7 @@
#define SSSD_KRB5_LOCATOR_DEBUG "SSSD_KRB5_LOCATOR_DEBUG"
#define DEBUG_KEY "[sssd_krb5_locator] "
-#define DEBUG(body) do { \
+#define PLUGIN_DEBUG(body) do { \
if (ctx->debug) { \
debug_fn body; \
} \
@@ -82,7 +82,7 @@ krb5_error_code sssd_krb5_locator_init(krb5_context context,
ctx->debug = false;
} else {
ctx->debug = true;
- DEBUG(("sssd_krb5_locator_init called\n"));
+ PLUGIN_DEBUG(("sssd_krb5_locator_init called\n"));
}
dummy = getenv(SSSD_KRB5_REALM);
@@ -95,9 +95,11 @@ krb5_error_code sssd_krb5_locator_init(krb5_context context,
ret = getaddrinfo(dummy, "kerberos", NULL, &ctx->sssd_kdc_addrinfo);
if (ret != 0) {
- DEBUG(("getaddrinfo failed [%d][%s].\n", ret, gai_strerror(ret)));
+ PLUGIN_DEBUG(("getaddrinfo failed [%d][%s].\n", ret,
+ gai_strerror(ret)));
if (ret == EAI_SYSTEM) {
- DEBUG(("getaddrinfo failed [%d][%s].\n", errno, strerror(errno)));
+ PLUGIN_DEBUG(("getaddrinfo failed [%d][%s].\n", errno,
+ strerror(errno)));
}
goto failed;
}
@@ -122,7 +124,7 @@ void sssd_krb5_locator_close(void *private_data)
if (private_data == NULL) return;
ctx = (struct sssd_ctx *) private_data;
- DEBUG(("sssd_krb5_locator_close called\n"));
+ PLUGIN_DEBUG(("sssd_krb5_locator_close called\n"));
freeaddrinfo(ctx->sssd_kdc_addrinfo);
free(ctx->sssd_realm);
@@ -148,9 +150,9 @@ krb5_error_code sssd_krb5_locator_lookup(void *private_data,
if (private_data == NULL) return KRB5_PLUGIN_NO_HANDLE;
ctx = (struct sssd_ctx *) private_data;
- DEBUG(("sssd_realm[%s] requested realm[%s] family[%d] socktype[%d] "
- "locate_service[%d]\n", ctx->sssd_realm, realm, family, socktype,
- svc));
+ PLUGIN_DEBUG(("sssd_realm[%s] requested realm[%s] family[%d] socktype[%d] "
+ "locate_service[%d]\n", ctx->sssd_realm, realm, family,
+ socktype, svc));
switch (svc) {
case locate_service_kdc:
@@ -188,25 +190,27 @@ krb5_error_code sssd_krb5_locator_lookup(void *private_data,
ret = getnameinfo(ai->ai_addr, ai->ai_addrlen, hostip, NI_MAXHOST,
NULL, 0, NI_NUMERICHOST);
if (ret != 0) {
- DEBUG(("getnameinfo failed [%d][%s].\n", ret, gai_strerror(ret)));
+ PLUGIN_DEBUG(("getnameinfo failed [%d][%s].\n", ret,
+ gai_strerror(ret)));
if (ret == EAI_SYSTEM) {
- DEBUG(("getnameinfo failed [%d][%s].\n", errno, strerror(errno)));
+ PLUGIN_DEBUG(("getnameinfo failed [%d][%s].\n", errno,
+ strerror(errno)));
}
}
- DEBUG(("addr[%s] family[%d] socktype[%d] - ", hostip, ai->ai_family,
- ai->ai_socktype));
+ PLUGIN_DEBUG(("addr[%s] family[%d] socktype[%d] - ", hostip,
+ ai->ai_family, ai->ai_socktype));
if ((family == AF_UNSPEC || ai->ai_family == family) &&
ai->ai_socktype == socktype) {
ret = cbfunc(cbdata, socktype, ai->ai_addr);
if (ret != 0) {
- DEBUG(("\ncbfunc failed\n"));
+ PLUGIN_DEBUG(("\ncbfunc failed\n"));
} else {
- DEBUG(("used\n"));
+ PLUGIN_DEBUG(("used\n"));
}
} else {
- DEBUG((" NOT used\n"));
+ PLUGIN_DEBUG((" NOT used\n"));
}
}
--
1.6.2.5
More information about the sssd-devel
mailing list