Update NEWS for 1.6.22
[pkg-k5-afs_openafs.git] / src / WINNT / afssvrcfg / afscfg.cpp
blobfea5636423ec48092018751b22e3a68f65eb14dd
1 /*
2 * Copyright 2000, International Business Machines Corporation and others.
3 * All Rights Reserved.
5 * This software has been released under the terms of the IBM Public
6 * License. For details, see the LICENSE file in the top-level source
7 * directory or online at http://www.openafs.org/dl/license10.html
8 */
11 * INCLUDES _________________________________________________________________
15 #include <winsock2.h>
16 #include <ws2tcpip.h>
18 extern "C" {
19 #include <afs/param.h>
20 #include <afs/stds.h>
23 #include "afscfg.h"
24 #include "resource.h"
25 #include "graphics.h"
26 #include <string.h>
27 #include "get_cur_config.h"
28 #include "partition_utils.h"
29 extern "C" {
30 #include <afs\dirpath.h>
31 #include <afs\afs_clientAdmin.h>
33 #include <afs\lanahelper.h>
37 * DEFINITIONS _________________________________________________________________
43 * PROTOTYPES _________________________________________________________________
46 static void SetConfigDefaults();
47 static void RunCfgTool();
48 static void RunWizard();
49 static void CloseLibHandles(BOOL bExiting = FALSE);
51 void RegisterWizardHelp();
52 void RegisterConfigToolHelp();
54 // These are the prototypes for the dialog procs of each wizard page.
55 BOOL CALLBACK IntroPageDlgProc(HWND hRHS, UINT msg, WPARAM wp, LPARAM lp);
56 BOOL CALLBACK InfoPageDlgProc(HWND hwndDlg, UINT msg, WPARAM wp, LPARAM lp);
57 BOOL CALLBACK InfoPage2DlgProc(HWND hRHS, UINT msg, WPARAM wp, LPARAM lp);
58 BOOL CALLBACK FileServerPageDlgProc(HWND hwndDlg, UINT msg, WPARAM wp, LPARAM lp);
59 BOOL CALLBACK DBServerPageDlgProc(HWND hwndDlg, UINT msg, WPARAM wp, LPARAM lp);
60 BOOL CALLBACK BackupPageDlgProc(HWND hwndDlg, UINT msg, WPARAM wp, LPARAM lp);
61 BOOL CALLBACK PartitionPageDlgProc(HWND hwndDlg, UINT msg, WPARAM wp, LPARAM lp);
62 BOOL CALLBACK RootAfsPageDlgProc(HWND hwndDlg, UINT msg, WPARAM wp, LPARAM lp);
63 BOOL CALLBACK ReplicationPageDlgProc(HWND hwndDlg, UINT msg, WPARAM wp, LPARAM lp);
64 BOOL CALLBACK SysControlPageDlgProc(HWND hwndDlg, UINT msg, WPARAM wp, LPARAM lp);
65 BOOL CALLBACK ConfigServerPageDlgProc(HWND hwndDlg, UINT msg, WPARAM wp, LPARAM lp);
68 static WIZARD_STATE g_aStates[] = {
69 { sidSTEP_ONE, IDD_INTRO_PAGE, (DLGPROC)IntroPageDlgProc, 0 },
70 { sidSTEP_TWO, IDD_INFO_PAGE, (DLGPROC)InfoPageDlgProc, 0 },
71 { sidSTEP_THREE, IDD_INFO_PAGE2_FIRST_SERVER, (DLGPROC)InfoPage2DlgProc, 0 },
72 { sidSTEP_FOUR, IDD_INFO_PAGE2_NOT_FIRST_SERVER,(DLGPROC)InfoPage2DlgProc, 0 },
73 { sidSTEP_FIVE, IDD_FILE_SERVER_PAGE, (DLGPROC)FileServerPageDlgProc, 0 },
74 { sidSTEP_SIX, IDD_DB_SERVER_PAGE, (DLGPROC)DBServerPageDlgProc, 0 },
75 { sidSTEP_SEVEN, IDD_BACKUP_SERVER_PAGE, (DLGPROC)BackupPageDlgProc, 0 },
76 { sidSTEP_EIGHT, IDD_PARTITION_PAGE, (DLGPROC)PartitionPageDlgProc, 0 },
77 { sidSTEP_NINE, IDD_ROOT_VOLUMES_PAGE, (DLGPROC)RootAfsPageDlgProc, 0 },
78 { sidSTEP_TEN, IDD_REPLICATION_PAGE, (DLGPROC)ReplicationPageDlgProc, 0 },
79 { sidSTEP_ELEVEN, IDD_SYS_CONTROL_PAGE, (DLGPROC)SysControlPageDlgProc, 0 },
80 { sidSTEP_TWELVE, IDD_CONFIG_SERVER_PAGE, (DLGPROC)ConfigServerPageDlgProc, 0 }
83 size_t g_nNumStates = sizeof(g_aStates) / sizeof(g_aStates[0]);
86 // Res ID's of text descriptions of each state
87 UINT g_StateDesc[] = {
88 IDS_INTRO_PAGE,
89 IDS_INFO_PAGE,
90 IDS_INFO_PAGE2,
91 IDS_INFO_PAGE2,
92 IDS_FS_PAGE,
93 IDS_DB_PAGE,
94 IDS_BK_PAGE,
95 IDS_PARTITION_PAGE,
96 IDS_ROOT_AFS_PAGE,
97 IDS_REP_PAGE,
98 IDS_SC_PAGE,
99 IDS_CONFIG_PAGE
105 * EXPORTED VARIABLES _________________________________________________________________
108 LPWIZARD g_pWiz = NULL;
109 LPPROPSHEET g_pSheet = NULL;
111 CFG_DATA g_CfgData;
113 void *g_hToken = 0;
114 void *g_hCell = 0;
115 void *g_hClient = 0;
116 void *g_hServer = 0;
118 static void *hClientCell = 0;
120 LOGFILE g_LogFile;
125 * EXPORTED FUNCTIONS _________________________________________________________________
128 extern "C" int WINAPI WinMain (HINSTANCE hInst, HINSTANCE hPrev, LPSTR pszCmdLineA, int nCmdShow)
130 afs_status_t nStatus;
132 TaLocale_LoadCorrespondingModule (hInst);
134 // Tell the applib our application's name
135 TCHAR szAppName[cchRESOURCE];
136 AfsAppLib_SetAppName(GetResString(GetAppTitleID(), szAppName));
138 // Open the admin libraries
139 int nResult = afsclient_Init(&nStatus);
140 if (!nResult) {
141 ShowError(0, nStatus, IDS_CANT_INIT_ADMIN_LIBS);
142 return 0;
145 // Open the log file
146 char szLogPath[MAX_PATH];
147 sprintf(szLogPath, "%s\\%s", AFSDIR_SERVER_LOGS_DIRPATH, LOG_FILE_NAME);
148 if (!g_LogFile.Open(szLogPath))
149 ShowError(0, 0, IDS_CANT_OPEN_LOG_FILE);
151 // Register the help file with the applib's help system
152 AfsAppLib_RegisterHelpFile(TEXT("TaAfsCfg.hlp"));
154 /* Start up sockets */
155 WSADATA WSAjunk;
156 WSAStartup(0x0101, &WSAjunk);
158 memset(&g_CfgData, 0, sizeof(CFG_DATA));
160 // Get this machine's local name
161 char szLocalName[sizeof(g_CfgData.szLocalName) / sizeof(TCHAR)];
162 if (gethostname(szLocalName, sizeof(szLocalName)) != 0) {
163 ShowError(GetFocus(), WSAGetLastError(), IDS_ERROR_LOCAL_HOST_NAME);
164 return 0;
166 CopyAnsiToString(g_CfgData.szLocalName, szLocalName);
168 // Turn the local name into a host name
169 struct hostent *pHostEnt = gethostbyname(szLocalName);
170 if (!pHostEnt) {
171 ShowError(GetFocus(), WSAGetLastError(), IDS_ERROR_HOST_NAME);
172 return 0;
174 CopyAnsiToString(g_CfgData.szHostname, pHostEnt->h_name, sizeof(g_CfgData.szHostname));
176 RegisterFastListClass();
178 // Get current config status
179 BOOL bCanceled = FALSE;
180 DWORD dwStatus = GetCurrentConfig(NULL, bCanceled);
181 if (dwStatus || bCanceled) {
182 if (!bCanceled)
183 ShowError(GetFocus(), dwStatus, IDS_CONFIG_CHECK_FAILED);
184 return 0;
187 // Run the appropriate interface
188 if ((strstr(_strlwr(pszCmdLineA), "wizard") != 0))
189 RunWizard();
190 else
191 RunCfgTool();
193 FreePartitionTable();
195 // Disconnect from the config and admin libraries
196 CloseLibHandles(TRUE);
198 return 0;
202 * This is a dialog proc that is shared by all of the wizard pages. It
203 * handles things that are common to all of them. Each page also has its
204 * own dialog proc.
206 BOOL CALLBACK WizStep_Common_DlgProc(HWND hRHS, UINT msg, WPARAM wp, LPARAM lp)
208 // Get the dialog's resource ID
209 int nIDD = GetWindowLong(hRHS, GWL_ID);
211 if (AfsAppLib_HandleHelp(nIDD, hRHS, msg, wp, lp))
212 return TRUE;
214 switch (msg) {
215 case WM_INITDIALOG: MakeBold(hRHS, IDC_TITLE);
216 RedrawGraphic();
217 break;
219 case WM_COMMAND:
220 switch (LOWORD(wp)) {
221 case IDCANCEL:
222 QueryCancelWiz();
223 return TRUE;
225 break;
228 return FALSE;
231 BOOL QueryCancelWiz()
233 int nChoice = Message(MB_YESNO, IDS_WIZARD_APP_TITLE, IDS_CANCEL_DESC);
234 if (nChoice == IDYES) {
235 g_LogFile.Write("User has chosen to cancel the program.\r\n");
236 if (g_pWiz)
237 g_pWiz->Show(FALSE);
238 return TRUE;
241 return FALSE;
246 * Accessor functions for the g_CfgData variable. There are versions
247 * for both TCHARs and char *'s.
249 TCHAR GetDeviceName() { return g_CfgData.chDeviceName; }
250 LPTSTR GetPartitionName() { return g_CfgData.szPartitionName; }
251 LPTSTR GetHostName() { return g_CfgData.szHostname; }
252 LPTSTR GetSysControlMachine() { return g_CfgData.szSysControlMachine; }
253 LPTSTR GetCellName() { return g_CfgData.szCellName; }
254 LPTSTR GetServerPW() { return g_CfgData.szServerPW; }
255 LPTSTR GetAdminName() { return g_CfgData.szAdminName; }
256 LPTSTR GetAdminPW() { return g_CfgData.szAdminPW; }
257 LPTSTR GetAdminUID() { return g_CfgData.szAdminUID; }
258 LPTSTR GetLocalName() { return g_CfgData.szLocalName; }
259 LPTSTR GetHostname() { return g_CfgData.szHostname; }
260 LPTSTR GetCellServDbHostname() { return g_CfgData.szCellServDbHostname; }
261 LPTSTR GetClientCellName() { return g_CfgData.szClientCellName; }
262 LPTSTR GetSalvageLogFileName() { return g_CfgData.szSalvageLogFileName; }
264 LPTSTR GetClientNetbiosName()
266 static TCHAR szValue[MAX_MACHINE_NAME_LEN + 1] = "";
268 if ( szValue[0] == 0 )
269 CopyAnsiToString(GetClientNetbiosNameA(), szValue);
271 return szValue;
274 char GetDeviceNameA()
276 static char szValueA[2];
278 TCHAR devName[2] = TEXT("X");
279 devName[0] = g_CfgData.chDeviceName;
281 CopyStringToAnsi(szValueA, devName);
283 return szValueA[0];
286 char *GetPartitionNameA()
288 static char szValueA[MAX_PARTITION_NAME_LEN + 1];
290 CopyStringToAnsi(szValueA, g_CfgData.szPartitionName);
292 return szValueA;
295 char *GetSysControlMachineA()
297 static char szValueA[MAX_MACHINE_NAME_LEN + 1];
299 CopyStringToAnsi(szValueA, g_CfgData.szSysControlMachine);
301 return szValueA;
304 char *GetCellNameA()
306 static char szValueA[MAX_CELL_NAME_LEN + 1];
308 CopyStringToAnsi(szValueA, g_CfgData.szCellName);
310 return szValueA;
313 char *GetServerPWA()
315 static char szValueA[MAX_SERVER_PW_LEN + 1];
317 CopyStringToAnsi(szValueA, g_CfgData.szServerPW);
319 return szValueA;
322 char *GetAdminNameA()
324 static char szValueA[MAX_ADMIN_NAME_LEN + 1];
326 CopyStringToAnsi(szValueA, g_CfgData.szAdminName);
328 return szValueA;
331 char *GetAdminPWA()
333 static char szValueA[MAX_ADMIN_PW_LEN + 1];
335 CopyStringToAnsi(szValueA, g_CfgData.szAdminPW);
337 return szValueA;
340 char *GetAdminUIDA()
342 static char szValueA[MAX_UID_LEN + 1];
344 CopyStringToAnsi(szValueA, g_CfgData.szAdminUID);
346 return szValueA;
349 char *GetLocalNameA()
351 static char szValueA[MAX_MACHINE_NAME_LEN + 1];
353 CopyStringToAnsi(szValueA, g_CfgData.szLocalName);
355 return szValueA;
358 char *GetHostnameA()
360 static char szValueA[MAX_MACHINE_NAME_LEN + 1];
362 CopyStringToAnsi(szValueA, g_CfgData.szHostname);
364 return szValueA;
367 char *GetCellServDbHostnameA()
369 static char szValueA[MAX_MACHINE_NAME_LEN + 1];
371 CopyStringToAnsi(szValueA, g_CfgData.szCellServDbHostname);
373 return szValueA;
376 char *GetClientCellNameA()
378 static char szValueA[MAX_CELL_NAME_LEN + 1];
380 CopyStringToAnsi(szValueA, g_CfgData.szClientCellName);
382 return szValueA;
385 char *GetClientNetbiosNameA()
387 static char szValueA[MAX_MACHINE_NAME_LEN + 1]="";
389 if ( szValueA[0] == 0 )
390 lana_GetNetbiosName(szValueA, LANA_NETBIOS_NAME_FULL);
392 return szValueA;
395 char *GetSalvageLogFileNameA()
397 static char szValueA[_MAX_PATH];
399 CopyStringToAnsi(szValueA, g_CfgData.szSalvageLogFileName);
401 return szValueA;
405 BOOL GetLibHandles(afs_status_t *pStatus)
407 ASSERT(g_CfgData.szHostname[0]);
409 int nResult;
411 // ************************* NOTE ********************************
412 // * You MUST have already determined whether or not the host
413 // * and client config info is valid before calling this function.
414 // ***************************************************************
416 // This function can be called at any time to get handles to the cell and
417 // the config library. It will try to get the most powerful handle to the
418 // cell that it can, and then use that to open the config library. If the
419 // libraries are already open, it will close them first. Two handles to
420 // the config library will be opened, one to the server to be configured,
421 // and one to the client machine we are configuring from.
423 // There are two types of cell handles, NULL and Standard. A null handle
424 // can make calls to any server except DB servers. We need this primarily
425 // to talk to the bos server to determine the machine's current configuration,
426 // and to configure the client information if it is not already. A standard
427 // handle can talk to any server. Standard handles can be either authenticated
428 // or unauthenticated.
430 // Close all current handles
431 CloseLibHandles();
433 g_LogFile.Write("Getting handles to the cell and the config library.\r\n");
435 if (!hClientCell) {
436 // Start by getting a null cell handle and using it to open the client
437 // connection to the config library.
438 g_LogFile.Write("Opening a NULL cell handle to use with the client config library handle.\r\n");
439 nResult = afsclient_NullCellOpen(&hClientCell, pStatus);
440 if (!nResult) {
441 g_LogFile.Write("Failed to open a NULL cell handle: %lx.\r\n", (unsigned long)*pStatus);
442 return FALSE;
445 // Get the client handle. We never need a better handle than this
446 // for the client, and so this handle will never be upgraded.
447 g_LogFile.Write("Getting config handle for the client.\r\n");
448 if (!cfg_HostOpen(hClientCell, GetHostnameA(), &g_hClient, pStatus)) {
449 g_LogFile.Write("Failed to get config handle: %lx.\r\n", (unsigned long)*pStatus);
450 return FALSE;
454 // Now we need to get the most powerful cell handle that we can and use it
455 // to open the config library for the server.
457 // If the client info is valid and we know what cell the server should be in,
458 // and the client has that cell in its CellServDB, then we can get a Standard cell
459 // handle. However there is an exception: if this is the first server in the
460 // cell then there may not yet be an authentication server to talk to. In that
461 // case we use a null cell handle.
462 if (g_CfgData.bValidClientInfo && // Client config is valid
463 g_CfgData.szCellName[0] && // We have a cell name
464 (!g_CfgData.bFirstServer || g_CfgData.bAuthServerRunning)) // Auth server is running
466 g_LogFile.Write("Opening a non-NULL cell handle to use with the server config library handle.\r\n");
468 // Do we have the user info necessary to authenticate?
469 BOOL bHaveUserInfo = g_CfgData.szAdminName[0] && g_CfgData.szAdminPW[0];
471 // Open a standard cell handle. szAdminName and szAdminPW will either be NULL, or
472 // if they have been entered by the user, will be the admin name and password strings.
473 if ((!g_CfgData.bFirstServer || g_CfgData.bAdminPrincipalCreated) && bHaveUserInfo) {
474 g_LogFile.Write("Getting tokens in cell %s for user '%s'.\r\n", GetCellNameA(), GetAdminNameA());
475 nResult = afsclient_TokenGetNew(GetCellNameA(), GetAdminNameA(), GetAdminPWA(), &g_hToken, pStatus);
476 } else {
477 g_LogFile.Write("Getting unauthenticated tokens for cell '%s'.\r\n", GetCellNameA());
478 nResult = afsclient_TokenGetNew(GetCellNameA(), "", "", &g_hToken, pStatus);
481 if (!nResult) {
482 g_LogFile.Write("Failed to get tokens for the specified cell: %lx.\r\n", (unsigned long)*pStatus);
483 return FALSE;
486 // If the admin name and password are NULL, then this will be an unauthenticated
487 // connection to the cell.
488 g_LogFile.Write("Getting cell handle for cell %s.\r\n", GetCellNameA());
489 nResult = afsclient_CellOpen(GetCellNameA(), g_hToken, &g_hCell, pStatus);
490 if (!nResult) {
491 g_LogFile.Write("Failed to open the cell: %lx.\r\n", (unsigned long)*pStatus);
492 return FALSE;
494 } else {
495 g_LogFile.Write("Opening a NULL cell handle to use with the server config library handle.\r\n");
496 nResult = afsclient_NullCellOpen(&g_hCell, pStatus);
497 if (!nResult) {
498 g_LogFile.Write("Failed to open a NULL cell handle: %lx.\r\n", (unsigned long)*pStatus);
499 return FALSE;
503 // Get the server handle
504 g_LogFile.Write("Getting config library handle for the server.\r\n");
505 if (!cfg_HostOpen(g_hCell, GetHostnameA(), &g_hServer, pStatus)) {
506 g_LogFile.Write("Failed to get config library handle for the server: %lx.\r\n", (unsigned long)*pStatus);
507 return FALSE;
510 return TRUE;
513 BOOL GetHandles(HWND hParentDlg)
515 afs_status_t nStatus;
517 if (!GetLibHandles(&nStatus)) {
518 ShowError(hParentDlg, nStatus, IDS_GET_TOKENS_ERROR);
519 g_CfgData.szAdminPW[0] = 0;
520 return FALSE;
523 return TRUE;
528 * Static FUNCTIONS _________________________________________________________________
531 static void CloseLibHandles(BOOL bExiting)
533 afs_status_t nStatus;
535 // We will close them in the reverse order of their creation.
536 if (g_hServer) {
537 cfg_HostClose(g_hServer, &nStatus);
538 g_hServer = 0;
541 if (g_hCell) {
542 afsclient_CellClose(g_hCell, &nStatus);
543 g_hCell = 0;
546 if (g_hToken) {
547 afsclient_TokenClose(g_hToken, &nStatus);
548 g_hToken = 0;
551 // Only close the client cfg and cell handles if we are exiting.
552 if (bExiting) {
553 if (g_hClient) {
554 cfg_HostClose(g_hClient, &nStatus);
555 g_hClient = 0;
558 if (hClientCell) {
559 afsclient_CellClose(hClientCell, &nStatus);
560 hClientCell = 0;
565 static void SetConfigDefaults()
567 if (g_CfgData.bWizard) {
568 if (g_CfgData.configFS == CS_NULL)
569 g_CfgData.configFS = CS_CONFIGURE;
571 if (g_CfgData.configDB == CS_NULL)
572 g_CfgData.configDB = CS_CONFIGURE;
574 if (g_CfgData.configBak == CS_NULL)
575 g_CfgData.configBak = CS_CONFIGURE;
577 if (g_CfgData.configPartition == CS_NULL)
578 g_CfgData.configPartition = CS_CONFIGURE;
580 if (g_CfgData.configRootVolumes == CS_NULL)
581 g_CfgData.configRootVolumes = CS_CONFIGURE;
583 if (g_CfgData.configRep == CS_NULL)
584 g_CfgData.configRep = CS_CONFIGURE;
586 if (g_CfgData.configSCS == CS_NULL)
587 g_CfgData.configSCS = CS_DONT_CONFIGURE;
589 if (g_CfgData.configSCC == CS_NULL)
590 g_CfgData.configSCC = CS_DONT_CONFIGURE;
593 lstrcpy(g_CfgData.szAdminName, TEXT("admin"));
594 lstrcpy(g_CfgData.szAdminUID, TEXT("0"));
596 g_CfgData.bUseNextUid = TRUE;
600 // Prototypes for each property page's dialog proc
601 BOOL CALLBACK PartitionsPageDlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam);
602 BOOL CALLBACK ServicesPageDlgProc(HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM lParam);
604 static void RunCfgTool()
606 // If the client info is invalid, then the config tool cannot run. Inform the user and
607 // ask if they want to run the wizard instead.
608 if (!g_CfgData.bValidClientInfo) {
609 int nChoice = MsgBox(0, IDS_NEED_CLIENT_INFO, GetAppTitleID(), MB_YESNO | MB_ICONSTOP);
610 if (nChoice == IDYES)
611 RunWizard();
612 return;
615 // If the server info is invalid, then the config tool cannot run. The Wizard must be run
616 // to initially configure the server. Inform the user and ask if they want to run the wizard instead.
617 if (!g_CfgData.bValidServerInfo) {
618 int nChoice = MsgBox(0, IDS_NEED_SERVER_INFO, GetAppTitleID(), MB_OKCANCEL | MB_ICONEXCLAMATION);
619 if (nChoice == IDOK)
620 RunWizard();
621 return;
624 g_CfgData.bWizard = FALSE;
626 SetConfigDefaults();
628 RegisterConfigToolHelp();
630 // Create the prop sheet
631 g_pSheet = PropSheet_Create(IDS_CFG_TOOL_APP_TITLE, TRUE);
633 // Add the pages
634 PropSheet_AddTab(g_pSheet, IDS_PARTITIONS_PAGE_TITLE, IDD_PARTITIONS_PAGE, (DLGPROC)PartitionsPageDlgProc, 0, TRUE, TRUE);
635 PropSheet_AddTab(g_pSheet, IDS_SERVICES_PAGE_TITLE, IDD_SERVICES_PAGE, (DLGPROC)ServicesPageDlgProc, 0, TRUE);
637 // Let the user see it
638 PropSheet_ShowModal(g_pSheet);
641 static void RunWizard()
643 g_CfgData.bWizard = TRUE;
645 SetConfigDefaults();
647 RegisterWizardHelp();
649 g_pWiz = new WIZARD;
650 g_pWiz->SetDialogTemplate(IDD_WIZARD, IDC_WIZARD_LEFTPANE, IDC_WIZARD_RIGHTPANE, IDBACK, IDNEXT);
651 g_pWiz->SetGraphic(IDB_GRAPHIC_16, IDB_GRAPHIC_256);
652 g_pWiz->SetStates(g_aStates, g_nNumStates);
653 g_pWiz->SetGraphicCallback(PaintPageGraphic);
655 g_pWiz->SetState(sidSTEP_ONE);
656 g_pWiz->Show();
658 delete g_pWiz;
660 g_pWiz = 0;