1 /**************************************************************************************************
2 $Id: soa.c,v 1.65 2005/12/18 19:16:41 bboy Exp $
3
4 Copyright (C) 2002-2005 Don Moore <bboy@bboy.net>
5
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at Your option) any later version.
10
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 **************************************************************************************************/
20
21 #include "mydns.h"
22
23 char *mydns_soa_table_name = NULL;
24 char *mydns_soa_where_clause = NULL;
25
26 char *mydns_soa_active_types[] = { (char*)"Y", (char*)"N" };
27
28 /* Optional columns */
29 int mydns_soa_use_active = 0;
30 int mydns_soa_use_xfer = 0;
31 int mydns_soa_use_update_acl = 0;
32 int mydns_soa_use_recursive = 0;
33
34 /* Make this nonzero to enable debugging within this source file */
35 #define DEBUG_LIB_SOA 1
36
37 void
mydns_soa_get_active_types(SQL * sqlConn)38 mydns_soa_get_active_types(SQL *sqlConn) {
39 SQL_RES *res;
40 SQL_ROW row;
41 int querylen;
42 char *query;
43
44 char *YES = (char*)"Y";
45 char *NO = (char*)"N";
46
47 querylen = sql_build_query(&query, "SELECT DISTINCT(active) FROM %s LIMIT 1", mydns_soa_table_name);
48
49 if (!(res = sql_query(sqlConn, query, querylen))) {
50 RELEASE(query);
51 return;
52 }
53
54 #if DEBUG_ENABLED && DEBUG_LIB_SOA
55 {
56 int numresults = sql_num_rows(res);
57 DebugX("lib-soa", 1, _("SOA get active types: %d row%s: %s"), numresults, S(numresults), query);
58 }
59 #endif
60
61 RELEASE(query);
62
63 while ((row = sql_getrow(res, NULL))) {
64 char *VAL = row[0];
65 if ( !strcasecmp(VAL, "yes")
66 || !strcasecmp(VAL, "y")
67 || !strcasecmp(VAL, "true")
68 || !strcasecmp(VAL, "t")
69 || !strcasecmp(VAL, "active")
70 || !strcasecmp(VAL, "a")
71 || !strcasecmp(VAL, "on")
72 || !strcasecmp(VAL, "1") ) { YES = STRDUP(VAL); continue; }
73 if ( !strcasecmp(VAL, "no")
74 || !strcasecmp(VAL, "n")
75 || !strcasecmp(VAL, "false")
76 || !strcasecmp(VAL, "f")
77 || !strcasecmp(VAL, "inactive")
78 || !strcasecmp(VAL, "i")
79 || !strcasecmp(VAL, "off")
80 || !strcasecmp(VAL, "0") ) { NO = STRDUP(VAL); continue; }
81 }
82
83 sql_free(res);
84
85 mydns_soa_active_types[0] = YES;
86 mydns_soa_active_types[1] = NO;
87 }
88
89 /**************************************************************************************************
90 MYDNS_SOA_COUNT
91 Returns the number of zones in the soa table.
92 **************************************************************************************************/
93 long
mydns_soa_count(SQL * sqlConn)94 mydns_soa_count(SQL *sqlConn) {
95 return sql_count(sqlConn, "SELECT COUNT(*) FROM %s", mydns_soa_table_name);
96 }
97 /*--- mydns_soa_count() -------------------------------------------------------------------------*/
98
99
100 /**************************************************************************************************
101 MYDNS_SET_SOA_TABLE_NAME
102 **************************************************************************************************/
103 void
mydns_set_soa_table_name(const char * name)104 mydns_set_soa_table_name(const char *name) {
105 RELEASE(mydns_soa_table_name);
106 if (!name)
107 mydns_soa_table_name = STRDUP(MYDNS_SOA_TABLE);
108 else
109 mydns_soa_table_name = STRDUP(name);
110 }
111 /*--- mydns_set_soa_table_name() ----------------------------------------------------------------*/
112
113
114 /**************************************************************************************************
115 MYDNS_SET_SOA_WHERE_CLAUSE
116 **************************************************************************************************/
117 void
mydns_set_soa_where_clause(const char * where)118 mydns_set_soa_where_clause(const char *where) {
119 if (where && strlen(where)) {
120 mydns_soa_where_clause = STRDUP(where);
121 }
122 }
123 /*--- mydns_set_soa_where_clause() --------------------------------------------------------------*/
124
125
126 /**************************************************************************************************
127 MYDNS_SOA_PARSE
128 **************************************************************************************************/
129 static
130 #if !PROFILING
131 inline
132 #endif
133 MYDNS_SOA *
mydns_soa_parse(SQL_ROW row)134 mydns_soa_parse(SQL_ROW row) {
135 MYDNS_SOA *rv;
136 int len;
137
138 rv = (MYDNS_SOA *)ALLOCATE(sizeof(MYDNS_SOA), MYDNS_SOA);
139
140 rv->next = NULL;
141
142 rv->id = atou(row[0]);
143 strncpy(rv->origin, row[1], sizeof(rv->origin)-1);
144 strncpy(rv->ns, row[2], sizeof(rv->ns)-1);
145 if (!rv->ns[0])
146 snprintf(rv->ns, sizeof(rv->ns), "ns.%s", rv->origin);
147 strncpy(rv->mbox, row[3], sizeof(rv->mbox)-1);
148 if (!rv->mbox[0])
149 snprintf(rv->mbox, sizeof(rv->mbox), "hostmaster.%s", rv->origin);
150 rv->serial = atou(row[4]);
151 rv->refresh = atou(row[5]);
152 rv->retry = atou(row[6]);
153 rv->expire = atou(row[7]);
154 rv->minimum = atou(row[8]);
155 rv->ttl = atou(row[9]);
156
157 { int ridx = MYDNS_SOA_NUMFIELDS;
158 ridx += (mydns_soa_use_active)?1:0;
159 rv->recursive = ((mydns_soa_use_recursive)?GETBOOL(row[ridx]):0);
160 }
161
162 /* If 'ns' or 'mbox' don't end in a dot, append the origin */
163 len = strlen(rv->ns);
164 if (rv->ns[len-1] != '.') {
165 strncat(rv->ns, ".", sizeof(rv->ns) - len - 1);
166 strncat(rv->ns, rv->origin, sizeof(rv->ns) - len - 2);
167 }
168 len = strlen(rv->mbox);
169 if (rv->mbox[len-1] != '.') {
170 strncat(rv->mbox, ".", sizeof(rv->mbox) - len - 1);
171 strncat(rv->mbox, rv->origin, sizeof(rv->mbox) - len - 2);
172 }
173
174 /* Make sure TTL for SOA is at least the minimum */
175 if (rv->ttl < rv->minimum)
176 rv->ttl = rv->minimum;
177
178 return (rv);
179 }
180 /*--- mydns_soa_parse() -------------------------------------------------------------------------*/
181
182
183 /**************************************************************************************************
184 MYDNS_SOA_DUP
185 Create a duplicate copy of the record.
186 Make and return a copy of a MYDNS_SOA record. If 'recurse' is specified, copies all records
187 in the list.
188 **************************************************************************************************/
189 MYDNS_SOA *
mydns_soa_dup(MYDNS_SOA * start,int recurse)190 mydns_soa_dup(MYDNS_SOA *start, int recurse) {
191 register MYDNS_SOA *first = NULL, *last = NULL, *soa, *s, *tmp;
192
193 for (s = start; s; s = tmp) {
194 tmp = s->next;
195
196 soa = (MYDNS_SOA *)ALLOCATE(sizeof(MYDNS_SOA), MYDNS_SOA);
197
198 soa->id = s->id;
199 strncpy(soa->origin, s->origin, sizeof(soa->origin)-1);
200 strncpy(soa->ns, s->ns, sizeof(soa->ns)-1);
201 strncpy(soa->mbox, s->mbox, sizeof(soa->mbox)-1);
202 soa->serial = s->serial;
203 soa->refresh = s->refresh;
204 soa->retry = s->retry;
205 soa->expire = s->expire;
206 soa->minimum = s->minimum;
207 soa->ttl = s->ttl;
208 soa->recursive = s->recursive;
209 soa->next = NULL;
210 if (recurse) {
211 if (!first) first = soa;
212 if (last) last->next = soa;
213 last = soa;
214 } else
215 return (soa);
216 }
217 return (first);
218 }
219 /*--- mydns_soa_dup() ---------------------------------------------------------------------------*/
220
221
222 /**************************************************************************************************
223 MYDNS_SOA_SIZE
224 **************************************************************************************************/
225 #if !PROFILING
226 inline
227 #endif
228 size_t
mydns_soa_size(MYDNS_SOA * first)229 mydns_soa_size(MYDNS_SOA *first) {
230 register MYDNS_SOA *p;
231 register size_t size = 0;
232
233 for (p = first; p; p = p->next)
234 size += sizeof(MYDNS_SOA);
235
236 return (size);
237 }
238 /*--- mydns_soa_size() --------------------------------------------------------------------------*/
239
240
241 /**************************************************************************************************
242 _MYDNS_SOA_FREE
243 Frees the pointed-to structure. Don't call this function directly, call the macro.
244 **************************************************************************************************/
245 #if !PROFILING
246 inline
247 #endif
248 void
_mydns_soa_free(MYDNS_SOA * first)249 _mydns_soa_free(MYDNS_SOA *first) {
250 register MYDNS_SOA *p, *tmp;
251
252 for (p = first; p; p = tmp) {
253 tmp = p->next;
254 RELEASE(p);
255 }
256 }
257 /*--- mydns_soa_free() --------------------------------------------------------------------------*/
258
259
260 /**************************************************************************************************
261 MYDNS_SOA_LOAD
262 Returns 0 on success or nonzero if an error occurred.
263 **************************************************************************************************/
264 int
mydns_soa_load(SQL * sqlConn,MYDNS_SOA ** rptr,const char * origin)265 mydns_soa_load(SQL *sqlConn, MYDNS_SOA **rptr, const char *origin) {
266 MYDNS_SOA *first = NULL, *last = NULL;
267 size_t querylen;
268 char *query;
269 SQL_RES *res;
270 SQL_ROW row;
271 const char *c;
272 #ifdef DN_COLUMN_NAMES
273 int originlen = strlen(origin);
274 #endif
275
276 #if DEBUG_ENABLED && DEBUG_LIB_SOA
277 DebugX("lib-soa", 1, _("mydns_soa_load(%s)"), origin);
278 #endif
279
280 if (rptr) *rptr = NULL;
281
282 /* Verify args */
283 if (!sqlConn || !origin || !rptr) {
284 errno = EINVAL;
285 return (-1);
286 }
287
288 /* We're not escaping 'origin', so check it for illegal type chars */
289 for (c = origin; *c; c++)
290 if (SQL_BADCHAR(*c))
291 return (0);
292
293 #ifdef DN_COLUMN_NAMES
294 if (origin[originlen - 1] == '.')
295 origin[originlen - 1] = '\0'; /* Remove dot from origin for DN */
296 else
297 originlen = 0;
298 #endif
299
300 /* Construct query */
301 querylen = sql_build_query(&query,
302 "SELECT "MYDNS_SOA_FIELDS"%s%s FROM %s WHERE origin='%s'%s%s;",
303 (mydns_soa_use_active ? ",active" : ""),
304 (mydns_soa_use_recursive ? ",recursive" : ""),
305 mydns_soa_table_name, origin,
306 (mydns_soa_where_clause)? " AND " : "",
307 (mydns_soa_where_clause)? mydns_soa_where_clause : "");
308
309 #ifdef DN_COLUMN_NAMES
310 if (originlen)
311 origin[originlen - 1] = '.'; /* Re-add dot to origin for DN */
312 #endif
313
314 /* Submit query */
315 if (!(res = sql_query(sqlConn, query, querylen)))
316 return (-1);
317
318 #if DEBUG_ENABLED && DEBUG_LIB_SOA
319 {
320 int numresults = sql_num_rows(res);
321
322 DebugX("lib-soa", 1, _("SOA query: %d row%s: %s"), numresults, S(numresults), query);
323 }
324 #endif
325
326 RELEASE(query);
327
328 /* Add results to list */
329 while ((row = sql_getrow(res, NULL))) {
330 MYDNS_SOA *new;
331
332 #if DEBUG_ENABLED && DEBUG_LIB_SOA
333 DebugX("lib-soa", 1, _("SOA query: use_soa_active=%d soa_active=%s,%d"), mydns_soa_use_active,
334 (mydns_soa_use_active)?row[MYDNS_SOA_NUMFIELDS]:"<undef>",
335 (mydns_soa_use_active)?GETBOOL(row[MYDNS_SOA_NUMFIELDS]):-1);
336 DebugX("lib-soa", 1, _("SOA query: id=%s, origin=%s, ns=%s, mbox=%s, serial=%s, refresh=%s, "
337 "retry=%s, expire=%s, minimum=%s, ttl=%s"),
338 row[0], row[1], row[2], row[3], row[4], row[5], row[6], row[7], row[8], row[9]);
339 { int ridx = MYDNS_SOA_NUMFIELDS;
340 ridx += (mydns_soa_use_active)?1:0;
341 DebugX("lib-soa", 1, _("Soa query: recursive = %s"),
342 (mydns_soa_use_recursive)?row[ridx++]:_("not recursing"));
343 }
344 #endif
345
346 if (mydns_soa_use_active && row[MYDNS_SOA_NUMFIELDS] && !GETBOOL(row[MYDNS_SOA_NUMFIELDS]))
347 continue;
348
349 new = mydns_soa_parse(row);
350 if (!first) first = new;
351 if (last) last->next = new;
352 last = new;
353 }
354
355 *rptr = first;
356 sql_free(res);
357 return (0);
358 }
359 /*--- mydns_soa_load() --------------------------------------------------------------------------*/
360
361 /* vi:set ts=3: */
362