SAMLIB: Implement SamCreateGroupInDoamin and SamOpenGroup.

SAMSRV: Implement SamrCreateGroupInDomain and SamrOpenGroup.

svn path=/trunk/; revision=56896
This commit is contained in:
Eric Kohl 2012-07-15 13:35:40 +00:00
parent 46d2d14cb4
commit 0f649c901a
7 changed files with 436 additions and 10 deletions

View file

@ -209,6 +209,37 @@ SamCreateAliasInDomain(IN SAM_HANDLE DomainHandle,
}
NTSTATUS
NTAPI
SamCreateGroupInDomain(IN SAM_HANDLE DomainHandle,
IN PUNICODE_STRING AccountName,
IN ACCESS_MASK DesiredAccess,
OUT PSAM_HANDLE GroupHandle,
OUT PULONG RelativeId)
{
NTSTATUS Status;
TRACE("SamCreateGroupInDomain(%p,%p,0x%08x,%p,%p)\n",
DomainHandle, AccountName, DesiredAccess, GroupHandle, RelativeId);
RpcTryExcept
{
Status = SamrCreateGroupInDomain((SAMPR_HANDLE)DomainHandle,
(PRPC_UNICODE_STRING)AccountName,
DesiredAccess,
(SAMPR_HANDLE *)GroupHandle,
RelativeId);
}
RpcExcept(EXCEPTION_EXECUTE_HANDLER)
{
Status = I_RpcMapWin32Status(RpcExceptionCode());
}
RpcEndExcept;
return Status;
}
NTSTATUS
NTAPI
SamCreateUserInDomain(IN SAM_HANDLE DomainHandle,
@ -542,6 +573,35 @@ SamOpenDomain(IN SAM_HANDLE ServerHandle,
}
NTSTATUS
NTAPI
SamOpenGroup(IN SAM_HANDLE DomainHandle,
IN ACCESS_MASK DesiredAccess,
IN ULONG GroupId,
OUT PSAM_HANDLE GroupHandle)
{
NTSTATUS Status;
TRACE("SamOpenGroup(%p,0x%08x,%p,%p)\n",
DomainHandle, DesiredAccess, GroupId, GroupHandle);
RpcTryExcept
{
Status = SamrOpenGroup((SAMPR_HANDLE)DomainHandle,
DesiredAccess,
GroupId,
(SAMPR_HANDLE *)GroupHandle);
}
RpcExcept(EXCEPTION_EXECUTE_HANDLER)
{
Status = I_RpcMapWin32Status(RpcExceptionCode());
}
RpcEndExcept;
return Status;
}
NTSTATUS
NTAPI
SamOpenUser(IN SAM_HANDLE DomainHandle,

View file

@ -8,7 +8,7 @@
@ stdcall SamConnect(ptr ptr long ptr)
@ stub SamConnectWithCreds
@ stdcall SamCreateAliasInDomain(ptr ptr long ptr ptr)
@ stub SamCreateGroupInDomain
@ stdcall SamCreateGroupInDomain(ptr ptr long ptr ptr)
@ stub SamCreateUser2InDomain
@ stdcall SamCreateUserInDomain(ptr ptr long ptr ptr)
@ stub SamDeleteAlias
@ -30,7 +30,7 @@
@ stdcall SamLookupNamesInDomain(ptr long ptr ptr ptr)
@ stdcall SamOpenAlias(ptr long long ptr)
@ stdcall SamOpenDomain(ptr long ptr ptr)
@ stub SamOpenGroup
@ stdcall SamOpenGroup(ptr long long ptr)
@ stdcall SamOpenUser(ptr long long ptr)
@ stub SamQueryDisplayInformation
@ stdcall SamQueryInformationAlias(ptr long ptr)

View file

@ -59,6 +59,36 @@ SampRegCreateKey(IN HANDLE ParentKeyHandle,
}
NTSTATUS
SampRegDeleteKey(IN HANDLE ParentKeyHandle,
IN LPCWSTR KeyName)
{
OBJECT_ATTRIBUTES ObjectAttributes;
UNICODE_STRING SubKeyName;
HANDLE TargetKey;
NTSTATUS Status;
RtlInitUnicodeString(&SubKeyName,
(LPWSTR)KeyName);
InitializeObjectAttributes(&ObjectAttributes,
&SubKeyName,
OBJ_CASE_INSENSITIVE,
ParentKeyHandle,
NULL);
Status = NtOpenKey(&TargetKey,
DELETE,
&ObjectAttributes);
if (!NT_SUCCESS(Status))
return Status;
Status = NtDeleteKey(TargetKey);
NtClose(TargetKey);
return Status;
}
NTSTATUS
SampRegEnumerateSubKey(IN HANDLE KeyHandle,
IN ULONG Index,
@ -170,6 +200,20 @@ SampRegQueryKeyInfo(IN HANDLE KeyHandle,
}
NTSTATUS
SampRegDeleteValue(IN HANDLE KeyHandle,
IN LPWSTR ValueName)
{
UNICODE_STRING Name;
RtlInitUnicodeString(&Name,
ValueName);
return NtDeleteValueKey(KeyHandle,
&Name);
}
NTSTATUS
SampRegEnumerateValue(IN HANDLE KeyHandle,
IN ULONG Index,

View file

@ -1541,11 +1541,145 @@ SamrCreateGroupInDomain(IN SAMPR_HANDLE DomainHandle,
OUT SAMPR_HANDLE *GroupHandle,
OUT unsigned long *RelativeId)
{
UNIMPLEMENTED;
return STATUS_NOT_IMPLEMENTED;
UNICODE_STRING EmptyString = RTL_CONSTANT_STRING(L"");
SAM_DOMAIN_FIXED_DATA FixedDomainData;
SAM_GROUP_FIXED_DATA FixedGroupData;
PSAM_DB_OBJECT DomainObject;
PSAM_DB_OBJECT GroupObject;
ULONG ulSize;
ULONG ulRid;
WCHAR szRid[9];
NTSTATUS Status;
TRACE("SamrCreateGroupInDomain(%p %p %lx %p %p)\n",
DomainHandle, Name, DesiredAccess, GroupHandle, RelativeId);
/* Validate the domain handle */
Status = SampValidateDbObject(DomainHandle,
SamDbDomainObject,
DOMAIN_CREATE_GROUP,
&DomainObject);
if (!NT_SUCCESS(Status))
{
TRACE("failed with status 0x%08lx\n", Status);
return Status;
}
/* Get the fixed domain attributes */
ulSize = sizeof(SAM_DOMAIN_FIXED_DATA);
Status = SampGetObjectAttribute(DomainObject,
L"F",
NULL,
(PVOID)&FixedDomainData,
&ulSize);
if (!NT_SUCCESS(Status))
{
TRACE("failed with status 0x%08lx\n", Status);
return Status;
}
/* Increment the NextRid attribute */
ulRid = FixedDomainData.NextRid;
FixedDomainData.NextRid++;
/* Store the fixed domain attributes */
Status = SampSetObjectAttribute(DomainObject,
L"F",
REG_BINARY,
&FixedDomainData,
ulSize);
if (!NT_SUCCESS(Status))
{
TRACE("failed with status 0x%08lx\n", Status);
return Status;
}
TRACE("RID: %lx\n", ulRid);
/* Convert the RID into a string (hex) */
swprintf(szRid, L"%08lX", ulRid);
/* FIXME: Check whether the group name is already in use */
/* Create the group object */
Status = SampCreateDbObject(DomainObject,
L"Groups",
szRid,
SamDbGroupObject,
DesiredAccess,
&GroupObject);
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"Groups",
Name->Buffer,
ulRid);
if (!NT_SUCCESS(Status))
{
TRACE("failed with status 0x%08lx\n", Status);
return Status;
}
/* Initialize fixed user data */
memset(&FixedGroupData, 0, sizeof(SAM_GROUP_FIXED_DATA));
FixedGroupData.Version = 1;
FixedGroupData.GroupId = ulRid;
/* Set fixed user data attribute */
Status = SampSetObjectAttribute(GroupObject,
L"F",
REG_BINARY,
(LPVOID)&FixedGroupData,
sizeof(SAM_GROUP_FIXED_DATA));
if (!NT_SUCCESS(Status))
{
TRACE("failed with status 0x%08lx\n", Status);
return Status;
}
/* Set the Name attribute */
Status = SampSetObjectAttribute(GroupObject,
L"Name",
REG_SZ,
(LPVOID)Name->Buffer,
Name->MaximumLength);
if (!NT_SUCCESS(Status))
{
TRACE("failed with status 0x%08lx\n", Status);
return Status;
}
/* Set the AdminComment attribute */
Status = SampSetObjectAttribute(GroupObject,
L"AdminComment",
REG_SZ,
EmptyString.Buffer,
EmptyString.MaximumLength);
if (!NT_SUCCESS(Status))
{
TRACE("failed with status 0x%08lx\n", Status);
return Status;
}
if (NT_SUCCESS(Status))
{
*GroupHandle = (SAMPR_HANDLE)GroupObject;
*RelativeId = ulRid;
}
TRACE("returns with status 0x%08lx\n", Status);
return Status;
}
/* Function 10 */
/* Function 11 */
NTSTATUS
NTAPI
SamrEnumerateGroupsInDomain(IN SAMPR_HANDLE DomainHandle,
@ -1558,6 +1692,7 @@ SamrEnumerateGroupsInDomain(IN SAMPR_HANDLE DomainHandle,
return STATUS_NOT_IMPLEMENTED;
}
/* Function 12 */
NTSTATUS
NTAPI
@ -1567,6 +1702,7 @@ SamrCreateUserInDomain(IN SAMPR_HANDLE DomainHandle,
OUT SAMPR_HANDLE *UserHandle,
OUT unsigned long *RelativeId)
{
UNICODE_STRING EmptyString = RTL_CONSTANT_STRING(L"");
SAM_DOMAIN_FIXED_DATA FixedDomainData;
SAM_USER_FIXED_DATA FixedUserData;
PSAM_DB_OBJECT DomainObject;
@ -1684,7 +1820,7 @@ SamrCreateUserInDomain(IN SAMPR_HANDLE DomainHandle,
return Status;
}
/* Set the name attribute */
/* Set the Name attribute */
Status = SampSetObjectAttribute(UserObject,
L"Name",
REG_SZ,
@ -1696,6 +1832,102 @@ SamrCreateUserInDomain(IN SAMPR_HANDLE DomainHandle,
return Status;
}
/* Set the FullName attribute */
Status = SampSetObjectAttribute(UserObject,
L"FullName",
REG_SZ,
EmptyString.Buffer,
EmptyString.MaximumLength);
if (!NT_SUCCESS(Status))
{
TRACE("failed with status 0x%08lx\n", Status);
return Status;
}
/* Set the HomeDirectory attribute */
Status = SampSetObjectAttribute(UserObject,
L"HomeDirectory",
REG_SZ,
EmptyString.Buffer,
EmptyString.MaximumLength);
if (!NT_SUCCESS(Status))
{
TRACE("failed with status 0x%08lx\n", Status);
return Status;
}
/* Set the HomeDirectoryDrive attribute */
Status = SampSetObjectAttribute(UserObject,
L"HomeDirectoryDrive",
REG_SZ,
EmptyString.Buffer,
EmptyString.MaximumLength);
if (!NT_SUCCESS(Status))
{
TRACE("failed with status 0x%08lx\n", Status);
return Status;
}
/* Set the ScriptPath attribute */
Status = SampSetObjectAttribute(UserObject,
L"ScriptPath",
REG_SZ,
EmptyString.Buffer,
EmptyString.MaximumLength);
if (!NT_SUCCESS(Status))
{
TRACE("failed with status 0x%08lx\n", Status);
return Status;
}
/* Set the ProfilePath attribute */
Status = SampSetObjectAttribute(UserObject,
L"ProfilePath",
REG_SZ,
EmptyString.Buffer,
EmptyString.MaximumLength);
if (!NT_SUCCESS(Status))
{
TRACE("failed with status 0x%08lx\n", Status);
return Status;
}
/* Set the AdminComment attribute */
Status = SampSetObjectAttribute(UserObject,
L"AdminComment",
REG_SZ,
EmptyString.Buffer,
EmptyString.MaximumLength);
if (!NT_SUCCESS(Status))
{
TRACE("failed with status 0x%08lx\n", Status);
return Status;
}
/* Set the UserComment attribute */
Status = SampSetObjectAttribute(UserObject,
L"UserComment",
REG_SZ,
EmptyString.Buffer,
EmptyString.MaximumLength);
if (!NT_SUCCESS(Status))
{
TRACE("failed with status 0x%08lx\n", Status);
return Status;
}
/* Set the WorkStations attribute */
Status = SampSetObjectAttribute(UserObject,
L"WorkStations",
REG_SZ,
EmptyString.Buffer,
EmptyString.MaximumLength);
if (!NT_SUCCESS(Status))
{
TRACE("failed with status 0x%08lx\n", Status);
return Status;
}
/* FIXME: Set default user attributes */
if (NT_SUCCESS(Status))
@ -1709,6 +1941,7 @@ SamrCreateUserInDomain(IN SAMPR_HANDLE DomainHandle,
return Status;
}
/* Function 13 */
NTSTATUS
NTAPI
@ -1723,6 +1956,7 @@ SamrEnumerateUsersInDomain(IN SAMPR_HANDLE DomainHandle,
return STATUS_NOT_IMPLEMENTED;
}
/* Function 14 */
NTSTATUS
NTAPI
@ -1807,7 +2041,7 @@ SamrCreateAliasInDomain(IN SAMPR_HANDLE DomainHandle,
return STATUS_ALIAS_EXISTS;
}
/* Create the user object */
/* Create the alias object */
Status = SampCreateDbObject(DomainObject,
L"Aliases",
szRid,
@ -2239,6 +2473,7 @@ done:
return Status;
}
/* Function 17 */
NTSTATUS
NTAPI
@ -2265,6 +2500,7 @@ SamrLookupIdsInDomain(IN SAMPR_HANDLE DomainHandle,
return STATUS_NOT_IMPLEMENTED;
}
/* Function 19 */
NTSTATUS
NTAPI
@ -2273,10 +2509,47 @@ SamrOpenGroup(IN SAMPR_HANDLE DomainHandle,
IN unsigned long GroupId,
OUT SAMPR_HANDLE *GroupHandle)
{
UNIMPLEMENTED;
return STATUS_NOT_IMPLEMENTED;
PSAM_DB_OBJECT DomainObject;
PSAM_DB_OBJECT GroupObject;
WCHAR szRid[9];
NTSTATUS Status;
TRACE("SamrOpenGroup(%p %lx %lx %p)\n",
DomainHandle, DesiredAccess, GroupId, GroupHandle);
/* 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", GroupId);
/* Create the group object */
Status = SampOpenDbObject(DomainObject,
L"Groups",
szRid,
SamDbGroupObject,
DesiredAccess,
&GroupObject);
if (!NT_SUCCESS(Status))
{
TRACE("failed with status 0x%08lx\n", Status);
return Status;
}
*GroupHandle = (SAMPR_HANDLE)GroupObject;
return STATUS_SUCCESS;
}
/* Function 20 */
NTSTATUS
NTAPI
@ -2674,7 +2947,7 @@ SamrAddMemberToAlias(IN SAMPR_HANDLE AliasHandle,
TRACE("SamrAddMemberToAlias(%p %p)\n",
AliasHandle, MemberId);
/* Validate the domain handle */
/* Validate the alias handle */
Status = SampValidateDbObject(AliasHandle,
SamDbAliasObject,
ALIAS_ADD_MEMBER,

View file

@ -51,6 +51,13 @@ typedef struct _SAM_DB_OBJECT
#define SAMP_DB_SIGNATURE 0x87654321
typedef struct _SAM_ALIAS_FIXED_DATA
{
ULONG Version;
ULONG Reserved;
ULONG AliasId;
} SAM_ALIAS_FIXED_DATA, *PSAM_ALIAS_FIXED_DATA;
typedef struct _SAM_DOMAIN_FIXED_DATA
{
ULONG Version;
@ -73,6 +80,14 @@ typedef struct _SAM_DOMAIN_FIXED_DATA
BOOLEAN UasCompatibilityRequired;
} SAM_DOMAIN_FIXED_DATA, *PSAM_DOMAIN_FIXED_DATA;
typedef struct _SAM_GROUP_FIXED_DATA
{
ULONG Version;
ULONG Reserved;
ULONG GroupId;
ULONG Attributes;
} SAM_GROUP_FIXED_DATA, *PSAM_GROUP_FIXED_DATA;
typedef struct _SAM_USER_FIXED_DATA
{
ULONG Version;
@ -164,6 +179,10 @@ SampRegCreateKey(IN HANDLE ParentKeyHandle,
IN ACCESS_MASK DesiredAccess,
OUT HANDLE KeyHandle);
NTSTATUS
SampRegDeleteKey(IN HANDLE ParentKeyHandle,
IN LPCWSTR KeyName);
NTSTATUS
SampRegEnumerateSubKey(IN HANDLE KeyHandle,
IN ULONG Index,
@ -181,6 +200,10 @@ SampRegQueryKeyInfo(IN HANDLE KeyHandle,
OUT PULONG SubKeyCount,
OUT PULONG ValueCount);
NTSTATUS
SampRegDeleteValue(IN HANDLE KeyHandle,
IN LPWSTR ValueName);
NTSTATUS
SampRegEnumerateValue(IN HANDLE KeyHandle,
IN ULONG Index,

View file

@ -237,6 +237,15 @@ typedef struct _DOMAIN_NAME_INFORMATION
UNICODE_STRING DomainName;
} DOMAIN_NAME_INFORMATION, *PDOMAIN_NAME_INFORMATION;
typedef enum _GROUP_INFORMATION_CLASS
{
GroupGeneralInformation = 1,
GroupNameInformation,
GroupAttributeInformation,
GroupAdminCommentInformation,
GroupReplicationInformation
} GROUP_INFORMATION_CLASS;
typedef enum _USER_INFORMATION_CLASS
{
UserGeneralInformation = 1,
@ -301,6 +310,14 @@ SamCreateAliasInDomain(IN SAM_HANDLE DomainHandle,
OUT PSAM_HANDLE AliasHandle,
OUT PULONG RelativeId);
NTSTATUS
NTAPI
SamCreateGroupInDomain(IN SAM_HANDLE DomainHandle,
IN PUNICODE_STRING AccountName,
IN ACCESS_MASK DesiredAccess,
OUT PSAM_HANDLE GroupHandle,
OUT PULONG RelativeId);
NTSTATUS
NTAPI
SamCreateUserInDomain(IN SAM_HANDLE DomainHandle,
@ -371,6 +388,13 @@ SamOpenDomain(IN SAM_HANDLE ServerHandle,
IN PSID DomainId,
OUT PSAM_HANDLE DomainHandle);
NTSTATUS
NTAPI
SamOpenGroup(IN SAM_HANDLE DomainHandle,
IN ACCESS_MASK DesiredAccess,
IN ULONG GroupId,
OUT PSAM_HANDLE GroupHandle);
NTSTATUS
NTAPI
SamOpenUser(IN SAM_HANDLE DomainHandle,

View file

@ -382,6 +382,7 @@ typedef struct _SAMPR_GROUP_ADM_COMMENT_INFORMATION
RPC_UNICODE_STRING AdminComment;
} SAMPR_GROUP_ADM_COMMENT_INFORMATION, *PSAMPR_GROUP_ADM_COMMENT_INFORMATION;
cpp_quote("#ifndef _NTSAM_")
typedef enum _GROUP_INFORMATION_CLASS
{
GroupGeneralInformation = 1,
@ -390,6 +391,7 @@ typedef enum _GROUP_INFORMATION_CLASS
GroupAdminCommentInformation,
GroupReplicationInformation
} GROUP_INFORMATION_CLASS;
cpp_quote("#endif")
typedef [switch_type(GROUP_INFORMATION_CLASS)] union _SAMPR_GROUP_INFO_BUFFER
{