dblookup.c 18 KB

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