Index: dll/win32/advapi32/advapi32.h =================================================================== --- dll/win32/advapi32/advapi32.h (revision 64682) +++ dll/win32/advapi32/advapi32.h (working copy) @@ -178,4 +178,16 @@ DWORD CheckNtMartaPresent(VOID); +/* heap allocation helpers */ +static void *heap_alloc( size_t len ) __WINE_ALLOC_SIZE(1); +static inline void *heap_alloc( size_t len ) +{ + return HeapAlloc( GetProcessHeap(), 0, len ); +} + +static inline BOOL heap_free( void *mem ) +{ + return HeapFree( GetProcessHeap(), 0, mem ); +} + #endif /* __ADVAPI32_H */ Index: dll/win32/advapi32/sec/sid.c =================================================================== --- dll/win32/advapi32/sec/sid.c (revision 64682) +++ dll/win32/advapi32/sec/sid.c (working copy) @@ -17,17 +17,10 @@ WINE_DEFAULT_DEBUG_CHANNEL(advapi); +static BOOL ParseStringSidToSid(LPCWSTR StringSid, PSID pSid, LPDWORD cBytes); + #define MAX_GUID_STRING_LEN 39 -BOOL WINAPI -AddAuditAccessAceEx(PACL pAcl, - DWORD dwAceRevision, - DWORD AceFlags, - DWORD dwAccessMask, - PSID pSid, - BOOL bAuditSuccess, - BOOL bAuditFailure); - typedef struct RECORD { LPCWSTR key; @@ -34,6 +27,11 @@ DWORD value; } RECORD; +typedef struct _ACEFLAG +{ + LPCWSTR wstr; + DWORD value; +} ACEFLAG, *LPACEFLAG; typedef struct _MAX_SID { @@ -51,12 +49,6 @@ MAX_SID Sid; } WELLKNOWNSID; -typedef struct _ACEFLAG -{ - LPCWSTR wstr; - DWORD value; -} ACEFLAG, *LPACEFLAG; - static const WELLKNOWNSID WellKnownSids[] = { { {0,0}, WinNullSid, { SID_REVISION, 1, { SECURITY_NULL_SID_AUTHORITY }, { SECURITY_NULL_RID } } }, @@ -113,29 +105,31 @@ { {'S','I'}, WinSystemLabelSid, { SID_REVISION, 1, { SECURITY_MANDATORY_LABEL_AUTHORITY}, { SECURITY_MANDATORY_SYSTEM_RID } } }, }; +/* these SIDs must be constructed as relative to some domain - only the RID is well-known */ typedef struct WELLKNOWNRID { + WCHAR wstr[2]; WELL_KNOWN_SID_TYPE Type; DWORD Rid; } WELLKNOWNRID; static const WELLKNOWNRID WellKnownRids[] = { - { WinAccountAdministratorSid, DOMAIN_USER_RID_ADMIN }, - { WinAccountGuestSid, DOMAIN_USER_RID_GUEST }, - { WinAccountKrbtgtSid, DOMAIN_USER_RID_KRBTGT }, - { WinAccountDomainAdminsSid, DOMAIN_GROUP_RID_ADMINS }, - { WinAccountDomainUsersSid, DOMAIN_GROUP_RID_USERS }, - { WinAccountDomainGuestsSid, DOMAIN_GROUP_RID_GUESTS }, - { WinAccountComputersSid, DOMAIN_GROUP_RID_COMPUTERS }, - { WinAccountControllersSid, DOMAIN_GROUP_RID_CONTROLLERS }, - { WinAccountCertAdminsSid, DOMAIN_GROUP_RID_CERT_ADMINS }, - { WinAccountSchemaAdminsSid, DOMAIN_GROUP_RID_SCHEMA_ADMINS }, - { WinAccountEnterpriseAdminsSid, DOMAIN_GROUP_RID_ENTERPRISE_ADMINS }, - { WinAccountPolicyAdminsSid, DOMAIN_GROUP_RID_POLICY_ADMINS }, - { WinAccountRasAndIasServersSid, DOMAIN_ALIAS_RID_RAS_SERVERS }, + { {'L','A'}, WinAccountAdministratorSid, DOMAIN_USER_RID_ADMIN }, + { {'L','G'}, WinAccountGuestSid, DOMAIN_USER_RID_GUEST }, + { {0,0}, WinAccountKrbtgtSid, DOMAIN_USER_RID_KRBTGT }, + { {0,0}, WinAccountDomainAdminsSid, DOMAIN_GROUP_RID_ADMINS }, + { {0,0}, WinAccountDomainUsersSid, DOMAIN_GROUP_RID_USERS }, + { {0,0}, WinAccountDomainGuestsSid, DOMAIN_GROUP_RID_GUESTS }, + { {0,0}, WinAccountComputersSid, DOMAIN_GROUP_RID_COMPUTERS }, + { {0,0}, WinAccountControllersSid, DOMAIN_GROUP_RID_CONTROLLERS }, + { {0,0}, WinAccountCertAdminsSid, DOMAIN_GROUP_RID_CERT_ADMINS }, + { {0,0}, WinAccountSchemaAdminsSid, DOMAIN_GROUP_RID_SCHEMA_ADMINS }, + { {0,0}, WinAccountEnterpriseAdminsSid, DOMAIN_GROUP_RID_ENTERPRISE_ADMINS }, + { {0,0}, WinAccountPolicyAdminsSid, DOMAIN_GROUP_RID_POLICY_ADMINS }, + { {0,0}, WinAccountRasAndIasServersSid, DOMAIN_ALIAS_RID_RAS_SERVERS }, }; -static const SID sidWorld = { SID_REVISION, 1, { SECURITY_WORLD_SID_AUTHORITY} , { SECURITY_WORLD_RID } }; +static SID const sidWorld = { SID_REVISION, 1, { SECURITY_WORLD_SID_AUTHORITY} , { SECURITY_WORLD_RID } }; /* * ACE types @@ -176,7 +170,7 @@ static const char * debugstr_sid(PSID sid) { int auth = 0; - SID * psid = (SID *)sid; + SID * psid = sid; if (psid == NULL) return "(null)"; @@ -224,552 +218,48 @@ return "(too-big)"; } -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 }, - - { 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 }, -}; - -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 ) { - if (status) SetLastError( RtlNtStatusToDosError( status )); - return !status; + if (!NT_SUCCESS(status)) SetLastError( RtlNtStatusToDosError( status )); + return NT_SUCCESS(status); } - -/* Exported functions */ - -/* - * @implemented - */ -BOOL WINAPI -AllocateLocallyUniqueId(PLUID Luid) +static LPWSTR SERV_dup( LPCSTR str ) { - NTSTATUS Status; + UINT len; + LPWSTR wstr; - Status = NtAllocateLocallyUniqueId (Luid); - if (!NT_SUCCESS (Status)) - { - SetLastError(RtlNtStatusToDosError(Status)); - return FALSE; - } - - return TRUE; + if( !str ) + return NULL; + len = MultiByteToWideChar( CP_ACP, 0, str, -1, NULL, 0 ); + wstr = heap_alloc( len*sizeof (WCHAR) ); + MultiByteToWideChar( CP_ACP, 0, str, -1, wstr, len ); + return wstr; } - -/* - * @implemented +/************************************************************ + * ADVAPI_GetComputerSid */ -BOOL WINAPI -AllocateAndInitializeSid(PSID_IDENTIFIER_AUTHORITY pIdentifierAuthority, - BYTE nSubAuthorityCount, - DWORD dwSubAuthority0, - DWORD dwSubAuthority1, - DWORD dwSubAuthority2, - DWORD dwSubAuthority3, - DWORD dwSubAuthority4, - DWORD dwSubAuthority5, - DWORD dwSubAuthority6, - DWORD dwSubAuthority7, - PSID *pSid) +BOOL ADVAPI_GetComputerSid(PSID sid) { - NTSTATUS Status; - - Status = RtlAllocateAndInitializeSid(pIdentifierAuthority, - nSubAuthorityCount, - dwSubAuthority0, - dwSubAuthority1, - dwSubAuthority2, - dwSubAuthority3, - dwSubAuthority4, - dwSubAuthority5, - dwSubAuthority6, - dwSubAuthority7, - pSid); - if (!NT_SUCCESS(Status)) + static const struct /* same fields as struct SID */ { - SetLastError(RtlNtStatusToDosError(Status)); - return FALSE; - } + BYTE Revision; + BYTE SubAuthorityCount; + SID_IDENTIFIER_AUTHORITY IdentifierAuthority; + DWORD SubAuthority[4]; + } computer_sid = + { SID_REVISION, 4, { SECURITY_NT_AUTHORITY }, { SECURITY_NT_NON_UNIQUE, 0, 0, 0 } }; + memcpy( sid, &computer_sid, sizeof(computer_sid) ); return TRUE; } -/* - * @implemented - */ -BOOL WINAPI -CopySid(DWORD nDestinationSidLength, - PSID pDestinationSid, - PSID pSourceSid) -{ - NTSTATUS Status; - Status = RtlCopySid(nDestinationSidLength, - pDestinationSid, - pSourceSid); - if (!NT_SUCCESS (Status)) - { - SetLastError(RtlNtStatusToDosError(Status)); - return FALSE; - } - - 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) -{ - 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; - } - - 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); - - for( i=0; iSubAuthorityCount; i++ ) - { - sprintfW( buf, subauthfmt, pisid->SubAuthority[i] ); - DumpString(buf, -1, pwptr, plen); - } - 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); - return TRUE; - } - } - - return DumpSidNumeric(psid, pwptr, plen); -} - -static void DumpRights(DWORD mask, WCHAR **pwptr, ULONG *plen) -{ - 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; - } -} - - -/****************************************************************************** * ComputeStringSidSize */ static DWORD ComputeStringSidSize(LPCWSTR StringSid) @@ -794,6 +284,15 @@ for (i = 0; i < sizeof(WellKnownSids)/sizeof(WellKnownSids[0]); i++) if (!strncmpW(WellKnownSids[i].wstr, StringSid, 2)) return GetSidLengthRequired(WellKnownSids[i].Sid.SubAuthorityCount); + + for (i = 0; i < sizeof(WellKnownRids)/sizeof(WellKnownRids[0]); i++) + if (!strncmpW(WellKnownRids[i].wstr, StringSid, 2)) + { + MAX_SID local; + ADVAPI_GetComputerSid(&local); + return GetSidLengthRequired(*GetSidSubAuthorityCount(&local) + 1); + } + } return GetSidLengthRequired(0); @@ -821,7 +320,7 @@ *cBytes = ComputeStringSidSize(StringSid); if (!pisid) /* Simply compute the size */ { - TRACE("only size requested, returning TRUE\n"); + TRACE("only size requested, returning TRUE with %d\n", *cBytes); return TRUE; } @@ -900,6 +399,15 @@ bret = TRUE; } + for (i = 0; i < sizeof(WellKnownRids)/sizeof(WellKnownRids[0]); i++) + if (!strncmpW(WellKnownRids[i].wstr, StringSid, 2)) + { + ADVAPI_GetComputerSid(pisid); + pisid->SubAuthority[pisid->SubAuthorityCount] = WellKnownRids[i].Rid; + pisid->SubAuthorityCount++; + bret = TRUE; + } + if (!bret) FIXME("String constant not supported: %s\n", debugstr_wn(StringSid, 2)); } @@ -912,7 +420,293 @@ return bret; } + + +/* Exported functions */ + +/* + * @implemented + */ +BOOL WINAPI +AllocateLocallyUniqueId(PLUID Luid) +{ + NTSTATUS Status; + + Status = NtAllocateLocallyUniqueId (Luid); + if (!NT_SUCCESS (Status)) + { + SetLastError(RtlNtStatusToDosError(Status)); + return FALSE; + } + + return TRUE; +} + + /****************************************************************************** + * AllocateAndInitializeSid [ADVAPI32.@] + * + * PARAMS + * pIdentifierAuthority [] + * nSubAuthorityCount [] + * nSubAuthority0 [] + * nSubAuthority1 [] + * nSubAuthority2 [] + * nSubAuthority3 [] + * nSubAuthority4 [] + * nSubAuthority5 [] + * nSubAuthority6 [] + * nSubAuthority7 [] + * pSid [] + */ +BOOL WINAPI +AllocateAndInitializeSid( PSID_IDENTIFIER_AUTHORITY pIdentifierAuthority, + BYTE nSubAuthorityCount, + DWORD nSubAuthority0, DWORD nSubAuthority1, + DWORD nSubAuthority2, DWORD nSubAuthority3, + DWORD nSubAuthority4, DWORD nSubAuthority5, + DWORD nSubAuthority6, DWORD nSubAuthority7, + PSID *pSid ) +{ + return set_ntstatus( RtlAllocateAndInitializeSid( + pIdentifierAuthority, nSubAuthorityCount, + nSubAuthority0, nSubAuthority1, nSubAuthority2, nSubAuthority3, + nSubAuthority4, nSubAuthority5, nSubAuthority6, nSubAuthority7, + pSid )); +} + +/****************************************************************************** + * FreeSid [ADVAPI32.@] + * + * PARAMS + * pSid [] + */ +PVOID WINAPI +FreeSid( PSID pSid ) +{ + RtlFreeSid(pSid); + return NULL; /* is documented like this */ +} + +/****************************************************************************** + * CopySid [ADVAPI32.@] + * + * PARAMS + * nDestinationSidLength [] + * pDestinationSid [] + * pSourceSid [] + */ +BOOL WINAPI +CopySid( DWORD nDestinationSidLength, PSID pDestinationSid, PSID pSourceSid ) +{ + return set_ntstatus(RtlCopySid(nDestinationSidLength, pDestinationSid, pSourceSid)); +} + +/****************************************************************************** + * CreateWellKnownSid [ADVAPI32.@] + */ +BOOL WINAPI +CreateWellKnownSid( WELL_KNOWN_SID_TYPE WellKnownSidType, + PSID DomainSid, + PSID pSid, + 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; +} + +/****************************************************************************** + * IsWellKnownSid [ADVAPI32.@] + */ +BOOL WINAPI +IsWellKnownSid( PSID pSid, 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; +} + +/****************************************************************************** + * IsValidSid [ADVAPI32.@] + * + * PARAMS + * pSid [] + */ +BOOL WINAPI +IsValidSid( PSID pSid ) +{ + return RtlValidSid( pSid ); +} + +/****************************************************************************** + * EqualSid [ADVAPI32.@] + * + * PARAMS + * pSid1 [] + * pSid2 [] + */ +BOOL WINAPI +EqualSid( PSID pSid1, PSID pSid2 ) +{ + BOOL ret = RtlEqualSid( pSid1, pSid2 ); + SetLastError(ERROR_SUCCESS); + return ret; +} + +/****************************************************************************** + * EqualPrefixSid [ADVAPI32.@] + */ +BOOL WINAPI EqualPrefixSid (PSID pSid1, PSID pSid2) +{ + return RtlEqualPrefixSid(pSid1, pSid2); +} + +/****************************************************************************** + * GetSidLengthRequired [ADVAPI32.@] + * + * PARAMS + * nSubAuthorityCount [] + */ +DWORD WINAPI +GetSidLengthRequired( UCHAR nSubAuthorityCount ) +{ + return (DWORD)RtlLengthRequiredSid(nSubAuthorityCount); +} + +/****************************************************************************** + * InitializeSid [ADVAPI32.@] + * + * PARAMS + * pIdentifierAuthority [] + */ +BOOL WINAPI +InitializeSid ( + PSID pSid, + PSID_IDENTIFIER_AUTHORITY pIdentifierAuthority, + BYTE nSubAuthorityCount) +{ + return set_ntstatus(RtlInitializeSid(pSid, pIdentifierAuthority, nSubAuthorityCount)); +} + +/****************************************************************************** + * GetSidIdentifierAuthority [ADVAPI32.@] + * + * PARAMS + * pSid [] + */ +PSID_IDENTIFIER_AUTHORITY WINAPI +GetSidIdentifierAuthority( PSID pSid ) +{ + return RtlIdentifierAuthoritySid(pSid); +} + +/****************************************************************************** + * GetSidSubAuthority [ADVAPI32.@] + * + * PARAMS + * pSid [] + * nSubAuthority [] + */ +PDWORD WINAPI +GetSidSubAuthority( PSID pSid, DWORD nSubAuthority ) +{ + SetLastError(ERROR_SUCCESS); + return RtlSubAuthoritySid(pSid, nSubAuthority); +} + +/****************************************************************************** + * GetSidSubAuthorityCount [ADVAPI32.@] + * + * PARAMS + * pSid [] + */ +PUCHAR WINAPI +GetSidSubAuthorityCount (PSID pSid) +{ + SetLastError(ERROR_SUCCESS); + return RtlSubAuthorityCountSid(pSid); +} + +/****************************************************************************** + * GetLengthSid [ADVAPI32.@] + * + * PARAMS + * pSid [] + */ +DWORD WINAPI +GetLengthSid (PSID pSid) +{ + return RtlLengthSid(pSid); +} + + +/****************************************************************************** * ParseAclStringFlags */ static DWORD ParseAclStringFlags(LPCWSTR* StringAcl) @@ -923,15 +717,15 @@ 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') + else if (*szAcl == 'I') flags |= SE_DACL_AUTO_INHERITED; } szAcl++; @@ -965,6 +759,9 @@ LPCWSTR szAcl = *StringAcl; const ACEFLAG *lpaf = AceType; + while (*szAcl == ' ') + szAcl++; + while (lpaf->wstr && (len = strlenW(lpaf->wstr)) && strncmpW(lpaf->wstr, szAcl, len)) @@ -973,7 +770,7 @@ if (!lpaf->wstr) return 0; - *StringAcl += len; + *StringAcl = szAcl + len; return lpaf->value; } @@ -999,6 +796,9 @@ BYTE flags = 0; LPCWSTR szAcl = *StringAcl; + while (*szAcl == ' ') + szAcl++; + while (*szAcl != ';') { const ACEFLAG *lpaf = AceFlags; @@ -1011,7 +811,7 @@ if (!lpaf->wstr) return 0; - flags |= lpaf->value; + flags |= lpaf->value; szAcl += len; } @@ -1023,6 +823,40 @@ /****************************************************************************** * 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 }, + + { 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 }, +}; + static DWORD ParseAceStringRights(LPCWSTR* StringAcl) { UINT len = 0; @@ -1029,19 +863,22 @@ DWORD rights = 0; LPCWSTR szAcl = *StringAcl; + while (*szAcl == ' ') + szAcl++; + if ((*szAcl == '0') && (*(szAcl + 1) == 'x')) { LPCWSTR p = szAcl; - while (*p && *p != ';') + while (*p && *p != ';') p++; - if (p - szAcl <= 10 /* 8 hex digits + "0x" */ ) - { - rights = strtoulW(szAcl, NULL, 16); - szAcl = p; - } - else + if (p - szAcl <= 10 /* 8 hex digits + "0x" */ ) + { + rights = strtoulW(szAcl, NULL, 16); + szAcl = p; + } + else WARN("Invalid rights string format: %s\n", debugstr_wn(szAcl, p - szAcl)); } else @@ -1051,16 +888,16 @@ const ACEFLAG *lpaf = AceRights; while (lpaf->wstr && - (len = strlenW(lpaf->wstr)) && - strncmpW(lpaf->wstr, szAcl, len)) - { - lpaf++; - } + (len = strlenW(lpaf->wstr)) && + strncmpW(lpaf->wstr, szAcl, len)) + { + lpaf++; + } if (!lpaf->wstr) return 0; - rights |= lpaf->value; + rights |= lpaf->value; szAcl += len; } } @@ -1075,11 +912,8 @@ * * dacl_flags(string_ace1)(string_ace2)... (string_acen) */ -static BOOL -ParseStringAclToAcl(LPCWSTR StringAcl, - LPDWORD lpdwFlags, - PACL pAcl, - LPDWORD cBytes) +static BOOL ParseStringAclToAcl(LPCWSTR StringAcl, LPDWORD lpdwFlags, + PACL pAcl, LPDWORD cBytes) { DWORD val; DWORD sidlen; @@ -1087,11 +921,12 @@ DWORD acesize = 0; DWORD acecount = 0; PACCESS_ALLOWED_ACE pAce = NULL; /* pointer to current ACE */ + DWORD error = ERROR_INVALID_ACL; TRACE("%s\n", debugstr_w(StringAcl)); if (!StringAcl) - return FALSE; + return FALSE; if (pAcl) /* pAce is only useful if we're setting values */ pAce = (PACCESS_ALLOWED_ACE) (pAcl + 1); @@ -1106,15 +941,18 @@ /* Parse ACE type */ val = ParseAceStringType(&StringAcl); - if (pAce) + if (pAce) pAce->Header.AceType = (BYTE) val; if (*StringAcl != ';') + { + error = RPC_S_INVALID_STRING_UUID; goto lerr; + } StringAcl++; /* Parse ACE flags */ - val = ParseAceStringFlags(&StringAcl); - if (pAce) + val = ParseAceStringFlags(&StringAcl); + if (pAce) pAce->Header.AceFlags = (BYTE) val; if (*StringAcl != ';') goto lerr; @@ -1121,8 +959,8 @@ StringAcl++; /* Parse ACE rights */ - val = ParseAceStringRights(&StringAcl); - if (pAce) + val = ParseAceStringRights(&StringAcl); + if (pAce) pAce->Mask = val; if (*StringAcl != ';') goto lerr; @@ -1129,6 +967,8 @@ StringAcl++; /* Parse ACE object guid */ + while (*StringAcl == ' ') + StringAcl++; if (*StringAcl != ';') { FIXME("Support for *_OBJECT_ACE_TYPE not implemented\n"); @@ -1137,6 +977,8 @@ StringAcl++; /* Parse ACE inherit object guid */ + while (*StringAcl == ' ') + StringAcl++; if (*StringAcl != ';') { FIXME("Support for *_OBJECT_ACE_TYPE not implemented\n"); @@ -1146,10 +988,10 @@ /* Parse ACE account sid */ if (ParseStringSidToSid(StringAcl, pAce ? &pAce->SidStart : NULL, &sidlen)) - { + { while (*StringAcl && *StringAcl != ')') StringAcl++; - } + } if (*StringAcl != ')') goto lerr; @@ -1184,7 +1026,7 @@ return TRUE; lerr: - SetLastError(ERROR_INVALID_ACL); + SetLastError(error); WARN("Invalid ACE string format\n"); return FALSE; } @@ -1193,10 +1035,10 @@ /****************************************************************************** * ParseStringSecurityDescriptorToSecurityDescriptor */ -static BOOL -ParseStringSecurityDescriptorToSecurityDescriptor(LPCWSTR StringSecurityDescriptor, - SECURITY_DESCRIPTOR_RELATIVE* SecurityDescriptor, - LPDWORD cBytes) +static BOOL ParseStringSecurityDescriptorToSecurityDescriptor( + LPCWSTR StringSecurityDescriptor, + SECURITY_DESCRIPTOR_RELATIVE* SecurityDescriptor, + LPDWORD cBytes) { BOOL bret = FALSE; WCHAR toktype; @@ -1210,25 +1052,28 @@ if (SecurityDescriptor) lpNext = (LPBYTE)(SecurityDescriptor + 1); + while (*StringSecurityDescriptor == ' ') + StringSecurityDescriptor++; + while (*StringSecurityDescriptor) { toktype = *StringSecurityDescriptor; - /* Expect char identifier followed by ':' */ - StringSecurityDescriptor++; + /* Expect char identifier followed by ':' */ + StringSecurityDescriptor++; if (*StringSecurityDescriptor != ':') { SetLastError(ERROR_INVALID_PARAMETER); goto lend; } - StringSecurityDescriptor++; + StringSecurityDescriptor++; - /* Extract token */ - lptoken = StringSecurityDescriptor; - while (*lptoken && *lptoken != ':') + /* Extract token */ + lptoken = StringSecurityDescriptor; + while (*lptoken && *lptoken != ':') lptoken++; - if (*lptoken) + if (*lptoken) lptoken--; len = lptoken - StringSecurityDescriptor; @@ -1236,7 +1081,7 @@ tok[len] = 0; switch (toktype) - { + { case 'O': { DWORD bytes; @@ -1250,7 +1095,7 @@ lpNext += bytes; /* Advance to next token */ } - *cBytes += bytes; + *cBytes += bytes; break; } @@ -1268,13 +1113,13 @@ lpNext += bytes; /* Advance to next token */ } - *cBytes += bytes; + *cBytes += bytes; break; } case 'D': - { + { DWORD flags; DWORD bytes; @@ -1286,11 +1131,11 @@ SecurityDescriptor->Control |= SE_DACL_PRESENT | flags; SecurityDescriptor->Dacl = lpNext - (LPBYTE)SecurityDescriptor; lpNext += bytes; /* Advance to next token */ - } + } - *cBytes += bytes; + *cBytes += bytes; - break; + break; } case 'S': @@ -1306,18 +1151,18 @@ SecurityDescriptor->Control |= SE_SACL_PRESENT | flags; SecurityDescriptor->Sacl = lpNext - (LPBYTE)SecurityDescriptor; lpNext += bytes; /* Advance to next token */ - } + } - *cBytes += bytes; + *cBytes += bytes; - break; + break; } default: FIXME("Unknown token\n"); SetLastError(ERROR_INVALID_PARAMETER); - goto lend; - } + goto lend; + } StringSecurityDescriptor = lptoken; } @@ -1328,16 +1173,38 @@ return bret; } +/****************************************************************************** + * ConvertStringSecurityDescriptorToSecurityDescriptorA [ADVAPI32.@] + */ +BOOL WINAPI ConvertStringSecurityDescriptorToSecurityDescriptorA( + LPCSTR StringSecurityDescriptor, + DWORD StringSDRevision, + PSECURITY_DESCRIPTOR* SecurityDescriptor, + PULONG SecurityDescriptorSize) +{ + BOOL ret; + LPWSTR StringSecurityDescriptorW; + if(!StringSecurityDescriptor) + return FALSE; + + StringSecurityDescriptorW = SERV_dup(StringSecurityDescriptor); + ret = ConvertStringSecurityDescriptorToSecurityDescriptorW(StringSecurityDescriptorW, + StringSDRevision, SecurityDescriptor, + SecurityDescriptorSize); + heap_free(StringSecurityDescriptorW); + + return ret; +} + /****************************************************************************** * ConvertStringSecurityDescriptorToSecurityDescriptorW [ADVAPI32.@] - * @implemented */ -BOOL WINAPI -ConvertStringSecurityDescriptorToSecurityDescriptorW(LPCWSTR StringSecurityDescriptor, - DWORD StringSDRevision, - PSECURITY_DESCRIPTOR* SecurityDescriptor, - PULONG SecurityDescriptorSize) +BOOL WINAPI ConvertStringSecurityDescriptorToSecurityDescriptorW( + LPCWSTR StringSecurityDescriptor, + DWORD StringSDRevision, + PSECURITY_DESCRIPTOR* SecurityDescriptor, + PULONG SecurityDescriptorSize) { DWORD cBytes; SECURITY_DESCRIPTOR* psd; @@ -1358,13 +1225,13 @@ else if (StringSDRevision != SID_REVISION) { SetLastError(ERROR_UNKNOWN_REVISION); - goto lend; + goto lend; } /* Compute security descriptor length */ if (!ParseStringSecurityDescriptorToSecurityDescriptor(StringSecurityDescriptor, NULL, &cBytes)) - goto lend; + goto lend; psd = *SecurityDescriptor = LocalAlloc(GMEM_ZEROINIT, cBytes); if (!psd) goto lend; @@ -1376,7 +1243,7 @@ (SECURITY_DESCRIPTOR_RELATIVE *)psd, &cBytes)) { LocalFree(psd); - goto lend; + goto lend; } if (SecurityDescriptorSize) @@ -1383,433 +1250,427 @@ *SecurityDescriptorSize = cBytes; bret = TRUE; - + lend: TRACE(" ret=%d\n", bret); 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) +static BOOL DumpSidNumeric(PSID psid, WCHAR **pwptr, ULONG *plen) { - return RtlEqualPrefixSid (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 - */ -BOOL -WINAPI -EqualSid(PSID pSid1, - PSID pSid2) -{ - SetLastError(ERROR_SUCCESS); - return RtlEqualSid (pSid1, pSid2); -} + 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 - * - * 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); + for( i=0; iSubAuthorityCount; i++ ) + { + sprintfW( buf, subauthfmt, pisid->SubAuthority[i] ); + DumpString(buf, -1, pwptr, plen); + } + return TRUE; } - -/* - * @implemented - */ -DWORD -WINAPI -GetLengthSid(PSID pSid) +static BOOL DumpSid(PSID psid, WCHAR **pwptr, ULONG *plen) { - return (DWORD)RtlLengthSid(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 - */ -PSID_IDENTIFIER_AUTHORITY -WINAPI -GetSidIdentifierAuthority(PSID pSid) -{ - return RtlIdentifierAuthoritySid(pSid); + return DumpSidNumeric(psid, pwptr, plen); } +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 +}; -/* - * @implemented - */ -DWORD -WINAPI -GetSidLengthRequired(UCHAR nSubAuthorityCount) +static void DumpRights(DWORD mask, WCHAR **pwptr, ULONG *plen) { - return (DWORD)RtlLengthRequiredSid(nSubAuthorityCount); -} + static const WCHAR fmtW[] = {'0','x','%','x',0}; + WCHAR buf[15]; + size_t i; + if (mask == 0) + return; -/* - * @implemented - */ -PDWORD -WINAPI -GetSidSubAuthority(PSID pSid, - DWORD nSubAuthority) -{ - SetLastError(ERROR_SUCCESS); - return (PDWORD)RtlSubAuthoritySid(pSid, nSubAuthority); -} + /* 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; + } + } -/* - * @implemented - */ -PUCHAR -WINAPI -GetSidSubAuthorityCount(PSID pSid) -{ - SetLastError(ERROR_SUCCESS); - return RtlSubAuthorityCountSid(pSid); + /* build from bit names */ + for (i = 0; i < 32; i++) + if (mask & (1 << i)) + DumpString(AceRightBitNames[i], -1, pwptr, plen); } - -/* - * @implemented - */ -BOOL -WINAPI -InitializeSid(PSID Sid, - PSID_IDENTIFIER_AUTHORITY pIdentifierAuthority, - BYTE nSubAuthorityCount) +static BOOL DumpAce(LPVOID pace, WCHAR **pwptr, ULONG *plen) { - NTSTATUS Status; + 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 = ';'; - Status = RtlInitializeSid(Sid, - pIdentifierAuthority, - nSubAuthorityCount); - if (!NT_SUCCESS(Status)) + if (((PACE_HEADER)pace)->AceType > SYSTEM_ALARM_ACE_TYPE || ((PACE_HEADER)pace)->AceSize < sizeof(ACCESS_ALLOWED_ACE)) { - SetLastError(RtlNtStatusToDosError(Status)); + 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(&piace->SidStart, pwptr, plen)) + return FALSE; + DumpString(&closebr, 1, pwptr, plen); return TRUE; } - -/* - * @implemented - */ -BOOL -WINAPI -IsValidSid(PSID pSid) +static BOOL DumpAcl(PACL pacl, WCHAR **pwptr, ULONG *plen, BOOL protected, BOOL autoInheritReq, BOOL autoInherited) { - return (BOOL)RtlValidSid(pSid); -} + WORD count; + UINT 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); -/* - * @implemented - */ -BOOL -WINAPI -ConvertSidToStringSidW(PSID Sid, - LPWSTR *StringSid) -{ - NTSTATUS Status; - UNICODE_STRING UnicodeString; - WCHAR FixedBuffer[64]; + if (pacl == NULL) + return TRUE; - if (!RtlValidSid(Sid)) - { - SetLastError(ERROR_INVALID_SID); + if (!IsValidAcl(pacl)) return FALSE; - } - UnicodeString.Length = 0; - UnicodeString.MaximumLength = sizeof(FixedBuffer); - UnicodeString.Buffer = FixedBuffer; - Status = RtlConvertSidToUnicodeString(&UnicodeString, Sid, FALSE); - if (STATUS_BUFFER_TOO_SMALL == Status) + count = pacl->AceCount; + for (i = 0; i < count; i++) { - Status = RtlConvertSidToUnicodeString(&UnicodeString, Sid, TRUE); + LPVOID ace; + if (!GetAce(pacl, i, &ace)) + return FALSE; + if (!DumpAce(ace, pwptr, plen)) + return FALSE; } - if (!NT_SUCCESS(Status)) - { - SetLastError(RtlNtStatusToDosError(Status)); + 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; - } - *StringSid = LocalAlloc(LMEM_FIXED, UnicodeString.Length + sizeof(WCHAR)); - if (NULL == *StringSid) - { - if (UnicodeString.Buffer != FixedBuffer) - { - RtlFreeUnicodeString(&UnicodeString); - } - SetLastError(ERROR_NOT_ENOUGH_MEMORY); - return FALSE; - } + if (psid == NULL) + return TRUE; - MoveMemory(*StringSid, UnicodeString.Buffer, UnicodeString.Length); - ZeroMemory((PCHAR) *StringSid + UnicodeString.Length, sizeof(WCHAR)); - if (UnicodeString.Buffer != FixedBuffer) - { - RtlFreeUnicodeString(&UnicodeString); - } - + DumpString(prefix, -1, pwptr, plen); + if (!DumpSid(psid, pwptr, plen)) + return FALSE; return TRUE; } - -/* - * @implemented - */ -BOOL -WINAPI -ConvertSidToStringSidA(PSID Sid, - LPSTR *StringSid) +static BOOL DumpGroup(PSECURITY_DESCRIPTOR SecurityDescriptor, WCHAR **pwptr, ULONG *plen) { - LPWSTR StringSidW; - int Len; + static const WCHAR prefix[] = {'G',':',0}; + BOOL bDefaulted; + PSID psid; - if (!ConvertSidToStringSidW(Sid, &StringSidW)) - { + if (!GetSecurityDescriptorGroup(SecurityDescriptor, &psid, &bDefaulted)) return FALSE; - } - Len = WideCharToMultiByte(CP_ACP, 0, StringSidW, -1, NULL, 0, NULL, NULL); - if (Len <= 0) - { - LocalFree(StringSidW); - SetLastError(ERROR_NOT_ENOUGH_MEMORY); + if (psid == NULL) + return TRUE; + + DumpString(prefix, -1, pwptr, plen); + if (!DumpSid(psid, pwptr, plen)) return FALSE; - } + return TRUE; +} - *StringSid = LocalAlloc(LMEM_FIXED, Len); - if (NULL == *StringSid) - { - LocalFree(StringSidW); - SetLastError(ERROR_NOT_ENOUGH_MEMORY); +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 (!WideCharToMultiByte(CP_ACP, 0, StringSidW, -1, *StringSid, Len, NULL, NULL)) - { - LocalFree(StringSid); - LocalFree(StringSidW); + if (!GetSecurityDescriptorControl(SecurityDescriptor, &control, &revision)) return FALSE; - } - LocalFree(StringSidW); + 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; } - -/* - * @unimplemented - */ -BOOL -WINAPI -EqualDomainSid(IN PSID pSid1, - IN PSID pSid2, - OUT BOOL* pfEqual) +static BOOL DumpSacl(PSECURITY_DESCRIPTOR SecurityDescriptor, WCHAR **pwptr, ULONG *plen) { - UNIMPLEMENTED; - return FALSE; -} + 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; -/* - * @unimplemented - */ -BOOL -WINAPI -GetWindowsAccountDomainSid(IN PSID pSid, - OUT PSID ppDomainSid, - IN OUT DWORD* cbSid) -{ - UNIMPLEMENTED; - 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; } - -/* - * @unimplemented +/****************************************************************************** + * ConvertSecurityDescriptorToStringSecurityDescriptorW [ADVAPI32.@] */ -BOOL -WINAPI -CreateWellKnownSid(IN WELL_KNOWN_SID_TYPE WellKnownSidType, - IN PSID DomainSid OPTIONAL, - OUT PSID pSid, - IN OUT DWORD* cbSid) +BOOL WINAPI ConvertSecurityDescriptorToStringSecurityDescriptorW(PSECURITY_DESCRIPTOR SecurityDescriptor, DWORD SDRevision, SECURITY_INFORMATION RequestedInformation, LPWSTR *OutputString, PULONG OutputLen) { - unsigned int i; - TRACE("(%d, %s, %p, %p)\n", WellKnownSidType, debugstr_sid(DomainSid), pSid, cbSid); + ULONG len; + WCHAR *wptr, *wstr; - if (cbSid == NULL || (DomainSid && !IsValidSid(DomainSid))) + if (SDRevision != SDDL_REVISION_1) { - SetLastError(ERROR_INVALID_PARAMETER); + ERR("Program requested unknown SDDL revision %d\n", SDRevision); + SetLastError(ERROR_UNKNOWN_REVISION); return FALSE; } - for (i = 0; i < sizeof(WellKnownSids)/sizeof(WellKnownSids[0]); i++) { - if (WellKnownSids[i].Type == WellKnownSidType) { - DWORD length = GetSidLengthRequired(WellKnownSids[i].Sid.SubAuthorityCount); + len = 0; + if (RequestedInformation & OWNER_SECURITY_INFORMATION) + if (!DumpOwner(SecurityDescriptor, NULL, &len)) + return FALSE; + if (RequestedInformation & GROUP_SECURITY_INFORMATION) + if (!DumpGroup(SecurityDescriptor, NULL, &len)) + return FALSE; + if (RequestedInformation & DACL_SECURITY_INFORMATION) + if (!DumpDacl(SecurityDescriptor, NULL, &len)) + return FALSE; + if (RequestedInformation & SACL_SECURITY_INFORMATION) + if (!DumpSacl(SecurityDescriptor, NULL, &len)) + return FALSE; - 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); + wstr = wptr = LocalAlloc(0, (len + 1)*sizeof(WCHAR)); + if (wstr == NULL) 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; + if (RequestedInformation & OWNER_SECURITY_INFORMATION) + if (!DumpOwner(SecurityDescriptor, &wptr, NULL)) { + LocalFree (wstr); + return FALSE; } + if (RequestedInformation & GROUP_SECURITY_INFORMATION) + if (!DumpGroup(SecurityDescriptor, &wptr, NULL)) { + LocalFree (wstr); + return FALSE; + } + if (RequestedInformation & DACL_SECURITY_INFORMATION) + if (!DumpDacl(SecurityDescriptor, &wptr, NULL)) { + LocalFree (wstr); + return FALSE; + } + if (RequestedInformation & SACL_SECURITY_INFORMATION) + if (!DumpSacl(SecurityDescriptor, &wptr, NULL)) { + LocalFree (wstr); + return FALSE; + } + *wptr = 0; - SetLastError(ERROR_INVALID_PARAMETER); - return FALSE; + TRACE("ret: %s, %d\n", wine_dbgstr_w(wstr), len); + *OutputString = wstr; + if (OutputLen) + *OutputLen = strlenW(*OutputString)+1; + return TRUE; } - -/* - * @unimplemented +/****************************************************************************** + * ConvertSecurityDescriptorToStringSecurityDescriptorA [ADVAPI32.@] */ -BOOL -WINAPI -IsWellKnownSid(IN PSID pSid, - IN WELL_KNOWN_SID_TYPE WellKnownSidType) +BOOL WINAPI ConvertSecurityDescriptorToStringSecurityDescriptorA(PSECURITY_DESCRIPTOR SecurityDescriptor, DWORD SDRevision, SECURITY_INFORMATION Information, LPSTR *OutputString, PULONG OutputLen) { - unsigned int i; - TRACE("(%s, %d)\n", debugstr_sid(pSid), WellKnownSidType); + LPWSTR wstr; + ULONG len; + if (ConvertSecurityDescriptorToStringSecurityDescriptorW(SecurityDescriptor, SDRevision, Information, &wstr, &len)) + { + int lenA; - for (i = 0; i < sizeof(WellKnownSids) / sizeof(WellKnownSids[0]); i++) - { - if (WellKnownSids[i].Type == WellKnownSidType) + lenA = WideCharToMultiByte(CP_ACP, 0, wstr, len, NULL, 0, NULL, NULL); + *OutputString = heap_alloc(lenA); + if (*OutputString == NULL) { - if (EqualSid(pSid, (PSID)(&WellKnownSids[i].Sid.Revision))) - return TRUE; + 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; } - - 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); + *OutputString = NULL; + if (OutputLen) + *OutputLen = 0; + return FALSE; } - return bRetVal; } +/****************************************************************************** + * ConvertStringSidToSidW [ADVAPI32.@] + */ static const RECORD SidTable[] = { @@ -1854,13 +1715,7 @@ { NULL, 0 }, }; -/* - * @implemented - */ -BOOL -WINAPI -ConvertStringSidToSidW(IN LPCWSTR StringSid, - OUT PSID* sid) +BOOL WINAPI ConvertStringSidToSidW(LPCWSTR StringSid, PSID* sid) { DWORD size; DWORD i, cBytes, identAuth, csubauth; @@ -1867,7 +1722,7 @@ BOOL ret; SID* pisid; - TRACE("%s %p\n", debugstr_w(StringSid), sid); + TRACE("%s, %p\n", debugstr_w(StringSid), sid); if (!StringSid) { @@ -1984,4 +1839,103 @@ return ret; } +/****************************************************************************** + * ConvertStringSidToSidA [ADVAPI32.@] + */ +BOOL WINAPI ConvertStringSidToSidA(LPCSTR StringSid, PSID* Sid) +{ + BOOL bret = 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 + { + WCHAR *wStringSid = SERV_dup(StringSid); + bret = ConvertStringSidToSidW(wStringSid, Sid); + heap_free(wStringSid); + } + return bret; +} + +/****************************************************************************** + * ConvertSidToStringSidW [ADVAPI32.@] + * + * format of SID string is: + * S-----... + * where + * is the revision of the SID encoded as decimal + * is the identifier authority encoded as hex + * is the subauthority id encoded as decimal + */ +BOOL WINAPI ConvertSidToStringSidW( PSID pSid, LPWSTR *pstr ) +{ + DWORD len = 0; + LPWSTR wstr, wptr; + + TRACE("%p %p\n", pSid, pstr ); + + len = 0; + if (!DumpSidNumeric(pSid, NULL, &len)) + return FALSE; + wstr = wptr = LocalAlloc(0, (len+1) * sizeof(WCHAR)); + DumpSidNumeric(pSid, &wptr, NULL); + *wptr = 0; + + *pstr = wstr; + return TRUE; +} + +/****************************************************************************** + * ConvertSidToStringSidA [ADVAPI32.@] + */ +BOOL WINAPI ConvertSidToStringSidA(PSID pSid, LPSTR *pstr) +{ + LPWSTR wstr = NULL; + LPSTR str; + UINT len; + + TRACE("%p %p\n", pSid, pstr ); + + if( !ConvertSidToStringSidW( pSid, &wstr ) ) + return FALSE; + + len = WideCharToMultiByte( CP_ACP, 0, wstr, -1, NULL, 0, NULL, NULL ); + str = LocalAlloc( 0, len ); + WideCharToMultiByte( CP_ACP, 0, wstr, -1, str, len, NULL, NULL ); + LocalFree( wstr ); + + *pstr = str; + + 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; +} + /* EOF */