xref: /titanic_51/usr/src/lib/smbsrv/libsmb/common/smb_kmod.c (revision a90cf9f29973990687fa61de9f1f6ea22e924e40)
129bd2886SAlan Wright /*
229bd2886SAlan Wright  * CDDL HEADER START
329bd2886SAlan Wright  *
429bd2886SAlan Wright  * The contents of this file are subject to the terms of the
529bd2886SAlan Wright  * Common Development and Distribution License (the "License").
629bd2886SAlan Wright  * You may not use this file except in compliance with the License.
729bd2886SAlan Wright  *
829bd2886SAlan Wright  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
929bd2886SAlan Wright  * or http://www.opensolaris.org/os/licensing.
1029bd2886SAlan Wright  * See the License for the specific language governing permissions
1129bd2886SAlan Wright  * and limitations under the License.
1229bd2886SAlan Wright  *
1329bd2886SAlan Wright  * When distributing Covered Code, include this CDDL HEADER in each
1429bd2886SAlan Wright  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
1529bd2886SAlan Wright  * If applicable, add the following below this CDDL HEADER, with the
1629bd2886SAlan Wright  * fields enclosed by brackets "[]" replaced with your own identifying
1729bd2886SAlan Wright  * information: Portions Copyright [yyyy] [name of copyright owner]
1829bd2886SAlan Wright  *
1929bd2886SAlan Wright  * CDDL HEADER END
2029bd2886SAlan Wright  */
2129bd2886SAlan Wright /*
22148c5f43SAlan Wright  * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
23*a90cf9f2SGordon Ross  * Copyright 2015 Nexenta Systems, Inc.  All rights reserved.
2429bd2886SAlan Wright  */
2529bd2886SAlan Wright 
2629bd2886SAlan Wright #include <sys/types.h>
2729bd2886SAlan Wright #include <sys/stat.h>
2829bd2886SAlan Wright #include <sys/ioccom.h>
2929bd2886SAlan Wright #include <sys/param.h>
3029bd2886SAlan Wright #include <stddef.h>
3129bd2886SAlan Wright #include <stdio.h>
3229bd2886SAlan Wright #include <string.h>
3329bd2886SAlan Wright #include <strings.h>
3429bd2886SAlan Wright #include <stdlib.h>
3529bd2886SAlan Wright #include <unistd.h>
3629bd2886SAlan Wright #include <fcntl.h>
3729bd2886SAlan Wright #include <errno.h>
3829bd2886SAlan Wright 
3929bd2886SAlan Wright #include <smbsrv/smb_xdr.h>
4029bd2886SAlan Wright #include <smbsrv/smbinfo.h>
4129bd2886SAlan Wright #include <smbsrv/smb_ioctl.h>
4229bd2886SAlan Wright #include <smbsrv/libsmb.h>
4329bd2886SAlan Wright 
441e4c938bSGordon Ross #define	SMBDRV_DEVICE_PATH		"/dev/smbsrv"
4529bd2886SAlan Wright #define	SMB_IOC_DATA_SIZE		(256 * 1024)
4629bd2886SAlan Wright 
47b819cea2SGordon Ross int smb_kmod_ioctl(int, smb_ioc_header_t *, uint32_t);
4829bd2886SAlan Wright 
4929bd2886SAlan Wright 
5029bd2886SAlan Wright int	smbdrv_fd = -1;
5129bd2886SAlan Wright 
5229bd2886SAlan Wright int
5329bd2886SAlan Wright smb_kmod_bind(void)
5429bd2886SAlan Wright {
5529bd2886SAlan Wright 	if (smbdrv_fd != -1)
5629bd2886SAlan Wright 		(void) close(smbdrv_fd);
5729bd2886SAlan Wright 
5829bd2886SAlan Wright 	if ((smbdrv_fd = open(SMBDRV_DEVICE_PATH, 0)) < 0) {
5929bd2886SAlan Wright 		smbdrv_fd = -1;
6029bd2886SAlan Wright 		return (errno);
6129bd2886SAlan Wright 	}
6229bd2886SAlan Wright 
6329bd2886SAlan Wright 	return (0);
6429bd2886SAlan Wright }
6529bd2886SAlan Wright 
66fd9ee8b5Sjoyce mcintosh boolean_t
67fd9ee8b5Sjoyce mcintosh smb_kmod_isbound(void)
68fd9ee8b5Sjoyce mcintosh {
69fd9ee8b5Sjoyce mcintosh 	return ((smbdrv_fd == -1) ? B_FALSE : B_TRUE);
70fd9ee8b5Sjoyce mcintosh }
71fd9ee8b5Sjoyce mcintosh 
7212b65585SGordon Ross /* See also: smbsrv smb_server_store_cfg */
7329bd2886SAlan Wright int
7429bd2886SAlan Wright smb_kmod_setcfg(smb_kmod_cfg_t *cfg)
7529bd2886SAlan Wright {
7629bd2886SAlan Wright 	smb_ioc_cfg_t ioc;
7729bd2886SAlan Wright 
7829bd2886SAlan Wright 	ioc.maxworkers = cfg->skc_maxworkers;
7929bd2886SAlan Wright 	ioc.maxconnections = cfg->skc_maxconnections;
8029bd2886SAlan Wright 	ioc.keepalive = cfg->skc_keepalive;
8129bd2886SAlan Wright 	ioc.restrict_anon = cfg->skc_restrict_anon;
8229bd2886SAlan Wright 	ioc.signing_enable = cfg->skc_signing_enable;
8329bd2886SAlan Wright 	ioc.signing_required = cfg->skc_signing_required;
8429bd2886SAlan Wright 	ioc.oplock_enable = cfg->skc_oplock_enable;
8529bd2886SAlan Wright 	ioc.sync_enable = cfg->skc_sync_enable;
8629bd2886SAlan Wright 	ioc.secmode = cfg->skc_secmode;
8783d2dfe6SGordon Ross 	ioc.netbios_enable = cfg->skc_netbios_enable;
8812b65585SGordon Ross 	ioc.ipv6_enable = cfg->skc_ipv6_enable;
89cb174861Sjoyce mcintosh 	ioc.print_enable = cfg->skc_print_enable;
905f1ef25cSAram Hăvărneanu 	ioc.traverse_mounts = cfg->skc_traverse_mounts;
91*a90cf9f2SGordon Ross 	ioc.max_protocol = cfg->skc_max_protocol;
92148c5f43SAlan Wright 	ioc.exec_flags = cfg->skc_execflags;
9312b65585SGordon Ross 	ioc.negtok_len = cfg->skc_negtok_len;
94148c5f43SAlan Wright 	ioc.version = cfg->skc_version;
95*a90cf9f2SGordon Ross 	ioc.initial_credits = cfg->skc_initial_credits;
96*a90cf9f2SGordon Ross 	ioc.maximum_credits = cfg->skc_maximum_credits;
9729bd2886SAlan Wright 
9812b65585SGordon Ross 	(void) memcpy(ioc.machine_uuid, cfg->skc_machine_uuid, sizeof (uuid_t));
9912b65585SGordon Ross 	(void) memcpy(ioc.negtok, cfg->skc_negtok, sizeof (ioc.negtok));
10012b65585SGordon Ross 	(void) memcpy(ioc.native_os, cfg->skc_native_os,
10112b65585SGordon Ross 	    sizeof (ioc.native_os));
10212b65585SGordon Ross 	(void) memcpy(ioc.native_lm, cfg->skc_native_lm,
10312b65585SGordon Ross 	    sizeof (ioc.native_lm));
10412b65585SGordon Ross 
10529bd2886SAlan Wright 	(void) strlcpy(ioc.nbdomain, cfg->skc_nbdomain, sizeof (ioc.nbdomain));
10629bd2886SAlan Wright 	(void) strlcpy(ioc.fqdn, cfg->skc_fqdn, sizeof (ioc.fqdn));
10729bd2886SAlan Wright 	(void) strlcpy(ioc.hostname, cfg->skc_hostname, sizeof (ioc.hostname));
10829bd2886SAlan Wright 	(void) strlcpy(ioc.system_comment, cfg->skc_system_comment,
10929bd2886SAlan Wright 	    sizeof (ioc.system_comment));
11029bd2886SAlan Wright 
11129bd2886SAlan Wright 	return (smb_kmod_ioctl(SMB_IOC_CONFIG, &ioc.hdr, sizeof (ioc)));
11229bd2886SAlan Wright }
11329bd2886SAlan Wright 
11429bd2886SAlan Wright int
11529bd2886SAlan Wright smb_kmod_setgmtoff(int32_t gmtoff)
11629bd2886SAlan Wright {
11729bd2886SAlan Wright 	smb_ioc_gmt_t ioc;
11829bd2886SAlan Wright 
11929bd2886SAlan Wright 	ioc.offset = gmtoff;
12029bd2886SAlan Wright 	return (smb_kmod_ioctl(SMB_IOC_GMTOFF, &ioc.hdr,
12129bd2886SAlan Wright 	    sizeof (ioc)));
12229bd2886SAlan Wright }
12329bd2886SAlan Wright 
12429bd2886SAlan Wright int
12529bd2886SAlan Wright smb_kmod_start(int opipe, int lmshr, int udoor)
12629bd2886SAlan Wright {
12729bd2886SAlan Wright 	smb_ioc_start_t ioc;
12829bd2886SAlan Wright 
12929bd2886SAlan Wright 	ioc.opipe = opipe;
13029bd2886SAlan Wright 	ioc.lmshrd = lmshr;
13129bd2886SAlan Wright 	ioc.udoor = udoor;
13229bd2886SAlan Wright 	return (smb_kmod_ioctl(SMB_IOC_START, &ioc.hdr, sizeof (ioc)));
13329bd2886SAlan Wright }
13429bd2886SAlan Wright 
1359fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States void
1369fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_kmod_stop(void)
1379fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States {
1389fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	smb_ioc_header_t ioc;
1399fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
1409fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	(void) smb_kmod_ioctl(SMB_IOC_STOP, &ioc, sizeof (ioc));
1419fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States }
1429fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
1439fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States int
1449fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States smb_kmod_event_notify(uint32_t txid)
1459fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States {
1469fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	smb_ioc_event_t ioc;
1479fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
1489fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	ioc.txid = txid;
1499fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 	return (smb_kmod_ioctl(SMB_IOC_EVENT, &ioc.hdr, sizeof (ioc)));
1509fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States }
1519fb67ea3Safshin salek ardakani - Sun Microsystems - Irvine United States 
15229bd2886SAlan Wright int
153148c5f43SAlan Wright smb_kmod_share(nvlist_t *shrlist)
15429bd2886SAlan Wright {
15529bd2886SAlan Wright 	smb_ioc_share_t *ioc;
156148c5f43SAlan Wright 	uint32_t ioclen;
157148c5f43SAlan Wright 	char *shrbuf = NULL;
158148c5f43SAlan Wright 	size_t bufsz;
15929bd2886SAlan Wright 	int rc = ENOMEM;
16029bd2886SAlan Wright 
161148c5f43SAlan Wright 	if ((rc = nvlist_pack(shrlist, &shrbuf, &bufsz, NV_ENCODE_XDR, 0)) != 0)
162148c5f43SAlan Wright 		return (rc);
16329bd2886SAlan Wright 
164148c5f43SAlan Wright 	ioclen = sizeof (smb_ioc_share_t) + bufsz;
165148c5f43SAlan Wright 
166148c5f43SAlan Wright 	if ((ioc = malloc(ioclen)) != NULL) {
167148c5f43SAlan Wright 		ioc->shrlen = bufsz;
168148c5f43SAlan Wright 		bcopy(shrbuf, ioc->shr, bufsz);
169148c5f43SAlan Wright 		rc = smb_kmod_ioctl(SMB_IOC_SHARE, &ioc->hdr, ioclen);
17029bd2886SAlan Wright 		free(ioc);
17129bd2886SAlan Wright 	}
172148c5f43SAlan Wright 
173148c5f43SAlan Wright 	free(shrbuf);
17429bd2886SAlan Wright 	return (rc);
17529bd2886SAlan Wright }
17629bd2886SAlan Wright 
17729bd2886SAlan Wright int
178148c5f43SAlan Wright smb_kmod_unshare(nvlist_t *shrlist)
17929bd2886SAlan Wright {
18029bd2886SAlan Wright 	smb_ioc_share_t *ioc;
181148c5f43SAlan Wright 	uint32_t ioclen;
182148c5f43SAlan Wright 	char *shrbuf = NULL;
183148c5f43SAlan Wright 	size_t bufsz;
18429bd2886SAlan Wright 	int rc = ENOMEM;
18529bd2886SAlan Wright 
186148c5f43SAlan Wright 	if ((rc = nvlist_pack(shrlist, &shrbuf, &bufsz, NV_ENCODE_XDR, 0)) != 0)
187148c5f43SAlan Wright 		return (rc);
18829bd2886SAlan Wright 
189148c5f43SAlan Wright 	ioclen = sizeof (smb_ioc_share_t) + bufsz;
190148c5f43SAlan Wright 
191148c5f43SAlan Wright 	if ((ioc = malloc(ioclen)) != NULL) {
192148c5f43SAlan Wright 		ioc->shrlen = bufsz;
193148c5f43SAlan Wright 		bcopy(shrbuf, ioc->shr, bufsz);
194148c5f43SAlan Wright 		rc = smb_kmod_ioctl(SMB_IOC_UNSHARE, &ioc->hdr, ioclen);
19529bd2886SAlan Wright 		free(ioc);
19629bd2886SAlan Wright 	}
197148c5f43SAlan Wright 
198148c5f43SAlan Wright 	free(shrbuf);
19929bd2886SAlan Wright 	return (rc);
20029bd2886SAlan Wright }
20129bd2886SAlan Wright 
20229bd2886SAlan Wright int
203cb174861Sjoyce mcintosh smb_kmod_shareinfo(char *shrname, boolean_t *shortnames)
204cb174861Sjoyce mcintosh {
205cb174861Sjoyce mcintosh 	smb_ioc_shareinfo_t ioc;
206cb174861Sjoyce mcintosh 	int rc;
207cb174861Sjoyce mcintosh 
208cb174861Sjoyce mcintosh 	bzero(&ioc, sizeof (ioc));
209cb174861Sjoyce mcintosh 	(void) strlcpy(ioc.shrname, shrname, MAXNAMELEN);
210cb174861Sjoyce mcintosh 
211cb174861Sjoyce mcintosh 	rc = smb_kmod_ioctl(SMB_IOC_SHAREINFO, &ioc.hdr, sizeof (ioc));
212cb174861Sjoyce mcintosh 	if (rc == 0)
213cb174861Sjoyce mcintosh 		*shortnames = ioc.shortnames;
214cb174861Sjoyce mcintosh 	else
215cb174861Sjoyce mcintosh 		*shortnames = B_TRUE;
216cb174861Sjoyce mcintosh 
217cb174861Sjoyce mcintosh 	return (rc);
218cb174861Sjoyce mcintosh }
219cb174861Sjoyce mcintosh 
220cb174861Sjoyce mcintosh int
2211fcced4cSJordan Brown smb_kmod_get_open_num(smb_opennum_t *opennum)
22229bd2886SAlan Wright {
2231fcced4cSJordan Brown 	smb_ioc_opennum_t ioc;
22429bd2886SAlan Wright 	int rc;
22529bd2886SAlan Wright 
2261fcced4cSJordan Brown 	bzero(&ioc, sizeof (ioc));
2271fcced4cSJordan Brown 	ioc.qualtype = opennum->qualtype;
2281fcced4cSJordan Brown 	(void) strlcpy(ioc.qualifier, opennum->qualifier, MAXNAMELEN);
22929bd2886SAlan Wright 
2301fcced4cSJordan Brown 	rc = smb_kmod_ioctl(SMB_IOC_NUMOPEN, &ioc.hdr, sizeof (ioc));
2311fcced4cSJordan Brown 	if (rc == 0) {
2321fcced4cSJordan Brown 		opennum->open_users = ioc.open_users;
2331fcced4cSJordan Brown 		opennum->open_trees = ioc.open_trees;
2341fcced4cSJordan Brown 		opennum->open_files = ioc.open_files;
2351fcced4cSJordan Brown 	}
2361fcced4cSJordan Brown 
2371fcced4cSJordan Brown 	return (rc);
2381fcced4cSJordan Brown }
2391fcced4cSJordan Brown 
240cb174861Sjoyce mcintosh int
241cb174861Sjoyce mcintosh smb_kmod_get_spool_doc(uint32_t *spool_num, char *username,
242cb174861Sjoyce mcintosh     char *path, smb_inaddr_t *ipaddr)
243cb174861Sjoyce mcintosh {
244cb174861Sjoyce mcintosh 	smb_ioc_spooldoc_t ioc;
245cb174861Sjoyce mcintosh 	int rc;
246cb174861Sjoyce mcintosh 
247cb174861Sjoyce mcintosh 	bzero(&ioc, sizeof (ioc));
248cb174861Sjoyce mcintosh 	rc = smb_kmod_ioctl(SMB_IOC_SPOOLDOC, &ioc.hdr, sizeof (ioc));
249cb174861Sjoyce mcintosh 	if (rc == 0) {
250cb174861Sjoyce mcintosh 		*spool_num = ioc.spool_num;
251cb174861Sjoyce mcintosh 		(void) strlcpy(username, ioc.username, MAXNAMELEN);
252cb174861Sjoyce mcintosh 		(void) strlcpy(path, ioc.path, MAXPATHLEN);
253cb174861Sjoyce mcintosh 		*ipaddr = ioc.ipaddr;
254cb174861Sjoyce mcintosh 	}
255cb174861Sjoyce mcintosh 	return (rc);
256cb174861Sjoyce mcintosh }
257cb174861Sjoyce mcintosh 
2581fcced4cSJordan Brown /*
2591fcced4cSJordan Brown  * Initialization for an smb_kmod_enum request.  If this call succeeds,
2601fcced4cSJordan Brown  * smb_kmod_enum_fini() must be called later to deallocate resources.
2611fcced4cSJordan Brown  */
2621fcced4cSJordan Brown smb_netsvc_t *
2631fcced4cSJordan Brown smb_kmod_enum_init(smb_svcenum_t *request)
2641fcced4cSJordan Brown {
2651fcced4cSJordan Brown 	smb_netsvc_t		*ns;
2661fcced4cSJordan Brown 	smb_svcenum_t		*svcenum;
2671fcced4cSJordan Brown 	smb_ioc_svcenum_t	*ioc;
2681fcced4cSJordan Brown 	uint32_t		ioclen;
2691fcced4cSJordan Brown 
2701fcced4cSJordan Brown 	if ((ns = calloc(1, sizeof (smb_netsvc_t))) == NULL)
2711fcced4cSJordan Brown 		return (NULL);
2721fcced4cSJordan Brown 
2731fcced4cSJordan Brown 	ioclen = sizeof (smb_ioc_svcenum_t) + SMB_IOC_DATA_SIZE;
2741fcced4cSJordan Brown 	if ((ioc = malloc(ioclen)) == NULL) {
2751fcced4cSJordan Brown 		free(ns);
2761fcced4cSJordan Brown 		return (NULL);
2771fcced4cSJordan Brown 	}
2781fcced4cSJordan Brown 
2791fcced4cSJordan Brown 	bzero(ioc, ioclen);
2801fcced4cSJordan Brown 	svcenum = &ioc->svcenum;
2811fcced4cSJordan Brown 	svcenum->se_type   = request->se_type;
2821fcced4cSJordan Brown 	svcenum->se_level  = request->se_level;
2831fcced4cSJordan Brown 	svcenum->se_bavail = SMB_IOC_DATA_SIZE;
2841fcced4cSJordan Brown 	svcenum->se_nlimit = request->se_nlimit;
2851fcced4cSJordan Brown 	svcenum->se_nskip = request->se_nskip;
2861fcced4cSJordan Brown 	svcenum->se_buflen = SMB_IOC_DATA_SIZE;
2871fcced4cSJordan Brown 
2881fcced4cSJordan Brown 	list_create(&ns->ns_list, sizeof (smb_netsvcitem_t),
2891fcced4cSJordan Brown 	    offsetof(smb_netsvcitem_t, nsi_lnd));
2901fcced4cSJordan Brown 
2911fcced4cSJordan Brown 	ns->ns_ioc = ioc;
2921fcced4cSJordan Brown 	ns->ns_ioclen = ioclen;
2931fcced4cSJordan Brown 	return (ns);
2941fcced4cSJordan Brown }
2951fcced4cSJordan Brown 
2961fcced4cSJordan Brown /*
2971fcced4cSJordan Brown  * Cleanup resources allocated via smb_kmod_enum_init and smb_kmod_enum.
2981fcced4cSJordan Brown  */
2991fcced4cSJordan Brown void
3001fcced4cSJordan Brown smb_kmod_enum_fini(smb_netsvc_t *ns)
3011fcced4cSJordan Brown {
3021fcced4cSJordan Brown 	list_t			*lst;
3031fcced4cSJordan Brown 	smb_netsvcitem_t	*item;
3041fcced4cSJordan Brown 	smb_netuserinfo_t	*user;
3051fcced4cSJordan Brown 	smb_netconnectinfo_t	*tree;
3061fcced4cSJordan Brown 	smb_netfileinfo_t	*ofile;
3071fcced4cSJordan Brown 	uint32_t		se_type;
3081fcced4cSJordan Brown 
3091fcced4cSJordan Brown 	if (ns == NULL)
3101fcced4cSJordan Brown 		return;
3111fcced4cSJordan Brown 
3121fcced4cSJordan Brown 	lst = &ns->ns_list;
3131fcced4cSJordan Brown 	se_type = ns->ns_ioc->svcenum.se_type;
3141fcced4cSJordan Brown 
3151fcced4cSJordan Brown 	while ((item = list_head(lst)) != NULL) {
3161fcced4cSJordan Brown 		list_remove(lst, item);
3171fcced4cSJordan Brown 
3181fcced4cSJordan Brown 		switch (se_type) {
3191fcced4cSJordan Brown 		case SMB_SVCENUM_TYPE_USER:
3201fcced4cSJordan Brown 			user = &item->nsi_un.nsi_user;
3211fcced4cSJordan Brown 			free(user->ui_domain);
3221fcced4cSJordan Brown 			free(user->ui_account);
3231fcced4cSJordan Brown 			free(user->ui_workstation);
3241fcced4cSJordan Brown 			break;
3251fcced4cSJordan Brown 		case SMB_SVCENUM_TYPE_TREE:
3261fcced4cSJordan Brown 			tree = &item->nsi_un.nsi_tree;
3271fcced4cSJordan Brown 			free(tree->ci_username);
3281fcced4cSJordan Brown 			free(tree->ci_share);
3291fcced4cSJordan Brown 			break;
3301fcced4cSJordan Brown 		case SMB_SVCENUM_TYPE_FILE:
3311fcced4cSJordan Brown 			ofile = &item->nsi_un.nsi_ofile;
3321fcced4cSJordan Brown 			free(ofile->fi_path);
3331fcced4cSJordan Brown 			free(ofile->fi_username);
3341fcced4cSJordan Brown 			break;
3351fcced4cSJordan Brown 		default:
3361fcced4cSJordan Brown 			break;
3371fcced4cSJordan Brown 		}
3381fcced4cSJordan Brown 	}
3391fcced4cSJordan Brown 
3401fcced4cSJordan Brown 	list_destroy(&ns->ns_list);
3411fcced4cSJordan Brown 	free(ns->ns_items);
3421fcced4cSJordan Brown 	free(ns->ns_ioc);
3431fcced4cSJordan Brown 	free(ns);
3441fcced4cSJordan Brown }
3451fcced4cSJordan Brown 
3461fcced4cSJordan Brown /*
3471fcced4cSJordan Brown  * Enumerate users, connections or files.
3481fcced4cSJordan Brown  */
3491fcced4cSJordan Brown int
3501fcced4cSJordan Brown smb_kmod_enum(smb_netsvc_t *ns)
3511fcced4cSJordan Brown {
3521fcced4cSJordan Brown 	smb_ioc_svcenum_t	*ioc;
3531fcced4cSJordan Brown 	uint32_t		ioclen;
3541fcced4cSJordan Brown 	smb_svcenum_t		*svcenum;
3551fcced4cSJordan Brown 	smb_netsvcitem_t	*items;
3561fcced4cSJordan Brown 	smb_netuserinfo_t	*user;
3571fcced4cSJordan Brown 	smb_netconnectinfo_t	*tree;
3581fcced4cSJordan Brown 	smb_netfileinfo_t	*ofile;
3591fcced4cSJordan Brown 	uint8_t			*data;
3601fcced4cSJordan Brown 	uint32_t		len;
3611fcced4cSJordan Brown 	uint32_t		se_type;
3621fcced4cSJordan Brown 	uint_t			nbytes;
3631fcced4cSJordan Brown 	int			i;
3641fcced4cSJordan Brown 	int			rc;
3651fcced4cSJordan Brown 
3661fcced4cSJordan Brown 	ioc = ns->ns_ioc;
3671fcced4cSJordan Brown 	ioclen = ns->ns_ioclen;
3681fcced4cSJordan Brown 	rc = smb_kmod_ioctl(SMB_IOC_SVCENUM, &ioc->hdr, ioclen);
3691fcced4cSJordan Brown 	if (rc != 0)
3701fcced4cSJordan Brown 		return (rc);
3711fcced4cSJordan Brown 
3721fcced4cSJordan Brown 	svcenum = &ioc->svcenum;
3731fcced4cSJordan Brown 	items = calloc(svcenum->se_nitems, sizeof (smb_netsvcitem_t));
3741fcced4cSJordan Brown 	if (items == NULL)
3751fcced4cSJordan Brown 		return (ENOMEM);
3761fcced4cSJordan Brown 
3771fcced4cSJordan Brown 	ns->ns_items = items;
3781fcced4cSJordan Brown 	se_type = ns->ns_ioc->svcenum.se_type;
3791fcced4cSJordan Brown 	data = svcenum->se_buf;
3801fcced4cSJordan Brown 	len = svcenum->se_bused;
3811fcced4cSJordan Brown 
3821fcced4cSJordan Brown 	for (i = 0; i < svcenum->se_nitems; ++i) {
3831fcced4cSJordan Brown 		switch (se_type) {
3841fcced4cSJordan Brown 		case SMB_SVCENUM_TYPE_USER:
3851fcced4cSJordan Brown 			user = &items->nsi_un.nsi_user;
3861fcced4cSJordan Brown 			rc = smb_netuserinfo_decode(user, data, len, &nbytes);
3871fcced4cSJordan Brown 			break;
3881fcced4cSJordan Brown 		case SMB_SVCENUM_TYPE_TREE:
3891fcced4cSJordan Brown 			tree = &items->nsi_un.nsi_tree;
3901fcced4cSJordan Brown 			rc = smb_netconnectinfo_decode(tree, data, len,
3911fcced4cSJordan Brown 			    &nbytes);
3921fcced4cSJordan Brown 			break;
3931fcced4cSJordan Brown 		case SMB_SVCENUM_TYPE_FILE:
3941fcced4cSJordan Brown 			ofile = &items->nsi_un.nsi_ofile;
3951fcced4cSJordan Brown 			rc = smb_netfileinfo_decode(ofile, data, len, &nbytes);
3961fcced4cSJordan Brown 			break;
3971fcced4cSJordan Brown 		default:
3981fcced4cSJordan Brown 			rc = -1;
3991fcced4cSJordan Brown 			break;
4001fcced4cSJordan Brown 		}
4011fcced4cSJordan Brown 
4021fcced4cSJordan Brown 		if (rc != 0)
4031fcced4cSJordan Brown 			return (EINVAL);
4041fcced4cSJordan Brown 
4051fcced4cSJordan Brown 		list_insert_tail(&ns->ns_list, items);
4061fcced4cSJordan Brown 
4071fcced4cSJordan Brown 		++items;
4081fcced4cSJordan Brown 		data += nbytes;
4091fcced4cSJordan Brown 		len -= nbytes;
4101fcced4cSJordan Brown 	}
4111fcced4cSJordan Brown 
4121fcced4cSJordan Brown 	return (0);
4131fcced4cSJordan Brown }
4141fcced4cSJordan Brown 
4151fcced4cSJordan Brown /*
4161fcced4cSJordan Brown  * A NULL pointer is a wildcard indicator, which we pass on
4171fcced4cSJordan Brown  * as an empty string (by virtue of the bzero).
4181fcced4cSJordan Brown  */
4191fcced4cSJordan Brown int
4201fcced4cSJordan Brown smb_kmod_session_close(const char *client, const char *username)
4211fcced4cSJordan Brown {
4221fcced4cSJordan Brown 	smb_ioc_session_t ioc;
4231fcced4cSJordan Brown 	int rc;
4241fcced4cSJordan Brown 
4251fcced4cSJordan Brown 	bzero(&ioc, sizeof (ioc));
4261fcced4cSJordan Brown 
4271fcced4cSJordan Brown 	if (client != NULL)
4281fcced4cSJordan Brown 		(void) strlcpy(ioc.client, client, MAXNAMELEN);
4291fcced4cSJordan Brown 	if (username != NULL)
4301fcced4cSJordan Brown 		(void) strlcpy(ioc.username, username, MAXNAMELEN);
4311fcced4cSJordan Brown 
4321fcced4cSJordan Brown 	rc = smb_kmod_ioctl(SMB_IOC_SESSION_CLOSE, &ioc.hdr, sizeof (ioc));
43329bd2886SAlan Wright 	return (rc);
43429bd2886SAlan Wright }
43529bd2886SAlan Wright 
43629bd2886SAlan Wright int
4371fcced4cSJordan Brown smb_kmod_file_close(uint32_t uniqid)
43829bd2886SAlan Wright {
4391fcced4cSJordan Brown 	smb_ioc_fileid_t ioc;
44029bd2886SAlan Wright 	int rc;
44129bd2886SAlan Wright 
4421fcced4cSJordan Brown 	bzero(&ioc, sizeof (ioc));
4431fcced4cSJordan Brown 	ioc.uniqid = uniqid;
44429bd2886SAlan Wright 
4451fcced4cSJordan Brown 	rc = smb_kmod_ioctl(SMB_IOC_FILE_CLOSE, &ioc.hdr, sizeof (ioc));
44629bd2886SAlan Wright 	return (rc);
44729bd2886SAlan Wright }
44829bd2886SAlan Wright 
44929bd2886SAlan Wright void
45029bd2886SAlan Wright smb_kmod_unbind(void)
45129bd2886SAlan Wright {
45229bd2886SAlan Wright 	if (smbdrv_fd != -1) {
45329bd2886SAlan Wright 		(void) close(smbdrv_fd);
45429bd2886SAlan Wright 		smbdrv_fd = -1;
45529bd2886SAlan Wright 	}
45629bd2886SAlan Wright }
45729bd2886SAlan Wright 
458b819cea2SGordon Ross /*
459b819cea2SGordon Ross  * Note: The user-space smbd-d provides it own version of this function
460b819cea2SGordon Ross  * which directly calls the "kernel" module code (in user space).
461b819cea2SGordon Ross  */
462b819cea2SGordon Ross int
46329bd2886SAlan Wright smb_kmod_ioctl(int cmd, smb_ioc_header_t *ioc, uint32_t len)
46429bd2886SAlan Wright {
46529bd2886SAlan Wright 	int rc = EINVAL;
46629bd2886SAlan Wright 
46729bd2886SAlan Wright 	ioc->version = SMB_IOC_VERSION;
46829bd2886SAlan Wright 	ioc->cmd = cmd;
46929bd2886SAlan Wright 	ioc->len = len;
47029bd2886SAlan Wright 	ioc->crc = 0;
47129bd2886SAlan Wright 	ioc->crc = smb_crc_gen((uint8_t *)ioc, sizeof (smb_ioc_header_t));
47229bd2886SAlan Wright 
47329bd2886SAlan Wright 	if (smbdrv_fd != -1) {
47429bd2886SAlan Wright 		if (ioctl(smbdrv_fd, cmd, ioc) < 0)
47529bd2886SAlan Wright 			rc = errno;
47629bd2886SAlan Wright 		else
47729bd2886SAlan Wright 			rc = 0;
47829bd2886SAlan Wright 	}
47929bd2886SAlan Wright 	return (rc);
48029bd2886SAlan Wright }
481