diff options
author | Sumit Bose <sbose@redhat.com> | 2013-03-25 17:41:19 +0100 |
---|---|---|
committer | Jakub Hrozek <jhrozek@redhat.com> | 2013-04-22 15:33:40 +0200 |
commit | edaa983d094c239c3e1ba667bcd20ed3934be3b8 (patch) | |
tree | 3772f4bd4c396cb72784c698a2e66d911793aeff /src/providers/krb5 | |
parent | b3e247cef1f1c81a24ae7759903c11289744e94c (diff) | |
download | sssd-edaa983d094c239c3e1ba667bcd20ed3934be3b8.tar.gz sssd-edaa983d094c239c3e1ba667bcd20ed3934be3b8.tar.bz2 sssd-edaa983d094c239c3e1ba667bcd20ed3934be3b8.zip |
Allow usage of enterprise principals
Enterprise principals are currently most useful for the AD provider and
hence enabled here by default while for the other Kerberos based
authentication providers they are disabled by default.
If additional UPN suffixes are configured for the AD domain the user
principal stored in the AD LDAP server might not contain the real
Kerberos realm of the AD domain but one of the additional suffixes which
might be completely randomly chooses, e.g. are not related to any
existing DNS domain. This make it hard for a client to figure out the
right KDC to send requests to.
To get around this enterprise principals (see
http://tools.ietf.org/html/rfc6806 for details) were introduced.
Basically a default realm is added to the principal so that the Kerberos
client libraries at least know where to send the request to. It is not
in the responsibility of the KDC to either handle the request itself,
return a client referral if he thinks a different KDC can handle the
request or return and error. This feature is also use to allow
authentication in AD environments with cross forest trusts.
Fixes https://fedorahosted.org/sssd/ticket/1842
Diffstat (limited to 'src/providers/krb5')
-rw-r--r-- | src/providers/krb5/krb5_child.c | 14 | ||||
-rw-r--r-- | src/providers/krb5/krb5_child_handler.c | 6 | ||||
-rw-r--r-- | src/providers/krb5/krb5_common.h | 1 | ||||
-rw-r--r-- | src/providers/krb5/krb5_opts.h | 1 |
4 files changed, 18 insertions, 4 deletions
diff --git a/src/providers/krb5/krb5_child.c b/src/providers/krb5/krb5_child.c index dd01e70b..831905af 100644 --- a/src/providers/krb5/krb5_child.c +++ b/src/providers/krb5/krb5_child.c @@ -54,6 +54,7 @@ struct krb5_req { char *keytab; bool validate; bool upn_from_different_realm; + bool use_enterprise_princ; char *fast_ccname; const char *upn; @@ -1549,6 +1550,7 @@ static errno_t unpack_buffer(uint8_t *buf, size_t size, uint32_t len; uint32_t validate; uint32_t different_realm; + uint32_t use_enterprise_princ; struct pam_data *pd; errno_t ret; @@ -1571,6 +1573,8 @@ static errno_t unpack_buffer(uint8_t *buf, size_t size, SAFEALIGN_COPY_UINT32_CHECK(offline, buf + p, size, &p); SAFEALIGN_COPY_UINT32_CHECK(&different_realm, buf + p, size, &p); kr->upn_from_different_realm = (different_realm == 0) ? false : true; + SAFEALIGN_COPY_UINT32_CHECK(&use_enterprise_princ, buf + p, size, &p); + kr->use_enterprise_princ = (use_enterprise_princ == 0) ? false : true; SAFEALIGN_COPY_UINT32_CHECK(&len, buf + p, size, &p); if ((p + len ) > size) return EINVAL; kr->upn = talloc_strndup(pd, (char *)(buf + p), len); @@ -1578,9 +1582,11 @@ static errno_t unpack_buffer(uint8_t *buf, size_t size, p += len; DEBUG(SSSDBG_CONF_SETTINGS, - ("cmd [%d] uid [%llu] gid [%llu] validate [%s] offline [%s] " - "UPN [%s]\n", pd->cmd, (unsigned long long) kr->uid, + ("cmd [%d] uid [%llu] gid [%llu] validate [%s] " + "enterprise principal [%s] offline [%s] UPN [%s]\n", + pd->cmd, (unsigned long long) kr->uid, (unsigned long long) kr->gid, kr->validate ? "true" : "false", + kr->use_enterprise_princ ? "true" : "false", *offline ? "true" : "false", kr->upn ? kr->upn : "none")); if (pd->cmd == SSS_PAM_AUTHENTICATE || @@ -1912,6 +1918,7 @@ static int k5c_setup(struct krb5_req *kr, uint32_t offline) char *lifetime_str; char *use_fast_str; krb5_deltat lifetime; + int parse_flags; kr->realm = getenv(SSSD_KRB5_REALM); if (kr->realm == NULL) { @@ -1936,7 +1943,8 @@ static int k5c_setup(struct krb5_req *kr, uint32_t offline) } } - kerr = krb5_parse_name(kr->ctx, kr->upn, &kr->princ); + parse_flags = kr->use_enterprise_princ ? KRB5_PRINCIPAL_PARSE_ENTERPRISE : 0; + kerr = sss_krb5_parse_name_flags(kr->ctx, kr->upn, parse_flags, &kr->princ); if (kerr != 0) { KRB5_CHILD_DEBUG(SSSDBG_CRIT_FAILURE, kerr); return kerr; diff --git a/src/providers/krb5/krb5_child_handler.c b/src/providers/krb5/krb5_child_handler.c index 8ff65130..0b8cd6b2 100644 --- a/src/providers/krb5/krb5_child_handler.c +++ b/src/providers/krb5/krb5_child_handler.c @@ -130,6 +130,7 @@ static errno_t create_send_buffer(struct krb5child_req *kr, const char *keytab; uint32_t validate; uint32_t different_realm; + uint32_t use_enterprise_principal; size_t username_len = 0; errno_t ret; @@ -141,6 +142,8 @@ static errno_t create_send_buffer(struct krb5child_req *kr, validate = dp_opt_get_bool(kr->krb5_ctx->opts, KRB5_VALIDATE) ? 1 : 0; different_realm = kr->upn_from_different_realm ? 1 : 0; + use_enterprise_principal = dp_opt_get_bool(kr->krb5_ctx->opts, + KRB5_USE_ENTERPRISE_PRINCIPAL) ? 1 : 0; buf = talloc(kr, struct io_buffer); if (buf == NULL) { @@ -148,7 +151,7 @@ static errno_t create_send_buffer(struct krb5child_req *kr, return ENOMEM; } - buf->size = 7*sizeof(uint32_t) + strlen(kr->upn); + buf->size = 8*sizeof(uint32_t) + strlen(kr->upn); if (kr->pd->cmd == SSS_PAM_AUTHENTICATE || kr->pd->cmd == SSS_CMD_RENEW || @@ -182,6 +185,7 @@ static errno_t create_send_buffer(struct krb5child_req *kr, SAFEALIGN_COPY_UINT32(&buf->data[rp], &validate, &rp); SAFEALIGN_COPY_UINT32(&buf->data[rp], &kr->is_offline, &rp); SAFEALIGN_COPY_UINT32(&buf->data[rp], &different_realm, &rp); + SAFEALIGN_COPY_UINT32(&buf->data[rp], &use_enterprise_principal, &rp); SAFEALIGN_SET_UINT32(&buf->data[rp], strlen(kr->upn), &rp); safealign_memcpy(&buf->data[rp], kr->upn, strlen(kr->upn), &rp); diff --git a/src/providers/krb5/krb5_common.h b/src/providers/krb5/krb5_common.h index 13035291..85049360 100644 --- a/src/providers/krb5/krb5_common.h +++ b/src/providers/krb5/krb5_common.h @@ -65,6 +65,7 @@ enum krb5_opts { KRB5_USE_FAST, KRB5_FAST_PRINCIPAL, KRB5_CANONICALIZE, + KRB5_USE_ENTERPRISE_PRINCIPAL, KRB5_OPTS }; diff --git a/src/providers/krb5/krb5_opts.h b/src/providers/krb5/krb5_opts.h index 8ac29532..c8e64782 100644 --- a/src/providers/krb5/krb5_opts.h +++ b/src/providers/krb5/krb5_opts.h @@ -43,6 +43,7 @@ struct dp_option default_krb5_opts[] = { { "krb5_use_fast", DP_OPT_STRING, NULL_STRING, NULL_STRING }, { "krb5_fast_principal", DP_OPT_STRING, NULL_STRING, NULL_STRING }, { "krb5_canonicalize", DP_OPT_BOOL, BOOL_FALSE, BOOL_FALSE }, + { "krb5_use_enterprise_principal", DP_OPT_BOOL, BOOL_FALSE, BOOL_FALSE }, DP_OPTION_TERMINATOR }; |