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