From 71af2725e8f96b403af3f4aa140c413f751380c0 Mon Sep 17 00:00:00 2001 From: Sumit Bose Date: Thu, 9 Sep 2010 15:15:36 +0200 Subject: Store rootdse supported features in sdap_handler --- src/providers/ipa/ipa_auth.c | 4 +- src/providers/ldap/ldap_common.h | 3 ++ src/providers/ldap/sdap.c | 82 +++++++++++++++++++++++------- src/providers/ldap/sdap.h | 23 ++++++++- src/providers/ldap/sdap_async.h | 8 ++- src/providers/ldap/sdap_async_connection.c | 51 +++++++------------ src/providers/ldap/sdap_id_op.c | 4 +- 7 files changed, 112 insertions(+), 63 deletions(-) (limited to 'src/providers') diff --git a/src/providers/ipa/ipa_auth.c b/src/providers/ipa/ipa_auth.c index 2d91457db..23095e53b 100644 --- a/src/providers/ipa/ipa_auth.c +++ b/src/providers/ipa/ipa_auth.c @@ -92,7 +92,7 @@ static struct tevent_req *get_password_migration_flag_send(TALLOC_CTX *memctx, subreq = sdap_cli_connect_send(state, ev, sdap_auth_ctx->opts, sdap_auth_ctx->be, sdap_auth_ctx->service, - NULL); + true); if (subreq == NULL) { DEBUG(1, ("sdap_cli_connect_send failed.\n")); goto fail; @@ -118,7 +118,7 @@ static void get_password_migration_flag_auth_done(struct tevent_req *subreq) char *search_base; const char **attrs; - ret = sdap_cli_connect_recv(subreq, state, &state->sh, NULL); + ret = sdap_cli_connect_recv(subreq, state, &state->sh); talloc_zfree(subreq); if (ret) { DEBUG(1, ("sdap_auth request failed.\n")); diff --git a/src/providers/ldap/ldap_common.h b/src/providers/ldap/ldap_common.h index 5b7298bc1..2a0e9767d 100644 --- a/src/providers/ldap/ldap_common.h +++ b/src/providers/ldap/ldap_common.h @@ -42,6 +42,9 @@ struct sdap_id_ctx { struct fo_service *fo_service; struct sdap_service *service; + /* what rootDSE returns */ + struct sysdb_attrs *rootDSE; + /* LDAP connection cache */ struct sdap_id_conn_cache *conn_cache; diff --git a/src/providers/ldap/sdap.c b/src/providers/ldap/sdap.c index 39c67cc92..cfcaff095 100644 --- a/src/providers/ldap/sdap.c +++ b/src/providers/ldap/sdap.c @@ -325,37 +325,83 @@ errno_t setup_tls_config(struct dp_option *basic_opts) } -bool sdap_rootdse_sasl_mech_is_supported(struct sysdb_attrs *rootdse, - const char *sasl_mech) +bool sdap_check_sup_list(struct sup_list *l, const char *val) { - struct ldb_message_element *el = NULL; - struct ldb_val *val; int i; - if (!sasl_mech) return false; + if (!val) { + return false; + } - for (i = 0; i < rootdse->num; i++) { - if (strcasecmp(rootdse->a[i].name, "supportedSASLMechanisms")) { + for (i = 0; i < l->num_vals; i++) { + if (strcasecmp(val, (char *)l->vals[i])) { continue; } - el = &rootdse->a[i]; - break; + return true; } - if (!el) { - /* no supported SASL Mechanism at all ? */ - return false; + return false; +} + +static int sdap_init_sup_list(TALLOC_CTX *memctx, + struct sup_list *list, + int num, struct ldb_val *vals) +{ + int i; + + list->vals = talloc_array(memctx, char *, num); + if (!list->vals) { + return ENOMEM; } - for (i = 0; i < el->num_values; i++) { - val = &el->values[i]; - if (strncasecmp(sasl_mech, (const char *)val->data, val->length)) { - continue; + for (i = 0; i < num; i++) { + list->vals[i] = talloc_strndup(list->vals, + (char *)vals[i].data, vals[i].length); + if (!list->vals[i]) { + return ENOMEM; } - return true; } - return false; + list->num_vals = num; + + return EOK; +} + +int sdap_set_rootdse_supported_lists(struct sysdb_attrs *rootdse, + struct sdap_handle *sh) +{ + struct ldb_message_element *el = NULL; + int ret; + int i; + + for (i = 0; i < rootdse->num; i++) { + el = &rootdse->a[i]; + if (strcasecmp(el->name, "supportedControl") == 0) { + + ret = sdap_init_sup_list(sh, &sh->supported_controls, + el->num_values, el->values); + if (ret) { + return ret; + } + } else if (strcasecmp(el->name, "supportedExtension") == 0) { + + ret = sdap_init_sup_list(sh, &sh->supported_extensions, + el->num_values, el->values); + if (ret) { + return ret; + } + } else if (strcasecmp(el->name, "supportedSASLMechanisms") == 0) { + + ret = sdap_init_sup_list(sh, &sh->supported_saslmechs, + el->num_values, el->values); + if (ret) { + return ret; + } + } + } + + return EOK; + } int build_attrs_from_map(TALLOC_CTX *memctx, diff --git a/src/providers/ldap/sdap.h b/src/providers/ldap/sdap.h index 61e7fe254..c7921c788 100644 --- a/src/providers/ldap/sdap.h +++ b/src/providers/ldap/sdap.h @@ -93,6 +93,11 @@ struct ldap_cb_data { void *wakeup_cb_data; }; +struct sup_list { + int num_vals; + char **vals; +}; + struct sdap_handle { LDAP *ldap; bool connected; @@ -101,6 +106,10 @@ struct sdap_handle { struct sdap_fd_events *sdap_fd_events; + struct sup_list supported_saslmechs; + struct sup_list supported_controls; + struct sup_list supported_extensions; + struct sdap_op *ops; /* during release we need to lock access to the handler @@ -288,8 +297,18 @@ int sdap_get_msg_dn(TALLOC_CTX *memctx, struct sdap_handle *sh, errno_t setup_tls_config(struct dp_option *basic_opts); -bool sdap_rootdse_sasl_mech_is_supported(struct sysdb_attrs *rootdse, - const char *sasl_mech); +int sdap_set_rootdse_supported_lists(struct sysdb_attrs *rootdse, + struct sdap_handle *sh); +bool sdap_check_sup_list(struct sup_list *l, const char *val); + +#define sdap_is_sasl_mech_supported(sh, sasl_mech) \ + sdap_check_sup_list(&((sh)->supported_saslmechs), sasl_mech) + +#define sdap_is_control_supported(sh, ctrl_oid) \ + sdap_check_sup_list(&((sh)->supported_controls), ctrl_oid) + +#define sdap_is_extension_supported(sh, ext_oid) \ + sdap_check_sup_list(&((sh)->supported_extensions), ext_oid) int build_attrs_from_map(TALLOC_CTX *memctx, struct sdap_attr_map *map, diff --git a/src/providers/ldap/sdap_async.h b/src/providers/ldap/sdap_async.h index 60535064c..e5a60daa0 100644 --- a/src/providers/ldap/sdap_async.h +++ b/src/providers/ldap/sdap_async.h @@ -110,16 +110,14 @@ struct tevent_req *sdap_cli_connect_send(TALLOC_CTX *memctx, struct sdap_options *opts, struct be_ctx *be, struct sdap_service *service, - struct sysdb_attrs **rootdse); + bool skip_rootdse); int sdap_cli_connect_recv(struct tevent_req *req, TALLOC_CTX *memctx, - struct sdap_handle **gsh, - struct sysdb_attrs **rootdse); + struct sdap_handle **gsh); int sdap_cli_connect_recv_ext(struct tevent_req *req, TALLOC_CTX *memctx, bool *can_retry, - struct sdap_handle **gsh, - struct sysdb_attrs **rootdse); + struct sdap_handle **gsh); struct tevent_req *sdap_get_generic_send(TALLOC_CTX *memctx, struct tevent_context *ev, diff --git a/src/providers/ldap/sdap_async_connection.c b/src/providers/ldap/sdap_async_connection.c index 682d74c81..2d06dc58e 100644 --- a/src/providers/ldap/sdap_async_connection.c +++ b/src/providers/ldap/sdap_async_connection.c @@ -939,7 +939,6 @@ struct sdap_cli_connect_state { struct be_ctx *be; bool use_rootdse; - struct sysdb_attrs *rootdse; struct sdap_handle *sh; @@ -961,7 +960,7 @@ struct tevent_req *sdap_cli_connect_send(TALLOC_CTX *memctx, struct sdap_options *opts, struct be_ctx *be, struct sdap_service *service, - struct sysdb_attrs **rootdse) + bool skip_rootdse) { struct sdap_cli_connect_state *state; struct tevent_req *req; @@ -976,14 +975,7 @@ struct tevent_req *sdap_cli_connect_send(TALLOC_CTX *memctx, state->be = be; state->srv = NULL; state->be = be; - - if (rootdse) { - state->use_rootdse = true; - state->rootdse = *rootdse; - } else { - state->use_rootdse = false; - state->rootdse = NULL; - } + state->use_rootdse = !skip_rootdse; ret = sdap_cli_resolve_next(req); if (ret) { @@ -1068,7 +1060,7 @@ static void sdap_cli_connect_done(struct tevent_req *subreq) return; } - if (state->use_rootdse && !state->rootdse) { + if (state->use_rootdse) { /* fetch the rootDSE this time */ sdap_cli_rootdse_step(req); return; @@ -1078,8 +1070,7 @@ static void sdap_cli_connect_done(struct tevent_req *subreq) if (sasl_mech && state->use_rootdse) { /* check if server claims to support GSSAPI */ - if (!sdap_rootdse_sasl_mech_is_supported(state->rootdse, - sasl_mech)) { + if (!sdap_is_sasl_mech_supported(state->sh, sasl_mech)) { tevent_req_error(req, ENOTSUP); return; } @@ -1127,10 +1118,11 @@ static void sdap_cli_rootdse_done(struct tevent_req *subreq) struct tevent_req); struct sdap_cli_connect_state *state = tevent_req_data(req, struct sdap_cli_connect_state); + struct sysdb_attrs *rootdse; const char *sasl_mech; int ret; - ret = sdap_get_rootdse_recv(subreq, state, &state->rootdse); + ret = sdap_get_rootdse_recv(subreq, state, &rootdse); talloc_zfree(subreq); if (ret) { if (ret == ETIMEDOUT) { /* retry another server */ @@ -1158,12 +1150,18 @@ static void sdap_cli_rootdse_done(struct tevent_req *subreq) } } + /* save rootdse data about supported features */ + ret = sdap_set_rootdse_supported_lists(rootdse, state->sh); + if (ret) { + tevent_req_error(req, ret); + return; + } + sasl_mech = dp_opt_get_string(state->opts->basic, SDAP_SASL_MECH); if (sasl_mech && state->use_rootdse) { /* check if server claims to support GSSAPI */ - if (!sdap_rootdse_sasl_mech_is_supported(state->rootdse, - sasl_mech)) { + if (!sdap_is_sasl_mech_supported(state->sh, sasl_mech)) { tevent_req_error(req, ENOTSUP); return; } @@ -1287,17 +1285,15 @@ static void sdap_cli_auth_done(struct tevent_req *subreq) int sdap_cli_connect_recv(struct tevent_req *req, TALLOC_CTX *memctx, - struct sdap_handle **gsh, - struct sysdb_attrs **rootdse) + struct sdap_handle **gsh) { - return sdap_cli_connect_recv_ext(req, memctx, NULL, gsh, rootdse); + return sdap_cli_connect_recv_ext(req, memctx, NULL, gsh); } int sdap_cli_connect_recv_ext(struct tevent_req *req, TALLOC_CTX *memctx, bool *can_retry, - struct sdap_handle **gsh, - struct sysdb_attrs **rootdse) + struct sdap_handle **gsh) { struct sdap_cli_connect_state *state = tevent_req_data(req, struct sdap_cli_connect_state); @@ -1337,19 +1333,6 @@ int sdap_cli_connect_recv_ext(struct tevent_req *req, talloc_zfree(state->sh); } - if (rootdse) { - if (state->use_rootdse) { - *rootdse = talloc_steal(memctx, state->rootdse); - if (!*rootdse) { - return ENOMEM; - } - } else { - *rootdse = NULL; - } - } else { - talloc_zfree(rootdse); - } - return EOK; } diff --git a/src/providers/ldap/sdap_id_op.c b/src/providers/ldap/sdap_id_op.c index a005f0f70..4fa7733dc 100644 --- a/src/providers/ldap/sdap_id_op.c +++ b/src/providers/ldap/sdap_id_op.c @@ -460,7 +460,7 @@ static int sdap_id_op_connect_step(struct tevent_req *req) conn_data->conn_cache = conn_cache; subreq = sdap_cli_connect_send(conn_data, conn_cache->be->ev, conn_cache->opts, conn_cache->be, - conn_cache->service, &conn_data->rootDSE); + conn_cache->service, false); if (!subreq) { ret = ENOMEM; goto done; @@ -497,7 +497,7 @@ static void sdap_id_op_connect_done(struct tevent_req *subreq) int ret; ret = sdap_cli_connect_recv_ext(subreq, conn_data, &can_retry, - &conn_data->sh, &conn_data->rootDSE); + &conn_data->sh); conn_data->connect_req = NULL; talloc_zfree(subreq); -- cgit