summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--server/responder/pam/pamsrv.h10
-rw-r--r--server/responder/pam/pamsrv_util.c107
-rw-r--r--sss_client/pam_sss.c32
-rw-r--r--sss_client/sss_cli.h3
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,