add selected principals to the list (doesn't modify the ACLs yet!)

svn path=/trunk/; revision=17982
This commit is contained in:
Thomas Bluemel 2005-09-22 14:30:29 +00:00
parent 4a4df71398
commit ceb2e22d5f
4 changed files with 355 additions and 228 deletions

View file

@ -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);

View file

@ -14,6 +14,7 @@
<library>gdi32</library>
<library>comctl32</library>
<library>ole32</library>
<library>oleaut32</library>
<library>uxtheme</library>
<file>aclui.c</file>
<file>checklist.c</file>

View file

@ -32,6 +32,11 @@
#include <precomp.h>
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);
}

View file

@ -1,5 +1,6 @@
#include <windows.h>
#include <commctrl.h>
#include <oleauto.h>
#include <objsel.h>
#include <prsht.h>
#include <aclui.h>
@ -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)