コード例 #1
0
ファイル: nwfs_vfsops.c プロジェクト: AhmadTux/DragonFlyBSD
/* Unmount the filesystem described by mp. */
static int
nwfs_unmount(struct mount *mp, int mntflags)
{
	struct nwmount *nmp = VFSTONWFS(mp);
	struct ncp_conn *conn;
	int error, flags;

	NCPVODEBUG("nwfs_unmount: flags=%04x\n",mntflags);
	flags = 0;
	if (mntflags & MNT_FORCE)
		flags |= FORCECLOSE;
	/* There is 1 extra root vnode reference from nwfs_mount(). */
	error = vflush(mp, 1, flags);
	if (error)
		return (error);
	conn = NWFSTOCONN(nmp);
	ncp_conn_puthandle(nmp->connh,NULL,0);
	if (ncp_conn_lock(conn, curthread, proc0.p_ucred, NCPM_WRITE | NCPM_EXECUTE) == 0) {
		if(ncp_disconnect(conn))
			ncp_conn_unlock(conn, curthread);
	}
	mp->mnt_data = (qaddr_t)0;
	if (nmp->m.flags & NWFS_MOUNT_HAVE_NLS)
		kfree(nmp->m.nls.to_lower, M_NWFSDATA);
	kfree(nmp, M_NWFSDATA);
	mp->mnt_flag &= ~MNT_LOCAL;
	return (error);
}
コード例 #2
0
ファイル: inode.c プロジェクト: qwerty1023/wive-rtnl-firmware
static void ncp_put_super(struct super_block *sb)
{
	struct ncp_server *server = NCP_SBP(sb);

	ncp_lock_server(server);
	ncp_disconnect(server);
	ncp_unlock_server(server);

	ncp_stop_tasks(server);

#ifdef CONFIG_NCPFS_NLS
	/* unload the NLS charsets */
	unload_nls(server->nls_vol);
	unload_nls(server->nls_io);
#endif /* CONFIG_NCPFS_NLS */

	if (server->info_filp)
		fput(server->info_filp);
	fput(server->ncp_filp);
	kill_pid(server->m.wdog_pid, SIGTERM, 1);
	put_pid(server->m.wdog_pid);

	kfree(server->priv.data);
	kfree(server->auth.object_name);
	vfree(server->rxbuf);
	vfree(server->txbuf);
	vfree(server->packet);
	sb->s_fs_info = NULL;
	kfree(server);
}
コード例 #3
0
ファイル: inode.c プロジェクト: 020gzh/linux
static void ncp_put_super(struct super_block *sb)
{
	struct ncp_server *server = NCP_SBP(sb);

	ncp_lock_server(server);
	ncp_disconnect(server);
	ncp_unlock_server(server);

	ncp_stop_tasks(server);

	mutex_destroy(&server->rcv.creq_mutex);
	mutex_destroy(&server->root_setup_lock);
	mutex_destroy(&server->mutex);

	if (server->info_sock)
		sockfd_put(server->info_sock);
	sockfd_put(server->ncp_sock);
	kill_pid(server->m.wdog_pid, SIGTERM, 1);
	put_pid(server->m.wdog_pid);

	bdi_destroy(&server->bdi);
	kfree(server->priv.data);
	kfree(server->auth.object_name);
	vfree(server->rxbuf);
	vfree(server->txbuf);
	vfree(server->packet);
	call_rcu(&server->rcu, delayed_free);
}
コード例 #4
0
ファイル: inode.c プロジェクト: shattered/linux-m68k
static void
ncp_put_super(struct super_block *sb)
{
        struct ncp_server *server = NCP_SBP(sb);

	lock_super(sb);

	ncp_lock_server(server);
        ncp_disconnect(server);
	ncp_unlock_server(server);

	close_fp(server->ncp_filp);

	ncp_dont_catch_watchdog(server);
	close_fp(server->wdog_filp);
	close_fp(server->msg_filp);

        ncp_free_all_inodes(server);

        ncp_kfree_s(server->packet, server->packet_size);

	sb->s_dev = 0;
        ncp_kfree_s(NCP_SBP(sb), sizeof(struct ncp_server));
	NCP_SBP(sb) = NULL;

	unlock_super(sb);

        MOD_DEC_USE_COUNT;
}
コード例 #5
0
ファイル: ncpl_net.c プロジェクト: AhmadTux/DragonFlyBSD
static int
ncp_find_server_ipx(struct ncp_conn_loginfo *li, int type) {
	char server[NCP_BINDERY_NAME_LEN + 1];
	int error;
	char nearest[NCP_BINDERY_NAME_LEN + 1];
	struct nw_property prop;
	struct ipx_addr *n_addr = (struct ipx_addr *) ∝
/*	struct ncp_conn_loginfo ltmp;*/
	int connid;

	bzero(server, sizeof(server));
	bzero(nearest, sizeof(nearest));

	strcpy(server, li->server);
	ncp_str_upper(server);

	if ((error = sap_find_nearest(type, &li->ipxaddr, nearest)) != 0) {
		return error;
	}
	/* if no server specified return info about nearest */
	if (!li->server[0]) {
		strcpy(li->server, nearest);
		return 0;
	}
/*	printf("%s\n",ipx_ntoa(li->ipxaddr.sipx_addr));*/
	if (strcmp(server, nearest) == 0) {
		return 0;
	}
	/* We have to ask the nearest server for our wanted server */
	li->opt=0;
	if ((error = ncp_connect(li, &connid)) != 0) {
		return error;
	}
	if (ncp_read_property_value(connid, type, server, 1, "NET_ADDRESS", &prop) != 0) {
		ncp_disconnect(connid);
		return EHOSTUNREACH;
	}
	if ((error = ncp_disconnect(connid)) != 0) {
		return error;
	}
	li->ipxaddr.sipx_family = AF_IPX;
	li->ipxaddr.sipx_addr.x_net = n_addr->x_net;
	li->ipxaddr.sipx_port = n_addr->x_port;
	li->ipxaddr.sipx_addr.x_host = n_addr->x_host;
	return 0;
}
コード例 #6
0
ファイル: ncpl_conn.c プロジェクト: edgar-pek/PerspicuOS
/*
 * read rc file as follows:
 * 1. read [server] section
 * 2. override with [server:user] section
 * Since abcence of rcfile is not a bug, silently ignore that fact.
 * rcfile never closed to reduce number of open/close operations.
 */
