diff --git a/reactos/lib/aclui/aclui.c b/reactos/lib/aclui/aclui.c index 4d42f0d6023..ed9f2cfeb1c 100644 --- a/reactos/lib/aclui/aclui.c +++ b/reactos/lib/aclui/aclui.c @@ -30,11 +30,6 @@ HINSTANCE hDllInstance; -static PCWSTR ObjectPickerAttributes[] = -{ - L"ObjectSid", -}; - static VOID DestroySecurityPage(IN PSECURITY_PAGE sp) { @@ -95,6 +90,225 @@ FindSidInPrincipalsList(IN PPRINCIPAL_LISTITEM PrincipalsListHead, return NULL; } +static BOOL +AddPrincipalToList(IN PSECURITY_PAGE sp, + IN PSID Sid) +{ + if (!FindSidInPrincipalsList(sp->PrincipalsListHead, + Sid)) + { + DWORD SidLength, AccountNameSize, DomainNameSize; + SID_NAME_USE SidNameUse; + DWORD LookupResult; + PPRINCIPAL_LISTITEM AceListItem, *NextAcePtr; + + NextAcePtr = &sp->PrincipalsListHead; + for (AceListItem = sp->PrincipalsListHead; AceListItem != NULL; AceListItem = AceListItem->Next) + { + NextAcePtr = &AceListItem->Next; + } + + SidLength = GetLengthSid(Sid); + + AccountNameSize = 0; + DomainNameSize = 0; + + /* calculate the size of the buffer we need to calculate */ + LookupAccountSid(sp->ServerName, + Sid, + NULL, + &AccountNameSize, + NULL, + &DomainNameSize, + &SidNameUse); + + /* allocate the ace */ + AceListItem = HeapAlloc(GetProcessHeap(), + 0, + sizeof(PRINCIPAL_LISTITEM) + + SidLength + + ((AccountNameSize + DomainNameSize) * sizeof(WCHAR))); + if (AceListItem != NULL) + { + AceListItem->AccountName = (LPWSTR)((ULONG_PTR)(AceListItem + 1) + SidLength); + AceListItem->DomainName = AceListItem->AccountName + AccountNameSize; + + CopySid(SidLength, + (PSID)(AceListItem + 1), + Sid); + + LookupResult = ERROR_SUCCESS; + if (!LookupAccountSid(sp->ServerName, + Sid, + AceListItem->AccountName, + &AccountNameSize, + AceListItem->DomainName, + &DomainNameSize, + &SidNameUse)) + { + LookupResult = GetLastError(); + if (LookupResult != ERROR_NONE_MAPPED) + { + HeapFree(GetProcessHeap(), + 0, + AceListItem); + return FALSE; + } + } + + if (AccountNameSize == 0) + { + AceListItem->AccountName = NULL; + } + if (DomainNameSize == 0) + { + AceListItem->DomainName = NULL; + } + + AceListItem->Next = NULL; + if (LookupResult == ERROR_NONE_MAPPED) + { + if (!ConvertSidToStringSid(Sid, + &AceListItem->DisplayString)) + { + AceListItem->DisplayString = NULL; + } + } + else + { + LSA_HANDLE LsaHandle; + NTSTATUS Status; + + AceListItem->DisplayString = NULL; + + /* read the domain of the SID */ + if (OpenLSAPolicyHandle(sp->ServerName, + POLICY_LOOKUP_NAMES | POLICY_VIEW_LOCAL_INFORMATION, + &LsaHandle)) + { + PLSA_REFERENCED_DOMAIN_LIST ReferencedDomain; + PLSA_TRANSLATED_NAME Names; + PLSA_TRUST_INFORMATION Domain; + PLSA_UNICODE_STRING DomainName; + PPOLICY_ACCOUNT_DOMAIN_INFO PolicyAccountDomainInfo = NULL; + + Status = LsaLookupSids(LsaHandle, + 1, + &Sid, + &ReferencedDomain, + &Names); + if (NT_SUCCESS(Status)) + { + if (ReferencedDomain != NULL && + Names->DomainIndex >= 0) + { + Domain = &ReferencedDomain->Domains[Names->DomainIndex]; + DomainName = &Domain->Name; + } + else + { + Domain = NULL; + DomainName = NULL; + } + + AceListItem->SidNameUse = Names->Use; + + switch (Names->Use) + { + case SidTypeAlias: + if (Domain != NULL) + { + /* query the domain name for BUILTIN accounts */ + Status = LsaQueryInformationPolicy(LsaHandle, + PolicyAccountDomainInformation, + (PVOID*)&PolicyAccountDomainInfo); + if (NT_SUCCESS(Status)) + { + DomainName = &PolicyAccountDomainInfo->DomainName; + + /* make the user believe this is a group */ + AceListItem->SidNameUse = SidTypeGroup; + } + } + /* fall through */ + + case SidTypeUser: + { + if (Domain != NULL) + { + AceListItem->DisplayString = (LPWSTR)LocalAlloc(LMEM_FIXED, + (AccountNameSize * sizeof(WCHAR)) + + (DomainName->Length + sizeof(WCHAR)) + + (Names->Name.Length + sizeof(WCHAR)) + + (4 * sizeof(WCHAR))); + if (AceListItem->DisplayString != NULL) + { + WCHAR *s; + + /* NOTE: LSA_UNICODE_STRINGs are not always NULL-terminated! */ + + wcscpy(AceListItem->DisplayString, + AceListItem->AccountName); + wcscat(AceListItem->DisplayString, + L" ("); + s = AceListItem->DisplayString + wcslen(AceListItem->DisplayString); + CopyMemory(s, + DomainName->Buffer, + DomainName->Length); + s += DomainName->Length / sizeof(WCHAR); + *(s++) = L'\\'; + CopyMemory(s, + Names->Name.Buffer, + Names->Name.Length); + s += Names->Name.Length / sizeof(WCHAR); + *(s++) = L')'; + *s = L'\0'; + } + + /* mark the ace as a user unless it's a + BUILTIN account */ + if (PolicyAccountDomainInfo == NULL) + { + AceListItem->SidNameUse = SidTypeUser; + } + } + break; + } + + case SidTypeWellKnownGroup: + { + /* make the user believe this is a group */ + AceListItem->SidNameUse = SidTypeGroup; + break; + } + + default: + { + DPRINT("Unhandled SID type: 0x%x\n", Names->Use); + break; + } + } + + if (PolicyAccountDomainInfo != NULL) + { + LsaFreeMemory(PolicyAccountDomainInfo); + } + + LsaFreeMemory(ReferencedDomain); + LsaFreeMemory(Names); + } + LsaClose(LsaHandle); + } + } + + /* append item to the cached ACL */ + *NextAcePtr = AceListItem; + } + } + + return TRUE; +} + static VOID ReloadPrincipalsList(IN PSECURITY_PAGE sp) { @@ -118,15 +332,9 @@ ReloadPrincipalsList(IN PSECURITY_PAGE sp) &Dacl, &DaclDefaulted)) { - PPRINCIPAL_LISTITEM AceListItem, *NextAcePtr; PSID Sid; PVOID Ace; ULONG AceIndex; - DWORD AccountNameSize, DomainNameSize, SidLength; - SID_NAME_USE SidNameUse; - DWORD LookupResult; - - NextAcePtr = &sp->PrincipalsListHead; for (AceIndex = 0; AceIndex < Dacl->AceCount; @@ -137,208 +345,9 @@ ReloadPrincipalsList(IN PSECURITY_PAGE sp) &Ace); Sid = (PSID)&((PACCESS_ALLOWED_ACE)Ace)->SidStart; - - if (!FindSidInPrincipalsList(sp->PrincipalsListHead, - Sid)) - { - SidLength = GetLengthSid(Sid); - - AccountNameSize = 0; - DomainNameSize = 0; - - /* calculate the size of the buffer we need to calculate */ - LookupAccountSid(sp->ServerName, - Sid, - NULL, - &AccountNameSize, - NULL, - &DomainNameSize, - &SidNameUse); - - /* allocate the ace */ - AceListItem = HeapAlloc(GetProcessHeap(), - 0, - sizeof(PRINCIPAL_LISTITEM) + - SidLength + - ((AccountNameSize + DomainNameSize) * sizeof(WCHAR))); - if (AceListItem != NULL) - { - AceListItem->AccountName = (LPWSTR)((ULONG_PTR)(AceListItem + 1) + SidLength); - AceListItem->DomainName = AceListItem->AccountName + AccountNameSize; - - CopySid(SidLength, - (PSID)(AceListItem + 1), - Sid); - - LookupResult = ERROR_SUCCESS; - if (!LookupAccountSid(sp->ServerName, - Sid, - AceListItem->AccountName, - &AccountNameSize, - AceListItem->DomainName, - &DomainNameSize, - &SidNameUse)) - { - LookupResult = GetLastError(); - if (LookupResult != ERROR_NONE_MAPPED) - { - HeapFree(GetProcessHeap(), - 0, - AceListItem); - continue; - } - } - - if (AccountNameSize == 0) - { - AceListItem->AccountName = NULL; - } - if (DomainNameSize == 0) - { - AceListItem->DomainName = NULL; - } - - AceListItem->Next = NULL; - if (LookupResult == ERROR_NONE_MAPPED) - { - if (!ConvertSidToStringSid(Sid, - &AceListItem->DisplayString)) - { - AceListItem->DisplayString = NULL; - } - } - else - { - LSA_HANDLE LsaHandle; - NTSTATUS Status; - - AceListItem->DisplayString = NULL; - - /* read the domain of the SID */ - if (OpenLSAPolicyHandle(sp->ServerName, - POLICY_LOOKUP_NAMES | POLICY_VIEW_LOCAL_INFORMATION, - &LsaHandle)) - { - PLSA_REFERENCED_DOMAIN_LIST ReferencedDomain; - PLSA_TRANSLATED_NAME Names; - PLSA_TRUST_INFORMATION Domain; - PLSA_UNICODE_STRING DomainName; - PPOLICY_ACCOUNT_DOMAIN_INFO PolicyAccountDomainInfo = NULL; - - Status = LsaLookupSids(LsaHandle, - 1, - &Sid, - &ReferencedDomain, - &Names); - if (NT_SUCCESS(Status)) - { - if (ReferencedDomain != NULL && - Names->DomainIndex >= 0) - { - Domain = &ReferencedDomain->Domains[Names->DomainIndex]; - DomainName = &Domain->Name; - } - else - { - Domain = NULL; - DomainName = NULL; - } - - AceListItem->SidNameUse = Names->Use; - - switch (Names->Use) - { - case SidTypeAlias: - if (Domain != NULL) - { - /* query the domain name for BUILTIN accounts */ - Status = LsaQueryInformationPolicy(LsaHandle, - PolicyAccountDomainInformation, - (PVOID*)&PolicyAccountDomainInfo); - if (NT_SUCCESS(Status)) - { - DomainName = &PolicyAccountDomainInfo->DomainName; - - /* make the user believe this is a group */ - AceListItem->SidNameUse = SidTypeGroup; - } - } - /* fall through */ - - case SidTypeUser: - { - if (Domain != NULL) - { - AceListItem->DisplayString = (LPWSTR)LocalAlloc(LMEM_FIXED, - (AccountNameSize * sizeof(WCHAR)) + - (DomainName->Length + sizeof(WCHAR)) + - (Names->Name.Length + sizeof(WCHAR)) + - (4 * sizeof(WCHAR))); - if (AceListItem->DisplayString != NULL) - { - WCHAR *s; - - /* NOTE: LSA_UNICODE_STRINGs are not always NULL-terminated! */ - - wcscpy(AceListItem->DisplayString, - AceListItem->AccountName); - wcscat(AceListItem->DisplayString, - L" ("); - s = AceListItem->DisplayString + wcslen(AceListItem->DisplayString); - CopyMemory(s, - DomainName->Buffer, - DomainName->Length); - s += DomainName->Length / sizeof(WCHAR); - *(s++) = L'\\'; - CopyMemory(s, - Names->Name.Buffer, - Names->Name.Length); - s += Names->Name.Length / sizeof(WCHAR); - *(s++) = L')'; - *s = L'\0'; - } - - /* mark the ace as a user unless it's a - BUILTIN account */ - if (PolicyAccountDomainInfo == NULL) - { - AceListItem->SidNameUse = SidTypeUser; - } - } - break; - } - - case SidTypeWellKnownGroup: - { - /* make the user believe this is a group */ - AceListItem->SidNameUse = SidTypeGroup; - break; - } - - default: - { - DPRINT("Unhandled SID type: 0x%x\n", Names->Use); - break; - } - } - - if (PolicyAccountDomainInfo != NULL) - { - LsaFreeMemory(PolicyAccountDomainInfo); - } - - LsaFreeMemory(ReferencedDomain); - LsaFreeMemory(Names); - } - LsaClose(LsaHandle); - } - } - - /* append item to the cached ACL */ - *NextAcePtr = AceListItem; - NextAcePtr = &AceListItem->Next; - } - } + + AddPrincipalToList(sp, + Sid); } } LocalFree((HLOCAL)SecurityDescriptor); @@ -390,8 +399,6 @@ FillPrincipalsList(IN PSECURITY_PAGE sp) ListView_DeleteAllItems(sp->hWndPrincipalsList); - ReloadPrincipalsList(sp); - for (CurItem = sp->PrincipalsListHead; CurItem != NULL; CurItem = CurItem->Next) @@ -817,6 +824,20 @@ ResizeControls(IN PSECURITY_PAGE sp, hWndDeny); } +static BOOL +AddSelectedPrincipal(IN IDsObjectPicker *pDsObjectPicker, + IN HWND hwndParent OPTIONAL, + IN PSID pSid, + IN PVOID Context OPTIONAL) +{ + PSECURITY_PAGE sp = (PSECURITY_PAGE)Context; + + AddPrincipalToList(sp, + pSid); + + return TRUE; +} + static INT_PTR CALLBACK SecurityPageProc(IN HWND hwndDlg, IN UINT uMsg, @@ -881,28 +902,33 @@ SecurityPageProc(IN HWND hwndDlg, case IDC_ADD_PRINCIPAL: { HRESULT hRet; - IDsObjectPicker *pDsObjectPicker = NULL; - IDataObject *Selections = NULL; sp = (PSECURITY_PAGE)GetWindowLongPtr(hwndDlg, DWL_USER); hRet = InitializeObjectPicker(sp->ServerName, &sp->ObjectInfo, - ObjectPickerAttributes, - &pDsObjectPicker); + &sp->pDsObjectPicker); if (SUCCEEDED(hRet)) { - hRet = pDsObjectPicker->lpVtbl->InvokeDialog(pDsObjectPicker, - hwndDlg, - &Selections); + hRet = InvokeObjectPickerDialog(sp->pDsObjectPicker, + hwndDlg, + AddSelectedPrincipal, + sp); if (FAILED(hRet)) { - MessageBox(hwndDlg, L"InvokeDialog failed!\n", NULL, 0); + MessageBox(hwndDlg, L"InvokeObjectPickerDialog failed!\n", NULL, 0); } /* delete the instance */ - pDsObjectPicker->lpVtbl->Release(pDsObjectPicker); + FreeObjectPicker(sp->pDsObjectPicker); + + /* reload the principal list */ + FillPrincipalsList(sp); + } + else + { + MessageBox(hwndDlg, L"InitializeObjectPicker failed!\n", NULL, 0); } break; } @@ -972,6 +998,8 @@ SecurityPageProc(IN HWND hwndDlg, lvc.fmt = LVCFMT_LEFT; lvc.cx = rcLvClient.right; ListView_InsertColumn(sp->hWndPrincipalsList, 0, &lvc); + + ReloadPrincipalsList(sp); FillPrincipalsList(sp); diff --git a/reactos/lib/aclui/aclui.xml b/reactos/lib/aclui/aclui.xml index 8d260222f73..95412b773fe 100644 --- a/reactos/lib/aclui/aclui.xml +++ b/reactos/lib/aclui/aclui.xml @@ -14,6 +14,7 @@ gdi32 comctl32 ole32 + oleaut32 uxtheme aclui.c checklist.c diff --git a/reactos/lib/aclui/misc.c b/reactos/lib/aclui/misc.c index cebbfe4dbb9..2a2fa551dc7 100644 --- a/reactos/lib/aclui/misc.c +++ b/reactos/lib/aclui/misc.c @@ -32,6 +32,11 @@ #include +static PCWSTR ObjectPickerAttributes[] = +{ + L"ObjectSid", +}; + static INT LengthOfStrResource(IN HINSTANCE hInst, IN UINT uID) @@ -207,7 +212,6 @@ ListViewSelectItem(IN HWND hwnd, HRESULT InitializeObjectPicker(IN PCWSTR ServerName, IN PSI_OBJECT_INFO ObjectInfo, - IN PCWSTR Attributes[], OUT IDsObjectPicker **pDsObjectPicker) { HRESULT hRet; @@ -250,8 +254,8 @@ InitializeObjectPicker(IN PCWSTR ServerName, InitInfo.cDsScopeInfos = sizeof(Scopes) / sizeof(Scopes[0]); InitInfo.aDsScopeInfos = Scopes; InitInfo.flOptions = DSOP_FLAG_MULTISELECT | DSOP_SCOPE_TYPE_TARGET_COMPUTER; - InitInfo.cAttributesToFetch = sizeof(Attributes) / sizeof(Attributes[0]); - InitInfo.apwzAttributeNames = Attributes; + InitInfo.cAttributesToFetch = sizeof(ObjectPickerAttributes) / sizeof(ObjectPickerAttributes[0]); + InitInfo.apwzAttributeNames = ObjectPickerAttributes; for (i = 0; i < InitInfo.cDsScopeInfos; i++) { @@ -278,3 +282,82 @@ InitializeObjectPicker(IN PCWSTR ServerName, return hRet; } +HRESULT +InvokeObjectPickerDialog(IN IDsObjectPicker *pDsObjectPicker, + IN HWND hwndParent OPTIONAL, + IN POBJPICK_SELECTED_SID SelectedSidCallback, + IN PVOID Context OPTIONAL) +{ + IDataObject *pdo = NULL; + HRESULT hRet; + + hRet = pDsObjectPicker->lpVtbl->InvokeDialog(pDsObjectPicker, + hwndParent, + &pdo); + if (hRet == S_OK) + { + STGMEDIUM stm; + FORMATETC fe; + + fe.cfFormat = RegisterClipboardFormat(CFSTR_DSOP_DS_SELECTION_LIST); + fe.ptd = NULL; + fe.dwAspect = DVASPECT_CONTENT; + fe.lindex = -1; + fe.tymed = TYMED_HGLOBAL; + + hRet = pdo->lpVtbl->GetData(pdo, + &fe, + &stm); + if (SUCCEEDED(hRet)) + { + PDS_SELECTION_LIST SelectionList = (PDS_SELECTION_LIST)GlobalLock(stm.hGlobal); + if (SelectionList != NULL) + { + LPVARIANT vSid; + PSID pSid; + UINT i; + BOOL contLoop = TRUE; + + for (i = 0; i < SelectionList->cItems && contLoop; i++) + { + vSid = SelectionList->aDsSelection[i].pvarFetchedAttributes; + + if (vSid != NULL && V_VT(vSid) == (VT_ARRAY | VT_UI1)) + { + hRet = SafeArrayAccessData(V_ARRAY(vSid), + (void HUGEP**)&pSid); + if (FAILED(hRet)) + { + break; + } + + if (pSid != NULL) + { + contLoop = SelectedSidCallback(pDsObjectPicker, + hwndParent, + pSid, + Context); + } + + SafeArrayUnaccessData(V_ARRAY(vSid)); + } + } + + GlobalUnlock(stm.hGlobal); + } + + ReleaseStgMedium(&stm); + } + + pdo->lpVtbl->Release(pdo); + } + + return hRet; +} + +VOID +FreeObjectPicker(IN IDsObjectPicker *pDsObjectPicker) +{ + pDsObjectPicker->lpVtbl->Release(pDsObjectPicker); +} + diff --git a/reactos/lib/aclui/precomp.h b/reactos/lib/aclui/precomp.h index 0001269aff9..f6a8c182af4 100644 --- a/reactos/lib/aclui/precomp.h +++ b/reactos/lib/aclui/precomp.h @@ -1,5 +1,6 @@ #include #include +#include #include #include #include @@ -57,6 +58,7 @@ typedef struct _SECURITY_PAGE LPSECURITYINFO psi; SI_OBJECT_INFO ObjectInfo; + IDsObjectPicker *pDsObjectPicker; SI_ACCESS DefaultAccess; @@ -86,9 +88,22 @@ ListViewSelectItem(IN HWND hwnd, HRESULT InitializeObjectPicker(IN PCWSTR ServerName, IN PSI_OBJECT_INFO ObjectInfo, - IN PCWSTR Attributes[], OUT IDsObjectPicker **pDsObjectPicker); +VOID +FreeObjectPicker(IN IDsObjectPicker *pDsObjectPicker); + +typedef BOOL (*POBJPICK_SELECTED_SID)(IN IDsObjectPicker *pDsObjectPicker, + IN HWND hwndParent OPTIONAL, + IN PSID pSid, + IN PVOID Context OPTIONAL); + +HRESULT +InvokeObjectPickerDialog(IN IDsObjectPicker *pDsObjectPicker, + IN HWND hwndParent OPTIONAL, + IN POBJPICK_SELECTED_SID SelectedSidCallback, + IN PVOID Context OPTIONAL); + /* CHECKLIST CONTROL **********************************************************/ #define CIS_DENYDISABLED (0x8)