Leaked source code of windows server 2003
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.

1106 lines
28 KiB

  1. /*++
  2. Copyright (c) 1991 Microsoft Corporation
  3. Module Name:
  4. dbmisc.c
  5. Abstract:
  6. Local Security Authority - Miscellaneous API
  7. This file contains worker routines for miscellaneous API that are
  8. not specific to objects of a given type.
  9. Author:
  10. Scott Birrell (ScottBi) January 15, 1992
  11. Environment:
  12. Revision History:
  13. --*/
  14. #include <lsapch2.h>
  15. #include "dbp.h"
  16. #include "lsawmi.h"
  17. #include <names.h>
  18. #include <windns.h>
  19. #include <alloca.h>
  20. #include "adtp.h"
  21. NTSTATUS
  22. LsarClose(
  23. IN OUT LSAPR_HANDLE *ObjectHandle
  24. )
  25. /*++
  26. Routine Description:
  27. This function is the LSA server RPC worker routine for the LsaClose
  28. API.
  29. Arguments:
  30. ObjectHandle - Handle returned from an LsaOpen<object type> or
  31. LsaCreate<object type> call.
  32. Return Value:
  33. NTSTATUS - Standard Nt Result Code
  34. --*/
  35. {
  36. return LsapCloseHandle(
  37. ObjectHandle,
  38. STATUS_SUCCESS
  39. );
  40. }
  41. NTSTATUS
  42. LsapCloseHandle(
  43. IN OUT LSAPR_HANDLE *ObjectHandle,
  44. IN NTSTATUS PreliminaryStatus
  45. )
  46. /*++
  47. Routine Description:
  48. This function is the LSA server RPC worker routine for the LsaClose
  49. API.
  50. The LsaClose API closes a handle to an open object within the database.
  51. If closing a handle to the Policy object and there are no objects still
  52. open within the current connection to the LSA, the connection is closed.
  53. If a handle to an object within the database is closed and the object is
  54. marked for DELETE access, the object will be deleted when the last handle
  55. to that object is closed.
  56. Arguments:
  57. ObjectHandle - Handle returned from an LsaOpen<object type> or
  58. LsaCreate<object type> call.
  59. PreliminaryStatus - Status of the operation. Used to decide whether
  60. to abort or commit a transaction.
  61. Return Value:
  62. NTSTATUS - Standard Nt Result Code
  63. --*/
  64. {
  65. NTSTATUS Status;
  66. LSAP_DB_HANDLE InternalHandle = *ObjectHandle;
  67. LSAP_DB_OBJECT_TYPE_ID ObjectTypeId;
  68. LsapDsDebugOut(( DEB_FTRACE, "LsapCloseHandle\n" ));
  69. LsapTraceEvent(EVENT_TRACE_TYPE_START, LsaTraceEvent_Close);
  70. if ( *ObjectHandle == NULL ) {
  71. Status = STATUS_INVALID_HANDLE;
  72. goto Cleanup;
  73. }
  74. ObjectTypeId = InternalHandle->ObjectTypeId;
  75. if ( *ObjectHandle == LsapPolicyHandle ) {
  76. #if DBG
  77. DbgPrint("Closing global policy handle!!!\n");
  78. #endif
  79. DbgBreakPoint();
  80. Status = STATUS_INVALID_HANDLE;
  81. goto Cleanup;
  82. }
  83. //
  84. // Acquire the Lsa Database Lock
  85. //
  86. LsapDbAcquireLockEx( ObjectTypeId,
  87. LSAP_DB_READ_ONLY_TRANSACTION );
  88. //
  89. // Validate and close the object handle, dereference its container (if any).
  90. //
  91. Status = LsapDbCloseObject(
  92. ObjectHandle,
  93. LSAP_DB_VALIDATE_HANDLE |
  94. LSAP_DB_DEREFERENCE_CONTR |
  95. LSAP_DB_ADMIT_DELETED_OBJECT_HANDLES |
  96. LSAP_DB_READ_ONLY_TRANSACTION |
  97. LSAP_DB_DS_OP_TRANSACTION,
  98. PreliminaryStatus
  99. );
  100. LsapDbReleaseLockEx( ObjectTypeId,
  101. LSAP_DB_READ_ONLY_TRANSACTION );
  102. Cleanup:
  103. *ObjectHandle = NULL;
  104. LsapDsDebugOut(( DEB_FTRACE, "LsapCloseHandle: 0x%lx\n", Status ));
  105. LsapTraceEvent(EVENT_TRACE_TYPE_END, LsaTraceEvent_Close);
  106. return Status;
  107. }
  108. NTSTATUS
  109. LsarDeleteObject(
  110. IN OUT LSAPR_HANDLE *ObjectHandle
  111. )
  112. /*++
  113. Routine Description:
  114. This function is the LSA server RPC worker routine for the LsaDelete
  115. API.
  116. The LsaDelete API deletes an object from the LSA Database. The object must be
  117. open for DELETE access.
  118. Arguments:
  119. ObjectHandle - Pointer to Handle from an LsaOpen<object type> or
  120. LsaCreate<object type> call. On return, this location will contain
  121. NULL if the call is successful.
  122. Return Value:
  123. NTSTATUS - Standard Nt Result Code
  124. STATUS_ACCESS_DENIED - Caller does not have the appropriate access
  125. to complete the operation.
  126. STATUS_OBJECT_NAME_NOT_FOUND - There is no object in the
  127. target system's LSA Database having the name and type specified
  128. by the handle.
  129. --*/
  130. {
  131. return LsapDeleteObject( ObjectHandle , TRUE );
  132. }
  133. NTSTATUS
  134. LsapDeleteObject(
  135. IN OUT LSAPR_HANDLE *ObjectHandle,
  136. IN BOOL LockSce
  137. )
  138. /*++
  139. Routine Description:
  140. This is the worker routine for LsarDeleteObject, with an added
  141. semantics of not locking the SCE policy.
  142. --*/
  143. {
  144. NTSTATUS Status = STATUS_SUCCESS;
  145. NTSTATUS IgnoreStatus;
  146. LSAP_DB_HANDLE InternalHandle = *ObjectHandle;
  147. BOOLEAN ObjectReferenced = FALSE;
  148. ULONG ReferenceOptions = LSAP_DB_START_TRANSACTION |
  149. LSAP_DB_LOCK ;
  150. ULONG DereferenceOptions = LSAP_DB_FINISH_TRANSACTION |
  151. LSAP_DB_LOCK |
  152. LSAP_DB_DEREFERENCE_CONTR;
  153. PLSAPR_TRUST_INFORMATION TrustInformation = NULL;
  154. LSAPR_TRUST_INFORMATION OutputTrustInformation;
  155. BOOLEAN TrustInformationPresent = FALSE;
  156. LSAP_DB_OBJECT_TYPE_ID ObjectTypeId;
  157. PTRUSTED_DOMAIN_INFORMATION_EX CurrentTrustedDomainInfoEx = NULL;
  158. BOOLEAN ScePolicyLocked = FALSE;
  159. BOOLEAN NotifySce = FALSE;
  160. SECURITY_DB_OBJECT_TYPE ObjectType = SecurityDbObjectLsaPolicy;
  161. PSID ObjectSid = NULL;
  162. BOOL RevertResult = FALSE;
  163. BOOL Impersonating = FALSE;
  164. LsarpReturnCheckSetup();
  165. LsapDsDebugOut(( DEB_FTRACE, "LsarDeleteObject\n" ));
  166. ObjectTypeId = InternalHandle->ObjectTypeId;
  167. //
  168. // The LSA will only call SceNotify if the policy change was made via a handle
  169. // not marked 'SCE handle'. This prevents SCE from being notified of its own
  170. // changes. This is required to ensure that policy read from the LSA matches
  171. // that written by a non-SCE application.
  172. //
  173. if ( !InternalHandle->SceHandle &&
  174. !InternalHandle->SceHandleChild ) {
  175. switch ( ObjectTypeId ) {
  176. case AccountObject: {
  177. ULONG SidLength;
  178. ASSERT( InternalHandle->Sid );
  179. SidLength = RtlLengthSid( InternalHandle->Sid );
  180. ObjectSid = ( PSID )LsapAllocateLsaHeap( SidLength );
  181. if ( ObjectSid ) {
  182. RtlCopyMemory( ObjectSid, InternalHandle->Sid, SidLength );
  183. } else {
  184. Status = STATUS_INSUFFICIENT_RESOURCES;
  185. goto DeleteObjectError;
  186. }
  187. ObjectType = SecurityDbObjectLsaAccount;
  188. // FALLTHRU
  189. }
  190. case PolicyObject:
  191. if ( LockSce ) {
  192. RtlEnterCriticalSection( &LsapDbState.ScePolicyLock.CriticalSection );
  193. if ( LsapDbState.ScePolicyLock.NumberOfWaitingShared > MAX_SCE_WAITING_SHARED ) {
  194. Status = STATUS_TOO_MANY_THREADS;
  195. }
  196. RtlLeaveCriticalSection( &LsapDbState.ScePolicyLock.CriticalSection );
  197. if ( !NT_SUCCESS( Status )) {
  198. goto DeleteObjectError;
  199. }
  200. WaitForSingleObject( LsapDbState.SceSyncEvent, INFINITE );
  201. RtlAcquireResourceShared( &LsapDbState.ScePolicyLock, TRUE );
  202. ASSERT( !g_ScePolicyLocked );
  203. ScePolicyLocked = TRUE;
  204. }
  205. NotifySce = TRUE;
  206. break;
  207. default:
  208. break;
  209. }
  210. }
  211. //
  212. // Verify that the Object handle is valid, is of the expected type and
  213. // has all of the desired accesses granted. Reference the handle and
  214. // open a database transaction.
  215. //
  216. Status = LsapDbReferenceObject(
  217. *ObjectHandle,
  218. DELETE,
  219. ObjectTypeId,
  220. ObjectTypeId,
  221. ReferenceOptions
  222. );
  223. if (!NT_SUCCESS(Status)) {
  224. goto DeleteObjectError;
  225. }
  226. ObjectReferenced = TRUE;
  227. //
  228. // Perform object type specific pre-processing. Note that some
  229. // pre-processing is also done within LsapDbReferenceObject(), for
  230. // example, for local secrets.
  231. //
  232. switch (ObjectTypeId) {
  233. case PolicyObject:
  234. Status = STATUS_INVALID_PARAMETER;
  235. break;
  236. case TrustedDomainObject:
  237. if ( LsapDsWriteDs && InternalHandle->Sid == NULL ) {
  238. BOOLEAN TrustedStatus = InternalHandle->Trusted;
  239. //
  240. // Toggle trusted bit so that access cks do not prevent following
  241. // query from succeeding
  242. //
  243. InternalHandle->Trusted = TRUE;
  244. Status = LsarQueryInfoTrustedDomain( *ObjectHandle,
  245. TrustedDomainInformationEx,
  246. (PLSAPR_TRUSTED_DOMAIN_INFO *)
  247. &CurrentTrustedDomainInfoEx );
  248. InternalHandle->Trusted = TrustedStatus;
  249. if ( NT_SUCCESS( Status ) ) {
  250. InternalHandle->Sid = CurrentTrustedDomainInfoEx->Sid;
  251. CurrentTrustedDomainInfoEx->Sid = NULL;
  252. } else {
  253. LsapDsDebugOut(( DEB_ERROR,
  254. "Query for TD Sid failed with 0x%lx\n", Status ));
  255. }
  256. }
  257. if (LsapAdtAuditingEnabledHint(AuditCategoryPolicyChange, EVENTLOG_AUDIT_SUCCESS)) {
  258. //
  259. // If we're auditing deletions of TrustedDomain objects, we need
  260. // to retrieve the TrustedDomain name and keep it for later when
  261. // we generate the audit.
  262. //
  263. Status = LsapDbAcquireReadLockTrustedDomainList();
  264. if (NT_SUCCESS(Status))
  265. {
  266. Status = LsapDbLookupSidTrustedDomainList(
  267. InternalHandle->Sid,
  268. &TrustInformation
  269. );
  270. if (STATUS_NO_SUCH_DOMAIN==Status)
  271. {
  272. //
  273. // If we could not find by the SID, then lookup by the logical name
  274. // field.
  275. //
  276. Status = LsapDbLookupNameTrustedDomainList(
  277. (PLSAPR_UNICODE_STRING) &InternalHandle->LogicalNameU,
  278. &TrustInformation
  279. );
  280. }
  281. if ( NT_SUCCESS( Status )) {
  282. Status = LsapRpcCopyTrustInformation(
  283. NULL,
  284. &OutputTrustInformation,
  285. TrustInformation
  286. );
  287. TrustInformationPresent = NT_SUCCESS( Status );
  288. }
  289. LsapDbReleaseLockTrustedDomainList();
  290. }
  291. //
  292. // Reset the status to SUCCESS. Failure to get the information for
  293. // auditing should not be a failure to delete
  294. //
  295. Status = STATUS_SUCCESS;
  296. }
  297. if ( NT_SUCCESS( Status )) {
  298. //
  299. // Notify netlogon. Potentially ignore any failures
  300. //
  301. Status = LsapNotifyNetlogonOfTrustChange( InternalHandle->Sid,
  302. SecurityDbDelete );
  303. #if DBG
  304. if ( !NT_SUCCESS( Status ) ) {
  305. LsapDsDebugOut(( DEB_ERROR,
  306. "LsapNotifyNetlogonOfTrustChange failed with an unexpected 0x%lx\n",
  307. Status ));
  308. ASSERT( NT_SUCCESS(Status) );
  309. }
  310. #endif
  311. Status = STATUS_SUCCESS;
  312. }
  313. break;
  314. case AccountObject:
  315. {
  316. PLSAPR_PRIVILEGE_SET Privileges;
  317. LSAPR_HANDLE AccountHandle;
  318. PLSAPR_SID AccountSid = NULL;
  319. ULONG AuditEventId;
  320. AccountHandle = *ObjectHandle;
  321. AccountSid = LsapDbSidFromHandle( AccountHandle );
  322. if (LsapAdtAuditingEnabledHint(AuditCategoryPolicyChange, EVENTLOG_AUDIT_SUCCESS)) {
  323. Status = LsarEnumeratePrivilegesAccount(
  324. AccountHandle,
  325. &Privileges
  326. );
  327. if (!NT_SUCCESS( Status )) {
  328. LsapDsDebugOut(( DEB_ERROR,
  329. "LsarEnumeratePrivilegesAccount ret'd %x\n", Status ));
  330. break;
  331. }
  332. AuditEventId = SE_AUDITID_USER_RIGHT_REMOVED;
  333. //
  334. // Audit the privilege set change. Ignore failures from Auditing.
  335. //
  336. IgnoreStatus = LsapAdtGenerateLsaAuditEvent(
  337. AccountHandle,
  338. SE_CATEGID_POLICY_CHANGE,
  339. AuditEventId,
  340. (PPRIVILEGE_SET)Privileges,
  341. 1,
  342. (PSID *) &AccountSid,
  343. 0,
  344. NULL,
  345. NULL
  346. );
  347. MIDL_user_free( Privileges );
  348. }
  349. }
  350. break;
  351. case SecretObject:
  352. break;
  353. default:
  354. Status = STATUS_INVALID_PARAMETER;
  355. break;
  356. }
  357. if (!NT_SUCCESS(Status)) {
  358. goto DeleteObjectError;
  359. }
  360. Status = LsapDbDeleteObject( *ObjectHandle );
  361. if (!NT_SUCCESS(Status)) {
  362. goto DeleteObjectError;
  363. }
  364. //
  365. // Decrement the Reference Count so that the object's handle will be
  366. // freed upon dereference.
  367. //
  368. LsapDbDereferenceHandle( *ObjectHandle, TRUE );
  369. //
  370. // Perform object post-processing. The only post-processing is
  371. // the auditing of TrustedDomain object deletion.
  372. //
  373. if (TrustInformationPresent && LsapAdtAuditingEnabledHint(
  374. AuditCategoryPolicyChange,
  375. EVENTLOG_AUDIT_SUCCESS)) {
  376. if (ObjectTypeId == TrustedDomainObject) {
  377. (void) LsapAdtTrustedDomainRem(
  378. EVENTLOG_AUDIT_SUCCESS,
  379. (PUNICODE_STRING) &OutputTrustInformation.Name,
  380. InternalHandle->Sid,
  381. NULL, // UserSid
  382. NULL // UserAuthenticationId
  383. );
  384. //
  385. // Call fgs routine because we want to free the graph of the
  386. // structure, but not the top level of the structure.
  387. //
  388. _fgs__LSAPR_TRUST_INFORMATION ( &OutputTrustInformation );
  389. TrustInformation = NULL;
  390. }
  391. }
  392. //
  393. // Delete new object from the in-memory cache (if any)
  394. //
  395. if ( ObjectTypeId == AccountObject &&
  396. LsapDbIsCacheSupported( AccountObject ) &&
  397. LsapDbIsCacheValid( AccountObject )) {
  398. IgnoreStatus = LsapDbDeleteAccount( InternalHandle->Sid );
  399. }
  400. //
  401. // impersonate the client so that audit event shows correct user
  402. // Do this only for untrusted clients
  403. //
  404. if ( !InternalHandle->Trusted ) {
  405. if ( InternalHandle->Options & LSAP_DB_USE_LPC_IMPERSONATE ) {
  406. IgnoreStatus = LsapImpersonateClient( );
  407. } else {
  408. IgnoreStatus = I_RpcMapWin32Status(RpcImpersonateClient(0));
  409. }
  410. if ( NT_SUCCESS(IgnoreStatus) ) {
  411. Impersonating = TRUE;
  412. }
  413. else if ( ( IgnoreStatus == RPC_NT_NO_CALL_ACTIVE ) ||
  414. ( IgnoreStatus == RPC_NT_NO_CONTEXT_AVAILABLE ) ) {
  415. //
  416. // we dont want to fail the audit if
  417. // -- the call is not over RPC (RPC_NT_NO_CALL_ACTIVE)
  418. // -- the client died prematurely (RPC_NT_NO_CONTEXT_AVAILABLE)
  419. //
  420. IgnoreStatus = STATUS_SUCCESS;
  421. }
  422. DsysAssertMsg( NT_SUCCESS(IgnoreStatus), "LsapDeleteObject: failed to impersonate" );
  423. if (!NT_SUCCESS( IgnoreStatus )) {
  424. LsapAuditFailed( IgnoreStatus );
  425. }
  426. }
  427. //
  428. // Audit the deletion
  429. //
  430. IgnoreStatus = NtDeleteObjectAuditAlarm( &LsapState.SubsystemName,
  431. *ObjectHandle,
  432. InternalHandle->GenerateOnClose);
  433. //
  434. // unimpersonate
  435. //
  436. if ( !InternalHandle->Trusted ) {
  437. if ( Impersonating ) {
  438. if ( InternalHandle->Options & LSAP_DB_USE_LPC_IMPERSONATE ) {
  439. RevertResult = RevertToSelf();
  440. DsysAssertMsg( RevertResult, "LsapDeleteObject: RevertToSelf() failed" );
  441. } else {
  442. IgnoreStatus = I_RpcMapWin32Status(RpcRevertToSelf());
  443. DsysAssertMsg( NT_SUCCESS(IgnoreStatus), "LsapDeleteObject: RpcRevertToSelf() failed" );
  444. }
  445. }
  446. }
  447. DeleteObjectFinish:
  448. //
  449. // If we referenced the object, dereference it, close the database
  450. // transaction, notify the replicator of the delete, release the LSA
  451. // Database lock and return.
  452. //
  453. if (ObjectReferenced) {
  454. Status = LsapDbDereferenceObject(
  455. ObjectHandle,
  456. ObjectTypeId,
  457. ObjectTypeId,
  458. DereferenceOptions,
  459. SecurityDbDelete,
  460. Status
  461. );
  462. ObjectReferenced = FALSE;
  463. if (!NT_SUCCESS(Status)) {
  464. goto DeleteObjectError;
  465. }
  466. }
  467. if ( CurrentTrustedDomainInfoEx ) {
  468. LsaIFree_LSAPR_TRUSTED_DOMAIN_INFO(
  469. TrustedDomainInformationEx,
  470. (PLSAPR_TRUSTED_DOMAIN_INFO) CurrentTrustedDomainInfoEx );
  471. }
  472. //
  473. // Notify SCE of the change. Only notify for callers
  474. // that did not open their policy handles with LsaOpenPolicySce.
  475. //
  476. if ( NotifySce && NT_SUCCESS( Status )) {
  477. LsapSceNotify(
  478. SecurityDbDelete,
  479. ObjectType,
  480. ObjectSid
  481. );
  482. }
  483. if ( ScePolicyLocked ) {
  484. RtlReleaseResource( &LsapDbState.ScePolicyLock );
  485. }
  486. if ( ObjectSid ) {
  487. LsapFreeLsaHeap( ObjectSid );
  488. }
  489. LsarpReturnPrologue();
  490. LsapDsDebugOut(( DEB_FTRACE, "LsarDeleteObject: 0x%lx\n", Status ));
  491. //
  492. // Under all circumstances tell RPC we're done with this handle
  493. //
  494. *ObjectHandle = NULL;
  495. return(Status);
  496. DeleteObjectError:
  497. goto DeleteObjectFinish;
  498. }
  499. NTSTATUS
  500. LsarDelete(
  501. IN LSAPR_HANDLE ObjectHandle
  502. )
  503. /*++
  504. Routine Description:
  505. This function is the former LSA server RPC worker routine for the
  506. LsaDelete API. It has been termorarily retained for compatibility
  507. with pre Beta 2 versions 1.369 and earlier of the system. It has been
  508. necessary to replace this routine with a new one, LsarDeleteObject(),
  509. on the RPC interface. This is because, like LsarClose(), a pointer to a
  510. handle is required rather than a handle so that LsarDeleteObject() can
  511. inform the RPC server calling stub that the handle has been deleted by
  512. returning NULL. The client wrapper for LsaDelete() will try to call
  513. LsarDeleteObject(). If the server code does not contain this interface,
  514. the client will call LsarDelete(). In this event, the server's
  515. LSAPR_HANDLE_rundown() routine may attempt to rundown the handle after it
  516. has been deleted (versions 1.363 - 369 only).
  517. The LsaDelete API deletes an object from the LSA Database. The object must be
  518. open for DELETE access.
  519. Arguments:
  520. ObjectHandle - Handle from an LsaOpen<object type> or LsaCreate<object type>
  521. call.
  522. None.
  523. Return Value:
  524. NTSTATUS - Standard Nt Result Code
  525. STATUS_ACCESS_DENIED - Caller does not have the appropriate access
  526. to complete the operation.
  527. STATUS_OBJECT_NAME_NOT_FOUND - There is no object in the
  528. target system's LSA Database having the name and type specified
  529. by the handle.
  530. --*/
  531. {
  532. //
  533. // Call the replacement routine LsarDeleteObject()
  534. //
  535. return( LsarDeleteObject((LSAPR_HANDLE *) &ObjectHandle));
  536. }
  537. NTSTATUS
  538. LsarChangePassword(
  539. IN PLSAPR_UNICODE_STRING ServerName,
  540. IN PLSAPR_UNICODE_STRING DomainName,
  541. IN PLSAPR_UNICODE_STRING AccountName,
  542. IN PLSAPR_UNICODE_STRING OldPassword,
  543. IN PLSAPR_UNICODE_STRING NewPassword
  544. )
  545. /*++
  546. Routine Description:
  547. The LsaChangePassword API is used to change a user account's password.
  548. The user must have appropriate access to the user account and must
  549. know the current password value.
  550. Arguments:
  551. ServerName - The name of the Domain Controller at which the password
  552. can be changed.
  553. DomainName - The name of the domain in which the account exists.
  554. AccountName - The name of the account whose password is to be changed.
  555. NewPassword - The new password value.
  556. OldPassword - The old (current) password value.
  557. Return Values:
  558. NTSTATUS - Standard Nt Result Code
  559. STATUS_ACCESS_DENIED - Caller does not have the appropriate access
  560. to complete the operation.
  561. STATUS_ILL_FORMED_PASSWORD - The new password is poorly formed, e.g.
  562. contains characters that can't be entered from the keyboard.
  563. STATUS_PASSWORD_RESTRICTION - A restriction prevents the password
  564. from being changed. This may be for an number of reasons,
  565. including time restrictions on how often a password may be changed
  566. or length restrictions on the provided (new) password.
  567. This error might also be returned if the new password matched
  568. a password in the recent history log for the account. Security
  569. administrators indicate how many of the most recently used
  570. passwords may not be re-used.
  571. STATUS_WRONG_PASSWORD - OldPassword does not contain the user's
  572. current password.
  573. STATUS_NO_SUCH_USER - The SID provided does not lead to a user
  574. account.
  575. STATUS_CANT_UPDATE_MASTER - An attempt to update the master copy
  576. of the password was unsuccessful. Please try again later.
  577. --*/
  578. {
  579. NTSTATUS Status;
  580. LsarpReturnCheckSetup();
  581. LsapDsDebugOut(( DEB_FTRACE, "LsarChangePassword\n" ));
  582. DBG_UNREFERENCED_PARAMETER( ServerName );
  583. DBG_UNREFERENCED_PARAMETER( DomainName );
  584. DBG_UNREFERENCED_PARAMETER( AccountName );
  585. DBG_UNREFERENCED_PARAMETER( OldPassword );
  586. DBG_UNREFERENCED_PARAMETER( NewPassword );
  587. Status = STATUS_NOT_IMPLEMENTED;
  588. LsarpReturnPrologue();
  589. LsapDsDebugOut(( DEB_FTRACE, "LsarChangePassword: 0x%lx\n", Status ));
  590. return(Status);
  591. }
  592. NTSTATUS
  593. LsapDbIsRpcClientNetworkClient(
  594. OUT PBOOLEAN IsNetworkClient
  595. )
  596. /*++
  597. Routine Description:
  598. This call is used to determine if the current RPC call is from
  599. a network client (came in via the network as opposed to locally)
  600. or not.
  601. Arguments:
  602. IsNetworkClient - Pointer to a BOOLEAN that gets set to the results
  603. of whether this is a network client or not
  604. Return Values:
  605. STATUS_SUCCESS - Success
  606. --*/
  607. {
  608. RPC_STATUS RpcStatus;
  609. unsigned int ClientLocalFlag;
  610. RpcStatus = I_RpcBindingIsClientLocal ( NULL, &ClientLocalFlag );
  611. if ( RpcStatus != RPC_S_OK ) {
  612. return I_RpcMapWin32Status( RpcStatus );
  613. }
  614. *IsNetworkClient = (ClientLocalFlag == 0);
  615. return STATUS_SUCCESS;
  616. }
  617. NTSTATUS
  618. LsapValidateNetbiosName(
  619. IN const UNICODE_STRING * Name,
  620. OUT BOOLEAN * Valid
  621. )
  622. /*++
  623. Routine Description:
  624. Validates that a NetBIOS name conforms to certain minimum standards.
  625. For more details, see the description of NetpIsDomainNameValid.
  626. Arguments:
  627. Name name to validate
  628. Valid will be set to TRUE if validation checks out, FALSE otherwise
  629. Returns:
  630. STATUS_SUCCESS
  631. STATUS_INSUFFICIENT_RESOURCES
  632. --*/
  633. {
  634. WCHAR * Buffer;
  635. BOOLEAN BufferAllocated = FALSE;
  636. ASSERT( Name );
  637. ASSERT( Valid );
  638. ASSERT( LsapValidateLsaUnicodeString( Name ));
  639. //
  640. // Empty names and names that are too long are not allowed
  641. //
  642. if ( Name->Length == 0 ||
  643. Name->Length > DNLEN * sizeof( WCHAR )) {
  644. *Valid = FALSE;
  645. return STATUS_SUCCESS;
  646. }
  647. if ( Name->MaximumLength > Name->Length ) {
  648. Buffer = Name->Buffer;
  649. } else {
  650. SafeAllocaAllocate( Buffer, Name->Length + sizeof( WCHAR ));
  651. if ( Buffer == NULL ) {
  652. *Valid = FALSE;
  653. return STATUS_INSUFFICIENT_RESOURCES;
  654. }
  655. BufferAllocated = TRUE;
  656. RtlCopyMemory( Buffer, Name->Buffer, Name->Length );
  657. }
  658. Buffer[Name->Length / sizeof( WCHAR )] = L'\0';
  659. *Valid = ( TRUE == NetpIsDomainNameValid( Buffer ));
  660. if ( BufferAllocated ) {
  661. SafeAllocaFree( Buffer );
  662. }
  663. return STATUS_SUCCESS;
  664. }
  665. NTSTATUS
  666. LsapValidateDnsName(
  667. IN const UNICODE_STRING * Name,
  668. OUT BOOLEAN * Valid
  669. )
  670. /*++
  671. Routine Description:
  672. Validates that a DNS name conforms to certain minimum standards.
  673. Arguments:
  674. Name name to validate
  675. Valid will be set to TRUE if validation checks out, FALSE otherwise
  676. Returns:
  677. STATUS_SUCCESS
  678. STATUS_INSUFFICIENT_RESOURCES
  679. --*/
  680. {
  681. DNS_STATUS DnsStatus;
  682. WCHAR * Buffer;
  683. BOOLEAN BufferAllocated = FALSE;
  684. ASSERT( Name );
  685. ASSERT( Valid );
  686. ASSERT( LsapValidateLsaUnicodeString( Name ));
  687. //
  688. // Empty names and names that are too long are not allowed
  689. //
  690. if ( Name->Length == 0 ||
  691. Name->Length > DNS_MAX_NAME_LENGTH * sizeof( WCHAR )) {
  692. *Valid = FALSE;
  693. return STATUS_SUCCESS;
  694. }
  695. if ( Name->MaximumLength > Name->Length ) {
  696. Buffer = Name->Buffer;
  697. } else {
  698. SafeAllocaAllocate( Buffer, Name->Length + sizeof( WCHAR ));
  699. if ( Buffer == NULL ) {
  700. *Valid = FALSE;
  701. return STATUS_INSUFFICIENT_RESOURCES;
  702. }
  703. BufferAllocated = TRUE;
  704. RtlCopyMemory( Buffer, Name->Buffer, Name->Length );
  705. }
  706. Buffer[Name->Length / sizeof( WCHAR )] = L'\0';
  707. DnsStatus = DnsValidateName_W( Buffer, DnsNameDomain );
  708. //
  709. // Bug 350434: Must allow non-standard characters in DNS names
  710. // (which cause DNS_ERROR_NON_RFC_NAME)
  711. //
  712. *Valid = ( DnsStatus == ERROR_SUCCESS ||
  713. DnsStatus == DNS_ERROR_NON_RFC_NAME );
  714. if ( BufferAllocated ) {
  715. SafeAllocaFree( Buffer );
  716. }
  717. return STATUS_SUCCESS;
  718. }
  719. BOOLEAN
  720. LsapIsRunningOnPersonal(
  721. VOID
  722. )
  723. /*++
  724. Routine Description:
  725. This function checks the system to see if
  726. we are running on the personal version of
  727. the operating system.
  728. The personal version is denoted by the product
  729. id equal to WINNT, which is really workstation,
  730. and the product suite containing the personal
  731. suite string.
  732. Arguments:
  733. None.
  734. Return Value:
  735. TRUE if we are running on personal, FALSE otherwise.
  736. --*/
  737. {
  738. OSVERSIONINFOEXW OsVer = {0};
  739. ULONGLONG ConditionMask = 0;
  740. OsVer.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX);
  741. OsVer.wSuiteMask = VER_SUITE_PERSONAL;
  742. OsVer.wProductType = VER_NT_WORKSTATION;
  743. VER_SET_CONDITION( ConditionMask, VER_PRODUCT_TYPE, VER_EQUAL );
  744. VER_SET_CONDITION( ConditionMask, VER_SUITENAME, VER_AND );
  745. return RtlVerifyVersionInfo( &OsVer,
  746. VER_PRODUCT_TYPE | VER_SUITENAME,
  747. ConditionMask) == STATUS_SUCCESS;
  748. }
  749. NTSTATUS
  750. LsaITestCall(
  751. IN LSAPR_HANDLE PolicyHandle,
  752. IN LSAPR_TEST_INTERNAL_ROUTINES Call,
  753. IN PLSAPR_TEST_INTERNAL_ARG_LIST InputArgs,
  754. OUT PLSAPR_TEST_INTERNAL_ARG_LIST *OutputArgs
  755. )
  756. {
  757. return STATUS_NOT_IMPLEMENTED;
  758. }