From 64af76e2bef2565caa9738f675c108a4b3789237 Mon Sep 17 00:00:00 2001 From: Simo Sorce Date: Thu, 18 Oct 2012 18:43:56 -0400 Subject: Change pam data auth tokens. Use the new authtok abstraction and interfaces throught the code. --- src/responder/pam/pam_LOCAL_domain.c | 54 ++++++-------- src/responder/pam/pamsrv_cmd.c | 134 +++++++++++++++++++---------------- 2 files changed, 94 insertions(+), 94 deletions(-) (limited to 'src/responder') diff --git a/src/responder/pam/pam_LOCAL_domain.c b/src/responder/pam/pam_LOCAL_domain.c index 71446b4f..23eb7a2a 100644 --- a/src/responder/pam/pam_LOCAL_domain.c +++ b/src/responder/pam/pam_LOCAL_domain.c @@ -154,22 +154,19 @@ static void do_pam_acct_mgmt(struct LOCAL_request *lreq) static void do_pam_chauthtok(struct LOCAL_request *lreq) { int ret; - char *newauthtok; + const char *password; char *salt; char *new_hash; struct pam_data *pd; pd = lreq->preq->pd; - newauthtok = talloc_strndup(lreq, (char *) pd->newauthtok, - pd->newauthtok_size); - NULL_CHECK_OR_JUMP(newauthtok, ("talloc_strndup failed.\n"), lreq->error, - ENOMEM, done); - memset(pd->newauthtok, 0, pd->newauthtok_size); - - if (strlen(newauthtok) == 0) { + ret = sss_authtok_get_password(&pd->newauthtok, &password, NULL); + if (ret) { /* TODO: should we allow null passwords via a config option ? */ - DEBUG(1, ("Empty passwords are not allowed!\n")); + if (ret == ENOENT) { + DEBUG(1, ("Empty passwords are not allowed!\n")); + } lreq->error = EINVAL; goto done; } @@ -179,11 +176,10 @@ static void do_pam_chauthtok(struct LOCAL_request *lreq) lreq->error, ret, done); DEBUG(4, ("Using salt [%s]\n", salt)); - ret = s3crypt_sha512(lreq, newauthtok, salt, &new_hash); + ret = s3crypt_sha512(lreq, password, salt, &new_hash); NEQ_CHECK_OR_JUMP(ret, EOK, ("Hash generation failed.\n"), lreq->error, ret, done); DEBUG(4, ("New hash [%s]\n", new_hash)); - memset(newauthtok, 0, pd->newauthtok_size); lreq->mod_attrs = sysdb_new_attrs(lreq); NULL_CHECK_OR_JUMP(lreq->mod_attrs, ("sysdb_new_attrs failed.\n"), @@ -204,7 +200,7 @@ static void do_pam_chauthtok(struct LOCAL_request *lreq) lreq->error, ret, done); done: - return; + sss_authtok_set_empty(&pd->newauthtok); } int LOCAL_pam_handler(struct pam_auth_req *preq) @@ -223,9 +219,9 @@ int LOCAL_pam_handler(struct pam_auth_req *preq) NULL}; struct ldb_result *res; const char *username = NULL; - const char *password = NULL; + const char *pwdhash = NULL; char *new_hash = NULL; - char *authtok = NULL; + const char *password; struct pam_data *pd = preq->pd; int ret; @@ -287,25 +283,22 @@ int LOCAL_pam_handler(struct pam_auth_req *preq) DEBUG(4, ("allowing root to reset a password.\n")); break; } - authtok = talloc_strndup(lreq, (char *) pd->authtok, - pd->authtok_size); - NULL_CHECK_OR_JUMP(authtok, ("talloc_strndup failed.\n"), - lreq->error, ENOMEM, done); - memset(pd->authtok, 0, pd->authtok_size); - - password = ldb_msg_find_attr_as_string(res->msgs[0], SYSDB_PWD, NULL); - NULL_CHECK_OR_JUMP(password, ("No password stored.\n"), + ret = sss_authtok_get_password(&pd->authtok, &password, NULL); + NEQ_CHECK_OR_JUMP(ret, EOK, ("Failed to get password.\n"), + lreq->error, ret, done); + + pwdhash = ldb_msg_find_attr_as_string(res->msgs[0], SYSDB_PWD, NULL); + NULL_CHECK_OR_JUMP(pwdhash, ("No password stored.\n"), lreq->error, LDB_ERR_NO_SUCH_ATTRIBUTE, done); - DEBUG(4, ("user: [%s], password hash: [%s]\n", username, password)); + DEBUG(4, ("user: [%s], password hash: [%s]\n", username, pwdhash)); - ret = s3crypt_sha512(lreq, authtok, password, &new_hash); - memset(authtok, 0, pd->authtok_size); + ret = s3crypt_sha512(lreq, password, pwdhash, &new_hash); NEQ_CHECK_OR_JUMP(ret, EOK, ("nss_sha512_crypt failed.\n"), lreq->error, ret, done); DEBUG(4, ("user: [%s], new hash: [%s]\n", username, new_hash)); - if (strcmp(new_hash, password) != 0) { + if (strcmp(new_hash, pwdhash) != 0) { DEBUG(1, ("Passwords do not match.\n")); do_failed_login(lreq); goto done; @@ -338,13 +331,8 @@ int LOCAL_pam_handler(struct pam_auth_req *preq) } done: - if (pd->authtok != NULL) - memset(pd->authtok, 0, pd->authtok_size); - if (authtok != NULL) - memset(authtok, 0, pd->authtok_size); - if (pd->newauthtok != NULL) - memset(pd->newauthtok, 0, pd->newauthtok_size); - + sss_authtok_set_empty(&pd->newauthtok); + sss_authtok_set_empty(&pd->authtok); prepare_reply(lreq); return EOK; } diff --git a/src/responder/pam/pamsrv_cmd.c b/src/responder/pam/pamsrv_cmd.c index ed7438f8..813894d3 100644 --- a/src/responder/pam/pamsrv_cmd.c +++ b/src/responder/pam/pamsrv_cmd.c @@ -49,21 +49,38 @@ enum pam_verbosity { static void pam_reply(struct pam_auth_req *preq); -static int extract_authtok(uint32_t *type, uint32_t *size, uint8_t **tok, - size_t data_size, uint8_t *body, size_t blen, - size_t *c) { +static int extract_authtok_v2(TALLOC_CTX *mem_ctx, struct sss_auth_token *tok, + size_t data_size, uint8_t *body, size_t blen, + size_t *c) +{ + uint32_t auth_token_type; + uint32_t auth_token_length; + uint8_t *auth_token_data; + int ret = EOK; if (data_size < sizeof(uint32_t) || *c+data_size > blen || SIZE_T_OVERFLOW(*c, data_size)) return EINVAL; - *size = data_size - sizeof(uint32_t); - SAFEALIGN_COPY_UINT32_CHECK(type, &body[*c], blen, c); + SAFEALIGN_COPY_UINT32_CHECK(&auth_token_type, &body[*c], blen, c); + auth_token_length = data_size - sizeof(uint32_t); + auth_token_data = body+(*c); - *tok = body+(*c); + switch (auth_token_type) { + case SSS_AUTHTOK_TYPE_EMPTY: + sss_authtok_set_empty(tok); + break; + case SSS_AUTHTOK_TYPE_PASSWORD: + ret = sss_authtok_set_password(mem_ctx, tok, + (const char *)auth_token_data, + auth_token_length); + break; + default: + return EINVAL; + } - *c += (*size); + *c += auth_token_length; - return EOK; + return ret; } static int extract_string(char **var, size_t size, uint8_t *body, size_t blen, @@ -185,14 +202,13 @@ static int pam_parse_in_data_v2(struct sss_domain_info *domains, if (ret != EOK) return ret; break; case SSS_PAM_ITEM_AUTHTOK: - ret = extract_authtok(&pd->authtok_type, &pd->authtok_size, - &pd->authtok, size, body, blen, &c); + ret = extract_authtok_v2(pd, &pd->authtok, + size, body, blen, &c); if (ret != EOK) return ret; break; case SSS_PAM_ITEM_NEWAUTHTOK: - ret = extract_authtok(&pd->newauthtok_type, - &pd->newauthtok_size, - &pd->newauthtok, size, body, blen, &c); + ret = extract_authtok_v2(pd, &pd->newauthtok, + size, body, blen, &c); if (ret != EOK) return ret; break; default: @@ -232,14 +248,44 @@ static int pam_parse_in_data_v3(struct sss_domain_info *domains, return EOK; } +static int extract_authtok_v1(TALLOC_CTX *mem_ctx, struct sss_auth_token *tok, + uint8_t *body, size_t blen, size_t *c) +{ + uint32_t auth_token_type; + uint32_t auth_token_length; + uint8_t *auth_token_data; + int ret = EOK; + + SAFEALIGN_COPY_UINT32_CHECK(&auth_token_type, &body[*c], blen, c); + SAFEALIGN_COPY_UINT32_CHECK(&auth_token_length, &body[*c], blen, c); + auth_token_data = body+(*c); + + switch (auth_token_type) { + case SSS_AUTHTOK_TYPE_EMPTY: + sss_authtok_set_empty(tok); + break; + case SSS_AUTHTOK_TYPE_PASSWORD: + ret = sss_authtok_set_password(mem_ctx, tok, + (const char *)auth_token_data, + auth_token_length); + break; + default: + return EINVAL; + } + + *c += auth_token_length; + + return ret; +} + static int pam_parse_in_data(struct sss_domain_info *domains, const char *default_domain, struct pam_data *pd, uint8_t *body, size_t blen) { - int start; - int end; - int last; + size_t start; + size_t end; + size_t last; int ret; last = blen - 1; @@ -269,45 +315,15 @@ static int pam_parse_in_data(struct sss_domain_info *domains, if (body[end++] != '\0') return EINVAL; pd->rhost = (char *) &body[start]; - start = end; - pd->authtok_type = (int) body[start]; - - start += sizeof(uint32_t); - pd->authtok_size = (int) body[start]; - if (pd->authtok_size >= blen) return EINVAL; - - start += sizeof(uint32_t); - end = start + pd->authtok_size; - if (pd->authtok_size == 0) { - pd->authtok = NULL; - } else { - if (end <= blen) { - pd->authtok = (uint8_t *) &body[start]; - } else { - DEBUG(1, ("Invalid authtok size: %d\n", pd->authtok_size)); - return EINVAL; - } + ret = extract_authtok_v1(pd, &pd->authtok, body, blen, &end); + if (ret) { + DEBUG(1, ("Invalid auth token\n")); + return ret; } - - start = end; - pd->newauthtok_type = (int) body[start]; - - start += sizeof(uint32_t); - pd->newauthtok_size = (int) body[start]; - if (pd->newauthtok_size >= blen) return EINVAL; - - start += sizeof(uint32_t); - end = start + pd->newauthtok_size; - - if (pd->newauthtok_size == 0) { - pd->newauthtok = NULL; - } else { - if (end <= blen) { - pd->newauthtok = (uint8_t *) &body[start]; - } else { - DEBUG(1, ("Invalid newauthtok size: %d\n", pd->newauthtok_size)); - return EINVAL; - } + ret = extract_authtok_v1(pd, &pd->newauthtok, body, blen, &end); + if (ret) { + DEBUG(1, ("Invalid new auth token\n")); + return ret; } DEBUG_PAM_DATA(4, pd); @@ -763,9 +779,9 @@ static void pam_reply(struct pam_auth_req *preq) goto done; } - password = talloc_strndup(preq, pd->authtok, pd->authtok_size); - if (!password) { - DEBUG(0, ("Fatal: Out of memory copying password\n")); + ret = sss_authtok_get_password(&pd->authtok, &password, NULL); + if (ret) { + DEBUG(0, ("Failed to get password.\n")); goto done; } @@ -775,10 +791,6 @@ static void pam_reply(struct pam_auth_req *preq) &exp_date, &delay_until); pam_handle_cached_login(preq, ret, exp_date, delay_until); - if (password) { - for (i = 0; password[i]; i++) password[i] = 0; - talloc_zfree(password); - } return; } break; -- cgit