aboutsummaryrefslogtreecommitdiffstats
path: root/fs/9p/v9fs.c
diff options
context:
space:
mode:
authorLatchesar Ionkov <lucho@ionkov.net>2007-10-17 15:31:07 -0400
committerEric Van Hensbergen <ericvh@ericvh-desktop.austin.ibm.com>2007-10-17 15:31:07 -0400
commitba17674fe02909fef049fd4b620a2805bdb8c693 (patch)
treefaa05f8705324ac0b70031dbfb08b65b1339391a /fs/9p/v9fs.c
parentbd32b82df9876af439f1760a599c0e2da9198bda (diff)
9p: attach-per-user
The 9P2000 protocol requires the authentication and permission checks to be done in the file server. For that reason every user that accesses the file server tree has to authenticate and attach to the server separately. Multiple users can share the same connection to the server. Currently v9fs does a single attach and executes all I/O operations as a single user. This makes using v9fs in multiuser environment unsafe as it depends on the client doing the permission checking. This patch improves the 9P2000 support by allowing every user to attach separately. The patch defines three modes of access (new mount option 'access'): - attach-per-user (access=user) (default mode for 9P2000.u) If a user tries to access a file served by v9fs for the first time, v9fs sends an attach command to the server (Tattach) specifying the user. If the attach succeeds, the user can access the v9fs tree. As there is no uname->uid (string->integer) mapping yet, this mode works only with the 9P2000.u dialect. - allow only one user to access the tree (access=<uid>) Only the user with uid can access the v9fs tree. Other users that attempt to access it will get EPERM error. - do all operations as a single user (access=any) (default for 9P2000) V9fs does a single attach and all operations are done as a single user. If this mode is selected, the v9fs behavior is identical with the current one. Signed-off-by: Latchesar Ionkov <lucho@ionkov.net> Signed-off-by: Eric Van Hensbergen <ericvh@gmail.com>
Diffstat (limited to 'fs/9p/v9fs.c')
-rw-r--r--fs/9p/v9fs.c67
1 files changed, 52 insertions, 15 deletions
diff --git a/fs/9p/v9fs.c b/fs/9p/v9fs.c
index 68f82be3bf37..89ee0bace41d 100644
--- a/fs/9p/v9fs.c
+++ b/fs/9p/v9fs.c
@@ -91,6 +91,8 @@ enum {
91 Opt_legacy, Opt_nodevmap, 91 Opt_legacy, Opt_nodevmap,
92 /* Cache options */ 92 /* Cache options */
93 Opt_cache_loose, 93 Opt_cache_loose,
94 /* Access options */
95 Opt_access,
94 /* Error token */ 96 /* Error token */
95 Opt_err 97 Opt_err
96}; 98};
@@ -108,6 +110,7 @@ static match_table_t tokens = {
108 {Opt_nodevmap, "nodevmap"}, 110 {Opt_nodevmap, "nodevmap"},
109 {Opt_cache_loose, "cache=loose"}, 111 {Opt_cache_loose, "cache=loose"},
110 {Opt_cache_loose, "loose"}, 112 {Opt_cache_loose, "loose"},
113 {Opt_access, "access=%s"},
111 {Opt_err, NULL} 114 {Opt_err, NULL}
112}; 115};
113 116
@@ -125,10 +128,10 @@ static void v9fs_parse_options(struct v9fs_session_info *v9ses)
125 char *p; 128 char *p;
126 int option; 129 int option;
127 int ret; 130 int ret;
131 char *s, *e;
128 132
129 /* setup defaults */ 133 /* setup defaults */
130 v9ses->maxdata = 8192; 134 v9ses->maxdata = 8192;
131 v9ses->flags = V9FS_EXTENDED;
132 v9ses->afid = ~0; 135 v9ses->afid = ~0;
133 v9ses->debug = 0; 136 v9ses->debug = 0;
134 v9ses->cache = 0; 137 v9ses->cache = 0;
@@ -172,10 +175,10 @@ static void v9fs_parse_options(struct v9fs_session_info *v9ses)
172 v9ses->trans = v9fs_match_trans(&args[0]); 175 v9ses->trans = v9fs_match_trans(&args[0]);
173 break; 176 break;
174 case Opt_uname: 177 case Opt_uname:
175 match_strcpy(v9ses->name, &args[0]); 178 match_strcpy(v9ses->uname, &args[0]);
176 break; 179 break;
177 case Opt_remotename: 180 case Opt_remotename:
178 match_strcpy(v9ses->remotename, &args[0]); 181 match_strcpy(v9ses->aname, &args[0]);
179 break; 182 break;
180 case Opt_legacy: 183 case Opt_legacy:
181 v9ses->flags &= ~V9FS_EXTENDED; 184 v9ses->flags &= ~V9FS_EXTENDED;
@@ -186,6 +189,22 @@ static void v9fs_parse_options(struct v9fs_session_info *v9ses)
186 case Opt_cache_loose: 189 case Opt_cache_loose:
187 v9ses->cache = CACHE_LOOSE; 190 v9ses->cache = CACHE_LOOSE;
188 break; 191 break;
192
193 case Opt_access:
194 s = match_strdup(&args[0]);
195 v9ses->flags &= ~V9FS_ACCESS_MASK;
196 if (strcmp(s, "user") == 0)
197 v9ses->flags |= V9FS_ACCESS_USER;
198 else if (strcmp(s, "any") == 0)
199 v9ses->flags |= V9FS_ACCESS_ANY;
200 else {
201 v9ses->flags |= V9FS_ACCESS_SINGLE;
202 v9ses->uid = simple_strtol(s, &e, 10);
203 if (*e != '\0')
204 v9ses->uid = ~0;
205 }
206 break;
207
189 default: 208 default:
190 continue; 209 continue;
191 } 210 }
@@ -207,21 +226,22 @@ struct p9_fid *v9fs_session_init(struct v9fs_session_info *v9ses,
207 struct p9_trans *trans = NULL; 226 struct p9_trans *trans = NULL;
208 struct p9_fid *fid; 227 struct p9_fid *fid;
209 228
210 v9ses->name = __getname(); 229 v9ses->uname = __getname();
211 if (!v9ses->name) 230 if (!v9ses->uname)
212 return ERR_PTR(-ENOMEM); 231 return ERR_PTR(-ENOMEM);
213 232
214 v9ses->remotename = __getname(); 233 v9ses->aname = __getname();
215 if (!v9ses->remotename) { 234 if (!v9ses->aname) {
216 __putname(v9ses->name); 235 __putname(v9ses->uname);
217 return ERR_PTR(-ENOMEM); 236 return ERR_PTR(-ENOMEM);
218 } 237 }
219 238
220 strcpy(v9ses->name, V9FS_DEFUSER); 239 v9ses->flags = V9FS_EXTENDED | V9FS_ACCESS_USER;
221 strcpy(v9ses->remotename, V9FS_DEFANAME); 240 strcpy(v9ses->uname, V9FS_DEFUSER);
241 strcpy(v9ses->aname, V9FS_DEFANAME);
242 v9ses->uid = ~0;
222 v9ses->dfltuid = V9FS_DEFUID; 243 v9ses->dfltuid = V9FS_DEFUID;
223 v9ses->dfltgid = V9FS_DEFGID; 244 v9ses->dfltgid = V9FS_DEFGID;
224
225 v9ses->options = kstrdup(data, GFP_KERNEL); 245 v9ses->options = kstrdup(data, GFP_KERNEL);
226 v9fs_parse_options(v9ses); 246 v9fs_parse_options(v9ses);
227 247
@@ -255,8 +275,20 @@ struct p9_fid *v9fs_session_init(struct v9fs_session_info *v9ses,
255 goto error; 275 goto error;
256 } 276 }
257 277
258 fid = p9_client_attach(v9ses->clnt, NULL, v9ses->name, 278 if (!v9ses->clnt->dotu)
259 v9ses->remotename); 279 v9ses->flags &= ~V9FS_EXTENDED;
280
281 /* for legacy mode, fall back to V9FS_ACCESS_ANY */
282 if (!v9fs_extended(v9ses) &&
283 ((v9ses->flags&V9FS_ACCESS_MASK) == V9FS_ACCESS_USER)) {
284
285 v9ses->flags &= ~V9FS_ACCESS_MASK;
286 v9ses->flags |= V9FS_ACCESS_ANY;
287 v9ses->uid = ~0;
288 }
289
290 fid = p9_client_attach(v9ses->clnt, NULL, v9ses->uname, ~0,
291 v9ses->aname);
260 if (IS_ERR(fid)) { 292 if (IS_ERR(fid)) {
261 retval = PTR_ERR(fid); 293 retval = PTR_ERR(fid);
262 fid = NULL; 294 fid = NULL;
@@ -264,6 +296,11 @@ struct p9_fid *v9fs_session_init(struct v9fs_session_info *v9ses,
264 goto error; 296 goto error;
265 } 297 }
266 298
299 if ((v9ses->flags & V9FS_ACCESS_MASK) == V9FS_ACCESS_SINGLE)
300 fid->uid = v9ses->uid;
301 else
302 fid->uid = ~0;
303
267 return fid; 304 return fid;
268 305
269error: 306error:
@@ -284,8 +321,8 @@ void v9fs_session_close(struct v9fs_session_info *v9ses)
284 v9ses->clnt = NULL; 321 v9ses->clnt = NULL;
285 } 322 }
286 323
287 __putname(v9ses->name); 324 __putname(v9ses->uname);
288 __putname(v9ses->remotename); 325 __putname(v9ses->aname);
289 kfree(v9ses->options); 326 kfree(v9ses->options);
290} 327}
291 328