* Copyright 2006 Hervé Poussineau
*
* PROJECT: ReactOS system libraries
- * FILE: dll/win32/advapi32/sec/sid.c
- * PURPOSE: Security ID functions
+ * FILE: dll/win32/advapi32/wine/security.c
*/
#include <advapi32.h>
WINE_DEFAULT_DEBUG_CHANNEL(advapi);
+static DWORD ComputeStringSidSize(LPCWSTR StringSid);
+static BOOL ParseStringSidToSid(LPCWSTR StringSid, PSID pSid, LPDWORD cBytes);
+
#define MAX_GUID_STRING_LEN 39
BOOL WINAPI
{ NULL, 0 },
};
-static const LPCWSTR AceRightBitNames[32] = {
- SDDL_CREATE_CHILD, /* 0 */
- SDDL_DELETE_CHILD,
- SDDL_LIST_CHILDREN,
- SDDL_SELF_WRITE,
- SDDL_READ_PROPERTY, /* 4 */
- SDDL_WRITE_PROPERTY,
- SDDL_DELETE_TREE,
- SDDL_LIST_OBJECT,
- SDDL_CONTROL_ACCESS, /* 8 */
- NULL,
- NULL,
- NULL,
- NULL, /* 12 */
- NULL,
- NULL,
- NULL,
- SDDL_STANDARD_DELETE, /* 16 */
- SDDL_READ_CONTROL,
- SDDL_WRITE_DAC,
- SDDL_WRITE_OWNER,
- NULL, /* 20 */
- NULL,
- NULL,
- NULL,
- NULL, /* 24 */
- NULL,
- NULL,
- NULL,
- SDDL_GENERIC_ALL, /* 28 */
- SDDL_GENERIC_EXECUTE,
- SDDL_GENERIC_WRITE,
- SDDL_GENERIC_READ
-};
-
-
/* set last error code from NT status and get the proper boolean return value */
/* used for functions that are a simple wrapper around the corresponding ntdll API */
static __inline BOOL set_ntstatus( NTSTATUS status )
return !status;
}
+static const RECORD SidTable[] =
+{
+ { SDDL_ACCOUNT_OPERATORS, WinBuiltinAccountOperatorsSid },
+ { SDDL_ALIAS_PREW2KCOMPACC, WinBuiltinPreWindows2000CompatibleAccessSid },
+ { SDDL_ANONYMOUS, WinAnonymousSid },
+ { SDDL_AUTHENTICATED_USERS, WinAuthenticatedUserSid },
+ { SDDL_BUILTIN_ADMINISTRATORS, WinBuiltinAdministratorsSid },
+ { SDDL_BUILTIN_GUESTS, WinBuiltinGuestsSid },
+ { SDDL_BACKUP_OPERATORS, WinBuiltinBackupOperatorsSid },
+ { SDDL_BUILTIN_USERS, WinBuiltinUsersSid },
+ { SDDL_CERT_SERV_ADMINISTRATORS, WinAccountCertAdminsSid /* FIXME: DOMAIN_GROUP_RID_CERT_ADMINS */ },
+ { SDDL_CREATOR_GROUP, WinCreatorGroupSid },
+ { SDDL_CREATOR_OWNER, WinCreatorOwnerSid },
+ { SDDL_DOMAIN_ADMINISTRATORS, WinAccountDomainAdminsSid /* FIXME: DOMAIN_GROUP_RID_ADMINS */ },
+ { SDDL_DOMAIN_COMPUTERS, WinAccountComputersSid /* FIXME: DOMAIN_GROUP_RID_COMPUTERS */ },
+ { SDDL_DOMAIN_DOMAIN_CONTROLLERS, WinAccountControllersSid /* FIXME: DOMAIN_GROUP_RID_CONTROLLERS */ },
+ { SDDL_DOMAIN_GUESTS, WinAccountDomainGuestsSid /* FIXME: DOMAIN_GROUP_RID_GUESTS */ },
+ { SDDL_DOMAIN_USERS, WinAccountDomainUsersSid /* FIXME: DOMAIN_GROUP_RID_USERS */ },
+ { SDDL_ENTERPRISE_ADMINS, WinAccountEnterpriseAdminsSid /* FIXME: DOMAIN_GROUP_RID_ENTERPRISE_ADMINS */ },
+ { SDDL_ENTERPRISE_DOMAIN_CONTROLLERS, WinEnterpriseControllersSid },
+ { SDDL_EVERYONE, WinWorldSid },
+ { SDDL_GROUP_POLICY_ADMINS, WinAccountPolicyAdminsSid /* FIXME: DOMAIN_GROUP_RID_POLICY_ADMINS */ },
+ { SDDL_INTERACTIVE, WinInteractiveSid },
+ { SDDL_LOCAL_ADMIN, WinAccountAdministratorSid /* FIXME: DOMAIN_USER_RID_ADMIN */ },
+ { SDDL_LOCAL_GUEST, WinAccountGuestSid /* FIXME: DOMAIN_USER_RID_GUEST */ },
+ { SDDL_LOCAL_SERVICE, WinLocalServiceSid },
+ { SDDL_LOCAL_SYSTEM, WinLocalSystemSid },
+ { SDDL_NETWORK, WinNetworkSid },
+ { SDDL_NETWORK_CONFIGURATION_OPS, WinBuiltinNetworkConfigurationOperatorsSid },
+ { SDDL_NETWORK_SERVICE, WinNetworkServiceSid },
+ { SDDL_PRINTER_OPERATORS, WinBuiltinPrintOperatorsSid },
+ { SDDL_PERSONAL_SELF, WinSelfSid },
+ { SDDL_POWER_USERS, WinBuiltinPowerUsersSid },
+ { SDDL_RAS_SERVERS, WinAccountRasAndIasServersSid /* FIXME: DOMAIN_ALIAS_RID_RAS_SERVERS */ },
+ { SDDL_REMOTE_DESKTOP, WinBuiltinRemoteDesktopUsersSid },
+ { SDDL_REPLICATOR, WinBuiltinReplicatorSid },
+ { SDDL_RESTRICTED_CODE, WinRestrictedCodeSid },
+ { SDDL_SCHEMA_ADMINISTRATORS, WinAccountSchemaAdminsSid /* FIXME: DOMAIN_GROUP_RID_SCHEMA_ADMINS */ },
+ { SDDL_SERVER_OPERATORS, WinBuiltinSystemOperatorsSid },
+ { SDDL_SERVICE, WinServiceSid },
+ { NULL, 0 },
+};
/* Exported functions */
* @implemented
*/
BOOL WINAPI
-AllocateLocallyUniqueId(PLUID Luid)
+OpenProcessToken(HANDLE ProcessHandle,
+ DWORD DesiredAccess,
+ PHANDLE TokenHandle)
{
NTSTATUS Status;
- Status = NtAllocateLocallyUniqueId (Luid);
- if (!NT_SUCCESS (Status))
+ TRACE("%p, %x, %p.\n", ProcessHandle, DesiredAccess, TokenHandle);
+
+ Status = NtOpenProcessToken(ProcessHandle,
+ DesiredAccess,
+ TokenHandle);
+ if (!NT_SUCCESS(Status))
+ {
+ ERR("NtOpenProcessToken failed! Status %08x.\n", Status);
+ SetLastError(RtlNtStatusToDosError(Status));
+ return FALSE;
+ }
+
+ TRACE("Returning token %p.\n", *TokenHandle);
+
+ return TRUE;
+}
+
+/*
+ * @implemented
+ */
+BOOL WINAPI
+OpenThreadToken(HANDLE ThreadHandle,
+ DWORD DesiredAccess,
+ BOOL OpenAsSelf,
+ PHANDLE TokenHandle)
+{
+ NTSTATUS Status;
+
+ Status = NtOpenThreadToken(ThreadHandle,
+ DesiredAccess,
+ OpenAsSelf,
+ TokenHandle);
+ if (!NT_SUCCESS(Status))
+ {
+ SetLastError(RtlNtStatusToDosError(Status));
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+/*
+ * @implemented
+ */
+BOOL WINAPI
+AdjustTokenGroups(HANDLE TokenHandle,
+ BOOL ResetToDefault,
+ PTOKEN_GROUPS NewState,
+ DWORD BufferLength,
+ PTOKEN_GROUPS PreviousState,
+ PDWORD ReturnLength)
+{
+ NTSTATUS Status;
+
+ Status = NtAdjustGroupsToken(TokenHandle,
+ ResetToDefault,
+ NewState,
+ BufferLength,
+ PreviousState,
+ (PULONG)ReturnLength);
+ if (!NT_SUCCESS(Status))
+ {
+ SetLastError(RtlNtStatusToDosError(Status));
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+/*
+ * @implemented
+ */
+BOOL WINAPI
+AdjustTokenPrivileges(HANDLE TokenHandle,
+ BOOL DisableAllPrivileges,
+ PTOKEN_PRIVILEGES NewState,
+ DWORD BufferLength,
+ PTOKEN_PRIVILEGES PreviousState,
+ PDWORD ReturnLength)
+{
+ NTSTATUS Status;
+
+ Status = NtAdjustPrivilegesToken(TokenHandle,
+ DisableAllPrivileges,
+ NewState,
+ BufferLength,
+ PreviousState,
+ (PULONG)ReturnLength);
+ if (STATUS_NOT_ALL_ASSIGNED == Status)
+ {
+ SetLastError(ERROR_NOT_ALL_ASSIGNED);
+ return TRUE;
+ }
+
+ if (!NT_SUCCESS(Status))
+ {
+ SetLastError(RtlNtStatusToDosError(Status));
+ return FALSE;
+ }
+
+ /* AdjustTokenPrivileges is documented to do this */
+ SetLastError(ERROR_SUCCESS);
+
+ return TRUE;
+}
+
+/*
+ * @implemented
+ */
+BOOL WINAPI
+GetTokenInformation(HANDLE TokenHandle,
+ TOKEN_INFORMATION_CLASS TokenInformationClass,
+ LPVOID TokenInformation,
+ DWORD TokenInformationLength,
+ PDWORD ReturnLength)
+{
+ NTSTATUS Status;
+
+ Status = NtQueryInformationToken(TokenHandle,
+ TokenInformationClass,
+ TokenInformation,
+ TokenInformationLength,
+ (PULONG)ReturnLength);
+ if (!NT_SUCCESS(Status))
+ {
+ SetLastError(RtlNtStatusToDosError(Status));
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+/*
+ * @implemented
+ */
+BOOL WINAPI
+SetTokenInformation(HANDLE TokenHandle,
+ TOKEN_INFORMATION_CLASS TokenInformationClass,
+ LPVOID TokenInformation,
+ DWORD TokenInformationLength)
+{
+ NTSTATUS Status;
+
+ Status = NtSetInformationToken(TokenHandle,
+ TokenInformationClass,
+ TokenInformation,
+ TokenInformationLength);
+ if (!NT_SUCCESS(Status))
+ {
+ SetLastError(RtlNtStatusToDosError(Status));
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+/*
+ * @implemented
+ */
+BOOL WINAPI
+SetThreadToken(IN PHANDLE ThreadHandle OPTIONAL,
+ IN HANDLE TokenHandle)
+{
+ NTSTATUS Status;
+ HANDLE hThread;
+
+ hThread = (ThreadHandle != NULL) ? *ThreadHandle : NtCurrentThread();
+
+ Status = NtSetInformationThread(hThread,
+ ThreadImpersonationToken,
+ &TokenHandle,
+ sizeof(HANDLE));
+ if (!NT_SUCCESS(Status))
{
SetLastError(RtlNtStatusToDosError(Status));
return FALSE;
return TRUE;
}
+BOOL WINAPI
+CreateRestrictedToken(HANDLE TokenHandle,
+ DWORD Flags,
+ DWORD DisableSidCount,
+ PSID_AND_ATTRIBUTES pSidAndAttributes,
+ DWORD DeletePrivilegeCount,
+ PLUID_AND_ATTRIBUTES pLUIDAndAttributes,
+ DWORD RestrictedSidCount,
+ PSID_AND_ATTRIBUTES pSIDAndAttributes,
+ PHANDLE NewTokenHandle)
+{
+ UNIMPLEMENTED;
+ return FALSE;
+}
/*
* @implemented
return TRUE;
}
+/*
+ * @implemented
+ *
+ * RETURNS
+ * Docs says this function does NOT return a value
+ * even thou it's defined to return a PVOID...
+ */
+PVOID
+WINAPI
+FreeSid(PSID pSid)
+{
+ return RtlFreeSid(pSid);
+}
/*
* @implemented
return TRUE;
}
-static void DumpString(LPCWSTR string, int cch, WCHAR **pwptr, ULONG *plen)
-{
- if (cch == -1)
- cch = strlenW(string);
-
- if (plen)
- *plen += cch;
-
- if (pwptr)
- {
- memcpy(*pwptr, string, sizeof(WCHAR)*cch);
- *pwptr += cch;
- }
-}
-
-static BOOL DumpSidNumeric(PSID psid, WCHAR **pwptr, ULONG *plen)
+/*
+ * @unimplemented
+ */
+BOOL
+WINAPI
+CreateWellKnownSid(IN WELL_KNOWN_SID_TYPE WellKnownSidType,
+ IN PSID DomainSid OPTIONAL,
+ OUT PSID pSid,
+ IN OUT DWORD* cbSid)
{
- DWORD i;
- WCHAR fmt[] = { 'S','-','%','u','-','%','d',0 };
- WCHAR subauthfmt[] = { '-','%','u',0 };
- WCHAR buf[26];
- SID *pisid = psid;
+ unsigned int i;
+ TRACE("(%d, %s, %p, %p)\n", WellKnownSidType, debugstr_sid(DomainSid), pSid, cbSid);
- if( !IsValidSid( psid ) || pisid->Revision != SDDL_REVISION)
+ if (cbSid == NULL || (DomainSid && !IsValidSid(DomainSid)))
{
- SetLastError(ERROR_INVALID_SID);
+ SetLastError(ERROR_INVALID_PARAMETER);
return FALSE;
}
- if (pisid->IdentifierAuthority.Value[0] ||
- pisid->IdentifierAuthority.Value[1])
- {
- FIXME("not matching MS' bugs\n");
- SetLastError(ERROR_INVALID_SID);
- return FALSE;
- }
+ for (i = 0; i < sizeof(WellKnownSids)/sizeof(WellKnownSids[0]); i++) {
+ if (WellKnownSids[i].Type == WellKnownSidType) {
+ DWORD length = GetSidLengthRequired(WellKnownSids[i].Sid.SubAuthorityCount);
- sprintfW( buf, fmt, pisid->Revision,
- MAKELONG(
- MAKEWORD( pisid->IdentifierAuthority.Value[5],
- pisid->IdentifierAuthority.Value[4] ),
- MAKEWORD( pisid->IdentifierAuthority.Value[3],
- pisid->IdentifierAuthority.Value[2] )
- ) );
- DumpString(buf, -1, pwptr, plen);
+ if (*cbSid < length)
+ {
+ *cbSid = length;
+ SetLastError(ERROR_INSUFFICIENT_BUFFER);
+ return FALSE;
+ }
+ if (!pSid)
+ {
+ SetLastError(ERROR_INVALID_PARAMETER);
+ return FALSE;
+ }
+ CopyMemory(pSid, &WellKnownSids[i].Sid.Revision, length);
+ *cbSid = length;
+ return TRUE;
+ }
+ }
- for( i=0; i<pisid->SubAuthorityCount; i++ )
+ if (DomainSid == NULL || *GetSidSubAuthorityCount(DomainSid) == SID_MAX_SUB_AUTHORITIES)
{
- sprintfW( buf, subauthfmt, pisid->SubAuthority[i] );
- DumpString(buf, -1, pwptr, plen);
+ SetLastError(ERROR_INVALID_PARAMETER);
+ return FALSE;
}
- return TRUE;
-}
-static BOOL DumpSid(PSID psid, WCHAR **pwptr, ULONG *plen)
-{
- size_t i;
- for (i = 0; i < sizeof(WellKnownSids) / sizeof(WellKnownSids[0]); i++)
- {
- if (WellKnownSids[i].wstr[0] && EqualSid(psid, (PSID)&(WellKnownSids[i].Sid.Revision)))
- {
- DumpString(WellKnownSids[i].wstr, 2, pwptr, plen);
+ for (i = 0; i < sizeof(WellKnownRids)/sizeof(WellKnownRids[0]); i++)
+ if (WellKnownRids[i].Type == WellKnownSidType) {
+ UCHAR domain_subauth = *GetSidSubAuthorityCount(DomainSid);
+ DWORD domain_sid_length = GetSidLengthRequired(domain_subauth);
+ DWORD output_sid_length = GetSidLengthRequired(domain_subauth + 1);
+
+ if (*cbSid < output_sid_length)
+ {
+ *cbSid = output_sid_length;
+ SetLastError(ERROR_INSUFFICIENT_BUFFER);
+ return FALSE;
+ }
+ if (!pSid)
+ {
+ SetLastError(ERROR_INVALID_PARAMETER);
+ return FALSE;
+ }
+ CopyMemory(pSid, DomainSid, domain_sid_length);
+ (*GetSidSubAuthorityCount(pSid))++;
+ (*GetSidSubAuthority(pSid, domain_subauth)) = WellKnownRids[i].Rid;
+ *cbSid = output_sid_length;
return TRUE;
}
- }
- return DumpSidNumeric(psid, pwptr, plen);
+ SetLastError(ERROR_INVALID_PARAMETER);
+ return FALSE;
}
-static void DumpRights(DWORD mask, WCHAR **pwptr, ULONG *plen)
+/*
+ * @unimplemented
+ */
+BOOL
+WINAPI
+IsWellKnownSid(IN PSID pSid,
+ IN WELL_KNOWN_SID_TYPE WellKnownSidType)
{
- static const WCHAR fmtW[] = {'0','x','%','x',0};
- WCHAR buf[15];
- size_t i;
-
- if (mask == 0)
- return;
-
- /* first check if the right have name */
- for (i = 0; i < sizeof(AceRights)/sizeof(AceRights[0]); i++)
- {
- if (AceRights[i].wstr == NULL)
- break;
- if (mask == AceRights[i].value)
- {
- DumpString(AceRights[i].wstr, -1, pwptr, plen);
- return;
- }
- }
+ unsigned int i;
+ TRACE("(%s, %d)\n", debugstr_sid(pSid), WellKnownSidType);
- /* then check if it can be built from bit names */
- for (i = 0; i < 32; i++)
+ for (i = 0; i < sizeof(WellKnownSids) / sizeof(WellKnownSids[0]); i++)
{
- if ((mask & (1 << i)) && (AceRightBitNames[i] == NULL))
+ if (WellKnownSids[i].Type == WellKnownSidType)
{
- /* can't be built from bit names */
- sprintfW(buf, fmtW, mask);
- DumpString(buf, -1, pwptr, plen);
- return;
+ if (EqualSid(pSid, (PSID)(&WellKnownSids[i].Sid.Revision)))
+ return TRUE;
}
}
- /* build from bit names */
- for (i = 0; i < 32; i++)
- if (mask & (1 << i))
- DumpString(AceRightBitNames[i], -1, pwptr, plen);
+ return FALSE;
}
-static BOOL DumpAce(LPVOID pace, WCHAR **pwptr, ULONG *plen)
+/*
+ * @implemented
+ */
+BOOL
+WINAPI
+IsValidSid(PSID pSid)
{
- ACCESS_ALLOWED_ACE *piace; /* all the supported ACEs have the same memory layout */
- static const WCHAR openbr = '(';
- static const WCHAR closebr = ')';
- static const WCHAR semicolon = ';';
-
- if (((PACE_HEADER)pace)->AceType > SYSTEM_ALARM_ACE_TYPE || ((PACE_HEADER)pace)->AceSize < sizeof(ACCESS_ALLOWED_ACE))
- {
- SetLastError(ERROR_INVALID_ACL);
- return FALSE;
- }
-
- piace = pace;
- DumpString(&openbr, 1, pwptr, plen);
- switch (piace->Header.AceType)
- {
- case ACCESS_ALLOWED_ACE_TYPE:
- DumpString(SDDL_ACCESS_ALLOWED, -1, pwptr, plen);
- break;
- case ACCESS_DENIED_ACE_TYPE:
- DumpString(SDDL_ACCESS_DENIED, -1, pwptr, plen);
- break;
- case SYSTEM_AUDIT_ACE_TYPE:
- DumpString(SDDL_AUDIT, -1, pwptr, plen);
- break;
- case SYSTEM_ALARM_ACE_TYPE:
- DumpString(SDDL_ALARM, -1, pwptr, plen);
- break;
- }
- DumpString(&semicolon, 1, pwptr, plen);
-
- if (piace->Header.AceFlags & OBJECT_INHERIT_ACE)
- DumpString(SDDL_OBJECT_INHERIT, -1, pwptr, plen);
- if (piace->Header.AceFlags & CONTAINER_INHERIT_ACE)
- DumpString(SDDL_CONTAINER_INHERIT, -1, pwptr, plen);
- if (piace->Header.AceFlags & NO_PROPAGATE_INHERIT_ACE)
- DumpString(SDDL_NO_PROPAGATE, -1, pwptr, plen);
- if (piace->Header.AceFlags & INHERIT_ONLY_ACE)
- DumpString(SDDL_INHERIT_ONLY, -1, pwptr, plen);
- if (piace->Header.AceFlags & INHERITED_ACE)
- DumpString(SDDL_INHERITED, -1, pwptr, plen);
- if (piace->Header.AceFlags & SUCCESSFUL_ACCESS_ACE_FLAG)
- DumpString(SDDL_AUDIT_SUCCESS, -1, pwptr, plen);
- if (piace->Header.AceFlags & FAILED_ACCESS_ACE_FLAG)
- DumpString(SDDL_AUDIT_FAILURE, -1, pwptr, plen);
- DumpString(&semicolon, 1, pwptr, plen);
- DumpRights(piace->Mask, pwptr, plen);
- DumpString(&semicolon, 1, pwptr, plen);
- /* objects not supported */
- DumpString(&semicolon, 1, pwptr, plen);
- /* objects not supported */
- DumpString(&semicolon, 1, pwptr, plen);
- if (!DumpSid((PSID)&piace->SidStart, pwptr, plen))
- return FALSE;
- DumpString(&closebr, 1, pwptr, plen);
- return TRUE;
+ return (BOOL)RtlValidSid(pSid);
}
-static BOOL DumpAcl(PACL pacl, WCHAR **pwptr, ULONG *plen, BOOL protected, BOOL autoInheritReq, BOOL autoInherited)
+/*
+ * @implemented
+ */
+BOOL
+WINAPI
+EqualSid(PSID pSid1,
+ PSID pSid2)
{
- WORD count;
- int i;
+ SetLastError(ERROR_SUCCESS);
+ return RtlEqualSid (pSid1, pSid2);
+}
- if (protected)
- DumpString(SDDL_PROTECTED, -1, pwptr, plen);
- if (autoInheritReq)
- DumpString(SDDL_AUTO_INHERIT_REQ, -1, pwptr, plen);
- if (autoInherited)
- DumpString(SDDL_AUTO_INHERITED, -1, pwptr, plen);
+/*
+ * @implemented
+ */
+BOOL
+WINAPI
+EqualPrefixSid(PSID pSid1,
+ PSID pSid2)
+{
+ return RtlEqualPrefixSid (pSid1, pSid2);
+}
- if (pacl == NULL)
- return TRUE;
+/*
+ * @implemented
+ */
+DWORD
+WINAPI
+GetSidLengthRequired(UCHAR nSubAuthorityCount)
+{
+ return (DWORD)RtlLengthRequiredSid(nSubAuthorityCount);
+}
- if (!IsValidAcl(pacl))
- return FALSE;
+/*
+ * @implemented
+ */
+BOOL
+WINAPI
+InitializeSid(PSID Sid,
+ PSID_IDENTIFIER_AUTHORITY pIdentifierAuthority,
+ BYTE nSubAuthorityCount)
+{
+ NTSTATUS Status;
- count = pacl->AceCount;
- for (i = 0; i < count; i++)
+ Status = RtlInitializeSid(Sid,
+ pIdentifierAuthority,
+ nSubAuthorityCount);
+ if (!NT_SUCCESS(Status))
{
- LPVOID ace;
- if (!GetAce(pacl, i, &ace))
- return FALSE;
- if (!DumpAce(ace, pwptr, plen))
- return FALSE;
+ SetLastError(RtlNtStatusToDosError(Status));
+ return FALSE;
}
return TRUE;
}
-static BOOL DumpOwner(PSECURITY_DESCRIPTOR SecurityDescriptor, WCHAR **pwptr, ULONG *plen)
+/*
+ * @implemented
+ */
+PSID_IDENTIFIER_AUTHORITY
+WINAPI
+GetSidIdentifierAuthority(PSID pSid)
{
- static const WCHAR prefix[] = {'O',':',0};
- BOOL bDefaulted;
- PSID psid;
-
- if (!GetSecurityDescriptorOwner(SecurityDescriptor, &psid, &bDefaulted))
- return FALSE;
-
- if (psid == NULL)
- return TRUE;
-
- DumpString(prefix, -1, pwptr, plen);
- if (!DumpSid(psid, pwptr, plen))
- return FALSE;
- return TRUE;
+ return RtlIdentifierAuthoritySid(pSid);
}
-static BOOL DumpGroup(PSECURITY_DESCRIPTOR SecurityDescriptor, WCHAR **pwptr, ULONG *plen)
-{
- static const WCHAR prefix[] = {'G',':',0};
- BOOL bDefaulted;
- PSID psid;
-
- if (!GetSecurityDescriptorGroup(SecurityDescriptor, &psid, &bDefaulted))
- return FALSE;
-
- if (psid == NULL)
- return TRUE;
-
- DumpString(prefix, -1, pwptr, plen);
- if (!DumpSid(psid, pwptr, plen))
- return FALSE;
- return TRUE;
+/*
+ * @implemented
+ */
+PDWORD
+WINAPI
+GetSidSubAuthority(PSID pSid,
+ DWORD nSubAuthority)
+{
+ SetLastError(ERROR_SUCCESS);
+ return (PDWORD)RtlSubAuthoritySid(pSid, nSubAuthority);
}
-static BOOL DumpDacl(PSECURITY_DESCRIPTOR SecurityDescriptor, WCHAR **pwptr, ULONG *plen)
+/*
+ * @implemented
+ */
+PUCHAR
+WINAPI
+GetSidSubAuthorityCount(PSID pSid)
{
- static const WCHAR dacl[] = {'D',':',0};
- SECURITY_DESCRIPTOR_CONTROL control;
- BOOL present, defaulted;
- DWORD revision;
- PACL pacl;
-
- if (!GetSecurityDescriptorDacl(SecurityDescriptor, &present, &pacl, &defaulted))
- return FALSE;
-
- if (!GetSecurityDescriptorControl(SecurityDescriptor, &control, &revision))
- return FALSE;
-
- if (!present)
- return TRUE;
-
- DumpString(dacl, 2, pwptr, plen);
- if (!DumpAcl(pacl, pwptr, plen, control & SE_DACL_PROTECTED, control & SE_DACL_AUTO_INHERIT_REQ, control & SE_DACL_AUTO_INHERITED))
- return FALSE;
- return TRUE;
+ SetLastError(ERROR_SUCCESS);
+ return RtlSubAuthorityCountSid(pSid);
}
-static BOOL DumpSacl(PSECURITY_DESCRIPTOR SecurityDescriptor, WCHAR **pwptr, ULONG *plen)
+/*
+ * @implemented
+ */
+DWORD
+WINAPI
+GetLengthSid(PSID pSid)
{
- static const WCHAR sacl[] = {'S',':',0};
- SECURITY_DESCRIPTOR_CONTROL control;
- BOOL present, defaulted;
- DWORD revision;
- PACL pacl;
-
- if (!GetSecurityDescriptorSacl(SecurityDescriptor, &present, &pacl, &defaulted))
- return FALSE;
-
- if (!GetSecurityDescriptorControl(SecurityDescriptor, &control, &revision))
- return FALSE;
-
- if (!present)
- return TRUE;
-
- DumpString(sacl, 2, pwptr, plen);
- if (!DumpAcl(pacl, pwptr, plen, control & SE_SACL_PROTECTED, control & SE_SACL_AUTO_INHERIT_REQ, control & SE_SACL_AUTO_INHERITED))
- return FALSE;
- return TRUE;
+ return (DWORD)RtlLengthSid(pSid);
}
-/******************************************************************************
- * ConvertSecurityDescriptorToStringSecurityDescriptorW [ADVAPI32.@]
+/*
* @implemented
*/
BOOL WINAPI
-ConvertSecurityDescriptorToStringSecurityDescriptorW(PSECURITY_DESCRIPTOR SecurityDescriptor,
- DWORD SDRevision,
- SECURITY_INFORMATION SecurityInformation,
- LPWSTR *OutputString,
- PULONG OutputLen)
+AllocateLocallyUniqueId(PLUID Luid)
{
- ULONG len;
- WCHAR *wptr, *wstr;
+ NTSTATUS Status;
- if (SDRevision != SDDL_REVISION_1)
+ Status = NtAllocateLocallyUniqueId (Luid);
+ if (!NT_SUCCESS (Status))
{
- ERR("Program requested unknown SDDL revision %d\n", SDRevision);
- SetLastError(ERROR_UNKNOWN_REVISION);
+ SetLastError(RtlNtStatusToDosError(Status));
return FALSE;
}
- len = 0;
- if (SecurityInformation & OWNER_SECURITY_INFORMATION)
- if (!DumpOwner(SecurityDescriptor, NULL, &len))
- return FALSE;
- if (SecurityInformation & GROUP_SECURITY_INFORMATION)
- if (!DumpGroup(SecurityDescriptor, NULL, &len))
- return FALSE;
- if (SecurityInformation & DACL_SECURITY_INFORMATION)
- if (!DumpDacl(SecurityDescriptor, NULL, &len))
- return FALSE;
- if (SecurityInformation & SACL_SECURITY_INFORMATION)
- if (!DumpSacl(SecurityDescriptor, NULL, &len))
- return FALSE;
-
- wstr = wptr = LocalAlloc(0, (len + 1)*sizeof(WCHAR));
- if (wstr == NULL)
- return FALSE;
-
- if (SecurityInformation & OWNER_SECURITY_INFORMATION)
- if (!DumpOwner(SecurityDescriptor, &wptr, NULL))
- return FALSE;
- if (SecurityInformation & GROUP_SECURITY_INFORMATION)
- if (!DumpGroup(SecurityDescriptor, &wptr, NULL))
- return FALSE;
- if (SecurityInformation & DACL_SECURITY_INFORMATION)
- if (!DumpDacl(SecurityDescriptor, &wptr, NULL))
- return FALSE;
- if (SecurityInformation & SACL_SECURITY_INFORMATION)
- if (!DumpSacl(SecurityDescriptor, &wptr, NULL))
- return FALSE;
- *wptr = 0;
-
- TRACE("ret: %s, %d\n", wine_dbgstr_w(wstr), len);
- *OutputString = wstr;
- if (OutputLen)
- *OutputLen = strlenW(*OutputString)+1;
return TRUE;
}
-
-/******************************************************************************
- * ConvertSecurityDescriptorToStringSecurityDescriptorA [ADVAPI32.@]
+/*
* @implemented
*/
-BOOL WINAPI
-ConvertSecurityDescriptorToStringSecurityDescriptorA(PSECURITY_DESCRIPTOR SecurityDescriptor,
- DWORD SDRevision,
- SECURITY_INFORMATION Information,
- LPSTR *OutputString,
- PULONG OutputLen)
+BOOL
+WINAPI
+AccessCheck(IN PSECURITY_DESCRIPTOR pSecurityDescriptor,
+ IN HANDLE ClientToken,
+ IN DWORD DesiredAccess,
+ IN PGENERIC_MAPPING GenericMapping,
+ OUT PPRIVILEGE_SET PrivilegeSet OPTIONAL,
+ IN OUT LPDWORD PrivilegeSetLength,
+ OUT LPDWORD GrantedAccess,
+ OUT LPBOOL AccessStatus)
{
- LPWSTR wstr;
- ULONG len;
-
- if (ConvertSecurityDescriptorToStringSecurityDescriptorW(SecurityDescriptor, SDRevision, Information, &wstr, &len))
+ NTSTATUS Status;
+ NTSTATUS NtAccessStatus;
+
+ /* Do the access check */
+ Status = NtAccessCheck(pSecurityDescriptor,
+ ClientToken,
+ DesiredAccess,
+ GenericMapping,
+ PrivilegeSet,
+ (PULONG)PrivilegeSetLength,
+ (PACCESS_MASK)GrantedAccess,
+ &NtAccessStatus);
+
+ /* See if the access check operation succeeded */
+ if (!NT_SUCCESS(Status))
{
- int lenA;
-
- lenA = WideCharToMultiByte(CP_ACP, 0, wstr, len, NULL, 0, NULL, NULL);
- *OutputString = HeapAlloc(GetProcessHeap(), 0, lenA);
- if (*OutputString == NULL)
- {
- LocalFree(wstr);
- *OutputLen = 0;
- return FALSE;
- }
- WideCharToMultiByte(CP_ACP, 0, wstr, len, *OutputString, lenA, NULL, NULL);
- LocalFree(wstr);
+ /* Check failed */
+ SetLastError(RtlNtStatusToDosError(Status));
+ return FALSE;
+ }
- if (OutputLen != NULL)
- *OutputLen = lenA;
- return TRUE;
+ /* Now check the access status */
+ if (!NT_SUCCESS(NtAccessStatus))
+ {
+ /* Access denied */
+ SetLastError(RtlNtStatusToDosError(NtAccessStatus));
+ *AccessStatus = FALSE;
}
else
{
- *OutputString = NULL;
- if (OutputLen)
- *OutputLen = 0;
- return FALSE;
+ /* Access granted */
+ *AccessStatus = TRUE;
}
-}
+ /* Check succeeded */
+ return TRUE;
+}
-/******************************************************************************
- * ComputeStringSidSize
+/*
+ * @unimplemented
*/
-static DWORD ComputeStringSidSize(LPCWSTR StringSid)
+BOOL WINAPI AccessCheckByType(
+ PSECURITY_DESCRIPTOR pSecurityDescriptor,
+ PSID PrincipalSelfSid,
+ HANDLE ClientToken,
+ DWORD DesiredAccess,
+ POBJECT_TYPE_LIST ObjectTypeList,
+ DWORD ObjectTypeListLength,
+ PGENERIC_MAPPING GenericMapping,
+ PPRIVILEGE_SET PrivilegeSet,
+ LPDWORD PrivilegeSetLength,
+ LPDWORD GrantedAccess,
+ LPBOOL AccessStatus)
{
- if (StringSid[0] == 'S' && StringSid[1] == '-') /* S-R-I(-S)+ */
- {
- int ctok = 0;
- while (*StringSid)
- {
- if (*StringSid == '-')
- ctok++;
- StringSid++;
- }
-
- if (ctok >= 3)
- return GetSidLengthRequired(ctok - 2);
- }
- else /* String constant format - Only available in winxp and above */
- {
- unsigned int i;
+ FIXME("stub\n");
- for (i = 0; i < sizeof(WellKnownSids)/sizeof(WellKnownSids[0]); i++)
- if (!strncmpW(WellKnownSids[i].wstr, StringSid, 2))
- return GetSidLengthRequired(WellKnownSids[i].Sid.SubAuthorityCount);
- }
+ *AccessStatus = TRUE;
- return GetSidLengthRequired(0);
+ return !*AccessStatus;
}
-/******************************************************************************
- * ParseStringSidToSid
+/**********************************************************************
+ * PrivilegeCheck EXPORTED
+ *
+ * @implemented
*/
-static BOOL ParseStringSidToSid(LPCWSTR StringSid, PSID pSid, LPDWORD cBytes)
+BOOL WINAPI
+PrivilegeCheck(HANDLE ClientToken,
+ PPRIVILEGE_SET RequiredPrivileges,
+ LPBOOL pfResult)
{
- BOOL bret = FALSE;
- SID* pisid=pSid;
+ BOOLEAN Result;
+ NTSTATUS Status;
- TRACE("%s, %p, %p\n", debugstr_w(StringSid), pSid, cBytes);
- if (!StringSid)
+ Status = NtPrivilegeCheck(ClientToken,
+ RequiredPrivileges,
+ &Result);
+ if (!NT_SUCCESS(Status))
{
- SetLastError(ERROR_INVALID_PARAMETER);
- TRACE("StringSid is NULL, returning FALSE\n");
+ SetLastError(RtlNtStatusToDosError(Status));
return FALSE;
}
- while (*StringSid == ' ')
- StringSid++;
-
- *cBytes = ComputeStringSidSize(StringSid);
- if (!pisid) /* Simply compute the size */
- {
- TRACE("only size requested, returning TRUE\n");
- return TRUE;
- }
+ *pfResult = (BOOL)Result;
- if (StringSid[0] == 'S' && StringSid[1] == '-') /* S-R-I-S-S */
- {
- DWORD i = 0, identAuth;
- DWORD csubauth = ((*cBytes - GetSidLengthRequired(0)) / sizeof(DWORD));
+ return TRUE;
+}
- StringSid += 2; /* Advance to Revision */
- pisid->Revision = atoiW(StringSid);
+/******************************************************************************
+ * ParseAclStringFlags
+ */
+static DWORD ParseAclStringFlags(LPCWSTR* StringAcl)
+{
+ DWORD flags = 0;
+ LPCWSTR szAcl = *StringAcl;
- if (pisid->Revision != SDDL_REVISION)
+ while (*szAcl != '(')
+ {
+ if (*szAcl == 'P')
{
- TRACE("Revision %d is unknown\n", pisid->Revision);
- goto lend; /* ERROR_INVALID_SID */
+ flags |= SE_DACL_PROTECTED;
}
- if (csubauth == 0)
- {
- TRACE("SubAuthorityCount is 0\n");
- goto lend; /* ERROR_INVALID_SID */
- }
-
- pisid->SubAuthorityCount = csubauth;
-
- /* Advance to identifier authority */
- while (*StringSid && *StringSid != '-')
- StringSid++;
- if (*StringSid == '-')
- StringSid++;
-
- /* MS' implementation can't handle values greater than 2^32 - 1, so
- * we don't either; assume most significant bytes are always 0
- */
- pisid->IdentifierAuthority.Value[0] = 0;
- pisid->IdentifierAuthority.Value[1] = 0;
- identAuth = atoiW(StringSid);
- pisid->IdentifierAuthority.Value[5] = identAuth & 0xff;
- pisid->IdentifierAuthority.Value[4] = (identAuth & 0xff00) >> 8;
- pisid->IdentifierAuthority.Value[3] = (identAuth & 0xff0000) >> 16;
- pisid->IdentifierAuthority.Value[2] = (identAuth & 0xff000000) >> 24;
-
- /* Advance to first sub authority */
- while (*StringSid && *StringSid != '-')
- StringSid++;
- if (*StringSid == '-')
- StringSid++;
-
- while (*StringSid)
- {
- pisid->SubAuthority[i++] = atoiW(StringSid);
-
- while (*StringSid && *StringSid != '-')
- StringSid++;
- if (*StringSid == '-')
- StringSid++;
- }
-
- if (i != pisid->SubAuthorityCount)
- goto lend; /* ERROR_INVALID_SID */
-
- bret = TRUE;
- }
- else /* String constant format - Only available in winxp and above */
- {
- unsigned int i;
- pisid->Revision = SDDL_REVISION;
-
- for (i = 0; i < sizeof(WellKnownSids)/sizeof(WellKnownSids[0]); i++)
- if (!strncmpW(WellKnownSids[i].wstr, StringSid, 2))
- {
- DWORD j;
- pisid->SubAuthorityCount = WellKnownSids[i].Sid.SubAuthorityCount;
- pisid->IdentifierAuthority = WellKnownSids[i].Sid.IdentifierAuthority;
- for (j = 0; j < WellKnownSids[i].Sid.SubAuthorityCount; j++)
- pisid->SubAuthority[j] = WellKnownSids[i].Sid.SubAuthority[j];
- bret = TRUE;
- }
-
- if (!bret)
- FIXME("String constant not supported: %s\n", debugstr_wn(StringSid, 2));
- }
-
-lend:
- if (!bret)
- SetLastError(ERROR_INVALID_SID);
-
- TRACE("returning %s\n", bret ? "TRUE" : "FALSE");
- return bret;
-}
-
-/******************************************************************************
- * ParseAclStringFlags
- */
-static DWORD ParseAclStringFlags(LPCWSTR* StringAcl)
-{
- DWORD flags = 0;
- LPCWSTR szAcl = *StringAcl;
-
- while (*szAcl != '(')
- {
- if (*szAcl == 'P')
- {
- flags |= SE_DACL_PROTECTED;
- }
- else if (*szAcl == 'A')
+ else if (*szAcl == 'A')
{
szAcl++;
if (*szAcl == 'R')
return bret;
}
+/* Winehq cvs 20050916 */
+/******************************************************************************
+ * ConvertStringSecurityDescriptorToSecurityDescriptorA [ADVAPI32.@]
+ * @implemented
+ */
+BOOL
+WINAPI
+ConvertStringSecurityDescriptorToSecurityDescriptorA(LPCSTR StringSecurityDescriptor,
+ DWORD StringSDRevision,
+ PSECURITY_DESCRIPTOR* SecurityDescriptor,
+ PULONG SecurityDescriptorSize)
+{
+ UINT len;
+ BOOL ret = FALSE;
+ LPWSTR StringSecurityDescriptorW;
+
+ len = MultiByteToWideChar(CP_ACP, 0, StringSecurityDescriptor, -1, NULL, 0);
+ StringSecurityDescriptorW = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
+
+ if (StringSecurityDescriptorW)
+ {
+ MultiByteToWideChar(CP_ACP, 0, StringSecurityDescriptor, -1, StringSecurityDescriptorW, len);
+
+ ret = ConvertStringSecurityDescriptorToSecurityDescriptorW(StringSecurityDescriptorW,
+ StringSDRevision, SecurityDescriptor,
+ SecurityDescriptorSize);
+ HeapFree(GetProcessHeap(), 0, StringSecurityDescriptorW);
+ }
+
+ return ret;
+}
/******************************************************************************
* ConvertStringSecurityDescriptorToSecurityDescriptorW [ADVAPI32.@]
return bret;
}
-
-/* Winehq cvs 20050916 */
-/******************************************************************************
- * ConvertStringSecurityDescriptorToSecurityDescriptorA [ADVAPI32.@]
- * @implemented
- */
-BOOL
-WINAPI
-ConvertStringSecurityDescriptorToSecurityDescriptorA(LPCSTR StringSecurityDescriptor,
- DWORD StringSDRevision,
- PSECURITY_DESCRIPTOR* SecurityDescriptor,
- PULONG SecurityDescriptorSize)
+static void DumpString(LPCWSTR string, int cch, WCHAR **pwptr, ULONG *plen)
{
- UINT len;
- BOOL ret = FALSE;
- LPWSTR StringSecurityDescriptorW;
+ if (cch == -1)
+ cch = strlenW(string);
- len = MultiByteToWideChar(CP_ACP, 0, StringSecurityDescriptor, -1, NULL, 0);
- StringSecurityDescriptorW = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
+ if (plen)
+ *plen += cch;
- if (StringSecurityDescriptorW)
+ if (pwptr)
{
- MultiByteToWideChar(CP_ACP, 0, StringSecurityDescriptor, -1, StringSecurityDescriptorW, len);
-
- ret = ConvertStringSecurityDescriptorToSecurityDescriptorW(StringSecurityDescriptorW,
- StringSDRevision, SecurityDescriptor,
- SecurityDescriptorSize);
- HeapFree(GetProcessHeap(), 0, StringSecurityDescriptorW);
+ memcpy(*pwptr, string, sizeof(WCHAR)*cch);
+ *pwptr += cch;
}
-
- return ret;
-}
-
-/*
- * @implemented
- */
-BOOL
-WINAPI
-EqualPrefixSid(PSID pSid1,
- PSID pSid2)
-{
- return RtlEqualPrefixSid (pSid1, pSid2);
}
-
-/*
- * @implemented
- */
-BOOL
-WINAPI
-EqualSid(PSID pSid1,
- PSID pSid2)
+static BOOL DumpSidNumeric(PSID psid, WCHAR **pwptr, ULONG *plen)
{
- SetLastError(ERROR_SUCCESS);
- return RtlEqualSid (pSid1, pSid2);
-}
+ DWORD i;
+ WCHAR fmt[] = { 'S','-','%','u','-','%','d',0 };
+ WCHAR subauthfmt[] = { '-','%','u',0 };
+ WCHAR buf[26];
+ SID *pisid = psid;
+ if( !IsValidSid( psid ) || pisid->Revision != SDDL_REVISION)
+ {
+ SetLastError(ERROR_INVALID_SID);
+ return FALSE;
+ }
-/*
- * @implemented
- *
- * RETURNS
- * Docs says this function does NOT return a value
- * even thou it's defined to return a PVOID...
- */
-PVOID
-WINAPI
-FreeSid(PSID pSid)
-{
- return RtlFreeSid(pSid);
-}
+ if (pisid->IdentifierAuthority.Value[0] ||
+ pisid->IdentifierAuthority.Value[1])
+ {
+ FIXME("not matching MS' bugs\n");
+ SetLastError(ERROR_INVALID_SID);
+ return FALSE;
+ }
+ sprintfW( buf, fmt, pisid->Revision,
+ MAKELONG(
+ MAKEWORD( pisid->IdentifierAuthority.Value[5],
+ pisid->IdentifierAuthority.Value[4] ),
+ MAKEWORD( pisid->IdentifierAuthority.Value[3],
+ pisid->IdentifierAuthority.Value[2] )
+ ) );
+ DumpString(buf, -1, pwptr, plen);
-/*
- * @implemented
- */
-DWORD
-WINAPI
-GetLengthSid(PSID pSid)
-{
- return (DWORD)RtlLengthSid(pSid);
+ for( i=0; i<pisid->SubAuthorityCount; i++ )
+ {
+ sprintfW( buf, subauthfmt, pisid->SubAuthority[i] );
+ DumpString(buf, -1, pwptr, plen);
+ }
+ return TRUE;
}
-
-/*
- * @implemented
- */
-PSID_IDENTIFIER_AUTHORITY
-WINAPI
-GetSidIdentifierAuthority(PSID pSid)
+static BOOL DumpSid(PSID psid, WCHAR **pwptr, ULONG *plen)
{
- return RtlIdentifierAuthoritySid(pSid);
-}
-
+ size_t i;
+ for (i = 0; i < sizeof(WellKnownSids) / sizeof(WellKnownSids[0]); i++)
+ {
+ if (WellKnownSids[i].wstr[0] && EqualSid(psid, (PSID)&(WellKnownSids[i].Sid.Revision)))
+ {
+ DumpString(WellKnownSids[i].wstr, 2, pwptr, plen);
+ return TRUE;
+ }
+ }
-/*
- * @implemented
- */
-DWORD
-WINAPI
-GetSidLengthRequired(UCHAR nSubAuthorityCount)
-{
- return (DWORD)RtlLengthRequiredSid(nSubAuthorityCount);
+ return DumpSidNumeric(psid, pwptr, plen);
}
-
-/*
- * @implemented
- */
-PDWORD
-WINAPI
-GetSidSubAuthority(PSID pSid,
- DWORD nSubAuthority)
+static const LPCWSTR AceRightBitNames[32] = {
+ SDDL_CREATE_CHILD, /* 0 */
+ SDDL_DELETE_CHILD,
+ SDDL_LIST_CHILDREN,
+ SDDL_SELF_WRITE,
+ SDDL_READ_PROPERTY, /* 4 */
+ SDDL_WRITE_PROPERTY,
+ SDDL_DELETE_TREE,
+ SDDL_LIST_OBJECT,
+ SDDL_CONTROL_ACCESS, /* 8 */
+ NULL,
+ NULL,
+ NULL,
+ NULL, /* 12 */
+ NULL,
+ NULL,
+ NULL,
+ SDDL_STANDARD_DELETE, /* 16 */
+ SDDL_READ_CONTROL,
+ SDDL_WRITE_DAC,
+ SDDL_WRITE_OWNER,
+ NULL, /* 20 */
+ NULL,
+ NULL,
+ NULL,
+ NULL, /* 24 */
+ NULL,
+ NULL,
+ NULL,
+ SDDL_GENERIC_ALL, /* 28 */
+ SDDL_GENERIC_EXECUTE,
+ SDDL_GENERIC_WRITE,
+ SDDL_GENERIC_READ
+};
+
+static void DumpRights(DWORD mask, WCHAR **pwptr, ULONG *plen)
{
- SetLastError(ERROR_SUCCESS);
- return (PDWORD)RtlSubAuthoritySid(pSid, nSubAuthority);
+ static const WCHAR fmtW[] = {'0','x','%','x',0};
+ WCHAR buf[15];
+ size_t i;
+
+ if (mask == 0)
+ return;
+
+ /* first check if the right have name */
+ for (i = 0; i < sizeof(AceRights)/sizeof(AceRights[0]); i++)
+ {
+ if (AceRights[i].wstr == NULL)
+ break;
+ if (mask == AceRights[i].value)
+ {
+ DumpString(AceRights[i].wstr, -1, pwptr, plen);
+ return;
+ }
+ }
+
+ /* then check if it can be built from bit names */
+ for (i = 0; i < 32; i++)
+ {
+ if ((mask & (1 << i)) && (AceRightBitNames[i] == NULL))
+ {
+ /* can't be built from bit names */
+ sprintfW(buf, fmtW, mask);
+ DumpString(buf, -1, pwptr, plen);
+ return;
+ }
+ }
+
+ /* build from bit names */
+ for (i = 0; i < 32; i++)
+ if (mask & (1 << i))
+ DumpString(AceRightBitNames[i], -1, pwptr, plen);
+}
+
+static BOOL DumpAce(LPVOID pace, WCHAR **pwptr, ULONG *plen)
+{
+ ACCESS_ALLOWED_ACE *piace; /* all the supported ACEs have the same memory layout */
+ static const WCHAR openbr = '(';
+ static const WCHAR closebr = ')';
+ static const WCHAR semicolon = ';';
+
+ if (((PACE_HEADER)pace)->AceType > SYSTEM_ALARM_ACE_TYPE || ((PACE_HEADER)pace)->AceSize < sizeof(ACCESS_ALLOWED_ACE))
+ {
+ SetLastError(ERROR_INVALID_ACL);
+ return FALSE;
+ }
+
+ piace = pace;
+ DumpString(&openbr, 1, pwptr, plen);
+ switch (piace->Header.AceType)
+ {
+ case ACCESS_ALLOWED_ACE_TYPE:
+ DumpString(SDDL_ACCESS_ALLOWED, -1, pwptr, plen);
+ break;
+ case ACCESS_DENIED_ACE_TYPE:
+ DumpString(SDDL_ACCESS_DENIED, -1, pwptr, plen);
+ break;
+ case SYSTEM_AUDIT_ACE_TYPE:
+ DumpString(SDDL_AUDIT, -1, pwptr, plen);
+ break;
+ case SYSTEM_ALARM_ACE_TYPE:
+ DumpString(SDDL_ALARM, -1, pwptr, plen);
+ break;
+ }
+ DumpString(&semicolon, 1, pwptr, plen);
+
+ if (piace->Header.AceFlags & OBJECT_INHERIT_ACE)
+ DumpString(SDDL_OBJECT_INHERIT, -1, pwptr, plen);
+ if (piace->Header.AceFlags & CONTAINER_INHERIT_ACE)
+ DumpString(SDDL_CONTAINER_INHERIT, -1, pwptr, plen);
+ if (piace->Header.AceFlags & NO_PROPAGATE_INHERIT_ACE)
+ DumpString(SDDL_NO_PROPAGATE, -1, pwptr, plen);
+ if (piace->Header.AceFlags & INHERIT_ONLY_ACE)
+ DumpString(SDDL_INHERIT_ONLY, -1, pwptr, plen);
+ if (piace->Header.AceFlags & INHERITED_ACE)
+ DumpString(SDDL_INHERITED, -1, pwptr, plen);
+ if (piace->Header.AceFlags & SUCCESSFUL_ACCESS_ACE_FLAG)
+ DumpString(SDDL_AUDIT_SUCCESS, -1, pwptr, plen);
+ if (piace->Header.AceFlags & FAILED_ACCESS_ACE_FLAG)
+ DumpString(SDDL_AUDIT_FAILURE, -1, pwptr, plen);
+ DumpString(&semicolon, 1, pwptr, plen);
+ DumpRights(piace->Mask, pwptr, plen);
+ DumpString(&semicolon, 1, pwptr, plen);
+ /* objects not supported */
+ DumpString(&semicolon, 1, pwptr, plen);
+ /* objects not supported */
+ DumpString(&semicolon, 1, pwptr, plen);
+ if (!DumpSid((PSID)&piace->SidStart, pwptr, plen))
+ return FALSE;
+ DumpString(&closebr, 1, pwptr, plen);
+ return TRUE;
+}
+
+static BOOL DumpAcl(PACL pacl, WCHAR **pwptr, ULONG *plen, BOOL protected, BOOL autoInheritReq, BOOL autoInherited)
+{
+ WORD count;
+ int i;
+
+ if (protected)
+ DumpString(SDDL_PROTECTED, -1, pwptr, plen);
+ if (autoInheritReq)
+ DumpString(SDDL_AUTO_INHERIT_REQ, -1, pwptr, plen);
+ if (autoInherited)
+ DumpString(SDDL_AUTO_INHERITED, -1, pwptr, plen);
+
+ if (pacl == NULL)
+ return TRUE;
+
+ if (!IsValidAcl(pacl))
+ return FALSE;
+
+ count = pacl->AceCount;
+ for (i = 0; i < count; i++)
+ {
+ LPVOID ace;
+ if (!GetAce(pacl, i, &ace))
+ return FALSE;
+ if (!DumpAce(ace, pwptr, plen))
+ return FALSE;
+ }
+
+ return TRUE;
+}
+
+static BOOL DumpOwner(PSECURITY_DESCRIPTOR SecurityDescriptor, WCHAR **pwptr, ULONG *plen)
+{
+ static const WCHAR prefix[] = {'O',':',0};
+ BOOL bDefaulted;
+ PSID psid;
+
+ if (!GetSecurityDescriptorOwner(SecurityDescriptor, &psid, &bDefaulted))
+ return FALSE;
+
+ if (psid == NULL)
+ return TRUE;
+
+ DumpString(prefix, -1, pwptr, plen);
+ if (!DumpSid(psid, pwptr, plen))
+ return FALSE;
+ return TRUE;
+}
+
+static BOOL DumpGroup(PSECURITY_DESCRIPTOR SecurityDescriptor, WCHAR **pwptr, ULONG *plen)
+{
+ static const WCHAR prefix[] = {'G',':',0};
+ BOOL bDefaulted;
+ PSID psid;
+
+ if (!GetSecurityDescriptorGroup(SecurityDescriptor, &psid, &bDefaulted))
+ return FALSE;
+
+ if (psid == NULL)
+ return TRUE;
+
+ DumpString(prefix, -1, pwptr, plen);
+ if (!DumpSid(psid, pwptr, plen))
+ return FALSE;
+ return TRUE;
+}
+
+static BOOL DumpDacl(PSECURITY_DESCRIPTOR SecurityDescriptor, WCHAR **pwptr, ULONG *plen)
+{
+ static const WCHAR dacl[] = {'D',':',0};
+ SECURITY_DESCRIPTOR_CONTROL control;
+ BOOL present, defaulted;
+ DWORD revision;
+ PACL pacl;
+
+ if (!GetSecurityDescriptorDacl(SecurityDescriptor, &present, &pacl, &defaulted))
+ return FALSE;
+
+ if (!GetSecurityDescriptorControl(SecurityDescriptor, &control, &revision))
+ return FALSE;
+
+ if (!present)
+ return TRUE;
+
+ DumpString(dacl, 2, pwptr, plen);
+ if (!DumpAcl(pacl, pwptr, plen, control & SE_DACL_PROTECTED, control & SE_DACL_AUTO_INHERIT_REQ, control & SE_DACL_AUTO_INHERITED))
+ return FALSE;
+ return TRUE;
+}
+
+static BOOL DumpSacl(PSECURITY_DESCRIPTOR SecurityDescriptor, WCHAR **pwptr, ULONG *plen)
+{
+ static const WCHAR sacl[] = {'S',':',0};
+ SECURITY_DESCRIPTOR_CONTROL control;
+ BOOL present, defaulted;
+ DWORD revision;
+ PACL pacl;
+
+ if (!GetSecurityDescriptorSacl(SecurityDescriptor, &present, &pacl, &defaulted))
+ return FALSE;
+
+ if (!GetSecurityDescriptorControl(SecurityDescriptor, &control, &revision))
+ return FALSE;
+
+ if (!present)
+ return TRUE;
+
+ DumpString(sacl, 2, pwptr, plen);
+ if (!DumpAcl(pacl, pwptr, plen, control & SE_SACL_PROTECTED, control & SE_SACL_AUTO_INHERIT_REQ, control & SE_SACL_AUTO_INHERITED))
+ return FALSE;
+ return TRUE;
+}
+
+/******************************************************************************
+ * ConvertSecurityDescriptorToStringSecurityDescriptorW [ADVAPI32.@]
+ * @implemented
+ */
+BOOL WINAPI
+ConvertSecurityDescriptorToStringSecurityDescriptorW(PSECURITY_DESCRIPTOR SecurityDescriptor,
+ DWORD SDRevision,
+ SECURITY_INFORMATION SecurityInformation,
+ LPWSTR *OutputString,
+ PULONG OutputLen)
+{
+ ULONG len;
+ WCHAR *wptr, *wstr;
+
+ if (SDRevision != SDDL_REVISION_1)
+ {
+ ERR("Program requested unknown SDDL revision %d\n", SDRevision);
+ SetLastError(ERROR_UNKNOWN_REVISION);
+ return FALSE;
+ }
+
+ len = 0;
+ if (SecurityInformation & OWNER_SECURITY_INFORMATION)
+ if (!DumpOwner(SecurityDescriptor, NULL, &len))
+ return FALSE;
+ if (SecurityInformation & GROUP_SECURITY_INFORMATION)
+ if (!DumpGroup(SecurityDescriptor, NULL, &len))
+ return FALSE;
+ if (SecurityInformation & DACL_SECURITY_INFORMATION)
+ if (!DumpDacl(SecurityDescriptor, NULL, &len))
+ return FALSE;
+ if (SecurityInformation & SACL_SECURITY_INFORMATION)
+ if (!DumpSacl(SecurityDescriptor, NULL, &len))
+ return FALSE;
+
+ wstr = wptr = LocalAlloc(0, (len + 1)*sizeof(WCHAR));
+ if (wstr == NULL)
+ return FALSE;
+
+ if (SecurityInformation & OWNER_SECURITY_INFORMATION)
+ if (!DumpOwner(SecurityDescriptor, &wptr, NULL))
+ return FALSE;
+ if (SecurityInformation & GROUP_SECURITY_INFORMATION)
+ if (!DumpGroup(SecurityDescriptor, &wptr, NULL))
+ return FALSE;
+ if (SecurityInformation & DACL_SECURITY_INFORMATION)
+ if (!DumpDacl(SecurityDescriptor, &wptr, NULL))
+ return FALSE;
+ if (SecurityInformation & SACL_SECURITY_INFORMATION)
+ if (!DumpSacl(SecurityDescriptor, &wptr, NULL))
+ return FALSE;
+ *wptr = 0;
+
+ TRACE("ret: %s, %d\n", wine_dbgstr_w(wstr), len);
+ *OutputString = wstr;
+ if (OutputLen)
+ *OutputLen = strlenW(*OutputString)+1;
+ return TRUE;
}
+/******************************************************************************
+ * ConvertSecurityDescriptorToStringSecurityDescriptorA [ADVAPI32.@]
+ * @implemented
+ */
+BOOL WINAPI
+ConvertSecurityDescriptorToStringSecurityDescriptorA(PSECURITY_DESCRIPTOR SecurityDescriptor,
+ DWORD SDRevision,
+ SECURITY_INFORMATION Information,
+ LPSTR *OutputString,
+ PULONG OutputLen)
+{
+ LPWSTR wstr;
+ ULONG len;
+
+ if (ConvertSecurityDescriptorToStringSecurityDescriptorW(SecurityDescriptor, SDRevision, Information, &wstr, &len))
+ {
+ int lenA;
+
+ lenA = WideCharToMultiByte(CP_ACP, 0, wstr, len, NULL, 0, NULL, NULL);
+ *OutputString = HeapAlloc(GetProcessHeap(), 0, lenA);
+ if (*OutputString == NULL)
+ {
+ LocalFree(wstr);
+ *OutputLen = 0;
+ return FALSE;
+ }
+ WideCharToMultiByte(CP_ACP, 0, wstr, len, *OutputString, lenA, NULL, NULL);
+ LocalFree(wstr);
+
+ if (OutputLen != NULL)
+ *OutputLen = lenA;
+ return TRUE;
+ }
+ else
+ {
+ *OutputString = NULL;
+ if (OutputLen)
+ *OutputLen = 0;
+ return FALSE;
+ }
+}
/*
* @implemented
*/
-PUCHAR
+BOOL
WINAPI
-GetSidSubAuthorityCount(PSID pSid)
+ConvertStringSidToSidW(IN LPCWSTR StringSid,
+ OUT PSID* sid)
{
- SetLastError(ERROR_SUCCESS);
- return RtlSubAuthorityCountSid(pSid);
-}
+ DWORD size;
+ DWORD i, cBytes, identAuth, csubauth;
+ BOOL ret;
+ SID* pisid;
+
+ TRACE("%s %p\n", debugstr_w(StringSid), sid);
+
+ if (!StringSid)
+ {
+ SetLastError(ERROR_INVALID_SID);
+ return FALSE;
+ }
+
+ for (i = 0; i < sizeof(SidTable) / sizeof(SidTable[0]) - 1; i++)
+ {
+ if (wcscmp(StringSid, SidTable[i].key) == 0)
+ {
+ WELL_KNOWN_SID_TYPE knownSid = (WELL_KNOWN_SID_TYPE)SidTable[i].value;
+ size = SECURITY_MAX_SID_SIZE;
+ *sid = LocalAlloc(0, size);
+ if (!*sid)
+ {
+ SetLastError(ERROR_NOT_ENOUGH_MEMORY);
+ return FALSE;
+ }
+ ret = CreateWellKnownSid(knownSid,
+ NULL,
+ *sid,
+ &size);
+ if (!ret)
+ {
+ SetLastError(ERROR_INVALID_SID);
+ LocalFree(*sid);
+ }
+ return ret;
+ }
+ }
+
+ /* That's probably a string S-R-I-S-S... */
+ if (StringSid[0] != 'S' || StringSid[1] != '-')
+ {
+ SetLastError(ERROR_INVALID_SID);
+ return FALSE;
+ }
+ cBytes = ComputeStringSidSize(StringSid);
+ pisid = (SID*)LocalAlloc( 0, cBytes );
+ if (!pisid)
+ {
+ SetLastError(ERROR_NOT_ENOUGH_MEMORY);
+ return FALSE;
+ }
+ i = 0;
+ ret = FALSE;
+ csubauth = ((cBytes - GetSidLengthRequired(0)) / sizeof(DWORD));
+
+ StringSid += 2; /* Advance to Revision */
+ pisid->Revision = atoiW(StringSid);
+
+ if (pisid->Revision != SDDL_REVISION)
+ {
+ TRACE("Revision %d is unknown\n", pisid->Revision);
+ goto lend; /* ERROR_INVALID_SID */
+ }
+ if (csubauth == 0)
+ {
+ TRACE("SubAuthorityCount is 0\n");
+ goto lend; /* ERROR_INVALID_SID */
+ }
+
+ pisid->SubAuthorityCount = csubauth;
+
+ /* Advance to identifier authority */
+ while (*StringSid && *StringSid != '-')
+ StringSid++;
+ if (*StringSid == '-')
+ StringSid++;
+
+ /* MS' implementation can't handle values greater than 2^32 - 1, so
+ * we don't either; assume most significant bytes are always 0
+ */
+ pisid->IdentifierAuthority.Value[0] = 0;
+ pisid->IdentifierAuthority.Value[1] = 0;
+ identAuth = atoiW(StringSid);
+ pisid->IdentifierAuthority.Value[5] = identAuth & 0xff;
+ pisid->IdentifierAuthority.Value[4] = (identAuth & 0xff00) >> 8;
+ pisid->IdentifierAuthority.Value[3] = (identAuth & 0xff0000) >> 16;
+ pisid->IdentifierAuthority.Value[2] = (identAuth & 0xff000000) >> 24;
+
+ /* Advance to first sub authority */
+ while (*StringSid && *StringSid != '-')
+ StringSid++;
+ if (*StringSid == '-')
+ StringSid++;
+
+ while (*StringSid)
+ {
+ pisid->SubAuthority[i++] = atoiW(StringSid);
+
+ while (*StringSid && *StringSid != '-')
+ StringSid++;
+ if (*StringSid == '-')
+ StringSid++;
+ }
+
+ if (i != pisid->SubAuthorityCount)
+ goto lend; /* ERROR_INVALID_SID */
-/*
- * @implemented
- */
-BOOL
-WINAPI
-InitializeSid(PSID Sid,
- PSID_IDENTIFIER_AUTHORITY pIdentifierAuthority,
- BYTE nSubAuthorityCount)
-{
- NTSTATUS Status;
+ *sid = pisid;
+ ret = TRUE;
- Status = RtlInitializeSid(Sid,
- pIdentifierAuthority,
- nSubAuthorityCount);
- if (!NT_SUCCESS(Status))
+lend:
+ if (!ret)
{
- SetLastError(RtlNtStatusToDosError(Status));
- return FALSE;
+ LocalFree(pisid);
+ SetLastError(ERROR_INVALID_SID);
}
- return TRUE;
+ TRACE("returning %s\n", ret ? "TRUE" : "FALSE");
+ return ret;
}
-
/*
* @implemented
*/
BOOL
WINAPI
-IsValidSid(PSID pSid)
+ConvertStringSidToSidA(IN LPCSTR StringSid,
+ OUT PSID* sid)
{
- return (BOOL)RtlValidSid(pSid);
-}
+ BOOL bRetVal = FALSE;
+ TRACE("%s, %p\n", debugstr_a(StringSid), sid);
+ if (GetVersion() & 0x80000000)
+ SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+ else if (!StringSid || !sid)
+ SetLastError(ERROR_INVALID_PARAMETER);
+ else
+ {
+ UINT len = MultiByteToWideChar(CP_ACP, 0, StringSid, -1, NULL, 0);
+ LPWSTR wStringSid = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
+ if (wStringSid == NULL)
+ return FALSE;
+ MultiByteToWideChar(CP_ACP, 0, StringSid, - 1, wStringSid, len);
+ bRetVal = ConvertStringSidToSidW(wStringSid, sid);
+ HeapFree(GetProcessHeap(), 0, wStringSid);
+ }
+ return bRetVal;
+}
/*
* @implemented
return TRUE;
}
-
/*
* @implemented
*/
return FALSE;
}
- LocalFree(StringSidW);
-
- return TRUE;
-}
-
-
-/*
- * @unimplemented
- */
-BOOL
-WINAPI
-EqualDomainSid(IN PSID pSid1,
- IN PSID pSid2,
- OUT BOOL* pfEqual)
-{
- UNIMPLEMENTED;
- return FALSE;
-}
-
-
-/*
- * @unimplemented
- */
-BOOL
-WINAPI
-GetWindowsAccountDomainSid(IN PSID pSid,
- OUT PSID ppDomainSid,
- IN OUT DWORD* cbSid)
-{
- UNIMPLEMENTED;
- return FALSE;
-}
-
-
-/*
- * @unimplemented
- */
-BOOL
-WINAPI
-CreateWellKnownSid(IN WELL_KNOWN_SID_TYPE WellKnownSidType,
- IN PSID DomainSid OPTIONAL,
- OUT PSID pSid,
- IN OUT DWORD* cbSid)
-{
- unsigned int i;
- TRACE("(%d, %s, %p, %p)\n", WellKnownSidType, debugstr_sid(DomainSid), pSid, cbSid);
-
- if (cbSid == NULL || (DomainSid && !IsValidSid(DomainSid)))
- {
- SetLastError(ERROR_INVALID_PARAMETER);
- return FALSE;
- }
-
- for (i = 0; i < sizeof(WellKnownSids)/sizeof(WellKnownSids[0]); i++) {
- if (WellKnownSids[i].Type == WellKnownSidType) {
- DWORD length = GetSidLengthRequired(WellKnownSids[i].Sid.SubAuthorityCount);
-
- if (*cbSid < length)
- {
- *cbSid = length;
- SetLastError(ERROR_INSUFFICIENT_BUFFER);
- return FALSE;
- }
- if (!pSid)
- {
- SetLastError(ERROR_INVALID_PARAMETER);
- return FALSE;
- }
- CopyMemory(pSid, &WellKnownSids[i].Sid.Revision, length);
- *cbSid = length;
- return TRUE;
- }
- }
-
- if (DomainSid == NULL || *GetSidSubAuthorityCount(DomainSid) == SID_MAX_SUB_AUTHORITIES)
- {
- SetLastError(ERROR_INVALID_PARAMETER);
- return FALSE;
- }
-
- for (i = 0; i < sizeof(WellKnownRids)/sizeof(WellKnownRids[0]); i++)
- if (WellKnownRids[i].Type == WellKnownSidType) {
- UCHAR domain_subauth = *GetSidSubAuthorityCount(DomainSid);
- DWORD domain_sid_length = GetSidLengthRequired(domain_subauth);
- DWORD output_sid_length = GetSidLengthRequired(domain_subauth + 1);
-
- if (*cbSid < output_sid_length)
- {
- *cbSid = output_sid_length;
- SetLastError(ERROR_INSUFFICIENT_BUFFER);
- return FALSE;
- }
- if (!pSid)
- {
- SetLastError(ERROR_INVALID_PARAMETER);
- return FALSE;
- }
- CopyMemory(pSid, DomainSid, domain_sid_length);
- (*GetSidSubAuthorityCount(pSid))++;
- (*GetSidSubAuthority(pSid, domain_subauth)) = WellKnownRids[i].Rid;
- *cbSid = output_sid_length;
- return TRUE;
- }
-
- SetLastError(ERROR_INVALID_PARAMETER);
- return FALSE;
-}
-
-
-/*
- * @unimplemented
- */
-BOOL
-WINAPI
-IsWellKnownSid(IN PSID pSid,
- IN WELL_KNOWN_SID_TYPE WellKnownSidType)
-{
- unsigned int i;
- TRACE("(%s, %d)\n", debugstr_sid(pSid), WellKnownSidType);
-
- for (i = 0; i < sizeof(WellKnownSids) / sizeof(WellKnownSids[0]); i++)
- {
- if (WellKnownSids[i].Type == WellKnownSidType)
- {
- if (EqualSid(pSid, (PSID)(&WellKnownSids[i].Sid.Revision)))
- return TRUE;
- }
- }
-
- return FALSE;
-}
-
-
-/*
- * @implemented
- */
-BOOL
-WINAPI
-ConvertStringSidToSidA(IN LPCSTR StringSid,
- OUT PSID* sid)
-{
- BOOL bRetVal = FALSE;
-
- TRACE("%s, %p\n", debugstr_a(StringSid), sid);
- if (GetVersion() & 0x80000000)
- SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
- else if (!StringSid || !sid)
- SetLastError(ERROR_INVALID_PARAMETER);
- else
- {
- UINT len = MultiByteToWideChar(CP_ACP, 0, StringSid, -1, NULL, 0);
- LPWSTR wStringSid = HeapAlloc(GetProcessHeap(), 0, len * sizeof(WCHAR));
- if (wStringSid == NULL)
- return FALSE;
- MultiByteToWideChar(CP_ACP, 0, StringSid, - 1, wStringSid, len);
- bRetVal = ConvertStringSidToSidW(wStringSid, sid);
- HeapFree(GetProcessHeap(), 0, wStringSid);
- }
- return bRetVal;
-}
-
-
-static const RECORD SidTable[] =
-{
- { SDDL_ACCOUNT_OPERATORS, WinBuiltinAccountOperatorsSid },
- { SDDL_ALIAS_PREW2KCOMPACC, WinBuiltinPreWindows2000CompatibleAccessSid },
- { SDDL_ANONYMOUS, WinAnonymousSid },
- { SDDL_AUTHENTICATED_USERS, WinAuthenticatedUserSid },
- { SDDL_BUILTIN_ADMINISTRATORS, WinBuiltinAdministratorsSid },
- { SDDL_BUILTIN_GUESTS, WinBuiltinGuestsSid },
- { SDDL_BACKUP_OPERATORS, WinBuiltinBackupOperatorsSid },
- { SDDL_BUILTIN_USERS, WinBuiltinUsersSid },
- { SDDL_CERT_SERV_ADMINISTRATORS, WinAccountCertAdminsSid /* FIXME: DOMAIN_GROUP_RID_CERT_ADMINS */ },
- { SDDL_CREATOR_GROUP, WinCreatorGroupSid },
- { SDDL_CREATOR_OWNER, WinCreatorOwnerSid },
- { SDDL_DOMAIN_ADMINISTRATORS, WinAccountDomainAdminsSid /* FIXME: DOMAIN_GROUP_RID_ADMINS */ },
- { SDDL_DOMAIN_COMPUTERS, WinAccountComputersSid /* FIXME: DOMAIN_GROUP_RID_COMPUTERS */ },
- { SDDL_DOMAIN_DOMAIN_CONTROLLERS, WinAccountControllersSid /* FIXME: DOMAIN_GROUP_RID_CONTROLLERS */ },
- { SDDL_DOMAIN_GUESTS, WinAccountDomainGuestsSid /* FIXME: DOMAIN_GROUP_RID_GUESTS */ },
- { SDDL_DOMAIN_USERS, WinAccountDomainUsersSid /* FIXME: DOMAIN_GROUP_RID_USERS */ },
- { SDDL_ENTERPRISE_ADMINS, WinAccountEnterpriseAdminsSid /* FIXME: DOMAIN_GROUP_RID_ENTERPRISE_ADMINS */ },
- { SDDL_ENTERPRISE_DOMAIN_CONTROLLERS, WinEnterpriseControllersSid },
- { SDDL_EVERYONE, WinWorldSid },
- { SDDL_GROUP_POLICY_ADMINS, WinAccountPolicyAdminsSid /* FIXME: DOMAIN_GROUP_RID_POLICY_ADMINS */ },
- { SDDL_INTERACTIVE, WinInteractiveSid },
- { SDDL_LOCAL_ADMIN, WinAccountAdministratorSid /* FIXME: DOMAIN_USER_RID_ADMIN */ },
- { SDDL_LOCAL_GUEST, WinAccountGuestSid /* FIXME: DOMAIN_USER_RID_GUEST */ },
- { SDDL_LOCAL_SERVICE, WinLocalServiceSid },
- { SDDL_LOCAL_SYSTEM, WinLocalSystemSid },
- { SDDL_NETWORK, WinNetworkSid },
- { SDDL_NETWORK_CONFIGURATION_OPS, WinBuiltinNetworkConfigurationOperatorsSid },
- { SDDL_NETWORK_SERVICE, WinNetworkServiceSid },
- { SDDL_PRINTER_OPERATORS, WinBuiltinPrintOperatorsSid },
- { SDDL_PERSONAL_SELF, WinSelfSid },
- { SDDL_POWER_USERS, WinBuiltinPowerUsersSid },
- { SDDL_RAS_SERVERS, WinAccountRasAndIasServersSid /* FIXME: DOMAIN_ALIAS_RID_RAS_SERVERS */ },
- { SDDL_REMOTE_DESKTOP, WinBuiltinRemoteDesktopUsersSid },
- { SDDL_REPLICATOR, WinBuiltinReplicatorSid },
- { SDDL_RESTRICTED_CODE, WinRestrictedCodeSid },
- { SDDL_SCHEMA_ADMINISTRATORS, WinAccountSchemaAdminsSid /* FIXME: DOMAIN_GROUP_RID_SCHEMA_ADMINS */ },
- { SDDL_SERVER_OPERATORS, WinBuiltinSystemOperatorsSid },
- { SDDL_SERVICE, WinServiceSid },
- { NULL, 0 },
-};
-
+ LocalFree(StringSidW);
+
+ return TRUE;
+}
+
+BOOL
+WINAPI
+CreateProcessWithTokenW(IN HANDLE hToken,
+ IN DWORD dwLogonFlags,
+ IN LPCWSTR lpApplicationName OPTIONAL,
+ IN OUT LPWSTR lpCommandLine OPTIONAL,
+ IN DWORD dwCreationFlags,
+ IN LPVOID lpEnvironment OPTIONAL,
+ IN LPCWSTR lpCurrentDirectory OPTIONAL,
+ IN LPSTARTUPINFOW lpStartupInfo,
+ OUT LPPROCESS_INFORMATION lpProcessInfo)
+{
+ UNIMPLEMENTED;
+ return FALSE;
+}
+
/*
* @implemented
*/
-BOOL
-WINAPI
-ConvertStringSidToSidW(IN LPCWSTR StringSid,
- OUT PSID* sid)
+BOOL WINAPI
+DuplicateTokenEx(IN HANDLE ExistingTokenHandle,
+ IN DWORD dwDesiredAccess,
+ IN LPSECURITY_ATTRIBUTES lpTokenAttributes OPTIONAL,
+ IN SECURITY_IMPERSONATION_LEVEL ImpersonationLevel,
+ IN TOKEN_TYPE TokenType,
+ OUT PHANDLE DuplicateTokenHandle)
{
- DWORD size;
- DWORD i, cBytes, identAuth, csubauth;
- BOOL ret;
- SID* pisid;
+ OBJECT_ATTRIBUTES ObjectAttributes;
+ NTSTATUS Status;
+ SECURITY_QUALITY_OF_SERVICE Sqos;
- TRACE("%s %p\n", debugstr_w(StringSid), sid);
+ TRACE("%p 0x%08x 0x%08x 0x%08x %p\n", ExistingTokenHandle, dwDesiredAccess,
+ ImpersonationLevel, TokenType, DuplicateTokenHandle);
- if (!StringSid)
+ Sqos.Length = sizeof(SECURITY_QUALITY_OF_SERVICE);
+ Sqos.ImpersonationLevel = ImpersonationLevel;
+ Sqos.ContextTrackingMode = 0;
+ Sqos.EffectiveOnly = FALSE;
+
+ if (lpTokenAttributes != NULL)
{
- SetLastError(ERROR_INVALID_SID);
+ InitializeObjectAttributes(&ObjectAttributes,
+ NULL,
+ lpTokenAttributes->bInheritHandle ? OBJ_INHERIT : 0,
+ NULL,
+ lpTokenAttributes->lpSecurityDescriptor);
+ }
+ else
+ {
+ InitializeObjectAttributes(&ObjectAttributes,
+ NULL,
+ 0,
+ NULL,
+ NULL);
+ }
+
+ ObjectAttributes.SecurityQualityOfService = &Sqos;
+
+ Status = NtDuplicateToken(ExistingTokenHandle,
+ dwDesiredAccess,
+ &ObjectAttributes,
+ FALSE,
+ TokenType,
+ DuplicateTokenHandle);
+ if (!NT_SUCCESS(Status))
+ {
+ ERR("NtDuplicateToken failed: Status %08x\n", Status);
+ SetLastError(RtlNtStatusToDosError(Status));
return FALSE;
}
- for (i = 0; i < sizeof(SidTable) / sizeof(SidTable[0]) - 1; i++)
+ TRACE("Returning token %p.\n", *DuplicateTokenHandle);
+
+ return TRUE;
+}
+
+/*
+ * @implemented
+ */
+BOOL WINAPI
+DuplicateToken(IN HANDLE ExistingTokenHandle,
+ IN SECURITY_IMPERSONATION_LEVEL ImpersonationLevel,
+ OUT PHANDLE DuplicateTokenHandle)
+{
+ return DuplicateTokenEx(ExistingTokenHandle,
+ TOKEN_IMPERSONATE | TOKEN_QUERY,
+ NULL,
+ ImpersonationLevel,
+ TokenImpersonation,
+ DuplicateTokenHandle);
+}
+
+/******************************************************************************
+ * ComputeStringSidSize
+ */
+static DWORD ComputeStringSidSize(LPCWSTR StringSid)
+{
+ if (StringSid[0] == 'S' && StringSid[1] == '-') /* S-R-I(-S)+ */
{
- if (wcscmp(StringSid, SidTable[i].key) == 0)
+ int ctok = 0;
+ while (*StringSid)
{
- WELL_KNOWN_SID_TYPE knownSid = (WELL_KNOWN_SID_TYPE)SidTable[i].value;
- size = SECURITY_MAX_SID_SIZE;
- *sid = LocalAlloc(0, size);
- if (!*sid)
- {
- SetLastError(ERROR_NOT_ENOUGH_MEMORY);
- return FALSE;
- }
- ret = CreateWellKnownSid(knownSid,
- NULL,
- *sid,
- &size);
- if (!ret)
- {
- SetLastError(ERROR_INVALID_SID);
- LocalFree(*sid);
- }
- return ret;
+ if (*StringSid == '-')
+ ctok++;
+ StringSid++;
}
- }
- /* That's probably a string S-R-I-S-S... */
- if (StringSid[0] != 'S' || StringSid[1] != '-')
+ if (ctok >= 3)
+ return GetSidLengthRequired(ctok - 2);
+ }
+ else /* String constant format - Only available in winxp and above */
{
- SetLastError(ERROR_INVALID_SID);
- return FALSE;
+ unsigned int i;
+
+ for (i = 0; i < sizeof(WellKnownSids)/sizeof(WellKnownSids[0]); i++)
+ if (!strncmpW(WellKnownSids[i].wstr, StringSid, 2))
+ return GetSidLengthRequired(WellKnownSids[i].Sid.SubAuthorityCount);
}
- cBytes = ComputeStringSidSize(StringSid);
- pisid = (SID*)LocalAlloc( 0, cBytes );
- if (!pisid)
+ return GetSidLengthRequired(0);
+}
+
+/******************************************************************************
+ * ParseStringSidToSid
+ */
+static BOOL ParseStringSidToSid(LPCWSTR StringSid, PSID pSid, LPDWORD cBytes)
+{
+ BOOL bret = FALSE;
+ SID* pisid=pSid;
+
+ TRACE("%s, %p, %p\n", debugstr_w(StringSid), pSid, cBytes);
+ if (!StringSid)
{
- SetLastError(ERROR_NOT_ENOUGH_MEMORY);
+ SetLastError(ERROR_INVALID_PARAMETER);
+ TRACE("StringSid is NULL, returning FALSE\n");
return FALSE;
}
- i = 0;
- ret = FALSE;
- csubauth = ((cBytes - GetSidLengthRequired(0)) / sizeof(DWORD));
- StringSid += 2; /* Advance to Revision */
- pisid->Revision = atoiW(StringSid);
+ while (*StringSid == ' ')
+ StringSid++;
- if (pisid->Revision != SDDL_REVISION)
+ *cBytes = ComputeStringSidSize(StringSid);
+ if (!pisid) /* Simply compute the size */
{
- TRACE("Revision %d is unknown\n", pisid->Revision);
- goto lend; /* ERROR_INVALID_SID */
+ TRACE("only size requested, returning TRUE\n");
+ return TRUE;
}
- if (csubauth == 0)
+
+ if (StringSid[0] == 'S' && StringSid[1] == '-') /* S-R-I-S-S */
{
- TRACE("SubAuthorityCount is 0\n");
- goto lend; /* ERROR_INVALID_SID */
- }
+ DWORD i = 0, identAuth;
+ DWORD csubauth = ((*cBytes - GetSidLengthRequired(0)) / sizeof(DWORD));
- pisid->SubAuthorityCount = csubauth;
+ StringSid += 2; /* Advance to Revision */
+ pisid->Revision = atoiW(StringSid);
- /* Advance to identifier authority */
- while (*StringSid && *StringSid != '-')
- StringSid++;
- if (*StringSid == '-')
- StringSid++;
+ if (pisid->Revision != SDDL_REVISION)
+ {
+ TRACE("Revision %d is unknown\n", pisid->Revision);
+ goto lend; /* ERROR_INVALID_SID */
+ }
+ if (csubauth == 0)
+ {
+ TRACE("SubAuthorityCount is 0\n");
+ goto lend; /* ERROR_INVALID_SID */
+ }
- /* MS' implementation can't handle values greater than 2^32 - 1, so
- * we don't either; assume most significant bytes are always 0
- */
- pisid->IdentifierAuthority.Value[0] = 0;
- pisid->IdentifierAuthority.Value[1] = 0;
- identAuth = atoiW(StringSid);
- pisid->IdentifierAuthority.Value[5] = identAuth & 0xff;
- pisid->IdentifierAuthority.Value[4] = (identAuth & 0xff00) >> 8;
- pisid->IdentifierAuthority.Value[3] = (identAuth & 0xff0000) >> 16;
- pisid->IdentifierAuthority.Value[2] = (identAuth & 0xff000000) >> 24;
+ pisid->SubAuthorityCount = csubauth;
- /* Advance to first sub authority */
- while (*StringSid && *StringSid != '-')
- StringSid++;
- if (*StringSid == '-')
- StringSid++;
+ /* Advance to identifier authority */
+ while (*StringSid && *StringSid != '-')
+ StringSid++;
+ if (*StringSid == '-')
+ StringSid++;
- while (*StringSid)
- {
- pisid->SubAuthority[i++] = atoiW(StringSid);
+ /* MS' implementation can't handle values greater than 2^32 - 1, so
+ * we don't either; assume most significant bytes are always 0
+ */
+ pisid->IdentifierAuthority.Value[0] = 0;
+ pisid->IdentifierAuthority.Value[1] = 0;
+ identAuth = atoiW(StringSid);
+ pisid->IdentifierAuthority.Value[5] = identAuth & 0xff;
+ pisid->IdentifierAuthority.Value[4] = (identAuth & 0xff00) >> 8;
+ pisid->IdentifierAuthority.Value[3] = (identAuth & 0xff0000) >> 16;
+ pisid->IdentifierAuthority.Value[2] = (identAuth & 0xff000000) >> 24;
+ /* Advance to first sub authority */
while (*StringSid && *StringSid != '-')
StringSid++;
if (*StringSid == '-')
StringSid++;
+
+ while (*StringSid)
+ {
+ pisid->SubAuthority[i++] = atoiW(StringSid);
+
+ while (*StringSid && *StringSid != '-')
+ StringSid++;
+ if (*StringSid == '-')
+ StringSid++;
+ }
+
+ if (i != pisid->SubAuthorityCount)
+ goto lend; /* ERROR_INVALID_SID */
+
+ bret = TRUE;
}
+ else /* String constant format - Only available in winxp and above */
+ {
+ unsigned int i;
+ pisid->Revision = SDDL_REVISION;
- if (i != pisid->SubAuthorityCount)
- goto lend; /* ERROR_INVALID_SID */
+ for (i = 0; i < sizeof(WellKnownSids)/sizeof(WellKnownSids[0]); i++)
+ if (!strncmpW(WellKnownSids[i].wstr, StringSid, 2))
+ {
+ DWORD j;
+ pisid->SubAuthorityCount = WellKnownSids[i].Sid.SubAuthorityCount;
+ pisid->IdentifierAuthority = WellKnownSids[i].Sid.IdentifierAuthority;
+ for (j = 0; j < WellKnownSids[i].Sid.SubAuthorityCount; j++)
+ pisid->SubAuthority[j] = WellKnownSids[i].Sid.SubAuthority[j];
+ bret = TRUE;
+ }
- *sid = pisid;
- ret = TRUE;
+ if (!bret)
+ FIXME("String constant not supported: %s\n", debugstr_wn(StringSid, 2));
+ }
lend:
- if (!ret)
- {
- LocalFree(pisid);
+ if (!bret)
SetLastError(ERROR_INVALID_SID);
- }
- TRACE("returning %s\n", ret ? "TRUE" : "FALSE");
- return ret;
+ TRACE("returning %s\n", bret ? "TRUE" : "FALSE");
+ return bret;
+}
+
+/*
+ * @unimplemented
+ */
+BOOL
+WINAPI
+GetWindowsAccountDomainSid(IN PSID pSid,
+ OUT PSID ppDomainSid,
+ IN OUT DWORD* cbSid)
+{
+ UNIMPLEMENTED;
+ return FALSE;
+}
+
+/*
+ * @unimplemented
+ */
+BOOL
+WINAPI
+EqualDomainSid(IN PSID pSid1,
+ IN PSID pSid2,
+ OUT BOOL* pfEqual)
+{
+ UNIMPLEMENTED;
+ return FALSE;
}
/* EOF */