diff options
Diffstat (limited to 'src/providers/ldap')
-rw-r--r-- | src/providers/ldap/ldap_common.c | 10 | ||||
-rw-r--r-- | src/providers/ldap/ldap_id.c | 2 | ||||
-rw-r--r-- | src/providers/ldap/sdap.c | 84 | ||||
-rw-r--r-- | src/providers/ldap/sdap.h | 17 | ||||
-rw-r--r-- | src/providers/ldap/sdap_async.c | 1 | ||||
-rw-r--r-- | src/providers/ldap/sdap_async.h | 6 | ||||
-rw-r--r-- | src/providers/ldap/sdap_async_connection.c | 28 | ||||
-rw-r--r-- | src/providers/ldap/sdap_id_op.c | 9 |
8 files changed, 133 insertions, 24 deletions
diff --git a/src/providers/ldap/ldap_common.c b/src/providers/ldap/ldap_common.c index 4242a7e4..5e2572b8 100644 --- a/src/providers/ldap/ldap_common.c +++ b/src/providers/ldap/ldap_common.c @@ -81,17 +81,17 @@ struct dp_option default_basic_opts[] = { struct sdap_attr_map generic_attr_map[] = { { "ldap_entry_usn", NULL, SYSDB_USN, NULL }, - { "ldap_rootdse_last_usn", NULL, SYSDB_USN, NULL } + { "ldap_rootdse_last_usn", NULL, SYSDB_HIGH_USN, NULL } }; struct sdap_attr_map gen_ipa_attr_map[] = { - { "ldap_entry_usn", "entryUSN", SYSDB_USN, NULL }, - { "ldap_rootdse_last_usn", "lastUSN", SYSDB_HIGH_USN, NULL } + { "ldap_entry_usn", SDAP_IPA_USN, SYSDB_USN, NULL }, + { "ldap_rootdse_last_usn", SDAP_IPA_LAST_USN, SYSDB_HIGH_USN, NULL } }; struct sdap_attr_map gen_ad_attr_map[] = { - { "ldap_entry_usn", "uSNChanged", SYSDB_USN, NULL }, - { "ldap_rootdse_last_usn", "highestCommittedUSN", SYSDB_HIGH_USN, NULL } + { "ldap_entry_usn", SDAP_AD_USN, SYSDB_USN, NULL }, + { "ldap_rootdse_last_usn", SDAP_AD_LAST_USN, SYSDB_HIGH_USN, NULL } }; struct sdap_attr_map rfc2307_user_map[] = { diff --git a/src/providers/ldap/ldap_id.c b/src/providers/ldap/ldap_id.c index 9121a3e9..ce94731c 100644 --- a/src/providers/ldap/ldap_id.c +++ b/src/providers/ldap/ldap_id.c @@ -673,7 +673,7 @@ static void sdap_check_online_done(struct tevent_req *req) int dp_err = DP_ERR_FATAL; bool can_retry; - ret = sdap_cli_connect_recv_ext(req, NULL, &can_retry, NULL); + ret = sdap_cli_connect_recv(req, NULL, &can_retry, NULL, NULL); talloc_zfree(req); if (ret != EOK) { diff --git a/src/providers/ldap/sdap.c b/src/providers/ldap/sdap.c index 1a065cc8..ffe625b3 100644 --- a/src/providers/ldap/sdap.c +++ b/src/providers/ldap/sdap.c @@ -495,7 +495,6 @@ errno_t sdap_set_config_options_with_rootdse(struct sysdb_attrs *rootdse, -1 }; size_t c; - for (c = 0; search_base_options[c] != -1; c++) { if (dp_opt_get_string(opts->basic, search_base_options[c]) == NULL) { if (naming_context == NULL) { @@ -526,6 +525,89 @@ done: return ret; } +int sdap_get_server_opts_from_rootdse(TALLOC_CTX *memctx, + const char *server, + struct sysdb_attrs *rootdse, + struct sdap_options *opts, + struct sdap_server_opts **srv_opts) +{ + struct sdap_server_opts *so; + struct { + const char *last_name; + const char *entry_name; + } usn_attrs[] = { { SDAP_IPA_LAST_USN, SDAP_IPA_USN }, + { SDAP_AD_LAST_USN, SDAP_AD_USN }, + { NULL, NULL } }; + const char *last_usn_name; + const char *last_usn_value; + int ret; + int i; + + so = talloc_zero(memctx, struct sdap_server_opts); + if (!so) { + return ENOMEM; + } + so->server_id = talloc_strdup(so, server); + if (!so->server_id) { + talloc_zfree(so); + return ENOMEM; + } + + last_usn_name = opts->gen_map[SDAP_AT_LAST_USN].name; + if (last_usn_name) { + ret = sysdb_attrs_get_string(rootdse, + last_usn_name, &last_usn_value); + if (ret != EOK) { + switch (ret) { + case ENOENT: + DEBUG(1, ("%s configured but not found in rootdse!\n", + opts->gen_map[SDAP_AT_LAST_USN].opt_name)); + break; + case ERANGE: + DEBUG(1, ("Multiple values of %s found in rootdse!\n", + opts->gen_map[SDAP_AT_LAST_USN].opt_name)); + break; + default: + DEBUG(1, ("Unkown error (%d) checking rootdse!\n", ret)); + } + } else { + const char *entry_usn_name; + entry_usn_name = opts->gen_map[SDAP_AT_ENTRY_USN].name; + if (!entry_usn_name) { + DEBUG(1, ("%s found in rootdse but %s is not set!\n", + last_usn_name, + opts->gen_map[SDAP_AT_ENTRY_USN].opt_name)); + } else { + so->supports_usn = true; + } + } + } else { + /* no usn option configure, let's try to autodetect. */ + for (i = 0; usn_attrs[i].last_name; i++) { + ret = sysdb_attrs_get_string(rootdse, + usn_attrs[i].last_name, + &last_usn_value); + if (ret == EOK) { + /* Fixate discovered configuration */ + opts->gen_map[SDAP_AT_LAST_USN].name = + talloc_strdup(opts->gen_map, usn_attrs[i].last_name); + opts->gen_map[SDAP_AT_ENTRY_USN].name = + talloc_strdup(opts->gen_map, usn_attrs[i].entry_name); + so->supports_usn = true; + last_usn_name = usn_attrs[i].last_name; + break; + } + } + } + + if (!last_usn_name) { + DEBUG(5, ("No known USN scheme is supported by this server\n!")); + } + + *srv_opts = so; + return EOK; +} + int build_attrs_from_map(TALLOC_CTX *memctx, struct sdap_attr_map *map, size_t size, const char ***_attrs) diff --git a/src/providers/ldap/sdap.h b/src/providers/ldap/sdap.h index 5c4f4a54..68242f1a 100644 --- a/src/providers/ldap/sdap.h +++ b/src/providers/ldap/sdap.h @@ -130,6 +130,11 @@ struct sdap_ppolicy_data { #define SDAP_ROOTDSE_ATTR_NAMING_CONTEXTS "namingContexts" #define SDAP_ROOTDSE_ATTR_DEFAULT_NAMING_CONTEXT "defaultNamingContext" +#define SDAP_IPA_USN "entryUSN" +#define SDAP_IPA_LAST_USN "lastUSN" +#define SDAP_AD_USN "uSNChanged" +#define SDAP_AD_LAST_USN "highestCommittedUSN" + enum sdap_result { SDAP_SUCCESS, SDAP_NOT_FOUND, @@ -280,6 +285,13 @@ struct sdap_options { struct ldb_dn *groups_base; }; +struct sdap_server_opts { + char *server_id; + bool supports_usn; + char *max_user_value; + char *max_group_value; +}; + int sdap_get_map(TALLOC_CTX *memctx, struct confdb_ctx *cdb, const char *conf_path, @@ -328,4 +340,9 @@ int sdap_control_create(struct sdap_handle *sh, const char *oid, int iscritical, errno_t sdap_set_config_options_with_rootdse(struct sysdb_attrs *rootdse, struct sdap_handle *sh, struct sdap_options *opts); +int sdap_get_server_opts_from_rootdse(TALLOC_CTX *memctx, + const char *server, + struct sysdb_attrs *rootdse, + struct sdap_options *opts, + struct sdap_server_opts **srv_opts); #endif /* _SDAP_H_ */ diff --git a/src/providers/ldap/sdap_async.c b/src/providers/ldap/sdap_async.c index 6808ceaa..6929b293 100644 --- a/src/providers/ldap/sdap_async.c +++ b/src/providers/ldap/sdap_async.c @@ -655,6 +655,7 @@ struct tevent_req *sdap_get_rootdse_send(TALLOC_CTX *memctx, "supportedLDAPVersion", "supportedSASLMechanisms", SDAP_ROOTDSE_ATTR_DEFAULT_NAMING_CONTEXT, + SDAP_IPA_LAST_USN, SDAP_AD_LAST_USN, NULL }; diff --git a/src/providers/ldap/sdap_async.h b/src/providers/ldap/sdap_async.h index bf54bbd1..10d0c307 100644 --- a/src/providers/ldap/sdap_async.h +++ b/src/providers/ldap/sdap_async.h @@ -129,11 +129,9 @@ struct tevent_req *sdap_cli_connect_send(TALLOC_CTX *memctx, bool skip_rootdse); int sdap_cli_connect_recv(struct tevent_req *req, TALLOC_CTX *memctx, - 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 sdap_handle **gsh, + struct sdap_server_opts **srv_opts); 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 f143a013..2ad9639d 100644 --- a/src/providers/ldap/sdap_async_connection.c +++ b/src/providers/ldap/sdap_async_connection.c @@ -1063,6 +1063,8 @@ struct sdap_cli_connect_state { struct sdap_handle *sh; struct fo_server *srv; + + struct sdap_server_opts *srv_opts; }; static int sdap_cli_resolve_next(struct tevent_req *req); @@ -1094,6 +1096,7 @@ struct tevent_req *sdap_cli_connect_send(TALLOC_CTX *memctx, state->service = service; state->be = be; state->srv = NULL; + state->srv_opts = NULL; state->be = be; state->use_rootdse = !skip_rootdse; @@ -1286,6 +1289,15 @@ static void sdap_cli_rootdse_done(struct tevent_req *subreq) return; } + ret = sdap_get_server_opts_from_rootdse(state, + state->service->uri, rootdse, + state->opts, &state->srv_opts); + if (ret) { + DEBUG(1, ("sdap_get_server_opts_from_rootdse failed.\n")); + tevent_req_error(req, ret); + return; + } + sasl_mech = dp_opt_get_string(state->opts->basic, SDAP_SASL_MECH); if (sasl_mech && state->use_rootdse) { @@ -1416,15 +1428,9 @@ 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) -{ - 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) + 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); @@ -1464,6 +1470,10 @@ int sdap_cli_connect_recv_ext(struct tevent_req *req, talloc_zfree(state->sh); } + if (srv_opts) { + *srv_opts = talloc_steal(memctx, state->srv_opts); + } + return EOK; } diff --git a/src/providers/ldap/sdap_id_op.c b/src/providers/ldap/sdap_id_op.c index a79c64b9..c4194efb 100644 --- a/src/providers/ldap/sdap_id_op.c +++ b/src/providers/ldap/sdap_id_op.c @@ -494,15 +494,16 @@ done: /* Subrequest callback for connection completion */ static void sdap_id_op_connect_done(struct tevent_req *subreq) { - struct sdap_id_conn_data *conn_data = tevent_req_callback_data(subreq, - struct sdap_id_conn_data); + struct sdap_id_conn_data *conn_data = + tevent_req_callback_data(subreq, struct sdap_id_conn_data); struct sdap_id_conn_cache *conn_cache = conn_data->conn_cache; + struct sdap_server_opts *srv_opts; bool can_retry = false; bool is_offline = false; int ret; - ret = sdap_cli_connect_recv_ext(subreq, conn_data, &can_retry, - &conn_data->sh); + ret = sdap_cli_connect_recv(subreq, conn_data, &can_retry, + &conn_data->sh, &srv_opts); conn_data->connect_req = NULL; talloc_zfree(subreq); |