From 2b70174e1bcef3b34acb406c9f8d79b0ec0cacfa Mon Sep 17 00:00:00 2001 From: Steven Danneman Date: Tue, 25 Mar 2008 16:58:40 -0700 Subject: Augmented "wbinfo -m" to list additional information about the type, direction, and transitivty of trusts. * added several helper functions to convert the trust_flags field in the winbindd_tdc_domain to more useful administrator ideas of trust type, trust direction, and trust transitivity. * converted winbindd_list_trusted_domains() to enumerate the trusted domain cache, instead of the domain list, and return additional trust information to the calling process * modified wbinfo to pretty print this additional trust information when a new --verbose switch is given with -m. Thus "wbinfo -m" and "wbinfo -all-domains" output as before, but "wbinfo --verbose -m" prints extra trust info. * updated some comments and fixed typos (This used to be commit e7827bb6afa264c12ecdc0858f49707ca3d6104f) --- source3/nsswitch/wbinfo.c | 93 ++++++++++++++++++++++++++++------ source3/winbindd/winbindd_misc.c | 104 ++++++++++++++++++++++++++++++++++----- 2 files changed, 169 insertions(+), 28 deletions(-) (limited to 'source3') diff --git a/source3/nsswitch/wbinfo.c b/source3/nsswitch/wbinfo.c index 82d1061f6e..63748de016 100644 --- a/source3/nsswitch/wbinfo.c +++ b/source3/nsswitch/wbinfo.c @@ -83,7 +83,7 @@ static const char *get_winbind_domain(void) if (!WBC_ERROR_IS_OK(wbc_status)) { d_fprintf(stderr, "could not obtain winbind domain name!\n"); - /* HACK: (this module should not call lp_ funtions) */ + /* HACK: (this module should not call lp_ functions) */ return lp_workgroup(); } @@ -345,13 +345,15 @@ static bool wbinfo_wins_byip(char *ip) return true; } -/* List trusted domains */ +/* List all/trusted domains */ -static bool wbinfo_list_domains(bool list_all_domains) +static bool wbinfo_list_domains(bool list_all_domains, bool verbose) { struct winbindd_request request; struct winbindd_response response; + bool print_all = !list_all_domains && verbose; + ZERO_STRUCT(request); ZERO_STRUCT(response); @@ -368,21 +370,72 @@ static bool wbinfo_list_domains(bool list_all_domains) if (response.extra_data.data) { const char *extra_data = (char *)response.extra_data.data; char *name; - char *p; + char *beg, *end; TALLOC_CTX *frame = talloc_stackframe(); + if (print_all) { + d_printf("%-34s%-12s%-12s%-10s%-10s\n", + "Domain Name", " Trust Type", "Transitive", + "Incoming", "Outgoing"); + } + while(next_token_talloc(frame,&extra_data,&name,"\n")) { - p = strchr(name, '\\'); - if (p == 0) { - d_fprintf(stderr, "Got invalid response: %s\n", - extra_data); - TALLOC_FREE(frame); - SAFE_FREE(response.extra_data.data); - return false; + /* Print Domain Name */ + if ((beg = strchr(name, '\\')) == NULL) + goto error; + *beg = 0; + beg++; + if ((end = strchr(beg, '\\')) == NULL) + goto error; + *end = 0; + if(*beg == 0) + d_printf("%-34s", name); + else + d_printf("%-34s", beg); + + if (!print_all) { + d_printf("\n"); + continue; } - *p = 0; - d_printf("%s\n", name); + + /* Skip SID */ + beg = ++end; + if ((end = strchr(beg, '\\')) == NULL) + goto error; + + /* Print Trust Type */ + beg = ++end; + if ((end = strchr(beg, '\\')) == NULL) + goto error; + *end = 0; + d_printf(" %-12s", beg); + + /* Print Transitive */ + beg = ++end; + if ((end = strchr(beg, '\\')) == NULL) + goto error; + *end = 0; + d_printf("%-12s", beg); + + /* Print Incoming */ + beg = ++end; + if ((end = strchr(beg, '\\')) == NULL) + goto error; + *end = 0; + d_printf("%-10s", beg); + + /* Print Outgoing */ + beg = ++end; + d_printf("%-10s\n", beg); } + goto out; + +error: + d_fprintf(stderr, "Got invalid response: %s\n", extra_data); + TALLOC_FREE(frame); + SAFE_FREE(response.extra_data.data); + return false; +out: TALLOC_FREE(frame); SAFE_FREE(response.extra_data.data); } @@ -1278,6 +1331,7 @@ enum { OPT_LIST_OWN_DOMAIN, OPT_UID_INFO, OPT_GROUP_INFO, + OPT_VERBOSE }; int main(int argc, char **argv, char **envp) @@ -1289,6 +1343,7 @@ int main(int argc, char **argv, char **envp) static char *opt_domain_name; static int int_arg; int result = 1; + bool verbose = false; struct poptOption long_options[] = { POPT_AUTOHELP @@ -1341,6 +1396,7 @@ int main(int argc, char **argv, char **envp) /* "user%password,DOM\\user%password,user@EXAMPLE.COM,EXAMPLE.COM\\user%password" }, */ #endif { "separator", 0, POPT_ARG_NONE, 0, OPT_SEPARATOR, "Get the active winbind separator", NULL }, + { "verbose", 0, POPT_ARG_NONE, 0, OPT_VERBOSE, "Print additional information per command", NULL }, POPT_COMMON_CONFIGFILE POPT_COMMON_VERSION POPT_TABLEEND @@ -1363,6 +1419,11 @@ int main(int argc, char **argv, char **envp) while((opt = poptGetNextOpt(pc)) != -1) { /* get the generic configuration parameters like --domain */ + switch (opt) { + case OPT_VERBOSE: + verbose = True; + break; + } } poptFreeContext(pc); @@ -1471,7 +1532,7 @@ int main(int argc, char **argv, char **envp) } break; case 'm': - if (!wbinfo_list_domains(false)) { + if (!wbinfo_list_domains(false, verbose)) { d_fprintf(stderr, "Could not list trusted domains\n"); goto done; } @@ -1601,7 +1662,7 @@ int main(int argc, char **argv, char **envp) break; } case OPT_LIST_ALL_DOMAINS: - if (!wbinfo_list_domains(true)) { + if (!wbinfo_list_domains(true, verbose)) { goto done; } break; @@ -1613,6 +1674,8 @@ int main(int argc, char **argv, char **envp) /* generic configuration options */ case OPT_DOMAIN_NAME: break; + case OPT_VERBOSE: + break; default: d_fprintf(stderr, "Invalid option\n"); poptPrintHelp(pc, stderr, 0); diff --git a/source3/winbindd/winbindd_misc.c b/source3/winbindd/winbindd_misc.c index c22da3e8ef..93986d174e 100644 --- a/source3/winbindd/winbindd_misc.c +++ b/source3/winbindd/winbindd_misc.c @@ -97,27 +97,104 @@ enum winbindd_result winbindd_dual_check_machine_acct(struct winbindd_domain *do return NT_STATUS_IS_OK(result) ? WINBINDD_OK : WINBINDD_ERROR; } +/* Constants and helper functions for determining domain trust types */ + +enum trust_type { + EXTERNAL = 0, + FOREST, + IN_FOREST, + NONE, +}; + +const char *trust_type_strings[] = {"External", + "Forest", + "In Forest", + "None"}; + +static enum trust_type get_trust_type(struct winbindd_tdc_domain *domain) +{ + if (domain->trust_attribs == NETR_TRUST_ATTRIBUTE_QUARANTINED_DOMAIN) + return EXTERNAL; + else if (domain->trust_attribs == NETR_TRUST_ATTRIBUTE_FOREST_TRANSITIVE) + return FOREST; + else if (((domain->trust_flags & NETR_TRUST_FLAG_IN_FOREST) == NETR_TRUST_FLAG_IN_FOREST) && + ((domain->trust_flags & NETR_TRUST_FLAG_PRIMARY) == 0x0)) + return IN_FOREST; + return NONE; +} + +static const char *get_trust_type_string(struct winbindd_tdc_domain *domain) +{ + return trust_type_strings[get_trust_type(domain)]; +} + +static bool trust_is_inbound(struct winbindd_tdc_domain *domain) +{ + return (domain->trust_flags == 0x0) || + ((domain->trust_flags & NETR_TRUST_FLAG_IN_FOREST) == + NETR_TRUST_FLAG_IN_FOREST) || + ((domain->trust_flags & NETR_TRUST_FLAG_INBOUND) == + NETR_TRUST_FLAG_INBOUND); +} + +static bool trust_is_outbound(struct winbindd_tdc_domain *domain) +{ + return (domain->trust_flags == 0x0) || + ((domain->trust_flags & NETR_TRUST_FLAG_IN_FOREST) == + NETR_TRUST_FLAG_IN_FOREST) || + ((domain->trust_flags & NETR_TRUST_FLAG_OUTBOUND) == + NETR_TRUST_FLAG_OUTBOUND); +} + +static bool trust_is_transitive(struct winbindd_tdc_domain *domain) +{ + if ((domain->trust_attribs == NETR_TRUST_ATTRIBUTE_NON_TRANSITIVE) || + (domain->trust_attribs == NETR_TRUST_ATTRIBUTE_QUARANTINED_DOMAIN) || + (domain->trust_attribs == NETR_TRUST_ATTRIBUTE_TREAT_AS_EXTERNAL)) + return False; + return True; +} + void winbindd_list_trusted_domains(struct winbindd_cli_state *state) { - struct winbindd_domain *d = NULL; + struct winbindd_tdc_domain *dom_list = NULL; + struct winbindd_tdc_domain *d = NULL; + size_t num_domains = 0; int extra_data_len = 0; char *extra_data = NULL; + int i = 0; DEBUG(3, ("[%5lu]: list trusted domains\n", (unsigned long)state->pid)); - for ( d=domain_list(); d; d=d->next ) { + if( !wcache_tdc_fetch_list( &dom_list, &num_domains )) { + request_error(state); + goto done; + } + + for ( i = 0; i < num_domains; i++ ) { + d = &dom_list[i]; if ( !extra_data ) { - extra_data = talloc_asprintf( - state->mem_ctx, "%s\\%s\\%s", - d->name, d->alt_name ? d->alt_name : d->name, - sid_string_talloc(state->mem_ctx, &d->sid)); + extra_data = talloc_asprintf(state->mem_ctx, + "%s\\%s\\%s\\%s\\%s\\%s\\%s", + d->domain_name, + d->dns_name ? d->dns_name : d->domain_name, + sid_string_talloc(state->mem_ctx, &d->sid), + get_trust_type_string(d), + trust_is_transitive(d) ? "Yes" : "No", + trust_is_inbound(d) ? "Yes" : "No", + trust_is_outbound(d) ? "Yes" : "No"); } else { - extra_data = talloc_asprintf( - state->mem_ctx, "%s\n%s\\%s\\%s", - extra_data, d->name, - d->alt_name ? d->alt_name : d->name, - sid_string_talloc(state->mem_ctx, &d->sid)); + extra_data = talloc_asprintf(state->mem_ctx, + "%s\n%s\\%s\\%s\\%s\\%s\\%s\\%s", + extra_data, + d->domain_name, + d->dns_name ? d->dns_name : d->domain_name, + sid_string_talloc(state->mem_ctx, &d->sid), + get_trust_type_string(d), + trust_is_transitive(d) ? "Yes" : "No", + trust_is_inbound(d) ? "Yes" : "No", + trust_is_outbound(d) ? "Yes" : "No"); } } @@ -131,9 +208,10 @@ void winbindd_list_trusted_domains(struct winbindd_cli_state *state) state->response.length += extra_data_len+1; } - TALLOC_FREE( extra_data ); - request_ok(state); +done: + TALLOC_FREE( dom_list ); + TALLOC_FREE( extra_data ); } enum winbindd_result winbindd_dual_list_trusted_domains(struct winbindd_domain *domain, -- cgit