Blame


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