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