~ubuntu-branches/ubuntu/precise/autofs5/precise

« back to all changes in this revision

Viewing changes to debian/patches/autofs-5.0.5-replace-gplv3-code.patch

  • Committer: Bazaar Package Importer
  • Author(s): Chuck Short
  • Date: 2011-07-03 14:35:46 UTC
  • mfrom: (1.1.3 upstream)
  • Revision ID: james.westby@ubuntu.com-20110703143546-nej26krjij0rf792
Tags: 5.0.6-0ubuntu1
* New upstream release:
  - Dropped upstream patches 
  - Refreshed debian/patches/17ld.patch.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
autofs-5.0.5 - replace GPLv3 code
2
 
 
3
 
From: Ian Kent <raven@themaw.net>
4
 
 
5
 
The code to get SRV records from DNS was taken from Samba.
6
 
Samba is a GPLv3 licensed work which forces autofs to GPLv3.
7
 
 
8
 
I don't know enough about GPLv3 to know if that is a good thing
9
 
but I also don't like autofs being forced to GPLv3 because one
10
 
of the copyright holders won't grant permission to use the code
11
 
under a GPLv2 license.
12
 
---
13
 
 
14
 
 CHANGELOG        |    1 
15
 
 modules/dclist.c |  590 +++++++++++++++++-------------------------------------
16
 
 2 files changed, 192 insertions(+), 399 deletions(-)
17
 
 
18
 
 
19
 
diff --git a/CHANGELOG b/CHANGELOG
20
 
index b9d8299..347d7d7 100644
21
 
--- a/CHANGELOG
22
 
+++ b/CHANGELOG
23
 
@@ -61,6 +61,7 @@
24
 
 - fix prune cache valid check.
25
 
 - fix mountd vers retry.
26
 
 - fix expire race.
27
 
+- replace GPLv3 code.
28
 
 
29
 
 03/09/2009 autofs-5.0.5
30
 
 -----------------------
31
 
diff --git a/modules/dclist.c b/modules/dclist.c
32
 
index 967581c..aeb107f 100644
33
 
--- a/modules/dclist.c
34
 
+++ b/modules/dclist.c
35
 
@@ -1,19 +1,10 @@
36
 
 /*
37
 
- * Copyright 2009 Ian Kent <raven@themaw.net>
38
 
- * Copyright 2009 Red Hat, Inc.
39
 
- *
40
 
- * This module was apapted from code contained in the Samba distribution
41
 
- * file source/libads/dns.c which contained the following copyright
42
 
- * information:
43
 
- *
44
 
- * Unix SMB/CIFS implementation.
45
 
- * DNS utility library
46
 
- * Copyright (C) Gerald (Jerry) Carter           2006.
47
 
- * Copyright (C) Jeremy Allison                  2007.
48
 
+ * Copyright 2011 Ian Kent <raven@themaw.net>
49
 
+ * Copyright 2011 Red Hat, Inc.
50
 
  *
51
 
  * This program is free software; you can redistribute it and/or modify
52
 
  * it under the terms of the GNU General Public License as published by
53
 
- * the Free Software Foundation; either version 3 of the License, or
54
 
+ * the Free Software Foundation, either version 2 of the License, or
55
 
  * (at your option) any later version.
56
 
  *
57
 
  * This program is distributed in the hope that it will be useful,
58
 
@@ -25,7 +16,9 @@
59
 
  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
60
 
 */
61
 
 
62
 
+#include <sys/types.h>
63
 
 #include <netinet/in.h>
64
 
+#include <arpa/inet.h>
65
 
 #include <arpa/nameser.h>
66
 
 #include <stdlib.h>
67
 
 #include <string.h>
68
 
@@ -39,80 +32,21 @@
69
 
 #include "automount.h"
70
 
 #include "dclist.h"
71
 
 
72
 
-#define        MAX_DNS_PACKET_SIZE     0xffff
73
 
-#define        MAX_DNS_NAME_LENGTH     MAXHOSTNAMELEN
74
 
-/* The longest time we will cache dns srv records */
75
 
-#define MAX_TTL                        (60*60*1) /* 1 hours */
76
 
-
77
 
-#ifdef NS_HFIXEDSZ     /* Bind 8/9 interface */
78
 
-#if !defined(C_IN)     /* AIX 5.3 already defines C_IN */
79
 
-#  define C_IN         ns_c_in
80
 
-#endif
81
 
-#if !defined(T_A)      /* AIX 5.3 already defines T_A */
82
 
-#  define T_A          ns_t_a
83
 
