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

Reply via email to