11
11
12
12
#include <linux/module.h>
13
13
#include <linux/slab.h>
14
+ #include <linux/key.h>
15
+ #include <linux/ctype.h>
16
+ #include <keys/rxrpc-type.h>
14
17
#include "internal.h"
15
18
16
19
DECLARE_RWSEM (afs_proc_cells_sem );
@@ -23,45 +26,43 @@ static DECLARE_WAIT_QUEUE_HEAD(afs_cells_freeable_wq);
23
26
static struct afs_cell * afs_cell_root ;
24
27
25
28
/*
26
- * create a cell record
27
- * - "name" is the name of the cell
28
- * - "vllist" is a colon separated list of IP addresses in "a.b.c.d" format
29
+ * allocate a cell record and fill in its name, VL server address list and
30
+ * allocate an anonymous key
29
31
*/
30
- struct afs_cell * afs_cell_create (const char * name , char * vllist )
32
+ static struct afs_cell * afs_cell_alloc (const char * name , char * vllist )
31
33
{
32
34
struct afs_cell * cell ;
33
- char * next ;
35
+ size_t namelen ;
36
+ char keyname [4 + AFS_MAXCELLNAME + 1 ], * cp , * dp , * next ;
34
37
int ret ;
35
38
36
39
_enter ("%s,%s" , name , vllist );
37
40
38
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
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
49
if (!cell ) {
43
50
_leave (" = -ENOMEM" );
44
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
57
atomic_set (& cell -> usage , 1 );
51
-
52
58
INIT_LIST_HEAD (& cell -> link );
53
-
54
59
rwlock_init (& cell -> servers_lock );
55
60
INIT_LIST_HEAD (& cell -> servers );
56
-
57
61
init_rwsem (& cell -> vl_sem );
58
62
INIT_LIST_HEAD (& cell -> vl_list );
59
63
spin_lock_init (& cell -> vl_lock );
60
64
61
- strcpy (cell -> name , name );
62
-
63
65
/* fill in the VL server list from the rest of the string */
64
- ret = - EINVAL ;
65
66
do {
66
67
unsigned a , b , c , d ;
67
68
@@ -70,18 +71,73 @@ struct afs_cell *afs_cell_create(const char *name, char *vllist)
70
71
* next ++ = 0 ;
71
72
72
73
if (sscanf (vllist , "%u.%u.%u.%u" , & a , & b , & c , & d ) != 4 )
73
- goto badaddr ;
74
+ goto bad_address ;
74
75
75
76
if (a > 255 || b > 255 || c > 255 || d > 255 )
76
- goto badaddr ;
77
+ goto bad_address ;
77
78
78
79
cell -> vl_addrs [cell -> vl_naddrs ++ ].s_addr =
79
80
htonl ((a << 24 ) | (b << 16 ) | (c << 8 ) | d );
80
81
81
- if (cell -> vl_naddrs >= AFS_CELL_MAX_ADDRS )
82
- break ;
82
+ } while (cell -> vl_naddrs < AFS_CELL_MAX_ADDRS && (vllist = next ));
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
+
112
+ bad_address :
113
+ printk (KERN_ERR "kAFS: bad VL server IP address\n" );
114
+ ret = - EINVAL ;
115
+ error :
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
+ */
127
+ struct 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
142
/* add a proc directory for this cell */
87
143
ret = afs_proc_cell_setup (cell );
@@ -109,10 +165,9 @@ struct afs_cell *afs_cell_create(const char *name, char *vllist)
109
165
_leave (" = %p" , cell );
110
166
return cell ;
111
167
112
- badaddr :
113
- printk (KERN_ERR "kAFS: bad VL server IP address\n" );
114
168
error :
115
169
up_write (& afs_cells_sem );
170
+ key_put (cell -> anonymous_key );
116
171
kfree (cell );
117
172
_leave (" = %d" , ret );
118
173
return ERR_PTR (ret );
@@ -301,6 +356,7 @@ static void afs_cell_destroy(struct afs_cell *cell)
301
356
cachefs_relinquish_cookie (cell -> cache , 0 );
302
357
#endif
303
358
359
+ key_put (cell -> anonymous_key );
304
360
kfree (cell );
305
361
306
362
_leave (" [destroyed]" );
0 commit comments