From 1cabd594f224825bd0eae543216d87801091c33c Mon Sep 17 00:00:00 2001 From: Sumit Bose Date: Thu, 23 Apr 2009 16:33:39 +0200 Subject: fix for pam proxy chauthtok When a user from a domain served by the proxy backend changes his password with passwd the passwd command asks for the old password, but it is not validated by the pam_chauthtok call in the proxy backend, because it is running as root. If the request is coming the unpriviledged socket we now call pam_authenticate explicitly before pam_chauthtok. --- server/providers/data_provider.h | 1 + server/providers/dp_auth_util.c | 3 +++ server/providers/proxy.c | 26 +++++++++++++++++--------- server/responder/pam/pamsrv_cmd.c | 1 + 4 files changed, 22 insertions(+), 9 deletions(-) diff --git a/server/providers/data_provider.h b/server/providers/data_provider.h index 2c828fab..9278e396 100644 --- a/server/providers/data_provider.h +++ b/server/providers/data_provider.h @@ -115,6 +115,7 @@ struct pam_data { struct response_data *resp_list; bool offline_auth; + int priv; }; void pam_print_data(int l, struct pam_data *pd); diff --git a/server/providers/dp_auth_util.c b/server/providers/dp_auth_util.c index 99e57e2e..630dafe8 100644 --- a/server/providers/dp_auth_util.c +++ b/server/providers/dp_auth_util.c @@ -34,6 +34,7 @@ void pam_print_data(int l, struct pam_data *pd) DEBUG(l, ("authtok size: %d\n", pd->authtok_size)); DEBUG(l, ("newauthtok type: %d\n", pd->newauthtok_type)); DEBUG(l, ("newauthtok size: %d\n", pd->newauthtok_size)); + DEBUG(l, ("priv: %d\n", pd->priv)); } int pam_add_response(struct pam_data *pd, enum response_type type, @@ -74,6 +75,7 @@ bool dp_pack_pam_request(DBusMessage *msg, struct pam_data *pd) DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE, &(pd->newauthtok), pd->newauthtok_size, + DBUS_TYPE_INT32, &(pd->priv), DBUS_TYPE_INVALID); return ret; @@ -99,6 +101,7 @@ bool dp_unpack_pam_request(DBusMessage *msg, struct pam_data *pd, DBusError *dbu DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE, &(pd->newauthtok), &(pd->newauthtok_size), + DBUS_TYPE_INT32, &(pd->priv), DBUS_TYPE_INVALID); return ret; diff --git a/server/providers/proxy.c b/server/providers/proxy.c index 907f044e..0fea89df 100644 --- a/server/providers/proxy.c +++ b/server/providers/proxy.c @@ -66,8 +66,8 @@ struct proxy_auth_ctx { }; struct authtok_conv { - char *authtok; - char *oldauthtok; + uint32_t authtok_size; + uint8_t *authtok; }; static int proxy_internal_conv(int num_msg, const struct pam_message **msgm, @@ -90,7 +90,11 @@ static int proxy_internal_conv(int num_msg, const struct pam_message **msgm, case PAM_PROMPT_ECHO_OFF: DEBUG(4, ("Conversation message: [%s]\n", msgm[i]->msg)); reply[i].resp_retcode = 0; - reply[i].resp = strdup(auth_data->authtok); + reply[i].resp = calloc(auth_data->authtok_size + 1, + sizeof(char)); + if (reply[i].resp == NULL) goto failed; + memcpy(reply[i].resp, auth_data->authtok, auth_data->authtok_size); + break; default: DEBUG(1, ("Conversation style %d not supported.\n", @@ -142,9 +146,8 @@ static void proxy_pam_handler(struct be_req *req) { } switch (pd->cmd) { case SSS_PAM_AUTHENTICATE: -/* FIXME: \0 missing at the end */ - auth_data->authtok=(char *) pd->authtok; - auth_data->oldauthtok=NULL; + auth_data->authtok_size = pd->authtok_size; + auth_data->authtok = pd->authtok; pam_status=pam_authenticate(pamh, 0); break; case SSS_PAM_SETCRED: @@ -160,9 +163,14 @@ static void proxy_pam_handler(struct be_req *req) { pam_status=pam_close_session(pamh, 0); break; case SSS_PAM_CHAUTHTOK: -/* FIXME: \0 missing at the end */ - auth_data->authtok=(char *) pd->newauthtok; - auth_data->oldauthtok=(char *) pd->authtok; + if (pd->priv != 1) { + auth_data->authtok_size = pd->authtok_size; + auth_data->authtok = pd->authtok; + pam_status=pam_authenticate(pamh, 0); + if (pam_status != PAM_SUCCESS) break; + } + auth_data->authtok_size = pd->newauthtok_size; + auth_data->authtok = pd->newauthtok; pam_status=pam_chauthtok(pamh, 0); break; default: diff --git a/server/responder/pam/pamsrv_cmd.c b/server/responder/pam/pamsrv_cmd.c index 158cb32d..407d7fb9 100644 --- a/server/responder/pam/pamsrv_cmd.c +++ b/server/responder/pam/pamsrv_cmd.c @@ -295,6 +295,7 @@ static int pam_forwarder(struct cli_ctx *cctx, int pam_cmd) } pd->cmd = pam_cmd; + pd->priv = cctx->priv; ret = pam_parse_in_data(cctx->rctx->names, pd, body, blen); if (ret != EOK) { talloc_free(preq); -- cgit