summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSumit Bose <sbose@redhat.com>2009-04-23 16:33:39 +0200
committerStephen Gallagher <sgallagh@redhat.com>2009-04-27 07:03:08 -0400
commit1cabd594f224825bd0eae543216d87801091c33c (patch)
tree8fec444497a911e377d42de9e156eacb54a184b9
parenta03f9612e6560d4aa32e2813cce1bad88b550713 (diff)
downloadsssd-1cabd594f224825bd0eae543216d87801091c33c.tar.gz
sssd-1cabd594f224825bd0eae543216d87801091c33c.tar.xz
sssd-1cabd594f224825bd0eae543216d87801091c33c.zip
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.
-rw-r--r--server/providers/data_provider.h1
-rw-r--r--server/providers/dp_auth_util.c3
-rw-r--r--server/providers/proxy.c26
-rw-r--r--server/responder/pam/pamsrv_cmd.c1
4 files changed, 22 insertions, 9 deletions
diff --git a/server/providers/data_provider.h b/server/providers/data_provider.h
index 2c828fab3..9278e3961 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 99e57e2e8..630dafe8c 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 907f044e3..0fea89df9 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 158cb32d8..407d7fb98 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);