This is proposed fix to have completed trusted domains enumeration in winbind. This implementation checks returned code and depending on it does another call (STATUS_MORE_ENTRIES) or exits. As stored domain names and sids needs potential reallocation, I expect comments on this matter.
of course, comments/feedbacks are welcome -- cheers, +------------------------------------------------------------+ |Rafal 'Mimir' Szczesniak <[EMAIL PROTECTED]> | |*BSD, GNU/Linux and Samba / |__________________________________________________________/
Index: winbindd.c =================================================================== RCS file: /cvsroot/samba/source/nsswitch/winbindd.c,v retrieving revision 1.65 diff -u -r1.65 winbindd.c --- winbindd.c 27 Aug 2002 19:43:19 -0000 1.65 +++ winbindd.c 1 Sep 2002 09:16:32 -0000 @@ -750,7 +750,7 @@ printf("\t-h show this help message\n"); } - int main(int argc, char **argv) +int main(int argc, char **argv) { extern BOOL AllowDebugChange; extern pstring global_myname; Index: winbindd_cm.c =================================================================== RCS file: /cvsroot/samba/source/nsswitch/winbindd_cm.c,v retrieving revision 1.44 diff -u -r1.44 winbindd_cm.c --- winbindd_cm.c 30 Aug 2002 10:46:59 -0000 1.44 +++ winbindd_cm.c 1 Sep 2002 09:16:34 -0000 @@ -433,7 +433,7 @@ result = cli_full_connection(&(new_conn->cli), global_myname, new_conn->controller, &dc_ip, 0, "IPC$", "IPC", ipc_username, ipc_domain, - ipc_password, 0); + ipc_password, lp_use_spnego() ? 0 : +CLI_FULL_CONNECTION_DONT_SPNEGO); SAFE_FREE(ipc_username); SAFE_FREE(ipc_domain); Index: winbindd_rpc.c =================================================================== RCS file: /cvsroot/samba/source/nsswitch/winbindd_rpc.c,v retrieving revision 1.31 diff -u -r1.31 winbindd_rpc.c --- winbindd_rpc.c 5 Aug 2002 02:47:16 -0000 1.31 +++ winbindd_rpc.c 1 Sep 2002 09:16:35 -0000 @@ -3,8 +3,9 @@ Winbind rpc backend functions - Copyright (C) Tim Potter 2000-2001 - Copyright (C) Andrew Tridgell 2001 + Copyright (C) Tim Potter 2000-2001 + Copyright (C) Andrew Tridgell 2001 + Copyright (C) Rafal Szczesniak 2002 This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by @@ -581,19 +582,83 @@ CLI_POLICY_HND *hnd; NTSTATUS result = NT_STATUS_UNSUCCESSFUL; uint32 enum_ctx = 0; + + /* this gives us 'quantized' allocation of names/sids arrays */ + const int chunk_size = 4; + int chunk_num = 1; DEBUG(3,("rpc: trusted_domains\n")); *num_domains = 0; *alt_names = NULL; - + + *names = talloc(mem_ctx, sizeof(char*) * chunk_size); + if (!*names) { + DEBUG(0, ("Trusted domain names array couldn't be allocated: out of +memory\n")); + return NT_STATUS_NO_MEMORY; + }; + + *dom_sids = talloc(mem_ctx, sizeof(DOM_SID) * chunk_size); + if (!*dom_sids) { + DEBUG(0, ("Trusted domain sids array couldn't be allocated: out of +memory\n")); + return NT_STATUS_NO_MEMORY; + }; + if (!(hnd = cm_get_lsa_handle(lp_workgroup()))) - goto done; + return result; + + DEBUG(5, ("Starting trusted domains enumeration.\n")); - result = cli_lsa_enum_trust_dom(hnd->cli, mem_ctx, - &hnd->pol, &enum_ctx, - num_domains, names, dom_sids); -done: + do { + /* data returned in a single cli_lsa_enum_trust_dom call */ + uint32 num_dom = 0; + char** domain_names; + DOM_SID* domain_sids; + + result = cli_lsa_enum_trust_dom(hnd->cli, mem_ctx, + &hnd->pol, &enum_ctx, + &num_dom, &domain_names, &domain_sids); + + DEBUG(10, ("Returned %d trusted domain entries. Current enum_ctx = %d, +nt_status = %s\n", + num_dom, enum_ctx, nt_errstr(result))); + + /* collect returned entries */ + while ((enum_ctx - *num_domains <= num_dom) && (enum_ctx - +*num_domains > 0)) { + if (!domain_names[enum_ctx - *num_domains - 1]) continue; + + (*names)[*num_domains] = domain_names[enum_ctx - *num_domains +- 1]; + sid_copy(&(*dom_sids)[*num_domains], &(domain_sids[enum_ctx - +*num_domains - 1])); + + DEBUGADD(100, ("Collecting trusted domain (%d): %s %s\n", +*num_domains, + (*names)[*num_domains], +sid_string_static(&(*dom_sids)[*num_domains]))); + (*num_domains)++; + + /* check if arrays grows beyond their current size */ + if (!(*num_domains < chunk_size * chunk_num)) { + chunk_num++; + + *names = talloc_realloc(mem_ctx, *names, sizeof(char*) +* chunk_size * chunk_num); + if (!(*names) && sizeof (*names) != sizeof(char*) * +chunk_size * chunk_num) { + DEBUG(0, ("Realloc of trusted domain names +array failed (chunk_size = %d, chunk_num = %d)\n", + chunk_size, chunk_num)); + return NT_STATUS_NO_MEMORY; + } + + *dom_sids = talloc_realloc(mem_ctx, *dom_sids, +sizeof(DOM_SID) * chunk_size * chunk_num); + if (!(*dom_sids) && sizeof(*dom_sids) * chunk_size * +chunk_num) { + DEBUG(0, ("Realloc of trusted domain sids +array failed (chunk_size = %d, chunk_num = %d)\n", + chunk_size, chunk_num)); + return NT_STATUS_NO_MEMORY; + } + + DEBUG(10, ("Realloc of trusted domain arrays +succeeded. Current chunk size = %d, chunk_num = %d\n", + chunk_size, chunk_num)); + }; + + }; + + } while NT_STATUS_EQUAL(result, STATUS_MORE_ENTRIES); + return result; } Index: winbindd_util.c =================================================================== RCS file: /cvsroot/samba/source/nsswitch/winbindd_util.c,v retrieving revision 1.79 diff -u -r1.79 winbindd_util.c --- winbindd_util.c 18 Aug 2002 15:46:03 -0000 1.79 +++ winbindd_util.c 1 Sep 2002 09:16:36 -0000 @@ -164,7 +164,7 @@ int i; result = domain->methods->trusted_domains(domain, mem_ctx, &num_domains, - &names, &alt_names, &dom_sids); + &names, &alt_names, +&dom_sids); if (!NT_STATUS_IS_OK(result)) { continue; } @@ -173,9 +173,8 @@ the access methods of its parent */ for(i = 0; i < num_domains; i++) { DEBUG(10,("Found domain %s\n", names[i])); - add_trusted_domain(names[i], - alt_names?alt_names[i]:NULL, - domain->methods, &dom_sids[i]); + add_trusted_domain(names[i], alt_names?alt_names[i]:NULL, + domain->methods, &dom_sids[i]); } } @@ -195,8 +194,10 @@ /* Add ourselves as the first entry */ domain = add_trusted_domain(lp_workgroup(), NULL, &cache_methods, NULL); - /* Now we *must* get the domain sid for our primary domain. Go into - a holding pattern until that is available */ + /* + * Now we *must* get the domain sid for our primary domain. Go into + * a holding pattern until that is available + */ result = cache_methods.domain_sid(domain, &domain->sid); while (!NT_STATUS_IS_OK(result)) {