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 vfsmount *);
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 	INIT_LIST_HEAD(&inode->i_dentry);
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),
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 	kmem_cache_destroy(ncp_inode_cachep);
95 }
96 
ncp_remount(struct super_block * sb,int * flags,char * data)97 static int ncp_remount(struct super_block *sb, int *flags, char* data)
98 {
99 	*flags |= MS_NODIRATIME;
100 	return 0;
101 }
102 
103 static const struct super_operations ncp_sops =
104 {
105 	.alloc_inode	= ncp_alloc_inode,
106 	.destroy_inode	= ncp_destroy_inode,
107 	.drop_inode	= generic_delete_inode,
108 	.evict_inode	= ncp_evict_inode,
109 	.put_super	= ncp_put_super,
110 	.statfs		= ncp_statfs,
111 	.remount_fs	= ncp_remount,
112 	.show_options	= ncp_show_options,
113 };
114 
115 /*
116  * Fill in the ncpfs-specific information in the inode.
117  */
ncp_update_dirent(struct inode * inode,struct ncp_entry_info * nwinfo)118 static void ncp_update_dirent(struct inode *inode, struct ncp_entry_info *nwinfo)
119 {
120 	NCP_FINFO(inode)->DosDirNum = nwinfo->i.DosDirNum;
121 	NCP_FINFO(inode)->dirEntNum = nwinfo->i.dirEntNum;
122 	NCP_FINFO(inode)->volNumber = nwinfo->volume;
123 }
124 
ncp_update_inode(struct inode * inode,struct ncp_entry_info * nwinfo)125 void ncp_update_inode(struct inode *inode, struct ncp_entry_info *nwinfo)
126 {
127 	ncp_update_dirent(inode, nwinfo);
128 	NCP_FINFO(inode)->nwattr = nwinfo->i.attributes;
129 	NCP_FINFO(inode)->access = nwinfo->access;
130 	memcpy(NCP_FINFO(inode)->file_handle, nwinfo->file_handle,
131 			sizeof(nwinfo->file_handle));
132 	DPRINTK("ncp_update_inode: updated %s, volnum=%d, dirent=%u\n",
133 		nwinfo->i.entryName, NCP_FINFO(inode)->volNumber,
134 		NCP_FINFO(inode)->dirEntNum);
135 }
136 
ncp_update_dates(struct inode * inode,struct nw_info_struct * nwi)137 static void ncp_update_dates(struct inode *inode, struct nw_info_struct *nwi)
138 {
139 	/* NFS namespace mode overrides others if it's set. */
140 	DPRINTK(KERN_DEBUG "ncp_update_dates_and_mode: (%s) nfs.mode=0%o\n",
141 		nwi->entryName, nwi->nfs.mode);
142 	if (nwi->nfs.mode) {
143 		/* XXX Security? */
144 		inode->i_mode = nwi->nfs.mode;
145 	}
146 
147 	inode->i_blocks = (i_size_read(inode) + NCP_BLOCK_SIZE - 1) >> NCP_BLOCK_SHIFT;
148 
149 	inode->i_mtime.tv_sec = ncp_date_dos2unix(nwi->modifyTime, nwi->modifyDate);
150 	inode->i_ctime.tv_sec = ncp_date_dos2unix(nwi->creationTime, nwi->creationDate);
151 	inode->i_atime.tv_sec = ncp_date_dos2unix(0, nwi->lastAccessDate);
152 	inode->i_atime.tv_nsec = 0;
153 	inode->i_mtime.tv_nsec = 0;
154 	inode->i_ctime.tv_nsec = 0;
155 }
156 
ncp_update_attrs(struct inode * inode,struct ncp_entry_info * nwinfo)157 static void ncp_update_attrs(struct inode *inode, struct ncp_entry_info *nwinfo)
158 {
159 	struct nw_info_struct *nwi = &nwinfo->i;
160 	struct ncp_server *server = NCP_SERVER(inode);
161 
162 	if (nwi->attributes & aDIR) {
163 		inode->i_mode = server->m.dir_mode;
164 		/* for directories dataStreamSize seems to be some
165 		   Object ID ??? */
166 		i_size_write(inode, NCP_BLOCK_SIZE);
167 	} else {
168 		u32 size;
169 
170 		inode->i_mode = server->m.file_mode;
171 		size = le32_to_cpu(nwi->dataStreamSize);
172 		i_size_write(inode, size);
173 #ifdef CONFIG_NCPFS_EXTRAS
174 		if ((server->m.flags & (NCP_MOUNT_EXTRAS|NCP_MOUNT_SYMLINKS))
175 		 && (nwi->attributes & aSHARED)) {
176 			switch (nwi->attributes & (aHIDDEN|aSYSTEM)) {
177 				case aHIDDEN:
178 					if (server->m.flags & NCP_MOUNT_SYMLINKS) {
179 						if (/* (size >= NCP_MIN_SYMLINK_SIZE)
180 						 && */ (size <= NCP_MAX_SYMLINK_SIZE)) {
181 							inode->i_mode = (inode->i_mode & ~S_IFMT) | S_IFLNK;
182 							NCP_FINFO(inode)->flags |= NCPI_KLUDGE_SYMLINK;
183 							break;
184 						}
185 					}
186 					/* FALLTHROUGH */
187 				case 0:
188 					if (server->m.flags & NCP_MOUNT_EXTRAS)
189 						inode->i_mode |= S_IRUGO;
190 					break;
191 				case aSYSTEM:
192 					if (server->m.flags & NCP_MOUNT_EXTRAS)
193 						inode->i_mode |= (inode->i_mode >> 2) & S_IXUGO;
194 					break;
195 				/* case aSYSTEM|aHIDDEN: */
196 				default:
197 					/* reserved combination */
198 					break;
199 			}
200 		}
201 #endif
202 	}
203 	if (nwi->attributes & aRONLY) inode->i_mode &= ~S_IWUGO;
204 }
205 
ncp_update_inode2(struct inode * inode,struct ncp_entry_info * nwinfo)206 void ncp_update_inode2(struct inode* inode, struct ncp_entry_info *nwinfo)
207 {
208 	NCP_FINFO(inode)->flags = 0;
209 	if (!atomic_read(&NCP_FINFO(inode)->opened)) {
210 		NCP_FINFO(inode)->nwattr = nwinfo->i.attributes;
211 		ncp_update_attrs(inode, nwinfo);
212 	}
213 
214 	ncp_update_dates(inode, &nwinfo->i);
215 	ncp_update_dirent(inode, nwinfo);
216 }
217 
218 /*
219  * Fill in the inode based on the ncp_entry_info structure.  Used only for brand new inodes.
220  */
ncp_set_attr(struct inode * inode,struct ncp_entry_info * nwinfo)221 static void ncp_set_attr(struct inode *inode, struct ncp_entry_info *nwinfo)
222 {
223 	struct ncp_server *server = NCP_SERVER(inode);
224 
225 	NCP_FINFO(inode)->flags = 0;
226 
227 	ncp_update_attrs(inode, nwinfo);
228 
229 	DDPRINTK("ncp_read_inode: inode->i_mode = %u\n", inode->i_mode);
230 
231 	inode->i_nlink = 1;
232 	inode->i_uid = server->m.uid;
233 	inode->i_gid = server->m.gid;
234 
235 	ncp_update_dates(inode, &nwinfo->i);
236 	ncp_update_inode(inode, nwinfo);
237 }
238 
239 #if defined(CONFIG_NCPFS_EXTRAS) || defined(CONFIG_NCPFS_NFS_NS)
240 static const struct inode_operations ncp_symlink_inode_operations = {
241 	.readlink	= generic_readlink,
242 	.follow_link	= page_follow_link_light,
243 	.put_link	= page_put_link,
244 	.setattr	= ncp_notify_change,
245 };
246 #endif
247 
248 /*
249  * Get a new inode.
250  */
251 struct inode *
ncp_iget(struct super_block * sb,struct ncp_entry_info * info)252 ncp_iget(struct super_block *sb, struct ncp_entry_info *info)
253 {
254 	struct inode *inode;
255 
256 	if (info == NULL) {
257 		printk(KERN_ERR "ncp_iget: info is NULL\n");
258 		return NULL;
259 	}
260 
261 	inode = new_inode(sb);
262 	if (inode) {
263 		atomic_set(&NCP_FINFO(inode)->opened, info->opened);
264 
265 		inode->i_mapping->backing_dev_info = sb->s_bdi;
266 		inode->i_ino = info->ino;
267 		ncp_set_attr(inode, info);
268 		if (S_ISREG(inode->i_mode)) {
269 			inode->i_op = &ncp_file_inode_operations;
270 			inode->i_fop = &ncp_file_operations;
271 		} else if (S_ISDIR(inode->i_mode)) {
272 			inode->i_op = &ncp_dir_inode_operations;
273 			inode->i_fop = &ncp_dir_operations;
274 #ifdef CONFIG_NCPFS_NFS_NS
275 		} else if (S_ISCHR(inode->i_mode) || S_ISBLK(inode->i_mode) || S_ISFIFO(inode->i_mode) || S_ISSOCK(inode->i_mode)) {
276 			init_special_inode(inode, inode->i_mode,
277 				new_decode_dev(info->i.nfs.rdev));
278 #endif
279 #if defined(CONFIG_NCPFS_EXTRAS) || defined(CONFIG_NCPFS_NFS_NS)
280 		} else if (S_ISLNK(inode->i_mode)) {
281 			inode->i_op = &ncp_symlink_inode_operations;
282 			inode->i_data.a_ops = &ncp_symlink_aops;
283 #endif
284 		} else {
285 			make_bad_inode(inode);
286 		}
287 		insert_inode_hash(inode);
288 	} else
289 		printk(KERN_ERR "ncp_iget: iget failed!\n");
290 	return inode;
291 }
292 
293 static void
ncp_evict_inode(struct inode * inode)294 ncp_evict_inode(struct inode *inode)
295 {
296 	truncate_inode_pages(&inode->i_data, 0);
297 	end_writeback(inode);
298 
299 	if (S_ISDIR(inode->i_mode)) {
300 		DDPRINTK("ncp_evict_inode: put directory %ld\n", inode->i_ino);
301 	}
302 
303 	if (ncp_make_closed(inode) != 0) {
304 		/* We can't do anything but complain. */
305 		printk(KERN_ERR "ncp_evict_inode: could not close\n");
306 	}
307 }
308 
ncp_stop_tasks(struct ncp_server * server)309 static void ncp_stop_tasks(struct ncp_server *server) {
310 	struct sock* sk = server->ncp_sock->sk;
311 
312 	lock_sock(sk);
313 	sk->sk_error_report = server->error_report;
314 	sk->sk_data_ready   = server->data_ready;
315 	sk->sk_write_space  = server->write_space;
316 	release_sock(sk);
317 	del_timer_sync(&server->timeout_tm);
318 
319 	flush_work_sync(&server->rcv.tq);
320 	if (sk->sk_socket->type == SOCK_STREAM)
321 		flush_work_sync(&server->tx.tq);
322 	else
323 		flush_work_sync(&server->timeout_tq);
324 }
325 
ncp_show_options(struct seq_file * seq,struct vfsmount * mnt)326 static int  ncp_show_options(struct seq_file *seq, struct vfsmount *mnt)
327 {
328 	struct ncp_server *server = NCP_SBP(mnt->mnt_sb);
329 	unsigned int tmp;
330 
331 	if (server->m.uid != 0)
332 		seq_printf(seq, ",uid=%u", server->m.uid);
333 	if (server->m.gid != 0)
334 		seq_printf(seq, ",gid=%u", server->m.gid);
335 	if (server->m.mounted_uid != 0)
336 		seq_printf(seq, ",owner=%u", server->m.mounted_uid);
337 	tmp = server->m.file_mode & S_IALLUGO;
338 	if (tmp != NCP_DEFAULT_FILE_MODE)
339 		seq_printf(seq, ",mode=0%o", tmp);
340 	tmp = server->m.dir_mode & S_IALLUGO;
341 	if (tmp != NCP_DEFAULT_DIR_MODE)
342 		seq_printf(seq, ",dirmode=0%o", tmp);
343 	if (server->m.time_out != NCP_DEFAULT_TIME_OUT * HZ / 100) {
344 		tmp = server->m.time_out * 100 / HZ;
345 		seq_printf(seq, ",timeout=%u", tmp);
346 	}
347 	if (server->m.retry_count != NCP_DEFAULT_RETRY_COUNT)
348 		seq_printf(seq, ",retry=%u", server->m.retry_count);
349 	if (server->m.flags != 0)
350 		seq_printf(seq, ",flags=%lu", server->m.flags);
351 	if (server->m.wdog_pid != NULL)
352 		seq_printf(seq, ",wdogpid=%u", pid_vnr(server->m.wdog_pid));
353 
354 	return 0;
355 }
356 
357 static const struct ncp_option ncp_opts[] = {
358 	{ "uid",	OPT_INT,	'u' },
359 	{ "gid",	OPT_INT,	'g' },
360 	{ "owner",	OPT_INT,	'o' },
361 	{ "mode",	OPT_INT,	'm' },
362 	{ "dirmode",	OPT_INT,	'd' },
363 	{ "timeout",	OPT_INT,	't' },
364 	{ "retry",	OPT_INT,	'r' },
365 	{ "flags",	OPT_INT,	'f' },
366 	{ "wdogpid",	OPT_INT,	'w' },
367 	{ "ncpfd",	OPT_INT,	'n' },
368 	{ "infofd",	OPT_INT,	'i' },	/* v5 */
369 	{ "version",	OPT_INT,	'v' },
370 	{ NULL,		0,		0 } };
371 
ncp_parse_options(struct ncp_mount_data_kernel * data,char * options)372 static int ncp_parse_options(struct ncp_mount_data_kernel *data, char *options) {
373 	int optval;
374 	char *optarg;
375 	unsigned long optint;
376 	int version = 0;
377 	int ret;
378 
379 	data->flags = 0;
380 	data->int_flags = 0;
381 	data->mounted_uid = 0;
382 	data->wdog_pid = NULL;
383 	data->ncp_fd = ~0;
384 	data->time_out = NCP_DEFAULT_TIME_OUT;
385 	data->retry_count = NCP_DEFAULT_RETRY_COUNT;
386 	data->uid = 0;
387 	data->gid = 0;
388 	data->file_mode = NCP_DEFAULT_FILE_MODE;
389 	data->dir_mode = NCP_DEFAULT_DIR_MODE;
390 	data->info_fd = -1;
391 	data->mounted_vol[0] = 0;
392 
393 	while ((optval = ncp_getopt("ncpfs", &options, ncp_opts, NULL, &optarg, &optint)) != 0) {
394 		ret = optval;
395 		if (ret < 0)
396 			goto err;
397 		switch (optval) {
398 			case 'u':
399 				data->uid = optint;
400 				break;
401 			case 'g':
402 				data->gid = optint;
403 				break;
404 			case 'o':
405 				data->mounted_uid = optint;
406 				break;
407 			case 'm':
408 				data->file_mode = optint;
409 				break;
410 			case 'd':
411 				data->dir_mode = optint;
412 				break;
413 			case 't':
414 				data->time_out = optint;
415 				break;
416 			case 'r':
417 				data->retry_count = optint;
418 				break;
419 			case 'f':
420 				data->flags = optint;
421 				break;
422 			case 'w':
423 				data->wdog_pid = find_get_pid(optint);
424 				break;
425 			case 'n':
426 				data->ncp_fd = optint;
427 				break;
428 			case 'i':
429 				data->info_fd = optint;
430 				break;
431 			case 'v':
432 				ret = -ECHRNG;
433 				if (optint < NCP_MOUNT_VERSION_V4)
434 					goto err;
435 				if (optint > NCP_MOUNT_VERSION_V5)
436 					goto err;
437 				version = optint;
438 				break;
439 
440 		}
441 	}
442 	return 0;
443 err:
444 	put_pid(data->wdog_pid);
445 	data->wdog_pid = NULL;
446 	return ret;
447 }
448 
ncp_fill_super(struct super_block * sb,void * raw_data,int silent)449 static int ncp_fill_super(struct super_block *sb, void *raw_data, int silent)
450 {
451 	struct ncp_mount_data_kernel data;
452 	struct ncp_server *server;
453 	struct file *ncp_filp;
454 	struct inode *root_inode;
455 	struct inode *sock_inode;
456 	struct socket *sock;
457 	int error;
458 	int default_bufsize;
459 #ifdef CONFIG_NCPFS_PACKET_SIGNING
460 	int options;
461 #endif
462 	struct ncp_entry_info finfo;
463 
464 	data.wdog_pid = NULL;
465 	server = kzalloc(sizeof(struct ncp_server), GFP_KERNEL);
466 	if (!server)
467 		return -ENOMEM;
468 	sb->s_fs_info = server;
469 
470 	error = -EFAULT;
471 	if (raw_data == NULL)
472 		goto out;
473 	switch (*(int*)raw_data) {
474 		case NCP_MOUNT_VERSION:
475 			{
476 				struct ncp_mount_data* md = (struct ncp_mount_data*)raw_data;
477 
478 				data.flags = md->flags;
479 				data.int_flags = NCP_IMOUNT_LOGGEDIN_POSSIBLE;
480 				data.mounted_uid = md->mounted_uid;
481 				data.wdog_pid = find_get_pid(md->wdog_pid);
482 				data.ncp_fd = md->ncp_fd;
483 				data.time_out = md->time_out;
484 				data.retry_count = md->retry_count;
485 				data.uid = md->uid;
486 				data.gid = md->gid;
487 				data.file_mode = md->file_mode;
488 				data.dir_mode = md->dir_mode;
489 				data.info_fd = -1;
490 				memcpy(data.mounted_vol, md->mounted_vol,
491 					NCP_VOLNAME_LEN+1);
492 			}
493 			break;
494 		case NCP_MOUNT_VERSION_V4:
495 			{
496 				struct ncp_mount_data_v4* md = (struct ncp_mount_data_v4*)raw_data;
497 
498 				data.flags = md->flags;
499 				data.int_flags = 0;
500 				data.mounted_uid = md->mounted_uid;
501 				data.wdog_pid = find_get_pid(md->wdog_pid);
502 				data.ncp_fd = md->ncp_fd;
503 				data.time_out = md->time_out;
504 				data.retry_count = md->retry_count;
505 				data.uid = md->uid;
506 				data.gid = md->gid;
507 				data.file_mode = md->file_mode;
508 				data.dir_mode = md->dir_mode;
509 				data.info_fd = -1;
510 				data.mounted_vol[0] = 0;
511 			}
512 			break;
513 		default:
514 			error = -ECHRNG;
515 			if (memcmp(raw_data, "vers", 4) == 0) {
516 				error = ncp_parse_options(&data, raw_data);
517 			}
518 			if (error)
519 				goto out;
520 			break;
521 	}
522 	error = -EBADF;
523 	ncp_filp = fget(data.ncp_fd);
524 	if (!ncp_filp)
525 		goto out;
526 	error = -ENOTSOCK;
527 	sock_inode = ncp_filp->f_path.dentry->d_inode;
528 	if (!S_ISSOCK(sock_inode->i_mode))
529 		goto out_fput;
530 	sock = SOCKET_I(sock_inode);
531 	if (!sock)
532 		goto out_fput;
533 
534 	if (sock->type == SOCK_STREAM)
535 		default_bufsize = 0xF000;
536 	else
537 		default_bufsize = 1024;
538 
539 	sb->s_flags |= MS_NODIRATIME;	/* probably even noatime */
540 	sb->s_maxbytes = 0xFFFFFFFFU;
541 	sb->s_blocksize = 1024;	/* Eh...  Is this correct? */
542 	sb->s_blocksize_bits = 10;
543 	sb->s_magic = NCP_SUPER_MAGIC;
544 	sb->s_op = &ncp_sops;
545 	sb->s_d_op = &ncp_dentry_operations;
546 	sb->s_bdi = &server->bdi;
547 
548 	server = NCP_SBP(sb);
549 	memset(server, 0, sizeof(*server));
550 
551 	error = bdi_setup_and_register(&server->bdi, "ncpfs", BDI_CAP_MAP_COPY);
552 	if (error)
553 		goto out_bdi;
554 
555 	server->ncp_filp = ncp_filp;
556 	server->ncp_sock = sock;
557 
558 	if (data.info_fd != -1) {
559 		struct socket *info_sock;
560 
561 		error = -EBADF;
562 		server->info_filp = fget(data.info_fd);
563 		if (!server->info_filp)
564 			goto out_fput;
565 		error = -ENOTSOCK;
566 		sock_inode = server->info_filp->f_path.dentry->d_inode;
567 		if (!S_ISSOCK(sock_inode->i_mode))
568 			goto out_fput2;
569 		info_sock = SOCKET_I(sock_inode);
570 		if (!info_sock)
571 			goto out_fput2;
572 		error = -EBADFD;
573 		if (info_sock->type != SOCK_STREAM)
574 			goto out_fput2;
575 		server->info_sock = info_sock;
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 		printk(KERN_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 	DPRINTK("ncp_fill_super: NCP_SBP(sb) = %x\n", (int) 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 	DPRINTK("ncpfs: 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 	DPRINTK("ncp_fill_super: root vol=%d\n", NCP_FINFO(root_inode)->volNumber);
722 	sb->s_root = d_alloc_root(root_inode);
723         if (!sb->s_root)
724 		goto out_no_root;
725 	return 0;
726 
727 out_no_root:
728 	iput(root_inode);
729 out_disconnect:
730 	ncp_lock_server(server);
731 	ncp_disconnect(server);
732 	ncp_unlock_server(server);
733 out_rxbuf:
734 	ncp_stop_tasks(server);
735 	vfree(server->rxbuf);
736 out_txbuf:
737 	vfree(server->txbuf);
738 out_packet:
739 	vfree(server->packet);
740 out_nls:
741 #ifdef CONFIG_NCPFS_NLS
742 	unload_nls(server->nls_io);
743 	unload_nls(server->nls_vol);
744 #endif
745 	mutex_destroy(&server->rcv.creq_mutex);
746 	mutex_destroy(&server->root_setup_lock);
747 	mutex_destroy(&server->mutex);
748 out_fput2:
749 	if (server->info_filp)
750 		fput(server->info_filp);
751 out_fput:
752 	bdi_destroy(&server->bdi);
753 out_bdi:
754 	/* 23/12/1998 Marcin Dalecki <dalecki@cs.net.pl>:
755 	 *
756 	 * The previously used put_filp(ncp_filp); was bogus, since
757 	 * it doesn't perform proper unlocking.
758 	 */
759 	fput(ncp_filp);
760 out:
761 	put_pid(data.wdog_pid);
762 	sb->s_fs_info = NULL;
763 	kfree(server);
764 	return error;
765 }
766 
ncp_put_super(struct super_block * sb)767 static void ncp_put_super(struct super_block *sb)
768 {
769 	struct ncp_server *server = NCP_SBP(sb);
770 
771 	ncp_lock_server(server);
772 	ncp_disconnect(server);
773 	ncp_unlock_server(server);
774 
775 	ncp_stop_tasks(server);
776 
777 #ifdef CONFIG_NCPFS_NLS
778 	/* unload the NLS charsets */
779 	unload_nls(server->nls_vol);
780 	unload_nls(server->nls_io);
781 #endif /* CONFIG_NCPFS_NLS */
782 	mutex_destroy(&server->rcv.creq_mutex);
783 	mutex_destroy(&server->root_setup_lock);
784 	mutex_destroy(&server->mutex);
785 
786 	if (server->info_filp)
787 		fput(server->info_filp);
788 	fput(server->ncp_filp);
789 	kill_pid(server->m.wdog_pid, SIGTERM, 1);
790 	put_pid(server->m.wdog_pid);
791 
792 	bdi_destroy(&server->bdi);
793 	kfree(server->priv.data);
794 	kfree(server->auth.object_name);
795 	vfree(server->rxbuf);
796 	vfree(server->txbuf);
797 	vfree(server->packet);
798 	sb->s_fs_info = NULL;
799 	kfree(server);
800 }
801 
ncp_statfs(struct dentry * dentry,struct kstatfs * buf)802 static int ncp_statfs(struct dentry *dentry, struct kstatfs *buf)
803 {
804 	struct dentry* d;
805 	struct inode* i;
806 	struct ncp_inode_info* ni;
807 	struct ncp_server* s;
808 	struct ncp_volume_info vi;
809 	struct super_block *sb = dentry->d_sb;
810 	int err;
811 	__u8 dh;
812 
813 	d = sb->s_root;
814 	if (!d) {
815 		goto dflt;
816 	}
817 	i = d->d_inode;
818 	if (!i) {
819 		goto dflt;
820 	}
821 	ni = NCP_FINFO(i);
822 	if (!ni) {
823 		goto dflt;
824 	}
825 	s = NCP_SBP(sb);
826 	if (!s) {
827 		goto dflt;
828 	}
829 	if (!s->m.mounted_vol[0]) {
830 		goto dflt;
831 	}
832 
833 	err = ncp_dirhandle_alloc(s, ni->volNumber, ni->DosDirNum, &dh);
834 	if (err) {
835 		goto dflt;
836 	}
837 	err = ncp_get_directory_info(s, dh, &vi);
838 	ncp_dirhandle_free(s, dh);
839 	if (err) {
840 		goto dflt;
841 	}
842 	buf->f_type = NCP_SUPER_MAGIC;
843 	buf->f_bsize = vi.sectors_per_block * 512;
844 	buf->f_blocks = vi.total_blocks;
845 	buf->f_bfree = vi.free_blocks;
846 	buf->f_bavail = vi.free_blocks;
847 	buf->f_files = vi.total_dir_entries;
848 	buf->f_ffree = vi.available_dir_entries;
849 	buf->f_namelen = 12;
850 	return 0;
851 
852 	/* We cannot say how much disk space is left on a mounted
853 	   NetWare Server, because free space is distributed over
854 	   volumes, and the current user might have disk quotas. So
855 	   free space is not that simple to determine. Our decision
856 	   here is to err conservatively. */
857 
858 dflt:;
859 	buf->f_type = NCP_SUPER_MAGIC;
860 	buf->f_bsize = NCP_BLOCK_SIZE;
861 	buf->f_blocks = 0;
862 	buf->f_bfree = 0;
863 	buf->f_bavail = 0;
864 	buf->f_namelen = 12;
865 	return 0;
866 }
867 
ncp_notify_change(struct dentry * dentry,struct iattr * attr)868 int ncp_notify_change(struct dentry *dentry, struct iattr *attr)
869 {
870 	struct inode *inode = dentry->d_inode;
871 	int result = 0;
872 	__le32 info_mask;
873 	struct nw_modify_dos_info info;
874 	struct ncp_server *server;
875 
876 	result = -EIO;
877 
878 	server = NCP_SERVER(inode);
879 	if (!server)	/* How this could happen? */
880 		goto out;
881 
882 	/* ageing the dentry to force validation */
883 	ncp_age_dentry(server, dentry);
884 
885 	result = inode_change_ok(inode, attr);
886 	if (result < 0)
887 		goto out;
888 
889 	result = -EPERM;
890 	if (((attr->ia_valid & ATTR_UID) &&
891 	     (attr->ia_uid != server->m.uid)))
892 		goto out;
893 
894 	if (((attr->ia_valid & ATTR_GID) &&
895 	     (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 		DPRINTK("ncpfs: trying to change size to %ld\n",
963 			attr->ia_size);
964 
965 		if ((result = ncp_make_open(inode, O_WRONLY)) < 0) {
966 			result = -EACCES;
967 			goto out;
968 		}
969 		ncp_write_kernel(NCP_SERVER(inode), NCP_FINFO(inode)->file_handle,
970 			  attr->ia_size, 0, "", &written);
971 
972 		/* According to ndir, the changes only take effect after
973 		   closing the file */
974 		ncp_inode_close(inode);
975 		result = ncp_make_closed(inode);
976 		if (result)
977 			goto out;
978 
979 		if (attr->ia_size != i_size_read(inode)) {
980 			result = vmtruncate(inode, attr->ia_size);
981 			if (result)
982 				goto out;
983 			mark_inode_dirty(inode);
984 		}
985 	}
986 	if ((attr->ia_valid & ATTR_CTIME) != 0) {
987 		info_mask |= (DM_CREATE_TIME | DM_CREATE_DATE);
988 		ncp_date_unix2dos(attr->ia_ctime.tv_sec,
989 			     &info.creationTime, &info.creationDate);
990 	}
991 	if ((attr->ia_valid & ATTR_MTIME) != 0) {
992 		info_mask |= (DM_MODIFY_TIME | DM_MODIFY_DATE);
993 		ncp_date_unix2dos(attr->ia_mtime.tv_sec,
994 				  &info.modifyTime, &info.modifyDate);
995 	}
996 	if ((attr->ia_valid & ATTR_ATIME) != 0) {
997 		__le16 dummy;
998 		info_mask |= (DM_LAST_ACCESS_DATE);
999 		ncp_date_unix2dos(attr->ia_atime.tv_sec,
1000 				  &dummy, &info.lastAccessDate);
1001 	}
1002 	if (info_mask != 0) {
1003 		result = ncp_modify_file_or_subdir_dos_info(NCP_SERVER(inode),
1004 				      inode, info_mask, &info);
1005 		if (result != 0) {
1006 			if (info_mask == (DM_CREATE_TIME | DM_CREATE_DATE)) {
1007 				/* NetWare seems not to allow this. I
1008 				   do not know why. So, just tell the
1009 				   user everything went fine. This is
1010 				   a terrible hack, but I do not know
1011 				   how to do this correctly. */
1012 				result = 0;
1013 			} else
1014 				goto out;
1015 		}
1016 #ifdef CONFIG_NCPFS_STRONG
1017 		if ((!result) && (info_mask & DM_ATTRIBUTES))
1018 			NCP_FINFO(inode)->nwattr = info.attributes;
1019 #endif
1020 	}
1021 	if (result)
1022 		goto out;
1023 
1024 	setattr_copy(inode, attr);
1025 	mark_inode_dirty(inode);
1026 
1027 out:
1028 	if (result > 0)
1029 		result = -EACCES;
1030 	return result;
1031 }
1032 
ncp_mount(struct file_system_type * fs_type,int flags,const char * dev_name,void * data)1033 static struct dentry *ncp_mount(struct file_system_type *fs_type,
1034 	int flags, const char *dev_name, void *data)
1035 {
1036 	return mount_nodev(fs_type, flags, data, ncp_fill_super);
1037 }
1038 
1039 static struct file_system_type ncp_fs_type = {
1040 	.owner		= THIS_MODULE,
1041 	.name		= "ncpfs",
1042 	.mount		= ncp_mount,
1043 	.kill_sb	= kill_anon_super,
1044 	.fs_flags	= FS_BINARY_MOUNTDATA,
1045 };
1046 
init_ncp_fs(void)1047 static int __init init_ncp_fs(void)
1048 {
1049 	int err;
1050 	DPRINTK("ncpfs: init_ncp_fs called\n");
1051 
1052 	err = init_inodecache();
1053 	if (err)
1054 		goto out1;
1055 	err = register_filesystem(&ncp_fs_type);
1056 	if (err)
1057 		goto out;
1058 	return 0;
1059 out:
1060 	destroy_inodecache();
1061 out1:
1062 	return err;
1063 }
1064 
exit_ncp_fs(void)1065 static void __exit exit_ncp_fs(void)
1066 {
1067 	DPRINTK("ncpfs: exit_ncp_fs called\n");
1068 	unregister_filesystem(&ncp_fs_type);
1069 	destroy_inodecache();
1070 }
1071 
1072 module_init(init_ncp_fs)
1073 module_exit(exit_ncp_fs)
1074 MODULE_LICENSE("GPL");
1075