summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/external/krb5.m43
-rw-r--r--src/providers/krb5/krb5_child.c4
-rw-r--r--src/util/sss_krb5.c183
-rw-r--r--src/util/sss_krb5.h10
4 files changed, 192 insertions, 8 deletions
diff --git a/src/external/krb5.m4 b/src/external/krb5.m4
index d248cd7d..ce442cec 100644
--- a/src/external/krb5.m4
+++ b/src/external/krb5.m4
@@ -41,7 +41,8 @@ AC_CHECK_FUNCS([krb5_get_init_creds_opt_alloc krb5_get_error_message \
krb5_free_unparsed_name \
krb5_get_init_creds_opt_set_expire_callback \
krb5_get_init_creds_opt_set_fast_ccache_name \
- krb5_get_init_creds_opt_set_fast_flags])
+ krb5_get_init_creds_opt_set_fast_flags \
+ krb5_unparse_name_flags])
CFLAGS=$SAVE_CFLAGS
LIBS=$SAVE_LIBS
diff --git a/src/providers/krb5/krb5_child.c b/src/providers/krb5/krb5_child.c
index fcd108aa..ffc6c798 100644
--- a/src/providers/krb5/krb5_child.c
+++ b/src/providers/krb5/krb5_child.c
@@ -1460,11 +1460,11 @@ static int krb5_child_setup(struct krb5_req *kr, uint32_t offline)
DEBUG(1, ("krb5_parse_name failed.\n"));
goto failed;
}
- kerr = krb5_unparse_name_flags(kr->ctx, fast_princ_struct,
+ kerr = sss_krb5_unparse_name_flags(kr->ctx, fast_princ_struct,
KRB5_PRINCIPAL_UNPARSE_NO_REALM,
&tmp_str);
if (kerr) {
- DEBUG(1, ("krb5_unparse_name_flags failed.\n"));
+ DEBUG(1, ("sss_krb5_unparse_name_flags failed.\n"));
goto failed;
}
fast_principal = talloc_strdup(kr, tmp_str);
diff --git a/src/util/sss_krb5.c b/src/util/sss_krb5.c
index 064bc6b1..828e81b0 100644
--- a/src/util/sss_krb5.c
+++ b/src/util/sss_krb5.c
@@ -143,9 +143,9 @@ errno_t select_principal_from_keytab(TALLOC_CTX *mem_ctx,
}
if (_primary) {
- kerr = krb5_unparse_name_flags(krb_ctx, client_princ,
- KRB5_PRINCIPAL_UNPARSE_NO_REALM,
- &principal_string);
+ kerr = sss_krb5_unparse_name_flags(krb_ctx, client_princ,
+ KRB5_PRINCIPAL_UNPARSE_NO_REALM,
+ &principal_string);
if (kerr) {
DEBUG(1, ("krb5_unparse_name failed"));
ret = EFAULT;
@@ -410,8 +410,8 @@ static bool match_principal(krb5_context ctx,
primary_str_len = tmp_len-1;
}
- krb5_unparse_name_flags(ctx, principal, KRB5_PRINCIPAL_UNPARSE_NO_REALM,
- &primary);
+ sss_krb5_unparse_name_flags(ctx, principal, KRB5_PRINCIPAL_UNPARSE_NO_REALM,
+ &primary);
len_diff = strlen(primary)-primary_str_len;
@@ -741,3 +741,176 @@ krb5_error_code KRB5_CALLCONV sss_krb5_get_init_creds_opt_set_fast_flags(
return 0;
#endif
}
+
+
+#ifndef HAVE_KRB5_UNPARSE_NAME_FLAGS
+#ifndef REALM_SEP
+#define REALM_SEP '@'
+#endif
+#ifndef COMPONENT_SEP
+#define COMPONENT_SEP '/'
+#endif
+
+static int
+sss_krb5_copy_component_quoting(char *dest, const krb5_data *src, int flags)
+{
+ int j;
+ const char *cp = src->data;
+ char *q = dest;
+ int length = src->length;
+
+ if (flags & KRB5_PRINCIPAL_UNPARSE_DISPLAY) {
+ memcpy(dest, src->data, src->length);
+ return src->length;
+ }
+
+ for (j=0; j < length; j++,cp++) {
+ int no_realm = (flags & KRB5_PRINCIPAL_UNPARSE_NO_REALM) &&
+ !(flags & KRB5_PRINCIPAL_UNPARSE_SHORT);
+
+ switch (*cp) {
+ case REALM_SEP:
+ if (no_realm) {
+ *q++ = *cp;
+ break;
+ }
+ case COMPONENT_SEP:
+ case '\\':
+ *q++ = '\\';
+ *q++ = *cp;
+ break;
+ case '\t':
+ *q++ = '\\';
+ *q++ = 't';
+ break;
+ case '\n':
+ *q++ = '\\';
+ *q++ = 'n';
+ break;
+ case '\b':
+ *q++ = '\\';
+ *q++ = 'b';
+ break;
+ case '\0':
+ *q++ = '\\';
+ *q++ = '0';
+ break;
+ default:
+ *q++ = *cp;
+ }
+ }
+ return q - dest;
+}
+
+static int
+sss_krb5_component_length_quoted(const krb5_data *src, int flags)
+{
+ const char *cp = src->data;
+ int length = src->length;
+ int j;
+ int size = length;
+
+ if ((flags & KRB5_PRINCIPAL_UNPARSE_DISPLAY) == 0) {
+ int no_realm = (flags & KRB5_PRINCIPAL_UNPARSE_NO_REALM) &&
+ !(flags & KRB5_PRINCIPAL_UNPARSE_SHORT);
+
+ for (j = 0; j < length; j++,cp++)
+ if ((!no_realm && *cp == REALM_SEP) ||
+ *cp == COMPONENT_SEP ||
+ *cp == '\0' || *cp == '\\' || *cp == '\t' ||
+ *cp == '\n' || *cp == '\b')
+ size++;
+ }
+
+ return size;
+}
+
+#endif /* HAVE_KRB5_UNPARSE_NAME_FLAGS */
+
+
+krb5_error_code
+sss_krb5_unparse_name_flags(krb5_context context, krb5_const_principal principal,
+ int flags, char **name)
+{
+#ifdef HAVE_KRB5_UNPARSE_NAME_FLAGS
+ return krb5_unparse_name_flags(context, principal, flags, name);
+#else
+ char *cp, *q;
+ int i;
+ int length;
+ krb5_int32 nelem;
+ unsigned int totalsize = 0;
+ char *default_realm = NULL;
+ krb5_error_code ret = 0;
+
+ if (name != NULL)
+ *name = NULL;
+
+ if (!principal || !name)
+ return KRB5_PARSE_MALFORMED;
+
+ if (flags & KRB5_PRINCIPAL_UNPARSE_SHORT) {
+ /* omit realm if local realm */
+ krb5_principal_data p;
+
+ ret = krb5_get_default_realm(context, &default_realm);
+ if (ret != 0)
+ goto cleanup;
+
+ krb5_princ_realm(context, &p)->length = strlen(default_realm);
+ krb5_princ_realm(context, &p)->data = default_realm;
+
+ if (krb5_realm_compare(context, &p, principal))
+ flags |= KRB5_PRINCIPAL_UNPARSE_NO_REALM;
+ }
+
+ if ((flags & KRB5_PRINCIPAL_UNPARSE_NO_REALM) == 0) {
+ totalsize += sss_krb5_component_length_quoted(krb5_princ_realm(context,
+ principal),
+ flags);
+ totalsize++;
+ }
+
+ nelem = krb5_princ_size(context, principal);
+ for (i = 0; i < (int) nelem; i++) {
+ cp = krb5_princ_component(context, principal, i)->data;
+ totalsize += sss_krb5_component_length_quoted(krb5_princ_component(context, principal, i), flags);
+ totalsize++;
+ }
+ if (nelem == 0)
+ totalsize++;
+
+ *name = malloc(totalsize);
+
+ if (!*name) {
+ ret = ENOMEM;
+ goto cleanup;
+ }
+
+ q = *name;
+
+ for (i = 0; i < (int) nelem; i++) {
+ cp = krb5_princ_component(context, principal, i)->data;
+ length = krb5_princ_component(context, principal, i)->length;
+ q += sss_krb5_copy_component_quoting(q,
+ krb5_princ_component(context,
+ principal,
+ i),
+ flags);
+ *q++ = COMPONENT_SEP;
+ }
+
+ if (i > 0)
+ q--;
+ if ((flags & KRB5_PRINCIPAL_UNPARSE_NO_REALM) == 0) {
+ *q++ = REALM_SEP;
+ q += sss_krb5_copy_component_quoting(q, krb5_princ_realm(context, principal), flags);
+ }
+ *q++ = '\0';
+
+cleanup:
+ free(default_realm);
+
+ return ret;
+#endif /* HAVE_KRB5_UNPARSE_NAME_FLAGS */
+}
diff --git a/src/util/sss_krb5.h b/src/util/sss_krb5.h
index d17bfe96..15f862b4 100644
--- a/src/util/sss_krb5.h
+++ b/src/util/sss_krb5.h
@@ -102,4 +102,14 @@ krb5_error_code KRB5_CALLCONV sss_krb5_get_init_creds_opt_set_fast_flags(
#define SSS_KRB5_FAST_REQUIRED 0
#endif
+
+#ifndef HAVE_KRB5_UNPARSE_NAME_FLAGS
+#define KRB5_PRINCIPAL_UNPARSE_SHORT 0x1
+#define KRB5_PRINCIPAL_UNPARSE_NO_REALM 0x2
+#define KRB5_PRINCIPAL_UNPARSE_DISPLAY 0x4
+#endif
+krb5_error_code
+sss_krb5_unparse_name_flags(krb5_context context, krb5_const_principal principal,
+ int flags, char **name);
+
#endif /* __SSS_KRB5_H__ */