[SAMLIB]: Implement SamAddMemberToAlias, SamCreateAliasInDomain, SamEnumerateDomainsInSamServer, SamOpenAlias, SamQueryInformationDomain and SamQueryInformationUser.

[SAMSRV]: Implement SamrEnumerateDomainsInSamServer (buggy, probably a bug in WIDL), SamrQueryInformationDomain.DomainNameInformation, SamrCreateAliasInDomain, SamrOpenAlias and SamrAddMemberToAlias.
[SAMSRV]: Add more registry helper routines.
[SAMSRV]: Create builtin aliases upon setup.

svn path=/trunk/; revision=56690
This commit is contained in:
Eric Kohl 2012-06-03 20:54:06 +00:00
parent 769eb79128
commit f82ab0c4b0
8 changed files with 847 additions and 43 deletions

View file

@ -103,6 +103,31 @@ PSAMPR_SERVER_NAME_unbind(PSAMPR_SERVER_NAME pszSystemName,
}
NTSTATUS
NTAPI
SamAddMemberToAlias(IN SAM_HANDLE AliasHandle,
IN PSID MemberId)
{
NTSTATUS Status;
TRACE("SamAddMemberToAlias(%p %p)\n",
AliasHandle, MemberId);
RpcTryExcept
{
Status = SamrAddMemberToAlias((SAMPR_HANDLE)AliasHandle,
(PRPC_SID)MemberId);
}
RpcExcept(EXCEPTION_EXECUTE_HANDLER)
{
Status = I_RpcMapWin32Status(RpcExceptionCode());
}
RpcEndExcept;
return Status;
}
NTSTATUS
NTAPI
SamCloseHandle(IN SAM_HANDLE SamHandle)
@ -153,6 +178,37 @@ SamConnect(IN OUT PUNICODE_STRING ServerName,
}
NTSTATUS
NTAPI
SamCreateAliasInDomain(IN SAM_HANDLE DomainHandle,
IN PUNICODE_STRING AccountName,
IN ACCESS_MASK DesiredAccess,
OUT PSAM_HANDLE AliasHandle,
OUT PULONG RelativeId)
{
NTSTATUS Status;
TRACE("SamCreateAliasInDomain(%p,%p,0x%08x,%p,%p)\n",
DomainHandle, AccountName, DesiredAccess, AliasHandle, RelativeId);
RpcTryExcept
{
Status = SamrCreateAliasInDomain((SAMPR_HANDLE)DomainHandle,
(PRPC_UNICODE_STRING)AccountName,
DesiredAccess,
(SAMPR_HANDLE *)AliasHandle,
RelativeId);
}
RpcExcept(EXCEPTION_EXECUTE_HANDLER)
{
Status = I_RpcMapWin32Status(RpcExceptionCode());
}
RpcEndExcept;
return Status;
}
NTSTATUS
NTAPI
SamCreateUserInDomain(IN SAM_HANDLE DomainHandle,
@ -184,11 +240,61 @@ SamCreateUserInDomain(IN SAM_HANDLE DomainHandle,
}
NTSTATUS
NTAPI
SamEnumerateDomainsInSamServer(IN SAM_HANDLE ServerHandle,
IN OUT PSAM_ENUMERATE_HANDLE EnumerationContext,
OUT PVOID *Buffer,
IN ULONG PreferedMaximumLength,
OUT PULONG CountReturned)
{
PSAMPR_ENUMERATION_BUFFER EnumBuffer = NULL;
NTSTATUS Status;
TRACE("SamEnumerateDomainsInSamServer(%p,%p,%p,%lu,%p)\n",
ServerHandle, EnumerationContext, Buffer, PreferedMaximumLength,
CountReturned);
if ((EnumerationContext == NULL) ||
(Buffer == NULL) ||
(CountReturned == NULL))
return STATUS_INVALID_PARAMETER;
*Buffer = NULL;
RpcTryExcept
{
Status = SamrEnumerateDomainsInSamServer((SAMPR_HANDLE)ServerHandle,
EnumerationContext,
(PSAMPR_ENUMERATION_BUFFER *)&EnumBuffer,
PreferedMaximumLength,
CountReturned);
if (EnumBuffer != NULL)
{
if (EnumBuffer->Buffer != NULL)
{
*Buffer = EnumBuffer->Buffer;
}
midl_user_free(EnumBuffer);
}
}
RpcExcept(EXCEPTION_EXECUTE_HANDLER)
{
Status = I_RpcMapWin32Status(RpcExceptionCode());
}
RpcEndExcept;
return Status;
}
NTSTATUS
NTAPI
SamFreeMemory(IN PVOID Buffer)
{
if (Buffer!= NULL)
if (Buffer != NULL)
midl_user_free(Buffer);
return STATUS_SUCCESS;
@ -222,6 +328,35 @@ SamLookupDomainInSamServer(IN SAM_HANDLE ServerHandle,
}
NTSTATUS
NTAPI
SamOpenAlias(IN SAM_HANDLE DomainHandle,
IN ACCESS_MASK DesiredAccess,
IN ULONG AliasId,
OUT PSAM_HANDLE AliasHandle)
{
NTSTATUS Status;
TRACE("SamOpenAlias(%p 0x%08x %lx %p)\n",
DomainHandle, DesiredAccess, AliasId, AliasHandle);
RpcTryExcept
{
Status = SamrOpenAlias((SAMPR_HANDLE)DomainHandle,
DesiredAccess,
AliasId,
(SAMPR_HANDLE *)AliasHandle);
}
RpcExcept(EXCEPTION_EXECUTE_HANDLER)
{
Status = I_RpcMapWin32Status(RpcExceptionCode());
}
RpcEndExcept;
return Status;
}
NTSTATUS
NTAPI
SamOpenDomain(IN SAM_HANDLE ServerHandle,
@ -280,14 +415,57 @@ SamOpenUser(IN SAM_HANDLE DomainHandle,
}
NTSTATUS
NTAPI
SamQueryInformationDomain(IN SAM_HANDLE DomainHandle,
IN DOMAIN_INFORMATION_CLASS DomainInformationClass,
OUT PVOID *Buffer)
{
NTSTATUS Status;
TRACE("SamQueryInformationDomain(%p %lu %p)\n",
DomainHandle, DomainInformationClass, Buffer);
RpcTryExcept
{
Status = SamrQueryInformationDomain((SAMPR_HANDLE)DomainHandle,
DomainInformationClass,
(PSAMPR_DOMAIN_INFO_BUFFER *)Buffer);
}
RpcExcept(EXCEPTION_EXECUTE_HANDLER)
{
Status = I_RpcMapWin32Status(RpcExceptionCode());
}
RpcEndExcept;
return Status;
}
NTSTATUS
NTAPI
SamQueryInformationUser(IN SAM_HANDLE UserHandle,
IN USER_INFORMATION_CLASS UserInformationClass,
OUT PVOID *Buffer)
{
UNIMPLEMENTED;
return STATUS_NOT_IMPLEMENTED;
NTSTATUS Status;
TRACE("SamQueryInformationUser(%p %lu %p)\n",
UserHandle, UserInformationClass, Buffer);
RpcTryExcept
{
Status = SamrQueryInformationUser((SAMPR_HANDLE)UserHandle,
UserInformationClass,
(PSAMPR_USER_INFO_BUFFER *)Buffer);
}
RpcExcept(EXCEPTION_EXECUTE_HANDLER)
{
Status = I_RpcMapWin32Status(RpcExceptionCode());
}
RpcEndExcept;
return Status;
}
@ -349,6 +527,7 @@ NTSTATUS
NTAPI
SamShutdownSamServer(IN SAM_HANDLE ServerHandle)
{
UNIMPLEMENTED;
return STATUS_NOT_IMPLEMENTED;
}

View file

@ -1,4 +1,4 @@
@ stub SamAddMemberToAlias
@ stdcall SamAddMemberToAlias(ptr ptr)
@ stub SamAddMemberToGroup
@ stub SamAddMultipleMembersToAlias
@ stub SamChangePasswordUser2
@ -7,7 +7,7 @@
@ stdcall SamCloseHandle(ptr)
@ stdcall SamConnect(ptr ptr long ptr)
@ stub SamConnectWithCreds
@ stub SamCreateAliasInDomain
@ stdcall SamCreateAliasInDomain(ptr ptr long ptr ptr)
@ stub SamCreateGroupInDomain
@ stub SamCreateUser2InDomain
@ stdcall SamCreateUserInDomain(ptr ptr long ptr ptr)
@ -15,7 +15,7 @@
@ stub SamDeleteGroup
@ stub SamDeleteUser
@ stub SamEnumerateAliasesInDomain
@ stub SamEnumerateDomainsInSamServer
@ stdcall SamEnumerateDomainsInSamServer(ptr ptr ptr long ptr)
@ stub SamEnumerateGroupsInDomain
@ stub SamEnumerateUsersInDomain
@ stdcall SamFreeMemory(ptr)
@ -28,13 +28,13 @@
@ stdcall SamLookupDomainInSamServer(ptr ptr ptr)
@ stub SamLookupIdsInDomain
@ stub SamLookupNamesInDomain
@ stub SamOpenAlias
@ stdcall SamOpenAlias(ptr long long ptr)
@ stdcall SamOpenDomain(ptr long ptr ptr)
@ stub SamOpenGroup
@ stdcall SamOpenUser(ptr long long ptr)
@ stub SamQueryDisplayInformation
@ stub SamQueryInformationAlias
@ stub SamQueryInformationDomain
@ stdcall SamQueryInformationDomain(ptr long ptr)
@ stub SamQueryInformationGroup
@ stdcall SamQueryInformationUser(ptr long ptr)
@ stub SamQuerySecurityObject

View file

@ -16,7 +16,42 @@ WINE_DEFAULT_DEBUG_CHANNEL(samsrv);
/* FUNCTIONS ***************************************************************/
NTSTATUS
NTAPI
SampRegCloseKey(IN HANDLE KeyHandle)
{
return NtClose(KeyHandle);
}
NTSTATUS
SampRegCreateKey(IN HANDLE ParentKeyHandle,
IN LPCWSTR KeyName,
IN ACCESS_MASK DesiredAccess,
OUT HANDLE KeyHandle)
{
OBJECT_ATTRIBUTES ObjectAttributes;
UNICODE_STRING Name;
ULONG Disposition;
RtlInitUnicodeString(&Name, KeyName);
InitializeObjectAttributes(&ObjectAttributes,
&Name,
OBJ_CASE_INSENSITIVE | OBJ_OPENIF,
ParentKeyHandle,
NULL);
/* Create the key */
return ZwCreateKey(KeyHandle,
DesiredAccess,
&ObjectAttributes,
0,
NULL,
0,
&Disposition);
}
NTSTATUS
SampRegEnumerateSubKey(IN HANDLE KeyHandle,
IN ULONG Index,
IN ULONG Length,
@ -74,7 +109,6 @@ SampRegEnumerateSubKey(IN HANDLE KeyHandle,
NTSTATUS
NTAPI
SampRegOpenKey(IN HANDLE ParentKeyHandle,
IN LPCWSTR KeyName,
IN ACCESS_MASK DesiredAccess,
@ -171,5 +205,8 @@ SampRegQueryValue(HANDLE KeyHandle,
/* Free the memory and return status */
RtlFreeHeap(RtlGetProcessHeap(), 0, ValueInfo);
if ((Data == NULL) && (Status == STATUS_BUFFER_OVERFLOW))
Status = STATUS_SUCCESS;
return Status;
}

View file

@ -269,11 +269,201 @@ NTAPI
SamrEnumerateDomainsInSamServer(IN SAMPR_HANDLE ServerHandle,
IN OUT unsigned long *EnumerationContext,
OUT PSAMPR_ENUMERATION_BUFFER *Buffer,
IN unsigned long PreferedMaximumLength,
OUT unsigned long *CountReturned)
IN ULONG PreferedMaximumLength,
OUT PULONG CountReturned)
{
UNIMPLEMENTED;
return STATUS_NOT_IMPLEMENTED;
PSAM_DB_OBJECT ServerObject;
WCHAR DomainKeyName[64];
HANDLE DomainsKeyHandle;
HANDLE DomainKeyHandle;
ULONG EnumIndex;
ULONG EnumCount;
ULONG RequiredLength;
ULONG DataLength;
ULONG i;
PSAMPR_ENUMERATION_BUFFER EnumBuffer = NULL;
NTSTATUS Status;
TRACE("SamrEnumerateDomainsInSamServer(%p %p %p %lu %p)\n",
ServerHandle, EnumerationContext, Buffer, PreferedMaximumLength,
CountReturned);
/* Validate the server handle */
Status = SampValidateDbObject(ServerHandle,
SamDbServerObject,
SAM_SERVER_ENUMERATE_DOMAINS,
&ServerObject);
if (!NT_SUCCESS(Status))
return Status;
Status = SampRegOpenKey(ServerObject->KeyHandle,
L"Domains",
KEY_READ,
&DomainsKeyHandle);
if (!NT_SUCCESS(Status))
return Status;
EnumIndex = *EnumerationContext;
EnumCount = 0;
RequiredLength = 0;
while (TRUE)
{
Status = SampRegEnumerateSubKey(DomainsKeyHandle,
EnumIndex,
64 * sizeof(WCHAR),
DomainKeyName);
if (!NT_SUCCESS(Status))
break;
TRACE("EnumIndex: %lu\n", EnumIndex);
TRACE("Domain key name: %S\n", DomainKeyName);
Status = SampRegOpenKey(DomainsKeyHandle,
DomainKeyName,
KEY_READ,
&DomainKeyHandle);
TRACE("SampRegOpenKey returned %08lX\n", Status);
if (NT_SUCCESS(Status))
{
DataLength = 0;
Status = SampRegQueryValue(DomainKeyHandle,
L"Name",
NULL,
NULL,
&DataLength);
TRACE("SampRegQueryValue returned %08lX\n", Status);
if (NT_SUCCESS(Status))
{
TRACE("Data length: %lu\n", DataLength);
if ((RequiredLength + DataLength + sizeof(UNICODE_STRING)) > PreferedMaximumLength)
break;
RequiredLength += (DataLength + sizeof(UNICODE_STRING));
EnumCount++;
}
NtClose(DomainKeyHandle);
}
EnumIndex++;
}
TRACE("EnumCount: %lu\n", EnumCount);
TRACE("RequiredLength: %lu\n", RequiredLength);
EnumBuffer = midl_user_allocate(sizeof(SAMPR_ENUMERATION_BUFFER));
if (EnumBuffer == NULL)
{
Status = STATUS_INSUFFICIENT_RESOURCES;
goto done;
}
EnumBuffer->EntriesRead = EnumCount;
EnumBuffer->Buffer = midl_user_allocate(EnumCount * sizeof(SAMPR_RID_ENUMERATION));
if (EnumBuffer->Buffer == NULL)
{
Status = STATUS_INSUFFICIENT_RESOURCES;
goto done;
}
EnumIndex = *EnumerationContext;
for (i = 0; i < EnumCount; i++, EnumIndex++)
{
Status = SampRegEnumerateSubKey(DomainsKeyHandle,
EnumIndex,
64 * sizeof(WCHAR),
DomainKeyName);
if (!NT_SUCCESS(Status))
break;
TRACE("EnumIndex: %lu\n", EnumIndex);
TRACE("Domain key name: %S\n", DomainKeyName);
Status = SampRegOpenKey(DomainsKeyHandle,
DomainKeyName,
KEY_READ,
&DomainKeyHandle);
TRACE("SampRegOpenKey returned %08lX\n", Status);
if (NT_SUCCESS(Status))
{
DataLength = 0;
Status = SampRegQueryValue(DomainKeyHandle,
L"Name",
NULL,
NULL,
&DataLength);
TRACE("SampRegQueryValue returned %08lX\n", Status);
if (NT_SUCCESS(Status))
{
EnumBuffer->Buffer[i].RelativeId = 0;
EnumBuffer->Buffer[i].Name.Length = (USHORT)DataLength - sizeof(WCHAR);
EnumBuffer->Buffer[i].Name.MaximumLength = (USHORT)DataLength;
EnumBuffer->Buffer[i].Name.Buffer = midl_user_allocate(DataLength);
if (EnumBuffer->Buffer[i].Name.Buffer == NULL)
{
NtClose(DomainKeyHandle);
Status = STATUS_INSUFFICIENT_RESOURCES;
goto done;
}
Status = SampRegQueryValue(DomainKeyHandle,
L"Name",
NULL,
EnumBuffer->Buffer[i].Name.Buffer,
&DataLength);
TRACE("SampRegQueryValue returned %08lX\n", Status);
if (NT_SUCCESS(Status))
{
TRACE("Domain name: %S\n", EnumBuffer->Buffer[i].Name.Buffer);
}
}
NtClose(DomainKeyHandle);
if (!NT_SUCCESS(Status))
goto done;
}
}
if (NT_SUCCESS(Status))
{
*EnumerationContext += EnumCount;
*Buffer = EnumBuffer;
*CountReturned = EnumCount;
}
done:
if (!NT_SUCCESS(Status))
{
*EnumerationContext = 0;
*Buffer = NULL;
*CountReturned = 0;
if (EnumBuffer != NULL)
{
if (EnumBuffer->Buffer != NULL)
{
if (EnumBuffer->EntriesRead != 0)
{
for (i = 0; i < EnumBuffer->EntriesRead; i++)
{
if (EnumBuffer->Buffer[i].Name.Buffer != NULL)
midl_user_free(EnumBuffer->Buffer[i].Name.Buffer);
}
}
midl_user_free(EnumBuffer->Buffer);
}
midl_user_free(EnumBuffer);
}
}
NtClose(DomainsKeyHandle);
return Status;
}
/* Function 7 */
@ -348,6 +538,64 @@ SamrOpenDomain(IN SAMPR_HANDLE ServerHandle,
return Status;
}
static NTSTATUS
SampQueryDomainName(PSAM_DB_OBJECT DomainObject,
PSAMPR_DOMAIN_INFO_BUFFER *Buffer)
{
PSAMPR_DOMAIN_INFO_BUFFER InfoBuffer = NULL;
ULONG Length = 0;
NTSTATUS Status;
*Buffer = NULL;
InfoBuffer = midl_user_allocate(sizeof(SAMPR_DOMAIN_INFO_BUFFER));
if (InfoBuffer == NULL)
return STATUS_INSUFFICIENT_RESOURCES;
Status = SampGetObjectAttribute(DomainObject,
L"Name",
NULL,
NULL,
&Length);
if (!NT_SUCCESS(Status))
goto done;
InfoBuffer->Name.DomainName.Length = Length - sizeof(WCHAR);
InfoBuffer->Name.DomainName.MaximumLength = Length;
InfoBuffer->Name.DomainName.Buffer = midl_user_allocate(Length);
if (InfoBuffer->Name.DomainName.Buffer == NULL)
{
Status = STATUS_INSUFFICIENT_RESOURCES;
goto done;
}
Status = SampGetObjectAttribute(DomainObject,
L"Name",
NULL,
(PVOID)InfoBuffer->Name.DomainName.Buffer,
&Length);
if (!NT_SUCCESS(Status))
goto done;
*Buffer = InfoBuffer;
done:
if (!NT_SUCCESS(Status))
{
if (InfoBuffer != NULL)
{
if (InfoBuffer->Name.DomainName.Buffer != NULL)
midl_user_free(InfoBuffer->Name.DomainName.Buffer);
midl_user_free(InfoBuffer);
}
}
return Status;
}
/* Function 8 */
NTSTATUS
NTAPI
@ -355,8 +603,32 @@ SamrQueryInformationDomain(IN SAMPR_HANDLE DomainHandle,
IN DOMAIN_INFORMATION_CLASS DomainInformationClass,
OUT PSAMPR_DOMAIN_INFO_BUFFER *Buffer)
{
UNIMPLEMENTED;
return STATUS_NOT_IMPLEMENTED;
PSAM_DB_OBJECT DomainObject;
NTSTATUS Status;
TRACE("SamrQueryInformationDomain(%p %lu %p)\n",
DomainHandle, DomainInformationClass, Buffer);
/* Validate the server handle */
Status = SampValidateDbObject(DomainHandle,
SamDbDomainObject,
DOMAIN_READ_OTHER_PARAMETERS,
&DomainObject);
if (!NT_SUCCESS(Status))
return Status;
switch (DomainInformationClass)
{
case DomainNameInformation:
Status = SampQueryDomainName(DomainObject,
Buffer);
break;
default:
Status = STATUS_NOT_IMPLEMENTED;
}
return Status;
}
static NTSTATUS
@ -399,7 +671,7 @@ SamrSetInformationDomain(IN SAMPR_HANDLE DomainHandle,
{
case DomainNameInformation:
Status = SampSetDomainName(DomainObject,
(PSAMPR_DOMAIN_NAME_INFORMATION)DomainInformation);
&DomainInformation->Name);
break;
default:
@ -579,8 +851,116 @@ SamrCreateAliasInDomain(IN SAMPR_HANDLE DomainHandle,
OUT SAMPR_HANDLE *AliasHandle,
OUT unsigned long *RelativeId)
{
UNIMPLEMENTED;
return STATUS_NOT_IMPLEMENTED;
PSAM_DB_OBJECT DomainObject;
PSAM_DB_OBJECT AliasObject;
ULONG ulSize;
ULONG ulRid;
WCHAR szRid[9];
BOOL bAliasExists = FALSE;
NTSTATUS Status;
TRACE("SamrCreateAliasInDomain(%p %p %lx %p %p)\n",
DomainHandle, AccountName, DesiredAccess, AliasHandle, RelativeId);
/* Validate the domain handle */
Status = SampValidateDbObject(DomainHandle,
SamDbDomainObject,
DOMAIN_CREATE_ALIAS,
&DomainObject);
if (!NT_SUCCESS(Status))
{
TRACE("failed with status 0x%08lx\n", Status);
return Status;
}
/* Get the NextRID attribute */
ulSize = sizeof(ULONG);
Status = SampGetObjectAttribute(DomainObject,
L"NextRID",
NULL,
(LPVOID)&ulRid,
&ulSize);
if (!NT_SUCCESS(Status))
ulRid = DOMAIN_USER_RID_MAX + 1;
TRACE("RID: %lx\n", ulRid);
/* Convert the RID into a string (hex) */
swprintf(szRid, L"%08lX", ulRid);
/* Check whether the user name is already in use */
Status = SampCheckDbObjectNameAlias(DomainObject,
L"Aliases",
AccountName->Buffer,
&bAliasExists);
if (!NT_SUCCESS(Status))
{
TRACE("failed with status 0x%08lx\n", Status);
return Status;
}
if (bAliasExists)
{
TRACE("The alias account %S already exists!\n", AccountName->Buffer);
return STATUS_ALIAS_EXISTS;
}
/* Create the user object */
Status = SampCreateDbObject(DomainObject,
L"Aliases",
szRid,
SamDbAliasObject,
DesiredAccess,
&AliasObject);
if (!NT_SUCCESS(Status))
{
TRACE("failed with status 0x%08lx\n", Status);
return Status;
}
/* Add the name alias for the user object */
Status = SampSetDbObjectNameAlias(DomainObject,
L"Aliases",
AccountName->Buffer,
ulRid);
if (!NT_SUCCESS(Status))
{
TRACE("failed with status 0x%08lx\n", Status);
return Status;
}
/* Set the name attribute */
Status = SampSetObjectAttribute(AliasObject,
L"Name",
REG_SZ,
(LPVOID)AccountName->Buffer,
AccountName->MaximumLength);
if (!NT_SUCCESS(Status))
{
TRACE("failed with status 0x%08lx\n", Status);
return Status;
}
/* FIXME: Set default alias attributes */
if (NT_SUCCESS(Status))
{
*AliasHandle = (SAMPR_HANDLE)AliasObject;
*RelativeId = ulRid;
}
/* Increment the NextRID attribute */
ulRid++;
ulSize = sizeof(ULONG);
SampSetObjectAttribute(DomainObject,
L"NextRID",
REG_DWORD,
(LPVOID)&ulRid,
ulSize);
TRACE("returns with status 0x%08lx\n", Status);
return Status;
}
/* Function 15 */
@ -723,11 +1103,47 @@ NTSTATUS
NTAPI
SamrOpenAlias(IN SAMPR_HANDLE DomainHandle,
IN ACCESS_MASK DesiredAccess,
IN unsigned long AliasId,
IN ULONG AliasId,
OUT SAMPR_HANDLE *AliasHandle)
{
UNIMPLEMENTED;
return STATUS_NOT_IMPLEMENTED;
PSAM_DB_OBJECT DomainObject;
PSAM_DB_OBJECT AliasObject;
WCHAR szRid[9];
NTSTATUS Status;
TRACE("SamrOpenAlias(%p %lx %lx %p)\n",
DomainHandle, DesiredAccess, AliasId, AliasHandle);
/* Validate the domain handle */
Status = SampValidateDbObject(DomainHandle,
SamDbDomainObject,
DOMAIN_LOOKUP,
&DomainObject);
if (!NT_SUCCESS(Status))
{
TRACE("failed with status 0x%08lx\n", Status);
return Status;
}
/* Convert the RID into a string (hex) */
swprintf(szRid, L"%08lX", AliasId);
/* Create the alias object */
Status = SampOpenDbObject(DomainObject,
L"Aliases",
szRid,
SamDbAliasObject,
DesiredAccess,
&AliasObject);
if (!NT_SUCCESS(Status))
{
TRACE("failed with status 0x%08lx\n", Status);
return Status;
}
*AliasHandle = (SAMPR_HANDLE)AliasObject;
return STATUS_SUCCESS;
}
/* Function 28 */
@ -767,8 +1183,52 @@ NTAPI
SamrAddMemberToAlias(IN SAMPR_HANDLE AliasHandle,
IN PRPC_SID MemberId)
{
UNIMPLEMENTED;
return STATUS_NOT_IMPLEMENTED;
PSAM_DB_OBJECT AliasObject;
LPWSTR MemberIdString = NULL;
HANDLE MembersKeyHandle = NULL;
NTSTATUS Status;
TRACE("SamrAddMemberToAlias(%p %p)\n",
AliasHandle, MemberId);
/* Validate the domain handle */
Status = SampValidateDbObject(AliasHandle,
SamDbAliasObject,
ALIAS_ADD_MEMBER,
&AliasObject);
if (!NT_SUCCESS(Status))
{
TRACE("failed with status 0x%08lx\n", Status);
return Status;
}
ConvertSidToStringSidW(MemberId, &MemberIdString);
TRACE("Member SID: %S\n", MemberIdString);
Status = SampRegCreateKey(AliasObject->KeyHandle,
L"Members",
KEY_WRITE,
&MembersKeyHandle);
if (!NT_SUCCESS(Status))
{
TRACE("SampRegCreateKey failed with status 0x%08lx\n", Status);
goto done;
}
Status = SampRegSetValue(MembersKeyHandle,
MemberIdString,
REG_BINARY,
NULL,
0);
done:
if (MembersKeyHandle != NULL)
SampRegCloseKey(MembersKeyHandle);
if (MemberIdString != NULL)
LocalFree(MemberIdString);
return Status;
}
/* Function 32 */

View file

@ -17,6 +17,7 @@
#include <ndk/umtypes.h>
#include <ddk/ntsam.h>
#include <ntsecapi.h>
#include <sddl.h>
#include <samsrv/samsrv.h>
@ -105,14 +106,21 @@ SampGetObjectAttribute(PSAM_DB_OBJECT DbObject,
/* registry.h */
NTSTATUS
NTAPI
SampRegCloseKey(IN HANDLE KeyHandle);
NTSTATUS
SampRegCreateKey(IN HANDLE ParentKeyHandle,
IN LPCWSTR KeyName,
IN ACCESS_MASK DesiredAccess,
OUT HANDLE KeyHandle);
NTSTATUS
SampRegEnumerateSubKey(IN HANDLE KeyHandle,
IN ULONG Index,
IN ULONG Length,
OUT LPWSTR Buffer);
NTSTATUS
NTAPI
SampRegOpenKey(IN HANDLE ParentKeyHandle,
IN LPCWSTR KeyName,
IN ACCESS_MASK DesiredAccess,

View file

@ -59,35 +59,87 @@ SampIsSetupRunning(VOID)
static BOOL
SampCreateUserAccount(HKEY hDomainKey,
LPCWSTR lpAccountName,
ULONG ulRelativeId)
SampCreateAliasAccount(HKEY hDomainKey,
LPCWSTR lpAccountName,
ULONG ulRelativeId)
{
DWORD dwDisposition;
WCHAR szUserKeyName[32];
HKEY hUserKey = NULL;
WCHAR szAccountKeyName[32];
HKEY hAccountKey = NULL;
HKEY hNamesKey = NULL;
swprintf(szUserKeyName, L"Users\\%08lX", ulRelativeId);
swprintf(szAccountKeyName, L"Aliases\\%08lX", ulRelativeId);
if (!RegCreateKeyExW(hDomainKey,
szUserKeyName,
szAccountKeyName,
0,
NULL,
REG_OPTION_NON_VOLATILE,
KEY_ALL_ACCESS,
NULL,
&hUserKey,
&hAccountKey,
&dwDisposition))
{
RegSetValueEx(hUserKey,
RegSetValueEx(hAccountKey,
L"Name",
0,
REG_SZ,
(LPVOID)lpAccountName,
(wcslen(lpAccountName) + 1) * sizeof(WCHAR));
RegCloseKey(hUserKey);
RegCloseKey(hAccountKey);
}
if (!RegOpenKeyExW(hDomainKey,
L"Aliases\\Names",
0,
KEY_ALL_ACCESS,
&hNamesKey))
{
RegSetValueEx(hNamesKey,
lpAccountName,
0,
REG_DWORD,
(LPVOID)&ulRelativeId,
sizeof(ULONG));
RegCloseKey(hNamesKey);
}
return TRUE;
}
static BOOL
SampCreateUserAccount(HKEY hDomainKey,
LPCWSTR lpAccountName,
ULONG ulRelativeId)
{
DWORD dwDisposition;
WCHAR szAccountKeyName[32];
HKEY hAccountKey = NULL;
HKEY hNamesKey = NULL;
swprintf(szAccountKeyName, L"Users\\%08lX", ulRelativeId);
if (!RegCreateKeyExW(hDomainKey,
szAccountKeyName,
0,
NULL,
REG_OPTION_NON_VOLATILE,
KEY_ALL_ACCESS,
NULL,
&hAccountKey,
&dwDisposition))
{
RegSetValueEx(hAccountKey,
L"Name",
0,
REG_SZ,
(LPVOID)lpAccountName,
(wcslen(lpAccountName) + 1) * sizeof(WCHAR));
RegCloseKey(hAccountKey);
}
if (!RegOpenKeyExW(hDomainKey,
@ -119,7 +171,7 @@ SampCreateDomain(IN HKEY hDomainsKey,
{
DWORD dwDisposition;
HKEY hDomainKey = NULL;
HKEY hAliasKey = NULL;
HKEY hAliasesKey = NULL;
HKEY hGroupsKey = NULL;
HKEY hUsersKey = NULL;
HKEY hNamesKey = NULL;
@ -157,16 +209,16 @@ SampCreateDomain(IN HKEY hDomainsKey,
/* Create the Alias container */
if (!RegCreateKeyExW(hDomainKey,
L"Alias",
L"Aliases",
0,
NULL,
REG_OPTION_NON_VOLATILE,
KEY_ALL_ACCESS,
NULL,
&hAliasKey,
&hAliasesKey,
&dwDisposition))
{
if (!RegCreateKeyExW(hAliasKey,
if (!RegCreateKeyExW(hAliasesKey,
L"Names",
0,
NULL,
@ -177,7 +229,7 @@ SampCreateDomain(IN HKEY hDomainsKey,
&dwDisposition))
RegCloseKey(hNamesKey);
RegCloseKey(hAliasKey);
RegCloseKey(hAliasesKey);
}
/* Create the Groups container */
@ -344,6 +396,21 @@ SampInitializeSAM(VOID)
pBuiltinSid,
&hDomainKey))
{
SampCreateAliasAccount(hDomainKey,
L"Administrators",
DOMAIN_ALIAS_RID_ADMINS);
SampCreateAliasAccount(hDomainKey,
L"Users",
DOMAIN_ALIAS_RID_USERS);
SampCreateAliasAccount(hDomainKey,
L"Guests",
DOMAIN_ALIAS_RID_GUESTS);
SampCreateAliasAccount(hDomainKey,
L"Power Users",
DOMAIN_ALIAS_RID_POWER_USERS);
RegCloseKey(hDomainKey);
}

View file

@ -6,6 +6,12 @@
extern "C" {
#endif
#define ALIAS_ADD_MEMBER 1
#define ALIAS_REMOVE_MEMBER 2
#define ALIAS_LIST_MEMBERS 4
#define ALIAS_READ_INFORMATION 8
#define ALIAS_WRITE_ACCOUNT 16
#define DOMAIN_READ_PASSWORD_PARAMETERS 1
#define DOMAIN_WRITE_PASSWORD_PARAMS 2
#define DOMAIN_READ_OTHER_PARAMETERS 4
@ -38,6 +44,19 @@ extern "C" {
#define USER_WRITE_GROUP_INFORMATION 1024
typedef PVOID SAM_HANDLE, *PSAM_HANDLE;
typedef ULONG SAM_ENUMERATE_HANDLE, *PSAM_ENUMERATE_HANDLE;
typedef struct _SAM_RID_ENUMERATION
{
ULONG RelativeId;
UNICODE_STRING Name;
} SAM_RID_ENUMERATION, *PSAM_RID_ENUMERATION;
typedef struct _SAM_SID_ENUMERATION
{
PSID Sid;
UNICODE_STRING Name;
} SAM_SID_ENUMERATION, *PSAM_SID_ENUMERATION;
typedef enum _DOMAIN_INFORMATION_CLASS
{
@ -101,6 +120,11 @@ typedef struct _USER_SET_PASSWORD_INFORMATION
} USER_SET_PASSWORD_INFORMATION, *PUSER_SET_PASSWORD_INFORMATION;
NTSTATUS
NTAPI
SamAddMemberToAlias(IN SAM_HANDLE AliasHandle,
IN PSID MemberId);
NTSTATUS
NTAPI
SamCloseHandle(IN SAM_HANDLE SamHandle);
@ -112,6 +136,14 @@ SamConnect(IN OUT PUNICODE_STRING ServerName,
IN ACCESS_MASK DesiredAccess,
IN POBJECT_ATTRIBUTES ObjectAttributes);
NTSTATUS
NTAPI
SamCreateAliasInDomain(IN SAM_HANDLE DomainHandle,
IN PUNICODE_STRING AccountName,
IN ACCESS_MASK DesiredAccess,
OUT PSAM_HANDLE AliasHandle,
OUT PULONG RelativeId);
NTSTATUS
NTAPI
SamCreateUserInDomain(IN SAM_HANDLE DomainHandle,
@ -120,6 +152,14 @@ SamCreateUserInDomain(IN SAM_HANDLE DomainHandle,
OUT PSAM_HANDLE UserHandle,
OUT PULONG RelativeId);
NTSTATUS
NTAPI
SamEnumerateDomainsInSamServer(IN SAM_HANDLE ServerHandle,
IN OUT PSAM_ENUMERATE_HANDLE EnumerationContext,
OUT PVOID *Buffer,
IN ULONG PreferedMaximumLength,
OUT PULONG CountReturned);
NTSTATUS
NTAPI
SamFreeMemory(IN PVOID Buffer);
@ -130,6 +170,13 @@ SamLookupDomainInSamServer(IN SAM_HANDLE ServerHandle,
IN PUNICODE_STRING Name,
OUT PSID *DomainId);
NTSTATUS
NTAPI
SamOpenAlias(IN SAM_HANDLE DomainHandle,
IN ACCESS_MASK DesiredAccess,
IN ULONG AliasId,
OUT PSAM_HANDLE AliasHandle);
NTSTATUS
NTAPI
SamOpenDomain(IN SAM_HANDLE ServerHandle,
@ -144,6 +191,12 @@ SamOpenUser(IN SAM_HANDLE DomainHandle,
IN ULONG UserId,
OUT PSAM_HANDLE UserHandle);
NTSTATUS
NTAPI
SamQueryInformationDomain(IN SAM_HANDLE DomainHandle,
IN DOMAIN_INFORMATION_CLASS DomainInformationClass,
OUT PVOID *Buffer);
NTSTATUS
NTAPI
SamQueryInformationUser(IN SAM_HANDLE UserHandle,

View file

@ -1036,7 +1036,7 @@ interface samr
SamrOpenAlias(
[in] SAMPR_HANDLE DomainHandle,
[in] ACCESS_MASK DesiredAccess,
[in] unsigned long AliasId,
[in] ULONG AliasId,
[out] SAMPR_HANDLE *AliasHandle);
/* Function 28 */
@ -1088,7 +1088,7 @@ interface samr
SamrOpenUser(
[in] SAMPR_HANDLE DomainHandle,
[in] ACCESS_MASK DesiredAccess,
[in] unsigned long UserId,
[in] ULONG UserId,
[out] SAMPR_HANDLE *UserHandle);
/* Function 35 */