diff --git a/reactos/dll/win32/advapi32/advapi32.rbuild b/reactos/dll/win32/advapi32/advapi32.rbuild
index 07b0a5420d9..776a8ca930d 100644
--- a/reactos/dll/win32/advapi32/advapi32.rbuild
+++ b/reactos/dll/win32/advapi32/advapi32.rbuild
@@ -7,6 +7,8 @@
0x600
0x0500
0x0600
+
+
scm_client
lsa_client
ntdll
diff --git a/reactos/dll/win32/advapi32/sec/ac.c b/reactos/dll/win32/advapi32/sec/ac.c
index 3bf16a393c5..184231db08b 100644
--- a/reactos/dll/win32/advapi32/sec/ac.c
+++ b/reactos/dll/win32/advapi32/sec/ac.c
@@ -536,7 +536,7 @@ GetInheritanceSourceA (
PACL pAcl,
PFN_OBJECT_MGR_FUNCTS pfnArray OPTIONAL,
PGENERIC_MAPPING pGenericMapping,
- PINHERITED_FROM pInheritArray
+ PINHERITED_FROMA pInheritArray
)
{
/* That's all this function does, at least up to w2k3... Even MS was too
@@ -609,14 +609,14 @@ InternalTrusteeAToW(IN PTRUSTEE_A pTrusteeA,
//ASSERT(sizeof(TRUSTEE_W) == sizeof(TRUSTEE_A));
- TrusteeForm = GetTrusteeForm(pTrusteeA);
+ TrusteeForm = GetTrusteeFormA(pTrusteeA);
switch (TrusteeForm)
{
case TRUSTEE_IS_NAME:
{
/* directly copy the array, this works as the size of the EXPLICIT_ACCESS_A
structure matches the size of the EXPLICIT_ACCESS_W version */
- lpStr = GetTrusteeName(pTrusteeA);
+ lpStr = GetTrusteeNameA(pTrusteeA);
if (lpStr != NULL)
BufferSize = strlen(lpStr) + 1;
@@ -800,7 +800,7 @@ InternalExplicitAccessAToW(IN ULONG cCountOfExplicitEntries,
Size = cCountOfExplicitEntries * sizeof(EXPLICIT_ACCESS_W);
for (i = 0; i != cCountOfExplicitEntries; i++)
{
- TrusteeForm = GetTrusteeForm(&pListOfExplicitEntriesA[i].Trustee);
+ TrusteeForm = GetTrusteeFormA(&pListOfExplicitEntriesA[i].Trustee);
switch (TrusteeForm)
{
@@ -852,7 +852,7 @@ InternalExplicitAccessAToW(IN ULONG cCountOfExplicitEntries,
peaw[i].grfInheritance = pListOfExplicitEntriesA[i].grfInheritance;
/* convert or copy the TRUSTEE structure */
- TrusteeForm = GetTrusteeForm(&pListOfExplicitEntriesA[i].Trustee);
+ TrusteeForm = GetTrusteeFormA(&pListOfExplicitEntriesA[i].Trustee);
switch (TrusteeForm)
{
case TRUSTEE_IS_NAME:
diff --git a/reactos/dll/win32/advapi32/sec/misc.c b/reactos/dll/win32/advapi32/sec/misc.c
index 927a8e35a92..ae5ca3656b1 100644
--- a/reactos/dll/win32/advapi32/sec/misc.c
+++ b/reactos/dll/win32/advapi32/sec/misc.c
@@ -916,7 +916,7 @@ LookupAccountSidW (
{
*pdwAccountName = dwSrcLen;
RtlCopyMemory ( pAccountName, TranslatedName->Name.Buffer, TranslatedName->Name.Length );
- pAccountName[TranslatedName->Name.Length / sizeof(WCHAR)] = L'\0';
+ pAccountName[TranslatedName->Name.Length / sizeof(WCHAR)] = L'\0';
}
if ( peUse )
*peUse = TranslatedName->Use;
@@ -936,7 +936,7 @@ LookupAccountSidW (
{
*pdwDomainName = dwSrcLen;
RtlCopyMemory ( pDomainName, ReferencedDomain->Domains[0].Name.Buffer, ReferencedDomain->Domains[0].Name.Length );
- pDomainName[ReferencedDomain->Domains[0].Name.Length / sizeof(WCHAR)] = L'\0';
+ pDomainName[ReferencedDomain->Domains[0].Name.Length / sizeof(WCHAR)] = L'\0';
}
}
}
@@ -1960,7 +1960,7 @@ InternalfnProgressW(LPWSTR pObjectName,
NULL,
NULL);
- pifnProgressData->fnProgress(pObjectNameA,
+ pifnProgressData->fnProgress((LPWSTR)pObjectNameA, /* FIXME: wrong cast!! */
Status,
pInvokeSetting,
pifnProgressData->Args,
diff --git a/reactos/dll/win32/advapi32/sec/sid.c b/reactos/dll/win32/advapi32/sec/sid.c
index c4658957642..6b38fc573e4 100644
--- a/reactos/dll/win32/advapi32/sec/sid.c
+++ b/reactos/dll/win32/advapi32/sec/sid.c
@@ -1,9 +1,9 @@
-/* $Id$
- *
+/*
* COPYRIGHT: See COPYING in the top level directory
* WINE COPYRIGHT:
* Copyright 1999, 2000 Juergen Schmied
* Copyright 2003 CodeWeavers Inc. (Ulrich Czekalla)
+ * Copyright 2006 Hervé Poussineau
*
* PROJECT: ReactOS system libraries
* FILE: lib/advapi32/sec/sid.c
@@ -11,25 +11,20 @@
*/
#include
+#include
#include
#include
WINE_DEFAULT_DEBUG_CHANNEL(advapi);
+#define MAX_GUID_STRING_LEN 39
-static BOOL ParseStringSidToSid(LPCWSTR StringSid, PSID pSid, LPDWORD cBytes);
-static BOOL ParseStringAclToAcl(LPCWSTR StringAcl, LPDWORD lpdwFlags,
- PACL pAcl, LPDWORD cBytes);
-static BYTE ParseAceStringFlags(LPCWSTR* StringAcl);
-static BYTE ParseAceStringType(LPCWSTR* StringAcl);
-static DWORD ParseAceStringRights(LPCWSTR* StringAcl);
-static DWORD ParseAclStringFlags(LPCWSTR* StringAcl);
-
-typedef struct _ACEFLAG
+typedef struct RECORD
{
- LPCWSTR wstr;
- DWORD value;
-} ACEFLAG, *LPACEFLAG;
+ LPCWSTR key;
+ DWORD value;
+} RECORD;
+
typedef struct _MAX_SID
{
@@ -90,18 +85,6 @@ static const WELLKNOWNSID WellKnownSids[] =
static const SID sidWorld = { SID_REVISION, 1, { SECURITY_WORLD_SID_AUTHORITY} , { SECURITY_WORLD_RID } };
-/*
- * ACE access rights
- */
-static const WCHAR SDDL_READ_CONTROL[] = {'R','C',0};
-static const WCHAR SDDL_WRITE_DAC[] = {'W','D',0};
-static const WCHAR SDDL_WRITE_OWNER[] = {'W','O',0};
-static const WCHAR SDDL_STANDARD_DELETE[] = {'S','D',0};
-static const WCHAR SDDL_GENERIC_ALL[] = {'G','A',0};
-static const WCHAR SDDL_GENERIC_READ[] = {'G','R',0};
-static const WCHAR SDDL_GENERIC_WRITE[] = {'G','W',0};
-static const WCHAR SDDL_GENERIC_EXECUTE[] = {'G','X',0};
-
/*
* ACE types
*/
@@ -114,6 +97,19 @@ static const WCHAR SDDL_ALARM[] = {'A','L',0};
static const WCHAR SDDL_OBJECT_AUDIT[] = {'O','U',0};
static const WCHAR SDDL_OBJECT_ALARM[] = {'O','L',0};
+/*
+ * SDDL ADS Rights
+ */
+#define ADS_RIGHT_DS_CREATE_CHILD 0x0001
+#define ADS_RIGHT_DS_DELETE_CHILD 0x0002
+#define ADS_RIGHT_ACTRL_DS_LIST 0x0004
+#define ADS_RIGHT_DS_SELF 0x0008
+#define ADS_RIGHT_DS_READ_PROP 0x0010
+#define ADS_RIGHT_DS_WRITE_PROP 0x0020
+#define ADS_RIGHT_DS_DELETE_TREE 0x0040
+#define ADS_RIGHT_DS_LIST_OBJECT 0x0080
+#define ADS_RIGHT_DS_CONTROL_ACCESS 0x0100
+
/*
* ACE flags
*/
@@ -184,532 +180,343 @@ static __inline BOOL set_ntstatus( NTSTATUS status )
return !status;
}
-#define WINE_SIZE_OF_WORLD_ACCESS_ACL (sizeof(ACL) + FIELD_OFFSET(ACCESS_ALLOWED_ACE, SidStart) + sizeof(sidWorld))
-
-
-/* some helper functions - taken from winehq cvs 20050916 */
-/******************************************************************************
- * ComputeStringSidSize
- */
-static DWORD ComputeStringSidSize(LPCWSTR StringSid)
+static BOOL
+FindKeyInTable(
+ IN const RECORD* Table,
+ IN LPCWSTR Key,
+ OUT SIZE_T* pKeyLength,
+ OUT DWORD* pItem)
{
- int ctok = 0;
- DWORD size = sizeof(SID);
-
- while (*StringSid)
- {
- if (*StringSid == '-')
- ctok++;
- StringSid++;
- }
-
- if (ctok > 3)
- size += (ctok - 3) * sizeof(DWORD);
-
- return size;
-}
-
-/******************************************************************************
- * ParseAceStringType
- */
-static const ACEFLAG AceType[] =
-{
- { SDDL_ACCESS_ALLOWED, ACCESS_ALLOWED_ACE_TYPE },
- { SDDL_ALARM, SYSTEM_ALARM_ACE_TYPE },
- { SDDL_AUDIT, SYSTEM_AUDIT_ACE_TYPE },
- { SDDL_ACCESS_DENIED, ACCESS_DENIED_ACE_TYPE },
- { SDDL_OBJECT_ACCESS_ALLOWED, ACCESS_ALLOWED_OBJECT_ACE_TYPE },
- { SDDL_OBJECT_ACCESS_DENIED, ACCESS_DENIED_OBJECT_ACE_TYPE },
- { SDDL_OBJECT_ALARM, SYSTEM_ALARM_OBJECT_ACE_TYPE },
- { SDDL_OBJECT_AUDIT, SYSTEM_AUDIT_OBJECT_ACE_TYPE },
- { NULL, 0 },
-};
-
-static BYTE ParseAceStringType(LPCWSTR* StringAcl)
-{
- UINT len = 0;
- LPCWSTR szAcl = *StringAcl;
- const ACEFLAG *lpaf = AceType;
-
- while (lpaf->wstr &&
- (len = strlenW(lpaf->wstr)) &&
- strncmpW(lpaf->wstr, szAcl, len))
- lpaf++;
-
- if (!lpaf->wstr)
- return 0;
-
- *StringAcl += len;
- return lpaf->value;
-}
-
-
-/******************************************************************************
- * ParseAceStringFlags
- */
-static const ACEFLAG AceFlags[] =
-{
- { SDDL_CONTAINER_INHERIT, CONTAINER_INHERIT_ACE },
- { SDDL_AUDIT_FAILURE, FAILED_ACCESS_ACE_FLAG },
- { SDDL_INHERITED, INHERITED_ACE },
- { SDDL_INHERIT_ONLY, INHERIT_ONLY_ACE },
- { SDDL_NO_PROPAGATE, NO_PROPAGATE_INHERIT_ACE },
- { SDDL_OBJECT_INHERIT, OBJECT_INHERIT_ACE },
- { SDDL_AUDIT_SUCCESS, SUCCESSFUL_ACCESS_ACE_FLAG },
- { NULL, 0 },
-};
-
-static BYTE ParseAceStringFlags(LPCWSTR* StringAcl)
-{
- UINT len = 0;
- BYTE flags = 0;
- LPCWSTR szAcl = *StringAcl;
-
- while (*szAcl != ';')
- {
- const ACEFLAG *lpaf = AceFlags;
-
- while (lpaf->wstr &&
- (len = strlenW(lpaf->wstr)) &&
- strncmpW(lpaf->wstr, szAcl, len))
- lpaf++;
-
- if (!lpaf->wstr)
- return 0;
-
- flags |= lpaf->value;
- szAcl += len;
- }
-
- *StringAcl = szAcl;
- return flags;
-}
-
-
-/******************************************************************************
- * ParseAceStringRights
- */
-static const ACEFLAG AceRights[] =
-{
- { SDDL_GENERIC_ALL, GENERIC_ALL },
- { SDDL_GENERIC_READ, GENERIC_READ },
- { SDDL_GENERIC_WRITE, GENERIC_WRITE },
- { SDDL_GENERIC_EXECUTE, GENERIC_EXECUTE },
- { SDDL_READ_CONTROL, READ_CONTROL },
- { SDDL_STANDARD_DELETE, DELETE },
- { SDDL_WRITE_DAC, WRITE_DAC },
- { SDDL_WRITE_OWNER, WRITE_OWNER },
- { NULL, 0 },
-};
-
-static DWORD ParseAceStringRights(LPCWSTR* StringAcl)
-{
- UINT len = 0;
- DWORD rights = 0;
- LPCWSTR szAcl = *StringAcl;
-
- if ((*szAcl == '0') && (*(szAcl + 1) == 'x'))
- {
- LPCWSTR p = szAcl;
-
- while (*p && *p != ';')
- p++;
-
- if (p - szAcl <= 8)
+ const RECORD* pRecord = Table;
+ while (pRecord->key != NULL)
{
- rights = strtoulW(szAcl, NULL, 16);
- *StringAcl = p;
- }
- else
- WARN("Invalid rights string format: %s\n", debugstr_wn(szAcl, p - szAcl));
- }
- else
- {
- while (*szAcl != ';')
- {
- const ACEFLAG *lpaf = AceRights;
-
- while (lpaf->wstr &&
- (len = strlenW(lpaf->wstr)) &&
- strncmpW(lpaf->wstr, szAcl, len))
- {
- lpaf++;
- }
-
- if (!lpaf->wstr)
- return 0;
-
- rights |= lpaf->value;
- szAcl += len;
- }
- }
-
- *StringAcl = szAcl;
- return rights;
-}
-
-/******************************************************************************
- * ParseStringAclToAcl
- *
- * dacl_flags(string_ace1)(string_ace2)... (string_acen)
- */
-static BOOL ParseStringAclToAcl(LPCWSTR StringAcl, LPDWORD lpdwFlags,
- PACL pAcl, LPDWORD cBytes)
-{
- DWORD val;
- DWORD sidlen;
- DWORD length = sizeof(ACL);
- PACCESS_ALLOWED_ACE pAce = NULL; /* pointer to current ACE */
-
- TRACE("%s\n", debugstr_w(StringAcl));
-
- if (!StringAcl)
- return FALSE;
-
- if (pAcl) /* pAce is only useful if we're setting values */
- pAce = (PACCESS_ALLOWED_ACE) ((LPBYTE)pAcl + sizeof(PACL));
-
- /* Parse ACL flags */
- *lpdwFlags = ParseAclStringFlags(&StringAcl);
-
- /* Parse ACE */
- while (*StringAcl == '(')
- {
- StringAcl++;
-
- /* Parse ACE type */
- val = ParseAceStringType(&StringAcl);
- if (pAce)
- pAce->Header.AceType = (BYTE) val;
- if (*StringAcl != ';')
- goto lerr;
- StringAcl++;
-
- /* Parse ACE flags */
- val = ParseAceStringFlags(&StringAcl);
- if (pAce)
- pAce->Header.AceFlags = (BYTE) val;
- if (*StringAcl != ';')
- goto lerr;
- StringAcl++;
-
- /* Parse ACE rights */
- val = ParseAceStringRights(&StringAcl);
- if (pAce)
- pAce->Mask = val;
- if (*StringAcl != ';')
- goto lerr;
- StringAcl++;
-
- /* Parse ACE object guid */
- if (*StringAcl != ';')
- {
- FIXME("Support for *_OBJECT_ACE_TYPE not implemented\n");
- goto lerr;
- }
- StringAcl++;
-
- /* Parse ACE inherit object guid */
- if (*StringAcl != ';')
- {
- FIXME("Support for *_OBJECT_ACE_TYPE not implemented\n");
- goto lerr;
- }
- StringAcl++;
-
- /* Parse ACE account sid */
- if (ParseStringSidToSid(StringAcl, pAce ? (PSID)&pAce->SidStart : NULL, &sidlen))
- {
- while (*StringAcl && *StringAcl != ')')
- StringAcl++;
- }
-
- if (*StringAcl != ')')
- goto lerr;
- StringAcl++;
-
- length += FIELD_OFFSET(ACCESS_ALLOWED_ACE, SidStart) + sidlen;
- }
-
- *cBytes = length;
- return TRUE;
-
-lerr:
- WARN("Invalid ACE string format\n");
- return FALSE;
-}
-
-/******************************************************************************
- * ParseStringSecurityDescriptorToSecurityDescriptor
- */
-static BOOL ParseStringSecurityDescriptorToSecurityDescriptor(
- LPCWSTR StringSecurityDescriptor,
- SECURITY_DESCRIPTOR* SecurityDescriptor,
- LPDWORD cBytes)
-{
- BOOL bret = FALSE;
- WCHAR toktype;
- WCHAR tok[MAX_PATH];
- LPCWSTR lptoken;
- LPBYTE lpNext = NULL;
- DWORD len;
-
- *cBytes = 0;
-
- if (SecurityDescriptor)
- lpNext = ((LPBYTE) SecurityDescriptor) + sizeof(SECURITY_DESCRIPTOR);
-
- while (*StringSecurityDescriptor)
- {
- toktype = *StringSecurityDescriptor;
-
- /* Expect char identifier followed by ':' */
- StringSecurityDescriptor++;
- if (*StringSecurityDescriptor != ':')
- {
- SetLastError(ERROR_INVALID_PARAMETER);
- goto lend;
- }
- StringSecurityDescriptor++;
-
- /* Extract token */
- lptoken = StringSecurityDescriptor;
- while (*lptoken && *lptoken != ':')
- lptoken++;
-
- if (*lptoken)
- lptoken--;
-
- len = lptoken - StringSecurityDescriptor;
- memcpy( tok, StringSecurityDescriptor, len * sizeof(WCHAR) );
- tok[len] = 0;
-
- switch (toktype)
- {
- case 'O':
- {
- DWORD bytes;
-
- if (!ParseStringSidToSid(tok, (PSID)lpNext, &bytes))
- goto lend;
-
- if (SecurityDescriptor)
- {
- SecurityDescriptor->Owner = (PSID) ((DWORD) lpNext -
- (DWORD) SecurityDescriptor);
- lpNext += bytes; /* Advance to next token */
- }
-
- *cBytes += bytes;
-
- break;
- }
-
- case 'G':
- {
- DWORD bytes;
-
- if (!ParseStringSidToSid(tok, (PSID)lpNext, &bytes))
- goto lend;
-
- if (SecurityDescriptor)
- {
- SecurityDescriptor->Group = (PSID) ((DWORD) lpNext -
- (DWORD) SecurityDescriptor);
- lpNext += bytes; /* Advance to next token */
- }
-
- *cBytes += bytes;
-
- break;
- }
-
- case 'D':
- {
- DWORD flags;
- DWORD bytes;
-
- if (!ParseStringAclToAcl(tok, &flags, (PACL)lpNext, &bytes))
- goto lend;
-
- if (SecurityDescriptor)
- {
- SecurityDescriptor->Control |= SE_DACL_PRESENT | flags;
- SecurityDescriptor->Dacl = (PACL) ((DWORD) lpNext -
- (DWORD) SecurityDescriptor);
- lpNext += bytes; /* Advance to next token */
+ if (wcsncmp(pRecord->key, Key, wcslen(pRecord->key)) == 0)
+ {
+ *pKeyLength = wcslen(pRecord->key);
+ *pItem = pRecord->value;
+ return TRUE;
}
-
- *cBytes += bytes;
-
- break;
- }
-
- case 'S':
- {
- DWORD flags;
- DWORD bytes;
-
- if (!ParseStringAclToAcl(tok, &flags, (PACL)lpNext, &bytes))
- goto lend;
-
- if (SecurityDescriptor)
- {
- SecurityDescriptor->Control |= SE_SACL_PRESENT | flags;
- SecurityDescriptor->Sacl = (PACL) ((DWORD) lpNext -
- (DWORD) SecurityDescriptor);
- lpNext += bytes; /* Advance to next token */
- }
-
- *cBytes += bytes;
-
- break;
- }
-
- default:
- FIXME("Unknown token\n");
- SetLastError(ERROR_INVALID_PARAMETER);
- goto lend;
+ pRecord++;
}
-
- StringSecurityDescriptor = lptoken;
- }
-
- bret = TRUE;
-
-lend:
- 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')
- {
- szAcl++;
- if (*szAcl == 'R')
- flags |= SE_DACL_AUTO_INHERIT_REQ;
- else if (*szAcl == 'I')
- flags |= SE_DACL_AUTO_INHERITED;
- }
- szAcl++;
- }
-
- *StringAcl = szAcl;
- return flags;
-}
-
-/******************************************************************************
- * 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_INVALID_PARAMETER);
- TRACE("StringSid is NULL, returning FALSE\n");
+ SetLastError(ERROR_INVALID_PARAMETER);
return FALSE;
- }
+}
- *cBytes = ComputeStringSidSize(StringSid);
- if (!pisid) /* Simply compute the size */
- {
- TRACE("only size requested, returning TRUE\n");
- return TRUE;
- }
+static BOOL
+ParseSidString(
+ IN LPCWSTR Buffer,
+ OUT PSID* pSid,
+ OUT SIZE_T* pLength)
+{
+ WCHAR str[SDDL_ALIAS_SIZE + 1];
+ LPWSTR strSid;
+ LPCWSTR end;
+ BOOL ret;
+ DWORD i;
- if (*StringSid != 'S' || *StringSid != '-') /* S-R-I-S-S */
- {
- DWORD i = 0, identAuth;
- DWORD csubauth = ((*cBytes - sizeof(SID)) / sizeof(DWORD)) + 1;
+ wcsncpy(str, Buffer, SDDL_ALIAS_SIZE);
+ for (i = SDDL_ALIAS_SIZE; i > 0; i--)
+ {
+ str[i] = UNICODE_NULL;
+ if (ConvertStringSidToSidW(str, pSid))
+ {
+ *pLength = i;
+ return TRUE;
+ }
+ }
- StringSid += 2; /* Advance to Revision */
- pisid->Revision = atoiW(StringSid);
+ end = wcschr(Buffer, SDDL_ACE_ENDC);
+ if (!end)
+ {
+ SetLastError(ERROR_NOT_ENOUGH_MEMORY);
+ return FALSE;
+ }
+ strSid = (LPWSTR)LocalAlloc(0, (end - Buffer) * sizeof(WCHAR) + sizeof(UNICODE_NULL));
+ if (!strSid)
+ {
+ SetLastError(ERROR_NOT_ENOUGH_MEMORY);
+ return FALSE;
+ }
+ wcsncpy(strSid, Buffer, end - Buffer + 1);
+ strSid[end - Buffer] = UNICODE_NULL;
+ *pLength = end - Buffer;
+ ret = ConvertStringSidToSidW(strSid, pSid);
+ LocalFree(strSid);
+ return ret;
+}
- 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 */
- }
+static const RECORD DaclFlagTable[] =
+{
+ { SDDL_PROTECTED, SE_DACL_PROTECTED },
+ { SDDL_AUTO_INHERIT_REQ, SE_DACL_AUTO_INHERIT_REQ },
+ { SDDL_AUTO_INHERITED, SE_DACL_AUTO_INHERITED },
+ { NULL, 0 },
+};
- pisid->SubAuthorityCount = csubauth;
+static const RECORD SaclFlagTable[] =
+{
+ { SDDL_PROTECTED, SE_SACL_PROTECTED },
+ { SDDL_AUTO_INHERIT_REQ, SE_SACL_AUTO_INHERIT_REQ },
+ { SDDL_AUTO_INHERITED, SE_SACL_AUTO_INHERITED },
+ { NULL, 0 },
+};
- /* Advance to identifier authority */
- while (*StringSid && *StringSid != '-')
- StringSid++;
- if (*StringSid == '-')
- StringSid++;
+static const RECORD AceFlagTable[] =
+{
+ { SDDL_CONTAINER_INHERIT, CONTAINER_INHERIT_ACE },
+ { SDDL_OBJECT_INHERIT, OBJECT_INHERIT_ACE },
+ { SDDL_NO_PROPAGATE, NO_PROPAGATE_INHERIT_ACE },
+ { SDDL_INHERIT_ONLY, INHERIT_ONLY_ACE },
+ { SDDL_INHERITED, INHERITED_ACE },
+ { SDDL_AUDIT_SUCCESS, SUCCESSFUL_ACCESS_ACE_FLAG },
+ { SDDL_AUDIT_FAILURE, FAILED_ACCESS_ACE_FLAG },
+ { NULL, 0 },
+};
- /* 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;
+static BOOL
+ParseFlagsString(
+ IN LPCWSTR Buffer,
+ IN const RECORD* FlagTable,
+ IN WCHAR LimitChar,
+ OUT DWORD* pFlags,
+ OUT SIZE_T* pLength)
+{
+ LPCWSTR ptr = Buffer;
+ SIZE_T PartialLength;
+ DWORD Flag;
- /* Advance to first sub authority */
- while (*StringSid && *StringSid != '-')
- StringSid++;
- if (*StringSid == '-')
- StringSid++;
+ *pFlags = 0;
+ while (*ptr != LimitChar)
+ {
+ if (!FindKeyInTable(FlagTable, ptr, &PartialLength, &Flag))
+ return FALSE;
+ *pFlags |= Flag;
+ ptr += PartialLength;
+ }
+ *pLength = ptr - Buffer;
+ return TRUE;
+}
- while (*StringSid)
- {
- while (*StringSid && *StringSid != '-')
- StringSid++;
+static const RECORD AccessMaskTable[] =
+{
+ { SDDL_GENERIC_ALL, GENERIC_ALL },
+ { SDDL_GENERIC_READ, GENERIC_READ },
+ { SDDL_GENERIC_WRITE, GENERIC_WRITE },
+ { SDDL_GENERIC_EXECUTE, GENERIC_EXECUTE },
+ { SDDL_READ_CONTROL, READ_CONTROL },
+ { SDDL_STANDARD_DELETE, DELETE },
+ { SDDL_WRITE_DAC, WRITE_DAC },
+ { SDDL_WRITE_OWNER, WRITE_OWNER },
+ { SDDL_READ_PROPERTY, ADS_RIGHT_DS_READ_PROP },
+ { SDDL_WRITE_PROPERTY, ADS_RIGHT_DS_WRITE_PROP },
+ { SDDL_CREATE_CHILD, ADS_RIGHT_DS_CREATE_CHILD },
+ { SDDL_DELETE_CHILD, ADS_RIGHT_DS_DELETE_CHILD },
+ { SDDL_LIST_CHILDREN, ADS_RIGHT_ACTRL_DS_LIST },
+ { SDDL_SELF_WRITE, ADS_RIGHT_DS_SELF },
+ { SDDL_LIST_OBJECT, ADS_RIGHT_DS_LIST_OBJECT },
+ { SDDL_DELETE_TREE, ADS_RIGHT_DS_DELETE_TREE },
+ { SDDL_CONTROL_ACCESS, ADS_RIGHT_DS_CONTROL_ACCESS },
+ { SDDL_FILE_ALL, FILE_ALL_ACCESS },
+ { SDDL_FILE_READ, FILE_GENERIC_READ },
+ { SDDL_FILE_WRITE, FILE_GENERIC_WRITE },
+ { SDDL_FILE_EXECUTE, FILE_GENERIC_EXECUTE },
+ { SDDL_KEY_ALL, KEY_ALL_ACCESS },
+ { SDDL_KEY_READ, KEY_READ },
+ { SDDL_KEY_WRITE, KEY_WRITE },
+ { SDDL_KEY_EXECUTE, KEY_EXECUTE },
+ { NULL, 0 },
+};
- pisid->SubAuthority[i++] = atoiW(StringSid);
- }
+static BOOL
+ParseAccessMaskString(
+ IN LPCWSTR Buffer,
+ OUT DWORD* pAccessMask,
+ OUT SIZE_T* pLength)
+{
+ /* FIXME: Allow hexadecimal string for access rights! */
- if (i != pisid->SubAuthorityCount)
- goto lend; /* ERROR_INVALID_SID */
+ return ParseFlagsString(Buffer, AccessMaskTable, SDDL_SEPERATORC, pAccessMask, pLength);
+}
- bret = TRUE;
- }
- else /* String constant format - Only available in winxp and above */
- {
- pisid->Revision = SDDL_REVISION;
- pisid->SubAuthorityCount = 1;
+static BOOL
+ParseGuidString(
+ IN LPCWSTR Buffer,
+ OUT GUID* pGuid,
+ OUT BOOL* pIsGuidValid,
+ OUT SIZE_T* pLength)
+{
+ WCHAR GuidStr[MAX_GUID_STRING_LEN + 1];
+ LPCWSTR end;
- FIXME("String constant not supported: %s\n", debugstr_wn(StringSid, 2));
+ end = wcschr(Buffer, SDDL_SEPERATORC);
+ if (!end)
+ {
+ SetLastError(ERROR_INVALID_PARAMETER);
+ return FALSE;
+ }
- /* TODO: Lookup string of well-known SIDs in table */
- pisid->IdentifierAuthority.Value[5] = 0;
- pisid->SubAuthority[0] = 0;
+ *pLength = end - Buffer;
+ *pIsGuidValid = (end != Buffer);
+ if (!*pIsGuidValid)
+ return TRUE;
- bret = TRUE;
- }
+ if (end - Buffer > MAX_GUID_STRING_LEN - 1)
+ {
+ SetLastError(ERROR_INVALID_PARAMETER);
+ return FALSE;
+ }
+ GuidStr[end - Buffer] = UNICODE_NULL;
+ wcsncpy(GuidStr, Buffer, end - Buffer);
+ if (RPC_S_OK != UuidFromStringW((unsigned short*)&GuidStr, pGuid))
+ {
+ SetLastError(ERROR_INVALID_PARAMETER);
+ return FALSE;
+ }
+ return TRUE;
+}
-lend:
- if (!bret)
- SetLastError(ERROR_INVALID_SID);
+static const RECORD AceTypeTable[] =
+{
+ { SDDL_OBJECT_ACCESS_ALLOWED, ACCESS_ALLOWED_OBJECT_ACE_TYPE },
+ { SDDL_OBJECT_ACCESS_DENIED, ACCESS_DENIED_OBJECT_ACE_TYPE },
+ { SDDL_AUDIT, SYSTEM_AUDIT_ACE_TYPE },
+ { SDDL_ALARM, SYSTEM_ALARM_ACE_TYPE },
+ { SDDL_OBJECT_AUDIT, SYSTEM_AUDIT_OBJECT_ACE_TYPE },
+ { SDDL_OBJECT_ALARM, SYSTEM_ALARM_OBJECT_ACE_TYPE },
+ { SDDL_ACCESS_ALLOWED, ACCESS_ALLOWED_ACE_TYPE },
+ { SDDL_ACCESS_DENIED, ACCESS_DENIED_ACE_TYPE },
+ { NULL, 0 },
+};
- TRACE("returning %s\n", bret ? "TRUE" : "FALSE");
- return bret;
+static BOOL
+ParseAceString(
+ IN LPCWSTR Buffer,
+ IN PACL pAcl,
+ OUT SIZE_T* pLength)
+{
+ LPCWSTR ptr = Buffer;
+ SIZE_T PartialLength;
+ DWORD aceType, aceFlags, accessMask;
+ GUID object, inheritObject;
+ BOOL objectValid, inheritObjectValid;
+ PSID sid = NULL;
+ BOOL ret;
+
+ if (*ptr != SDDL_ACE_BEGINC)
+ {
+ SetLastError(ERROR_INVALID_PARAMETER);
+ return FALSE;
+ }
+ ptr++; /* Skip SDDL_ACE_BEGINC */
+
+ if (!FindKeyInTable(AceTypeTable, ptr, &PartialLength, &aceType))
+ return FALSE;
+ ptr += PartialLength;
+
+ if (*ptr != SDDL_SEPERATORC)
+ {
+ SetLastError(ERROR_INVALID_PARAMETER);
+ return FALSE;
+ }
+ ptr++; /* Skip SDDL_SEPERATORC */
+
+ if (!ParseFlagsString(ptr, AceFlagTable, SDDL_SEPERATORC, &aceFlags, &PartialLength))
+ return FALSE;
+ ptr += PartialLength + 1;
+
+ if (!ParseAccessMaskString(ptr, &accessMask, &PartialLength))
+ return FALSE;
+ ptr += PartialLength + 1;
+
+ if (!ParseGuidString(ptr, &object, &objectValid, &PartialLength))
+ return FALSE;
+ ptr += PartialLength + 1;
+
+ if (!ParseGuidString(ptr, &inheritObject, &inheritObjectValid, &PartialLength))
+ return FALSE;
+ ptr += PartialLength + 1;
+
+ if (!ParseSidString(ptr, &sid, &PartialLength))
+ return FALSE;
+ ptr += PartialLength;
+ if (*ptr != SDDL_ACE_ENDC)
+ {
+ SetLastError(ERROR_INVALID_PARAMETER);
+ return FALSE;
+ }
+ ptr++; /* Skip SDDL_ACE_ENDC */
+ *pLength = ptr - Buffer;
+
+ switch (aceType)
+ {
+ case ACCESS_ALLOWED_ACE_TYPE:
+ ret = AddAccessAllowedAceEx(
+ pAcl,
+ ACL_REVISION_DS,
+ aceFlags,
+ accessMask,
+ sid);
+ break;
+ case ACCESS_ALLOWED_OBJECT_ACE_TYPE:
+ ret = AddAccessAllowedObjectAce(
+ pAcl,
+ ACL_REVISION_DS,
+ aceFlags,
+ accessMask,
+ objectValid ? &object : NULL,
+ inheritObjectValid ? &inheritObject : NULL,
+ sid);
+ break;
+ case ACCESS_DENIED_ACE_TYPE:
+ ret = AddAccessDeniedAceEx(
+ pAcl,
+ ACL_REVISION_DS,
+ aceFlags,
+ accessMask,
+ sid);
+ break;
+ case ACCESS_DENIED_OBJECT_ACE_TYPE:
+ ret = AddAccessDeniedObjectAce(
+ pAcl,
+ ACL_REVISION_DS,
+ aceFlags,
+ accessMask,
+ objectValid ? &object : NULL,
+ inheritObjectValid ? &inheritObject : NULL,
+ sid);
+ break;
+ case SYSTEM_AUDIT_ACE_TYPE:
+ ret = AddAuditAccessAceEx(
+ pAcl,
+ ACL_REVISION_DS,
+ aceFlags,
+ accessMask,
+ sid,
+ FALSE,
+ FALSE);
+ break;
+ case SYSTEM_AUDIT_OBJECT_ACE_TYPE:
+ ret = AddAuditAccessObjectAce(
+ pAcl,
+ ACL_REVISION_DS,
+ aceFlags,
+ accessMask,
+ objectValid ? &object : NULL,
+ inheritObjectValid ? &inheritObject : NULL,
+ sid,
+ FALSE,
+ FALSE);
+ break;
+ case SYSTEM_ALARM_ACE_TYPE:
+ case SYSTEM_ALARM_OBJECT_ACE_TYPE:
+ default:
+ {
+ SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+ ret = FALSE;
+ }
+ }
+ LocalFree(sid);
+ return ret;
}
/* Exported functions */
@@ -793,60 +600,190 @@ CopySid (DWORD nDestinationSidLength,
return TRUE;
}
-/* Winehq cvs 20050916 */
/******************************************************************************
* ConvertStringSecurityDescriptorToSecurityDescriptorW [ADVAPI32.@]
* @implemented
*/
-BOOL WINAPI ConvertStringSecurityDescriptorToSecurityDescriptorW(
- LPCWSTR StringSecurityDescriptor,
- DWORD StringSDRevision,
- PSECURITY_DESCRIPTOR* SecurityDescriptor,
- PULONG SecurityDescriptorSize)
+BOOL WINAPI
+ConvertStringSecurityDescriptorToSecurityDescriptorW(
+ IN LPCWSTR StringSecurityDescriptor,
+ IN DWORD StringSDRevision,
+ OUT PSECURITY_DESCRIPTOR* SecurityDescriptor,
+ OUT PULONG SecurityDescriptorSize)
{
- DWORD cBytes;
- SECURITY_DESCRIPTOR* psd;
- BOOL bret = FALSE;
+ PSECURITY_DESCRIPTOR sd = NULL;
+ BOOL ret = FALSE;
- TRACE("%s\n", debugstr_w(StringSecurityDescriptor));
+ if (!StringSecurityDescriptor)
+ SetLastError(ERROR_INVALID_PARAMETER);
+ else if (StringSDRevision != SDDL_REVISION_1)
+ SetLastError(ERROR_INVALID_PARAMETER);
+ else
+ {
+ LPCWSTR ptr = StringSecurityDescriptor;
+ DWORD numberOfAces = 0;
+ DWORD relativeSdSize;
+ SIZE_T MaxAclSize;
+ PSECURITY_DESCRIPTOR relativeSd = NULL;
+ PSID pSid;
+ PACL pAcl;
+ BOOL present, dummy;
+ /* An easy way to know how much space we need for an ACL is to count
+ * the number of ACEs and say that we have 1 SID by ACE
+ */
+ ptr = wcschr(StringSecurityDescriptor, SDDL_ACE_BEGINC);
+ while (ptr != NULL)
+ {
+ numberOfAces++;
+ ptr = wcschr(ptr + 1, SDDL_ACE_BEGINC);
+ }
+ MaxAclSize = sizeof(ACL) + numberOfAces *
+ (sizeof(ACCESS_ALLOWED_OBJECT_ACE) + SECURITY_MAX_SID_SIZE);
- if (GetVersion() & 0x80000000)
- {
- SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
- goto lend;
- }
- else if (StringSDRevision != SID_REVISION)
- {
- SetLastError(ERROR_UNKNOWN_REVISION);
- goto lend;
- }
+ sd = (SECURITY_DESCRIPTOR*)LocalAlloc(0, sizeof(SECURITY_DESCRIPTOR));
+ if (!sd)
+ {
+ SetLastError(ERROR_NOT_ENOUGH_MEMORY);
+ return FALSE;
+ }
+ ret = InitializeSecurityDescriptor(sd, SECURITY_DESCRIPTOR_REVISION);
+ if (!ret)
+ goto cleanup;
- /* Compute security descriptor length */
- if (!ParseStringSecurityDescriptorToSecurityDescriptor(StringSecurityDescriptor,
- NULL, &cBytes))
- goto lend;
+ /* Now, really parse the string */
+ ptr = StringSecurityDescriptor;
+ while (*ptr)
+ {
+ if (ptr[1] != SDDL_DELIMINATORC)
+ {
+ SetLastError(ERROR_INVALID_PARAMETER);
+ ret = FALSE;
+ goto cleanup;
+ }
+ ptr += 2;
+ switch (ptr[-2])
+ {
+ case 'O':
+ case 'G':
+ {
+ PSID pSid;
+ SIZE_T Length;
- psd = *SecurityDescriptor = (SECURITY_DESCRIPTOR*) LocalAlloc(
- GMEM_ZEROINIT, cBytes);
+ ret = ParseSidString(ptr, &pSid, &Length);
+ if (!ret)
+ goto cleanup;
+ if (ptr[-2] == 'O')
+ ret = SetSecurityDescriptorOwner(sd, pSid, FALSE);
+ else
+ ret = SetSecurityDescriptorGroup(sd, pSid, FALSE);
+ if (!ret)
+ {
+ LocalFree(pSid);
+ goto cleanup;
+ }
+ ptr += Length;
+ break;
+ }
+ case 'D':
+ case 'S':
+ {
+ DWORD aclFlags;
+ SIZE_T Length;
+ BOOL isDacl = (ptr[-2] == 'D');
+
+ if (isDacl)
+ ret = ParseFlagsString(ptr, DaclFlagTable, SDDL_ACE_BEGINC, &aclFlags, &Length);
+ else
+ ret = ParseFlagsString(ptr, SaclFlagTable, SDDL_ACE_BEGINC, &aclFlags, &Length);
+ if (!ret)
+ goto cleanup;
+ pAcl = (PACL)LocalAlloc(0, MaxAclSize);
+ if (!pAcl)
+ {
+ SetLastError(ERROR_NOT_ENOUGH_MEMORY);
+ ret = FALSE;
+ goto cleanup;
+ }
+ if (!InitializeAcl(pAcl, (DWORD)MaxAclSize, ACL_REVISION_DS))
+ {
+ LocalFree(pAcl);
+ goto cleanup;
+ }
+ if (aclFlags != 0)
+ {
+ ret = SetSecurityDescriptorControl(
+ sd,
+ (SECURITY_DESCRIPTOR_CONTROL)aclFlags,
+ (SECURITY_DESCRIPTOR_CONTROL)aclFlags);
+ if (!ret)
+ {
+ LocalFree(pAcl);
+ goto cleanup;
+ }
+ }
+ ptr += Length;
+ while (*ptr == SDDL_ACE_BEGINC)
+ {
+ ret = ParseAceString(ptr, pAcl, &Length);
+ if (!ret)
+ {
+ LocalFree(pAcl);
+ goto cleanup;
+ }
+ ptr += Length;
+ }
+ if (isDacl)
+ ret = SetSecurityDescriptorDacl(sd, TRUE, pAcl, FALSE);
+ else
+ ret = SetSecurityDescriptorSacl(sd, TRUE, pAcl, FALSE);
+ if (!ret)
+ {
+ LocalFree(pAcl);
+ goto cleanup;
+ }
+ break;
+ }
+ default:
+ {
+ SetLastError(ERROR_INVALID_PARAMETER);
+ ret = FALSE;
+ goto cleanup;
+ }
+ }
+ }
- psd->Revision = SID_REVISION;
- psd->Control |= SE_SELF_RELATIVE;
+ relativeSdSize = 0;
+ while (TRUE)
+ {
+ if (relativeSd)
+ LocalFree(relativeSd);
+ relativeSd = LocalAlloc(0, relativeSdSize);
+ if (!relativeSd)
+ {
+ SetLastError(ERROR_NOT_ENOUGH_MEMORY);
+ goto cleanup;
+ }
+ ret = MakeSelfRelativeSD(sd, relativeSd, &relativeSdSize);
+ if (ret || GetLastError() != ERROR_INSUFFICIENT_BUFFER)
+ break;
+ }
+ if (SecurityDescriptorSize)
+ *SecurityDescriptorSize = relativeSdSize;
+ *SecurityDescriptor = relativeSd;
- if (!ParseStringSecurityDescriptorToSecurityDescriptor(StringSecurityDescriptor,
- psd, &cBytes))
- {
- LocalFree(psd);
- goto lend;
- }
-
- if (SecurityDescriptorSize)
- *SecurityDescriptorSize = cBytes;
-
- bret = TRUE;
-
-lend:
- TRACE(" ret=%d\n", bret);
- return bret;
+cleanup:
+ if (GetSecurityDescriptorOwner(sd, &pSid, &dummy))
+ LocalFree(pSid);
+ if (GetSecurityDescriptorGroup(sd, &pSid, &dummy))
+ LocalFree(pSid);
+ if (GetSecurityDescriptorDacl(sd, &present, &pAcl, &dummy) && present)
+ LocalFree(pAcl);
+ if (GetSecurityDescriptorSacl(sd, &present, &pAcl, &dummy) && present)
+ LocalFree(pAcl);
+ LocalFree(sd);
+ return ret;
+ }
+ return FALSE;
}
/* Winehq cvs 20050916 */
@@ -1204,16 +1141,206 @@ ConvertStringSidToSidA(
return bRetVal;
}
-/*
- * @unimplemented
+/******************************************************************************
+ * ComputeStringSidSize
*/
-BOOL STDCALL
-ConvertStringSidToSidW(
- IN LPCWSTR StringSid,
- OUT PSID* sid)
+static DWORD ComputeStringSidSize(LPCWSTR StringSid)
{
- FIXME("unimplemented!\n", __FUNCTION__);
- return FALSE;
+ DWORD size = sizeof(SID);
+
+ if (StringSid[0] == 'S' && StringSid[1] == '-') /* S-R-I-S-S */
+ {
+ int ctok = 0;
+ while (*StringSid)
+ {
+ if (*StringSid == '-')
+ ctok++;
+ StringSid++;
+ }
+
+ if (ctok > 3)
+ size += (ctok - 3) * sizeof(DWORD);
+ }
+ else /* String constant format - Only available in winxp and above */
+ {
+ int i;
+
+ for (i = 0; i < sizeof(WellKnownSids)/sizeof(WellKnownSids[0]); i++)
+ if (!strncmpW(WellKnownSids[i].wstr, StringSid, 2))
+ size += (WellKnownSids[i].Sid.SubAuthorityCount - 1) * sizeof(DWORD);
+ }
+
+ return size;
+}
+
+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, WinLogonIdsSid /* FIXME: SECURITY_SERVER_LOGON_RID */ },
+ { 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 },
+};
+
+/*
+ * @implemented
+ */
+BOOL WINAPI
+ConvertStringSidToSidW(
+ IN LPCWSTR StringSid,
+ OUT PSID* sid)
+{
+ DWORD size;
+ DWORD i, cBytes, identAuth, csubauth;
+ BOOL ret;
+ SID* pisid;
+
+ TRACE("%s %p\n", 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 - sizeof(SID)) / sizeof(DWORD)) + 1;
+
+ 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)
+ {
+ while (*StringSid && *StringSid != '-')
+ StringSid++;
+ if (*StringSid == '-')
+ StringSid++;
+
+ pisid->SubAuthority[i++] = atoiW(StringSid);
+ }
+
+ if (i != pisid->SubAuthorityCount)
+ goto lend; /* ERROR_INVALID_SID */
+
+ *sid = pisid;
+ ret = TRUE;
+
+lend:
+ if (!ret)
+ SetLastError(ERROR_INVALID_SID);
+
+ TRACE("returning %s\n", ret ? "TRUE" : "FALSE");
+ return ret;
}