• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  *  inode.c
3  *
4  *  Copyright (C) 1995, 1996 by Volker Lendecke
5  *  Modified for big endian by J.F. Chadima and David S. Miller
6  *  Modified 1997 Peter Waltenberg, Bill Hawes, David Woodhouse for 2.1 dcache
7  *  Modified 1998 Wolfram Pienkoss for NLS
8  *  Modified 2000 Ben Harris, University of Cambridge for NFS NS meta-info
9  *
10  */
11 
12 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
13 
14 #include <linux/module.h>
15 
16 #include <asm/uaccess.h>
17 #include <asm/byteorder.h>
18 
19 #include <linux/time.h>
20 #include <linux/kernel.h>
21 #include <linux/mm.h>
22 #include <linux/string.h>
23 #include <linux/stat.h>
24 #include <linux/errno.h>
25 #include <linux/file.h>
26 #include <linux/fcntl.h>
27 #include <linux/slab.h>
28 #include <linux/vmalloc.h>
29 #include <linux/init.h>
30 #include <linux/vfs.h>
31 #include <linux/mount.h>
32 #include <linux/seq_file.h>
33 #include <linux/namei.h>
34 
35 #include <net/sock.h>
36 
37 #include "ncp_fs.h"
38 #include "getopt.h"
39 
40 #define NCP_DEFAULT_FILE_MODE 0600
41 #define NCP_DEFAULT_DIR_MODE 0700
42 #define NCP_DEFAULT_TIME_OUT 10
43 #define NCP_DEFAULT_RETRY_COUNT 20
44 
45 static void ncp_evict_inode(struct inode *);
46 static void ncp_put_super(struct super_block *);
47 static int  ncp_statfs(struct dentry *, struct kstatfs *);
48 static int  ncp_show_options(struct seq_file *, struct dentry *);
49 
50 static struct kmem_cache * ncp_inode_cachep;
51 
ncp_alloc_inode(struct super_block * sb)52 static struct inode *ncp_alloc_inode(struct super_block *sb)
53 {
54 	struct ncp_inode_info *ei;
55 	ei = (struct ncp_inode_info *)kmem_cache_alloc(ncp_inode_cachep, GFP_KERNEL);
56 	if (!ei)
57 		return NULL;
58 	return &ei->vfs_inode;
59 }
60 
ncp_i_callback(struct rcu_head * head)61 static void ncp_i_callback(struct rcu_head *head)
62 {
63 	struct inode *inode = container_of(head, struct inode, i_rcu);
64 	kmem_cache_free(ncp_inode_cachep, NCP_FINFO(inode));
65 }
66 
ncp_destroy_inode(struct inode * inode)67 static void ncp_destroy_inode(struct inode *inode)
68 {
69 	call_rcu(&inode->i_rcu, ncp_i_callback);
70 }
71 
init_once(void * foo)72 static void init_once(void *foo)
73 {
74 	struct ncp_inode_info *ei = (struct ncp_inode_info *) foo;
75 
76 	mutex_init(&ei->open_mutex);
77 	inode_init_once(&ei->vfs_inode);
78 }
79 
init_inodecache(void)80 static int init_inodecache(void)
81 {
82 	ncp_inode_cachep = kmem_cache_create("ncp_inode_cache",
83 					     sizeof(struct ncp_inode_info),
84 					     0, (SLAB_RECLAIM_ACCOUNT|
85 						SLAB_MEM_SPREAD|SLAB_ACCOUNT),
86 					     init_once);
87 	if (ncp_inode_cachep == NULL)
88 		return -ENOMEM;
89 	return 0;
90 }
91 
destroy_inodecache(void)92 static void destroy_inodecache(void)
93 {
94 	/*
95 	 * Make sure all delayed rcu free inodes are flushed before we
96 	 * destroy cache.
97 	 */
98 	rcu_barrier();
99 	kmem_cache_destroy(ncp_inode_cachep);
100 }
101 
ncp_remount(struct super_block * sb,int * flags,char * data)102 static int ncp_remount(struct super_block *sb, int *flags, char* data)
103 {
104 	sync_filesystem(sb);
105 	*flags |= MS_NODIRATIME;
106 	return 0;
107 }
108 
109 static const struct super_operations ncp_sops =
110 {
111 	.alloc_inode	= ncp_alloc_inode,
112 	.destroy_inode	= ncp_destroy_inode,
113 	.drop_inode	= generic_delete_inode,
114 	.evict_inode	= ncp_evict_inode,
115 	.put_super	= ncp_put_super,
116 	.statfs		= ncp_statfs,
117 	.remount_fs	= ncp_remount,
118 	.show_options	= ncp_show_options,
119 };
120 
121 /*
122  * Fill in the ncpfs-specific information in the inode.
123  */
ncp_update_dirent(struct inode * inode,struct ncp_entry_info * nwinfo)124 static void ncp_update_dirent(struct inode *inode, struct ncp_entry_info *nwinfo)
125 {
126 	NCP_FINFO(inode)->DosDirNum = nwinfo->i.DosDirNum;
127 	NCP_FINFO(inode)->dirEntNum = nwinfo->i.dirEntNum;
128 	NCP_FINFO(inode)->volNumber = nwinfo->volume;
129 }
130 
ncp_update_inode(struct inode * inode,struct ncp_entry_info * nwinfo)131 void ncp_update_inode(struct inode *inode, struct ncp_entry_info *nwinfo)
132 {
133 	ncp_update_dirent(inode, nwinfo);
134 	NCP_FINFO(inode)->nwattr = nwinfo->i.attributes;
135 	NCP_FINFO(inode)->access = nwinfo->access;
136 	memcpy(NCP_FINFO(inode)->file_handle, nwinfo->file_handle,
137 			sizeof(nwinfo->file_handle));
138 	ncp_dbg(1, "updated %s, volnum=%d, dirent=%u\n",
139 		nwinfo->i.entryName, NCP_FINFO(inode)->volNumber,
140 		NCP_FINFO(inode)->dirEntNum);
141 }
142 
ncp_update_dates(struct inode * inode,struct nw_info_struct * nwi)143 static void ncp_update_dates(struct inode *inode, struct nw_info_struct *nwi)
144 {
145 	/* NFS namespace mode overrides others if it's set. */
146 	ncp_dbg(1, "(%s) nfs.mode=0%o\n", nwi->entryName, nwi->nfs.mode);
147 	if (nwi->nfs.mode) {
148 		/* XXX Security? */
149 		inode->i_mode = nwi->nfs.mode;
150 	}
151 
152 	inode->i_blocks = (i_size_read(inode) + NCP_BLOCK_SIZE - 1) >> NCP_BLOCK_SHIFT;
153 
154 	inode->i_mtime.tv_sec = ncp_date_dos2unix(nwi->modifyTime, nwi->modifyDate);
155 	inode->i_ctime.tv_sec = ncp_date_dos2unix(nwi->creationTime, nwi->creationDate);
156 	inode->i_atime.tv_sec = ncp_date_dos2unix(0, nwi->lastAccessDate);
157 	inode->i_atime.tv_nsec = 0;
158 	inode->i_mtime.tv_nsec = 0;
159 	inode->i_ctime.tv_nsec = 0;
160 }
161 
ncp_update_attrs(struct inode * inode,struct ncp_entry_info * nwinfo)162 static void ncp_update_attrs(struct inode *inode, struct ncp_entry_info *nwinfo)
163 {
164 	struct nw_info_struct *nwi = &nwinfo->i;
165 	struct ncp_server *server = NCP_SERVER(inode);
166 
167 	if (nwi->attributes & aDIR) {
168 		inode->i_mode = server->m.dir_mode;
169 		/* for directories dataStreamSize seems to be some
170 		   Object ID ??? */
171 		i_size_write(inode, NCP_BLOCK_SIZE);
172 	} else {
173 		u32 size;
174 
175 		inode->i_mode = server->m.file_mode;
176 		size = le32_to_cpu(nwi->dataStreamSize);
177 		i_size_write(inode, size);
178 #ifdef CONFIG_NCPFS_EXTRAS
179 		if ((server->m.flags & (NCP_MOUNT_EXTRAS|NCP_MOUNT_SYMLINKS))
180 		 && (nwi->attributes & aSHARED)) {
181 			switch (nwi->attributes & (aHIDDEN|aSYSTEM)) {
182 				case aHIDDEN:
183 					if (server->m.flags & NCP_MOUNT_SYMLINKS) {
184 						if (/* (size >= NCP_MIN_SYMLINK_SIZE)
185 						 && */ (size <= NCP_MAX_SYMLINK_SIZE)) {
186 							inode->i_mode = (inode->i_mode & ~S_IFMT) | S_IFLNK;
187 							NCP_FINFO(inode)->flags |= NCPI_KLUDGE_SYMLINK;
188 							break;
189 						}
190 					}
191 					/* FALLTHROUGH */
192 				case 0:
193 					if (server->m.flags & NCP_MOUNT_EXTRAS)
194 						inode->i_mode |= S_IRUGO;
195 					break;
196 				case aSYSTEM:
197 					if (server->m.flags & NCP_MOUNT_EXTRAS)
198 						inode->i_mode |= (inode->i_mode >> 2) & S_IXUGO;
199 					break;
200 				/* case aSYSTEM|aHIDDEN: */
201 				default:
202 					/* reserved combination */
203 					break;
204 			}
205 		}
206 #endif
207 	}
208 	if (nwi->attributes & aRONLY) inode->i_mode &= ~S_IWUGO;
209 }
210 
ncp_update_inode2(struct inode * inode,struct ncp_entry_info * nwinfo)211 void ncp_update_inode2(struct inode* inode, struct ncp_entry_info *nwinfo)
212 {
213 	NCP_FINFO(inode)->flags = 0;
214 	if (!atomic_read(&NCP_FINFO(inode)->opened)) {
215 		NCP_FINFO(inode)->nwattr = nwinfo->i.attributes;
216 		ncp_update_attrs(inode, nwinfo);
217 	}
218 
219 	ncp_update_dates(inode, &nwinfo->i);
220 	ncp_update_dirent(inode, nwinfo);
221 }
222 
223 /*
224  * Fill in the inode based on the ncp_entry_info structure.  Used only for brand new inodes.
225  */
ncp_set_attr(struct inode * inode,struct ncp_entry_info * nwinfo)226 static void ncp_set_attr(struct inode *inode, struct ncp_entry_info *nwinfo)
227 {
228 	struct ncp_server *server = NCP_SERVER(inode);
229 
230 	NCP_FINFO(inode)->flags = 0;
231 
232 	ncp_update_attrs(inode, nwinfo);
233 
234 	ncp_dbg(2, "inode->i_mode = %u\n", inode->i_mode);
235 
236 	set_nlink(inode, 1);
237 	inode->i_uid = server->m.uid;
238 	inode->i_gid = server->m.gid;
239 
240 	ncp_update_dates(inode, &nwinfo->i);
241 	ncp_update_inode(inode, nwinfo);
242 }
243 
244 #if defined(CONFIG_NCPFS_EXTRAS) || defined(CONFIG_NCPFS_NFS_NS)
245 static const struct inode_operations ncp_symlink_inode_operations = {
246 	.readlink	= generic_readlink,
247 	.get_link	= page_get_link,
248 	.setattr	= ncp_notify_change,
249 };
250 #endif
251 
252 /*
253  * Get a new inode.
254  */
255 struct inode *
ncp_iget(struct super_block * sb,struct ncp_entry_info * info)256 ncp_iget(struct super_block *sb, struct ncp_entry_info *info)
257 {
258 	struct inode *inode;
259 
260 	if (info == NULL) {
261 		pr_err("%s: info is NULL\n", __func__);
262 		return NULL;
263 	}
264 
265 	inode = new_inode(sb);
266 	if (inode) {
267 		atomic_set(&NCP_FINFO(inode)->opened, info->opened);
268 
269 		inode->i_ino = info->ino;
270 		ncp_set_attr(inode, info);
271 		if (S_ISREG(inode->i_mode)) {
272 			inode->i_op = &ncp_file_inode_operations;
273 			inode->i_fop = &ncp_file_operations;
274 		} else if (S_ISDIR(inode->i_mode)) {
275 			inode->i_op = &ncp_dir_inode_operations;
276 			inode->i_fop = &ncp_dir_operations;
277 #ifdef CONFIG_NCPFS_NFS_NS
278 		} else if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode) || S_ISFIFO(inode->i_mode) || S_ISSOCK(inode->i_mode)) {
279 			init_special_inode(inode, inode->i_mode,
280 				new_decode_dev(info->i.nfs.rdev));
281 #endif
282 #if defined(CONFIG_NCPFS_EXTRAS) || defined(CONFIG_NCPFS_NFS_NS)
283 		} else if (S_ISLNK(inode->i_mode)) {
284 			inode->i_op = &ncp_symlink_inode_operations;
285 			inode_nohighmem(inode);
286 			inode->i_data.a_ops = &ncp_symlink_aops;
287 #endif
288 		} else {
289 			make_bad_inode(inode);
290 		}
291 		insert_inode_hash(inode);
292 	} else
293 		pr_err("%s: iget failed!\n", __func__);
294 	return inode;
295 }
296 
297 static void
ncp_evict_inode(struct inode * inode)298 ncp_evict_inode(struct inode *inode)
299 {
300 	truncate_inode_pages_final(&inode->i_data);
301 	clear_inode(inode);
302 
303 	if (S_ISDIR(inode->i_mode)) {
304 		ncp_dbg(2, "put directory %ld\n", inode->i_ino);
305 	}
306 
307 	if (ncp_make_closed(inode) != 0) {
308 		/* We can't do anything but complain. */
309 		pr_err("%s: could not close\n", __func__);
310 	}
311 }
312 
ncp_stop_tasks(struct ncp_server * server)313 static void ncp_stop_tasks(struct ncp_server *server) {
314 	struct sock* sk = server->ncp_sock->sk;
315 
316 	lock_sock(sk);
317 	sk->sk_error_report = server->error_report;
318 	sk->sk_data_ready   = server->data_ready;
319 	sk->sk_write_space  = server->write_space;
320 	release_sock(sk);
321 	del_timer_sync(&server->timeout_tm);
322 
323 	flush_work(&server->rcv.tq);
324 	if (sk->sk_socket->type == SOCK_STREAM)
325 		flush_work(&server->tx.tq);
326 	else
327 		flush_work(&server->timeout_tq);
328 }
329 
ncp_show_options(struct seq_file * seq,struct dentry * root)330 static int  ncp_show_options(struct seq_file *seq, struct dentry *root)
331 {
332 	struct ncp_server *server = NCP_SBP(root->d_sb);
333 	unsigned int tmp;
334 
335 	if (!uid_eq(server->m.uid, GLOBAL_ROOT_UID))
336 		seq_printf(seq, ",uid=%u",
337 			   from_kuid_munged(&init_user_ns, server->m.uid));
338 	if (!gid_eq(server->m.gid, GLOBAL_ROOT_GID))
339 		seq_printf(seq, ",gid=%u",
340 			   from_kgid_munged(&init_user_ns, server->m.gid));
341 	if (!uid_eq(server->m.mounted_uid, GLOBAL_ROOT_UID))
342 		seq_printf(seq, ",owner=%u",
343 			   from_kuid_munged(&init_user_ns, server->m.mounted_uid));
344 	tmp = server->m.file_mode & S_IALLUGO;
345 	if (tmp != NCP_DEFAULT_FILE_MODE)
346 		seq_printf(seq, ",mode=0%o", tmp);
347 	tmp = server->m.dir_mode & S_IALLUGO;
348 	if (tmp != NCP_DEFAULT_DIR_MODE)
349 		seq_printf(seq, ",dirmode=0%o", tmp);
350 	if (server->m.time_out != NCP_DEFAULT_TIME_OUT * HZ / 100) {
351 		tmp = server->m.time_out * 100 / HZ;
352 		seq_printf(seq, ",timeout=%u", tmp);
353 	}
354 	if (server->m.retry_count != NCP_DEFAULT_RETRY_COUNT)
355 		seq_printf(seq, ",retry=%u", server->m.retry_count);
356 	if (server->m.flags != 0)
357 		seq_printf(seq, ",flags=%lu", server->m.flags);
358 	if (server->m.wdog_pid != NULL)
359 		seq_printf(seq, ",wdogpid=%u", pid_vnr(server->m.wdog_pid));
360 
361 	return 0;
362 }
363 
364 static const struct ncp_option ncp_opts[] = {
365 	{ "uid",	OPT_INT,	'u' },
366 	{ "gid",	OPT_INT,	'g' },
367 	{ "owner",	OPT_INT,	'o' },
368 	{ "mode",	OPT_INT,	'm' },
369 	{ "dirmode",	OPT_INT,	'd' },
370 	{ "timeout",	OPT_INT,	't' },
371 	{ "retry",	OPT_INT,	'r' },
372 	{ "flags",	OPT_INT,	'f' },
373 	{ "wdogpid",	OPT_INT,	'w' },
374 	{ "ncpfd",	OPT_INT,	'n' },
375 	{ "infofd",	OPT_INT,	'i' },	/* v5 */
376 	{ "version",	OPT_INT,	'v' },
377 	{ NULL,		0,		0 } };
378 
ncp_parse_options(struct ncp_mount_data_kernel * data,char * options)379 static int ncp_parse_options(struct ncp_mount_data_kernel *data, char *options) {
380 	int optval;
381 	char *optarg;
382 	unsigned long optint;
383 	int version = 0;
384 	int ret;
385 
386 	data->flags = 0;
387 	data->int_flags = 0;
388 	data->mounted_uid = GLOBAL_ROOT_UID;
389 	data->wdog_pid = NULL;
390 	data->ncp_fd = ~0;
391 	data->time_out = NCP_DEFAULT_TIME_OUT;
392 	data->retry_count = NCP_DEFAULT_RETRY_COUNT;
393 	data->uid = GLOBAL_ROOT_UID;
394 	data->gid = GLOBAL_ROOT_GID;
395 	data->file_mode = NCP_DEFAULT_FILE_MODE;
396 	data->dir_mode = NCP_DEFAULT_DIR_MODE;
397 	data->info_fd = -1;
398 	data->mounted_vol[0] = 0;
399 
400 	while ((optval = ncp_getopt("ncpfs", &options, ncp_opts, NULL, &optarg, &optint)) != 0) {
401 		ret = optval;
402 		if (ret < 0)
403 			goto err;
404 		switch (optval) {
405 			case 'u':
406 				data->uid = make_kuid(current_user_ns(), optint);
407 				if (!uid_valid(data->uid)) {
408 					ret = -EINVAL;
409 					goto err;
410 				}
411 				break;
412 			case 'g':
413 				data->gid = make_kgid(current_user_ns(), optint);
414 				if (!gid_valid(data->gid)) {
415 					ret = -EINVAL;
416 					goto err;
417 				}
418 				break;
419 			case 'o':
420 				data->mounted_uid = make_kuid(current_user_ns(), optint);
421 				if (!uid_valid(data->mounted_uid)) {
422 					ret = -EINVAL;
423 					goto err;
424 				}
425 				break;
426 			case 'm':
427 				data->file_mode = optint;
428 				break;
429 			case 'd':
430 				data->dir_mode = optint;
431 				break;
432 			case 't':
433 				data->time_out = optint;
434 				break;
435 			case 'r':
436 				data->retry_count = optint;
437 				break;
438 			case 'f':
439 				data->flags = optint;
440 				break;
441 			case 'w':
442 				data->wdog_pid = find_get_pid(optint);
443 				break;
444 			case 'n':
445 				data->ncp_fd = optint;
446 				break;
447 			case 'i':
448 				data->info_fd = optint;
449 				break;
450 			case 'v':
451 				ret = -ECHRNG;
452 				if (optint < NCP_MOUNT_VERSION_V4)
453 					goto err;
454 				if (optint > NCP_MOUNT_VERSION_V5)
455 					goto err;
456 				version = optint;
457 				break;
458 
459 		}
460 	}
461 	return 0;
462 err:
463 	put_pid(data->wdog_pid);
464 	data->wdog_pid = NULL;
465 	return ret;
466 }
467 
ncp_fill_super(struct super_block * sb,void * raw_data,int silent)468 static int ncp_fill_super(struct super_block *sb, void *raw_data, int silent)
469 {
470 	struct ncp_mount_data_kernel data;
471 	struct ncp_server *server;
472 	struct inode *root_inode;
473 	struct socket *sock;
474 	int error;
475 	int default_bufsize;
476 #ifdef CONFIG_NCPFS_PACKET_SIGNING
477 	int options;
478 #endif
479 	struct ncp_entry_info finfo;
480 
481 	memset(&data, 0, sizeof(data));
482 	server = kzalloc(sizeof(struct ncp_server), GFP_KERNEL);
483 	if (!server)
484 		return -ENOMEM;
485 	sb->s_fs_info = server;
486 
487 	error = -EFAULT;
488 	if (raw_data == NULL)
489 		goto out;
490 	switch (*(int*)raw_data) {
491 		case NCP_MOUNT_VERSION:
492 			{
493 				struct ncp_mount_data* md = (struct ncp_mount_data*)raw_data;
494 
495 				data.flags = md->flags;
496 				data.int_flags = NCP_IMOUNT_LOGGEDIN_POSSIBLE;
497 				data.mounted_uid = make_kuid(current_user_ns(), md->mounted_uid);
498 				data.wdog_pid = find_get_pid(md->wdog_pid);
499 				data.ncp_fd = md->ncp_fd;
500 				data.time_out = md->time_out;
501 				data.retry_count = md->retry_count;
502 				data.uid = make_kuid(current_user_ns(), md->uid);
503 				data.gid = make_kgid(current_user_ns(), md->gid);
504 				data.file_mode = md->file_mode;
505 				data.dir_mode = md->dir_mode;
506 				data.info_fd = -1;
507 				memcpy(data.mounted_vol, md->mounted_vol,
508 					NCP_VOLNAME_LEN+1);
509 			}
510 			break;
511 		case NCP_MOUNT_VERSION_V4:
512 			{
513 				struct ncp_mount_data_v4* md = (struct ncp_mount_data_v4*)raw_data;
514 
515 				data.flags = md->flags;
516 				data.mounted_uid = make_kuid(current_user_ns(), md->mounted_uid);
517 				data.wdog_pid = find_get_pid(md->wdog_pid);
518 				data.ncp_fd = md->ncp_fd;
519 				data.time_out = md->time_out;
520 				data.retry_count = md->retry_count;
521 				data.uid = make_kuid(current_user_ns(), md->uid);
522 				data.gid = make_kgid(current_user_ns(), md->gid);
523 				data.file_mode = md->file_mode;
524 				data.dir_mode = md->dir_mode;
525 				data.info_fd = -1;
526 			}
527 			break;
528 		default:
529 			error = -ECHRNG;
530 			if (memcmp(raw_data, "vers", 4) == 0) {
531 				error = ncp_parse_options(&data, raw_data);
532 			}
533 			if (error)
534 				goto out;
535 			break;
536 	}
537 	error = -EINVAL;
538 	if (!uid_valid(data.mounted_uid) || !uid_valid(data.uid) ||
539 	    !gid_valid(data.gid))
540 		goto out;
541 	sock = sockfd_lookup(data.ncp_fd, &error);
542 	if (!sock)
543 		goto out;
544 
545 	if (sock->type == SOCK_STREAM)
546 		default_bufsize = 0xF000;
547 	else
548 		default_bufsize = 1024;
549 
550 	sb->s_flags |= MS_NODIRATIME;	/* probably even noatime */
551 	sb->s_maxbytes = 0xFFFFFFFFU;
552 	sb->s_blocksize = 1024;	/* Eh...  Is this correct? */
553 	sb->s_blocksize_bits = 10;
554 	sb->s_magic = NCP_SUPER_MAGIC;
555 	sb->s_op = &ncp_sops;
556 	sb->s_d_op = &ncp_dentry_operations;
557 	sb->s_bdi = &server->bdi;
558 
559 	server = NCP_SBP(sb);
560 	memset(server, 0, sizeof(*server));
561 
562 	error = bdi_setup_and_register(&server->bdi, "ncpfs");
563 	if (error)
564 		goto out_fput;
565 
566 	server->ncp_sock = sock;
567 
568 	if (data.info_fd != -1) {
569 		struct socket *info_sock = sockfd_lookup(data.info_fd, &error);
570 		if (!info_sock)
571 			goto out_bdi;
572 		server->info_sock = info_sock;
573 		error = -EBADFD;
574 		if (info_sock->type != SOCK_STREAM)
575 			goto out_fput2;
576 	}
577 
578 /*	server->lock = 0;	*/
579 	mutex_init(&server->mutex);
580 	server->packet = NULL;
581 /*	server->buffer_size = 0;	*/
582 /*	server->conn_status = 0;	*/
583 /*	server->root_dentry = NULL;	*/
584 /*	server->root_setuped = 0;	*/
585 	mutex_init(&server->root_setup_lock);
586 #ifdef CONFIG_NCPFS_PACKET_SIGNING
587 /*	server->sign_wanted = 0;	*/
588 /*	server->sign_active = 0;	*/
589 #endif
590 	init_rwsem(&server->auth_rwsem);
591 	server->auth.auth_type = NCP_AUTH_NONE;
592 /*	server->auth.object_name_len = 0;	*/
593 /*	server->auth.object_name = NULL;	*/
594 /*	server->auth.object_type = 0;		*/
595 /*	server->priv.len = 0;			*/
596 /*	server->priv.data = NULL;		*/
597 
598 	server->m = data;
599 	/* Although anything producing this is buggy, it happens
600 	   now because of PATH_MAX changes.. */
601 	if (server->m.time_out < 1) {
602 		server->m.time_out = 10;
603 		pr_info("You need to recompile your ncpfs utils..\n");
604 	}
605 	server->m.time_out = server->m.time_out * HZ / 100;
606 	server->m.file_mode = (server->m.file_mode & S_IRWXUGO) | S_IFREG;
607 	server->m.dir_mode = (server->m.dir_mode & S_IRWXUGO) | S_IFDIR;
608 
609 #ifdef CONFIG_NCPFS_NLS
610 	/* load the default NLS charsets */
611 	server->nls_vol = load_nls_default();
612 	server->nls_io = load_nls_default();
613 #endif /* CONFIG_NCPFS_NLS */
614 
615 	atomic_set(&server->dentry_ttl, 0);	/* no caching */
616 
617 	INIT_LIST_HEAD(&server->tx.requests);
618 	mutex_init(&server->rcv.creq_mutex);
619 	server->tx.creq		= NULL;
620 	server->rcv.creq	= NULL;
621 
622 	init_timer(&server->timeout_tm);
623 #undef NCP_PACKET_SIZE
624 #define NCP_PACKET_SIZE 131072
625 	error = -ENOMEM;
626 	server->packet_size = NCP_PACKET_SIZE;
627 	server->packet = vmalloc(NCP_PACKET_SIZE);
628 	if (server->packet == NULL)
629 		goto out_nls;
630 	server->txbuf = vmalloc(NCP_PACKET_SIZE);
631 	if (server->txbuf == NULL)
632 		goto out_packet;
633 	server->rxbuf = vmalloc(NCP_PACKET_SIZE);
634 	if (server->rxbuf == NULL)
635 		goto out_txbuf;
636 
637 	lock_sock(sock->sk);
638 	server->data_ready	= sock->sk->sk_data_ready;
639 	server->write_space	= sock->sk->sk_write_space;
640 	server->error_report	= sock->sk->sk_error_report;
641 	sock->sk->sk_user_data	= server;
642 	sock->sk->sk_data_ready	  = ncp_tcp_data_ready;
643 	sock->sk->sk_error_report = ncp_tcp_error_report;
644 	if (sock->type == SOCK_STREAM) {
645 		server->rcv.ptr = (unsigned char*)&server->rcv.buf;
646 		server->rcv.len = 10;
647 		server->rcv.state = 0;
648 		INIT_WORK(&server->rcv.tq, ncp_tcp_rcv_proc);
649 		INIT_WORK(&server->tx.tq, ncp_tcp_tx_proc);
650 		sock->sk->sk_write_space = ncp_tcp_write_space;
651 	} else {
652 		INIT_WORK(&server->rcv.tq, ncpdgram_rcv_proc);
653 		INIT_WORK(&server->timeout_tq, ncpdgram_timeout_proc);
654 		server->timeout_tm.data = (unsigned long)server;
655 		server->timeout_tm.function = ncpdgram_timeout_call;
656 	}
657 	release_sock(sock->sk);
658 
659 	ncp_lock_server(server);
660 	error = ncp_connect(server);
661 	ncp_unlock_server(server);
662 	if (error < 0)
663 		goto out_rxbuf;
664 	ncp_dbg(1, "NCP_SBP(sb) = %p\n", NCP_SBP(sb));
665 
666 	error = -EMSGSIZE;	/* -EREMOTESIDEINCOMPATIBLE */
667 #ifdef CONFIG_NCPFS_PACKET_SIGNING
668 	if (ncp_negotiate_size_and_options(server, default_bufsize,
669 		NCP_DEFAULT_OPTIONS, &(server->buffer_size), &options) == 0)
670 	{
671 		if (options != NCP_DEFAULT_OPTIONS)
672 		{
673 			if (ncp_negotiate_size_and_options(server,
674 				default_bufsize,
675 				options & 2,
676 				&(server->buffer_size), &options) != 0)
677 
678 			{
679 				goto out_disconnect;
680 			}
681 		}
682 		ncp_lock_server(server);
683 		if (options & 2)
684 			server->sign_wanted = 1;
685 		ncp_unlock_server(server);
686 	}
687 	else
688 #endif	/* CONFIG_NCPFS_PACKET_SIGNING */
689 	if (ncp_negotiate_buffersize(server, default_bufsize,
690   				     &(server->buffer_size)) != 0)
691 		goto out_disconnect;
692 	ncp_dbg(1, "bufsize = %d\n", server->buffer_size);
693 
694 	memset(&finfo, 0, sizeof(finfo));
695 	finfo.i.attributes	= aDIR;
696 	finfo.i.dataStreamSize	= 0;	/* ignored */
697 	finfo.i.dirEntNum	= 0;
698 	finfo.i.DosDirNum	= 0;
699 #ifdef CONFIG_NCPFS_SMALLDOS
700 	finfo.i.NSCreator	= NW_NS_DOS;
701 #endif
702 	finfo.volume		= NCP_NUMBER_OF_VOLUMES;
703 	/* set dates of mountpoint to Jan 1, 1986; 00:00 */
704 	finfo.i.creationTime	= finfo.i.modifyTime
705 				= cpu_to_le16(0x0000);
706 	finfo.i.creationDate	= finfo.i.modifyDate
707 				= finfo.i.lastAccessDate
708 				= cpu_to_le16(0x0C21);
709 	finfo.i.nameLen		= 0;
710 	finfo.i.entryName[0]	= '\0';
711 
712 	finfo.opened		= 0;
713 	finfo.ino		= 2;	/* tradition */
714 
715 	server->name_space[finfo.volume] = NW_NS_DOS;
716 
717 	error = -ENOMEM;
718         root_inode = ncp_iget(sb, &finfo);
719         if (!root_inode)
720 		goto out_disconnect;
721 	ncp_dbg(1, "root vol=%d\n", NCP_FINFO(root_inode)->volNumber);
722 	sb->s_root = d_make_root(root_inode);
723         if (!sb->s_root)
724 		goto out_disconnect;
725 	return 0;
726 
727 out_disconnect:
728 	ncp_lock_server(server);
729 	ncp_disconnect(server);
730 	ncp_unlock_server(server);
731 out_rxbuf:
732 	ncp_stop_tasks(server);
733 	vfree(server->rxbuf);
734 out_txbuf:
735 	vfree(server->txbuf);
736 out_packet:
737 	vfree(server->packet);
738 out_nls:
739 #ifdef CONFIG_NCPFS_NLS
740 	unload_nls(server->nls_io);
741 	unload_nls(server->nls_vol);
742 #endif
743 	mutex_destroy(&server->rcv.creq_mutex);
744 	mutex_destroy(&server->root_setup_lock);
745 	mutex_destroy(&server->mutex);
746 out_fput2:
747 	if (server->info_sock)
748 		sockfd_put(server->info_sock);
749 out_bdi:
750 	bdi_destroy(&server->bdi);
751 out_fput:
752 	sockfd_put(sock);
753 out:
754 	put_pid(data.wdog_pid);
755 	sb->s_fs_info = NULL;
756 	kfree(server);
757 	return error;
758 }
759 
delayed_free(struct rcu_head * p)760 static void delayed_free(struct rcu_head *p)
761 {
762 	struct ncp_server *server = container_of(p, struct ncp_server, rcu);
763 #ifdef CONFIG_NCPFS_NLS
764 	/* unload the NLS charsets */
765 	unload_nls(server->nls_vol);
766 	unload_nls(server->nls_io);
767 #endif /* CONFIG_NCPFS_NLS */
768 	kfree(server);
769 }
770 
ncp_put_super(struct super_block * sb)771 static void ncp_put_super(struct super_block *sb)
772 {
773 	struct ncp_server *server = NCP_SBP(sb);
774 
775 	ncp_lock_server(server);
776 	ncp_disconnect(server);
777 	ncp_unlock_server(server);
778 
779 	ncp_stop_tasks(server);
780 
781 	mutex_destroy(&server->rcv.creq_mutex);
782 	mutex_destroy(&server->root_setup_lock);
783 	mutex_destroy(&server->mutex);
784 
785 	if (server->info_sock)
786 		sockfd_put(server->info_sock);
787 	sockfd_put(server->ncp_sock);
788 	kill_pid(server->m.wdog_pid, SIGTERM, 1);
789 	put_pid(server->m.wdog_pid);
790 
791 	bdi_destroy(&server->bdi);
792 	kfree(server->priv.data);
793 	kfree(server->auth.object_name);
794 	vfree(server->rxbuf);
795 	vfree(server->txbuf);
796 	vfree(server->packet);
797 	call_rcu(&server->rcu, delayed_free);
798 }
799 
ncp_statfs(struct dentry * dentry,struct kstatfs * buf)800 static int ncp_statfs(struct dentry *dentry, struct kstatfs *buf)
801 {
802 	struct dentry* d;
803 	struct inode* i;
804 	struct ncp_inode_info* ni;
805 	struct ncp_server* s;
806 	struct ncp_volume_info vi;
807 	struct super_block *sb = dentry->d_sb;
808 	int err;
809 	__u8 dh;
810 
811 	d = sb->s_root;
812 	if (!d) {
813 		goto dflt;
814 	}
815 	i = d_inode(d);
816 	if (!i) {
817 		goto dflt;
818 	}
819 	ni = NCP_FINFO(i);
820 	if (!ni) {
821 		goto dflt;
822 	}
823 	s = NCP_SBP(sb);
824 	if (!s) {
825 		goto dflt;
826 	}
827 	if (!s->m.mounted_vol[0]) {
828 		goto dflt;
829 	}
830 
831 	err = ncp_dirhandle_alloc(s, ni->volNumber, ni->DosDirNum, &dh);
832 	if (err) {
833 		goto dflt;
834 	}
835 	err = ncp_get_directory_info(s, dh, &vi);
836 	ncp_dirhandle_free(s, dh);
837 	if (err) {
838 		goto dflt;
839 	}
840 	buf->f_type = NCP_SUPER_MAGIC;
841 	buf->f_bsize = vi.sectors_per_block * 512;
842 	buf->f_blocks = vi.total_blocks;
843 	buf->f_bfree = vi.free_blocks;
844 	buf->f_bavail = vi.free_blocks;
845 	buf->f_files = vi.total_dir_entries;
846 	buf->f_ffree = vi.available_dir_entries;
847 	buf->f_namelen = 12;
848 	return 0;
849 
850 	/* We cannot say how much disk space is left on a mounted
851 	   NetWare Server, because free space is distributed over
852 	   volumes, and the current user might have disk quotas. So
853 	   free space is not that simple to determine. Our decision
854 	   here is to err conservatively. */
855 
856 dflt:;
857 	buf->f_type = NCP_SUPER_MAGIC;
858 	buf->f_bsize = NCP_BLOCK_SIZE;
859 	buf->f_blocks = 0;
860 	buf->f_bfree = 0;
861 	buf->f_bavail = 0;
862 	buf->f_namelen = 12;
863 	return 0;
864 }
865 
ncp_notify_change(struct dentry * dentry,struct iattr * attr)866 int ncp_notify_change(struct dentry *dentry, struct iattr *attr)
867 {
868 	struct inode *inode = d_inode(dentry);
869 	int result = 0;
870 	__le32 info_mask;
871 	struct nw_modify_dos_info info;
872 	struct ncp_server *server;
873 
874 	result = -EIO;
875 
876 	server = NCP_SERVER(inode);
877 	if (!server)	/* How this could happen? */
878 		goto out;
879 
880 	result = -EPERM;
881 	if (IS_DEADDIR(d_inode(dentry)))
882 		goto out;
883 
884 	/* ageing the dentry to force validation */
885 	ncp_age_dentry(server, dentry);
886 
887 	result = setattr_prepare(dentry, attr);
888 	if (result < 0)
889 		goto out;
890 
891 	result = -EPERM;
892 	if ((attr->ia_valid & ATTR_UID) && !uid_eq(attr->ia_uid, server->m.uid))
893 		goto out;
894 
895 	if ((attr->ia_valid & ATTR_GID) && !gid_eq(attr->ia_gid, server->m.gid))
896 		goto out;
897 
898 	if (((attr->ia_valid & ATTR_MODE) &&
899 	     (attr->ia_mode &
900 	      ~(S_IFREG | S_IFDIR | S_IRWXUGO))))
901 		goto out;
902 
903 	info_mask = 0;
904 	memset(&info, 0, sizeof(info));
905 
906 #if 1
907         if ((attr->ia_valid & ATTR_MODE) != 0)
908         {
909 		umode_t newmode = attr->ia_mode;
910 
911 		info_mask |= DM_ATTRIBUTES;
912 
913                 if (S_ISDIR(inode->i_mode)) {
914                 	newmode &= server->m.dir_mode;
915 		} else {
916 #ifdef CONFIG_NCPFS_EXTRAS
917 			if (server->m.flags & NCP_MOUNT_EXTRAS) {
918 				/* any non-default execute bit set */
919 				if (newmode & ~server->m.file_mode & S_IXUGO)
920 					info.attributes |= aSHARED | aSYSTEM;
921 				/* read for group/world and not in default file_mode */
922 				else if (newmode & ~server->m.file_mode & S_IRUGO)
923 					info.attributes |= aSHARED;
924 			} else
925 #endif
926 				newmode &= server->m.file_mode;
927                 }
928                 if (newmode & S_IWUGO)
929                 	info.attributes &= ~(aRONLY|aRENAMEINHIBIT|aDELETEINHIBIT);
930                 else
931 			info.attributes |=  (aRONLY|aRENAMEINHIBIT|aDELETEINHIBIT);
932 
933 #ifdef CONFIG_NCPFS_NFS_NS
934 		if (ncp_is_nfs_extras(server, NCP_FINFO(inode)->volNumber)) {
935 			result = ncp_modify_nfs_info(server,
936 						     NCP_FINFO(inode)->volNumber,
937 						     NCP_FINFO(inode)->dirEntNum,
938 						     attr->ia_mode, 0);
939 			if (result != 0)
940 				goto out;
941 			info.attributes &= ~(aSHARED | aSYSTEM);
942 			{
943 				/* mark partial success */
944 				struct iattr tmpattr;
945 
946 				tmpattr.ia_valid = ATTR_MODE;
947 				tmpattr.ia_mode = attr->ia_mode;
948 
949 				setattr_copy(inode, &tmpattr);
950 				mark_inode_dirty(inode);
951 			}
952 		}
953 #endif
954         }
955 #endif
956 
957 	/* Do SIZE before attributes, otherwise mtime together with size does not work...
958 	 */
959 	if ((attr->ia_valid & ATTR_SIZE) != 0) {
960 		int written;
961 
962 		ncp_dbg(1, "trying to change size to %llu\n", attr->ia_size);
963 
964 		if ((result = ncp_make_open(inode, O_WRONLY)) < 0) {
965 			result = -EACCES;
966 			goto out;
967 		}
968 		ncp_write_kernel(NCP_SERVER(inode), NCP_FINFO(inode)->file_handle,
969 			  attr->ia_size, 0, "", &written);
970 
971 		/* According to ndir, the changes only take effect after
972 		   closing the file */
973 		ncp_inode_close(inode);
974 		result = ncp_make_closed(inode);
975 		if (result)
976 			goto out;
977 
978 		if (attr->ia_size != i_size_read(inode)) {
979 			truncate_setsize(inode, attr->ia_size);
980 			mark_inode_dirty(inode);
981 		}
982 	}
983 	if ((attr->ia_valid & ATTR_CTIME) != 0) {
984 		info_mask |= (DM_CREATE_TIME | DM_CREATE_DATE);
985 		ncp_date_unix2dos(attr->ia_ctime.tv_sec,
986 			     &info.creationTime, &info.creationDate);
987 	}
988 	if ((attr->ia_valid & ATTR_MTIME) != 0) {
989 		info_mask |= (DM_MODIFY_TIME | DM_MODIFY_DATE);
990 		ncp_date_unix2dos(attr->ia_mtime.tv_sec,
991 				  &info.modifyTime, &info.modifyDate);
992 	}
993 	if ((attr->ia_valid & ATTR_ATIME) != 0) {
994 		__le16 dummy;
995 		info_mask |= (DM_LAST_ACCESS_DATE);
996 		ncp_date_unix2dos(attr->ia_atime.tv_sec,
997 				  &dummy, &info.lastAccessDate);
998 	}
999 	if (info_mask != 0) {
1000 		result = ncp_modify_file_or_subdir_dos_info(NCP_SERVER(inode),
1001 				      inode, info_mask, &info);
1002 		if (result != 0) {
1003 			if (info_mask == (DM_CREATE_TIME | DM_CREATE_DATE)) {
1004 				/* NetWare seems not to allow this. I
1005 				   do not know why. So, just tell the
1006 				   user everything went fine. This is
1007 				   a terrible hack, but I do not know
1008 				   how to do this correctly. */
1009 				result = 0;
1010 			} else
1011 				goto out;
1012 		}
1013 #ifdef CONFIG_NCPFS_STRONG
1014 		if ((!result) && (info_mask & DM_ATTRIBUTES))
1015 			NCP_FINFO(inode)->nwattr = info.attributes;
1016 #endif
1017 	}
1018 	if (result)
1019 		goto out;
1020 
1021 	setattr_copy(inode, attr);
1022 	mark_inode_dirty(inode);
1023 
1024 out:
1025 	if (result > 0)
1026 		result = -EACCES;
1027 	return result;
1028 }
1029 
ncp_mount(struct file_system_type * fs_type,int flags,const char * dev_name,void * data)1030 static struct dentry *ncp_mount(struct file_system_type *fs_type,
1031 	int flags, const char *dev_name, void *data)
1032 {
1033 	return mount_nodev(fs_type, flags, data, ncp_fill_super);
1034 }
1035 
1036 static struct file_system_type ncp_fs_type = {
1037 	.owner		= THIS_MODULE,
1038 	.name		= "ncpfs",
1039 	.mount		= ncp_mount,
1040 	.kill_sb	= kill_anon_super,
1041 	.fs_flags	= FS_BINARY_MOUNTDATA,
1042 };
1043 MODULE_ALIAS_FS("ncpfs");
1044 
init_ncp_fs(void)1045 static int __init init_ncp_fs(void)
1046 {
1047 	int err;
1048 	ncp_dbg(1, "called\n");
1049 
1050 	err = init_inodecache();
1051 	if (err)
1052 		goto out1;
1053 	err = register_filesystem(&ncp_fs_type);
1054 	if (err)
1055 		goto out;
1056 	return 0;
1057 out:
1058 	destroy_inodecache();
1059 out1:
1060 	return err;
1061 }
1062 
exit_ncp_fs(void)1063 static void __exit exit_ncp_fs(void)
1064 {
1065 	ncp_dbg(1, "called\n");
1066 	unregister_filesystem(&ncp_fs_type);
1067 	destroy_inodecache();
1068 }
1069 
1070 module_init(init_ncp_fs)
1071 module_exit(exit_ncp_fs)
1072 MODULE_LICENSE("GPL");
1073