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.

886 lines
25 KiB

  1. /*++
  2. Copyright (c) 1996 Microsoft Corporation
  3. Module Name:
  4. kerberos.cpp
  5. Abstract:
  6. Routines to read/write/configure kerberos policy settings
  7. The following modules have links to kerberos policy
  8. scejet.c <SceJetAddSection>
  9. inftojet.c <SceConvertpInfKeyValue>
  10. pfget.c <ScepGetKerberosPolicy>
  11. config.c <ScepConfigureKerberosPolicy>
  12. analyze.c <ScepAnalyzeKerberosPolicy>
  13. Author:
  14. Jin Huang (jinhuang) 17-Dec-1997
  15. Revision History:
  16. jinhuang 28-Jan-1998 splitted to client-server
  17. --*/
  18. #include "headers.h"
  19. #include "serverp.h"
  20. #include "kerberos.h"
  21. #include "kerbcon.h"
  22. #include "pfp.h"
  23. #define MAXDWORD 0xffffffff
  24. static PWSTR KerbItems[] = {
  25. {(PWSTR)TEXT("MaxTicketAge")},
  26. {(PWSTR)TEXT("MaxRenewAge")},
  27. {(PWSTR)TEXT("MaxServiceAge")},
  28. {(PWSTR)TEXT("MaxClockSkew")},
  29. {(PWSTR)TEXT("TicketValidateClient")}
  30. };
  31. #define MAX_KERB_ITEMS 5
  32. #define IDX_KERB_MAX 0
  33. #define IDX_KERB_RENEW 1
  34. #define IDX_KERB_SERVICE 2
  35. #define IDX_KERB_CLOCK 3
  36. #define IDX_KERB_VALIDATE 4
  37. SCESTATUS
  38. ScepGetKerberosPolicy(
  39. IN PSCECONTEXT hProfile,
  40. IN SCETYPE ProfileType,
  41. OUT PSCE_KERBEROS_TICKET_INFO * ppKerberosInfo,
  42. OUT PSCE_ERROR_LOG_INFO *Errlog OPTIONAL
  43. )
  44. /*++
  45. Routine Description:
  46. This routine retrieves kerberos policy information from the Jet database
  47. and stores in the output buffer ppKerberosInfo.
  48. Arguments:
  49. hProfile - The profile handle context
  50. ppKerberosInfo - the output buffer to hold kerberos settings.
  51. Errlog - A buffer to hold all error codes/text encountered when
  52. parsing the INF file. If Errlog is NULL, no further error
  53. information is returned except the return DWORD
  54. Return value:
  55. SCESTATUS - SCESTATUS_SUCCESS
  56. SCESTATUS_NOT_ENOUGH_RESOURCE
  57. SCESTATUS_INVALID_PARAMETER
  58. SCESTATUS_BAD_FORMAT
  59. SCESTATUS_INVALID_DATA
  60. --*/
  61. {
  62. SCESTATUS rc;
  63. PSCESECTION hSection=NULL;
  64. SCE_KEY_LOOKUP AccessKeys[] = {
  65. {(PWSTR)TEXT("MaxTicketAge"), offsetof(struct _SCE_KERBEROS_TICKET_INFO_, MaxTicketAge), 'D'},
  66. {(PWSTR)TEXT("MaxRenewAge"), offsetof(struct _SCE_KERBEROS_TICKET_INFO_, MaxRenewAge), 'D'},
  67. {(PWSTR)TEXT("MaxServiceAge"), offsetof(struct _SCE_KERBEROS_TICKET_INFO_, MaxServiceAge), 'D'},
  68. {(PWSTR)TEXT("MaxClockSkew"), offsetof(struct _SCE_KERBEROS_TICKET_INFO_, MaxClockSkew), 'D'},
  69. {(PWSTR)TEXT("TicketValidateClient"), offsetof(struct _SCE_KERBEROS_TICKET_INFO_, TicketValidateClient), 'D'}
  70. };
  71. DWORD cKeys = sizeof(AccessKeys) / sizeof(SCE_KEY_LOOKUP);
  72. SCE_KERBEROS_TICKET_INFO TicketInfo;
  73. if ( ppKerberosInfo == NULL ) {
  74. return(SCESTATUS_INVALID_PARAMETER);
  75. }
  76. rc = ScepGetFixValueSection(
  77. hProfile,
  78. szKerberosPolicy,
  79. AccessKeys,
  80. cKeys,
  81. ProfileType,
  82. (PVOID)&TicketInfo,
  83. &hSection,
  84. Errlog
  85. );
  86. if ( rc != SCESTATUS_SUCCESS ) {
  87. return(rc);
  88. }
  89. //
  90. // copy the value in TicketInfo to ppKerberosInfo
  91. //
  92. if ( NULL == *ppKerberosInfo ) {
  93. *ppKerberosInfo = (PSCE_KERBEROS_TICKET_INFO)ScepAlloc(0, sizeof(SCE_KERBEROS_TICKET_INFO));
  94. }
  95. if ( *ppKerberosInfo ) {
  96. memcpy(*ppKerberosInfo, &TicketInfo, sizeof(SCE_KERBEROS_TICKET_INFO));
  97. } else {
  98. rc = SCESTATUS_NOT_ENOUGH_RESOURCE;
  99. }
  100. SceJetCloseSection(&hSection, TRUE);
  101. return(rc);
  102. }
  103. #if _WIN32_WINNT>=0x0500
  104. SCESTATUS
  105. ScepConfigureKerberosPolicy(
  106. IN PSCECONTEXT hProfile,
  107. IN PSCE_KERBEROS_TICKET_INFO pKerberosInfo,
  108. IN DWORD ConfigOptions
  109. )
  110. /* ++
  111. Routine Description:
  112. This routine configure the kerberos policy settings in the area of security
  113. policy.
  114. Arguments:
  115. pKerberosInfo - The buffer which contains kerberos policy settings
  116. Return value:
  117. SCESTATUS_SUCCESS
  118. SCESTATUS_NOT_ENOUGH_RESOURCE
  119. SCESTATUS_INVALID_PARAMETER
  120. SCESTATUS_OTHER_ERROR
  121. -- */
  122. {
  123. if ( !pKerberosInfo ) {
  124. //
  125. // if no info to configure
  126. //
  127. return SCESTATUS_SUCCESS;
  128. }
  129. NTSTATUS NtStatus;
  130. LSA_HANDLE lsaHandle=NULL;
  131. DWORD rc = NO_ERROR;
  132. BOOL bDefaultUsed=FALSE;
  133. BOOL bDefined=FALSE;
  134. //
  135. // open LSA policy to configure kerberos policy
  136. //
  137. NtStatus = ScepOpenLsaPolicy(
  138. MAXIMUM_ALLOWED,
  139. &lsaHandle,
  140. TRUE
  141. );
  142. if (!NT_SUCCESS(NtStatus)) {
  143. lsaHandle = NULL;
  144. rc = RtlNtStatusToDosError( NtStatus );
  145. ScepLogOutput3( 1, rc, SCEDLL_LSA_POLICY);
  146. if ( ConfigOptions & SCE_RSOP_CALLBACK )
  147. ScepRsopLog(SCE_RSOP_KERBEROS_INFO, rc, NULL, 0, 0);
  148. return(ScepDosErrorToSceStatus(rc));
  149. }
  150. //
  151. // query current kerberos policy settings into pBuffer
  152. //
  153. PPOLICY_DOMAIN_KERBEROS_TICKET_INFO pBuffer=NULL;
  154. POLICY_DOMAIN_KERBEROS_TICKET_INFO TicketInfo;
  155. NtStatus = LsaQueryDomainInformationPolicy(
  156. lsaHandle,
  157. PolicyDomainKerberosTicketInformation,
  158. (PVOID *)&pBuffer
  159. );
  160. if ( NT_SUCCESS(NtStatus) && pBuffer ) {
  161. //
  162. // transfer ticket info to TicketInfo buffer
  163. //
  164. TicketInfo.AuthenticationOptions = pBuffer->AuthenticationOptions;
  165. TicketInfo.MaxTicketAge = pBuffer->MaxTicketAge;
  166. TicketInfo.MaxRenewAge = pBuffer->MaxRenewAge;
  167. TicketInfo.MaxServiceTicketAge = pBuffer->MaxServiceTicketAge;
  168. TicketInfo.MaxClockSkew = pBuffer->MaxClockSkew;
  169. //
  170. // free the buffer
  171. //
  172. LsaFreeMemory((PVOID)pBuffer);
  173. } else {
  174. //
  175. // no kerberos policy is configured yet because by default it's not created.
  176. // let's create it now. set a default ticket info
  177. //
  178. TicketInfo.AuthenticationOptions = POLICY_KERBEROS_VALIDATE_CLIENT;
  179. TicketInfo.MaxTicketAge.QuadPart = (LONGLONG) KERBDEF_MAX_TICKET*60*60 * 10000000L;
  180. TicketInfo.MaxRenewAge.QuadPart = (LONGLONG) KERBDEF_MAX_RENEW*24*60*60 * 10000000L;
  181. TicketInfo.MaxServiceTicketAge.QuadPart = (LONGLONG) KERBDEF_MAX_SERVICE*60 * 10000000L;
  182. TicketInfo.MaxClockSkew.QuadPart = (LONGLONG) KERBDEF_MAX_CLOCK*60 * 10000000L;
  183. bDefaultUsed = TRUE;
  184. }
  185. pBuffer = &TicketInfo;
  186. //
  187. // process each field in pKerberosInfo
  188. //
  189. BOOL bFlagSet=FALSE;
  190. ULONG lOptions=0;
  191. ULONG lValue=0;
  192. SCE_TATTOO_KEYS *pTattooKeys=NULL;
  193. DWORD cTattooKeys=0;
  194. PSCESECTION hSectionDomain=NULL;
  195. PSCESECTION hSectionTattoo=NULL;
  196. #define MAX_KERB_KEYS 5
  197. //
  198. // if in policy propagation, open the policy sections
  199. // since kerberos policy is only available on DCs and kerberos policy (account policy)
  200. // can't be reset to local settings on each DC, there is no point to query/save
  201. // the tattoo values
  202. //
  203. /* do not take tattoo value for kerberos
  204. if ( (ConfigOptions & SCE_POLICY_TEMPLATE) &&
  205. hProfile ) {
  206. pTattooKeys = (SCE_TATTOO_KEYS *)ScepAlloc(LPTR,MAX_KERB_KEYS*sizeof(SCE_TATTOO_KEYS));
  207. if ( !pTattooKeys ) {
  208. ScepLogOutput3(1, ERROR_NOT_ENOUGH_MEMORY, SCESRV_POLICY_TATTOO_ERROR_CREATE);
  209. }
  210. }
  211. */
  212. if ( pKerberosInfo->MaxRenewAge != SCE_NO_VALUE ) {
  213. ScepTattooCheckAndUpdateArray(pTattooKeys, &cTattooKeys,
  214. (PWSTR)L"MaxRenewAge", ConfigOptions,
  215. KERBDEF_MAX_RENEW);
  216. }
  217. if ( pKerberosInfo->MaxRenewAge == SCE_FOREVER_VALUE ) {
  218. if ( pBuffer->MaxRenewAge.HighPart != MINLONG ||
  219. pBuffer->MaxRenewAge.LowPart != 0 ) {
  220. //
  221. // Maximum LARGE_INTEGER .ie. never
  222. //
  223. pBuffer->MaxRenewAge.HighPart = MINLONG;
  224. pBuffer->MaxRenewAge.LowPart = 0;
  225. bFlagSet = TRUE;
  226. }
  227. bDefined = TRUE;
  228. } else if ( SCE_NO_VALUE != pKerberosInfo->MaxRenewAge ) {
  229. //
  230. // ticket is renewable, the max age is stored in MaxRenewAge
  231. // using days
  232. //
  233. lValue = (DWORD) (pBuffer->MaxRenewAge.QuadPart /
  234. (LONGLONG)(10000000L) );
  235. lValue /= 3600;
  236. lValue /= 24;
  237. if ( lValue != pKerberosInfo->MaxRenewAge ) {
  238. pBuffer->MaxRenewAge.QuadPart = (LONGLONG)pKerberosInfo->MaxRenewAge*24*3600 * 10000000L;
  239. bFlagSet = TRUE;
  240. }
  241. bDefined = TRUE;
  242. }
  243. //
  244. // validate client ?
  245. //
  246. if ( pKerberosInfo->TicketValidateClient != SCE_NO_VALUE ) {
  247. if ( pKerberosInfo->TicketValidateClient ) {
  248. lOptions |= POLICY_KERBEROS_VALIDATE_CLIENT;
  249. }
  250. ScepTattooCheckAndUpdateArray(pTattooKeys, &cTattooKeys,
  251. (PWSTR)L"TicketValidateClient", ConfigOptions,
  252. KERBDEF_VALIDATE);
  253. if ( ( pBuffer->AuthenticationOptions & POLICY_KERBEROS_VALIDATE_CLIENT ) !=
  254. ( lOptions & POLICY_KERBEROS_VALIDATE_CLIENT ) ) {
  255. pBuffer->AuthenticationOptions = lOptions;
  256. bFlagSet = TRUE;
  257. }
  258. bDefined = TRUE;
  259. }
  260. //
  261. // max ticket age
  262. //
  263. if ( pKerberosInfo->MaxTicketAge != SCE_NO_VALUE ) {
  264. ScepTattooCheckAndUpdateArray(pTattooKeys, &cTattooKeys,
  265. (PWSTR)L"MaxTicketAge", ConfigOptions,
  266. KERBDEF_MAX_TICKET);
  267. bDefined = TRUE;
  268. }
  269. if ( pKerberosInfo->MaxTicketAge == SCE_FOREVER_VALUE ) {
  270. if ( pBuffer->MaxTicketAge.HighPart != MINLONG ||
  271. pBuffer->MaxTicketAge.LowPart != 0 ) {
  272. //
  273. // Maximum LARGE_INTEGER .ie. never
  274. //
  275. pBuffer->MaxTicketAge.HighPart = MINLONG;
  276. pBuffer->MaxTicketAge.LowPart = 0;
  277. bFlagSet = TRUE;
  278. }
  279. bDefined = TRUE;
  280. } else if ( pKerberosInfo->MaxTicketAge != SCE_NO_VALUE ) {
  281. // in hours
  282. lValue = (DWORD) (pBuffer->MaxTicketAge.QuadPart /
  283. (LONGLONG)(10000000L) );
  284. lValue /= 3600;
  285. if ( lValue != pKerberosInfo->MaxTicketAge ) {
  286. pBuffer->MaxTicketAge.QuadPart = (LONGLONG)pKerberosInfo->MaxTicketAge*60*60 * 10000000L;
  287. bFlagSet = TRUE;
  288. }
  289. bDefined = TRUE;
  290. }
  291. //
  292. // max service ticket age
  293. //
  294. if ( pKerberosInfo->MaxServiceAge != SCE_NO_VALUE ) {
  295. ScepTattooCheckAndUpdateArray(pTattooKeys, &cTattooKeys,
  296. (PWSTR)L"MaxServiceAge", ConfigOptions,
  297. KERBDEF_MAX_SERVICE);
  298. bDefined = TRUE;
  299. }
  300. if ( pKerberosInfo->MaxServiceAge == SCE_FOREVER_VALUE ) {
  301. if ( pBuffer->MaxServiceTicketAge.HighPart != MINLONG ||
  302. pBuffer->MaxServiceTicketAge.LowPart != 0 ) {
  303. //
  304. // Maximum LARGE_INTEGER .ie. never
  305. //
  306. pBuffer->MaxServiceTicketAge.HighPart = MINLONG;
  307. pBuffer->MaxServiceTicketAge.LowPart = 0;
  308. bFlagSet = TRUE;
  309. }
  310. bDefined = TRUE;
  311. } else if ( pKerberosInfo->MaxServiceAge != SCE_NO_VALUE ) {
  312. // in minutes
  313. lValue = (DWORD) (pBuffer->MaxServiceTicketAge.QuadPart /
  314. (LONGLONG)(10000000L) );
  315. lValue /= 60;
  316. if ( lValue != pKerberosInfo->MaxServiceAge ) {
  317. pBuffer->MaxServiceTicketAge.QuadPart = (LONGLONG)pKerberosInfo->MaxServiceAge*60 * 10000000L;
  318. bFlagSet = TRUE;
  319. }
  320. bDefined = TRUE;
  321. }
  322. //
  323. // max clock
  324. //
  325. if ( pKerberosInfo->MaxClockSkew != SCE_NO_VALUE ) {
  326. ScepTattooCheckAndUpdateArray(pTattooKeys, &cTattooKeys,
  327. (PWSTR)L"MaxClockSkew", ConfigOptions,
  328. KERBDEF_MAX_CLOCK);
  329. bDefined = TRUE;
  330. }
  331. if ( pKerberosInfo->MaxClockSkew == SCE_FOREVER_VALUE ) {
  332. if ( pBuffer->MaxClockSkew.HighPart != MINLONG ||
  333. pBuffer->MaxClockSkew.LowPart != 0 ) {
  334. //
  335. // Maximum LARGE_INTEGER .ie. never
  336. //
  337. pBuffer->MaxClockSkew.HighPart = MINLONG;
  338. pBuffer->MaxClockSkew.LowPart = 0;
  339. bFlagSet = TRUE;
  340. }
  341. bDefined = TRUE;
  342. } else if ( pKerberosInfo->MaxClockSkew != SCE_NO_VALUE ) {
  343. // in minutes
  344. lValue = (DWORD) (pBuffer->MaxClockSkew.QuadPart /
  345. (LONGLONG)(10000000L) );
  346. lValue /= 60;
  347. if ( lValue != pKerberosInfo->MaxClockSkew ) {
  348. pBuffer->MaxClockSkew.QuadPart = (LONGLONG)pKerberosInfo->MaxClockSkew*60 * 10000000L;
  349. bFlagSet = TRUE;
  350. }
  351. bDefined = TRUE;
  352. }
  353. if ( bFlagSet || (bDefaultUsed && bDefined) ) {
  354. //
  355. // if anything for kerberos to configure
  356. //
  357. NtStatus = LsaSetDomainInformationPolicy(
  358. lsaHandle,
  359. PolicyDomainKerberosTicketInformation,
  360. (PVOID)pBuffer
  361. );
  362. rc = RtlNtStatusToDosError( NtStatus );
  363. if ( rc != NO_ERROR ) {
  364. ScepLogOutput3(1, rc, SCEDLL_SCP_ERROR_KERBEROS);
  365. } else {
  366. ScepLogOutput3(1, 0, SCEDLL_SCP_KERBEROS);
  367. }
  368. }
  369. if ( (ConfigOptions & SCE_POLICY_TEMPLATE) &&
  370. hProfile && pTattooKeys && cTattooKeys ) {
  371. ScepTattooOpenPolicySections(
  372. hProfile,
  373. szKerberosPolicy,
  374. &hSectionDomain,
  375. &hSectionTattoo
  376. );
  377. ScepLogOutput3(3,0,SCESRV_POLICY_TATTOO_ARRAY,cTattooKeys);
  378. //
  379. // some policy is different than the system setting
  380. // check if we should save the existing setting as the tattoo value
  381. // also remove reset'ed tattoo policy
  382. //
  383. ScepTattooManageValues(hSectionDomain, hSectionTattoo, pTattooKeys, cTattooKeys, rc);
  384. if ( hSectionDomain ) SceJetCloseSection(&hSectionDomain,TRUE);
  385. if ( hSectionTattoo ) SceJetCloseSection(&hSectionTattoo,TRUE);
  386. }
  387. if ( pTattooKeys ) ScepFree(pTattooKeys);
  388. if ( ConfigOptions & SCE_RSOP_CALLBACK )
  389. ScepRsopLog(SCE_RSOP_KERBEROS_INFO, rc, NULL, 0, 0);
  390. //
  391. // close LSA policy
  392. //
  393. LsaClose( lsaHandle );
  394. return(ScepDosErrorToSceStatus(rc));
  395. }
  396. SCESTATUS
  397. ScepAnalyzeKerberosPolicy(
  398. IN PSCECONTEXT hProfile OPTIONAL,
  399. IN PSCE_KERBEROS_TICKET_INFO pKerInfo,
  400. IN DWORD Options
  401. )
  402. /* ++
  403. Routine Description:
  404. This routine queries the system kerberos policy settings and compare them
  405. with the template settings.
  406. Arguments:
  407. hProfile - the profile context
  408. pKerInfo - The buffer which contains kerberos settings to compare with or
  409. the buffer to query system settings into
  410. Options - the option(s) for the analysis, e.g., SCE_SYSTEM_SETTINGS
  411. Return value:
  412. -- */
  413. {
  414. NTSTATUS NtStatus;
  415. LSA_HANDLE lsaHandle=NULL;
  416. DWORD rc32 = NO_ERROR;
  417. SCESTATUS rc=SCESTATUS_SUCCESS;
  418. PPOLICY_DOMAIN_KERBEROS_TICKET_INFO pBuffer=NULL;
  419. DWORD dValue;
  420. PSCESECTION hSection=NULL;
  421. POLICY_DOMAIN_KERBEROS_TICKET_INFO KerbTicketInfo;
  422. if ( !pKerInfo ) {
  423. //
  424. // if no template info, do not analyze
  425. //
  426. if ( Options & SCE_SYSTEM_SETTINGS ) {
  427. return SCESTATUS_INVALID_PARAMETER;
  428. } else {
  429. return SCESTATUS_SUCCESS;
  430. }
  431. }
  432. //
  433. // open LSA policy to configure kerberos policy
  434. //
  435. NtStatus = ScepOpenLsaPolicy(
  436. MAXIMUM_ALLOWED,
  437. &lsaHandle,
  438. TRUE
  439. );
  440. if (!NT_SUCCESS(NtStatus)) {
  441. lsaHandle = NULL;
  442. rc32 = RtlNtStatusToDosError( NtStatus );
  443. ScepLogOutput3( 1, rc32, SCEDLL_LSA_POLICY);
  444. return(ScepDosErrorToSceStatus(rc32));
  445. }
  446. if ( !(Options & SCE_SYSTEM_SETTINGS) ) {
  447. //
  448. // Prepare kerberos section
  449. //
  450. rc = ScepStartANewSection(
  451. hProfile,
  452. &hSection,
  453. (Options & SCE_GENERATE_ROLLBACK) ? SCEJET_TABLE_SMP : SCEJET_TABLE_SAP,
  454. szKerberosPolicy
  455. );
  456. }
  457. if ( rc != SCESTATUS_SUCCESS ) {
  458. ScepLogOutput3(1, ScepSceStatusToDosError(rc),
  459. SCEDLL_SAP_START_SECTION, (PWSTR)szKerberosPolicy);
  460. } else {
  461. DWORD KerbValues[MAX_KERB_ITEMS];
  462. for ( dValue=0; dValue<MAX_KERB_ITEMS; dValue++ ) {
  463. KerbValues[dValue] = SCE_ERROR_VALUE;
  464. }
  465. //
  466. // query current kerberos policy settings into pBuffer
  467. //
  468. NtStatus = LsaQueryDomainInformationPolicy(
  469. lsaHandle,
  470. PolicyDomainKerberosTicketInformation,
  471. (PVOID *)&pBuffer
  472. );
  473. if ( STATUS_NOT_FOUND == NtStatus ) {
  474. //
  475. // there is no Kerberos policy
  476. //
  477. KerbTicketInfo.AuthenticationOptions = POLICY_KERBEROS_VALIDATE_CLIENT;
  478. KerbTicketInfo.MaxTicketAge.QuadPart = (LONGLONG) KERBDEF_MAX_TICKET*60*60 * 10000000L;
  479. KerbTicketInfo.MaxRenewAge.QuadPart = (LONGLONG) KERBDEF_MAX_RENEW*24*60*60 * 10000000L;
  480. KerbTicketInfo.MaxServiceTicketAge.QuadPart = (LONGLONG) KERBDEF_MAX_SERVICE*60 * 10000000L;
  481. KerbTicketInfo.MaxClockSkew.QuadPart = (LONGLONG) KERBDEF_MAX_CLOCK*60 * 10000000L;
  482. pBuffer = &KerbTicketInfo;
  483. NtStatus = STATUS_SUCCESS;
  484. }
  485. rc = ScepDosErrorToSceStatus(
  486. RtlNtStatusToDosError( NtStatus ));
  487. if ( NT_SUCCESS(NtStatus) && pBuffer ) {
  488. //
  489. // analyze kerberos values
  490. // max ticket age
  491. //
  492. if ( pBuffer->MaxTicketAge.HighPart == MINLONG &&
  493. pBuffer->MaxTicketAge.LowPart == 0 ) {
  494. //
  495. // Maximum password age value is MINLONG,0
  496. //
  497. dValue = SCE_FOREVER_VALUE;
  498. } else {
  499. dValue = (DWORD) ( pBuffer->MaxTicketAge.QuadPart /
  500. (LONGLONG)(10000000L) );
  501. //
  502. // using hours
  503. //
  504. // dValue /= 24;
  505. dValue /= 3600;
  506. }
  507. rc = SCESTATUS_SUCCESS;
  508. if ( Options & SCE_SYSTEM_SETTINGS ) {
  509. pKerInfo->MaxTicketAge = dValue;
  510. } else {
  511. rc = ScepCompareAndSaveIntValue(
  512. hSection,
  513. L"MaxTicketAge",
  514. (Options & SCE_GENERATE_ROLLBACK),
  515. pKerInfo->MaxTicketAge,
  516. dValue);
  517. }
  518. if ( SCESTATUS_SUCCESS == rc ) {
  519. KerbValues[IDX_KERB_MAX] = 1;
  520. if ( pBuffer->MaxRenewAge.HighPart == MINLONG &&
  521. pBuffer->MaxRenewAge.LowPart == 0 ) {
  522. //
  523. // Maximum age value is MINLONG,0
  524. //
  525. dValue = SCE_FOREVER_VALUE;
  526. } else {
  527. dValue = (DWORD) ( pBuffer->MaxRenewAge.QuadPart /
  528. (LONGLONG)(10000000L) );
  529. //
  530. // using days
  531. //
  532. dValue /= 3600;
  533. dValue /= 24;
  534. }
  535. if ( Options & SCE_SYSTEM_SETTINGS ) {
  536. pKerInfo->MaxRenewAge = dValue;
  537. } else {
  538. rc = ScepCompareAndSaveIntValue(
  539. hSection,
  540. L"MaxRenewAge",
  541. (Options & SCE_GENERATE_ROLLBACK),
  542. pKerInfo->MaxRenewAge,
  543. dValue);
  544. }
  545. if ( SCESTATUS_SUCCESS == rc ) {
  546. KerbValues[IDX_KERB_RENEW] = 1;
  547. if ( pBuffer->MaxServiceTicketAge.HighPart == MINLONG &&
  548. pBuffer->MaxServiceTicketAge.LowPart == 0 ) {
  549. //
  550. // Maximum age value is MINLONG,0
  551. //
  552. dValue = SCE_FOREVER_VALUE;
  553. } else {
  554. dValue = (DWORD) ( pBuffer->MaxServiceTicketAge.QuadPart /
  555. (LONGLONG)(10000000L) );
  556. //
  557. // using minutes
  558. //
  559. dValue /= 60;
  560. }
  561. if ( Options & SCE_SYSTEM_SETTINGS ) {
  562. pKerInfo->MaxServiceAge = dValue;
  563. } else {
  564. rc = ScepCompareAndSaveIntValue(
  565. hSection,
  566. L"MaxServiceAge",
  567. (Options & SCE_GENERATE_ROLLBACK),
  568. pKerInfo->MaxServiceAge,
  569. dValue);
  570. }
  571. if ( SCESTATUS_SUCCESS == rc ) {
  572. KerbValues[IDX_KERB_SERVICE] = 1;
  573. if ( pBuffer->MaxClockSkew.HighPart == MINLONG &&
  574. pBuffer->MaxClockSkew.LowPart == 0 ) {
  575. //
  576. // Maximum age value is MINLONG,0
  577. //
  578. dValue = SCE_FOREVER_VALUE;
  579. } else {
  580. dValue = (DWORD) ( pBuffer->MaxClockSkew.QuadPart /
  581. (LONGLONG)(10000000L) );
  582. //
  583. // using minutes
  584. //
  585. dValue /= 60;
  586. }
  587. if ( Options & SCE_SYSTEM_SETTINGS ) {
  588. pKerInfo->MaxClockSkew = dValue;
  589. } else {
  590. rc = ScepCompareAndSaveIntValue(
  591. hSection,
  592. L"MaxClockSkew",
  593. (Options & SCE_GENERATE_ROLLBACK),
  594. pKerInfo->MaxClockSkew,
  595. dValue);
  596. }
  597. if ( SCESTATUS_SUCCESS == rc ) {
  598. KerbValues[IDX_KERB_CLOCK] = 1;
  599. //
  600. // validate client
  601. //
  602. dValue = ( pBuffer->AuthenticationOptions & POLICY_KERBEROS_VALIDATE_CLIENT ) ? 1 : 0;
  603. if ( Options & SCE_SYSTEM_SETTINGS ) {
  604. pKerInfo->TicketValidateClient = dValue;
  605. } else {
  606. rc = ScepCompareAndSaveIntValue(
  607. hSection,
  608. L"TicketValidateClient",
  609. (Options & SCE_GENERATE_ROLLBACK),
  610. pKerInfo->TicketValidateClient,
  611. dValue);
  612. }
  613. if ( SCESTATUS_SUCCESS == rc ) {
  614. KerbValues[IDX_KERB_VALIDATE] = 1;
  615. }
  616. }
  617. }
  618. }
  619. }
  620. if ( !(Options & SCE_SYSTEM_SETTINGS) ) {
  621. if ( rc == SCESTATUS_SUCCESS ) {
  622. ScepLogOutput3( 1, 0, SCEDLL_SAP_KERBEROS);
  623. } else {
  624. ScepLogOutput3( 1, ScepSceStatusToDosError(rc),
  625. SCEDLL_SAP_ERROR_KERBEROS);
  626. }
  627. }
  628. if ( pBuffer != &KerbTicketInfo ) {
  629. //
  630. // free the buffer
  631. //
  632. LsaFreeMemory((PVOID)pBuffer);
  633. }
  634. }
  635. if ( !(Options & SCE_SYSTEM_SETTINGS) ) {
  636. if ( SCESTATUS_SUCCESS != rc &&
  637. !(Options & SCE_GENERATE_ROLLBACK) ) {
  638. for ( dValue=0; dValue<MAX_KERB_ITEMS; dValue++ ) {
  639. if ( KerbValues[dValue] == SCE_ERROR_VALUE ) {
  640. ScepCompareAndSaveIntValue(
  641. hSection,
  642. KerbItems[dValue],
  643. FALSE,
  644. SCE_NO_VALUE,
  645. SCE_ERROR_VALUE
  646. );
  647. }
  648. }
  649. }
  650. //
  651. // close the section
  652. //
  653. SceJetCloseSection(&hSection, TRUE);
  654. }
  655. }
  656. LsaClose( lsaHandle );
  657. if ( ( rc == SCESTATUS_PROFILE_NOT_FOUND) ||
  658. ( rc == SCESTATUS_RECORD_NOT_FOUND) ) {
  659. rc = SCESTATUS_SUCCESS;
  660. }
  661. return(rc);
  662. }
  663. #endif