577 lines
13 KiB
C++
577 lines
13 KiB
C++
/**********************************************************************/
|
|
/** Microsoft Windows NT **/
|
|
/** Copyright(c) Microsoft Corp., 1991-1996 **/
|
|
/**********************************************************************/
|
|
|
|
/*
|
|
WelcomeDlg.cpp
|
|
|
|
CPropertyPage support for User management wizard
|
|
|
|
FILE HISTORY:
|
|
jony Apr-1996 created
|
|
*/
|
|
|
|
#include "stdafx.h"
|
|
#include "Speckle.h"
|
|
#include "wizbased.h"
|
|
#include "Welcome.h"
|
|
#include "trstlist.h"
|
|
|
|
#include <winreg.h>
|
|
#include <lmerr.h>
|
|
#include <lmapibuf.h>
|
|
|
|
#ifdef _DEBUG
|
|
#undef THIS_FILE
|
|
static char THIS_FILE[] = __FILE__;
|
|
#endif
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// CWelcomeDlg property page
|
|
|
|
IMPLEMENT_DYNCREATE(CWelcomeDlg, CWizBaseDlg)
|
|
|
|
CWelcomeDlg::CWelcomeDlg() : CWizBaseDlg(CWelcomeDlg::IDD)
|
|
{
|
|
//{{AFX_DATA_INIT(CWelcomeDlg)
|
|
//}}AFX_DATA_INIT
|
|
|
|
m_pFont = NULL;
|
|
}
|
|
|
|
CWelcomeDlg::~CWelcomeDlg()
|
|
{
|
|
if (m_pFont != NULL) delete m_pFont;
|
|
}
|
|
|
|
void CWelcomeDlg::DoDataExchange(CDataExchange* pDX)
|
|
{
|
|
CPropertyPage::DoDataExchange(pDX);
|
|
//{{AFX_DATA_MAP(CWelcomeDlg)
|
|
DDX_Control(pDX, IDC_DOMAIN_LIST, m_cbDomainList);
|
|
//}}AFX_DATA_MAP
|
|
}
|
|
|
|
|
|
BEGIN_MESSAGE_MAP(CWelcomeDlg, CPropertyPage)
|
|
//{{AFX_MSG_MAP(CWelcomeDlg)
|
|
ON_WM_SHOWWINDOW()
|
|
//}}AFX_MSG_MAP
|
|
|
|
END_MESSAGE_MAP()
|
|
|
|
/////////////////////////////////////////////////////////////////////////////
|
|
// CWelcomeDlg message handlers
|
|
BOOL CWelcomeDlg::OnInitDialog()
|
|
{
|
|
CPropertyPage::OnInitDialog();
|
|
CSpeckleApp* pApp = (CSpeckleApp*)AfxGetApp();
|
|
// read cached domain list from registry
|
|
DWORD dwRet;
|
|
HKEY hKey;
|
|
DWORD cbProv = 0;
|
|
TCHAR* lpProv = NULL;
|
|
|
|
BOOL bFoundOne = FALSE;
|
|
|
|
long lRet = RegConnectRegistry(
|
|
(LPTSTR)pApp->m_csServer.GetBuffer(pApp->m_csServer.GetLength()),
|
|
HKEY_LOCAL_MACHINE,
|
|
&hKey);
|
|
|
|
dwRet = RegOpenKey(hKey,
|
|
TEXT("SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon"), &hKey );
|
|
|
|
TCHAR* lpPrimaryDomain = NULL;
|
|
if ((dwRet = RegQueryValueEx( hKey, TEXT(/*"CachePrimaryDomain"*/"DefaultDomainName"), NULL, NULL, NULL, &cbProv )) == ERROR_SUCCESS)
|
|
{
|
|
lpPrimaryDomain = (TCHAR*)malloc(cbProv);
|
|
if (lpPrimaryDomain == NULL)
|
|
{
|
|
AfxMessageBox(IDS_GENERIC_NO_HEAP, MB_ICONEXCLAMATION);
|
|
ExitProcess(1);
|
|
}
|
|
dwRet = RegQueryValueEx( hKey, TEXT(/*"CachePrimaryDomain"*/"DefaultDomainName"), NULL, NULL, (LPBYTE) lpPrimaryDomain, &cbProv );
|
|
bFoundOne = TRUE;
|
|
}
|
|
|
|
m_csPrimaryDomain = lpPrimaryDomain;
|
|
free(lpPrimaryDomain);
|
|
RegCloseKey(hKey);
|
|
|
|
CString csMachineName;
|
|
DWORD dwSize = MAX_COMPUTERNAME_LENGTH + 1;
|
|
GetComputerName(csMachineName.GetBufferSetLength(MAX_COMPUTERNAME_LENGTH + 1), &dwSize);
|
|
|
|
pApp->m_csCurrentMachine = csMachineName;
|
|
|
|
// read the list of trusted domains
|
|
CTrustList pList;
|
|
if (!pList.BuildTrustList((LPTSTR)pApp->m_csServer.GetBuffer(pApp->m_csServer.GetLength())))
|
|
{
|
|
/* if this fails its probably because they are running the wizard
|
|
from a machine account that doesn't exist on the domain level.
|
|
Add only the local machine and select it.*/
|
|
m_cbDomainList.AddString(pApp->m_csCurrentMachine);
|
|
m_cbDomainList.SelectString(-1, pApp->m_csCurrentMachine);
|
|
}
|
|
|
|
else
|
|
{
|
|
UINT i;
|
|
for(i = 0 ; i < pList.m_dwTrustCount ; i++)
|
|
m_cbDomainList.AddString(pList.m_ppszTrustList[i]);
|
|
|
|
// remove the current machine from the list
|
|
// if ((i = m_cbDomainList.FindStringExact(-1, pApp->m_csCurrentMachine)) != LB_ERR)
|
|
// m_cbDomainList.DeleteString(i);
|
|
|
|
// now select the default domain into view
|
|
int nSel = m_cbDomainList.SelectString(-1, m_csPrimaryDomain);
|
|
m_cbDomainList.GetWindowText(m_csDomain);
|
|
UpdateData(FALSE);
|
|
}
|
|
|
|
// welcome text
|
|
m_pFont = new CFont;
|
|
LOGFONT lf;
|
|
|
|
memset(&lf, 0, sizeof(LOGFONT)); // Clear out structure.
|
|
lf.lfHeight = 15;
|
|
_tcscpy(lf.lfFaceName, L"MS Sans Serif");
|
|
lf.lfWeight = 700;
|
|
m_pFont->CreateFontIndirect(&lf); // Create the font.
|
|
|
|
CString cs;
|
|
cs.LoadString(IDS_WELCOME_STRING);
|
|
CWnd* pWnd = GetDlgItem(IDC_STATIC1);
|
|
pWnd->SetWindowText(cs);
|
|
pWnd->SetFont(m_pFont);
|
|
|
|
return TRUE; // return TRUE unless you set the focus to a control
|
|
// EXCEPTION: OCX Property Pages should return FALSE
|
|
}
|
|
|
|
LRESULT CWelcomeDlg::OnWizardNext()
|
|
{
|
|
UpdateData(TRUE);
|
|
CSpeckleApp* pApp = (CSpeckleApp*)AfxGetApp();
|
|
|
|
// get the DC of the selected domain
|
|
m_cbDomainList.GetWindowText(m_csDomain);
|
|
|
|
// same as last time? no need to check again.
|
|
if (m_csLastDomain == m_csDomain) return CPropertyPage::OnWizardNext();
|
|
|
|
CWaitCursor wait;
|
|
|
|
pApp->m_csDomain = m_csDomain;
|
|
pApp->m_bDomain = FALSE;
|
|
TCHAR* pDomain = m_csDomain.GetBuffer(m_csDomain.GetLength());
|
|
m_csDomain.ReleaseBuffer();
|
|
|
|
TCHAR* pDC;
|
|
NET_API_STATUS nApi;
|
|
|
|
// local machine?
|
|
if (m_csDomain == pApp->m_csCurrentMachine)
|
|
{
|
|
pApp->m_csServer = CString(L"\\\\") + pApp->m_csCurrentMachine;
|
|
pDC = pApp->m_csServer.GetBuffer(pApp->m_csServer.GetLength());
|
|
}
|
|
|
|
else
|
|
{
|
|
nApi = NetGetDCName(NULL,
|
|
pDomain,
|
|
(LPBYTE*)&pDC);
|
|
|
|
if (nApi != NERR_Success)
|
|
{
|
|
AfxMessageBox(IDS_NODC, MB_ICONSTOP);
|
|
return -1;
|
|
}
|
|
pApp->m_csServer = pDC;
|
|
pApp->m_bDomain = TRUE;
|
|
}
|
|
|
|
// we really shouldn't proceed until we know we are an admin on the remote machine
|
|
BYTE sidBuffer[100];
|
|
PSID pSID = (PSID)&sidBuffer;
|
|
BOOL bRet;
|
|
|
|
// create a SID for the Administrators group
|
|
SID_IDENTIFIER_AUTHORITY SIDAuth = SECURITY_NT_AUTHORITY;
|
|
bRet = AllocateAndInitializeSid(&SIDAuth,
|
|
2,
|
|
SECURITY_BUILTIN_DOMAIN_RID,
|
|
DOMAIN_ALIAS_RID_ADMINS,
|
|
0,
|
|
0,
|
|
0,
|
|
0,
|
|
0,
|
|
0,
|
|
&pSID);
|
|
|
|
if (!bRet)
|
|
{
|
|
DWORD dw = GetLastError();
|
|
ASSERT(0);
|
|
}
|
|
|
|
TCHAR pName[256];
|
|
DWORD dwNameLen = 256;
|
|
TCHAR pDomainName[256];
|
|
DWORD dwDomainNameLen = 256;
|
|
SID_NAME_USE SNU;
|
|
|
|
bRet = LookupAccountSid(pDC,
|
|
pSID,
|
|
pName,
|
|
&dwNameLen,
|
|
pDomainName,
|
|
&dwDomainNameLen,
|
|
&SNU);
|
|
|
|
// get the users name and domain from the reg for comparison
|
|
DWORD dwRet;
|
|
HKEY hKey;
|
|
DWORD cbProv = 0;
|
|
|
|
CString csUsername;
|
|
CString csDomainName;
|
|
dwRet = RegOpenKey(HKEY_LOCAL_MACHINE,
|
|
TEXT("SOFTWARE\\Microsoft\\Windows NT\\CurrentVersion\\Winlogon"), &hKey );
|
|
|
|
if ((dwRet = RegQueryValueEx( hKey, TEXT("DefaultDomainName"), NULL, NULL, NULL, &cbProv )) == ERROR_SUCCESS)
|
|
{
|
|
dwRet = RegQueryValueEx( hKey, TEXT("DefaultDomainName"),
|
|
NULL,
|
|
NULL,
|
|
(LPBYTE)csDomainName.GetBufferSetLength(cbProv),
|
|
&cbProv );
|
|
}
|
|
|
|
TCHAR* lpDefaultUserName = NULL;
|
|
if ((dwRet = RegQueryValueEx( hKey, TEXT("DefaultUserName"), NULL, NULL, NULL, &cbProv )) == ERROR_SUCCESS)
|
|
{
|
|
dwRet = RegQueryValueEx( hKey, TEXT("DefaultUserName"),
|
|
NULL,
|
|
NULL,
|
|
(LPBYTE)csUsername.GetBufferSetLength(cbProv),
|
|
&cbProv );
|
|
}
|
|
|
|
RegCloseKey(hKey);
|
|
|
|
// now enumerate the members of the admin group to see if we are a member
|
|
BOOL bAdmin = FALSE;
|
|
PLOCALGROUP_MEMBERS_INFO_1 pMembers;
|
|
DWORD dwEntriesRead, dwTotalEntries;
|
|
DWORD dwResumeHandle = 0;
|
|
nApi = NetLocalGroupGetMembers(pDC,
|
|
pName,
|
|
1,
|
|
(LPBYTE*)&pMembers,
|
|
5000,
|
|
&dwEntriesRead,
|
|
&dwTotalEntries,
|
|
&dwResumeHandle);
|
|
|
|
if (nApi == NERR_Success)
|
|
{
|
|
USHORT sIndex = 0;
|
|
while (sIndex < dwEntriesRead)
|
|
{
|
|
TCHAR pName[50];
|
|
DWORD dwNameSize = 50;
|
|
TCHAR pDomain[50];
|
|
DWORD dwDomainNameSize = 50;
|
|
SID_NAME_USE pUse;
|
|
LookupAccountSid(pDC, pMembers[sIndex].lgrmi1_sid,
|
|
pName, &dwNameSize,
|
|
pDomain, &dwDomainNameSize,
|
|
&pUse);
|
|
|
|
if (((pUse == SidTypeGroup) && (bParseGlobalGroup(pName, csUsername, csDomainName))) ||
|
|
((!csUsername.CompareNoCase(pName)) && (!csDomainName.CompareNoCase(pDomain))))
|
|
{
|
|
bAdmin = TRUE;
|
|
break;
|
|
}
|
|
|
|
sIndex++;
|
|
}
|
|
|
|
NetApiBufferFree(pMembers);
|
|
|
|
while ((dwResumeHandle != 0) && (!bAdmin))
|
|
{
|
|
nApi = NetLocalGroupGetMembers(pDC,
|
|
pName,
|
|
1,
|
|
(LPBYTE*)&pMembers,
|
|
5000,
|
|
&dwEntriesRead,
|
|
&dwTotalEntries,
|
|
&dwResumeHandle);
|
|
|
|
if (nApi == NERR_Success)
|
|
{
|
|
USHORT sIndex = 0;
|
|
while (sIndex < dwEntriesRead)
|
|
{
|
|
TCHAR pName[50];
|
|
DWORD dwNameSize = 50;
|
|
TCHAR pDomain[50];
|
|
DWORD dwDomainNameSize = 50;
|
|
SID_NAME_USE pUse;
|
|
LookupAccountSid(pDC, pMembers[sIndex].lgrmi1_sid,
|
|
pName, &dwNameSize,
|
|
pDomain, &dwDomainNameSize,
|
|
&pUse);
|
|
|
|
if (((pUse == SidTypeGroup) && (bParseGlobalGroup(pName, csUsername, csDomainName))) ||
|
|
((!csUsername.CompareNoCase(pName)) && (!csDomainName.CompareNoCase(pDomain))))
|
|
{
|
|
bAdmin = TRUE;
|
|
break;
|
|
}
|
|
|
|
sIndex++;
|
|
}
|
|
}
|
|
NetApiBufferFree(pMembers);
|
|
}
|
|
}
|
|
|
|
if (!bAdmin) // not in the administrators group - check the account ops group
|
|
{
|
|
BYTE sidBuffer[100];
|
|
PSID pSID = (PSID)&sidBuffer;
|
|
BOOL bRet;
|
|
|
|
// create a SID for the Account Operators group
|
|
SID_IDENTIFIER_AUTHORITY SIDAuth = SECURITY_NT_AUTHORITY;
|
|
bRet = AllocateAndInitializeSid(&SIDAuth,
|
|
2,
|
|
SECURITY_BUILTIN_DOMAIN_RID,
|
|
DOMAIN_ALIAS_RID_ACCOUNT_OPS,
|
|
0,
|
|
0,
|
|
0,
|
|
0,
|
|
0,
|
|
0,
|
|
&pSID);
|
|
|
|
if (!bRet)
|
|
{
|
|
DWORD dw = GetLastError();
|
|
ASSERT(0);
|
|
}
|
|
|
|
TCHAR pName[256];
|
|
DWORD dwNameLen = 256;
|
|
TCHAR pDomainName[256];
|
|
DWORD dwDomainNameLen = 256;
|
|
SID_NAME_USE SNU;
|
|
|
|
bRet = LookupAccountSid(pDC,
|
|
pSID,
|
|
pName,
|
|
&dwNameLen,
|
|
pDomainName,
|
|
&dwDomainNameLen,
|
|
&SNU);
|
|
|
|
// now enumerate the members of the group to see if we are a member
|
|
PLOCALGROUP_MEMBERS_INFO_1 pMembers;
|
|
DWORD dwEntriesRead, dwTotalEntries;
|
|
DWORD dwResumeHandle = 0;
|
|
nApi = NetLocalGroupGetMembers(pDC,
|
|
pName,
|
|
1,
|
|
(LPBYTE*)&pMembers,
|
|
5000,
|
|
&dwEntriesRead,
|
|
&dwTotalEntries,
|
|
&dwResumeHandle);
|
|
|
|
if (nApi == NERR_Success)
|
|
{
|
|
USHORT sIndex = 0;
|
|
while (sIndex < dwEntriesRead)
|
|
{
|
|
TCHAR pName[50];
|
|
DWORD dwNameSize = 50;
|
|
TCHAR pDomain[50];
|
|
DWORD dwDomainNameSize = 50;
|
|
SID_NAME_USE pUse;
|
|
LookupAccountSid(pDC, pMembers[sIndex].lgrmi1_sid,
|
|
pName, &dwNameSize,
|
|
pDomain, &dwDomainNameSize,
|
|
&pUse);
|
|
|
|
if (((pUse == SidTypeGroup) && (bParseGlobalGroup(pName, csUsername, csDomainName))) ||
|
|
((!csUsername.CompareNoCase(pName)) && (!csDomainName.CompareNoCase(pDomain))))
|
|
{
|
|
bAdmin = TRUE;
|
|
break;
|
|
}
|
|
|
|
sIndex++;
|
|
}
|
|
|
|
NetApiBufferFree(pMembers);
|
|
|
|
while ((dwResumeHandle != 0) && (!bAdmin))
|
|
{
|
|
nApi = NetLocalGroupGetMembers(pDC,
|
|
pName,
|
|
1,
|
|
(LPBYTE*)&pMembers,
|
|
5000,
|
|
&dwEntriesRead,
|
|
&dwTotalEntries,
|
|
&dwResumeHandle);
|
|
|
|
if (nApi == NERR_Success)
|
|
{
|
|
USHORT sIndex = 0;
|
|
while (sIndex < dwEntriesRead)
|
|
{
|
|
TCHAR pName[50];
|
|
DWORD dwNameSize = 50;
|
|
TCHAR pDomain[50];
|
|
DWORD dwDomainNameSize = 50;
|
|
SID_NAME_USE pUse;
|
|
LookupAccountSid(pDC, pMembers[sIndex].lgrmi1_sid,
|
|
pName, &dwNameSize,
|
|
pDomain, &dwDomainNameSize,
|
|
&pUse);
|
|
|
|
if (((pUse == SidTypeGroup) && (bParseGlobalGroup(pName, csUsername, csDomainName))) ||
|
|
((!csUsername.CompareNoCase(pName)) && (!csDomainName.CompareNoCase(pDomain))))
|
|
{
|
|
bAdmin = TRUE;
|
|
break;
|
|
}
|
|
|
|
sIndex++;
|
|
}
|
|
}
|
|
NetApiBufferFree(pMembers);
|
|
}
|
|
}
|
|
|
|
}
|
|
|
|
// not an admin? don't continue
|
|
if (!bAdmin)
|
|
{
|
|
AfxMessageBox(IDS_NOT_ADMIN);
|
|
return -1;
|
|
}
|
|
|
|
// store the domain name for a possible rerun.
|
|
m_csLastDomain = m_csDomain;
|
|
|
|
return CPropertyPage::OnWizardNext();
|
|
|
|
}
|
|
|
|
// this gets called to look into a global group which is included in the admin or account ops local group.
|
|
// these groups live on the DC of the domain passed in.
|
|
BOOL CWelcomeDlg::bParseGlobalGroup(LPTSTR lpGroupName, CString& lpName, CString& lpDomain)
|
|
{
|
|
DWORD dwEntriesRead;
|
|
DWORD dwTotalEntries;
|
|
DWORD dwResumeHandle = 0;
|
|
CSpeckleApp* pApp = (CSpeckleApp*)AfxGetApp();
|
|
|
|
TCHAR* pDomain = lpDomain.GetBuffer(lpDomain.GetLength());
|
|
lpDomain.ReleaseBuffer();
|
|
|
|
TCHAR* pServer;
|
|
NET_API_STATUS nApi = NetGetDCName(NULL,
|
|
pDomain,
|
|
(LPBYTE*)&pServer);
|
|
|
|
if (nApi != NERR_Success)
|
|
{
|
|
AfxMessageBox(IDS_NODC, MB_ICONSTOP);
|
|
return FALSE;
|
|
}
|
|
|
|
PGROUP_USERS_INFO_1 pMembers;
|
|
nApi = NetGroupGetUsers(pServer,
|
|
lpGroupName,
|
|
1,
|
|
(LPBYTE*)&pMembers,
|
|
5000,
|
|
&dwEntriesRead,
|
|
&dwTotalEntries,
|
|
&dwResumeHandle);
|
|
|
|
if (nApi != ERROR_SUCCESS)
|
|
{
|
|
NetApiBufferFree(pServer);
|
|
return FALSE;
|
|
}
|
|
|
|
USHORT sIndex;
|
|
for (sIndex = 0; sIndex < dwEntriesRead; sIndex++)
|
|
{
|
|
if (!lpName.CompareNoCase(pMembers[sIndex].grui1_name))
|
|
{
|
|
NetApiBufferFree(pServer);
|
|
return TRUE;
|
|
}
|
|
}
|
|
|
|
while (dwResumeHandle != 0)
|
|
{
|
|
nApi = NetGroupGetUsers(pServer,
|
|
lpGroupName,
|
|
1,
|
|
(LPBYTE*)&pMembers,
|
|
5000,
|
|
&dwEntriesRead,
|
|
&dwTotalEntries,
|
|
&dwResumeHandle);
|
|
|
|
if (nApi != ERROR_SUCCESS)
|
|
{
|
|
NetApiBufferFree(pServer);
|
|
return FALSE;
|
|
}
|
|
|
|
for (sIndex = 0; sIndex < dwEntriesRead; sIndex++)
|
|
{
|
|
if (!lpName.CompareNoCase(pMembers[sIndex].grui1_name))
|
|
{
|
|
NetApiBufferFree(pServer);
|
|
return TRUE;
|
|
}
|
|
}
|
|
}
|
|
|
|
NetApiBufferFree(pServer);
|
|
return FALSE;
|
|
}
|
|
|
|
|
|
void CWelcomeDlg::OnShowWindow(BOOL bShow, UINT nStatus)
|
|
{
|
|
CPropertyPage::OnShowWindow(bShow, nStatus);
|
|
|
|
CSpeckleApp* pApp = (CSpeckleApp*)AfxGetApp();
|
|
|
|
if (bShow) pApp->m_cps1.SetWizardButtons(PSWIZB_NEXT);
|
|
else pApp->m_cps1.SetWizardButtons(PSWIZB_BACK | PSWIZB_NEXT);
|
|
|
|
}
|