static bool test_wbc_get_sidaliases(struct torture_context *tctx) { struct wbcDomainSid builtin; struct wbcDomainInfo *info; struct wbcInterfaceDetails *details; struct wbcDomainSid sids[2]; uint32_t *rids; uint32_t num_rids; wbcErr ret; torture_assert_wbc_ok(tctx, wbcInterfaceDetails(&details), "wbcInterfaceDetails failed"); torture_assert_wbc_ok( tctx, wbcDomainInfo(details->netbios_domain, &info), "wbcDomainInfo failed"); wbcFreeMemory(details); sids[0] = info->sid; sids[0].sub_auths[sids[0].num_auths++] = 500; sids[1] = info->sid; sids[1].sub_auths[sids[1].num_auths++] = 512; wbcFreeMemory(info); torture_assert_wbc_ok( tctx, wbcStringToSid("S-1-5-32", &builtin), "wbcStringToSid failed"); ret = wbcGetSidAliases(&builtin, sids, 2, &rids, &num_rids); torture_assert_wbc_ok(tctx, ret, "wbcGetSidAliases failed"); wbcFreeMemory(rids); return true; }
/* Convert a Unix uid to a Windows SID, allocating a SID if needed */ wbcErr wbcUidToSid(uid_t uid, struct wbcDomainSid *sid) { int ret; char *str_sid; enum sss_id_type type; wbcErr wbc_status; ret = sss_nss_getsidbyid(uid, &str_sid, &type); if (ret != 0) { return WBC_ERR_UNKNOWN_FAILURE; } if (type != SSS_ID_TYPE_UID && type != SSS_ID_TYPE_BOTH) { free(str_sid); return WBC_ERR_UNKNOWN_USER; } wbc_status = wbcStringToSid(str_sid, sid); free(str_sid); if (!WBC_ERROR_IS_OK(wbc_status)) { return wbc_status; } return WBC_ERR_SUCCESS; }
static bool test_wbc_lookup_rids(struct torture_context *tctx) { struct wbcDomainSid builtin; uint32_t rids[2] = { 544, 545 }; const char *domain_name, **names; enum wbcSidType *types; wbcErr ret; wbcStringToSid("S-1-5-32", &builtin); ret = wbcLookupRids(&builtin, 2, rids, &domain_name, &names, &types); torture_assert_wbc_ok(tctx, ret, "wbcLookupRids failed"); torture_assert_str_equal( tctx, names[0], "Administrators", "S-1-5-32-544 not mapped to 'Administrators'"); torture_assert_str_equal( tctx, names[1], "Users", "S-1-5-32-545 not mapped to 'Users'"); wbcFreeMemory(discard_const_p(char ,domain_name)); wbcFreeMemory(names); wbcFreeMemory(types); return true; }
static bool wbinfo_get_userdomgroups(const char *user_sid_str) { wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE; uint32_t num_sids; uint32_t i; struct wbcDomainSid user_sid, *sids = NULL; /* Send request */ wbc_status = wbcStringToSid(user_sid_str, &user_sid); if (!WBC_ERROR_IS_OK(wbc_status)) { return false; } wbc_status = wbcLookupUserSids(&user_sid, true, &num_sids, &sids); if (!WBC_ERROR_IS_OK(wbc_status)) { return false; } for (i = 0; i < num_sids; i++) { char *str = NULL; wbc_status = wbcSidToString(&sids[i], &str); if (!WBC_ERROR_IS_OK(wbc_status)) { wbcFreeMemory(sids); return false; } d_printf("%s\n", str); wbcFreeMemory(str); } wbcFreeMemory(sids); return true; }
wbcErr wbcUidToSid(uid_t uid, struct wbcDomainSid *sid) { wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE; struct winbindd_request request; struct winbindd_response response; if (!sid) { wbc_status = WBC_ERR_INVALID_PARAM; BAIL_ON_WBC_ERROR(wbc_status); } /* Initialize request */ ZERO_STRUCT(request); ZERO_STRUCT(response); request.data.uid = uid; /* Make request */ wbc_status = wbcRequestResponse(WINBINDD_UID_TO_SID, &request, &response); BAIL_ON_WBC_ERROR(wbc_status); wbc_status = wbcStringToSid(response.data.sid.sid, sid); BAIL_ON_WBC_ERROR(wbc_status); done: return wbc_status; }
static bool wbinfo_lookupsid(const char *sid_str) { wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE; struct wbcDomainSid sid; char *domain; char *name; enum wbcSidType type; /* Send off request */ wbc_status = wbcStringToSid(sid_str, &sid); if (!WBC_ERROR_IS_OK(wbc_status)) { return false; } wbc_status = wbcLookupSid(&sid, &domain, &name, &type); if (!WBC_ERROR_IS_OK(wbc_status)) { return false; } /* Display response */ d_printf("%s%c%s %d\n", domain, winbind_separator(), name, type); return true; }
/* Lookup the current status of a trusted domain */ wbcErr wbcDomainInfo(const char *domain, struct wbcDomainInfo **dinfo) { struct winbindd_request request; struct winbindd_response response; wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE; struct wbcDomainInfo *info = NULL; if (!domain || !dinfo) { wbc_status = WBC_ERR_INVALID_PARAM; BAIL_ON_WBC_ERROR(wbc_status); } /* Initialize request */ ZERO_STRUCT(request); ZERO_STRUCT(response); strncpy(request.domain_name, domain, sizeof(request.domain_name)-1); wbc_status = wbcRequestResponse(WINBINDD_DOMAIN_INFO, &request, &response); BAIL_ON_WBC_ERROR(wbc_status); info = talloc(NULL, struct wbcDomainInfo); BAIL_ON_PTR_ERROR(info, wbc_status); info->short_name = talloc_strdup(info, response.data.domain_info.name); BAIL_ON_PTR_ERROR(info->short_name, wbc_status); info->dns_name = talloc_strdup(info, response.data.domain_info.alt_name); BAIL_ON_PTR_ERROR(info->dns_name, wbc_status); wbc_status = wbcStringToSid(response.data.domain_info.sid, &info->sid); BAIL_ON_WBC_ERROR(wbc_status); if (response.data.domain_info.native_mode) info->domain_flags |= WBC_DOMINFO_DOMAIN_NATIVE; if (response.data.domain_info.active_directory) info->domain_flags |= WBC_DOMINFO_DOMAIN_AD; if (response.data.domain_info.primary) info->domain_flags |= WBC_DOMINFO_DOMAIN_PRIMARY; *dinfo = info; wbc_status = WBC_ERR_SUCCESS; done: if (!WBC_ERROR_IS_OK(wbc_status)) { talloc_free(info); } return wbc_status; }
static bool wbinfo_get_sidaliases(const char *domain, const char *user_sid_str) { wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE; struct wbcDomainInfo *dinfo = NULL; uint32_t i; struct wbcDomainSid user_sid; uint32_t *alias_rids = NULL; uint32_t num_alias_rids; char *domain_sid_str = NULL; /* Send request */ if ((domain == NULL) || (strequal(domain, ".")) || (domain[0] == '\0')) { domain = get_winbind_domain(); } /* Send request */ wbc_status = wbcDomainInfo(domain, &dinfo); if (!WBC_ERROR_IS_OK(wbc_status)) { d_printf("wbcDomainInfo(%s) failed: %s\n", domain, wbcErrorString(wbc_status)); goto done; } wbc_status = wbcStringToSid(user_sid_str, &user_sid); if (!WBC_ERROR_IS_OK(wbc_status)) { goto done; } wbc_status = wbcGetSidAliases(&dinfo->sid, &user_sid, 1, &alias_rids, &num_alias_rids); if (!WBC_ERROR_IS_OK(wbc_status)) { goto done; } wbc_status = wbcSidToString(&dinfo->sid, &domain_sid_str); if (!WBC_ERROR_IS_OK(wbc_status)) { goto done; } for (i = 0; i < num_alias_rids; i++) { d_printf("%s-%d\n", domain_sid_str, alias_rids[i]); } wbcFreeMemory(alias_rids); done: if (domain_sid_str) { wbcFreeMemory(domain_sid_str); } if (dinfo) { wbcFreeMemory(dinfo); } return (WBC_ERR_SUCCESS == wbc_status); }
static bool test_wbc_sidtostring(struct torture_context *tctx) { struct wbcDomainSid sid; const char *sid_string = "S-1-5-32"; char *sid_string2; torture_assert_wbc_ok(tctx, wbcStringToSid(sid_string, &sid), "wbcStringToSid failed"); torture_assert_wbc_ok(tctx, wbcSidToString(&sid, &sid_string2), "wbcSidToString failed"); torture_assert_str_equal(tctx, sid_string, sid_string2, "sid strings differ"); wbcFreeMemory(sid_string2); return true; }
/* Convert a domain and name to SID */ wbcErr wbcLookupName(const char *domain, const char *name, struct wbcDomainSid *sid, enum wbcSidType *name_type) { struct winbindd_request request; struct winbindd_response response; wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE; if (!sid || !name_type) { wbc_status = WBC_ERR_INVALID_PARAM; BAIL_ON_WBC_ERROR(wbc_status); } /* Initialize request */ ZERO_STRUCT(request); ZERO_STRUCT(response); /* dst is already null terminated from the memset above */ strncpy(request.data.name.dom_name, domain, sizeof(request.data.name.dom_name)-1); strncpy(request.data.name.name, name, sizeof(request.data.name.name)-1); wbc_status = wbcRequestResponse(WINBINDD_LOOKUPNAME, &request, &response); BAIL_ON_WBC_ERROR(wbc_status); wbc_status = wbcStringToSid(response.data.sid.sid, sid); BAIL_ON_WBC_ERROR(wbc_status); *name_type = (enum wbcSidType)response.data.sid.type; wbc_status = WBC_ERR_SUCCESS; done: return wbc_status; }
/* Convert a domain and name to SID */ wbcErr wbcLookupName(const char *domain, const char *name, struct wbcDomainSid *sid, enum wbcSidType *name_type) { char *fq_name = NULL; char *str_sid; enum sss_id_type type; int ret; wbcErr wbc_status; if (domain == NULL || name == NULL || strnlen(domain, MAX_NAME_LEN) == MAX_NAME_LEN || strnlen(name, MAX_NAME_LEN) == MAX_NAME_LEN) { return WBC_ERR_INVALID_PARAM; } ret = asprintf(&fq_name, "%s@%s", name, domain); if (ret == -1) { return WBC_ERR_NO_MEMORY; } ret = sss_nss_getsidbyname(fq_name, &str_sid, &type); free(fq_name); if (ret != 0) { return WBC_ERR_UNKNOWN_FAILURE; } ret = sss_id_type_to_wbcSidType(type, name_type); if (ret != 0) { return WBC_ERR_UNKNOWN_FAILURE; } wbc_status = wbcStringToSid(str_sid, sid); free(str_sid); if (!WBC_ERROR_IS_OK(wbc_status)) { return wbc_status; } return WBC_ERR_SUCCESS; }
static bool wbinfo_get_user_sidinfo(const char *sid_str) { wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE; struct passwd *pwd = NULL; struct wbcDomainSid sid; wbc_status = wbcStringToSid(sid_str, &sid); wbc_status = wbcGetpwsid(&sid, &pwd); if (!WBC_ERROR_IS_OK(wbc_status)) { return false; } d_printf("%s:%s:%d:%d:%s:%s:%s\n", pwd->pw_name, pwd->pw_passwd, pwd->pw_uid, pwd->pw_gid, pwd->pw_gecos, pwd->pw_dir, pwd->pw_shell); return true; }
static bool wbinfo_set_uid_mapping(uid_t uid, const char *sid_str) { wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE; struct wbcDomainSid sid; /* Send request */ wbc_status = wbcStringToSid(sid_str, &sid); if (!WBC_ERROR_IS_OK(wbc_status)) { return false; } wbc_status = wbcSetUidMapping(uid, &sid); if (!WBC_ERROR_IS_OK(wbc_status)) { return false; } /* Display response */ d_printf("uid %d now mapped to sid %s\n", uid, sid_str); return true; }
static bool wbinfo_remove_gid_mapping(gid_t gid, const char *sid_str) { wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE; struct wbcDomainSid sid; /* Send request */ wbc_status = wbcStringToSid(sid_str, &sid); if (!WBC_ERROR_IS_OK(wbc_status)) { return false; } wbc_status = wbcRemoveGidMapping(gid, &sid); if (!WBC_ERROR_IS_OK(wbc_status)) { return false; } /* Display response */ d_printf("Removed gid %d to sid %s mapping\n", gid, sid_str); return true; }
static bool wbinfo_sid_to_gid(const char *sid_str) { wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE; struct wbcDomainSid sid; gid_t gid; /* Send request */ wbc_status = wbcStringToSid(sid_str, &sid); if (!WBC_ERROR_IS_OK(wbc_status)) { return false; } wbc_status = wbcSidToGid(&sid, &gid); if (!WBC_ERROR_IS_OK(wbc_status)) { return false; } /* Display response */ d_printf("%d\n", (int)gid); return true; }
static int net_idmap_restore(struct net_context *c, int argc, const char **argv) { TALLOC_CTX *ctx; FILE *input; if (c->display_usage) { d_printf(_("Usage:\n" "net idmap restore [inputfile]\n" " Restore ID mappings from file\n" " inputfile\tFile to load ID mappings from. If " "not given, load data from stdin.\n")); return 0; } if (! winbind_ping()) { d_fprintf(stderr, _("To use net idmap Winbindd must be running.\n")); return -1; } ctx = talloc_new(NULL); ALLOC_CHECK(ctx); if (argc == 1) { input = fopen(argv[0], "r"); } else { input = stdin; } while (!feof(input)) { char line[128], sid_string[128]; int len; struct wbcDomainSid sid; enum id_type type = ID_TYPE_NOT_SPECIFIED; unsigned long idval; wbcErr wbc_status; if (fgets(line, 127, input) == NULL) break; len = strlen(line); if ( (len > 0) && (line[len-1] == '\n') ) line[len-1] = '\0'; if (sscanf(line, "GID %lu %128s", &idval, sid_string) == 2) { type = ID_TYPE_GID; } else if (sscanf(line, "UID %lu %128s", &idval, sid_string) == 2) { type = ID_TYPE_UID; } else if (sscanf(line, "USER HWM %lu", &idval) == 1) { /* set uid hwm */ wbc_status = wbcSetUidHwm(idval); if (!WBC_ERROR_IS_OK(wbc_status)) { d_fprintf(stderr, _("Could not set USER HWM: %s\n"), wbcErrorString(wbc_status)); } continue; } else if (sscanf(line, "GROUP HWM %lu", &idval) == 1) { /* set gid hwm */ wbc_status = wbcSetGidHwm(idval); if (!WBC_ERROR_IS_OK(wbc_status)) { d_fprintf(stderr, _("Could not set GROUP HWM: %s\n"), wbcErrorString(wbc_status)); } continue; } else { d_fprintf(stderr, _("ignoring invalid line [%s]\n"), line); continue; } wbc_status = wbcStringToSid(sid_string, &sid); if (!WBC_ERROR_IS_OK(wbc_status)) { d_fprintf(stderr, _("ignoring invalid sid [%s]: %s\n"), sid_string, wbcErrorString(wbc_status)); continue; } if (type == ID_TYPE_UID) { wbc_status = wbcSetUidMapping(idval, &sid); } else { wbc_status = wbcSetGidMapping(idval, &sid); } if (!WBC_ERROR_IS_OK(wbc_status)) { d_fprintf(stderr, _("Could not set mapping of %s %lu to sid %s: %s\n"), (type == ID_TYPE_GID) ? "GID" : "UID", idval, sid_string, wbcErrorString(wbc_status)); continue; } } if (input != stdin) { fclose(input); } talloc_free(ctx); return 0; }
static DWORD FillDomainInfo( OUT struct wbcDomainInfo *pWbcDomInfo, IN PLSA_TRUSTED_DOMAIN_INFO pLsaDomInfo ) { DWORD dwErr = LW_ERROR_INTERNAL; if (pLsaDomInfo->pszDnsDomain) { pWbcDomInfo->dns_name = _wbc_strdup(pLsaDomInfo->pszDnsDomain); BAIL_ON_NULL_PTR(pLsaDomInfo->pszDnsDomain, dwErr); } if (pLsaDomInfo->pszNetbiosDomain) { pWbcDomInfo->short_name = _wbc_strdup(pLsaDomInfo->pszNetbiosDomain); BAIL_ON_NULL_PTR(pLsaDomInfo->pszNetbiosDomain, dwErr); } if (pLsaDomInfo->pszDomainSID) { dwErr = wbcStringToSid(pLsaDomInfo->pszDomainSID, &pWbcDomInfo->sid); BAIL_ON_LSA_ERR(dwErr); } /* Domain flags */ pWbcDomInfo->domain_flags = WBC_DOMINFO_DOMAIN_AD; if (pLsaDomInfo->dwDomainFlags & LSA_DM_DOMAIN_FLAG_PRIMARY) { pWbcDomInfo->domain_flags |= WBC_DOMINFO_DOMAIN_PRIMARY; pWbcDomInfo->trust_flags |= WBC_DOMINFO_TRUST_INCOMING; pWbcDomInfo->trust_flags |= WBC_DOMINFO_TRUST_OUTGOING; pWbcDomInfo->trust_flags |= WBC_DOMINFO_TRUST_TRANSITIVE; } if ((pLsaDomInfo->dwDomainFlags & LSA_DM_DOMAIN_FLAG_OFFLINE) || (pLsaDomInfo->dwDomainFlags & LSA_DM_DOMAIN_FLAG_FORCE_OFFLINE)) { pWbcDomInfo->domain_flags |= WBC_DOMINFO_DOMAIN_OFFLINE; } /* Trust Flags */ if (pLsaDomInfo->dwTrustFlags & LSA_TRUST_FLAG_INBOUND) { pWbcDomInfo->trust_flags |= WBC_DOMINFO_TRUST_INCOMING; } if (pLsaDomInfo->dwTrustFlags & LSA_TRUST_FLAG_OUTBOUND) { pWbcDomInfo->trust_flags |= WBC_DOMINFO_TRUST_OUTGOING; } if ((pLsaDomInfo->dwTrustAttributes & (LSA_TRUST_ATTRIBUTE_WITHIN_FOREST| LSA_TRUST_ATTRIBUTE_FOREST_TRANSITIVE)) || (pLsaDomInfo->dwTrustFlags & LSA_TRUST_FLAG_IN_FOREST)) { pWbcDomInfo->trust_flags |= WBC_DOMINFO_TRUST_TRANSITIVE; } /* Trust Type */ if (pLsaDomInfo->dwTrustAttributes & LSA_TRUST_ATTRIBUTE_WITHIN_FOREST) { pWbcDomInfo->trust_type |= WBC_DOMINFO_TRUSTTYPE_IN_FOREST; } if (pLsaDomInfo->dwTrustAttributes & LSA_TRUST_ATTRIBUTE_FOREST_TRANSITIVE) { pWbcDomInfo->trust_type |= WBC_DOMINFO_TRUSTTYPE_FOREST; } if (pLsaDomInfo->dwTrustAttributes & LSA_TRUST_ATTRIBUTE_NON_TRANSITIVE) { pWbcDomInfo->trust_type |= WBC_DOMINFO_TRUSTTYPE_EXTERNAL; } switch (pLsaDomInfo->dwTrustMode) { case LSA_TRUST_MODE_MY_FOREST: pWbcDomInfo->trust_type = WBC_DOMINFO_TRUSTTYPE_IN_FOREST; pWbcDomInfo->trust_flags |= (WBC_DOMINFO_TRUST_INCOMING| WBC_DOMINFO_TRUST_OUTGOING); break; case LSA_TRUST_MODE_OTHER_FOREST: pWbcDomInfo->trust_type = WBC_DOMINFO_TRUSTTYPE_FOREST; break; case LSA_TRUST_MODE_EXTERNAL: pWbcDomInfo->trust_type = WBC_DOMINFO_TRUSTTYPE_EXTERNAL; break; } cleanup: return dwErr; }
/* Get alias membership for sids */ wbcErr wbcGetSidAliases(const struct wbcDomainSid *dom_sid, struct wbcDomainSid *sids, uint32_t num_sids, uint32_t **alias_rids, uint32_t *num_alias_rids) { uint32_t i; const char *s; struct winbindd_request request; struct winbindd_response response; ssize_t extra_data_len = 0; char * extra_data = NULL; ssize_t buflen = 0; struct wbcDomainSid sid; wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE; uint32_t * rids = NULL; /* Initialise request */ ZERO_STRUCT(request); ZERO_STRUCT(response); if (!dom_sid) { wbc_status = WBC_ERR_INVALID_PARAM; goto done; } wbcSidToStringBuf(dom_sid, request.data.sid, sizeof(request.data.sid)); /* Lets assume each sid is around 57 characters * S-1-5-21-AAAAAAAAAAA-BBBBBBBBBBB-CCCCCCCCCCC-DDDDDDDDDDD\n */ buflen = 57 * num_sids; extra_data = (char *)malloc(buflen); if (!extra_data) { wbc_status = WBC_ERR_NO_MEMORY; goto done; } /* Build the sid list */ for (i=0; i<num_sids; i++) { char sid_str[WBC_SID_STRING_BUFLEN]; size_t sid_len; sid_len = wbcSidToStringBuf(&sids[i], sid_str, sizeof(sid_str)); if (buflen < extra_data_len + sid_len + 2) { buflen *= 2; extra_data = (char *)realloc(extra_data, buflen); if (!extra_data) { wbc_status = WBC_ERR_NO_MEMORY; BAIL_ON_WBC_ERROR(wbc_status); } } strncpy(&extra_data[extra_data_len], sid_str, buflen - extra_data_len); extra_data_len += sid_len; extra_data[extra_data_len++] = '\n'; extra_data[extra_data_len] = '\0'; } extra_data_len += 1; request.extra_data.data = extra_data; request.extra_len = extra_data_len; wbc_status = wbcRequestResponse(WINBINDD_GETSIDALIASES, &request, &response); BAIL_ON_WBC_ERROR(wbc_status); if (response.data.num_entries && !response.extra_data.data) { wbc_status = WBC_ERR_INVALID_RESPONSE; goto done; } rids = (uint32_t *)wbcAllocateMemory(response.data.num_entries, sizeof(uint32_t), NULL); BAIL_ON_PTR_ERROR(sids, wbc_status); s = (const char *)response.extra_data.data; for (i = 0; i < response.data.num_entries; i++) { char *n = strchr(s, '\n'); if (n) { *n = '\0'; } wbc_status = wbcStringToSid(s, &sid); BAIL_ON_WBC_ERROR(wbc_status); wbc_status = _sid_to_rid(&sid, &rids[i]); BAIL_ON_WBC_ERROR(wbc_status); s += strlen(s) + 1; } *num_alias_rids = response.data.num_entries; *alias_rids = rids; rids = NULL; wbc_status = WBC_ERR_SUCCESS; done: free(extra_data); winbindd_free_response(&response); wbcFreeMemory(rids); return wbc_status; }
/* Get the groups a user belongs to */ wbcErr wbcLookupUserSids(const struct wbcDomainSid *user_sid, bool domain_groups_only, uint32_t *num_sids, struct wbcDomainSid **_sids) { uint32_t i; const char *s; struct winbindd_request request; struct winbindd_response response; struct wbcDomainSid *sids = NULL; wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE; int cmd; /* Initialise request */ ZERO_STRUCT(request); ZERO_STRUCT(response); if (!user_sid) { wbc_status = WBC_ERR_INVALID_PARAM; BAIL_ON_WBC_ERROR(wbc_status); } wbcSidToStringBuf(user_sid, request.data.sid, sizeof(request.data.sid)); if (domain_groups_only) { cmd = WINBINDD_GETUSERDOMGROUPS; } else { cmd = WINBINDD_GETUSERSIDS; } wbc_status = wbcRequestResponse(cmd, &request, &response); BAIL_ON_WBC_ERROR(wbc_status); if (response.data.num_entries && !response.extra_data.data) { wbc_status = WBC_ERR_INVALID_RESPONSE; BAIL_ON_WBC_ERROR(wbc_status); } sids = (struct wbcDomainSid *)wbcAllocateMemory( response.data.num_entries, sizeof(struct wbcDomainSid), NULL); BAIL_ON_PTR_ERROR(sids, wbc_status); s = (const char *)response.extra_data.data; for (i = 0; i < response.data.num_entries; i++) { char *n = strchr(s, '\n'); if (n) { *n = '\0'; } wbc_status = wbcStringToSid(s, &sids[i]); BAIL_ON_WBC_ERROR(wbc_status); s += strlen(s) + 1; } *num_sids = response.data.num_entries; *_sids = sids; sids = NULL; wbc_status = WBC_ERR_SUCCESS; done: winbindd_free_response(&response); if (sids) { wbcFreeMemory(sids); } return wbc_status; }
wbcErr wbcLookupSids(const struct wbcDomainSid *sids, int num_sids, struct wbcDomainInfo **pdomains, int *pnum_domains, struct wbcTranslatedName **pnames) { struct winbindd_request request; struct winbindd_response response; wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE; int buflen, i, extra_len, num_domains, num_names; char *sidlist, *p, *q, *extra_data; struct wbcDomainInfo *domains = NULL; struct wbcTranslatedName *names = NULL; buflen = num_sids * (WBC_SID_STRING_BUFLEN + 1) + 1; sidlist = (char *)malloc(buflen); if (sidlist == NULL) { return WBC_ERR_NO_MEMORY; } p = sidlist; for (i=0; i<num_sids; i++) { int remaining; int len; remaining = buflen - (p - sidlist); len = wbcSidToStringBuf(&sids[i], p, remaining); if (len > remaining) { free(sidlist); return WBC_ERR_UNKNOWN_FAILURE; } p += len; *p++ = '\n'; } *p++ = '\0'; ZERO_STRUCT(request); ZERO_STRUCT(response); request.extra_data.data = sidlist; request.extra_len = p - sidlist; wbc_status = wbcRequestResponse(WINBINDD_LOOKUPSIDS, &request, &response); free(sidlist); if (!WBC_ERROR_IS_OK(wbc_status)) { return wbc_status; } extra_len = response.length - sizeof(struct winbindd_response); extra_data = (char *)response.extra_data.data; if ((extra_len <= 0) || (extra_data[extra_len-1] != '\0')) { goto wbc_err_invalid; } p = extra_data; num_domains = strtoul(p, &q, 10); if (*q != '\n') { goto wbc_err_invalid; } p = q+1; domains = (struct wbcDomainInfo *)wbcAllocateMemory( num_domains+1, sizeof(struct wbcDomainInfo), wbcDomainInfosDestructor); if (domains == NULL) { wbc_status = WBC_ERR_NO_MEMORY; goto fail; } for (i=0; i<num_domains; i++) { q = strchr(p, ' '); if (q == NULL) { goto wbc_err_invalid; } *q = '\0'; wbc_status = wbcStringToSid(p, &domains[i].sid); if (!WBC_ERROR_IS_OK(wbc_status)) { goto fail; } p = q+1; q = strchr(p, '\n'); if (q == NULL) { goto wbc_err_invalid; } *q = '\0'; domains[i].short_name = wbcStrDup(p); if (domains[i].short_name == NULL) { wbc_status = WBC_ERR_NO_MEMORY; goto fail; } p = q+1; } num_names = strtoul(p, &q, 10); if (*q != '\n') { goto wbc_err_invalid; } p = q+1; if (num_names != num_sids) { goto wbc_err_invalid; } names = (struct wbcTranslatedName *)wbcAllocateMemory( num_names+1, sizeof(struct wbcTranslatedName), wbcTranslatedNamesDestructor); if (names == NULL) { wbc_status = WBC_ERR_NO_MEMORY; goto fail; } for (i=0; i<num_names; i++) { names[i].domain_index = strtoul(p, &q, 10); if (*q != ' ') { goto wbc_err_invalid; } p = q+1; names[i].type = strtoul(p, &q, 10); if (*q != ' ') { goto wbc_err_invalid; } p = q+1; q = strchr(p, '\n'); if (q == NULL) { goto wbc_err_invalid; } *q = '\0'; names[i].name = wbcStrDup(p); if (names[i].name == NULL) { wbc_status = WBC_ERR_NO_MEMORY; goto fail; } p = q+1; } if (*p != '\0') { goto wbc_err_invalid; } *pdomains = domains; *pnames = names; winbindd_free_response(&response); return WBC_ERR_SUCCESS; wbc_err_invalid: wbc_status = WBC_ERR_INVALID_RESPONSE; fail: winbindd_free_response(&response); wbcFreeMemory(domains); wbcFreeMemory(names); return wbc_status; }
static wbcErr process_domain_info_string(struct wbcDomainInfo *info, char *info_string) { wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE; char *r = NULL; char *s = NULL; 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 = strdup(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 = strdup(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 ((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_OUTGOING; } /* Online/Offline status */ r = s; if (r == NULL) { wbc_status = WBC_ERR_INVALID_RESPONSE; BAIL_ON_WBC_ERROR(wbc_status); } if ( strcmp(r, "Offline") == 0) { info->domain_flags |= WBC_DOMINFO_DOMAIN_OFFLINE; } wbc_status = WBC_ERR_SUCCESS; done: return wbc_status; }
static wbcErr wbc_create_auth_info(const struct winbindd_response *resp, struct wbcAuthUserInfo **_i) { wbcErr wbc_status = WBC_ERR_SUCCESS; struct wbcAuthUserInfo *i; struct wbcDomainSid domain_sid; char *p; uint32_t sn = 0; uint32_t j; i = (struct wbcAuthUserInfo *)wbcAllocateMemory( 1, sizeof(struct wbcAuthUserInfo), wbcAuthUserInfoDestructor); BAIL_ON_PTR_ERROR(i, wbc_status); i->user_flags = resp->data.auth.info3.user_flgs; i->account_name = strdup(resp->data.auth.info3.user_name); BAIL_ON_PTR_ERROR(i->account_name, wbc_status); if (resp->data.auth.validation_level == 6) { i->user_principal = strdup(resp->data.auth.info6.principal_name); BAIL_ON_PTR_ERROR(i->user_principal, wbc_status); } else { i->user_principal = NULL; } i->full_name = strdup(resp->data.auth.info3.full_name); BAIL_ON_PTR_ERROR(i->full_name, wbc_status); i->domain_name = strdup(resp->data.auth.info3.logon_dom); BAIL_ON_PTR_ERROR(i->domain_name, wbc_status); if (resp->data.auth.validation_level == 6) { i->dns_domain_name = strdup(resp->data.auth.info6.dns_domainname); BAIL_ON_PTR_ERROR(i->dns_domain_name, wbc_status); } else { i->dns_domain_name = NULL; } i->acct_flags = resp->data.auth.info3.acct_flags; memcpy(i->user_session_key, resp->data.auth.user_session_key, sizeof(i->user_session_key)); memcpy(i->lm_session_key, resp->data.auth.first_8_lm_hash, sizeof(i->lm_session_key)); i->logon_count = resp->data.auth.info3.logon_count; i->bad_password_count = resp->data.auth.info3.bad_pw_count; i->logon_time = resp->data.auth.info3.logon_time; i->logoff_time = resp->data.auth.info3.logoff_time; i->kickoff_time = resp->data.auth.info3.kickoff_time; i->pass_last_set_time = resp->data.auth.info3.pass_last_set_time; i->pass_can_change_time = resp->data.auth.info3.pass_can_change_time; i->pass_must_change_time= resp->data.auth.info3.pass_must_change_time; i->logon_server = strdup(resp->data.auth.info3.logon_srv); BAIL_ON_PTR_ERROR(i->logon_server, wbc_status); i->logon_script = strdup(resp->data.auth.info3.logon_script); BAIL_ON_PTR_ERROR(i->logon_script, wbc_status); i->profile_path = strdup(resp->data.auth.info3.profile_path); BAIL_ON_PTR_ERROR(i->profile_path, wbc_status); i->home_directory= strdup(resp->data.auth.info3.home_dir); BAIL_ON_PTR_ERROR(i->home_directory, wbc_status); i->home_drive = strdup(resp->data.auth.info3.dir_drive); BAIL_ON_PTR_ERROR(i->home_drive, wbc_status); i->num_sids = 2; i->num_sids += resp->data.auth.info3.num_groups; i->num_sids += resp->data.auth.info3.num_other_sids; i->sids = (struct wbcSidWithAttr *)calloc( sizeof(struct wbcSidWithAttr), i->num_sids); BAIL_ON_PTR_ERROR(i->sids, wbc_status); wbc_status = wbcStringToSid(resp->data.auth.info3.dom_sid, &domain_sid); BAIL_ON_WBC_ERROR(wbc_status); sn = 0; if (!sid_attr_compose(&i->sids[sn], &domain_sid, resp->data.auth.info3.user_rid, 0)) { wbc_status = WBC_ERR_INVALID_SID; goto done; } sn++; if (!sid_attr_compose(&i->sids[sn], &domain_sid, resp->data.auth.info3.group_rid, 0)) { wbc_status = WBC_ERR_INVALID_SID; goto done; } sn++; p = (char *)resp->extra_data.data; if (!p) { wbc_status = WBC_ERR_INVALID_RESPONSE; BAIL_ON_WBC_ERROR(wbc_status); } for (j=0; j < resp->data.auth.info3.num_groups; j++) { uint32_t rid; uint32_t attrs; int ret; char *s = p; char *e = strchr(p, '\n'); if (!e) { wbc_status = WBC_ERR_INVALID_RESPONSE; BAIL_ON_WBC_ERROR(wbc_status); } e[0] = '\0'; p = &e[1]; ret = sscanf(s, "0x%08X:0x%08X", &rid, &attrs); if (ret != 2) { wbc_status = WBC_ERR_INVALID_RESPONSE; BAIL_ON_WBC_ERROR(wbc_status); } if (!sid_attr_compose(&i->sids[sn], &domain_sid, rid, attrs)) { wbc_status = WBC_ERR_INVALID_SID; goto done; } sn++; } for (j=0; j < resp->data.auth.info3.num_other_sids; j++) { uint32_t attrs; int ret; char *s = p; char *a; char *e = strchr(p, '\n'); if (!e) { wbc_status = WBC_ERR_INVALID_RESPONSE; BAIL_ON_WBC_ERROR(wbc_status); } e[0] = '\0'; p = &e[1]; e = strchr(s, ':'); if (!e) { wbc_status = WBC_ERR_INVALID_RESPONSE; BAIL_ON_WBC_ERROR(wbc_status); } e[0] = '\0'; a = &e[1]; ret = sscanf(a, "0x%08X", &attrs); if (ret != 1) { wbc_status = WBC_ERR_INVALID_RESPONSE; BAIL_ON_WBC_ERROR(wbc_status); } wbc_status = wbcStringToSid(s, &i->sids[sn].sid); BAIL_ON_WBC_ERROR(wbc_status); i->sids[sn].attributes = attrs; sn++; } i->num_sids = sn; *_i = i; i = NULL; done: wbcFreeMemory(i); return wbc_status; }