Commit 07567a5509327bcbf2c867286eb1524447c9b954

Authored by Wang Lei
Committed by Steve French
1 parent 1a4240f476

DNS: Make AFS go to the DNS for AFSDB records for unknown cells

Add DNS query support for AFS so that it can get the IP addresses of Volume
Location servers from the DNS using an AFSDB record.

This requires userspace support.  /etc/request-key.conf must be configured to
invoke a helper for dns_resolver type keys with a subtype of "afsdb:" in the
description.

Signed-off-by: Wang Lei <wang840925@gmail.com>
Signed-off-by: David Howells <dhowells@redhat.com>
Signed-off-by: Steve French <sfrench@us.ibm.com>

Showing 2 changed files with 31 additions and 10 deletions Side-by-side Diff

... ... @@ -2,6 +2,7 @@
2 2 tristate "Andrew File System support (AFS) (EXPERIMENTAL)"
3 3 depends on INET && EXPERIMENTAL
4 4 select AF_RXRPC
  5 + select DNS_RESOLVER
5 6 help
6 7 If you say Y here, you will get an experimental Andrew File System
7 8 driver. It currently only supports unsecured read-only AFS access.
... ... @@ -13,6 +13,7 @@
13 13 #include <linux/slab.h>
14 14 #include <linux/key.h>
15 15 #include <linux/ctype.h>
  16 +#include <linux/dns_resolver.h>
16 17 #include <linux/sched.h>
17 18 #include <keys/rxrpc-type.h>
18 19 #include "internal.h"
... ... @@ -36,6 +37,8 @@
36 37 struct key *key;
37 38 size_t namelen;
38 39 char keyname[4 + AFS_MAXCELLNAME + 1], *cp, *dp, *next;
  40 + char *dvllist = NULL, *_vllist = NULL;
  41 + char delimiter = ':';
39 42 int ret;
40 43  
41 44 _enter("%s,%s", name, vllist);
42 45  
... ... @@ -43,8 +46,10 @@
43 46 BUG_ON(!name); /* TODO: want to look up "this cell" in the cache */
44 47  
45 48 namelen = strlen(name);
46   - if (namelen > AFS_MAXCELLNAME)
  49 + if (namelen > AFS_MAXCELLNAME) {
  50 + _leave(" = -ENAMETOOLONG");
47 51 return ERR_PTR(-ENAMETOOLONG);
  52 + }
48 53  
49 54 /* allocate and initialise a cell record */
50 55 cell = kzalloc(sizeof(struct afs_cell) + namelen + 1, GFP_KERNEL);
51 56  
52 57  
... ... @@ -64,15 +69,31 @@
64 69 INIT_LIST_HEAD(&cell->vl_list);
65 70 spin_lock_init(&cell->vl_lock);
66 71  
  72 + /* if the ip address is invalid, try dns query */
  73 + if (!vllist || strlen(vllist) < 7) {
  74 + ret = dns_query("afsdb", name, namelen, "ipv4", &dvllist, NULL);
  75 + if (ret < 0) {
  76 + _leave(" = %d", ret);
  77 + return ERR_PTR(ret);
  78 + }
  79 + _vllist = dvllist;
  80 +
  81 + /* change the delimiter for user-space reply */
  82 + delimiter = ',';
  83 +
  84 + } else {
  85 + _vllist = vllist;
  86 + }
  87 +
67 88 /* fill in the VL server list from the rest of the string */
68 89 do {
69 90 unsigned a, b, c, d;
70 91  
71   - next = strchr(vllist, ':');
  92 + next = strchr(_vllist, delimiter);
72 93 if (next)
73 94 *next++ = 0;
74 95  
75   - if (sscanf(vllist, "%u.%u.%u.%u", &a, &b, &c, &d) != 4)
  96 + if (sscanf(_vllist, "%u.%u.%u.%u", &a, &b, &c, &d) != 4)
76 97 goto bad_address;
77 98  
78 99 if (a > 255 || b > 255 || c > 255 || d > 255)
... ... @@ -81,7 +102,7 @@
81 102 cell->vl_addrs[cell->vl_naddrs++].s_addr =
82 103 htonl((a << 24) | (b << 16) | (c << 8) | d);
83 104  
84   - } while (cell->vl_naddrs < AFS_CELL_MAX_ADDRS && (vllist = next));
  105 + } while (cell->vl_naddrs < AFS_CELL_MAX_ADDRS && (_vllist = next));
85 106  
86 107 /* create a key to represent an anonymous user */
87 108 memcpy(keyname, "afs@", 4);
... ... @@ -110,6 +131,7 @@
110 131 ret = -EINVAL;
111 132 error:
112 133 key_put(cell->anonymous_key);
  134 + kfree(dvllist);
113 135 kfree(cell);
114 136 _leave(" = %d", ret);
115 137 return ERR_PTR(ret);
116 138  
... ... @@ -201,14 +223,12 @@
201 223 }
202 224  
203 225 cp = strchr(rootcell, ':');
204   - if (!cp) {
205   - printk(KERN_ERR "kAFS: no VL server IP addresses specified\n");
206   - _leave(" = -EINVAL");
207   - return -EINVAL;
208   - }
  226 + if (!cp)
  227 + _debug("kAFS: no VL server IP addresses specified");
  228 + else
  229 + *cp++ = 0;
209 230  
210 231 /* allocate a cell record for the root cell */
211   - *cp++ = 0;
212 232 new_root = afs_cell_create(rootcell, cp);
213 233 if (IS_ERR(new_root)) {
214 234 _leave(" = %ld", PTR_ERR(new_root));