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
smb_kmod_bind(void)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
smb_kmod_isbound(void)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
smb_kmod_setcfg(smb_kmod_cfg_t * cfg)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
smb_kmod_setgmtoff(int32_t gmtoff)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
smb_kmod_start(int opipe,int lmshr,int udoor)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
smb_kmod_stop(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
smb_kmod_event_notify(uint32_t txid)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
smb_kmod_share(nvlist_t * shrlist)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
smb_kmod_unshare(nvlist_t * shrlist)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
smb_kmod_shareinfo(char * shrname,boolean_t * shortnames)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
smb_kmod_get_open_num(smb_opennum_t * opennum)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
smb_kmod_get_spool_doc(uint32_t * spool_num,char * username,char * path,smb_inaddr_t * ipaddr)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 *
smb_kmod_enum_init(smb_svcenum_t * request)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
smb_kmod_enum_fini(smb_netsvc_t * ns)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
smb_kmod_enum(smb_netsvc_t * ns)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
smb_kmod_session_close(const char * client,const char * username)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
smb_kmod_file_close(uint32_t uniqid)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
smb_kmod_unbind(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
smb_kmod_ioctl(int cmd,smb_ioc_header_t * ioc,uint32_t len)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