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