summaryrefslogtreecommitdiffstats
path: root/src/providers/krb5
diff options
context:
space:
mode:
authorJakub Hrozek <jhrozek@redhat.com>2012-09-12 19:23:48 +0200
committerJakub Hrozek <jhrozek@redhat.com>2012-09-13 16:51:38 +0200
commitd25e7c659361ebd794ef011dc9305543f266e8c4 (patch)
tree7203927b13d500ce1b41c12db712625bfe6f5f15 /src/providers/krb5
parent3c79852d5d5ba4111c0535bafea43450dba8ed12 (diff)
downloadsssd-d25e7c659361ebd794ef011dc9305543f266e8c4.tar.gz
sssd-d25e7c659361ebd794ef011dc9305543f266e8c4.tar.xz
sssd-d25e7c659361ebd794ef011dc9305543f266e8c4.zip
FO: Check server validity before setting status
The list of resolved servers is allocated on the back end context and kept in the fo_service structure. However, a single request often resolves a server and keeps a pointer until the end of a request and only then gives feedback about the server based on the request result. This presents a big race condition in case the SRV resolution is used. When there are requests coming in in parallel, it is possible that an incoming request will invalidate a server until another request that holds a pointer to the original server is able to give a feedback. This patch simply checks if a server is in the list of servers maintained by a service before reading its status. https://fedorahosted.org/sssd/ticket/1364
Diffstat (limited to 'src/providers/krb5')
-rw-r--r--src/providers/krb5/krb5_auth.c14
1 files changed, 9 insertions, 5 deletions
diff --git a/src/providers/krb5/krb5_auth.c b/src/providers/krb5/krb5_auth.c
index ec488e7dd..a305bb69c 100644
--- a/src/providers/krb5/krb5_auth.c
+++ b/src/providers/krb5/krb5_auth.c
@@ -819,6 +819,7 @@ static void krb5_child_done(struct tevent_req *subreq)
/* ..which is unreachable by now.. */
if (res->msg_status == PAM_AUTHTOK_LOCK_BUSY) {
be_fo_set_port_status(state->be_ctx,
+ state->krb5_ctx->service->name,
kr->kpasswd_srv, PORT_NOT_WORKING);
/* ..try to resolve next kpasswd server */
if (krb5_next_kpasswd(req) == NULL) {
@@ -827,6 +828,7 @@ static void krb5_child_done(struct tevent_req *subreq)
return;
} else {
be_fo_set_port_status(state->be_ctx,
+ state->krb5_ctx->service->name,
kr->kpasswd_srv, PORT_WORKING);
}
}
@@ -837,7 +839,8 @@ static void krb5_child_done(struct tevent_req *subreq)
if (res->msg_status == PAM_AUTHINFO_UNAVAIL ||
(kr->kpasswd_srv == NULL && res->msg_status == PAM_AUTHTOK_LOCK_BUSY)) {
if (kr->srv != NULL) {
- be_fo_set_port_status(state->be_ctx, kr->srv, PORT_NOT_WORKING);
+ be_fo_set_port_status(state->be_ctx, state->krb5_ctx->service->name,
+ kr->srv, PORT_NOT_WORKING);
/* ..try to resolve next KDC */
if (krb5_next_kdc(req) == NULL) {
tevent_req_error(req, ENOMEM);
@@ -845,7 +848,8 @@ static void krb5_child_done(struct tevent_req *subreq)
return;
}
} else if (kr->srv != NULL) {
- be_fo_set_port_status(state->be_ctx, kr->srv, PORT_WORKING);
+ be_fo_set_port_status(state->be_ctx, state->krb5_ctx->service->name,
+ kr->srv, PORT_WORKING);
}
/* Now only a successful authentication or password change is left.
@@ -917,19 +921,19 @@ static struct tevent_req *krb5_next_server(struct tevent_req *req)
switch (pd->cmd) {
case SSS_PAM_AUTHENTICATE:
case SSS_CMD_RENEW:
- be_fo_set_port_status(state->be_ctx,
+ be_fo_set_port_status(state->be_ctx, state->krb5_ctx->service->name,
state->kr->srv, PORT_NOT_WORKING);
next_req = krb5_next_kdc(req);
break;
case SSS_PAM_CHAUTHTOK:
case SSS_PAM_CHAUTHTOK_PRELIM:
if (state->kr->kpasswd_srv) {
- be_fo_set_port_status(state->be_ctx,
+ be_fo_set_port_status(state->be_ctx, state->krb5_ctx->service->name,
state->kr->kpasswd_srv, PORT_NOT_WORKING);
next_req = krb5_next_kpasswd(req);
break;
} else {
- be_fo_set_port_status(state->be_ctx,
+ be_fo_set_port_status(state->be_ctx, state->krb5_ctx->service->name,
state->kr->srv, PORT_NOT_WORKING);
next_req = krb5_next_kdc(req);
break;