-#endif
84
 
-
85
 
-#  define T_SRV        ns_t_srv
86
 
-#if !defined(T_NS)     /* AIX 5.3 already defines T_NS */
87
 
-#  define T_NS                 ns_t_ns
88
 
-#endif
89
 
-#else
90
 
-#  ifdef HFIXEDSZ
91
 
-#    define NS_HFIXEDSZ HFIXEDSZ
92
 
-#  else
93
 
-#    define NS_HFIXEDSZ sizeof(HEADER)
94
 
-#  endif       /* HFIXEDSZ */
95
 
-#  ifdef PACKETSZ
96
 
-#    define NS_PACKETSZ        PACKETSZ
97
 
-#  else        /* 512 is usually the default */
98
 
-#    define NS_PACKETSZ        512
99
 
-#  endif       /* PACKETSZ */
100
 
-#  define T_SRV        33
101
 
-#endif
102
 
-
103
 
-#define SVAL(buf, pos) (*(const uint16_t *)((const char *)(buf) + (pos)))
104
 
-#define IVAL(buf, pos) (*(const uint32_t *)((const char *)(buf) + (pos)))
105
 
-
106
 
-#if __BYTE_ORDER == __LITTLE_ENDIAN
107
 
-#define SREV(x) ((((x)&0xFF)<<8) | (((x)>>8)&0xFF))
108
 
-#define IREV(x) ((SREV(x)<<16) | (SREV((x)>>16)))
109
 
-#else
110
 
-#define SREV(x) (x)
111
 
-#define IREV(x) (x)
112
 
-#endif
113
 
-
114
 
-#define RSVAL(buf, pos) SREV(SVAL(buf, pos))
115
 
-#define RIVAL(buf, pos) IREV(IVAL(buf, pos))
116
 
-
117
 
-#define QSORT_CAST     (int (*)(const void *, const void *))
118
 
-
119
 
-/* DNS query section in replies */
120
 
-
121
 
-struct dns_query {
122
 
-       const char *hostname;
123
 
-       uint16_t type;
124
 
-       uint16_t in_class;
125
 
-};
126
 
-
127
 
-/* DNS RR record in reply */
128
 
+#define MAX_TTL                (60*60) /* 1 hour */
129
 
 
130
 
