• 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 <linux/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/sched/signal.h>
34 #include <linux/namei.h>
35 
36 #include <net/sock.h>
37 
38 #include "ncp_fs.h"
39 #include "getopt.h"
40 
41 #define NCP_DEFAULT_FILE_MODE 0600
42 #define NCP_DEFAULT_DIR_MODE 0700
43 #define NCP_DEFAULT_TIME_OUT 10
44 #define NCP_DEFAULT_RETRY_COUNT 20
45 
46 static void ncp_evict_inode(struct inode *);
47 static void ncp_put_super(struct super_block *);
48 static int  ncp_statfs(struct dentry *, struct kstatfs *);
49 static int  ncp_show_options(struct seq_file *, struct dentry *);
50 
51 static struct kmem_cache * ncp_inode_cachep;
52 
ncp_alloc_inode(struct super_block * sb)53 static struct inode *ncp_alloc_inode(struct super_block *sb)
54 {
55 	struct ncp_inode_info *ei;
56 	ei = (struct ncp_inode_info *)kmem_cache_alloc(ncp_inode_cachep, GFP_KERNEL);
57 	if (!ei)
58 		return NULL;
59 	return &ei->vfs_inode;
60 }
61 
ncp_i_callback(struct rcu_head * head)62 static void ncp_i_callback(struct rcu_head *head)
63 {
64 	struct inode *inode = container_of(head, struct inode, i_rcu);
65 	kmem_cache_free(ncp_inode_cachep, NCP_FINFO(inode));
66 }
67 
ncp_destroy_inode(struct inode * inode)68 static void ncp_destroy_inode(struct inode *inode)
69 {
70 	call_rcu(&inode->i_rcu, ncp_i_callback);
71 }
72 
init_once(void * foo)73 static void init_once(void *foo)
74 {
75 	struct ncp_inode_info *ei = (struct ncp_inode_info *) foo;
76 
77 	mutex_init(&ei->open_mutex);
78 	inode_init_once(&ei->vfs_inode);
79 }
80 
init_inodecache(void)81 static int init_inodecache(void)
82 {
83 	ncp_inode_cachep = kmem_cache_create("ncp_inode_cache",
84 					     sizeof(struct ncp_inode_info),
85 					     0, (SLAB_RECLAIM_ACCOUNT|
86 						SLAB_MEM_SPREAD|SLAB_ACCOUNT),
87 					     init_once);
88 	if (ncp_inode_cachep == NULL)
89 		return -ENOMEM;
90 	return 0;
91 }
92 
destroy_inodecache(void)93 static void destroy_inodecache(void)
94 {
95 	/*
96 	 * Make sure all delayed rcu free inodes are flushed before we
97 	 * destroy cache.
98 	 */
99 	rcu_barrier();
100 	kmem_cache_destroy(ncp_inode_cachep);
101 }
102 
ncp_remount(struct super_block * sb,int * flags,char * data)103 static int ncp_remount(struct super_block *sb, int *flags, char* data)
104 {
105 	sync_filesystem(sb);
106 	*flags |= MS_NODIRATIME;
107 	return 0;
108 }
109 
110 static const struct super_operations ncp_sops =
111 {
112 	.alloc_inode	= ncp_alloc_inode,
113 	.destroy_inode	= ncp_destroy_inode,
114 	.drop_inode	= generic_delete_inode,
115 	.evict_inode	= ncp_evict_inode,
116 	.put_super	= ncp_put_super,
117 	.statfs		= ncp_statfs,
118 	.remount_fs	= ncp_remount,
119 	.show_options	= ncp_show_options,
120 };
121 
122 /*
123  * Fill in the ncpfs-specific information in the inode.
124  */
ncp_update_dirent(struct inode * inode,struct ncp_entry_info * nwinfo)125 static void ncp_update_dirent(struct inode *inode, struct ncp_entry_info *nwinfo)
126 {
127 	NCP_FINFO(inode)->DosDirNum = nwinfo->i.DosDirNum;
128 	NCP_FINFO(inode)->dirEntNum = nwinfo->i.dirEntNum;
129 	NCP_FINFO(inode)->volNumber = nwinfo->volume;
130 }
131 
ncp_update_inode(struct inode * inode,struct ncp_entry_info * nwinfo)132 void ncp_update_inode(struct inode *inode, struct ncp_entry_info *nwinfo)
133 {
134 	ncp_update_dirent(inode, nwinfo);
135 	NCP_FINFO(inode)->nwattr = nwinfo->i.attributes;
136 	NCP_FINFO(inode)->access = nwinfo->access;
137 	memcpy(NCP_FINFO(inode)->file_handle, nwinfo->file_handle,
138 			sizeof(nwinfo->file_handle));
139 	ncp_dbg(1, "updated %s, volnum=%d, dirent=%u\n",
140 		nwinfo->i.entryName, NCP_FINFO(inode)->volNumber,
141 		NCP_FINFO(inode)->dirEntNum);
142 }
143 
ncp_update_dates(struct inode * inode,struct nw_info_struct * nwi)144 static void ncp_update_dates(struct inode *inode, struct nw_info_struct *nwi)
145 {
146 	/* NFS namespace mode overrides others if it's set. */
147 	ncp_dbg(1, "(%s) nfs.mode=0%o\n", nwi->entryName, nwi->nfs.mode);
148 	if (nwi->nfs.mode) {
149 		/* XXX Security? */
150 		inode->i_mode = nwi->nfs.mode;
151 	}
152 
153 	inode->i_blocks = (i_size_read(inode) + NCP_BLOCK_SIZE - 1) >> NCP_BLOCK_SHIFT;
154 
155 	inode->i_mtime.tv_sec = ncp_date_dos2unix(nwi->modifyTime, nwi->modifyDate);
156 	inode->i_ctime.tv_sec = ncp_date_dos2unix(nwi->creationTime, nwi->creationDate);
157 	inode->i_atime.tv_sec = ncp_date_dos2unix(0, nwi->lastAccessDate);
158 	inode->i_atime.tv_nsec = 0;
159 	inode->i_mtime.tv_nsec = 0;
160 	inode->i_ctime.tv_nsec = 0;
161 }
162 
ncp_update_attrs(struct inode * inode,struct ncp_entry_info * nwinfo)163 static void ncp_update_attrs(struct inode *inode, struct ncp_entry_info *nwinfo)
164 {
165 	struct nw_info_struct *nwi = &nwinfo->i;
166 	struct ncp_server *server = NCP_SERVER(inode);
167 
168 	if (nwi->attributes & aDIR) {
169 		inode->i_mode = server->m.dir_mode;
170 		/* for directories dataStreamSize seems to be some
171 		   Object ID ??? */
172 		i_size_write(inode, NCP_BLOCK_SIZE);
173 	} else {
174 		u32 size;
175 
176 		inode->i_mode = server->m.file_mode;
177 		size = le32_to_cpu(nwi->dataStreamSize);
178 		i_size_write(inode, size);
179 #ifdef CONFIG_NCPFS_EXTRAS
180 		if ((server->m.flags & (NCP_MOUNT_EXTRAS|NCP_MOUNT_SYMLINKS))
181 		 && (nwi->attributes & aSHARED)) {
182 			switch (nwi->attributes & (aHIDDEN|aSYSTEM)) {
183 				case aHIDDEN:
184 					if (server->m.flags & NCP_MOUNT_SYMLINKS) {
185 						if (/* (size >= NCP_MIN_SYMLINK_SIZE)
186 						 && */ (size <= NCP_MAX_SYMLINK_SIZE)) {
187 							inode->i_mode = (inode->i_mode & ~S_IFMT) | S_IFLNK;
188 							NCP_FINFO(inode)->flags |= NCPI_KLUDGE_SYMLINK;
189 							break;
190 						}
191 					}
192 					/* FALLTHROUGH */
193 				case 0:
194 					if (server->m.flags & NCP_MOUNT_EXTRAS)
195 						inode->i_mode |= S_IRUGO;
196 					break;
197 				case aSYSTEM:
198 					if (server->m.flags & NCP_MOUNT_EXTRAS)
199 						inode->i_mode |= (inode->i_mode >> 2) & S_IXUGO;
200 					break;
201 				/* case aSYSTEM|aHIDDEN: */
202 				default:
203 					/* reserved combination */
204 					break;
205 			}
206 		}
207 #endif
208 	}
209 	if (nwi->attributes & aRONLY) inode->i_mode &= ~S_IWUGO;
210 }
211 
ncp_update_inode2(struct inode * inode,struct ncp_entry_info * nwinfo)212 void ncp_update_inode2(struct inode* inode, struct ncp_entry_info *nwinfo)
213 {
214 	NCP_FINFO(inode)->flags = 0;
215 	if (!atomic_read(&NCP_FINFO(inode)->opened)) {
216 		NCP_FINFO(inode)->nwattr = nwinfo->i.attributes;
217 		ncp_update_attrs(inode, nwinfo);
218 	}
219 
220 	ncp_update_dates(inode, &nwinfo->i);
221 	ncp_update_dirent(inode, nwinfo);
222 }
223 
224 /*
225  * Fill in the inode based on the ncp_entry_info structure.  Used only for brand new inodes.
226  */
ncp_set_attr(struct inode * inode,struct ncp_entry_info * nwinfo)227 static void ncp_set_attr(struct inode *inode, struct ncp_entry_info *nwinfo)
228 {
229 	struct ncp_server *server = NCP_SERVER(inode);
230 
231 	NCP_FINFO(inode)->flags = 0;
232 
233 	ncp_update_attrs(inode, nwinfo);
234 
235 	ncp_dbg(2, "inode->i_mode = %u\n", inode->i_mode);
236 
237 	set_nlink(inode, 1);
238 	inode->i_uid = server->m.uid;
239 	inode->i_gid = server->m.gid;
240 
241 	ncp_update_dates(inode, &nwinfo->i);
242 	ncp_update_inode(inode, nwinfo);
243 }
244 
245 #if defined(CONFIG_NCPFS_EXTRAS) || defined(CONFIG_NCPFS_NFS_NS)
246 static const struct inode_operations ncp_symlink_inode_operations = {
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 
558 	server = NCP_SBP(sb);
559 	memset(server, 0, sizeof(*server));
560 
561 	error = super_setup_bdi(sb);
562 	if (error)
563 		goto out_fput;
564 
565 	server->ncp_sock = sock;
566 
567 	if (data.info_fd != -1) {
568 		struct socket *info_sock = sockfd_lookup(data.info_fd, &error);
569 		if (!info_sock)
570 			goto out_fput;
571 		server->info_sock = info_sock;
572 		error = -EBADFD;
573 		if (info_sock->type != SOCK_STREAM)
574 			goto out_fput2;
575 	}
576 
577 /*	server->lock = 0;	*/
578 	mutex_init(&server->mutex);
579 	server->packet = NULL;
580 /*	server->buffer_size = 0;	*/
581 /*	server->conn_status = 0;	*/
582 /*	server->root_dentry = NULL;	*/
583 /*	server->root_setuped = 0;	*/
584 	mutex_init(&server->root_setup_lock);
585 #ifdef CONFIG_NCPFS_PACKET_SIGNING
586 /*	server->sign_wanted = 0;	*/
587 /*	server->sign_active = 0;	*/
588 #endif
589 	init_rwsem(&server->auth_rwsem);
590 	server->auth.auth_type = NCP_AUTH_NONE;
591 /*	server->auth.object_name_len = 0;	*/
592 /*	server->auth.object_name = NULL;	*/
593 /*	server->auth.object_type = 0;		*/
594 /*	server->priv.len = 0;			*/
595 /*	server->priv.data = NULL;		*/
596 
597 	server->m = data;
598 	/* Although anything producing this is buggy, it happens
599 	   now because of PATH_MAX changes.. */
600 	if (server->m.time_out < 1) {
601 		server->m.time_out = 10;
602 		pr_info("You need to recompile your ncpfs utils..\n");
603 	}
604 	server->m.time_out = server->m.time_out * HZ / 100;
605 	server->m.file_mode = (server->m.file_mode & S_IRWXUGO) | S_IFREG;
606 	server->m.dir_mode = (server->m.dir_mode & S_IRWXUGO) | S_IFDIR;
607 
608 #ifdef CONFIG_NCPFS_NLS
609 	/* load the default NLS charsets */
610 	server->nls_vol = load_nls_default();
611 	server->nls_io = load_nls_default();
612 #endif /* CONFIG_NCPFS_NLS */
613 
614 	atomic_set(&server->dentry_ttl, 0);	/* no caching */
615 
616 	INIT_LIST_HEAD(&server->tx.requests);
617 	mutex_init(&server->rcv.creq_mutex);
618 	server->tx.creq		= NULL;
619 	server->rcv.creq	= NULL;
620 
621 	init_timer(&server->timeout_tm);
622 #undef NCP_PACKET_SIZE
623 #define NCP_PACKET_SIZE 131072
624 	error = -ENOMEM;
625 	server->packet_size = NCP_PACKET_SIZE;
626 	server->packet = vmalloc(NCP_PACKET_SIZE);
627 	if (server->packet == NULL)
628 		goto out_nls;
629 	server->txbuf = vmalloc(NCP_PACKET_SIZE);
630 	if (server->txbuf == NULL)
631 		goto out_packet;
632 	server->rxbuf = vmalloc(NCP_PACKET_SIZE);
633 	if (server->rxbuf == NULL)
634 		goto out_txbuf;
635 
636 	lock_sock(sock->sk);
637 	server->data_ready	= sock->sk->sk_data_ready;
638 	server->write_space	= sock->sk->sk_write_space;
639 	server->error_report	= sock->sk->sk_error_report;
640 	sock->sk->sk_user_data	= server;
641 	sock->sk->sk_data_ready	  = ncp_tcp_data_ready;
642 	sock->sk->sk_error_report = ncp_tcp_error_report;
643 	if (sock->type == SOCK_STREAM) {
644 		server->rcv.ptr = (unsigned char*)&server->rcv.buf;
645 		server->rcv.len = 10;
646 		server->rcv.state = 0;
647 		INIT_WORK(&server->rcv.tq, ncp_tcp_rcv_proc);
648 		INIT_WORK(&server->tx.tq, ncp_tcp_tx_proc);
649 		sock->sk->sk_write_space = ncp_tcp_write_space;
650 	} else {
651 		INIT_WORK(&server->rcv.tq, ncpdgram_rcv_proc);
652 		INIT_WORK(&server->timeout_tq, ncpdgram_timeout_proc);
653 		server->timeout_tm.data = (unsigned long)server;
654 		server->timeout_tm.function = ncpdgram_timeout_call;
655 	}
656 	release_sock(sock->sk);
657 
658 	ncp_lock_server(server);
659 	error = ncp_connect(server);
660 	ncp_unlock_server(server);
661 	if (error < 0)
662 		goto out_rxbuf;
663 	ncp_dbg(1, "NCP_SBP(sb) = %p\n", NCP_SBP(sb));
664 
665 	error = -EMSGSIZE;	/* -EREMOTESIDEINCOMPATIBLE */
666 #ifdef CONFIG_NCPFS_PACKET_SIGNING
667 	if (ncp_negotiate_size_and_options(server, default_bufsize,
668 		NCP_DEFAULT_OPTIONS, &(server->buffer_size), &options) == 0)
669 	{
670 		if (options != NCP_DEFAULT_OPTIONS)
671 		{
672 			if (ncp_negotiate_size_and_options(server,
673 				default_bufsize,
674 				options & 2,
675 				&(server->buffer_size), &options) != 0)
676 
677 			{
678 				goto out_disconnect;
679 			}
680 		}
681 		ncp_lock_server(server);
682 		if (options & 2)
683 			server->sign_wanted = 1;
684 		ncp_unlock_server(server);
685 	}
686 	else
687 #endif	/* CONFIG_NCPFS_PACKET_SIGNING */
688 	if (ncp_negotiate_buffersize(server, default_bufsize,
689   				     &(server->buffer_size)) != 0)
690 		goto out_disconnect;
691 	ncp_dbg(1, "bufsize = %d\n", server->buffer_size);
692 
693 	memset(&finfo, 0, sizeof(finfo));
694 	finfo.i.attributes	= aDIR;
695 	finfo.i.dataStreamSize	= 0;	/* ignored */
696 	finfo.i.dirEntNum	= 0;
697 	finfo.i.DosDirNum	= 0;
698 #ifdef CONFIG_NCPFS_SMALLDOS
699 	finfo.i.NSCreator	= NW_NS_DOS;
700 #endif
701 	finfo.volume		= NCP_NUMBER_OF_VOLUMES;
702 	/* set dates of mountpoint to Jan 1, 1986; 00:00 */
703 	finfo.i.creationTime	= finfo.i.modifyTime
704 				= cpu_to_le16(0x0000);
705 	finfo.i.creationDate	= finfo.i.modifyDate
706 				= finfo.i.lastAccessDate
707 				= cpu_to_le16(0x0C21);
708 	finfo.i.nameLen		= 0;
709 	finfo.i.entryName[0]	= '\0';
710 
711 	finfo.opened		= 0;
712 	finfo.ino		= 2;	/* tradition */
713 
714 	server->name_space[finfo.volume] = NW_NS_DOS;
715 
716 	error = -ENOMEM;
717         root_inode = ncp_iget(sb, &finfo);
718         if (!root_inode)
719 		goto out_disconnect;
720 	ncp_dbg(1, "root vol=%d\n", NCP_FINFO(root_inode)->volNumber);
721 	sb->s_root = d_make_root(root_inode);
722         if (!sb->s_root)
723 		goto out_disconnect;
724 	return 0;
725 
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_sock)
747 		sockfd_put(server->info_sock);
748 out_fput:
749 	sockfd_put(sock);
750 out:
751 	put_pid(data.wdog_pid);
752 	sb->s_fs_info = NULL;
753 	kfree(server);
754 	return error;
755 }
756 
delayed_free(struct rcu_head * p)757 static void delayed_free(struct rcu_head *p)
758 {
759 	struct ncp_server *server = container_of(p, struct ncp_server, rcu);
760 #ifdef CONFIG_NCPFS_NLS
761 	/* unload the NLS charsets */
762 	unload_nls(server->nls_vol);
763 	unload_nls(server->nls_io);
764 #endif /* CONFIG_NCPFS_NLS */
765 	kfree(server);
766 }
767 
ncp_put_super(struct super_block * sb)768 static void ncp_put_super(struct super_block *sb)
769 {
770 	struct ncp_server *server = NCP_SBP(sb);
771 
772 	ncp_lock_server(server);
773 	ncp_disconnect(server);
774 	ncp_unlock_server(server);
775 
776 	ncp_stop_tasks(server);
777 
778 	mutex_destroy(&server->rcv.creq_mutex);
779 	mutex_destroy(&server->root_setup_lock);
780 	mutex_destroy(&server->mutex);
781 
782 	if (server->info_sock)
783 		sockfd_put(server->info_sock);
784 	sockfd_put(server->ncp_sock);
785 	kill_pid(server->m.wdog_pid, SIGTERM, 1);
786 	put_pid(server->m.wdog_pid);
787 
788 	kfree(server->priv.data);
789 	kfree(server->auth.object_name);
790 	vfree(server->rxbuf);
791 	vfree(server->txbuf);
792 	vfree(server->packet);
793 	call_rcu(&server->rcu, delayed_free);
794 }
795 
ncp_statfs(struct dentry * dentry,struct kstatfs * buf)796 static int ncp_statfs(struct dentry *dentry, struct kstatfs *buf)
797 {
798 	struct dentry* d;
799 	struct inode* i;
800 	struct ncp_inode_info* ni;
801 	struct ncp_server* s;
802 	struct ncp_volume_info vi;
803 	struct super_block *sb = dentry->d_sb;
804 	int err;
805 	__u8 dh;
806 
807 	d = sb->s_root;
808 	if (!d) {
809 		goto dflt;
810 	}
811 	i = d_inode(d);
812 	if (!i) {
813 		goto dflt;
814 	}
815 	ni = NCP_FINFO(i);
816 	if (!ni) {
817 		goto dflt;
818 	}
819 	s = NCP_SBP(sb);
820 	if (!s) {
821 		goto dflt;
822 	}
823 	if (!s->m.mounted_vol[0]) {
824 		goto dflt;
825 	}
826 
827 	err = ncp_dirhandle_alloc(s, ni->volNumber, ni->DosDirNum, &dh);
828 	if (err) {
829 		goto dflt;
830 	}
831 	err = ncp_get_directory_info(s, dh, &vi);
832 	ncp_dirhandle_free(s, dh);
833 	if (err) {
834 		goto dflt;
835 	}
836 	buf->f_type = NCP_SUPER_MAGIC;
837 	buf->f_bsize = vi.sectors_per_block * 512;
838 	buf->f_blocks = vi.total_blocks;
839 	buf->f_bfree = vi.free_blocks;
840 	buf->f_bavail = vi.free_blocks;
841 	buf->f_files = vi.total_dir_entries;
842 	buf->f_ffree = vi.available_dir_entries;
843 	buf->f_namelen = 12;
844 	return 0;
845 
846 	/* We cannot say how much disk space is left on a mounted
847 	   NetWare Server, because free space is distributed over
848 	   volumes, and the current user might have disk quotas. So
849 	   free space is not that simple to determine. Our decision
850 	   here is to err conservatively. */
851 
852 dflt:;
853 	buf->f_type = NCP_SUPER_MAGIC;
854 	buf->f_bsize = NCP_BLOCK_SIZE;
855 	buf->f_blocks = 0;
856 	buf->f_bfree = 0;
857 	buf->f_bavail = 0;
858 	buf->f_namelen = 12;
859 	return 0;
860 }
861 
ncp_notify_change(struct dentry * dentry,struct iattr * attr)862 int ncp_notify_change(struct dentry *dentry, struct iattr *attr)
863 {
864 	struct inode *inode = d_inode(dentry);
865 	int result = 0;
866 	__le32 info_mask;
867 	struct nw_modify_dos_info info;
868 	struct ncp_server *server;
869 
870 	result = -EIO;
871 
872 	server = NCP_SERVER(inode);
873 	if (!server)	/* How this could happen? */
874 		goto out;
875 
876 	result = -EPERM;
877 	if (IS_DEADDIR(d_inode(dentry)))
878 		goto out;
879 
880 	/* ageing the dentry to force validation */
881 	ncp_age_dentry(server, dentry);
882 
883 	result = setattr_prepare(dentry, attr);
884 	if (result < 0)
885 		goto out;
886 
887 	result = -EPERM;
888 	if ((attr->ia_valid & ATTR_UID) && !uid_eq(attr->ia_uid, server->m.uid))
889 		goto out;
890 
891 	if ((attr->ia_valid & ATTR_GID) && !gid_eq(attr->ia_gid, server->m.gid))
892 		goto out;
893 
894 	if (((attr->ia_valid & ATTR_MODE) &&
895 	     (attr->ia_mode &
896 	      ~(S_IFREG | S_IFDIR | S_IRWXUGO))))
897 		goto out;
898 
899 	info_mask = 0;
900 	memset(&info, 0, sizeof(info));
901 
902 #if 1
903         if ((attr->ia_valid & ATTR_MODE) != 0)
904         {
905 		umode_t newmode = attr->ia_mode;
906 
907 		info_mask |= DM_ATTRIBUTES;
908 
909                 if (S_ISDIR(inode->i_mode)) {
910                 	newmode &= server->m.dir_mode;
911 		} else {
912 #ifdef CONFIG_NCPFS_EXTRAS
913 			if (server->m.flags & NCP_MOUNT_EXTRAS) {
914 				/* any non-default execute bit set */
915 				if (newmode & ~server->m.file_mode & S_IXUGO)
916 					info.attributes |= aSHARED | aSYSTEM;
917 				/* read for group/world and not in default file_mode */
918 				else if (newmode & ~server->m.file_mode & S_IRUGO)
919 					info.attributes |= aSHARED;
920 			} else
921 #endif
922 				newmode &= server->m.file_mode;
923                 }
924                 if (newmode & S_IWUGO)
925                 	info.attributes &= ~(aRONLY|aRENAMEINHIBIT|aDELETEINHIBIT);
926                 else
927 			info.attributes |=  (aRONLY|aRENAMEINHIBIT|aDELETEINHIBIT);
928 
929 #ifdef CONFIG_NCPFS_NFS_NS
930 		if (ncp_is_nfs_extras(server, NCP_FINFO(inode)->volNumber)) {
931 			result = ncp_modify_nfs_info(server,
932 						     NCP_FINFO(inode)->volNumber,
933 						     NCP_FINFO(inode)->dirEntNum,
934 						     attr->ia_mode, 0);
935 			if (result != 0)
936 				goto out;
937 			info.attributes &= ~(aSHARED | aSYSTEM);
938 			{
939 				/* mark partial success */
940 				struct iattr tmpattr;
941 
942 				tmpattr.ia_valid = ATTR_MODE;
943 				tmpattr.ia_mode = attr->ia_mode;
944 
945 				setattr_copy(inode, &tmpattr);
946 				mark_inode_dirty(inode);
947 			}
948 		}
949 #endif
950         }
951 #endif
952 
953 	/* Do SIZE before attributes, otherwise mtime together with size does not work...
954 	 */
955 	if ((attr->ia_valid & ATTR_SIZE) != 0) {
956 		int written;
957 
958 		ncp_dbg(1, "trying to change size to %llu\n", attr->ia_size);
959 
960 		if ((result = ncp_make_open(inode, O_WRONLY)) < 0) {
961 			result = -EACCES;
962 			goto out;
963 		}
964 		ncp_write_kernel(NCP_SERVER(inode), NCP_FINFO(inode)->file_handle,
965 			  attr->ia_size, 0, "", &written);
966 
967 		/* According to ndir, the changes only take effect after
968 		   closing the file */
969 		ncp_inode_close(inode);
970 		result = ncp_make_closed(inode);
971 		if (result)
972 			goto out;
973 
974 		if (attr->ia_size != i_size_read(inode)) {
975 			truncate_setsize(inode, attr->ia_size);
976 			mark_inode_dirty(inode);
977 		}
978 	}
979 	if ((attr->ia_valid & ATTR_CTIME) != 0) {
980 		info_mask |= (DM_CREATE_TIME | DM_CREATE_DATE);
981 		ncp_date_unix2dos(attr->ia_ctime.tv_sec,
982 			     &info.creationTime, &info.creationDate);
983 	}
984 	if ((attr->ia_valid & ATTR_MTIME) != 0) {
985 		info_mask |= (DM_MODIFY_TIME | DM_MODIFY_DATE);
986 		ncp_date_unix2dos(attr->ia_mtime.tv_sec,
987 				  &info.modifyTime, &info.modifyDate);
988 	}
989 	if ((attr->ia_valid & ATTR_ATIME) != 0) {
990 		__le16 dummy;
991 		info_mask |= (DM_LAST_ACCESS_DATE);
992 		ncp_date_unix2dos(attr->ia_atime.tv_sec,
993 				  &dummy, &info.lastAccessDate);
994 	}
995 	if (info_mask != 0) {
996 		result = ncp_modify_file_or_subdir_dos_info(NCP_SERVER(inode),
997 				      inode, info_mask, &info);
998 		if (result != 0) {
999 			if (info_mask == (DM_CREATE_TIME | DM_CREATE_DATE)) {
1000 				/* NetWare seems not to allow this. I
1001 				   do not know why. So, just tell the
1002 				   user everything went fine. This is
1003 				   a terrible hack, but I do not know
1004 				   how to do this correctly. */
1005 				result = 0;
1006 			} else
1007 				goto out;
1008 		}
1009 #ifdef CONFIG_NCPFS_STRONG
1010 		if ((!result) && (info_mask & DM_ATTRIBUTES))
1011 			NCP_FINFO(inode)->nwattr = info.attributes;
1012 #endif
1013 	}
1014 	if (result)
1015 		goto out;
1016 
1017 	setattr_copy(inode, attr);
1018 	mark_inode_dirty(inode);
1019 
1020 out:
1021 	if (result > 0)
1022 		result = -EACCES;
1023 	return result;
1024 }
1025 
ncp_mount(struct file_system_type * fs_type,int flags,const char * dev_name,void * data)1026 static struct dentry *ncp_mount(struct file_system_type *fs_type,
1027 	int flags, const char *dev_name, void *data)
1028 {
1029 	return mount_nodev(fs_type, flags, data, ncp_fill_super);
1030 }
1031 
1032 static struct file_system_type ncp_fs_type = {
1033 	.owner		= THIS_MODULE,
1034 	.name		= "ncpfs",
1035 	.mount		= ncp_mount,
1036 	.kill_sb	= kill_anon_super,
1037 	.fs_flags	= FS_BINARY_MOUNTDATA,
1038 };
1039 MODULE_ALIAS_FS("ncpfs");
1040 
init_ncp_fs(void)1041 static int __init init_ncp_fs(void)
1042 {
1043 	int err;
1044 	ncp_dbg(1, "called\n");
1045 
1046 	err = init_inodecache();
1047 	if (err)
1048 		goto out1;
1049 	err = register_filesystem(&ncp_fs_type);
1050 	if (err)
1051 		goto out;
1052 	return 0;
1053 out:
1054 	destroy_inodecache();
1055 out1:
1056 	return err;
1057 }
1058 
exit_ncp_fs(void)1059 static void __exit exit_ncp_fs(void)
1060 {
1061 	ncp_dbg(1, "called\n");
1062 	unregister_filesystem(&ncp_fs_type);
1063 	destroy_inodecache();
1064 }
1065 
1066 module_init(init_ncp_fs)
1067 module_exit(exit_ncp_fs)
1068 MODULE_LICENSE("GPL");
1069