s3: Add wbinfo --dc-info
[obnox/samba-ctdb.git] / nsswitch / libwbclient / wbc_util.c
index c39023f15e29778fba2335fdc924c200f5652a48..2065f4be0535d14458a56c718f65e66910d651d8 100644 (file)
@@ -179,6 +179,94 @@ 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 = talloc_zero_array(NULL, const char *,
+                                 response.data.num_entries);
+       BAIL_ON_PTR_ERROR(names, wbc_status);
+
+       ips = talloc_zero_array(NULL, const char *,
+                               response.data.num_entries);
+       BAIL_ON_PTR_ERROR(names, 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] = talloc_strndup(names, 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] = talloc_strndup(ips, 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)