Added stubs for AccessCheckByType, AddAuditAccessAce,
GetNamedSecurityInfoA, GetNamedSecurityInfoW.
Implemented ConvertStringSecurityDescriptorToSecurityDescriptorW,
DeleteAce, MakeAbsoluteSD, GetAclInformation, ConvertStringSidToSidW,
RtlDeleteAce, RtlQueryInformationAcl.
diff --git a/dlls/advapi32/advapi32.spec b/dlls/advapi32/advapi32.spec
index db1e9f1..5b6586c 100644
--- a/dlls/advapi32/advapi32.spec
+++ b/dlls/advapi32/advapi32.spec
@@ -3,13 +3,13 @@
@ stdcall AccessCheck(ptr long long ptr ptr ptr ptr ptr)
@ stdcall AccessCheckAndAuditAlarmA(str ptr str str ptr long ptr long ptr ptr ptr)
@ stdcall AccessCheckAndAuditAlarmW(wstr ptr wstr wstr ptr long ptr long ptr ptr ptr)
-@ stub AccessCheckByType #(ptr ptr long long ptr long ptr ptr ptr ptr ptr) AccessCheckByType
+@ stdcall AccessCheckByType(ptr ptr long long ptr long ptr ptr ptr ptr ptr)
@ stdcall AddAccessAllowedAce (ptr long long ptr)
@ stdcall AddAccessAllowedAceEx (ptr long long long ptr)
@ stdcall AddAccessDeniedAce(ptr long long ptr)
@ stdcall AddAccessDeniedAceEx(ptr long long long ptr)
@ stdcall AddAce(ptr long long ptr long)
-@ stub AddAuditAccessAce
+@ stdcall AddAuditAccessAce(ptr long long ptr long long)
@ stub AdjustTokenGroups
@ stdcall AdjustTokenPrivileges(long long ptr long ptr ptr)
@ stdcall AllocateAndInitializeSid(ptr long long long long long long long long long ptr)
@@ -31,7 +31,7 @@
@ stub ConvertSidToStringSidA #(ptr str) ConvertSidToStringSidA
@ stub ConvertSidToStringSidW #(ptr wstr) ConvertSidToStringSidW
@ stub ConvertStringSecurityDescriptorToSecurityDescriptorA #(str long ptr ptr) ConvertStringSecurityDescriptorToSecurityDescriptorA
-@ stub ConvertStringSecurityDescriptorToSecurityDescriptorW #(wstr long ptr ptr) ConvertStringSecurityDescriptorToSecurityDescriptorW
+@ stdcall ConvertStringSecurityDescriptorToSecurityDescriptorW(wstr long ptr ptr)
@ stdcall CopySid(long ptr ptr)
@ stub CreatePrivateObjectSecurity
@ stub CreateProcessAsUserA
@@ -78,7 +78,7 @@
@ stdcall CryptSetProvParam(long long ptr long)
@ stdcall CryptVerifySignatureA(long ptr long long ptr long)
@ stdcall CryptVerifySignatureW(long ptr long long ptr long) CryptVerifySignatureA
-@ stub DeleteAce
+@ stdcall DeleteAce(ptr long)
@ stdcall DeleteService(long)
@ stdcall DeregisterEventSource(long)
@ stub DestroyPrivateObjectSecurity
@@ -103,8 +103,8 @@
@ stub GetKernelObjectSecurity
@ stdcall GetLengthSid(ptr)
@ stub GetMangledSiteSid
-@ stub GetNamedSecurityInfoA #(str long long ptr ptr ptr ptr ptr) GetNamedSecurityInfoA
-@ stub GetNamedSecurityInfoW #(wstr long long ptr ptr ptr ptr ptr) GetNamedSecurityInfoW
+@ stdcall GetNamedSecurityInfoA (str long long ptr ptr ptr ptr ptr)
+@ stdcall GetNamedSecurityInfoW (wstr long long ptr ptr ptr ptr ptr)
@ stdcall GetNumberOfEventLogRecords (long ptr)
@ stdcall GetOldestEventLogRecord (long ptr)
@ stub GetPrivateObjectSecurity
@@ -158,7 +158,7 @@
@ stdcall LookupPrivilegeNameW(wstr ptr ptr long)
@ stdcall LookupPrivilegeValueA(ptr ptr ptr)
@ stdcall LookupPrivilegeValueW(ptr ptr ptr)
-@ stub MakeAbsoluteSD
+@ stdcall MakeAbsoluteSD(ptr ptr ptr ptr ptr ptr ptr ptr ptr ptr ptr)
@ stdcall MakeSelfRelativeSD(ptr ptr ptr)
@ stub MapGenericMask
@ stdcall NotifyBootConfigStatus(long)
diff --git a/dlls/advapi32/security.c b/dlls/advapi32/security.c
index dd02b79..17f14f1 100644
--- a/dlls/advapi32/security.c
+++ b/dlls/advapi32/security.c
@@ -1,5 +1,6 @@
/*
* Copyright 1999, 2000 Juergen Schmied <juergen.schmied@debitel.net>
+ * Copyright 2003 CodeWeavers Inc. (Ulrich Czekalla)
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -30,12 +31,66 @@
#include "ntstatus.h"
#include "ntsecapi.h"
#include "accctrl.h"
+#include "sddl.h"
#include "wine/debug.h"
#include "wine/unicode.h"
WINE_DEFAULT_DEBUG_CHANNEL(advapi);
+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 BOOL ParseStringSecurityDescriptorToSecurityDescriptor(
+ LPCWSTR StringSecurityDescriptor,
+ PSECURITY_DESCRIPTOR SecurityDescriptor,
+ LPDWORD cBytes);
+static DWORD ParseAclStringFlags(LPCWSTR* StringAcl);
+
+typedef struct _ACEFLAG
+{
+ LPCWSTR wstr;
+ DWORD value;
+} ACEFLAG, *LPACEFLAG;
+
+/*
+ * 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
+ */
+static const WCHAR SDDL_ACCESS_ALLOWED[] = {'A',0};
+static const WCHAR SDDL_ACCESS_DENIED[] = {'D',0};
+static const WCHAR SDDL_OBJECT_ACCESS_ALLOWED[] = {'O','A',0};
+static const WCHAR SDDL_OBJECT_ACCESS_DENIED[] = {'O','D',0};
+static const WCHAR SDDL_AUDIT[] = {'A','U',0};
+static const WCHAR SDDL_ALARM[] = {'A','L',0};
+static const WCHAR SDDL_OBJECT_AUDIT[] = {'O','U',0};
+static const WCHAR SDDL_OBJECT_ALARMp[] = {'O','L',0};
+
+/*
+ * ACE flags
+ */
+static const WCHAR SDDL_CONTAINER_INHERIT[] = {'C','I',0};
+static const WCHAR SDDL_OBJECT_INHERIT[] = {'O','I',0};
+static const WCHAR SDDL_NO_PROPAGATE[] = {'N','P',0};
+static const WCHAR SDDL_INHERIT_ONLY[] = {'I','O',0};
+static const WCHAR SDDL_INHERITED[] = {'I','D',0};
+static const WCHAR SDDL_AUDIT_SUCCESS[] = {'S','A',0};
+static const WCHAR SDDL_AUDIT_FAILURE[] = {'F','A',0};
+
#define CallWin32ToNt(func) \
{ NTSTATUS ret; \
ret = (func); \
@@ -503,6 +558,30 @@
CallWin32ToNt (RtlCreateSecurityDescriptor(pDescr, revision ));
}
+
+/******************************************************************************
+ * MakeAbsoluteSD [ADVAPI32.@]
+ */
+BOOL WINAPI MakeAbsoluteSD (
+ IN PSECURITY_DESCRIPTOR pSelfRelativeSecurityDescriptor,
+ OUT PSECURITY_DESCRIPTOR pAbsoluteSecurityDescriptor,
+ OUT LPDWORD lpdwAbsoluteSecurityDescriptorSize,
+ OUT PACL pDacl,
+ OUT LPDWORD lpdwDaclSize,
+ OUT PACL pSacl,
+ OUT LPDWORD lpdwSaclSize,
+ OUT PSID pOwner,
+ OUT LPDWORD lpdwOwnerSize,
+ OUT PSID pPrimaryGroup,
+ OUT LPDWORD lpdwPrimaryGroupSize)
+{
+ CallWin32ToNt (RtlSelfRelativeToAbsoluteSD(pSelfRelativeSecurityDescriptor,
+ pAbsoluteSecurityDescriptor, lpdwAbsoluteSecurityDescriptorSize,
+ pDacl, lpdwDaclSize, pSacl, lpdwSaclSize, pOwner, lpdwOwnerSize,
+ pPrimaryGroup, lpdwPrimaryGroupSize));
+}
+
+
/******************************************************************************
* GetSecurityDescriptorLength [ADVAPI32.@]
*/
@@ -719,6 +798,14 @@
}
/******************************************************************************
+ * DeleteAce [ADVAPI32.@]
+ */
+BOOL WINAPI DeleteAce(PACL pAcl, DWORD dwAceIndex)
+{
+ CallWin32ToNt(RtlDeleteAce(pAcl, dwAceIndex));
+}
+
+/******************************************************************************
* FindFirstFreeAce [ADVAPI32.@]
*/
BOOL WINAPI FindFirstFreeAce(IN PACL pAcl, LPVOID * pAce)
@@ -743,9 +830,8 @@
DWORD nAclInformationLength,
ACL_INFORMATION_CLASS dwAclInformationClass)
{
- FIXME("(%p,%p,%ld,%d): stub\n",pAcl, pAclInformation,
- nAclInformationLength, dwAclInformationClass);
- return FALSE;
+ CallWin32ToNt(RtlQueryInformationAcl(pAcl, pAclInformation,
+ nAclInformationLength, dwAclInformationClass));
}
/******************************************************************************
@@ -1255,6 +1341,31 @@
GenericMapping, PrivilegeSet, PrivilegeSetLength, GrantedAccess, (PBOOLEAN)AccessStatus));
}
+
+/******************************************************************************
+ * AccessCheckByType [ADVAPI32.@]
+ */
+BOOL WINAPI AccessCheckByType(
+ PSECURITY_DESCRIPTOR pSecurityDescriptor,
+ PSID PrincipalSelfSid,
+ HANDLE ClientToken,
+ DWORD DesiredAccess,
+ POBJECT_TYPE_LIST ObjectTypeList,
+ DWORD ObjectTypeListLength,
+ PGENERIC_MAPPING GenericMapping,
+ PPRIVILEGE_SET PrivilegeSet,
+ LPDWORD PrivilegeSetLength,
+ LPDWORD GrantedAccess,
+ LPBOOL AccessStatus)
+{
+ FIXME("stub\n");
+
+ *AccessStatus = TRUE;
+
+ return !*AccessStatus;
+}
+
+
/*************************************************************************
* SetKernelObjectSecurity [ADVAPI32.@]
*/
@@ -1266,6 +1377,22 @@
CallWin32ToNt (NtSetSecurityObject (Handle, SecurityInformation, SecurityDescriptor));
}
+
+/******************************************************************************
+ * AddAuditAccessAce [ADVAPI32.@]
+ */
+BOOL WINAPI AddAuditAccessAce(
+ IN OUT PACL pAcl,
+ IN DWORD dwAceRevision,
+ IN DWORD dwAccessMask,
+ IN PSID pSid,
+ IN BOOL bAuditSuccess,
+ IN BOOL bAuditFailure)
+{
+ FIXME("Stub\n");
+ return TRUE;
+}
+
/******************************************************************************
* LookupAccountNameA [ADVAPI32.@]
*/
@@ -1418,3 +1545,601 @@
FIXME("%p %p %p\n",pacl, pcCountOfExplicitEntries, pListOfExplicitEntries);
return ERROR_CALL_NOT_IMPLEMENTED;
}
+
+
+/******************************************************************************
+ * 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;
+}
+
+/******************************************************************************
+ * ParseAceStringType
+ */
+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;
+ LPACEFLAG 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
+ */
+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 != ';')
+ {
+ LPACEFLAG 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
+ */
+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)
+ {
+ rights = strtoulW(szAcl, NULL, 16);
+ *StringAcl = p;
+ }
+ else
+ WARN("Invalid rights string format: %s\n", debugstr_wn(szAcl, p - szAcl));
+ }
+ else
+ {
+ while (*szAcl != ';')
+ {
+ LPACEFLAG 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");
+ goto lerr;
+ }
+ StringAcl++;
+
+ /* Parse ACE inherit object guid */
+ if (*StringAcl != ';')
+ {
+ FIXME("Support for *_OBJECT_ACE_TYPE not implemented");
+ 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 += sizeof(ACCESS_ALLOWED_ACE) - sizeof(DWORD) + sidlen;
+ }
+
+ *cBytes = length;
+ return TRUE;
+
+lerr:
+ WARN("Invalid ACE string format\n");
+ return FALSE;
+}
+
+
+/******************************************************************************
+ * ParseStringSecurityDescriptorToSecurityDescriptor
+ */
+static BOOL ParseStringSecurityDescriptorToSecurityDescriptor(
+ LPCWSTR StringSecurityDescriptor,
+ PSECURITY_DESCRIPTOR SecurityDescriptor,
+ LPDWORD cBytes)
+{
+ BOOL bret = FALSE;
+ WCHAR toktype;
+ WCHAR tok[MAX_PATH];
+ LPCWSTR lptoken;
+ LPBYTE lpNext = NULL;
+
+ *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--;
+
+ strncpyW(tok, StringSecurityDescriptor, lptoken - StringSecurityDescriptor);
+
+ 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 */
+ }
+
+ *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;
+ }
+
+ StringSecurityDescriptor = lptoken;
+ }
+
+ bret = TRUE;
+
+lend:
+ return bret;
+}
+
+/******************************************************************************
+ * ConvertStringSecurityDescriptorToSecurityDescriptorW [ADVAPI32.@]
+ */
+BOOL WINAPI ConvertStringSecurityDescriptorToSecurityDescriptorW(
+ LPCWSTR StringSecurityDescriptor,
+ DWORD StringSDRevision,
+ PSECURITY_DESCRIPTOR* SecurityDescriptor,
+ PULONG SecurityDescriptorSize)
+{
+ DWORD cBytes;
+ PSECURITY_DESCRIPTOR psd;
+ BOOL bret = FALSE;
+
+ TRACE("%s\n", debugstr_w(StringSecurityDescriptor));
+
+ if (GetVersion() & 0x80000000)
+ {
+ SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+ goto lend;
+ }
+ else if (StringSDRevision != SID_REVISION)
+ {
+ SetLastError(ERROR_UNKNOWN_REVISION);
+ goto lend;
+ }
+
+ /* Compute security descriptor length */
+ if (!ParseStringSecurityDescriptorToSecurityDescriptor(StringSecurityDescriptor,
+ NULL, &cBytes))
+ goto lend;
+
+ psd = *SecurityDescriptor = (PSECURITY_DESCRIPTOR) LocalAlloc(
+ GMEM_ZEROINIT, cBytes);
+
+ psd->Revision = SID_REVISION;
+ psd->Control |= SE_SELF_RELATIVE;
+
+ if (!ParseStringSecurityDescriptorToSecurityDescriptor(StringSecurityDescriptor,
+ psd, &cBytes))
+ {
+ LocalFree(psd);
+ goto lend;
+ }
+
+ if (SecurityDescriptorSize)
+ *SecurityDescriptorSize = cBytes;
+
+ bret = TRUE;
+
+lend:
+ TRACE(" ret=%d\n", bret);
+ return bret;
+}
+
+/******************************************************************************
+ * ConvertStringSidToSidW [ADVAPI32.@]
+ */
+BOOL WINAPI ConvertStringSidToSidW(LPCWSTR StringSid, PSID* Sid)
+{
+ BOOL bret = FALSE;
+ DWORD cBytes;
+
+ if (GetVersion() & 0x80000000)
+ SetLastError(ERROR_CALL_NOT_IMPLEMENTED);
+ else if (ParseStringSidToSid(StringSid, NULL, &cBytes))
+ {
+ PSID pSid = *Sid = (PSID) LocalAlloc(0, cBytes);
+
+ bret = ParseStringSidToSid(StringSid, pSid, &cBytes);
+ if (!bret)
+ LocalFree(*Sid);
+ }
+
+ return bret;
+}
+
+/******************************************************************************
+ * ComputeStringSidSize
+ */
+static DWORD ComputeStringSidSize(LPCWSTR StringSid)
+{
+ int ctok = 0;
+ DWORD size = sizeof(SID);
+
+ while (*StringSid)
+ {
+ if (*StringSid == '-')
+ ctok++;
+ StringSid++;
+ }
+
+ if (ctok > 3)
+ size += (ctok - 3) * sizeof(DWORD);
+
+ return size;
+}
+
+/******************************************************************************
+ * ParseStringSidToSid
+ */
+static BOOL ParseStringSidToSid(LPCWSTR StringSid, PSID pSid, LPDWORD cBytes)
+{
+ BOOL bret = FALSE;
+
+ if (!StringSid)
+ {
+ SetLastError(ERROR_INVALID_PARAMETER);
+ return FALSE;
+ }
+
+ *cBytes = ComputeStringSidSize(StringSid);
+ if (!pSid) /* Simply compute the size */
+ return TRUE;
+
+ if (*StringSid != 'S' || *StringSid != '-') /* S-R-I-S-S */
+ {
+ int i = 0;
+ int csubauth = ((*cBytes - sizeof(SID)) / sizeof(DWORD)) + 1;
+
+ StringSid += 2; /* Advance to Revision */
+ pSid->Revision = atoiW(StringSid);
+
+ if (pSid->Revision != SDDL_REVISION)
+ goto lend; /* ERROR_INVALID_SID */
+
+ pSid->SubAuthorityCount = csubauth;
+
+ while (*StringSid && *StringSid != '-')
+ StringSid++; /* Advance to identifier authority */
+
+ pSid->IdentifierAuthority.Value[5] = atoiW(StringSid);
+
+ if (pSid->IdentifierAuthority.Value[5] > 5)
+ goto lend; /* ERROR_INVALID_SID */
+
+ while (*StringSid)
+ {
+ while (*StringSid && *StringSid != '-')
+ StringSid++;
+
+ pSid->SubAuthority[i++] = atoiW(StringSid);
+ }
+
+ if (i != pSid->SubAuthorityCount)
+ goto lend; /* ERROR_INVALID_SID */
+
+ bret = TRUE;
+ }
+ else /* String constant format - Only available in winxp and above */
+ {
+ pSid->Revision = SDDL_REVISION;
+ pSid->SubAuthorityCount = 1;
+
+ FIXME("String constant not supported: %s\n", debugstr_wn(StringSid, 2));
+
+ /* TODO: Lookup string of well-known SIDs in table */
+ pSid->IdentifierAuthority.Value[5] = 0;
+ pSid->SubAuthority[0] = 0;
+
+ bret = TRUE;
+ }
+
+lend:
+ if (!bret)
+ SetLastError(ERROR_INVALID_SID);
+
+ return bret;
+}
+
+/******************************************************************************
+ * GetNamedSecurityInfoA [ADVAPI32.@]
+ */
+DWORD WINAPI GetNamedSecurityInfoA(LPSTR pObjectName,
+ SE_OBJECT_TYPE ObjectType, SECURITY_INFORMATION SecurityInfo,
+ PSID* ppsidOwner, PSID* ppsidGroup, PACL* ppDacl, PACL* ppSacl,
+ PSECURITY_DESCRIPTOR* ppSecurityDescriptor)
+{
+ FIXME("%s %d %ld %p %p %p %p %p\n", pObjectName, ObjectType, SecurityInfo,
+ ppsidOwner, ppsidGroup, ppDacl, ppSacl, ppSecurityDescriptor);
+ return ERROR_CALL_NOT_IMPLEMENTED;
+}
+
+/******************************************************************************
+ * GetNamedSecurityInfoW [ADVAPI32.@]
+ */
+DWORD WINAPI GetNamedSecurityInfoW(LPWSTR pObjectName,
+ SE_OBJECT_TYPE ObjectType, SECURITY_INFORMATION SecurityInfo,
+ PSID* ppsidOwner, PSID* ppsidGroup, PACL* ppDacl, PACL* ppSacl,
+ PSECURITY_DESCRIPTOR* ppSecurityDescriptor)
+{
+ FIXME("%s %d %ld %p %p %p %p %p\n", debugstr_w(pObjectName), ObjectType, SecurityInfo,
+ ppsidOwner, ppsidGroup, ppDacl, ppSacl, ppSecurityDescriptor);
+ return ERROR_CALL_NOT_IMPLEMENTED;
+}
diff --git a/dlls/ntdll/ntdll.spec b/dlls/ntdll/ntdll.spec
index 72a48e3..3b79ea0 100644
--- a/dlls/ntdll/ntdll.spec
+++ b/dlls/ntdll/ntdll.spec
@@ -340,7 +340,7 @@
@ stub RtlDecompressBuffer
@ stub RtlDecompressFragment
@ stub RtlDelete
-@ stub RtlDeleteAce
+@ stdcall RtlDeleteAce(ptr long)
@ stdcall RtlDeleteCriticalSection(ptr)
@ stub RtlDeleteElementGenericTable
@ stub RtlDeleteRegistryValue
@@ -488,7 +488,7 @@
@ stdcall RtlPrefixUnicodeString(ptr ptr long)
@ stub RtlProtectHeap
@ stdcall RtlQueryEnvironmentVariable_U(ptr ptr ptr)
-@ stub RtlQueryInformationAcl
+@ stdcall RtlQueryInformationAcl(ptr ptr long long)
@ stub RtlQueryProcessBackTraceInformation
@ stub RtlQueryProcessDebugInformation
@ stub RtlQueryProcessHeapInformation
diff --git a/dlls/ntdll/sec.c b/dlls/ntdll/sec.c
index 945ba28..af4cc47 100644
--- a/dlls/ntdll/sec.c
+++ b/dlls/ntdll/sec.c
@@ -2,6 +2,7 @@
* Security functions
*
* Copyright 1996-1998 Marcus Meissner
+ * Copyright 2003 CodeWeavers Inc. (Ulrich Czekalla)
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
@@ -897,6 +898,35 @@
return STATUS_SUCCESS;
}
+/**************************************************************************
+ * RtlDeleteAce [NTDLL.@]
+ */
+NTSTATUS WINAPI RtlDeleteAce(PACL pAcl, DWORD dwAceIndex)
+{
+ NTSTATUS status;
+ PACE_HEADER pAce;
+
+ status = RtlGetAce(pAcl,dwAceIndex,(LPVOID*)&pAce);
+
+ if (STATUS_SUCCESS == status)
+ {
+ PACE_HEADER pcAce;
+ DWORD len = 0;
+
+ pcAce = (PACE_HEADER)(((BYTE*)pAce)+pAce->AceSize);
+ for (; dwAceIndex < pAcl->AceCount; dwAceIndex++)
+ {
+ len += pcAce->AceSize;
+ pcAce = (PACE_HEADER)(((BYTE*)pcAce) + pcAce->AceSize);
+ }
+
+ memcpy(pAce, ((BYTE*)pAce)+pAce->AceSize, len);
+ pAcl->AceCount--;
+ }
+
+ return status;
+}
+
/******************************************************************************
* RtlAddAccessAllowedAce [NTDLL.@]
*/
@@ -1161,3 +1191,74 @@
TRACE("%s (%u %u)\n",debugstr_w(String->Buffer),String->Length,String->MaximumLength);
return status;
}
+
+/******************************************************************************
+ * RtlQueryInformationAcl (NTDLL.@)
+ */
+NTSTATUS WINAPI RtlQueryInformationAcl(
+ PACL pAcl,
+ LPVOID pAclInformation,
+ DWORD nAclInformationLength,
+ ACL_INFORMATION_CLASS dwAclInformationClass)
+{
+ NTSTATUS status = STATUS_SUCCESS;
+
+ TRACE("pAcl=%p pAclInfo=%p len=%ld, class=%d\n",
+ pAcl, pAclInformation, nAclInformationLength, dwAclInformationClass);
+
+ switch (dwAclInformationClass)
+ {
+ case AclRevisionInformation:
+ {
+ PACL_REVISION_INFORMATION paclrev = (PACL_REVISION_INFORMATION) pAclInformation;
+
+ if (nAclInformationLength < sizeof(ACL_REVISION_INFORMATION))
+ status = STATUS_INVALID_PARAMETER;
+ else
+ paclrev->AclRevision = pAcl->AclRevision;
+
+ break;
+ }
+
+ case AclSizeInformation:
+ {
+ PACL_SIZE_INFORMATION paclsize = (PACL_SIZE_INFORMATION) pAclInformation;
+
+ if (nAclInformationLength < sizeof(ACL_SIZE_INFORMATION))
+ status = STATUS_INVALID_PARAMETER;
+ else
+ {
+ INT i;
+ PACE_HEADER ace;
+
+ paclsize->AceCount = pAcl->AceCount;
+
+ paclsize->AclBytesInUse = 0;
+ ace = (PACE_HEADER) (pAcl + 1);
+
+ for (i = 0; i < pAcl->AceCount; i++)
+ {
+ paclsize->AclBytesInUse += ace->AceSize;
+ ace = (PACE_HEADER)(((BYTE*)ace)+ace->AceSize);
+ }
+
+ if (pAcl->AclSize < paclsize->AclBytesInUse)
+ {
+ WARN("Acl has %ld bytes free\n", pAcl->AclSize - paclsize->AclBytesInUse);
+ paclsize->AclBytesFree = 0;
+ paclsize->AclBytesInUse = pAcl->AclSize;
+ }
+ else
+ paclsize->AclBytesFree = pAcl->AclSize - paclsize->AclBytesInUse;
+ }
+
+ break;
+ }
+
+ default:
+ WARN("Unknown AclInformationClass value: %d\n", dwAclInformationClass);
+ status = STATUS_INVALID_PARAMETER;
+ }
+
+ return status;
+}
diff --git a/include/Makefile.in b/include/Makefile.in
index 2be65d9..44c703d 100644
--- a/include/Makefile.in
+++ b/include/Makefile.in
@@ -153,6 +153,7 @@
rpcndr.h \
rpcnterr.h \
rpcproxy.h \
+ sddl.h \
setupapi.h \
shellapi.h \
shlguid.h \
diff --git a/include/sddl.h b/include/sddl.h
new file mode 100644
index 0000000..2b483c8
--- /dev/null
+++ b/include/sddl.h
@@ -0,0 +1,81 @@
+/*
+ * Copyright (C) 2003 Ulrich Czekalla for CodeWeavers
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 2.1 of the License, or (at your option) any later version.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
+ */
+
+#ifndef __SDDL_H__
+#define __SDDL_H__
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/*
+ * SDDL Version information
+ */
+#define SDDL_REVISION_1 1
+#define SDDL_REVISION SDDL_REVISION_1
+
+/*
+ * SDDL Component tags
+ */
+#define SDDL_OWNER TEXT("O")
+#define SDDL_GROUP TEXT("G")
+#define SDDL_DACL TEXT("D")
+#define SDDL_SACL TEXT("S")
+
+/*
+ * SDDL Seperators - character version
+ */
+#define SDDL_SEPERATORC TEXT(";")
+#define SDDL_DELIMINATORC TEXT(":")
+#define SDDL_ACE_BEGINC TEXT("(")
+#define SDDL_ACE_ENDC TEXT(")")
+
+/*
+ * SDDL Seperators - string version
+ */
+#define SDDL_SEPERATOR TEXT(";")
+#define SDDL_DELIMINATOR TEXT(":")
+#define SDDL_ACE_BEGIN TEXT("(")
+#define SDDL_ACE_END TEXT(")")
+
+BOOL WINAPI ConvertSidToStringSidA( PSID, LPSTR* );
+BOOL WINAPI ConvertSidToStringSidW( PSID, LPWSTR* );
+#define ConvertSidToStringSid WINELIB_NAME_AW(ConvertSidToStringSid)
+
+BOOL WINAPI ConvertStringSidToSidA( LPCSTR, PSID* );
+BOOL WINAPI ConvertStringSidToSidW( LPCWSTR, PSID* );
+#define ConvertStringSidToSid WINELIB_NAME_AW(ConvertStringSidToSid)
+
+BOOL WINAPI ConvertStringSecurityDescriptorToSecurityDescriptorA(
+ LPCSTR, DWORD, PSECURITY_DESCRIPTOR*, PULONG );
+BOOL WINAPI ConvertStringSecurityDescriptorToSecurityDescriptorW(
+ LPCWSTR, DWORD, PSECURITY_DESCRIPTOR*, PULONG );
+#define ConvertStringSecurityDescriptorToSecurityDescriptor WINELIB_NAME_AW(ConvertStringSecurityDescriptorToSecurityDescriptor)
+
+BOOL WINAPI ConvertSecurityDescriptorToStringSecurityDescriptorA(
+ PSECURITY_DESCRIPTOR, DWORD, SECURITY_INFORMATION, LPSTR*, PULONG );
+BOOL WINAPI ConvertSecurityDescriptorToStringSecurityDescriptorW(
+ PSECURITY_DESCRIPTOR, DWORD, SECURITY_INFORMATION, LPWSTR*, PULONG );
+#define ConvertSecurityDescriptorToStringSecurityDescriptor WINELIB_NAME_AW(ConvertSecurityDescriptorToStringSecurityDescriptor)
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* __SDDL_H__ */
diff --git a/include/winbase.h b/include/winbase.h
index 8168c26..b97317f 100644
--- a/include/winbase.h
+++ b/include/winbase.h
@@ -1182,6 +1182,7 @@
void WINAPI DebugBreak(void);
BOOL WINAPI DebugBreakProcess(HANDLE);
BOOL WINAPI DebugSetProcessKillOnExit(BOOL);
+BOOL WINAPI DeleteAce(PACL,DWORD);
void WINAPI DeleteFiber(LPVOID);
BOOL WINAPI DeleteTimerQueueEx(HANDLE,HANDLE);
BOOL WINAPI DeleteTimerQueueTimer(HANDLE,HANDLE,HANDLE);
@@ -1353,6 +1354,8 @@
BOOL WINAPI LookupPrivilegeValueA(LPCSTR,LPCSTR,PLUID);
BOOL WINAPI LookupPrivilegeValueW(LPCWSTR,LPCWSTR,PLUID);
#define LookupPrivilegeValue WINELIB_NAME_AW(LookupPrivilegeValue)
+BOOL WINAPI MakeAbsoluteSD(PSECURITY_DESCRIPTOR,PSECURITY_DESCRIPTOR,LPDWORD,
+ PACL,LPDWORD,PACL,LPDWORD,PSID,LPDWORD,PSID,LPDWORD);
BOOL WINAPI MakeSelfRelativeSD(PSECURITY_DESCRIPTOR,PSECURITY_DESCRIPTOR,LPDWORD);
HMODULE WINAPI MapHModuleSL(WORD);
WORD WINAPI MapHModuleLS(HMODULE);
diff --git a/include/winnt.h b/include/winnt.h
index 9f3950b..a63eccf 100644
--- a/include/winnt.h
+++ b/include/winnt.h
@@ -2861,6 +2861,18 @@
AclSizeInformation
} ACL_INFORMATION_CLASS;
+typedef struct _ACL_REVISION_INFORMATION
+{
+ DWORD AclRevision;
+} ACL_REVISION_INFORMATION, *PACL_REVISION_INFORMATION;
+
+typedef struct _ACL_SIZE_INFORMATION
+{
+ DWORD AceCount;
+ DWORD AclBytesInUse;
+ DWORD AclBytesFree;
+} ACL_SIZE_INFORMATION, *PACL_SIZE_INFORMATION;
+
/* SECURITY_DESCRIPTOR */
#define SECURITY_DESCRIPTOR_REVISION 1
#define SECURITY_DESCRIPTOR_REVISION1 1
@@ -3207,6 +3219,7 @@
#define CONTAINER_INHERIT_ACE 0x02
#define NO_PROPAGATE_INHERIT_ACE 0x04
#define INHERIT_ONLY_ACE 0x08
+#define INHERITED_ACE 0x10
#define VALID_INHERIT_FLAGS 0x0F
/* AceFlags mask for what events we (should) audit */
@@ -3579,6 +3592,12 @@
#include <guiddef.h>
+typedef struct _OBJECT_TYPE_LIST {
+ WORD Level;
+ WORD Sbz;
+ GUID *ObjectType;
+} OBJECT_TYPE_LIST, *POBJECT_TYPE_LIST;
+
typedef struct _RTL_CRITICAL_SECTION_DEBUG
{
WORD Type;
diff --git a/include/winternl.h b/include/winternl.h
index 0ad0c7b..f47f415 100644
--- a/include/winternl.h
+++ b/include/winternl.h
@@ -1098,6 +1098,7 @@
BOOLEAN WINAPI RtlCreateUnicodeStringFromAsciiz(PUNICODE_STRING,LPCSTR);
NTSTATUS WINAPI RtlCreateUserThread(HANDLE,const SECURITY_DESCRIPTOR*,BOOLEAN,PVOID,SIZE_T,SIZE_T,PRTL_THREAD_START_ROUTINE,void*,HANDLE*,CLIENT_ID*);
+NTSTATUS WINAPI RtlDeleteAce(PACL,DWORD);
NTSTATUS WINAPI RtlDeleteCriticalSection(RTL_CRITICAL_SECTION *);
void WINAPI RtlDeleteResource(LPRTL_RWLOCK);
DWORD WINAPI RtlDeleteSecurityObject(DWORD);
@@ -1226,6 +1227,7 @@
BOOLEAN WINAPI RtlPrefixUnicodeString(const UNICODE_STRING*,const UNICODE_STRING*,BOOLEAN);
NTSTATUS WINAPI RtlQueryEnvironmentVariable_U(PWSTR,PUNICODE_STRING,PUNICODE_STRING);
+NTSTATUS WINAPI RtlQueryInformationAcl(PACL,LPVOID,DWORD,ACL_INFORMATION_CLASS);
NTSTATUS WINAPI RtlQueryTimeZoneInformation(LPTIME_ZONE_INFORMATION);
void WINAPI RtlRaiseException(PEXCEPTION_RECORD);
@@ -1238,6 +1240,8 @@
void WINAPI RtlSecondsSince1970ToTime(DWORD,LARGE_INTEGER *);
void WINAPI RtlSecondsSince1980ToTime(DWORD,LARGE_INTEGER *);
+NTSTATUS WINAPI RtlSelfRelativeToAbsoluteSD(PSECURITY_DESCRIPTOR,PSECURITY_DESCRIPTOR,
+ PDWORD,PACL,PDWORD,PACL,PDWORD,PSID,PDWORD,PSID,PDWORD);
void WINAPI RtlSetAllBits(PRTL_BITMAP);
void WINAPI RtlSetBits(PRTL_BITMAP,ULONG,ULONG);
NTSTATUS WINAPI RtlSetCurrentDirectory_U(const UNICODE_STRING*);