/*
 *  ioctl.c
 *
 *  Copyright (C) 1995, 1996 by Volker Lendecke
 *  Modified 1997 Peter Waltenberg, Bill Hawes, David Woodhouse for 2.1 dcache
 *  Modified 1998, 1999 Wolfram Pienkoss for NLS
 *
 */

#include <linux/capability.h>
#include <linux/compat.h>
#include <linux/errno.h>
#include <linux/fs.h>
#include <linux/ioctl.h>
#include <linux/time.h>
#include <linux/mm.h>
#include <linux/mount.h>
#include <linux/highuid.h>
#include <linux/smp_lock.h>
#include <linux/vmalloc.h>
#include <linux/sched.h>

#include <linux/ncp_fs.h>

#include <asm/uaccess.h>

#include "ncplib_kernel.h"

/* maximum limit for ncp_objectname_ioctl */
#define NCP_OBJECT_NAME_MAX_LEN	4096
/* maximum limit for ncp_privatedata_ioctl */
#define NCP_PRIVATE_DATA_MAX_LEN 8192
/* maximum negotiable packet size */
#define NCP_PACKET_SIZE_INTERNAL 65536

static int
ncp_get_fs_info(struct ncp_server * server, struct file *file,
		struct ncp_fs_info __user *arg)
{
	struct inode *inode = file->f_path.dentry->d_inode;
	struct ncp_fs_info info;

	if (file_permission(file, MAY_WRITE) != 0
	    && current_uid() != server->m.mounted_uid)
		return -EACCES;

	if (copy_from_user(&info, arg, sizeof(info)))
		return -EFAULT;

	if (info.version != NCP_GET_FS_INFO_VERSION) {
		DPRINTK("info.version invalid: %d\n", info.version);
		return -EINVAL;
	}
	/* TODO: info.addr = server->m.serv_addr; */
	SET_UID(info.mounted_uid, server->m.mounted_uid);
	info.connection		= server->connection;
	info.buffer_size	= server->buffer_size;
	info.volume_number	= NCP_FINFO(inode)->volNumber;
	info.directory_id	= NCP_FINFO(inode)->DosDirNum;

	if (copy_to_user(arg, &info, sizeof(info)))
		return -EFAULT;
	return 0;
}

static int
ncp_get_fs_info_v2(struct ncp_server * server, struct file *file,
		   struct ncp_fs_info_v2 __user * arg)
{
	struct inode *inode = file->f_path.dentry->d_inode;
	struct ncp_fs_info_v2 info2;

	if (file_permission(file, MAY_WRITE) != 0
	    && current_uid() != server->m.mounted_uid)
		return -EACCES;

	if (copy_from_user(&info2, arg, sizeof(info2)))
		return -EFAULT;

	if (info2.version != NCP_GET_FS_INFO_VERSION_V2) {
		DPRINTK("info.version invalid: %d\n", info2.version);
		return -EINVAL;
	}
	info2.mounted_uid   = server->m.mounted_uid;
	info2.connection    = server->connection;
	info2.buffer_size   = server->buffer_size;
	info2.volume_number = NCP_FINFO(inode)->volNumber;
	info2.directory_id  = NCP_FINFO(inode)->DosDirNum;
	info2.dummy1 = info2.dummy2 = info2.dummy3 = 0;

	if (copy_to_user(arg, &info2, sizeof(info2)))
		return -EFAULT;
	return 0;
}

#ifdef CONFIG_COMPAT
struct compat_ncp_objectname_ioctl
{
	s32		auth_type;
	u32		object_name_len;
	compat_caddr_t	object_name;	/* a userspace data, in most cases user name */
};

struct compat_ncp_fs_info_v2 {
	s32 version;
	u32 mounted_uid;
	u32 connection;
	u32 buffer_size;

	u32 volume_number;
	u32 directory_id;

	u32 dummy1;
	u32 dummy2;
	u32 dummy3;
};

struct compat_ncp_ioctl_request {
	u32 function;
	u32 size;
	compat_caddr_t data;
};

struct compat_ncp_privatedata_ioctl
{
	u32		len;
	compat_caddr_t	data;		/* ~1000 for NDS */
};

