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.

1053 lines
24 KiB

  1. /*++
  2. Copyright (c) 1997 Microsoft Corporation
  3. Module Name:
  4. sam.c
  5. Abstract:
  6. Domain Name System (DNS) Server -- Admin Client API
  7. Functions developed for SAM as simplified interfaces \ examples.
  8. Author:
  9. Jim Gilroy (jamesg) September 1997
  10. Environment:
  11. User Mode - Win32
  12. Revision History:
  13. --*/
  14. #include "dnsclip.h"
  15. #define MAX_SAM_BACKOFF (32000) // wait up to 32 seconds
  16. //
  17. // Type specific update functions.
  18. //
  19. VOID
  20. DNS_API_FUNCTION
  21. DnssrvFillRecordHeader(
  22. IN OUT PDNS_RPC_RECORD pRecord,
  23. IN DWORD dwTtl,
  24. IN DWORD dwTimeStamp,
  25. IN BOOL fSuppressNotify
  26. )
  27. {
  28. pRecord->dwTtlSeconds = dwTtl;
  29. pRecord->dwTimeStamp = dwTimeStamp;
  30. pRecord->dwFlags = 0;
  31. if ( fSuppressNotify )
  32. {
  33. pRecord->dwFlags |= DNS_RPC_FLAG_SUPPRESS_NOTIFY;
  34. }
  35. }
  36. DWORD
  37. DNS_API_FUNCTION
  38. DnssrvWriteNameToFlatBuffer(
  39. IN OUT PCHAR pchWrite,
  40. IN LPCSTR pszName
  41. )
  42. /*++
  43. Routine Description:
  44. Write DNS name (or string) to flat buffer.
  45. Arguments:
  46. pchWrite -- location to write name at
  47. pszName -- name or string to write
  48. Return Value:
  49. Length of name written, including count byte. Caller may countinue in
  50. buffer at pchWrite + returned length.
  51. 0 on name error.
  52. --*/
  53. {
  54. DWORD length;
  55. //
  56. // get name length
  57. // whether name or string, must be 255 or less to fit
  58. // counted character format
  59. length = strlen( pszName );
  60. if ( length > DNS_MAX_NAME_LENGTH )
  61. {
  62. return( 0 );
  63. }
  64. //
  65. // write name to desired location
  66. // - count byte first
  67. // - then name itself
  68. * (PUCHAR) pchWrite = (UCHAR) length;
  69. pchWrite++;
  70. RtlCopyMemory(
  71. pchWrite,
  72. pszName,
  73. length );
  74. return( length+1 );
  75. }
  76. DNS_STATUS
  77. DNS_API_FUNCTION
  78. DnssrvFillOutSingleIndirectionRecord(
  79. IN OUT PDNS_RPC_RECORD pRecord,
  80. IN WORD wType,
  81. IN LPCSTR pszName
  82. )
  83. {
  84. PCHAR pwriteName;
  85. DWORD length;
  86. DWORD dataLength = 0;
  87. //
  88. // find name write position and final data length for various types
  89. //
  90. switch( wType )
  91. {
  92. case DNS_TYPE_MX:
  93. pwriteName = (PCHAR) &pRecord->Data.MX.nameExchange;
  94. dataLength += sizeof(WORD);
  95. break;
  96. case DNS_TYPE_SRV:
  97. pwriteName = (PCHAR) &pRecord->Data.SRV.nameTarget;
  98. dataLength += 3*sizeof(WORD);
  99. break;
  100. default:
  101. // all plain single-indirection types (CNAME, NS, PTR, etc)
  102. pwriteName = (PCHAR) &pRecord->Data.PTR.nameNode;
  103. }
  104. //
  105. // write name
  106. // - note name's datalength includes count character
  107. //
  108. length = DnssrvWriteNameToFlatBuffer( pwriteName, pszName );
  109. if ( !length )
  110. {
  111. return( ERROR_INVALID_DATA );
  112. }
  113. dataLength += length;
  114. // set record header fields
  115. pRecord->wType = wType;
  116. pRecord->wDataLength = (WORD)dataLength;
  117. ASSERT( (PCHAR)pRecord + SIZEOF_DNS_RPC_RECORD_HEADER + dataLength
  118. == pwriteName + length );
  119. return( ERROR_SUCCESS );
  120. }
  121. DNS_STATUS
  122. DNS_API_FUNCTION
  123. DnssrvAddARecord(
  124. IN LPCWSTR pwszServer,
  125. IN LPCSTR pszNodeName,
  126. IN IP_ADDRESS ipAddress,
  127. IN DWORD dwTtl,
  128. IN DWORD dwTimeout,
  129. IN BOOL fSuppressNotify
  130. )
  131. {
  132. DNS_RPC_RECORD record;
  133. // pack up data and send
  134. DnssrvFillRecordHeader(
  135. & record,
  136. dwTtl,
  137. dwTimeout,
  138. fSuppressNotify );
  139. record.wType = DNS_TYPE_A;
  140. record.wDataLength = sizeof(IP_ADDRESS);
  141. record.Data.A.ipAddress = ipAddress;
  142. return DnssrvUpdateRecord(
  143. pwszServer,
  144. NULL, // zone not specified
  145. pszNodeName,
  146. &record,
  147. NULL );
  148. }
  149. DNS_STATUS
  150. DNS_API_FUNCTION
  151. DnssrvAddCnameRecord(
  152. IN LPCWSTR pwszServer,
  153. IN LPCSTR pszNodeName,
  154. IN LPCSTR pszCannonicalName,
  155. IN DWORD dwTtl,
  156. IN DWORD dwTimeout,
  157. IN BOOL fSuppressNotify
  158. )
  159. {
  160. DNS_RPC_RECORD record;
  161. // pack up data and send
  162. DnssrvFillRecordHeader(
  163. & record,
  164. dwTtl,
  165. dwTimeout,
  166. fSuppressNotify );
  167. DnssrvFillOutSingleIndirectionRecord(
  168. & record,
  169. DNS_TYPE_CNAME,
  170. pszCannonicalName );
  171. return DnssrvUpdateRecord(
  172. pwszServer,
  173. NULL, // zone not specified
  174. pszNodeName,
  175. &record,
  176. NULL );
  177. }
  178. DNS_STATUS
  179. DNS_API_FUNCTION
  180. DnssrvAddMxRecord(
  181. IN LPCWSTR pwszServer,
  182. IN LPCSTR pszNodeName,
  183. IN LPCSTR pszMailExchangeHost,
  184. IN WORD wPreference,
  185. IN DWORD dwTtl,
  186. IN DWORD dwTimeout,
  187. IN BOOL fSuppressNotify
  188. )
  189. {
  190. DNS_RPC_RECORD record;
  191. // pack up data and send
  192. DnssrvFillRecordHeader(
  193. & record,
  194. dwTtl,
  195. dwTimeout,
  196. fSuppressNotify );
  197. DnssrvFillOutSingleIndirectionRecord(
  198. & record,
  199. DNS_TYPE_MX,
  200. pszMailExchangeHost );
  201. record.Data.MX.wPreference = wPreference;
  202. return DnssrvUpdateRecord(
  203. pwszServer,
  204. NULL, // zone not specified
  205. pszNodeName,
  206. &record,
  207. NULL );
  208. }
  209. DNS_STATUS
  210. DNS_API_FUNCTION
  211. DnssrvAddNsRecord(
  212. IN LPCWSTR pwszServer,
  213. IN LPCSTR pszNodeName,
  214. IN LPCSTR pszNsHostName,
  215. IN DWORD dwTtl,
  216. IN DWORD dwTimeout,
  217. IN BOOL fSuppressNotify
  218. )
  219. {
  220. DNS_RPC_RECORD record;
  221. DWORD length;
  222. // pack up data and send
  223. DnssrvFillRecordHeader(
  224. & record,
  225. dwTtl,
  226. dwTimeout,
  227. fSuppressNotify );
  228. DnssrvFillOutSingleIndirectionRecord(
  229. & record,
  230. DNS_TYPE_NS,
  231. pszNsHostName );
  232. return DnssrvUpdateRecord(
  233. pwszServer,
  234. NULL, // zone not specified
  235. pszNodeName,
  236. &record,
  237. NULL );
  238. }
  239. DNS_STATUS
  240. DNS_API_FUNCTION
  241. DnssrvConcatDnsNames(
  242. OUT PCHAR pszResult,
  243. IN LPCSTR pszDomain,
  244. IN LPCSTR pszName
  245. )
  246. /*++
  247. Routine Description:
  248. Concatenate two DNS names.
  249. Result is FQDN DNS name -- dot terminated.
  250. Note, currently no validity check is done on names being appended.
  251. If they are invalid DNS names then result is invalid DNS name.
  252. Arguments:
  253. pszResult -- result name buffer; should be DNS_MAX_NAME_BUFFER_LEN to
  254. be protected from name overwrite
  255. pszDomain -- domain name to write
  256. pszName -- name (like a host name) to prepend to domain name
  257. Return Value:
  258. ERROR_SUCCESS if successful. pszResult then contains FQDN
  259. DNS_ERROR_INVALID_NAME on failure.
  260. --*/
  261. {
  262. DWORD lengthDomain;
  263. DWORD lengthName;
  264. // handle NULL name case
  265. if ( !pszName )
  266. {
  267. strcpy( pszResult, pszDomain );
  268. return( ERROR_SUCCESS );
  269. }
  270. //
  271. // build combined name
  272. // - verify combined length within DNS limit
  273. // - put dot between names
  274. // - dot terminate combined name (make FQDN)
  275. //
  276. lengthDomain = strlen( pszDomain );
  277. lengthName = strlen( pszName );
  278. if ( lengthDomain + lengthName + 2 > DNS_MAX_NAME_LENGTH )
  279. {
  280. return( DNS_ERROR_INVALID_NAME );
  281. }
  282. strcpy( pszResult, pszName );
  283. if ( pszDomain[lengthName-1] != '.' )
  284. {
  285. strcat( pszResult, "." );
  286. }
  287. strcat( pszResult, pszDomain );
  288. if ( pszDomain[lengthDomain-1] != '.' )
  289. {
  290. strcat( pszResult, "." );
  291. }
  292. return( ERROR_SUCCESS );
  293. }
  294. DNS_STATUS
  295. DNS_API_FUNCTION
  296. DnssrvSbsAddClientToIspZone(
  297. IN LPCWSTR pwszServer,
  298. IN LPCSTR pszIspZone,
  299. IN LPCSTR pszClient,
  300. IN LPCSTR pszClientHost,
  301. IN IP_ADDRESS ipClientHost,
  302. IN DWORD dwTtl
  303. )
  304. {
  305. DNS_STATUS status;
  306. INT recordCount = (-1);
  307. INT backoff = 0;
  308. CHAR szdomain[ DNS_MAX_NAME_BUFFER_LENGTH ];
  309. CHAR szhost[ DNS_MAX_NAME_BUFFER_LENGTH ];
  310. CHAR sztarget[ DNS_MAX_NAME_BUFFER_LENGTH ];
  311. //
  312. // to register in ISP zone need to register
  313. // - MX
  314. // - CNAME for web server
  315. // - host for web and mail server
  316. //
  317. // build FQDN for domain and host and cname
  318. // - do this now so we know names are valid
  319. //
  320. status = DnssrvConcatDnsNames(
  321. szdomain,
  322. pszIspZone,
  323. pszClient );
  324. if ( status != ERROR_SUCCESS )
  325. {
  326. return( status );
  327. }
  328. status = DnssrvConcatDnsNames(
  329. szhost,
  330. szdomain,
  331. pszClientHost );
  332. if ( status != ERROR_SUCCESS )
  333. {
  334. return( status );
  335. }
  336. status = DnssrvConcatDnsNames(
  337. sztarget,
  338. szdomain,
  339. "www" );
  340. if ( status != ERROR_SUCCESS )
  341. {
  342. return( status );
  343. }
  344. //
  345. // do registrations, looping in case server is unable to complete
  346. // immediately but is open for update
  347. //
  348. while ( 1 )
  349. {
  350. // if retrying backoff, but continue trying
  351. if ( backoff )
  352. {
  353. if ( backoff > MAX_SAM_BACKOFF )
  354. {
  355. break;
  356. }
  357. Sleep( backoff );
  358. }
  359. backoff += 1000;
  360. //
  361. // remove any old entries at client domain
  362. //
  363. if ( recordCount < 0 )
  364. {
  365. status = DnssrvDeleteNode(
  366. pwszServer,
  367. pszIspZone,
  368. szdomain,
  369. 1 // delete subtree
  370. );
  371. if ( status == DNS_ERROR_NAME_DOES_NOT_EXIST )
  372. {
  373. status = ERROR_SUCCESS;
  374. }
  375. }
  376. // register A record
  377. else if ( recordCount < 1 )
  378. {
  379. status = DnssrvAddARecord(
  380. pwszServer,
  381. szhost,
  382. ipClientHost,
  383. dwTtl,
  384. 0, // no timeout
  385. TRUE ); // suppress notify
  386. }
  387. // register CNAME for WEB server
  388. else if ( recordCount < 2 )
  389. {
  390. status = DnssrvAddCnameRecord(
  391. pwszServer,
  392. sztarget,
  393. szhost,
  394. dwTtl,
  395. 0, // no timeout
  396. TRUE ); // suppress notify
  397. }
  398. // register MX at client's domain root
  399. // then at wildcard
  400. else if ( recordCount < 3 )
  401. {
  402. status = DnssrvAddMxRecord(
  403. pwszServer,
  404. szdomain,
  405. szhost,
  406. 10, // preference
  407. dwTtl,
  408. 0, // no timeout
  409. TRUE ); // suppress notify
  410. }
  411. else if ( recordCount < 4 )
  412. {
  413. // prepare *.<client>.isp name for wildcard MX record
  414. status = DnssrvConcatDnsNames(
  415. sztarget,
  416. szdomain,
  417. "*" );
  418. if ( status != ERROR_SUCCESS )
  419. {
  420. ASSERT( FALSE );
  421. break;
  422. }
  423. status = DnssrvAddMxRecord(
  424. pwszServer,
  425. sztarget,
  426. szhost,
  427. 10, // preference
  428. dwTtl,
  429. 0, // no timeout
  430. TRUE ); // suppress notify
  431. }
  432. // all desired records registered
  433. else
  434. {
  435. ASSERT( recordCount == 4 );
  436. break;
  437. }
  438. //
  439. // check status on operations
  440. // - if successful, inc count and reset backoff to move
  441. // onto next operation
  442. // - if zone locked, continue after backoff
  443. // - other errors are terminal
  444. //
  445. if ( status == ERROR_SUCCESS ||
  446. status == DNS_ERROR_RECORD_ALREADY_EXISTS )
  447. {
  448. recordCount++;
  449. backoff = 0;
  450. }
  451. else if ( status == DNS_ERROR_ZONE_LOCKED )
  452. {
  453. continue;
  454. }
  455. else
  456. {
  457. break;
  458. }
  459. }
  460. return( status );
  461. }
  462. //
  463. // Record deleting functions.
  464. //
  465. // This example uses A records.
  466. // Could be cloned to handle MX or CNAME or NS.
  467. // OR could expand this function to choose type
  468. //
  469. BOOL
  470. DNS_API_FUNCTION
  471. DnssrvMatchDnsRpcName(
  472. IN PDNS_RPC_NAME pRpcName,
  473. IN LPCSTR pszName
  474. )
  475. {
  476. CHAR nameBuf[ DNS_MAX_NAME_BUFFER_LENGTH ] = "";
  477. RtlCopyMemory(
  478. nameBuf,
  479. pRpcName->achName,
  480. pRpcName->cchNameLength );
  481. return Dns_NameCompare_UTF8( nameBuf, (LPSTR)pszName );
  482. }
  483. DNS_STATUS
  484. DNS_API_FUNCTION
  485. DnssrvDeleteARecord(
  486. IN LPCWSTR pwszServer,
  487. IN LPCSTR pszNodeName,
  488. IN IP_ADDRESS ipAddress,
  489. IN BOOL fSuppressNotify
  490. )
  491. {
  492. DNS_RPC_RECORD record;
  493. DNSDBG( RPC2, ( "DnssrvDeleteARecord()\n" ));
  494. // pack up data and send
  495. DnssrvFillRecordHeader(
  496. & record,
  497. 0, // TTL irrelevant for delete
  498. 0, // timeout irrelevant
  499. fSuppressNotify );
  500. record.wType = DNS_TYPE_A;
  501. record.wDataLength = sizeof(IP_ADDRESS);
  502. record.Data.A.ipAddress = ipAddress;
  503. return DnssrvUpdateRecord(
  504. pwszServer,
  505. NULL, // zone not specified
  506. pszNodeName,
  507. NULL, // no add
  508. &record );
  509. }
  510. DNS_STATUS
  511. DNS_API_FUNCTION
  512. DnssrvDeleteCnameRecord(
  513. IN LPCWSTR pwszServer,
  514. IN LPCSTR pszNodeName,
  515. IN LPCSTR pszCannonicalName,
  516. IN BOOL fSuppressNotify
  517. )
  518. {
  519. DNS_RPC_RECORD record;
  520. // pack up data and send
  521. DnssrvFillRecordHeader(
  522. & record,
  523. 0, // TTL irrelevant for delete
  524. 0, // timeout irrelevant
  525. fSuppressNotify );
  526. DnssrvFillOutSingleIndirectionRecord(
  527. & record,
  528. DNS_TYPE_CNAME,
  529. pszCannonicalName );
  530. return DnssrvUpdateRecord(
  531. pwszServer,
  532. NULL, // zone not specified
  533. pszNodeName,
  534. NULL,
  535. &record );
  536. }
  537. DNS_STATUS
  538. DNS_API_FUNCTION
  539. DnssrvDeleteMxRecord(
  540. IN LPCWSTR pwszServer,
  541. IN LPCSTR pszNodeName,
  542. IN LPCSTR pszMailExchangeHost,
  543. IN WORD wPreference,
  544. IN BOOL fSuppressNotify
  545. )
  546. {
  547. DNS_RPC_RECORD record;
  548. // pack up data and send
  549. DnssrvFillRecordHeader(
  550. & record,
  551. 0, // TTL irrelevant for delete
  552. 0, // timeout irrelevant
  553. fSuppressNotify );
  554. DnssrvFillOutSingleIndirectionRecord(
  555. & record,
  556. DNS_TYPE_MX,
  557. pszMailExchangeHost );
  558. record.Data.MX.wPreference = wPreference;
  559. return DnssrvUpdateRecord(
  560. pwszServer,
  561. NULL, // zone not specified
  562. pszNodeName,
  563. NULL,
  564. &record );
  565. }
  566. DNS_STATUS
  567. DNS_API_FUNCTION
  568. DnssrvDeleteNsRecord(
  569. IN LPCWSTR pwszServer,
  570. IN LPCSTR pszNodeName,
  571. IN LPCSTR pszNsHostName,
  572. IN BOOL fSuppressNotify
  573. )
  574. {
  575. DNS_RPC_RECORD record;
  576. // pack up data and send
  577. DnssrvFillRecordHeader(
  578. & record,
  579. 0, // TTL irrelevant for delete
  580. 0, // timeout irrelevant
  581. fSuppressNotify );
  582. DnssrvFillOutSingleIndirectionRecord(
  583. & record,
  584. DNS_TYPE_NS,
  585. pszNsHostName );
  586. return DnssrvUpdateRecord(
  587. pwszServer,
  588. NULL, // zone not specified
  589. pszNodeName,
  590. NULL,
  591. &record );
  592. }
  593. #if 0
  594. DNS_STATUS
  595. DNS_API_FUNCTION
  596. DnssrvSbsDeleteRecord(
  597. IN LPCWSTR pwszServer,
  598. IN LPCSTR pszZone,
  599. IN LPCSTR pszDomain,
  600. IN LPCSTR pszOwner,
  601. IN WORD wType,
  602. IN LPCSTR pszDataName,
  603. IN IP_ADDRESS ipHost
  604. )
  605. {
  606. PDNS_RPC_RECORD prpcRecord;
  607. DNS_STATUS status;
  608. BOOL ffound;
  609. INT countRecords;
  610. PBYTE pbyte;
  611. PBYTE pstopByte;
  612. PBYTE pbuffer;
  613. DWORD bufferLength;
  614. CHAR szdomain[ DNS_MAX_NAME_BUFFER_LENGTH ];
  615. CHAR szhost[ DNS_MAX_NAME_BUFFER_LENGTH ];
  616. DNSDBG( RPC2, ( "DnssrvSbsDeleteRecord()\n" ));
  617. //
  618. // to register in ISP zone need to register
  619. // - MX
  620. // - CNAME for web server
  621. // - host for web and mail server
  622. //
  623. // build FQDN for domain and host and cname
  624. // - do this now so we know names are valid
  625. //
  626. status = DnssrvConcatDnsNames(
  627. szdomain,
  628. pszZone,
  629. pszDomain );
  630. if ( status != ERROR_SUCCESS )
  631. {
  632. return( status );
  633. }
  634. status = DnssrvConcatDnsNames(
  635. szhost,
  636. szdomain,
  637. pszOwner );
  638. if ( status != ERROR_SUCCESS )
  639. {
  640. return( status );
  641. }
  642. //
  643. // enumerate records at a particular node
  644. //
  645. status = DnssrvEnumRecords(
  646. pwszServer,
  647. szhost,
  648. NULL,
  649. wType,
  650. ( DNS_RPC_VIEW_ALL_DATA | DNS_RPC_VIEW_NO_CHILDREN ),
  651. & bufferLength,
  652. & pbuffer );
  653. if ( status != ERROR_SUCCESS )
  654. {
  655. DNSDBG( RPC2, ( "DnssrvEnumRecord() failed %p.\n", status ));
  656. return( status );
  657. }
  658. pstopByte = pbuffer + bufferLength;
  659. pbyte = pbuffer;
  660. //
  661. // read node info
  662. // - extract record count
  663. //
  664. countRecords = ((PDNS_RPC_NODE)pbyte)->wRecordCount;
  665. pbyte += ((PDNS_RPC_NODE)pbyte)->wLength;
  666. pbyte = DNS_NEXT_DWORD_PTR(pbyte);
  667. //
  668. // loop through all records in node, delete appropriate one
  669. //
  670. DNSDBG( RPC2, (
  671. "Checking %d records for matching record.\n",
  672. countRecords ));
  673. while ( countRecords-- )
  674. {
  675. prpcRecord = (PDNS_RPC_RECORD) pbyte;
  676. if ( !DNS_IS_RPC_RECORD_WITHIN_BUFFER( prpcRecord, pstopByte ) )
  677. {
  678. DNS_PRINT((
  679. "ERROR: Bogus buffer at %p\n"
  680. "\tRecord leads past buffer end at %p\n"
  681. "\twith %d records remaining.\n",
  682. prpcRecord,
  683. pstopByte,
  684. countRecords+1 ));
  685. DNS_ASSERT( FALSE );
  686. return( DNS_ERROR_INVALID_DATA );
  687. }
  688. // if type not desired type, then not interesting
  689. if ( prpcRecord->wType != wType )
  690. {
  691. DNS_ASSERT( FALSE );
  692. return( DNS_ERROR_INVALID_DATA );
  693. }
  694. DNSDBG( RPC2, (
  695. "Checking record at %p for matching data of type %d.\n",
  696. prpcRecord,
  697. wType ));
  698. //
  699. // check for data match, delete if match
  700. //
  701. switch ( wType )
  702. {
  703. case DNS_TYPE_A:
  704. ffound = ( prpcRecord->Data.A.ipAddress == ipHost );
  705. DNSDBG( RPC2, (
  706. "%s match between A record %lx and desired IP %lx\n",
  707. ffound ? "Found" : "No",
  708. prpcRecord->Data.A.ipAddress,
  709. ipHost ));
  710. break;
  711. case DNS_TYPE_MX:
  712. ffound = DnssrvMatchDnsRpcName(
  713. & prpcRecord->Data.MX.nameExchange,
  714. pszDataName );
  715. break;
  716. case DNS_TYPE_NS:
  717. case DNS_TYPE_CNAME:
  718. case DNS_TYPE_PTR:
  719. ffound = DnssrvMatchDnsRpcName(
  720. & prpcRecord->Data.MX.nameExchange,
  721. pszDataName );
  722. break;
  723. default:
  724. return( DNS_ERROR_INVALID_DATA );
  725. }
  726. if ( ffound )
  727. {
  728. DNSDBG( RPC2, (
  729. "Found record (handle = %p) with desired data\n"
  730. "\t... deleting record\n",
  731. prpcRecord->hRecord ));
  732. status = DnssrvDeleteRecord(
  733. pwszServer,
  734. szhost,
  735. prpcRecord->hRecord );
  736. if ( status != ERROR_SUCCESS )
  737. {
  738. return( status );
  739. }
  740. // shouldn't need to continue, as no duplicates allowed in general case
  741. // however to rule out glue or WINS cached data, continue compare\delete
  742. // until node is clear
  743. }
  744. // position ourselves at next record
  745. pbyte = (PCHAR) DNS_GET_NEXT_RPC_RECORD( prpcRecord );
  746. // continue looking for matching records
  747. }
  748. return( ERROR_SUCCESS );
  749. }
  750. #endif
  751. DNS_STATUS
  752. DNS_API_FUNCTION
  753. DnssrvSbsDeleteRecord(
  754. IN LPCWSTR pwszServer,
  755. IN LPCSTR pszZone,
  756. IN LPCSTR pszDomain,
  757. IN LPCSTR pszOwner,
  758. IN WORD wType,
  759. IN LPCSTR pszDataName,
  760. IN IP_ADDRESS ipHost
  761. )
  762. {
  763. DNS_STATUS status;
  764. CHAR szdomain[ DNS_MAX_NAME_BUFFER_LENGTH ];
  765. CHAR szhost[ DNS_MAX_NAME_BUFFER_LENGTH ];
  766. DNSDBG( RPC2, ( "DnssrvSbsDeleteRecord()\n" ));
  767. //
  768. // to register in ISP zone need to register
  769. // - MX
  770. // - CNAME for web server
  771. // - host for web and mail server
  772. //
  773. // build FQDN for domain and host and cname
  774. // - do this now so we know names are valid
  775. //
  776. status = DnssrvConcatDnsNames(
  777. szdomain,
  778. pszZone,
  779. pszDomain );
  780. if ( status != ERROR_SUCCESS )
  781. {
  782. return( status );
  783. }
  784. status = DnssrvConcatDnsNames(
  785. szhost,
  786. szdomain,
  787. pszOwner );
  788. if ( status != ERROR_SUCCESS )
  789. {
  790. return( status );
  791. }
  792. //
  793. // dispatch to appropriate type delete routine
  794. //
  795. switch ( wType )
  796. {
  797. case DNS_TYPE_A:
  798. return DnssrvDeleteARecord(
  799. pwszServer,
  800. szhost,
  801. ipHost,
  802. FALSE // no notify suppress
  803. );
  804. case DNS_TYPE_NS:
  805. return DnssrvDeleteNsRecord(
  806. pwszServer,
  807. szhost,
  808. pszDataName,
  809. FALSE // no notify suppress
  810. );
  811. case DNS_TYPE_CNAME:
  812. return DnssrvDeleteCnameRecord(
  813. pwszServer,
  814. szhost,
  815. pszDataName,
  816. FALSE // no notify suppress
  817. );
  818. case DNS_TYPE_MX:
  819. return DnssrvDeleteMxRecord(
  820. pwszServer,
  821. szhost,
  822. pszDataName,
  823. (WORD) ipHost,
  824. FALSE // no notify suppress
  825. );
  826. default:
  827. return( DNS_ERROR_INVALID_DATA );
  828. }
  829. return( ERROR_SUCCESS );
  830. }
  831. //
  832. // End sam.c
  833. //