summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlexander Bokovoy <abokovoy@redhat.com>2013-07-09 14:05:02 +0300
committerAlexander Bokovoy <abokovoy@redhat.com>2013-07-11 12:39:28 +0300
commit8d6d8459ebaef42959cbbaa771163976439f00bc (patch)
treef69e59f65f8c4e517647ccd219642c3e6d55917e
parentad575f067c49fdc511e9139668529d46b2f5f8bf (diff)
downloadfreeipa-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.
-rw-r--r--daemons/ipa-kdb/ipa_kdb_mspac.c79
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 {