I'm sending two patches related to the last USN detection (ticket #734). I did some testing and they seem to work just fine. The only thing I'm not sure about is if I got right what Simo exactly meant by the ticket, but I hope I got it right.
Thanks Jan
From b71727ac1133bf7d1d67545acf81f7d3a61df0fe Mon Sep 17 00:00:00 2001 From: Jan Zeleny <jzel...@redhat.com> Date: Mon, 7 Mar 2011 10:25:21 +0100 Subject: [PATCH 1/2] Add value of the last USN to server configuration Related: https://fedorahosted.org/sssd/ticket/734 --- src/providers/ldap/sdap.c | 15 +++++++++++++++ src/providers/ldap/sdap.h | 1 + 2 files changed, 16 insertions(+), 0 deletions(-) diff --git a/src/providers/ldap/sdap.c b/src/providers/ldap/sdap.c index 5e4e56d..cddc5c5 100644 --- a/src/providers/ldap/sdap.c +++ b/src/providers/ldap/sdap.c @@ -590,6 +590,7 @@ int sdap_get_server_opts_from_rootdse(TALLOC_CTX *memctx, const char *last_usn_name; const char *last_usn_value; const char *entry_usn_name; + char *endptr = NULL; int ret; int i; @@ -628,6 +629,13 @@ int sdap_get_server_opts_from_rootdse(TALLOC_CTX *memctx, opts->gen_map[SDAP_AT_ENTRY_USN].opt_name)); } else { so->supports_usn = true; + so->last_usn = strtoul(last_usn_value, &endptr, 10); + if (endptr != NULL && (*endptr != '\0' || endptr == last_usn_value)) { + DEBUG(3, ("USN is not valid (value: %s)\n", last_usn_value)); + so->last_usn = 0; + } else { + DEBUG(9, ("USN value: %s (int: %lu)\n", last_usn_value, so->last_usn)); + } } } } else { @@ -643,6 +651,13 @@ int sdap_get_server_opts_from_rootdse(TALLOC_CTX *memctx, opts->gen_map[SDAP_AT_ENTRY_USN].name = talloc_strdup(opts->gen_map, usn_attrs[i].entry_name); so->supports_usn = true; + so->last_usn = strtoul(last_usn_value, &endptr, 10); + if (endptr != NULL && (*endptr != '\0' || endptr == last_usn_value)) { + DEBUG(3, ("USN is not valid (value: %s)\n", last_usn_value)); + so->last_usn = 0; + } else { + DEBUG(9, ("USN value: %s (int: %lu)\n", last_usn_value, so->last_usn)); + } last_usn_name = usn_attrs[i].last_name; break; } diff --git a/src/providers/ldap/sdap.h b/src/providers/ldap/sdap.h index 31e72cd..e74a87b 100644 --- a/src/providers/ldap/sdap.h +++ b/src/providers/ldap/sdap.h @@ -304,6 +304,7 @@ struct sdap_options { struct sdap_server_opts { char *server_id; bool supports_usn; + unsigned long last_usn; char *max_user_value; char *max_group_value; }; -- 1.7.4.1
From c4daa3f0da179e757bbe50a0e1a1b1adcc15b201 Mon Sep 17 00:00:00 2001 From: Jan Zeleny <jzel...@redhat.com> Date: Mon, 7 Mar 2011 13:38:43 +0100 Subject: [PATCH 2/2] Add last usn checking after reconnection When reconnecting to the LDAP server supporting USNs (either because of new incomming id operation or invokation of callback responsible for checking status of the backend), detect whether the highest USN is lower than the one SSSD has recorded. If so, setup enumeration/cleanup to refresh potentionally changed account information in the SSSD cache. Related ticket: https://fedorahosted.org/sssd/ticket/734 --- src/providers/ldap/ldap_id.c | 18 +++++++++++++++++- src/providers/ldap/sdap_id_op.c | 16 ++++++++++++++++ 2 files changed, 33 insertions(+), 1 deletions(-) diff --git a/src/providers/ldap/ldap_id.c b/src/providers/ldap/ldap_id.c index 9a23428..1f10bbb 100644 --- a/src/providers/ldap/ldap_id.c +++ b/src/providers/ldap/ldap_id.c @@ -688,8 +688,13 @@ static void sdap_check_online_done(struct tevent_req *req) int ret; int dp_err = DP_ERR_FATAL; bool can_retry; + struct sdap_id_ctx *ctx; + struct sdap_server_opts *srv_opts; + + ctx = talloc_get_type(be_req->be_ctx->bet_info[BET_ID].pvt_bet_data, + struct sdap_id_ctx); - ret = sdap_cli_connect_recv(req, NULL, &can_retry, NULL, NULL); + ret = sdap_cli_connect_recv(req, NULL, &can_retry, NULL, &srv_opts); talloc_zfree(req); if (ret != EOK) { @@ -698,6 +703,17 @@ static void sdap_check_online_done(struct tevent_req *req) } } else { dp_err = DP_ERR_OK; + + if (strcmp(srv_opts->server_id, ctx->srv_opts->server_id) == 0 && + srv_opts->supports_usn && + ctx->srv_opts->last_usn > srv_opts->last_usn) { + ret = sdap_id_setup_tasks(ctx); + if (ret != EOK) { + dp_err= DP_ERR_FATAL; + } + } + + sdap_steal_server_opts(ctx, &srv_opts); } sdap_handler_done(be_req, dp_err, 0, NULL); diff --git a/src/providers/ldap/sdap_id_op.c b/src/providers/ldap/sdap_id_op.c index c38a803..29cd835 100644 --- a/src/providers/ldap/sdap_id_op.c +++ b/src/providers/ldap/sdap_id_op.c @@ -498,6 +498,7 @@ static void sdap_id_op_connect_done(struct tevent_req *subreq) 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 = NULL; + struct sdap_server_opts *current_srv_opts = NULL; bool can_retry = false; bool is_offline = false; int ret; @@ -527,6 +528,21 @@ static void sdap_id_op_connect_done(struct tevent_req *subreq) } if (ret == EOK) { + current_srv_opts = conn_cache->id_ctx->srv_opts; + if (current_srv_opts) { + DEBUG(8, ("Old USN: %lu, New USN: %lu\n", current_srv_opts->last_usn, srv_opts->last_usn)); + + if (strcmp(srv_opts->server_id, current_srv_opts->server_id) == 0 && + srv_opts->supports_usn && + current_srv_opts->last_usn > srv_opts->last_usn) { + DEBUG(5, ("Server was probably re-initialized\n")); + + ret = sdap_id_setup_tasks(conn_cache->id_ctx); + if (ret != EOK) { + DEBUG(4, ("Failed to set up enumeration for reconnected server!\n")); + } + } + } ret = sdap_id_conn_data_set_expire_timer(conn_data); sdap_steal_server_opts(conn_cache->id_ctx, &srv_opts); } -- 1.7.4.1
_______________________________________________ sssd-devel mailing list sssd-devel@lists.fedorahosted.org https://fedorahosted.org/mailman/listinfo/sssd-devel