#define NCP_IOC_GET_FS_INFO_V2_32	_IOWR('n', 4, struct compat_ncp_fs_info_v2)
#define NCP_IOC_NCPREQUEST_32		_IOR('n', 1, struct compat_ncp_ioctl_request)
#define NCP_IOC_GETOBJECTNAME_32	_IOWR('n', 9, struct compat_ncp_objectname_ioctl)
#define NCP_IOC_SETOBJECTNAME_32	_IOR('n', 9, struct compat_ncp_objectname_ioctl)
#define NCP_IOC_GETPRIVATEDATA_32	_IOWR('n', 10, struct compat_ncp_privatedata_ioctl)
#define NCP_IOC_SETPRIVATEDATA_32	_IOR('n', 10, struct compat_ncp_privatedata_ioctl)

static int
ncp_get_compat_fs_info_v2(struct ncp_server * server, struct file *file,
		   struct compat_ncp_fs_info_v2 __user * arg)
{
	struct inode *inode = file->f_path.dentry->d_inode;
	struct compat_ncp_fs_info_v2 info2;

	if (file_permission(file, MAY_WRITE) != 0
	    && current_uid() != server->m.mounted_uid)
		return -EACCES;

	if (copy_from_user(&info2, arg, sizeof(info2)))
		return -EFAULT;

	if (info2.version != NCP_GET_FS_INFO_VERSION_V2) {
		DPRINTK("info.version invalid: %d\n", info2.version);
		return -EINVAL;
	}
	info2.mounted_uid   = server->m.mounted_uid;
	info2.connection    = server->connection;
	info2.buffer_size   = server->buffer_size;
	info2.volume_number = NCP_FINFO(inode)->volNumber;
	info2.directory_id  = NCP_FINFO(inode)->DosDirNum;
	info2.dummy1 = info2.dummy2 = info2.dummy3 = 0;

	if (copy_to_user(arg, &info2, sizeof(info2)))
		return -EFAULT;
	return 0;
}
#endif

#define NCP_IOC_GETMOUNTUID16		_IOW('n', 2, u16)
#define NCP_IOC_GETMOUNTUID32		_IOW('n', 2, u32)
#define NCP_IOC_GETMOUNTUID64		_IOW('n', 2, u64)

#ifdef CONFIG_NCPFS_NLS
/* Here we are select the iocharset and the codepage for NLS.
 * Thanks Petr Vandrovec for idea and many hints.
 */
static int
ncp_set_charsets(struct ncp_server* server, struct ncp_nls_ioctl __user *arg)
{
	struct ncp_nls_ioctl user;
	struct nls_table *codepage;
	struct nls_table *iocharset;
	struct nls_table *oldset_io;
	struct nls_table *oldset_cp;

	if (!capable(CAP_SYS_ADMIN))
		return -EACCES;
	if (server->root_setuped)
		return -EBUSY;

	if (copy_from_user(&user, arg, sizeof(user)))
		return -EFAULT;

	codepage = NULL;
	user.codepage[NCP_IOCSNAME_LEN] = 0;
	if (!user.codepage[0] || !strcmp(user.codepage, "default"))
		codepage = load_nls_default();
	else {
		codepage = load_nls(user.codepage);
		if (!codepage) {
			return -EBADRQC;
		}
	}

	iocharset = NULL;
	user.iocharset[NCP_IOCSNAME_LEN] = 0;
	if (!user.iocharset[0] || !strcmp(user.iocharset, "default")) {
		iocharset = load_nls_default();
		NCP_CLR_FLAG(server, NCP_FLAG_UTF8);
	} else if (!strcmp(user.iocharset, "utf8")) {
		iocharset = load_nls_default();
		NCP_SET_FLAG(server, NCP_FLAG_UTF8);
	} else {
		iocharset = load_nls(user.iocharset);
		if (!iocharset) {
			unload_nls(codepage);
			return -EBADRQC;
		}
		NCP_CLR_FLAG(server, NCP_FLAG_UTF8);
	}

	oldset_cp = server->nls_vol;
	server->nls_vol = codepage;
	oldset_io = server->nls_io;
	server->nls_io = iocharset;

	if (oldset_cp)
		unload_nls(oldset_cp);
	if (oldset_io)
		unload_nls(oldset_io);

	return 0;
}

