aboutsummaryrefslogtreecommitdiffstats
path: root/fs/afs/volume.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/volume.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/volume.c')
-rw-r--r--fs/afs/volume.c109
1 files changed, 22 insertions, 87 deletions
diff --git a/fs/afs/volume.c b/fs/afs/volume.c
index 45491cfd4f4f..15e13678c216 100644
--- a/fs/afs/volume.c
+++ b/fs/afs/volume.c
@@ -41,83 +41,20 @@ static const char *afs_voltypes[] = { "R/W", "R/O", "BAK" };
41 * - Rule 3: If parent volume is R/W, then only mount R/W volume unless 41 * - Rule 3: If parent volume is R/W, then only mount R/W volume unless
42 * explicitly told otherwise 42 * explicitly told otherwise
43 */ 43 */
44struct afs_volume *afs_volume_lookup(const char *name, struct afs_cell *cell, 44struct afs_volume *afs_volume_lookup(struct afs_mount_params *params)
45 int rwpath)
46{ 45{
47 struct afs_vlocation *vlocation = NULL; 46 struct afs_vlocation *vlocation = NULL;
48 struct afs_volume *volume = NULL; 47 struct afs_volume *volume = NULL;
49 struct afs_server *server = NULL; 48 struct afs_server *server = NULL;
50 afs_voltype_t type;
51 const char *cellname, *volname, *suffix;
52 char srvtmask; 49 char srvtmask;
53 int force, ret, loop, cellnamesz, volnamesz; 50 int ret, loop;
54 51
55 _enter("%s,,%d,", name, rwpath); 52 _enter("{%*.*s,%d}",
56 53 params->volnamesz, params->volnamesz, params->volname, params->rwpath);
57 if (!name || (name[0] != '%' && name[0] != '#') || !name[1]) {
58 printk("kAFS: unparsable volume name\n");
59 return ERR_PTR(-EINVAL);
60 }
61
62 /* determine the type of volume we're looking for */
63 force = 0;
64 type = AFSVL_ROVOL;
65
66 if (rwpath || name[0] == '%') {
67 type = AFSVL_RWVOL;
68 force = 1;
69 }
70
71 suffix = strrchr(name, '.');
72 if (suffix) {
73 if (strcmp(suffix, ".readonly") == 0) {
74 type = AFSVL_ROVOL;
75 force = 1;
76 } else if (strcmp(suffix, ".backup") == 0) {
77 type = AFSVL_BACKVOL;
78 force = 1;
79 } else if (suffix[1] == 0) {
80 } else {
81 suffix = NULL;
82 }
83 }
84
85 /* split the cell and volume names */
86 name++;
87 volname = strchr(name, ':');
88 if (volname) {
89 cellname = name;
90 cellnamesz = volname - name;
91 volname++;
92 } else {
93 volname = name;
94 cellname = NULL;
95 cellnamesz = 0;
96 }
97
98 volnamesz = suffix ? suffix - volname : strlen(volname);
99
100 _debug("CELL:%*.*s [%p] VOLUME:%*.*s SUFFIX:%s TYPE:%d%s",
101 cellnamesz, cellnamesz, cellname ?: "", cell,
102 volnamesz, volnamesz, volname, suffix ?: "-",
103 type,
104 force ? " FORCE" : "");
105
106 /* lookup the cell record */
107 if (cellname || !cell) {
108 cell = afs_cell_lookup(cellname, cellnamesz);
109 if (IS_ERR(cell)) {
110 ret = PTR_ERR(cell);
111 printk("kAFS: unable to lookup cell '%s'\n",
112 cellname ?: "");
113 goto error;
114 }
115 } else {
116 afs_get_cell(cell);
117 }
118 54
119 /* lookup the volume location record */ 55 /* lookup the volume location record */
120 vlocation = afs_vlocation_lookup(cell, volname, volnamesz); 56 vlocation = afs_vlocation_lookup(params->cell, params->key,
57 params->volname, params->volnamesz);
121 if (IS_ERR(vlocation)) { 58 if (IS_ERR(vlocation)) {
122 ret = PTR_ERR(vlocation); 59 ret = PTR_ERR(vlocation);
123 vlocation = NULL; 60 vlocation = NULL;
@@ -126,30 +63,30 @@ struct afs_volume *afs_volume_lookup(const char *name, struct afs_cell *cell,
126 63
127 /* make the final decision on the type we want */ 64 /* make the final decision on the type we want */
128 ret = -ENOMEDIUM; 65 ret = -ENOMEDIUM;
129 if (force && !(vlocation->vldb.vidmask & (1 << type))) 66 if (params->force && !(vlocation->vldb.vidmask & (1 << params->type)))
130 goto error; 67 goto error;
131 68
132 srvtmask = 0; 69 srvtmask = 0;
133 for (loop = 0; loop < vlocation->vldb.nservers; loop++) 70 for (loop = 0; loop < vlocation->vldb.nservers; loop++)
134 srvtmask |= vlocation->vldb.srvtmask[loop]; 71 srvtmask |= vlocation->vldb.srvtmask[loop];
135 72
136 if (force) { 73 if (params->force) {
137 if (!(srvtmask & (1 << type))) 74 if (!(srvtmask & (1 << params->type)))
138 goto error; 75 goto error;
139 } else if (srvtmask & AFS_VOL_VTM_RO) { 76 } else if (srvtmask & AFS_VOL_VTM_RO) {
140 type = AFSVL_ROVOL; 77 params->type = AFSVL_ROVOL;
141 } else if (srvtmask & AFS_VOL_VTM_RW) { 78 } else if (srvtmask & AFS_VOL_VTM_RW) {
142 type = AFSVL_RWVOL; 79 params->type = AFSVL_RWVOL;
143 } else { 80 } else {
144 goto error; 81 goto error;
145 } 82 }
146 83
147 down_write(&cell->vl_sem); 84 down_write(&params->cell->vl_sem);
148 85
149 /* is the volume already active? */ 86 /* is the volume already active? */
150 if (vlocation->vols[type]) { 87 if (vlocation->vols[params->type]) {
151 /* yes - re-use it */ 88 /* yes - re-use it */
152 volume = vlocation->vols[type]; 89 volume = vlocation->vols[params->type];
153 afs_get_volume(volume); 90 afs_get_volume(volume);
154 goto success; 91 goto success;
155 } 92 }
@@ -163,10 +100,10 @@ struct afs_volume *afs_volume_lookup(const char *name, struct afs_cell *cell,
163 goto error_up; 100 goto error_up;
164 101
165 atomic_set(&volume->usage, 1); 102 atomic_set(&volume->usage, 1);
166 volume->type = type; 103 volume->type = params->type;
167 volume->type_force = force; 104 volume->type_force = params->force;
168 volume->cell = cell; 105 volume->cell = params->cell;
169 volume->vid = vlocation->vldb.vid[type]; 106 volume->vid = vlocation->vldb.vid[params->type];
170 107
171 init_rwsem(&volume->server_sem); 108 init_rwsem(&volume->server_sem);
172 109
@@ -196,28 +133,26 @@ struct afs_volume *afs_volume_lookup(const char *name, struct afs_cell *cell,
196 afs_get_vlocation(vlocation); 133 afs_get_vlocation(vlocation);
197 volume->vlocation = vlocation; 134 volume->vlocation = vlocation;
198 135
199 vlocation->vols[type] = volume; 136 vlocation->vols[volume->type] = volume;
200 137
201success: 138success:
202 _debug("kAFS selected %s volume %08x", 139 _debug("kAFS selected %s volume %08x",
203 afs_voltypes[volume->type], volume->vid); 140 afs_voltypes[volume->type], volume->vid);
204 up_write(&cell->vl_sem); 141 up_write(&params->cell->vl_sem);
205 afs_put_vlocation(vlocation); 142 afs_put_vlocation(vlocation);
206 afs_put_cell(cell);
207 _leave(" = %p", volume); 143 _leave(" = %p", volume);
208 return volume; 144 return volume;
209 145
210 /* clean up */ 146 /* clean up */
211error_up: 147error_up:
212 up_write(&cell->vl_sem); 148 up_write(&params->cell->vl_sem);
213error: 149error:
214 afs_put_vlocation(vlocation); 150 afs_put_vlocation(vlocation);
215 afs_put_cell(cell);
216 _leave(" = %d", ret); 151 _leave(" = %d", ret);
217 return ERR_PTR(ret); 152 return ERR_PTR(ret);
218 153
219error_discard: 154error_discard:
220 up_write(&cell->vl_sem); 155 up_write(&params->cell->vl_sem);
221 156
222 for (loop = volume->nservers - 1; loop >= 0; loop--) 157 for (loop = volume->nservers - 1; loop >= 0; loop--)
223 afs_put_server(volume->servers[loop]); 158 afs_put_server(volume->servers[loop]);