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; }
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); }
wbcErr wb_is_trusted_domain(const char *domain) { wbcErr result; struct wbcDomainInfo *info = NULL; result = wbcDomainInfo(domain, &info); if (WBC_ERROR_IS_OK(result)) { wbcFreeMemory(info); } return result; }
static bool test_wbc_domain_info(struct torture_context *tctx) { struct wbcDomainInfo *info; struct wbcInterfaceDetails *details; torture_assert_wbc_ok(tctx, wbcInterfaceDetails(&details), "wbcInterfaceDetails failed"); torture_assert_wbc_ok( tctx, wbcDomainInfo(details->netbios_domain, &info), "wbcDomainInfo failed"); wbcFreeMemory(details); torture_assert(tctx, info, "wbcDomainInfo returned NULL pointer"); wbcFreeMemory(info); return true; }
static bool wbinfo_domain_info(const char *domain) { wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE; struct wbcDomainInfo *dinfo = NULL; char *sid_str = NULL; 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)) { return false; } wbc_status = wbcSidToString(&dinfo->sid, &sid_str); if (!WBC_ERROR_IS_OK(wbc_status)) { wbcFreeMemory(dinfo); return false; } /* Display response */ d_printf("Name : %s\n", dinfo->short_name); d_printf("Alt_Name : %s\n", dinfo->dns_name); d_printf("SID : %s\n", sid_str); d_printf("Active Directory : %s\n", (dinfo->domain_flags & WBC_DOMINFO_DOMAIN_AD) ? "Yes" : "No"); d_printf("Native : %s\n", (dinfo->domain_flags & WBC_DOMINFO_DOMAIN_NATIVE) ? "Yes" : "No"); d_printf("Primary : %s\n", (dinfo->domain_flags & WBC_DOMINFO_DOMAIN_PRIMARY) ? "Yes" : "No"); wbcFreeMemory(sid_str); wbcFreeMemory(dinfo); return true; }
static bool wbinfo_lookuprids(const char *domain, const char *arg) { wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE; struct wbcDomainInfo *dinfo = NULL; char *domain_name = NULL; const char **names = NULL; enum wbcSidType *types = NULL; size_t i; int num_rids; uint32 *rids = NULL; const char *p; char *ridstr; TALLOC_CTX *mem_ctx = NULL; bool ret = false; 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; } mem_ctx = talloc_new(NULL); if (mem_ctx == NULL) { d_printf("talloc_new failed\n"); goto done; } num_rids = 0; rids = NULL; p = arg; while (next_token_talloc(mem_ctx, &p, &ridstr, " ,\n")) { uint32 rid = strtoul(ridstr, NULL, 10); ADD_TO_ARRAY(mem_ctx, uint32, rid, &rids, &num_rids); } if (rids == NULL) { d_printf("no rids\n"); goto done; } wbc_status = wbcLookupRids(&dinfo->sid, num_rids, rids, (const char **)&domain_name, &names, &types); if (!WBC_ERROR_IS_OK(wbc_status)) { d_printf("winbind_lookup_rids failed: %s\n", wbcErrorString(wbc_status)); goto done; } d_printf("Domain: %s\n", domain_name); for (i=0; i<num_rids; i++) { d_printf("%8d: %s (%s)\n", rids[i], names[i], sid_type_lookup(types[i])); } ret = true; done: if (dinfo) { wbcFreeMemory(dinfo); } if (domain_name) { wbcFreeMemory(domain_name); } if (names) { wbcFreeMemory(names); } if (types) { wbcFreeMemory(types); } TALLOC_FREE(mem_ctx); return ret; }
wbcErr wbcInterfaceDetails(struct wbcInterfaceDetails **_details) { wbcErr wbc_status = WBC_ERR_UNKNOWN_FAILURE; struct wbcInterfaceDetails *info; struct wbcDomainInfo *domain = NULL; struct winbindd_request request; struct winbindd_response response; /* Initialize request */ ZERO_STRUCT(request); ZERO_STRUCT(response); info = (struct wbcInterfaceDetails *)wbcAllocateMemory( 1, sizeof(struct wbcInterfaceDetails), wbcInterfaceDetailsDestructor); BAIL_ON_PTR_ERROR(info, wbc_status); /* first the interface version */ wbc_status = wbcRequestResponse(WINBINDD_INTERFACE_VERSION, NULL, &response); BAIL_ON_WBC_ERROR(wbc_status); info->interface_version = response.data.interface_version; /* then the samba version and the winbind separator */ wbc_status = wbcRequestResponse(WINBINDD_INFO, NULL, &response); BAIL_ON_WBC_ERROR(wbc_status); info->winbind_version = strdup(response.data.info.samba_version); BAIL_ON_PTR_ERROR(info->winbind_version, wbc_status); info->winbind_separator = response.data.info.winbind_separator; /* then the local netbios name */ wbc_status = wbcRequestResponse(WINBINDD_NETBIOS_NAME, NULL, &response); BAIL_ON_WBC_ERROR(wbc_status); info->netbios_name = strdup(response.data.netbios_name); BAIL_ON_PTR_ERROR(info->netbios_name, wbc_status); /* then the local workgroup name */ wbc_status = wbcRequestResponse(WINBINDD_DOMAIN_NAME, NULL, &response); BAIL_ON_WBC_ERROR(wbc_status); info->netbios_domain = strdup(response.data.domain_name); BAIL_ON_PTR_ERROR(info->netbios_domain, wbc_status); wbc_status = wbcDomainInfo(info->netbios_domain, &domain); if (wbc_status == WBC_ERR_DOMAIN_NOT_FOUND) { /* maybe it's a standalone server */ domain = NULL; wbc_status = WBC_ERR_SUCCESS; } else { BAIL_ON_WBC_ERROR(wbc_status); } if (domain) { info->dns_domain = strdup(domain->dns_name); wbcFreeMemory(domain); BAIL_ON_PTR_ERROR(info->dns_domain, wbc_status); } else { info->dns_domain = NULL; } *_details = info; info = NULL; wbc_status = WBC_ERR_SUCCESS; done: wbcFreeMemory(info); return wbc_status; }
NTSTATUS get_user_from_kerberos_info(TALLOC_CTX *mem_ctx, const char *cli_name, const char *princ_name, struct PAC_LOGON_INFO *logon_info, bool *is_mapped, bool *mapped_to_guest, char **ntuser, char **ntdomain, char **username, struct passwd **_pw) { NTSTATUS status; char *domain = NULL; char *realm = NULL; char *user = NULL; char *p; char *fuser = NULL; char *unixuser = NULL; struct passwd *pw = NULL; DEBUG(3, ("Kerberos ticket principal name is [%s]\n", princ_name)); p = strchr_m(princ_name, '@'); if (!p) { DEBUG(3, ("[%s] Doesn't look like a valid principal\n", princ_name)); return NT_STATUS_LOGON_FAILURE; } user = talloc_strndup(mem_ctx, princ_name, p - princ_name); if (!user) { return NT_STATUS_NO_MEMORY; } realm = talloc_strdup(talloc_tos(), p + 1); if (!realm) { return NT_STATUS_NO_MEMORY; } if (!strequal(realm, lp_realm())) { DEBUG(3, ("Ticket for foreign realm %s@%s\n", user, realm)); if (!lp_allow_trusted_domains()) { return NT_STATUS_LOGON_FAILURE; } } if (logon_info && logon_info->info3.base.domain.string) { domain = talloc_strdup(mem_ctx, logon_info->info3.base.domain.string); if (!domain) { return NT_STATUS_NO_MEMORY; } DEBUG(10, ("Domain is [%s] (using PAC)\n", domain)); } else { /* If we have winbind running, we can (and must) shorten the username by using the short netbios name. Otherwise we will have inconsistent user names. With Kerberos, we get the fully qualified realm, with ntlmssp we get the short name. And even w2k3 does use ntlmssp if you for example connect to an ip address. */ wbcErr wbc_status; struct wbcDomainInfo *info = NULL; DEBUG(10, ("Mapping [%s] to short name using winbindd\n", realm)); wbc_status = wbcDomainInfo(realm, &info); if (WBC_ERROR_IS_OK(wbc_status)) { domain = talloc_strdup(mem_ctx, info->short_name); wbcFreeMemory(info); } else { DEBUG(3, ("Could not find short name: %s\n", wbcErrorString(wbc_status))); domain = talloc_strdup(mem_ctx, realm); } if (!domain) { return NT_STATUS_NO_MEMORY; } DEBUG(10, ("Domain is [%s] (using Winbind)\n", domain)); } fuser = talloc_asprintf(mem_ctx, "%s%c%s", domain, *lp_winbind_separator(), user); if (!fuser) { return NT_STATUS_NO_MEMORY; } *is_mapped = map_username(mem_ctx, fuser, &fuser); if (!fuser) { return NT_STATUS_NO_MEMORY; } pw = smb_getpwnam(mem_ctx, fuser, &unixuser, true); if (pw) { if (!unixuser) { return NT_STATUS_NO_MEMORY; } /* if a real user check pam account restrictions */ /* only really perfomed if "obey pam restriction" is true */ /* do this before an eventual mapping to guest occurs */ status = smb_pam_accountcheck(pw->pw_name, cli_name); if (!NT_STATUS_IS_OK(status)) { DEBUG(1, ("PAM account restrictions prevent user " "[%s] login\n", unixuser)); return status; } } if (!pw) { /* this was originally the behavior of Samba 2.2, if a user did not have a local uid but has been authenticated, then map them to a guest account */ if (lp_map_to_guest() == MAP_TO_GUEST_ON_BAD_UID) { *mapped_to_guest = true; fuser = talloc_strdup(mem_ctx, lp_guestaccount()); if (!fuser) { return NT_STATUS_NO_MEMORY; } pw = smb_getpwnam(mem_ctx, fuser, &unixuser, true); } /* extra sanity check that the guest account is valid */ if (!pw) { DEBUG(1, ("Username %s is invalid on this system\n", fuser)); return NT_STATUS_LOGON_FAILURE; } } if (!unixuser) { return NT_STATUS_NO_MEMORY; } *username = talloc_strdup(mem_ctx, unixuser); if (!*username) { return NT_STATUS_NO_MEMORY; } *ntuser = user; *ntdomain = domain; *_pw = pw; return NT_STATUS_OK; }