Merge commit 'samba/v3-2-test' into wbc-test
authorGerald W. Carter <jerry@samba.org>
Thu, 17 Apr 2008 16:11:22 +0000 (18:11 +0200)
committerGerald W. Carter <jerry@samba.org>
Thu, 17 Apr 2008 16:11:22 +0000 (18:11 +0200)
(This used to be commit 7c2e735df3d8a4105a4944411d111fc66c13b01f)

source3/nsswitch/libwbclient/wbc_pam.c
source3/nsswitch/libwbclient/wbc_sid.c
source3/nsswitch/libwbclient/wbc_util.c
source3/nsswitch/libwbclient/wbclient.c
source3/nsswitch/libwbclient/wbclient.h
source3/nsswitch/wbinfo.c

index f207f3ca0a7ddcf7db2654a05d0872bb26f276e5..a0e91faaf36eca2b01a6136d57b687ca7d944f48 100644 (file)
@@ -138,7 +138,7 @@ static wbcErr wbc_create_auth_info(TALLOC_CTX *mem_ctx,
 
        p = (char *)resp->extra_data.data;
        if (!p) {
-               wbc_status = WBC_INVALID_RESPONSE;
+               wbc_status = WBC_ERR_INVALID_RESPONSE;
                BAIL_ON_WBC_ERROR(wbc_status);
        }
 
@@ -149,7 +149,7 @@ static wbcErr wbc_create_auth_info(TALLOC_CTX *mem_ctx,
                char *s = p;
                char *e = strchr(p, '\n');
                if (!e) {
-                       wbc_status = WBC_INVALID_RESPONSE;
+                       wbc_status = WBC_ERR_INVALID_RESPONSE;
                        BAIL_ON_WBC_ERROR(wbc_status);
                }
                e[0] = '\0';
@@ -157,7 +157,7 @@ static wbcErr wbc_create_auth_info(TALLOC_CTX *mem_ctx,
 
                ret = sscanf(s, "0x%08X:0x%08X", &rid, &attrs);
                if (ret != 2) {
-                       wbc_status = WBC_INVALID_RESPONSE;
+                       wbc_status = WBC_ERR_INVALID_RESPONSE;
                        BAIL_ON_WBC_ERROR(wbc_status);
                }
 
@@ -173,7 +173,7 @@ static wbcErr wbc_create_auth_info(TALLOC_CTX *mem_ctx,
                char *a;
                char *e = strchr(p, '\n');
                if (!e) {
-                       wbc_status = WBC_INVALID_RESPONSE;
+                       wbc_status = WBC_ERR_INVALID_RESPONSE;
                        BAIL_ON_WBC_ERROR(wbc_status);
                }
                e[0] = '\0';
@@ -181,7 +181,7 @@ static wbcErr wbc_create_auth_info(TALLOC_CTX *mem_ctx,
 
                e = strchr(s, ':');
                if (!e) {
-                       wbc_status = WBC_INVALID_RESPONSE;
+                       wbc_status = WBC_ERR_INVALID_RESPONSE;
                        BAIL_ON_WBC_ERROR(wbc_status);
                }
                e[0] = '\0';
@@ -190,7 +190,7 @@ static wbcErr wbc_create_auth_info(TALLOC_CTX *mem_ctx,
                ret = sscanf(a, "0x%08X",
                             &attrs);
                if (ret != 1) {
-                       wbc_status = WBC_INVALID_RESPONSE;
+                       wbc_status = WBC_ERR_INVALID_RESPONSE;
                        BAIL_ON_WBC_ERROR(wbc_status);
                }
 
index 6ef9f44c3bee4b88ff5b3047d2ce55c96a8887e4..de9b02822f508b8d4c6655f8235b5f9dcc4c0301 100644 (file)
@@ -372,21 +372,21 @@ wbcErr wbcLookupRids(struct wbcDomainSid *dom_sid,
                char *q;
 
                if (*p == '\0') {
-                       wbc_status = WBC_INVALID_RESPONSE;
+                       wbc_status = WBC_ERR_INVALID_RESPONSE;
                        BAIL_ON_WBC_ERROR(wbc_status);
                }
 
                (*types)[i] = (enum wbcSidType)strtoul(p, &q, 10);
 
                if (*q != ' ') {
-                       wbc_status = WBC_INVALID_RESPONSE;
+                       wbc_status = WBC_ERR_INVALID_RESPONSE;
                        BAIL_ON_WBC_ERROR(wbc_status);
                }
 
                p = q+1;
 
                if ((q = strchr(p, '\n')) == NULL) {
-                       wbc_status = WBC_INVALID_RESPONSE;
+                       wbc_status = WBC_ERR_INVALID_RESPONSE;
                        BAIL_ON_WBC_ERROR(wbc_status);
                }
 
@@ -399,7 +399,7 @@ wbcErr wbcLookupRids(struct wbcDomainSid *dom_sid,
        }
 
        if (*p != '\0') {
-               wbc_status = WBC_INVALID_RESPONSE;
+               wbc_status = WBC_ERR_INVALID_RESPONSE;
                BAIL_ON_WBC_ERROR(wbc_status);
        }
 
@@ -471,7 +471,7 @@ wbcErr wbcLookupUserSids(const struct wbcDomainSid *user_sid,
 
        if (response.data.num_entries &&
            !response.extra_data.data) {
-               wbc_status = WBC_INVALID_RESPONSE;
+               wbc_status = WBC_ERR_INVALID_RESPONSE;
                BAIL_ON_WBC_ERROR(wbc_status);
        }
 
index edcad282216537c281629b612c0e358192ed6f77..d7af4d1bf2cebc773e00336eecca40c7eaccabe0 100644 (file)
@@ -3,7 +3,7 @@
 
    Winbind client API
 
-   Copyright (C) Gerald (Jerry) Carter 2007
+   Copyright (C) Gerald (Jerry) Carter 2007-2008
 
 
    This library is free software; you can redistribute it and/or
@@ -170,11 +170,11 @@ wbcErr wbcDomainInfo(const char *domain, struct wbcDomainInfo **dinfo)
        BAIL_ON_WBC_ERROR(wbc_status);
 
        if (response.data.domain_info.native_mode)
-               info->flags |= WBC_DOMINFO_NATIVE;
+               info->domain_flags |= WBC_DOMINFO_NATIVE;
        if (response.data.domain_info.active_directory)
-               info->flags |= WBC_DOMINFO_AD;
+               info->domain_flags |= WBC_DOMINFO_AD;
        if (response.data.domain_info.primary)
-               info->flags |= WBC_DOMINFO_PRIMARY;
+               info->domain_flags |= WBC_DOMINFO_PRIMARY;
 
        *dinfo = info;
 
@@ -268,3 +268,214 @@ wbcErr wbcResolveWinsByIP(const char *ip, const char **name)
  done:
        return wbc_status;
 }
+
+/**
+ */
+
+static wbcErr process_domain_info_string(TALLOC_CTX *ctx, 
+                                        struct wbcDomainInfo *info,
+                                        char *info_string)
+{
+       wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
+       char *r = NULL;
+       char *s = NULL;
+
+       if (!info || !info_string) {
+               wbc_status = WBC_ERR_INVALID_PARAM;
+               BAIL_ON_WBC_ERROR(wbc_status);
+       }
+
+       r = info_string;
+
+       /* Short Name */
+       if ((s = strchr(r, '\\')) == NULL) {
+               wbc_status = WBC_ERR_INVALID_RESPONSE;
+               BAIL_ON_WBC_ERROR(wbc_status);
+       }
+       *s = '\0';
+       s++;
+
+       info->short_name = talloc_strdup(ctx, r);
+       BAIL_ON_PTR_ERROR(info->short_name, wbc_status);
+
+
+       /* DNS Name */
+       r = s;
+       if ((s = strchr(r, '\\')) == NULL) {
+               wbc_status = WBC_ERR_INVALID_RESPONSE;
+               BAIL_ON_WBC_ERROR(wbc_status);
+       }
+       *s = '\0';
+       s++;
+
+       info->dns_name = talloc_strdup(ctx, r);
+       BAIL_ON_PTR_ERROR(info->dns_name, wbc_status);
+
+       /* SID */
+       r = s;
+       if ((s = strchr(r, '\\')) == NULL) {
+               wbc_status = WBC_ERR_INVALID_RESPONSE;
+               BAIL_ON_WBC_ERROR(wbc_status);
+       }
+       *s = '\0';
+       s++;
+
+       wbc_status = wbcStringToSid(r, &info->sid);
+       BAIL_ON_WBC_ERROR(wbc_status);
+       
+       /* Trust type */
+       r = s;
+       if ((s = strchr(r, '\\')) == NULL) {
+               wbc_status = WBC_ERR_INVALID_RESPONSE;
+               BAIL_ON_WBC_ERROR(wbc_status);
+       }
+       *s = '\0';
+       s++;
+
+       if (strcmp(r, "None") == 0) {
+               info->trust_type = WBC_DOMINFO_TRUSTTYPE_NONE;
+       } else if (strcmp(r, "External") == 0) {
+               info->trust_type = WBC_DOMINFO_TRUSTTYPE_EXTERNAL;
+       } else if (strcmp(r, "Forest") == 0) {
+               info->trust_type = WBC_DOMINFO_TRUSTTYPE_FOREST;
+       } else if (strcmp(r, "In Forest") == 0) {
+               info->trust_type = WBC_DOMINFO_TRUSTTYPE_IN_FOREST;
+       } else {
+               wbc_status = WBC_ERR_INVALID_RESPONSE;
+               BAIL_ON_WBC_ERROR(wbc_status);
+       }
+
+       /* Transitive */
+       r = s;
+       if ((s = strchr(r, '\\')) == NULL) {
+               wbc_status = WBC_ERR_INVALID_RESPONSE;
+               BAIL_ON_WBC_ERROR(wbc_status);
+       }
+       *s = '\0';
+       s++;
+
+       if (strcmp(r, "Yes") == 0) {
+               info->trust_flags |= WBC_DOMINFO_TRUST_TRANSITIVE;              
+       }
+       
+       /* Incoming */
+       r = s;
+       if ((s = strchr(r, '\\')) == NULL) {
+               wbc_status = WBC_ERR_INVALID_RESPONSE;
+               BAIL_ON_WBC_ERROR(wbc_status);
+       }
+       *s = '\0';
+       s++;
+
+       if (strcmp(r, "Yes") == 0) {
+               info->trust_flags |= WBC_DOMINFO_TRUST_INCOMING;                
+       }
+
+       /* Outgoing */
+       r = s;
+       if (r == NULL) {
+               wbc_status = WBC_ERR_INVALID_RESPONSE;
+               BAIL_ON_WBC_ERROR(wbc_status);
+       }
+
+       if (strcmp(r, "Yes") == 0) {
+               info->trust_flags |= WBC_DOMINFO_TRUST_OUTGOING;                
+       }
+
+       wbc_status = WBC_ERR_SUCCESS;
+
+ done:
+       return wbc_status;
+}
+
+/** @brief Enumerate the domain trusts known by Winbind
+ *
+ * @param **domains     Pointer to the allocated domain list array
+ * @param *num_domains  Pointer to number of domains returned
+ *
+ * @return #wbcErr
+ *
+ **/
+wbcErr wbcListTrusts(struct wbcDomainInfo **domains, size_t *num_domains)
+{
+       struct winbindd_response response;
+       wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
+       char *p = NULL;
+       char *q = NULL;
+       char *extra_data = NULL;        
+       int count = 0;  
+       struct wbcDomainInfo *d_list = NULL;
+       int i = 0;
+       
+       *domains = NULL;
+       *num_domains = 0;
+       
+       ZERO_STRUCT(response);
+
+       /* Send request */
+
+       wbc_status = wbcRequestResponse(WINBINDD_LIST_TRUSTDOM,
+                                       NULL,
+                                       &response);
+       BAIL_ON_WBC_ERROR(wbc_status);
+
+       /* Decode the response */
+
+       p = (char *)response.extra_data.data;
+
+       if (strlen(p) == 0) {
+               /* We should always at least get back our 
+                  own SAM domain */
+               
+               wbc_status = WBC_ERR_DOMAIN_NOT_FOUND;
+               BAIL_ON_WBC_ERROR(wbc_status);
+       }
+
+       /* Count number of domains */
+
+       count = 0;      
+       while (p) {
+               count++;
+
+               if ((q = strchr(p, '\n')) != NULL)
+                       q++;
+               p = q;          
+       }
+
+       d_list = talloc_array(NULL, struct wbcDomainInfo, count);
+       BAIL_ON_PTR_ERROR(d_list, wbc_status);
+
+       extra_data = strdup((char*)response.extra_data.data);
+       BAIL_ON_PTR_ERROR(extra_data, wbc_status);
+
+       p = extra_data; 
+
+       /* Outer loop processes the list of domain information */
+
+       for (i=0; i<count && p; i++) {
+               char *next = strchr(p, '\n');
+               
+               if (next) {
+                       *next = '\0';
+                       next++;
+               }
+
+               wbc_status = process_domain_info_string(d_list, &d_list[i], p);
+               BAIL_ON_WBC_ERROR(wbc_status);
+
+               p = next;
+       }
+
+       *domains = d_list;      
+       *num_domains = i;       
+       
+ done:
+       if (!WBC_ERROR_IS_OK(wbc_status)) {
+               if (d_list)
+                       talloc_free(d_list);
+               if (extra_data)
+                       free(extra_data);
+       }
+
+       return wbc_status;
+}
index b52c6b01e478a196b3898e2afc37e58190ca3c7f..9383fd5406d58a00f57b1325f30d5f957513a9ea 100644 (file)
@@ -106,8 +106,8 @@ const char *wbcErrorString(wbcErr error)
                return "WBC_ERR_WINBIND_NOT_AVAILABLE";
        case WBC_ERR_DOMAIN_NOT_FOUND:
                return "WBC_ERR_DOMAIN_NOT_FOUND";
-       case WBC_INVALID_RESPONSE:
-               return "WBC_INVALID_RESPONSE";
+       case WBC_ERR_INVALID_RESPONSE:
+               return "WBC_ERR_INVALID_RESPONSE";
        case WBC_ERR_NSS_ERROR:
                return "WBC_ERR_NSS_ERROR";
        case WBC_ERR_AUTH_ERROR:
index b36b5bbe889b0266a65696153b6a94929ebe6cc3..05cee9ab2b926f09bc58f133143ce732a6678191 100644 (file)
@@ -40,7 +40,7 @@ enum _wbcErrType {
        WBC_ERR_INVALID_PARAM,  /**< An Invalid parameter was supplied **/
        WBC_ERR_WINBIND_NOT_AVAILABLE,   /**< Winbind daemon is not available **/
        WBC_ERR_DOMAIN_NOT_FOUND,        /**< Domain is not trusted or cannot be found **/
-       WBC_INVALID_RESPONSE,        /**< Winbind returned an invalid response **/
+       WBC_ERR_INVALID_RESPONSE,        /**< Winbind returned an invalid response **/
        WBC_ERR_NSS_ERROR,            /**< NSS_STATUS error **/
        WBC_ERR_AUTH_ERROR        /**< Authentication failed **/
 };
@@ -128,15 +128,32 @@ struct wbcDomainInfo {
        char *short_name;
        char *dns_name;
        struct wbcDomainSid sid;
-       uint32_t flags;
+       uint32_t domain_flags;
+       uint32_t trust_flags;
+       uint32_t trust_type;
 };
 
-/* wbcDomainInfo->flags */
+/* wbcDomainInfo->domain_flags */
 
+#define WBC_DOMINFO_UNKNOWN           0x00000000
 #define WBC_DOMINFO_NATIVE            0x00000001
 #define WBC_DOMINFO_AD                0x00000002
 #define WBC_DOMINFO_PRIMARY           0x00000004
 
+/* wbcDomainInfo->trust_flags */
+
+#define WBC_DOMINFO_TRUST_TRANSITIVE  0x00000001
+#define WBC_DOMINFO_TRUST_INCOMING    0x00000002
+#define WBC_DOMINFO_TRUST_OUTGOING    0x00000004
+
+/* wbcDomainInfo->trust_type */
+
+#define WBC_DOMINFO_TRUSTTYPE_NONE       0x00000000
+#define WBC_DOMINFO_TRUSTTYPE_FOREST     0x00000001
+#define WBC_DOMINFO_TRUSTTYPE_IN_FOREST  0x00000002
+#define WBC_DOMINFO_TRUSTTYPE_EXTERNAL   0x00000003
+
+
 /**
  * @brief Auth User Parameters
  **/
@@ -390,6 +407,10 @@ wbcErr wbcGetGroups(const char *account,
 wbcErr wbcDomainInfo(const char *domain,
                     struct wbcDomainInfo **info);
 
+wbcErr wbcListTrusts(struct wbcDomainInfo **domains, 
+                    size_t *num_domains);
+
+
 /*
  * Athenticate functions
  */
index 1e943a5eee36d1019da7d609d2541bb98d4b47a3..ed49be74316501ba11902c2173100eb646e40c24 100644 (file)
@@ -341,101 +341,67 @@ static bool wbinfo_wins_byip(const char *ip)
 
 static bool wbinfo_list_domains(bool list_all_domains, bool verbose)
 {
-       struct winbindd_request request;
-       struct winbindd_response response;
-
+       struct wbcDomainInfo *domain_list = NULL;
+       size_t num_domains;
+       wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
        bool print_all = !list_all_domains && verbose;
+       int i;
 
-       ZERO_STRUCT(request);
-       ZERO_STRUCT(response);
-
-       /* Send request */
-
-       request.data.list_all_domains = list_all_domains;
-
-       if (winbindd_request_response(WINBINDD_LIST_TRUSTDOM, &request, &response) !=
-           NSS_STATUS_SUCCESS)
+       wbc_status = wbcListTrusts(&domain_list, &num_domains);
+       if (!WBC_ERROR_IS_OK(wbc_status)) {
                return false;
+       }
 
-       /* Display response */
+       if (print_all) {
+               d_printf("%-16s%-24s%-12s%-12s%-5s%-5s\n", 
+                        "Domain Name", "DNS Domain", "Trust Type", 
+                        "Transitive", "In", "Out");
+       }
 
-       if (response.extra_data.data) {
-               const char *extra_data = (char *)response.extra_data.data;
-               char *name;
-               char *beg, *end;
-               TALLOC_CTX *frame = talloc_stackframe();
+       for (i=0; i<num_domains; i++) {
+               d_printf("%-16s", domain_list[i].short_name);
 
-               if (print_all) {
-                       d_printf("%-16s%-24s%-12s%-12s%-5s%-5s\n", 
-                                "Domain Name", "DNS Domain", "Trust Type", 
-                                "Transitive", "In", "Out");
+               if (!print_all) {
+                       d_printf("\n"); 
+                       continue;
                }
 
-               while(next_token_talloc(frame,&extra_data,&name,"\n")) {
-                       /* Print Domain Name */
-                       if ((beg = strchr(name, '\\')) == NULL)
-                               goto error;
-                       *beg = 0;
-                       beg++;
-                       if ((end = strchr(beg, '\\')) == NULL)
-                               goto error;
-                       *end = 0;
-
-                       /* Print short name */
+               d_printf("%-24s", domain_list[i].dns_name);
 
-                       d_printf("%-16s", name);
-
-                       if (!print_all) {
-                               d_printf("\n"); 
-                               continue;
-                       }
+               switch(domain_list[i].trust_type) {
+               case WBC_DOMINFO_TRUSTTYPE_NONE:
+                       d_printf("None        ");
+                       break;
+               case WBC_DOMINFO_TRUSTTYPE_FOREST:              
+                       d_printf("Forest      ");
+                       break;
+               case WBC_DOMINFO_TRUSTTYPE_EXTERNAL:            
+                       d_printf("External    ");
+                       break;
+               case WBC_DOMINFO_TRUSTTYPE_IN_FOREST:
+                       d_printf("In-Forest   ");
+                       break;
+               }
 
-                       /* Print DNS domain */
+               if (domain_list[i].trust_flags & WBC_DOMINFO_TRUST_TRANSITIVE) {
+                       d_printf("Yes         ");
+               } else {
+                       d_printf("No          ");
+               }
 
-                       if (beg) {
-                               d_printf("%-24s", beg);
-                       }
+               if (domain_list[i].trust_flags & WBC_DOMINFO_TRUST_INCOMING) {
+                       d_printf("Yes  ");
+               } else {
+                       d_printf("No   ");
+               }
 
-                       /* 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("%-5s", beg);
-
-                       /* Print Outgoing */
-                       beg = ++end;
-                       d_printf("%-5s\n", beg);
+               if (domain_list[i].trust_flags & WBC_DOMINFO_TRUST_OUTGOING) {
+                       d_printf("Yes  ");
+               } else {
+                       d_printf("No   ");
                }
-               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);
+               d_printf("\n");
        }
 
        return true;
@@ -519,12 +485,12 @@ static bool wbinfo_domain_info(const char *domain)
        d_printf("SID               : %s\n", sid_str);
 
        d_printf("Active Directory  : %s\n",
-                (dinfo->flags & WBC_DOMINFO_AD) ? "Yes" : "No");
+                (dinfo->domain_flags & WBC_DOMINFO_AD) ? "Yes" : "No");
        d_printf("Native            : %s\n",
-                (dinfo->flags & WBC_DOMINFO_NATIVE) ? "Yes" : "No");
+                (dinfo->domain_flags & WBC_DOMINFO_NATIVE) ? "Yes" : "No");
 
        d_printf("Primary           : %s\n",
-                (dinfo->flags & WBC_DOMINFO_PRIMARY) ? "Yes" : "No");
+                (dinfo->domain_flags & WBC_DOMINFO_PRIMARY) ? "Yes" : "No");
 
        wbcFreeMemory(sid_str);
        wbcFreeMemory(dinfo);