static int
ncp_get_charsets(struct ncp_server* server, struct ncp_nls_ioctl __user *arg)
{
	struct ncp_nls_ioctl user;
	int len;

	memset(&user, 0, sizeof(user));
	if (server->nls_vol && server->nls_vol->charset) {
		len = strlen(server->nls_vol->charset);
		if (len > NCP_IOCSNAME_LEN)
			len = NCP_IOCSNAME_LEN;
		strncpy(user.codepage, server->nls_vol->charset, len);
		user.codepage[len] = 0;
	}

	if (NCP_IS_FLAG(server, NCP_FLAG_UTF8))
		strcpy(user.iocharset, "utf8");
	else if (server->nls_io && server->nls_io->charset) {
		len = strlen(server->nls_io->charset);
		if (len > NCP_IOCSNAME_LEN)
			len = NCP_IOCSNAME_LEN;
		strncpy(user.iocharset,	server->nls_io->charset, len);
		user.iocharset[len] = 0;
	}

	if (copy_to_user(arg, &user, sizeof(user)))
		return -EFAULT;
	return 0;
}
#endif /* CONFIG_NCPFS_NLS */

static int __ncp_ioctl(struct inode *inode, struct file *filp,
	      unsigned int cmd, unsigned long arg)
{
	struct ncp_server *server = NCP_SERVER(inode);
	int result;
	struct ncp_ioctl_request request;
	char* bouncebuffer;
	void __user *argp = (void __user *)arg;
	uid_t uid = current_uid();

	switch (cmd) {
#ifdef CONFIG_COMPAT
	case NCP_IOC_NCPREQUEST_32:
#endif
	case NCP_IOC_NCPREQUEST:
		if (file_permission(filp, MAY_WRITE) != 0
		    && uid != server->m.mounted_uid)
			return -EACCES;

#ifdef CONFIG_COMPAT
		if (cmd == NCP_IOC_NCPREQUEST_32) {
			struct compat_ncp_ioctl_request request32;
			if (copy_from_user(&request32, argp, sizeof(request32)))
				return -EFAULT;
			request.function = request32.function;
			request.size = request32.size;
			request.data = compat_ptr(request32.data);
		} else
#endif
		if (copy_from_user(&request, argp, sizeof(request)))
			return -EFAULT;

		if ((request.function > 255)
		    || (request.size >
		  NCP_PACKET_SIZE - sizeof(struct ncp_request_header))) {
			return -EINVAL;
		}
		bouncebuffer = vmalloc(NCP_PACKET_SIZE_INTERNAL);
		if (!bouncebuffer)
			return -ENOMEM;
		if (copy_from_user(bouncebuffer, request.data, request.size)) {
			vfree(bouncebuffer);
			return -EFAULT;
		}
		ncp_lock_server(server);

		/* FIXME: We hack around in the server's structures
		   here to be able to use ncp_request */

		server->has_subfunction = 0;
		server->current_size = request.size;
		memcpy(server->packet, bouncebuffer, request.size);

		result = ncp_request2(server, request.function, 
			bouncebuffer, NCP_PACKET_SIZE_INTERNAL);
		if (result < 0)
			result = -EIO;
		else
			result = server->reply_size;
		ncp_unlock_server(server);
		DPRINTK("ncp_ioctl: copy %d bytes\n",
			result);
		if (result >= 0)
			if (copy_to_user(request.data, bouncebuffer, result))
				result = -EFAULT;
		vfree(bouncebuffer);
		return result;

	case NCP_IOC_CONN_LOGGED_IN:

		if (!capable(CAP_SYS_ADMIN))
			return -EACCES;
		if (!(server->m.int_flags & NCP_IMOUNT_LOGGEDIN_POSSIBLE))
			return -EINVAL;
		if (server->root_setuped)
			return -EBUSY;
		server->root_setuped = 1;
		return ncp_conn_logged_in(inode->i_sb);

	case NCP_IOC_GET_FS_INFO:
		return ncp_get_fs_info(server, filp, argp);

	case NCP_IOC_GET_FS_INFO_V2:
		return ncp_get_fs_info_v2(server, filp, argp);

#ifdef CONFIG_COMPAT
	case NCP_IOC_GET_FS_INFO_V2_32:
		return ncp_get_compat_fs_info_v2(server, filp, argp);
#endif
	/* we have too many combinations of CONFIG_COMPAT,
	 * CONFIG_64BIT and CONFIG_UID16, so just handle
	 * any of the possible ioctls */
	case NCP_IOC_GETMOUNTUID16:
	case NCP_IOC_GETMOUNTUID32:
	case NCP_IOC_GETMOUNTUID64:
		if (file_permission(filp, MAY_READ) != 0
			&& uid != server->m.mounted_uid)
			return -EACCES;

		if (cmd == NCP_IOC_GETMOUNTUID16) {
			u16 uid;
			SET_UID(uid, server->m.mounted_uid);
			if (put_user(uid, (u16 __user *)argp))
				return -EFAULT;
		} else if (cmd == NCP_IOC_GETMOUNTUID32) {
			if (put_user(server->m.mounted_uid,
						(u32 __user *)argp))
				return -EFAULT;
		} else {
			if (put_user(server->m.mounted_uid,
						(u64 __user *)argp))
				return -EFAULT;
		}
		return 0;

	case NCP_IOC_GETROOT:
		{
			struct ncp_setroot_ioctl sr;

			if (file_permission(filp, MAY_READ) != 0
			    && uid != server->m.mounted_uid)
				return -EACCES;

			if (server->m.mounted_vol[0]) {
				struct dentry* dentry = inode->i_sb->s_root;

				if (dentry) {
					struct inode* s_inode = dentry->d_inode;
				
					if (s_inode) {
						sr.volNumber = NCP_FINFO(s_inode)->volNumber;
						sr.dirEntNum = NCP_FINFO(s_inode)->dirEntNum;
						sr.namespace = server->name_space[sr.volNumber];
					} else
						DPRINTK("ncpfs: s_root->d_inode==NULL\n");
				} else
					DPRINTK("ncpfs: s_root==NULL\n");
			} else {
				sr.volNumber = -1;
				sr.namespace = 0;
				sr.dirEntNum = 0;
			}
			if (copy_to_user(argp, &sr, sizeof(sr)))
				return -EFAULT;
			return 0;
		}

	case NCP_IOC_SETROOT:
		{
			struct ncp_setroot_ioctl sr;
			__u32 vnum;
			__le32 de;
			__le32 dosde;
			struct dentry* dentry;

			if (!capable(CAP_SYS_ADMIN))
			{
				return -EACCES;
			}
			if (server->root_setuped) return -EBUSY;
			if (copy_from_user(&sr, argp, sizeof(sr)))
				return -EFAULT;
			if (sr.volNumber < 0) {
				server->m.mounted_vol[0] = 0;
				vnum = NCP_NUMBER_OF_VOLUMES;
				de = 0;
				dosde = 0;
			} else if (sr.volNumber >= NCP_NUMBER_OF_VOLUMES) {
				return -EINVAL;
			} else if (ncp_mount_subdir(server, sr.volNumber,
						sr.namespace, sr.dirEntNum,
						&vnum, &de, &dosde)) {
				return -ENOENT;
			}
			
			dentry = inode->i_sb->s_root;
			server->root_setuped = 1;
			if (dentry) {
				struct inode* s_inode = dentry->d_inode;
				
				if (inode) {
					NCP_FINFO(s_inode)->volNumber = vnum;
					NCP_FINFO(s_inode)->dirEntNum = de;
					NCP_FINFO(s_inode)->DosDirNum = dosde;
				} else
					DPRINTK("ncpfs: s_root->d_inode==NULL\n");
			} else
				DPRINTK("ncpfs: s_root==NULL\n");

			return 0;
		}

#ifdef CONFIG_NCPFS_PACKET_SIGNING	
	case NCP_IOC_SIGN_INIT:
		if (file_permission(filp, MAY_WRITE) != 0
		    && uid != server->m.mounted_uid)
			return -EACCES;

		if (argp) {
			if (server->sign_wanted)
			{
				struct ncp_sign_init sign;

				if (copy_from_user(&sign, argp, sizeof(sign)))
					return -EFAULT;
				memcpy(server->sign_root,sign.sign_root,8);
				memcpy(server->sign_last,sign.sign_last,16);
				server->sign_active = 1;
			}
			/* ignore when signatures not wanted */
		} else {
			server->sign_active = 0;
		}
		return 0;		
		
        case NCP_IOC_SIGN_WANTED:
		if (file_permission(filp, MAY_READ) != 0
		    && uid != server->m.mounted_uid)
			return -EACCES;
		
                if (put_user(server->sign_wanted, (int __user *)argp))
			return -EFAULT;
                return 0;

	case NCP_IOC_SET_SIGN_WANTED:
		{
			int newstate;

			if (file_permission(filp, MAY_WRITE) != 0
			    && uid != server->m.mounted_uid)
				return -EACCES;

			/* get only low 8 bits... */
			if (get_user(newstate, (unsigned char __user *)argp))
				return -EFAULT;
			if (server->sign_active) {
				/* cannot turn signatures OFF when active */
				if (!newstate) return -EINVAL;
			} else {
				server->sign_wanted = newstate != 0;
			}
			return 0;
		}

#endif /* CONFIG_NCPFS_PACKET_SIGNING */

#ifdef CONFIG_NCPFS_IOCTL_LOCKING
	case NCP_IOC_LOCKUNLOCK:
		if (file_permission(filp, MAY_WRITE) != 0
		    && uid != server->m.mounted_uid)
			return -EACCES;

		{
			struct ncp_lock_ioctl	 rqdata;

			if (copy_from_user(&rqdata, argp, sizeof(rqdata)))
				return -EFAULT;
			if (rqdata.origin != 0)
				return -EINVAL;
			/* check for cmd */
			switch (rqdata.cmd) {
				case NCP_LOCK_EX:
				case NCP_LOCK_SH:
						if (rqdata.timeout == 0)
							rqdata.timeout = NCP_LOCK_DEFAULT_TIMEOUT;
						else if (rqdata.timeout > NCP_LOCK_MAX_TIMEOUT)
							rqdata.timeout = NCP_LOCK_MAX_TIMEOUT;
						break;
				case NCP_LOCK_LOG:
						rqdata.timeout = NCP_LOCK_DEFAULT_TIMEOUT;	/* has no effect */
				case NCP_LOCK_CLEAR:
						break;
				default:
						return -EINVAL;
			}
			/* locking needs both read and write access */
			if ((result = ncp_make_open(inode, O_RDWR)) != 0)
			{
				return result;
			}
			result = -EIO;
			if (!ncp_conn_valid(server))
				goto outrel;
			result = -EISDIR;
			if (!S_ISREG(inode->i_mode))
				goto outrel;
			if (rqdata.cmd == NCP_LOCK_CLEAR)
			{
				result = ncp_ClearPhysicalRecord(NCP_SERVER(inode),
							NCP_FINFO(inode)->file_handle, 
							rqdata.offset,
							rqdata.length);
				if (result > 0) result = 0;	/* no such lock */
			}
			else
			{
				int lockcmd;

				switch (rqdata.cmd)
				{
					case NCP_LOCK_EX:  lockcmd=1; break;
					case NCP_LOCK_SH:  lockcmd=3; break;
					default:	   lockcmd=0; break;
				}
				result = ncp_LogPhysicalRecord(NCP_SERVER(inode),
							NCP_FINFO(inode)->file_handle,
							lockcmd,
							rqdata.offset,
							rqdata.length,
							rqdata.timeout);
				if (result > 0) result = -EAGAIN;
			}
outrel:			
			ncp_inode_close(inode);
			return result;
		}
#endif	/* CONFIG_NCPFS_IOCTL_LOCKING */

#ifdef CONFIG_COMPAT
	case NCP_IOC_GETOBJECTNAME_32:
		if (uid != server->m.mounted_uid)
			return -EACCES;
		{
			struct compat_ncp_objectname_ioctl user;
			size_t outl;

			if (copy_from_user(&user, argp, sizeof(user)))
				return -EFAULT;
			user.auth_type = server->auth.auth_type;
			outl = user.object_name_len;
			user.object_name_len = server->auth.object_name_len;
			if (outl > user.object_name_len)
				outl = user.object_name_len;
			if (outl) {
				if (copy_to_user(compat_ptr(user.object_name),
						 server->auth.object_name,
						 outl)) return -EFAULT;
			}
			if (copy_to_user(argp, &user, sizeof(user)))
				return -EFAULT;
			return 0;
		}
#endif

	case NCP_IOC_GETOBJECTNAME:
		if (uid != server->m.mounted_uid)
			return -EACCES;
		{
			struct ncp_objectname_ioctl user;
			size_t outl;

			if (copy_from_user(&user, argp, sizeof(user)))
				return -EFAULT;
			user.auth_type = server->auth.auth_type;
			outl = user.object_name_len;
			user.object_name_len = server->auth.object_name_len;
			if (outl > user.object_name_len)
				outl = user.object_name_len;
			if (outl) {
				if (copy_to_user(user.object_name,
						 server->auth.object_name,
						 outl)) return -EFAULT;
			}
			if (copy_to_user(argp, &user, sizeof(user)))
				return -EFAULT;
			return 0;
		}

#ifdef CONFIG_COMPAT
	case NCP_IOC_SETOBJECTNAME_32:
#endif
	case NCP_IOC_SETOBJECTNAME:
		if (uid != server->m.mounted_uid)
			return -EACCES;
		{
			struct ncp_objectname_ioctl user;
			void* newname;
			void* oldname;
			size_t oldnamelen;
			void* oldprivate;
			size_t oldprivatelen;

#ifdef CONFIG_COMPAT
			if (cmd == NCP_IOC_SETOBJECTNAME_32) {
				struct compat_ncp_objectname_ioctl user32;
				if (copy_from_user(&user32, argp, sizeof(user32)))
					return -EFAULT;
				user.auth_type = user32.auth_type;
				user.object_name_len = user32.object_name_len;
				user.object_name = compat_ptr(user32.object_name);
			} else
#endif
			if (copy_from_user(&user, argp, sizeof(user)))
				return -EFAULT;

			if (user.object_name_len > NCP_OBJECT_NAME_MAX_LEN)
				return -ENOMEM;
			if (user.object_name_len) {
				newname = memdup_user(user.object_name,
						      user.object_name_len);
				if (IS_ERR(newname))
					return PTR_ERR(newname);
			} else {
				newname = NULL;
			}
			/* enter critical section */
			/* maybe that kfree can sleep so do that this way */
			/* it is at least more SMP friendly (in future...) */
			oldname = server->auth.object_name;
			oldnamelen = server->auth.object_name_len;
			oldprivate = server->priv.data;
			oldprivatelen = server->priv.len;
			server->auth.auth_type = user.auth_type;
			server->auth.object_name_len = user.object_name_len;
			server->auth.object_name = newname;
			server->priv.len = 0;
			server->priv.data = NULL;
			/* leave critical section */
			kfree(oldprivate);
			kfree(oldname);
			return 0;
		}

#ifdef CONFIG_COMPAT
	case NCP_IOC_GETPRIVATEDATA_32:
#endif
	case NCP_IOC_GETPRIVATEDATA:
		if (uid != server->m.mounted_uid)
			return -EACCES;
		{
			struct ncp_privatedata_ioctl user;
			size_t outl;

#ifdef CONFIG_COMPAT
			if (cmd == NCP_IOC_GETPRIVATEDATA_32) {
				struct compat_ncp_privatedata_ioctl user32;
				if (copy_from_user(&user32, argp, sizeof(user32)))
					return -EFAULT;
				user.len = user32.len;
				user.data = compat_ptr(user32.data);
			} else
#endif
			if (copy_from_user(&user, argp, sizeof(user)))
				return -EFAULT;

			outl = user.len;
			user.len = server->priv.len;
			if (outl > user.len) outl = user.len;
			if (outl) {
				if (copy_to_user(user.data,
						 server->priv.data,
						 outl)) return -EFAULT;
			}
#ifdef CONFIG_COMPAT
			if (cmd == NCP_IOC_GETPRIVATEDATA_32) {
				struct compat_ncp_privatedata_ioctl user32;
				user32.len = user.len;
				user32.data = (unsigned long) user.data;
				if (copy_to_user(argp, &user32, sizeof(user32)))
					return -EFAULT;
			} else
#endif
			if (copy_to_user(argp, &user, sizeof(user)))
				return -EFAULT;

			return 0;
		}

#ifdef CONFIG_COMPAT
	case NCP_IOC_SETPRIVATEDATA_32:
#endif
	case NCP_IOC_SETPRIVATEDATA:
		if (uid != server->m.mounted_uid)
			return -EACCES;
		{
			struct ncp_privatedata_ioctl user;
			void* new;
			void* old;
			size_t oldlen;

#ifdef CONFIG_COMPAT
			if (cmd == NCP_IOC_SETPRIVATEDATA_32) {
				struct compat_ncp_privatedata_ioctl user32;
				if (copy_from_user(&user32, argp, sizeof(user32)))
					return -EFAULT;
				user.len = user32.len;
				user.data = compat_ptr(user32.data);
			} else
#endif
			if (copy_from_user(&user, argp, sizeof(user)))
				return -EFAULT;

			if (user.len > NCP_PRIVATE_DATA_MAX_LEN)
				return -ENOMEM;
			if (user.len) {
				new = memdup_user(user.data, user.len);
				if (IS_ERR(new))
					return PTR_ERR(new);
			} else {
				new = NULL;
			}
			/* enter critical section */
			old = server->priv.data;
			oldlen = server->priv.len;
			server->priv.len = user.len;
			server->priv.data = new;
			/* leave critical section */
			kfree(old);
			return 0;
		}

#ifdef CONFIG_NCPFS_NLS
	case NCP_IOC_SETCHARSETS:
		return ncp_set_charsets(server, argp);
		
	case NCP_IOC_GETCHARSETS:
		return ncp_get_charsets(server, argp);

#endif /* CONFIG_NCPFS_NLS */

	case NCP_IOC_SETDENTRYTTL:
		if (file_permission(filp, MAY_WRITE) != 0 &&
		    uid != server->m.mounted_uid)
			return -EACCES;

		{
			u_int32_t user;

			if (copy_from_user(&user, argp, sizeof(user)))
				return -EFAULT;
			/* 20 secs at most... */
			if (user > 20000)
				return -EINVAL;
			user = (user * HZ) / 1000;
			server->dentry_ttl = user;
			return 0;
		}
		
	case NCP_IOC_GETDENTRYTTL:
		{
			u_int32_t user = (server->dentry_ttl * 1000) / HZ;
			if (copy_to_user(argp, &user, sizeof(user)))
				return -EFAULT;
			return 0;
		}

	}
	return -EINVAL;
}