-struct dns_rr {
131
 
-       const char *hostname;
132
 
-       uint16_t type;
133
 
-       uint16_t in_class;
134
 
-       uint32_t ttl;
135
 
-       uint16_t rdatalen;
136
 
-       uint8_t *rdata;
137
 
+struct rr {
138
 
+       unsigned int type;
139
 
+       unsigned int class;
140
 
+       unsigned long ttl;
141
 
+       unsigned int len;
142
 
 };
143
 
 
144
 
-/* SRV records */
145
 
-
146
 
-struct dns_rr_srv {
147
 
-       const char *hostname;
148
 
-       uint16_t priority;
149
 
-       uint16_t weight;
150
 
-       uint16_t port;
151
 
-       uint32_t ttl;
152
 
+struct srv_rr {
153
 
+       const char *name;
154
 
+       unsigned int priority;
155
 
+       unsigned int weight;
156
 
+       unsigned int port;
157
 
+       unsigned long ttl;
158
 
 };
159
 
 
160
 
 static pthread_mutex_t dclist_mutex = PTHREAD_MUTEX_INITIALIZER;
161
 
@@ -133,374 +67,224 @@ static void dclist_mutex_unlock(void)
162
 
        return;
163
 
 }
164
 
 
165
 
-static int dns_parse_query(unsigned int logopt,
166
 
-                          uint8_t *start, uint8_t *end,
167
 
-                          uint8_t **ptr, struct dns_query *q)
168
 
+static int do_srv_query(unsigned int logopt, char *name, u_char **packet)
169
 
 {
170
 
-       uint8_t *p = *ptr;
171
 
-       char hostname[MAX_DNS_NAME_LENGTH];
172
 
-       char buf[MAX_ERR_BUF];
173
 
-       int namelen;
174
 
-
175
 
-       if (!start || !end || !q || !*ptr)
176
 
-               return 0;
177
 
-
178
 
-       memset(q, 0, sizeof(*q));
179
 
-
180
 
-       /* See RFC 1035 for details. If this fails, then return. */
181
 
-
182
 
-       namelen = dn_expand(start, end, p, hostname, sizeof(hostname));
183
 
-       if (namelen < 0) {
184
 
-               error(logopt, "failed to expand query hostname");
185
 
-               return 0;
186
 
-       }
187
 
+       unsigned int len = PACKETSZ;
188
 
+       unsigned int last_len = len;
189
 
+       char ebuf[MAX_ERR_BUF];
190
 
+       u_char *buf;
191
 
+
192
 
+       while (1) {
193
 
+               buf = malloc(last_len);
194
 
+               if (!buf) {
195
 
+                       char *estr = strerror_r(errno, ebuf, MAX_ERR_BUF);
196
 
+                       error(logopt, "malloc: %s", estr);
197
 
+                       return -1;
198
 
+               }
199
 
 
200
 
-       p += namelen;
201
 
-       q->hostname = strdup(hostname);
202
 
-       if (!q) {
203
 
-               char *estr = strerror_r(errno, buf, MAX_ERR_BUF);
204
 
-               error(logopt, "strdup: %s", estr);
205
 
-               return 0;
206
 
-       }
207
 
+               len = res_query(name, C_IN, T_SRV, buf, last_len);
208
 
+               if (len < 0) {
209
 
+                       char *estr = strerror_r(errno, ebuf, MAX_ERR_BUF);
210
 
+                       error(logopt, "Failed to resolve %s (%s)", name, estr);
211
 
+                       free(buf);
212
 
+                       return -1;
213
 
+               }
214
 
 
215
 
-       /* check that we have space remaining */
216
 
+               if (len == last_len) {
217
 
+                       /* These shouldn't too large, bump by PACKETSZ only */
218
 
+                       last_len += PACKETSZ;
219
 
+                       free(buf);
220
 
+                       continue;
221
 
+               }
222
 
 
223
 
-       if (p + 4 > end) {
224
 
-               error(logopt, "insufficient buffer space for result");
225
 
-               free((void *) q->hostname);
226
 
-               return 0;
227
 
+               break;
228
 
        }
229
 
 
230
 
-       q->type     = RSVAL(p, 0);
231
 
-       q->in_class = RSVAL(p, 2);
232
 
-       p += 4;
233
 
+       *packet = buf;
234
 
 
235
 
-       *ptr = p;
236
 
-
237
 
-       return 1;
238
 
+       return len;
239
 
 }
240
 
 
241
 
-static int dns_parse_rr(unsigned int logopt,
242
 
-                       uint8_t *start, uint8_t *end,
243
 
-                       uint8_t **ptr, struct dns_rr *rr)
244
 
+static int get_name_len(u_char *buffer, u_char *start, u_char *end)
245
 
 {
246
 
-       uint8_t *p = *ptr;
247
 
-       char hostname[MAX_DNS_NAME_LENGTH];
248
 
-       char buf[MAX_ERR_BUF];
249
 
-       int namelen;
250
 
-
251
 
-       if (!start || !end || !rr || !*ptr)
252
 
-               return 0;
253
 
-
254
 
-       memset(rr, 0, sizeof(*rr));
255
 
-
256
 
-       /* pull the name from the answer */
257
 
-
258
 
-       namelen = dn_expand(start, end, p, hostname, sizeof(hostname));
259
 
-       if (namelen < 0) {
260
 
-               error(logopt, "failed to expand query hostname");
261
 
-               return 0;
262
 
-       }
263
 
-       p += namelen;
264
 
-       rr->hostname = strdup(hostname);
265
 
-       if (!rr->hostname) {
266
 
-               char *estr = strerror_r(errno, buf, MAX_ERR_BUF);
267
 
-               error(logopt, "strdup: %s", estr);
268
 
-               return 0;
269
 
-       }
270
 
-
271
 
-       /* check that we have space remaining */
272
 
-
273
 
-       if (p + 10 > end) {
274
 
-               error(logopt, "insufficient buffer space for result");
275
 
-               free((void *) rr->hostname);
276
 
-               return 0;
277
 
-       }
278
 
-
279
 
-       /* pull some values and then skip onto the string */
280
 
-
281
 
-       rr->type     = RSVAL(p, 0);
282
 
-       rr->in_class = RSVAL(p, 2);
283
 
-       rr->ttl      = RIVAL(p, 4);
284
 
-       rr->rdatalen = RSVAL(p, 8);
285
 
-
286
 
-       p += 10;
287
 
-
288
 
-       /* sanity check the available space */
289
 
-
290
 
-       if (p + rr->rdatalen > end) {
291
 
-               error(logopt, "insufficient buffer space for data");
292
 
-               free((void *) rr->hostname);
293
 
-               return 0;
294
 
-       }
295
 
-
296
 
-       /* save a point to the rdata for this section */
297
 
-
298
 
-       rr->rdata = p;
299
 
-       p += rr->rdatalen;
300
 
-
301
 
-       *ptr = p;
302
 
-
303
 
-       return 1;
304
 
+       char tmp[MAXDNAME];
305
 
+       return dn_expand(buffer, end, start, tmp, MAXDNAME);
306
 
 }
307
 
 
308
 
-static int dns_parse_rr_srv(unsigned int logopt,
309
 
-                           uint8_t *start, uint8_t *end,
310
 
-                           uint8_t **ptr, struct dns_rr_srv *srv)
311
 
+static int get_data_offset(u_char *buffer,
312
 
+                          u_char *start, u_char *end,
313
 
+                          struct rr *rr)
314
 
 {
315
 
-       struct dns_rr rr;
316
 
-       uint8_t *p;
317
 
-       char dcname[MAX_DNS_NAME_LENGTH];
318
 
-       char buf[MAX_ERR_BUF];
319
 
-       int namelen;
320
 
-
321
 
-       if (!start || !end || !srv || !*ptr)
322
 
-               return 0;
323
 
-
324
 
-       /* Parse the RR entry.  Coming out of the this, ptr is at the beginning
325
 
-          of the next record */
326
 
-
327
 
-       if (!dns_parse_rr(logopt, start, end, ptr, &rr)) {
328
 
-               error(logopt, "Failed to parse RR record");
329
 
-               return 0;
330
 
-       }
331
 
+       u_char *cp = start;
332
 
+       int name_len;
333
 
 
334
 
-       if (rr.type != T_SRV) {
335
 
-               error(logopt, "Bad answer type (%d)", rr.type);
336
 
-               return 0;
337
 
-       }
338
 
-
339
 
-       p = rr.rdata;
340
 
+       name_len = get_name_len(buffer, start, end);
341
 
+       if (name_len < 0)
342
 
+               return -1;
343
 
+       cp += name_len;
344
 
 
345
 
-       srv->priority = RSVAL(p, 0);
346
 
-       srv->weight   = RSVAL(p, 2);
347
 
-       srv->port     = RSVAL(p, 4);
348
 
-       srv->ttl      = rr.ttl;
349
 
+       GETSHORT(rr->type, cp);
350
 
+       GETSHORT(rr->class, cp);
351
 
+       GETLONG(rr->ttl, cp);
352
 
+       GETSHORT(rr->len, cp);
353
 
 
354
 
-       p += 6;
355
 
+       return (cp - start);
356
 
+}
357
 
 
358
 
-       namelen = dn_expand(start, end, p, dcname, sizeof(dcname));
359
 
-       if (namelen < 0) {
360
 
-               error(logopt, "Failed to expand dcname");
361
 
-               return 0;
362
 
+static struct srv_rr *parse_srv_rr(unsigned int logopt,
363
 
+                                  u_char *buffer, u_char *start, u_char *end,
364
 
+                                  struct rr *rr, struct srv_rr *srv)
365
 
+{
366
 
+       u_char *cp = start;
367
 
+       char ebuf[MAX_ERR_BUF];
368
 
+       char tmp[MAXDNAME];
369
 
+       int len;
370
 
+
371
 
+       GETSHORT(srv->priority, cp);
372
 
+       GETSHORT(srv->weight, cp);
373
 
+       GETSHORT(srv->port, cp);
374
 
+       srv->ttl = rr->ttl;
375
 
+
376
 
+       len = dn_expand(buffer, end, cp, tmp, MAXDNAME);
377
 
+       if (len < 0) {
378
 
+               error(logopt, "failed to expand name");
379
 
+               return NULL;
380
 
        }
381
 
-
382
 
-       srv->hostname = strdup(dcname);
383
 
-       if (!srv->hostname) {
384
 
-               char *estr = strerror_r(errno, buf, MAX_ERR_BUF);
385
 
+       srv->name = strdup(tmp);
386
 
+       if (!srv->name) {
387
 
+               char *estr = strerror_r(errno, ebuf, MAX_ERR_BUF);
388
 
                error(logopt, "strdup: %s", estr);
389
 
-               return 0;
390
 
+               return NULL;
391
 
        }
392
 
 
393
 
-       debug(logopt, "Parsed %s [%u, %u, %u]",
394
 
-             srv->hostname, srv->priority, srv->weight, srv->port);
395
 
-
396
 
-       return 1;
397
 
+       return srv;
398
 
 }
399
 
 
400
 
-/*********************************************************************
401
 
- Sort SRV record list based on weight and priority.  See RFC 2782.
402
 
-*********************************************************************/
403
 
-
404
 
-static int dnssrvcmp(struct dns_rr_srv *a, struct dns_rr_srv *b)
405
 
+static int cmp(struct srv_rr *a, struct srv_rr *b)
406
 
 {
407
 
-       if (a->priority == b->priority) {
408
 
-               /* randomize entries with an equal weight and priority */
409
 
-               if (a->weight == b->weight)
410
 
-                       return 0;
411
 
+       if (a->priority < b->priority)
412
 
+               return -1;
413
 
 
414
 
-               /* higher weights should be sorted lower */
415
 
-               if (a->weight > b->weight)
416
 
-                       return -1;
417
 
-               else
418
 
-                       return 1;
419
 
-       }
420
 
+       if (a->priority > b->priority)
421
 
+               return 1;
422
 
 
423
 
-       if (a->priority < b->priority)
424
 
+       if (!a->weight || a->weight == b->weight)
425
 
+               return 0;
426
 
+
427
 
+       if (a->weight > b->weight)
428
 
                return -1;
429
 
 
430
 
        return 1;
431
 
 }
432
 
 
433
 
-#define DNS_FAILED_WAITTIME          30
434
 
-
435
 
-static int dns_send_req(unsigned int logopt,
436
 
-                       const char *name, int q_type, uint8_t **rbuf,
437
 
-                       int *resp_length)
438
 
+static void free_srv_rrs(struct srv_rr *dcs, unsigned int count)
439
 
 {
440
 
-       uint8_t *buffer = NULL;
441
 
-       size_t buf_len = 0;
442
 
-       int resp_len = NS_PACKETSZ;
443
 
-       static time_t last_dns_check = 0;
444
 
-       static unsigned int last_dns_status = 0;
445
 
-       time_t now = time(NULL);
446
 
-       char buf[MAX_ERR_BUF];
447
 
-
448
 
-       /* Try to prevent bursts of DNS lookups if the server is down */
449
 
-
450
 
-       /* Protect against large clock changes */
451
 
-
452
 
-       if (last_dns_check > now)
453
 
-               last_dns_check = 0;
454
 
+       int i;
455
 
 
456
 
-       /* IF we had a DNS timeout or a bad server and we are still
457
 
-          in the 30 second cache window, just return the previous
458
 
-          status and save the network timeout. */
459
 
-
460
 
-       if ((last_dns_status == ETIMEDOUT ||
461
 
-            last_dns_status == ECONNREFUSED) &&
462
 
-            ((last_dns_check + DNS_FAILED_WAITTIME) > now)) {
463
 
-               char *estr = strerror_r(last_dns_status, buf, MAX_ERR_BUF);
464
 
-               debug(logopt, "Returning cached status (%s)", estr);
465
 
-               return last_dns_status;
466
 
+       for (i = 0; i < count; i++) {
467
 
+               if (dcs[i].name)
468
 
+                       free((void *) dcs[i].name);
469
 
        }
470
 
-
471
 
-       /* Send the Query */
472
 
-       do {
473
 
-               if (buffer)
474
 
-                       free(buffer);
475
 
-
476
 
-               buf_len = resp_len * sizeof(uint8_t);
477
 
-
478
 
-               if (buf_len) {
479
 
-                       buffer = malloc(buf_len);
480
 
-                       if (!buffer) {
481
 
-                               char *estr = strerror_r(errno, buf, MAX_ERR_BUF);
482
 
-                               error(logopt, "malloc: %s", estr);
483
 
-                               last_dns_status = ENOMEM;
484
 
-                               last_dns_check = time(NULL);
485
 
-                               return last_dns_status;
486
 
-                       }
487
 
-               }
488
 
-
489
 
-               resp_len = res_query(name, C_IN, q_type, buffer, buf_len);
490
 
-               if (resp_len < 0) {
491
 
-                       char *estr = strerror_r(errno, buf, MAX_ERR_BUF);
492
 
-                       error(logopt, "Failed to resolve %s (%s)", name, estr);
493
 
-                       free(buffer);
494
 
-                       last_dns_status = ENOENT;
495
 
-                       last_dns_check = time(NULL);
496
 
-                       return last_dns_status;
497
 
-               }
498
 
-
499
 
-               /* On AIX, Solaris, and possibly some older glibc systems (e.g. SLES8)
500
 
-                  truncated replies never give back a resp_len > buflen
501
 
-                  which ends up causing DNS resolve failures on large tcp DNS replies */
502
 
-
503
 
-               if (buf_len == resp_len) {
504
 
-                       if (resp_len == MAX_DNS_PACKET_SIZE) {
505
 
-                               error(logopt,
506
 
-                                     "DNS reply too large when resolving %s",
507
 
-                                     name);
508
 
-                               free(buffer);
509
 
-                               last_dns_status = EMSGSIZE;
510
 
-                               last_dns_check = time(NULL);
511
 
-                               return last_dns_status;
512
 
-                       }
513
 
-
514
 
-                       resp_len = MIN(resp_len * 2, MAX_DNS_PACKET_SIZE);
515
 
-               }
516
 
-       } while (buf_len < resp_len && resp_len <= MAX_DNS_PACKET_SIZE);
517
 
-
518
 
-       *rbuf = buffer;
519
 
-       *resp_length = resp_len;
520
 
-
521
 
-       last_dns_check = time(NULL);
522
 
-       last_dns_status = 0;
523
 
-
524
 
-       return 0;
525
 
+       free(dcs);
526
 
 }
527
 
 
528
 
-static int dns_lookup_srv(unsigned int logopt, const char *name,
529
 
-                         struct dns_rr_srv **dclist, int *numdcs)
530
 
+int get_srv_rrs(unsigned int logopt,
531
 
+               char *name, struct srv_rr **dcs, unsigned int *dcs_count)
532
 
 {
533
 
-       uint8_t *buffer = NULL;
534
 
-       int resp_len = 0;
535
 
-       struct dns_rr_srv *dcs = NULL;
536
 
-       int query_count, answer_count;
537
 
-       uint8_t *p = buffer;
538
 
-       int rrnum;
539
 
-       int idx = 0;
540
 
-       char buf[MAX_ERR_BUF];
541
 
-       int ret;
542
 
+       struct srv_rr *srvs;
543
 
+       unsigned int srv_num;
544
 
+       HEADER *header;
545
 
+       u_char *packet;
546
 
+       u_char *start;
547
 
+       u_char *end;
548
 
+       unsigned int count;
549
 
+       int i, len;
550
 
+       char ebuf[MAX_ERR_BUF];
551
 
+
552
 
+       len = do_srv_query(logopt, name, &packet);
553
 
+       if (len < 0)
554
 
+               return 0;
555
 
 
556
 
-       if (!name || !dclist)
557
 
-               return -EINVAL;
558
 
+       header = (HEADER *) packet;
559
 
+       start = packet + sizeof(HEADER);
560
 
+       end = packet + len;
561
 
 
562
 
-       /* Send the request.  May have to loop several times in case
563
 
-          of large replies */
564
 
+       srvs = NULL;
565
 
+       srv_num = 0;
566
 
 
567
 
-       ret = dns_send_req(logopt, name, T_SRV, &buffer, &resp_len);
568
 
-       if (ret) {
569
 
-               error(logopt, "Failed to send DNS query");
570
 
-               return ret;
571
 
+       /* Skip over question */
572
 
+       len = get_name_len(packet, start, end);
573
 
+       if (len < 0) {
574
 
+               error(logopt, "failed to get name length");
575
 
+               goto error_out;
576
 
        }
577
 
-       p = buffer;
578
 
 
579
 
-       /* For some insane reason, the ns_initparse() et. al. routines are only
580
 
-          available in libresolv.a, and not the shared lib.  Who knows why....
581
 
-          So we have to parse the DNS reply ourselves */
582
 
+       start += len + QFIXEDSZ;
583
 
 
584
 
-       /* Pull the answer RR's count from the header.
585
 
-        * Use the NMB ordering macros */
586
 
+       count = ntohs(header->ancount);
587
 
 
588
 
-       query_count      = RSVAL(p, 4);
589
 
-       answer_count     = RSVAL(p, 6);
590
 
+       debug(logopt, "%d records returned in the answer section", count);
591
 
 
592
 
-       debug(logopt,
593
 
-             "%d records returned in the answer section.",
594
 
-              answer_count);
595
 
+       if (count <= 0) {
596
 
+               error(logopt, "no records found in answers section");
597
 
+               goto error_out;
598
 
+       }
599
 
 
600
 
-       if (answer_count) {
601
 
-               dcs = malloc(sizeof(struct dns_rr_srv) * answer_count);
602
 
-               if (!dcs) {
603
 
-                       char *estr = strerror_r(errno, buf, MAX_ERR_BUF);
604
 
-                       error(logopt, "malloc: %s", estr);
605
 
-                       free(buffer);
606
 
-                       return ENOMEM;
607
 
-               }
608
 
+       srvs = malloc(sizeof(struct srv_rr) * count);
609
 
+       if (!srvs) {
610
 
+               char *estr = strerror_r(errno, ebuf, MAX_ERR_BUF);
611
 
+               error(logopt, "malloc: %s", estr);
612
 
+               goto error_out;
613
 
        }
614
 
+       memset(srvs, 0, sizeof(struct srv_rr) * count);
615
 
 
616
 
-       /* now skip the header */
617
 
+       srv_num = 0;
618
 
+       for (i = 0; i < count && (start < end); i++) {
619
 
+               unsigned int data_offset;
620
 
+               struct srv_rr srv;
621
 
+               struct srv_rr *psrv;
622
 
+               struct rr rr;
623
 
 
624
 
-       p += NS_HFIXEDSZ;
625
 
+               memset(&rr, 0, sizeof(struct rr));
626
 
 
627
 
-       /* parse the query section */
628
 
+               data_offset = get_data_offset(packet, start, end, &rr);
629
 
+               if (data_offset <= 0) {
630
 
+                       error(logopt, "failed to get start of data");
631
 
+                       goto error_out;
632
 
+               }
633
 
+               start += data_offset;
634
 
 
635
 
-       for (rrnum = 0; rrnum < query_count; rrnum++) {
636
 
-               struct dns_query q;
637
 
+               if (rr.type != T_SRV)
638
 
+                       continue;
639
 
 
640
 
-               ret = dns_parse_query(logopt, buffer, buffer+resp_len, &p, &q);
641
 
-               if (!ret) {
642
 
-                       error(logopt,
643
 
-                             "Failed to parse query record [%d]", rrnum);
644
 
-                       free(buffer);
645
 
-                       free(dcs);
646
 
-                       return EBADMSG;
647
 
+               psrv = parse_srv_rr(logopt, packet, start, end, &rr, &srv);
648
 
+               if (psrv) {
649
 
+                       memcpy(&srvs[srv_num], psrv, sizeof(struct srv_rr));
650
 
+                       srv_num++;
651
 
                }
652
 
-       }
653
 
 
654
 
-       /* now we are at the answer section */
655
 
+               start += rr.len;
656
 
+       }
657
 
+       free(packet);
658
 
 
659
 
-       for (rrnum = 0; rrnum < answer_count; rrnum++) {
660
 
-               ret = dns_parse_rr_srv(logopt,
661
 
-                                      buffer, buffer+resp_len,
662
 
-                                      &p, &dcs[rrnum]);
663
 
-               if (!ret) {
664
 
-                       error(logopt,
665
 
-                             "Failed to parse answer record [%d]", rrnum);
666
 
-                       free(buffer);
667
 
-                       free(dcs);
668
 
-                       return EBADMSG;
669
 
-               }
670
 
+       if (!srv_num) {
671
 
+               error(logopt, "no srv resource records found");
672
 
+               goto error_srvs;
673
 
        }
674
 
-       idx = rrnum;
675
 
 
676
 
-       qsort(dcs, idx, sizeof(struct dns_rr_srv), QSORT_CAST dnssrvcmp);
677
 
+       qsort(srvs, srv_num, sizeof(struct srv_rr),
678
 
+               (int (*)(const void *, const void *)) cmp);
679
 
 
680
 
-       *dclist = dcs;
681
 
-       *numdcs = idx;
682
 
+       *dcs = srvs;
683
 
+       *dcs_count = srv_num;
684
 
 
685
 
+       return 1;
686
 
+
687
 
+error_out:
688
 
+       free(packet);
689
 
+error_srvs:
690
 
+       if (srvs)
691
 
+               free_srv_rrs(srvs, srv_num);
692
 
        return 0;
693
 
 }
694
 
 
695
 
@@ -553,14 +337,14 @@ void free_dclist(struct dclist *dclist)
696
 
 static char *getdnsdomainname(unsigned int logopt)
697
 
 {
698
 
        struct addrinfo hints, *ni;
699
 
-       char name[MAX_DNS_NAME_LENGTH + 1];
700
 
+       char name[MAXDNAME + 1];
701
 
        char buf[MAX_ERR_BUF];
702
 
        char *dnsdomain = NULL;
703
 
        char *ptr;
704
 
        int ret;
705
 
 
706
 
        memset(name, 0, sizeof(name));
707
 
-       if (gethostname(name, MAX_DNS_NAME_LENGTH) == -1) {
708
 
+       if (gethostname(name, MAXDNAME) == -1) {
709
 
                char *estr = strerror_r(errno, buf, MAX_ERR_BUF);
710
 
                error(logopt, "gethostname: %s", estr);
711
 
                return NULL;
712
 
@@ -593,14 +377,12 @@ struct dclist *get_dc_list(unsigned int logopt, const char *uri)
713
 
 {
714
 
        LDAPURLDesc *ludlist = NULL;
715
 
        LDAPURLDesc **ludp;
716
 
-       struct dns_rr_srv *dcs;
717
 
        unsigned int min_ttl = MAX_TTL;
718
 
        struct dclist *dclist = NULL;;
719
 
        char buf[MAX_ERR_BUF];
720
 
        char *dn_uri, *esc_uri;
721
 
        char *domain;
722
 
        char *list;
723
 
-       int numdcs;
724
 
        int ret;
725
 
 
726
 
        if (strcmp(uri, "ldap:///") && strcmp(uri, "ldaps:///")) {
727
 
@@ -679,6 +461,8 @@ struct dclist *get_dc_list(unsigned int logopt, const char *uri)
728
 
        list = NULL;
729
 
        for (ludp = &ludlist; *ludp != NULL;) {
730
 
                LDAPURLDesc *lud = *ludp;
731
 
+               struct srv_rr *dcs = NULL;
732
 
+               unsigned int numdcs = 0;
733
 
                size_t req_len, len;
734
 
                char *request = NULL;
735
 
                char *tmp;
736
 
@@ -716,7 +500,7 @@ struct dclist *get_dc_list(unsigned int logopt, const char *uri)
737
 
                }
738
 
 
739
 
                dclist_mutex_lock();
740
 
-               if (dns_lookup_srv(logopt, request, &dcs, &numdcs)) {
741
 
+               if (!get_srv_rrs(logopt, request, &dcs, &numdcs)) {
742
 
                        error(logopt,
743
 
                              "DNS SRV query failed for domain %s", domain);
744
 
                        dclist_mutex_unlock();
745
 
@@ -733,7 +517,7 @@ struct dclist *get_dc_list(unsigned int logopt, const char *uri)
746
 
                for (i = 0; i < numdcs; i++) {
747
 
                        if (dcs[i].ttl > 0 && dcs[i].ttl < min_ttl)
748
 
                                min_ttl = dcs[i].ttl;
749
 
-                       len += strlen(dcs[i].hostname);
750
 
+                       len += strlen(dcs[i].name);
751
 
                        if (dcs[i].port > 0)
752
 
                                len += sizeof(":65535");
753
 
                }
754
 
@@ -742,6 +526,8 @@ struct dclist *get_dc_list(unsigned int logopt, const char *uri)
755
 
                if (!tmp) {
756
 
                        char *estr = strerror_r(errno, buf, MAX_ERR_BUF);
757
 
                        error(logopt, "realloc: %s", estr);
758
 
+                       if (dcs)
759
 
+                               free_srv_rrs(dcs, numdcs);
760
 
                        goto out_error;
761
 
                }
762
 
 
763
 
@@ -755,13 +541,15 @@ struct dclist *get_dc_list(unsigned int logopt, const char *uri)
764
 
                                strcat(tmp, " ");
765
 
                        strcat(tmp, lud->lud_scheme);
766
 
                        strcat(tmp, "://");
767
 
-                       strcat(tmp, dcs[i].hostname);
768
 
+                       strcat(tmp, dcs[i].name);
769
 
                        if (dcs[i].port > 0) {
770
 
                                char port[7];
771
 
                                ret = snprintf(port, 7, ":%d", dcs[i].port);
772
 
                                if (ret > 6) {
773
 
                                        error(logopt,
774
 
                                              "invalid port: %u", dcs[i].port);
775
 
+                                       if (dcs)
776
 
+                                               free_srv_rrs(dcs, numdcs);
777
 
                                        goto out_error;
778
 
                                }
779
 
                                strcat(tmp, port);
780
 
@@ -771,10 +559,14 @@ struct dclist *get_dc_list(unsigned int logopt, const char *uri)
781
 
 
782
 
                *ludp = lud->lud_next;
783
 
                ber_memfree(domain);
784
 
+               free_srv_rrs(dcs, numdcs);
785
 
        }
786
 
 
787
 
        ldap_free_urldesc(ludlist);
788
 
 
789
 
+       if (!list)
790
 
+               goto out_error;
791
 
+
792
 
        dclist->expire = time(NULL) + min_ttl;
793
 
        dclist->uri = list;
794