/* Editor Settings: expandtabs and use 4 spaces for indentation
* ex: set softtabstop=4 tabstop=8 expandtab shiftwidth=4: *
*/
/*
* Copyright Likewise Software
* All rights reserved.
*
* This library is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2.1 of the license, or (at
* your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser
* General Public License for more details. You should have received a copy
* of the GNU Lesser General Public License along with this program. If
* not, see .
*
* LIKEWISE SOFTWARE MAKES THIS SOFTWARE AVAILABLE UNDER OTHER LICENSING
* TERMS AS WELL. IF YOU HAVE ENTERED INTO A SEPARATE LICENSE AGREEMENT
* WITH LIKEWISE SOFTWARE, THEN YOU MAY ELECT TO USE THE SOFTWARE UNDER THE
* TERMS OF THAT SOFTWARE LICENSE AGREEMENT INSTEAD OF THE TERMS OF THE GNU
* LESSER GENERAL PUBLIC LICENSE, NOTWITHSTANDING THE ABOVE NOTICE. IF YOU
* HAVE QUESTIONS, OR WISH TO REQUEST A COPY OF THE ALTERNATE LICENSING
* TERMS OFFERED BY LIKEWISE SOFTWARE, PLEASE CONTACT LIKEWISE SOFTWARE AT
* license@likewisesoftware.com
*/
//#include
#include "includes.h"
extern int verbose_mode;
#define DISPLAY_DOMAINS(names, num) \
{ \
UINT32 i; \
for (i = 0; i < num; i++) { \
wchar16_t *name = names[i]; \
w16printfw(L"Domain name: [%ws]\n", name); \
} \
}
static
BOOL
CallSamrConnect(
handle_t hBinding,
const wchar16_t *system_name,
CONNECT_HANDLE *phConn
);
static
BOOL
CallSamrClose(
handle_t hBinding,
CONNECT_HANDLE *phConn
);
static
BOOL
CallSamrEnumDomains(
handle_t hBinding,
CONNECT_HANDLE hConn,
PSID *ppDomainSid,
PSID *ppBuiltinSid
);
static
BOOL
CallSamrOpenDomains(
handle_t hBinding,
CONNECT_HANDLE hConn,
PSID pDomainSid,
PSID pBuiltinSid,
DOMAIN_HANDLE *phDomain,
DOMAIN_HANDLE *phBuiltin
);
static
BOOL
CallSamrEnumDomainUsers(
handle_t hBinding,
DOMAIN_HANDLE hDomain
);
static
BOOL
CallSamrEnumDomainAliases(
handle_t hBinding,
DOMAIN_HANDLE hDomain
);
handle_t CreateSamrBinding(handle_t *binding, const wchar16_t *host)
{
RPCSTATUS status = RPC_S_OK;
size_t hostname_size = 0;
char *hostname = NULL;
PIO_CREDS creds = NULL;
if (binding == NULL) return NULL;
if (host)
{
hostname_size = wc16slen(host) + 1;
hostname = (char*) malloc(hostname_size * sizeof(char));
if (hostname == NULL) return NULL;
wc16stombs(hostname, host, hostname_size);
}
if (LwIoGetActiveCreds(NULL, &creds) != STATUS_SUCCESS)
{
return NULL;
}
status = InitSamrBindingDefault(binding, hostname, creds);
if (status != RPC_S_OK) {
int result;
unsigned char errmsg[dce_c_error_string_len];
dce_error_inq_text(status, errmsg, &result);
if (result == 0) {
printf("Error: %s\n", errmsg);
} else {
printf("Unknown error: %08lx\n", (unsigned long int)status);
}
SAFE_FREE(hostname);
return NULL;
}
if (creds) {
LwIoDeleteCreds(creds);
}
SAFE_FREE(hostname);
return *binding;
}
static
void
GetSessionKey(handle_t binding, unsigned char** sess_key,
unsigned16* sess_key_len, unsigned32* st)
{
rpc_transport_info_handle_t info = NULL;
rpc_binding_inq_transport_info(binding, &info, st);
if (*st)
{
goto error;
}
rpc_smb_transport_info_inq_session_key(info, sess_key,
sess_key_len);
cleanup:
return;
error:
*sess_key = NULL;
*sess_key_len = 0;
goto cleanup;
}
/*
Utility function for getting SAM domain name given a hostname
*/
NTSTATUS GetSamDomainName(wchar16_t **domname, const wchar16_t *hostname)
{
const UINT32 conn_access = SAMR_ACCESS_OPEN_DOMAIN |
SAMR_ACCESS_ENUM_DOMAINS;
const UINT32 enum_size = 32;
const char *builtin = "Builtin";
NTSTATUS status = STATUS_SUCCESS;
NTSTATUS ret = STATUS_SUCCESS;
handle_t samr_binding = NULL;
CONNECT_HANDLE hConn = NULL;
UINT32 resume = 0;
UINT32 count = 0;
UINT32 i = 0;
wchar16_t **dom_names = NULL;
if (domname == NULL)
{
status = STATUS_INVALID_PARAMETER;
goto done;
}
samr_binding = CreateSamrBinding(&samr_binding, hostname);
if (samr_binding == NULL) return STATUS_UNSUCCESSFUL;
status = SamrConnect2(samr_binding, hostname, conn_access, &hConn);
if (status != 0) rpc_fail(status);
dom_names = NULL;
do {
status = SamrEnumDomains(samr_binding, hConn, &resume,
enum_size, &dom_names, &count);
if (status != STATUS_SUCCESS &&
status != STATUS_MORE_ENTRIES) rpc_fail(status);
for (i = 0; i < count; i++) {
char n[32] = {0};
wc16stombs(n, dom_names[i], sizeof(n));
if (strcasecmp(n, builtin)) {
*domname = (wchar16_t*) wc16sdup(dom_names[i]);
ret = STATUS_SUCCESS;
SamrFreeMemory((void*)dom_names);
goto found;
}
}
SamrFreeMemory((void*)dom_names);
} while (status == STATUS_MORE_ENTRIES);
*domname = NULL;
ret = STATUS_NOT_FOUND;
found:
status = SamrClose(samr_binding, hConn);
if (status != 0) return status;
done:
FreeSamrBinding(&samr_binding);
return status;
}
/*
Utility function for getting SAM domain SID given a hostname
*/
NTSTATUS GetSamDomainSid(PSID* sid, const wchar16_t *hostname)
{
const UINT32 conn_access = SAMR_ACCESS_OPEN_DOMAIN |
SAMR_ACCESS_ENUM_DOMAINS;
NTSTATUS status = STATUS_SUCCESS;
handle_t samr_b = NULL;
CONNECT_HANDLE hConn = NULL;
wchar16_t *domname = NULL;
PSID out_sid = NULL;
if (sid == NULL)
{
status = STATUS_INVALID_PARAMETER;
goto done;
}
status = GetSamDomainName(&domname, hostname);
if (status != 0) goto done;
samr_b = CreateSamrBinding(&samr_b, hostname);
if (samr_b == NULL) rpc_fail(STATUS_UNSUCCESSFUL);
status = SamrConnect2(samr_b, hostname, conn_access, &hConn);
if (status != 0) rpc_fail(status);
status = SamrLookupDomain(samr_b, hConn, domname, &out_sid);
if (status != 0) rpc_fail(status);
status = SamrClose(samr_b, hConn);
if (status != 0) rpc_fail(status);
/* Allocate a copy of sid so it can be freed clean by the caller */
MsRpcDuplicateSid(sid, out_sid);
done:
FreeSamrBinding(&samr_b);
if (out_sid) {
SamrFreeMemory((void*)out_sid);
}
SAFE_FREE(domname);
return status;
}
NTSTATUS
EnsureUserAccount(
PCWSTR pwszHostname,
PWSTR pwszUsername,
PBOOL pbCreated
)
{
const UINT32 account_flags = ACB_NORMAL;
const UINT32 conn_access = SAMR_ACCESS_OPEN_DOMAIN |
SAMR_ACCESS_ENUM_DOMAINS;
const UINT32 domain_access = DOMAIN_ACCESS_OPEN_ACCOUNT |
DOMAIN_ACCESS_ENUM_ACCOUNTS |
DOMAIN_ACCESS_CREATE_USER |
DOMAIN_ACCESS_LOOKUP_INFO_2;
NTSTATUS status = STATUS_SUCCESS;
PSID sid = NULL;
handle_t samr_b = NULL;
CONNECT_HANDLE hConn = NULL;
DOMAIN_HANDLE hDomain = NULL;
ACCOUNT_HANDLE hUser = NULL;
UINT32 user_rid = 0;
BOOL bCreated = FALSE;
status = GetSamDomainSid(&sid, pwszHostname);
if (status != 0) rpc_fail(status);
CreateSamrBinding(&samr_b, pwszHostname);
if (samr_b == NULL) goto done;
status = SamrConnect2(samr_b, pwszHostname, conn_access, &hConn);
if (status != 0) rpc_fail(status)
status = SamrOpenDomain(samr_b, hConn, domain_access, sid, &hDomain);
if (status != 0) rpc_fail(status);
status = SamrCreateUser(samr_b, hDomain, pwszUsername, account_flags,
&hUser, &user_rid);
if (status == STATUS_SUCCESS)
{
bCreated = TRUE;
status = SamrClose(samr_b, hUser);
if (status != 0) rpc_fail(status);
} else if (status != 0 &&
status != STATUS_USER_EXISTS) rpc_fail(status);
status = SamrClose(samr_b, hDomain);
if (status != 0) rpc_fail(status);
status = SamrClose(samr_b, hConn);
if (status != 0) rpc_fail(status);
if (pbCreated)
{
*pbCreated = bCreated;
}
done:
FreeSamrBinding(&samr_b);
if (sid) MsRpcFreeSid(sid);
return status;
}
NTSTATUS
CleanupAccount(
PCWSTR pwszHostname,
PWSTR pwszUsername
)
{
const UINT32 conn_access = SAMR_ACCESS_OPEN_DOMAIN |
SAMR_ACCESS_ENUM_DOMAINS;
const UINT32 domain_access = DOMAIN_ACCESS_OPEN_ACCOUNT;
const UINT32 user_access = DELETE;
handle_t samr_b = NULL;
NTSTATUS status = STATUS_SUCCESS;
CONNECT_HANDLE hConn = NULL;
DOMAIN_HANDLE hDomain = NULL;
ACCOUNT_HANDLE hAccount = NULL;
PSID sid = NULL;
wchar16_t *names[1] = {0};
UINT32 *rids = NULL;
UINT32 *types = NULL;
UINT32 rids_count = 0;
status = GetSamDomainSid(&sid, pwszHostname);
if (status != 0) rpc_fail(status);
CreateSamrBinding(&samr_b, pwszHostname);
if (samr_b == NULL) rpc_fail(status);
status = SamrConnect2(samr_b, pwszHostname, conn_access, &hConn);
if (status != 0) rpc_fail(status);
status = SamrOpenDomain(samr_b, hConn, domain_access, sid, &hDomain);
if (status != 0) rpc_fail(status);
names[0] = pwszUsername;
status = SamrLookupNames(samr_b, hDomain, 1, names, &rids, &types,
&rids_count);
/* if no account has been found return success */
if (status == STATUS_NONE_MAPPED) {
status = STATUS_SUCCESS;
goto done;
} else if (status != 0) {
rpc_fail(status);
}
status = SamrOpenUser(samr_b, hDomain, user_access, rids[0], &hAccount);
if (status != 0) rpc_fail(status);
status = SamrDeleteUser(samr_b, hAccount);
if (status != 0) rpc_fail(status);
status = SamrClose(samr_b, hDomain);
if (status != 0) rpc_fail(status);
status = SamrClose(samr_b, hConn);
if (status != 0) rpc_fail(status);
FreeSamrBinding(&samr_b);
done:
if (rids) SamrFreeMemory((void*)rids);
if (types) SamrFreeMemory((void*)types);
SAFE_FREE(sid);
return status;
}
NTSTATUS
EnsureAlias(
PCWSTR pwszHostname,
PWSTR pwszAliasname,
PBOOL pbCreated
)
{
const UINT32 conn_access = SAMR_ACCESS_OPEN_DOMAIN |
SAMR_ACCESS_ENUM_DOMAINS;
const UINT32 domain_access = DOMAIN_ACCESS_OPEN_ACCOUNT |
DOMAIN_ACCESS_ENUM_ACCOUNTS |
DOMAIN_ACCESS_CREATE_ALIAS |
DOMAIN_ACCESS_LOOKUP_INFO_2;
const UINT32 alias_access = ALIAS_ACCESS_LOOKUP_INFO |
ALIAS_ACCESS_SET_INFO;
NTSTATUS status = STATUS_SUCCESS;
PSID sid = NULL;
handle_t samr_b = NULL;
CONNECT_HANDLE hConn = NULL;
DOMAIN_HANDLE hDomain = NULL;
ACCOUNT_HANDLE hAlias = NULL;
UINT32 alias_rid = 0;
BOOL bCreated = FALSE;
status = GetSamDomainSid(&sid, pwszHostname);
if (status != 0) rpc_fail(status);
CreateSamrBinding(&samr_b, pwszHostname);
if (samr_b == NULL) goto done;
status = SamrConnect2(samr_b, pwszHostname, conn_access, &hConn);
if (status != 0) rpc_fail(status);
status = SamrOpenDomain(samr_b, hConn, domain_access, sid, &hDomain);
if (status != 0) return status;
status = SamrCreateDomAlias(samr_b, hDomain, pwszAliasname, alias_access,
&hAlias, &alias_rid);
if (status == STATUS_SUCCESS) {
/* Let caller know that new alias have been created */
bCreated = TRUE;
status = SamrClose(samr_b, hAlias);
if (status != 0) rpc_fail(status);
} else if (status != 0 &&
status != STATUS_ALIAS_EXISTS) rpc_fail(status);
status = SamrClose(samr_b, hDomain);
if (status != 0) rpc_fail(status);
status = SamrClose(samr_b, hConn);
if (status != 0) rpc_fail(status);
if (pbCreated)
{
*pbCreated = bCreated;
}
done:
FreeSamrBinding(&samr_b);
if (sid) MsRpcFreeSid(sid);
return status;
}
NTSTATUS
CleanupAlias(
PCWSTR pwszHostname,
PWSTR pwszUsername
)
{
const UINT32 conn_access = SAMR_ACCESS_OPEN_DOMAIN |
SAMR_ACCESS_ENUM_DOMAINS;
const UINT32 domain_access = DOMAIN_ACCESS_OPEN_ACCOUNT;
const UINT32 alias_access = DELETE;
handle_t samr_b = NULL;
NTSTATUS status = STATUS_SUCCESS;
CONNECT_HANDLE hConn = NULL;
DOMAIN_HANDLE hDomain = NULL;
ACCOUNT_HANDLE hAlias = NULL;
PSID sid = NULL;
wchar16_t *names[1] = {0};
UINT32 *rids = NULL;
UINT32 *types = NULL;
UINT32 rids_count = 0;
status = GetSamDomainSid(&sid, pwszHostname);
if (status != 0) rpc_fail(status);
CreateSamrBinding(&samr_b, pwszHostname);
if (samr_b == NULL) goto done;
status = SamrConnect2(samr_b, pwszHostname, conn_access, &hConn);
if (status != 0) rpc_fail(status);
status = SamrOpenDomain(samr_b, hConn, domain_access, sid, &hDomain);
if (status != 0) rpc_fail(status);
names[0] = pwszUsername;
status = SamrLookupNames(samr_b, hDomain, 1, names, &rids, &types,
&rids_count);
/* if no account has been found return success */
if (status == STATUS_NONE_MAPPED) {
status = STATUS_SUCCESS;
goto done;
} else if (status != 0) {
rpc_fail(status)
}
status = SamrOpenAlias(samr_b, hDomain, alias_access, rids[0], &hAlias);
if (status != 0) rpc_fail(status);
status = SamrDeleteDomAlias(samr_b, hAlias);
if (status != 0) rpc_fail(status);
status = SamrClose(samr_b, hDomain);
if (status != 0) rpc_fail(status);
status = SamrClose(samr_b, hConn);
if (status != 0) rpc_fail(status);
FreeSamrBinding(&samr_b);
done:
if (rids) SamrFreeMemory((void*)rids);
if (types) SamrFreeMemory((void*)types);
SAFE_FREE(sid);
return status;
}
static
BOOL
CallSamrConnect(
handle_t hBinding,
const wchar16_t *system_name,
CONNECT_HANDLE *phConn
)
{
BOOL ret = TRUE;
BOOL connected = FALSE;
NTSTATUS status = STATUS_SUCCESS;
UINT32 access_mask = SAMR_ACCESS_OPEN_DOMAIN |
SAMR_ACCESS_ENUM_DOMAINS |
SAMR_ACCESS_CONNECT_TO_SERVER;
UINT32 level_in = 0;
UINT32 level_out = 0;
SamrConnectInfo info_in;
SamrConnectInfo info_out;
CONNECT_HANDLE hConn = NULL;
CONNECT_HANDLE h = NULL;
memset(&info_in, 0, sizeof(info_in));
memset(&info_out, 0, sizeof(info_out));
DISPLAY_COMMENT(("Testing SamrConnect2\n"));
status = SamrConnect2(hBinding, system_name, access_mask, &h);
if (status) {
DISPLAY_ERROR(("SamrConnect2 error %s\n", NtStatusToName(status)));
ret = FALSE;
} else {
connected = TRUE;
hConn = h;
}
DISPLAY_COMMENT(("Testing SamrConnect3\n"));
status = SamrConnect3(hBinding, system_name, access_mask, &h);
if (status) {
DISPLAY_ERROR(("SamrConnect3 error %s\n", NtStatusToName(status)));
ret = FALSE;
} else {
if (connected) {
CallSamrClose(hBinding, &hConn);
}
connected = TRUE;
hConn = h;
}
DISPLAY_COMMENT(("Testing SamrConnect4\n"));
status = SamrConnect4(hBinding, system_name, 0, access_mask, &h);
if (status) {
DISPLAY_ERROR(("SamrConnect4 error %s\n", NtStatusToName(status)));
ret = FALSE;
} else {
if (connected) {
CallSamrClose(hBinding, &hConn);
}
connected = TRUE;
hConn = h;
}
DISPLAY_COMMENT(("Testing SamrConnect5\n"));
level_in = 1;
info_in.info1.client_version = SAMR_CONNECT_POST_WIN2K;
status = SamrConnect5(hBinding, system_name, access_mask, level_in, &info_in,
&level_out, &info_out, &h);
if (status) {
DISPLAY_ERROR(("SamrConnect5 error %s\n", NtStatusToName(status)));
ret = FALSE;
} else {
if (connected) {
CallSamrClose(hBinding, &hConn);
}
connected = TRUE;
hConn = h;
}
*phConn = hConn;
return ret;
}
static
BOOL
CallSamrClose(
handle_t hBinding,
CONNECT_HANDLE *phConn
)
{
BOOL ret = TRUE;
NTSTATUS status = STATUS_SUCCESS;
CONNECT_HANDLE hConn = NULL;
DISPLAY_COMMENT(("Testing SamrClose\n"));
hConn = *phConn;
status = SamrClose(hBinding, hConn);
if (status) {
DISPLAY_ERROR(("SamrClose error %s\n", NtStatusToName(status)));
}
return ret;
}
static
BOOL
CallSamrEnumDomains(
handle_t hBinding,
CONNECT_HANDLE hConn,
PSID *ppDomainSid,
PSID *ppBuiltinSid
)
{
BOOL ret = TRUE;
NTSTATUS status = STATUS_SUCCESS;
UINT32 resume = 0;
UINT32 max_size = 16;
wchar16_t **domains = NULL;
UINT32 num_entries = 0;
UINT32 i = 0;
PSID pSid = NULL;
PSID pDomainSid = NULL;
PSID pBuiltinSid = NULL;
DISPLAY_COMMENT(("Testing SamrEnumDomains with max_size = %d\n", max_size));
do {
status = SamrEnumDomains(hBinding, hConn, &resume, max_size,
&domains, &num_entries);
if (status != STATUS_SUCCESS &&
status != STATUS_MORE_ENTRIES) {
DISPLAY_ERROR(("SamrEnumDomains error %s\n", NtStatusToName(status)));
} else {
DISPLAY_DOMAINS(domains, num_entries);
if (domains) {
SamrFreeMemory((void*)domains);
}
}
} while (status == STATUS_MORE_ENTRIES);
resume = 0;
max_size *= 2;
DISPLAY_COMMENT(("Testing SamrEnumDomains with max_size = %d\n", max_size));
do {
status = SamrEnumDomains(hBinding, hConn, &resume, max_size,
&domains, &num_entries);
if (status != STATUS_SUCCESS &&
status != STATUS_MORE_ENTRIES) {
DISPLAY_ERROR(("SamrEnumDomains error %s\n", NtStatusToName(status)));
} else {
DISPLAY_DOMAINS(domains, num_entries);
if (domains) {
SamrFreeMemory((void*)domains);
}
}
} while (status == STATUS_MORE_ENTRIES);
resume = 0;
max_size *= 2;
DISPLAY_COMMENT(("Testing SamrEnumDomains with max_size = %d\n", max_size));
do {
status = SamrEnumDomains(hBinding, hConn, &resume, max_size,
&domains, &num_entries);
if (status != STATUS_SUCCESS &&
status != STATUS_MORE_ENTRIES) {
DISPLAY_ERROR(("SamrEnumDomains error %s\n", NtStatusToName(status)));
} else {
DISPLAY_DOMAINS(domains, num_entries);
if (domains) {
SamrFreeMemory((void*)domains);
}
}
} while (status == STATUS_MORE_ENTRIES);
resume = 0;
max_size = (UINT32)(-1);
DISPLAY_COMMENT(("Testing SamrEnumDomains with max_size = %d\n", max_size));
do {
status = SamrEnumDomains(hBinding, hConn, &resume, max_size,
&domains, &num_entries);
if (status != STATUS_SUCCESS &&
status != STATUS_MORE_ENTRIES) {
DISPLAY_ERROR(("SamrEnumDomains error %s\n", NtStatusToName(status)));
ret = FALSE;
} else {
DISPLAY_DOMAINS(domains, num_entries);
for (i = 0; i < num_entries; i++) {
wchar16_t *domain = domains[i];
DISPLAY_COMMENT(("Testing SamrLookupDomain\n"));
status = SamrLookupDomain(hBinding, hConn, domain, &pSid);
if (status) {
DISPLAY_ERROR(("SamrLookupDomain error %s\n",
NtStatusToName(status)));
ret = FALSE;
} else {
if (pSid->SubAuthorityCount > 1) {
DISPLAY_COMMENT(("Found domain SID\n"));
pDomainSid = pSid;
} else {
DISPLAY_COMMENT(("Found builtin domain SID\n"));
pBuiltinSid = pSid;
}
}
}
if (domains) {
SamrFreeMemory((void*)domains);
}
}
} while (status == STATUS_MORE_ENTRIES);
*ppDomainSid = pDomainSid;
*ppBuiltinSid = pBuiltinSid;
return ret;
}
static
BOOL
CallSamrOpenDomains(
handle_t hBinding,
CONNECT_HANDLE hConn,
PSID pDomainSid,
PSID pBuiltinSid,
DOMAIN_HANDLE *phDomain,
DOMAIN_HANDLE *phBuiltin
)
{
BOOL ret = TRUE;
NTSTATUS status = STATUS_SUCCESS;
UINT32 access_mask = DOMAIN_ACCESS_OPEN_ACCOUNT |
DOMAIN_ACCESS_ENUM_ACCOUNTS |
DOMAIN_ACCESS_CREATE_USER |
DOMAIN_ACCESS_CREATE_ALIAS |
DOMAIN_ACCESS_LOOKUP_INFO_2 |
DOMAIN_ACCESS_LOOKUP_INFO_1;
DOMAIN_HANDLE hDomain = NULL;
DOMAIN_HANDLE hBuiltin = NULL;
DomainInfo *pInfo = NULL;
UINT16 i = 0;
if (pDomainSid) {
DISPLAY_COMMENT(("Testing SamrOpenDomain\n"));
status = SamrOpenDomain(hBinding, hConn, access_mask, pDomainSid,
&hDomain);
if (status) {
DISPLAY_ERROR(("SamrOpenDomain error %s\n", NtStatusToName(status)));
ret = FALSE;
} else {
for (i = 1; i <= 13; i++) {
if (i == 10)
{
/* domain info level 10 doesn't exist */
continue;
}
DISPLAY_COMMENT(("Testing SamrQueryDomainInfo (level=%d)\n", i));
status = SamrQueryDomainInfo(hBinding, hDomain, i, &pInfo);
if (status) {
DISPLAY_ERROR(("SamrQueryDomainInfo error %s\n", NtStatusToName(status)));
ret = FALSE;
}
if (pInfo)
{
SamrFreeMemory(pInfo);
}
}
}
} else {
DISPLAY_COMMENT(("Domain skipped\n"));
}
if (pBuiltinSid) {
DISPLAY_COMMENT(("Testing SamrOpenDomain\n"));
status = SamrOpenDomain(hBinding, hConn, access_mask, pBuiltinSid,
&hBuiltin);
if (status) {
DISPLAY_ERROR(("SamrOpenDomain error %s\n", NtStatusToName(status)));
ret = FALSE;
} else {
for (i = 1; i <= 13; i++) {
if (i == 10)
{
/* domain info level 10 doesn't exist */
continue;
}
DISPLAY_COMMENT(("Testing SamrQueryDomainInfo (level=%d)\n", i));
status = SamrQueryDomainInfo(hBinding, hBuiltin, i, &pInfo);
if (status) {
DISPLAY_ERROR(("SamrQueryDomainInfo error %s\n", NtStatusToName(status)));
ret = FALSE;
}
if (pInfo)
{
SamrFreeMemory(pInfo);
}
}
}
} else {
DISPLAY_COMMENT(("Builtin domain skipped\n"));
}
*phDomain = hDomain;
*phBuiltin = hBuiltin;
return ret;
}
#define DISPLAY_USERS(names, num) \
{ \
UINT32 i; \
for (i = 0; i < num; i++) { \
wchar16_t *name = names[i]; \
w16printfw(L"User name: [%ws]\n", name); \
} \
}
static
BOOL
CallSamrEnumDomainUsers(
handle_t hBinding,
DOMAIN_HANDLE hDomain
)
{
BOOL ret = TRUE;
NTSTATUS status = STATUS_SUCCESS;
UINT32 resume = 0;
UINT32 max_size = 16;
UINT32 account_flags = 0;
wchar16_t **users = NULL;
UINT32 *rids = NULL;
UINT32 *types = NULL;
UINT32 num_entries = 0;
UINT32 rids_count = 0;
UINT32 i = 0;
wchar16_t *names[2];
DISPLAY_COMMENT(("Testing SamrEnumDomainUsers with max_size = %d\n", max_size));
resume = 0;
account_flags = ACB_NORMAL;
do {
status = SamrEnumDomainUsers(hBinding, hDomain, &resume, account_flags,
max_size, &users, &rids, &num_entries);
if (status != STATUS_SUCCESS &&
status != STATUS_MORE_ENTRIES) {
DISPLAY_ERROR(("SamrEnumDomainUsers error %s\n", NtStatusToName(status)));
} else {
DISPLAY_USERS(users, num_entries);
if (users) {
SamrFreeMemory((void*)users);
}
}
} while (status == STATUS_MORE_ENTRIES);
resume = 0;
max_size *= 2;
DISPLAY_COMMENT(("Testing SamrEnumDomainUsers with max_size = %d\n", max_size));
do {
status = SamrEnumDomainUsers(hBinding, hDomain, &resume, account_flags,
max_size, &users, &rids, &num_entries);
if (status != STATUS_SUCCESS &&
status != STATUS_MORE_ENTRIES) {
DISPLAY_ERROR(("SamrEnumDomainUsers error %s\n", NtStatusToName(status)));
} else {
DISPLAY_USERS(users, num_entries);
if (users) {
SamrFreeMemory((void*)users);
}
}
} while (status == STATUS_MORE_ENTRIES);
resume = 0;
max_size *= 2;
DISPLAY_COMMENT(("Testing SamrEnumDomainUsers with max_size = %d\n", max_size));
do {
status = SamrEnumDomainUsers(hBinding, hDomain, &resume, account_flags,
max_size, &users, &rids, &num_entries);
if (status != STATUS_SUCCESS &&
status != STATUS_MORE_ENTRIES) {
DISPLAY_ERROR(("SamrEnumDomainUsers error %s\n", NtStatusToName(status)));
} else {
DISPLAY_USERS(users, num_entries);
if (users) {
SamrFreeMemory((void*)users);
}
}
} while (status == STATUS_MORE_ENTRIES);
resume = 0;
max_size = (UINT32)(-1);
DISPLAY_COMMENT(("Testing SamrEnumDomainUsers with max_size = %d\n", max_size));
do {
status = SamrEnumDomainUsers(hBinding, hDomain, &resume, account_flags,
max_size, &users, &rids, &num_entries);
if (status != STATUS_SUCCESS &&
status != STATUS_MORE_ENTRIES) {
DISPLAY_ERROR(("SamrEnumDomainUsers error %s\n", NtStatusToName(status)));
ret = FALSE;
} else {
DISPLAY_USERS(users, num_entries);
for (i = 0; i < num_entries; i++) {
wchar16_t *user = users[i];
names[0] = user;
names[1] = NULL;
DISPLAY_COMMENT(("Testing SamrLookupNames\n"));
status = SamrLookupNames(hBinding, hDomain, 1, names,
&rids, &types, &rids_count);
if (status) {
DISPLAY_ERROR(("SamrLookupNames error %s\n",
NtStatusToName(status)));
}
if (rids) {
SamrFreeMemory(rids);
}
if (types) {
SamrFreeMemory(types);
}
}
if (users) {
SamrFreeMemory((void*)users);
}
}
} while (status == STATUS_MORE_ENTRIES);
return ret;
}
static
BOOL
CallSamrEnumDomainAliases(
handle_t hBinding,
DOMAIN_HANDLE hDomain
)
{
BOOL ret = TRUE;
NTSTATUS status = STATUS_SUCCESS;
UINT32 resume = 0;
UINT32 account_flags = 0;
wchar16_t **aliases = NULL;
UINT32 *rids = NULL;
UINT32 *types = NULL;
UINT32 num_entries = 0;
UINT32 rids_count = 0;
UINT32 i = 0;
wchar16_t *names[2];
resume = 0;
account_flags = ACB_NORMAL;
DISPLAY_COMMENT(("Testing SamrEnumDomainAliases\n"));
do {
status = SamrEnumDomainAliases(hBinding, hDomain, &resume, account_flags,
&aliases, &rids, &num_entries);
if (status != STATUS_SUCCESS &&
status != STATUS_MORE_ENTRIES) {
DISPLAY_ERROR(("SamrEnumDomainAliases error %s\n", NtStatusToName(status)));
ret = FALSE;
} else {
DISPLAY_USERS(aliases, num_entries);
for (i = 0; i < num_entries; i++) {
wchar16_t *alias = aliases[i];
names[0] = alias;
names[1] = NULL;
DISPLAY_COMMENT(("Testing SamrLookupNames\n"));
status = SamrLookupNames(hBinding, hDomain, 1, names,
&rids, &types, &rids_count);
if (status) {
DISPLAY_ERROR(("SamrLookupNames error %s\n",
NtStatusToName(status)));
}
if (rids) {
SamrFreeMemory(rids);
}
if (types) {
SamrFreeMemory(types);
}
}
if (aliases) {
SamrFreeMemory((void*)aliases);
}
}
} while (status == STATUS_MORE_ENTRIES);
return ret;
}
int
TestSamrConnect(struct test *t, const wchar16_t *hostname,
const wchar16_t *user, const wchar16_t *pass,
struct parameter *options, int optcount)
{
PCSTR pszDefSysName = NULL;
BOOL ret = TRUE;
enum param_err perr = perr_success;
handle_t hBinding = NULL;
CONNECT_HANDLE hConn = NULL;
PWSTR pwszSysName = NULL;
perr = fetch_value(options, optcount, "systemname", pt_w16string,
&pwszSysName, &pszDefSysName);
if (!perr_is_ok(perr)) perr_fail(perr);
TESTINFO(t, hostname, user, pass);
SET_SESSION_CREDS(hCreds);
CreateSamrBinding(&hBinding, hostname);
ret &= CallSamrConnect(hBinding,
pwszSysName,
&hConn);
ret &= CallSamrClose(hBinding,
&hConn);
done:
FreeSamrBinding(&hBinding);
RELEASE_SESSION_CREDS;
SAFE_FREE(pwszSysName);
return (int)ret;
}
int
TestSamrDomains(struct test *t, const wchar16_t *hostname,
const wchar16_t *user, const wchar16_t *pass,
struct parameter *options, int optcount)
{
PCSTR pszDefSysName = "";
BOOL ret = TRUE;
enum param_err perr = perr_success;
handle_t hBinding = NULL;
CONNECT_HANDLE hConn = NULL;
PSID pDomainSid = NULL;
PSID pBuiltinSid = NULL;
PWSTR pwszSysName = NULL;
perr = fetch_value(options, optcount, "systemname", pt_w16string,
&pwszSysName, &pszDefSysName);
if (!perr_is_ok(perr)) perr_fail(perr);
TESTINFO(t, hostname, user, pass);
SET_SESSION_CREDS(hCreds);
CreateSamrBinding(&hBinding, hostname);
ret &= CallSamrConnect(hBinding,
pwszSysName,
&hConn);
ret &= CallSamrEnumDomains(hBinding,
hConn,
&pDomainSid,
&pBuiltinSid);
ret &= CallSamrClose(hBinding,
&hConn);
done:
FreeSamrBinding(&hBinding);
SAFE_FREE(pwszSysName);
return (int)ret;
}
int
TestSamrDomainsQuery(struct test *t, const wchar16_t *hostname,
const wchar16_t *user, const wchar16_t *pass,
struct parameter *options, int optcount)
{
PCSTR pszDefSysName = "";
BOOL ret = TRUE;
enum param_err perr = perr_success;
handle_t hBinding = NULL;
CONNECT_HANDLE hConn = NULL;
PSID pDomainSid = NULL;
PSID pBuiltinSid = NULL;
PWSTR pwszSysName = NULL;
DOMAIN_HANDLE hDomain = NULL;
DOMAIN_HANDLE hBuiltin = NULL;
perr = fetch_value(options, optcount, "systemname", pt_w16string,
&pwszSysName, &pszDefSysName);
if (!perr_is_ok(perr)) perr_fail(perr);
TESTINFO(t, hostname, user, pass);
SET_SESSION_CREDS(hCreds);
CreateSamrBinding(&hBinding, hostname);
ret &= CallSamrConnect(hBinding,
pwszSysName,
&hConn);
ret &= CallSamrEnumDomains(hBinding,
hConn,
&pDomainSid,
&pBuiltinSid);
ret &= CallSamrOpenDomains(hBinding,
hConn,
pDomainSid,
pBuiltinSid,
&hDomain,
&hBuiltin);
ret &= CallSamrClose(hBinding,
&hDomain);
ret &= CallSamrClose(hBinding,
&hBuiltin);
ret &= CallSamrClose(hBinding,
&hConn);
done:
FreeSamrBinding(&hBinding);
SAFE_FREE(pwszSysName);
return (int)ret;
}
int
TestSamrUsers(struct test *t, const wchar16_t *hostname,
const wchar16_t *user, const wchar16_t *pass,
struct parameter *options, int optcount)
{
PCSTR pszDefSysName = "";
BOOL ret = TRUE;
enum param_err perr = perr_success;
handle_t hBinding = NULL;
CONNECT_HANDLE hConn = NULL;
PSID pDomainSid = NULL;
PSID pBuiltinSid = NULL;
PWSTR pwszSysName = NULL;
DOMAIN_HANDLE hDomain = NULL;
DOMAIN_HANDLE hBuiltin = NULL;
perr = fetch_value(options, optcount, "systemname", pt_w16string,
&pwszSysName, &pszDefSysName);
if (!perr_is_ok(perr)) perr_fail(perr);
TESTINFO(t, hostname, user, pass);
SET_SESSION_CREDS(hCreds);
CreateSamrBinding(&hBinding, hostname);
ret &= CallSamrConnect(hBinding,
pwszSysName,
&hConn);
ret &= CallSamrEnumDomains(hBinding,
hConn,
&pDomainSid,
&pBuiltinSid);
ret &= CallSamrOpenDomains(hBinding,
hConn,
pDomainSid,
pBuiltinSid,
&hDomain,
&hBuiltin);
ret &= CallSamrEnumDomainUsers(hBinding,
hDomain);
ret &= CallSamrEnumDomainUsers(hBinding,
hBuiltin);
ret &= CallSamrClose(hBinding,
&hConn);
done:
FreeSamrBinding(&hBinding);
SAFE_FREE(pwszSysName);
return (int)ret;
}
int
TestSamrAliases(struct test *t, const wchar16_t *hostname,
const wchar16_t *user, const wchar16_t *pass,
struct parameter *options, int optcount)
{
PCSTR pszDefSysName = "";
BOOL ret = TRUE;
enum param_err perr = perr_success;
handle_t hBinding = NULL;
CONNECT_HANDLE hConn = NULL;
PSID pDomainSid = NULL;
PSID pBuiltinSid = NULL;
PWSTR pwszSysName = NULL;
DOMAIN_HANDLE hDomain = NULL;
DOMAIN_HANDLE hBuiltin = NULL;
perr = fetch_value(options, optcount, "systemname", pt_w16string,
&pwszSysName, &pszDefSysName);
if (!perr_is_ok(perr)) perr_fail(perr);
TESTINFO(t, hostname, user, pass);
SET_SESSION_CREDS(hCreds);
CreateSamrBinding(&hBinding, hostname);
ret &= CallSamrConnect(hBinding,
pwszSysName,
&hConn);
ret &= CallSamrEnumDomains(hBinding,
hConn,
&pDomainSid,
&pBuiltinSid);
ret &= CallSamrOpenDomains(hBinding,
hConn,
pDomainSid,
pBuiltinSid,
&hDomain,
&hBuiltin);
ret &= CallSamrEnumDomainAliases(hBinding,
&hDomain);
ret &= CallSamrEnumDomainAliases(hBinding,
&hBuiltin);
ret &= CallSamrClose(hBinding,
&hConn);
done:
return (int)ret;
}
int TestSamrQueryUser(struct test *t, const wchar16_t *hostname,
const wchar16_t *user, const wchar16_t *pass,
struct parameter *options, int optcount)
{
const UINT32 conn_access_mask = SAMR_ACCESS_OPEN_DOMAIN |
SAMR_ACCESS_ENUM_DOMAINS |
SAMR_ACCESS_CONNECT_TO_SERVER;
const UINT32 dom_access_mask = DOMAIN_ACCESS_OPEN_ACCOUNT |
DOMAIN_ACCESS_ENUM_ACCOUNTS |
DOMAIN_ACCESS_CREATE_USER |
DOMAIN_ACCESS_CREATE_ALIAS |
DOMAIN_ACCESS_LOOKUP_INFO_2;
const UINT32 usr_access_mask = USER_ACCESS_GET_NAME_ETC |
USER_ACCESS_GET_LOCALE |
USER_ACCESS_GET_LOGONINFO |
USER_ACCESS_GET_ATTRIBUTES |
USER_ACCESS_CHANGE_PASSWORD |
DELETE;
const char *def_guestname = "Guest";
const char *def_domainname = "Builtin";
const int def_level = 0;
NTSTATUS status = STATUS_SUCCESS;
enum param_err perr = perr_success;
handle_t samr_binding = NULL;
int i = 0;
CONNECT_HANDLE hConn = NULL;
DOMAIN_HANDLE hDomain = NULL;
ACCOUNT_HANDLE hUser = NULL;
PSID sid = NULL;
wchar16_t *names[1];
wchar16_t *username = NULL;
wchar16_t *domainname = NULL;
UINT32 *rids = NULL;
UINT32 *types = NULL;
UINT32 rids_count = 0;
UserInfo *info = NULL;
INT32 level = 0;
TESTINFO(t, hostname, user, pass);
SET_SESSION_CREDS(hCreds);
samr_binding = CreateSamrBinding(&samr_binding, hostname);
if (samr_binding == NULL) return -1;
perr = fetch_value(options, optcount, "username", pt_w16string, &username,
&def_guestname);
if (!perr_is_ok(perr)) perr_fail(perr);
perr = fetch_value(options, optcount, "domainname", pt_w16string, &domainname,
&def_domainname);
if (!perr_is_ok(perr)) perr_fail(perr);
perr = fetch_value(options, optcount, "level", pt_int32, &level,
&def_level);
if (!perr_is_ok(perr)) perr_fail(perr);
PARAM_INFO("domainname", pt_w16string, domainname);
PARAM_INFO("username", pt_w16string, username);
PARAM_INFO("level", pt_int32, &level);
names[0] = username;
/*
* Simple user account querying
*/
status = SamrConnect2(samr_binding, hostname, conn_access_mask, &hConn);
if (status != 0) rpc_fail(status);
status = SamrLookupDomain(samr_binding, hConn, domainname, &sid);
if (status != 0) rpc_fail(status);
status = SamrOpenDomain(samr_binding, hConn, dom_access_mask, sid,
&hDomain);
if (status != 0) rpc_fail(status);
status = SamrLookupNames(samr_binding, hDomain, 1, names, &rids, &types,
&rids_count);
if (status != 0) rpc_fail(status);
status = SamrOpenUser(samr_binding, hDomain, usr_access_mask, rids[0],
&hUser);
if (status != 0) rpc_fail(status);
SamrFreeMemory((void*)rids);
SamrFreeMemory((void*)types);
if (level == 0) {
for (i = 1; i < 26; i++) {
if (i == 5) continue; /* infolevel 5 is still broken for some reason */
INPUT_ARG_PTR(samr_binding);
INPUT_ARG_PTR(hUser);
INPUT_ARG_UINT(i);
CALL_MSRPC(status = SamrQueryUserInfo(samr_binding, hUser,
(UINT16)i, &info));
if (status != STATUS_SUCCESS &&
status != STATUS_INVALID_INFO_CLASS) rpc_fail(status);
SamrFreeMemory((void*)info);
info = NULL;
}
} else {
INPUT_ARG_PTR(samr_binding);
INPUT_ARG_PTR(hUser);
INPUT_ARG_UINT(level);
CALL_MSRPC(status = SamrQueryUserInfo(samr_binding, hUser,
(UINT16)level, &info));
if (status != STATUS_SUCCESS &&
status != STATUS_INVALID_INFO_CLASS) rpc_fail(status);
SamrFreeMemory((void*)info);
info = NULL;
}
status = SamrClose(samr_binding, hUser);
if (status != 0) rpc_fail(status);
status = SamrClose(samr_binding, hDomain);
if (status != 0) rpc_fail(status);
status = SamrClose(samr_binding, hConn);
if (status != 0) rpc_fail(status);
RELEASE_SESSION_CREDS;
done:
SAFE_FREE(username);
SAFE_FREE(domainname);
SamrDestroyMemory();
return (status == STATUS_SUCCESS);
}
#define DISPLAY_ALIAS_INFO(info, level) \
if (verbose_mode ) { \
switch ((level)) { \
case 1: \
OUTPUT_ARG_UNICODE_STRING(&(info)->all.name); \
OUTPUT_ARG_UNICODE_STRING(&(info)->all.description); \
OUTPUT_ARG_UINT((info)->all.num_members); \
break; \
\
case 2: \
OUTPUT_ARG_UNICODE_STRING(&(info)->name); \
break; \
\
case 3: \
OUTPUT_ARG_UNICODE_STRING(&(info)->description); \
break; \
} \
}
int TestSamrQueryAlias(struct test *t, const wchar16_t *hostname,
const wchar16_t *user, const wchar16_t *pass,
struct parameter *options, int optcount)
{
const UINT32 conn_access_mask = SAMR_ACCESS_OPEN_DOMAIN |
SAMR_ACCESS_ENUM_DOMAINS |
SAMR_ACCESS_CONNECT_TO_SERVER;
const UINT32 dom_access_mask = DOMAIN_ACCESS_OPEN_ACCOUNT |
DOMAIN_ACCESS_ENUM_ACCOUNTS |
DOMAIN_ACCESS_CREATE_USER |
DOMAIN_ACCESS_CREATE_ALIAS |
DOMAIN_ACCESS_LOOKUP_INFO_2;
const UINT32 alias_access_mask = ALIAS_ACCESS_GET_MEMBERS |
ALIAS_ACCESS_LOOKUP_INFO;
const char *def_guestsname = "Guests";
const char *def_domainname = "Builtin";
const int def_level = 0;
NTSTATUS status = STATUS_SUCCESS;
enum param_err perr = perr_success;
handle_t samr_binding = NULL;
int i = 0;
CONNECT_HANDLE hConn = NULL;
DOMAIN_HANDLE hDomain = NULL;
ACCOUNT_HANDLE hAlias = NULL;
PSID sid = NULL;
wchar16_t *names[1];
wchar16_t *aliasname = NULL;
wchar16_t *domainname = NULL;
UINT32 *rids = NULL;
UINT32 *types = NULL;
UINT32 rids_count = 0;
AliasInfo *info = NULL;
INT32 level = 0;
TESTINFO(t, hostname, user, pass);
SET_SESSION_CREDS(hCreds);
samr_binding = CreateSamrBinding(&samr_binding, hostname);
if (samr_binding == NULL) return -1;
perr = fetch_value(options, optcount, "aliasname", pt_w16string, &aliasname,
&def_guestsname);
if (!perr_is_ok(perr)) perr_fail(perr);
perr = fetch_value(options, optcount, "domainname", pt_w16string, &domainname,
&def_domainname);
if (!perr_is_ok(perr)) perr_fail(perr);
perr = fetch_value(options, optcount, "level", pt_int32, &level,
&def_level);
if (!perr_is_ok(perr)) perr_fail(perr);
PARAM_INFO("domainname", pt_w16string, domainname);
PARAM_INFO("aliasname", pt_w16string, aliasname);
PARAM_INFO("level", pt_int32, &level);
names[0] = aliasname;
/*
* Simple alias account querying
*/
status = SamrConnect2(samr_binding, hostname, conn_access_mask, &hConn);
if (status != 0) rpc_fail(status);
status = SamrLookupDomain(samr_binding, hConn, domainname, &sid);
if (status != 0) rpc_fail(status);
status = SamrOpenDomain(samr_binding, hConn, dom_access_mask, sid,
&hDomain);
if (status != 0) rpc_fail(status);
status = SamrLookupNames(samr_binding, hDomain, 1, names, &rids, &types,
&rids_count);
if (status != 0) rpc_fail(status);
status = SamrOpenAlias(samr_binding, hDomain, alias_access_mask, rids[0],
&hAlias);
if (status != 0) rpc_fail(status);
SamrFreeMemory((void*)rids);
SamrFreeMemory((void*)types);
if (level == 0) {
for (i = 1; i <= 3; i++) {
INPUT_ARG_PTR(samr_binding);
INPUT_ARG_PTR(hAlias);
INPUT_ARG_UINT(i);
CALL_MSRPC(status = SamrQueryAliasInfo(samr_binding, hAlias,
(UINT16)i, &info));
if (status != STATUS_SUCCESS &&
status != STATUS_INVALID_INFO_CLASS) rpc_fail(status);
DISPLAY_ALIAS_INFO(info, i);
SamrFreeMemory((void*)info);
info = NULL;
}
} else {
INPUT_ARG_PTR(samr_binding);
INPUT_ARG_PTR(hAlias);
INPUT_ARG_UINT(level);
CALL_MSRPC(status = SamrQueryAliasInfo(samr_binding, hAlias,
(UINT16)level, &info));
if (status != STATUS_SUCCESS &&
status != STATUS_INVALID_INFO_CLASS) rpc_fail(status);
DISPLAY_ALIAS_INFO(info, i);
SamrFreeMemory((void*)info);
info = NULL;
}
status = SamrClose(samr_binding, hAlias);
if (status != 0) rpc_fail(status);
status = SamrClose(samr_binding, hDomain);
if (status != 0) rpc_fail(status);
status = SamrClose(samr_binding, hConn);
if (status != 0) rpc_fail(status);
RELEASE_SESSION_CREDS;
done:
SAFE_FREE(aliasname);
SamrDestroyMemory();
return (status == STATUS_SUCCESS);
}
int TestSamrAlias(struct test *t, const wchar16_t *hostname,
const wchar16_t *user, const wchar16_t *pass,
struct parameter *options, int optcount)
{
const UINT32 conn_access_mask = SAMR_ACCESS_OPEN_DOMAIN |
SAMR_ACCESS_ENUM_DOMAINS |
SAMR_ACCESS_CONNECT_TO_SERVER;
const UINT32 dom_access_mask = DOMAIN_ACCESS_OPEN_ACCOUNT |
DOMAIN_ACCESS_ENUM_ACCOUNTS |
DOMAIN_ACCESS_CREATE_USER |
DOMAIN_ACCESS_CREATE_ALIAS |
DOMAIN_ACCESS_LOOKUP_INFO_2;
const UINT32 alias_access_mask = ALIAS_ACCESS_LOOKUP_INFO |
ALIAS_ACCESS_SET_INFO |
ALIAS_ACCESS_ADD_MEMBER |
ALIAS_ACCESS_REMOVE_MEMBER |
ALIAS_ACCESS_GET_MEMBERS |
DELETE;
const char *testalias = "TestAlias";
const char *testuser = "TestUser";
const char *testalias_desc = "TestAlias Comment";
NTSTATUS status = STATUS_SUCCESS;
enum param_err perr = perr_success;
handle_t samr_binding = NULL;
UINT32 user_rid = 0;
UINT32 *rids = NULL;
UINT32 *types = NULL;
UINT32 num_rids = 0;
wchar16_t *aliasname = NULL;
wchar16_t *aliasdesc = NULL;
wchar16_t *username = NULL;
wchar16_t *domname = NULL;
int i = 0;
UINT32 rids_count = 0;
CONNECT_HANDLE hConn = NULL;
DOMAIN_HANDLE hDomain = NULL;
ACCOUNT_HANDLE hAlias = NULL;
ACCOUNT_HANDLE hUser = NULL;
wchar16_t *names[1] = {0};
PSID sid = NULL;
PSID user_sid = NULL;
AliasInfo *aliasinfo = NULL;
AliasInfo setaliasinfo;
PSID* member_sids = NULL;
UINT32 members_num = 0;
BOOL bAliasCreated = FALSE;
BOOL bUserCreated = FALSE;
TESTINFO(t, hostname, user, pass);
SET_SESSION_CREDS(hCreds);
samr_binding = CreateSamrBinding(&samr_binding, hostname);
if (samr_binding == NULL) return false;
perr = fetch_value(options, optcount, "aliasname", pt_w16string, &aliasname, &testalias);
if (!perr_is_ok(perr)) perr_fail(perr);
perr = fetch_value(options, optcount, "aliasdesc", pt_w16string, &aliasdesc, &testalias_desc);
if (!perr_is_ok(perr)) perr_fail(perr);
perr = fetch_value(options, optcount, "username", pt_w16string, &username, &testuser);
if (!perr_is_ok(perr)) perr_fail(perr);
PARAM_INFO("aliasname", pt_w16string, aliasname);
PARAM_INFO("aliasdesc", pt_w16string, aliasdesc);
PARAM_INFO("username", pt_w16string, username);
/*
* Creating and querying/setting alias (in the host domain)
*/
status = SamrConnect2(samr_binding, hostname, conn_access_mask, &hConn);
if (status != 0) rpc_fail(status);
status = GetSamDomainName(&domname, hostname);
if (status != 0) rpc_fail(status);
status = SamrLookupDomain(samr_binding, hConn, domname, &sid);
if (status != 0) rpc_fail(status);
status = SamrOpenDomain(samr_binding, hConn, dom_access_mask, sid,
&hDomain);
if (status != 0) rpc_fail(status);
/*
* Ensure alias to perform tests on
*/
status = EnsureAlias(hostname, aliasname, &bAliasCreated);
if (status != 0) rpc_fail(status);
names[0] = aliasname;
status = SamrLookupNames(samr_binding, hDomain, 1, names,
&rids, &types, &rids_count);
if (status != 0) rpc_fail(status);
if (rids_count == 0 || rids_count != 1) {
printf("Incosistency found when looking for alias name\n");
rpc_fail(STATUS_UNSUCCESSFUL);
}
status = SamrOpenAlias(samr_binding, hDomain, alias_access_mask,
rids[0], &hAlias);
if (status != 0) rpc_fail(status);
if (rids) SamrFreeMemory((void*)rids);
if (types) SamrFreeMemory((void*)types);
rids = NULL;
types = NULL;
/*
* Ensure a user account which will soon become alias member
*/
status = EnsureUserAccount(hostname, username, &bUserCreated);
if (status != 0) rpc_fail(status);
names[0] = username;
status = SamrLookupNames(samr_binding, hDomain, 1, names, &rids, &types,
&rids_count);
if (status != 0) rpc_fail(status);
if (rids_count == 0 || rids_count != 1) {
printf("Incosistency found when looking for alias name\n");
rpc_fail(STATUS_UNSUCCESSFUL);
}
user_rid = rids[0];
if (rids) SamrFreeMemory((void*)rids);
if (types) SamrFreeMemory((void*)types);
rids = NULL;
types = NULL;
for (i = 3; i > 1; i--) {
INPUT_ARG_PTR(samr_binding);
INPUT_ARG_PTR(hAlias);
INPUT_ARG_UINT(i);
CALL_MSRPC(status = SamrQueryAliasInfo(samr_binding, hAlias,
(UINT16)i, &aliasinfo));
if (status != 0) rpc_fail(status);
if (aliasinfo) SamrFreeMemory((void*)aliasinfo);
}
status = SamrQueryAliasInfo(samr_binding, hAlias, 1, &aliasinfo);
if (status != 0) rpc_fail(status);
status = InitUnicodeString(&setaliasinfo.description, aliasdesc);
if (status != 0) rpc_fail(status);
status = SamrSetAliasInfo(samr_binding, hAlias, 3, &setaliasinfo);
if (status != 0) rpc_fail(status);
status = MsRpcAllocateSidAppendRid(&user_sid, sid, user_rid);
if (status != 0) rpc_fail(status);
status = SamrGetAliasMembership(samr_binding, hDomain, &user_sid, 1,
&rids, &num_rids);
if (status != 0) rpc_fail(status);
/*
* Adding, deleting and querying members in alias
*/
status = SamrAddAliasMember(samr_binding, hAlias, user_sid);
if (status != 0) rpc_fail(status);
status = SamrGetMembersInAlias(samr_binding, hAlias, &member_sids,
&members_num);
if (status != 0) rpc_fail(status);
status = SamrDeleteAliasMember(samr_binding, hAlias, user_sid);
if (status != 0) rpc_fail(status);
/*
* Cleanup
*/
if (bAliasCreated) {
status = SamrDeleteDomAlias(samr_binding, hAlias);
if (status != 0) rpc_fail(status);
} else {
status = SamrClose(samr_binding, hAlias);
if (status != 0) rpc_fail(status);
}
if (bUserCreated) {
status = SamrDeleteUser(samr_binding, hUser);
if (status != 0) rpc_fail(status);
}
status = SamrClose(samr_binding, hDomain);
if (status != 0) rpc_fail(status);
status = SamrClose(samr_binding, hConn);
if (status != 0) rpc_fail(status);
FreeSamrBinding(&samr_binding);
RELEASE_SESSION_CREDS;
done:
if (aliasinfo) SamrFreeMemory((void*)aliasinfo);
if (rids) SamrFreeMemory((void*)rids);
if (member_sids) SamrFreeMemory((void*)member_sids);
if (domname) SamrFreeMemory((void*)domname);
if (rids) SamrFreeMemory((void*)rids);
if (types) SamrFreeMemory((void*)types);
FreeUnicodeString(&setaliasinfo.description);
if (user_sid) MsRpcFreeSid(user_sid);
SAFE_FREE(aliasname);
SAFE_FREE(aliasdesc);
SAFE_FREE(username);
return (status == STATUS_SUCCESS);
}
int TestSamrUsersInAliases(struct test *t, const wchar16_t *hostname,
const wchar16_t *user, const wchar16_t *pass,
struct parameter *options, int optcount)
{
const UINT32 conn_access_mask = SAMR_ACCESS_OPEN_DOMAIN |
SAMR_ACCESS_ENUM_DOMAINS |
SAMR_ACCESS_CONNECT_TO_SERVER;
const UINT32 builtin_dom_access_mask = DOMAIN_ACCESS_OPEN_ACCOUNT |
DOMAIN_ACCESS_ENUM_ACCOUNTS |
DOMAIN_ACCESS_LOOKUP_INFO_2;
const char *btin_sidstr = "S-1-5-32";
NTSTATUS status = STATUS_SUCCESS;
enum param_err perr = perr_success;
handle_t samr_binding = NULL;
CONNECT_HANDLE hConn = NULL;
DOMAIN_HANDLE hBtinDomain = NULL;
char *sidstr = NULL;
PSID sid = NULL;
DomainInfo *dominfo = NULL;
TESTINFO(t, hostname, user, pass);
SET_SESSION_CREDS(hCreds);
samr_binding = CreateSamrBinding(&samr_binding, hostname);
if (samr_binding == NULL) return false;
/*
* Querying user membership in aliases
*/
perr = fetch_value(options, optcount, "sid", pt_string, &sidstr,
&btin_sidstr);
if (!perr_is_ok(perr)) perr_fail(perr);
RtlAllocateSidFromCString(&sid, sidstr);
status = SamrConnect2(samr_binding, hostname, conn_access_mask,
&hConn);
if (status != 0) rpc_fail(status);
status = SamrOpenDomain(samr_binding, hConn, builtin_dom_access_mask,
sid, &hBtinDomain);
if (status == 0) {
UINT32 acct_flags = ACB_NORMAL;
UINT32 resume = 0;
wchar16_t **names = NULL;
UINT32 *rids = NULL;
UINT32 num_entries = 0;
UINT32 i = 0;
PSID alias_sid = NULL;
do {
status = SamrEnumDomainAliases(samr_binding, hBtinDomain,
&resume, acct_flags, &names, &rids,
&num_entries);
for (i = 0; i < num_entries; i++) {
UINT32 *member_rids = NULL;
UINT32 count = 0;
status = MsRpcAllocateSidAppendRid(&alias_sid,
sid,
rids[i]);
/* there's actually no need to check status code here */
status = SamrGetAliasMembership(samr_binding,
hBtinDomain,
&alias_sid, 1, &member_rids,
&count);
SAFE_FREE(alias_sid);
if (member_rids) SamrFreeMemory((void*)member_rids);
}
if (names) SamrFreeMemory((void*)names);
if (rids) SamrFreeMemory((void*)rids);
names = NULL;
rids = NULL;
} while (status == STATUS_MORE_ENTRIES);
status = SamrQueryDomainInfo(samr_binding, hBtinDomain,
(UINT16)2, &dominfo);
status = SamrClose(samr_binding, hBtinDomain);
}
status = SamrClose(samr_binding, hConn);
if (status != 0) rpc_fail(status);
FreeSamrBinding(&samr_binding);
RELEASE_SESSION_CREDS;
done:
RTL_FREE(&sid);
SAFE_FREE(sidstr);
return (status == STATUS_SUCCESS);
}
int TestSamrOpenDomain(struct test *t, const wchar16_t *hostname,
const wchar16_t *user, const wchar16_t *pass,
struct parameter *options, int optcount)
{
const UINT32 conn_access_mask = SAMR_ACCESS_OPEN_DOMAIN |
SAMR_ACCESS_ENUM_DOMAINS |
SAMR_ACCESS_CONNECT_TO_SERVER;
const UINT32 dom_access_mask = DOMAIN_ACCESS_OPEN_ACCOUNT |
DOMAIN_ACCESS_ENUM_ACCOUNTS |
DOMAIN_ACCESS_CREATE_USER |
DOMAIN_ACCESS_CREATE_ALIAS |
DOMAIN_ACCESS_LOOKUP_INFO_2 |
DOMAIN_ACCESS_LOOKUP_INFO_1;
const char *def_domainname = "BUILTIN";
NTSTATUS status = STATUS_SUCCESS;
enum param_err perr = perr_success;
handle_t samr_binding = NULL;
CONNECT_HANDLE hConn = NULL;
DOMAIN_HANDLE hDomain = NULL;
PSID sid = NULL;
wchar16_t *domainname = NULL;
SET_SESSION_CREDS(hCreds);
perr = fetch_value(options, optcount, "domainname", pt_w16string,
&domainname, &def_domainname);
if (!perr_is_ok(perr)) perr_fail(perr);
samr_binding = CreateSamrBinding(&samr_binding, hostname);
if (samr_binding == NULL) return false;
status = SamrConnect2(samr_binding, hostname, conn_access_mask,
&hConn);
if (status != 0) rpc_fail(status);
status = SamrLookupDomain(samr_binding, hConn, domainname, &sid);
if (status != 0) rpc_fail(status);
status = SamrOpenDomain(samr_binding, hConn, dom_access_mask,
sid, &hDomain);
if (status != 0) rpc_fail(status);
status = SamrClose(samr_binding, hDomain);
if (status != 0) rpc_fail(status);
status = SamrClose(samr_binding, hConn);
if (status != 0) rpc_fail(status);
FreeSamrBinding(&samr_binding);
RELEASE_SESSION_CREDS;
done:
if (sid) SamrFreeMemory((void*)sid);
SAFE_FREE(domainname);
return (status == STATUS_SUCCESS);
}
int TestSamrQueryDomain(struct test *t, const wchar16_t *hostname,
const wchar16_t *user, const wchar16_t *pass,
struct parameter *options, int optcount)
{
const UINT32 conn_access_mask = SAMR_ACCESS_OPEN_DOMAIN |
SAMR_ACCESS_ENUM_DOMAINS |
SAMR_ACCESS_CONNECT_TO_SERVER;
const UINT32 dom_access_mask = DOMAIN_ACCESS_OPEN_ACCOUNT |
DOMAIN_ACCESS_ENUM_ACCOUNTS |
DOMAIN_ACCESS_CREATE_USER |
DOMAIN_ACCESS_CREATE_ALIAS |
DOMAIN_ACCESS_LOOKUP_INFO_2 |
DOMAIN_ACCESS_LOOKUP_INFO_1;
NTSTATUS status = STATUS_SUCCESS;
handle_t samr_binding = NULL;
int i = 0;
CONNECT_HANDLE hConn = NULL;
DOMAIN_HANDLE hDomain = NULL;
PSID sid = NULL;
DomainInfo *dominfo = NULL;
wchar16_t *domname = NULL;
SET_SESSION_CREDS(hCreds);
samr_binding = CreateSamrBinding(&samr_binding, hostname);
if (samr_binding == NULL) return false;
status = SamrConnect2(samr_binding, hostname, conn_access_mask,
&hConn);
if (status != 0) rpc_fail(status);
status = GetSamDomainName(&domname, hostname);
if (status != 0) rpc_fail(status);
status = SamrLookupDomain(samr_binding, hConn, domname, &sid);
if (status != 0) rpc_fail(status);
status = SamrOpenDomain(samr_binding, hConn, dom_access_mask,
sid, &hDomain);
if (status != 0) rpc_fail(status);
for (i = 1; i < 13; i++) {
if (i == 10) continue;
INPUT_ARG_PTR(samr_binding);
INPUT_ARG_PTR(hDomain);
INPUT_ARG_INT(i);
INPUT_ARG_PTR(dominfo);
CALL_MSRPC(status = SamrQueryDomainInfo(samr_binding, hDomain,
(UINT16)i, &dominfo));
OUTPUT_ARG_PTR(dominfo);
if (dominfo) {
SamrFreeMemory((void*)dominfo);
}
}
status = SamrClose(samr_binding, hDomain);
if (status != 0) rpc_fail(status);
status = SamrClose(samr_binding, hConn);
if (status != 0) rpc_fail(status);
FreeSamrBinding(&samr_binding);
RELEASE_SESSION_CREDS;
done:
if (sid) SamrFreeMemory((void*)sid);
SAFE_FREE(domname);
return (status == STATUS_SUCCESS);
}
#define DISPLAY_ACCOUNTS(type, flags, names, rids, num) \
{ \
UINT32 i; \
for (i = 0; i < num; i++) { \
wchar16_t *name = enum_names[i]; \
UINT32 rid = enum_rids[i]; \
\
w16printfw(L"%hhs (flags=0x%08x): %ws (rid=0x%x)\n",\
(type), (flags), (name), (rid)); \
} \
}
int TestSamrEnumUsers(struct test *t, const wchar16_t *hostname,
const wchar16_t *user, const wchar16_t *pass,
struct parameter *options, int optcount)
{
const UINT32 conn_access_mask = SAMR_ACCESS_OPEN_DOMAIN |
SAMR_ACCESS_ENUM_DOMAINS |
SAMR_ACCESS_CONNECT_TO_SERVER;
const UINT32 dom_access_mask = DOMAIN_ACCESS_OPEN_ACCOUNT |
DOMAIN_ACCESS_ENUM_ACCOUNTS |
DOMAIN_ACCESS_CREATE_USER |
DOMAIN_ACCESS_CREATE_ALIAS |
DOMAIN_ACCESS_LOOKUP_INFO_2;
const int def_specifydomain = 0;
const char *def_domainname = "BUILTIN";
const int def_acb_flags = 0;
NTSTATUS status = STATUS_SUCCESS;
handle_t samr_binding = NULL;
enum param_err perr = perr_success;
UINT32 resume = 0;
UINT32 num_entries = 0;
UINT32 max_size = 0;
UINT32 acb_flags = 0;
UINT32 account_flags = 0;
wchar16_t **enum_names = NULL;
wchar16_t *domname = NULL;
wchar16_t *domainname = NULL;
UINT32 *enum_rids = NULL;
CONNECT_HANDLE hConn = NULL;
DOMAIN_HANDLE hDomain = NULL;
PSID sid = NULL;
int specifydomain = 0;
perr = fetch_value(options, optcount, "specifydomain", pt_int32,
&specifydomain, &def_specifydomain);
if (!perr_is_ok(perr)) perr_fail(perr);
perr = fetch_value(options, optcount, "domainname", pt_w16string,
&domainname, &def_domainname);
if (!perr_is_ok(perr)) perr_fail(perr);
perr = fetch_value(options, optcount, "acbflags", pt_uint32,
&acb_flags, &def_acb_flags);
if (!perr_is_ok(perr)) perr_fail(perr);
SET_SESSION_CREDS(hCreds);
samr_binding = CreateSamrBinding(&samr_binding, hostname);
if (samr_binding == NULL) return false;
status = SamrConnect2(samr_binding, hostname, conn_access_mask,
&hConn);
if (status != 0) rpc_fail(status);
if (specifydomain) {
domname = wc16sdup(domainname);
} else {
status = GetSamDomainName(&domname, hostname);
if (status != 0) rpc_fail(status);
}
status = SamrLookupDomain(samr_binding, hConn, domname, &sid);
if (status != 0) rpc_fail(status);
status = SamrOpenDomain(samr_binding, hConn, dom_access_mask,
sid, &hDomain);
if (status != 0) rpc_fail(status);
/*
* Enumerating domain users
*/
max_size = 128;
resume = 0;
account_flags = ACB_NORMAL;
do {
status = SamrEnumDomainUsers(samr_binding, hDomain, &resume,
account_flags, max_size, &enum_names,
&enum_rids, &num_entries);
if (status == STATUS_SUCCESS ||
status == STATUS_MORE_ENTRIES)
DISPLAY_ACCOUNTS("User", account_flags, enum_names, enum_rids,
num_entries);
if (enum_names) SamrFreeMemory((void*)enum_names);
if (enum_rids) SamrFreeMemory((void*)enum_rids);
} while (status == STATUS_MORE_ENTRIES);
resume = 0;
account_flags = ACB_DOMTRUST;
do {
status = SamrEnumDomainUsers(samr_binding, hDomain, &resume,
account_flags, max_size, &enum_names,
&enum_rids, &num_entries);
if (status == STATUS_SUCCESS ||
status == STATUS_MORE_ENTRIES)
DISPLAY_ACCOUNTS("Domain trust", account_flags, enum_names,
enum_rids, num_entries);
if (enum_names) SamrFreeMemory((void*)enum_names);
if (enum_rids) SamrFreeMemory((void*)enum_rids);
} while (status == STATUS_MORE_ENTRIES);
resume = 0;
account_flags = ACB_WSTRUST;
do {
status = SamrEnumDomainUsers(samr_binding, hDomain, &resume,
account_flags, max_size, &enum_names,
&enum_rids, &num_entries);
if (status == STATUS_SUCCESS ||
status == STATUS_MORE_ENTRIES)
DISPLAY_ACCOUNTS("Workstation", account_flags, enum_names,
enum_rids, num_entries);
if (enum_names) SamrFreeMemory((void*)enum_names);
if (enum_rids) SamrFreeMemory((void*)enum_rids);
} while (status == STATUS_MORE_ENTRIES);
resume = 0;
account_flags = acb_flags;
do {
status = SamrEnumDomainUsers(samr_binding, hDomain, &resume,
account_flags, max_size, &enum_names,
&enum_rids, &num_entries);
if (status == STATUS_SUCCESS ||
status == STATUS_MORE_ENTRIES)
DISPLAY_ACCOUNTS("Account", account_flags,
enum_names, enum_rids, num_entries);
if (enum_names) SamrFreeMemory((void*)enum_names);
if (enum_rids) SamrFreeMemory((void*)enum_rids);
} while (status == STATUS_MORE_ENTRIES);
SamrClose(samr_binding, hDomain);
if (status != 0) rpc_fail(status);
SamrClose(samr_binding, hConn);
if (status != 0) rpc_fail(status);
FreeSamrBinding(&samr_binding);
RELEASE_SESSION_CREDS;
done:
if (sid) {
SamrFreeMemory((void*)sid);
}
SAFE_FREE(domname);
SAFE_FREE(domainname);
return (status == STATUS_SUCCESS);
}
int TestSamrQueryDisplayInfo(struct test *t, const wchar16_t *hostname,
const wchar16_t *user, const wchar16_t *pass,
struct parameter *options, int optcount)
{
const UINT32 conn_access_mask = SAMR_ACCESS_OPEN_DOMAIN |
SAMR_ACCESS_ENUM_DOMAINS |
SAMR_ACCESS_CONNECT_TO_SERVER;
const UINT32 dom_access_mask = DOMAIN_ACCESS_OPEN_ACCOUNT |
DOMAIN_ACCESS_ENUM_ACCOUNTS |
DOMAIN_ACCESS_CREATE_USER |
DOMAIN_ACCESS_CREATE_ALIAS |
DOMAIN_ACCESS_LOOKUP_INFO_2;
const int def_specifydomain = 0;
const char *def_domainname = "BUILTIN";
const int def_level = 0;
const int def_max_entries = 64;
const int def_buf_size = 512;
NTSTATUS status = STATUS_SUCCESS;
handle_t samr_binding = NULL;
enum param_err perr = perr_success;
wchar16_t *domname = NULL;
wchar16_t *domainname = NULL;
CONNECT_HANDLE hConn = NULL;
DOMAIN_HANDLE hDomain = NULL;
PSID sid = NULL;
int specifydomain = 0;
INT32 level = 0;
UINT32 start_idx = 0;
UINT32 max_entries = 0;
UINT32 buf_size = 0;
UINT32 total_size = 0;
UINT32 returned_size = 0;
SamrDisplayInfo *info = NULL;
perr = fetch_value(options, optcount, "specifydomain", pt_int32,
&specifydomain, &def_specifydomain);
if (!perr_is_ok(perr)) perr_fail(perr);
perr = fetch_value(options, optcount, "domainname", pt_w16string,
&domainname, &def_domainname);
if (!perr_is_ok(perr)) perr_fail(perr);
perr = fetch_value(options, optcount, "level", pt_int32, &level,
&def_level);
if (!perr_is_ok(perr)) perr_fail(perr);
perr = fetch_value(options, optcount, "maxentries", pt_int32, &max_entries,
&def_max_entries);
if (!perr_is_ok(perr)) perr_fail(perr);
perr = fetch_value(options, optcount, "maxsize", pt_int32, &buf_size,
&def_buf_size);
if (!perr_is_ok(perr)) perr_fail(perr);
SET_SESSION_CREDS(hCreds);
samr_binding = CreateSamrBinding(&samr_binding, hostname);
if (samr_binding == NULL) return false;
status = SamrConnect2(samr_binding, hostname, conn_access_mask,
&hConn);
if (status != 0) rpc_fail(status);
if (specifydomain) {
domname = wc16sdup(domainname);
} else {
status = GetSamDomainName(&domname, hostname);
if (status != 0) rpc_fail(status);
}
status = SamrLookupDomain(samr_binding, hConn, domname, &sid);
if (status != 0) rpc_fail(status);
status = SamrOpenDomain(samr_binding, hConn, dom_access_mask,
sid, &hDomain);
if (status != 0) rpc_fail(status);
if (level == 0) {
for (level = 1; level <= 5; level++) {
start_idx = 0;
do {
CALL_MSRPC(status = SamrQueryDisplayInfo(samr_binding,
hDomain,
(UINT16)level,
start_idx,
max_entries,
buf_size,
&total_size,
&returned_size,
&info));
switch (level) {
case 1:
if (info && info->info1.count) {
start_idx =
info->info1.entries[info->info1.count - 1].idx + 1;
}
break;
case 2:
if (info && info->info2.count) {
start_idx =
info->info2.entries[info->info2.count - 1].idx + 1;
}
break;
case 3:
if (info && info->info3.count) {
start_idx =
info->info3.entries[info->info3.count - 1].idx + 1;
}
break;
case 4:
if (info && info->info4.count) {
start_idx =
info->info4.entries[info->info4.count - 1].idx + 1;
}
break;
case 5:
if (info && info->info5.count) {
start_idx =
info->info5.entries[info->info5.count - 1].idx + 1;
}
break;
}
if (info) {
SamrFreeMemory(info);
}
} while (status == STATUS_MORE_ENTRIES);
}
} else {
do {
CALL_MSRPC(status = SamrQueryDisplayInfo(samr_binding, hDomain,
(UINT16)level, start_idx,
max_entries, buf_size,
&total_size, &returned_size,
&info));
switch (level) {
case 1:
if (info && info->info1.count) {
start_idx =
info->info1.entries[info->info1.count - 1].idx + 1;
}
break;
case 2:
if (info && info->info2.count) {
start_idx =
info->info2.entries[info->info2.count - 1].idx + 1;
}
break;
case 3:
if (info && info->info3.count) {
start_idx =
info->info3.entries[info->info3.count - 1].idx + 1;
}
break;
case 4:
if (info && info->info4.count) {
start_idx =
info->info4.entries[info->info4.count - 1].idx + 1;
}
break;
case 5:
if (info && info->info5.count) {
start_idx =
info->info5.entries[info->info5.count - 1].idx + 1;
}
break;
}
if (info) {
SamrFreeMemory(info);
}
} while (status == STATUS_MORE_ENTRIES);
}
SamrClose(samr_binding, hDomain);
if (status != 0) rpc_fail(status);
SamrClose(samr_binding, hConn);
if (status != 0) rpc_fail(status);
FreeSamrBinding(&samr_binding);
RELEASE_SESSION_CREDS;
done:
if (sid) {
SamrFreeMemory((void*)sid);
}
SAFE_FREE(domname);
SAFE_FREE(domainname);
return (status == STATUS_SUCCESS);
}
int TestSamrEnumDomains(struct test *t, const wchar16_t *hostname,
const wchar16_t *user, const wchar16_t *pass,
struct parameter *options, int optcount)
{
const UINT32 conn_access_mask = SAMR_ACCESS_OPEN_DOMAIN |
SAMR_ACCESS_ENUM_DOMAINS |
SAMR_ACCESS_CONNECT_TO_SERVER;
const UINT32 def_max_size = (UINT32)(-1);
NTSTATUS status = STATUS_SUCCESS;
enum param_err perr = perr_success;
handle_t samr_binding = NULL;
UINT32 resume = 0;
UINT32 num_entries = 0;
UINT32 max_size = 0;
wchar16_t **enum_domains = NULL;
CONNECT_HANDLE hConn = NULL;
perr = fetch_value(options, optcount, "maxsize", pt_uint32,
&max_size, &def_max_size);
if (!perr_is_ok(perr)) perr_fail(perr);
SET_SESSION_CREDS(hCreds);
samr_binding = CreateSamrBinding(&samr_binding, hostname);
if (samr_binding == NULL) return false;
status = SamrConnect2(samr_binding, hostname, conn_access_mask,
&hConn);
if (status != 0) rpc_fail(status);
resume = 0;
do {
status = SamrEnumDomains(samr_binding, hConn, &resume, max_size,
&enum_domains, &num_entries);
DISPLAY_DOMAINS(enum_domains, num_entries);
if (enum_domains) SamrFreeMemory((void*)enum_domains);
} while (status == STATUS_MORE_ENTRIES);
status = SamrClose(samr_binding, hConn);
if (status != 0) rpc_fail(status);
FreeSamrBinding(&samr_binding);
RELEASE_SESSION_CREDS;
done:
return (status == STATUS_SUCCESS);
}
int TestSamrCreateUserAccount(struct test *t, const wchar16_t *hostname,
const wchar16_t *user, const wchar16_t *pass,
struct parameter *options, int optcount)
{
const UINT32 conn_access_mask = SAMR_ACCESS_OPEN_DOMAIN |
SAMR_ACCESS_ENUM_DOMAINS |
SAMR_ACCESS_CONNECT_TO_SERVER;
const UINT32 dom_access_mask = DOMAIN_ACCESS_OPEN_ACCOUNT |
DOMAIN_ACCESS_ENUM_ACCOUNTS |
DOMAIN_ACCESS_CREATE_USER |
DOMAIN_ACCESS_CREATE_ALIAS |
DOMAIN_ACCESS_LOOKUP_INFO_2;
const UINT32 usr_access_mask = USER_ACCESS_GET_NAME_ETC |
USER_ACCESS_GET_LOCALE |
USER_ACCESS_GET_LOGONINFO |
USER_ACCESS_GET_ATTRIBUTES |
USER_ACCESS_CHANGE_PASSWORD |
DELETE;
const UINT32 account_flags = ACB_NORMAL;
const char *newuser = "Testuser";
NTSTATUS status = STATUS_SUCCESS;
enum param_err perr = perr_success;
handle_t samr_binding = NULL;
wchar16_t *newusername = NULL;
wchar16_t *domname = NULL;
UINT32 rid = 0;
CONNECT_HANDLE hConn = NULL;
DOMAIN_HANDLE hDomain = NULL;
ACCOUNT_HANDLE hAccount = NULL;
PSID sid = NULL;
perr = fetch_value(options, optcount, "username", pt_w16string,
&newusername, &newuser);
if (!perr_is_ok(perr)) perr_fail(perr);
SET_SESSION_CREDS(hCreds);
/*
* Make sure there's no account with the same name already
*/
status = CleanupAccount(hostname, newusername);
if (status != 0) goto done;
samr_binding = CreateSamrBinding(&samr_binding, hostname);
if (samr_binding == NULL) return false;
/*
* Creating and deleting user account
*/
status = SamrConnect2(samr_binding, hostname, conn_access_mask,
&hConn);
if (status != 0) rpc_fail(status);
status = GetSamDomainName(&domname, hostname);
if (status != 0) rpc_fail(status);
status = SamrLookupDomain(samr_binding, hConn, domname, &sid);
if (status != 0) rpc_fail(status);
status = SamrOpenDomain(samr_binding, hConn, dom_access_mask,
sid, &hDomain);
if (status != 0) rpc_fail(status);
status = SamrCreateUser(samr_binding, hDomain, newusername,
account_flags, &hAccount, &rid);
if (status != 0) rpc_fail(status);
status = SamrClose(samr_binding, hAccount);
if (status != 0) rpc_fail(status);
status = SamrOpenUser(samr_binding, hDomain, usr_access_mask,
rid, &hAccount);
if (status != 0) rpc_fail(status);
status = SamrDeleteUser(samr_binding, hAccount);
if (status != 0) rpc_fail(status);
status = SamrClose(samr_binding, hDomain);
if (status != 0) rpc_fail(status);
status = SamrClose(samr_binding, hConn);
if (status != 0) rpc_fail(status);
FreeSamrBinding(&samr_binding);
RELEASE_SESSION_CREDS;
done:
if (sid) SamrFreeMemory((void*)sid);
SAFE_FREE(newusername);
SAFE_FREE(domname);
return (status == STATUS_SUCCESS);
}
int TestSamrCreateAlias(struct test *t, const wchar16_t *hostname,
const wchar16_t *user, const wchar16_t *pass,
struct parameter *options, int optcount)
{
const UINT32 conn_access_mask = SAMR_ACCESS_OPEN_DOMAIN |
SAMR_ACCESS_ENUM_DOMAINS |
SAMR_ACCESS_CONNECT_TO_SERVER;
const UINT32 dom_access_mask = DOMAIN_ACCESS_OPEN_ACCOUNT |
DOMAIN_ACCESS_ENUM_ACCOUNTS |
DOMAIN_ACCESS_CREATE_USER |
DOMAIN_ACCESS_CREATE_ALIAS |
DOMAIN_ACCESS_LOOKUP_INFO_2;
const UINT32 alias_access = ALIAS_ACCESS_LOOKUP_INFO |
ALIAS_ACCESS_SET_INFO |
DELETE;
const char *def_aliasname = "Testalias";
NTSTATUS status = STATUS_SUCCESS;
enum param_err perr = perr_success;
handle_t samr_binding = NULL;
wchar16_t *newaliasname = NULL;
wchar16_t *domname = NULL;
UINT32 rid = 0;
CONNECT_HANDLE hConn = NULL;
DOMAIN_HANDLE hDomain = NULL;
ACCOUNT_HANDLE hAccount = NULL;
PSID sid = NULL;
perr = fetch_value(options, optcount, "aliasname", pt_w16string,
&newaliasname, &def_aliasname);
if (!perr_is_ok(perr)) perr_fail(perr);
SET_SESSION_CREDS(hCreds);
status = CleanupAlias(hostname, newaliasname);
if (status != 0) rpc_fail(status);
samr_binding = CreateSamrBinding(&samr_binding, hostname);
if (samr_binding == NULL) return false;
status = SamrConnect2(samr_binding, hostname, conn_access_mask,
&hConn);
if (status != 0) rpc_fail(status);
status = GetSamDomainName(&domname, hostname);
if (status != 0) rpc_fail(status);
status = SamrLookupDomain(samr_binding, hConn, domname, &sid);
if (status != 0) rpc_fail(status);
status = SamrOpenDomain(samr_binding, hConn, dom_access_mask,
sid, &hDomain);
if (status != 0) rpc_fail(status);
status = SamrCreateDomAlias(samr_binding, hDomain, newaliasname,
alias_access, &hAccount, &rid);
if (status != 0) rpc_fail(status);
status = SamrClose(samr_binding, hAccount);
if (status != 0) rpc_fail(status);
status = SamrOpenAlias(samr_binding, hDomain, alias_access, rid,
&hAccount);
if (status != 0) rpc_fail(status);
status = SamrDeleteDomAlias(samr_binding, hAccount);
if (status != 0) rpc_fail(status);
status = SamrClose(samr_binding, hDomain);
if (status != 0) rpc_fail(status);
status = SamrClose(samr_binding, hConn);
if (status != 0) rpc_fail(status);
FreeSamrBinding(&samr_binding);
RELEASE_SESSION_CREDS;
done:
if (sid) SamrFreeMemory((void*)sid);
SAFE_FREE(domname);
SAFE_FREE(newaliasname);
return (status == STATUS_SUCCESS);
}
int TestSamrCreateGroup(struct test *t, const wchar16_t *hostname,
const wchar16_t *user, const wchar16_t *pass,
struct parameter *options, int optcount)
{
const UINT32 conn_access_mask = SAMR_ACCESS_OPEN_DOMAIN |
SAMR_ACCESS_ENUM_DOMAINS |
SAMR_ACCESS_CONNECT_TO_SERVER;
const UINT32 dom_access_mask = DOMAIN_ACCESS_OPEN_ACCOUNT |
DOMAIN_ACCESS_ENUM_ACCOUNTS |
DOMAIN_ACCESS_CREATE_USER |
DOMAIN_ACCESS_CREATE_ALIAS |
DOMAIN_ACCESS_CREATE_GROUP |
DOMAIN_ACCESS_LOOKUP_INFO_2;
const UINT32 group_access = GROUP_ACCESS_LOOKUP_INFO |
GROUP_ACCESS_SET_INFO |
DELETE;
const char *def_groupname = "Testgroup";
NTSTATUS status = STATUS_SUCCESS;
enum param_err perr = perr_success;
handle_t samr_binding = NULL;
wchar16_t *newgroupname = NULL;
wchar16_t *domname = NULL;
UINT32 rid = 0;
CONNECT_HANDLE hConn = NULL;
DOMAIN_HANDLE hDomain = NULL;
ACCOUNT_HANDLE hAccount = NULL;
PSID sid = NULL;
perr = fetch_value(options, optcount, "groupname", pt_w16string,
&newgroupname, &def_groupname);
if (!perr_is_ok(perr)) perr_fail(perr);
SET_SESSION_CREDS(hCreds);
samr_binding = CreateSamrBinding(&samr_binding, hostname);
if (samr_binding == NULL) return false;
status = SamrConnect2(samr_binding, hostname, conn_access_mask,
&hConn);
if (status != 0) rpc_fail(status);
status = GetSamDomainName(&domname, hostname);
if (status != 0) rpc_fail(status);
status = SamrLookupDomain(samr_binding, hConn, domname, &sid);
if (status != 0) rpc_fail(status);
status = SamrOpenDomain(samr_binding, hConn, dom_access_mask,
sid, &hDomain);
if (status != 0) rpc_fail(status);
status = SamrCreateDomGroup(samr_binding, hDomain, newgroupname,
group_access, &hAccount, &rid);
if (status != 0) rpc_fail(status);
status = SamrClose(samr_binding, hAccount);
if (status != 0) rpc_fail(status);
status = SamrOpenGroup(samr_binding, hDomain, group_access, rid,
&hAccount);
if (status != 0) rpc_fail(status);
status = SamrDeleteDomGroup(samr_binding, hAccount);
if (status != 0) rpc_fail(status);
status = SamrClose(samr_binding, hDomain);
if (status != 0) rpc_fail(status);
status = SamrClose(samr_binding, hConn);
if (status != 0) rpc_fail(status);
FreeSamrBinding(&samr_binding);
RELEASE_SESSION_CREDS;
done:
if (sid) SamrFreeMemory((void*)sid);
SAFE_FREE(domname);
SAFE_FREE(newgroupname);
return (status == STATUS_SUCCESS);
}
int TestSamrSetUserPassword(struct test *t, const wchar16_t *hostname,
const wchar16_t *user, const wchar16_t *pass,
struct parameter *options, int optcount)
{
const UINT32 conn_access_mask = SAMR_ACCESS_OPEN_DOMAIN |
SAMR_ACCESS_ENUM_DOMAINS |
SAMR_ACCESS_CONNECT_TO_SERVER;
const UINT32 dom_access_mask = DOMAIN_ACCESS_OPEN_ACCOUNT |
DOMAIN_ACCESS_ENUM_ACCOUNTS |
DOMAIN_ACCESS_CREATE_USER |
DOMAIN_ACCESS_CREATE_ALIAS |
DOMAIN_ACCESS_LOOKUP_INFO_1;
const UINT32 usr_access_mask = USER_ACCESS_GET_NAME_ETC |
USER_ACCESS_GET_LOCALE |
USER_ACCESS_GET_LOGONINFO |
USER_ACCESS_GET_ATTRIBUTES |
USER_ACCESS_CHANGE_PASSWORD |
USER_ACCESS_SET_PASSWORD |
USER_ACCESS_SET_ATTRIBUTES |
DELETE;
const char *newuser = "Testuser";
const char *testpass = "JustTesting30$";
const UINT32 def_primary_gid = 513;
NTSTATUS status = STATUS_SUCCESS;
RPCSTATUS rpcstatus;
enum param_err perr = perr_success;
handle_t samr_binding;
BOOL bNewAcct = FALSE;
wchar16_t *newusername, *domname;
UINT32 rid;
CONNECT_HANDLE hConn = NULL;
DOMAIN_HANDLE hDomain = NULL;
ACCOUNT_HANDLE hAccount = NULL;
PSID sid = NULL;
UINT32 *rids, *types, rids_count;
wchar16_t *names[1];
UserInfo userinfo;
UserInfo26 *info26 = NULL;
unsigned char initval[16] = {0};
wchar16_t *password;
unsigned char *sess_key;
unsigned16 sess_key_len;
unsigned char digested_sess_key[16] = {0};
struct md5context ctx;
UserInfo9 *info9 = NULL;
UINT32 primary_gid = 0;
memset((void*)&userinfo, 0, sizeof(userinfo));
perr = fetch_value(options, optcount, "username", pt_w16string,
&newusername, &newuser);
if (!perr_is_ok(perr)) perr_fail(perr)
perr = fetch_value(options, optcount, "password", pt_w16string,
&password, &testpass);
if (!perr_is_ok(perr)) perr_fail(perr);
perr = fetch_value(options, optcount, "primarygid", pt_uint32,
&primary_gid, &def_primary_gid);
if (!perr_is_ok(perr)) perr_fail(perr);
SET_SESSION_CREDS(hCreds);
samr_binding = CreateSamrBinding(&samr_binding, hostname);
if (samr_binding == NULL) return false;
status = EnsureUserAccount(hostname, newusername, &bNewAcct);
if (status != 0) rpc_fail(status);
/*
* Creating and deleting user account
*/
status = SamrConnect2(samr_binding, hostname, conn_access_mask,
&hConn);
if (status != 0) rpc_fail(status);
GetSessionKey(samr_binding, &sess_key, &sess_key_len, &rpcstatus);
if (rpcstatus != 0) return false;
status = GetSamDomainName(&domname, hostname);
if (status != 0) rpc_fail(status);
status = SamrLookupDomain(samr_binding, hConn, domname, &sid);
if (status != 0) rpc_fail(status);
status = SamrOpenDomain(samr_binding, hConn, dom_access_mask,
sid, &hDomain);
if (status != 0) rpc_fail(status);
names[0] = newusername;
status = SamrLookupNames(samr_binding, hDomain, 1, names, &rids, &types,
&rids_count);
if (status != 0) rpc_fail(status);
rid = rids[0];
status = SamrOpenUser(samr_binding, hDomain, usr_access_mask,
rid, &hAccount);
if (status != 0) rpc_fail(status);
info9 = &userinfo.info9;
info9->primary_gid = primary_gid;
status = SamrSetUserInfo(samr_binding, hAccount, 9, &userinfo);
if (status != 0) rpc_fail(status);
info26 = &userinfo.info26;
EncodePassBufferW16(info26->password.data, password);
info26->password_len = strlen(testpass);
memset(initval, 0, sizeof(initval));
md5init(&ctx);
md5update(&ctx, initval, 16);
md5update(&ctx, sess_key, (unsigned int)sess_key_len);
md5final(&ctx, digested_sess_key);
rc4(info26->password.data, 516, digested_sess_key, 16);
memcpy((void*)&info26->password.data, initval, 16);
status = SamrSetUserInfo(samr_binding, hAccount, 26, &userinfo);
if (status != 0) rpc_fail(status);
if (bNewAcct) {
status = SamrDeleteUser(samr_binding, hAccount);
if (status != 0) rpc_fail(status);
}
status = SamrClose(samr_binding, hDomain);
if (status != 0) rpc_fail(status);
status = SamrClose(samr_binding, hConn);
if (status != 0) rpc_fail(status);
FreeSamrBinding(&samr_binding);
RELEASE_SESSION_CREDS;
done:
if (sid) SamrFreeMemory((void*)sid);
if (rids) SamrFreeMemory((void*)rids);
if (types) SamrFreeMemory((void*)types);
SAFE_FREE(newusername);
SAFE_FREE(password);
SAFE_FREE(domname);
SAFE_FREE(sess_key);
return (status == STATUS_SUCCESS);
}
int TestSamrMultipleConnections(struct test *t, const wchar16_t *hostname,
const wchar16_t *user, const wchar16_t *pass,
struct parameter *options, int optcount)
{
const UINT32 conn_access = SAMR_ACCESS_OPEN_DOMAIN |
SAMR_ACCESS_ENUM_DOMAINS |
SAMR_ACCESS_CONNECT_TO_SERVER;
NTSTATUS status = STATUS_SUCCESS;
handle_t samr_binding1 = NULL;
handle_t samr_binding2 = NULL;
CONNECT_HANDLE hConn1 = NULL;
CONNECT_HANDLE hConn2 = NULL;
unsigned char *key1 = NULL;
unsigned char *key2 = NULL;
unsigned16 key_len1, key_len2;
RPCSTATUS st = 0;
samr_binding1 = NULL;
samr_binding2 = NULL;
SET_SESSION_CREDS(hCreds);
samr_binding1 = CreateSamrBinding(&samr_binding1, hostname);
if (samr_binding1 == NULL) return false;
status = SamrConnect2(samr_binding1, hostname, conn_access, &hConn1);
if (status != 0) rpc_fail(status);
GetSessionKey(samr_binding1, &key1, &key_len1, &st);
if (st != 0) return false;
samr_binding2 = CreateSamrBinding(&samr_binding2, hostname);
if (samr_binding2 == NULL) return false;
status = SamrConnect2(samr_binding2, hostname, conn_access, &hConn2);
if (status != 0) rpc_fail(status);
GetSessionKey(samr_binding2, &key2, &key_len2, &st);
if (st != 0) return false;
status = SamrClose(samr_binding1, hConn1);
if (status != 0) rpc_fail(status);
status = SamrClose(samr_binding2, hConn2);
if (status != 0) rpc_fail(status);
FreeSamrBinding(&samr_binding1);
FreeSamrBinding(&samr_binding2);
RELEASE_SESSION_CREDS;
done:
return (status == STATUS_SUCCESS);
}
int TestSamrChangeUserPassword(struct test *t, const wchar16_t *hostname,
const wchar16_t *user, const wchar16_t *pass,
struct parameter *options, int optcount)
{
const char *defusername = "TestUser";
const char *defoldpass = "";
const char *defnewpass = "secret";
NTSTATUS status = STATUS_SUCCESS;
enum param_err perr = perr_success;
handle_t samr_b = NULL;
wchar16_t *username = NULL;
wchar16_t *oldpassword = NULL;
wchar16_t *newpassword = NULL;
UINT8 old_nthash[16] = {0};
UINT8 new_nthash[16] = {0};
UINT8 old_lmhash[16] = {0};
size_t oldlen, newlen;
UINT8 ntpassbuf[516] = {0};
UINT8 ntverhash[16] = {0};
perr = fetch_value(options, optcount, "username", pt_w16string,
&username, &defusername);
if (!perr_is_ok(perr)) perr_fail(perr);
perr = fetch_value(options, optcount, "oldpass", pt_w16string,
&oldpassword, &defoldpass);
if (!perr_is_ok(perr)) perr_fail(perr);
perr = fetch_value(options, optcount, "newpass", pt_w16string,
&newpassword, &defnewpass);
if (!perr_is_ok(perr)) perr_fail(perr);
SET_SESSION_CREDS(hCreds);
samr_b = CreateSamrBinding(&samr_b, hostname);
if (samr_b == NULL) return STATUS_UNSUCCESSFUL;
oldlen = wc16slen(oldpassword);
newlen = wc16slen(newpassword);
/* prepare NT password hashes */
md4hash(old_nthash, oldpassword);
md4hash(new_nthash, newpassword);
/* prepare LM password hash */
deshash(old_lmhash, oldpassword);
/* encode password buffer */
EncodePassBufferW16(ntpassbuf, newpassword);
rc4(ntpassbuf, 516, old_nthash, 16);
/* encode NT verifier */
des56(ntverhash, old_nthash, 8, new_nthash);
des56(&ntverhash[8], &old_nthash[8], 8, &new_nthash[7]);
status = SamrChangePasswordUser2(samr_b, hostname, username, ntpassbuf,
ntverhash, 0, NULL, NULL);
if (status != 0) rpc_fail(status);
FreeSamrBinding(&samr_b);
RELEASE_SESSION_CREDS;
done:
SAFE_FREE(username);
SAFE_FREE(oldpassword);
SAFE_FREE(newpassword);
return (status == STATUS_SUCCESS);
}
int TestSamrEnumAliases(struct test *t, const wchar16_t *hostname,
const wchar16_t *user, const wchar16_t *pass,
struct parameter *options, int optcount)
{
const UINT32 conn_access_mask = SAMR_ACCESS_OPEN_DOMAIN |
SAMR_ACCESS_ENUM_DOMAINS |
SAMR_ACCESS_CONNECT_TO_SERVER;
const UINT32 dom_access_mask = DOMAIN_ACCESS_OPEN_ACCOUNT |
DOMAIN_ACCESS_ENUM_ACCOUNTS |
DOMAIN_ACCESS_CREATE_USER |
DOMAIN_ACCESS_CREATE_ALIAS |
DOMAIN_ACCESS_LOOKUP_INFO_2;
const int def_specifydomain = 0;
const char *def_domainname = "BUILTIN";
NTSTATUS status = STATUS_SUCCESS;
handle_t samr_binding;
enum param_err perr = perr_success;
UINT32 resume, num_entries, max_size;
UINT32 account_flags;
wchar16_t **enum_names, *domname, *domainname;
UINT32 *enum_rids;
CONNECT_HANDLE hConn = NULL;
DOMAIN_HANDLE hDomain = NULL;
PSID sid = NULL;
int specifydomain;
perr = fetch_value(options, optcount, "specifydomain", pt_int32,
&specifydomain, &def_specifydomain);
if (!perr_is_ok(perr)) perr_fail(perr);
perr = fetch_value(options, optcount, "domainname", pt_w16string,
&domainname, &def_domainname);
if (!perr_is_ok(perr)) perr_fail(perr);
SET_SESSION_CREDS(hCreds);
samr_binding = CreateSamrBinding(&samr_binding, hostname);
if (samr_binding == NULL) return false;
status = SamrConnect2(samr_binding, hostname, conn_access_mask,
&hConn);
if (status != 0) rpc_fail(status);
if (specifydomain) {
domname = wc16sdup(domainname);
} else {
status = GetSamDomainName(&domname, hostname);
if (status != 0) rpc_fail(status);
}
status = SamrLookupDomain(samr_binding, hConn, domname, &sid);
if (status != 0) rpc_fail(status);
status = SamrOpenDomain(samr_binding, hConn, dom_access_mask,
sid, &hDomain);
if (status != 0) rpc_fail(status);
/*
* Enumerating domain aliases
*/
max_size = 128;
resume = 0;
account_flags = ACB_NORMAL;
do {
enum_names = NULL;
enum_rids = NULL;
status = SamrEnumDomainAliases(samr_binding, hDomain, &resume,
account_flags, &enum_names, &enum_rids,
&num_entries);
if (status == STATUS_SUCCESS ||
status == STATUS_MORE_ENTRIES)
DISPLAY_ACCOUNTS("Alias", account_flags, enum_names, enum_rids,
num_entries);
if (enum_names) SamrFreeMemory((void*)enum_names);
if (enum_rids) SamrFreeMemory((void*)enum_rids);
} while (status == STATUS_MORE_ENTRIES);
SamrClose(samr_binding, hDomain);
if (status != 0) rpc_fail(status);
SamrClose(samr_binding, hConn);
if (status != 0) rpc_fail(status);
RELEASE_SESSION_CREDS;
done:
if (sid) SamrFreeMemory((void*)sid);
SAFE_FREE(domname);
SAFE_FREE(domainname);
return true;
}
int TestSamrGetUserGroups(struct test *t, const wchar16_t *hostname,
const wchar16_t *user, const wchar16_t *pass,
struct parameter *options, int optcount)
{
const UINT32 conn_access = SAMR_ACCESS_OPEN_DOMAIN |
SAMR_ACCESS_ENUM_DOMAINS;
const UINT32 domain_access = DOMAIN_ACCESS_OPEN_ACCOUNT |
DOMAIN_ACCESS_ENUM_ACCOUNTS |
DOMAIN_ACCESS_CREATE_USER |
DOMAIN_ACCESS_LOOKUP_INFO_2;
const UINT32 user_access = USER_ACCESS_GET_NAME_ETC |
USER_ACCESS_GET_LOCALE |
USER_ACCESS_GET_LOGONINFO |
USER_ACCESS_GET_ATTRIBUTES |
USER_ACCESS_GET_GROUPS |
USER_ACCESS_GET_GROUP_MEMBERSHIP;
const UINT32 lsa_access = LSA_ACCESS_LOOKUP_NAMES_SIDS;
const char *def_username = "Guest";
const int def_resolvesids = 0;
const UINT32 def_resolvelevel = 6;
NTSTATUS status = STATUS_SUCCESS;
enum param_err perr = perr_success;
handle_t samr_b = NULL;
handle_t lsa_b = NULL;
PSID domsid = NULL;
CONNECT_HANDLE hConn = NULL;
DOMAIN_HANDLE hDomain = NULL;
ACCOUNT_HANDLE hUser = NULL;
POLICY_HANDLE hPolicy = NULL;
wchar16_t *username = NULL;
int resolvesids = 0;
UINT32 resolve_level = 0;
wchar16_t *names[1] = {0};
UINT32 *rids = NULL;
UINT32 *types = NULL;
UINT32 rids_count = 0;
UINT32 *grp_rids = NULL;
UINT32 *grp_attrs = NULL;
UINT32 grp_count = 0;
int i = 0;
PSID* grp_sids = NULL;
wchar16_t **grp_sidstrs = NULL;
SidArray sid_array = {0};
RefDomainList *domains = NULL;
TranslatedName *trans_names = NULL;
UINT32 names_count = 0;
wchar16_t *grp_name = NULL;
wchar16_t *dom_name = NULL;
perr = fetch_value(options, optcount, "username", pt_w16string,
&username, &def_username);
if (!perr_is_ok(perr)) perr_fail(perr);
perr = fetch_value(options, optcount, "resolvesids", pt_int32,
&resolvesids, &def_resolvesids);
if (!perr_is_ok(perr)) perr_fail(perr);
perr = fetch_value(options, optcount, "resolvelevel", pt_uint32,
&resolve_level, &def_resolvelevel);
if (!perr_is_ok(perr)) perr_fail(perr);
PARAM_INFO("username", pt_w16string, username);
PARAM_INFO("resolvesids", pt_int32, &resolvesids);
PARAM_INFO("resolvelevel", pt_uint32, &resolve_level);
SET_SESSION_CREDS(hCreds);
status = GetSamDomainSid(&domsid, hostname);
if (status != 0) rpc_fail(status);
samr_b = CreateSamrBinding(&samr_b, hostname);
if (samr_b == NULL) return false;
status = SamrConnect2(samr_b, hostname, conn_access, &hConn);
if (status != 0) rpc_fail(status);
status = SamrOpenDomain(samr_b, hConn, domain_access, domsid, &hDomain);
if (status != 0) rpc_fail(status);
names[0] = username;
status = SamrLookupNames(samr_b, hDomain, 1, names, &rids, &types,
&rids_count);
if (status != 0) rpc_fail(status);
status = SamrOpenUser(samr_b, hDomain, user_access, rids[0], &hUser);
if (status != 0) rpc_fail(status);
INPUT_ARG_PTR(samr_b);
INPUT_ARG_PTR(hUser);
INPUT_ARG_PTR(grp_rids);
INPUT_ARG_PTR(grp_attrs);
CALL_MSRPC(status = SamrGetUserGroups(samr_b, hUser, &grp_rids,
&grp_attrs, &grp_count));
OUTPUT_ARG_PTR(grp_rids);
OUTPUT_ARG_PTR(grp_attrs);
OUTPUT_ARG_PTR(grp_count);
grp_sids = (PSID*) malloc(sizeof(PSID) * grp_count);
if (grp_sids == NULL) rpc_fail(STATUS_NO_MEMORY);
grp_sidstrs = (wchar16_t**) malloc(sizeof(wchar16_t*) * grp_count);
if (grp_sidstrs == NULL) rpc_fail(STATUS_NO_MEMORY);
if (resolvesids) {
sid_array.num_sids = grp_count;
sid_array.sids = (SidPtr*) malloc(sizeof(SidPtr) * grp_count);
if (sid_array.sids == NULL) rpc_fail(STATUS_NO_MEMORY);
}
for (i = 0; i < grp_count; i++) {
status = MsRpcAllocateSidAppendRid(&grp_sids[i],
domsid,
grp_rids[i]);
if (status != 0) rpc_fail(status);
status = RtlAllocateWC16StringFromSid(&grp_sidstrs[i], grp_sids[i]);
if (status != 0) rpc_fail(status);
if (resolvesids) {
sid_array.sids[i].sid = grp_sids[i];
}
}
if (resolvesids) {
lsa_b = CreateLsaBinding(&lsa_b, hostname);
if (lsa_b == NULL) rpc_fail(STATUS_UNSUCCESSFUL);
status = LsaOpenPolicy2(lsa_b, hostname, NULL, lsa_access, &hPolicy);
if (status != 0) rpc_fail(status);
status = LsaLookupSids(lsa_b, hPolicy, &sid_array, &domains,
&trans_names, resolve_level, &names_count);
if (status != 0) rpc_fail(status);
}
for (i = 0; i < grp_count; i++) {
w16printfw(L"%ws", grp_sidstrs[i]);
if (resolvesids && i < names_count) {
LsaDomainInfo *di = NULL;
TranslatedName *tn = &(trans_names[i]);
grp_name = GetFromUnicodeString(&tn->name);
if (grp_name == NULL) rpc_fail(STATUS_NO_MEMORY);
di = &(domains->domains[tn->sid_index]);
dom_name = GetFromUnicodeStringEx(&di->name);
if (dom_name == NULL) rpc_fail(STATUS_NO_MEMORY);
w16printfw(L" [%ws\\%ws]", dom_name, grp_name);
SAFE_FREE(grp_name);
SAFE_FREE(dom_name);
}
printf("\n");
}
status = SamrClose(samr_b, hUser);
if (status != 0) rpc_fail(status);
status = SamrClose(samr_b, hDomain);
if (status != 0) rpc_fail(status);
status = SamrClose(samr_b, hConn);
if (status != 0) rpc_fail(status);
if (resolvesids) {
status = LsaClose(lsa_b, hPolicy);
if (status != 0) rpc_fail(status);
FreeLsaBinding(&lsa_b);
}
FreeSamrBinding(&samr_b);
RELEASE_SESSION_CREDS;
done:
SAFE_FREE(username);
if (domsid) MsRpcFreeSid(domsid);
if (rids) SamrFreeMemory((void*)rids);
if (types) SamrFreeMemory((void*)types);
if (grp_rids) SamrFreeMemory((void*)grp_rids);
if (grp_attrs) SamrFreeMemory((void*)grp_attrs);
if (trans_names) LsaRpcFreeMemory((void*)trans_names);
if (domains) LsaRpcFreeMemory((void*)domains);
for (i = 0; i < grp_count; i++) {
MsRpcFreeSid(grp_sids[i]);
RTL_FREE(&grp_sidstrs[i]);
}
SAFE_FREE(grp_sids);
SAFE_FREE(grp_sidstrs);
SAFE_FREE(sid_array.sids);
SAFE_FREE(grp_name);
SAFE_FREE(dom_name);
SamrDestroyMemory();
LsaRpcDestroyMemory();
return (status == STATUS_SUCCESS);
}
int TestSamrGetUserAliases(struct test *t, const wchar16_t *hostname,
const wchar16_t *user, const wchar16_t *pass,
struct parameter *options, int optcount)
{
const UINT32 conn_access = SAMR_ACCESS_OPEN_DOMAIN |
SAMR_ACCESS_ENUM_DOMAINS;
const UINT32 domain_access = DOMAIN_ACCESS_OPEN_ACCOUNT |
DOMAIN_ACCESS_ENUM_ACCOUNTS |
DOMAIN_ACCESS_LOOKUP_INFO_2;
const UINT32 btin_access = DOMAIN_ACCESS_OPEN_ACCOUNT |
DOMAIN_ACCESS_ENUM_ACCOUNTS |
DOMAIN_ACCESS_LOOKUP_INFO_2;
const UINT32 lsa_access = LSA_ACCESS_LOOKUP_NAMES_SIDS;
const char *btin_sidstr = "S-1-5-32";
const char *def_username = "Guest";
const int def_resolvesids = 0;
const UINT32 def_resolvelevel = 6;
NTSTATUS status = STATUS_SUCCESS;
enum param_err perr = perr_success;
handle_t samr_b = NULL;
handle_t lsa_b = NULL;
PSID btinsid = NULL;
PSID domsid = NULL;
POLICY_HANDLE hPolicy = NULL;
CONNECT_HANDLE hConn = NULL;
DOMAIN_HANDLE hBtinDomain = NULL;
DOMAIN_HANDLE hDomain = NULL;
wchar16_t *username = NULL;
int resolvesids = 0;
wchar16_t *names[1];
RefDomainList *usr_domains = NULL;
TranslatedSid2 *trans_sids = NULL;
PSID usr_sid = NULL;
UINT32 sids_count = 0;
UINT32 level = 0;
UINT32 resolve_level = 0;
UINT32 *btin_rids = NULL;
UINT32 *dom_rids = NULL;
UINT32 btin_rids_count = 0;
UINT32 dom_rids_count = 0;
SidArray sid_array = {0};
UINT32 alias_count = 0;
int i = 0;
wchar16_t **alias_sidstrs = NULL;
RefDomainList *alias_domains = NULL;
TranslatedName *trans_names = NULL;
UINT32 names_count = 0;
wchar16_t *alias_name = NULL;
wchar16_t *dom_name = NULL;
perr = fetch_value(options, optcount, "username", pt_w16string,
&username, &def_username);
if (!perr_is_ok(perr)) perr_fail(perr);
perr = fetch_value(options, optcount, "resolvesids", pt_int32,
&resolvesids, &def_resolvesids);
if (!perr_is_ok(perr)) perr_fail(perr);
perr = fetch_value(options, optcount, "resolvelevel", pt_uint32,
&resolve_level, &def_resolvelevel);
if (!perr_is_ok(perr)) perr_fail(perr);
PARAM_INFO("username", pt_w16string, username);
PARAM_INFO("resolvesids", pt_int32, &resolvesids);
PARAM_INFO("resolvelevel", pt_uint32, &resolve_level);
SET_SESSION_CREDS(hCreds);
/*
* Resolve username to sid first
*/
lsa_b = CreateLsaBinding(&lsa_b, hostname);
if (lsa_b == NULL) rpc_fail(STATUS_UNSUCCESSFUL);
status = LsaOpenPolicy2(lsa_b, hostname, NULL, lsa_access, &hPolicy);
if (status != 0) rpc_fail(status);
names[0] = username;
level = LSA_LOOKUP_NAMES_ALL;
status = LsaLookupNames2(lsa_b, hPolicy, 1, names, &usr_domains, &trans_sids,
level, &sids_count);
if (status != 0) rpc_fail(status);
if (sids_count == 0) rpc_fail(STATUS_UNSUCCESSFUL);
/* Create user account sid */
MsRpcDuplicateSid(&domsid, usr_domains->domains[trans_sids[0].index].sid);
if (domsid == NULL) rpc_fail(STATUS_NO_MEMORY);
status = MsRpcAllocateSidAppendRid(&usr_sid, domsid, trans_sids[0].rid);
if (status != 0) rpc_fail(status);
samr_b = CreateSamrBinding(&samr_b, hostname);
if (samr_b == NULL) return false;
status = SamrConnect2(samr_b, hostname, conn_access, &hConn);
if (status != 0) rpc_fail(status);
RtlAllocateSidFromCString(&btinsid, btin_sidstr);
status = SamrOpenDomain(samr_b, hConn, btin_access, btinsid, &hBtinDomain);
if (status != 0) rpc_fail(status);
INPUT_ARG_PTR(samr_b);
INPUT_ARG_PTR(hBtinDomain);
INPUT_ARG_PTR(usr_sid);
INPUT_ARG_UINT(sids_count);
CALL_MSRPC(status = SamrGetAliasMembership(samr_b,
hBtinDomain,
&usr_sid,
sids_count,
&btin_rids,
&btin_rids_count));
OUTPUT_ARG_PTR(&btin_rids);
OUTPUT_ARG_UINT(btin_rids_count);
status = SamrOpenDomain(samr_b, hConn, domain_access, domsid, &hDomain);
if (status != 0) rpc_fail(status);
INPUT_ARG_PTR(samr_b);
INPUT_ARG_PTR(hDomain);
INPUT_ARG_PTR(usr_sid);
INPUT_ARG_UINT(sids_count);
CALL_MSRPC(status = SamrGetAliasMembership(samr_b,
&hDomain,
&usr_sid,
sids_count,
&dom_rids,
&dom_rids_count));
OUTPUT_ARG_PTR(&dom_rids);
OUTPUT_ARG_UINT(dom_rids_count);
alias_count = btin_rids_count + dom_rids_count;
alias_sidstrs = (wchar16_t**) malloc(sizeof(wchar16_t*) * alias_count);
if (alias_sidstrs == NULL) rpc_fail(STATUS_NO_MEMORY);
if (resolvesids) {
sid_array.num_sids = alias_count;
sid_array.sids = (SidPtr*) malloc(sizeof(SidPtr) * alias_count);
if (sid_array.sids == NULL) rpc_fail(STATUS_NO_MEMORY);
}
for (i = 0; i < alias_count; i++) {
PSID alias_sid = NULL;
PSID dom_sid = (i < btin_rids_count) ? btinsid : domsid;
UINT32 rid = 0;
if (i < btin_rids_count) {
rid = btin_rids[i];
} else {
rid = dom_rids[i - btin_rids_count];
}
status = MsRpcAllocateSidAppendRid(&alias_sid, dom_sid, rid);
if (status != 0) rpc_fail(status);
status = RtlAllocateWC16StringFromSid(&alias_sidstrs[i], alias_sid);
if (status != 0) rpc_fail(status);
if (resolvesids) {
sid_array.sids[i].sid = alias_sid;
}
};
if (resolvesids) {
lsa_b = CreateLsaBinding(&lsa_b, hostname);
if (lsa_b == NULL) rpc_fail(STATUS_UNSUCCESSFUL);
status = LsaOpenPolicy2(lsa_b, hostname, NULL, lsa_access, &hPolicy);
if (status != 0) rpc_fail(status);
status = LsaLookupSids(lsa_b, hPolicy, &sid_array, &alias_domains,
&trans_names, resolve_level, &names_count);
if (status != 0) rpc_fail(status);
}
for (i = 0; i < alias_count; i++) {
w16printfw(L"%ws", alias_sidstrs[i]);
if (resolvesids && i < names_count) {
LsaDomainInfo *di = NULL;
TranslatedName *tn = &(trans_names[i]);
alias_name = GetFromUnicodeString(&tn->name);
if (alias_name == NULL) rpc_fail(STATUS_NO_MEMORY);
di = &(alias_domains->domains[tn->sid_index]);
dom_name = GetFromUnicodeStringEx(&di->name);
if (dom_name == NULL) rpc_fail(STATUS_NO_MEMORY);
w16printfw(L" [%ws\\%ws]", dom_name, alias_name);
SAFE_FREE(alias_name);
SAFE_FREE(dom_name);
}
printf("\n");
}
status = LsaClose(lsa_b, hPolicy);
if (status != 0) rpc_fail(status);
status = SamrClose(samr_b, hBtinDomain);
if (status != 0) rpc_fail(status);
status = SamrClose(samr_b, hDomain);
if (status != 0) rpc_fail(status);
status = SamrClose(samr_b, hConn);
if (status != 0) rpc_fail(status);
FreeLsaBinding(&lsa_b);
FreeSamrBinding(&samr_b);
RELEASE_SESSION_CREDS;
done:
SAFE_FREE(username);
RTL_FREE(&btinsid);
if (domsid) MsRpcFreeSid(domsid);
if (usr_sid) MsRpcFreeSid(usr_sid);
if (usr_domains) LsaRpcFreeMemory((void*)usr_domains);
if (trans_sids) LsaRpcFreeMemory((void*)trans_sids);
if (alias_domains) LsaRpcFreeMemory((void*)alias_domains);
if (trans_names) LsaRpcFreeMemory((void*)trans_names);
if (btin_rids) SamrFreeMemory((void*)btin_rids);
if (dom_rids) SamrFreeMemory((void*)dom_rids);
for (i = 0; i < alias_count; i++) {
if (resolvesids) {
MsRpcFreeSid(sid_array.sids[i].sid);
}
RTL_FREE(&alias_sidstrs[i]);
}
SAFE_FREE(sid_array.sids);
SAFE_FREE(alias_sidstrs);
return (status == STATUS_SUCCESS);
}
int TestSamrQuerySecurity(struct test *t, const wchar16_t *hostname,
const wchar16_t *user, const wchar16_t *pass,
struct parameter *options, int optcount)
{
const PSTR pszDefSidStr = "S-1-5-32-544";
const ULONG ulDefSecurityInfo = OWNER_SECURITY_INFORMATION;
const DWORD dwConnAccess = SAMR_ACCESS_OPEN_DOMAIN |
SAMR_ACCESS_ENUM_DOMAINS;
const DWORD dwDomainAccess = DOMAIN_ACCESS_OPEN_ACCOUNT |
DOMAIN_ACCESS_ENUM_ACCOUNTS |
DOMAIN_ACCESS_CREATE_USER |
DOMAIN_ACCESS_LOOKUP_INFO_2;
const DWORD dwUserAccess = READ_CONTROL |
USER_ACCESS_GET_NAME_ETC |
USER_ACCESS_GET_LOCALE |
USER_ACCESS_GET_LOGONINFO |
USER_ACCESS_GET_ATTRIBUTES |
USER_ACCESS_GET_GROUPS |
USER_ACCESS_GET_GROUP_MEMBERSHIP;
NTSTATUS ntStatus = STATUS_SUCCESS;
enum param_err perr = perr_success;
PSID pSid = NULL;
PSID pDomainSid = NULL;
PWSTR pwszSidStr = NULL;
ULONG ulRid = 0;
ULONG ulSecurityInfo = 0;
handle_t bSamr = NULL;
CONNECT_HANDLE hConn = NULL;
DOMAIN_HANDLE hDomain = NULL;
ACCOUNT_HANDLE hUser = NULL;
PSECURITY_DESCRIPTOR_RELATIVE pSecDescRel = NULL;
UINT32 ulSecDescRelLen = 0;
PSECURITY_DESCRIPTOR_ABSOLUTE pSecDesc = NULL;
ULONG ulSecDescLen = 1024;
PACL pDacl = NULL;
ULONG ulDaclLen = 1024;
PACL pSacl = NULL;
ULONG ulSaclLen = 1024;
PSID pOwnerSid = NULL;
ULONG ulOwnerSidLen = 1024;
PSID pGroupSid = NULL;
ULONG ulGroupSidLen = 1024;
TESTINFO(t, hostname, user, pass);
perr = fetch_value(options, optcount, "sid", pt_sid,
&pSid, &pszDefSidStr);
if (!perr_is_ok(perr)) perr_fail(perr);
perr = fetch_value(options, optcount, "security_info", pt_uint32,
&ulSecurityInfo, &ulDefSecurityInfo);
if (!perr_is_ok(perr)) perr_fail(perr);
ntStatus = RtlAllocateWC16StringFromSid(&pwszSidStr,
pSid);
if (ntStatus != 0) rpc_fail(ntStatus);
PARAM_INFO("sid", pt_w16string, pwszSidStr);
PARAM_INFO("security_info", pt_uint32, &ulSecurityInfo);
SET_SESSION_CREDS(hCreds);
CreateSamrBinding(&bSamr, hostname);
if (bSamr == NULL) return false;
ntStatus = SamrConnect2(bSamr,
hostname,
dwConnAccess,
&hConn);
if (ntStatus != 0) rpc_fail(ntStatus);
/* Create domain SID from account SID */
ntStatus = RtlDuplicateSid(&pDomainSid,
pSid);
if (ntStatus != 0) rpc_fail(ntStatus);
pDomainSid->SubAuthorityCount--;
ntStatus = SamrOpenDomain(bSamr,
hConn,
dwDomainAccess,
pDomainSid,
&hDomain);
if (ntStatus != 0) rpc_fail(ntStatus);
ulRid = pSid->SubAuthority[pSid->SubAuthorityCount - 1];
ntStatus = SamrOpenUser(bSamr,
hDomain,
dwUserAccess,
ulRid,
&hUser);
if (ntStatus != 0) rpc_fail(ntStatus);
ntStatus = SamrQuerySecurity(bSamr,
hUser,
ulSecurityInfo,
&pSecDescRel,
&ulSecDescRelLen);
if (ntStatus != 0) rpc_fail(ntStatus);
ulSecDescLen = 1024;
ntStatus = RTL_ALLOCATE(&pSecDesc,
VOID,
ulSecDescLen);
if (ntStatus != 0) rpc_fail(ntStatus);
ulDaclLen = 1024;
ntStatus = RTL_ALLOCATE(&pDacl,
VOID,
ulDaclLen);
if (ntStatus != 0) rpc_fail(ntStatus);
ulSaclLen = 1024;
ntStatus = RTL_ALLOCATE(&pSacl,
VOID,
ulSaclLen);
if (ntStatus != 0) rpc_fail(ntStatus);
ulOwnerSidLen = 1024;
ntStatus = RTL_ALLOCATE(&pOwnerSid,
VOID,
ulOwnerSidLen);
if (ntStatus != 0) rpc_fail(ntStatus);
ulGroupSidLen = 1024;
ntStatus = RTL_ALLOCATE(&pGroupSid,
VOID,
ulGroupSidLen);
if (ntStatus != 0) rpc_fail(ntStatus);
ntStatus = RtlSelfRelativeToAbsoluteSD(pSecDescRel,
pSecDesc,
&ulSecDescLen,
pDacl,
&ulDaclLen,
pSacl,
&ulSaclLen,
pOwnerSid,
&ulOwnerSidLen,
pGroupSid,
&ulGroupSidLen);
if (ntStatus != 0) rpc_fail(ntStatus);
ntStatus = SamrClose(bSamr, hUser);
if (ntStatus != 0) rpc_fail(ntStatus);
ntStatus = SamrClose(bSamr, hDomain);
if (ntStatus != 0) rpc_fail(ntStatus);
ntStatus = SamrClose(bSamr, hConn);
if (ntStatus != 0) rpc_fail(ntStatus);
done:
if (pSecDesc)
{
SamrFreeMemory(pSecDesc);
}
RTL_FREE(&pwszSidStr);
RTL_FREE(&pSid);
RTL_FREE(&pDomainSid);
RTL_FREE(&pSecDesc);
return (ntStatus == STATUS_SUCCESS);
}
void SetupSamrTests(struct test *t)
{
NTSTATUS status = STATUS_SUCCESS;
status = SamrInitMemory();
if (status) return;
AddTest(t, "SAMR-QUERY-USER", TestSamrQueryUser);
AddTest(t, "SAMR-QUERY-ALIAS", TestSamrQueryAlias);
AddTest(t, "SAMR-ALIAS", TestSamrAlias);
AddTest(t, "SAMR-ALIAS-MEMBERS", TestSamrUsersInAliases);
AddTest(t, "SAMR-QUERY-DOMAIN", TestSamrQueryDomain);
AddTest(t, "SAMR-ENUM-USERS", TestSamrEnumUsers);
AddTest(t, "SAMR-OPEN-DOMAIN", TestSamrOpenDomain);
AddTest(t, "SAMR-ENUM-DOMAINS", TestSamrEnumDomains);
AddTest(t, "SAMR-CREATE-USER", TestSamrCreateUserAccount);
AddTest(t, "SAMR-CREATE-ALIAS", TestSamrCreateAlias);
AddTest(t, "SAMR-CREATE-GROUP", TestSamrCreateGroup);
AddTest(t, "SAMR-USER-PASSWORD", TestSamrSetUserPassword);
AddTest(t, "SAMR-MULTIPLE-CONNECTION", TestSamrMultipleConnections);
AddTest(t, "SAMR-USER-PASSWORD-CHANGE", TestSamrChangeUserPassword);
AddTest(t, "SAMR-ENUM-ALIASES", TestSamrEnumAliases);
AddTest(t, "SAMR-GET-USER-GROUPS", TestSamrGetUserGroups);
AddTest(t, "SAMR-GET-USER-ALIASES", TestSamrGetUserAliases);
AddTest(t, "SAMR-QUERY-DISPLAY-INFO", TestSamrQueryDisplayInfo);
AddTest(t, "SAMR-CONNECT", TestSamrConnect);
AddTest(t, "SAMR-DOMAINS", TestSamrDomains);
AddTest(t, "SAMR-DOMAINS-QUERY", TestSamrDomainsQuery);
AddTest(t, "SAMR-USERS", TestSamrUsers);
AddTest(t, "SAMR-ALIASES", TestSamrAliases);
AddTest(t, "SAMR-QUERY-SECURITY", TestSamrQuerySecurity);
}
/*
local variables:
mode: c
c-basic-offset: 4
indent-tabs-mode: nil
tab-width: 4
end:
*/