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.

901 lines
16 KiB

  1. //----------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1992 - 1993.
  5. //
  6. // File: drt.cxx
  7. //
  8. // Contents: Main for OleDs DRT
  9. //
  10. //
  11. // History: 28-Oct-94 KrishnaG, created OleDs DRT
  12. // 28-Oct-94 ChuckC, rewritten.
  13. //
  14. //----------------------------------------------------------------------------
  15. #include "precomp.h"
  16. DWORD
  17. LdapOpen(
  18. WCHAR *domainName,
  19. int portno,
  20. HLDAP * phLdapHandle
  21. )
  22. {
  23. int ldaperr = 0;
  24. void *ldapOption;
  25. HLDAP hLdapHandle = NULL;
  26. DWORD dwError = 0;
  27. hLdapHandle = ldap_init(domainName, portno );
  28. if (hLdapHandle == NULL ) {
  29. dwError = ERROR_BAD_NETPATH;
  30. goto error;
  31. }
  32. //
  33. // Now process versioning
  34. //
  35. ldapOption = (void *) LDAP_VERSION3;
  36. ldaperr = ldap_set_option(
  37. hLdapHandle,
  38. LDAP_OPT_VERSION,
  39. &(ldapOption)
  40. );
  41. ldapOption = LDAP_OPT_ON;
  42. ldaperr = ldap_set_option(
  43. hLdapHandle,
  44. LDAP_OPT_ENCRYPT,
  45. &(ldapOption)
  46. );
  47. ldaperr = ldap_connect(hLdapHandle, NULL);
  48. if (ldaperr) {
  49. dwError = CheckAndSetExtendedError(hLdapHandle, ldaperr);
  50. goto error;
  51. }
  52. //
  53. // Disabled Callback function support and chasing external referrals
  54. // KrishnaG - do I need to support this.
  55. *phLdapHandle = hLdapHandle;
  56. return(dwError);
  57. error:
  58. if (hLdapHandle != NULL) {
  59. ldaperr = ldap_unbind( hLdapHandle );
  60. }
  61. return (dwError);
  62. }
  63. DWORD
  64. LdapBind(
  65. HLDAP hLdapHandle
  66. )
  67. {
  68. int ldaperr = 0;
  69. ldaperr = ldap_bind_s(hLdapHandle, NULL, NULL, LDAP_AUTH_SSPI);
  70. return (ldaperr);
  71. }
  72. DWORD
  73. LdapSearchHelper(
  74. HLDAP hLdapHandle,
  75. WCHAR *base,
  76. int scope,
  77. WCHAR *filter,
  78. WCHAR *attrs[],
  79. int attrsonly,
  80. struct l_timeval *timeout,
  81. LDAPMessage **res
  82. )
  83. {
  84. int nCount = 0;
  85. int j = 0;
  86. int ldaperr = 0;
  87. DWORD dwError = 0;
  88. if ( timeout == NULL )
  89. {
  90. ldaperr = ldap_search_s(
  91. hLdapHandle,
  92. base,
  93. scope,
  94. filter,
  95. attrs,
  96. attrsonly,
  97. res
  98. );
  99. dwError = CheckAndSetExtendedError(hLdapHandle, ldaperr);
  100. }
  101. else
  102. {
  103. ldaperr = ldap_search_st(
  104. hLdapHandle,
  105. base,
  106. scope,
  107. filter,
  108. attrs,
  109. attrsonly,
  110. timeout,
  111. res
  112. );
  113. dwError = CheckAndSetExtendedError(hLdapHandle, ldaperr);
  114. }
  115. //
  116. // Is there an error with checking the no of results
  117. //
  118. return (dwError);
  119. }
  120. DWORD
  121. LdapSearchS(
  122. HLDAP hLdapHandle,
  123. WCHAR *base,
  124. int scope,
  125. WCHAR *filter,
  126. WCHAR *attrs[],
  127. int attrsonly,
  128. LDAPMessage **res
  129. )
  130. {
  131. DWORD dwError = 0;
  132. dwError = LdapSearchHelper(
  133. hLdapHandle,
  134. base,
  135. scope,
  136. filter,
  137. attrs,
  138. attrsonly,
  139. NULL,
  140. res
  141. );
  142. //
  143. // Is there a check needed for connection errors
  144. //
  145. return(dwError);
  146. }
  147. DWORD
  148. LdapSearchST(
  149. HLDAP hLdapHandle,
  150. WCHAR *base,
  151. int scope,
  152. WCHAR *filter,
  153. WCHAR *attrs[],
  154. int attrsonly,
  155. struct l_timeval *timeout,
  156. LDAPMessage **res
  157. )
  158. {
  159. DWORD dwError = 0;
  160. dwError = LdapSearchHelper(
  161. hLdapHandle,
  162. base,
  163. scope,
  164. filter,
  165. attrs,
  166. attrsonly,
  167. timeout,
  168. res
  169. );
  170. return(dwError);
  171. }
  172. //
  173. // Completely new functionality - block ported from YihsinS code in ADSI
  174. //
  175. DWORD
  176. LdapAbandon(
  177. HLDAP hLdapHandle,
  178. int msgid
  179. )
  180. {
  181. // No error code, 0 if success, -1 otherwise
  182. return ldap_abandon( hLdapHandle, msgid );
  183. }
  184. DWORD
  185. LdapResult(
  186. HLDAP hLdapHandle,
  187. int msgid,
  188. int all,
  189. struct l_timeval *timeout,
  190. LDAPMessage **res,
  191. int *restype
  192. )
  193. {
  194. DWORD dwError = 0;
  195. int ldaperr = 0;
  196. *restype = ldap_result( hLdapHandle, msgid, all, timeout, res );
  197. if ( *restype == -1 ) // error
  198. ldaperr = LdapGetLastError();
  199. if (ldaperr) {
  200. if (!ldap_count_entries( hLdapHandle, *res )) {
  201. dwError = CheckAndSetExtendedError( hLdapHandle, ldaperr);
  202. }
  203. }else {
  204. dwError = 0;
  205. }
  206. return(dwError);
  207. }
  208. void
  209. LdapMsgFree(
  210. LDAPMessage *res
  211. )
  212. {
  213. ldap_msgfree( res ); // Returns the type of message freed which
  214. // is not interesting
  215. }
  216. int
  217. LdapResult2Error(
  218. HLDAP hLdapHandle,
  219. LDAPMessage *res,
  220. int freeit
  221. )
  222. {
  223. return ldap_result2error( hLdapHandle, res, freeit );
  224. }
  225. DWORD
  226. LdapFirstEntry(
  227. HLDAP hLdapHandle,
  228. LDAPMessage *res,
  229. LDAPMessage **pfirst
  230. )
  231. {
  232. DWORD dwError = 0;
  233. int ldaperr = 0;
  234. *pfirst = ldap_first_entry( hLdapHandle, res );
  235. if ( *pfirst == NULL )
  236. {
  237. ldaperr = LdapGetLastError();
  238. dwError = CheckAndSetExtendedError( hLdapHandle, ldaperr);
  239. }
  240. return(dwError);
  241. }
  242. DWORD
  243. LdapNextEntry(
  244. HLDAP hLdapHandle,
  245. LDAPMessage *entry,
  246. LDAPMessage **pnext
  247. )
  248. {
  249. DWORD dwError = 0;
  250. int ldaperr = 0;
  251. *pnext = ldap_next_entry( hLdapHandle, entry );
  252. if ( *pnext == NULL )
  253. {
  254. ldaperr = LdapGetLastError();
  255. dwError = CheckAndSetExtendedError( hLdapHandle, ldaperr);
  256. }
  257. return(dwError);
  258. }
  259. int
  260. LdapCountEntries(
  261. HLDAP hLdapHandle,
  262. LDAPMessage *res
  263. )
  264. {
  265. return ldap_count_entries( hLdapHandle, res );
  266. }
  267. DWORD
  268. LdapFirstAttribute(
  269. HLDAP hLdapHandle,
  270. LDAPMessage *entry,
  271. void **ptr,
  272. WCHAR **pattr
  273. )
  274. {
  275. // NOTE: The return value from ldap_first_attribute is static and
  276. // should not be freed
  277. *pattr = ldap_first_attribute( hLdapHandle, entry,
  278. (struct berelement **) ptr ); // static data
  279. if ( *pattr == NULL )
  280. {
  281. DWORD dwError = 0;
  282. int ldaperr = 0;
  283. // Error occurred or end of attributes
  284. ldaperr = LdapGetLastError();
  285. CheckAndSetExtendedError( hLdapHandle, ldaperr);
  286. return(dwError);
  287. }
  288. return NO_ERROR;
  289. }
  290. DWORD
  291. LdapNextAttribute(
  292. HLDAP hLdapHandle,
  293. LDAPMessage *entry,
  294. void *ptr,
  295. WCHAR **pattr
  296. )
  297. {
  298. // NOTE: The return value from ldap_next_attribute is static and
  299. // should not be freed
  300. *pattr = ldap_next_attribute( hLdapHandle, entry,
  301. (struct berelement *) ptr ); // static data
  302. #if 0 // Ignore the error code here since at the end of the enumeration,
  303. // we will probably get an error code here ( both Andy and umich's
  304. // dll will return errors sometimes. No error returned from NTDS,
  305. // but errors are returned from Exchange server )
  306. if ( *pattr == NULL )
  307. {
  308. DWORD hr = NO_ERROR;
  309. int ldaperr = 0;
  310. // Error occurred or end of attributes
  311. ldaperr = LdapGetLastError();
  312. dwError = CheckAndSetExtendedError( hLdapHandle, ldaperr);
  313. return(dwError);
  314. }
  315. #endif
  316. return S_OK;
  317. }
  318. //
  319. // NOTE: LdapGetValues return S_OK if attribute [attr] has no values
  320. // (*[pvalues] =NULL, *[pcount]=0) but all else ok.
  321. //
  322. DWORD
  323. LdapGetValues(
  324. HLDAP hLdapHandle,
  325. LDAPMessage *entry,
  326. WCHAR *attr,
  327. WCHAR ***pvalues,
  328. int *pcount
  329. )
  330. {
  331. DWORD dwError = 0;
  332. int ldaperr = 0;
  333. *pvalues = ldap_get_values( hLdapHandle, entry, attr );
  334. if ( *pvalues == NULL ) {
  335. *pcount=0;
  336. //
  337. // ldap_get_values succeeds if attribute has no values
  338. // but all else ok. (confiremed with anoopa)
  339. //
  340. ldaperr = LdapGetLastError();
  341. if (ldaperr) {
  342. dwError = CheckAndSetExtendedError( hLdapHandle, ldaperr);
  343. }
  344. //
  345. // KrishnaG if *pvalues is NULL which means I don't get back a
  346. // value - return an ERROR
  347. //
  348. return(ERROR_DS_NO_ATTRIBUTE_OR_VALUE);
  349. }
  350. *pcount = ldap_count_values( *pvalues );
  351. return S_OK;
  352. }
  353. //
  354. // NOTE: LdapGetValuesLen return S_OK if attribute [attr] has no values
  355. // (*[pvalues] =NULL, *[pcount]=0) but all else ok.
  356. //
  357. DWORD
  358. LdapGetValuesLen(
  359. HLDAP hLdapHandle,
  360. LDAPMessage *entry,
  361. WCHAR *attr,
  362. struct berval ***pvalues,
  363. int *pcount
  364. )
  365. {
  366. //
  367. // NOTE: this can contain binary data as well as strings,
  368. // strings are ascii, no conversion is done here
  369. //
  370. char *pszAttrA = NULL;
  371. DWORD dwError = 0;
  372. int ldaperr = 0;
  373. *pvalues = ldap_get_values_len( hLdapHandle, entry, attr );
  374. if ( *pvalues == NULL ){
  375. *pcount=0;
  376. //
  377. // ldap_get_values succeeds if attribute has no values
  378. // but all else ok. (confiremed with anoopa)
  379. //
  380. ldaperr = LdapGetLastError();
  381. if (ldaperr) {
  382. dwError = CheckAndSetExtendedError( hLdapHandle,ldaperr);
  383. }
  384. return(ERROR_DS_NO_ATTRIBUTE_OR_VALUE);
  385. }
  386. *pcount = ldap_count_values_len( *pvalues );
  387. return S_OK;
  388. }
  389. void
  390. LdapValueFree(
  391. WCHAR **vals
  392. )
  393. {
  394. ldap_value_free( vals );
  395. }
  396. void
  397. LdapValueFreeLen(
  398. struct berval **vals
  399. )
  400. {
  401. ldap_value_free_len( vals );
  402. }
  403. void
  404. LdapMemFree(
  405. WCHAR *pszString
  406. )
  407. {
  408. ldap_memfree( pszString );
  409. }
  410. void
  411. LdapAttributeFree(
  412. WCHAR *pszString
  413. )
  414. {
  415. // String from ldap_first/next_attribute should not be freed,
  416. // so do nothing here
  417. }
  418. DWORD
  419. LdapGetDn(
  420. HLDAP hLdapHandle,
  421. LDAPMessage *entry,
  422. WCHAR **pdn
  423. )
  424. {
  425. int ldaperr = 0;
  426. DWORD dwError = 0;
  427. *pdn = ldap_get_dn( hLdapHandle, entry );
  428. if ( *pdn == NULL )
  429. {
  430. // Error occurred
  431. ldaperr = LdapGetLastError();
  432. dwError = CheckAndSetExtendedError( hLdapHandle, ldaperr);
  433. return(dwError);
  434. }
  435. return(dwError);
  436. }
  437. DWORD
  438. CheckAndSetExtendedError(
  439. HLDAP hLdapHandle,
  440. int ldaperr
  441. )
  442. {
  443. DWORD dwErr = NO_ERROR;
  444. switch (ldaperr) {
  445. case LDAP_SUCCESS :
  446. dwErr = NO_ERROR;
  447. break;
  448. case LDAP_OPERATIONS_ERROR :
  449. dwErr = ERROR_DS_OPERATIONS_ERROR;
  450. break;
  451. case LDAP_PROTOCOL_ERROR :
  452. dwErr = ERROR_DS_PROTOCOL_ERROR;
  453. break;
  454. case LDAP_TIMELIMIT_EXCEEDED :
  455. dwErr = ERROR_DS_TIMELIMIT_EXCEEDED;
  456. break;
  457. case LDAP_SIZELIMIT_EXCEEDED :
  458. dwErr = ERROR_DS_SIZELIMIT_EXCEEDED;
  459. break;
  460. case LDAP_COMPARE_FALSE :
  461. dwErr = ERROR_DS_COMPARE_FALSE;
  462. break;
  463. case LDAP_COMPARE_TRUE :
  464. dwErr = ERROR_DS_COMPARE_TRUE;
  465. break;
  466. case LDAP_AUTH_METHOD_NOT_SUPPORTED :
  467. dwErr = ERROR_DS_AUTH_METHOD_NOT_SUPPORTED;
  468. break;
  469. case LDAP_STRONG_AUTH_REQUIRED :
  470. dwErr = ERROR_DS_STRONG_AUTH_REQUIRED;
  471. break;
  472. case LDAP_PARTIAL_RESULTS :
  473. //
  474. // Make sure we handle
  475. // partial results.
  476. //
  477. dwErr = ERROR_MORE_DATA;
  478. break;
  479. case LDAP_REFERRAL :
  480. dwErr = ERROR_DS_REFERRAL;
  481. break;
  482. case LDAP_ADMIN_LIMIT_EXCEEDED :
  483. dwErr = ERROR_DS_ADMIN_LIMIT_EXCEEDED;
  484. break;
  485. case LDAP_UNAVAILABLE_CRIT_EXTENSION :
  486. dwErr = ERROR_DS_UNAVAILABLE_CRIT_EXTENSION;
  487. break;
  488. case LDAP_CONFIDENTIALITY_REQUIRED :
  489. dwErr = ERROR_DS_CONFIDENTIALITY_REQUIRED;
  490. break;
  491. case LDAP_NO_SUCH_ATTRIBUTE :
  492. dwErr = ERROR_DS_NO_ATTRIBUTE_OR_VALUE;
  493. break;
  494. case LDAP_UNDEFINED_TYPE :
  495. dwErr = ERROR_DS_ATTRIBUTE_TYPE_UNDEFINED;
  496. break;
  497. case LDAP_INAPPROPRIATE_MATCHING :
  498. dwErr = ERROR_DS_INAPPROPRIATE_MATCHING;
  499. break;
  500. case LDAP_CONSTRAINT_VIOLATION :
  501. dwErr = ERROR_DS_CONSTRAINT_VIOLATION;
  502. break;
  503. case LDAP_ATTRIBUTE_OR_VALUE_EXISTS :
  504. dwErr = ERROR_DS_ATTRIBUTE_OR_VALUE_EXISTS;
  505. break;
  506. case LDAP_INVALID_SYNTAX :
  507. dwErr = ERROR_DS_INVALID_ATTRIBUTE_SYNTAX;
  508. break;
  509. case LDAP_NO_SUCH_OBJECT :
  510. dwErr = ERROR_DS_NO_SUCH_OBJECT;
  511. break;
  512. case LDAP_ALIAS_PROBLEM :
  513. dwErr = ERROR_DS_ALIAS_PROBLEM;
  514. break;
  515. case LDAP_INVALID_DN_SYNTAX :
  516. dwErr = ERROR_DS_INVALID_DN_SYNTAX;
  517. break;
  518. case LDAP_IS_LEAF :
  519. dwErr = ERROR_DS_IS_LEAF;
  520. break;
  521. case LDAP_ALIAS_DEREF_PROBLEM :
  522. dwErr = ERROR_DS_ALIAS_DEREF_PROBLEM;
  523. break;
  524. case LDAP_INAPPROPRIATE_AUTH :
  525. dwErr = ERROR_DS_INAPPROPRIATE_AUTH;
  526. break;
  527. case LDAP_INVALID_CREDENTIALS :
  528. dwErr = ERROR_LOGON_FAILURE;
  529. break;
  530. case LDAP_INSUFFICIENT_RIGHTS :
  531. dwErr = ERROR_ACCESS_DENIED;
  532. break;
  533. case LDAP_BUSY :
  534. dwErr = ERROR_DS_BUSY;
  535. break;
  536. case LDAP_UNAVAILABLE :
  537. dwErr = ERROR_DS_UNAVAILABLE;
  538. break;
  539. case LDAP_UNWILLING_TO_PERFORM :
  540. dwErr = ERROR_DS_UNWILLING_TO_PERFORM;
  541. break;
  542. case LDAP_LOOP_DETECT :
  543. dwErr = ERROR_DS_LOOP_DETECT;
  544. break;
  545. case LDAP_NAMING_VIOLATION :
  546. dwErr = ERROR_DS_NAMING_VIOLATION;
  547. break;
  548. case LDAP_OBJECT_CLASS_VIOLATION :
  549. dwErr = ERROR_DS_OBJ_CLASS_VIOLATION;
  550. break;
  551. case LDAP_NOT_ALLOWED_ON_NONLEAF :
  552. dwErr = ERROR_DS_CANT_ON_NON_LEAF;
  553. break;
  554. case LDAP_NOT_ALLOWED_ON_RDN :
  555. dwErr = ERROR_DS_CANT_ON_RDN;
  556. break;
  557. case LDAP_ALREADY_EXISTS :
  558. dwErr = ERROR_OBJECT_ALREADY_EXISTS;
  559. break;
  560. case LDAP_NO_OBJECT_CLASS_MODS :
  561. dwErr = ERROR_DS_CANT_MOD_OBJ_CLASS;
  562. break;
  563. case LDAP_RESULTS_TOO_LARGE :
  564. dwErr = ERROR_DS_OBJECT_RESULTS_TOO_LARGE;
  565. break;
  566. case LDAP_AFFECTS_MULTIPLE_DSAS :
  567. dwErr = ERROR_DS_AFFECTS_MULTIPLE_DSAS;
  568. break;
  569. case LDAP_OTHER :
  570. dwErr = ERROR_GEN_FAILURE;
  571. break;
  572. case LDAP_SERVER_DOWN :
  573. dwErr = ERROR_DS_SERVER_DOWN;
  574. break;
  575. case LDAP_LOCAL_ERROR :
  576. dwErr = ERROR_DS_LOCAL_ERROR;
  577. break;
  578. case LDAP_ENCODING_ERROR :
  579. dwErr = ERROR_DS_ENCODING_ERROR;
  580. break;
  581. case LDAP_DECODING_ERROR :
  582. dwErr = ERROR_DS_DECODING_ERROR;
  583. break;
  584. case LDAP_TIMEOUT :
  585. dwErr = ERROR_TIMEOUT;
  586. break;
  587. case LDAP_AUTH_UNKNOWN :
  588. dwErr = ERROR_DS_AUTH_UNKNOWN;
  589. break;
  590. case LDAP_FILTER_ERROR :
  591. dwErr = ERROR_DS_FILTER_UNKNOWN;
  592. break;
  593. case LDAP_USER_CANCELLED :
  594. dwErr = ERROR_CANCELLED;
  595. break;
  596. case LDAP_PARAM_ERROR :
  597. dwErr = ERROR_DS_PARAM_ERROR;
  598. break;
  599. case LDAP_NO_MEMORY :
  600. dwErr = ERROR_NOT_ENOUGH_MEMORY;
  601. break;
  602. case LDAP_CONNECT_ERROR :
  603. dwErr = ERROR_CONNECTION_REFUSED;
  604. break;
  605. case LDAP_NOT_SUPPORTED :
  606. dwErr = ERROR_DS_NOT_SUPPORTED;
  607. break;
  608. case LDAP_NO_RESULTS_RETURNED :
  609. dwErr = ERROR_DS_NO_RESULTS_RETURNED;
  610. break;
  611. case LDAP_CONTROL_NOT_FOUND :
  612. dwErr = ERROR_DS_CONTROL_NOT_FOUND;
  613. break;
  614. case LDAP_MORE_RESULTS_TO_RETURN :
  615. dwErr = ERROR_MORE_DATA;
  616. break;
  617. case LDAP_CLIENT_LOOP :
  618. dwErr = ERROR_DS_CLIENT_LOOP;
  619. break;
  620. case LDAP_REFERRAL_LIMIT_EXCEEDED :
  621. dwErr = ERROR_DS_REFERRAL_LIMIT_EXCEEDED;
  622. break;
  623. default:
  624. dwErr = ERROR_DS_BUSY;
  625. }
  626. return(dwErr);
  627. }
  628. DWORD
  629. LdapAddS(
  630. HLDAP hLdapHandle,
  631. WCHAR *dn,
  632. LDAPModW *attrs[]
  633. )
  634. {
  635. DWORD dwError = 0;
  636. int ldaperr = 0;
  637. ldaperr = ldap_add_s( hLdapHandle, dn, attrs );
  638. dwError = CheckAndSetExtendedError(hLdapHandle, ldaperr);
  639. return(dwError);
  640. }
  641. DWORD
  642. LdapModifyS(
  643. HLDAP hLdapHandle,
  644. WCHAR *dn,
  645. LDAPModW *mods[]
  646. )
  647. {
  648. DWORD dwError = 0;
  649. int ldaperr = 0;
  650. ldaperr = ldap_modify_s( hLdapHandle, dn, mods);
  651. dwError = CheckAndSetExtendedError(hLdapHandle, ldaperr);
  652. return(dwError);
  653. }
  654. DWORD
  655. LdapDeleteS(
  656. HLDAP hLdapHandle,
  657. WCHAR *dn
  658. )
  659. {
  660. DWORD dwError = 0;
  661. int ldaperr = 0;
  662. ldaperr = ldap_delete_s( hLdapHandle, dn );
  663. dwError = CheckAndSetExtendedError(hLdapHandle, ldaperr);
  664. return(dwError);
  665. }