add all ACEs to their principals

svn path=/trunk/; revision=18972
This commit is contained in:
Thomas Bluemel
2005-11-03 11:28:56 +00:00
parent 34ac8ceb9f
commit f46f194ae4
3 changed files with 335 additions and 81 deletions
+284 -79
View File
@@ -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)
+36 -2
View File
@@ -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));
+15
View File
@@ -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 */