/*
 *  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/slab.h>
#include <linux/highuid.h>
#include <linux/vmalloc.h>
#include <linux/sched.h>

#include <asm/uaccess.h>

#include "ncp_fs.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 inode *inode,
		struct ncp_fs_info __user *arg)
{
	struct ncp_fs_info info;

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

	if (info.version != NCP_GET_FS_INFO_VERSION) {
		ncp_dbg(1, "info.version invalid: %d\n", info.version);
		return -EINVAL;
	}
	/* TODO: info.addr = server->m.serv_addr; */
	SET_UID(info.mounted_uid, from_kuid_munged(current_user_ns(), 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 inode *inode,
		   struct ncp_fs_info_v2 __user * arg)
{
	struct ncp_fs_info_v2 info2;

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

	if (info2.version != NCP_GET_FS_INFO_VERSION_V2) {
		ncp_dbg(1, "info.version invalid: %d\n", info2.version);
		return -EINVAL;
	}
	info2.mounted_uid   = from_kuid_munged(current_user_ns(), 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 inode *inode,
		   struct compat_ncp_fs_info_v2 __user * arg)
{
	struct compat_ncp_fs_info_v2 info2;

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

	if (info2.version != NCP_GET_FS_INFO_VERSION_V2) {
		ncp_dbg(1, "info.version invalid: %d\n", info2.version);
		return -EINVAL;
	}
	info2.mounted_uid   = from_kuid_munged(current_user_ns(), 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;
	int utf8;
	int err;

	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();
		utf8 = 0;
	} else if (!strcmp(user.iocharset, "utf8")) {
		iocharset = load_nls_default();
		utf8 = 1;
	} else {
		iocharset = load_nls(user.iocharset);
		if (!iocharset) {
			unload_nls(codepage);
			return -EBADRQC;
		}
		utf8 = 0;
	}

	mutex_lock(&server->root_setup_lock);
	if (server->root_setuped) {
		oldset_cp = codepage;
		oldset_io = iocharset;
		err = -EBUSY;
	} else {
		if (utf8)
			NCP_SET_FLAG(server, NCP_FLAG_UTF8);
		else
			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;
		err = 0;
	}
	mutex_unlock(&server->root_setup_lock);
	unload_nls(oldset_cp);
	unload_nls(oldset_io);

	return err;
}

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));
	mutex_lock(&server->root_setup_lock);
	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;
	}
	mutex_unlock(&server->root_setup_lock);

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

