diff options
-rw-r--r-- | src/providers/data_provider.h | 4 | ||||
-rw-r--r-- | src/providers/dp_auth_util.c | 6 | ||||
-rw-r--r-- | src/providers/krb5/krb5_auth.c | 46 | ||||
-rw-r--r-- | src/providers/krb5/krb5_auth.h | 3 | ||||
-rw-r--r-- | src/providers/krb5/krb5_child.c | 71 | ||||
-rw-r--r-- | src/providers/krb5/krb5_utils.c | 8 | ||||
-rw-r--r-- | src/responder/pam/pamsrv_cmd.c | 18 | ||||
-rw-r--r-- | src/tests/krb5_utils-tests.c | 4 |
8 files changed, 71 insertions, 89 deletions
diff --git a/src/providers/data_provider.h b/src/providers/data_provider.h index 76ba4cff..c43b9885 100644 --- a/src/providers/data_provider.h +++ b/src/providers/data_provider.h @@ -112,10 +112,6 @@ struct pam_data { bool offline_auth; bool last_auth_saved; int priv; - uid_t pw_uid; - gid_t gr_gid; - - const char *upn; }; /* from dp_auth_util.c */ diff --git a/src/providers/dp_auth_util.c b/src/providers/dp_auth_util.c index 39cc0f60..16fb28c7 100644 --- a/src/providers/dp_auth_util.c +++ b/src/providers/dp_auth_util.c @@ -35,8 +35,6 @@ void pam_print_data(int l, struct pam_data *pd) 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)); - DEBUG(l, ("pw_uid: %d\n", pd->pw_uid)); - DEBUG(l, ("gr_gid: %d\n", pd->gr_gid)); DEBUG(l, ("cli_pid: %d\n", pd->cli_pid)); } @@ -86,8 +84,6 @@ bool dp_pack_pam_request(DBusMessage *msg, struct pam_data *pd) &(pd->newauthtok), pd->newauthtok_size, DBUS_TYPE_INT32, &(pd->priv), - DBUS_TYPE_INT32, &(pd->pw_uid), - DBUS_TYPE_INT32, &(pd->gr_gid), DBUS_TYPE_UINT32, &(pd->cli_pid), DBUS_TYPE_INVALID); @@ -115,8 +111,6 @@ bool dp_unpack_pam_request(DBusMessage *msg, struct pam_data *pd, DBusError *dbu &(pd->newauthtok), &(pd->newauthtok_size), DBUS_TYPE_INT32, &(pd->priv), - DBUS_TYPE_INT32, &(pd->pw_uid), - DBUS_TYPE_INT32, &(pd->gr_gid), DBUS_TYPE_UINT32, &(pd->cli_pid), DBUS_TYPE_INVALID); diff --git a/src/providers/krb5/krb5_auth.c b/src/providers/krb5/krb5_auth.c index 19bc998e..0e5230c6 100644 --- a/src/providers/krb5/krb5_auth.c +++ b/src/providers/krb5/krb5_auth.c @@ -316,7 +316,7 @@ errno_t create_send_buffer(struct krb5child_req *kr, struct io_buffer **io_buf) return ENOMEM; } - buf->size = 9*sizeof(uint32_t) + strlen(kr->pd->upn) + strlen(kr->ccname) + + buf->size = 9*sizeof(uint32_t) + strlen(kr->upn) + strlen(kr->ccname) + strlen(keytab) + kr->pd->authtok_size; if (kr->pd->cmd == SSS_PAM_CHAUTHTOK) { @@ -332,13 +332,13 @@ errno_t create_send_buffer(struct krb5child_req *kr, struct io_buffer **io_buf) rp = 0; COPY_UINT32(&buf->data[rp], &kr->pd->cmd, rp); - COPY_UINT32(&buf->data[rp], &kr->pd->pw_uid, rp); - COPY_UINT32(&buf->data[rp], &kr->pd->gr_gid, rp); + COPY_UINT32(&buf->data[rp], &kr->uid, rp); + COPY_UINT32(&buf->data[rp], &kr->gid, rp); COPY_UINT32(&buf->data[rp], &validate, rp); COPY_UINT32(&buf->data[rp], &kr->is_offline, rp); - COPY_UINT32_VALUE(&buf->data[rp], strlen(kr->pd->upn), rp); - COPY_MEM(&buf->data[rp], kr->pd->upn, rp, strlen(kr->pd->upn)); + COPY_UINT32_VALUE(&buf->data[rp], strlen(kr->upn), rp); + COPY_MEM(&buf->data[rp], kr->upn, rp, strlen(kr->upn)); COPY_UINT32_VALUE(&buf->data[rp], strlen(kr->ccname), rp); COPY_MEM(&buf->data[rp], kr->ccname, rp, strlen(kr->ccname)); @@ -516,7 +516,7 @@ static errno_t fork_child(struct krb5child_req *kr) * ccache file. In this case we can drop the privileges, too. */ if (!dp_opt_get_bool(kr->krb5_ctx->opts, KRB5_VALIDATE) || kr->pd->authtok_size == 0) { - ret = become_user(kr->pd->pw_uid, kr->pd->gr_gid); + ret = become_user(kr->uid, kr->gid); if (ret != EOK) { DEBUG(1, ("become_user failed.\n")); return ret; @@ -718,7 +718,7 @@ void krb5_pam_handler(struct be_req *be_req) goto done; } - attrs = talloc_array(be_req, const char *, 4); + attrs = talloc_array(be_req, const char *, 6); if (attrs == NULL) { goto done; } @@ -726,7 +726,9 @@ void krb5_pam_handler(struct be_req *be_req) attrs[0] = SYSDB_UPN; attrs[1] = SYSDB_HOMEDIR; attrs[2] = SYSDB_CCACHE_FILE; - attrs[3] = NULL; + attrs[3] = SYSDB_UIDNUM; + attrs[4] = SYSDB_GIDNUM; + attrs[5] = NULL; ret = sysdb_get_user_attr(be_req, be_req->be_ctx->sysdb, be_req->be_ctx->domain, pd->user, attrs, @@ -753,7 +755,7 @@ static void get_user_attr_done(void *pvt, int err, struct ldb_result *res) krb5_error_code kerr; int ret; struct pam_data *pd = talloc_get_type(be_req->req_data, struct pam_data); - int pam_status=PAM_SYSTEM_ERR; + int pam_status = PAM_SYSTEM_ERR; int dp_err = DP_ERR_FATAL; const char *ccache_file = NULL; const char *realm; @@ -784,15 +786,15 @@ static void get_user_attr_done(void *pvt, int err, struct ldb_result *res) break; case 1: - pd->upn = ldb_msg_find_attr_as_string(res->msgs[0], SYSDB_UPN, NULL); - if (pd->upn == NULL) { + kr->upn = ldb_msg_find_attr_as_string(res->msgs[0], SYSDB_UPN, NULL); + if (kr->upn == NULL) { /* NOTE: this is a hack, works only in some environments */ - pd->upn = talloc_asprintf(be_req, "%s@%s", pd->user, realm); - if (pd->upn == NULL) { + kr->upn = talloc_asprintf(be_req, "%s@%s", pd->user, realm); + if (kr->upn == NULL) { DEBUG(1, ("failed to build simple upn.\n")); goto failed; } - DEBUG(9, ("Using simple UPN [%s].\n", pd->upn)); + DEBUG(9, ("Using simple UPN [%s].\n", kr->upn)); } kr->homedir = ldb_msg_find_attr_as_string(res->msgs[0], SYSDB_HOMEDIR, @@ -801,18 +803,30 @@ static void get_user_attr_done(void *pvt, int err, struct ldb_result *res) DEBUG(4, ("Home directory for user [%s] not known.\n", pd->user)); } + kr->uid = ldb_msg_find_attr_as_uint64(res->msgs[0], SYSDB_UIDNUM, 0); + if (kr->uid == 0) { + DEBUG(4, ("UID for user [%s] not known.\n", pd->user)); + goto failed; + } + + kr->gid = ldb_msg_find_attr_as_uint64(res->msgs[0], SYSDB_GIDNUM, 0); + if (kr->gid == 0) { + DEBUG(4, ("GID for user [%s] not known.\n", pd->user)); + goto failed; + } + ccache_file = ldb_msg_find_attr_as_string(res->msgs[0], SYSDB_CCACHE_FILE, NULL); if (ccache_file != NULL) { - ret = check_if_ccache_file_is_used(pd->pw_uid, ccache_file, + ret = check_if_ccache_file_is_used(kr->uid, ccache_file, &kr->active_ccache_present); if (ret != EOK) { DEBUG(1, ("check_if_ccache_file_is_used failed.\n")); goto failed; } - kerr = check_for_valid_tgt(ccache_file, realm, pd->upn, + kerr = check_for_valid_tgt(ccache_file, realm, kr->upn, &kr->valid_tgt_present); if (kerr != 0) { DEBUG(1, ("check_for_valid_tgt failed.\n")); diff --git a/src/providers/krb5/krb5_auth.h b/src/providers/krb5/krb5_auth.h index a011af89..3e11f270 100644 --- a/src/providers/krb5/krb5_auth.h +++ b/src/providers/krb5/krb5_auth.h @@ -48,6 +48,9 @@ struct krb5child_req { const char *ccname; const char *homedir; + const char *upn; + uid_t uid; + gid_t gid; bool is_offline; struct fo_server *srv; bool active_ccache_present; diff --git a/src/providers/krb5/krb5_child.c b/src/providers/krb5/krb5_child.c index 5e185940..d1cc53fd 100644 --- a/src/providers/krb5/krb5_child.c +++ b/src/providers/krb5/krb5_child.c @@ -89,6 +89,10 @@ struct krb5_req { char *ccname; char *keytab; bool validate; + + const char *upn; + uid_t uid; + gid_t gid; }; static krb5_context krb5_error_ctx; @@ -507,7 +511,7 @@ static krb5_error_code get_and_save_tgt(struct krb5_req *kr, /* We drop root privileges which were needed to read the keytab file * for the validation validation of the credentials here to run the * ccache I/O operations with user privileges. */ - ret = become_user(kr->pd->pw_uid, kr->pd->gr_gid); + ret = become_user(kr->uid, kr->gid); if (ret != EOK) { DEBUG(1, ("become_user failed.\n")); return ret; @@ -723,34 +727,35 @@ static errno_t create_empty_ccache(int fd, struct krb5_req *kr) } static errno_t unpack_buffer(uint8_t *buf, size_t size, struct pam_data *pd, - char **ccname, char **keytab, uint32_t *validate, - uint32_t *offline) + struct krb5_req *kr, uint32_t *offline) { size_t p = 0; uint32_t len; + uint32_t validate; COPY_UINT32_CHECK(&pd->cmd, buf + p, p, size); - COPY_UINT32_CHECK(&pd->pw_uid, buf + p, p, size); - COPY_UINT32_CHECK(&pd->gr_gid, buf + p, p, size); - COPY_UINT32_CHECK(validate, buf + p, p, size); + COPY_UINT32_CHECK(&kr->uid, buf + p, p, size); + COPY_UINT32_CHECK(&kr->gid, buf + p, p, size); + COPY_UINT32_CHECK(&validate, buf + p, p, size); + kr->validate = (validate == 0) ? false : true; COPY_UINT32_CHECK(offline, buf + p, p, size); COPY_UINT32_CHECK(&len, buf + p, p, size); if ((p + len ) > size) return EINVAL; - pd->upn = talloc_strndup(pd, (char *)(buf + p), len); - if (pd->upn == NULL) return ENOMEM; + kr->upn = talloc_strndup(pd, (char *)(buf + p), len); + if (kr->upn == NULL) return ENOMEM; p += len; COPY_UINT32_CHECK(&len, buf + p, p, size); if ((p + len ) > size) return EINVAL; - *ccname = talloc_strndup(pd, (char *)(buf + p), len); - if (*ccname == NULL) return ENOMEM; + kr->ccname = talloc_strndup(pd, (char *)(buf + p), len); + if (kr->ccname == NULL) return ENOMEM; p += len; COPY_UINT32_CHECK(&len, buf + p, p, size); if ((p + len ) > size) return EINVAL; - *keytab = talloc_strndup(pd, (char *)(buf + p), len); - if (*keytab == NULL) return ENOMEM; + kr->keytab = talloc_strndup(pd, (char *)(buf + p), len); + if (kr->keytab == NULL) return ENOMEM; p += len; COPY_UINT32_CHECK(&len, buf + p, p, size); @@ -804,20 +809,10 @@ static int krb5_cleanup(void *ptr) return EOK; } -static int krb5_setup(struct pam_data *pd, const char *user_princ_str, - uint32_t offline, struct krb5_req **krb5_req) +static int krb5_setup(struct krb5_req *kr, uint32_t offline) { - struct krb5_req *kr = NULL; krb5_error_code kerr = 0; - kr = talloc_zero(pd, struct krb5_req); - if (kr == NULL) { - DEBUG(1, ("talloc failed.\n")); - kerr = ENOMEM; - goto failed; - } - talloc_set_destructor((TALLOC_CTX *) kr, krb5_cleanup); - kr->krb5_ctx = talloc_zero(kr, struct krb5_child_ctx); if (kr->krb5_ctx == NULL) { DEBUG(1, ("talloc failed.\n")); @@ -829,7 +824,7 @@ static int krb5_setup(struct pam_data *pd, const char *user_princ_str, if (kr->krb5_ctx->changepw_principle == NULL) { DEBUG(1, ("Cannot read [%s] from environment.\n", SSSD_KRB5_CHANGEPW_PRINCIPLE)); - if (pd->cmd == SSS_PAM_CHAUTHTOK) { + if (kr->pd->cmd == SSS_PAM_CHAUTHTOK) { goto failed; } } @@ -839,9 +834,7 @@ static int krb5_setup(struct pam_data *pd, const char *user_princ_str, DEBUG(2, ("Cannot read [%s] from environment.\n", SSSD_KRB5_REALM)); } - kr->pd = pd; - - switch(pd->cmd) { + switch(kr->pd->cmd) { case SSS_PAM_AUTHENTICATE: /* If we are offline, we need to create an empty ccache file */ if (offline) { @@ -855,7 +848,7 @@ static int krb5_setup(struct pam_data *pd, const char *user_princ_str, kr->child_req = changepw_child; break; default: - DEBUG(1, ("PAM command [%d] not supported.\n", pd->cmd)); + DEBUG(1, ("PAM command [%d] not supported.\n", kr->pd->cmd)); kerr = EINVAL; goto failed; } @@ -866,7 +859,7 @@ static int krb5_setup(struct pam_data *pd, const char *user_princ_str, goto failed; } - kerr = krb5_parse_name(kr->ctx, user_princ_str, &kr->princ); + kerr = krb5_parse_name(kr->ctx, kr->upn, &kr->princ); if (kerr != 0) { KRB5_DEBUG(1, kerr); goto failed; @@ -904,11 +897,9 @@ static int krb5_setup(struct pam_data *pd, const char *user_princ_str, * krb5_get_init_creds_opt_set_pa */ - *krb5_req = kr; return EOK; failed: - talloc_free(kr); return kerr; } @@ -920,9 +911,6 @@ int main(int argc, const char *argv[]) ssize_t len = 0; struct pam_data *pd = NULL; struct krb5_req *kr = NULL; - char *ccname; - char *keytab; - uint32_t validate; uint32_t offline; int opt; poptContext pc; @@ -997,20 +985,25 @@ int main(int argc, const char *argv[]) } close(STDIN_FILENO); - ret = unpack_buffer(buf, len, pd, &ccname, &keytab, &validate, &offline); + kr = talloc_zero(pd, struct krb5_req); + if (kr == NULL) { + DEBUG(1, ("talloc failed.\n")); + goto fail; + } + talloc_set_destructor((TALLOC_CTX *) kr, krb5_cleanup); + kr->pd = pd; + + ret = unpack_buffer(buf, len, pd, kr, &offline); if (ret != EOK) { DEBUG(1, ("unpack_buffer failed.\n")); goto fail; } - ret = krb5_setup(pd, pd->upn, offline, &kr); + ret = krb5_setup(kr, offline); if (ret != EOK) { DEBUG(1, ("krb5_setup failed.\n")); goto fail; } - kr->ccname = ccname; - kr->keytab = keytab; - kr->validate = (validate == 0) ? false : true; ret = kr->child_req(STDOUT_FILENO, kr); if (ret != EOK) { diff --git a/src/providers/krb5/krb5_utils.c b/src/providers/krb5/krb5_utils.c index 489030af..a75ad782 100644 --- a/src/providers/krb5/krb5_utils.c +++ b/src/providers/krb5/krb5_utils.c @@ -74,21 +74,21 @@ char *expand_ccname_template(TALLOC_CTX *mem_ctx, struct krb5child_req *kr, kr->pd->user); break; case 'U': - if (kr->pd->pw_uid <= 0) { + if (kr->uid <= 0) { DEBUG(1, ("Cannot expand uid template " "because uid is invalid.\n")); return NULL; } result = talloc_asprintf_append(result, "%s%d", p, - kr->pd->pw_uid); + kr->uid); break; case 'p': - if (kr->pd->upn == NULL) { + if (kr->upn == NULL) { DEBUG(1, ("Cannot expand user principle name template " "because upn is empty.\n")); return NULL; } - result = talloc_asprintf_append(result, "%s%s", p, kr->pd->upn); + result = talloc_asprintf_append(result, "%s%s", p, kr->upn); break; case '%': result = talloc_asprintf_append(result, "%s%%", p); diff --git a/src/responder/pam/pamsrv_cmd.c b/src/responder/pam/pamsrv_cmd.c index 37aad829..254b18e5 100644 --- a/src/responder/pam/pamsrv_cmd.c +++ b/src/responder/pam/pamsrv_cmd.c @@ -1064,24 +1064,6 @@ static void pam_check_user_callback(void *ptr, int status, case 1: /* BINGO */ - preq->pd->pw_uid = - ldb_msg_find_attr_as_int(res->msgs[0], SYSDB_UIDNUM, -1); - if (preq->pd->pw_uid == -1) { - DEBUG(1, ("Failed to find uid for user [%s] in domain [%s].\n", - preq->pd->user, preq->pd->domain)); - preq->pd->pam_status = PAM_SYSTEM_ERR; - pam_reply(preq); - } - - preq->pd->gr_gid = - ldb_msg_find_attr_as_int(res->msgs[0], SYSDB_GIDNUM, -1); - if (preq->pd->gr_gid == -1) { - DEBUG(1, ("Failed to find gid for user [%s] in domain [%s].\n", - preq->pd->user, preq->pd->domain)); - preq->pd->pam_status = PAM_SYSTEM_ERR; - pam_reply(preq); - } - pam_dom_forwarder(preq); return; diff --git a/src/tests/krb5_utils-tests.c b/src/tests/krb5_utils-tests.c index 8676f3bf..362daf47 100644 --- a/src/tests/krb5_utils-tests.c +++ b/src/tests/krb5_utils-tests.c @@ -64,8 +64,8 @@ void setup_talloc_context(void) fail_unless(pd != NULL, "Cannot create krb5_ctx structure."); pd->user = discard_const(USERNAME); - pd->pw_uid = atoi(UID); - pd->upn = PRINCIPLE_NAME; + kr->uid = atoi(UID); + kr->upn = PRINCIPLE_NAME; pd->cli_pid = atoi(PID); krb5_ctx->opts = talloc_zero_array(tmp_ctx, struct dp_option, KRB5_OPTS); |