xref: /onnv-gate/usr/src/lib/smbsrv/libsmb/common/smb_kmod.c (revision 13138:89c014c50a5f)
19832Samw@Sun.COM /*
29832Samw@Sun.COM  * CDDL HEADER START
39832Samw@Sun.COM  *
49832Samw@Sun.COM  * The contents of this file are subject to the terms of the
59832Samw@Sun.COM  * Common Development and Distribution License (the "License").
69832Samw@Sun.COM  * You may not use this file except in compliance with the License.
79832Samw@Sun.COM  *
89832Samw@Sun.COM  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
99832Samw@Sun.COM  * or http://www.opensolaris.org/os/licensing.
109832Samw@Sun.COM  * See the License for the specific language governing permissions
119832Samw@Sun.COM  * and limitations under the License.
129832Samw@Sun.COM  *
139832Samw@Sun.COM  * When distributing Covered Code, include this CDDL HEADER in each
149832Samw@Sun.COM  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
159832Samw@Sun.COM  * If applicable, add the following below this CDDL HEADER, with the
169832Samw@Sun.COM  * fields enclosed by brackets "[]" replaced with your own identifying
179832Samw@Sun.COM  * information: Portions Copyright [yyyy] [name of copyright owner]
189832Samw@Sun.COM  *
199832Samw@Sun.COM  * CDDL HEADER END
209832Samw@Sun.COM  */
219832Samw@Sun.COM /*
2212508Samw@Sun.COM  * Copyright (c) 2009, 2010, Oracle and/or its affiliates. All rights reserved.
239832Samw@Sun.COM  */
249832Samw@Sun.COM 
259832Samw@Sun.COM #include <sys/types.h>
269832Samw@Sun.COM #include <sys/stat.h>
279832Samw@Sun.COM #include <sys/ioccom.h>
289832Samw@Sun.COM #include <sys/param.h>
299832Samw@Sun.COM #include <stddef.h>
309832Samw@Sun.COM #include <stdio.h>
319832Samw@Sun.COM #include <string.h>
329832Samw@Sun.COM #include <strings.h>
339832Samw@Sun.COM #include <stdlib.h>
349832Samw@Sun.COM #include <unistd.h>
359832Samw@Sun.COM #include <fcntl.h>
369832Samw@Sun.COM #include <errno.h>
379832Samw@Sun.COM 
389832Samw@Sun.COM #include <smbsrv/smb_xdr.h>
399832Samw@Sun.COM #include <smbsrv/smbinfo.h>
409832Samw@Sun.COM #include <smbsrv/smb_ioctl.h>
419832Samw@Sun.COM #include <smbsrv/smb_ioctl.h>
429832Samw@Sun.COM #include <smbsrv/libsmb.h>
439832Samw@Sun.COM 
449832Samw@Sun.COM #define	SMBDRV_DEVICE_PATH		"/devices/pseudo/smbsrv@0:smbsrv"
459832Samw@Sun.COM #define	SMB_IOC_DATA_SIZE		(256 * 1024)
469832Samw@Sun.COM 
479832Samw@Sun.COM static int smb_kmod_ioctl(int, smb_ioc_header_t *, uint32_t);
489832Samw@Sun.COM 
499832Samw@Sun.COM 
509832Samw@Sun.COM int	smbdrv_fd = -1;
519832Samw@Sun.COM 
529832Samw@Sun.COM int
smb_kmod_bind(void)539832Samw@Sun.COM smb_kmod_bind(void)
549832Samw@Sun.COM {
559832Samw@Sun.COM 	if (smbdrv_fd != -1)
569832Samw@Sun.COM 		(void) close(smbdrv_fd);
579832Samw@Sun.COM 
589832Samw@Sun.COM 	if ((smbdrv_fd = open(SMBDRV_DEVICE_PATH, 0)) < 0) {
599832Samw@Sun.COM 		smbdrv_fd = -1;
609832Samw@Sun.COM 		return (errno);
619832Samw@Sun.COM 	}
629832Samw@Sun.COM 
639832Samw@Sun.COM 	return (0);
649832Samw@Sun.COM }
659832Samw@Sun.COM 
66*13082SJoyce.McIntosh@Sun.COM boolean_t
smb_kmod_isbound(void)67*13082SJoyce.McIntosh@Sun.COM smb_kmod_isbound(void)
68*13082SJoyce.McIntosh@Sun.COM {
69*13082SJoyce.McIntosh@Sun.COM 	return ((smbdrv_fd == -1) ? B_FALSE : B_TRUE);
70*13082SJoyce.McIntosh@Sun.COM }
71*13082SJoyce.McIntosh@Sun.COM 
729832Samw@Sun.COM int
smb_kmod_setcfg(smb_kmod_cfg_t * cfg)739832Samw@Sun.COM smb_kmod_setcfg(smb_kmod_cfg_t *cfg)
749832Samw@Sun.COM {
759832Samw@Sun.COM 	smb_ioc_cfg_t ioc;
769832Samw@Sun.COM 
779832Samw@Sun.COM 	ioc.maxworkers = cfg->skc_maxworkers;
789832Samw@Sun.COM 	ioc.maxconnections = cfg->skc_maxconnections;
799832Samw@Sun.COM 	ioc.keepalive = cfg->skc_keepalive;
809832Samw@Sun.COM 	ioc.restrict_anon = cfg->skc_restrict_anon;
819832Samw@Sun.COM 	ioc.signing_enable = cfg->skc_signing_enable;
829832Samw@Sun.COM 	ioc.signing_required = cfg->skc_signing_required;
839832Samw@Sun.COM 	ioc.oplock_enable = cfg->skc_oplock_enable;
849832Samw@Sun.COM 	ioc.sync_enable = cfg->skc_sync_enable;
859832Samw@Sun.COM 	ioc.secmode = cfg->skc_secmode;
869832Samw@Sun.COM 	ioc.ipv6_enable = cfg->skc_ipv6_enable;
8712890SJoyce.McIntosh@Sun.COM 	ioc.print_enable = cfg->skc_print_enable;
8812508Samw@Sun.COM 	ioc.exec_flags = cfg->skc_execflags;
8912508Samw@Sun.COM 	ioc.version = cfg->skc_version;
909832Samw@Sun.COM 
919832Samw@Sun.COM 	(void) strlcpy(ioc.nbdomain, cfg->skc_nbdomain, sizeof (ioc.nbdomain));
929832Samw@Sun.COM 	(void) strlcpy(ioc.fqdn, cfg->skc_fqdn, sizeof (ioc.fqdn));
939832Samw@Sun.COM 	(void) strlcpy(ioc.hostname, cfg->skc_hostname, sizeof (ioc.hostname));
949832Samw@Sun.COM 	(void) strlcpy(ioc.system_comment, cfg->skc_system_comment,
959832Samw@Sun.COM 	    sizeof (ioc.system_comment));
969832Samw@Sun.COM 
979832Samw@Sun.COM 	return (smb_kmod_ioctl(SMB_IOC_CONFIG, &ioc.hdr, sizeof (ioc)));
989832Samw@Sun.COM }
999832Samw@Sun.COM 
1009832Samw@Sun.COM int
smb_kmod_setgmtoff(int32_t gmtoff)1019832Samw@Sun.COM smb_kmod_setgmtoff(int32_t gmtoff)
1029832Samw@Sun.COM {
1039832Samw@Sun.COM 	smb_ioc_gmt_t ioc;
1049832Samw@Sun.COM 
1059832Samw@Sun.COM 	ioc.offset = gmtoff;
1069832Samw@Sun.COM 	return (smb_kmod_ioctl(SMB_IOC_GMTOFF, &ioc.hdr,
1079832Samw@Sun.COM 	    sizeof (ioc)));
1089832Samw@Sun.COM }
1099832Samw@Sun.COM 
1109832Samw@Sun.COM int
smb_kmod_start(int opipe,int lmshr,int udoor)1119832Samw@Sun.COM smb_kmod_start(int opipe, int lmshr, int udoor)
1129832Samw@Sun.COM {
1139832Samw@Sun.COM 	smb_ioc_start_t ioc;
1149832Samw@Sun.COM 
1159832Samw@Sun.COM 	ioc.opipe = opipe;
1169832Samw@Sun.COM 	ioc.lmshrd = lmshr;
1179832Samw@Sun.COM 	ioc.udoor = udoor;
1189832Samw@Sun.COM 	return (smb_kmod_ioctl(SMB_IOC_START, &ioc.hdr, sizeof (ioc)));
1199832Samw@Sun.COM }
1209832Samw@Sun.COM 
12111963SAfshin.Ardakani@Sun.COM void
smb_kmod_stop(void)12211963SAfshin.Ardakani@Sun.COM smb_kmod_stop(void)
12311963SAfshin.Ardakani@Sun.COM {
12411963SAfshin.Ardakani@Sun.COM 	smb_ioc_header_t ioc;
12511963SAfshin.Ardakani@Sun.COM 
12611963SAfshin.Ardakani@Sun.COM 	(void) smb_kmod_ioctl(SMB_IOC_STOP, &ioc, sizeof (ioc));
12711963SAfshin.Ardakani@Sun.COM }
12811963SAfshin.Ardakani@Sun.COM 
12911963SAfshin.Ardakani@Sun.COM int
smb_kmod_event_notify(uint32_t txid)13011963SAfshin.Ardakani@Sun.COM smb_kmod_event_notify(uint32_t txid)
13111963SAfshin.Ardakani@Sun.COM {
13211963SAfshin.Ardakani@Sun.COM 	smb_ioc_event_t ioc;
13311963SAfshin.Ardakani@Sun.COM 
13411963SAfshin.Ardakani@Sun.COM 	ioc.txid = txid;
13511963SAfshin.Ardakani@Sun.COM 	return (smb_kmod_ioctl(SMB_IOC_EVENT, &ioc.hdr, sizeof (ioc)));
13611963SAfshin.Ardakani@Sun.COM }
13711963SAfshin.Ardakani@Sun.COM 
1389832Samw@Sun.COM int
smb_kmod_share(nvlist_t * shrlist)13912508Samw@Sun.COM smb_kmod_share(nvlist_t *shrlist)
1409832Samw@Sun.COM {
1419832Samw@Sun.COM 	smb_ioc_share_t *ioc;
14212508Samw@Sun.COM 	uint32_t ioclen;
14312508Samw@Sun.COM 	char *shrbuf = NULL;
14412508Samw@Sun.COM 	size_t bufsz;
1459832Samw@Sun.COM 	int rc = ENOMEM;
1469832Samw@Sun.COM 
14712508Samw@Sun.COM 	if ((rc = nvlist_pack(shrlist, &shrbuf, &bufsz, NV_ENCODE_XDR, 0)) != 0)
14812508Samw@Sun.COM 		return (rc);
14912508Samw@Sun.COM 
15012508Samw@Sun.COM 	ioclen = sizeof (smb_ioc_share_t) + bufsz;
1519832Samw@Sun.COM 
15212508Samw@Sun.COM 	if ((ioc = malloc(ioclen)) != NULL) {
15312508Samw@Sun.COM 		ioc->shrlen = bufsz;
15412508Samw@Sun.COM 		bcopy(shrbuf, ioc->shr, bufsz);
15512508Samw@Sun.COM 		rc = smb_kmod_ioctl(SMB_IOC_SHARE, &ioc->hdr, ioclen);
1569832Samw@Sun.COM 		free(ioc);
1579832Samw@Sun.COM 	}
15812508Samw@Sun.COM 
15912508Samw@Sun.COM 	free(shrbuf);
1609832Samw@Sun.COM 	return (rc);
1619832Samw@Sun.COM }
1629832Samw@Sun.COM 
1639832Samw@Sun.COM int
smb_kmod_unshare(nvlist_t * shrlist)16412508Samw@Sun.COM smb_kmod_unshare(nvlist_t *shrlist)
1659832Samw@Sun.COM {
1669832Samw@Sun.COM 	smb_ioc_share_t *ioc;
16712508Samw@Sun.COM 	uint32_t ioclen;
16812508Samw@Sun.COM 	char *shrbuf = NULL;
16912508Samw@Sun.COM 	size_t bufsz;
1709832Samw@Sun.COM 	int rc = ENOMEM;
1719832Samw@Sun.COM 
17212508Samw@Sun.COM 	if ((rc = nvlist_pack(shrlist, &shrbuf, &bufsz, NV_ENCODE_XDR, 0)) != 0)
17312508Samw@Sun.COM 		return (rc);
17412508Samw@Sun.COM 
17512508Samw@Sun.COM 	ioclen = sizeof (smb_ioc_share_t) + bufsz;
1769832Samw@Sun.COM 
17712508Samw@Sun.COM 	if ((ioc = malloc(ioclen)) != NULL) {
17812508Samw@Sun.COM 		ioc->shrlen = bufsz;
17912508Samw@Sun.COM 		bcopy(shrbuf, ioc->shr, bufsz);
18012508Samw@Sun.COM 		rc = smb_kmod_ioctl(SMB_IOC_UNSHARE, &ioc->hdr, ioclen);
1819832Samw@Sun.COM 		free(ioc);
1829832Samw@Sun.COM 	}
18312508Samw@Sun.COM 
18412508Samw@Sun.COM 	free(shrbuf);
1859832Samw@Sun.COM 	return (rc);
1869832Samw@Sun.COM }
1879832Samw@Sun.COM 
1889832Samw@Sun.COM int
smb_kmod_shareinfo(char * shrname,boolean_t * shortnames)18912890SJoyce.McIntosh@Sun.COM smb_kmod_shareinfo(char *shrname, boolean_t *shortnames)
19012890SJoyce.McIntosh@Sun.COM {
19112890SJoyce.McIntosh@Sun.COM 	smb_ioc_shareinfo_t ioc;
19212890SJoyce.McIntosh@Sun.COM 	int rc;
19312890SJoyce.McIntosh@Sun.COM 
19412890SJoyce.McIntosh@Sun.COM 	bzero(&ioc, sizeof (ioc));
19512890SJoyce.McIntosh@Sun.COM 	(void) strlcpy(ioc.shrname, shrname, MAXNAMELEN);
19612890SJoyce.McIntosh@Sun.COM 
19712890SJoyce.McIntosh@Sun.COM 	rc = smb_kmod_ioctl(SMB_IOC_SHAREINFO, &ioc.hdr, sizeof (ioc));
19812890SJoyce.McIntosh@Sun.COM 	if (rc == 0)
19912890SJoyce.McIntosh@Sun.COM 		*shortnames = ioc.shortnames;
20012890SJoyce.McIntosh@Sun.COM 	else
20112890SJoyce.McIntosh@Sun.COM 		*shortnames = B_TRUE;
20212890SJoyce.McIntosh@Sun.COM 
20312890SJoyce.McIntosh@Sun.COM 	return (rc);
20412890SJoyce.McIntosh@Sun.COM }
20512890SJoyce.McIntosh@Sun.COM 
20612890SJoyce.McIntosh@Sun.COM int
smb_kmod_get_open_num(smb_opennum_t * opennum)20710122SJordan.Brown@Sun.COM smb_kmod_get_open_num(smb_opennum_t *opennum)
2089832Samw@Sun.COM {
20910122SJordan.Brown@Sun.COM 	smb_ioc_opennum_t ioc;
2109832Samw@Sun.COM 	int rc;
2119832Samw@Sun.COM 
21210122SJordan.Brown@Sun.COM 	bzero(&ioc, sizeof (ioc));
21310122SJordan.Brown@Sun.COM 	ioc.qualtype = opennum->qualtype;
21410122SJordan.Brown@Sun.COM 	(void) strlcpy(ioc.qualifier, opennum->qualifier, MAXNAMELEN);
21510122SJordan.Brown@Sun.COM 
21610122SJordan.Brown@Sun.COM 	rc = smb_kmod_ioctl(SMB_IOC_NUMOPEN, &ioc.hdr, sizeof (ioc));
21710122SJordan.Brown@Sun.COM 	if (rc == 0) {
21810122SJordan.Brown@Sun.COM 		opennum->open_users = ioc.open_users;
21910122SJordan.Brown@Sun.COM 		opennum->open_trees = ioc.open_trees;
22010122SJordan.Brown@Sun.COM 		opennum->open_files = ioc.open_files;
22110122SJordan.Brown@Sun.COM 	}
22210122SJordan.Brown@Sun.COM 
22310122SJordan.Brown@Sun.COM 	return (rc);
22410122SJordan.Brown@Sun.COM }
22510122SJordan.Brown@Sun.COM 
22612890SJoyce.McIntosh@Sun.COM int
smb_kmod_get_spool_doc(uint32_t * spool_num,char * username,char * path,smb_inaddr_t * ipaddr)22712890SJoyce.McIntosh@Sun.COM smb_kmod_get_spool_doc(uint32_t *spool_num, char *username,
22812890SJoyce.McIntosh@Sun.COM     char *path, smb_inaddr_t *ipaddr)
22912890SJoyce.McIntosh@Sun.COM {
23012890SJoyce.McIntosh@Sun.COM 	smb_ioc_spooldoc_t ioc;
23112890SJoyce.McIntosh@Sun.COM 	int rc;
23212890SJoyce.McIntosh@Sun.COM 
23312890SJoyce.McIntosh@Sun.COM 	bzero(&ioc, sizeof (ioc));
23412890SJoyce.McIntosh@Sun.COM 	rc = smb_kmod_ioctl(SMB_IOC_SPOOLDOC, &ioc.hdr, sizeof (ioc));
23512890SJoyce.McIntosh@Sun.COM 	if (rc == 0) {
23612890SJoyce.McIntosh@Sun.COM 		*spool_num = ioc.spool_num;
23712890SJoyce.McIntosh@Sun.COM 		(void) strlcpy(username, ioc.username, MAXNAMELEN);
23812890SJoyce.McIntosh@Sun.COM 		(void) strlcpy(path, ioc.path, MAXPATHLEN);
23912890SJoyce.McIntosh@Sun.COM 		*ipaddr = ioc.ipaddr;
24012890SJoyce.McIntosh@Sun.COM 	}
24112890SJoyce.McIntosh@Sun.COM 	return (rc);
24212890SJoyce.McIntosh@Sun.COM }
24312890SJoyce.McIntosh@Sun.COM 
24410122SJordan.Brown@Sun.COM /*
24510122SJordan.Brown@Sun.COM  * Initialization for an smb_kmod_enum request.  If this call succeeds,
24610122SJordan.Brown@Sun.COM  * smb_kmod_enum_fini() must be called later to deallocate resources.
24710122SJordan.Brown@Sun.COM  */
24810122SJordan.Brown@Sun.COM smb_netsvc_t *
smb_kmod_enum_init(smb_svcenum_t * request)24910122SJordan.Brown@Sun.COM smb_kmod_enum_init(smb_svcenum_t *request)
25010122SJordan.Brown@Sun.COM {
25110122SJordan.Brown@Sun.COM 	smb_netsvc_t		*ns;
25210122SJordan.Brown@Sun.COM 	smb_svcenum_t		*svcenum;
25310122SJordan.Brown@Sun.COM 	smb_ioc_svcenum_t	*ioc;
25410122SJordan.Brown@Sun.COM 	uint32_t		ioclen;
25510122SJordan.Brown@Sun.COM 
25610122SJordan.Brown@Sun.COM 	if ((ns = calloc(1, sizeof (smb_netsvc_t))) == NULL)
25710122SJordan.Brown@Sun.COM 		return (NULL);
25810122SJordan.Brown@Sun.COM 
25910122SJordan.Brown@Sun.COM 	ioclen = sizeof (smb_ioc_svcenum_t) + SMB_IOC_DATA_SIZE;
26010122SJordan.Brown@Sun.COM 	if ((ioc = malloc(ioclen)) == NULL) {
26110122SJordan.Brown@Sun.COM 		free(ns);
26210122SJordan.Brown@Sun.COM 		return (NULL);
26310122SJordan.Brown@Sun.COM 	}
26410122SJordan.Brown@Sun.COM 
26510122SJordan.Brown@Sun.COM 	bzero(ioc, ioclen);
26610122SJordan.Brown@Sun.COM 	svcenum = &ioc->svcenum;
26710122SJordan.Brown@Sun.COM 	svcenum->se_type   = request->se_type;
26810122SJordan.Brown@Sun.COM 	svcenum->se_level  = request->se_level;
26910122SJordan.Brown@Sun.COM 	svcenum->se_bavail = SMB_IOC_DATA_SIZE;
27010122SJordan.Brown@Sun.COM 	svcenum->se_nlimit = request->se_nlimit;
27110122SJordan.Brown@Sun.COM 	svcenum->se_nskip = request->se_nskip;
27210122SJordan.Brown@Sun.COM 	svcenum->se_buflen = SMB_IOC_DATA_SIZE;
27310122SJordan.Brown@Sun.COM 
27410122SJordan.Brown@Sun.COM 	list_create(&ns->ns_list, sizeof (smb_netsvcitem_t),
27510122SJordan.Brown@Sun.COM 	    offsetof(smb_netsvcitem_t, nsi_lnd));
27610122SJordan.Brown@Sun.COM 
27710122SJordan.Brown@Sun.COM 	ns->ns_ioc = ioc;
27810122SJordan.Brown@Sun.COM 	ns->ns_ioclen = ioclen;
27910122SJordan.Brown@Sun.COM 	return (ns);
28010122SJordan.Brown@Sun.COM }
28110122SJordan.Brown@Sun.COM 
28210122SJordan.Brown@Sun.COM /*
28310122SJordan.Brown@Sun.COM  * Cleanup resources allocated via smb_kmod_enum_init and smb_kmod_enum.
28410122SJordan.Brown@Sun.COM  */
28510122SJordan.Brown@Sun.COM void
smb_kmod_enum_fini(smb_netsvc_t * ns)28610122SJordan.Brown@Sun.COM smb_kmod_enum_fini(smb_netsvc_t *ns)
28710122SJordan.Brown@Sun.COM {
28810122SJordan.Brown@Sun.COM 	list_t			*lst;
28910122SJordan.Brown@Sun.COM 	smb_netsvcitem_t	*item;
29010122SJordan.Brown@Sun.COM 	smb_netuserinfo_t	*user;
29110122SJordan.Brown@Sun.COM 	smb_netconnectinfo_t	*tree;
29210122SJordan.Brown@Sun.COM 	smb_netfileinfo_t	*ofile;
29310122SJordan.Brown@Sun.COM 	uint32_t		se_type;
29410122SJordan.Brown@Sun.COM 
29510122SJordan.Brown@Sun.COM 	if (ns == NULL)
29610122SJordan.Brown@Sun.COM 		return;
29710122SJordan.Brown@Sun.COM 
29810122SJordan.Brown@Sun.COM 	lst = &ns->ns_list;
29910122SJordan.Brown@Sun.COM 	se_type = ns->ns_ioc->svcenum.se_type;
30010122SJordan.Brown@Sun.COM 
30110122SJordan.Brown@Sun.COM 	while ((item = list_head(lst)) != NULL) {
30210122SJordan.Brown@Sun.COM 		list_remove(lst, item);
3039832Samw@Sun.COM 
30410122SJordan.Brown@Sun.COM 		switch (se_type) {
30510122SJordan.Brown@Sun.COM 		case SMB_SVCENUM_TYPE_USER:
30610122SJordan.Brown@Sun.COM 			user = &item->nsi_un.nsi_user;
30710122SJordan.Brown@Sun.COM 			free(user->ui_domain);
30810122SJordan.Brown@Sun.COM 			free(user->ui_account);
30910122SJordan.Brown@Sun.COM 			free(user->ui_workstation);
31010122SJordan.Brown@Sun.COM 			break;
31110122SJordan.Brown@Sun.COM 		case SMB_SVCENUM_TYPE_TREE:
31210122SJordan.Brown@Sun.COM 			tree = &item->nsi_un.nsi_tree;
31310122SJordan.Brown@Sun.COM 			free(tree->ci_username);
31410122SJordan.Brown@Sun.COM 			free(tree->ci_share);
31510122SJordan.Brown@Sun.COM 			break;
31610122SJordan.Brown@Sun.COM 		case SMB_SVCENUM_TYPE_FILE:
31710122SJordan.Brown@Sun.COM 			ofile = &item->nsi_un.nsi_ofile;
31810122SJordan.Brown@Sun.COM 			free(ofile->fi_path);
31910122SJordan.Brown@Sun.COM 			free(ofile->fi_username);
32010122SJordan.Brown@Sun.COM 			break;
32110122SJordan.Brown@Sun.COM 		default:
32210122SJordan.Brown@Sun.COM 			break;
32310122SJordan.Brown@Sun.COM 		}
32410122SJordan.Brown@Sun.COM 	}
32510122SJordan.Brown@Sun.COM 
32610122SJordan.Brown@Sun.COM 	list_destroy(&ns->ns_list);
32710122SJordan.Brown@Sun.COM 	free(ns->ns_items);
32810122SJordan.Brown@Sun.COM 	free(ns->ns_ioc);
32910122SJordan.Brown@Sun.COM 	free(ns);
33010122SJordan.Brown@Sun.COM }
33110122SJordan.Brown@Sun.COM 
33210122SJordan.Brown@Sun.COM /*
33310122SJordan.Brown@Sun.COM  * Enumerate users, connections or files.
33410122SJordan.Brown@Sun.COM  */
33510122SJordan.Brown@Sun.COM int
smb_kmod_enum(smb_netsvc_t * ns)33610122SJordan.Brown@Sun.COM smb_kmod_enum(smb_netsvc_t *ns)
33710122SJordan.Brown@Sun.COM {
33810122SJordan.Brown@Sun.COM 	smb_ioc_svcenum_t	*ioc;
33910122SJordan.Brown@Sun.COM 	uint32_t		ioclen;
34010122SJordan.Brown@Sun.COM 	smb_svcenum_t		*svcenum;
34110122SJordan.Brown@Sun.COM 	smb_netsvcitem_t	*items;
34210122SJordan.Brown@Sun.COM 	smb_netuserinfo_t	*user;
34310122SJordan.Brown@Sun.COM 	smb_netconnectinfo_t	*tree;
34410122SJordan.Brown@Sun.COM 	smb_netfileinfo_t	*ofile;
34510122SJordan.Brown@Sun.COM 	uint8_t			*data;
34610122SJordan.Brown@Sun.COM 	uint32_t		len;
34710122SJordan.Brown@Sun.COM 	uint32_t		se_type;
34810122SJordan.Brown@Sun.COM 	uint_t			nbytes;
34910122SJordan.Brown@Sun.COM 	int			i;
35010122SJordan.Brown@Sun.COM 	int			rc;
35110122SJordan.Brown@Sun.COM 
35210122SJordan.Brown@Sun.COM 	ioc = ns->ns_ioc;
35310122SJordan.Brown@Sun.COM 	ioclen = ns->ns_ioclen;
35410122SJordan.Brown@Sun.COM 	rc = smb_kmod_ioctl(SMB_IOC_SVCENUM, &ioc->hdr, ioclen);
35510122SJordan.Brown@Sun.COM 	if (rc != 0)
35610122SJordan.Brown@Sun.COM 		return (rc);
35710122SJordan.Brown@Sun.COM 
35810122SJordan.Brown@Sun.COM 	svcenum = &ioc->svcenum;
35910122SJordan.Brown@Sun.COM 	items = calloc(svcenum->se_nitems, sizeof (smb_netsvcitem_t));
36010122SJordan.Brown@Sun.COM 	if (items == NULL)
36110122SJordan.Brown@Sun.COM 		return (ENOMEM);
36210122SJordan.Brown@Sun.COM 
36310122SJordan.Brown@Sun.COM 	ns->ns_items = items;
36410122SJordan.Brown@Sun.COM 	se_type = ns->ns_ioc->svcenum.se_type;
36510122SJordan.Brown@Sun.COM 	data = svcenum->se_buf;
36610122SJordan.Brown@Sun.COM 	len = svcenum->se_bused;
36710122SJordan.Brown@Sun.COM 
36810122SJordan.Brown@Sun.COM 	for (i = 0; i < svcenum->se_nitems; ++i) {
36910122SJordan.Brown@Sun.COM 		switch (se_type) {
37010122SJordan.Brown@Sun.COM 		case SMB_SVCENUM_TYPE_USER:
37110122SJordan.Brown@Sun.COM 			user = &items->nsi_un.nsi_user;
37210122SJordan.Brown@Sun.COM 			rc = smb_netuserinfo_decode(user, data, len, &nbytes);
37310122SJordan.Brown@Sun.COM 			break;
37410122SJordan.Brown@Sun.COM 		case SMB_SVCENUM_TYPE_TREE:
37510122SJordan.Brown@Sun.COM 			tree = &items->nsi_un.nsi_tree;
37610122SJordan.Brown@Sun.COM 			rc = smb_netconnectinfo_decode(tree, data, len,
37710122SJordan.Brown@Sun.COM 			    &nbytes);
37810122SJordan.Brown@Sun.COM 			break;
37910122SJordan.Brown@Sun.COM 		case SMB_SVCENUM_TYPE_FILE:
38010122SJordan.Brown@Sun.COM 			ofile = &items->nsi_un.nsi_ofile;
38110122SJordan.Brown@Sun.COM 			rc = smb_netfileinfo_decode(ofile, data, len, &nbytes);
38210122SJordan.Brown@Sun.COM 			break;
38310122SJordan.Brown@Sun.COM 		default:
38410122SJordan.Brown@Sun.COM 			rc = -1;
38510122SJordan.Brown@Sun.COM 			break;
38610122SJordan.Brown@Sun.COM 		}
38710122SJordan.Brown@Sun.COM 
38810122SJordan.Brown@Sun.COM 		if (rc != 0)
38910122SJordan.Brown@Sun.COM 			return (EINVAL);
39010122SJordan.Brown@Sun.COM 
39110122SJordan.Brown@Sun.COM 		list_insert_tail(&ns->ns_list, items);
39210122SJordan.Brown@Sun.COM 
39310122SJordan.Brown@Sun.COM 		++items;
39410122SJordan.Brown@Sun.COM 		data += nbytes;
39510122SJordan.Brown@Sun.COM 		len -= nbytes;
39610122SJordan.Brown@Sun.COM 	}
39710122SJordan.Brown@Sun.COM 
39810122SJordan.Brown@Sun.COM 	return (0);
39910122SJordan.Brown@Sun.COM }
40010122SJordan.Brown@Sun.COM 
40110122SJordan.Brown@Sun.COM /*
40210122SJordan.Brown@Sun.COM  * A NULL pointer is a wildcard indicator, which we pass on
40310122SJordan.Brown@Sun.COM  * as an empty string (by virtue of the bzero).
40410122SJordan.Brown@Sun.COM  */
40510122SJordan.Brown@Sun.COM int
smb_kmod_session_close(const char * client,const char * username)40610122SJordan.Brown@Sun.COM smb_kmod_session_close(const char *client, const char *username)
40710122SJordan.Brown@Sun.COM {
40810122SJordan.Brown@Sun.COM 	smb_ioc_session_t ioc;
40910122SJordan.Brown@Sun.COM 	int rc;
41010122SJordan.Brown@Sun.COM 
41110122SJordan.Brown@Sun.COM 	bzero(&ioc, sizeof (ioc));
41210122SJordan.Brown@Sun.COM 
41310122SJordan.Brown@Sun.COM 	if (client != NULL)
41410122SJordan.Brown@Sun.COM 		(void) strlcpy(ioc.client, client, MAXNAMELEN);
41510122SJordan.Brown@Sun.COM 	if (username != NULL)
41610122SJordan.Brown@Sun.COM 		(void) strlcpy(ioc.username, username, MAXNAMELEN);
41710122SJordan.Brown@Sun.COM 
41810122SJordan.Brown@Sun.COM 	rc = smb_kmod_ioctl(SMB_IOC_SESSION_CLOSE, &ioc.hdr, sizeof (ioc));
4199832Samw@Sun.COM 	return (rc);
4209832Samw@Sun.COM }
4219832Samw@Sun.COM 
4229832Samw@Sun.COM int
smb_kmod_file_close(uint32_t uniqid)42310122SJordan.Brown@Sun.COM smb_kmod_file_close(uint32_t uniqid)
4249832Samw@Sun.COM {
42510122SJordan.Brown@Sun.COM 	smb_ioc_fileid_t ioc;
42610122SJordan.Brown@Sun.COM 	int rc;
4279832Samw@Sun.COM 
42810122SJordan.Brown@Sun.COM 	bzero(&ioc, sizeof (ioc));
42910122SJordan.Brown@Sun.COM 	ioc.uniqid = uniqid;
4309832Samw@Sun.COM 
43110122SJordan.Brown@Sun.COM 	rc = smb_kmod_ioctl(SMB_IOC_FILE_CLOSE, &ioc.hdr, sizeof (ioc));
4329832Samw@Sun.COM 	return (rc);
4339832Samw@Sun.COM }
4349832Samw@Sun.COM 
4359832Samw@Sun.COM void
smb_kmod_unbind(void)4369832Samw@Sun.COM smb_kmod_unbind(void)
4379832Samw@Sun.COM {
4389832Samw@Sun.COM 	if (smbdrv_fd != -1) {
4399832Samw@Sun.COM 		(void) close(smbdrv_fd);
4409832Samw@Sun.COM 		smbdrv_fd = -1;
4419832Samw@Sun.COM 	}
4429832Samw@Sun.COM }
4439832Samw@Sun.COM 
4449832Samw@Sun.COM static int
smb_kmod_ioctl(int cmd,smb_ioc_header_t * ioc,uint32_t len)4459832Samw@Sun.COM smb_kmod_ioctl(int cmd, smb_ioc_header_t *ioc, uint32_t len)
4469832Samw@Sun.COM {
4479832Samw@Sun.COM 	int rc = EINVAL;
4489832Samw@Sun.COM 
4499832Samw@Sun.COM 	ioc->version = SMB_IOC_VERSION;
4509832Samw@Sun.COM 	ioc->cmd = cmd;
4519832Samw@Sun.COM 	ioc->len = len;
4529832Samw@Sun.COM 	ioc->crc = 0;
4539832Samw@Sun.COM 	ioc->crc = smb_crc_gen((uint8_t *)ioc, sizeof (smb_ioc_header_t));
4549832Samw@Sun.COM 
4559832Samw@Sun.COM 	if (smbdrv_fd != -1) {
4569832Samw@Sun.COM 		if (ioctl(smbdrv_fd, cmd, ioc) < 0)
4579832Samw@Sun.COM 			rc = errno;
4589832Samw@Sun.COM 		else
4599832Samw@Sun.COM 			rc = 0;
4609832Samw@Sun.COM 	}
4619832Samw@Sun.COM 	return (rc);
4629832Samw@Sun.COM }
463