Skip to content

Commit

Permalink
LDAP: Bind to the LDAP server also in the auth
Browse files Browse the repository at this point in the history
When dealing with id_provider not being the same as auth_provider, SSSD
has to bind the DN of the user which wants to authenticate with the
ldap_default_bind_dn and the password provided by the user.

In order to do so, the least intrusive way is just by replacing
sdap_connect*() functions by sdap_cli_connect*() functions in the LDAP's
auth module.

The simple change also allowed us to remove some code that is already
executed as part of sdap_cli_connect*() and some functions had their
names adapted to reflect better their new purpose.

Resolves:
https://pagure.io/SSSD/sssd/issue/3451

Signed-off-by: Fabiano Fidêncio <fidencio@redhat.com>
Reviewed-by: Sumit Bose <sbose@redhat.com>
  • Loading branch information
fidencio authored and Lukas Slebodnik committed Nov 3, 2017
1 parent 6ab49ae commit add7286
Showing 1 changed file with 25 additions and 89 deletions.
114 changes: 25 additions & 89 deletions src/providers/ldap/ldap_auth.c
Expand Up @@ -619,14 +619,11 @@ struct auth_state {
char *dn;
enum pwexpire pw_expire_type;
void *pw_expire_data;

struct fo_server *srv;
};

static struct tevent_req *auth_get_server(struct tevent_req *req);
static struct tevent_req *auth_connect_send(struct tevent_req *req);
static void auth_get_dn_done(struct tevent_req *subreq);
static void auth_do_bind(struct tevent_req *req);
static void auth_resolve_done(struct tevent_req *subreq);
static void auth_connect_done(struct tevent_req *subreq);
static void auth_bind_user_done(struct tevent_req *subreq);

Expand Down Expand Up @@ -659,15 +656,14 @@ static struct tevent_req *auth_send(TALLOC_CTX *memctx,
state->ctx = ctx;
state->username = username;
state->authtok = authtok;
state->srv = NULL;
if (try_chpass_service && ctx->chpass_service != NULL &&
ctx->chpass_service->name != NULL) {
state->sdap_service = ctx->chpass_service;
} else {
state->sdap_service = ctx->service;
}

if (!auth_get_server(req)) goto fail;
if (!auth_connect_send(req)) goto fail;

return req;

Expand All @@ -676,75 +672,37 @@ static struct tevent_req *auth_send(TALLOC_CTX *memctx,
return NULL;
}

static struct tevent_req *auth_get_server(struct tevent_req *req)
static struct tevent_req *auth_connect_send(struct tevent_req *req)
{
struct tevent_req *next_req;
struct tevent_req *subreq;
struct auth_state *state = tevent_req_data(req,
struct auth_state);

/* NOTE: this call may cause service->uri to be refreshed
* with a new valid server. Do not use service->uri before */
next_req = be_resolve_server_send(state,
state->ev,
state->ctx->be,
state->sdap_service->name,
state->srv == NULL ? true : false);
if (!next_req) {
DEBUG(SSSDBG_CRIT_FAILURE, "be_resolve_server_send failed.\n");
return NULL;
}

tevent_req_set_callback(next_req, auth_resolve_done, req);
return next_req;
}

static void auth_resolve_done(struct tevent_req *subreq)
{
struct tevent_req *req = tevent_req_callback_data(subreq,
struct tevent_req);
struct auth_state *state = tevent_req_data(req,
struct auth_state);
int ret;
bool use_tls;

ret = be_resolve_server_recv(subreq, state, &state->srv);
talloc_zfree(subreq);
if (ret) {
/* all servers have been tried and none
* was found good, go offline */
tevent_req_error(req, ETIMEDOUT);
return;
/* Check for undocumented debugging feature to disable TLS
* for authentication. This should never be used in production
* for obvious reasons.
*/
use_tls = !dp_opt_get_bool(state->ctx->opts->basic, SDAP_DISABLE_AUTH_TLS);
if (!use_tls) {
sss_log(SSS_LOG_ALERT, "LDAP authentication being performed over "
"insecure connection. This should be done "
"for debugging purposes only.");
}

/* Determine whether we need to use TLS */
if (sdap_is_secure_uri(state->ctx->service->uri)) {
DEBUG(SSSDBG_TRACE_INTERNAL,
"[%s] is a secure channel. No need to run START_TLS\n",
state->ctx->service->uri);
use_tls = false;
} else {
subreq = sdap_cli_connect_send(state, state->ev, state->ctx->opts,
state->ctx->be,
state->sdap_service, false,
use_tls ? CON_TLS_ON : CON_TLS_OFF, false);

/* Check for undocumented debugging feature to disable TLS
* for authentication. This should never be used in production
* for obvious reasons.
*/
use_tls = !dp_opt_get_bool(state->ctx->opts->basic, SDAP_DISABLE_AUTH_TLS);
if (!use_tls) {
sss_log(SSS_LOG_ALERT, "LDAP authentication being performed over "
"insecure connection. This should be done "
"for debugging purposes only.");
}
}

subreq = sdap_connect_send(state, state->ev, state->ctx->opts,
state->sdap_service->uri,
state->sdap_service->sockaddr, use_tls);
if (!subreq) {
if (subreq == NULL) {
tevent_req_error(req, ENOMEM);
return;
return NULL;
}

tevent_req_set_callback(subreq, auth_connect_done, req);

return subreq;
}

static void auth_connect_done(struct tevent_req *subreq)
Expand All @@ -755,35 +713,13 @@ static void auth_connect_done(struct tevent_req *subreq)
struct auth_state);
int ret;

ret = sdap_connect_recv(subreq, state, &state->sh);
ret = sdap_cli_connect_recv(subreq, state, NULL, &state->sh, NULL);
talloc_zfree(subreq);
if (ret) {
if (state->srv) {
/* mark this server as bad if connection failed */
be_fo_set_port_status(state->ctx->be,
state->sdap_service->name,
state->srv, PORT_NOT_WORKING);
}

if (auth_get_server(req) == NULL) {
if (ret != EOK) {
if (auth_connect_send(req) == NULL) {
tevent_req_error(req, ENOMEM);
}
return;
} else if (state->srv) {
be_fo_set_port_status(state->ctx->be, state->sdap_service->name,
state->srv, PORT_WORKING);
}

/* In case the ID provider is set to proxy, this might be the first
* LDAP operation at all, so we need to set the connection status
*/
if (state->sh->connected == false) {
ret = sdap_set_connected(state->sh, state->ev);
if (ret) {
DEBUG(SSSDBG_OP_FAILURE, "Cannot set connected status\n");
tevent_req_error(req, ret);
return;
}
}

ret = get_user_dn(state, state->ctx->be->domain,
Expand Down Expand Up @@ -870,7 +806,7 @@ static void auth_bind_user_done(struct tevent_req *subreq)
break;
case ETIMEDOUT:
case ERR_NETWORK_IO:
if (auth_get_server(req) == NULL) {
if (auth_connect_send(req) == NULL) {
tevent_req_error(req, ENOMEM);
}
return;
Expand Down

0 comments on commit add7286

Please sign in to comment.