Add PKI subject mapping to user principals

Fix long-standing inability to clear user principal attribute fields
pull/1/head
Timothy Pearson 9 years ago
parent c70ce69a08
commit d9172dad3c

@ -51,9 +51,30 @@
extern "C" { extern "C" {
#include <hdb.h> #include <hdb.h>
#include <hdb_asn1.h>
#include <kadm5/admin.h> #include <kadm5/admin.h>
#include <kadm5/private.h> #include <kadm5/private.h>
#include <kadm5/kadm5-private.h> #include <kadm5/kadm5-private.h>
// ========================================================================
// Taken from asn1-common.h and slightly modified for C++ compilability
// ========================================================================
#define ASN1_MALLOC_ENCODE_HDB(T, B, BL, S, L, R) \
do { \
(BL) = length_##T((S)); \
(B) = (unsigned char*)malloc((BL)); \
if((B) == NULL) { \
(R) = ENOMEM; \
} else { \
(R) = encode_##T(((unsigned char*)(B)) + (BL) - 1, (BL), \
(S), (L)); \
if((R) != 0) { \
free((B)); \
(B) = NULL; \
} \
} \
} while (0)
// ========================================================================
} }
#include "libtdeldap.h" #include "libtdeldap.h"
@ -930,6 +951,14 @@ void add_single_attribute_operation(LDAPMod **mods, int *i, TQString attr, TQStr
mods[*i]->mod_values = values; mods[*i]->mod_values = values;
(*i)++; (*i)++;
} }
else {
char **values = (char**)malloc(sizeof(char*));
values[0] = NULL;
mods[*i]->mod_op = LDAP_MOD_REPLACE;
mods[*i]->mod_type = strdup(attr.ascii());
mods[*i]->mod_values = values;
(*i)++;
}
} }
void add_single_binary_attribute_operation(LDAPMod **mods, int *i, TQString attr, TQByteArray &ba) { void add_single_binary_attribute_operation(LDAPMod **mods, int *i, TQString attr, TQByteArray &ba) {
@ -1023,9 +1052,68 @@ int LDAPManager::updateUserInfo(LDAPUserInfo user, TQString *errstr) {
return -1; return -1;
} }
else { else {
// Create certificate ACL extension data
TQString pkinit_acl_subject = TQString::null;
PKICertificateEntryList::Iterator it;
for (it = user.pkiCertificates.begin(); it != user.pkiCertificates.end(); ++it) {
PKICertificateEntry certificateData = *it;
TQCString ssldata(certificateData.second);
ssldata[certificateData.second.size()] = 0;
ssldata.replace("-----BEGIN CERTIFICATE-----", "");
ssldata.replace("-----END CERTIFICATE-----", "");
ssldata.replace("\n", "");
KSSLCertificate* cert = KSSLCertificate::fromString(ssldata);
if (cert) {
bool expired = false;
if (TQDateTime::currentDateTime(Qt::UTC) > cert->getQDTNotAfter()) {
expired = true;
}
if ((certificateData.first == PKICertificateStatus::Revoked) || expired) {
continue;
}
else {
// NOTE
// At this time Heimdal only appears to support one certificate ACL string
// Use the last valid certificate subject when creating that string
TQStringList reversedSubjectChunks;
TQStringList subjectChunks = TQStringList::split("/", cert->getSubject());
for (TQStringList::Iterator it = subjectChunks.begin(); it != subjectChunks.end(); it++) {
reversedSubjectChunks.prepend(*it);
}
pkinit_acl_subject = reversedSubjectChunks.join(",");
}
}
}
TQByteArray acl_asn1_data;
if (pkinit_acl_subject != "") {
krb5_error_code krb5_ret;
HDB_extension extended_attributes;
memset(&extended_attributes, 0, sizeof(extended_attributes));
extended_attributes.mandatory = true;
extended_attributes.data.element = HDB_extension::HDB_extension_data::choice_HDB_extension_data_pkinit_acl;
HDB_Ext_PKINIT_acl* pkinit_acl = &extended_attributes.data.u.pkinit_acl;
pkinit_acl->val = (HDB_Ext_PKINIT_acl::HDB_Ext_PKINIT_acl_val*)malloc(sizeof(pkinit_acl->val[0]));
pkinit_acl->len = 1;
pkinit_acl->val->subject = const_cast<char*>(pkinit_acl_subject.ascii());
pkinit_acl->val->issuer = NULL;
pkinit_acl->val->anchor = NULL;
unsigned char *asn1_encoding_buf;
size_t initial_size = 0;
size_t resultant_size = 0;
ASN1_MALLOC_ENCODE_HDB(HDB_extension, asn1_encoding_buf, initial_size, &extended_attributes, &resultant_size, krb5_ret);
if (initial_size == resultant_size) {
acl_asn1_data.resize(resultant_size);
memcpy(acl_asn1_data.data(), asn1_encoding_buf, resultant_size);
}
free(pkinit_acl->val);
free(asn1_encoding_buf);
}
// Assemble the LDAPMod structure // Assemble the LDAPMod structure
// We will replace any existing attributes with the new values // We will replace any existing attributes with the new values
int number_of_parameters = 40; // 40 primary attributes int number_of_parameters = 49; // 49 primary attributes
LDAPMod *mods[number_of_parameters+1]; LDAPMod *mods[number_of_parameters+1];
set_up_attribute_operations(mods, number_of_parameters); set_up_attribute_operations(mods, number_of_parameters);
@ -1087,6 +1175,7 @@ int LDAPManager::updateUserInfo(LDAPUserInfo user, TQString *errstr) {
add_single_attribute_operation(mods, &i, "businessCategory", user.businessCategory); add_single_attribute_operation(mods, &i, "businessCategory", user.businessCategory);
add_single_attribute_operation(mods, &i, "carLicense", user.carLicense); add_single_attribute_operation(mods, &i, "carLicense", user.carLicense);
add_single_attribute_operation(mods, &i, "notes", user.notes); add_single_attribute_operation(mods, &i, "notes", user.notes);
add_single_binary_attribute_operation(mods, &i, "krb5ExtendedAttributes", acl_asn1_data);
LDAPMod *prevterm = mods[i]; LDAPMod *prevterm = mods[i];
mods[i] = NULL; mods[i] = NULL;

Loading…
Cancel
Save