Add ability to store extended principal attributes in LDAP
A careful code review was undertaken, and it was determined that the best way to store the extended attributes was in a native ASN1 encoded field. LDAP does not understand the SEQUENCE of SEQUENCE structures used extensively throughout the extended attributes structure, and there was already a precedent set for storing the krb5Key data in a native ASN1 encoded field.
This commit is contained in:
@@ -2,6 +2,7 @@
|
|||||||
* Copyright (c) 1999-2001, 2003, PADL Software Pty Ltd.
|
* Copyright (c) 1999-2001, 2003, PADL Software Pty Ltd.
|
||||||
* Copyright (c) 2004, Andrew Bartlett.
|
* Copyright (c) 2004, Andrew Bartlett.
|
||||||
* Copyright (c) 2003 - 2008, Kungliga Tekniska Högskolan.
|
* Copyright (c) 2003 - 2008, Kungliga Tekniska Högskolan.
|
||||||
|
* Copyright (c) 2015, Timothy Pearson.
|
||||||
* All rights reserved.
|
* All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
@@ -91,6 +92,7 @@ static char * krb5kdcentry_attrs[] = {
|
|||||||
"krb5PasswordEnd",
|
"krb5PasswordEnd",
|
||||||
"krb5PrincipalName",
|
"krb5PrincipalName",
|
||||||
"krb5PrincipalRealm",
|
"krb5PrincipalRealm",
|
||||||
|
"krb5ExtendedAttributes",
|
||||||
"krb5ValidEnd",
|
"krb5ValidEnd",
|
||||||
"krb5ValidStart",
|
"krb5ValidStart",
|
||||||
"modifiersName",
|
"modifiersName",
|
||||||
@@ -516,6 +518,33 @@ LDAP_entry2mods(krb5_context context, HDB * db, hdb_entry_ex * ent,
|
|||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (is_heimdal_entry && ent->entry.extensions) {
|
||||||
|
if (!is_new_entry) {
|
||||||
|
vals = ldap_get_values_len(HDB2LDAP(db), msg, "krb5ExtendedAttributes");
|
||||||
|
if (vals) {
|
||||||
|
ldap_value_free_len(vals);
|
||||||
|
ret = LDAP_addmod(&mods, LDAP_MOD_DELETE, "krb5ExtendedAttributes", NULL);
|
||||||
|
if (ret)
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < ent->entry.extensions->len; i++) {
|
||||||
|
unsigned char *buf;
|
||||||
|
size_t size, sz = 0;
|
||||||
|
|
||||||
|
ASN1_MALLOC_ENCODE(HDB_extension, buf, size, &ent->entry.extensions->val[i], &sz, ret);
|
||||||
|
if (ret)
|
||||||
|
goto out;
|
||||||
|
if (size != sz)
|
||||||
|
krb5_abortx(context, "internal error in ASN.1 encoder");
|
||||||
|
|
||||||
|
ret = LDAP_addmod_len(&mods, LDAP_MOD_ADD, "krb5ExtendedAttributes", buf, sz);
|
||||||
|
if (ret)
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (is_heimdal_entry && ent->entry.valid_start) {
|
if (is_heimdal_entry && ent->entry.valid_start) {
|
||||||
if (orig.entry.valid_end == NULL
|
if (orig.entry.valid_end == NULL
|
||||||
|| (*(ent->entry.valid_start) != *(orig.entry.valid_start))) {
|
|| (*(ent->entry.valid_start) != *(orig.entry.valid_start))) {
|
||||||
@@ -981,6 +1010,7 @@ LDAP_message2entry(krb5_context context, HDB * db, LDAPMessage * msg,
|
|||||||
char *unparsed_name = NULL, *dn = NULL, *ntPasswordIN = NULL;
|
char *unparsed_name = NULL, *dn = NULL, *ntPasswordIN = NULL;
|
||||||
char *samba_acct_flags = NULL;
|
char *samba_acct_flags = NULL;
|
||||||
struct berval **keys;
|
struct berval **keys;
|
||||||
|
struct berval **extensions;
|
||||||
struct berval **vals;
|
struct berval **vals;
|
||||||
int tmp, tmp_time, i, ret, have_arcfour = 0;
|
int tmp, tmp_time, i, ret, have_arcfour = 0;
|
||||||
|
|
||||||
@@ -1048,6 +1078,33 @@ LDAP_message2entry(krb5_context context, HDB * db, LDAPMessage * msg,
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
extensions = ldap_get_values_len(HDB2LDAP(db), msg, "krb5ExtendedAttributes");
|
||||||
|
if (extensions != NULL) {
|
||||||
|
size_t l;
|
||||||
|
|
||||||
|
ent->entry.extensions = malloc(sizeof(*(ent->entry.extensions)));
|
||||||
|
if (ent->entry.etypes == NULL) {
|
||||||
|
ret = krb5_enomem(context);
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
ent->entry.extensions->len = ldap_count_values_len(extensions);
|
||||||
|
ent->entry.extensions->val = (HDB_extension *) calloc(ent->entry.extensions->len, sizeof(HDB_extension));
|
||||||
|
if (ent->entry.extensions->val == NULL) {
|
||||||
|
ent->entry.extensions->len = 0;
|
||||||
|
ret = krb5_enomem(context);
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
for (i = 0; i < ent->entry.extensions->len; i++) {
|
||||||
|
ret = decode_HDB_extension((unsigned char *) extensions[i]->bv_val,
|
||||||
|
(size_t) extensions[i]->bv_len, &ent->entry.extensions->val[i], &l);
|
||||||
|
if (ret)
|
||||||
|
krb5_set_error_message(context, ret, "decode_HDB_extension failed");
|
||||||
|
}
|
||||||
|
ber_bvecfree(extensions);
|
||||||
|
} else {
|
||||||
|
ent->entry.extensions = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
vals = ldap_get_values_len(HDB2LDAP(db), msg, "krb5EncryptionType");
|
vals = ldap_get_values_len(HDB2LDAP(db), msg, "krb5EncryptionType");
|
||||||
if (vals != NULL) {
|
if (vals != NULL) {
|
||||||
ent->entry.etypes = malloc(sizeof(*(ent->entry.etypes)));
|
ent->entry.etypes = malloc(sizeof(*(ent->entry.etypes)));
|
||||||
|
@@ -113,6 +113,11 @@ attributetype ( 1.3.6.1.4.1.5322.10.1.12
|
|||||||
EQUALITY octetStringMatch
|
EQUALITY octetStringMatch
|
||||||
SYNTAX 1.3.6.1.4.1.1466.115.121.1.40{128} )
|
SYNTAX 1.3.6.1.4.1.1466.115.121.1.40{128} )
|
||||||
|
|
||||||
|
attributetype ( 1.3.6.1.4.1.5322.10.1.13
|
||||||
|
NAME 'krb5ExtendedAttributes'
|
||||||
|
DESC 'Encoded ASN1 HDB Extension Attributes as an octet string'
|
||||||
|
SYNTAX 1.3.6.1.4.1.1466.115.121.1.5 )
|
||||||
|
|
||||||
# Object class definitions
|
# Object class definitions
|
||||||
|
|
||||||
objectclass ( 1.3.6.1.4.1.5322.10.2.1
|
objectclass ( 1.3.6.1.4.1.5322.10.2.1
|
||||||
@@ -129,7 +134,7 @@ objectclass ( 1.3.6.1.4.1.5322.10.2.2
|
|||||||
MUST ( krb5KeyVersionNumber )
|
MUST ( krb5KeyVersionNumber )
|
||||||
MAY ( krb5ValidStart $ krb5ValidEnd $ krb5PasswordEnd $
|
MAY ( krb5ValidStart $ krb5ValidEnd $ krb5PasswordEnd $
|
||||||
krb5MaxLife $ krb5MaxRenew $ krb5KDCFlags $
|
krb5MaxLife $ krb5MaxRenew $ krb5KDCFlags $
|
||||||
krb5EncryptionType $ krb5Key ) )
|
krb5EncryptionType $ krb5Key $ krb5ExtendedAttributes ) )
|
||||||
|
|
||||||
objectclass ( 1.3.6.1.4.1.5322.10.2.3
|
objectclass ( 1.3.6.1.4.1.5322.10.2.3
|
||||||
NAME 'krb5Realm'
|
NAME 'krb5Realm'
|
||||||
|
Reference in New Issue
Block a user