diff options
author | Alexander Bokovoy <abokovoy@redhat.com> | 2013-07-09 14:05:02 +0300 |
---|---|---|
committer | Alexander Bokovoy <abokovoy@redhat.com> | 2013-07-11 12:39:28 +0300 |
commit | 8d6d8459ebaef42959cbbaa771163976439f00bc (patch) | |
tree | f69e59f65f8c4e517647ccd219642c3e6d55917e /daemons/ipa-kdb | |
parent | ad575f067c49fdc511e9139668529d46b2f5f8bf (diff) | |
download | freeipa-8d6d8459ebaef42959cbbaa771163976439f00bc.tar.gz freeipa-8d6d8459ebaef42959cbbaa771163976439f00bc.tar.xz freeipa-8d6d8459ebaef42959cbbaa771163976439f00bc.zip |
Generate syntethic MS-PAC for all services running on IPA master
MS-PAC is required to be present in TGT if one wants to connect to
AD services using this TGT. Users get MS-PAC by default, SSSD in
ipa_server_mode uses host/fqdn@REALM principal to talk to AD LDAP.
This patch enables other services running on IPA master to connect
to AD services. This is required for IPA python code doing discovery
of remote AD domain settings shortly after IPA-AD trust has been
established.
Diffstat (limited to 'daemons/ipa-kdb')
-rw-r--r-- | daemons/ipa-kdb/ipa_kdb_mspac.c | 79 |
1 files changed, 73 insertions, 6 deletions
diff --git a/daemons/ipa-kdb/ipa_kdb_mspac.c b/daemons/ipa-kdb/ipa_kdb_mspac.c index 92dc8dd7f..96eac6f27 100644 --- a/daemons/ipa-kdb/ipa_kdb_mspac.c +++ b/daemons/ipa-kdb/ipa_kdb_mspac.c @@ -93,9 +93,21 @@ static char *memberof_pac_attrs[] = { NULL }; + +static struct { + char *service; + int length; +} supported_services[] = { + {"cifs", sizeof("cifs")}, + {"HTTP", sizeof("HTTP")}, + {NULL, 0} +}; + + #define SID_ID_AUTHS 6 #define SID_SUB_AUTHS 15 #define MAX(a,b) (((a)>(b))?(a):(b)) +#define MIN(a,b) (((a)<(b))?(a):(b)) #define AUTHZ_DATA_TYPE_PAC "MS-PAC" #define AUTHZ_DATA_TYPE_PAD "PAD" @@ -395,10 +407,14 @@ static krb5_error_code ipadb_fill_info3(struct ipadb_context *ipactx, char *strres; int intres; int ret; + int i; char **objectclasses = NULL; size_t c; bool is_host = false; bool is_user = false; + bool is_service = false; + krb5_principal princ; + krb5_data *data; ret = ipadb_ldap_attr_to_strlist(lcontext, lentry, "objectClass", &objectclasses); @@ -407,6 +423,9 @@ static krb5_error_code ipadb_fill_info3(struct ipadb_context *ipactx, if (strcasecmp(objectclasses[c], "ipaHost") == 0) { is_host = true; } + if (strcasecmp(objectclasses[c], "ipaService") == 0) { + is_service = true; + } if (strcasecmp(objectclasses[c], "ipaNTUserAttrs") == 0) { is_user = true; } @@ -415,8 +434,8 @@ static krb5_error_code ipadb_fill_info3(struct ipadb_context *ipactx, } free(objectclasses); - if (!is_host && !is_user) { - /* We only handle users and hosts */ + if (!is_host && !is_user && !is_service) { + /* We only handle users and hosts, and services */ return ENOENT; } @@ -433,6 +452,54 @@ static krb5_error_code ipadb_fill_info3(struct ipadb_context *ipactx, free(strres); return ENOENT; } + } else if (is_service) { + ret = ipadb_ldap_attr_to_str(lcontext, lentry, "krbPrincipalName", &strres); + if (ret) { + /* krbPrincipalName is mandatory for services */ + return ret; + } + + ret = krb5_parse_name(ipactx->kcontext, strres, &princ); + + free(strres); + if (ret) { + return ENOENT; + } + + if (krb5_princ_size(ipactx->kcontext, princ) != 2) { + krb5_free_principal(ipactx->kcontext, princ); + return ENOENT; + } + + data = krb5_princ_component(ipactx->context, princ, 0); + for (i = 0; supported_services[i].service; i++) { + if (0 == memcmp(data->data, supported_services[i].service, + MIN(supported_services[i].length, data->length))) { + break; + } + } + + if (supported_services[i].service == NULL) { + krb5_free_principal(ipactx->kcontext, princ); + return ENOENT; + } + + data = krb5_princ_component(ipactx->context, princ, 1); + strres = malloc(data->length); + if (strres == NULL) { + krb5_free_principal(ipactx->kcontext, princ); + return ENOENT; + } + + memcpy(strres, data->data, data->length); + krb5_free_principal(ipactx->kcontext, princ); + + /* Only add PAC to TGT to services on IPA masters to allow querying + * AD LDAP server */ + if (!is_master_host(ipactx, strres)) { + free(strres); + return ENOENT; + } } else { ret = ipadb_ldap_attr_to_str(lcontext, lentry, "uid", &strres); if (ret) { @@ -444,7 +511,7 @@ static krb5_error_code ipadb_fill_info3(struct ipadb_context *ipactx, info3->base.account_name.string = talloc_strdup(memctx, strres); free(strres); - if (is_host) { + if (is_host || is_service) { prigid = 515; /* Well known RID for domain computers group */ } else { ret = ipadb_ldap_attr_to_int(lcontext, lentry, "gidNumber", &intres); @@ -567,7 +634,7 @@ static krb5_error_code ipadb_fill_info3(struct ipadb_context *ipactx, info3->base.logon_count = 0; /* we do not have this info yet */ info3->base.bad_password_count = 0; /* we do not have this info yet */ - if (is_host) { + if (is_host || is_service) { /* Well know RID of domain controllers group */ info3->base.rid = 516; } else { @@ -658,7 +725,7 @@ static krb5_error_code ipadb_fill_info3(struct ipadb_context *ipactx, } if (info3->base.primary_gid == 0) { - if (is_host) { + if (is_host || is_service) { info3->base.primary_gid = 515; /* Well known RID for domain computers group */ } else { if (ipactx->mspac->fallback_rid) { @@ -698,7 +765,7 @@ static krb5_error_code ipadb_fill_info3(struct ipadb_context *ipactx, return ENOENT; } - if (is_host) { + if (is_host || is_service) { info3->base.domain_sid = talloc_memdup(memctx, &ipactx->mspac->domsid, sizeof(ipactx->mspac->domsid)); } else { |