/* Lists Groups */ wbcErr wbcListGroups(const char *domain_name, uint32_t *_num_groups, const char ***_groups) { wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE; struct winbindd_request request; struct winbindd_response response; uint32_t num_groups = 0; const char **groups = NULL; const char *next; /* Initialise request */ ZERO_STRUCT(request); ZERO_STRUCT(response); if (domain_name) { strncpy(request.domain_name, domain_name, sizeof(request.domain_name)-1); } wbc_status = wbcRequestResponse(WINBINDD_LIST_GROUPS, &request, &response); BAIL_ON_WBC_ERROR(wbc_status); groups = wbcAllocateStringArray(response.data.num_entries); if (groups == NULL) { return WBC_ERR_NO_MEMORY; } /* Look through extra data */ next = (const char *)response.extra_data.data; while (next) { const char *current; char *k; if (num_groups >= response.data.num_entries) { wbc_status = WBC_ERR_INVALID_RESPONSE; goto done; } current = next; k = strchr(next, ','); if (k) { k[0] = '\0'; next = k+1; } else { next = NULL; } groups[num_groups] = strdup(current); BAIL_ON_PTR_ERROR(groups[num_groups], wbc_status); num_groups += 1; } if (num_groups != response.data.num_entries) { wbc_status = WBC_ERR_INVALID_RESPONSE; goto done; } *_num_groups = response.data.num_entries; *_groups = groups; groups = NULL; wbc_status = WBC_ERR_SUCCESS; done: winbindd_free_response(&response); wbcFreeMemory(groups); 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; }
wbcErr wbcLookupRids(struct wbcDomainSid *dom_sid, int num_rids, uint32_t *rids, const char **pp_domain_name, const char ***pnames, enum wbcSidType **ptypes) { size_t i, len, ridbuf_size; char *ridlist; char *p; struct winbindd_request request; struct winbindd_response response; char *domain_name = NULL; const char **names = NULL; enum wbcSidType *types = NULL; wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE; /* Initialise request */ ZERO_STRUCT(request); ZERO_STRUCT(response); if (!dom_sid || (num_rids == 0)) { wbc_status = WBC_ERR_INVALID_PARAM; BAIL_ON_WBC_ERROR(wbc_status); } wbcSidToStringBuf(dom_sid, request.data.sid, sizeof(request.data.sid)); /* Even if all the Rids were of maximum 32bit values, we would only have 11 bytes per rid in the final array ("4294967296" + \n). Add one more byte for the terminating '\0' */ ridbuf_size = (sizeof(char)*11) * num_rids + 1; ridlist = (char *)malloc(ridbuf_size); BAIL_ON_PTR_ERROR(ridlist, wbc_status); len = 0; for (i=0; i<num_rids; i++) { len += snprintf(ridlist + len, ridbuf_size - len, "%u\n", rids[i]); } ridlist[len] = '\0'; len += 1; request.extra_data.data = ridlist; request.extra_len = len; wbc_status = wbcRequestResponse(WINBINDD_LOOKUPRIDS, &request, &response); free(ridlist); BAIL_ON_WBC_ERROR(wbc_status); domain_name = wbcStrDup(response.data.domain_name); BAIL_ON_PTR_ERROR(domain_name, wbc_status); names = wbcAllocateStringArray(num_rids); BAIL_ON_PTR_ERROR(names, wbc_status); types = (enum wbcSidType *)wbcAllocateMemory( num_rids, sizeof(enum wbcSidType), NULL); BAIL_ON_PTR_ERROR(types, wbc_status); p = (char *)response.extra_data.data; for (i=0; i<num_rids; i++) { char *q; if (*p == '\0') { wbc_status = WBC_ERR_INVALID_RESPONSE; goto done; } types[i] = (enum wbcSidType)strtoul(p, &q, 10); if (*q != ' ') { wbc_status = WBC_ERR_INVALID_RESPONSE; goto done; } p = q+1; if ((q = strchr(p, '\n')) == NULL) { wbc_status = WBC_ERR_INVALID_RESPONSE; goto done; } *q = '\0'; names[i] = strdup(p); BAIL_ON_PTR_ERROR(names[i], wbc_status); p = q+1; } if (*p != '\0') { wbc_status = WBC_ERR_INVALID_RESPONSE; goto done; } wbc_status = WBC_ERR_SUCCESS; done: winbindd_free_response(&response); if (WBC_ERROR_IS_OK(wbc_status)) { *pp_domain_name = domain_name; *pnames = names; *ptypes = types; } else { wbcFreeMemory(domain_name); wbcFreeMemory(names); wbcFreeMemory(types); } return wbc_status; }
wbcErr wbcLookupRids(struct wbcDomainSid *dom_sid, int num_rids, uint32_t *rids, const char **pp_domain_name, const char ***pnames, enum wbcSidType **ptypes) { struct wbcDomainSid obj_sid = {0}; size_t c; wbcErr err; char *domain; char *name; enum wbcSidType type; const char **names = NULL; enum wbcSidType *types = NULL; obj_sid.sid_rev_num = dom_sid->sid_rev_num; obj_sid.num_auths = dom_sid->num_auths + 1; for (c = 0; c < 6; c++) { obj_sid.id_auth[c] = dom_sid->id_auth[c]; } for (c = 0; c < WBC_MAXSUBAUTHS; c++) { obj_sid.sub_auths[c] = dom_sid->sub_auths[c]; } names = wbcAllocateStringArray(num_rids + 1); if (names == NULL) { err = WBC_ERR_NO_MEMORY; goto done; } types = wbcAllocateMemory(num_rids + 1, sizeof(enum wbcSidType), NULL); if (types == NULL) { err = WBC_ERR_NO_MEMORY; goto done; } for (c = 0; c < num_rids; c++) { obj_sid.sub_auths[obj_sid.num_auths - 1] = rids[c]; err = wbcLookupSid(&obj_sid, &domain, &name, &type); if (err != WBC_ERR_SUCCESS) { goto done; } names[c] = strdup(name); wbcFreeMemory(name); if (names[c] == NULL) { err = WBC_ERR_NO_MEMORY; goto done; } types[c] = type; if (c == 0) { *pp_domain_name = domain; } else { wbcFreeMemory(domain); } } *pnames = names; *ptypes = types; err = WBC_ERR_SUCCESS; done: if (err != WBC_ERR_SUCCESS) { wbcFreeMemory(types); wbcFreeMemory(names); } return err; }