summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSumit Bose <sbose@redhat.com>2010-09-09 15:15:36 +0200
committerStephen Gallagher <sgallagh@redhat.com>2010-09-15 11:46:33 -0400
commit71af2725e8f96b403af3f4aa140c413f751380c0 (patch)
treea2e2211a59445872e69a79974a142d5f6ccc95de
parent6057958313bde8dc0f43dc97d2ba3e0897722382 (diff)
downloadsssd-71af2725e8f96b403af3f4aa140c413f751380c0.tar.gz
sssd-71af2725e8f96b403af3f4aa140c413f751380c0.tar.xz
sssd-71af2725e8f96b403af3f4aa140c413f751380c0.zip
Store rootdse supported features in sdap_handler
-rw-r--r--src/providers/ipa/ipa_auth.c4
-rw-r--r--src/providers/ldap/ldap_common.h3
-rw-r--r--src/providers/ldap/sdap.c82
-rw-r--r--src/providers/ldap/sdap.h23
-rw-r--r--src/providers/ldap/sdap_async.h8
-rw-r--r--src/providers/ldap/sdap_async_connection.c51
-rw-r--r--src/providers/ldap/sdap_id_op.c4
7 files changed, 112 insertions, 63 deletions
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);