int
ncp_li_readrc(struct ncp_conn_loginfo *li) {
	int i, val, error;
	char uname[NCP_BINDERY_NAME_LEN*2+1];
	char *sect = NULL, *p;

	/*
	 * if info from cmd line incomplete, try to find existing
	 * connection and fill server/user from it.
	 */
	if (li->server[0] == 0 || li->user == NULL) {
		int connHandle;
		struct ncp_conn_stat cs;
		
		if ((error = ncp_conn_scan(li, &connHandle)) != 0) {
			ncp_error("no default connection found", errno);
			return error;
		}
		ncp_conn_getinfo(connHandle, &cs);
		ncp_li_setserver(li, cs.li.server);
		ncp_li_setuser(li, cs.user);
		ncp_li_setpassword(li, "");
		ncp_disconnect(connHandle);
	}
	if (ncp_open_rcfile()) 	return 0;
	
	for (i = 0; i < 2; i++) {
		switch (i) {
		    case 0:
			sect = li->server;
			break;
		    case 1:
			strcat(strcat(strcpy(uname,li->server),":"),li->user ? li->user : "******");
			sect = uname;
			break;
		}
		rc_getstringptr(ncp_rc, sect, "password", &p);
		if (p)
			ncp_li_setpassword(li, p);
		rc_getint(ncp_rc,sect, "timeout", &li->timeout);
		rc_getint(ncp_rc,sect, "retry_count", &li->retry_count);
		rc_getint(ncp_rc,sect, "sig_level", &li->sig_level);
		if (rc_getint(ncp_rc,sect,"access_mode",&val) == 0)
			li->access_mode = val;
		if(rc_getbool(ncp_rc,sect,"bindery",&val) == 0 && val) {
			li->opt |= NCP_OPT_BIND;
		}
	}
	return 0;
}
コード例 #7
0
ファイル: ncpl_conn.c プロジェクト: edgar-pek/PerspicuOS
/*
 * Lookup existing connection based on li structure, if connection
 * found, it will be referenced. Otherwise full login sequence performed.
 */
