diff options
author | Volker Lendecke <vl@samba.org> | 2009-02-19 20:03:06 +0100 |
---|---|---|
committer | Volker Lendecke <vl@samba.org> | 2009-02-19 20:06:29 +0100 |
commit | a13f065bad0f4d21a67e68b743f17f45bf0a4691 (patch) | |
tree | 7eb924bc6c423482cb08428fda3226710d7c55d4 /source3 | |
parent | 669617036eecbbe2fb9b53c15faa76be147d916a (diff) | |
download | samba-a13f065bad0f4d21a67e68b743f17f45bf0a4691.tar.gz samba-a13f065bad0f4d21a67e68b743f17f45bf0a4691.tar.bz2 samba-a13f065bad0f4d21a67e68b743f17f45bf0a4691.zip |
Fix a O(n^2) algorithm in regdb_fetch_keys()
Diffstat (limited to 'source3')
-rw-r--r-- | source3/registry/reg_backend_db.c | 32 |
1 files changed, 27 insertions, 5 deletions
diff --git a/source3/registry/reg_backend_db.c b/source3/registry/reg_backend_db.c index 612b448cac..fe5f192713 100644 --- a/source3/registry/reg_backend_db.c +++ b/source3/registry/reg_backend_db.c @@ -942,7 +942,6 @@ done: int regdb_fetch_keys(const char *key, REGSUBKEY_CTR *ctr) { - WERROR werr; uint32 num_items; uint8 *buf; uint32 buflen, len; @@ -973,12 +972,35 @@ int regdb_fetch_keys(const char *key, REGSUBKEY_CTR *ctr) buflen = value.dsize; len = tdb_unpack( buf, buflen, "d", &num_items); + /* + * The following code breaks the abstraction that reg_objects.c sets + * up with regsubkey_ctr_addkey(). But if we use that with the current + * data structure of ctr->subkeys being an unsorted array, we end up + * with an O(n^2) algorithm for retrieving keys from the tdb + * file. This is pretty pointless, as we have to trust the data + * structure on disk not to have duplicates anyway. The alternative to + * breaking this abstraction would be to set up a more sophisticated + * data structure in REGSUBKEY_CTR. + * + * This makes "net conf list" for a registry with >1000 shares + * actually usable :-) + */ + + ctr->subkeys = talloc_array(ctr, char *, num_items); + if (ctr->subkeys == NULL) { + DEBUG(5, ("regdb_fetch_keys: could not allocate subkeys\n")); + goto done; + } + ctr->num_subkeys = num_items; + for (i=0; i<num_items; i++) { len += tdb_unpack(buf+len, buflen-len, "f", subkeyname); - werr = regsubkey_ctr_addkey(ctr, subkeyname); - if (!W_ERROR_IS_OK(werr)) { - DEBUG(5, ("regdb_fetch_keys: regsubkey_ctr_addkey " - "failed: %s\n", win_errstr(werr))); + ctr->subkeys[i] = talloc_strdup(ctr->subkeys, subkeyname); + if (ctr->subkeys[i] == NULL) { + DEBUG(5, ("regdb_fetch_keys: could not allocate " + "subkeyname\n")); + TALLOC_FREE(ctr->subkeys); + ctr->num_subkeys = 0; goto done; } } |