You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
305 lines
7.8 KiB
305 lines
7.8 KiB
// Copyright (c) 1997-1999 Microsoft Corporation
|
|
#include "precomp.h"
|
|
#include "chklist.h"
|
|
#include "Principal.h"
|
|
#include "CHString1.h"
|
|
|
|
//-------------------------------------------------------------
|
|
CPrincipal::CPrincipal(CWbemClassObject &userInst, SecurityStyle secStyle) :
|
|
m_secStyle(secStyle),
|
|
m_perms(0),
|
|
m_inheritedPerms(0),
|
|
m_editable(true)
|
|
{
|
|
//------------------------------------------------
|
|
// figure out what security strategy we're dealing with and load it
|
|
// into my "generic" definition.
|
|
|
|
memset(m_name, 0, 100 * sizeof(TCHAR));
|
|
_tcsncpy(m_name, (LPCTSTR)userInst.GetString("Name"), 100);
|
|
|
|
memset(m_domain, 0, 100 * sizeof(TCHAR));
|
|
_tcsncpy(m_domain, (LPCTSTR)userInst.GetString("Authority"), 100);
|
|
|
|
// if pre-M3 security...
|
|
if(m_secStyle == RootSecStyle)
|
|
{
|
|
// this is the only instance for this guy so save it.
|
|
|
|
// convert the convoluted "bits" into my real "generic" bits.
|
|
m_perms |= (userInst.GetBool("EditSecurity") ? ACL_WRITE_DAC : 0);
|
|
m_perms |= (userInst.GetBool("Enabled") ? ACL_ENABLE : 0);
|
|
m_perms |= (userInst.GetBool("ExecuteMethods") ? ACL_METHOD_EXECUTE : 0);
|
|
|
|
// NOTE: each "level" implies all the levels below so I INTENTIONALLY
|
|
// left out the 'breaks' so the bits would fall through and accumulate.
|
|
switch(userInst.GetLong("Permissions"))
|
|
{
|
|
case 2: // class write
|
|
m_perms |= ACL_CLASS_WRITE;
|
|
|
|
case 1: // instance write
|
|
m_perms |= ACL_INSTANCE_WRITE;
|
|
}
|
|
|
|
// remember for dirty bit processing later.
|
|
m_origPerms = m_perms;
|
|
}
|
|
else //new M3+ security
|
|
{
|
|
// ACL bits perfectly match m_perms.
|
|
// NOTE: this securityStyle can have multiple aces per principal.
|
|
AddAce(userInst);
|
|
}
|
|
}
|
|
|
|
//------------------------------------------
|
|
// move m_perms into the checkboxes
|
|
void CPrincipal::LoadChecklist(HWND list, int OSType)
|
|
{
|
|
INT_PTR itemCount = CBL_GetItemCount(list);
|
|
CPermission *permItem = 0;
|
|
UINT state;
|
|
|
|
::EnableWindow(list, m_editable);
|
|
|
|
// for each permission item...
|
|
for(INT_PTR x = 0; x < itemCount; x++)
|
|
{
|
|
// which permission item is this
|
|
permItem = (CPermission *)CBL_GetItemData(list, x);
|
|
|
|
state = BST_UNCHECKED; // and enabled (local)
|
|
|
|
// if its a local perm...
|
|
if(IS_BITSET(m_perms, permItem->m_permBit))
|
|
{
|
|
// local perms override inherited perms.
|
|
state = BST_CHECKED;
|
|
}
|
|
else if(IS_BITSET(m_inheritedPerms, permItem->m_permBit))
|
|
{
|
|
// you got it from your parent.
|
|
state = CLST_CHECKDISABLED;
|
|
}
|
|
// set it.
|
|
CBL_SetState(list, x, ALLOW_COL, state);
|
|
} //endfor
|
|
}
|
|
|
|
//------------------------------------------
|
|
// move the checkboxes into m_perms.
|
|
void CPrincipal::SaveChecklist(HWND list, int OSType)
|
|
{
|
|
INT_PTR itemCount = CBL_GetItemCount(list);
|
|
CPermission *permItem = 0;
|
|
LPARAM state = 0, state1 = 0;
|
|
|
|
// clear this principal's perm bits.
|
|
m_perms = 0;
|
|
|
|
// for each perm...
|
|
for(INT_PTR x = 0; x < itemCount; x++)
|
|
{
|
|
// get permission item.
|
|
permItem = (CPermission *)CBL_GetItemData(list, x);
|
|
|
|
// what's the check state?
|
|
state = CBL_GetState(list, x, ALLOW_COL);
|
|
|
|
// if its enabled (local) & checked, set the matching bit.
|
|
// NOTE: This "explicit compare will eliminate CLST_DISABLEDed states which
|
|
// shouldn't be saved off.
|
|
if((state == BST_CHECKED) ||
|
|
((state == CLST_CHECKDISABLED) && (OSType != OSTYPE_WINNT)))
|
|
{
|
|
m_perms |= permItem->m_permBit;
|
|
}
|
|
} //endfor
|
|
}
|
|
|
|
//------------------------------------------
|
|
// WARNING: this logic assumes it will only be called when the principal is
|
|
// being read in. If you want to add aces interactively, its a whole different
|
|
// game.
|
|
void CPrincipal::AddAce(CWbemClassObject &princ)
|
|
{
|
|
DWORD flags = princ.GetLong("Flags");
|
|
|
|
// if inherited...
|
|
if(IS_BITSET(flags, INHERITED_ACE))
|
|
{
|
|
// simply accumulate bits.
|
|
m_inheritedPerms |= princ.GetLong("Mask");
|
|
m_editable = false;
|
|
}
|
|
else if(flags == CONTAINER_INHERIT_ACE)
|
|
{
|
|
m_perms |= princ.GetLong("Mask");
|
|
|
|
// this is the first local ace, we can edit it so save the source instance.
|
|
// NOTE: Any additional "local" aces that exactly match CONTAINER_INHERIT_ACE
|
|
// will be merged in but the the ClassObject will be tossed.
|
|
//if(!(bool)m_userInst)
|
|
//{
|
|
// m_userInst = princ;
|
|
// }
|
|
|
|
// remember for dirty bit processing later.
|
|
m_origPerms = m_perms;
|
|
}
|
|
else
|
|
{
|
|
// this will disable the checklist control for this principal.
|
|
m_editable = false;
|
|
}
|
|
}
|
|
|
|
//------------------------------------------
|
|
HRESULT CPrincipal::DeleteSelf(CWbemServices &service)
|
|
{
|
|
HRESULT hr = S_OK;
|
|
|
|
if(m_secStyle == RootSecStyle)
|
|
{
|
|
CHString1 path, fmt("__NTLMuser.Name=\"%s\",Authority=\"%s\"");
|
|
path.Format(fmt, m_name, m_domain);
|
|
|
|
hr = service.DeleteInstance((LPCTSTR)path);
|
|
}
|
|
return hr;
|
|
}
|
|
|
|
//------------------------------------------
|
|
// move m_perms into the checkboxes
|
|
HRESULT CPrincipal::Put(CWbemServices &service, CWbemClassObject &userInst)
|
|
{
|
|
HRESULT hr = E_FAIL;
|
|
|
|
if(m_editable)
|
|
{
|
|
// if pre-M3 security...
|
|
if(m_secStyle == RootSecStyle)
|
|
{
|
|
DWORD perm = 0;
|
|
// convert my "generic" bits back to convoluted "bits".
|
|
userInst = service.CreateInstance("__NTLMUser");
|
|
userInst.Put("Name", (bstr_t)m_name);
|
|
userInst.Put("Authority", (bstr_t)m_domain);
|
|
userInst.Put("EditSecurity", (bool)((m_perms & ACL_WRITE_DAC) != 0));
|
|
userInst.Put("Enabled", (bool)((m_perms & ACL_ENABLE) != 0));
|
|
userInst.Put("ExecuteMethods", (bool)((m_perms & ACL_METHOD_EXECUTE) != 0));
|
|
|
|
if(m_perms & ACL_CLASS_WRITE)
|
|
{
|
|
perm = 2;
|
|
}
|
|
else if(m_perms & ACL_INSTANCE_WRITE)
|
|
{
|
|
perm = 1;
|
|
}
|
|
else
|
|
{
|
|
perm = 0;
|
|
}
|
|
userInst.Put("Permissions", (long)perm);
|
|
|
|
hr = service.PutInstance(userInst);
|
|
}
|
|
else //new M3+ security
|
|
{
|
|
// ACL bits perfectly match m_perms.
|
|
userInst = service.CreateInstance("__NTLMUser9x");
|
|
userInst.Put("Name", (bstr_t)m_name);
|
|
userInst.Put("Authority", (bstr_t)m_domain);
|
|
userInst.Put("Flags", (long)CONTAINER_INHERIT_ACE);
|
|
userInst.Put("Mask", (long)m_perms);
|
|
userInst.Put("Type", (long)ACCESS_ALLOWED_ACE_TYPE);
|
|
hr = S_OK;
|
|
}
|
|
}
|
|
|
|
return hr;
|
|
}
|
|
|
|
//-----------------------------------------------------------------------------
|
|
// Indexes into the SID image list IDB_SID_ICONS.
|
|
#define IDB_GROUP 0
|
|
#define IDB_USER 1
|
|
#define IDB_ALIAS 2
|
|
#define IDB_UNKNOWN 3
|
|
#define IDB_SYSTEM 4
|
|
#define IDB_REMOTE 5
|
|
#define IDB_WORLD 6
|
|
#define IDB_CREATOR_OWNER 7
|
|
#define IDB_NETWORK 8
|
|
#define IDB_INTERACTIVE 9
|
|
#define IDB_DELETEDACCOUNT 10
|
|
|
|
//TODO: match the magic strings when provider catches up.
|
|
|
|
int CPrincipal::GetImageIndex(void)
|
|
{
|
|
UINT idBitmap = 0;
|
|
return IDB_USER;
|
|
/*
|
|
switch (m_SidType)
|
|
{
|
|
case SidTypeUser:
|
|
return IDB_USER;
|
|
break;
|
|
|
|
case SidTypeGroup:
|
|
return IDB_GROUP;
|
|
break;
|
|
|
|
case SidTypeAlias:
|
|
return IDB_ALIAS;
|
|
break;
|
|
|
|
case SidTypeWellKnownGroup:
|
|
if(_tcsicmp(m_name, _T("Everyone")) == 0)
|
|
{
|
|
return IDB_WORLD;
|
|
}
|
|
else if(_tcsicmp(m_name, _T("Creator Owner")) == 0)
|
|
{
|
|
return IDB_CREATOR_OWNER;
|
|
}
|
|
else if(_tcsicmp(m_name, _T("NETWORK")) == 0)
|
|
{
|
|
return IDB_NETWORK;
|
|
}
|
|
else if(_tcsicmp(m_name, _T("INTERACTIVE")) == 0)
|
|
{
|
|
return IDB_INTERACTIVE;
|
|
}
|
|
else if(_tcsicmp(m_name, _T("SYSTEM")) == 0)
|
|
{
|
|
return IDB_SYSTEM;
|
|
}
|
|
else
|
|
{
|
|
// wasn't that well known afterall :)
|
|
return IDB_GROUP;
|
|
}
|
|
break;
|
|
|
|
case SidTypeDeletedAccount:
|
|
return IDB_DELETEDACCOUNT;
|
|
break;
|
|
|
|
case SidTypeInvalid:
|
|
case SidTypeUnknown:
|
|
return IDB_UNKNOWN;
|
|
break;
|
|
|
|
case SidTypeDomain:
|
|
default:
|
|
// Should never get here.
|
|
return IDB_UNKNOWN;
|
|
break;
|
|
}
|
|
return IDB_UNKNOWN;
|
|
*/
|
|
}
|