int
ncp_li_login(struct ncp_conn_loginfo *li, int *aconnid) {
	int connHandle, error;

	if ((error = ncp_conn_scan(li, &connHandle)) == 0) {
		*aconnid = connHandle;
		return 0;
	}
	error = ncp_connect(li, &connHandle);
	if (error) return errno;
	error = ncp_login(connHandle, li->user, li->objtype, li->password);
	if (error) {
		ncp_disconnect(connHandle);
	} else
		*aconnid = connHandle;
	return error;
}
コード例 #8
0
ファイル: ncp_subr.c プロジェクト: UnitedMarsupials/kame
void
ncp_at_exit(struct proc *p) {
	struct ncp_conn *ncp, *nncp;

	if (ncp_conn_putprochandles(p) == 0) return;

	ncp_conn_locklist(LK_EXCLUSIVE, p);
	for (ncp = conn_list.slh_first; ncp; ncp = nncp) {
		nncp = ncp->nc_next.sle_next;
		if (ncp->ref_cnt != 0) continue;
		if (ncp_conn_lock(ncp, p, p->p_ucred,NCPM_READ|NCPM_EXECUTE|NCPM_WRITE))
			continue;
		if (ncp_disconnect(ncp) != 0)
			ncp_conn_unlock(ncp,p);
	}
	ncp_conn_unlocklist(p);
	return;
}
コード例 #9
0
ファイル: ncplogin.c プロジェクト: AhmadTux/freebsd
static void
logout(int argc, char *argv[], struct ncp_conn_loginfo *li) {
	int error = 0, connid, opt;

	connid = -1;
	while ((opt = getopt(argc, argv, STDPARAM_OPT"c:")) != -1){
		switch (opt) {
		    case 'c':
			connid = atoi(optarg);
			break;
		    case STDPARAM_ARGS:
			if (ncp_li_arg(li, opt, optarg))
				exit(1);
			break;
		    default:
			logout_usage();
			/*NOTREACHED*/
		}
	}
	if (connid == -1) {
		if (li->server[0] == 0)
			errx(EX_USAGE, "no server name specified");
		if (li->user == 0) 
			errx(EX_USAGE, "no user name specified");
		if (ncp_conn_scan(li, &connid))
			errx(EX_OSERR, "You are not attached to server %s",
			     li->server);
	}
	if (ncp_setpermanent(connid, 0) < 0 && errno != EACCES) {
		ncp_error("Connection isn't valid", errno);
		exit(EX_OSERR);
	}
        error = ncp_disconnect(connid);
	if (error) {
		if (errno == EACCES) {
			warnx("you logged out, but connection belongs"
			      "to other user and not closed");
		} else {
			ncp_error("Can't logout with connid %d", error, connid);
			error = 1;
		}
	}
	exit(error ? 1 : 0);
}
コード例 #10
0
ファイル: ncp_subr.c プロジェクト: UnitedMarsupials/kame
void
ncp_done(void) {
	struct ncp_conn *ncp, *nncp;
	struct proc *p = curproc;
	
	untimeout(ncp_timer,NULL,ncp_timer_handle);
	rm_at_exit(ncp_at_exit);
	ncp_conn_locklist(LK_EXCLUSIVE, p);
	for (ncp = conn_list.slh_first; ncp; ncp = nncp) {
		nncp = ncp->nc_next.sle_next;
		ncp->ref_cnt = 0;
		if (ncp_conn_lock(ncp, p, p->p_ucred,NCPM_READ|NCPM_EXECUTE|NCPM_WRITE)) {
			NCPFATAL("Can't lock connection !\n");
			continue;
		}
		if (ncp_disconnect(ncp) != 0)
			ncp_conn_unlock(ncp,p);
	}
	ncp_conn_unlocklist(p);
}
コード例 #11
0
static void ncp_put_super(struct super_block *sb)
{
	struct ncp_server *server = NCP_SBP(sb);

	ncp_lock_server(server);
	ncp_disconnect(server);
	ncp_unlock_server(server);

	fput(server->ncp_filp);
	kill_proc(server->m.wdog_pid, SIGTERM, 1);

	if (server->priv.data) 
		ncp_kfree_s(server->priv.data, server->priv.len);
	if (server->auth.object_name)
		ncp_kfree_s(server->auth.object_name, server->auth.object_name_len);
	ncp_kfree_s(server->packet, server->packet_size);

	ncp_kfree_s(NCP_SBP(sb), sizeof(struct ncp_server));

	MOD_DEC_USE_COUNT;
}
コード例 #12
0
ファイル: inode.c プロジェクト: qwerty1023/wive-rtnl-firmware
static int ncp_fill_super(struct super_block *sb, void *raw_data, int silent)
{
	struct ncp_mount_data_kernel data;
	struct ncp_server *server;
	struct file *ncp_filp;
	struct inode *root_inode;
	struct inode *sock_inode;
	struct socket *sock;
	int error;
	int default_bufsize;
#ifdef CONFIG_NCPFS_PACKET_SIGNING
	int options;
#endif
	struct ncp_entry_info finfo;

	data.wdog_pid = NULL;
	server = kzalloc(sizeof(struct ncp_server), GFP_KERNEL);
	if (!server)
		return -ENOMEM;
	sb->s_fs_info = server;

	error = -EFAULT;
	if (raw_data == NULL)
		goto out;
	switch (*(int*)raw_data) {
		case NCP_MOUNT_VERSION:
			{
				struct ncp_mount_data* md = (struct ncp_mount_data*)raw_data;

				data.flags = md->flags;
				data.int_flags = NCP_IMOUNT_LOGGEDIN_POSSIBLE;
				data.mounted_uid = md->mounted_uid;
				data.wdog_pid = find_get_pid(md->wdog_pid);
				data.ncp_fd = md->ncp_fd;
				data.time_out = md->time_out;
				data.retry_count = md->retry_count;
				data.uid = md->uid;
				data.gid = md->gid;
				data.file_mode = md->file_mode;
				data.dir_mode = md->dir_mode;
				data.info_fd = -1;
				memcpy(data.mounted_vol, md->mounted_vol,
					NCP_VOLNAME_LEN+1);
			}
			break;
		case NCP_MOUNT_VERSION_V4:
			{
				struct ncp_mount_data_v4* md = (struct ncp_mount_data_v4*)raw_data;

				data.flags = md->flags;
				data.int_flags = 0;
				data.mounted_uid = md->mounted_uid;
				data.wdog_pid = find_get_pid(md->wdog_pid);
				data.ncp_fd = md->ncp_fd;
				data.time_out = md->time_out;
				data.retry_count = md->retry_count;
				data.uid = md->uid;
				data.gid = md->gid;
				data.file_mode = md->file_mode;
				data.dir_mode = md->dir_mode;
				data.info_fd = -1;
				data.mounted_vol[0] = 0;
			}
			break;
		default:
			error = -ECHRNG;
			if (memcmp(raw_data, "vers", 4) == 0) {
				error = ncp_parse_options(&data, raw_data);
			}
			if (error)
				goto out;
			break;
	}
	error = -EBADF;
	ncp_filp = fget(data.ncp_fd);
	if (!ncp_filp)
		goto out;
	error = -ENOTSOCK;
	sock_inode = ncp_filp->f_path.dentry->d_inode;
	if (!S_ISSOCK(sock_inode->i_mode))
		goto out_fput;
	sock = SOCKET_I(sock_inode);
	if (!sock)
		goto out_fput;
		
	if (sock->type == SOCK_STREAM)
		default_bufsize = 0xF000;
	else
		default_bufsize = 1024;

	sb->s_flags |= MS_NODIRATIME;	/* probably even noatime */
	sb->s_maxbytes = 0xFFFFFFFFU;
	sb->s_blocksize = 1024;	/* Eh...  Is this correct? */
	sb->s_blocksize_bits = 10;
	sb->s_magic = NCP_SUPER_MAGIC;
	sb->s_op = &ncp_sops;

	server = NCP_SBP(sb);
	memset(server, 0, sizeof(*server));

	server->ncp_filp = ncp_filp;
	server->ncp_sock = sock;
	
	if (data.info_fd != -1) {
		struct socket *info_sock;

		error = -EBADF;
		server->info_filp = fget(data.info_fd);
		if (!server->info_filp)
			goto out_fput;
		error = -ENOTSOCK;
		sock_inode = server->info_filp->f_path.dentry->d_inode;
		if (!S_ISSOCK(sock_inode->i_mode))
			goto out_fput2;
		info_sock = SOCKET_I(sock_inode);
		if (!info_sock)
			goto out_fput2;
		error = -EBADFD;
		if (info_sock->type != SOCK_STREAM)
			goto out_fput2;
		server->info_sock = info_sock;
	}

/*	server->lock = 0;	*/
	mutex_init(&server->mutex);
	server->packet = NULL;
/*	server->buffer_size = 0;	*/
/*	server->conn_status = 0;	*/
/*	server->root_dentry = NULL;	*/
/*	server->root_setuped = 0;	*/
#ifdef CONFIG_NCPFS_PACKET_SIGNING
/*	server->sign_wanted = 0;	*/
/*	server->sign_active = 0;	*/
#endif
	server->auth.auth_type = NCP_AUTH_NONE;
/*	server->auth.object_name_len = 0;	*/
/*	server->auth.object_name = NULL;	*/
/*	server->auth.object_type = 0;		*/
/*	server->priv.len = 0;			*/
/*	server->priv.data = NULL;		*/

	server->m = data;
	/* Althought anything producing this is buggy, it happens
	   now because of PATH_MAX changes.. */
	if (server->m.time_out < 1) {
		server->m.time_out = 10;
		printk(KERN_INFO "You need to recompile your ncpfs utils..\n");
	}
	server->m.time_out = server->m.time_out * HZ / 100;
	server->m.file_mode = (server->m.file_mode & S_IRWXUGO) | S_IFREG;
	server->m.dir_mode = (server->m.dir_mode & S_IRWXUGO) | S_IFDIR;

#ifdef CONFIG_NCPFS_NLS
	/* load the default NLS charsets */
	server->nls_vol = load_nls_default();
	server->nls_io = load_nls_default();
#endif /* CONFIG_NCPFS_NLS */

	server->dentry_ttl = 0;	/* no caching */

	INIT_LIST_HEAD(&server->tx.requests);
	mutex_init(&server->rcv.creq_mutex);
	server->tx.creq		= NULL;
	server->rcv.creq	= NULL;
	server->data_ready	= sock->sk->sk_data_ready;
	server->write_space	= sock->sk->sk_write_space;
	server->error_report	= sock->sk->sk_error_report;
	sock->sk->sk_user_data	= server;

	init_timer(&server->timeout_tm);
#undef NCP_PACKET_SIZE
#define NCP_PACKET_SIZE 131072
	error = -ENOMEM;
	server->packet_size = NCP_PACKET_SIZE;
	server->packet = vmalloc(NCP_PACKET_SIZE);
	if (server->packet == NULL)
		goto out_nls;
	server->txbuf = vmalloc(NCP_PACKET_SIZE);
	if (server->txbuf == NULL)
		goto out_packet;
	server->rxbuf = vmalloc(NCP_PACKET_SIZE);
	if (server->rxbuf == NULL)
		goto out_txbuf;

	sock->sk->sk_data_ready	  = ncp_tcp_data_ready;
	sock->sk->sk_error_report = ncp_tcp_error_report;
	if (sock->type == SOCK_STREAM) {
		server->rcv.ptr = (unsigned char*)&server->rcv.buf;
		server->rcv.len = 10;
		server->rcv.state = 0;
		INIT_WORK(&server->rcv.tq, ncp_tcp_rcv_proc);
		INIT_WORK(&server->tx.tq, ncp_tcp_tx_proc);
		sock->sk->sk_write_space = ncp_tcp_write_space;
	} else {
		INIT_WORK(&server->rcv.tq, ncpdgram_rcv_proc);
		INIT_WORK(&server->timeout_tq, ncpdgram_timeout_proc);
		server->timeout_tm.data = (unsigned long)server;
		server->timeout_tm.function = ncpdgram_timeout_call;
	}

	ncp_lock_server(server);
	error = ncp_connect(server);
	ncp_unlock_server(server);
	if (error < 0)
		goto out_rxbuf;
	DPRINTK("ncp_fill_super: NCP_SBP(sb) = %x\n", (int) NCP_SBP(sb));

	error = -EMSGSIZE;	/* -EREMOTESIDEINCOMPATIBLE */
#ifdef CONFIG_NCPFS_PACKET_SIGNING
	if (ncp_negotiate_size_and_options(server, default_bufsize,
		NCP_DEFAULT_OPTIONS, &(server->buffer_size), &options) == 0)
	{
		if (options != NCP_DEFAULT_OPTIONS)
		{
			if (ncp_negotiate_size_and_options(server, 
				default_bufsize,
				options & 2, 
				&(server->buffer_size), &options) != 0)
				
			{
				goto out_disconnect;
			}
		}
		if (options & 2)
			server->sign_wanted = 1;
	}
	else 
#endif	/* CONFIG_NCPFS_PACKET_SIGNING */
	if (ncp_negotiate_buffersize(server, default_bufsize,
  				     &(server->buffer_size)) != 0)
		goto out_disconnect;
	DPRINTK("ncpfs: bufsize = %d\n", server->buffer_size);

	memset(&finfo, 0, sizeof(finfo));
	finfo.i.attributes	= aDIR;
	finfo.i.dataStreamSize	= 0;	/* ignored */
	finfo.i.dirEntNum	= 0;
	finfo.i.DosDirNum	= 0;
#ifdef CONFIG_NCPFS_SMALLDOS
	finfo.i.NSCreator	= NW_NS_DOS;
#endif
	finfo.volume		= NCP_NUMBER_OF_VOLUMES;
	/* set dates of mountpoint to Jan 1, 1986; 00:00 */
	finfo.i.creationTime	= finfo.i.modifyTime
				= cpu_to_le16(0x0000);
	finfo.i.creationDate	= finfo.i.modifyDate
				= finfo.i.lastAccessDate
				= cpu_to_le16(0x0C21);
	finfo.i.nameLen		= 0;
	finfo.i.entryName[0]	= '\0';

	finfo.opened		= 0;
	finfo.ino		= 2;	/* tradition */

	server->name_space[finfo.volume] = NW_NS_DOS;

	error = -ENOMEM;
        root_inode = ncp_iget(sb, &finfo);
        if (!root_inode)
		goto out_disconnect;
	DPRINTK("ncp_fill_super: root vol=%d\n", NCP_FINFO(root_inode)->volNumber);
	sb->s_root = d_alloc_root(root_inode);
        if (!sb->s_root)
		goto out_no_root;
	sb->s_root->d_op = &ncp_root_dentry_operations;
	return 0;

out_no_root:
	iput(root_inode);
out_disconnect:
	ncp_lock_server(server);
	ncp_disconnect(server);
	ncp_unlock_server(server);
out_rxbuf:
	ncp_stop_tasks(server);
	vfree(server->rxbuf);
out_txbuf:
	vfree(server->txbuf);
out_packet:
	vfree(server->packet);
out_nls:
#ifdef CONFIG_NCPFS_NLS
	unload_nls(server->nls_io);
	unload_nls(server->nls_vol);
#endif
out_fput2:
	if (server->info_filp)
		fput(server->info_filp);
out_fput:
	/* 23/12/1998 Marcin Dalecki <*****@*****.**>:
	 * 
	 * The previously used put_filp(ncp_filp); was bogous, since
	 * it doesn't proper unlocking.
	 */
	fput(ncp_filp);
out:
	put_pid(data.wdog_pid);
	sb->s_fs_info = NULL;
	kfree(server);
	return error;
}
コード例 #13
0
ファイル: inode.c プロジェクト: shattered/linux-m68k
struct super_block *
ncp_read_super(struct super_block *sb, void *raw_data, int silent)
{
	struct ncp_mount_data *data = (struct ncp_mount_data *) raw_data;
        struct ncp_server *server;
	struct file *ncp_filp;
	struct file *wdog_filp;
	struct file *msg_filp;
	kdev_t dev = sb->s_dev;
	int error;

	if (data == NULL)
	{
		printk("ncp_read_super: missing data argument\n");
		sb->s_dev = 0;
		return NULL;
	}

	if (data->version != NCP_MOUNT_VERSION)
	{
		printk("ncp warning: mount version %s than kernel\n",
		       (data->version < NCP_MOUNT_VERSION) ?
                       "older" : "newer");
		sb->s_dev = 0;
		return NULL;
	}

	if (   (data->ncp_fd >= NR_OPEN)
	    || ((ncp_filp = current->files->fd[data->ncp_fd]) == NULL)
	    || (!S_ISSOCK(ncp_filp->f_inode->i_mode)))
	{
		printk("ncp_read_super: invalid ncp socket\n");
		sb->s_dev = 0;
		return NULL;
	}

	if (   (data->wdog_fd >= NR_OPEN)
	    || ((wdog_filp = current->files->fd[data->wdog_fd]) == NULL)
	    || (!S_ISSOCK(wdog_filp->f_inode->i_mode)))
	{
		printk("ncp_read_super: invalid wdog socket\n");
		sb->s_dev = 0;
		return NULL;
	}

	if (   (data->message_fd >= NR_OPEN)
	    || ((msg_filp = current->files->fd[data->message_fd]) == NULL)
	    || (!S_ISSOCK(msg_filp->f_inode->i_mode)))
	{
		printk("ncp_read_super: invalid wdog socket\n");
		sb->s_dev = 0;
		return NULL;
	}

        /* We must malloc our own super-block info */
        server = (struct ncp_server *)ncp_kmalloc(sizeof(struct ncp_server),
                                                   GFP_KERNEL);

        if (server == NULL)
	{
                printk("ncp_read_super: could not alloc ncp_server\n");
                return NULL;
        }

	ncp_filp->f_count += 1;
	wdog_filp->f_count += 1;
	msg_filp->f_count += 1;

	lock_super(sb);

        NCP_SBP(sb) = server;
        
	sb->s_blocksize = 1024; /* Eh...  Is this correct? */
	sb->s_blocksize_bits = 10;
	sb->s_magic = NCP_SUPER_MAGIC;
	sb->s_dev = dev;
	sb->s_op = &ncp_sops;

	server->ncp_filp    = ncp_filp;
	server->wdog_filp   = wdog_filp;
	server->msg_filp    = msg_filp;
	server->lock        = 0;
	server->wait        = NULL;
        server->packet      = NULL;
	server->buffer_size = 0;
	server->conn_status = 0;

        server->m = *data;
	server->m.file_mode = (server->m.file_mode &
			       (S_IRWXU|S_IRWXG|S_IRWXO)) | S_IFREG;
	server->m.dir_mode  = (server->m.dir_mode &
			       (S_IRWXU|S_IRWXG|S_IRWXO)) | S_IFDIR;

	/* protect against invalid mount points */
	server->m.mount_point[sizeof(server->m.mount_point)-1] = '\0';

	server->packet_size = NCP_PACKET_SIZE;
	server->packet      = ncp_kmalloc(NCP_PACKET_SIZE, GFP_KERNEL);

	if (server->packet == NULL)
	{
		printk("ncpfs: could not alloc packet\n");
		error = -ENOMEM;
		unlock_super(sb);
		goto fail;
	}
   
        /*
         * Make the connection to the server
         */

	if (ncp_catch_watchdog(server) != 0)
	{
		printk("ncp_read_super: Could not catch watchdog\n");
		error = -EINVAL;
		unlock_super(sb);
		goto fail;
	}

	if (ncp_catch_message(server) != 0)
	{
		printk("ncp_read_super: Could not catch messages\n");
		ncp_dont_catch_watchdog(server);
		error = -EINVAL;
		unlock_super(sb);
		goto fail;
	}

	ncp_lock_server(server);
	error = ncp_connect(server);
	ncp_unlock_server(server);
	unlock_super(sb);

	if (error < 0)
	{
		sb->s_dev = 0;
		printk("ncp_read_super: Failed connection, bailing out "
                       "(error = %d).\n", -error);
                ncp_kfree_s(server->packet, server->packet_size);
		ncp_dont_catch_watchdog(server);
                goto fail;
	}

        DPRINTK("ncp_read_super: NCP_SBP(sb) = %x\n", (int)NCP_SBP(sb));

	ncp_init_root(server);

	if (!(sb->s_mounted = iget(sb, ncp_info_ino(server, &(server->root)))))
	{
		sb->s_dev = 0;
		printk("ncp_read_super: get root inode failed\n");
                goto disconnect;
	}

	if (ncp_negotiate_buffersize(server, NCP_DEFAULT_BUFSIZE,
				     &(server->buffer_size)) != 0)
	{
		sb->s_dev = 0;
		printk("ncp_read_super: could not get bufsize\n");
		goto disconnect;
	}

	DPRINTK("ncpfs: bufsize = %d\n", server->buffer_size);

        MOD_INC_USE_COUNT;
	return sb;

 disconnect:
	ncp_lock_server(server);
	ncp_disconnect(server);
	ncp_unlock_server(server);
	ncp_kfree_s(server->packet, server->packet_size);
	ncp_dont_catch_watchdog(server);
 fail:
	ncp_filp->f_count -= 1;
	wdog_filp->f_count -= 1;
	msg_filp->f_count -= 1;
        ncp_kfree_s(NCP_SBP(sb), sizeof(struct ncp_server));
        return NULL;
}
コード例 #14
0
struct super_block *
ncp_read_super(struct super_block *sb, void *raw_data, int silent)
{
	struct ncp_mount_data *data = (struct ncp_mount_data *) raw_data;
	struct ncp_server *server;
	struct file *ncp_filp;
	struct inode *root_inode;
	kdev_t dev = sb->s_dev;
	int error;
#ifdef CONFIG_NCPFS_PACKET_SIGNING
	int options;
#endif
	struct ncpfs_inode_info finfo;

	MOD_INC_USE_COUNT;
	if (data == NULL)
		goto out_no_data;
	if (data->version != NCP_MOUNT_VERSION)
		goto out_bad_mount;
	ncp_filp = fget(data->ncp_fd);
	if (!ncp_filp)
		goto out_bad_file;
	if (!S_ISSOCK(ncp_filp->f_dentry->d_inode->i_mode))
		goto out_bad_file2;

	lock_super(sb);

	sb->s_blocksize = 1024;	/* Eh...  Is this correct? */
	sb->s_blocksize_bits = 10;
	sb->s_magic = NCP_SUPER_MAGIC;
	sb->s_dev = dev;
	sb->s_op = &ncp_sops;

	/* We must malloc our own super-block info */
	server = (struct ncp_server *) ncp_kmalloc(sizeof(struct ncp_server),
						   GFP_KERNEL);
	if (server == NULL)
		goto out_no_server;
	NCP_SBP(sb) = server;

	server->ncp_filp = ncp_filp;
	server->lock = 0;
	server->wait = NULL;
	server->packet = NULL;
	server->buffer_size = 0;
	server->conn_status = 0;
	server->root_dentry = NULL;
	server->root_setuped = 0;
#ifdef CONFIG_NCPFS_PACKET_SIGNING
	server->sign_wanted = 0;
	server->sign_active = 0;
#endif
	server->auth.auth_type = NCP_AUTH_NONE;
	server->auth.object_name_len = 0;
	server->auth.object_name = NULL;
	server->auth.object_type = 0;
	server->priv.len = 0;
	server->priv.data = NULL;

	server->m = *data;
	/* Althought anything producing this is buggy, it happens
	   now because of PATH_MAX changes.. */
	if (server->m.time_out < 10) {
		server->m.time_out = 10;
		printk(KERN_INFO "You need to recompile your ncpfs utils..\n");
	}
	server->m.file_mode = (server->m.file_mode &
			       (S_IRWXU | S_IRWXG | S_IRWXO)) | S_IFREG;
	server->m.dir_mode = (server->m.dir_mode &
			      (S_IRWXU | S_IRWXG | S_IRWXO)) | S_IFDIR;

	server->packet_size = NCP_PACKET_SIZE;
	server->packet = ncp_kmalloc(NCP_PACKET_SIZE, GFP_KERNEL);
	if (server->packet == NULL)
		goto out_no_packet;

	ncp_lock_server(server);
	error = ncp_connect(server);
	ncp_unlock_server(server);
	if (error < 0)
		goto out_no_connect;
	DPRINTK(KERN_DEBUG "ncp_read_super: NCP_SBP(sb) = %x\n", (int) NCP_SBP(sb));

#ifdef CONFIG_NCPFS_PACKET_SIGNING
	if (ncp_negotiate_size_and_options(server, NCP_DEFAULT_BUFSIZE,
		NCP_DEFAULT_OPTIONS, &(server->buffer_size), &options) == 0)
	{
		if (options != NCP_DEFAULT_OPTIONS)
		{
			if (ncp_negotiate_size_and_options(server, 
				NCP_DEFAULT_BUFSIZE,
				options & 2, 
				&(server->buffer_size), &options) != 0)
				
			{
				goto out_no_bufsize;
			}
		}
		if (options & 2)
			server->sign_wanted = 1;
	}
	else 
#endif	/* CONFIG_NCPFS_PACKET_SIGNING */
	if (ncp_negotiate_buffersize(server, NCP_DEFAULT_BUFSIZE,
  				     &(server->buffer_size)) != 0)
		goto out_no_bufsize;
	DPRINTK(KERN_DEBUG "ncpfs: bufsize = %d\n", server->buffer_size);

	ncp_init_root(server, &finfo);
	server->name_space[finfo.nw_info.i.volNumber] = NW_NS_DOS;
        root_inode = ncp_iget(sb, &finfo);
        if (!root_inode)
		goto out_no_root;
	DPRINTK(KERN_DEBUG "ncp_read_super: root vol=%d\n", NCP_FINFO(root_inode)->volNumber);
        server->root_dentry = sb->s_root = d_alloc_root(root_inode, NULL);
        if (!sb->s_root)
		goto out_no_root;
	server->root_dentry->d_op = &ncp_dentry_operations;
	unlock_super(sb);
	return sb;

out_no_root:
	printk(KERN_ERR "ncp_read_super: get root inode failed\n");
	iput(root_inode);
	goto out_disconnect;
out_no_bufsize:
	printk(KERN_ERR "ncp_read_super: could not get bufsize\n");
out_disconnect:
	ncp_lock_server(server);
	ncp_disconnect(server);
	ncp_unlock_server(server);
	goto out_free_packet;
out_no_connect:
	printk(KERN_ERR "ncp_read_super: Failed connection, error=%d\n", error);
out_free_packet:
	ncp_kfree_s(server->packet, server->packet_size);
	goto out_free_server;
out_no_packet:
	printk(KERN_ERR "ncp_read_super: could not alloc packet\n");
out_free_server:
	ncp_kfree_s(NCP_SBP(sb), sizeof(struct ncp_server));
	goto out_unlock;
out_no_server:
	printk(KERN_ERR "ncp_read_super: could not alloc ncp_server\n");
out_unlock:
	/* 23/12/1998 Marcin Dalecki <*****@*****.**>:
	 * 
	 * The previously used put_filp(ncp_filp); was bogous, since
	 * it doesn't proper unlocking.
	 */
	fput(ncp_filp);
	unlock_super(sb);
	goto out;

out_bad_file2:
	fput(ncp_filp);
out_bad_file:
	printk(KERN_ERR "ncp_read_super: invalid ncp socket\n");
	goto out;
out_bad_mount:
	printk(KERN_INFO "ncp_read_super: kernel requires mount version %d\n",
		NCP_MOUNT_VERSION);
	goto out;
out_no_data:
	printk(KERN_ERR "ncp_read_super: missing data argument\n");
out:
	sb->s_dev = 0;
	MOD_DEC_USE_COUNT;
	return NULL;
}
コード例 #15
0
ファイル: ncp_mod.c プロジェクト: UnitedMarsupials/kame
static int
ncp_conn_handler(struct proc *p, struct sncp_request_args *uap,
	struct ncp_conn *conn, struct ncp_handle *hp)
{
	int error=0, rqsize, subfn;
	struct ucred *cred;
	