static int ncp_ioctl_need_write(unsigned int cmd)
{
	switch (cmd) {
	case NCP_IOC_GET_FS_INFO:
	case NCP_IOC_GET_FS_INFO_V2:
	case NCP_IOC_NCPREQUEST:
	case NCP_IOC_SETDENTRYTTL:
	case NCP_IOC_SIGN_INIT:
	case NCP_IOC_LOCKUNLOCK:
	case NCP_IOC_SET_SIGN_WANTED:
		return 1;
	case NCP_IOC_GETOBJECTNAME:
	case NCP_IOC_SETOBJECTNAME:
	case NCP_IOC_GETPRIVATEDATA:
	case NCP_IOC_SETPRIVATEDATA:
	case NCP_IOC_SETCHARSETS:
	case NCP_IOC_GETCHARSETS:
	case NCP_IOC_CONN_LOGGED_IN:
	case NCP_IOC_GETDENTRYTTL:
	case NCP_IOC_GETMOUNTUID2:
	case NCP_IOC_SIGN_WANTED:
	case NCP_IOC_GETROOT:
	case NCP_IOC_SETROOT:
		return 0;
	default:
		/* unkown IOCTL command, assume write */
		return 1;
	}
}

int ncp_ioctl(struct inode *inode, struct file *filp,
	      unsigned int cmd, unsigned long arg)
{
	int ret;

	if (ncp_ioctl_need_write(cmd)) {
		/*
		 * inside the ioctl(), any failures which
		 * are because of file_permission() are
		 * -EACCESS, so it seems consistent to keep
		 *  that here.
		 */
		if (mnt_want_write(filp->f_path.mnt))
			return -EACCES;
	}
	ret = __ncp_ioctl(inode, filp, cmd, arg);
	if (ncp_ioctl_need_write(cmd))
		mnt_drop_write(filp->f_path.mnt);
	return ret;
}

#ifdef CONFIG_COMPAT
long ncp_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
{
	struct inode *inode = file->f_path.dentry->d_inode;
	int ret;

	lock_kernel();
	arg = (unsigned long) compat_ptr(arg);
	ret = ncp_ioctl(inode, file, cmd, arg);
	unlock_kernel();
	return ret;
}
#endif
