summaryrefslogtreecommitdiffstats
path: root/server/providers/ldap/sdap_async_connection.c
diff options
context:
space:
mode:
authorJakub Hrozek <jhrozek@redhat.com>2009-11-19 18:47:56 -0500
committerStephen Gallagher <sgallagh@redhat.com>2009-11-25 11:03:12 -0500
commitf5aa0c046e75f2ecc2b96424847765c8ccb3a302 (patch)
treedc757760d4579e55172d90a5dae57084c8dccfac /server/providers/ldap/sdap_async_connection.c
parentb67dbadc979cbe86545e2275223483d429b74747 (diff)
downloadsssd-f5aa0c046e75f2ecc2b96424847765c8ccb3a302.tar.gz
sssd-f5aa0c046e75f2ecc2b96424847765c8ccb3a302.tar.xz
sssd-f5aa0c046e75f2ecc2b96424847765c8ccb3a302.zip
Get TGT in a child process.
To avoid blocking in a synchronous call, the TGT is saved in a separate process Fixes: #277
Diffstat (limited to 'server/providers/ldap/sdap_async_connection.c')
-rw-r--r--server/providers/ldap/sdap_async_connection.c216
1 files changed, 52 insertions, 164 deletions
diff --git a/server/providers/ldap/sdap_async_connection.c b/server/providers/ldap/sdap_async_connection.c
index a5e6ccfa9..b742471c6 100644
--- a/server/providers/ldap/sdap_async_connection.c
+++ b/server/providers/ldap/sdap_async_connection.c
@@ -547,168 +547,22 @@ static int sasl_bind_recv(struct tevent_req *req, int *ldaperr)
/* ==Perform-Kinit-given-keytab-and-principal============================= */
-static int sdap_krb5_get_tgt_sync(TALLOC_CTX *memctx,
- const char *realm_str,
- const char *princ_str,
- const char *keytab_name)
-{
- char *ccname;
- char *realm_name = NULL;
- char *full_princ = NULL;
- krb5_context context = NULL;
- krb5_keytab keytab = NULL;
- krb5_ccache ccache = NULL;
- krb5_principal kprinc;
- krb5_creds my_creds;
- krb5_get_init_creds_opt options;
- krb5_error_code krberr;
- int ret;
-
- krberr = krb5_init_context(&context);
- if (krberr) {
- DEBUG(2, ("Failed to init kerberos context\n"));
- return EFAULT;
- }
-
- if (!realm_str) {
- krberr = krb5_get_default_realm(context, &realm_name);
- if (krberr) {
- DEBUG(2, ("Failed to get default realm name: %s\n",
- sss_krb5_get_error_message(context, krberr)));
- ret = EFAULT;
- goto done;
- }
- } else {
- realm_name = talloc_strdup(memctx, realm_str);
- if (!realm_name) {
- ret = ENOMEM;
- goto done;
- }
- }
-
- if (princ_str) {
- if (!strchr(princ_str, '@')) {
- full_princ = talloc_asprintf(memctx, "%s@%s",
- princ_str, realm_name);
- } else {
- full_princ = talloc_strdup(memctx, princ_str);
- }
- } else {
- char hostname[512];
-
- ret = gethostname(hostname, 511);
- if (ret == -1) {
- ret = errno;
- goto done;
- }
- hostname[511] = '\0';
-
- full_princ = talloc_asprintf(memctx, "host/%s@%s",
- hostname, realm_name);
- }
- if (!full_princ) {
- ret = ENOMEM;
- goto done;
- }
- DEBUG(4, ("Principal name is: [%s]\n", full_princ));
-
- krberr = krb5_parse_name(context, full_princ, &kprinc);
- if (krberr) {
- DEBUG(2, ("Unable to build principal: %s\n",
- sss_krb5_get_error_message(context, krberr)));
- ret = EFAULT;
- goto done;
- }
-
- if (keytab_name) {
- krberr = krb5_kt_resolve(context, keytab_name, &keytab);
- } else {
- krberr = krb5_kt_default(context, &keytab);
- }
- if (krberr) {
- DEBUG(2, ("Failed to read keytab file: %s\n",
- sss_krb5_get_error_message(context, krberr)));
- ret = EFAULT;
- goto done;
- }
-
- ccname = talloc_asprintf(memctx, "FILE:%s/ccache_%s", DB_PATH, realm_name);
- if (!ccname) {
- ret = ENOMEM;
- goto done;
- }
-
- ret = setenv("KRB5CCNAME", ccname, 1);
- if (ret == -1) {
- DEBUG(2, ("Unable to set env. variable KRB5CCNAME!\n"));
- ret = EFAULT;
- goto done;
- }
-
- krberr = krb5_cc_resolve(context, ccname, &ccache);
- if (krberr) {
- DEBUG(2, ("Failed to set cache name: %s\n",
- sss_krb5_get_error_message(context, krberr)));
- ret = EFAULT;
- goto done;
- }
-
- memset(&my_creds, 0, sizeof(my_creds));
- memset(&options, 0, sizeof(options));
-
- krb5_get_init_creds_opt_set_address_list(&options, NULL);
- krb5_get_init_creds_opt_set_forwardable(&options, 0);
- krb5_get_init_creds_opt_set_proxiable(&options, 0);
- /* set a very short lifetime, we don't keep the ticket around */
- krb5_get_init_creds_opt_set_tkt_life(&options, 300);
-
- krberr = krb5_get_init_creds_keytab(context, &my_creds, kprinc,
- keytab, 0, NULL, &options);
-
- if (krberr) {
- DEBUG(2, ("Failed to init credentials: %s\n",
- sss_krb5_get_error_message(context, krberr)));
- ret = EFAULT;
- goto done;
- }
-
- krberr = krb5_cc_initialize(context, ccache, kprinc);
- if (krberr) {
- DEBUG(2, ("Failed to init ccache: %s\n",
- sss_krb5_get_error_message(context, krberr)));
- ret = EFAULT;
- goto done;
- }
-
- krberr = krb5_cc_store_cred(context, ccache, &my_creds);
- if (krberr) {
- DEBUG(2, ("Failed to store creds: %s\n",
- sss_krb5_get_error_message(context, krberr)));
- ret = EFAULT;
- goto done;
- }
-
- ret = EOK;
-
-done:
- if (keytab) krb5_kt_close(context, keytab);
- if (context) krb5_free_context(context);
- return ret;
-}
-
struct sdap_kinit_state {
int result;
};
-/* TODO: make it really async */
+static void sdap_kinit_done(struct tevent_req *subreq);
+
struct tevent_req *sdap_kinit_send(TALLOC_CTX *memctx,
struct tevent_context *ev,
struct sdap_handle *sh,
+ int timeout,
const char *keytab,
const char *principal,
const char *realm)
{
struct tevent_req *req;
+ struct tevent_req *subreq;
struct sdap_kinit_state *state;
int ret;
@@ -723,31 +577,62 @@ struct tevent_req *sdap_kinit_send(TALLOC_CTX *memctx,
ret = setenv("KRB5_KTNAME", keytab, 1);
if (ret == -1) {
DEBUG(2, ("Failed to set KRB5_KTNAME to %s\n", keytab));
- ret = EFAULT;
- goto fail;
+ return NULL;
}
}
- ret = sdap_krb5_get_tgt_sync(state, realm, principal, keytab);
- if (ret == EOK) {
- state->result = SDAP_AUTH_SUCCESS;
- } else {
- goto fail;
+ subreq = sdap_krb5_get_tgt_send(state, ev, timeout,
+ realm, principal, keytab);
+ if (!subreq) {
+ talloc_zfree(req);
+ return NULL;
}
+ tevent_req_set_callback(subreq, sdap_kinit_done, req);
- tevent_req_post(req, ev);
return req;
+}
-fail:
- tevent_req_error(req, ret);
- tevent_req_post(req, ev);
- return req;
+static void sdap_kinit_done(struct tevent_req *subreq)
+{
+ struct tevent_req *req = tevent_req_callback_data(subreq,
+ struct tevent_req);
+ struct sdap_kinit_state *state = tevent_req_data(req,
+ struct sdap_kinit_state);
+
+ int ret;
+ int result;
+ char *ccname = NULL;
+
+ ret = sdap_krb5_get_tgt_recv(subreq, state, &result, &ccname);
+ talloc_zfree(subreq);
+ if (ret != EOK) {
+ state->result = ret;
+ DEBUG(1, ("child failed (%d [%s])\n", ret, strerror(ret)));
+ tevent_req_error(req, ret);
+ }
+
+ if (result == EOK) {
+ ret = setenv("KRB5CCNAME", ccname, 1);
+ if (ret == -1) {
+ DEBUG(2, ("Unable to set env. variable KRB5CCNAME!\n"));
+ state->result = EFAULT;
+ tevent_req_error(req, EFAULT);
+ }
+
+ state->result = SDAP_AUTH_SUCCESS;
+ tevent_req_done(req);
+ return;
+ }
+
+ DEBUG(4, ("Could not get TGT: %d [%s]\n", result, strerror(result)));
+ state->result = SDAP_AUTH_FAILED;
+ tevent_req_error(req, EIO);
}
int sdap_kinit_recv(struct tevent_req *req, enum sdap_result *result)
{
struct sdap_kinit_state *state = tevent_req_data(req,
- struct sdap_kinit_state);
+ struct sdap_kinit_state);
enum tevent_req_state tstate;
uint64_t err = EIO;
@@ -1068,7 +953,10 @@ static void sdap_cli_kinit_step(struct tevent_req *req)
struct sdap_cli_connect_state);
struct tevent_req *subreq;
- subreq = sdap_kinit_send(state, state->ev, state->sh,
+ subreq = sdap_kinit_send(state, state->ev,
+ state->sh,
+ dp_opt_get_int(state->opts->basic,
+ SDAP_OPT_TIMEOUT),
dp_opt_get_string(state->opts->basic,
SDAP_KRB5_KEYTAB),
dp_opt_get_string(state->opts->basic,