	char *pdata;

	cred = p->p_ucred;
	error = copyin(&uap->ncpbuf->rqsize, &rqsize, sizeof(int));
	if (error) return(error);
	error = 0;
	pdata = uap->ncpbuf->packet;
	subfn = *(pdata++) & 0xff;
	rqsize--;
	switch (subfn) {
	    case NCP_CONN_READ: case NCP_CONN_WRITE: {
		struct ncp_rw rwrq;
		struct uio auio;
		struct iovec iov;
	
		if (rqsize != sizeof(rwrq)) return (EBADRPC);	
		error = copyin(pdata,&rwrq,rqsize);
		if (error) return (error);
		iov.iov_base = rwrq.nrw_base;
		iov.iov_len = rwrq.nrw_cnt;
		auio.uio_iov = &iov;
		auio.uio_iovcnt = 1;
		auio.uio_offset = rwrq.nrw_offset;
		auio.uio_resid = rwrq.nrw_cnt;
		auio.uio_segflg = UIO_USERSPACE;
		auio.uio_rw = (subfn == NCP_CONN_READ) ? UIO_READ : UIO_WRITE;
		auio.uio_procp = p;
		error = ncp_conn_lock(conn,p,cred,NCPM_EXECUTE);
		if (error) return(error);
		if (subfn == NCP_CONN_READ)
			error = ncp_read(conn, &rwrq.nrw_fh, &auio, cred);
		else
			error = ncp_write(conn, &rwrq.nrw_fh, &auio, cred);
		rwrq.nrw_cnt -= auio.uio_resid;
		ncp_conn_unlock(conn,p);
		p->p_retval[0] = rwrq.nrw_cnt;
		break;
	    } /* case int_read/write */
	    case NCP_CONN_SETFLAGS: {
		u_int16_t mask, flags;

		error = copyin(pdata,&mask, sizeof(mask));
		if (error) return error;
		pdata += sizeof(mask);
		error = copyin(pdata,&flags,sizeof(flags));
		if (error) return error;
		error = ncp_conn_lock(conn,p,cred,NCPM_WRITE);
		if (error) return error;
		if (mask & NCPFL_PERMANENT) {
			conn->flags &= ~NCPFL_PERMANENT;
			conn->flags |= (flags & NCPFL_PERMANENT);
		}
		if (mask & NCPFL_PRIMARY) {
			error = ncp_conn_setprimary(conn, flags & NCPFL_PRIMARY);
			if (error) {
				ncp_conn_unlock(conn,p);
				break;
			}
		}
		ncp_conn_unlock(conn,p);
		break;
	    }
	    case NCP_CONN_LOGIN: {
		struct ncp_conn_login la;

		if (rqsize != sizeof(la)) return (EBADRPC);	
		if ((error = copyin(pdata,&la,rqsize)) != 0) break;
		error = ncp_conn_lock(conn, p, cred, NCPM_EXECUTE | NCPM_WRITE);
		if (error) return error;
		error = ncp_login(conn, la.username, la.objtype, la.password, p, p->p_ucred);
		ncp_conn_unlock(conn, p);
		p->p_retval[0] = error;
		break;
	    }
	    case NCP_CONN_GETINFO: {
		struct ncp_conn_stat ncs;
		int len = sizeof(ncs);

		error = ncp_conn_lock(conn, p, p->p_ucred, NCPM_READ);
		if (error) return error;
		ncp_conn_getinfo(conn, &ncs);
		copyout(&len, &uap->ncpbuf->rpsize, sizeof(int));
		error = copyout(&ncs, &uap->ncpbuf->packet, len);
		ncp_conn_unlock(conn, p);
		break;
	    }
	    case NCP_CONN_GETUSER: {
		int len;

		error = ncp_conn_lock(conn, p, p->p_ucred, NCPM_READ);
		if (error) return error;
		len = (conn->li.user) ? strlen(conn->li.user) + 1 : 0;
		copyout(&len, &uap->ncpbuf->rpsize, sizeof(int));
		if (len) {
			error = copyout(conn->li.user, &uap->ncpbuf->packet, len);
		}
		ncp_conn_unlock(conn, p);
		break;
	    }
	    case NCP_CONN_CONN2REF: {
		int len = sizeof(int);

		error = ncp_conn_lock(conn, p, p->p_ucred, NCPM_READ);
		if (error) return error;
		copyout(&len, &uap->ncpbuf->rpsize, sizeof(int));
		if (len) {
			error = copyout(&conn->nc_id, &uap->ncpbuf->packet, len);
		}
		ncp_conn_unlock(conn, p);
		break;
	    }
	    case NCP_CONN_FRAG: {
		struct ncp_conn_frag nf;

		if (rqsize != sizeof(nf)) return (EBADRPC);	
		if ((error = copyin(pdata, &nf, rqsize)) != 0) break;
		error = ncp_conn_lock(conn, p, cred, NCPM_EXECUTE);
		if (error) return error;
		error = ncp_conn_frag_rq(conn, p, &nf);
		ncp_conn_unlock(conn, p);
		copyout(&nf, &pdata, sizeof(nf));
		p->p_retval[0] = error;
		break;
	    }
	    case NCP_CONN_DUP: {
		struct ncp_handle *newhp;
		int len = sizeof(NWCONN_HANDLE);

		error = ncp_conn_lock(conn, p, cred, NCPM_READ);
		if (error) break;
		copyout(&len, &uap->ncpbuf->rpsize, len);
		error = ncp_conn_gethandle(conn, p, &newhp);
		if (!error)
			error = copyout(&newhp->nh_id, uap->ncpbuf->packet, len);
		ncp_conn_unlock(conn,p);
		break;
	    }
	    case NCP_CONN_CONNCLOSE: {
		error = ncp_conn_lock(conn, p, cred, NCPM_EXECUTE);
		if (error) break;
		ncp_conn_puthandle(hp, p, 0);
		error = ncp_disconnect(conn);
		if (error)
			ncp_conn_unlock(conn, p);
		break;
	    }
	    default:
		    error = EOPNOTSUPP;
	}
	return error;
}