From ff874295933646b8adcaed82bc91b07bdeb3acb5 Mon Sep 17 00:00:00 2001 From: Love Hornquist Astrand Date: Sat, 3 Oct 2009 13:20:41 -0700 Subject: [PATCH] Make LDAP code fetch less attributes from LDAP server when KDC is asking MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Johan Gadsjö did a awesome analysis of the LDAP access pattens and sent us a patch that reduced the calls the ldap server by 4 times as many. The patch was adopted and change to avoid compile time depencies and make the determination runtime instead. Thanks! --- lib/hdb/hdb-ldap.c | 57 ++++++++++++++++++++------------------- lib/hdb/hdb.h | 1 + lib/kadm5/chpass_s.c | 4 +-- lib/kadm5/delete_s.c | 2 +- lib/kadm5/get_princs_s.c | 2 +- lib/kadm5/get_s.c | 2 +- lib/kadm5/ipropd_master.c | 2 +- lib/kadm5/log.c | 2 +- lib/kadm5/modify_s.c | 2 +- lib/kadm5/randkey_s.c | 2 +- lib/kadm5/rename_s.c | 2 +- 11 files changed, 40 insertions(+), 38 deletions(-) diff --git a/lib/hdb/hdb-ldap.c b/lib/hdb/hdb-ldap.c index 173a9dd88..143509444 100644 --- a/lib/hdb/hdb-ldap.c +++ b/lib/hdb/hdb-ldap.c @@ -46,7 +46,7 @@ static krb5_error_code LDAP_close(krb5_context context, HDB *); static krb5_error_code LDAP_message2entry(krb5_context context, HDB * db, LDAPMessage * msg, - hdb_entry_ex * ent); + int flags, hdb_entry_ex * ent); static const char *default_structural_object = "account"; static char *structural_object; @@ -402,7 +402,7 @@ LDAP_entry2mods(krb5_context context, HDB * db, hdb_entry_ex * ent, if (msg != NULL) { - ret = LDAP_message2entry(context, db, msg, &orig); + ret = LDAP_message2entry(context, db, msg, 0, &orig); if (ret) goto out; @@ -933,7 +933,7 @@ LDAP_principal2message(krb5_context context, HDB * db, */ static krb5_error_code LDAP_message2entry(krb5_context context, HDB * db, LDAPMessage * msg, - hdb_entry_ex * ent) + int flags, hdb_entry_ex * ent) { char *unparsed_name = NULL, *dn = NULL, *ntPasswordIN = NULL; char *samba_acct_flags = NULL; @@ -1115,31 +1115,32 @@ LDAP_message2entry(krb5_context context, HDB * db, LDAPMessage * msg, ent->entry.created_by.principal = NULL; - ret = LDAP_get_string_value(db, msg, "creatorsName", &dn); - if (ret == 0) { - if (LDAP_dn2principal(context, db, dn, &ent->entry.created_by.principal) - != 0) { - ent->entry.created_by.principal = NULL; + if (flags & HDB_F_ADMIN_DATA) { + ret = LDAP_get_string_value(db, msg, "creatorsName", &dn); + if (ret == 0) { + LDAP_dn2principal(context, db, dn, &ent->entry.created_by.principal); + free(dn); } - free(dn); - } - ent->entry.modified_by = (Event *) malloc(sizeof(Event)); - if (ent->entry.modified_by == NULL) { - ret = ENOMEM; - krb5_set_error_message(context, ret, "malloc: out of memory"); - goto out; - } - ret = LDAP_get_generalized_time_value(db, msg, "modifyTimestamp", - &ent->entry.modified_by->time); - if (ret == 0) { - ret = LDAP_get_string_value(db, msg, "modifiersName", &dn); - if (LDAP_dn2principal(context, db, dn, &ent->entry.modified_by->principal)) - ent->entry.modified_by->principal = NULL; - free(dn); - } else { - free(ent->entry.modified_by); - ent->entry.modified_by = NULL; + ent->entry.modified_by = calloc(1, sizeof(*ent->entry.modified_by)); + if (ent->entry.modified_by == NULL) { + ret = ENOMEM; + krb5_set_error_message(context, ret, "malloc: out of memory"); + goto out; + } + + ret = LDAP_get_generalized_time_value(db, msg, "modifyTimestamp", + &ent->entry.modified_by->time); + if (ret == 0) { + ret = LDAP_get_string_value(db, msg, "modifiersName", &dn); + if (ret == 0) { + LDAP_dn2principal(context, db, dn, &ent->entry.modified_by->principal); + free(dn); + } else { + free(ent->entry.modified_by); + ent->entry.modified_by = NULL; + } + } } ent->entry.valid_start = malloc(sizeof(*ent->entry.valid_start)); @@ -1411,7 +1412,7 @@ LDAP_seq(krb5_context context, HDB * db, unsigned flags, hdb_entry_ex * entry) break; case LDAP_RES_SEARCH_ENTRY: /* We have an entry. Parse it. */ - ret = LDAP_message2entry(context, db, e, entry); + ret = LDAP_message2entry(context, db, e, flags, entry); ldap_msgfree(e); break; case LDAP_RES_SEARCH_RESULT: @@ -1582,7 +1583,7 @@ LDAP_fetch(krb5_context context, HDB * db, krb5_const_principal principal, goto out; } - ret = LDAP_message2entry(context, db, e, entry); + ret = LDAP_message2entry(context, db, e, flags, entry); if (ret == 0) { if (db->hdb_master_key_set && (flags & HDB_F_DECRYPT)) { ret = hdb_unseal_keys(context, db, &entry->entry); diff --git a/lib/hdb/hdb.h b/lib/hdb/hdb.h index 8eba864fd..bf4ffc31c 100644 --- a/lib/hdb/hdb.h +++ b/lib/hdb/hdb.h @@ -53,6 +53,7 @@ enum hdb_lockop{ HDB_RLOCK, HDB_WLOCK }; #define HDB_F_GET_KRBTGT 16 /* fetch krbtgt */ #define HDB_F_GET_ANY 28 /* fetch any of client,server,krbtgt */ #define HDB_F_CANON 32 /* want canonicalition */ +#define HDB_F_ADMIN_DATA 64 /* want data that kdc don't use */ /* hdb_capability_flags */ #define HDB_CAP_F_HANDLE_ENTERPRISE_PRINCIPAL 1 diff --git a/lib/kadm5/chpass_s.c b/lib/kadm5/chpass_s.c index bb8c54eaf..0131bba0c 100644 --- a/lib/kadm5/chpass_s.c +++ b/lib/kadm5/chpass_s.c @@ -54,7 +54,7 @@ change(void *server_handle, return ret; ret = context->db->hdb_fetch(context->context, context->db, princ, - HDB_F_DECRYPT|HDB_F_GET_ANY, &ent); + HDB_F_DECRYPT|HDB_F_GET_ANY|HDB_F_ADMIN_DATA, &ent); if(ret) goto out; @@ -167,7 +167,7 @@ kadm5_s_chpass_principal_with_key(void *server_handle, if(ret) return ret; ret = context->db->hdb_fetch(context->context, context->db, princ, - HDB_F_GET_ANY, &ent); + HDB_F_GET_ANY|HDB_F_ADMIN_DATA, &ent); if(ret == HDB_ERR_NOENTRY) goto out; ret = _kadm5_set_keys2(context, &ent.entry, n_key_data, key_data); diff --git a/lib/kadm5/delete_s.c b/lib/kadm5/delete_s.c index 754580697..704cfaf82 100644 --- a/lib/kadm5/delete_s.c +++ b/lib/kadm5/delete_s.c @@ -49,7 +49,7 @@ kadm5_s_delete_principal(void *server_handle, krb5_principal princ) return ret; } ret = context->db->hdb_fetch(context->context, context->db, princ, - HDB_F_DECRYPT|HDB_F_GET_ANY, &ent); + HDB_F_DECRYPT|HDB_F_GET_ANY|HDB_F_ADMIN_DATA, &ent); if(ret == HDB_ERR_NOENTRY) goto out; if(ent.entry.flags.immutable) { diff --git a/lib/kadm5/get_princs_s.c b/lib/kadm5/get_princs_s.c index b59df07d3..55c8f2e98 100644 --- a/lib/kadm5/get_princs_s.c +++ b/lib/kadm5/get_princs_s.c @@ -99,7 +99,7 @@ kadm5_s_get_principals(void *server_handle, } d.princs = NULL; d.count = 0; - ret = hdb_foreach(context->context, context->db, 0, foreach, &d); + ret = hdb_foreach(context->context, context->db, HDB_F_ADMIN_DATA, foreach, &d); context->db->hdb_close(context->context, context->db); if(ret == 0) ret = add_princ(&d, NULL); diff --git a/lib/kadm5/get_s.c b/lib/kadm5/get_s.c index 531f6f475..3a25bea13 100644 --- a/lib/kadm5/get_s.c +++ b/lib/kadm5/get_s.c @@ -79,7 +79,7 @@ kadm5_s_get_principal(void *server_handle, if(ret) return ret; ret = context->db->hdb_fetch(context->context, context->db, princ, - HDB_F_DECRYPT|HDB_F_GET_ANY, &ent); + HDB_F_DECRYPT|HDB_F_GET_ANY|HDB_F_ADMIN_DATA, &ent); context->db->hdb_close(context->context, context->db); if(ret) return _kadm5_error_code(ret); diff --git a/lib/kadm5/ipropd_master.c b/lib/kadm5/ipropd_master.c index 925b43d43..b2f677993 100644 --- a/lib/kadm5/ipropd_master.c +++ b/lib/kadm5/ipropd_master.c @@ -361,7 +361,7 @@ send_complete (krb5_context context, slave *s, return ret; } - ret = hdb_foreach (context, db, 0, prop_one, s); + ret = hdb_foreach (context, db, HDB_F_ADMIN_DATA, prop_one, s); if (ret) { krb5_warn (context, ret, "hdb_foreach"); slave_dead(context, s); diff --git a/lib/kadm5/log.c b/lib/kadm5/log.c index 7694c7158..51d091280 100644 --- a/lib/kadm5/log.c +++ b/lib/kadm5/log.c @@ -575,7 +575,7 @@ kadm5_log_replay_modify (kadm5_server_context *context, memset(&ent, 0, sizeof(ent)); ret = context->db->hdb_fetch(context->context, context->db, log_ent.entry.principal, - HDB_F_DECRYPT|HDB_F_GET_ANY, &ent); + HDB_F_DECRYPT|HDB_F_GET_ANY|HDB_F_ADMIN_DATA, &ent); if (ret) goto out; if (mask & KADM5_PRINC_EXPIRE_TIME) { diff --git a/lib/kadm5/modify_s.c b/lib/kadm5/modify_s.c index ea0ec5dd7..bf16982c9 100644 --- a/lib/kadm5/modify_s.c +++ b/lib/kadm5/modify_s.c @@ -54,7 +54,7 @@ modify_principal(void *server_handle, if(ret) return ret; ret = context->db->hdb_fetch(context->context, context->db, - princ->principal, HDB_F_GET_ANY, &ent); + princ->principal, HDB_F_GET_ANY|HDB_F_ADMIN_DATA, &ent); if(ret) goto out; ret = _kadm5_setup_entry(context, &ent, mask, princ, mask, NULL, 0); diff --git a/lib/kadm5/randkey_s.c b/lib/kadm5/randkey_s.c index 519135ab2..6ac540021 100644 --- a/lib/kadm5/randkey_s.c +++ b/lib/kadm5/randkey_s.c @@ -55,7 +55,7 @@ kadm5_s_randkey_principal(void *server_handle, if(ret) return ret; ret = context->db->hdb_fetch(context->context, context->db, princ, - HDB_F_GET_ANY, &ent); + HDB_F_GET_ANY|HDB_F_ADMIN_DATA, &ent); if(ret) goto out; diff --git a/lib/kadm5/rename_s.c b/lib/kadm5/rename_s.c index e6e2aac27..ea2929425 100644 --- a/lib/kadm5/rename_s.c +++ b/lib/kadm5/rename_s.c @@ -52,7 +52,7 @@ kadm5_s_rename_principal(void *server_handle, if(ret) return ret; ret = context->db->hdb_fetch(context->context, context->db, - source, HDB_F_GET_ANY, &ent); + source, HDB_F_GET_ANY|HDB_F_ADMIN_DATA, &ent); if(ret){ context->db->hdb_close(context->context, context->db); goto out;