diff --git a/dlls/advapi32/advapi32.spec b/dlls/advapi32/advapi32.spec index db1e9f1c373..5b6586c5d7c 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 dd02b79dddd..17f14f1d7fd 100644 --- a/dlls/advapi32/security.c +++ b/dlls/advapi32/security.c @@ -1,5 +1,6 @@ /* * Copyright 1999, 2000 Juergen Schmied + * 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 @@ InitializeSecurityDescriptor( SECURITY_DESCRIPTOR *pDescr, DWORD revision ) 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.@] */ @@ -718,6 +797,14 @@ BOOL WINAPI AddAce( CallWin32ToNt(RtlAddAce(pAcl, dwAceRevision, dwStartingAceIndex, pAceList, nAceListLength)); } +/****************************************************************************** + * DeleteAce [ADVAPI32.@] + */ +BOOL WINAPI DeleteAce(PACL pAcl, DWORD dwAceIndex) +{ + CallWin32ToNt(RtlDeleteAce(pAcl, dwAceIndex)); +} + /****************************************************************************** * FindFirstFreeAce [ADVAPI32.@] */ @@ -743,9 +830,8 @@ BOOL WINAPI GetAclInformation( 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 @@ AccessCheck( 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 @@ BOOL WINAPI SetKernelObjectSecurity ( 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 @@ DWORD WINAPI GetExplicitEntriesFromAclW( PACL pacl, PULONG pcCountOfExplicitEntr 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 72a48e3ba78..3b79ea0d08f 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 945ba282eb0..af4cc47ac16 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 @@ NTSTATUS WINAPI RtlAddAce( 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 @@ NTSTATUS WINAPI RtlConvertSidToUnicodeString( 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 2be65d95a6e..44c703d04c5 100644 --- a/include/Makefile.in +++ b/include/Makefile.in @@ -153,6 +153,7 @@ WINDOWS_INCLUDES = \ 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 00000000000..2b483c83622 --- /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 8168c26357c..b97317fa713 100644 --- a/include/winbase.h +++ b/include/winbase.h @@ -1182,6 +1182,7 @@ BOOL WINAPI DebugActiveProcessStop(DWORD); 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 LockFileEx(HANDLE, DWORD, DWORD, DWORD, DWORD, LPOVERLAPPED); 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 9f3950b0593..a63eccff02c 100644 --- a/include/winnt.h +++ b/include/winnt.h @@ -2861,6 +2861,18 @@ typedef enum _ACL_INFORMATION_CLASS 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 @@ typedef struct _ACE_HEADER { #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 @@ typedef enum _CM_ERROR_CONTROL_TYPE #include +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 0ad0c7b4c3d..f47f4150ab2 100644 --- a/include/winternl.h +++ b/include/winternl.h @@ -1098,6 +1098,7 @@ BOOLEAN WINAPI RtlCreateUnicodeString(PUNICODE_STRING,LPCWSTR); 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 RtlPrefixString(const STRING*,const STRING*,BOOLEAN); 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 @@ ULONG WINAPI RtlRemoveVectoredExceptionHandler(PVOID); 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*);