aboutsummaryrefslogtreecommitdiffstats
path: root/fs/afs/cell.c
diff options
context:
space:
mode:
authorDavid Howells <dhowells@redhat.com>2007-04-26 18:57:07 -0400
committerDavid S. Miller <davem@davemloft.net>2007-04-26 18:57:07 -0400
commit00d3b7a4533e367b0dc2812a706db8f9f071c27f (patch)
treef0b1ae0266267cb2c54cb11aa61ad0758ce9c0f5 /fs/afs/cell.c
parent436058a49e0fb91c74454dbee9cfee6fb53b4336 (diff)
[AFS]: Add security support.
Add security support to the AFS filesystem. Kerberos IV tickets are added as RxRPC keys are added to the session keyring with the klog program. open() and other VFS operations then find this ticket with request_key() and either use it immediately (eg: mkdir, unlink) or attach it to a file descriptor (open). Signed-off-by: David Howells <dhowells@redhat.com> Signed-off-by: David S. Miller <davem@davemloft.net>
Diffstat (limited to 'fs/afs/cell.c')
-rw-r--r--fs/afs/cell.c98
1 files changed, 77 insertions, 21 deletions
diff --git a/fs/afs/cell.c b/fs/afs/cell.c
index 733c60246ab0..9b1311a1df51 100644
--- a/fs/afs/cell.c
+++ b/fs/afs/cell.c
@@ -11,6 +11,9 @@
11 11
12#include <linux/module.h> 12#include <linux/module.h>
13#include <linux/slab.h> 13#include <linux/slab.h>
14#include <linux/key.h>
15#include <linux/ctype.h>
16#include <keys/rxrpc-type.h>
14#include "internal.h" 17#include "internal.h"
15 18
16DECLARE_RWSEM(afs_proc_cells_sem); 19DECLARE_RWSEM(afs_proc_cells_sem);
@@ -23,45 +26,43 @@ static DECLARE_WAIT_QUEUE_HEAD(afs_cells_freeable_wq);
23static struct afs_cell *afs_cell_root; 26static struct afs_cell *afs_cell_root;
24 27
25/* 28/*
26 * create a cell record 29 * allocate a cell record and fill in its name, VL server address list and
27 * - "name" is the name of the cell 30 * allocate an anonymous key
28 * - "vllist" is a colon separated list of IP addresses in "a.b.c.d" format
29 */ 31 */
30struct afs_cell *afs_cell_create(const char *name, char *vllist) 32static struct afs_cell *afs_cell_alloc(const char *name, char *vllist)
31{ 33{
32 struct afs_cell *cell; 34 struct afs_cell *cell;
33 char *next; 35 size_t namelen;
36 char keyname[4 + AFS_MAXCELLNAME + 1], *cp, *dp, *next;
34 int ret; 37 int ret;
35 38
36 _enter("%s,%s", name, vllist); 39 _enter("%s,%s", name, vllist);
37 40
38 BUG_ON(!name); /* TODO: want to look up "this cell" in the cache */ 41 BUG_ON(!name); /* TODO: want to look up "this cell" in the cache */
39 42
43 namelen = strlen(name);
44 if (namelen > AFS_MAXCELLNAME)
45 return ERR_PTR(-ENAMETOOLONG);
46
40 /* allocate and initialise a cell record */ 47 /* allocate and initialise a cell record */
41 cell = kmalloc(sizeof(struct afs_cell) + strlen(name) + 1, GFP_KERNEL); 48 cell = kzalloc(sizeof(struct afs_cell) + namelen + 1, GFP_KERNEL);
42 if (!cell) { 49 if (!cell) {
43 _leave(" = -ENOMEM"); 50 _leave(" = -ENOMEM");
44 return ERR_PTR(-ENOMEM); 51 return ERR_PTR(-ENOMEM);
45 } 52 }
46 53
47 down_write(&afs_cells_sem); 54 memcpy(cell->name, name, namelen);
55 cell->name[namelen] = 0;
48 56
49 memset(cell, 0, sizeof(struct afs_cell));
50 atomic_set(&cell->usage, 1); 57 atomic_set(&cell->usage, 1);
51
52 INIT_LIST_HEAD(&cell->link); 58 INIT_LIST_HEAD(&cell->link);
53
54 rwlock_init(&cell->servers_lock); 59 rwlock_init(&cell->servers_lock);
55 INIT_LIST_HEAD(&cell->servers); 60 INIT_LIST_HEAD(&cell->servers);
56
57 init_rwsem(&cell->vl_sem); 61 init_rwsem(&cell->vl_sem);
58 INIT_LIST_HEAD(&cell->vl_list); 62 INIT_LIST_HEAD(&cell->vl_list);
59 spin_lock_init(&cell->vl_lock); 63 spin_lock_init(&cell->vl_lock);
60 64
61 strcpy(cell->name, name);
62
63 /* fill in the VL server list from the rest of the string */ 65 /* fill in the VL server list from the rest of the string */
64 ret = -EINVAL;
65 do { 66 do {
66 unsigned a, b, c, d; 67 unsigned a, b, c, d;
67 68
@@ -70,18 +71,73 @@ struct afs_cell *afs_cell_create(const char *name, char *vllist)
70 *next++ = 0; 71 *next++ = 0;
71 72
72 if (sscanf(vllist, "%u.%u.%u.%u", &a, &b, &c, &d) != 4) 73 if (sscanf(vllist, "%u.%u.%u.%u", &a, &b, &c, &d) != 4)
73 goto badaddr; 74 goto bad_address;
74 75
75 if (a > 255 || b > 255 || c > 255 || d > 255) 76 if (a > 255 || b > 255 || c > 255 || d > 255)
76 goto badaddr; 77 goto bad_address;
77 78
78 cell->vl_addrs[cell->vl_naddrs++].s_addr = 79 cell->vl_addrs[cell->vl_naddrs++].s_addr =
79 htonl((a << 24) | (b << 16) | (c << 8) | d); 80 htonl((a << 24) | (b << 16) | (c << 8) | d);
80 81
81 if (cell->vl_naddrs >= AFS_CELL_MAX_ADDRS) 82 } while (cell->vl_naddrs < AFS_CELL_MAX_ADDRS && (vllist = next));
82 break; 83
84 /* create a key to represent an anonymous user */
85 memcpy(keyname, "afs@", 4);
86 dp = keyname + 4;
87 cp = cell->name;
88 do {
89 *dp++ = toupper(*cp);
90 } while (*cp++);
91 cell->anonymous_key = key_alloc(&key_type_rxrpc, keyname, 0, 0, current,
92 KEY_POS_SEARCH, KEY_ALLOC_NOT_IN_QUOTA);
93 if (IS_ERR(cell->anonymous_key)) {
94 _debug("no key");
95 ret = PTR_ERR(cell->anonymous_key);
96 goto error;
97 }
98
99 ret = key_instantiate_and_link(cell->anonymous_key, NULL, 0,
100 NULL, NULL);
101 if (ret < 0) {
102 _debug("instantiate failed");
103 goto error;
104 }
105
106 _debug("anon key %p{%x}",
107 cell->anonymous_key, key_serial(cell->anonymous_key));
108
109 _leave(" = %p", cell);
110 return cell;
111
112bad_address:
113 printk(KERN_ERR "kAFS: bad VL server IP address\n");
114 ret = -EINVAL;
115error:
116 key_put(cell->anonymous_key);
117 kfree(cell);
118 _leave(" = %d", ret);
119 return ERR_PTR(ret);
120}
83 121
84 } while ((vllist = next)); 122/*
123 * create a cell record
124 * - "name" is the name of the cell
125 * - "vllist" is a colon separated list of IP addresses in "a.b.c.d" format
126 */
127struct afs_cell *afs_cell_create(const char *name, char *vllist)
128{
129 struct afs_cell *cell;
130 int ret;
131
132 _enter("%s,%s", name, vllist);
133
134 cell = afs_cell_alloc(name, vllist);
135 if (IS_ERR(cell)) {
136 _leave(" = %ld", PTR_ERR(cell));
137 return cell;
138 }
139
140 down_write(&afs_cells_sem);
85 141
86 /* add a proc directory for this cell */ 142 /* add a proc directory for this cell */
87 ret = afs_proc_cell_setup(cell); 143 ret = afs_proc_cell_setup(cell);
@@ -109,10 +165,9 @@ struct afs_cell *afs_cell_create(const char *name, char *vllist)
109 _leave(" = %p", cell); 165 _leave(" = %p", cell);
110 return cell; 166 return cell;
111 167
112badaddr:
113 printk(KERN_ERR "kAFS: bad VL server IP address\n");
114error: 168error:
115 up_write(&afs_cells_sem); 169 up_write(&afs_cells_sem);
170 key_put(cell->anonymous_key);
116 kfree(cell); 171 kfree(cell);
117 _leave(" = %d", ret); 172 _leave(" = %d", ret);
118 return ERR_PTR(ret); 173 return ERR_PTR(ret);
@@ -301,6 +356,7 @@ static void afs_cell_destroy(struct afs_cell *cell)
301 cachefs_relinquish_cookie(cell->cache, 0); 356 cachefs_relinquish_cookie(cell->cache, 0);
302#endif 357#endif
303 358
359 key_put(cell->anonymous_key);
304 kfree(cell); 360 kfree(cell);
305 361
306 _leave(" [destroyed]"); 362 _leave(" [destroyed]");