static long __ncp_ioctl(struct inode *inode, 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;

	switch (cmd) {
#ifdef CONFIG_COMPAT
	case NCP_IOC_NCPREQUEST_32:
#endif
	case NCP_IOC_NCPREQUEST:
#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);
		ncp_dbg(1, "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 (!(server->m.int_flags & NCP_IMOUNT_LOGGEDIN_POSSIBLE))
			return -EINVAL;
		mutex_lock(&server->root_setup_lock);
		if (server->root_setuped)
			result = -EBUSY;
		else {
			result = ncp_conn_logged_in(inode->i_sb);
			if (result == 0)
				server->root_setuped = 1;
		}
		mutex_unlock(&server->root_setup_lock);
		return result;

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

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

#ifdef CONFIG_COMPAT
	case NCP_IOC_GET_FS_INFO_V2_32:
		return ncp_get_compat_fs_info_v2(server, inode, 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:
		{
			u16 uid;

			SET_UID(uid, from_kuid_munged(current_user_ns(), server->m.mounted_uid));
			if (put_user(uid, (u16 __user *)argp))
				return -EFAULT;
			return 0;
		}
	case NCP_IOC_GETMOUNTUID32:
	{
		uid_t uid = from_kuid_munged(current_user_ns(), server->m.mounted_uid);
		if (put_user(uid, (u32 __user *)argp))
			return -EFAULT;
		return 0;
	}
	case NCP_IOC_GETMOUNTUID64:
	{
		uid_t uid = from_kuid_munged(current_user_ns(), server->m.mounted_uid);
		if (put_user(uid, (u64 __user *)argp))
			return -EFAULT;
		return 0;
	}
	case NCP_IOC_GETROOT:
		{
			struct ncp_setroot_ioctl sr;

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

				if (dentry) {
					struct inode* s_inode = d_inode(dentry);

					if (s_inode) {
						sr.volNumber = NCP_FINFO(s_inode)->volNumber;
						sr.dirEntNum = NCP_FINFO(s_inode)->dirEntNum;
						sr.namespace = server->name_space[sr.volNumber];
						result = 0;
					} else
						ncp_dbg(1, "d_inode(s_root)==NULL\n");
				} else
					ncp_dbg(1, "s_root==NULL\n");
			} else {
				sr.volNumber = -1;
				sr.namespace = 0;
				sr.dirEntNum = 0;
				result = 0;
			}
			mutex_unlock(&server->root_setup_lock);
			if (!result && copy_to_user(argp, &sr, sizeof(sr)))
				result = -EFAULT;
			return result;
		}

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

			if (copy_from_user(&sr, argp, sizeof(sr)))
				return -EFAULT;
			mutex_lock(&server->root_setup_lock);
			if (server->root_setuped)
				result = -EBUSY;
			else {
				if (sr.volNumber < 0) {
					server->m.mounted_vol[0] = 0;
					vnum = NCP_NUMBER_OF_VOLUMES;
					de = 0;
					dosde = 0;
					result = 0;
				} else if (sr.volNumber >= NCP_NUMBER_OF_VOLUMES) {
					result = -EINVAL;
				} else if (ncp_mount_subdir(server, sr.volNumber,
							sr.namespace, sr.dirEntNum,
							&vnum, &de, &dosde)) {
					result = -ENOENT;
				} else
					result = 0;

				if (result == 0) {
					dentry = inode->i_sb->s_root;
					if (dentry) {
						struct inode* s_inode = d_inode(dentry);

						if (s_inode) {
							NCP_FINFO(s_inode)->volNumber = vnum;
							NCP_FINFO(s_inode)->dirEntNum = de;
							NCP_FINFO(s_inode)->DosDirNum = dosde;
							server->root_setuped = 1;
						} else {
							ncp_dbg(1, "d_inode(s_root)==NULL\n");
							result = -EIO;
						}
					} else {
						ncp_dbg(1, "s_root==NULL\n");
						result = -EIO;
					}
				}
			}
			mutex_unlock(&server->root_setup_lock);

			return result;
		}

#ifdef CONFIG_NCPFS_PACKET_SIGNING
	case NCP_IOC_SIGN_INIT:
		{
			struct ncp_sign_init sign;

			if (argp)
				if (copy_from_user(&sign, argp, sizeof(sign)))
					return -EFAULT;
			ncp_lock_server(server);
			mutex_lock(&server->rcv.creq_mutex);
			if (argp) {
				if (server->sign_wanted) {
					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;
			}
			mutex_unlock(&server->rcv.creq_mutex);
			ncp_unlock_server(server);
			return 0;
		}

        case NCP_IOC_SIGN_WANTED:
		{
			int state;

			ncp_lock_server(server);
			state = server->sign_wanted;
			ncp_unlock_server(server);
			if (put_user(state, (int __user *)argp))
				return -EFAULT;
			return 0;
		}

	case NCP_IOC_SET_SIGN_WANTED:
		{
			int newstate;

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

#endif /* CONFIG_NCPFS_PACKET_SIGNING */

#ifdef CONFIG_NCPFS_IOCTL_LOCKING
	case NCP_IOC_LOCKUNLOCK:
		{
			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)
							return -EINVAL;
						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 = -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:
		{
			struct compat_ncp_objectname_ioctl user;
			size_t outl;

			if (copy_from_user(&user, argp, sizeof(user)))
				return -EFAULT;
			down_read(&server->auth_rwsem);
			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;
			result = 0;
			if (outl) {
				if (copy_to_user(compat_ptr(user.object_name),
						 server->auth.object_name,
						 outl))
					result = -EFAULT;
			}
			up_read(&server->auth_rwsem);
			if (!result && copy_to_user(argp, &user, sizeof(user)))
				result = -EFAULT;
			return result;
		}
#endif

	case NCP_IOC_GETOBJECTNAME:
		{
			struct ncp_objectname_ioctl user;
			size_t outl;

			if (copy_from_user(&user, argp, sizeof(user)))
				return -EFAULT;
			down_read(&server->auth_rwsem);
			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;
			result = 0;
			if (outl) {
				if (copy_to_user(user.object_name,
						 server->auth.object_name,
						 outl))
					result = -EFAULT;
			}
			up_read(&server->auth_rwsem);
			if (!result && copy_to_user(argp, &user, sizeof(user)))
				result = -EFAULT;
			return result;
		}

#ifdef CONFIG_COMPAT
	case NCP_IOC_SETOBJECTNAME_32:
#endif
	case NCP_IOC_SETOBJECTNAME:
		{
			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;
			}
			down_write(&server->auth_rwsem);
			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;
			up_write(&server->auth_rwsem);
			kfree(oldprivate);
			kfree(oldname);
			return 0;
		}

#ifdef CONFIG_COMPAT
	case NCP_IOC_GETPRIVATEDATA_32:
#endif
	case NCP_IOC_GETPRIVATEDATA:
		{
			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;

			down_read(&server->auth_rwsem);
			outl = user.len;
			user.len = server->priv.len;
			if (outl > user.len) outl = user.len;
			result = 0;
			if (outl) {
				if (copy_to_user(user.data,
						 server->priv.data,
						 outl))
					result = -EFAULT;
			}
			up_read(&server->auth_rwsem);
			if (result)
				return result;
#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:
		{
			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;
			}
			down_write(&server->auth_rwsem);
			old = server->priv.data;
			oldlen = server->priv.len;
			server->priv.len = user.len;
			server->priv.data = new;
			up_write(&server->auth_rwsem);
			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:
		{
			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;
			atomic_set(&server->dentry_ttl, user);
			return 0;
		}

	case NCP_IOC_GETDENTRYTTL:
		{
			u_int32_t user = (atomic_read(&server->dentry_ttl) * 1000) / HZ;
			if (copy_to_user(argp, &user, sizeof(user)))
				return -EFAULT;
			return 0;
		}

	}
	return -EINVAL;
}

long ncp_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
{
	struct inode *inode = file_inode(filp);
	struct ncp_server *server = NCP_SERVER(inode);
	kuid_t uid = current_uid();
	int need_drop_write = 0;
	long ret;

	switch (cmd) {
	case NCP_IOC_SETCHARSETS:
	case NCP_IOC_CONN_LOGGED_IN:
	case NCP_IOC_SETROOT:
		if (!capable(CAP_SYS_ADMIN)) {
			ret = -EPERM;
			goto out;
		}
		break;
	}
	if (!uid_eq(server->m.mounted_uid, uid)) {
		switch (cmd) {
		/*
		 * Only mount owner can issue these ioctls.  Information
		 * necessary to authenticate to other NDS servers are
		 * stored here.
		 */
		case NCP_IOC_GETOBJECTNAME:
		case NCP_IOC_SETOBJECTNAME:
		case NCP_IOC_GETPRIVATEDATA:
		case NCP_IOC_SETPRIVATEDATA:
#ifdef CONFIG_COMPAT
		case NCP_IOC_GETOBJECTNAME_32:
		case NCP_IOC_SETOBJECTNAME_32:
		case NCP_IOC_GETPRIVATEDATA_32:
		case NCP_IOC_SETPRIVATEDATA_32:
#endif
			ret = -EACCES;
			goto out;
		/*
		 * These require write access on the inode if user id
		 * does not match.  Note that they do not write to the
		 * file...  But old code did mnt_want_write, so I keep
		 * it as is.  Of course not for mountpoint owner, as
		 * that breaks read-only mounts altogether as ncpmount
		 * needs working NCP_IOC_NCPREQUEST and
		 * NCP_IOC_GET_FS_INFO.  Some of these codes (setdentryttl,
		 * signinit, setsignwanted) should be probably restricted
		 * to owner only, or even more to CAP_SYS_ADMIN).
		 */
		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:
#ifdef CONFIG_COMPAT
		case NCP_IOC_GET_FS_INFO_V2_32:
		case NCP_IOC_NCPREQUEST_32:
#endif
			ret = mnt_want_write_file(filp);
			if (ret)
				goto out;
			need_drop_write = 1;
			ret = inode_permission(inode, MAY_WRITE);
			if (ret)
				goto outDropWrite;
			break;
		/*
		 * Read access required.
		 */
		case NCP_IOC_GETMOUNTUID16:
		case NCP_IOC_GETMOUNTUID32:
		case NCP_IOC_GETMOUNTUID64:
		case NCP_IOC_GETROOT:
		case NCP_IOC_SIGN_WANTED:
			ret = inode_permission(inode, MAY_READ);
			if (ret)
				goto out;
			break;
		/*
		 * Anybody can read these.
		 */
		case NCP_IOC_GETCHARSETS:
		case NCP_IOC_GETDENTRYTTL:
		default:
		/* Three codes below are protected by CAP_SYS_ADMIN above. */
		case NCP_IOC_SETCHARSETS:
		case NCP_IOC_CONN_LOGGED_IN:
		case NCP_IOC_SETROOT:
			break;
		}
	}
	ret = __ncp_ioctl(inode, cmd, arg);
outDropWrite:
	if (need_drop_write)
		mnt_drop_write_file(filp);
out:
	return ret;
}

#ifdef CONFIG_COMPAT
long ncp_compat_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
{
	long ret;

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