summaryrefslogtreecommitdiffstats
path: root/sss_client
diff options
context:
space:
mode:
Diffstat (limited to 'sss_client')
-rw-r--r--sss_client/pam_sss.c138
-rw-r--r--sss_client/sss_cli.h15
2 files changed, 150 insertions, 3 deletions
diff --git a/sss_client/pam_sss.c b/sss_client/pam_sss.c
index 3ed642a7a..2b676f078 100644
--- a/sss_client/pam_sss.c
+++ b/sss_client/pam_sss.c
@@ -9,6 +9,7 @@
#include <stdlib.h>
#include <stdint.h>
#include <syslog.h>
+#include <locale.h>
#include <security/pam_modules.h>
#include <security/pam_misc.h>
@@ -39,6 +40,8 @@ struct pam_items {
size_t pam_authtok_size;
int pam_newauthtok_type;
size_t pam_newauthtok_size;
+ char *pam_cli_locale;
+ size_t pam_cli_locale_size;
};
#define DEBUG_MGS_LEN 1024
@@ -71,6 +74,126 @@ static void logger(pam_handle_t *pamh, int level, const char *fmt, ...) {
va_end(ap);
}
+
+static size_t add_authtok_item(enum pam_item_type type,
+ enum sss_authtok_type authtok_type,
+ const char *tok, const size_t size,
+ uint8_t *buf) {
+ size_t rp=0;
+
+ if (tok == NULL) return 0;
+
+ ((uint32_t *)(&buf[rp]))[0] = type;
+ rp += sizeof(uint32_t);
+
+ ((uint32_t *)(&buf[rp]))[0] = size + sizeof(uint32_t);
+ rp += sizeof(uint32_t);
+
+ ((uint32_t *)(&buf[rp]))[0] = authtok_type;
+ rp += sizeof(uint32_t);
+
+ memcpy(&buf[rp], tok, size);
+ rp += size;
+
+ return rp;
+}
+
+static size_t add_string_item(enum pam_item_type type, const char *str,
+ const size_t size, uint8_t *buf) {
+ size_t rp=0;
+
+ if (*str == '\0') return 0;
+
+ ((uint32_t *)(&buf[rp]))[0] = type;
+ rp += sizeof(uint32_t);
+
+ ((uint32_t *)(&buf[rp]))[0] = size;
+ rp += sizeof(uint32_t);
+
+ memcpy(&buf[rp], str, size);
+ rp += size;
+
+ return rp;
+}
+
+static int pack_message_v2(struct pam_items *pi, size_t *size, uint8_t **buffer) {
+ int len;
+ uint8_t *buf;
+ int rp;
+
+ len = sizeof(uint32_t) +
+ 2*sizeof(uint32_t) + pi->pam_user_size +
+ sizeof(uint32_t);
+ len += *pi->pam_service != '\0' ?
+ 2*sizeof(uint32_t) + pi->pam_service_size : 0;
+ len += *pi->pam_tty != '\0' ?
+ 2*sizeof(uint32_t) + pi->pam_tty_size : 0;
+ len += *pi->pam_ruser != '\0' ?
+ 2*sizeof(uint32_t) + pi->pam_ruser_size : 0;
+ len += *pi->pam_rhost != '\0' ?
+ 2*sizeof(uint32_t) + pi->pam_rhost_size : 0;
+ len += *pi->pam_cli_locale != '\0' ?
+ 2*sizeof(uint32_t) + pi->pam_cli_locale_size : 0;
+ len += pi->pam_authtok != NULL ?
+ 3*sizeof(uint32_t) + pi->pam_authtok_size : 0;
+ len += pi->pam_newauthtok != NULL ?
+ 3*sizeof(uint32_t) + pi->pam_newauthtok_size : 0;
+
+ buf = malloc(len);
+ if (buf == NULL) {
+ D(("malloc failed."));
+ return PAM_BUF_ERR;
+ }
+
+ rp = 0;
+ ((uint32_t *)(&buf[rp]))[0] = START_OF_PAM_REQUEST;
+ rp += sizeof(uint32_t);
+
+ rp += add_string_item(PAM_ITEM_USER, pi->pam_user, pi->pam_user_size,
+ &buf[rp]);
+
+ rp += add_string_item(PAM_ITEM_SERVICE, pi->pam_service,
+ pi->pam_service_size, &buf[rp]);
+
+ rp += add_string_item(PAM_ITEM_TTY, pi->pam_tty, pi->pam_tty_size,
+ &buf[rp]);
+
+ rp += add_string_item(PAM_ITEM_RUSER, pi->pam_ruser, pi->pam_ruser_size,
+ &buf[rp]);
+
+ rp += add_string_item(PAM_ITEM_RHOST, pi->pam_rhost, pi->pam_rhost_size,
+ &buf[rp]);
+
+ rp += add_string_item(PAM_CLI_LOCALE, pi->pam_cli_locale,
+ pi->pam_cli_locale_size, &buf[rp]);
+
+ rp += add_authtok_item(PAM_ITEM_AUTHTOK, pi->pam_authtok_type,
+ pi->pam_authtok, pi->pam_authtok_size, &buf[rp]);
+ _pam_overwrite_n((void *)pi->pam_authtok, pi->pam_authtok_size);
+ free((void *)pi->pam_authtok);
+ pi->pam_authtok = NULL;
+
+ rp += add_authtok_item(PAM_ITEM_NEWAUTHTOK, pi->pam_newauthtok_type,
+ pi->pam_newauthtok, pi->pam_newauthtok_size,
+ &buf[rp]);
+ _pam_overwrite_n((void *)pi->pam_newauthtok, pi->pam_newauthtok_size);
+ free((void *)pi->pam_newauthtok);
+ pi->pam_newauthtok = NULL;
+
+ ((uint32_t *)(&buf[rp]))[0] = END_OF_PAM_REQUEST;
+ rp += sizeof(uint32_t);
+
+ if (rp != len) {
+ D(("error during packet creation."));
+ return PAM_BUF_ERR;
+ }
+
+ *size = len;
+ *buffer = buf;
+
+ return 0;
+}
+
static int pack_message(struct pam_items *pi, size_t *size, uint8_t **buffer) {
int len;
uint8_t *buf;
@@ -347,6 +470,7 @@ static int eval_response(pam_handle_t *pamh, size_t buflen, uint8_t *buf)
static int get_pam_items(pam_handle_t *pamh, struct pam_items *pi)
{
int ret;
+ char *cli_locale;
pi->pam_authtok_type = SSS_AUTHTOK_TYPE_EMPTY;
pi->pam_authtok = NULL;
@@ -388,6 +512,15 @@ static int get_pam_items(pam_handle_t *pamh, struct pam_items *pi)
if (ret != PAM_SUCCESS) return ret;
if (pi->pamstack_oldauthtok == NULL) pi->pamstack_oldauthtok="";
+ cli_locale = setlocale(LC_ALL, NULL);
+ if (cli_locale == NULL) {
+ pi->pam_cli_locale = "";
+ } else {
+ pi->pam_cli_locale = strdup(cli_locale);
+ if (pi->pam_cli_locale == NULL) return PAM_BUF_ERR;
+ }
+ pi->pam_cli_locale_size = strlen(pi->pam_cli_locale)+1;
+
return PAM_SUCCESS;
}
@@ -406,6 +539,7 @@ static void print_pam_items(struct pam_items pi)
if (pi.pam_newauthtok != NULL) {
D(("Newauthtok: %s", *pi.pam_newauthtok!='\0' ? pi.pam_newauthtok : "(not available)"));
}
+ D(("Locale: %s", *pi.pam_cli_locale!='\0' ? pi.pam_cli_locale : "(not available)"));
}
static int pam_sss(int task, pam_handle_t *pamh, int pam_flags, int argc,
@@ -550,7 +684,7 @@ static int pam_sss(int task, pam_handle_t *pamh, int pam_flags, int argc,
goto done;
}
pi.pam_newauthtok_type = SSS_AUTHTOK_TYPE_PASSWORD;
- pi.pam_newauthtok_size=strlen(pi.pam_authtok);
+ pi.pam_newauthtok_size=strlen(pi.pam_newauthtok);
}
if (flags & FLAGS_FORWARD_PASS) {
@@ -564,7 +698,7 @@ static int pam_sss(int task, pam_handle_t *pamh, int pam_flags, int argc,
print_pam_items(pi);
- ret = pack_message(&pi, &rd.len, &buf);
+ ret = pack_message_v2(&pi, &rd.len, &buf);
if (ret != 0) {
D(("pack_message failed."));
pam_status = PAM_SYSTEM_ERR;
diff --git a/sss_client/sss_cli.h b/sss_client/sss_cli.h
index ba412fd07..63daf7bca 100644
--- a/sss_client/sss_cli.h
+++ b/sss_client/sss_cli.h
@@ -22,7 +22,7 @@
#define SSS_PAM_PRIV_SOCKET_NAME "/var/lib/sss/pipes/private/pam"
#define SSS_NSS_PROTOCOL_VERSION 1
-#define SSS_PAM_PROTOCOL_VERSION 1
+#define SSS_PAM_PROTOCOL_VERSION 2
enum sss_cli_command {
/* null */
@@ -138,8 +138,21 @@ enum sss_authtok_type {
SSS_AUTHTOK_TYPE_PASSWORD = 0x0001,
};
+#define START_OF_PAM_REQUEST 0x4d415049
#define END_OF_PAM_REQUEST 0x4950414d
+enum pam_item_type {
+ PAM_ITEM_EMPTY = 0x0000,
+ PAM_ITEM_USER,
+ PAM_ITEM_SERVICE,
+ PAM_ITEM_TTY,
+ PAM_ITEM_RUSER,
+ PAM_ITEM_RHOST,
+ PAM_ITEM_AUTHTOK,
+ PAM_ITEM_NEWAUTHTOK,
+ PAM_CLI_LOCALE,
+};
+
#define SSS_NSS_MAX_ENTRIES 256
#define SSS_NSS_HEADER_SIZE (sizeof(uint32_t) * 4)
struct sss_cli_req_data {