Augmented "wbinfo -m" to list additional information about the type, direction, and...
authorSteven Danneman <steven.danneman@isilon.com>
Tue, 25 Mar 2008 23:58:40 +0000 (16:58 -0700)
committerGerald W. Carter <jerry@samba.org>
Mon, 31 Mar 2008 18:40:58 +0000 (13:40 -0500)
* 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

source/nsswitch/wbinfo.c
source/winbindd/winbindd_misc.c

index 82d1061f6edb2e231a3f16565406194ca830bf77..63748de016e92418ab1318cae47bc084621df289 100644 (file)
@@ -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);
index c22da3e8ef5780b1a0593dd84cb06b7db385b626..93986d174e54b8e2682ea04dcc143ac35bd04ba1 100644 (file)
@@ -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,