sdap_async_connection.c revision bc76428246c4ce532abd0eadcd539069fc1d94a8
b6ff72be73dad3d1394cf2c71e29e67624ff030bChristian Maeder/*
beff4152e9f0fe90885458d1a1733b183a2a8816Christian Maeder SSSD
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder
e6d40133bc9f858308654afb1262b8b483ec5922Till Mossakowski Async LDAP Helper routines
2725abe920f91de62ae5c0b7230c1627cccf5fabChristian Maeder
98890889ffb2e8f6f722b00e265a211f13b5a861Corneliu-Claudiu Prodescu Copyright (C) Simo Sorce <ssorce@redhat.com> - 2009
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder Copyright (C) 2010, rhafer@suse.de, Novell Inc.
3f69b6948966979163bdfe8331c38833d5d90ecdChristian Maeder
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder This program is free software; you can redistribute it and/or modify
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder it under the terms of the GNU General Public License as published by
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder the Free Software Foundation; either version 3 of the License, or
f3a94a197960e548ecd6520bb768cb0d547457bbChristian Maeder (at your option) any later version.
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder This program is distributed in the hope that it will be useful,
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder but WITHOUT ANY WARRANTY; without even the implied warranty of
109a53dbf4c9233f869f63ba7a7f3fece49973c3Christian Maeder MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
109a53dbf4c9233f869f63ba7a7f3fece49973c3Christian Maeder GNU General Public License for more details.
0a26144c20fa9cdcd05011ca5019cbac8e4afae0cmaeder
0a26144c20fa9cdcd05011ca5019cbac8e4afae0cmaeder You should have received a copy of the GNU General Public License
d1c667fd9445963d9d31e2cf5d0ead15e77082a4cmaeder along with this program. If not, see <http://www.gnu.org/licenses/>.
93603bd881e43d4ff5a57d7ca4e2b9fa619f25b4cmaeder*/
d1c667fd9445963d9d31e2cf5d0ead15e77082a4cmaeder
109a53dbf4c9233f869f63ba7a7f3fece49973c3Christian Maeder#include <unistd.h>
109a53dbf4c9233f869f63ba7a7f3fece49973c3Christian Maeder#include <fcntl.h>
109a53dbf4c9233f869f63ba7a7f3fece49973c3Christian Maeder#include <sasl/sasl.h>
bbba10ee00dcf6bcbc9f22473b1acd0983b10512notanartist#include "util/util.h"
df87ff823273ae2969e9d29e833845b4c0a9ee77notanartist#include "util/sss_krb5.h"
109a53dbf4c9233f869f63ba7a7f3fece49973c3Christian Maeder#include "util/sss_ldap.h"
109a53dbf4c9233f869f63ba7a7f3fece49973c3Christian Maeder#include "util/strtonum.h"
ea5ccb1c6e89486a54e1f4bd95840147e96093edChristian Maeder#include "providers/ldap/sdap_async_private.h"
109a53dbf4c9233f869f63ba7a7f3fece49973c3Christian Maeder#include "providers/ldap/ldap_common.h"
109a53dbf4c9233f869f63ba7a7f3fece49973c3Christian Maeder
85e1d54a475bfc30b3eac5ae6c5e42a2d7e93f10Christian Maedererrno_t deref_string_to_val(const char *str, int *val)
85e1d54a475bfc30b3eac5ae6c5e42a2d7e93f10Christian Maeder{
109a53dbf4c9233f869f63ba7a7f3fece49973c3Christian Maeder if (strcasecmp(str, "never") == 0) {
91e24fc45834b35f2a3830d72565640251149bf3Christian Maeder *val = LDAP_DEREF_NEVER;
109a53dbf4c9233f869f63ba7a7f3fece49973c3Christian Maeder } else if (strcasecmp(str, "searching") == 0) {
109a53dbf4c9233f869f63ba7a7f3fece49973c3Christian Maeder *val = LDAP_DEREF_SEARCHING;
109a53dbf4c9233f869f63ba7a7f3fece49973c3Christian Maeder } else if (strcasecmp(str, "finding") == 0) {
109a53dbf4c9233f869f63ba7a7f3fece49973c3Christian Maeder *val = LDAP_DEREF_FINDING;
109a53dbf4c9233f869f63ba7a7f3fece49973c3Christian Maeder } else if (strcasecmp(str, "always") == 0) {
109a53dbf4c9233f869f63ba7a7f3fece49973c3Christian Maeder *val = LDAP_DEREF_ALWAYS;
109a53dbf4c9233f869f63ba7a7f3fece49973c3Christian Maeder } else {
0130083f314580170af1195037be3325f125fbceChristian Maeder DEBUG(1, ("Illegal deref option [%s].\n", str));
109a53dbf4c9233f869f63ba7a7f3fece49973c3Christian Maeder return EINVAL;
0130083f314580170af1195037be3325f125fbceChristian Maeder }
109a53dbf4c9233f869f63ba7a7f3fece49973c3Christian Maeder
109a53dbf4c9233f869f63ba7a7f3fece49973c3Christian Maeder return EOK;
109a53dbf4c9233f869f63ba7a7f3fece49973c3Christian Maeder}
109a53dbf4c9233f869f63ba7a7f3fece49973c3Christian Maeder
109a53dbf4c9233f869f63ba7a7f3fece49973c3Christian Maeder/* ==Connect-to-LDAP-Server=============================================== */
109a53dbf4c9233f869f63ba7a7f3fece49973c3Christian Maeder
109a53dbf4c9233f869f63ba7a7f3fece49973c3Christian Maederstruct sdap_rebind_proc_params {
bbba6dd86153aacb0f662b182b128df0eb09fd54Christian Maeder struct sdap_options *opts;
109a53dbf4c9233f869f63ba7a7f3fece49973c3Christian Maeder struct sdap_handle *sh;
a461314c811f4187dff85c8be079a41b2f13f176Christian Maeder bool use_start_tls;
4eb859461f8fd904f40f57261cf23e5c73cf8ecaChristian Maeder};
a31430de8b0632d29f42634d6395e982bf31b14dChristian Maeder
109a53dbf4c9233f869f63ba7a7f3fece49973c3Christian Maederstatic int sdap_rebind_proc(LDAP *ldap, LDAP_CONST char *url, ber_tag_t request,
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder ber_int_t msgid, void *params);
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder
be43c3fa0292555bd126784ae27ff5c1d23438cbChristian Maederstruct sdap_connect_state {
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder struct tevent_context *ev;
16b71dad8d398af412d66a4f4763f1ada5b03d23Christian Maeder struct sdap_options *opts;
f39b8dd9651dfcc38b06191cda23cacbfc298323Christian Maeder struct sdap_handle *sh;
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder const char *uri;
7f7460e7095628f3437b116ee78d3043d11f8febChristian Maeder bool use_start_tls;
3a9d784341454573b50b32fa1b494e7418df3086Christian Maeder
dff1de7ad15d1582e25d636c3724dd202874897fChristian Maeder struct sdap_op *op;
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder struct sdap_msg *reply;
9d6562465b41f17c7967d4e5678f34811d958cb2Christian Maeder int result;
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder};
502483734c83d0bf1eadcc94113d0362f8713784Christian Maeder
b53688bfed888214b485cf76439d57262d80e0a7Christian Maederstatic void sdap_sys_connect_done(struct tevent_req *subreq);
be43c3fa0292555bd126784ae27ff5c1d23438cbChristian Maederstatic void sdap_connect_done(struct sdap_op *op,
7f7460e7095628f3437b116ee78d3043d11f8febChristian Maeder struct sdap_msg *reply,
16b71dad8d398af412d66a4f4763f1ada5b03d23Christian Maeder int error, void *pvt);
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder
96ae1a1d2197d0e0d5b80da2474b64c456feb1b0Christian Maederstruct tevent_req *sdap_connect_send(TALLOC_CTX *memctx,
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder struct tevent_context *ev,
38c817b94e0a5b1ae94178b1075c187e07bcc5e1Christian Maeder struct sdap_options *opts,
38c817b94e0a5b1ae94178b1075c187e07bcc5e1Christian Maeder const char *uri,
38c817b94e0a5b1ae94178b1075c187e07bcc5e1Christian Maeder struct sockaddr_storage *sockaddr,
38c817b94e0a5b1ae94178b1075c187e07bcc5e1Christian Maeder bool use_start_tls)
4eb859461f8fd904f40f57261cf23e5c73cf8ecaChristian Maeder{
4eb859461f8fd904f40f57261cf23e5c73cf8ecaChristian Maeder struct tevent_req *req;
4eb859461f8fd904f40f57261cf23e5c73cf8ecaChristian Maeder struct tevent_req *subreq;
4eb859461f8fd904f40f57261cf23e5c73cf8ecaChristian Maeder struct sdap_connect_state *state;
4eb859461f8fd904f40f57261cf23e5c73cf8ecaChristian Maeder int ret;
4eb859461f8fd904f40f57261cf23e5c73cf8ecaChristian Maeder int timeout;
4eb859461f8fd904f40f57261cf23e5c73cf8ecaChristian Maeder
4eb859461f8fd904f40f57261cf23e5c73cf8ecaChristian Maeder req = tevent_req_create(memctx, &state, struct sdap_connect_state);
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder if (!req) return NULL;
2353f65833a3da763392f771223250cd50b8d873Christian Maeder
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder state->reply = talloc(state, struct sdap_msg);
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder if (!state->reply) {
dff1de7ad15d1582e25d636c3724dd202874897fChristian Maeder talloc_zfree(req);
dff1de7ad15d1582e25d636c3724dd202874897fChristian Maeder return NULL;
96ae1a1d2197d0e0d5b80da2474b64c456feb1b0Christian Maeder }
8c8545dd3bf34fbcbc16904b65d249658f8f9efcChristian Maeder
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder state->ev = ev;
d81905a5b924415c524d702df26204683c82c12eChristian Maeder state->opts = opts;
96ae1a1d2197d0e0d5b80da2474b64c456feb1b0Christian Maeder state->use_start_tls = use_start_tls;
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder state->uri = talloc_asprintf(state, "%s", uri);
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder if (!state->uri) {
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder talloc_zfree(req);
dff1de7ad15d1582e25d636c3724dd202874897fChristian Maeder return NULL;
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder }
cb2044812811d66efe038d914966e04290be93faChristian Maeder
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder state->sh = sdap_handle_create(state);
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder if (!state->sh) {
dff1de7ad15d1582e25d636c3724dd202874897fChristian Maeder talloc_zfree(req);
0ae7a79e865d4a6022d705d160530682b3c1f825Christian Maeder return NULL;
083bc1972a66d73749760eab3a90bf4eb9ca7951Christian Maeder }
6352f3c31da3043783a13be6594aacb2147378baRazvan Pascanu
fefee7e1dee1ee5f0768a03a4abae88d1ca2c3fdRazvan Pascanu state->sh->page_size = dp_opt_get_int(state->opts->basic,
b324cda6178c49ddeead3ce62b832ccf644cbcabRazvan Pascanu SDAP_PAGE_SIZE);
fefee7e1dee1ee5f0768a03a4abae88d1ca2c3fdRazvan Pascanu
bc263f610d20a9cd3014ddfca903026127fa0d48Christian Maeder timeout = dp_opt_get_int(state->opts->basic, SDAP_NETWORK_TIMEOUT);
966519955f5f7111abac20118563132b9dd41165Christian Maeder
8c8545dd3bf34fbcbc16904b65d249658f8f9efcChristian Maeder subreq = sss_ldap_init_send(state, ev, state->uri, sockaddr,
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder sizeof(struct sockaddr_storage),
0b13f102310e03a20b38c870b5acb88712f316a4Christian Maeder timeout);
0b13f102310e03a20b38c870b5acb88712f316a4Christian Maeder if (subreq == NULL) {
0b13f102310e03a20b38c870b5acb88712f316a4Christian Maeder ret = ENOMEM;
33fcc19ef2b59493b4e91eebf701df95fd230765Christian Maeder DEBUG(1, ("sss_ldap_init_send failed.\n"));
33fcc19ef2b59493b4e91eebf701df95fd230765Christian Maeder goto fail;
33fcc19ef2b59493b4e91eebf701df95fd230765Christian Maeder }
d4ebd9e5adc974cfa2bdf4bdd155e07be0e26f75Christian Maeder
d4ebd9e5adc974cfa2bdf4bdd155e07be0e26f75Christian Maeder tevent_req_set_callback(subreq, sdap_sys_connect_done, req);
d4ebd9e5adc974cfa2bdf4bdd155e07be0e26f75Christian Maeder return req;
0d79ea4ed8512a802ecb6645edac141e0fbcee3fChristian Maeder
0d79ea4ed8512a802ecb6645edac141e0fbcee3fChristian Maederfail:
0d79ea4ed8512a802ecb6645edac141e0fbcee3fChristian Maeder tevent_req_error(req, ret);
a31430de8b0632d29f42634d6395e982bf31b14dChristian Maeder tevent_req_post(req, ev);
a31430de8b0632d29f42634d6395e982bf31b14dChristian Maeder return req;
a31430de8b0632d29f42634d6395e982bf31b14dChristian Maeder}
ce8a93047aaf0dc36fa221642292d47852a9862aChristian Maeder
ce8a93047aaf0dc36fa221642292d47852a9862aChristian Maederstatic void sdap_sys_connect_done(struct tevent_req *subreq)
ce8a93047aaf0dc36fa221642292d47852a9862aChristian Maeder{
9f4902edfa3d477e42343e0ec357a2f93b1119d1Christian Maeder struct tevent_req *req = tevent_req_callback_data(subreq,
9f4902edfa3d477e42343e0ec357a2f93b1119d1Christian Maeder struct tevent_req);
9f4902edfa3d477e42343e0ec357a2f93b1119d1Christian Maeder struct sdap_connect_state *state = tevent_req_data(req,
9f4902edfa3d477e42343e0ec357a2f93b1119d1Christian Maeder struct sdap_connect_state);
9f4902edfa3d477e42343e0ec357a2f93b1119d1Christian Maeder struct timeval tv;
9f4902edfa3d477e42343e0ec357a2f93b1119d1Christian Maeder int ver;
9ee80c455784287a8b5e1b6bac1f8efa6a2f4bb3cmaeder int lret;
93603bd881e43d4ff5a57d7ca4e2b9fa619f25b4cmaeder int optret;
9ee80c455784287a8b5e1b6bac1f8efa6a2f4bb3cmaeder int ret = EOK;
8865728716566f42fa73e7e0bc080ba3225df764Christian Maeder int msgid;
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder char *errmsg = NULL;
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder bool ldap_referrals;
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder const char *ldap_deref;
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder int ldap_deref_val;
1f2c732265a1292f0d7c51a4a7ca6be5dd370df6cmaeder struct sdap_rebind_proc_params *rebind_proc_params;
1f2c732265a1292f0d7c51a4a7ca6be5dd370df6cmaeder int sd;
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder bool sasl_nocanon;
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder const char *sasl_mech;
beff4152e9f0fe90885458d1a1733b183a2a8816Christian Maeder ber_len_t sasl_minssf;
fdac680252d7347858bd67b4c2a2aaa52e623815Christian Maeder
fdac680252d7347858bd67b4c2a2aaa52e623815Christian Maeder ret = sss_ldap_init_recv(subreq, &state->sh->ldap, &sd);
a9e804dbec424ec36e34bab955cbe90edac5baa6Christian Maeder talloc_zfree(subreq);
f8cc2399c16fcda7e3bf9d901a0de0cc8a455f86Ewaryst Schulz if (ret != EOK) {
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder DEBUG(1, ("sdap_async_connect_call request failed.\n"));
b76d27eba526ecac2a20400fa505ec5c642ae7d2Dominik Luecke tevent_req_error(req, ret);
b76d27eba526ecac2a20400fa505ec5c642ae7d2Dominik Luecke return;
8a5c05062ef501bf725a86a370a5145a198e81fdKlaus Luettich }
8a5c05062ef501bf725a86a370a5145a198e81fdKlaus Luettich
8a5c05062ef501bf725a86a370a5145a198e81fdKlaus Luettich ret = setup_ldap_connection_callbacks(state->sh, state->ev);
2353f65833a3da763392f771223250cd50b8d873Christian Maeder if (ret != EOK) {
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder DEBUG(1, ("setup_ldap_connection_callbacks failed.\n"));
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder goto fail;
2353f65833a3da763392f771223250cd50b8d873Christian Maeder }
2353f65833a3da763392f771223250cd50b8d873Christian Maeder
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder /* If sss_ldap_init_recv() does not return a valid file descriptor we have
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder * to assume that the connection callback will be called by internally by
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder * the OpenLDAP client library. */
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder if (sd != -1) {
a3a7d8b3cdf05c8040c62dbcf9a15dc5042cd721Christian Maeder ret = sdap_call_conn_cb(state->uri, sd, state->sh);
a3a7d8b3cdf05c8040c62dbcf9a15dc5042cd721Christian Maeder if (ret != EOK) {
a3a7d8b3cdf05c8040c62dbcf9a15dc5042cd721Christian Maeder DEBUG(1, ("sdap_call_conn_cb failed.\n"));
0b13f102310e03a20b38c870b5acb88712f316a4Christian Maeder goto fail;
a3a7d8b3cdf05c8040c62dbcf9a15dc5042cd721Christian Maeder }
a3a7d8b3cdf05c8040c62dbcf9a15dc5042cd721Christian Maeder }
a3a7d8b3cdf05c8040c62dbcf9a15dc5042cd721Christian Maeder
00df6fd583c19393fa141d5a0e21ac74c7bf5b19Christian Maeder /* Force ldap version to 3 */
a3a7d8b3cdf05c8040c62dbcf9a15dc5042cd721Christian Maeder ver = LDAP_VERSION3;
cb2044812811d66efe038d914966e04290be93faChristian Maeder lret = ldap_set_option(state->sh->ldap, LDAP_OPT_PROTOCOL_VERSION, &ver);
a3a7d8b3cdf05c8040c62dbcf9a15dc5042cd721Christian Maeder if (lret != LDAP_OPT_SUCCESS) {
96ae1a1d2197d0e0d5b80da2474b64c456feb1b0Christian Maeder DEBUG(1, ("Failed to set ldap version to 3\n"));
a3a7d8b3cdf05c8040c62dbcf9a15dc5042cd721Christian Maeder goto fail;
a3a7d8b3cdf05c8040c62dbcf9a15dc5042cd721Christian Maeder }
8d780c893d6df5dab3dcc7d8444b7517f6547f11Christian Maeder
a3a7d8b3cdf05c8040c62dbcf9a15dc5042cd721Christian Maeder /* TODO: maybe this can be remove when we go async, currently we need it
a3a7d8b3cdf05c8040c62dbcf9a15dc5042cd721Christian Maeder * to handle EINTR during poll(). */
a3a7d8b3cdf05c8040c62dbcf9a15dc5042cd721Christian Maeder ret = ldap_set_option(state->sh->ldap, LDAP_OPT_RESTART, LDAP_OPT_ON);
dff1de7ad15d1582e25d636c3724dd202874897fChristian Maeder if (ret != LDAP_OPT_SUCCESS) {
a3a7d8b3cdf05c8040c62dbcf9a15dc5042cd721Christian Maeder DEBUG(1, ("Failed to set restart option.\n"));
a3a7d8b3cdf05c8040c62dbcf9a15dc5042cd721Christian Maeder }
a3a7d8b3cdf05c8040c62dbcf9a15dc5042cd721Christian Maeder
a3a7d8b3cdf05c8040c62dbcf9a15dc5042cd721Christian Maeder /* Set Network Timeout */
a3a7d8b3cdf05c8040c62dbcf9a15dc5042cd721Christian Maeder tv.tv_sec = dp_opt_get_int(state->opts->basic, SDAP_NETWORK_TIMEOUT);
a3a7d8b3cdf05c8040c62dbcf9a15dc5042cd721Christian Maeder tv.tv_usec = 0;
a3a7d8b3cdf05c8040c62dbcf9a15dc5042cd721Christian Maeder lret = ldap_set_option(state->sh->ldap, LDAP_OPT_NETWORK_TIMEOUT, &tv);
bc263f610d20a9cd3014ddfca903026127fa0d48Christian Maeder if (lret != LDAP_OPT_SUCCESS) {
966519955f5f7111abac20118563132b9dd41165Christian Maeder DEBUG(1, ("Failed to set network timeout to %d\n",
bbba6dd86153aacb0f662b182b128df0eb09fd54Christian Maeder dp_opt_get_int(state->opts->basic, SDAP_NETWORK_TIMEOUT)));
16b71dad8d398af412d66a4f4763f1ada5b03d23Christian Maeder goto fail;
d96bfd1d7a4595bfff87771b91797330fa939455Christian Maeder }
d96bfd1d7a4595bfff87771b91797330fa939455Christian Maeder
8c8545dd3bf34fbcbc16904b65d249658f8f9efcChristian Maeder /* Set Default Timeout */
d27b1887e61f1dc53d77c37f59dbf5019242a686Christian Maeder tv.tv_sec = dp_opt_get_int(state->opts->basic, SDAP_OPT_TIMEOUT);
34d14197eb3dd643a8e6ef3ed8cba5629528e97fAivaras Jakubauskas tv.tv_usec = 0;
9f4902edfa3d477e42343e0ec357a2f93b1119d1Christian Maeder lret = ldap_set_option(state->sh->ldap, LDAP_OPT_TIMEOUT, &tv);
9f4902edfa3d477e42343e0ec357a2f93b1119d1Christian Maeder if (lret != LDAP_OPT_SUCCESS) {
d4ebd9e5adc974cfa2bdf4bdd155e07be0e26f75Christian Maeder DEBUG(1, ("Failed to set default timeout to %d\n",
0d79ea4ed8512a802ecb6645edac141e0fbcee3fChristian Maeder dp_opt_get_int(state->opts->basic, SDAP_OPT_TIMEOUT)));
a31430de8b0632d29f42634d6395e982bf31b14dChristian Maeder goto fail;
ce8a93047aaf0dc36fa221642292d47852a9862aChristian Maeder }
9ee80c455784287a8b5e1b6bac1f8efa6a2f4bb3cmaeder
d4ebd9e5adc974cfa2bdf4bdd155e07be0e26f75Christian Maeder /* Set Referral chasing */
a3a7d8b3cdf05c8040c62dbcf9a15dc5042cd721Christian Maeder ldap_referrals = dp_opt_get_bool(state->opts->basic, SDAP_REFERRALS);
b6ff72be73dad3d1394cf2c71e29e67624ff030bChristian Maeder lret = ldap_set_option(state->sh->ldap, LDAP_OPT_REFERRALS,
b6ff72be73dad3d1394cf2c71e29e67624ff030bChristian Maeder (ldap_referrals ? LDAP_OPT_ON : LDAP_OPT_OFF));
a3a7d8b3cdf05c8040c62dbcf9a15dc5042cd721Christian Maeder if (lret != LDAP_OPT_SUCCESS) {
a3a7d8b3cdf05c8040c62dbcf9a15dc5042cd721Christian Maeder DEBUG(1, ("Failed to set referral chasing to %s\n",
a3a7d8b3cdf05c8040c62dbcf9a15dc5042cd721Christian Maeder (ldap_referrals ? "LDAP_OPT_ON" : "LDAP_OPT_OFF")));
a3a7d8b3cdf05c8040c62dbcf9a15dc5042cd721Christian Maeder goto fail;
0b13f102310e03a20b38c870b5acb88712f316a4Christian Maeder }
2360728d4185c0c04279c999941c64d36626af79Christian Maeder
a3a7d8b3cdf05c8040c62dbcf9a15dc5042cd721Christian Maeder if (ldap_referrals) {
a3a7d8b3cdf05c8040c62dbcf9a15dc5042cd721Christian Maeder rebind_proc_params = talloc_zero(state->sh,
00df6fd583c19393fa141d5a0e21ac74c7bf5b19Christian Maeder struct sdap_rebind_proc_params);
2360728d4185c0c04279c999941c64d36626af79Christian Maeder if (rebind_proc_params == NULL) {
2360728d4185c0c04279c999941c64d36626af79Christian Maeder DEBUG(1, ("talloc_zero failed.\n"));
a3a7d8b3cdf05c8040c62dbcf9a15dc5042cd721Christian Maeder ret = ENOMEM;
96ae1a1d2197d0e0d5b80da2474b64c456feb1b0Christian Maeder goto fail;
2360728d4185c0c04279c999941c64d36626af79Christian Maeder }
a3a7d8b3cdf05c8040c62dbcf9a15dc5042cd721Christian Maeder
8d780c893d6df5dab3dcc7d8444b7517f6547f11Christian Maeder rebind_proc_params->opts = state->opts;
2360728d4185c0c04279c999941c64d36626af79Christian Maeder rebind_proc_params->sh = state->sh;
a3a7d8b3cdf05c8040c62dbcf9a15dc5042cd721Christian Maeder rebind_proc_params->use_start_tls = state->use_start_tls;
dff1de7ad15d1582e25d636c3724dd202874897fChristian Maeder
2360728d4185c0c04279c999941c64d36626af79Christian Maeder lret = ldap_set_rebind_proc(state->sh->ldap, sdap_rebind_proc,
a3a7d8b3cdf05c8040c62dbcf9a15dc5042cd721Christian Maeder rebind_proc_params);
a3a7d8b3cdf05c8040c62dbcf9a15dc5042cd721Christian Maeder if (lret != LDAP_SUCCESS) {
a3a7d8b3cdf05c8040c62dbcf9a15dc5042cd721Christian Maeder DEBUG(1, ("ldap_set_rebind_proc failed.\n"));
a3a7d8b3cdf05c8040c62dbcf9a15dc5042cd721Christian Maeder goto fail;
a3a7d8b3cdf05c8040c62dbcf9a15dc5042cd721Christian Maeder }
a3a7d8b3cdf05c8040c62dbcf9a15dc5042cd721Christian Maeder }
a3a7d8b3cdf05c8040c62dbcf9a15dc5042cd721Christian Maeder
bc263f610d20a9cd3014ddfca903026127fa0d48Christian Maeder /* Set alias dereferencing */
966519955f5f7111abac20118563132b9dd41165Christian Maeder ldap_deref = dp_opt_get_string(state->opts->basic, SDAP_DEREF);
bbba6dd86153aacb0f662b182b128df0eb09fd54Christian Maeder if (ldap_deref != NULL) {
5a448e9be8c4482a978b174b744237757335140fChristian Maeder ret = deref_string_to_val(ldap_deref, &ldap_deref_val);
d96bfd1d7a4595bfff87771b91797330fa939455Christian Maeder if (ret != EOK) {
8c8545dd3bf34fbcbc16904b65d249658f8f9efcChristian Maeder DEBUG(1, ("deref_string_to_val failed.\n"));
d27b1887e61f1dc53d77c37f59dbf5019242a686Christian Maeder goto fail;
34d14197eb3dd643a8e6ef3ed8cba5629528e97fAivaras Jakubauskas }
9f4902edfa3d477e42343e0ec357a2f93b1119d1Christian Maeder
9f4902edfa3d477e42343e0ec357a2f93b1119d1Christian Maeder lret = ldap_set_option(state->sh->ldap, LDAP_OPT_DEREF, &ldap_deref_val);
d4ebd9e5adc974cfa2bdf4bdd155e07be0e26f75Christian Maeder if (lret != LDAP_OPT_SUCCESS) {
0d79ea4ed8512a802ecb6645edac141e0fbcee3fChristian Maeder DEBUG(1, ("Failed to set deref option to %d\n", ldap_deref_val));
a31430de8b0632d29f42634d6395e982bf31b14dChristian Maeder goto fail;
ce8a93047aaf0dc36fa221642292d47852a9862aChristian Maeder }
9ee80c455784287a8b5e1b6bac1f8efa6a2f4bb3cmaeder
d4ebd9e5adc974cfa2bdf4bdd155e07be0e26f75Christian Maeder }
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder /* Set host name canonicalization for LDAP SASL bind */
9f4902edfa3d477e42343e0ec357a2f93b1119d1Christian Maeder sasl_nocanon = !dp_opt_get_bool(state->opts->basic, SDAP_SASL_CANONICALIZE);
9f4902edfa3d477e42343e0ec357a2f93b1119d1Christian Maeder lret = ldap_set_option(state->sh->ldap, LDAP_OPT_X_SASL_NOCANON,
9f4902edfa3d477e42343e0ec357a2f93b1119d1Christian Maeder sasl_nocanon ? LDAP_OPT_ON : LDAP_OPT_OFF);
9f4902edfa3d477e42343e0ec357a2f93b1119d1Christian Maeder if (lret != LDAP_OPT_SUCCESS) {
9f4902edfa3d477e42343e0ec357a2f93b1119d1Christian Maeder /* Do not fail, just warn into both debug logs and syslog */
ce8a93047aaf0dc36fa221642292d47852a9862aChristian Maeder DEBUG(SSSDBG_MINOR_FAILURE,
a3a7d8b3cdf05c8040c62dbcf9a15dc5042cd721Christian Maeder ("Failed to set LDAP SASL nocanon option to %s. If your system "
ce8a93047aaf0dc36fa221642292d47852a9862aChristian Maeder "is configured to use SASL, LDAP operations might fail.\n",
ce8a93047aaf0dc36fa221642292d47852a9862aChristian Maeder sasl_nocanon ? "true" : "false"));
ce8a93047aaf0dc36fa221642292d47852a9862aChristian Maeder sss_log(SSS_LOG_INFO,
a3a7d8b3cdf05c8040c62dbcf9a15dc5042cd721Christian Maeder "Failed to set LDAP SASL nocanon option to %s. If your system "
0b13f102310e03a20b38c870b5acb88712f316a4Christian Maeder "is configured to use SASL, LDAP operations might fail.\n",
dff1de7ad15d1582e25d636c3724dd202874897fChristian Maeder sasl_nocanon ? "true" : "false");
0b13f102310e03a20b38c870b5acb88712f316a4Christian Maeder }
0b13f102310e03a20b38c870b5acb88712f316a4Christian Maeder
dff1de7ad15d1582e25d636c3724dd202874897fChristian Maeder sasl_mech = dp_opt_get_string(state->opts->basic, SDAP_SASL_MECH);
0b13f102310e03a20b38c870b5acb88712f316a4Christian Maeder if (sasl_mech != NULL) {
9ee80c455784287a8b5e1b6bac1f8efa6a2f4bb3cmaeder sasl_minssf = (ber_len_t) dp_opt_get_int(state->opts->basic,
9ee80c455784287a8b5e1b6bac1f8efa6a2f4bb3cmaeder SDAP_SASL_MINSSF);
9ee80c455784287a8b5e1b6bac1f8efa6a2f4bb3cmaeder lret = ldap_set_option(state->sh->ldap, LDAP_OPT_X_SASL_SSF_MIN,
cb2044812811d66efe038d914966e04290be93faChristian Maeder &sasl_minssf);
0b13f102310e03a20b38c870b5acb88712f316a4Christian Maeder if (lret != LDAP_OPT_SUCCESS) {
96ae1a1d2197d0e0d5b80da2474b64c456feb1b0Christian Maeder DEBUG(SSSDBG_CRIT_FAILURE,
0b13f102310e03a20b38c870b5acb88712f316a4Christian Maeder ("Failed to set LDAP MIN SSF option to %lu\n", sasl_minssf));
0b13f102310e03a20b38c870b5acb88712f316a4Christian Maeder goto fail;
96ae1a1d2197d0e0d5b80da2474b64c456feb1b0Christian Maeder }
96ae1a1d2197d0e0d5b80da2474b64c456feb1b0Christian Maeder }
0b13f102310e03a20b38c870b5acb88712f316a4Christian Maeder
ce8a93047aaf0dc36fa221642292d47852a9862aChristian Maeder /* if we do not use start_tls the connection is not really connected yet
ce8a93047aaf0dc36fa221642292d47852a9862aChristian Maeder * just fake an async procedure and leave connection to the bind call */
ce8a93047aaf0dc36fa221642292d47852a9862aChristian Maeder if (!state->use_start_tls) {
9f4902edfa3d477e42343e0ec357a2f93b1119d1Christian Maeder tevent_req_done(req);
9f4902edfa3d477e42343e0ec357a2f93b1119d1Christian Maeder return;
16b71dad8d398af412d66a4f4763f1ada5b03d23Christian Maeder }
96ae1a1d2197d0e0d5b80da2474b64c456feb1b0Christian Maeder
ce8a93047aaf0dc36fa221642292d47852a9862aChristian Maeder DEBUG(4, ("Executing START TLS\n"));
ce8a93047aaf0dc36fa221642292d47852a9862aChristian Maeder
ce8a93047aaf0dc36fa221642292d47852a9862aChristian Maeder lret = ldap_start_tls(state->sh->ldap, NULL, NULL, &msgid);
ce8a93047aaf0dc36fa221642292d47852a9862aChristian Maeder if (lret != LDAP_SUCCESS) {
0b13f102310e03a20b38c870b5acb88712f316a4Christian Maeder optret = sss_ldap_get_diagnostic_msg(state, state->sh->ldap,
0b13f102310e03a20b38c870b5acb88712f316a4Christian Maeder &errmsg);
0b13f102310e03a20b38c870b5acb88712f316a4Christian Maeder if (optret == LDAP_SUCCESS) {
0b13f102310e03a20b38c870b5acb88712f316a4Christian Maeder DEBUG(3, ("ldap_start_tls failed: [%s] [%s]\n",
a3a7d8b3cdf05c8040c62dbcf9a15dc5042cd721Christian Maeder sss_ldap_err2string(lret),
a3a7d8b3cdf05c8040c62dbcf9a15dc5042cd721Christian Maeder errmsg));
8bb80c9684e905de8dcfcfb1291542677e7d77b6Christian Maeder sss_log(SSS_LOG_ERR, "Could not start TLS. %s", errmsg);
ce8a93047aaf0dc36fa221642292d47852a9862aChristian Maeder }
ce8a93047aaf0dc36fa221642292d47852a9862aChristian Maeder else {
ce8a93047aaf0dc36fa221642292d47852a9862aChristian Maeder DEBUG(3, ("ldap_start_tls failed: [%s]\n",
dff1de7ad15d1582e25d636c3724dd202874897fChristian Maeder sss_ldap_err2string(lret)));
8bb80c9684e905de8dcfcfb1291542677e7d77b6Christian Maeder sss_log(SSS_LOG_ERR, "Could not start TLS. "
00df6fd583c19393fa141d5a0e21ac74c7bf5b19Christian Maeder "Check for certificate issues.");
a3a7d8b3cdf05c8040c62dbcf9a15dc5042cd721Christian Maeder }
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder goto fail;
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder }
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder
b6ff72be73dad3d1394cf2c71e29e67624ff030bChristian Maeder ret = sdap_set_connected(state->sh, state->ev);
a3a7d8b3cdf05c8040c62dbcf9a15dc5042cd721Christian Maeder if (ret) goto fail;
a3a7d8b3cdf05c8040c62dbcf9a15dc5042cd721Christian Maeder
a3a7d8b3cdf05c8040c62dbcf9a15dc5042cd721Christian Maeder /* FIXME: get timeouts from configuration, for now 5 secs. */
a3a7d8b3cdf05c8040c62dbcf9a15dc5042cd721Christian Maeder ret = sdap_op_add(state, state->ev, state->sh, msgid,
a3a7d8b3cdf05c8040c62dbcf9a15dc5042cd721Christian Maeder sdap_connect_done, req, 5, &state->op);
a3a7d8b3cdf05c8040c62dbcf9a15dc5042cd721Christian Maeder if (ret) {
a3a7d8b3cdf05c8040c62dbcf9a15dc5042cd721Christian Maeder DEBUG(1, ("Failed to set up operation!\n"));
a3a7d8b3cdf05c8040c62dbcf9a15dc5042cd721Christian Maeder goto fail;
bc263f610d20a9cd3014ddfca903026127fa0d48Christian Maeder }
966519955f5f7111abac20118563132b9dd41165Christian Maeder
a3a7d8b3cdf05c8040c62dbcf9a15dc5042cd721Christian Maeder return;
a3a7d8b3cdf05c8040c62dbcf9a15dc5042cd721Christian Maeder
a3a7d8b3cdf05c8040c62dbcf9a15dc5042cd721Christian Maederfail:
a3a7d8b3cdf05c8040c62dbcf9a15dc5042cd721Christian Maeder if (ret) {
dff1de7ad15d1582e25d636c3724dd202874897fChristian Maeder tevent_req_error(req, ret);
a3a7d8b3cdf05c8040c62dbcf9a15dc5042cd721Christian Maeder } else {
cb2044812811d66efe038d914966e04290be93faChristian Maeder if (lret == LDAP_SERVER_DOWN) {
a3a7d8b3cdf05c8040c62dbcf9a15dc5042cd721Christian Maeder tevent_req_error(req, ETIMEDOUT);
8d780c893d6df5dab3dcc7d8444b7517f6547f11Christian Maeder } else {
a3a7d8b3cdf05c8040c62dbcf9a15dc5042cd721Christian Maeder tevent_req_error(req, EIO);
96ae1a1d2197d0e0d5b80da2474b64c456feb1b0Christian Maeder }
a3a7d8b3cdf05c8040c62dbcf9a15dc5042cd721Christian Maeder }
a3a7d8b3cdf05c8040c62dbcf9a15dc5042cd721Christian Maeder return;
a3a7d8b3cdf05c8040c62dbcf9a15dc5042cd721Christian Maeder}
00df6fd583c19393fa141d5a0e21ac74c7bf5b19Christian Maeder
a3a7d8b3cdf05c8040c62dbcf9a15dc5042cd721Christian Maederstatic void sdap_connect_done(struct sdap_op *op,
a3a7d8b3cdf05c8040c62dbcf9a15dc5042cd721Christian Maeder struct sdap_msg *reply,
a3a7d8b3cdf05c8040c62dbcf9a15dc5042cd721Christian Maeder int error, void *pvt)
a3a7d8b3cdf05c8040c62dbcf9a15dc5042cd721Christian Maeder{
bbba6dd86153aacb0f662b182b128df0eb09fd54Christian Maeder struct tevent_req *req = talloc_get_type(pvt, struct tevent_req);
16b71dad8d398af412d66a4f4763f1ada5b03d23Christian Maeder struct sdap_connect_state *state = tevent_req_data(req,
8c8545dd3bf34fbcbc16904b65d249658f8f9efcChristian Maeder struct sdap_connect_state);
33fcc19ef2b59493b4e91eebf701df95fd230765Christian Maeder char *errmsg = NULL;
d27b1887e61f1dc53d77c37f59dbf5019242a686Christian Maeder char *tlserr;
a3a7d8b3cdf05c8040c62dbcf9a15dc5042cd721Christian Maeder int ret;
9f4902edfa3d477e42343e0ec357a2f93b1119d1Christian Maeder int optret;
9f4902edfa3d477e42343e0ec357a2f93b1119d1Christian Maeder
34d14197eb3dd643a8e6ef3ed8cba5629528e97fAivaras Jakubauskas if (error) {
0d79ea4ed8512a802ecb6645edac141e0fbcee3fChristian Maeder tevent_req_error(req, error);
d4ebd9e5adc974cfa2bdf4bdd155e07be0e26f75Christian Maeder return;
a31430de8b0632d29f42634d6395e982bf31b14dChristian Maeder }
ce8a93047aaf0dc36fa221642292d47852a9862aChristian Maeder
9ee80c455784287a8b5e1b6bac1f8efa6a2f4bb3cmaeder state->reply = talloc_steal(state, reply);
0b13f102310e03a20b38c870b5acb88712f316a4Christian Maeder
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder ret = ldap_parse_result(state->sh->ldap, state->reply->msg,
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder &state->result, NULL, &errmsg, NULL, NULL, 0);
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder if (ret != LDAP_SUCCESS) {
9f4902edfa3d477e42343e0ec357a2f93b1119d1Christian Maeder DEBUG(2, ("ldap_parse_result failed (%d)\n", state->op->msgid));
9f4902edfa3d477e42343e0ec357a2f93b1119d1Christian Maeder tevent_req_error(req, EIO);
9f4902edfa3d477e42343e0ec357a2f93b1119d1Christian Maeder return;
12aef5992d3af07dee81a4e02cf4be65a83f28bcChristian Maeder }
2360728d4185c0c04279c999941c64d36626af79Christian Maeder
2360728d4185c0c04279c999941c64d36626af79Christian Maeder DEBUG(3, ("START TLS result: %s(%d), %s\n",
9f4902edfa3d477e42343e0ec357a2f93b1119d1Christian Maeder sss_ldap_err2string(state->result), state->result, errmsg));
9f4902edfa3d477e42343e0ec357a2f93b1119d1Christian Maeder ldap_memfree(errmsg);
a3a7d8b3cdf05c8040c62dbcf9a15dc5042cd721Christian Maeder
f39b8dd9651dfcc38b06191cda23cacbfc298323Christian Maeder if (ldap_tls_inplace(state->sh->ldap)) {
2360728d4185c0c04279c999941c64d36626af79Christian Maeder DEBUG(9, ("SSL/TLS handler already in place.\n"));
2360728d4185c0c04279c999941c64d36626af79Christian Maeder tevent_req_done(req);
0130083f314580170af1195037be3325f125fbceChristian Maeder return;
d81905a5b924415c524d702df26204683c82c12eChristian Maeder }
96ae1a1d2197d0e0d5b80da2474b64c456feb1b0Christian Maeder
2360728d4185c0c04279c999941c64d36626af79Christian Maeder/* FIXME: take care that ldap_install_tls might block */
f39b8dd9651dfcc38b06191cda23cacbfc298323Christian Maeder ret = ldap_install_tls(state->sh->ldap);
8d780c893d6df5dab3dcc7d8444b7517f6547f11Christian Maeder if (ret != LDAP_SUCCESS) {
2360728d4185c0c04279c999941c64d36626af79Christian Maeder
bc263f610d20a9cd3014ddfca903026127fa0d48Christian Maeder optret = sss_ldap_get_diagnostic_msg(state, state->sh->ldap,
966519955f5f7111abac20118563132b9dd41165Christian Maeder &tlserr);
2360728d4185c0c04279c999941c64d36626af79Christian Maeder if (optret == LDAP_SUCCESS) {
2360728d4185c0c04279c999941c64d36626af79Christian Maeder DEBUG(3, ("ldap_install_tls failed: [%s] [%s]\n",
00df6fd583c19393fa141d5a0e21ac74c7bf5b19Christian Maeder sss_ldap_err2string(ret),
2360728d4185c0c04279c999941c64d36626af79Christian Maeder tlserr));
f39b8dd9651dfcc38b06191cda23cacbfc298323Christian Maeder sss_log(SSS_LOG_ERR, "Could not start TLS encryption. %s", tlserr);
dff1de7ad15d1582e25d636c3724dd202874897fChristian Maeder }
2360728d4185c0c04279c999941c64d36626af79Christian Maeder else {
2360728d4185c0c04279c999941c64d36626af79Christian Maeder DEBUG(3, ("ldap_install_tls failed: [%s]\n",
2360728d4185c0c04279c999941c64d36626af79Christian Maeder sss_ldap_err2string(ret)));
2360728d4185c0c04279c999941c64d36626af79Christian Maeder sss_log(SSS_LOG_ERR, "Could not start TLS encryption. "
2360728d4185c0c04279c999941c64d36626af79Christian Maeder "Check for certificate issues.");
d27b1887e61f1dc53d77c37f59dbf5019242a686Christian Maeder }
8994ef587ce7c7c39ddd20f0f7e4575838a6694aChristian Maeder
33fcc19ef2b59493b4e91eebf701df95fd230765Christian Maeder state->result = ret;
ce8a93047aaf0dc36fa221642292d47852a9862aChristian Maeder tevent_req_error(req, EIO);
ce8a93047aaf0dc36fa221642292d47852a9862aChristian Maeder return;
ce8a93047aaf0dc36fa221642292d47852a9862aChristian Maeder }
ce8a93047aaf0dc36fa221642292d47852a9862aChristian Maeder
ce8a93047aaf0dc36fa221642292d47852a9862aChristian Maeder tevent_req_done(req);
0b13f102310e03a20b38c870b5acb88712f316a4Christian Maeder}
9ee80c455784287a8b5e1b6bac1f8efa6a2f4bb3cmaeder
2360728d4185c0c04279c999941c64d36626af79Christian Maederint sdap_connect_recv(struct tevent_req *req,
2360728d4185c0c04279c999941c64d36626af79Christian Maeder TALLOC_CTX *memctx,
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder struct sdap_handle **sh)
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder{
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder struct sdap_connect_state *state = tevent_req_data(req,
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder struct sdap_connect_state);
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder
a3a7d8b3cdf05c8040c62dbcf9a15dc5042cd721Christian Maeder TEVENT_REQ_RETURN_ON_ERROR(req);
a3a7d8b3cdf05c8040c62dbcf9a15dc5042cd721Christian Maeder
dff1de7ad15d1582e25d636c3724dd202874897fChristian Maeder *sh = talloc_steal(memctx, state->sh);
a3a7d8b3cdf05c8040c62dbcf9a15dc5042cd721Christian Maeder if (!*sh) {
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder return ENOMEM;
91e24fc45834b35f2a3830d72565640251149bf3Christian Maeder }
91e24fc45834b35f2a3830d72565640251149bf3Christian Maeder return EOK;
91e24fc45834b35f2a3830d72565640251149bf3Christian Maeder}
91e24fc45834b35f2a3830d72565640251149bf3Christian Maeder
91e24fc45834b35f2a3830d72565640251149bf3Christian Maeder/* ==Simple-Bind========================================================== */
91e24fc45834b35f2a3830d72565640251149bf3Christian Maeder
b53688bfed888214b485cf76439d57262d80e0a7Christian Maederstruct simple_bind_state {
a3a7d8b3cdf05c8040c62dbcf9a15dc5042cd721Christian Maeder struct tevent_context *ev;
d56ece59c372cb887355825901222b9f3377f7e6Thiemo Wiedemeyer struct sdap_handle *sh;
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder const char *user_dn;
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder struct berval *pw;
a3a7d8b3cdf05c8040c62dbcf9a15dc5042cd721Christian Maeder
a3a7d8b3cdf05c8040c62dbcf9a15dc5042cd721Christian Maeder struct sdap_op *op;
2360728d4185c0c04279c999941c64d36626af79Christian Maeder
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder struct sdap_msg *reply;
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder struct sdap_ppolicy_data *ppolicy;
a3a7d8b3cdf05c8040c62dbcf9a15dc5042cd721Christian Maeder int result;
a3a7d8b3cdf05c8040c62dbcf9a15dc5042cd721Christian Maeder};
a3a7d8b3cdf05c8040c62dbcf9a15dc5042cd721Christian Maeder
a3a7d8b3cdf05c8040c62dbcf9a15dc5042cd721Christian Maederstatic void simple_bind_done(struct sdap_op *op,
8762d0e3d492aba4d1621fb0de685f0be1372864notanartist struct sdap_msg *reply,
bbba10ee00dcf6bcbc9f22473b1acd0983b10512notanartist int error, void *pvt);
a3a7d8b3cdf05c8040c62dbcf9a15dc5042cd721Christian Maeder
76d027be764e2ff61bef959efb3ac8f56499e646Christian Maederstatic struct tevent_req *simple_bind_send(TALLOC_CTX *memctx,
9f85afecbd79b3df5a0bb17bd28cd0b288dc3213Kristina Sojakova struct tevent_context *ev,
a166da43d4e8f9dfa7a2651d033c6bea02627ca6Mihai Codescu struct sdap_handle *sh,
22b772f8753f0cdb4508ba460356c238de2ee375Jonathan von Schroeder const char *user_dn,
7bbfb15142ab4286dfc6fcde2fc94a5512297e41Jonathan von Schroeder struct berval *pw)
a3a7d8b3cdf05c8040c62dbcf9a15dc5042cd721Christian Maeder{
a3a7d8b3cdf05c8040c62dbcf9a15dc5042cd721Christian Maeder struct tevent_req *req;
63da71bfb4226f504944b293fb77177ebcaea7d4Ewaryst Schulz struct simple_bind_state *state;
a3a7d8b3cdf05c8040c62dbcf9a15dc5042cd721Christian Maeder int ret = EOK;
a3a7d8b3cdf05c8040c62dbcf9a15dc5042cd721Christian Maeder int msgid;
8762d0e3d492aba4d1621fb0de685f0be1372864notanartist int ldap_err;
af6e92e4a9ca308f928f9909acee115f801c5db5Ewaryst Schulz LDAPControl **request_controls = NULL;
b47b1ea8a412f6e4c731779f6a572384e7cf06d8Christian Maeder LDAPControl *ctrls[2] = { NULL, NULL };
26b1c101b72100b69045effdfaab3889de6c8c93Christian Maeder
a68ff26ddb1d300f7e16097edef615f130fcd5ceChristian Maeder req = tevent_req_create(memctx, &state, struct simple_bind_state);
9f226cec9f978edaba67aee4c4e04e3d3b994b87Daniel Calegari if (!req) return NULL;
f730570f7c284b252ad2e24cf23cc594021f9e25Jonathan von Schroeder
6f70475dddc12732bdbef3e3dd116373e34cd6b9Christian Maeder state->reply = talloc(state, struct sdap_msg);
897a04683fb30873e84dc3360dea770a4435971cChristian Maeder if (!state->reply) {
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder talloc_zfree(req);
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder return NULL;
a3a7d8b3cdf05c8040c62dbcf9a15dc5042cd721Christian Maeder }
a3a7d8b3cdf05c8040c62dbcf9a15dc5042cd721Christian Maeder
a3a7d8b3cdf05c8040c62dbcf9a15dc5042cd721Christian Maeder state->ev = ev;
a3a7d8b3cdf05c8040c62dbcf9a15dc5042cd721Christian Maeder state->sh = sh;
8762d0e3d492aba4d1621fb0de685f0be1372864notanartist state->user_dn = user_dn;
bbba10ee00dcf6bcbc9f22473b1acd0983b10512notanartist state->pw = pw;
a3a7d8b3cdf05c8040c62dbcf9a15dc5042cd721Christian Maeder
63da71bfb4226f504944b293fb77177ebcaea7d4Ewaryst Schulz ret = sss_ldap_control_create(LDAP_CONTROL_PASSWORDPOLICYREQUEST,
76d027be764e2ff61bef959efb3ac8f56499e646Christian Maeder 0, NULL, 0, &ctrls[0]);
9f85afecbd79b3df5a0bb17bd28cd0b288dc3213Kristina Sojakova if (ret != LDAP_SUCCESS && ret != LDAP_NOT_SUPPORTED) {
a166da43d4e8f9dfa7a2651d033c6bea02627ca6Mihai Codescu DEBUG(1, ("sss_ldap_control_create failed to create "
22b772f8753f0cdb4508ba460356c238de2ee375Jonathan von Schroeder "Password Policy control.\n"));
7bbfb15142ab4286dfc6fcde2fc94a5512297e41Jonathan von Schroeder goto fail;
f730570f7c284b252ad2e24cf23cc594021f9e25Jonathan von Schroeder }
a3a7d8b3cdf05c8040c62dbcf9a15dc5042cd721Christian Maeder request_controls = ctrls;
a3a7d8b3cdf05c8040c62dbcf9a15dc5042cd721Christian Maeder
a3a7d8b3cdf05c8040c62dbcf9a15dc5042cd721Christian Maeder DEBUG(4, ("Executing simple bind as: %s\n", state->user_dn));
a3a7d8b3cdf05c8040c62dbcf9a15dc5042cd721Christian Maeder
8762d0e3d492aba4d1621fb0de685f0be1372864notanartist ret = ldap_sasl_bind(state->sh->ldap, state->user_dn, LDAP_SASL_SIMPLE,
af6e92e4a9ca308f928f9909acee115f801c5db5Ewaryst Schulz state->pw, request_controls, NULL, &msgid);
b47b1ea8a412f6e4c731779f6a572384e7cf06d8Christian Maeder if (ctrls[0]) ldap_control_free(ctrls[0]);
26b1c101b72100b69045effdfaab3889de6c8c93Christian Maeder if (ret == -1 || msgid == -1) {
a68ff26ddb1d300f7e16097edef615f130fcd5ceChristian Maeder ret = ldap_get_option(state->sh->ldap,
9f226cec9f978edaba67aee4c4e04e3d3b994b87Daniel Calegari LDAP_OPT_RESULT_CODE, &ldap_err);
6f70475dddc12732bdbef3e3dd116373e34cd6b9Christian Maeder if (ret != LDAP_OPT_SUCCESS) {
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder DEBUG(1, ("ldap_bind failed (couldn't get ldap error)\n"));
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder ret = LDAP_LOCAL_ERROR;
2353f65833a3da763392f771223250cd50b8d873Christian Maeder } else {
1ebf8299efa3cdb39c73d40d15e1d1a8a2246e68notanartist DEBUG(1, ("ldap_bind failed (%d)[%s]\n",
1ebf8299efa3cdb39c73d40d15e1d1a8a2246e68notanartist ldap_err, sss_ldap_err2string(ldap_err)));
1ebf8299efa3cdb39c73d40d15e1d1a8a2246e68notanartist ret = ldap_err;
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder }
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder goto fail;
897a04683fb30873e84dc3360dea770a4435971cChristian Maeder }
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder DEBUG(8, ("ldap simple bind sent, msgid = %d\n", msgid));
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder
a3a7d8b3cdf05c8040c62dbcf9a15dc5042cd721Christian Maeder if (!sh->connected) {
a3a7d8b3cdf05c8040c62dbcf9a15dc5042cd721Christian Maeder ret = sdap_set_connected(sh, ev);
a3a7d8b3cdf05c8040c62dbcf9a15dc5042cd721Christian Maeder if (ret) goto fail;
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder }
8762d0e3d492aba4d1621fb0de685f0be1372864notanartist
1ebf8299efa3cdb39c73d40d15e1d1a8a2246e68notanartist /* FIXME: get timeouts from configuration, for now 5 secs. */
1ebf8299efa3cdb39c73d40d15e1d1a8a2246e68notanartist ret = sdap_op_add(state, ev, sh, msgid,
8762d0e3d492aba4d1621fb0de685f0be1372864notanartist simple_bind_done, req, 5, &state->op);
1ebf8299efa3cdb39c73d40d15e1d1a8a2246e68notanartist if (ret) {
1ebf8299efa3cdb39c73d40d15e1d1a8a2246e68notanartist DEBUG(1, ("Failed to set up operation!\n"));
1ebf8299efa3cdb39c73d40d15e1d1a8a2246e68notanartist goto fail;
1ebf8299efa3cdb39c73d40d15e1d1a8a2246e68notanartist }
1ebf8299efa3cdb39c73d40d15e1d1a8a2246e68notanartist
1ebf8299efa3cdb39c73d40d15e1d1a8a2246e68notanartist return req;
1ebf8299efa3cdb39c73d40d15e1d1a8a2246e68notanartist
1ebf8299efa3cdb39c73d40d15e1d1a8a2246e68notanartistfail:
1ebf8299efa3cdb39c73d40d15e1d1a8a2246e68notanartist if (ret == LDAP_SERVER_DOWN) {
1ebf8299efa3cdb39c73d40d15e1d1a8a2246e68notanartist tevent_req_error(req, ETIMEDOUT);
bbba10ee00dcf6bcbc9f22473b1acd0983b10512notanartist } else {
bbba10ee00dcf6bcbc9f22473b1acd0983b10512notanartist tevent_req_error(req, EIO);
bbba10ee00dcf6bcbc9f22473b1acd0983b10512notanartist }
bbba10ee00dcf6bcbc9f22473b1acd0983b10512notanartist tevent_req_post(req, ev);
bbba10ee00dcf6bcbc9f22473b1acd0983b10512notanartist return req;
bbba10ee00dcf6bcbc9f22473b1acd0983b10512notanartist}
bbba10ee00dcf6bcbc9f22473b1acd0983b10512notanartist
bbba10ee00dcf6bcbc9f22473b1acd0983b10512notanartiststatic void simple_bind_done(struct sdap_op *op,
bbba10ee00dcf6bcbc9f22473b1acd0983b10512notanartist struct sdap_msg *reply,
bbba10ee00dcf6bcbc9f22473b1acd0983b10512notanartist int error, void *pvt)
8762d0e3d492aba4d1621fb0de685f0be1372864notanartist{
bbba10ee00dcf6bcbc9f22473b1acd0983b10512notanartist struct tevent_req *req = talloc_get_type(pvt, struct tevent_req);
df87ff823273ae2969e9d29e833845b4c0a9ee77notanartist struct simple_bind_state *state = tevent_req_data(req,
df87ff823273ae2969e9d29e833845b4c0a9ee77notanartist struct simple_bind_state);
df87ff823273ae2969e9d29e833845b4c0a9ee77notanartist char *errmsg = NULL;
df87ff823273ae2969e9d29e833845b4c0a9ee77notanartist char *nval;
df87ff823273ae2969e9d29e833845b4c0a9ee77notanartist errno_t ret;
df87ff823273ae2969e9d29e833845b4c0a9ee77notanartist int lret;
df87ff823273ae2969e9d29e833845b4c0a9ee77notanartist LDAPControl **response_controls;
df87ff823273ae2969e9d29e833845b4c0a9ee77notanartist int c;
c3b00d3435293c71ab4e750be084a2d8dcf6209fnotanartist ber_int_t pp_grace;
7ebcceae3d34771cae3bbb8c8060bef0b894376eChristian Maeder ber_int_t pp_expire;
8a5c05062ef501bf725a86a370a5145a198e81fdKlaus Luettich LDAPPasswordPolicyError pp_error;
8a5c05062ef501bf725a86a370a5145a198e81fdKlaus Luettich
a3a7d8b3cdf05c8040c62dbcf9a15dc5042cd721Christian Maeder if (error) {
a3a7d8b3cdf05c8040c62dbcf9a15dc5042cd721Christian Maeder tevent_req_error(req, error);
2360728d4185c0c04279c999941c64d36626af79Christian Maeder return;
8a5c05062ef501bf725a86a370a5145a198e81fdKlaus Luettich }
8a5c05062ef501bf725a86a370a5145a198e81fdKlaus Luettich
7ebcceae3d34771cae3bbb8c8060bef0b894376eChristian Maeder state->reply = talloc_steal(state, reply);
8a5c05062ef501bf725a86a370a5145a198e81fdKlaus Luettich
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder lret = ldap_parse_result(state->sh->ldap, state->reply->msg,
a3a7d8b3cdf05c8040c62dbcf9a15dc5042cd721Christian Maeder &state->result, NULL, &errmsg, NULL,
a3a7d8b3cdf05c8040c62dbcf9a15dc5042cd721Christian Maeder &response_controls, 0);
a3a7d8b3cdf05c8040c62dbcf9a15dc5042cd721Christian Maeder if (lret != LDAP_SUCCESS) {
a3a7d8b3cdf05c8040c62dbcf9a15dc5042cd721Christian Maeder DEBUG(SSSDBG_MINOR_FAILURE,
a3a7d8b3cdf05c8040c62dbcf9a15dc5042cd721Christian Maeder ("ldap_parse_result failed (%d)\n", state->op->msgid));
bbba10ee00dcf6bcbc9f22473b1acd0983b10512notanartist ret = EIO;
3ec3a22fe2b9c38a3575c98a82b4e3f988af64a6Eugen Kuksa goto done;
4c872eeb600fe8479dbda395405cf13c3d573c24Soeren D. Schulze }
a3a7d8b3cdf05c8040c62dbcf9a15dc5042cd721Christian Maeder
bc263f610d20a9cd3014ddfca903026127fa0d48Christian Maeder if (response_controls == NULL) {
024703c9d1326c23e307c0b0d453ed3358e87fe4cmaeder DEBUG(SSSDBG_TRACE_LIBS, ("Server returned no controls.\n"));
f8cc2399c16fcda7e3bf9d901a0de0cc8a455f86Ewaryst Schulz state->ppolicy = NULL;
a3a7d8b3cdf05c8040c62dbcf9a15dc5042cd721Christian Maeder } else {
53a3042e1da2253fd3f103bfef4deb47fc0bf6a6Ewaryst Schulz for (c = 0; response_controls[c] != NULL; c++) {
a3a7d8b3cdf05c8040c62dbcf9a15dc5042cd721Christian Maeder DEBUG(SSSDBG_TRACE_INTERNAL,
a3a7d8b3cdf05c8040c62dbcf9a15dc5042cd721Christian Maeder ("Server returned control [%s].\n",
a3a7d8b3cdf05c8040c62dbcf9a15dc5042cd721Christian Maeder response_controls[c]->ldctl_oid));
a3a7d8b3cdf05c8040c62dbcf9a15dc5042cd721Christian Maeder if (strcmp(response_controls[c]->ldctl_oid,
8762d0e3d492aba4d1621fb0de685f0be1372864notanartist LDAP_CONTROL_PASSWORDPOLICYRESPONSE) == 0) {
a3a7d8b3cdf05c8040c62dbcf9a15dc5042cd721Christian Maeder lret = ldap_parse_passwordpolicy_control(state->sh->ldap,
a3a7d8b3cdf05c8040c62dbcf9a15dc5042cd721Christian Maeder response_controls[c],
c30231257d9116b514dce02703a515fe21cd427dTill Mossakowski &pp_expire, &pp_grace,
427ff3172ae2dfebe3c8fc972735158999997e8aChristian Maeder &pp_error);
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder if (lret != LDAP_SUCCESS) {
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder DEBUG(SSSDBG_MINOR_FAILURE,
a3a7d8b3cdf05c8040c62dbcf9a15dc5042cd721Christian Maeder ("ldap_parse_passwordpolicy_control failed.\n"));
a3a7d8b3cdf05c8040c62dbcf9a15dc5042cd721Christian Maeder ret = EIO;
1f2c732265a1292f0d7c51a4a7ca6be5dd370df6cmaeder goto done;
a3a7d8b3cdf05c8040c62dbcf9a15dc5042cd721Christian Maeder }
a3a7d8b3cdf05c8040c62dbcf9a15dc5042cd721Christian Maeder
bbba10ee00dcf6bcbc9f22473b1acd0983b10512notanartist DEBUG(7, ("Password Policy Response: expire [%d] grace [%d] "
3ec3a22fe2b9c38a3575c98a82b4e3f988af64a6Eugen Kuksa "error [%s].\n", pp_expire, pp_grace,
4c872eeb600fe8479dbda395405cf13c3d573c24Soeren D. Schulze ldap_passwordpolicy_err2txt(pp_error)));
a3a7d8b3cdf05c8040c62dbcf9a15dc5042cd721Christian Maeder if (!state->ppolicy)
bc263f610d20a9cd3014ddfca903026127fa0d48Christian Maeder state->ppolicy = talloc_zero(state,
024703c9d1326c23e307c0b0d453ed3358e87fe4cmaeder struct sdap_ppolicy_data);
f8cc2399c16fcda7e3bf9d901a0de0cc8a455f86Ewaryst Schulz if (state->ppolicy == NULL) {
a3a7d8b3cdf05c8040c62dbcf9a15dc5042cd721Christian Maeder ret = ENOMEM;
53a3042e1da2253fd3f103bfef4deb47fc0bf6a6Ewaryst Schulz goto done;
a3a7d8b3cdf05c8040c62dbcf9a15dc5042cd721Christian Maeder }
a3a7d8b3cdf05c8040c62dbcf9a15dc5042cd721Christian Maeder state->ppolicy->grace = pp_grace;
a3a7d8b3cdf05c8040c62dbcf9a15dc5042cd721Christian Maeder state->ppolicy->expire = pp_expire;
a3a7d8b3cdf05c8040c62dbcf9a15dc5042cd721Christian Maeder if (state->result == LDAP_SUCCESS) {
987bd66ac5bc367e2bbe50ce2b6355993fb335d9cmaeder if (pp_error == PP_changeAfterReset) {
a3a7d8b3cdf05c8040c62dbcf9a15dc5042cd721Christian Maeder DEBUG(SSSDBG_TRACE_LIBS,
a3a7d8b3cdf05c8040c62dbcf9a15dc5042cd721Christian Maeder ("Password was reset. "
c30231257d9116b514dce02703a515fe21cd427dTill Mossakowski "User must set a new password.\n"));
427ff3172ae2dfebe3c8fc972735158999997e8aChristian Maeder state->result = LDAP_X_SSSD_PASSWORD_EXPIRED;
3490b73f69b58ab742417b0867d0e2d4a7778cc0Christian Maeder } else if (pp_grace > 0) {
3490b73f69b58ab742417b0867d0e2d4a7778cc0Christian Maeder DEBUG(SSSDBG_TRACE_LIBS,
59aa5703ac7f3b99e97cd5926e77088b256c5f40Christian Maeder ("Password expired. "
bbba10ee00dcf6bcbc9f22473b1acd0983b10512notanartist "[%d] grace logins remaining.\n",
987bd66ac5bc367e2bbe50ce2b6355993fb335d9cmaeder pp_grace));
bbba10ee00dcf6bcbc9f22473b1acd0983b10512notanartist } else if (pp_expire > 0) {
beff4152e9f0fe90885458d1a1733b183a2a8816Christian Maeder DEBUG(SSSDBG_TRACE_LIBS,
beff4152e9f0fe90885458d1a1733b183a2a8816Christian Maeder ("Password will expire in [%d] seconds.\n",
7968d3a131e5a684ec1ff0c6d88aae638549153dChristian Maeder pp_expire));
3490b73f69b58ab742417b0867d0e2d4a7778cc0Christian Maeder }
78c294da55788b25e175180168371c9536a6d440Christian Maeder } else if (state->result == LDAP_INVALID_CREDENTIALS &&
beff4152e9f0fe90885458d1a1733b183a2a8816Christian Maeder pp_error == PP_passwordExpired) {
beff4152e9f0fe90885458d1a1733b183a2a8816Christian Maeder DEBUG(SSSDBG_TRACE_LIBS,
8a5c05062ef501bf725a86a370a5145a198e81fdKlaus Luettich ("Password expired user must set a new password.\n"));
b76d27eba526ecac2a20400fa505ec5c642ae7d2Dominik Luecke state->result = LDAP_X_SSSD_PASSWORD_EXPIRED;
beff4152e9f0fe90885458d1a1733b183a2a8816Christian Maeder }
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder } else if (strcmp(response_controls[c]->ldctl_oid,
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder LDAP_CONTROL_PWEXPIRED) == 0) {
1ebf8299efa3cdb39c73d40d15e1d1a8a2246e68notanartist DEBUG(SSSDBG_TRACE_LIBS,
beff4152e9f0fe90885458d1a1733b183a2a8816Christian Maeder ("Password expired user must set a new password.\n"));
7968d3a131e5a684ec1ff0c6d88aae638549153dChristian Maeder state->result = LDAP_X_SSSD_PASSWORD_EXPIRED;
beff4152e9f0fe90885458d1a1733b183a2a8816Christian Maeder } else if (strcmp(response_controls[c]->ldctl_oid,
beff4152e9f0fe90885458d1a1733b183a2a8816Christian Maeder LDAP_CONTROL_PWEXPIRING) == 0) {
a3a7d8b3cdf05c8040c62dbcf9a15dc5042cd721Christian Maeder /* ignore controls with suspiciously long values */
a3a7d8b3cdf05c8040c62dbcf9a15dc5042cd721Christian Maeder if (response_controls[c]->ldctl_value.bv_len > 32) {
a3a7d8b3cdf05c8040c62dbcf9a15dc5042cd721Christian Maeder continue;
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder }
b6ff72be73dad3d1394cf2c71e29e67624ff030bChristian Maeder
b6ff72be73dad3d1394cf2c71e29e67624ff030bChristian Maeder if (!state->ppolicy) {
78c294da55788b25e175180168371c9536a6d440Christian Maeder state->ppolicy = talloc(state, struct sdap_ppolicy_data);
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder }
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder
a3a7d8b3cdf05c8040c62dbcf9a15dc5042cd721Christian Maeder if (state->ppolicy == NULL) {
78c294da55788b25e175180168371c9536a6d440Christian Maeder ret = ENOMEM;
78c294da55788b25e175180168371c9536a6d440Christian Maeder goto done;
bc263f610d20a9cd3014ddfca903026127fa0d48Christian Maeder }
511284753313165e629cedf508752d6818ccc4d2Christian Maeder /* ensure that bv_val is a null-terminated string */
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder nval = talloc_strndup(NULL,
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder response_controls[c]->ldctl_value.bv_val,
78c294da55788b25e175180168371c9536a6d440Christian Maeder response_controls[c]->ldctl_value.bv_len);
78c294da55788b25e175180168371c9536a6d440Christian Maeder if (nval == NULL) {
78c294da55788b25e175180168371c9536a6d440Christian Maeder ret = ENOMEM;
78c294da55788b25e175180168371c9536a6d440Christian Maeder goto done;
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder }
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder state->ppolicy->expire = strtouint32(nval, NULL, 10);
a3a7d8b3cdf05c8040c62dbcf9a15dc5042cd721Christian Maeder ret = errno;
a3a7d8b3cdf05c8040c62dbcf9a15dc5042cd721Christian Maeder talloc_zfree(nval);
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder if (ret != EOK) {
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder DEBUG(SSSDBG_MINOR_FAILURE,
a3a7d8b3cdf05c8040c62dbcf9a15dc5042cd721Christian Maeder ("Could not convert control response to an integer. ",
a3a7d8b3cdf05c8040c62dbcf9a15dc5042cd721Christian Maeder "[%s]\n", strerror(ret)));
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder goto done;
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder }
8865728716566f42fa73e7e0bc080ba3225df764Christian Maeder
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder DEBUG(SSSDBG_TRACE_LIBS,
b6ff72be73dad3d1394cf2c71e29e67624ff030bChristian Maeder ("Password will expire in [%d] seconds.\n",
b6ff72be73dad3d1394cf2c71e29e67624ff030bChristian Maeder state->ppolicy->expire));
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder }
a3a7d8b3cdf05c8040c62dbcf9a15dc5042cd721Christian Maeder }
dff1de7ad15d1582e25d636c3724dd202874897fChristian Maeder }
a3a7d8b3cdf05c8040c62dbcf9a15dc5042cd721Christian Maeder
a3a7d8b3cdf05c8040c62dbcf9a15dc5042cd721Christian Maeder DEBUG(SSSDBG_TRACE_FUNC, ("Bind result: %s(%d), %s\n",
a3a7d8b3cdf05c8040c62dbcf9a15dc5042cd721Christian Maeder sss_ldap_err2string(state->result), state->result,
8bb80c9684e905de8dcfcfb1291542677e7d77b6Christian Maeder errmsg ? errmsg : "no errmsg set"));
be43c3fa0292555bd126784ae27ff5c1d23438cbChristian Maeder
91ba5d95b2472cb075646b6120a559dc6581a867Christian Maeder ret = EOK;
be43c3fa0292555bd126784ae27ff5c1d23438cbChristian Maederdone:
91ba5d95b2472cb075646b6120a559dc6581a867Christian Maeder ldap_controls_free(response_controls);
be43c3fa0292555bd126784ae27ff5c1d23438cbChristian Maeder ldap_memfree(errmsg);
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder
be43c3fa0292555bd126784ae27ff5c1d23438cbChristian Maeder if (ret == EOK) {
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder tevent_req_done(req);
b6ff72be73dad3d1394cf2c71e29e67624ff030bChristian Maeder } else {
be43c3fa0292555bd126784ae27ff5c1d23438cbChristian Maeder tevent_req_error(req, ret);
91ba5d95b2472cb075646b6120a559dc6581a867Christian Maeder }
be43c3fa0292555bd126784ae27ff5c1d23438cbChristian Maeder}
91ba5d95b2472cb075646b6120a559dc6581a867Christian Maeder
d1c667fd9445963d9d31e2cf5d0ead15e77082a4cmaederstatic int simple_bind_recv(struct tevent_req *req,
d1c667fd9445963d9d31e2cf5d0ead15e77082a4cmaeder TALLOC_CTX *memctx,
d1c667fd9445963d9d31e2cf5d0ead15e77082a4cmaeder int *ldaperr,
d1c667fd9445963d9d31e2cf5d0ead15e77082a4cmaeder struct sdap_ppolicy_data **ppolicy)
d1c667fd9445963d9d31e2cf5d0ead15e77082a4cmaeder{
d1c667fd9445963d9d31e2cf5d0ead15e77082a4cmaeder struct simple_bind_state *state = tevent_req_data(req,
b6ff72be73dad3d1394cf2c71e29e67624ff030bChristian Maeder struct simple_bind_state);
a31430de8b0632d29f42634d6395e982bf31b14dChristian Maeder
a31430de8b0632d29f42634d6395e982bf31b14dChristian Maeder *ldaperr = LDAP_OTHER;
be43c3fa0292555bd126784ae27ff5c1d23438cbChristian Maeder TEVENT_REQ_RETURN_ON_ERROR(req);
f03420e44d8204b2945edaab5c70a84e7c381892Christian Maeder
d1c667fd9445963d9d31e2cf5d0ead15e77082a4cmaeder *ldaperr = state->result;
d1c667fd9445963d9d31e2cf5d0ead15e77082a4cmaeder *ppolicy = talloc_steal(memctx, state->ppolicy);
be43c3fa0292555bd126784ae27ff5c1d23438cbChristian Maeder return EOK;
91ba5d95b2472cb075646b6120a559dc6581a867Christian Maeder}
dff1de7ad15d1582e25d636c3724dd202874897fChristian Maeder
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder/* ==SASL-Bind============================================================ */
dff1de7ad15d1582e25d636c3724dd202874897fChristian Maeder
91ba5d95b2472cb075646b6120a559dc6581a867Christian Maederstruct sasl_bind_state {
dff1de7ad15d1582e25d636c3724dd202874897fChristian Maeder struct tevent_context *ev;
dff1de7ad15d1582e25d636c3724dd202874897fChristian Maeder struct sdap_handle *sh;
be43c3fa0292555bd126784ae27ff5c1d23438cbChristian Maeder
f03420e44d8204b2945edaab5c70a84e7c381892Christian Maeder const char *sasl_mech;
f03420e44d8204b2945edaab5c70a84e7c381892Christian Maeder const char *sasl_user;
be43c3fa0292555bd126784ae27ff5c1d23438cbChristian Maeder struct berval *sasl_cred;
d81905a5b924415c524d702df26204683c82c12eChristian Maeder
96ae1a1d2197d0e0d5b80da2474b64c456feb1b0Christian Maeder int result;
96ae1a1d2197d0e0d5b80da2474b64c456feb1b0Christian Maeder};
f03420e44d8204b2945edaab5c70a84e7c381892Christian Maeder
f03420e44d8204b2945edaab5c70a84e7c381892Christian Maederstatic int sdap_sasl_interact(LDAP *ld, unsigned flags,
f03420e44d8204b2945edaab5c70a84e7c381892Christian Maeder void *defaults, void *interact);
be43c3fa0292555bd126784ae27ff5c1d23438cbChristian Maeder
d1c667fd9445963d9d31e2cf5d0ead15e77082a4cmaederstatic struct tevent_req *sasl_bind_send(TALLOC_CTX *memctx,
9f4902edfa3d477e42343e0ec357a2f93b1119d1Christian Maeder struct tevent_context *ev,
9f4902edfa3d477e42343e0ec357a2f93b1119d1Christian Maeder struct sdap_handle *sh,
9f4902edfa3d477e42343e0ec357a2f93b1119d1Christian Maeder const char *sasl_mech,
9f4902edfa3d477e42343e0ec357a2f93b1119d1Christian Maeder const char *sasl_user,
9f4902edfa3d477e42343e0ec357a2f93b1119d1Christian Maeder struct berval *sasl_cred)
9f4902edfa3d477e42343e0ec357a2f93b1119d1Christian Maeder{
0b13f102310e03a20b38c870b5acb88712f316a4Christian Maeder struct tevent_req *req;
0b13f102310e03a20b38c870b5acb88712f316a4Christian Maeder struct sasl_bind_state *state;
be43c3fa0292555bd126784ae27ff5c1d23438cbChristian Maeder int ret = EOK;
f03420e44d8204b2945edaab5c70a84e7c381892Christian Maeder int optret;
f03420e44d8204b2945edaab5c70a84e7c381892Christian Maeder char *diag_msg = NULL;
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder
818b228955ef40dd5a253bd942dd6ab8779ed713Christian Maeder req = tevent_req_create(memctx, &state, struct sasl_bind_state);
be43c3fa0292555bd126784ae27ff5c1d23438cbChristian Maeder if (!req) return NULL;
bbba6dd86153aacb0f662b182b128df0eb09fd54Christian Maeder
16b71dad8d398af412d66a4f4763f1ada5b03d23Christian Maeder state->ev = ev;
353187efd08a2cb65226f414f192b59d312f27acChristian Maeder state->sh = sh;
8c8545dd3bf34fbcbc16904b65d249658f8f9efcChristian Maeder state->sasl_mech = sasl_mech;
33fcc19ef2b59493b4e91eebf701df95fd230765Christian Maeder state->sasl_user = sasl_user;
d4ebd9e5adc974cfa2bdf4bdd155e07be0e26f75Christian Maeder state->sasl_cred = sasl_cred;
0d79ea4ed8512a802ecb6645edac141e0fbcee3fChristian Maeder
9ee80c455784287a8b5e1b6bac1f8efa6a2f4bb3cmaeder DEBUG(4, ("Executing sasl bind mech: %s, user: %s\n",
9ee80c455784287a8b5e1b6bac1f8efa6a2f4bb3cmaeder sasl_mech, sasl_user));
be43c3fa0292555bd126784ae27ff5c1d23438cbChristian Maeder
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder /* FIXME: Warning, this is a sync call!
be43c3fa0292555bd126784ae27ff5c1d23438cbChristian Maeder * No async variant exist in openldap libraries yet */
4a2f7efdf67dfcda0946f1b6373f41976ddea7a4Christian Maeder
dff1de7ad15d1582e25d636c3724dd202874897fChristian Maeder ret = ldap_sasl_interactive_bind_s(state->sh->ldap, NULL,
3490b73f69b58ab742417b0867d0e2d4a7778cc0Christian Maeder sasl_mech, NULL, NULL,
7968d3a131e5a684ec1ff0c6d88aae638549153dChristian Maeder LDAP_SASL_QUIET,
7968d3a131e5a684ec1ff0c6d88aae638549153dChristian Maeder (*sdap_sasl_interact), state);
3490b73f69b58ab742417b0867d0e2d4a7778cc0Christian Maeder state->result = ret;
beff4152e9f0fe90885458d1a1733b183a2a8816Christian Maeder if (ret != LDAP_SUCCESS) {
78c294da55788b25e175180168371c9536a6d440Christian Maeder DEBUG(SSSDBG_CRIT_FAILURE,
1f2c732265a1292f0d7c51a4a7ca6be5dd370df6cmaeder ("ldap_sasl_bind failed (%d)[%s]\n",
ab2f38d9cd1249f6bc9cc5b838dc2fcd76189c0fChristian Maeder ret, sss_ldap_err2string(ret)));
974b0baababf2878820de073b8fad8db68bef08aDominik Luecke
8d780c893d6df5dab3dcc7d8444b7517f6547f11Christian Maeder optret = sss_ldap_get_diagnostic_msg(state, state->sh->ldap,
8d780c893d6df5dab3dcc7d8444b7517f6547f11Christian Maeder &diag_msg);
be43c3fa0292555bd126784ae27ff5c1d23438cbChristian Maeder if (optret == EOK) {
083bc1972a66d73749760eab3a90bf4eb9ca7951Christian Maeder DEBUG(SSSDBG_MINOR_FAILURE,
bc263f610d20a9cd3014ddfca903026127fa0d48Christian Maeder ("Extended failure message: [%s]\n", diag_msg));
bc263f610d20a9cd3014ddfca903026127fa0d48Christian Maeder }
be43c3fa0292555bd126784ae27ff5c1d23438cbChristian Maeder talloc_zfree(diag_msg);
966519955f5f7111abac20118563132b9dd41165Christian Maeder
dff1de7ad15d1582e25d636c3724dd202874897fChristian Maeder goto fail;
dff1de7ad15d1582e25d636c3724dd202874897fChristian Maeder }
00df6fd583c19393fa141d5a0e21ac74c7bf5b19Christian Maeder
dff1de7ad15d1582e25d636c3724dd202874897fChristian Maeder if (!sh->connected) {
be43c3fa0292555bd126784ae27ff5c1d23438cbChristian Maeder ret = sdap_set_connected(sh, ev);
0ae7a79e865d4a6022d705d160530682b3c1f825Christian Maeder if (ret) goto fail;
f03420e44d8204b2945edaab5c70a84e7c381892Christian Maeder }
0ae7a79e865d4a6022d705d160530682b3c1f825Christian Maeder
be43c3fa0292555bd126784ae27ff5c1d23438cbChristian Maeder tevent_req_post(req, ev);
dff1de7ad15d1582e25d636c3724dd202874897fChristian Maeder return req;
34d14197eb3dd643a8e6ef3ed8cba5629528e97fAivaras Jakubauskas
34d14197eb3dd643a8e6ef3ed8cba5629528e97fAivaras Jakubauskasfail:
34d14197eb3dd643a8e6ef3ed8cba5629528e97fAivaras Jakubauskas if (ret == LDAP_SERVER_DOWN) {
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder tevent_req_error(req, ETIMEDOUT);
0a26144c20fa9cdcd05011ca5019cbac8e4afae0cmaeder } else {
0a26144c20fa9cdcd05011ca5019cbac8e4afae0cmaeder tevent_req_error(req, EIO);
0a26144c20fa9cdcd05011ca5019cbac8e4afae0cmaeder }
0a26144c20fa9cdcd05011ca5019cbac8e4afae0cmaeder tevent_req_post(req, ev);
0a26144c20fa9cdcd05011ca5019cbac8e4afae0cmaeder return req;
0a26144c20fa9cdcd05011ca5019cbac8e4afae0cmaeder}
0a26144c20fa9cdcd05011ca5019cbac8e4afae0cmaeder
d1c667fd9445963d9d31e2cf5d0ead15e77082a4cmaederstatic int sdap_sasl_interact(LDAP *ld, unsigned flags,
d590edc7ecb39262bd96ec70608cbb0cf4284ba5cmaeder void *defaults, void *interact)
d1c667fd9445963d9d31e2cf5d0ead15e77082a4cmaeder{
d1c667fd9445963d9d31e2cf5d0ead15e77082a4cmaeder struct sasl_bind_state *state = talloc_get_type(defaults,
d1c667fd9445963d9d31e2cf5d0ead15e77082a4cmaeder struct sasl_bind_state);
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder sasl_interact_t *in = (sasl_interact_t *)interact;
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder if (!ld) return LDAP_PARAM_ERROR;
16b71dad8d398af412d66a4f4763f1ada5b03d23Christian Maeder
a3a7d8b3cdf05c8040c62dbcf9a15dc5042cd721Christian Maeder while (in->id != SASL_CB_LIST_END) {
a3a7d8b3cdf05c8040c62dbcf9a15dc5042cd721Christian Maeder
96ae1a1d2197d0e0d5b80da2474b64c456feb1b0Christian Maeder switch (in->id) {
96ae1a1d2197d0e0d5b80da2474b64c456feb1b0Christian Maeder case SASL_CB_GETREALM:
96ae1a1d2197d0e0d5b80da2474b64c456feb1b0Christian Maeder case SASL_CB_USER:
96ae1a1d2197d0e0d5b80da2474b64c456feb1b0Christian Maeder case SASL_CB_PASS:
96ae1a1d2197d0e0d5b80da2474b64c456feb1b0Christian Maeder if (in->defresult) {
96ae1a1d2197d0e0d5b80da2474b64c456feb1b0Christian Maeder in->result = in->defresult;
96ae1a1d2197d0e0d5b80da2474b64c456feb1b0Christian Maeder } else {
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder in->result = "";
a3a7d8b3cdf05c8040c62dbcf9a15dc5042cd721Christian Maeder }
be43c3fa0292555bd126784ae27ff5c1d23438cbChristian Maeder in->len = strlen(in->result);
16b71dad8d398af412d66a4f4763f1ada5b03d23Christian Maeder break;
be43c3fa0292555bd126784ae27ff5c1d23438cbChristian Maeder case SASL_CB_AUTHNAME:
be43c3fa0292555bd126784ae27ff5c1d23438cbChristian Maeder if (state->sasl_user) {
be43c3fa0292555bd126784ae27ff5c1d23438cbChristian Maeder in->result = state->sasl_user;
fefee7e1dee1ee5f0768a03a4abae88d1ca2c3fdRazvan Pascanu } else if (in->defresult) {
fefee7e1dee1ee5f0768a03a4abae88d1ca2c3fdRazvan Pascanu in->result = in->defresult;
fefee7e1dee1ee5f0768a03a4abae88d1ca2c3fdRazvan Pascanu } else {
fefee7e1dee1ee5f0768a03a4abae88d1ca2c3fdRazvan Pascanu in->result = "";
16b71dad8d398af412d66a4f4763f1ada5b03d23Christian Maeder }
fefee7e1dee1ee5f0768a03a4abae88d1ca2c3fdRazvan Pascanu in->len = strlen(in->result);
9308cb2aebeae23f49713896e6d7028b0ac0f83enotanartist break;
2360728d4185c0c04279c999941c64d36626af79Christian Maeder case SASL_CB_NOECHOPROMPT:
fefee7e1dee1ee5f0768a03a4abae88d1ca2c3fdRazvan Pascanu case SASL_CB_ECHOPROMPT:
fefee7e1dee1ee5f0768a03a4abae88d1ca2c3fdRazvan Pascanu goto fail;
fefee7e1dee1ee5f0768a03a4abae88d1ca2c3fdRazvan Pascanu }
66a774f13272fde036481edd2298081ab3d04678Razvan Pascanu
9308cb2aebeae23f49713896e6d7028b0ac0f83enotanartist in++;
2360728d4185c0c04279c999941c64d36626af79Christian Maeder }
66a774f13272fde036481edd2298081ab3d04678Razvan Pascanu
16b71dad8d398af412d66a4f4763f1ada5b03d23Christian Maeder return LDAP_SUCCESS;
16b71dad8d398af412d66a4f4763f1ada5b03d23Christian Maeder
16b71dad8d398af412d66a4f4763f1ada5b03d23Christian Maederfail:
16b71dad8d398af412d66a4f4763f1ada5b03d23Christian Maeder return LDAP_UNAVAILABLE;
16b71dad8d398af412d66a4f4763f1ada5b03d23Christian Maeder}
16b71dad8d398af412d66a4f4763f1ada5b03d23Christian Maeder
b53688bfed888214b485cf76439d57262d80e0a7Christian Maederstatic int sasl_bind_recv(struct tevent_req *req, int *ldaperr)
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder{
9dd71ac51c9a6e72bcb126224f9c64131698b636Christian Maeder struct sasl_bind_state *state = tevent_req_data(req,
a3a7d8b3cdf05c8040c62dbcf9a15dc5042cd721Christian Maeder struct sasl_bind_state);
a3a7d8b3cdf05c8040c62dbcf9a15dc5042cd721Christian Maeder enum tevent_req_state tstate;
a3a7d8b3cdf05c8040c62dbcf9a15dc5042cd721Christian Maeder uint64_t err = EIO;
beff4152e9f0fe90885458d1a1733b183a2a8816Christian Maeder
0ea2cddb8715a770e646895e16b7b8085f49167cChristian Maeder if (tevent_req_is_error(req, &tstate, &err)) {
0ea2cddb8715a770e646895e16b7b8085f49167cChristian Maeder if (tstate != TEVENT_REQ_IN_PROGRESS) {
7245138e91992b96b153b8ac527e263d9dc8ff5bChristian Maeder *ldaperr = LDAP_OTHER;
7245138e91992b96b153b8ac527e263d9dc8ff5bChristian Maeder return err;
7245138e91992b96b153b8ac527e263d9dc8ff5bChristian Maeder }
7245138e91992b96b153b8ac527e263d9dc8ff5bChristian Maeder }
7245138e91992b96b153b8ac527e263d9dc8ff5bChristian Maeder
0ea2cddb8715a770e646895e16b7b8085f49167cChristian Maeder *ldaperr = state->result;
7968d3a131e5a684ec1ff0c6d88aae638549153dChristian Maeder return EOK;
7968d3a131e5a684ec1ff0c6d88aae638549153dChristian Maeder}
7968d3a131e5a684ec1ff0c6d88aae638549153dChristian Maeder
7968d3a131e5a684ec1ff0c6d88aae638549153dChristian Maeder/* ==Perform-Kinit-given-keytab-and-principal============================= */
a461314c811f4187dff85c8be079a41b2f13f176Christian Maeder
a461314c811f4187dff85c8be079a41b2f13f176Christian Maederstruct sdap_kinit_state {
a461314c811f4187dff85c8be079a41b2f13f176Christian Maeder const char *keytab;
a461314c811f4187dff85c8be079a41b2f13f176Christian Maeder const char *principal;
a461314c811f4187dff85c8be079a41b2f13f176Christian Maeder const char *realm;
a461314c811f4187dff85c8be079a41b2f13f176Christian Maeder int timeout;
0130083f314580170af1195037be3325f125fbceChristian Maeder int lifetime;
0130083f314580170af1195037be3325f125fbceChristian Maeder
c770b05f3d85f8eeb25ba15f7192044f9dd534ddSoeren D. Schulze const char *krb_service_name;
c770b05f3d85f8eeb25ba15f7192044f9dd534ddSoeren D. Schulze struct tevent_context *ev;
c770b05f3d85f8eeb25ba15f7192044f9dd534ddSoeren D. Schulze struct be_ctx *be;
c770b05f3d85f8eeb25ba15f7192044f9dd534ddSoeren D. Schulze
c770b05f3d85f8eeb25ba15f7192044f9dd534ddSoeren D. Schulze struct fo_server *kdc_srv;
c770b05f3d85f8eeb25ba15f7192044f9dd534ddSoeren D. Schulze int result;
0130083f314580170af1195037be3325f125fbceChristian Maeder time_t expire_time;
0130083f314580170af1195037be3325f125fbceChristian Maeder};
0130083f314580170af1195037be3325f125fbceChristian Maeder
0130083f314580170af1195037be3325f125fbceChristian Maederstatic void sdap_kinit_done(struct tevent_req *subreq);
0130083f314580170af1195037be3325f125fbceChristian Maederstatic struct tevent_req *sdap_kinit_next_kdc(struct tevent_req *req);
0130083f314580170af1195037be3325f125fbceChristian Maederstatic void sdap_kinit_kdc_resolved(struct tevent_req *subreq);
0130083f314580170af1195037be3325f125fbceChristian Maeder
057b3bffc58757a98e8e7c1aeaf5cbbc986b3117Christian Maederstruct tevent_req *sdap_kinit_send(TALLOC_CTX *memctx,
3bcd9d942601d59dd55a6069d8b2d1c33d7ced0eChristian Maeder struct tevent_context *ev,
3bcd9d942601d59dd55a6069d8b2d1c33d7ced0eChristian Maeder struct be_ctx *be,
057b3bffc58757a98e8e7c1aeaf5cbbc986b3117Christian Maeder struct sdap_handle *sh,
c770b05f3d85f8eeb25ba15f7192044f9dd534ddSoeren D. Schulze const char *krb_service_name,
c770b05f3d85f8eeb25ba15f7192044f9dd534ddSoeren D. Schulze int timeout,
c770b05f3d85f8eeb25ba15f7192044f9dd534ddSoeren D. Schulze const char *keytab,
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder const char *principal,
9d6562465b41f17c7967d4e5678f34811d958cb2Christian Maeder const char *realm,
9d6562465b41f17c7967d4e5678f34811d958cb2Christian Maeder bool canonicalize,
daec53c285f692c56db0cefe16061b46ba602cf0Christian Maeder int lifetime)
daec53c285f692c56db0cefe16061b46ba602cf0Christian Maeder{
daec53c285f692c56db0cefe16061b46ba602cf0Christian Maeder struct tevent_req *req;
daec53c285f692c56db0cefe16061b46ba602cf0Christian Maeder struct tevent_req *subreq;
daec53c285f692c56db0cefe16061b46ba602cf0Christian Maeder struct sdap_kinit_state *state;
daec53c285f692c56db0cefe16061b46ba602cf0Christian Maeder int ret;
daec53c285f692c56db0cefe16061b46ba602cf0Christian Maeder
a3a7d8b3cdf05c8040c62dbcf9a15dc5042cd721Christian Maeder DEBUG(6, ("Attempting kinit (%s, %s, %s, %d)\n",
a3a7d8b3cdf05c8040c62dbcf9a15dc5042cd721Christian Maeder keytab ? keytab : "default",
daec53c285f692c56db0cefe16061b46ba602cf0Christian Maeder principal, realm, lifetime));
daec53c285f692c56db0cefe16061b46ba602cf0Christian Maeder
daec53c285f692c56db0cefe16061b46ba602cf0Christian Maeder if (lifetime < 0 || lifetime > INT32_MAX) {
daec53c285f692c56db0cefe16061b46ba602cf0Christian Maeder DEBUG(1, ("Ticket lifetime out of range.\n"));
daec53c285f692c56db0cefe16061b46ba602cf0Christian Maeder return NULL;
daec53c285f692c56db0cefe16061b46ba602cf0Christian Maeder }
daec53c285f692c56db0cefe16061b46ba602cf0Christian Maeder
a3a7d8b3cdf05c8040c62dbcf9a15dc5042cd721Christian Maeder req = tevent_req_create(memctx, &state, struct sdap_kinit_state);
a3a7d8b3cdf05c8040c62dbcf9a15dc5042cd721Christian Maeder if (!req) return NULL;
93bc87ee96c68506945dbad8c704badaa42ecf14Christian Maeder
b6ff72be73dad3d1394cf2c71e29e67624ff030bChristian Maeder state->result = SDAP_AUTH_FAILED;
b6ff72be73dad3d1394cf2c71e29e67624ff030bChristian Maeder state->keytab = keytab;
b6ff72be73dad3d1394cf2c71e29e67624ff030bChristian Maeder state->principal = principal;
3bcd9d942601d59dd55a6069d8b2d1c33d7ced0eChristian Maeder state->realm = realm;
9db2bd64088c7e5935b94dd9c3ad5cdc24f48814Christian Maeder state->ev = ev;
0a64bfd28dff15bc93e1f7a86e0a8052e879636dChristian Maeder state->be = be;
0a64bfd28dff15bc93e1f7a86e0a8052e879636dChristian Maeder state->timeout = timeout;
0a64bfd28dff15bc93e1f7a86e0a8052e879636dChristian Maeder state->lifetime = lifetime;
0a64bfd28dff15bc93e1f7a86e0a8052e879636dChristian Maeder state->krb_service_name = krb_service_name;
0a64bfd28dff15bc93e1f7a86e0a8052e879636dChristian Maeder
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder if (keytab) {
0b13f102310e03a20b38c870b5acb88712f316a4Christian Maeder ret = setenv("KRB5_KTNAME", keytab, 1);
0b13f102310e03a20b38c870b5acb88712f316a4Christian Maeder if (ret == -1) {
0b13f102310e03a20b38c870b5acb88712f316a4Christian Maeder DEBUG(2, ("Failed to set KRB5_KTNAME to %s\n", keytab));
0b13f102310e03a20b38c870b5acb88712f316a4Christian Maeder talloc_free(req);
0b13f102310e03a20b38c870b5acb88712f316a4Christian Maeder return NULL;
0b13f102310e03a20b38c870b5acb88712f316a4Christian Maeder }
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder }
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder if (canonicalize) {
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder ret = setenv("KRB5_CANONICALIZE", "true", 1);
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder } else {
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder ret = setenv("KRB5_CANONICALIZE", "false", 1);
2353f65833a3da763392f771223250cd50b8d873Christian Maeder }
2353f65833a3da763392f771223250cd50b8d873Christian Maeder if (ret == -1) {
9308cb2aebeae23f49713896e6d7028b0ac0f83enotanartist DEBUG(2, ("Failed to set KRB5_CANONICALIZE to %s\n",
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder ((canonicalize)?"true":"false")));
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder talloc_free(req);
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder return NULL;
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder }
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder subreq = sdap_kinit_next_kdc(req);
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder if (!subreq) {
9308cb2aebeae23f49713896e6d7028b0ac0f83enotanartist talloc_free(req);
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder return NULL;
2353f65833a3da763392f771223250cd50b8d873Christian Maeder }
00df6fd583c19393fa141d5a0e21ac74c7bf5b19Christian Maeder
00df6fd583c19393fa141d5a0e21ac74c7bf5b19Christian Maeder return req;
00df6fd583c19393fa141d5a0e21ac74c7bf5b19Christian Maeder}
f39b8dd9651dfcc38b06191cda23cacbfc298323Christian Maeder
528539f3d544c24afe14e979fe51f03e50aa6e9cChristian Maederstatic struct tevent_req *sdap_kinit_next_kdc(struct tevent_req *req)
0ae7a79e865d4a6022d705d160530682b3c1f825Christian Maeder{
863d4b011d04907325f3eed8e89975e38603cb05Christian Maeder struct tevent_req *next_req;
0ae7a79e865d4a6022d705d160530682b3c1f825Christian Maeder struct sdap_kinit_state *state = tevent_req_data(req,
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder struct sdap_kinit_state);
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder
a3a7d8b3cdf05c8040c62dbcf9a15dc5042cd721Christian Maeder DEBUG(7, ("Resolving next KDC for service %s\n", state->krb_service_name));
a3a7d8b3cdf05c8040c62dbcf9a15dc5042cd721Christian Maeder
a3a7d8b3cdf05c8040c62dbcf9a15dc5042cd721Christian Maeder next_req = be_resolve_server_send(state, state->ev,
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder state->be,
59a10395caff224b2ec541f94dac5082a506c00fChristian Maeder state->krb_service_name,
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder state->kdc_srv == NULL ? true : false);
be43c3fa0292555bd126784ae27ff5c1d23438cbChristian Maeder if (next_req == NULL) {
be43c3fa0292555bd126784ae27ff5c1d23438cbChristian Maeder DEBUG(1, ("be_resolve_server_send failed.\n"));
be43c3fa0292555bd126784ae27ff5c1d23438cbChristian Maeder return NULL;
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder }
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder tevent_req_set_callback(next_req, sdap_kinit_kdc_resolved, req);
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder
2353f65833a3da763392f771223250cd50b8d873Christian Maeder return next_req;
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder}
9308cb2aebeae23f49713896e6d7028b0ac0f83enotanartist
2353f65833a3da763392f771223250cd50b8d873Christian Maederstatic void sdap_kinit_kdc_resolved(struct tevent_req *subreq)
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder{
12aef5992d3af07dee81a4e02cf4be65a83f28bcChristian Maeder struct tevent_req *req = tevent_req_callback_data(subreq,
12aef5992d3af07dee81a4e02cf4be65a83f28bcChristian Maeder struct tevent_req);
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder struct sdap_kinit_state *state = tevent_req_data(req,
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder struct sdap_kinit_state);
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder struct tevent_req *tgtreq;
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder int ret;
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder ret = be_resolve_server_recv(subreq, &state->kdc_srv);
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder talloc_zfree(subreq);
be43c3fa0292555bd126784ae27ff5c1d23438cbChristian Maeder if (ret != EOK) {
b6ff72be73dad3d1394cf2c71e29e67624ff030bChristian Maeder /* all servers have been tried and none
057b3bffc58757a98e8e7c1aeaf5cbbc986b3117Christian Maeder * was found good, go offline */
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder tevent_req_error(req, EIO);
9175e29c044318498a40f323f189f9dfd50378efChristian Maeder return;
057b3bffc58757a98e8e7c1aeaf5cbbc986b3117Christian Maeder }
502483734c83d0bf1eadcc94113d0362f8713784Christian Maeder
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder DEBUG(7, ("KDC resolved, attempting to get TGT...\n"));
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder tgtreq = sdap_get_tgt_send(state, state->ev, state->realm,
16b71dad8d398af412d66a4f4763f1ada5b03d23Christian Maeder state->principal, state->keytab,
16b71dad8d398af412d66a4f4763f1ada5b03d23Christian Maeder state->lifetime, state->timeout);
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder if (!tgtreq) {
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder tevent_req_error(req, ENOMEM);
c5a4c5f506ea34fa527065b4187127a18c6e2418Christian Maeder return;
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder }
96ae1a1d2197d0e0d5b80da2474b64c456feb1b0Christian Maeder tevent_req_set_callback(tgtreq, sdap_kinit_done, req);
96ae1a1d2197d0e0d5b80da2474b64c456feb1b0Christian Maeder}
afb32b54f3e87b51c5a6242040022f497f7f20abChristian Maeder
96ae1a1d2197d0e0d5b80da2474b64c456feb1b0Christian Maederstatic void sdap_kinit_done(struct tevent_req *subreq)
3d3889e0cefcdce9b3f43c53aaa201943ac2e895Jonathan von Schroeder{
16b71dad8d398af412d66a4f4763f1ada5b03d23Christian Maeder struct tevent_req *req = tevent_req_callback_data(subreq,
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder struct tevent_req);
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder struct sdap_kinit_state *state = tevent_req_data(req,
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder struct sdap_kinit_state);
2353f65833a3da763392f771223250cd50b8d873Christian Maeder
4b1833c7d3af466e6bcba24f16304e0a78e8da87Christian Maeder int ret;
fba4eac6b080849889892e1e273ac4c74ddde840Christian Maeder int result;
4347b243063d414f97a68b64e30a4f27a612af0aChristian Maeder char *ccname = NULL;
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder time_t expire_time;
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder krb5_error_code kerr;
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder struct tevent_req *nextreq;
2353f65833a3da763392f771223250cd50b8d873Christian Maeder
2353f65833a3da763392f771223250cd50b8d873Christian Maeder ret = sdap_get_tgt_recv(subreq, state, &result,
9d6562465b41f17c7967d4e5678f34811d958cb2Christian Maeder &kerr, &ccname, &expire_time);
9d6562465b41f17c7967d4e5678f34811d958cb2Christian Maeder talloc_zfree(subreq);
502483734c83d0bf1eadcc94113d0362f8713784Christian Maeder if (ret == ETIMEDOUT) {
9d6562465b41f17c7967d4e5678f34811d958cb2Christian Maeder /* The child didn't even respond. Perhaps the KDC is too busy,
9d6562465b41f17c7967d4e5678f34811d958cb2Christian Maeder * retry with another KDC */
c5a4c5f506ea34fa527065b4187127a18c6e2418Christian Maeder DEBUG(SSSDBG_MINOR_FAILURE,
c5a4c5f506ea34fa527065b4187127a18c6e2418Christian Maeder ("Communication with KDC timed out, trying the next one\n"));
c5a4c5f506ea34fa527065b4187127a18c6e2418Christian Maeder be_fo_set_port_status(state->be, state->kdc_srv, PORT_NOT_WORKING);
be43c3fa0292555bd126784ae27ff5c1d23438cbChristian Maeder nextreq = sdap_kinit_next_kdc(req);
9d6562465b41f17c7967d4e5678f34811d958cb2Christian Maeder if (!nextreq) {
2353f65833a3da763392f771223250cd50b8d873Christian Maeder tevent_req_error(req, ENOMEM);
dbc98cd8a9a829e020cfa0a9f3aff89de75caaa9Christian Maeder }
2353f65833a3da763392f771223250cd50b8d873Christian Maeder return;
cb2044812811d66efe038d914966e04290be93faChristian Maeder } else if (ret != EOK) {
cb2044812811d66efe038d914966e04290be93faChristian Maeder /* A severe error while executing the child. Abort the operation. */
9d6562465b41f17c7967d4e5678f34811d958cb2Christian Maeder state->result = SDAP_AUTH_FAILED;
0130083f314580170af1195037be3325f125fbceChristian Maeder DEBUG(1, ("child failed (%d [%s])\n", ret, strerror(ret)));
0130083f314580170af1195037be3325f125fbceChristian Maeder tevent_req_error(req, ret);
502483734c83d0bf1eadcc94113d0362f8713784Christian Maeder return;
cb2044812811d66efe038d914966e04290be93faChristian Maeder }
c5a4c5f506ea34fa527065b4187127a18c6e2418Christian Maeder
0130083f314580170af1195037be3325f125fbceChristian Maeder if (result == EOK) {
0130083f314580170af1195037be3325f125fbceChristian Maeder ret = setenv("KRB5CCNAME", ccname, 1);
0130083f314580170af1195037be3325f125fbceChristian Maeder if (ret == -1) {
0130083f314580170af1195037be3325f125fbceChristian Maeder DEBUG(2, ("Unable to set env. variable KRB5CCNAME!\n"));
0130083f314580170af1195037be3325f125fbceChristian Maeder state->result = SDAP_AUTH_FAILED;
0130083f314580170af1195037be3325f125fbceChristian Maeder tevent_req_error(req, EFAULT);
c5a4c5f506ea34fa527065b4187127a18c6e2418Christian Maeder }
cb2044812811d66efe038d914966e04290be93faChristian Maeder
be43c3fa0292555bd126784ae27ff5c1d23438cbChristian Maeder state->expire_time = expire_time;
0130083f314580170af1195037be3325f125fbceChristian Maeder state->result = SDAP_AUTH_SUCCESS;
502483734c83d0bf1eadcc94113d0362f8713784Christian Maeder tevent_req_done(req);
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder return;
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder } else {
c5a4c5f506ea34fa527065b4187127a18c6e2418Christian Maeder if (kerr == KRB5_KDC_UNREACH) {
be43c3fa0292555bd126784ae27ff5c1d23438cbChristian Maeder be_fo_set_port_status(state->be, state->kdc_srv, PORT_NOT_WORKING);
be43c3fa0292555bd126784ae27ff5c1d23438cbChristian Maeder nextreq = sdap_kinit_next_kdc(req);
502483734c83d0bf1eadcc94113d0362f8713784Christian Maeder if (!nextreq) {
c5a4c5f506ea34fa527065b4187127a18c6e2418Christian Maeder tevent_req_error(req, ENOMEM);
c5a4c5f506ea34fa527065b4187127a18c6e2418Christian Maeder }
2353f65833a3da763392f771223250cd50b8d873Christian Maeder return;
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder }
c5a4c5f506ea34fa527065b4187127a18c6e2418Christian Maeder
16b71dad8d398af412d66a4f4763f1ada5b03d23Christian Maeder }
be43c3fa0292555bd126784ae27ff5c1d23438cbChristian Maeder
be43c3fa0292555bd126784ae27ff5c1d23438cbChristian Maeder DEBUG(4, ("Could not get TGT: %d [%s]\n", result, strerror(result)));
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder state->result = SDAP_AUTH_FAILED;
2360728d4185c0c04279c999941c64d36626af79Christian Maeder tevent_req_error(req, EIO);
cb2044812811d66efe038d914966e04290be93faChristian Maeder}
2360728d4185c0c04279c999941c64d36626af79Christian Maeder
16b71dad8d398af412d66a4f4763f1ada5b03d23Christian Maederint sdap_kinit_recv(struct tevent_req *req,
16b71dad8d398af412d66a4f4763f1ada5b03d23Christian Maeder enum sdap_result *result,
16b71dad8d398af412d66a4f4763f1ada5b03d23Christian Maeder time_t *expire_time)
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder{
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder struct sdap_kinit_state *state = tevent_req_data(req,
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder struct sdap_kinit_state);
8c8545dd3bf34fbcbc16904b65d249658f8f9efcChristian Maeder enum tevent_req_state tstate;
8c8545dd3bf34fbcbc16904b65d249658f8f9efcChristian Maeder uint64_t err = EIO;
8c8545dd3bf34fbcbc16904b65d249658f8f9efcChristian Maeder
8c8545dd3bf34fbcbc16904b65d249658f8f9efcChristian Maeder if (tevent_req_is_error(req, &tstate, &err)) {
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder if (tstate != TEVENT_REQ_IN_PROGRESS) {
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder *result = SDAP_ERROR;
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder return err;
b6ff72be73dad3d1394cf2c71e29e67624ff030bChristian Maeder }
b6ff72be73dad3d1394cf2c71e29e67624ff030bChristian Maeder }
b6ff72be73dad3d1394cf2c71e29e67624ff030bChristian Maeder
b6ff72be73dad3d1394cf2c71e29e67624ff030bChristian Maeder *result = state->result;
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder *expire_time = state->expire_time;
c5a4c5f506ea34fa527065b4187127a18c6e2418Christian Maeder return EOK;
c5a4c5f506ea34fa527065b4187127a18c6e2418Christian Maeder}
b6ff72be73dad3d1394cf2c71e29e67624ff030bChristian Maeder
b6ff72be73dad3d1394cf2c71e29e67624ff030bChristian Maeder
b6ff72be73dad3d1394cf2c71e29e67624ff030bChristian Maeder/* ==Authenticaticate-User-by-DN========================================== */
a3a7d8b3cdf05c8040c62dbcf9a15dc5042cd721Christian Maeder
c5a4c5f506ea34fa527065b4187127a18c6e2418Christian Maederstruct sdap_auth_state {
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder const char *user_dn;
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder struct berval pw;
0ede68718d0fd43b5d67c233ccfb7a2b673fc9cbChristian Maeder struct sdap_ppolicy_data *ppolicy;
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder
0ede68718d0fd43b5d67c233ccfb7a2b673fc9cbChristian Maeder int result;
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder bool is_sasl;
0ede68718d0fd43b5d67c233ccfb7a2b673fc9cbChristian Maeder};
502483734c83d0bf1eadcc94113d0362f8713784Christian Maeder
502483734c83d0bf1eadcc94113d0362f8713784Christian Maederstatic void sdap_auth_done(struct tevent_req *subreq);
502483734c83d0bf1eadcc94113d0362f8713784Christian Maederstatic int sdap_auth_get_authtok(const char *authtok_type,
502483734c83d0bf1eadcc94113d0362f8713784Christian Maeder struct dp_opt_blob authtok,
502483734c83d0bf1eadcc94113d0362f8713784Christian Maeder struct berval *pw);
502483734c83d0bf1eadcc94113d0362f8713784Christian Maeder
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder/* TODO: handle sasl_cred */
b53688bfed888214b485cf76439d57262d80e0a7Christian Maederstruct tevent_req *sdap_auth_send(TALLOC_CTX *memctx,
9175e29c044318498a40f323f189f9dfd50378efChristian Maeder struct tevent_context *ev,
a3a7d8b3cdf05c8040c62dbcf9a15dc5042cd721Christian Maeder struct sdap_handle *sh,
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder const char *sasl_mech,
b6ff72be73dad3d1394cf2c71e29e67624ff030bChristian Maeder const char *sasl_user,
b6ff72be73dad3d1394cf2c71e29e67624ff030bChristian Maeder const char *user_dn,
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder const char *authtok_type,
be43c3fa0292555bd126784ae27ff5c1d23438cbChristian Maeder struct dp_opt_blob authtok)
be43c3fa0292555bd126784ae27ff5c1d23438cbChristian Maeder{
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder struct tevent_req *req, *subreq;
bbba6dd86153aacb0f662b182b128df0eb09fd54Christian Maeder struct sdap_auth_state *state;
be43c3fa0292555bd126784ae27ff5c1d23438cbChristian Maeder int ret;
7968d3a131e5a684ec1ff0c6d88aae638549153dChristian Maeder
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder req = tevent_req_create(memctx, &state, struct sdap_auth_state);
16b71dad8d398af412d66a4f4763f1ada5b03d23Christian Maeder if (!req) return NULL;
a3a7d8b3cdf05c8040c62dbcf9a15dc5042cd721Christian Maeder
a3a7d8b3cdf05c8040c62dbcf9a15dc5042cd721Christian Maeder state->user_dn = user_dn;
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder
b53688bfed888214b485cf76439d57262d80e0a7Christian Maeder ret = sdap_auth_get_authtok(authtok_type, authtok, &state->pw);
7f7460e7095628f3437b116ee78d3043d11f8febChristian Maeder if (ret != EOK) {
a3a7d8b3cdf05c8040c62dbcf9a15dc5042cd721Christian Maeder if (ret == ENOSYS) {
a3a7d8b3cdf05c8040c62dbcf9a15dc5042cd721Christian Maeder DEBUG(1, ("Getting authtok is not supported with the "
a3a7d8b3cdf05c8040c62dbcf9a15dc5042cd721Christian Maeder "crypto library compiled with, authentication "
5941ba0b9a99ac98f78a89a9f3303102657e36ccChristian Maeder "might fail!\n"));
a3a7d8b3cdf05c8040c62dbcf9a15dc5042cd721Christian Maeder } else {
a3a7d8b3cdf05c8040c62dbcf9a15dc5042cd721Christian Maeder DEBUG(1, ("Cannot parse authtok.\n"));
5941ba0b9a99ac98f78a89a9f3303102657e36ccChristian Maeder tevent_req_error(req, ret);
5941ba0b9a99ac98f78a89a9f3303102657e36ccChristian Maeder return tevent_req_post(req, ev);
}
}
if (sasl_mech) {
state->is_sasl = true;
subreq = sasl_bind_send(state, ev, sh, sasl_mech, sasl_user, NULL);
if (!subreq) {
tevent_req_error(req, ENOMEM);
return tevent_req_post(req, ev);
}
} else {
state->is_sasl = false;
subreq = simple_bind_send(state, ev, sh, user_dn, &state->pw);
if (!subreq) {
tevent_req_error(req, ENOMEM);
return tevent_req_post(req, ev);
}
}
tevent_req_set_callback(subreq, sdap_auth_done, req);
return req;
}
static int sdap_auth_get_authtok(const char *authtok_type,
struct dp_opt_blob authtok,
struct berval *pw)
{
if (!authtok_type) return EOK;
if (!pw) return EINVAL;
if (strcasecmp(authtok_type,"password") == 0) {
pw->bv_len = authtok.length;
pw->bv_val = (char *) authtok.data;
} else {
DEBUG(1, ("Authentication token type [%s] is not supported\n",
authtok_type));
return EINVAL;
}
return EOK;
}
static void sdap_auth_done(struct tevent_req *subreq)
{
struct tevent_req *req = tevent_req_callback_data(subreq,
struct tevent_req);
struct sdap_auth_state *state = tevent_req_data(req,
struct sdap_auth_state);
int ret;
if (state->is_sasl) {
ret = sasl_bind_recv(subreq, &state->result);
state->ppolicy = NULL;
} else {
ret = simple_bind_recv(subreq, state, &state->result, &state->ppolicy);
}
if (ret != EOK) {
tevent_req_error(req, ret);
return;
}
tevent_req_done(req);
}
int sdap_auth_recv(struct tevent_req *req,
TALLOC_CTX *memctx,
enum sdap_result *result,
struct sdap_ppolicy_data **ppolicy)
{
struct sdap_auth_state *state = tevent_req_data(req,
struct sdap_auth_state);
*result = SDAP_ERROR;
TEVENT_REQ_RETURN_ON_ERROR(req);
if (ppolicy != NULL) {
*ppolicy = talloc_steal(memctx, state->ppolicy);
}
switch (state->result) {
case LDAP_SUCCESS:
*result = SDAP_AUTH_SUCCESS;
break;
case LDAP_INVALID_CREDENTIALS:
*result = SDAP_AUTH_FAILED;
break;
case LDAP_X_SSSD_PASSWORD_EXPIRED:
*result = SDAP_AUTH_PW_EXPIRED;
break;
default:
break;
}
return EOK;
}
/* ==Client connect============================================ */
struct sdap_cli_connect_state {
struct tevent_context *ev;
struct sdap_options *opts;
struct sdap_service *service;
struct be_ctx *be;
bool use_rootdse;
struct sysdb_attrs *rootdse;
struct sdap_handle *sh;
struct fo_server *srv;
struct sdap_server_opts *srv_opts;
enum connect_tls force_tls;
bool do_auth;
};
static int sdap_cli_resolve_next(struct tevent_req *req);
static void sdap_cli_resolve_done(struct tevent_req *subreq);
static void sdap_cli_connect_done(struct tevent_req *subreq);
static void sdap_cli_rootdse_step(struct tevent_req *req);
static void sdap_cli_rootdse_done(struct tevent_req *subreq);
static errno_t sdap_cli_use_rootdse(struct sdap_cli_connect_state *state);
static void sdap_cli_kinit_step(struct tevent_req *req);
static void sdap_cli_kinit_done(struct tevent_req *subreq);
static void sdap_cli_auth_step(struct tevent_req *req);
static void sdap_cli_auth_done(struct tevent_req *subreq);
static void sdap_cli_rootdse_auth_done(struct tevent_req *subreq);
struct tevent_req *sdap_cli_connect_send(TALLOC_CTX *memctx,
struct tevent_context *ev,
struct sdap_options *opts,
struct be_ctx *be,
struct sdap_service *service,
bool skip_rootdse,
enum connect_tls force_tls,
bool skip_auth)
{
struct sdap_cli_connect_state *state;
struct tevent_req *req;
int ret;
req = tevent_req_create(memctx, &state, struct sdap_cli_connect_state);
if (!req) return NULL;
state->ev = ev;
state->opts = opts;
state->service = service;
state->be = be;
state->srv = NULL;
state->srv_opts = NULL;
state->use_rootdse = !skip_rootdse;
state->force_tls = force_tls;
state->do_auth = !skip_auth;
ret = sdap_cli_resolve_next(req);
if (ret) {
tevent_req_error(req, ret);
tevent_req_post(req, ev);
}
return req;
}
static int sdap_cli_resolve_next(struct tevent_req *req)
{
struct sdap_cli_connect_state *state = tevent_req_data(req,
struct sdap_cli_connect_state);
struct tevent_req *subreq;
/* Before stepping to next server destroy any connection from previous attempt */
talloc_zfree(state->sh);
/* NOTE: this call may cause service->uri to be refreshed
* with a new valid server. Do not use service->uri before */
subreq = be_resolve_server_send(state, state->ev,
state->be, state->service->name,
state->srv == NULL ? true : false);
if (!subreq) {
return ENOMEM;
}
tevent_req_set_callback(subreq, sdap_cli_resolve_done, req);
return EOK;
}
static void sdap_cli_resolve_done(struct tevent_req *subreq)
{
struct tevent_req *req = tevent_req_callback_data(subreq,
struct tevent_req);
struct sdap_cli_connect_state *state = tevent_req_data(req,
struct sdap_cli_connect_state);
int ret;
bool use_tls;
switch (state->force_tls) {
case CON_TLS_DFL:
use_tls = dp_opt_get_bool(state->opts->basic, SDAP_ID_TLS);
break;
case CON_TLS_ON:
use_tls = true;
break;
case CON_TLS_OFF:
use_tls = false;
break;
default:
tevent_req_error(req, EINVAL);
break;
}
ret = be_resolve_server_recv(subreq, &state->srv);
talloc_zfree(subreq);
if (ret) {
state->srv = NULL;
/* all servers have been tried and none
* was found good, go offline */
tevent_req_error(req, EIO);
return;
}
if (use_tls && sdap_is_secure_uri(state->service->uri)) {
DEBUG(8, ("[%s] is a secure channel. No need to run START_TLS\n",
state->service->uri));
use_tls = false;
}
subreq = sdap_connect_send(state, state->ev, state->opts,
state->service->uri,
state->service->sockaddr,
use_tls);
if (!subreq) {
tevent_req_error(req, ENOMEM);
return;
}
tevent_req_set_callback(subreq, sdap_cli_connect_done, req);
}
static void sdap_cli_connect_done(struct tevent_req *subreq)
{
struct tevent_req *req = tevent_req_callback_data(subreq,
struct tevent_req);
struct sdap_cli_connect_state *state = tevent_req_data(req,
struct sdap_cli_connect_state);
const char *sasl_mech;
int ret;
talloc_zfree(state->sh);
ret = sdap_connect_recv(subreq, state, &state->sh);
talloc_zfree(subreq);
if (ret) {
/* retry another server */
be_fo_set_port_status(state->be, state->srv, PORT_NOT_WORKING);
ret = sdap_cli_resolve_next(req);
if (ret != EOK) {
tevent_req_error(req, ret);
}
return;
}
if (state->use_rootdse) {
/* fetch the rootDSE this time */
sdap_cli_rootdse_step(req);
return;
}
sasl_mech = dp_opt_get_string(state->opts->basic, SDAP_SASL_MECH);
if (state->do_auth && sasl_mech && state->use_rootdse) {
/* check if server claims to support GSSAPI */
if (!sdap_is_sasl_mech_supported(state->sh, sasl_mech)) {
tevent_req_error(req, ENOTSUP);
return;
}
}
if (state->do_auth && sasl_mech && (strcasecmp(sasl_mech, "GSSAPI") == 0)) {
if (dp_opt_get_bool(state->opts->basic, SDAP_KRB5_KINIT)) {
sdap_cli_kinit_step(req);
return;
}
}
sdap_cli_auth_step(req);
}
static void sdap_cli_rootdse_step(struct tevent_req *req)
{
struct sdap_cli_connect_state *state = tevent_req_data(req,
struct sdap_cli_connect_state);
struct tevent_req *subreq;
int ret;
subreq = sdap_get_rootdse_send(state, state->ev, state->opts, state->sh);
if (!subreq) {
tevent_req_error(req, ENOMEM);
return;
}
tevent_req_set_callback(subreq, sdap_cli_rootdse_done, req);
if (!state->sh->connected) {
/* this rootdse search is performed before we actually do a bind,
* so we need to set up the callbacks or we will never get notified
* of a reply */
ret = sdap_set_connected(state->sh, state->ev);
if (ret) {
tevent_req_error(req, ret);
}
}
}
static void sdap_cli_rootdse_done(struct tevent_req *subreq)
{
struct tevent_req *req = tevent_req_callback_data(subreq,
struct tevent_req);
struct sdap_cli_connect_state *state = tevent_req_data(req,
struct sdap_cli_connect_state);
const char *sasl_mech;
int ret;
ret = sdap_get_rootdse_recv(subreq, state, &state->rootdse);
talloc_zfree(subreq);
if (ret) {
if (ret == ETIMEDOUT) { /* retry another server */
be_fo_set_port_status(state->be, state->srv, PORT_NOT_WORKING);
ret = sdap_cli_resolve_next(req);
if (ret != EOK) {
tevent_req_error(req, ret);
}
return;
}
/* RootDSE was not available on
* the server.
* Continue, and just assume that the
* features requested by the config
* work properly.
*/
state->rootdse = NULL;
}
ret = sdap_cli_use_rootdse(state);
if (ret != EOK) {
DEBUG(SSSDBG_OP_FAILURE, ("sdap_cli_use_rootdse failed\n"));
tevent_req_error(req, ret);
return;
}
sasl_mech = dp_opt_get_string(state->opts->basic, SDAP_SASL_MECH);
if (state->do_auth && sasl_mech && state->rootdse) {
/* check if server claims to support GSSAPI */
if (!sdap_is_sasl_mech_supported(state->sh, sasl_mech)) {
tevent_req_error(req, ENOTSUP);
return;
}
}
if (state->do_auth && sasl_mech && (strcasecmp(sasl_mech, "GSSAPI") == 0)) {
if (dp_opt_get_bool(state->opts->basic, SDAP_KRB5_KINIT)) {
sdap_cli_kinit_step(req);
return;
}
}
sdap_cli_auth_step(req);
}
static errno_t sdap_cli_use_rootdse(struct sdap_cli_connect_state *state)
{
errno_t ret;
if (state->rootdse) {
/* save rootdse data about supported features */
ret = sdap_set_rootdse_supported_lists(state->rootdse, state->sh);
if (ret) {
DEBUG(SSSDBG_OP_FAILURE,
("sdap_set_rootdse_supported_lists failed\n"));
return ret;
}
ret = sdap_set_config_options_with_rootdse(state->rootdse, state->opts);
if (ret) {
DEBUG(SSSDBG_OP_FAILURE,
("sdap_set_config_options_with_rootdse failed.\n"));
return ret;
}
}
ret = sdap_get_server_opts_from_rootdse(state,
state->service->uri,
state->rootdse,
state->opts, &state->srv_opts);
if (ret) {
DEBUG(SSSDBG_OP_FAILURE,
("sdap_get_server_opts_from_rootdse failed.\n"));
return ret;
}
return EOK;
}
static void sdap_cli_kinit_step(struct tevent_req *req)
{
struct sdap_cli_connect_state *state = tevent_req_data(req,
struct sdap_cli_connect_state);
struct tevent_req *subreq;
const char *realm;
realm = dp_opt_get_string(state->opts->basic, SDAP_SASL_REALM);
if (!realm) {
realm = dp_opt_get_string(state->opts->basic, SDAP_KRB5_REALM);
}
subreq = sdap_kinit_send(state, state->ev,
state->be,
state->sh,
state->service->kinit_service_name,
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,
SDAP_SASL_AUTHID),
realm,
dp_opt_get_bool(state->opts->basic,
SDAP_KRB5_CANONICALIZE),
dp_opt_get_int(state->opts->basic,
SDAP_KRB5_TICKET_LIFETIME));
if (!subreq) {
tevent_req_error(req, ENOMEM);
return;
}
tevent_req_set_callback(subreq, sdap_cli_kinit_done, req);
}
static void sdap_cli_kinit_done(struct tevent_req *subreq)
{
struct tevent_req *req = tevent_req_callback_data(subreq,
struct tevent_req);
struct sdap_cli_connect_state *state = tevent_req_data(req,
struct sdap_cli_connect_state);
enum sdap_result result;
time_t expire_time;
int ret;
ret = sdap_kinit_recv(subreq, &result, &expire_time);
talloc_zfree(subreq);
if (ret != EOK || result != SDAP_AUTH_SUCCESS) {
/* We're not able to authenticate to the LDAP server.
* There's not much we can do except for going offline */
DEBUG(SSSDBG_TRACE_FUNC,
("Cannot get a TGT: ret [%d] result [%d]\n", ret, result));
tevent_req_error(req, EACCES);
return;
}
state->sh->expire_time = expire_time;
sdap_cli_auth_step(req);
}
static void sdap_cli_auth_step(struct tevent_req *req)
{
struct sdap_cli_connect_state *state = tevent_req_data(req,
struct sdap_cli_connect_state);
struct tevent_req *subreq;
time_t now;
int expire_timeout;
const char *sasl_mech = dp_opt_get_string(state->opts->basic,
SDAP_SASL_MECH);
const char *user_dn = dp_opt_get_string(state->opts->basic,
SDAP_DEFAULT_BIND_DN);
if (!state->do_auth ||
(sasl_mech == NULL && user_dn == NULL)) {
DEBUG(SSSDBG_TRACE_LIBS,
("No authentication requested or SASL auth forced off\n"));
tevent_req_done(req);
return;
}
/* Set the LDAP expiration time
* If SASL has already set it, use the sooner of the two
*/
now = time(NULL);
expire_timeout = dp_opt_get_int(state->opts->basic, SDAP_EXPIRE_TIMEOUT);
if (!state->sh->expire_time
|| (state->sh->expire_time > (now + expire_timeout))) {
state->sh->expire_time = now + expire_timeout;
}
subreq = sdap_auth_send(state,
state->ev,
state->sh,
sasl_mech,
dp_opt_get_string(state->opts->basic,
SDAP_SASL_AUTHID),
user_dn,
dp_opt_get_string(state->opts->basic,
SDAP_DEFAULT_AUTHTOK_TYPE),
dp_opt_get_blob(state->opts->basic,
SDAP_DEFAULT_AUTHTOK));
if (!subreq) {
tevent_req_error(req, ENOMEM);
return;
}
tevent_req_set_callback(subreq, sdap_cli_auth_done, req);
}
static void sdap_cli_auth_done(struct tevent_req *subreq)
{
struct tevent_req *req = tevent_req_callback_data(subreq,
struct tevent_req);
struct sdap_cli_connect_state *state = tevent_req_data(req,
struct sdap_cli_connect_state);
enum sdap_result result;
int ret;
ret = sdap_auth_recv(subreq, NULL, &result, NULL);
talloc_zfree(subreq);
if (ret) {
tevent_req_error(req, ret);
return;
}
if (result != SDAP_AUTH_SUCCESS) {
tevent_req_error(req, EACCES);
return;
}
if (state->use_rootdse && !state->rootdse) {
/* We weren't able to read rootDSE during unauthenticated bind.
* Let's try again now that we are authenticated */
subreq = sdap_get_rootdse_send(state, state->ev,
state->opts, state->sh);
if (!subreq) {
tevent_req_error(req, ENOMEM);
return;
}
tevent_req_set_callback(subreq, sdap_cli_rootdse_auth_done, req);
return;
}
tevent_req_done(req);
}
static void sdap_cli_rootdse_auth_done(struct tevent_req *subreq)
{
errno_t ret;
struct tevent_req *req = tevent_req_callback_data(subreq,
struct tevent_req);
struct sdap_cli_connect_state *state = tevent_req_data(req,
struct sdap_cli_connect_state);
ret = sdap_get_rootdse_recv(subreq, state, &state->rootdse);
talloc_zfree(subreq);
if (ret) {
if (ret == ETIMEDOUT) {
/* The server we authenticated against went down. Retry another
* one */
be_fo_set_port_status(state->be, state->srv, PORT_NOT_WORKING);
ret = sdap_cli_resolve_next(req);
if (ret != EOK) {
tevent_req_error(req, ret);
}
return;
}
/* RootDSE was not available on
* the server.
* Continue, and just assume that the
* features requested by the config
* work properly.
*/
state->use_rootdse = false;
state->rootdse = NULL;
tevent_req_done(req);
return;
}
/* We were able to get rootDSE after authentication */
ret = sdap_cli_use_rootdse(state);
if (ret != EOK) {
DEBUG(SSSDBG_OP_FAILURE, ("sdap_cli_use_rootdse failed\n"));
tevent_req_error(req, ret);
return;
}
tevent_req_done(req);
}
int sdap_cli_connect_recv(struct tevent_req *req,
TALLOC_CTX *memctx,
bool *can_retry,
struct sdap_handle **gsh,
struct sdap_server_opts **srv_opts)
{
struct sdap_cli_connect_state *state = tevent_req_data(req,
struct sdap_cli_connect_state);
enum tevent_req_state tstate;
uint64_t err;
if (can_retry) {
*can_retry = true;
}
if (tevent_req_is_error(req, &tstate, &err)) {
/* mark the server as bad if connection failed */
if (state->srv) {
be_fo_set_port_status(state->be, state->srv, PORT_NOT_WORKING);
} else {
if (can_retry) {
*can_retry = false;
}
}
if (tstate == TEVENT_REQ_USER_ERROR) {
return err;
}
return EIO;
} else if (state->srv) {
be_fo_set_port_status(state->be, state->srv, PORT_WORKING);
}
if (gsh) {
if (*gsh) {
talloc_zfree(*gsh);
}
*gsh = talloc_steal(memctx, state->sh);
if (!*gsh) {
return ENOMEM;
}
} else {
talloc_zfree(state->sh);
}
if (srv_opts) {
*srv_opts = talloc_steal(memctx, state->srv_opts);
}
return EOK;
}
static int synchronous_tls_setup(LDAP *ldap)
{
int lret;
int optret;
int ldaperr;
int msgid;
char *errmsg = NULL;
char *diag_msg;
LDAPMessage *result = NULL;
TALLOC_CTX *tmp_ctx;
DEBUG(4, ("Executing START TLS\n"));
tmp_ctx = talloc_new(NULL);
if (!tmp_ctx) return LDAP_NO_MEMORY;
lret = ldap_start_tls(ldap, NULL, NULL, &msgid);
if (lret != LDAP_SUCCESS) {
optret = sss_ldap_get_diagnostic_msg(tmp_ctx, ldap, &diag_msg);
if (optret == LDAP_SUCCESS) {
DEBUG(3, ("ldap_start_tls failed: [%s] [%s]\n",
sss_ldap_err2string(lret), diag_msg));
sss_log(SSS_LOG_ERR, "Could not start TLS. %s", diag_msg);
} else {
DEBUG(3, ("ldap_start_tls failed: [%s]\n", sss_ldap_err2string(lret)));
sss_log(SSS_LOG_ERR, "Could not start TLS. "
"Check for certificate issues.");
}
goto done;
}
lret = ldap_result(ldap, msgid, 1, NULL, &result);
if (lret != LDAP_RES_EXTENDED) {
DEBUG(2, ("Unexpected ldap_result, expected [%d] got [%d].\n",
LDAP_RES_EXTENDED, lret));
lret = LDAP_PARAM_ERROR;
goto done;
}
lret = ldap_parse_result(ldap, result, &ldaperr, NULL, &errmsg, NULL, NULL,
0);
if (lret != LDAP_SUCCESS) {
DEBUG(2, ("ldap_parse_result failed (%d) [%d][%s]\n", msgid, lret,
sss_ldap_err2string(lret)));
goto done;
}
DEBUG(3, ("START TLS result: %s(%d), %s\n",
sss_ldap_err2string(ldaperr), ldaperr, errmsg));
if (ldap_tls_inplace(ldap)) {
DEBUG(9, ("SSL/TLS handler already in place.\n"));
lret = LDAP_SUCCESS;
goto done;
}
lret = ldap_install_tls(ldap);
if (lret != LDAP_SUCCESS) {
optret = sss_ldap_get_diagnostic_msg(tmp_ctx, ldap, &diag_msg);
if (optret == LDAP_SUCCESS) {
DEBUG(3, ("ldap_install_tls failed: [%s] [%s]\n",
sss_ldap_err2string(lret), diag_msg));
sss_log(SSS_LOG_ERR, "Could not start TLS encryption. %s", diag_msg);
} else {
DEBUG(3, ("ldap_install_tls failed: [%s]\n",
sss_ldap_err2string(lret)));
sss_log(SSS_LOG_ERR, "Could not start TLS encryption. "
"Check for certificate issues.");
}
goto done;
}
lret = LDAP_SUCCESS;
done:
if (result) ldap_msgfree(result);
if (errmsg) ldap_memfree(errmsg);
talloc_zfree(tmp_ctx);
return lret;
}
static int sdap_rebind_proc(LDAP *ldap, LDAP_CONST char *url, ber_tag_t request,
ber_int_t msgid, void *params)
{
struct sdap_rebind_proc_params *p = talloc_get_type(params,
struct sdap_rebind_proc_params);
const char *sasl_mech;
const char *user_dn;
struct berval password = {0, NULL};
LDAPControl **request_controls = NULL;
LDAPControl *ctrls[2] = { NULL, NULL };
TALLOC_CTX *tmp_ctx = NULL;
struct sasl_bind_state *sasl_bind_state;
int ret;
if (p->use_start_tls) {
ret = synchronous_tls_setup(ldap);
if (ret != LDAP_SUCCESS) {
DEBUG(1, ("synchronous_tls_setup failed.\n"));
return ret;
}
}
tmp_ctx = talloc_new(NULL);
if (tmp_ctx == NULL) {
DEBUG(1, ("talloc_new failed.\n"));
return LDAP_NO_MEMORY;
}
sasl_mech = dp_opt_get_string(p->opts->basic, SDAP_SASL_MECH);
if (sasl_mech == NULL) {
ret = sss_ldap_control_create(LDAP_CONTROL_PASSWORDPOLICYREQUEST,
0, NULL, 0, &ctrls[0]);
if (ret != LDAP_SUCCESS && ret != LDAP_NOT_SUPPORTED) {
DEBUG(1, ("sss_ldap_control_create failed to create "
"Password Policy control.\n"));
goto done;
}
request_controls = ctrls;
user_dn = dp_opt_get_string(p->opts->basic, SDAP_DEFAULT_BIND_DN);
if (user_dn != NULL) {
ret = sdap_auth_get_authtok(dp_opt_get_string(p->opts->basic,
SDAP_DEFAULT_AUTHTOK_TYPE),
dp_opt_get_blob(p->opts->basic,
SDAP_DEFAULT_AUTHTOK),
&password);
if (ret != EOK) {
DEBUG(SSSDBG_CRIT_FAILURE,
("sdap_auth_get_authtok failed.\n"));
ret = LDAP_LOCAL_ERROR;
goto done;
}
}
ret = ldap_sasl_bind_s(ldap, user_dn, LDAP_SASL_SIMPLE, &password,
request_controls, NULL, NULL);
if (ret != LDAP_SUCCESS) {
DEBUG(SSSDBG_CRIT_FAILURE,
("ldap_sasl_bind_s failed (%d)[%s]\n", ret,
sss_ldap_err2string(ret)));
}
} else {
sasl_bind_state = talloc_zero(tmp_ctx, struct sasl_bind_state);
if (sasl_bind_state == NULL) {
DEBUG(1, ("talloc_zero failed.\n"));
ret = LDAP_NO_MEMORY;
goto done;
}
sasl_bind_state->sasl_user = dp_opt_get_string(p->opts->basic,
SDAP_SASL_AUTHID);
ret = ldap_sasl_interactive_bind_s(ldap, NULL,
sasl_mech, NULL, NULL,
LDAP_SASL_QUIET,
(*sdap_sasl_interact),
sasl_bind_state);
if (ret != LDAP_SUCCESS) {
DEBUG(1, ("ldap_sasl_interactive_bind_s failed (%d)[%s]\n", ret,
sss_ldap_err2string(ret)));
}
}
DEBUG(7, ("%s bind to [%s].\n",
(ret == LDAP_SUCCESS ? "Successfully" : "Failed to"), url));
done:
if (ctrls[0]) ldap_control_free(ctrls[0]);
talloc_free(tmp_ctx);
return ret;
}