1b819cea2SGordon Ross /*
2b819cea2SGordon Ross  * This file and its contents are supplied under the terms of the
3b819cea2SGordon Ross  * Common Development and Distribution License ("CDDL"), version 1.0.
4b819cea2SGordon Ross  * You may only use this file in accordance with the terms of version
5b819cea2SGordon Ross  * 1.0 of the CDDL.
6b819cea2SGordon Ross  *
7b819cea2SGordon Ross  * A full copy of the text of the CDDL should have accompanied this
8b819cea2SGordon Ross  * source.  A copy of the CDDL is also available via the Internet at
9b819cea2SGordon Ross  * http://www.illumos.org/license/CDDL.
10b819cea2SGordon Ross  */
11b819cea2SGordon Ross 
12b819cea2SGordon Ross /*
133e2c0c09SMatt Barden  * Copyright 2017 Nexenta Systems, Inc.  All rights reserved.
14b819cea2SGordon Ross  */
15b819cea2SGordon Ross 
16b819cea2SGordon Ross /*
17b819cea2SGordon Ross  * These replace NODIRECT functions of the same name in
18b819cea2SGordon Ross  * $SRC/lib/smbsrv/libsmb/common/smb_kmod.c including:
19b819cea2SGordon Ross  *	smb_kmod_bind, smb_kmod_ioctl, smb_kmod_isbound,
20b819cea2SGordon Ross  *	smb_kmod_start, smb_kmod_stop, smb_kmod_unbind.
21b819cea2SGordon Ross  *
22b819cea2SGordon Ross  * For all the other smb_kmod_... functions, we can just use the
23b819cea2SGordon Ross  * libsmb code because those all call smb_kmod_ioctl, for which
24b819cea2SGordon Ross  * we have an override here.
25b819cea2SGordon Ross  *
26b819cea2SGordon Ross  * The replacment functions here just call the libfksmbsrv code
27b819cea2SGordon Ross  * directly where the real (in-kernel) versions would be entered
28b819cea2SGordon Ross  * via the driver framework (open, close, ioctl).  Aside from that,
29b819cea2SGordon Ross  * the call sequences are intentionally the same (where possible).
30b819cea2SGordon Ross  * In particular, that makes it possible to debug startup/teardown
31b819cea2SGordon Ross  * problems in the user-space version of this code.
32b819cea2SGordon Ross  */
33b819cea2SGordon Ross 
34b819cea2SGordon Ross #include <sys/types.h>
35b819cea2SGordon Ross #include <sys/stat.h>
36b819cea2SGordon Ross #include <sys/ioccom.h>
37b819cea2SGordon Ross #include <sys/param.h>
38b819cea2SGordon Ross #include <stddef.h>
39b819cea2SGordon Ross #include <stdio.h>
40b819cea2SGordon Ross #include <string.h>
41b819cea2SGordon Ross #include <strings.h>
42b819cea2SGordon Ross #include <stdlib.h>
43b819cea2SGordon Ross #include <unistd.h>
44b819cea2SGordon Ross #include <fcntl.h>
45b819cea2SGordon Ross #include <errno.h>
46b819cea2SGordon Ross #include <note.h>
47b819cea2SGordon Ross 
48b819cea2SGordon Ross #include <smbsrv/smbinfo.h>
49b819cea2SGordon Ross #include <smbsrv/smb_ioctl.h>
50b819cea2SGordon Ross #include "smbd.h"
51b819cea2SGordon Ross 
52b819cea2SGordon Ross boolean_t smbdrv_opened = B_FALSE;
53b819cea2SGordon Ross 
54b819cea2SGordon Ross /*
55b819cea2SGordon Ross  * We want to adjust a few things in the standard configuration
56b819cea2SGordon Ross  * passed to the "fake" version of the smbsrv kernel module.
57b819cea2SGordon Ross  *
58b819cea2SGordon Ross  * Reduce the maximum number of connections and workers, just for
59b819cea2SGordon Ross  * convenience while debugging.  (Don't want hundreds of threads.)
60b819cea2SGordon Ross  */
61b819cea2SGordon Ross static void
fksmbd_adjust_config(smb_ioc_header_t * ioc_hdr)62b819cea2SGordon Ross fksmbd_adjust_config(smb_ioc_header_t *ioc_hdr)
63b819cea2SGordon Ross {
64b819cea2SGordon Ross 	smb_ioc_cfg_t *ioc = (smb_ioc_cfg_t *)ioc_hdr;
6512b65585SGordon Ross 	char *s;
66b819cea2SGordon Ross 
67b819cea2SGordon Ross 	ioc->maxconnections = 10;
68b819cea2SGordon Ross 	ioc->maxworkers = 20;
69b819cea2SGordon Ross 	smbd_report("maxconnections=%d, maxworkers=%d",
70b819cea2SGordon Ross 	    ioc->maxconnections, ioc->maxworkers);
7112b65585SGordon Ross 
72c51c88bdSMatt Barden 	if ((s = getenv("SMB_MAX_PROTOCOL")) != NULL) {
733e2c0c09SMatt Barden 		ioc->max_protocol = strtol(s, NULL, 16);
743e2c0c09SMatt Barden 		smbd_report("max_protocol=0x%x", ioc->max_protocol);
753e2c0c09SMatt Barden 	}
763e2c0c09SMatt Barden 
773e2c0c09SMatt Barden 	if ((s = getenv("SMB_MIN_PROTOCOL")) != NULL) {
783e2c0c09SMatt Barden 		ioc->min_protocol = strtol(s, NULL, 16);
793e2c0c09SMatt Barden 		smbd_report("min_protocol=0x%x", ioc->min_protocol);
80c51c88bdSMatt Barden 	}
81c51c88bdSMatt Barden 
8212b65585SGordon Ross 	if ((s = getenv("SMB_SIGNING")) != NULL) {
8312b65585SGordon Ross 		ioc->signing_enable = 0;
8412b65585SGordon Ross 		ioc->signing_required = 0;
8512b65585SGordon Ross 		switch (s[0]) {
8612b65585SGordon Ross 		case 'e':
8712b65585SGordon Ross 			ioc->signing_enable = 1;
8812b65585SGordon Ross 			break;
8912b65585SGordon Ross 		case 'r':
9012b65585SGordon Ross 			ioc->signing_enable = 1;
9112b65585SGordon Ross 			ioc->signing_required = 1;
9212b65585SGordon Ross 			break;
9312b65585SGordon Ross 		default:
9412b65585SGordon Ross 			smbd_report("env SMB_SIGNING invalid");
9512b65585SGordon Ross 			break;
9612b65585SGordon Ross 		}
9712b65585SGordon Ross 	}
9812b65585SGordon Ross 	smbd_report("signing: enable=%d, required=%d",
9912b65585SGordon Ross 	    ioc->signing_enable, ioc->signing_required);
100b819cea2SGordon Ross }
101b819cea2SGordon Ross 
102b819cea2SGordon Ross boolean_t
smb_kmod_isbound(void)103b819cea2SGordon Ross smb_kmod_isbound(void)
104b819cea2SGordon Ross {
105b819cea2SGordon Ross 	return (smbdrv_opened);
106b819cea2SGordon Ross }
107b819cea2SGordon Ross 
108b819cea2SGordon Ross int
smb_kmod_bind(boolean_t smbd)109*34bbc83aSGordon Ross smb_kmod_bind(boolean_t smbd)
110b819cea2SGordon Ross {
111b819cea2SGordon Ross 	int rc;
112b819cea2SGordon Ross 
113*34bbc83aSGordon Ross 	if (!smbd)
114*34bbc83aSGordon Ross 		return (ENXIO);
115*34bbc83aSGordon Ross 
116b819cea2SGordon Ross 	if (smbdrv_opened) {
117b819cea2SGordon Ross 		smbdrv_opened = B_FALSE;
118b819cea2SGordon Ross 		(void) fksmbsrv_drv_close();
119b819cea2SGordon Ross 	}
120b819cea2SGordon Ross 
121b819cea2SGordon Ross 	rc = fksmbsrv_drv_open();
122b819cea2SGordon Ross 	if (rc == 0)
123b819cea2SGordon Ross 		smbdrv_opened = B_TRUE;
124b819cea2SGordon Ross 
125b819cea2SGordon Ross 	return (rc);
126b819cea2SGordon Ross }
127b819cea2SGordon Ross 
128b819cea2SGordon Ross void
smb_kmod_unbind(void)129b819cea2SGordon Ross smb_kmod_unbind(void)
130b819cea2SGordon Ross {
131b819cea2SGordon Ross 	if (smbdrv_opened) {
132b819cea2SGordon Ross 		smbdrv_opened = B_FALSE;
133b819cea2SGordon Ross 		(void) fksmbsrv_drv_close();
134b819cea2SGordon Ross 	}
135b819cea2SGordon Ross }
136b819cea2SGordon Ross 
137b819cea2SGordon Ross int
smb_kmod_ioctl(int cmd,smb_ioc_header_t * ioc,uint32_t len)138b819cea2SGordon Ross smb_kmod_ioctl(int cmd, smb_ioc_header_t *ioc, uint32_t len)
139b819cea2SGordon Ross {
140b819cea2SGordon Ross 	int rc;
141b819cea2SGordon Ross 
142b819cea2SGordon Ross 	_NOTE(ARGUNUSED(len));
143b819cea2SGordon Ross 
144b819cea2SGordon Ross 	if (!smbdrv_opened)
145b819cea2SGordon Ross 		return (EBADF);
146b819cea2SGordon Ross 
147b819cea2SGordon Ross 	if (cmd == SMB_IOC_CONFIG)
148b819cea2SGordon Ross 		fksmbd_adjust_config(ioc);
149b819cea2SGordon Ross 
150b819cea2SGordon Ross 	rc = fksmbsrv_drv_ioctl(cmd, ioc);
151b819cea2SGordon Ross 	return (rc);
152b819cea2SGordon Ross }
153b819cea2SGordon Ross 
154b819cea2SGordon Ross /* ARGSUSED */
155b819cea2SGordon Ross int
smb_kmod_start(int opipe,int lmshr,int udoor)156b819cea2SGordon Ross smb_kmod_start(int opipe, int lmshr, int udoor)
157b819cea2SGordon Ross {
158b819cea2SGordon Ross 	smb_ioc_start_t ioc;
159b819cea2SGordon Ross 	int rc;
160b819cea2SGordon Ross 
161b819cea2SGordon Ross 	bzero(&ioc, sizeof (ioc));
162b819cea2SGordon Ross 
163b819cea2SGordon Ross 	/* These three are unused */
164b819cea2SGordon Ross 	ioc.opipe = -1;
165b819cea2SGordon Ross 	ioc.lmshrd = -1;
166b819cea2SGordon Ross 	ioc.udoor = -1;
167b819cea2SGordon Ross 
168b819cea2SGordon Ross 	/* These are the "door" dispatch callbacks */
169b819cea2SGordon Ross 	ioc.lmshr_func = NULL; /* not used */
17068b2bbf2SGordon Ross 	ioc.opipe_func = NULL; /* not used */
171b819cea2SGordon Ross 	ioc.udoor_func = (void *)fksmbd_door_dispatch;
172b819cea2SGordon Ross 
173b819cea2SGordon Ross 	rc = smb_kmod_ioctl(SMB_IOC_START, &ioc.hdr, sizeof (ioc));
174b819cea2SGordon Ross 	return (rc);
175b819cea2SGordon Ross }
176b819cea2SGordon Ross 
177b819cea2SGordon Ross void
smb_kmod_stop(void)178b819cea2SGordon Ross smb_kmod_stop(void)
179b819cea2SGordon Ross {
180b819cea2SGordon Ross 	smb_ioc_header_t ioc;
181b819cea2SGordon Ross 
182b819cea2SGordon Ross 	bzero(&ioc, sizeof (ioc));
183b819cea2SGordon Ross 	(void) smb_kmod_ioctl(SMB_IOC_STOP, &ioc, sizeof (ioc));
184b819cea2SGordon Ross }
185