diff options
author | David Howells <dhowells@redhat.com> | 2007-04-26 18:57:07 -0400 |
---|---|---|
committer | David S. Miller <davem@davemloft.net> | 2007-04-26 18:57:07 -0400 |
commit | 00d3b7a4533e367b0dc2812a706db8f9f071c27f (patch) | |
tree | f0b1ae0266267cb2c54cb11aa61ad0758ce9c0f5 /fs/afs/volume.c | |
parent | 436058a49e0fb91c74454dbee9cfee6fb53b4336 (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.c | 109 |
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 | */ |
44 | struct afs_volume *afs_volume_lookup(const char *name, struct afs_cell *cell, | 44 | struct 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(¶ms->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 | ||
201 | success: | 138 | success: |
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(¶ms->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 */ |
211 | error_up: | 147 | error_up: |
212 | up_write(&cell->vl_sem); | 148 | up_write(¶ms->cell->vl_sem); |
213 | error: | 149 | error: |
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 | ||
219 | error_discard: | 154 | error_discard: |
220 | up_write(&cell->vl_sem); | 155 | up_write(¶ms->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]); |