lsa: lsa_CreateTrustedDomainEx takes lsa_TrustDomainInfoAuthInfo, not
[samba.git] / nsswitch / libwbclient / wbc_util.c
index e2e657a903af441d5859133f6e0ad3d88b56bfcd..af134ba7e5b410abb0c5388507704687c0e8794b 100644 (file)
@@ -203,6 +203,92 @@ wbcErr wbcDomainInfo(const char *domain, struct wbcDomainInfo **dinfo)
        return wbc_status;
 }
 
+/* Get the list of current DCs */
+wbcErr wbcDcInfo(const char *domain, size_t *num_dcs,
+                const char ***dc_names, const char ***dc_ips)
+{
+       struct winbindd_request request;
+       struct winbindd_response response;
+       const char **names = NULL;
+       const char **ips = NULL;
+       wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE;
+       size_t extra_len;
+       int i;
+       char *p;
+
+       /* Initialise request */
+
+       ZERO_STRUCT(request);
+       ZERO_STRUCT(response);
+
+       if (domain != NULL) {
+               strncpy(request.domain_name, domain,
+                       sizeof(request.domain_name) - 1);
+       }
+
+       wbc_status = wbcRequestResponse(WINBINDD_DC_INFO,
+                                       &request, &response);
+       BAIL_ON_WBC_ERROR(wbc_status);
+
+       names = wbcAllocateStringArray(response.data.num_entries);
+       BAIL_ON_PTR_ERROR(names, wbc_status);
+
+       ips = wbcAllocateStringArray(response.data.num_entries);
+       BAIL_ON_PTR_ERROR(ips, wbc_status);
+
+       wbc_status = WBC_ERR_INVALID_RESPONSE;
+
+       p = (char *)response.extra_data.data;
+
+       if (response.length < (sizeof(struct winbindd_response)+1)) {
+               goto done;
+       }
+
+       extra_len = response.length - sizeof(struct winbindd_response);
+
+       if (p[extra_len-1] != '\0') {
+               goto done;
+       }
+
+       for (i=0; i<response.data.num_entries; i++) {
+               char *q;
+
+               q = strchr(p, '\n');
+               if (q == NULL) {
+                       goto done;
+               }
+               names[i] = strndup(p, q-p);
+               BAIL_ON_PTR_ERROR(names[i], wbc_status);
+               p = q+1;
+
+               q = strchr(p, '\n');
+               if (q == NULL) {
+                       goto done;
+               }
+               ips[i] = strndup(p, q-p);
+               BAIL_ON_PTR_ERROR(ips[i], wbc_status);
+               p = q+1;
+       }
+       if (p[0] != '\0') {
+               goto done;
+       }
+
+        wbc_status = WBC_ERR_SUCCESS;
+done:
+       if (response.extra_data.data)
+               free(response.extra_data.data);
+
+       if (WBC_ERROR_IS_OK(wbc_status)) {
+               *num_dcs = response.data.num_entries;
+               *dc_names = names;
+               names = NULL;
+               *dc_ips = ips;
+               ips = NULL;
+       }
+       wbcFreeMemory(names);
+       wbcFreeMemory(ips);
+       return wbc_status;
+}
 
 /* Resolve a NetbiosName via WINS */
 wbcErr wbcResolveWinsByName(const char *name, char **ip)
@@ -537,13 +623,13 @@ static void wbcDomainControllerInfoExDestructor(void *ptr)
 {
        struct wbcDomainControllerInfoEx *i =
                (struct wbcDomainControllerInfoEx *)ptr;
-       free((char *)(i->dc_unc));
-       free((char *)(i->dc_address));
-       free((char *)(i->domain_guid));
-       free((char *)(i->domain_name));
-       free((char *)(i->forest_name));
-       free((char *)(i->dc_site_name));
-       free((char *)(i->client_site_name));
+       free(discard_const_p(char, i->dc_unc));
+       free(discard_const_p(char, i->dc_address));
+       free(discard_const_p(char, i->domain_guid));
+       free(discard_const_p(char, i->domain_name));
+       free(discard_const_p(char, i->forest_name));
+       free(discard_const_p(char, i->dc_site_name));
+       free(discard_const_p(char, i->client_site_name));
 }
 
 static wbcErr wbc_create_domain_controller_info_ex(const struct winbindd_response *resp,
@@ -672,7 +758,7 @@ static void wbcNamedBlobDestructor(void *ptr)
        struct wbcNamedBlob *b = (struct wbcNamedBlob *)ptr;
 
        while (b->name != NULL) {
-               free((char *)(b->name));
+               free(discard_const_p(char, b->name));
                free(b->blob.data);
                b += 1;
        }
@@ -701,6 +787,10 @@ wbcErr wbcAddNamedBlob(size_t *num_blobs,
                *num_blobs + 2, sizeof(struct wbcNamedBlob),
                wbcNamedBlobDestructor);
 
+       if (blobs == NULL) {
+               return WBC_ERR_NO_MEMORY;
+       }
+
        if (*pblobs != NULL) {
                struct wbcNamedBlob *old = *pblobs;
                memcpy(blobs, old, sizeof(struct wbcNamedBlob) * (*num_blobs));