This patcheset does the minimal necessary work to separate initialization from actual providers code for ldap and kerberos and uses this to introduce a first basic ipa provider skeleton that simply reuses the ldap and krb5 providers code.
Simo. -- Simo Sorce * Red Hat, Inc * New York
>From 5736d0bbdb7e550f4054e4ad39603e5901264b1d Mon Sep 17 00:00:00 2001 From: Simo Sorce <sso...@redhat.com> Date: Thu, 15 Oct 2009 17:21:02 -0400 Subject: [PATCH 1/3] Move all ldap provider init functions Put all init functions in their own file so that the other files can be reused in other providers w/o having them in the way. --- server/Makefile.am | 1 + server/providers/ldap/ldap_auth.c | 71 +----------------- server/providers/ldap/ldap_common.c | 6 ++ server/providers/ldap/ldap_common.h | 37 +++++++++ server/providers/ldap/ldap_id.c | 91 ++++------------------- server/providers/ldap/ldap_init.c | 142 +++++++++++++++++++++++++++++++++++ 6 files changed, 203 insertions(+), 145 deletions(-) create mode 100644 server/providers/ldap/ldap_init.c diff --git a/server/Makefile.am b/server/Makefile.am index 9adce0c..bfafa6b 100644 --- a/server/Makefile.am +++ b/server/Makefile.am @@ -429,6 +429,7 @@ endif libsss_ldap_la_SOURCES = \ providers/ldap/ldap_id.c \ providers/ldap/ldap_auth.c \ + providers/ldap/ldap_init.c \ providers/ldap/ldap_common.c \ providers/ldap/sdap_async.c \ providers/ldap/sdap.c \ diff --git a/server/providers/ldap/ldap_auth.c b/server/providers/ldap/ldap_auth.c index a35c43a..31f9c43 100644 --- a/server/providers/ldap/ldap_auth.c +++ b/server/providers/ldap/ldap_auth.c @@ -40,7 +40,6 @@ #include "util/util.h" #include "db/sysdb.h" -#include "providers/dp_backend.h" #include "providers/ldap/ldap_common.h" #include "providers/ldap/sdap_async.h" @@ -51,11 +50,6 @@ enum pwexpire { PWEXPIRE_SHADOW }; -struct sdap_auth_ctx { - struct be_ctx *be; - struct sdap_options *opts; -}; - static errno_t check_pwexpire_kerberos(const char *expire_date, time_t now, enum sdap_result *result) { @@ -581,7 +575,7 @@ static void sdap_auth4chpass_done(struct tevent_req *req); static void sdap_pam_chpass_done(struct tevent_req *req); static void sdap_pam_auth_reply(struct be_req *breq, int dp_err, int result); -static void sdap_pam_chpass_send(struct be_req *breq) +void sdap_pam_chpass_handler(struct be_req *breq) { struct sdap_pam_chpass_state *state; struct sdap_auth_ctx *ctx; @@ -771,8 +765,7 @@ struct sdap_pam_auth_state { static void sdap_pam_auth_done(struct tevent_req *req); static void sdap_password_cache_done(struct tevent_req *req); -/* FIXME: convert caller to tevent_req too ?*/ -static void sdap_pam_auth_send(struct be_req *breq) +void sdap_pam_auth_handler(struct be_req *breq) { struct sdap_pam_auth_state *state; struct sdap_auth_ctx *ctx; @@ -956,63 +949,3 @@ static void sdap_pam_auth_reply(struct be_req *req, int dp_err, int result) req->fn(req, dp_err, result, NULL); } -/* ==Module-Initialization-and-Dispose==================================== */ - -static void sdap_shutdown(struct be_req *req) -{ - /* TODO: Clean up any internal data */ - req->fn(req, DP_ERR_OK, EOK, NULL); -} - -struct bet_ops sdap_auth_ops = { - .handler = sdap_pam_auth_send, - .finalize = sdap_shutdown -}; - -struct bet_ops sdap_chpass_ops = { - .handler = sdap_pam_chpass_send, - .finalize = sdap_shutdown -}; - -int sssm_ldap_auth_init(struct be_ctx *bectx, - struct bet_ops **ops, - void **pvt_data) -{ - struct sdap_auth_ctx *ctx; - int ret; - - ctx = talloc(bectx, struct sdap_auth_ctx); - if (!ctx) return ENOMEM; - - ctx->be = bectx; - - ret = ldap_get_options(ctx, bectx->cdb, bectx->conf_path, - &ctx->opts); - if (ret != EOK) goto done; - - ret = setup_tls_config(ctx->opts->basic); - if (ret != EOK) { - DEBUG(1, ("setup_tls_config failed [%d][%s].\n", ret, strerror(ret))); - goto done; - } - - *ops = &sdap_auth_ops; - *pvt_data = ctx; - ret = EOK; - -done: - if (ret != EOK) { - talloc_free(ctx); - } - return ret; -} - -int sssm_ldap_chpass_init(struct be_ctx *bectx, - struct bet_ops **ops, - void **pvt_data) -{ - int ret; - ret = sssm_ldap_auth_init(bectx, ops, pvt_data); - *ops = &sdap_chpass_ops; - return ret; -} diff --git a/server/providers/ldap/ldap_common.c b/server/providers/ldap/ldap_common.c index bb68ffb..b03e58f 100644 --- a/server/providers/ldap/ldap_common.c +++ b/server/providers/ldap/ldap_common.c @@ -194,3 +194,9 @@ done: return ret; } +void sdap_handler_done(struct be_req *req, int dp_err, + int error, const char *errstr) +{ + return req->fn(req, dp_err, error, errstr); +} + diff --git a/server/providers/ldap/ldap_common.h b/server/providers/ldap/ldap_common.h index 9cf4dde..a6e77e9 100644 --- a/server/providers/ldap/ldap_common.h +++ b/server/providers/ldap/ldap_common.h @@ -22,8 +22,45 @@ #ifndef _LDAP_COMMON_H_ #define _LDAP_COMMON_H_ +#include "providers/dp_backend.h" #include "providers/ldap/sdap.h" +struct sdap_id_ctx { + struct be_ctx *be; + + struct sdap_options *opts; + + /* global sdap handler */ + struct sdap_handle *gsh; + + /* enumeration loop timer */ + struct timeval last_run; + + char *max_user_timestamp; + char *max_group_timestamp; +}; + +struct sdap_auth_ctx { + struct be_ctx *be; + struct sdap_options *opts; +}; + +/* id */ +void sdap_account_info_handler(struct be_req *breq); +int sdap_id_setup_tasks(struct sdap_id_ctx *ctx); + +/* auth */ +void sdap_pam_auth_handler(struct be_req *breq); + +/* chpass */ +void sdap_pam_chpass_handler(struct be_req *breq); + + + +void sdap_handler_done(struct be_req *req, int dp_err, + int error, const char *errstr); + +/* options parser */ int ldap_get_options(TALLOC_CTX *memctx, struct confdb_ctx *cdb, const char *conf_path, diff --git a/server/providers/ldap/ldap_id.c b/server/providers/ldap/ldap_id.c index 3663f20..04aaa08 100644 --- a/server/providers/ldap/ldap_id.c +++ b/server/providers/ldap/ldap_id.c @@ -32,27 +32,6 @@ #include "providers/ldap/ldap_common.h" #include "providers/ldap/sdap_async.h" -struct sdap_id_ctx { - struct be_ctx *be; - - struct sdap_options *opts; - - /* global sdap handler */ - struct sdap_handle *gsh; - - /* enumeration loop timer */ - struct timeval last_run; - - char *max_user_timestamp; - char *max_group_timestamp; -}; - -static void sdap_req_done(struct be_req *req, int dp_err, - int error, const char *errstr) -{ - return req->fn(req, dp_err, error, errstr); -} - static int build_attrs_from_map(TALLOC_CTX *memctx, struct sdap_id_map *map, size_t size, @@ -257,7 +236,7 @@ static void users_get_done(struct tevent_req *req) } } - sdap_req_done(breq, dp_err, ret, error); + sdap_handler_done(breq, dp_err, ret, error); } /* =Groups-Related-Functions-(by-name,by-uid)============================= */ @@ -422,7 +401,7 @@ static void groups_get_done(struct tevent_req *req) } } - return sdap_req_done(breq, dp_err, ret, error); + return sdap_handler_done(breq, dp_err, ret, error); } /* =Get-Groups-for-User================================================== */ @@ -562,7 +541,7 @@ static void groups_by_user_done(struct tevent_req *req) } } - return sdap_req_done(breq, dp_err, ret, error); + return sdap_handler_done(breq, dp_err, ret, error); } @@ -570,8 +549,8 @@ static void groups_by_user_done(struct tevent_req *req) /* =Get-Account-Info-Call================================================= */ /* FIXME: embed this function in sssd_be and only call out - * specific functions from modules */ -static void sdap_get_account_info(struct be_req *breq) + * specific functions from modules ? */ +void sdap_account_info_handler(struct be_req *breq) { struct sdap_id_ctx *ctx; struct be_acct_req *ar; @@ -582,7 +561,7 @@ static void sdap_get_account_info(struct be_req *breq) ctx = talloc_get_type(breq->be_ctx->bet_info[BET_ID].pvt_bet_data, struct sdap_id_ctx); if (be_is_offline(ctx->be)) { - return sdap_req_done(breq, DP_ERR_OFFLINE, EAGAIN, "Offline"); + return sdap_handler_done(breq, DP_ERR_OFFLINE, EAGAIN, "Offline"); } ar = talloc_get_type(breq->req_data, struct be_acct_req); @@ -592,7 +571,7 @@ static void sdap_get_account_info(struct be_req *breq) /* skip enumerations on demand */ if (strcmp(ar->filter_value, "*") == 0) { - return sdap_req_done(breq, DP_ERR_OK, EOK, "Success"); + return sdap_handler_done(breq, DP_ERR_OK, EOK, "Success"); } req = users_get_send(breq, breq->be_ctx->ev, ctx, @@ -600,7 +579,7 @@ static void sdap_get_account_info(struct be_req *breq) ar->filter_type, ar->attr_type); if (!req) { - return sdap_req_done(breq, DP_ERR_FATAL, ENOMEM, "Out of memory"); + return sdap_handler_done(breq, DP_ERR_FATAL, ENOMEM, "Out of memory"); } tevent_req_set_callback(req, users_get_done, breq); @@ -610,7 +589,7 @@ static void sdap_get_account_info(struct be_req *breq) case BE_REQ_GROUP: /* group */ if (strcmp(ar->filter_value, "*") == 0) { - return sdap_req_done(breq, DP_ERR_OK, EOK, "Success"); + return sdap_handler_done(breq, DP_ERR_OK, EOK, "Success"); } /* skip enumerations on demand */ @@ -619,7 +598,7 @@ static void sdap_get_account_info(struct be_req *breq) ar->filter_type, ar->attr_type); if (!req) { - return sdap_req_done(breq, DP_ERR_FATAL, ENOMEM, "Out of memory"); + return sdap_handler_done(breq, DP_ERR_FATAL, ENOMEM, "Out of memory"); } tevent_req_set_callback(req, groups_get_done, breq); @@ -656,7 +635,7 @@ static void sdap_get_account_info(struct be_req *breq) err = "Invalid request type"; } - if (ret != EOK) return sdap_req_done(breq, DP_ERR_FATAL, ret, err); + if (ret != EOK) return sdap_handler_done(breq, DP_ERR_FATAL, ret, err); } @@ -1151,63 +1130,23 @@ static void enum_groups_op_done(struct tevent_req *subreq) tevent_req_done(req); } - - -/* ==Initialization-Functions============================================= */ - -static void sdap_shutdown(struct be_req *req) -{ - /* TODO: Clean up any internal data */ - sdap_req_done(req, DP_ERR_OK, EOK, NULL); -} - -struct bet_ops sdap_id_ops = { - .handler = sdap_get_account_info, - .finalize = sdap_shutdown -}; - -int sssm_ldap_init(struct be_ctx *bectx, - struct bet_ops **ops, - void **pvt_data) +int sdap_id_setup_tasks(struct sdap_id_ctx *ctx) { struct tevent_timer *enum_task; - struct sdap_id_ctx *ctx; - int ret; - - ctx = talloc_zero(bectx, struct sdap_id_ctx); - if (!ctx) return ENOMEM; - - ctx->be = bectx; - - ret = ldap_get_options(ctx, bectx->cdb, bectx->conf_path, &ctx->opts); - if (ret != EOK) goto done; - - ret = setup_tls_config(ctx->opts->basic); - if (ret != EOK) { - DEBUG(1, ("setup_tls_config failed [%d][%s].\n", ret, strerror(ret))); - goto done; - } + int ret = EOK; /* set up enumeration task */ if (ctx->be->domain->enumerate) { /* run the first immediately */ ctx->last_run = tevent_timeval_current(); enum_task = tevent_add_timer(ctx->be->ev, ctx, ctx->last_run, - ldap_id_enumerate, ctx); + ldap_id_enumerate, ctx); if (!enum_task) { DEBUG(0, ("FATAL: failed to setup enumeration task!\n")); ret = EFAULT; - goto done; } } - *ops = &sdap_id_ops; - *pvt_data = ctx; - ret = EOK; - -done: - if (ret != EOK) { - talloc_free(ctx); - } return ret; } + diff --git a/server/providers/ldap/ldap_init.c b/server/providers/ldap/ldap_init.c new file mode 100644 index 0000000..295ff19 --- /dev/null +++ b/server/providers/ldap/ldap_init.c @@ -0,0 +1,142 @@ +/* + SSSD + + LDAP Provider Initialization functions + + Authors: + Simo Sorce <sso...@redhat.com> + + Copyright (C) 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 "providers/ldap/ldap_common.h" + +static void sdap_shutdown(struct be_req *req); + +/* Id Handler */ +struct bet_ops sdap_id_ops = { + .handler = sdap_account_info_handler, + .finalize = sdap_shutdown +}; + +/* Auth Handler */ +struct bet_ops sdap_auth_ops = { + .handler = sdap_pam_auth_handler, + .finalize = sdap_shutdown +}; + +/* Chpass Handler */ +struct bet_ops sdap_chpass_ops = { + .handler = sdap_pam_chpass_handler, + .finalize = sdap_shutdown +}; + +int sssm_ldap_init(struct be_ctx *bectx, + struct bet_ops **ops, + void **pvt_data) +{ + struct sdap_id_ctx *ctx; + int ret; + + ctx = talloc_zero(bectx, struct sdap_id_ctx); + if (!ctx) return ENOMEM; + + ctx->be = bectx; + + ret = ldap_get_options(ctx, bectx->cdb, + bectx->conf_path, &ctx->opts); + if (ret != EOK) { + goto done; + } + + ret = setup_tls_config(ctx->opts->basic); + if (ret != EOK) { + DEBUG(1, ("setup_tls_config failed [%d][%s].\n", + ret, strerror(ret))); + goto done; + } + + ret = sdap_id_setup_tasks(ctx); + if (ret != EOK) { + goto done; + } + + *ops = &sdap_id_ops; + *pvt_data = ctx; + ret = EOK; + +done: + if (ret != EOK) { + talloc_free(ctx); + } + return ret; +} + +int sssm_ldap_auth_init(struct be_ctx *bectx, + struct bet_ops **ops, + void **pvt_data) +{ + struct sdap_auth_ctx *ctx; + int ret; + + ctx = talloc(bectx, struct sdap_auth_ctx); + if (!ctx) return ENOMEM; + + ctx->be = bectx; + + ret = ldap_get_options(ctx, bectx->cdb, + bectx->conf_path, &ctx->opts); + if (ret != EOK) { + goto done; + } + + ret = setup_tls_config(ctx->opts->basic); + if (ret != EOK) { + DEBUG(1, ("setup_tls_config failed [%d][%s].\n", + ret, strerror(ret))); + goto done; + } + + *ops = &sdap_auth_ops; + *pvt_data = ctx; + ret = EOK; + +done: + if (ret != EOK) { + talloc_free(ctx); + } + return ret; +} + +int sssm_ldap_chpass_init(struct be_ctx *bectx, + struct bet_ops **ops, + void **pvt_data) +{ + int ret; + + ret = sssm_ldap_auth_init(bectx, ops, pvt_data); + + *ops = &sdap_chpass_ops; + + return ret; +} + +static void sdap_shutdown(struct be_req *req) +{ + /* TODO: Clean up any internal data */ + sdap_handler_done(req, DP_ERR_OK, EOK, NULL); +} + -- 1.6.2.5
>From 8c1f2152e6aebd3256fc2808a276f6b9e3bc7963 Mon Sep 17 00:00:00 2001 From: Simo Sorce <sso...@redhat.com> Date: Thu, 15 Oct 2009 17:39:36 -0400 Subject: [PATCH 2/3] Move all krb5 provider init functions Put all init functions in their own file so that the other files can be reused in other providers w/o having them in the way. --- server/Makefile.am | 3 +- server/krb5_plugin/sssd_krb5_locator_plugin.c | 2 +- server/providers/krb5/krb5_auth.c | 204 +++---------------------- server/providers/krb5/krb5_auth.h | 21 +-- server/providers/krb5/krb5_common.h | 40 +++++ server/providers/krb5/krb5_init.c | 189 +++++++++++++++++++++++ 6 files changed, 264 insertions(+), 195 deletions(-) create mode 100644 server/providers/krb5/krb5_common.h create mode 100644 server/providers/krb5/krb5_init.c diff --git a/server/Makefile.am b/server/Makefile.am index bfafa6b..f674093 100644 --- a/server/Makefile.am +++ b/server/Makefile.am @@ -457,7 +457,8 @@ libsss_proxy_la_LDFLAGS = \ libsss_krb5_la_SOURCES = \ providers/krb5/krb5_utils.c \ - providers/krb5/krb5_auth.c + providers/krb5/krb5_auth.c \ + providers/krb5/krb5_init.c libsss_krb5_la_CFLAGS = \ $(AM_CFLAGS) \ $(KRB5_CFLAGS) diff --git a/server/krb5_plugin/sssd_krb5_locator_plugin.c b/server/krb5_plugin/sssd_krb5_locator_plugin.c index 7ccdb3f..fc5f426 100644 --- a/server/krb5_plugin/sssd_krb5_locator_plugin.c +++ b/server/krb5_plugin/sssd_krb5_locator_plugin.c @@ -31,7 +31,7 @@ #include <krb5/locate_plugin.h> -#include "providers/krb5/krb5_auth.h" +#include "providers/krb5/krb5_common.h" #define SSSD_KRB5_LOCATOR_DEBUG "SSSD_KRB5_LOCATOR_DEBUG" #define DEBUG_KEY "[sssd_krb5_locator] " diff --git a/server/providers/krb5/krb5_auth.c b/server/providers/krb5/krb5_auth.c index 4d98b93..1e689d9 100644 --- a/server/providers/krb5/krb5_auth.c +++ b/server/providers/krb5/krb5_auth.c @@ -27,16 +27,12 @@ #include <sys/types.h> #include <sys/wait.h> -#include <unistd.h> #include <fcntl.h> #include <pwd.h> -#include <sys/stat.h> - #include <security/pam_modules.h> #include "util/util.h" -#include "providers/dp_backend.h" #include "db/sysdb.h" #include "providers/krb5/krb5_auth.h" #include "providers/krb5/krb5_utils.h" @@ -141,7 +137,8 @@ errno_t create_send_buffer(struct krb5child_req *kr, struct io_buffer **io_buf) return EOK; } -static struct krb5_ctx *get_krb5_ctx(struct be_req *be_req) { +static struct krb5_ctx *get_krb5_ctx(struct be_req *be_req) +{ struct pam_data *pd; pd = talloc_get_type(be_req->req_data, struct pam_data); @@ -161,7 +158,8 @@ static struct krb5_ctx *get_krb5_ctx(struct be_req *be_req) { } } -static void fd_nonblocking(int fd) { +static void fd_nonblocking(int fd) +{ int flags; flags = fcntl(fd, F_GETFL, 0); @@ -297,9 +295,9 @@ failed: return err; } -static void wait_for_child_handler(struct tevent_context *ev, - struct tevent_signal *sige, int signum, - int count, void *__siginfo, void *pvt) +void krb5_child_sig_handler(struct tevent_context *ev, + struct tevent_signal *sige, int signum, + int count, void *__siginfo, void *pvt) { int ret; int child_status; @@ -496,12 +494,12 @@ struct read_pipe_state { size_t len; }; -static void read_pipe_done(struct tevent_context *ev, struct tevent_fd *fde, - uint16_t flags, void *pvt); +static void read_pipe_done(struct tevent_context *ev, + struct tevent_fd *fde, + uint16_t flags, void *pvt); static struct tevent_req *read_pipe_send(TALLOC_CTX *memctx, - struct tevent_context *ev, - int fd) + struct tevent_context *ev, int fd) { struct tevent_req *req; struct read_pipe_state *state; @@ -530,8 +528,9 @@ fail: return NULL; } -static void read_pipe_done(struct tevent_context *ev, struct tevent_fd *fde, - uint16_t flags, void *pvt) +static void read_pipe_done(struct tevent_context *ev, + struct tevent_fd *fde, + uint16_t flags, void *pvt) { ssize_t size; struct tevent_req *req = talloc_get_type(pvt, struct tevent_req); @@ -569,7 +568,8 @@ static void read_pipe_done(struct tevent_context *ev, struct tevent_fd *fde, } static ssize_t read_pipe_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx, - uint8_t **buf, uint64_t *error) { + uint8_t **buf, uint64_t *error) +{ struct read_pipe_state *state = tevent_req_data(req, struct read_pipe_state); enum tevent_req_state tstate; @@ -590,8 +590,9 @@ struct handle_child_state { static void handle_child_done(struct tevent_req *subreq); -static struct tevent_req *handle_child_send(TALLOC_CTX *mem_ctx, struct tevent_context *ev, - struct krb5child_req *kr) +static struct tevent_req *handle_child_send(TALLOC_CTX *mem_ctx, + struct tevent_context *ev, + struct krb5child_req *kr) { int ret; struct tevent_req *req; @@ -656,8 +657,10 @@ static void handle_child_done(struct tevent_req *subreq) return; } -static ssize_t handle_child_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx, - uint8_t **buf, uint64_t *error) { +static ssize_t handle_child_recv(struct tevent_req *req, + TALLOC_CTX *mem_ctx, + uint8_t **buf, uint64_t *error) +{ struct handle_child_state *state = tevent_req_data(req, struct handle_child_state); enum tevent_req_state tstate; @@ -674,7 +677,7 @@ static void get_user_upn_done(void *pvt, int err, struct ldb_result *res); static void krb5_pam_handler_done(struct tevent_req *req); static void krb5_pam_handler_cache_done(struct tevent_req *treq); -static void krb5_pam_handler(struct be_req *be_req) +void krb5_pam_handler(struct be_req *be_req) { struct pam_data *pd; const char **attrs; @@ -968,162 +971,3 @@ static void krb_reply(struct be_req *req, int dp_err, int result) req->fn(req, dp_err, result, NULL); } - -struct bet_ops krb5_auth_ops = { - .handler = krb5_pam_handler, - .finalize = NULL, -}; - -struct bet_ops krb5_chpass_ops = { - .handler = krb5_pam_handler, - .finalize = NULL, -}; - - -int sssm_krb5_auth_init(struct be_ctx *bectx, - struct bet_ops **ops, 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; - - 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); - 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); - 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->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, - wait_for_child_handler, NULL); - if (sige == NULL) { - DEBUG(1, ("tevent_add_signal failed.\n")); - ret = ENOMEM; - goto fail; - } - - if (debug_to_file != 0) { - ret = open_debug_file_ex("krb5_child", &debug_filep); - if (ret != EOK) { - DEBUG(0, ("Error setting up logging (%d) [%s]\n", - ret, strerror(ret))); - 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 fail; - } - - v = fcntl(ctx->child_debug_fd, F_GETFD, 0); - fcntl(ctx->child_debug_fd, F_SETFD, v & ~FD_CLOEXEC); - } - - *ops = &krb5_auth_ops; - *pvt_auth_data = ctx; - return EOK; - -fail: - talloc_free(ctx); - return ret; -} - -int sssm_krb5_chpass_init(struct be_ctx *bectx, struct bet_ops **ops, - void **pvt_auth_data) -{ - return sssm_krb5_auth_init(bectx, ops, pvt_auth_data); -} diff --git a/server/providers/krb5/krb5_auth.h b/server/providers/krb5/krb5_auth.h index 1fd7c58..9e9142c 100644 --- a/server/providers/krb5/krb5_auth.h +++ b/server/providers/krb5/krb5_auth.h @@ -26,23 +26,12 @@ #ifndef __KRB5_AUTH_H__ #define __KRB5_AUTH_H__ -#include "config.h" - -#include <stdbool.h> - -#ifdef HAVE_KRB5_KRB5_H -#include <krb5/krb5.h> -#else -#include <krb5.h> -#endif +#include "providers/dp_backend.h" +#include "providers/krb5/krb5_common.h" #define MAX_CHILD_MSG_SIZE 255 #define CCACHE_ENV_NAME "KRB5CCNAME" - #define SSSD_KRB5_CHANGEPW_PRINCIPLE "SSSD_KRB5_CHANGEPW_PRINCIPLE" -#define SSSD_KRB5_KDC "SSSD_KRB5_KDC" -#define SSSD_KRB5_REALM "SSSD_KRB5_REALM" - typedef enum { INIT_PW, INIT_KT, RENEW, VALIDATE } action_type; @@ -95,4 +84,10 @@ struct krb5_ctx { int child_debug_fd; }; +void krb5_pam_handler(struct be_req *be_req); + +void krb5_child_sig_handler(struct tevent_context *ev, + struct tevent_signal *sige, int signum, + int count, void *__siginfo, void *pvt); + #endif /* __KRB5_AUTH_H__ */ diff --git a/server/providers/krb5/krb5_common.h b/server/providers/krb5/krb5_common.h new file mode 100644 index 0000000..64e4360 --- /dev/null +++ b/server/providers/krb5/krb5_common.h @@ -0,0 +1,40 @@ +/* + SSSD + + Kerberos Backend, common header file + + Authors: + Sumit Bose <sb...@redhat.com> + + Copyright (C) 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/>. +*/ + +#ifndef __KRB5_COMMON_H__ +#define __KRB5_COMMON_H__ + +#include "config.h" +#include <stdbool.h> +#ifdef HAVE_KRB5_KRB5_H +#include <krb5/krb5.h> +#else +#include <krb5.h> +#endif + +#define SSSD_KRB5_KDC "SSSD_KRB5_KDC" +#define SSSD_KRB5_REALM "SSSD_KRB5_REALM" + +#endif /* __KRB5_COMMON_H__ */ diff --git a/server/providers/krb5/krb5_init.c b/server/providers/krb5/krb5_init.c new file mode 100644 index 0000000..676d078 --- /dev/null +++ b/server/providers/krb5/krb5_init.c @@ -0,0 +1,189 @@ +/* + SSSD + + Kerberos 5 Backend Module + + Authors: + Sumit Bose <sb...@redhat.com> + + Copyright (C) 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 <unistd.h> +#include <fcntl.h> +#include <sys/stat.h> +#include "providers/krb5/krb5_auth.h" + +struct bet_ops krb5_auth_ops = { + .handler = krb5_pam_handler, + .finalize = NULL, +}; + +struct bet_ops krb5_chpass_ops = { + .handler = krb5_pam_handler, + .finalize = NULL, +}; + +int sssm_krb5_auth_init(struct be_ctx *bectx, + struct bet_ops **ops, + 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; + + 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); + 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); + 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->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; + } + + if (debug_to_file != 0) { + ret = open_debug_file_ex("krb5_child", &debug_filep); + if (ret != EOK) { + DEBUG(0, ("Error setting up logging (%d) [%s]\n", + ret, strerror(ret))); + 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 fail; + } + + v = fcntl(ctx->child_debug_fd, F_GETFD, 0); + fcntl(ctx->child_debug_fd, F_SETFD, v & ~FD_CLOEXEC); + } + + *ops = &krb5_auth_ops; + *pvt_auth_data = ctx; + return EOK; + +fail: + talloc_free(ctx); + return ret; +} + +int sssm_krb5_chpass_init(struct be_ctx *bectx, + struct bet_ops **ops, + void **pvt_auth_data) +{ + return sssm_krb5_auth_init(bectx, ops, pvt_auth_data); +} -- 1.6.2.5
>From c0a87ff700500ba4978f82e5aa5a420847f7ab73 Mon Sep 17 00:00:00 2001 From: Simo Sorce <sso...@redhat.com> Date: Thu, 15 Oct 2009 17:54:46 -0400 Subject: [PATCH 3/3] Add first basic IPA provider --- server/Makefile.am | 24 ++++- server/providers/ipa/ipa_init.c | 233 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 256 insertions(+), 1 deletions(-) create mode 100644 server/providers/ipa/ipa_init.c diff --git a/server/Makefile.am b/server/Makefile.am index f674093..d13211c 100644 --- a/server/Makefile.am +++ b/server/Makefile.am @@ -80,7 +80,8 @@ TESTS = \ sssdlib_LTLIBRARIES = \ libsss_ldap.la \ libsss_krb5.la \ - libsss_proxy.la + libsss_proxy.la \ + libsss_ipa.la ldblib_LTLIBRARIES = \ memberof.la @@ -468,6 +469,27 @@ libsss_krb5_la_LDFLAGS = \ -version-info 1:0:0 \ -module +libsss_ipa_la_SOURCES = \ + providers/ipa/ipa_init.c \ + providers/ldap/ldap_id.c \ + providers/ldap/ldap_auth.c \ + providers/ldap/ldap_common.c \ + providers/ldap/sdap_async.c \ + providers/ldap/sdap.c \ + util/sss_ldap.c \ + providers/krb5/krb5_utils.c \ + providers/krb5/krb5_auth.c +libsss_ipa_la_CFLAGS = \ + $(AM_CFLAGS) \ + $(LDAP_CFLAGS) \ + $(KRB5_CFLAGS) +libsss_ipa_la_LIBADD = \ + $(OPENLDAP_LIBS) \ + $(KRB5_LIBS) +libsss_ipa_la_LDFLAGS = \ + -version-info 1:0:0 \ + -module + krb5_child_SOURCES = \ $(SSSD_DEBUG_OBJ) \ providers/krb5/krb5_child.c diff --git a/server/providers/ipa/ipa_init.c b/server/providers/ipa/ipa_init.c new file mode 100644 index 0000000..ebbeec4 --- /dev/null +++ b/server/providers/ipa/ipa_init.c @@ -0,0 +1,233 @@ +/* + SSSD + + IPA Provider Initialization functions + + Authors: + Simo Sorce <sso...@redhat.com> + + Copyright (C) 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 <unistd.h> +#include <sys/stat.h> +#include "providers/ldap/ldap_common.h" +#include "providers/krb5/krb5_auth.h" + +/* Id Handler */ +struct bet_ops ipa_id_ops = { + .handler = sdap_account_info_handler, + .finalize = NULL +}; + +struct bet_ops ipa_auth_ops = { + .handler = krb5_pam_handler, + .finalize = NULL, +}; + +struct bet_ops ipa_chpass_ops = { + .handler = krb5_pam_handler, + .finalize = NULL, +}; + +int sssm_ipa_init(struct be_ctx *bectx, + struct bet_ops **ops, + void **pvt_data) +{ + struct sdap_id_ctx *ctx; + int ret; + + ctx = talloc_zero(bectx, struct sdap_id_ctx); + if (!ctx) return ENOMEM; + + ctx->be = bectx; + + ret = ldap_get_options(ctx, bectx->cdb, + bectx->conf_path, &ctx->opts); + if (ret != EOK) { + goto done; + } + + ret = setup_tls_config(ctx->opts->basic); + if (ret != EOK) { + DEBUG(1, ("setup_tls_config failed [%d][%s].\n", + ret, strerror(ret))); + goto done; + } + + ret = sdap_id_setup_tasks(ctx); + if (ret != EOK) { + goto done; + } + + *ops = &ipa_id_ops; + *pvt_data = ctx; + ret = EOK; + +done: + if (ret != EOK) { + talloc_free(ctx); + } + return ret; +} + +int sssm_ipa_auth_init(struct be_ctx *bectx, + struct bet_ops **ops, + void **pvt_auth_data) +{ + struct krb5_ctx *ctx = NULL; + struct tevent_signal *sige; + struct stat stat_buf; + char *value = NULL; + int int_value; + int ret; + + 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); + 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); + 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->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; + } + + *ops = &ipa_auth_ops; + *pvt_auth_data = ctx; + return EOK; + +fail: + talloc_free(ctx); + return ret; +} + +int sssm_ipa_chpass_init(struct be_ctx *bectx, + struct bet_ops **ops, + void **pvt_auth_data) +{ + return sssm_ipa_auth_init(bectx, ops, pvt_auth_data); +} -- 1.6.2.5
_______________________________________________ sssd-devel mailing list sssd-devel@lists.fedorahosted.org https://fedorahosted.org/mailman/listinfo/sssd-devel