|
|
//+---------------------------------------------------------------------------
//
// Microsoft Windows
// Copyright (C) Microsoft Corporation 1996-2001.
//
// File: cprivs.cpp
//
// Contents: implementation of CConfigPrivs
//
//----------------------------------------------------------------------------
#include "stdafx.h"
#include "wsecmgr.h"
#include "CPrivs.h"
#include "GetUser.h"
#include "AddGrp.h"
#include "snapmgr.h"
#include "util.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__; #endif
typedef struct _OBJECT_ATTRIBUTES { ULONG Length; HANDLE RootDirectory; PUNICODE_STRING ObjectName; ULONG Attributes; PVOID SecurityDescriptor; // Points to type SECURITY_DESCRIPTOR
PVOID SecurityQualityOfService; // Points to type SECURITY_QUALITY_OF_SERVICE
} OBJECT_ATTRIBUTES; typedef OBJECT_ATTRIBUTES *POBJECT_ATTRIBUTES;
#define InitializeObjectAttributes( p, n, a, r, s ) { \
(p)->Length = sizeof( OBJECT_ATTRIBUTES ); \ (p)->RootDirectory = r; \ (p)->Attributes = a; \ (p)->ObjectName = n; \ (p)->SecurityDescriptor = s; \ (p)->SecurityQualityOfService = NULL; \ }
#define NT_SUCCESS(Status) ((NTSTATUS)(Status) >= 0)
BOOL WseceditGetNameForSpecialSids( OUT PWSTR *ppszEveryone OPTIONAL, OUT PWSTR *ppszAuthUsers OPTIONAL, OUT PWSTR *ppszAdmins OPTIONAL, OUT PWSTR *ppszAdministrator OPTIONAL );
PSID WseceditpGetAccountDomainSid( );
/////////////////////////////////////////////////////////////////////////////
// CConfigPrivs dialog
/////////////////////////////////////////////////////////////////////////////
CConfigPrivs::CConfigPrivs(UINT nTemplateID) : CAttribute(nTemplateID ? nTemplateID : IDD), m_fDirty(false)
{ //{{AFX_DATA_INIT(CConfigPrivs)
//}}AFX_DATA_INIT
m_pHelpIDs = (DWORD_PTR)a106HelpIDs; m_uTemplateResID = IDD; }
void CConfigPrivs::DoDataExchange(CDataExchange* pDX) { CAttribute::DoDataExchange(pDX); DDX_Control(pDX, IDC_GRANTLIST, m_lbGrant); DDX_Control(pDX, IDC_REMOVE, m_btnRemove); DDX_Control(pDX, IDC_ADD, m_btnAdd); DDX_Control(pDX, IDC_TITLE, m_btnTitle); }
BEGIN_MESSAGE_MAP(CConfigPrivs, CAttribute) ON_BN_CLICKED(IDC_ADD, OnAdd) ON_BN_CLICKED(IDC_REMOVE, OnRemove) ON_BN_CLICKED(IDC_CONFIGURE, OnConfigure) END_MESSAGE_MAP()
/////////////////////////////////////////////////////////////////////////////
// CConfigPrivs message handlers
/////////////////////////////////////////////////////////////////////////////
void CConfigPrivs::OnAdd() { CSCEAddGroup gu(this); PSCE_NAME_LIST pName = 0;
if( IDD_CONFIG_PRIVS == m_uTemplateResID ) //Raid #404989
{ gu.m_fCheckName = FALSE; } gu.m_dwFlags = SCE_SHOW_USERS | SCE_SHOW_LOCALGROUPS | SCE_SHOW_GLOBAL | SCE_SHOW_WELLKNOWN | SCE_SHOW_BUILTIN; gu.SetModeBits(m_pSnapin->GetModeBits());
CString str; str.LoadString( IDS_ADD_USERGROUP ); gu.m_sTitle.Format( IDS_ADD_TITLE, str ); gu.m_sDescription.LoadString( IDS_ADD_USERGROUP );
CThemeContextActivator activator; if (gu.DoModal() ==IDOK ) { pName = gu.GetUsers(); UINT cstrMax = 0; //Raid #271219
LPWSTR pstrMax = NULL; UINT cstr = 0; while(pName) { if (LB_ERR == m_lbGrant.FindStringExact(-1,pName->Name)) { if( LB_ERR == m_lbGrant.AddString(pName->Name) ) { return; } m_fDirty = true; cstr = wcslen(pName->Name); if( cstr > cstrMax ) { cstrMax = cstr; pstrMax = pName->Name; } } pName = pName->Next; } SetModified(TRUE);
CDC* pCDC = m_lbGrant.GetDC(); CSize strsize = pCDC->GetOutputTextExtent(pstrMax); m_lbGrant.ReleaseDC(pCDC); RECT winsize; m_lbGrant.GetWindowRect(&winsize); if( strsize.cx > winsize.right-winsize.left ) { m_lbGrant.SetHorizontalExtent(strsize.cx); } } }
void CConfigPrivs::OnRemove() { int cbItems; int *pnItems;
cbItems = m_lbGrant.GetSelCount(); pnItems = new int [cbItems];
if ( pnItems ) {
m_lbGrant.GetSelItems(cbItems,pnItems);
if (cbItems) { m_fDirty = true; SetModified(TRUE); }
while(cbItems--) { m_lbGrant.DeleteString(pnItems[cbItems]); }
delete[] pnItems; } }
void CConfigPrivs::OnConfigure() { CAttribute::OnConfigure();
if (m_bConfigure == m_bOriginalConfigure) { m_fDirty = false; } else { m_fDirty = true; } }
BOOL CConfigPrivs::OnApply() { if ( !m_bReadOnly ) { PSCE_PRIVILEGE_ASSIGNMENT ppa = 0; PSCE_NAME_LIST pNames = 0; CString strItem; int cItems = 0; int i = 0;
UpdateData(TRUE);
if(!m_bConfigure) { PSCE_PRIVILEGE_ASSIGNMENT pDelete;
pDelete = GetPrivData();
//
// Remove the item from the template
if( pDelete && pDelete != (PSCE_PRIVILEGE_ASSIGNMENT)ULongToPtr(SCE_NO_VALUE) ) { m_pData->SetID((LONG_PTR)NULL); if (m_pData->GetSetting()) //Raid #390777
{ m_pData->SetSetting((LONG_PTR)ULongToPtr(SCE_NO_VALUE)); } m_pData->SetUnits((LPTSTR)pDelete->Name); m_pData->SetStatus(SCE_STATUS_NOT_CONFIGURED); m_pData->SetBase((LONG_PTR)ULongToPtr(SCE_NO_VALUE));
m_pData->GetBaseProfile()->UpdatePrivilegeAssignedTo( TRUE, // Delete the profile.
&pDelete); m_pData->GetBaseProfile()->SetDirty(AREA_PRIVILEGES); m_pData->Update(m_pSnapin); } } else if (m_fDirty) {
ppa = GetPrivData();
PWSTR pszPrivName = m_pData->GetUnits();
if ( ppa ) { //
// to handle configured privilege case where Units is NULL
//
pszPrivName = ppa->Name; }
int cSpecialItems = m_lbGrant.GetCount(); DWORD dwIds = 0; CString strDenyItem;
//
// simulate SCE engine behavior to special case certain privileges/rights
//
if ( pszPrivName ) { if ( lstrcmpi(pszPrivName, SE_INTERACTIVE_LOGON_NAME) == 0 ) { if ( cSpecialItems == 0 ) { //
// logon locally right cannot be assigned to no one
//
dwIds = IDS_PRIV_WARNING_LOCAL_LOGON;
} else {
PWSTR pszAdmins = NULL;
//
// get the administrators group name
// logon locally right must be assigned to the administrator group
//
if ( WseceditGetNameForSpecialSids(NULL, NULL, &pszAdmins, NULL) ) { for (i=0;i<cSpecialItems;i++) { m_lbGrant.GetText(i,strDenyItem); if ( (lstrcmpi((LPTSTR)(LPCTSTR)strDenyItem, pszAdmins)) == 0 ) { break; } }
if ( i >= cSpecialItems ) { //
// cannot find administrators
//
dwIds = IDS_PRIV_WARNING_LOCAL_LOGON; }
LocalFree(pszAdmins);
}
else { dwIds = IDS_PRIV_WARNING_ACCOUNT_TRANSLATION; }
} } else if (lstrcmpi(pszPrivName, SE_DENY_INTERACTIVE_LOGON_NAME) == 0 ) { PWSTR pszEveryone = NULL; PWSTR pszAuthUsers = NULL; PWSTR pszAdmins = NULL; PWSTR pszAdministrator=NULL;
//
// deny logon locally right cannot be assigned to any of the following
// everyone, authenticated users, administrators, administrator
//
if ( WseceditGetNameForSpecialSids(&pszEveryone, &pszAuthUsers, &pszAdmins, &pszAdministrator) ) {
//
// make sure this check covers the free text administrator account as well
//
PWSTR pTemp = wcschr(pszAdministrator, L'\\');
if ( pTemp ) { pTemp++; }
for (i=0;i<cSpecialItems;i++) { m_lbGrant.GetText(i,strDenyItem); if ( lstrcmpi((LPTSTR)(LPCTSTR)strDenyItem, pszEveryone) == 0 || lstrcmpi((LPTSTR)(LPCTSTR)strDenyItem, pszAuthUsers) == 0 || lstrcmpi((LPTSTR)(LPCTSTR)strDenyItem, pszAdmins) == 0 || lstrcmpi((LPTSTR)(LPCTSTR)strDenyItem, pszAdministrator) == 0 || (pTemp && lstrcmpi((LPTSTR)(LPCTSTR)strDenyItem, pTemp) == 0 ) ) { dwIds = IDS_PRIV_WARNING_DENYLOCAL_LOGON; break; } }
LocalFree(pszEveryone); LocalFree(pszAuthUsers); LocalFree(pszAdmins); LocalFree(pszAdministrator); }
else { dwIds = IDS_PRIV_WARNING_ACCOUNT_TRANSLATION; } }
if (dwIds == IDS_PRIV_WARNING_LOCAL_LOGON || dwIds == IDS_PRIV_WARNING_DENYLOCAL_LOGON || dwIds == IDS_PRIV_WARNING_ACCOUNT_TRANSLATION ) {
//
// if any of the items fail the check, display the warning
// or popup a warning message box
//
CString strWarning; strWarning.LoadString(dwIds);
CWnd *pWarn = GetDlgItem(IDC_WARNING); if (pWarn) { pWarn->SetWindowText(strWarning); pWarn->ShowWindow(SW_SHOW); pWarn = GetDlgItem(IDC_WARNING_ICON); if (pWarn) pWarn->ShowWindow(SW_SHOW); } else { //
// Dialog box not available in some modes such as Local Policy
//
AfxMessageBox(strWarning); }
return FALSE; } }
if ( ppa == NULL && m_pData->GetUnits() ) { if ( m_pData->GetBaseProfile()->UpdatePrivilegeAssignedTo( FALSE, &ppa, m_pData->GetUnits() ) == ERROR_SUCCESS) { m_pData->GetBaseProfile()->SetDirty(AREA_PRIVILEGES); SetPrivData(ppa); } }
if ( ppa ) { PSCE_NAME_LIST pNewList=NULL;
cItems = m_lbGrant.GetCount(); HRESULT hr=S_OK;
if (cItems != LB_ERR && m_bConfigure) { for (i=0;i<cItems;i++) { m_lbGrant.GetText(i,strItem); if ( SceAddToNameList(&pNewList, (LPTSTR)(LPCTSTR)strItem, strItem.GetLength()) != SCESTATUS_SUCCESS) { hr = E_FAIL; break; } } } else hr = E_FAIL;
if ( SUCCEEDED(hr) ) { SceFreeMemory(ppa->AssignedTo,SCE_STRUCT_NAME_LIST); ppa->AssignedTo = pNewList;
SetPrivData(ppa); m_pData->Update(m_pSnapin); m_fDirty = false; } else { //
// free the new list, failed due to memory problem
//
if ( pNewList ) { SceFreeMemory(pNewList,SCE_STRUCT_NAME_LIST); } } } } }
return CAttribute::OnApply(); }
void CConfigPrivs::OnCancel() { m_bConfigure = m_bOriginalConfigure; CAttribute::OnCancel(); }
PSCE_PRIVILEGE_ASSIGNMENT CConfigPrivs::GetPrivData() { ASSERT(m_pData); if (m_pData) { return (PSCE_PRIVILEGE_ASSIGNMENT) m_pData->GetID(); } return NULL; }
void CConfigPrivs::SetPrivData(PSCE_PRIVILEGE_ASSIGNMENT ppa) { ASSERT(m_pData); if (m_pData) { m_pData->SetID((LONG_PTR)ppa); if (ppa) { m_pData->SetBase((LONG_PTR)ppa->AssignedTo); } else { m_pData->SetBase(NULL); } } }
BOOL CConfigPrivs::OnInitDialog() { CAttribute::OnInitDialog();
PSCE_PRIVILEGE_ASSIGNMENT ppa; PSCE_NAME_LIST pNames;
UpdateData(FALSE);
::SetMapMode(::GetDC(m_lbGrant.m_hWnd), MM_TEXT); ppa = GetPrivData();
if ( ppa ) {
pNames = ppa->AssignedTo; UINT cstrMax = 0; //Raid #271219
LPWSTR pstrMax = NULL; UINT cstr = 0; while(pNames) { m_lbGrant.AddString(pNames->Name); cstr = wcslen(pNames->Name); if( cstr > cstrMax ) { cstrMax = cstr; pstrMax = pNames->Name; } pNames = pNames->Next; }
CDC* pCDC = m_lbGrant.GetDC(); CSize strsize = pCDC->GetOutputTextExtent(pstrMax); m_lbGrant.ReleaseDC(pCDC); RECT winsize; m_lbGrant.GetWindowRect(&winsize); if( strsize.cx > winsize.right-winsize.left ) { m_lbGrant.SetHorizontalExtent(strsize.cx); } m_bConfigure = TRUE; } else if(m_pData->GetBase() == (LONG_PTR)ULongToPtr(SCE_NO_VALUE)){ m_bConfigure = FALSE; }
if (m_pData->GetSetting()) { CWnd *pWarn = GetDlgItem(IDC_WARNING); if (pWarn) { CString strWarning; strWarning.LoadString(IDS_PRIV_WARNING); pWarn->SetWindowText(strWarning); pWarn->ShowWindow(SW_SHOW);
pWarn = GetDlgItem(IDC_WARNING_ICON); if (pWarn) { pWarn->ShowWindow(SW_SHOW); } } }
m_bOriginalConfigure = m_bConfigure;
//
// Update the user controls depending on the setting.
//
AddUserControl(IDC_GRANTLIST); AddUserControl(IDC_ADD); AddUserControl(IDC_REMOVE);
m_btnTitle.SetWindowText(m_pData->GetAttrPretty()); UpdateData(FALSE); EnableUserControls(m_bConfigure); return TRUE;
// return TRUE unless you set the focus to a control
// EXCEPTION: OCX Property Pages should return FALSE
}
void CConfigPrivs::SetInitialValue(DWORD_PTR dw) {
}
BOOL WseceditGetNameForSpecialSids( OUT PWSTR *ppszEveryone OPTIONAL, OUT PWSTR *ppszAuthUsers OPTIONAL, OUT PWSTR *ppszAdmins OPTIONAL, OUT PWSTR *ppszAdministrator OPTIONAL ) /*++
Routine Description:
This routine returns the localized account name for the Everyone and the Auth User SIDs
Arguments:
ppszEveryone - ptr to fill in (should be freed outside)
ppszAuthUsers - ptr to fill in (should be freed outside)
ppszAdmins - ptr to fill in for Administrators
ppszAdministrator - ptr to fill in for local administrator account
Return value:
TRUE if succeeded else FALSE
-- */
{ //
// buffers for the SIDs
//
SID Sid; DWORD dwSize = sizeof(SID); PSID pSid=NULL;
BOOL bError = TRUE;
//
// variables for sid lookup
//
SID_NAME_USE tmp; DWORD dwSizeDom; PWSTR dummyBuf = NULL;
if ( ppszEveryone ) {
//
// create the SID for "everyone"
//
if ( CreateWellKnownSid( WinWorldSid, NULL, &Sid, &dwSize)) {
//
// get the required size of the account name and domain buffer
//
dwSize = 0; dwSizeDom = 0;
LookupAccountSid( NULL, &Sid, NULL, &dwSize, NULL, &dwSizeDom, &tmp );
*ppszEveryone = (PWSTR)LocalAlloc(LMEM_ZEROINIT, ((dwSize + 1) * sizeof(WCHAR))); dummyBuf = (PWSTR)LocalAlloc(LMEM_ZEROINIT, ((dwSizeDom + 1) * sizeof(WCHAR)));
if ( *ppszEveryone && dummyBuf ) {
//
// lookup the SID to get the account name - domain name is ignored
//
if ( LookupAccountSid( NULL, &Sid, *ppszEveryone, &dwSize, dummyBuf, &dwSizeDom, &tmp ) ) { bError = FALSE; } } }
LocalFree(dummyBuf); dummyBuf = NULL;
if (bError) { LocalFree(*ppszEveryone); *ppszEveryone = NULL; return FALSE; } }
//
// "Authenticated Users"
//
if ( ppszAuthUsers ) {
dwSize = sizeof(SID); bError = TRUE;
//
// create the SID for "authenticated users"
//
if ( CreateWellKnownSid( WinAuthenticatedUserSid, NULL, &Sid, &dwSize)) {
//
// get the required size of account name and domain buffers
//
dwSize = 0; dwSizeDom = 0;
LookupAccountSid( NULL, &Sid, NULL, &dwSize, NULL, &dwSizeDom, &tmp );
*ppszAuthUsers = (PWSTR)LocalAlloc(LMEM_ZEROINIT, ((dwSize + 1) * sizeof(WCHAR))); dummyBuf = (PWSTR)LocalAlloc(LMEM_ZEROINIT, ((dwSizeDom + 1) * sizeof(WCHAR)));
if ( *ppszAuthUsers && dummyBuf ) {
//
// lookup the SID to get account name - domain name is ignored
//
if ( LookupAccountSid( NULL, &Sid, *ppszAuthUsers, &dwSize, dummyBuf, &dwSizeDom, &tmp ) ) { bError = FALSE; } } }
LocalFree(dummyBuf); dummyBuf = NULL;
if (bError) {
LocalFree(*ppszAuthUsers); *ppszAuthUsers = NULL;
if ( ppszEveryone ) { LocalFree(*ppszEveryone); *ppszEveryone = NULL; } return FALSE; } }
//
// administrators group
//
if ( ppszAdmins ) {
dwSize = 0; bError = TRUE;
//
// get the size for the well known SID of administrators group
//
CreateWellKnownSid( WinBuiltinAdministratorsSid, NULL, pSid, &dwSize);
if ( dwSize > 0 ) {
//
// alocate buffer and create the well known SID
// cannot use the SID buffer because Admins SID has more than
// one subauthority
//
pSid = (PSID)LocalAlloc(LPTR, dwSize);
if ( pSid &&
CreateWellKnownSid( WinBuiltinAdministratorsSid, NULL, pSid, &dwSize) ) {
dwSize = 0; dwSizeDom = 0;
//
// get the size for account name and domain buffers
//
LookupAccountSid( NULL, pSid, NULL, &dwSize, NULL, &dwSizeDom, &tmp );
*ppszAdmins = (PWSTR)LocalAlloc(LMEM_ZEROINIT, ((dwSize + 1) * sizeof(WCHAR))); dummyBuf = (PWSTR)LocalAlloc(LMEM_ZEROINIT, ((dwSizeDom + 1) * sizeof(WCHAR)));
if ( *ppszAdmins && dummyBuf ) {
//
// look up the name, domain name (BUILTIN) is ignored
//
if ( LookupAccountSid( NULL, pSid, *ppszAdmins, &dwSize, dummyBuf, &dwSizeDom, &tmp ) ) { bError = FALSE; } } }
LocalFree(pSid); pSid = NULL; }
LocalFree(dummyBuf); dummyBuf = NULL;
if (bError) {
//
// anything fail will free all buffers and return FALSE
//
LocalFree(*ppszAdmins); *ppszAdmins = NULL;
if ( ppszAuthUsers ) {
LocalFree(*ppszAuthUsers); *ppszAuthUsers = NULL; }
if ( ppszEveryone ) { LocalFree(*ppszEveryone); *ppszEveryone = NULL; } return FALSE; } }
//
// the administrator user account
//
if ( ppszAdministrator ) {
dwSize = 0; bError = TRUE;
PWSTR dummy2=NULL;
//
// Get Account domain SID first
//
PSID pDomSid = WseceditpGetAccountDomainSid();
if ( pDomSid ) {
//
// get the size for the administrator account (local account domain is used)
//
CreateWellKnownSid( WinAccountAdministratorSid, pDomSid, pSid, &dwSize);
if ( dwSize > 0 ) {
//
// cannot use the SID buffer because administrator account SID
// has more than one subauthority
//
pSid = (PSID)LocalAlloc(LPTR, dwSize);
if ( pSid && CreateWellKnownSid( WinAccountAdministratorSid, pDomSid, pSid, &dwSize) ) {
//
// get size for the account name and domain buffer
//
dwSize = 0; dwSizeDom = 0;
LookupAccountSid( NULL, pSid, NULL, &dwSize, NULL, &dwSizeDom, &tmp );
dummy2 = (PWSTR)LocalAlloc(LMEM_ZEROINIT, ((dwSize + 1) * sizeof(WCHAR))); dummyBuf = (PWSTR)LocalAlloc(LMEM_ZEROINIT, ((dwSizeDom + 1) * sizeof(WCHAR)));
if ( dummy2 && dummyBuf ) {
//
// lookup the account name and domain name
//
if ( LookupAccountSid( NULL, pSid, dummy2, &dwSize, dummyBuf, &dwSizeDom, &tmp ) ) {
*ppszAdministrator = (PWSTR)LocalAlloc(LPTR, (dwSize+dwSizeDom+2)*sizeof(WCHAR));
if ( *ppszAdministrator ) {
//
// the name to return is a fully qualified name such as Domain\Administrator
//
wcscpy(*ppszAdministrator, dummyBuf); wcscat(*ppszAdministrator, L"\\"); wcscat(*ppszAdministrator, dummy2);
bError = FALSE; } } } }
LocalFree(pSid); pSid = NULL; }
LocalFree(dummyBuf); dummyBuf = NULL;
LocalFree(dummy2); dummy2 = NULL;
LocalFree(pDomSid); }
if (bError) {
//
// anything fail will free all buffers and return FALSE
//
LocalFree(*ppszAdministrator); *ppszAdministrator = NULL;
if ( ppszAdmins ) {
LocalFree(*ppszAdmins); *ppszAdmins = NULL; }
if ( ppszAuthUsers ) {
LocalFree(*ppszAuthUsers); *ppszAuthUsers = NULL; }
if ( ppszEveryone ) { LocalFree(*ppszEveryone); *ppszEveryone = NULL; } return FALSE; }
}
return TRUE;
}
PSID WseceditpGetAccountDomainSid( ) {
NTSTATUS Status;
LSA_HANDLE PolicyHandle; OBJECT_ATTRIBUTES PolicyObjectAttributes; PPOLICY_ACCOUNT_DOMAIN_INFO PolicyAccountDomainInfo=NULL;
PSID DomainSid=NULL;
//
// Open the policy database
//
InitializeObjectAttributes( &PolicyObjectAttributes, NULL, // Name
0, // Attributes
NULL, // Root
NULL ); // Security Descriptor
Status = LsaOpenPolicy( NULL, (PLSA_OBJECT_ATTRIBUTES)&PolicyObjectAttributes, POLICY_VIEW_LOCAL_INFORMATION, &PolicyHandle );
if ( NT_SUCCESS(Status) ) {
//
// Query the account domain information
//
Status = LsaQueryInformationPolicy( PolicyHandle, PolicyAccountDomainInformation, (PVOID *)&PolicyAccountDomainInfo );
if ( NT_SUCCESS(Status) ) {
DWORD Len = GetLengthSid(PolicyAccountDomainInfo->DomainSid);
DomainSid = (PSID)LocalAlloc(LPTR, Len );
if ( DomainSid ) {
Status = CopySid( Len, DomainSid, PolicyAccountDomainInfo->DomainSid );
if ( !NT_SUCCESS(Status) ) { LocalFree(DomainSid); DomainSid = NULL; } }
LsaFreeMemory(PolicyAccountDomainInfo);
}
LsaClose( PolicyHandle );
}
return(DomainSid); }
|