From f46f194ae4e92f181b6959ab2e3b8e405903161b Mon Sep 17 00:00:00 2001 From: Thomas Bluemel Date: Thu, 3 Nov 2005 11:28:56 +0000 Subject: [PATCH] add all ACEs to their principals svn path=/trunk/; revision=18972 --- reactos/lib/aclui/aclui.c | 363 ++++++++++++++++++++++++++-------- reactos/lib/aclui/checklist.c | 38 +++- reactos/lib/aclui/precomp.h | 15 ++ 3 files changed, 335 insertions(+), 81 deletions(-) diff --git a/reactos/lib/aclui/aclui.c b/reactos/lib/aclui/aclui.c index dc7bb91802d..3a4223f8449 100644 --- a/reactos/lib/aclui/aclui.c +++ b/reactos/lib/aclui/aclui.c @@ -30,6 +30,45 @@ HINSTANCE hDllInstance; +static PSID +AceHeaderToSID(IN PACE_HEADER AceHeader) +{ + PSID Sid = NULL; + switch (AceHeader->AceType) + { + case ACCESS_ALLOWED_ACE_TYPE: + Sid = (PSID)&((PACCESS_ALLOWED_ACE)AceHeader)->SidStart; + break; +#if 0 + case ACCESS_ALLOWED_CALLBACK_ACE_TYPE: + Sid = (PSID)&((PACCESS_ALLOWED_CALLBACK_ACE)AceHeader)->SidStart; + break; + case ACCESS_ALLOWED_CALLBACK_OBJECT_ACE_TYPE: + Sid = (PSID)&((PACCESS_ALLOWED_CALLBACK_OBJECT_ACE)AceHeader)->SidStart; + break; +#endif + case ACCESS_ALLOWED_OBJECT_ACE_TYPE: + Sid = (PSID)&((PACCESS_ALLOWED_OBJECT_ACE)AceHeader)->SidStart; + break; + case ACCESS_DENIED_ACE_TYPE: + Sid = (PSID)&((PACCESS_DENIED_ACE)AceHeader)->SidStart; + break; +#if 0 + case ACCESS_DENIED_CALLBACK_ACE_TYPE: + Sid = (PSID)&((PACCESS_DENIED_CALLBACK_ACE)AceHeader)->SidStart; + break; + case ACCESS_DENIED_CALLBACK_OBJECT_ACE_TYPE: + Sid = (PSID)&((PACCESS_DENIED_CALLBACK_OBJECT_ACE)AceHeader)->SidStart; + break; +#endif + case SYSTEM_AUDIT_OBJECT_ACE_TYPE: + Sid = (PSID)&((PACCESS_DENIED_OBJECT_ACE)AceHeader)->SidStart; + break; + } + + return Sid; +} + static VOID DestroySecurityPage(IN PSECURITY_PAGE sp) { @@ -49,10 +88,22 @@ static VOID FreePrincipalsList(IN PPRINCIPAL_LISTITEM *PrincipalsListHead) { PPRINCIPAL_LISTITEM CurItem, NextItem; + PACE_ENTRY AceEntry, NextAceEntry; CurItem = *PrincipalsListHead; while (CurItem != NULL) { + /* Free all ACEs */ + AceEntry = CurItem->ACEs; + while (AceEntry != NULL) + { + NextAceEntry = AceEntry->Next; + HeapFree(GetProcessHeap(), + 0, + AceEntry); + AceEntry = NextAceEntry; + } + /* free the SID string if present */ if (CurItem->DisplayString != NULL) { @@ -70,9 +121,40 @@ FreePrincipalsList(IN PPRINCIPAL_LISTITEM *PrincipalsListHead) *PrincipalsListHead = NULL; } +static PACE_ENTRY +AddAceToPrincipal(IN PPRINCIPAL_LISTITEM Principal, + IN PACE_HEADER AceHeader) +{ + PACE_ENTRY AceEntry, *AceLink; + + AceEntry = HeapAlloc(GetProcessHeap(), + 0, + sizeof(ACE_ENTRY) + AceHeader->AceSize); + if (AceEntry != NULL) + { + AceEntry->Next = NULL; + + /* copy the ACE */ + CopyMemory(AceEntry + 1, + AceHeader, + AceHeader->AceSize); + + /* append it to the list */ + AceLink = &Principal->ACEs; + while (*AceLink != NULL) + { + AceLink = &(*AceLink)->Next; + } + *AceLink = AceEntry; + } + + return AceEntry; +} + static PPRINCIPAL_LISTITEM -FindSidInPrincipalsList(IN PPRINCIPAL_LISTITEM PrincipalsListHead, - IN PSID Sid) +FindSidInPrincipalsListAddAce(IN PPRINCIPAL_LISTITEM PrincipalsListHead, + IN PSID Sid, + IN PACE_HEADER AceHeader) { PPRINCIPAL_LISTITEM CurItem; @@ -83,7 +165,14 @@ FindSidInPrincipalsList(IN PPRINCIPAL_LISTITEM PrincipalsListHead, if (EqualSid((PSID)(CurItem + 1), Sid)) { - return CurItem; + if (AddAceToPrincipal(CurItem, + AceHeader) != NULL) + { + return CurItem; + } + + /* unable to add the ACE to the principal */ + break; } } @@ -92,15 +181,21 @@ FindSidInPrincipalsList(IN PPRINCIPAL_LISTITEM PrincipalsListHead, static BOOL AddPrincipalToList(IN PSECURITY_PAGE sp, - IN PSID Sid) + IN PSID Sid, + IN PACE_HEADER AceHeader) { - if (!FindSidInPrincipalsList(sp->PrincipalsListHead, - Sid)) + PPRINCIPAL_LISTITEM PrincipalListItem = NULL; + PACE_ENTRY AceEntry = NULL; + BOOL Ret = FALSE; + + if (!FindSidInPrincipalsListAddAce(sp->PrincipalsListHead, + Sid, + AceHeader)) { DWORD SidLength, AccountNameSize, DomainNameSize; SID_NAME_USE SidNameUse; DWORD LookupResult; - PPRINCIPAL_LISTITEM AceListItem, *NextAcePtr; + PPRINCIPAL_LISTITEM PrincipalListItem, *PrincipalLink; AccountNameSize = 0; DomainNameSize = 0; @@ -118,69 +213,82 @@ AddPrincipalToList(IN PSECURITY_PAGE sp, if (LookupResult != ERROR_NONE_MAPPED && LookupResult != ERROR_INSUFFICIENT_BUFFER) { - return FALSE; + goto Cleanup; } } - NextAcePtr = &sp->PrincipalsListHead; - for (AceListItem = sp->PrincipalsListHead; - AceListItem != NULL; - AceListItem = AceListItem->Next) + PrincipalLink = &sp->PrincipalsListHead; + while (*PrincipalLink != NULL) { - NextAcePtr = &AceListItem->Next; + PrincipalLink = &(*PrincipalLink)->Next; } SidLength = GetLengthSid(Sid); - /* allocate the ace */ - AceListItem = HeapAlloc(GetProcessHeap(), - 0, - sizeof(PRINCIPAL_LISTITEM) + SidLength + - ((AccountNameSize + DomainNameSize) * sizeof(WCHAR))); - if (AceListItem != NULL) + /* allocate the principal */ + PrincipalListItem = HeapAlloc(GetProcessHeap(), + 0, + sizeof(PRINCIPAL_LISTITEM) + SidLength + + ((AccountNameSize + DomainNameSize) * sizeof(WCHAR))); + if (PrincipalListItem != NULL) { - AceListItem->AccountName = (LPWSTR)((ULONG_PTR)(AceListItem + 1) + SidLength); - AceListItem->DomainName = AceListItem->AccountName + AccountNameSize; + PrincipalListItem->AccountName = (LPWSTR)((ULONG_PTR)(PrincipalListItem + 1) + SidLength); + PrincipalListItem->DomainName = PrincipalListItem->AccountName + AccountNameSize; CopySid(SidLength, - (PSID)(AceListItem + 1), + (PSID)(PrincipalListItem + 1), Sid); LookupResult = ERROR_SUCCESS; if (!LookupAccountSid(sp->ServerName, Sid, - AceListItem->AccountName, + PrincipalListItem->AccountName, &AccountNameSize, - AceListItem->DomainName, + PrincipalListItem->DomainName, &DomainNameSize, &SidNameUse)) { LookupResult = GetLastError(); if (LookupResult != ERROR_NONE_MAPPED) { - HeapFree(GetProcessHeap(), - 0, - AceListItem); - return FALSE; + goto Cleanup; } } if (AccountNameSize == 0) { - AceListItem->AccountName = NULL; + PrincipalListItem->AccountName = NULL; } if (DomainNameSize == 0) { - AceListItem->DomainName = NULL; + PrincipalListItem->DomainName = NULL; } - AceListItem->Next = NULL; + /* allocate some memory for the ACE and copy it */ + AceEntry = HeapAlloc(GetProcessHeap(), + 0, + sizeof(ACE_ENTRY) + AceHeader->AceSize); + if (AceEntry == NULL) + { + goto Cleanup; + } + AceEntry->Next = NULL; + CopyMemory(AceEntry + 1, + AceHeader, + AceHeader->AceSize); + + /* add the ACE to the list */ + PrincipalListItem->ACEs = AceEntry; + + PrincipalListItem->Next = NULL; + Ret = TRUE; + if (LookupResult == ERROR_NONE_MAPPED) { if (!ConvertSidToStringSid(Sid, - &AceListItem->DisplayString)) + &PrincipalListItem->DisplayString)) { - AceListItem->DisplayString = NULL; + PrincipalListItem->DisplayString = NULL; } } else @@ -188,7 +296,7 @@ AddPrincipalToList(IN PSECURITY_PAGE sp, LSA_HANDLE LsaHandle; NTSTATUS Status; - AceListItem->DisplayString = NULL; + PrincipalListItem->DisplayString = NULL; /* read the domain of the SID */ if (OpenLSAPolicyHandle(sp->ServerName, @@ -220,7 +328,7 @@ AddPrincipalToList(IN PSECURITY_PAGE sp, DomainName = NULL; } - AceListItem->SidNameUse = Names->Use; + PrincipalListItem->SidNameUse = Names->Use; switch (Names->Use) { @@ -236,7 +344,7 @@ AddPrincipalToList(IN PSECURITY_PAGE sp, DomainName = &PolicyAccountDomainInfo->DomainName; /* make the user believe this is a group */ - AceListItem->SidNameUse = SidTypeGroup; + PrincipalListItem->SidNameUse = SidTypeGroup; } } /* fall through */ @@ -247,19 +355,19 @@ AddPrincipalToList(IN PSECURITY_PAGE sp, { SIZE_T Size = (AccountNameSize + DomainName->Length + Names->Name.Length + 6) * sizeof(WCHAR); - AceListItem->DisplayString = (LPWSTR)LocalAlloc(LMEM_FIXED, + PrincipalListItem->DisplayString = (LPWSTR)LocalAlloc(LMEM_FIXED, Size); - if (AceListItem->DisplayString != NULL) + if (PrincipalListItem->DisplayString != NULL) { WCHAR *s; /* NOTE: LSA_UNICODE_STRINGs are not always NULL-terminated! */ - wcscpy(AceListItem->DisplayString, - AceListItem->AccountName); - wcscat(AceListItem->DisplayString, + wcscpy(PrincipalListItem->DisplayString, + PrincipalListItem->AccountName); + wcscat(PrincipalListItem->DisplayString, L" ("); - s = AceListItem->DisplayString + wcslen(AceListItem->DisplayString); + s = PrincipalListItem->DisplayString + wcslen(PrincipalListItem->DisplayString); CopyMemory(s, DomainName->Buffer, DomainName->Length); @@ -272,12 +380,17 @@ AddPrincipalToList(IN PSECURITY_PAGE sp, *(s++) = L')'; *s = L'\0'; } + else + { + Ret = FALSE; + break; + } /* mark the ace as a user unless it's a BUILTIN account */ if (PolicyAccountDomainInfo == NULL) { - AceListItem->SidNameUse = SidTypeUser; + PrincipalListItem->SidNameUse = SidTypeUser; } } break; @@ -286,7 +399,7 @@ AddPrincipalToList(IN PSECURITY_PAGE sp, case SidTypeWellKnownGroup: { /* make the user believe this is a group */ - AceListItem->SidNameUse = SidTypeGroup; + PrincipalListItem->SidNameUse = SidTypeGroup; break; } @@ -309,12 +422,38 @@ AddPrincipalToList(IN PSECURITY_PAGE sp, } } - /* append item to the cached ACL */ - *NextAcePtr = AceListItem; + if (Ret) + { + /* append item to the principals list */ + *PrincipalLink = PrincipalListItem; + } } } - return TRUE; + if (!Ret) + { +Cleanup: + if (PrincipalListItem != NULL) + { + if (PrincipalListItem->DisplayString != NULL) + { + LocalFree((HLOCAL)PrincipalListItem->DisplayString); + } + + HeapFree(GetProcessHeap(), + 0, + PrincipalListItem); + } + + if (AceEntry != NULL) + { + HeapFree(GetProcessHeap(), + 0, + AceEntry); + } + } + + return Ret; } static VOID @@ -342,21 +481,24 @@ ReloadPrincipalsList(IN PSECURITY_PAGE sp) DaclPresent && Dacl != NULL) { PSID Sid; - PVOID Ace; + PACE_HEADER AceHeader; ULONG AceIndex; for (AceIndex = 0; AceIndex < Dacl->AceCount; AceIndex++) { - GetAce(Dacl, - AceIndex, - &Ace); + if (GetAce(Dacl, + AceIndex, + (LPVOID*)&AceHeader) && + AceHeader != NULL) + { + Sid = AceHeaderToSID(AceHeader); - Sid = (PSID)&((PACCESS_ALLOWED_ACE)Ace)->SidStart; - - AddPrincipalToList(sp, - Sid); + AddPrincipalToList(sp, + Sid, + AceHeader); + } } } LocalFree((HLOCAL)SecurityDescriptor); @@ -534,18 +676,21 @@ LoadPermissionsList(IN PSECURITY_PAGE sp, HRESULT hRet; PSI_ACCESS AccessList; ULONG nAccessList, DefaultAccessIndex; - + WCHAR szSpecialPermissions[255]; + BOOLEAN SpecialPermissionsPresent = FALSE; + ACCESS_MASK SpecialPermissionsMask = 0; + /* clear the permissions list */ - + SendMessage(sp->hAceCheckList, CLM_CLEAR, 0, 0); - + /* query the access rights from the server */ hRet = sp->psi->lpVtbl->GetAccessRights(sp->psi, GuidObjectType, - dwFlags, + dwFlags, /* FIXME */ &AccessList, &nAccessList, &DefaultAccessIndex); @@ -554,13 +699,13 @@ LoadPermissionsList(IN PSECURITY_PAGE sp, LPCWSTR NameStr; PSI_ACCESS CurAccess, LastAccess; WCHAR NameBuffer[MAX_PATH]; - + /* save the default access rights to be used when adding ACEs later */ if (DefaultAccess != NULL) { *DefaultAccess = AccessList[DefaultAccessIndex]; } - + LastAccess = AccessList + nAccessList; for (CurAccess = &AccessList[0]; CurAccess != LastAccess; @@ -590,9 +735,36 @@ LoadPermissionsList(IN PSECURITY_PAGE sp, SendMessage(sp->hAceCheckList, CLM_ADDITEM, - CIS_NONE, + (WPARAM)CurAccess->mask, (LPARAM)NameStr); } + else if (CurAccess->dwFlags & SI_ACCESS_SPECIFIC) + { + SpecialPermissionsPresent = TRUE; + SpecialPermissionsMask |= CurAccess->mask; + } + } + } + + /* add the special permissions check item in case the specific access rights + aren't displayed */ + if (SpecialPermissionsPresent && + LoadString(hDllInstance, + IDS_SPECIAL_PERMISSIONS, + szSpecialPermissions, + sizeof(szSpecialPermissions) / sizeof(szSpecialPermissions[0]))) + { + /* add the special permissions check item */ + sp->SpecialPermCheckIndex = (INT)SendMessage(sp->hAceCheckList, + CLM_ADDITEM, + (WPARAM)SpecialPermissionsMask, + (LPARAM)szSpecialPermissions); + if (sp->SpecialPermCheckIndex != -1) + { + SendMessage(sp->hAceCheckList, + CLM_SETITEMSTATE, + (WPARAM)sp->SpecialPermCheckIndex, + CIS_ALLOWDISABLED | CIS_DENYDISABLED | CIS_NONE); } } } @@ -839,16 +1011,62 @@ EndDeferWnds: hWndDeny); } +static PACE_HEADER +BuildDefaultPrincipalAce(IN PSECURITY_PAGE sp, + IN PSID pSid) +{ + PACCESS_ALLOWED_ACE Ace; + DWORD SidLen; + WORD AceSize; + + SidLen = GetLengthSid(pSid); + AceSize = sizeof(ACCESS_ALLOWED_ACE) + (WORD)SidLen - sizeof(DWORD); + Ace = HeapAlloc(GetProcessHeap(), + 0, + AceSize); + if (Ace != NULL) + { + Ace->Header.AceType = ACCESS_ALLOWED_ACE_TYPE; + Ace->Header.AceFlags = 0; /* FIXME */ + Ace->Header.AceSize = AceSize; + Ace->Mask = sp->DefaultAccess.mask; + + if (CopySid(SidLen, + (PSID)&Ace->SidStart, + pSid)) + { + return &Ace->Header; + } + + HeapFree(GetProcessHeap(), + 0, + Ace); + } + + return NULL; +} + static BOOL AddSelectedPrincipal(IN IDsObjectPicker *pDsObjectPicker, IN HWND hwndParent OPTIONAL, IN PSID pSid, IN PVOID Context OPTIONAL) { + PACE_HEADER AceHeader; PSECURITY_PAGE sp = (PSECURITY_PAGE)Context; - AddPrincipalToList(sp, - pSid); + AceHeader = BuildDefaultPrincipalAce(sp, + pSid); + if (AceHeader != NULL) + { + AddPrincipalToList(sp, + pSid, + AceHeader); + + HeapFree(GetProcessHeap(), + 0, + AceHeader); + } return TRUE; } @@ -1041,23 +1259,9 @@ SecurityPageProc(IN HWND hwndDlg, /* hide controls in case the flags aren't present */ if (sp->ObjectInfo.dwFlags & SI_ADVANCED) { - WCHAR szSpecialPermissions[255]; - /* editing the permissions is least the user can do when the advanced button is showed */ sp->ObjectInfo.dwFlags |= SI_EDIT_PERMS; - - if (LoadString(hDllInstance, - IDS_SPECIAL_PERMISSIONS, - szSpecialPermissions, - sizeof(szSpecialPermissions) / sizeof(szSpecialPermissions[0]))) - { - /* add the special permissions check item */ - sp->SpecialPermCheckIndex = (INT)SendMessage(sp->hAceCheckList, - CLM_ADDITEM, - CIS_ALLOWDISABLED | CIS_DENYDISABLED | CIS_NONE, - (LPARAM)szSpecialPermissions); - } } else { @@ -1254,7 +1458,8 @@ EditSecurity(IN HWND hwndOwner, return Ret; } -BOOL STDCALL +BOOL +WINAPI DllMain(IN HINSTANCE hinstDLL, IN DWORD dwReason, IN LPVOID lpvReserved) diff --git a/reactos/lib/aclui/checklist.c b/reactos/lib/aclui/checklist.c index 58e652e37d8..5c51067f1cd 100644 --- a/reactos/lib/aclui/checklist.c +++ b/reactos/lib/aclui/checklist.c @@ -41,6 +41,7 @@ typedef struct _CHECKITEM { struct _CHECKITEM *Next; + ACCESS_MASK AccessMask; DWORD State; WCHAR Name[1]; } CHECKITEM, *PCHECKITEM; @@ -145,6 +146,29 @@ FindCheckItemByIndex(IN PCHECKLISTWND infoPtr, return Found; } +static UINT +FindCheckItemIndexByAccessMask(IN PCHECKLISTWND infoPtr, + IN ACCESS_MASK AccessMask) +{ + PCHECKITEM Item; + UINT Index = 0, Found = -1; + + for (Item = infoPtr->CheckItemListHead; + Item != NULL; + Item = Item->Next) + { + if (Item->AccessMask == AccessMask) + { + Found = Index; + break; + } + + Index++; + } + + return Found; +} + static INT CheckItemToIndex(IN PCHECKLISTWND infoPtr, IN PCHECKITEM Item) @@ -469,6 +493,7 @@ static PCHECKITEM AddCheckItem(IN PCHECKLISTWND infoPtr, IN LPWSTR Name, IN DWORD State, + IN ACCESS_MASK AccessMask, OUT INT *Index) { PCHECKITEM CurItem; @@ -488,6 +513,7 @@ AddCheckItem(IN PCHECKLISTWND infoPtr, } Item->Next = NULL; + Item->AccessMask = AccessMask; Item->State = State & CIS_MASK; wcscpy(Item->Name, Name); @@ -1692,7 +1718,8 @@ CheckListWndProc(IN HWND hwnd, INT Index = -1; PCHECKITEM Item = AddCheckItem(infoPtr, (LPWSTR)lParam, - (DWORD)wParam, + CIS_NONE, + (ACCESS_MASK)wParam, &Index); if (Item != NULL) { @@ -1824,6 +1851,13 @@ CheckListWndProc(IN HWND hwnd, break; } + case CLM_FINDITEMBYACCESSMASK: + { + Ret = (LRESULT)FindCheckItemIndexByAccessMask(infoPtr, + (ACCESS_MASK)wParam); + break; + } + case WM_SETFONT: { Ret = (LRESULT)RetChangeControlFont(infoPtr, @@ -2129,7 +2163,7 @@ CheckListWndProc(IN HWND hwnd, MakeCheckItemVisible(infoPtr, infoPtr->FocusedCheckItem); - OtherBox = ((infoPtr->FocusedCheckItemBox == CLB_ALLOW) ? CLB_DENY : CLB_ALLOW); + OtherBox = ((infoPtr->FocusedCheckItemBox == CLB_ALLOW) ? CLB_DENY : CLB_ALLOW); OtherStateMask = ((OtherBox == CLB_ALLOW) ? (CIS_ALLOW | CIS_ALLOWDISABLED) : (CIS_DENY | CIS_DENYDISABLED)); diff --git a/reactos/lib/aclui/precomp.h b/reactos/lib/aclui/precomp.h index 303de04f543..1581d31421e 100644 --- a/reactos/lib/aclui/precomp.h +++ b/reactos/lib/aclui/precomp.h @@ -27,9 +27,15 @@ ULONG DbgPrint(PCH Format,...); extern HINSTANCE hDllInstance; +typedef struct _ACE_ENTRY +{ + struct _ACE_ENTRY *Next; +} ACE_ENTRY, *PACE_ENTRY; + typedef struct _PRINCIPAL_LISTITEM { struct _PRINCIPAL_LISTITEM *Next; + PACE_ENTRY ACEs; SID_NAME_USE SidNameUse; WCHAR *DisplayString; WCHAR *AccountName; @@ -130,6 +136,7 @@ InvokeObjectPickerDialog(IN IDsObjectPicker *pDsObjectPicker, #define CLM_ENABLEQUICKSEARCH (WM_USER + 9) #define CLM_SETQUICKSEARCH_TIMEOUT_RESET (WM_USER + 10) #define CLM_SETQUICKSEARCH_TIMEOUT_SETFOCUS (WM_USER + 11) +#define CLM_FINDITEMBYACCESSMASK (WM_USER + 12) #define CLN_CHANGINGITEMCHECKBOX (101) @@ -148,4 +155,12 @@ RegisterCheckListControl(HINSTANCE hInstance); VOID UnregisterCheckListControl(VOID); +/* DLLMAIN ********************************************************************/ + +BOOL +WINAPI +DllMain(IN HINSTANCE hinstDLL, + IN DWORD dwReason, + IN LPVOID lpvReserved); + /* EOF */