Source code of Windows XP (NT5)
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.

733 lines
18 KiB

  1. /*
  2. * Registry keys for compat:
  3. * HKLM\System\CurrentControlSet\Control\Lsa\Kerberos\Domains
  4. * Keys:
  5. * <Realm>
  6. * Values:
  7. * REG_MULTI_SZ KdcNames
  8. * Names of KDCs for realm
  9. * REG_MULTI_SZ KpasswdNames
  10. * Names of Kpasswd servers for realm
  11. * REG_MULTI_SZ AlternateDomainNames
  12. * Other names for realm (aliases)
  13. * REG_DWORD RealmFlags
  14. * Send address = 1
  15. * TCP Supported = 2
  16. * Delegate ok = 4
  17. * REG_DWORD ApReqChecksumType
  18. * Default AP-REQ checksum type for this realm
  19. * REG_DWORD PreAuthType
  20. * Default preauth type for this realm
  21. *
  22. * HKLM\System\CurrentControlSet\Control\Lsa\Kerberos\UserList
  23. * Each value represents a Kerberos principal to be mapped to
  24. * a local user.
  25. * Values:
  26. * <principal name> : <local user>
  27. * Specific principal to this local user
  28. * <domain name> : <local user>
  29. * All users in this domain to this local user
  30. * '*' : <local user>
  31. * All users to this local user
  32. * '*' : '*'
  33. * All users to a corresponding local user by name
  34. *
  35. * HKLM\System\CurrentControlSet\Control\Lsa\Kerberos
  36. * Values:
  37. * REG_DWORD SkewTime (5 min)
  38. * Clock skew time
  39. * REG_DWORD MaxPacketSize (4000)
  40. * KerbGlobalMaxDatagramSize
  41. * REG_DWORD StartupTime (120 sec)
  42. * REG_DWORD KdcWaitTime (5 sec)
  43. * REG_DWORD KdcBackoffTime (5 sec)
  44. * REG_DWORD KdcSendRetries (3)
  45. * REG_DWORD UseSidCache (False)
  46. * REG_DWORD LogLevel (o)
  47. * KerbGlobalLoggingLevel
  48. * REG_DWORD DefaultEncryptionType (RC4_HMAC)
  49. * KerbGlobalDefaultPreauthEtype - Use this etype
  50. * for preauth data
  51. * REG_DWORD FarKdcTimeout (10 min)
  52. * REG_DWORD StronglyEncryptDatagram (False)
  53. * KerbGlobalUseStrongEncryptionForDatagram
  54. * REG_DWORD MaxReferralCount (6)
  55. * REG_DWORD SupportNewPkinit (True)
  56. */
  57. //#define UNICODE
  58. //#define _UNICODE
  59. #define STRICT
  60. #include <nt.h>
  61. #include <ntrtl.h>
  62. #include <nturtl.h>
  63. #include <windows.h>
  64. #include <memory.h>
  65. #include <stdlib.h>
  66. #include <string.h>
  67. #define ERR_NDI_LOW_MEM ERROR_NOT_ENOUGH_MEMORY
  68. #define OK ERROR_SUCCESS
  69. #include <commctrl.h>
  70. //#include <winnetwk.h>
  71. #include <stdarg.h>
  72. #define SECURITY_WIN32
  73. #include <security.h>
  74. //#include <ntsecapi.h>
  75. #include <wincrypt.h>
  76. #include <kerbcon.h>
  77. #include <kerbcomm.h>
  78. #include <secpkg.h>
  79. #include <kerbdefs.h>
  80. #include <mitutil.h>
  81. #include "kerbconf.h"
  82. #include "kerbconfres.h"
  83. HINSTANCE hInstance;
  84. krb5_rgy_t *rgy;
  85. LPTSTR default_domain;
  86. BOOL CALLBACK Krb5NdiRealmsProc(HWND, UINT, WPARAM, LPARAM);
  87. BOOL CALLBACK AddRealmProc(HWND, UINT, WPARAM, LPARAM);
  88. #define Message(s) \
  89. MessageBox(NULL, s, TEXT("Error"), MB_OK)
  90. #ifdef DBG
  91. #define DPRINTF(s) dprintf s
  92. int debug = 0;
  93. void dprintf(const TCHAR *fmt, ...)
  94. {
  95. static TCHAR szTemp[512];
  96. va_list ap;
  97. va_start (ap, fmt);
  98. wvsprintf(szTemp, fmt, ap);
  99. OutputDebugString(szTemp);
  100. if (debug)
  101. MessageBox(NULL, szTemp, TEXT("Debug"), MB_OK);
  102. va_end (ap);
  103. }
  104. #else
  105. #define DPRINTF(s)
  106. #endif
  107. #define PFREE(p) \
  108. if ((p)) { \
  109. free((p)); \
  110. (p) = NULL; \
  111. }
  112. void
  113. FreeRealm(krb5_realm_t *rp)
  114. {
  115. name_list_t *np, *cp;
  116. np = rp->kdc.lh_first;
  117. while(np) {
  118. cp = np;
  119. np = np->list.le_next;
  120. if (cp->name)
  121. free(cp->name);
  122. free(cp);
  123. }
  124. np = rp->kpasswd.lh_first;
  125. while(np) {
  126. cp = np;
  127. np = np->list.le_next;
  128. if (cp->name)
  129. free(cp->name);
  130. free(cp);
  131. }
  132. np = rp->altname.lh_first;
  133. while(np) {
  134. cp = np;
  135. np = np->list.le_next;
  136. if (cp->name)
  137. free(cp->name);
  138. free(cp);
  139. }
  140. free(rp);
  141. }
  142. void
  143. FreeRgy(krb5_rgy_t *rgy)
  144. {
  145. krb5_realm_t *rp, *crp;
  146. if (rgy) {
  147. rp = rgy->realms.lh_first;
  148. while(rp) {
  149. crp = rp;
  150. rp = rp->list.le_next;
  151. FreeRealm(crp);
  152. }
  153. free(rgy);
  154. }
  155. }
  156. DWORD
  157. RegGetInt(const HKEY hKey, LPCTSTR value)
  158. {
  159. DWORD retCode;
  160. DWORD dwType;
  161. DWORD dataLen;
  162. DWORD keyData;
  163. dataLen = sizeof(keyData);
  164. retCode = RegQueryValueEx(hKey, value, 0,
  165. &dwType, (LPBYTE)&keyData, &dataLen);
  166. if (retCode == ERROR_SUCCESS &&
  167. dwType == REG_DWORD) {
  168. return(keyData);
  169. }
  170. return((DWORD)-1);
  171. }
  172. DWORD
  173. RegSetInt(LPCTSTR key, const DWORD val)
  174. {
  175. HKEY hKey;
  176. DWORD retCode = (DWORD)-1;
  177. retCode = RegCreateKey(HKEY_LOCAL_MACHINE,
  178. REGKEY,
  179. &hKey);
  180. if (retCode == ERROR_SUCCESS) {
  181. retCode = RegSetValueEx(hKey, key, 0,
  182. REG_DWORD, (LPBYTE)&val, sizeof(val));
  183. if (retCode == ERROR_SUCCESS) {
  184. RegCloseKey(hKey);
  185. return(0);
  186. }
  187. }
  188. RegCloseKey(hKey);
  189. return(retCode);
  190. }
  191. LPTSTR
  192. RegGetStr(const HKEY hKey, LPCTSTR value)
  193. {
  194. DWORD retCode;
  195. DWORD dwType;
  196. DWORD dataLen;
  197. LPBYTE keyData = NULL;
  198. dataLen = 0;
  199. retCode = RegQueryValueEx(hKey, value, 0,
  200. &dwType, (LPBYTE)NULL, &dataLen);
  201. if (retCode == ERROR_SUCCESS) {
  202. keyData = malloc(dataLen);
  203. if (!keyData)
  204. return(NULL);
  205. retCode = RegQueryValueEx(hKey, value, 0,
  206. &dwType, keyData, &dataLen);
  207. if (retCode == ERROR_SUCCESS) {
  208. return((LPTSTR)keyData);
  209. }
  210. }
  211. if (keyData)
  212. free(keyData);
  213. return(NULL);
  214. }
  215. DWORD
  216. RegSetStr(LPCTSTR key, LPCTSTR val, INT len)
  217. {
  218. HKEY hKey;
  219. DWORD retCode = (DWORD)-1;
  220. if (len == 0)
  221. len = lstrlen(val) + 1;
  222. retCode = RegCreateKey(HKEY_LOCAL_MACHINE,
  223. REGKEY,
  224. &hKey);
  225. if (retCode == ERROR_SUCCESS) {
  226. retCode = RegSetValueEx(hKey, key, 0,
  227. ((lstrlen(val)+1) != len)?
  228. REG_MULTI_SZ:REG_SZ,
  229. (LPBYTE)val, len);
  230. if (retCode == ERROR_SUCCESS) {
  231. RegCloseKey(hKey);
  232. return(0);
  233. }
  234. }
  235. RegCloseKey(hKey);
  236. return(retCode);
  237. }
  238. DWORD
  239. RegDelete(LPCTSTR key)
  240. {
  241. HKEY hKey;
  242. DWORD retCode;
  243. retCode = RegOpenKey(HKEY_LOCAL_MACHINE,
  244. REGKEY,
  245. &hKey);
  246. if (retCode == ERROR_SUCCESS)
  247. retCode = RegDeleteValue(hKey, key);
  248. RegCloseKey(hKey);
  249. return(retCode);
  250. }
  251. LPTSTR
  252. lstrdup(LPCTSTR s)
  253. {
  254. LPTSTR sp;
  255. sp = malloc(lstrlen(s)*sizeof(TCHAR));
  256. if (sp) {
  257. lstrcpy(sp, s);
  258. }
  259. return sp;
  260. }
  261. // Read in krb5 conf properties and attach to ndi object
  262. UINT
  263. Krb5NdiCreate(void)
  264. {
  265. LPTSTR pStr, key;
  266. HKEY hKey, hKeyRealm;
  267. DWORD retCode;
  268. DWORD i, dwVal;
  269. static TCHAR FAR keyValue[255], valData[255];
  270. DWORD keyLen;
  271. PPOLICY_DNS_DOMAIN_INFO DnsDomainInfo = NULL;
  272. rgy = (krb5_rgy_t *)malloc(sizeof(krb5_rgy_t));
  273. if (!rgy)
  274. return ERR_NDI_LOW_MEM;
  275. memset(rgy, 0, sizeof(krb5_rgy_t));
  276. retCode = RegOpenKey(HKEY_LOCAL_MACHINE,
  277. KERB_DOMAINS_KEY,
  278. &hKey);
  279. if (retCode == ERROR_SUCCESS) {
  280. krb5_realm_t *pRealm;
  281. name_list_t *pName;
  282. for (i = 0; retCode == ERROR_SUCCESS; i++) {
  283. keyLen = sizeof(keyValue);
  284. retCode = RegEnumKey(hKey, i, keyValue, keyLen);
  285. if (retCode != ERROR_SUCCESS)
  286. continue;
  287. pRealm = NewRealm(lstrlen(keyValue)+1);
  288. if (!pRealm) {
  289. RegCloseKey(hKey);
  290. return ERR_NDI_LOW_MEM;
  291. }
  292. lstrcpy((LPTSTR)&pRealm->name, keyValue);
  293. key = (LPTSTR)malloc(lstrlen(REGKEY)+10+lstrlen(keyValue));
  294. if (!key) {
  295. RegCloseKey(hKey);
  296. return ERR_NDI_LOW_MEM;
  297. }
  298. lstrcpy(key, KERB_DOMAINS_KEY TEXT("\\"));
  299. lstrcat((LPTSTR)key, keyValue);
  300. retCode = RegOpenKey(HKEY_LOCAL_MACHINE,
  301. key,
  302. &hKeyRealm);
  303. if (retCode == ERROR_SUCCESS) {
  304. pStr = RegGetStr(hKeyRealm, KERB_DOMAIN_KDC_NAMES_VALUE);
  305. while (pStr && *pStr) {
  306. pName = NewNameList();
  307. if (!pName) {
  308. RegCloseKey(hKeyRealm);
  309. RegCloseKey(hKey);
  310. return ERR_NDI_LOW_MEM;
  311. }
  312. pName->name = lstrdup(pStr);
  313. LIST_INSERT_HEAD(&pRealm->kdc, pName, list);
  314. pStr += lstrlen(pStr)+1;
  315. }
  316. pStr = RegGetStr(hKeyRealm, KERB_DOMAIN_KPASSWD_NAMES_VALUE);
  317. while (pStr && *pStr) {
  318. pName = NewNameList();
  319. if (!pName) {
  320. RegCloseKey(hKeyRealm);
  321. RegCloseKey(hKey);
  322. return ERR_NDI_LOW_MEM;
  323. }
  324. pName->name = lstrdup(pStr);
  325. LIST_INSERT_HEAD(&pRealm->kpasswd, pName, list);
  326. pStr += lstrlen(pStr)+1;
  327. }
  328. pStr = RegGetStr(hKeyRealm, KERB_DOMAIN_ALT_NAMES_VALUE);
  329. while (pStr && *pStr) {
  330. pName = NewNameList();
  331. if (!pName) {
  332. RegCloseKey(hKeyRealm);
  333. RegCloseKey(hKey);
  334. return ERR_NDI_LOW_MEM;
  335. }
  336. pName->name = lstrdup(pStr);
  337. LIST_INSERT_HEAD(&pRealm->altname, pName, list);
  338. pStr += lstrlen(pStr)+1;
  339. }
  340. dwVal = RegGetInt(hKeyRealm, KERB_DOMAIN_FLAGS_VALUE);
  341. if (dwVal == -1) {
  342. dwVal = 0;
  343. }
  344. pRealm->realm_flags = dwVal;
  345. dwVal = RegGetInt(hKeyRealm, KERB_DOMAIN_AP_REQ_CSUM_VALUE);
  346. if (dwVal == -1) {
  347. dwVal = KERB_DEFAULT_AP_REQ_CSUM;
  348. }
  349. pRealm->ap_req_chksum = dwVal;
  350. dwVal = RegGetInt(hKeyRealm, KERB_DOMAIN_PREAUTH_VALUE);
  351. if (dwVal == -1) {
  352. dwVal = KERB_DEFAULT_PREAUTH_TYPE;
  353. }
  354. pRealm->preauth_type = dwVal;
  355. RegCloseKey(hKeyRealm);
  356. free(key);
  357. }
  358. LIST_INSERT_HEAD(&rgy->realms, pRealm, list);
  359. }
  360. RegCloseKey(hKey);
  361. //
  362. }
  363. #if 1
  364. retCode = RegOpenKey(HKEY_LOCAL_MACHINE,
  365. TEXT("System\\CurrentControlSet\\Services\\Tcpip\\Parameters"),
  366. &hKey);
  367. if (retCode == ERROR_SUCCESS) {
  368. default_domain = RegGetStr(hKey, TEXT("Domain"));
  369. RegCloseKey(hKey);
  370. }
  371. #else
  372. retCode = LsaQueryInformationPolicy(
  373. LsaHandle,
  374. PolicyDnsDomainInformation,
  375. (PVOID *) &DnsDomainInfo
  376. );
  377. if (!NT_SUCCESS(retCode))
  378. {
  379. printf("Failed to query dns domain info: 0x%x\n",Status);
  380. goto Cleanup;
  381. }
  382. if ( DnsDomainInfo->DnsDomainName.Length == 0 ) {
  383. printf("Machine is not configured to log on to an external KDC. Probably a workgroup member\n");
  384. goto Cleanup;
  385. } else { // nonempty dns domain, but no sid. Assume we're in an RFC1510 domain.
  386. printf( "default realm = %wZ ",
  387. &DnsDomainInfo->DnsDomainName );
  388. if ( DnsDomainInfo->Sid != NULL ) {
  389. printf( "(NT Domain)\n" );
  390. } else {
  391. printf( "(external)\n" );
  392. }
  393. #endif
  394. return OK;
  395. }
  396. /* Write out any conf parameters */
  397. static void
  398. SaveRealm(krb5_realm_t *rp)
  399. {
  400. name_list_t *np;
  401. DPRINTF((TEXT("\n%s: %s\n\t"), rp->name, KERB_DOMAIN_KDC_NAMES_VALUE));
  402. for (np = rp->kdc.lh_first; np; np = np->list.le_next) {
  403. DPRINTF((TEXT("%s "), np->name));
  404. }
  405. DPRINTF((TEXT("\n%s: %s\n\t"), rp->name, KERB_DOMAIN_KPASSWD_NAMES_VALUE));
  406. for (np = rp->kpasswd.lh_first; np; np = np->list.le_next) {
  407. DPRINTF((TEXT("%s "), np->name));
  408. }
  409. DPRINTF((TEXT("\n%s: %s\n\t"), rp->name, KERB_DOMAIN_ALT_NAMES_VALUE));
  410. for (np = rp->altname.lh_first; np; np = np->list.le_next) {
  411. DPRINTF((TEXT("%s "), np->name));
  412. }
  413. DPRINTF((TEXT("\n%s: 0x%x\n"), KERB_DOMAIN_FLAGS_VALUE,
  414. rp->realm_flags));
  415. DPRINTF((TEXT("\n%s: 0x%x\n"), KERB_DOMAIN_AP_REQ_CSUM_VALUE,
  416. rp->ap_req_chksum));
  417. DPRINTF((TEXT("\n%s: 0x%x\n"), KERB_DOMAIN_PREAUTH_VALUE,
  418. rp->preauth_type));
  419. }
  420. UINT
  421. Krb5NdiInstall(krb5_rgy_t *rgy)
  422. {
  423. krb5_realm_t *rp;
  424. if (rgy) {
  425. DPRINTF((TEXT("Realms\n")));
  426. for (rp = rgy->realms.lh_first; rp; rp = rp->list.le_next) {
  427. DPRINTF((TEXT("%s\n"), rp->name));
  428. SaveRealm(rp);
  429. }
  430. }
  431. return OK;
  432. }
  433. /* Destroy any conf parameters */
  434. UINT
  435. Krb5NdiDestroy(krb5_rgy_t *rgy)
  436. {
  437. FreeRgy(rgy);
  438. return OK;
  439. }
  440. void
  441. ShowRealm(HWND hDlg)
  442. {
  443. int idx;
  444. krb5_realm_t *pRealm;
  445. name_list_t *pNlist;
  446. SendDlgItemMessage(hDlg, IDC_REALM_KDC, CB_RESETCONTENT, 0, 0L);
  447. SendDlgItemMessage(hDlg, IDC_REALM_ADMIN, CB_RESETCONTENT, 0, 0L);
  448. SendDlgItemMessage(hDlg, IDC_REALM_ALT_NAMES, CB_RESETCONTENT, 0, 0L);
  449. SetDlgItemText(hDlg, IDC_REALM_DEF_DOMAIN, TEXT(""));
  450. idx = (int)SendDlgItemMessage(hDlg, IDC_REALMS, LB_GETCURSEL, 0, 0L);
  451. if (idx == LB_ERR)
  452. return;
  453. pRealm = (krb5_realm_t FAR *)SendDlgItemMessage(hDlg, IDC_REALMS,
  454. LB_GETITEMDATA, idx, 0L);
  455. for (pNlist = pRealm->kdc.lh_first; pNlist; pNlist = pNlist->list.le_next) {
  456. idx = SendDlgItemMessage(hDlg, IDC_REALM_KDC, CB_ADDSTRING, 0,
  457. (LPARAM)pNlist->name);
  458. SetDlgItemText(hDlg, IDC_REALM_KDC, pNlist->name);
  459. SendDlgItemMessage(hDlg, IDC_REALM_KDC, CB_SETITEMDATA, idx,
  460. (LPARAM)(name_list_t FAR *)pNlist);
  461. }
  462. for (pNlist = pRealm->kpasswd.lh_first; pNlist; pNlist = pNlist->list.le_next) {
  463. idx = SendDlgItemMessage(hDlg, IDC_REALM_ADMIN, CB_ADDSTRING, 0,
  464. (LPARAM)pNlist->name);
  465. SetDlgItemText(hDlg, IDC_REALM_ADMIN, pNlist->name);
  466. SendDlgItemMessage(hDlg, IDC_REALM_ADMIN, CB_SETITEMDATA, idx,
  467. (LPARAM)(name_list_t FAR *)pNlist);
  468. }
  469. for (pNlist = pRealm->altname.lh_first; pNlist; pNlist = pNlist->list.le_next) {
  470. idx = SendDlgItemMessage(hDlg, IDC_REALM_ALT_NAMES, CB_ADDSTRING, 0,
  471. (LPARAM)pNlist->name);
  472. SetDlgItemText(hDlg, IDC_REALM_ALT_NAMES, pNlist->name);
  473. SendDlgItemMessage(hDlg, IDC_REALM_ALT_NAMES, CB_SETITEMDATA, idx,
  474. (LPARAM)(name_list_t FAR *)pNlist);
  475. }
  476. CheckDlgButton(hDlg, IDC_KDC_TCP,
  477. (pRealm->realm_flags & KERB_MIT_REALM_TCP_SUPPORTED)?
  478. BST_CHECKED:BST_UNCHECKED);
  479. CheckDlgButton(hDlg, IDC_ADDRREQ,
  480. (pRealm->realm_flags & KERB_MIT_REALM_SEND_ADDRESS)?
  481. BST_CHECKED:BST_UNCHECKED);
  482. CheckDlgButton(hDlg, IDC_KDC_DELEG,
  483. (pRealm->realm_flags & KERB_MIT_REALM_TRUSTED_FOR_DELEGATION)?
  484. BST_CHECKED:BST_UNCHECKED);
  485. CheckDlgButton(hDlg, IDC_KDC_CANONICALIZE,
  486. (pRealm->realm_flags & KERB_MIT_REALM_DOES_CANONICALIZE)?
  487. BST_CHECKED:BST_UNCHECKED);
  488. SetDlgItemInt(hDlg, IDC_CHKSUM, pRealm->ap_req_chksum, FALSE);
  489. SetDlgItemText(hDlg, IDC_REALM_DEF_DOMAIN,
  490. STRDEF(default_domain, TEXT("")));
  491. }
  492. BOOL CALLBACK
  493. AddRealmProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
  494. {
  495. TCHAR realm_name[255];
  496. krb5_realm_t *pRealm;
  497. switch (message) {
  498. case WM_INITDIALOG:
  499. SetFocus(GetDlgItem(hDlg, IDC_NEW_REALM));
  500. return 0;
  501. case WM_COMMAND:
  502. switch (LOWORD(wParam)) {
  503. case IDOK:
  504. GetDlgItemText(hDlg, IDC_NEW_REALM,
  505. realm_name, sizeof(realm_name));
  506. pRealm = NewRealm(lstrlen(realm_name));
  507. if (pRealm)
  508. lstrcpy(pRealm->name, realm_name);
  509. EndDialog(hDlg, (int)pRealm);
  510. return TRUE;
  511. case IDCANCEL:
  512. EndDialog(hDlg, 0);
  513. return TRUE;
  514. }
  515. break;
  516. }
  517. return FALSE;
  518. }
  519. void
  520. AddRealm(HWND hDlg, krb5_rgy_t *rgy)
  521. {
  522. krb5_realm_t *pRealm;
  523. if (pRealm = (krb5_realm_t *) DialogBox(hInstance,
  524. MAKEINTRESOURCE(IDD_REALM_ADD),
  525. hDlg,
  526. AddRealmProc)) {
  527. int idx;
  528. LIST_INSERT_HEAD(&rgy->realms, pRealm, list);
  529. idx = SendDlgItemMessage(hDlg, IDC_REALMS, LB_ADDSTRING, 0,
  530. (LPARAM)(LPSTR)pRealm->name);
  531. SendDlgItemMessage(hDlg, IDC_REALMS, LB_SETITEMDATA, idx,
  532. (LPARAM)(krb5_realm_t FAR *)pRealm);
  533. SendDlgItemMessage(hDlg, IDC_REALMS, LB_SETCURSEL, idx, 0L);
  534. ShowRealm(hDlg);
  535. }
  536. }
  537. void
  538. RemoveRealm(HWND hDlg)
  539. {
  540. TCHAR *msg;
  541. int idx;
  542. krb5_realm_t *pRealm;
  543. idx = (int) SendDlgItemMessage(hDlg, IDC_REALMS, LB_GETCURSEL, 0, 0L);
  544. pRealm = (krb5_realm_t FAR *)SendDlgItemMessage(hDlg, IDC_REALMS,
  545. LB_GETITEMDATA, idx, 0L);
  546. #define FMT TEXT("You are about to remove the realm \"%s\"\n\rDo you want to continue ?")
  547. msg = malloc(lstrlen(FMT) + lstrlen(pRealm->name));
  548. if (!msg)
  549. return;
  550. wsprintf(msg, FMT, pRealm->name);
  551. #undef FMT
  552. if (MessageBox(hDlg, msg, TEXT("Confirm Delete"),
  553. MB_YESNO|MB_ICONEXCLAMATION|MB_DEFBUTTON2|MB_SETFOREGROUND) == IDYES) {
  554. idx = SendDlgItemMessage(hDlg, IDC_REALMS, LB_DELETESTRING, idx, 0L);
  555. LIST_REMOVE(pRealm, list);
  556. FreeRealm(pRealm);
  557. SendDlgItemMessage(hDlg, IDC_REALMS, CB_SETCURSEL, 0, 0L);
  558. ShowRealm(hDlg);
  559. }
  560. free(msg);
  561. }
  562. BOOL CALLBACK
  563. Krb5NdiRealmsProc(HWND hDlg, UINT message, WPARAM wParam, LPARAM lParam)
  564. {
  565. static PROPSHEETPAGE *ps;
  566. krb5_realm_t *pRealm;
  567. switch (message) {
  568. case WM_INITDIALOG:
  569. for (pRealm = rgy->realms.lh_first; pRealm; pRealm = pRealm->list.le_next) {
  570. int idx = SendDlgItemMessage(hDlg, IDC_REALMS, LB_ADDSTRING, 0,
  571. (LPARAM)(LPSTR)pRealm->name);
  572. SendDlgItemMessage(hDlg, IDC_REALMS, LB_SETITEMDATA, idx,
  573. (LPARAM)(krb5_realm_t FAR *)pRealm);
  574. }
  575. SendDlgItemMessage(hDlg, IDC_REALMS, LB_SETCURSEL, 0, 0L);
  576. ShowRealm(hDlg);
  577. ps = (PROPSHEETPAGE *)lParam;
  578. return TRUE;
  579. case WM_COMMAND:
  580. switch (LOWORD(wParam)) {
  581. case IDC_REALMS:
  582. switch (HIWORD(wParam)) {
  583. case LBN_SELCHANGE:
  584. ShowRealm(hDlg);
  585. break;
  586. }
  587. return 0;
  588. /* NOTREACHED */
  589. case IDC_REALM_ADD:
  590. AddRealm(hDlg, rgy);
  591. break;
  592. case IDC_REALM_REMOVE:
  593. RemoveRealm(hDlg);
  594. break;
  595. }
  596. break;
  597. case WM_NOTIFY:
  598. switch (((NMHDR *)lParam)->code) {
  599. case PSN_SETACTIVE:
  600. case PSN_RESET:
  601. /* reset button states */
  602. if (((NMHDR *)lParam)->code == PSN_RESET)
  603. SetWindowLong(hDlg, DWL_MSGRESULT, FALSE);
  604. break;
  605. case PSN_APPLY:
  606. /* Save the settings */
  607. SetWindowLong(hDlg, DWL_MSGRESULT, TRUE);
  608. break;
  609. case PSN_KILLACTIVE:
  610. SetWindowLong(hDlg, DWL_MSGRESULT, FALSE);
  611. return 1;
  612. }
  613. break;
  614. }
  615. return FALSE;
  616. }
  617. int WINAPI
  618. WinMain(HINSTANCE hInst, HINSTANCE hPrevInst, LPSTR lpszCmdLn, int nShowCmd)
  619. {
  620. PROPSHEETHEADER psh;
  621. PROPSHEETPAGE psp[1];
  622. int err = 0;
  623. hInstance = hInst;
  624. if ((err = Krb5NdiCreate()) != OK)
  625. return err;
  626. psp[0].dwSize = sizeof(PROPSHEETPAGE);
  627. psp[0].dwFlags = 0;
  628. psp[0].hInstance = hInst;
  629. psp[0].pszTemplate = MAKEINTRESOURCE(IDD_REALMS);
  630. psp[0].pszIcon = NULL;
  631. psp[0].pfnDlgProc = (DLGPROC)Krb5NdiRealmsProc;
  632. psp[0].lParam = (LPARAM)rgy;
  633. psh.dwSize = sizeof(PROPSHEETHEADER);
  634. psh.dwFlags = PSH_PROPSHEETPAGE | PSH_NOAPPLYNOW;
  635. psh.hwndParent = NULL;
  636. psh.hInstance = hInst;
  637. psh.pszIcon = NULL;
  638. psh.pszCaption = (LPTSTR)TEXT("Kerberos v5 Configuration");
  639. psh.pStartPage = 0;
  640. psh.nPages = sizeof(psp)/sizeof(psp[0]);
  641. psh.ppsp = (LPCPROPSHEETPAGE)&psp;
  642. if (PropertySheet(&psh))
  643. Krb5NdiInstall(rgy);
  644. Krb5NdiDestroy(rgy);
  645. return err;
  646. }