summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSumit Bose <sbose@redhat.com>2013-02-12 14:02:27 +0100
committerMartin Kosek <mkosek@redhat.com>2013-03-08 10:46:00 +0100
commit4e3468211e37f71ca9d434512b68a4caddb2b314 (patch)
tree5a599968c095e95b27fba3ec3065ded066bdfe17
parent3eb64f0a5c1968c97af5bfb4718c36b9f824ea8f (diff)
downloadfreeipa-4e3468211e37f71ca9d434512b68a4caddb2b314.tar.gz
freeipa-4e3468211e37f71ca9d434512b68a4caddb2b314.tar.xz
freeipa-4e3468211e37f71ca9d434512b68a4caddb2b314.zip
ipa-kdb: add PAC only if requested
Instead of always adding a PAC to the Kerberos ticket the global default for the authorization data and the authorization data of the service entry is evaluated and the PAC is added accordingly. https://fedorahosted.org/freeipa/ticket/2960
-rw-r--r--daemons/ipa-kdb/ipa_kdb_mspac.c142
1 files changed, 140 insertions, 2 deletions
diff --git a/daemons/ipa-kdb/ipa_kdb_mspac.c b/daemons/ipa-kdb/ipa_kdb_mspac.c
index eafba9739..2662b947b 100644
--- a/daemons/ipa-kdb/ipa_kdb_mspac.c
+++ b/daemons/ipa-kdb/ipa_kdb_mspac.c
@@ -96,6 +96,10 @@ static char *memberof_pac_attrs[] = {
#define SID_SUB_AUTHS 15
#define MAX(a,b) (((a)>(b))?(a):(b))
+#define AUTHZ_DATA_TYPE_PAC "MS-PAC"
+#define AUTHZ_DATA_TYPE_PAD "PAD"
+#define AUTHZ_DATA_TYPE_NONE "NONE"
+
static int string_to_sid(char *str, struct dom_sid *sid)
{
unsigned long val;
@@ -1515,6 +1519,127 @@ done:
return kerr;
}
+void get_authz_data_types(krb5_context context, krb5_db_entry *entry,
+ bool *_with_pac, bool *_with_pad)
+{
+ struct ipadb_e_data *ied = NULL;
+ struct ipadb_context *ipactx;
+ size_t c;
+ bool none_found = false;
+ bool srv_none_found = false;
+ char **authz_data_list;
+ bool with_pac = false;
+ bool srv_with_pac = false;
+ bool with_pad = false;
+ bool srv_with_pad = false;
+ char *sep;
+ krb5_data *service_type;
+ char *authz_data_type;
+ bool service_specific;
+
+ if (entry != NULL) {
+ ied = (struct ipadb_e_data *) entry->e_data;
+ }
+
+ if (ied == NULL || ied->authz_data == NULL) {
+ if (context == NULL) {
+ krb5_klog_syslog(LOG_ERR, "Missing Kerberos context, no " \
+ "authorization data will be added.");
+ goto done;
+ }
+
+ ipactx = ipadb_get_context(context);
+ if (ipactx == NULL || ipactx->authz_data == NULL) {
+ krb5_klog_syslog(LOG_ERR, "No default authorization data types " \
+ "available, no authorization data will " \
+ "be added.");
+ goto done;
+ }
+
+ authz_data_list = ipactx->authz_data;
+ } else {
+ authz_data_list = ied->authz_data;
+ }
+
+
+ for (c = 0; authz_data_list[c]; c++) {
+ service_specific = false;
+ authz_data_type = authz_data_list[c];
+ sep = strchr(authz_data_list[c], ':');
+ if (sep != NULL) {
+ if (entry->princ == NULL) {
+ krb5_klog_syslog(LOG_ERR, "Missing principal in database "
+ "entry, no authorization data will " \
+ "be added.");
+ goto done;
+ }
+
+ service_type = krb5_princ_component(context, entry->princ, 0);
+ if (service_type == NULL) {
+ krb5_klog_syslog(LOG_ERR, "Missing service type in database "
+ "entry, no authorization data will " \
+ "be added.");
+ goto done;
+ }
+
+ if (service_type->length == (sep - authz_data_list[c]) &&
+ strncmp(authz_data_list[c], service_type->data,
+ service_type->length) == 0) {
+ service_specific = true;
+ authz_data_type = sep + 1;
+ } else {
+ /* Service specific default does not apply, skipping this
+ * entry. */
+ continue;
+ }
+ }
+
+ if (strcmp(authz_data_type, AUTHZ_DATA_TYPE_PAC) == 0) {
+ if (service_specific) {
+ srv_with_pac = true;
+ } else {
+ with_pac = true;
+ }
+ } else if (strcmp(authz_data_type, AUTHZ_DATA_TYPE_PAD) == 0) {
+ if (service_specific) {
+ srv_with_pad = true;
+ } else {
+ with_pad = true;
+ }
+ } else if (strcmp(authz_data_type, AUTHZ_DATA_TYPE_NONE) == 0) {
+ if (service_specific) {
+ srv_none_found = true;
+ } else {
+ none_found = true;
+ }
+ } else {
+ krb5_klog_syslog(LOG_ERR, "Ignoring unsupported " \
+ "authorization data type [%s].",
+ authz_data_list[c]);
+ }
+ }
+
+done:
+ if (srv_none_found || srv_with_pac || srv_with_pad) {
+ none_found = srv_none_found;
+ with_pac = srv_with_pac;
+ with_pad = srv_with_pad;
+ }
+
+ if (none_found) {
+ with_pac = false;
+ with_pad = false;
+ }
+
+ if (_with_pac != NULL) {
+ *_with_pac = with_pac;
+ }
+ if (_with_pad != NULL) {
+ *_with_pad = with_pad;
+ }
+
+}
+
krb5_error_code ipadb_sign_authdata(krb5_context context,
unsigned int flags,
krb5_const_principal client_princ,
@@ -1537,6 +1662,8 @@ krb5_error_code ipadb_sign_authdata(krb5_context context,
krb5_error_code kerr;
krb5_pac pac = NULL;
krb5_data pac_data;
+ bool with_pac;
+ bool with_pad;
/* When using s4u2proxy client_princ actually refers to the proxied user
* while client->princ to the proxy service asking for the TGS on behalf
@@ -1547,9 +1674,20 @@ krb5_error_code ipadb_sign_authdata(krb5_context context,
ks_client_princ = client->princ;
}
+ /* We only need to check the server entry here, because even if the client
+ * is a service with a valid authorization data it will result to NONE
+ * because ipadb_get_pac() can only generate a pac for 'real' IPA users.
+ * (I assume this will be the same for PAD.) */
+ get_authz_data_types(context, server, &with_pac, &with_pad);
+
+ if (with_pad) {
+ krb5_klog_syslog(LOG_ERR, "PAD authorization data is requested but " \
+ "currently not supported.");
+ }
+
is_as_req = ((flags & KRB5_KDB_FLAG_CLIENT_REFERRALS_ONLY) != 0);
- if (is_as_req && (flags & KRB5_KDB_FLAG_INCLUDE_PAC)) {
+ if (is_as_req && with_pac && (flags & KRB5_KDB_FLAG_INCLUDE_PAC)) {
kerr = ipadb_get_pac(context, client, &pac);
if (kerr != 0 && kerr != ENOENT) {
@@ -1557,7 +1695,7 @@ krb5_error_code ipadb_sign_authdata(krb5_context context,
}
}
- if (!is_as_req) {
+ if (!is_as_req && with_pac) {
/* find the existing PAC, if present */
kerr = krb5_find_authdata(context, tgt_auth_data, NULL,
KRB5_AUTHDATA_WIN2K_PAC, &pac_auth_data);