dblookup.c 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969
  1. #include <u.h>
  2. #include <libc.h>
  3. #include <bio.h>
  4. #include <ndb.h>
  5. #include <ip.h>
  6. #include "dns.h"
  7. static Ndb *db;
  8. Area *owned;
  9. Area *delegated;
  10. static RR* dblookup1(char*, int, int, int);
  11. static RR* addrrr(Ndbtuple*, Ndbtuple*);
  12. static RR* nsrr(Ndbtuple*, Ndbtuple*);
  13. static RR* cnamerr(Ndbtuple*, Ndbtuple*);
  14. static RR* mxrr(Ndbtuple*, Ndbtuple*);
  15. static RR* soarr(Ndbtuple*, Ndbtuple*);
  16. static RR* ptrrr(Ndbtuple*, Ndbtuple*);
  17. static Ndbtuple* look(Ndbtuple*, Ndbtuple*, char*);
  18. static RR* doaxfr(Ndb*, char*);
  19. static RR* nullrr(Ndbtuple *entry, Ndbtuple *pair);
  20. static RR* txtrr(Ndbtuple *entry, Ndbtuple *pair);
  21. static Lock dblock;
  22. static void createptrs(void);
  23. static int implemented[Tall] =
  24. {
  25. [Ta] 1,
  26. [Tns] 1,
  27. [Tsoa] 1,
  28. [Tmx] 1,
  29. [Tptr] 1,
  30. [Tcname] 1,
  31. [Tnull] 1,
  32. [Ttxt] 1,
  33. };
  34. int
  35. opendatabase(void)
  36. {
  37. char buf[256];
  38. Ndb *xdb;
  39. if(db == nil){
  40. snprint(buf, sizeof(buf), "%s/ndb", mntpt);
  41. xdb = ndbopen(dbfile);
  42. if(xdb != nil)
  43. xdb->nohash = 1;
  44. db = ndbcat(ndbopen(buf), xdb);
  45. }
  46. if(db == nil)
  47. return -1;
  48. else
  49. return 0;
  50. }
  51. /*
  52. * lookup an RR in the network database, look for matches
  53. * against both the domain name and the wildcarded domain name.
  54. *
  55. * the lock makes sure only one process can be accessing the data
  56. * base at a time. This is important since there's a lot of
  57. * shared state there.
  58. *
  59. * e.g. for x.research.bell-labs.com, first look for a match against
  60. * the x.research.bell-labs.com. If nothing matches, try *.research.bell-labs.com.
  61. */
  62. RR*
  63. dblookup(char *name, int class, int type, int auth, int ttl)
  64. {
  65. RR *rp, *tp;
  66. char buf[256];
  67. char *wild, *cp;
  68. DN *dp, *ndp;
  69. int err;
  70. static int parallel;
  71. static int parfd[2];
  72. static char token[1];
  73. /* so far only internet lookups are implemented */
  74. if(class != Cin)
  75. return 0;
  76. err = Rname;
  77. if(type == Tall){
  78. rp = 0;
  79. for (type = Ta; type < Tall; type++)
  80. if(implemented[type])
  81. rrcat(&rp, dblookup(name, class, type, auth, ttl));
  82. return rp;
  83. }
  84. lock(&dblock);
  85. dp = dnlookup(name, class, 1);
  86. if(opendatabase() < 0)
  87. goto out;
  88. if(dp->rr)
  89. err = 0;
  90. /* first try the given name */
  91. rp = 0;
  92. if(cachedb)
  93. rp = rrlookup(dp, type, NOneg);
  94. else
  95. rp = dblookup1(name, type, auth, ttl);
  96. if(rp)
  97. goto out;
  98. /* try lower case version */
  99. for(cp = name; *cp; cp++)
  100. *cp = tolower(*cp);
  101. if(cachedb)
  102. rp = rrlookup(dp, type, NOneg);
  103. else
  104. rp = dblookup1(name, type, auth, ttl);
  105. if(rp)
  106. goto out;
  107. /* walk the domain name trying the wildcard '*' at each position */
  108. for(wild = strchr(name, '.'); wild; wild = strchr(wild+1, '.')){
  109. snprint(buf, sizeof(buf), "*%s", wild);
  110. ndp = dnlookup(buf, class, 1);
  111. if(ndp->rr)
  112. err = 0;
  113. if(cachedb)
  114. rp = rrlookup(ndp, type, NOneg);
  115. else
  116. rp = dblookup1(buf, type, auth, ttl);
  117. if(rp)
  118. break;
  119. }
  120. out:
  121. /* add owner to uncached records */
  122. if(rp){
  123. for(tp = rp; tp; tp = tp->next)
  124. tp->owner = dp;
  125. } else
  126. dp->nonexistent = err;
  127. unlock(&dblock);
  128. return rp;
  129. }
  130. /*
  131. * lookup an RR in the network database
  132. */
  133. static RR*
  134. dblookup1(char *name, int type, int auth, int ttl)
  135. {
  136. Ndbtuple *t, *nt;
  137. RR *rp, *list, **l;
  138. Ndbs s;
  139. char val[Ndbvlen], dname[Ndbvlen];
  140. char *attr;
  141. DN *dp;
  142. RR *(*f)(Ndbtuple*, Ndbtuple*);
  143. int found, x;
  144. dp = 0;
  145. switch(type){
  146. case Tptr:
  147. attr = "ptr";
  148. f = ptrrr;
  149. break;
  150. case Ta:
  151. attr = "ip";
  152. f = addrrr;
  153. break;
  154. case Tnull:
  155. attr = "nullrr";
  156. f = nullrr;
  157. break;
  158. case Tns:
  159. attr = "ns";
  160. f = nsrr;
  161. break;
  162. case Tsoa:
  163. attr = "soa";
  164. f = soarr;
  165. break;
  166. case Tmx:
  167. attr = "mx";
  168. f = mxrr;
  169. break;
  170. case Tcname:
  171. attr = "cname";
  172. f = cnamerr;
  173. break;
  174. case Taxfr:
  175. case Tixfr:
  176. return doaxfr(db, name);
  177. default:
  178. return nil;
  179. }
  180. /*
  181. * find a matching entry in the database
  182. */
  183. t = ndbgetval(db, &s, "dom", name, attr, val);
  184. /*
  185. * hack for local names
  186. */
  187. if(t == 0 && strchr(name, '.') == 0)
  188. t = ndbgetval(db, &s, "sys", name, attr, val);
  189. if(t == 0)
  190. return nil;
  191. /* search whole entry for default domain name */
  192. strncpy(dname, name, Ndbvlen);
  193. for(nt = t; nt; nt = nt->entry)
  194. if(strcmp(nt->attr, "dom") == 0){
  195. strcpy(dname, nt->val);
  196. break;
  197. }
  198. /* ttl is maximum of soa minttl and entry's ttl ala rfc883 */
  199. nt = look(t, s.t, "ttl");
  200. if(nt){
  201. x = atoi(nt->val);
  202. if(x > ttl)
  203. ttl = x;
  204. }
  205. /* default ttl is one day */
  206. if(ttl < 0)
  207. ttl = DEFTTL;
  208. /*
  209. * The database has 2 levels of precedence; line and entry.
  210. * Pairs on the same line bind tighter than pairs in the
  211. * same entry, so we search the line first.
  212. */
  213. found = 0;
  214. list = 0;
  215. l = &list;
  216. for(nt = s.t;; ){
  217. if(found == 0 && strcmp(nt->attr, "dom") == 0){
  218. strcpy(dname, nt->val);
  219. found = 1;
  220. }
  221. if(cistrcmp(attr, nt->attr) == 0){
  222. rp = (*f)(t, nt);
  223. rp->auth = auth;
  224. rp->db = 1;
  225. if(ttl)
  226. rp->ttl = ttl;
  227. if(dp == 0)
  228. dp = dnlookup(dname, Cin, 1);
  229. rp->owner = dp;
  230. *l = rp;
  231. l = &rp->next;
  232. nt->ptr = 1;
  233. }
  234. nt = nt->line;
  235. if(nt == s.t)
  236. break;
  237. }
  238. /* search whole entry */
  239. for(nt = t; nt; nt = nt->entry)
  240. if(nt->ptr == 0 && cistrcmp(attr, nt->attr) == 0){
  241. rp = (*f)(t, nt);
  242. rp->db = 1;
  243. if(ttl)
  244. rp->ttl = ttl;
  245. rp->auth = auth;
  246. if(dp == 0)
  247. dp = dnlookup(dname, Cin, 1);
  248. rp->owner = dp;
  249. *l = rp;
  250. l = &rp->next;
  251. }
  252. ndbfree(t);
  253. return list;
  254. }
  255. /*
  256. * make various types of resource records from a database entry
  257. */
  258. static RR*
  259. addrrr(Ndbtuple *entry, Ndbtuple *pair)
  260. {
  261. RR *rp;
  262. uchar addr[IPaddrlen];
  263. USED(entry);
  264. parseip(addr, pair->val);
  265. if(isv4(addr))
  266. rp = rralloc(Ta);
  267. else
  268. rp = rralloc(Taaaa);
  269. rp->ip = dnlookup(pair->val, Cin, 1);
  270. return rp;
  271. }
  272. static RR*
  273. nullrr(Ndbtuple *entry, Ndbtuple *pair)
  274. {
  275. RR *rp;
  276. USED(entry);
  277. rp = rralloc(Tnull);
  278. rp->null->data = (uchar*)estrdup(pair->val);
  279. rp->null->dlen = strlen((char*)rp->null->data);
  280. return rp;
  281. }
  282. static RR*
  283. txtrr(Ndbtuple *entry, Ndbtuple *pair)
  284. {
  285. RR *rp;
  286. USED(entry);
  287. rp = rralloc(Ttxt);
  288. rp->txt = dnlookup(pair->val, Cin, 1);
  289. return rp;
  290. }
  291. static RR*
  292. cnamerr(Ndbtuple *entry, Ndbtuple *pair)
  293. {
  294. RR *rp;
  295. USED(entry);
  296. rp = rralloc(Tcname);
  297. rp->host = dnlookup(pair->val, Cin, 1);
  298. return rp;
  299. }
  300. static RR*
  301. mxrr(Ndbtuple *entry, Ndbtuple *pair)
  302. {
  303. RR * rp;
  304. rp = rralloc(Tmx);
  305. rp->host = dnlookup(pair->val, Cin, 1);
  306. pair = look(entry, pair, "pref");
  307. if(pair)
  308. rp->pref = atoi(pair->val);
  309. else
  310. rp->pref = 1;
  311. return rp;
  312. }
  313. static RR*
  314. nsrr(Ndbtuple *entry, Ndbtuple *pair)
  315. {
  316. RR *rp;
  317. Ndbtuple *t;
  318. rp = rralloc(Tns);
  319. rp->host = dnlookup(pair->val, Cin, 1);
  320. t = look(entry, pair, "soa");
  321. if(t && t->val[0] == 0)
  322. rp->local = 1;
  323. return rp;
  324. }
  325. static RR*
  326. ptrrr(Ndbtuple *entry, Ndbtuple *pair)
  327. {
  328. RR *rp;
  329. USED(entry);
  330. rp = rralloc(Tns);
  331. rp->ptr = dnlookup(pair->val, Cin, 1);
  332. return rp;
  333. }
  334. static RR*
  335. soarr(Ndbtuple *entry, Ndbtuple *pair)
  336. {
  337. RR *rp;
  338. Ndbtuple *ns, *mb, *t;
  339. char mailbox[Domlen];
  340. Ndb *ndb;
  341. char *p;
  342. rp = rralloc(Tsoa);
  343. rp->soa->serial = 1;
  344. for(ndb = db; ndb; ndb = ndb->next)
  345. if(ndb->mtime > rp->soa->serial)
  346. rp->soa->serial = ndb->mtime;
  347. rp->soa->refresh = Day;
  348. rp->soa->retry = Hour;
  349. rp->soa->expire = Day;
  350. rp->soa->minttl = Day;
  351. t = look(entry, pair, "ttl");
  352. if(t)
  353. rp->soa->minttl = atoi(t->val);
  354. t = look(entry, pair, "refresh");
  355. if(t)
  356. rp->soa->refresh = atoi(t->val);
  357. t = look(entry, pair, "serial");
  358. if(t)
  359. rp->soa->serial = strtoul(t->val, 0, 10);
  360. ns = look(entry, pair, "ns");
  361. if(ns == 0)
  362. ns = look(entry, pair, "dom");
  363. rp->host = dnlookup(ns->val, Cin, 1);
  364. /* accept all of:
  365. * mbox=person
  366. * mbox=person@machine.dom
  367. * mbox=person.machine.dom
  368. */
  369. mb = look(entry, pair, "mbox");
  370. if(mb == nil)
  371. mb = look(entry, pair, "mb");
  372. if(mb){
  373. if(strchr(mb->val, '.')) {
  374. p = strchr(mb->val, '@');
  375. if(p != nil)
  376. *p = '.';
  377. rp->rmb = dnlookup(mb->val, Cin, 1);
  378. } else {
  379. snprint(mailbox, sizeof(mailbox), "%s.%s",
  380. mb->val, ns->val);
  381. rp->rmb = dnlookup(mailbox, Cin, 1);
  382. }
  383. } else {
  384. snprint(mailbox, sizeof(mailbox), "postmaster.%s",
  385. ns->val);
  386. rp->rmb = dnlookup(mailbox, Cin, 1);
  387. }
  388. return rp;
  389. }
  390. /*
  391. * Look for a pair with the given attribute. look first on the same line,
  392. * then in the whole entry.
  393. */
  394. static Ndbtuple*
  395. look(Ndbtuple *entry, Ndbtuple *line, char *attr)
  396. {
  397. Ndbtuple *nt;
  398. /* first look on same line (closer binding) */
  399. for(nt = line;;){
  400. if(cistrcmp(attr, nt->attr) == 0)
  401. return nt;
  402. nt = nt->line;
  403. if(nt == line)
  404. break;
  405. }
  406. /* search whole tuple */
  407. for(nt = entry; nt; nt = nt->entry)
  408. if(cistrcmp(attr, nt->attr) == 0)
  409. return nt;
  410. return 0;
  411. }
  412. static RR**
  413. linkrr(RR *rp, DN *dp, RR **l)
  414. {
  415. rp->owner = dp;
  416. rp->auth = 1;
  417. rp->db = 1;
  418. *l = rp;
  419. return &rp->next;
  420. }
  421. /* these are answered specially by the tcp version */
  422. static RR*
  423. doaxfr(Ndb *db, char *name)
  424. {
  425. USED(db, name);
  426. return 0;
  427. }
  428. /*
  429. * our area is the part of the domain tree that
  430. * we serve
  431. */
  432. static void
  433. addarea(DN *dp, RR *rp, Ndbtuple *t)
  434. {
  435. Area **l, *s;
  436. if(t->val[0])
  437. l = &delegated;
  438. else
  439. l = &owned;
  440. /*
  441. * The area contains a copy of the soa rr that created it.
  442. * The owner of the the soa rr should stick around as long
  443. * as the area does.
  444. */
  445. s = emalloc(sizeof(*s));
  446. s->len = strlen(dp->name);
  447. rrcopy(rp, &s->soarr);
  448. s->soarr->owner = dp;
  449. s->soarr->db = 1;
  450. s->soarr->ttl = Hour;
  451. s->next = *l;
  452. *l = s;
  453. }
  454. static void
  455. freearea(Area **l)
  456. {
  457. Area *s;
  458. while(s = *l){
  459. *l = s->next;
  460. rrfree(s->soarr);
  461. free(s);
  462. }
  463. }
  464. /*
  465. * read the all the soa's from the database to determine area's.
  466. * this is only used when we're not caching the database.
  467. */
  468. static void
  469. dbfile2area(Ndb *db)
  470. {
  471. Ndbtuple *t;
  472. if(debug)
  473. syslog(0, logfile, "rereading %s", db->file);
  474. Bseek(&db->b, 0, 0);
  475. while(t = ndbparse(db)){
  476. ndbfree(t);
  477. }
  478. }
  479. /*
  480. * read the database into the cache
  481. */
  482. static void
  483. dbpair2cache(DN *dp, Ndbtuple *entry, Ndbtuple *pair)
  484. {
  485. RR *rp;
  486. Ndbtuple *t;
  487. static ulong ord;
  488. rp = 0;
  489. if(cistrcmp(pair->attr, "ip") == 0){
  490. dp->ordinal = ord++;
  491. rp = addrrr(entry, pair);
  492. } else if(cistrcmp(pair->attr, "ns") == 0){
  493. rp = nsrr(entry, pair);
  494. } else if(cistrcmp(pair->attr, "soa") == 0){
  495. rp = soarr(entry, pair);
  496. addarea(dp, rp, pair);
  497. } else if(cistrcmp(pair->attr, "mx") == 0){
  498. rp = mxrr(entry, pair);
  499. } else if(cistrcmp(pair->attr, "cname") == 0){
  500. rp = cnamerr(entry, pair);
  501. } else if(cistrcmp(pair->attr, "nullrr") == 0){
  502. rp = nullrr(entry, pair);
  503. } else if(cistrcmp(pair->attr, "txtrr") == 0){
  504. rp = txtrr(entry, pair);
  505. }
  506. if(rp == 0)
  507. return;
  508. rp->owner = dp;
  509. rp->db = 1;
  510. t = look(entry, pair, "ttl");
  511. if(t)
  512. rp->ttl = atoi(t->val);
  513. rrattach(rp, 0);
  514. }
  515. static void
  516. dbtuple2cache(Ndbtuple *t)
  517. {
  518. Ndbtuple *et, *nt;
  519. DN *dp;
  520. for(et = t; et; et = et->entry){
  521. if(strcmp(et->attr, "dom") == 0){
  522. dp = dnlookup(et->val, Cin, 1);
  523. /* first same line */
  524. for(nt = et->line; nt != et; nt = nt->line){
  525. dbpair2cache(dp, t, nt);
  526. nt->ptr = 1;
  527. }
  528. /* then rest of entry */
  529. for(nt = t; nt; nt = nt->entry){
  530. if(nt->ptr == 0)
  531. dbpair2cache(dp, t, nt);
  532. nt->ptr = 0;
  533. }
  534. }
  535. }
  536. }
  537. static void
  538. dbfile2cache(Ndb *db)
  539. {
  540. Ndbtuple *t;
  541. if(debug)
  542. syslog(0, logfile, "rereading %s", db->file);
  543. Bseek(&db->b, 0, 0);
  544. while(t = ndbparse(db)){
  545. dbtuple2cache(t);
  546. ndbfree(t);
  547. }
  548. }
  549. void
  550. db2cache(int doit)
  551. {
  552. Ndb *ndb;
  553. Dir *d;
  554. ulong youngest, temp;
  555. static ulong lastcheck;
  556. static ulong lastyoungest;
  557. if(now < lastcheck + 2*Min && !doit)
  558. return;
  559. lock(&dblock);
  560. if(opendatabase() < 0){
  561. unlock(&dblock);
  562. return;
  563. }
  564. /*
  565. * file may be changing as we are reading it, so loop till
  566. * mod times are consistent.
  567. *
  568. * we don't use the times in the ndb records because they may
  569. * change outside of refreshing our cached knowledge.
  570. */
  571. for(;;){
  572. lastcheck = now;
  573. youngest = 0;
  574. for(ndb = db; ndb; ndb = ndb->next){
  575. /* the dirfstat avoids walking the mount table each time */
  576. if((d = dirfstat(Bfildes(&ndb->b))) != nil ||
  577. (d = dirstat(ndb->file)) != nil){
  578. temp = d->mtime; /* ulong vs int crap */
  579. if(temp > youngest)
  580. youngest = temp;
  581. free(d);
  582. }
  583. }
  584. if(!doit && youngest == lastyoungest){
  585. unlock(&dblock);
  586. return;
  587. }
  588. /* forget our area definition */
  589. freearea(&owned);
  590. freearea(&delegated);
  591. /* reopen all the files (to get oldest for time stamp) */
  592. for(ndb = db; ndb; ndb = ndb->next)
  593. ndbreopen(ndb);
  594. if(cachedb){
  595. /* mark all db records as timed out */
  596. dnagedb();
  597. /* read in new entries */
  598. for(ndb = db; ndb; ndb = ndb->next)
  599. dbfile2cache(ndb);
  600. /* mark as authentic anything in our domain */
  601. dnauthdb();
  602. /* remove old entries */
  603. dnageall(1);
  604. } else {
  605. /* read all the soa's to get database defaults */
  606. for(ndb = db; ndb; ndb = ndb->next)
  607. dbfile2area(ndb);
  608. }
  609. doit = 0;
  610. lastyoungest = youngest;
  611. createptrs();
  612. }
  613. unlock(&dblock);
  614. }
  615. /*
  616. * true if a name is in our area
  617. */
  618. Area*
  619. inmyarea(char *name)
  620. {
  621. int len;
  622. Area *s, *d;
  623. len = strlen(name);
  624. for(s = owned; s; s = s->next){
  625. if(s->len > len)
  626. continue;
  627. if(cistrcmp(s->soarr->owner->name, name + len - s->len) == 0)
  628. if(len == s->len || name[len - s->len - 1] == '.')
  629. break;
  630. }
  631. if(s == 0)
  632. return 0;
  633. for(d = delegated; d; d = d->next){
  634. if(d->len > len)
  635. continue;
  636. if(cistrcmp(d->soarr->owner->name, name + len - d->len) == 0)
  637. if(len == d->len || name[len - d->len - 1] == '.')
  638. return 0;
  639. }
  640. return s;
  641. }
  642. extern uchar ipaddr[IPaddrlen];
  643. /*
  644. * get all my xxx
  645. */
  646. Ndbtuple*
  647. lookupinfo(char *attr)
  648. {
  649. char buf[64];
  650. char *a[2];
  651. static Ndbtuple *t;
  652. snprint(buf, sizeof buf, "%I", ipaddr);
  653. a[0] = attr;
  654. lock(&dblock);
  655. if(opendatabase() < 0){
  656. unlock(&dblock);
  657. return nil;
  658. }
  659. t = ndbipinfo(db, "ip", buf, a, 1);
  660. unlock(&dblock);
  661. return t;
  662. }
  663. char *localservers = "local#dns#servers";
  664. char *localserverprefix = "local#dns#server";
  665. /*
  666. * return non-zero is this is a bad delegation
  667. */
  668. int
  669. baddelegation(RR *rp, RR *nsrp, uchar *addr)
  670. {
  671. Ndbtuple *nt;
  672. static Ndbtuple *t;
  673. if(t == nil)
  674. t = lookupinfo("dom");
  675. if(t == nil)
  676. return 0;
  677. for(; rp; rp = rp->next){
  678. if(rp->type != Tns)
  679. continue;
  680. /* see if delegation is looping */
  681. if(nsrp)
  682. if(rp->owner != nsrp->owner)
  683. if(subsume(rp->owner->name, nsrp->owner->name) &&
  684. strcmp(nsrp->owner->name, localservers) != 0){
  685. syslog(0, logfile, "delegation loop %R -> %R from %I", nsrp, rp, addr);
  686. return 1;
  687. }
  688. /* see if delegating to us what we don't own */
  689. for(nt = t; nt != nil; nt = nt->entry)
  690. if(rp->host && cistrcmp(rp->host->name, nt->val) == 0)
  691. break;
  692. if(nt != nil && !inmyarea(rp->owner->name)){
  693. syslog(0, logfile, "bad delegation %R from %I", rp, addr);
  694. return 1;
  695. }
  696. }
  697. return 0;
  698. }
  699. static void
  700. addlocaldnsserver(DN *dp, int class, char *ipaddr, int i)
  701. {
  702. DN *nsdp;
  703. RR *rp;
  704. char buf[32];
  705. /* ns record for name server, make up an impossible name */
  706. rp = rralloc(Tns);
  707. snprint(buf, sizeof(buf), "%s%d", localserverprefix, i);
  708. nsdp = dnlookup(buf, class, 1);
  709. rp->host = nsdp;
  710. rp->owner = dp;
  711. rp->local = 1;
  712. rp->db = 1;
  713. rp->ttl = 10*Min;
  714. rrattach(rp, 1);
  715. /* A record */
  716. rp = rralloc(Ta);
  717. rp->ip = dnlookup(ipaddr, class, 1);
  718. rp->owner = nsdp;
  719. rp->local = 1;
  720. rp->db = 1;
  721. rp->ttl = 10*Min;
  722. rrattach(rp, 1);
  723. }
  724. /*
  725. * return list of dns server addresses to use when
  726. * acting just as a resolver.
  727. */
  728. RR*
  729. dnsservers(int class)
  730. {
  731. Ndbtuple *t, *nt;
  732. RR *nsrp;
  733. DN *dp;
  734. char *p;
  735. int i, n;
  736. char *buf, *args[5];
  737. dp = dnlookup(localservers, class, 1);
  738. nsrp = rrlookup(dp, Tns, NOneg);
  739. if(nsrp != nil)
  740. return nsrp;
  741. p = getenv("DNSSERVER");
  742. if(p != nil){
  743. buf = estrdup(p);
  744. n = tokenize(buf, args, nelem(args));
  745. for(i = 0; i < n; i++)
  746. addlocaldnsserver(dp, class, args[i], i);
  747. free(buf);
  748. } else {
  749. t = lookupinfo("@dns");
  750. if(t == nil)
  751. return nil;
  752. i = 0;
  753. for(nt = t; nt != nil; nt = nt->entry){
  754. addlocaldnsserver(dp, class, nt->val, i);
  755. i++;
  756. }
  757. ndbfree(t);
  758. }
  759. return rrlookup(dp, Tns, NOneg);
  760. }
  761. static void
  762. addlocaldnsdomain(DN *dp, int class, char *domain)
  763. {
  764. RR *rp;
  765. /* A record */
  766. rp = rralloc(Tptr);
  767. rp->ptr = dnlookup(domain, class, 1);
  768. rp->owner = dp;
  769. rp->db = 1;
  770. rp->ttl = 10*Min;
  771. rrattach(rp, 1);
  772. }
  773. /*
  774. * return list of domains to use when resolving names without '.'s
  775. */
  776. RR*
  777. domainlist(int class)
  778. {
  779. Ndbtuple *t, *nt;
  780. RR *rp;
  781. DN *dp;
  782. dp = dnlookup("local#dns#domains", class, 1);
  783. rp = rrlookup(dp, Tptr, NOneg);
  784. if(rp != nil)
  785. return rp;
  786. t = lookupinfo("dnsdomain");
  787. if(t == nil)
  788. return nil;
  789. for(nt = t; nt != nil; nt = nt->entry)
  790. addlocaldnsdomain(dp, class, nt->val);
  791. ndbfree(t);
  792. return rrlookup(dp, Tptr, NOneg);
  793. }
  794. char *v4ptrdom = ".in-addr.arpa";
  795. char *v6ptrdom = ".ip6.int";
  796. char *attribs[] = {
  797. "ipmask",
  798. 0
  799. };
  800. /*
  801. * create ptrs that are in our areas
  802. */
  803. static void
  804. createptrs(void)
  805. {
  806. int len, dlen, n;
  807. Area *s;
  808. char *f[40];
  809. char buf[Domlen+1];
  810. uchar net[IPaddrlen];
  811. uchar mask[IPaddrlen];
  812. char ipa[48];
  813. Ndbtuple *t, *nt;
  814. dlen = strlen(v4ptrdom);
  815. for(s = owned; s; s = s->next){
  816. len = strlen(s->soarr->owner->name);
  817. if(len <= dlen)
  818. continue;
  819. if(cistrcmp(s->soarr->owner->name+len-dlen, v4ptrdom) != 0)
  820. continue;
  821. /* get mask and net value */
  822. strncpy(buf, s->soarr->owner->name, sizeof(buf));
  823. buf[sizeof(buf)-1] = 0;
  824. n = getfields(buf, f, nelem(f), 0, ".");
  825. memset(mask, 0xff, IPaddrlen);
  826. ipmove(net, v4prefix);
  827. switch(n){
  828. case 3: /* /8 */
  829. net[IPv4off] = atoi(f[0]);
  830. mask[IPv4off+1] = 0;
  831. mask[IPv4off+2] = 0;
  832. mask[IPv4off+3] = 0;
  833. break;
  834. case 4: /* /16 */
  835. net[IPv4off] = atoi(f[1]);
  836. net[IPv4off+1] = atoi(f[0]);
  837. mask[IPv4off+2] = 0;
  838. mask[IPv4off+3] = 0;
  839. break;
  840. case 5: /* /24 */
  841. net[IPv4off] = atoi(f[2]);
  842. net[IPv4off+1] = atoi(f[1]);
  843. net[IPv4off+2] = atoi(f[0]);
  844. mask[IPv4off+3] = 0;
  845. break;
  846. case 6: /* rfc2317 */
  847. net[IPv4off] = atoi(f[3]);
  848. net[IPv4off+1] = atoi(f[2]);
  849. net[IPv4off+2] = atoi(f[1]);
  850. net[IPv4off+3] = atoi(f[0]);
  851. sprint(ipa, "%I", net);
  852. t = ndbipinfo(db, "ip", ipa, attribs, 1);
  853. nt = look(t, t, "ipmask");
  854. if(nt == nil){ /* we're confused */
  855. ndbfree(t);
  856. continue;
  857. }
  858. parseipmask(mask, nt->val);
  859. n = 5;
  860. break;
  861. default:
  862. continue;
  863. }
  864. /* go through all domain entries looking for RR's in this network and create ptrs */
  865. dnptr(net, mask, s->soarr->owner->name, 6-n, 0);
  866. }
  867. }