diff options
-rw-r--r-- | server/responder/pam/pamsrv.h | 10 | ||||
-rw-r--r-- | server/responder/pam/pamsrv_util.c | 107 | ||||
-rw-r--r-- | sss_client/pam_sss.c | 32 | ||||
-rw-r--r-- | sss_client/sss_cli.h | 3 |
4 files changed, 133 insertions, 19 deletions
diff --git a/server/responder/pam/pamsrv.h b/server/responder/pam/pamsrv.h index c5250f8d..ac29cb16 100644 --- a/server/responder/pam/pamsrv.h +++ b/server/responder/pam/pamsrv.h @@ -41,7 +41,7 @@ struct pam_data { }; int pam_add_response(struct pam_data *pd, enum response_type type, - int len, uint8_t *data); + int len, const uint8_t *data); void pam_print_data(int l, struct pam_data *pd); typedef void (*pam_dp_callback_t)(struct pam_data *pd); @@ -52,8 +52,8 @@ int pam_dp_send_req(struct cli_ctx *cctx, pam_dp_callback_t callback, int timeout, struct pam_data *pd); -int dp_pack_pam_request(DBusMessage *msg, struct pam_data *pd); -int dp_unpack_pam_request(DBusMessage *msg, struct pam_data *pd, DBusError *dbus_error); -int dp_pack_pam_response(DBusMessage *msg, struct pam_data *pd); -int dp_unpack_pam_response(DBusMessage *msg, struct pam_data *pd, DBusError *dbus_error); +bool dp_pack_pam_request(DBusMessage *msg, struct pam_data *pd); +bool dp_unpack_pam_request(DBusMessage *msg, struct pam_data *pd, DBusError *dbus_error); +bool dp_pack_pam_response(DBusMessage *msg, struct pam_data *pd); +bool dp_unpack_pam_response(DBusMessage *msg, struct pam_data *pd, DBusError *dbus_error); #endif /* __PAMSRV_H__ */ diff --git a/server/responder/pam/pamsrv_util.c b/server/responder/pam/pamsrv_util.c index fb82cdcb..1d0ab103 100644 --- a/server/responder/pam/pamsrv_util.c +++ b/server/responder/pam/pamsrv_util.c @@ -17,7 +17,7 @@ void pam_print_data(int l, struct pam_data *pd) } int pam_add_response(struct pam_data *pd, enum response_type type, - int len, uint8_t *data) + int len, const uint8_t *data) { struct response_data *new; @@ -34,7 +34,7 @@ int pam_add_response(struct pam_data *pd, enum response_type type, return EOK; } -int dp_pack_pam_request(DBusMessage *msg, struct pam_data *pd) +bool dp_pack_pam_request(DBusMessage *msg, struct pam_data *pd) { int ret; @@ -59,7 +59,7 @@ int dp_pack_pam_request(DBusMessage *msg, struct pam_data *pd) return ret; } -int dp_unpack_pam_request(DBusMessage *msg, struct pam_data *pd, DBusError *dbus_error) +bool dp_unpack_pam_request(DBusMessage *msg, struct pam_data *pd, DBusError *dbus_error) { int ret; @@ -84,27 +84,106 @@ int dp_unpack_pam_request(DBusMessage *msg, struct pam_data *pd, DBusError *dbus return ret; } -int dp_pack_pam_response(DBusMessage *msg, struct pam_data *pd) +bool dp_pack_pam_response(DBusMessage *msg, struct pam_data *pd) { int ret; + struct response_data *resp; ret = dbus_message_append_args(msg, DBUS_TYPE_UINT32, &(pd->pam_status), DBUS_TYPE_STRING, &(pd->domain), DBUS_TYPE_INVALID); - - return ret; + if (!ret) return ret; + + resp = pd->resp_list; + while (resp != NULL) { + ret=dbus_message_append_args(msg, + DBUS_TYPE_UINT32, &(resp->type), + DBUS_TYPE_UINT32, &(resp->len), + DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE, + &(resp->data), + resp->len, + DBUS_TYPE_INVALID); + if (!ret) return ret; + + resp = resp->next; + } + + return true; } -int dp_unpack_pam_response(DBusMessage *msg, struct pam_data *pd, DBusError *dbus_error) +bool dp_unpack_pam_response(DBusMessage *msg, struct pam_data *pd, DBusError *dbus_error) { int ret; - - ret = dbus_message_get_args(msg, dbus_error, - DBUS_TYPE_UINT32, &(pd->pam_status), - DBUS_TYPE_STRING, &(pd->domain), - DBUS_TYPE_INVALID); - - return ret; + DBusMessageIter iter; + DBusMessageIter sub_iter; + int type; + int len; + int len_msg; + const uint8_t *data; + + if (!dbus_message_iter_init(msg, &iter)) { + DEBUG(1, ("pam response has no arguments.\n")); + return false; + } + + if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_UINT32) { + DEBUG(1, ("pam response format error.\n")); + return false; + } + dbus_message_iter_get_basic(&iter, &(pd->pam_status)); + + if (!dbus_message_iter_next(&iter)) { + DEBUG(1, ("pam response has too few arguments.\n")); + return false; + } + + if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_STRING) { + DEBUG(1, ("pam response format error.\n")); + return false; + } + dbus_message_iter_get_basic(&iter, &(pd->domain)); + + while(dbus_message_iter_next(&iter)) { + if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_UINT32) { + DEBUG(1, ("pam response format error.\n")); + return false; + } + dbus_message_iter_get_basic(&iter, &type); + + if (!dbus_message_iter_next(&iter)) { + DEBUG(1, ("pam response format error.\n")); + return false; + } + + if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_UINT32) { + DEBUG(1, ("pam response format error.\n")); + return false; + } + dbus_message_iter_get_basic(&iter, &len); + + if (!dbus_message_iter_next(&iter)) { + DEBUG(1, ("pam response format error.\n")); + return false; + } + + if (dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_ARRAY || + dbus_message_iter_get_element_type(&iter) != DBUS_TYPE_BYTE) { + DEBUG(1, ("pam response format error.\n")); + return false; + } + + dbus_message_iter_recurse(&iter, &sub_iter); + dbus_message_iter_get_fixed_array(&sub_iter, &data, &len_msg); + if (len != len_msg) { + DEBUG(1, ("pam response format error.\n")); + return false; + } + + pam_add_response(pd, type, len, data); + + } + + return true; } diff --git a/sss_client/pam_sss.c b/sss_client/pam_sss.c index 7f854f95..d919c1cf 100644 --- a/sss_client/pam_sss.c +++ b/sss_client/pam_sss.c @@ -36,7 +36,9 @@ struct pam_items { static int eval_response(pam_handle_t *pamh, int buflen, uint8_t *buf) { + int ret; int p=0; + char *env_item; int32_t *c; int32_t *type; int32_t *len; @@ -61,6 +63,36 @@ static int eval_response(pam_handle_t *pamh, int buflen, uint8_t *buf) case PAM_DOMAIN_NAME: D(("domain name: [%s]", &buf[p])); break; + case ENV_ITEM: + case PAM_ENV_ITEM: + case ALL_ENV_ITEM: + if (buf[p + (*len -1)] != '\0') { + D(("env item does not end with \\0.\n")); + break; + } + + D(("env item: [%s]", &buf[p])); + if (*type == PAM_ENV_ITEM || *type == ALL_ENV_ITEM) { + ret = pam_putenv(pamh, &buf[p]); + if (ret != PAM_SUCCESS) { + D(("pam_putenv failed.\n")); + break; + } + } + + if (*type == ENV_ITEM || *type == ALL_ENV_ITEM) { + env_item = strdup(&buf[p]); + if (env_item == NULL) { + D(("strdup failed\n")); + break; + } + ret = putenv(env_item); + if (ret == -1) { + D(("putenv failed.\n")); + break; + } + } + break; } p += *len; diff --git a/sss_client/sss_cli.h b/sss_client/sss_cli.h index d0eec991..17749af8 100644 --- a/sss_client/sss_cli.h +++ b/sss_client/sss_cli.h @@ -157,6 +157,9 @@ enum sss_status { enum response_type { PAM_USER_INFO = 0x01, PAM_DOMAIN_NAME, + PAM_ENV_ITEM, /* only pam environment */ + ENV_ITEM, /* only user environment */ + ALL_ENV_ITEM, /* pam and user environment */ }; enum nss_status sss_nss_make_request(enum sss_cli_command cmd, |