dblookup.c 18 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948
  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. break;
  595. /* forget our area definition */
  596. freearea(&owned);
  597. freearea(&delegated);
  598. /* reopen all the files (to get oldest for time stamp) */
  599. for(ndb = db; ndb; ndb = ndb->next)
  600. ndbreopen(ndb);
  601. if(cachedb){
  602. /* mark all db records as timed out */
  603. dnagedb();
  604. /* read in new entries */
  605. for(ndb = db; ndb; ndb = ndb->next)
  606. dbfile2cache(ndb);
  607. /* mark as authentic anything in our domain */
  608. dnauthdb();
  609. /* remove old entries */
  610. dnageall(1);
  611. } else {
  612. /* read all the soa's to get database defaults */
  613. for(ndb = db; ndb; ndb = ndb->next)
  614. dbfile2area(ndb);
  615. }
  616. doit = 0;
  617. lastyoungest = youngest;
  618. createptrs();
  619. }
  620. unlock(&dblock);
  621. }
  622. extern uchar ipaddr[IPaddrlen];
  623. /*
  624. * get all my xxx
  625. */
  626. Ndbtuple*
  627. lookupinfo(char *attr)
  628. {
  629. char buf[64];
  630. char *a[2];
  631. static Ndbtuple *t;
  632. snprint(buf, sizeof buf, "%I", ipaddr);
  633. a[0] = attr;
  634. lock(&dblock);
  635. if(opendatabase() < 0){
  636. unlock(&dblock);
  637. return nil;
  638. }
  639. t = ndbipinfo(db, "ip", buf, a, 1);
  640. unlock(&dblock);
  641. return t;
  642. }
  643. char *localservers = "local#dns#servers";
  644. char *localserverprefix = "local#dns#server";
  645. /*
  646. * return non-zero is this is a bad delegation
  647. */
  648. int
  649. baddelegation(RR *rp, RR *nsrp, uchar *addr)
  650. {
  651. Ndbtuple *nt;
  652. static Ndbtuple *t;
  653. if(t == nil)
  654. t = lookupinfo("dom");
  655. if(t == nil)
  656. return 0;
  657. for(; rp; rp = rp->next){
  658. if(rp->type != Tns)
  659. continue;
  660. /* see if delegation is looping */
  661. if(nsrp)
  662. if(rp->owner != nsrp->owner)
  663. if(subsume(rp->owner->name, nsrp->owner->name) &&
  664. strcmp(nsrp->owner->name, localservers) != 0){
  665. syslog(0, logfile, "delegation loop %R -> %R from %I", nsrp, rp, addr);
  666. return 1;
  667. }
  668. /* see if delegating to us what we don't own */
  669. for(nt = t; nt != nil; nt = nt->entry)
  670. if(rp->host && cistrcmp(rp->host->name, nt->val) == 0)
  671. break;
  672. if(nt != nil && !inmyarea(rp->owner->name)){
  673. syslog(0, logfile, "bad delegation %R from %I", rp, addr);
  674. return 1;
  675. }
  676. }
  677. return 0;
  678. }
  679. static void
  680. addlocaldnsserver(DN *dp, int class, char *ipaddr, int i)
  681. {
  682. DN *nsdp;
  683. RR *rp;
  684. char buf[32];
  685. /* ns record for name server, make up an impossible name */
  686. rp = rralloc(Tns);
  687. snprint(buf, sizeof(buf), "%s%d", localserverprefix, i);
  688. nsdp = dnlookup(buf, class, 1);
  689. rp->host = nsdp;
  690. rp->owner = dp;
  691. rp->local = 1;
  692. rp->db = 1;
  693. rp->ttl = 10*Min;
  694. rrattach(rp, 1);
  695. /* A record */
  696. rp = rralloc(Ta);
  697. rp->ip = dnlookup(ipaddr, class, 1);
  698. rp->owner = nsdp;
  699. rp->local = 1;
  700. rp->db = 1;
  701. rp->ttl = 10*Min;
  702. rrattach(rp, 1);
  703. }
  704. /*
  705. * return list of dns server addresses to use when
  706. * acting just as a resolver.
  707. */
  708. RR*
  709. dnsservers(int class)
  710. {
  711. Ndbtuple *t, *nt;
  712. RR *nsrp;
  713. DN *dp;
  714. char *p;
  715. int i, n;
  716. char *buf, *args[5];
  717. dp = dnlookup(localservers, class, 1);
  718. nsrp = rrlookup(dp, Tns, NOneg);
  719. if(nsrp != nil)
  720. return nsrp;
  721. p = getenv("DNSSERVER");
  722. if(p != nil){
  723. buf = estrdup(p);
  724. n = tokenize(buf, args, nelem(args));
  725. for(i = 0; i < n; i++)
  726. addlocaldnsserver(dp, class, args[i], i);
  727. free(buf);
  728. } else {
  729. t = lookupinfo("@dns");
  730. if(t == nil)
  731. return nil;
  732. i = 0;
  733. for(nt = t; nt != nil; nt = nt->entry){
  734. addlocaldnsserver(dp, class, nt->val, i);
  735. i++;
  736. }
  737. ndbfree(t);
  738. }
  739. return rrlookup(dp, Tns, NOneg);
  740. }
  741. static void
  742. addlocaldnsdomain(DN *dp, int class, char *domain)
  743. {
  744. RR *rp;
  745. /* A record */
  746. rp = rralloc(Tptr);
  747. rp->ptr = dnlookup(domain, class, 1);
  748. rp->owner = dp;
  749. rp->db = 1;
  750. rp->ttl = 10*Min;
  751. rrattach(rp, 1);
  752. }
  753. /*
  754. * return list of domains to use when resolving names without '.'s
  755. */
  756. RR*
  757. domainlist(int class)
  758. {
  759. Ndbtuple *t, *nt;
  760. RR *rp;
  761. DN *dp;
  762. dp = dnlookup("local#dns#domains", class, 1);
  763. rp = rrlookup(dp, Tptr, NOneg);
  764. if(rp != nil)
  765. return rp;
  766. t = lookupinfo("dnsdomain");
  767. if(t == nil)
  768. return nil;
  769. for(nt = t; nt != nil; nt = nt->entry)
  770. addlocaldnsdomain(dp, class, nt->val);
  771. ndbfree(t);
  772. return rrlookup(dp, Tptr, NOneg);
  773. }
  774. char *v4ptrdom = ".in-addr.arpa";
  775. char *v6ptrdom = ".ip6.arpa"; /* ip6.int deprecated, rfc 3152 */
  776. char *attribs[] = {
  777. "ipmask",
  778. 0
  779. };
  780. /*
  781. * create ptrs that are in our areas
  782. */
  783. static void
  784. createptrs(void)
  785. {
  786. int len, dlen, n;
  787. Area *s;
  788. char *f[40];
  789. char buf[Domlen+1];
  790. uchar net[IPaddrlen];
  791. uchar mask[IPaddrlen];
  792. char ipa[48];
  793. Ndbtuple *t, *nt;
  794. dlen = strlen(v4ptrdom);
  795. for(s = owned; s; s = s->next){
  796. len = strlen(s->soarr->owner->name);
  797. if(len <= dlen)
  798. continue;
  799. if(cistrcmp(s->soarr->owner->name+len-dlen, v4ptrdom) != 0)
  800. continue;
  801. /* get mask and net value */
  802. strncpy(buf, s->soarr->owner->name, sizeof(buf));
  803. buf[sizeof(buf)-1] = 0;
  804. n = getfields(buf, f, nelem(f), 0, ".");
  805. memset(mask, 0xff, IPaddrlen);
  806. ipmove(net, v4prefix);
  807. switch(n){
  808. case 3: /* /8 */
  809. net[IPv4off] = atoi(f[0]);
  810. mask[IPv4off+1] = 0;
  811. mask[IPv4off+2] = 0;
  812. mask[IPv4off+3] = 0;
  813. break;
  814. case 4: /* /16 */
  815. net[IPv4off] = atoi(f[1]);
  816. net[IPv4off+1] = atoi(f[0]);
  817. mask[IPv4off+2] = 0;
  818. mask[IPv4off+3] = 0;
  819. break;
  820. case 5: /* /24 */
  821. net[IPv4off] = atoi(f[2]);
  822. net[IPv4off+1] = atoi(f[1]);
  823. net[IPv4off+2] = atoi(f[0]);
  824. mask[IPv4off+3] = 0;
  825. break;
  826. case 6: /* rfc2317 */
  827. net[IPv4off] = atoi(f[3]);
  828. net[IPv4off+1] = atoi(f[2]);
  829. net[IPv4off+2] = atoi(f[1]);
  830. net[IPv4off+3] = atoi(f[0]);
  831. sprint(ipa, "%I", net);
  832. t = ndbipinfo(db, "ip", ipa, attribs, 1);
  833. if(t == nil) /* could be a reverse with no forward */
  834. continue;
  835. nt = look(t, t, "ipmask");
  836. if(nt == nil){ /* we're confused */
  837. ndbfree(t);
  838. continue;
  839. }
  840. parseipmask(mask, nt->val);
  841. n = 5;
  842. break;
  843. default:
  844. continue;
  845. }
  846. /* go through all domain entries looking for RR's in this network and create ptrs */
  847. dnptr(net, mask, s->soarr->owner->name, 6-n, 0);
  848. }
  849. }