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.

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