1 /*
2 * This file and its contents are supplied under the terms of the
3 * Common Development and Distribution License ("CDDL"), version 1.0.
4 * You may only use this file in accordance with the terms of version
5 * 1.0 of the CDDL.
6 *
7 * A full copy of the text of the CDDL should have accompanied this
8 * source. A copy of the CDDL is also available via the Internet at
9 * http://www.illumos.org/license/CDDL.
10 */
11
12 /*
13 * Copyright 2014 Nexenta Systems, Inc. All rights reserved.
14 */
15
16 /*
17 * These replace NODIRECT functions of the same name in
18 * $SRC/lib/smbsrv/libsmb/common/smb_kmod.c including:
19 * smb_kmod_bind, smb_kmod_ioctl, smb_kmod_isbound,
20 * smb_kmod_start, smb_kmod_stop, smb_kmod_unbind.
21 *
22 * For all the other smb_kmod_... functions, we can just use the
23 * libsmb code because those all call smb_kmod_ioctl, for which
24 * we have an override here.
25 *
26 * The replacment functions here just call the libfksmbsrv code
27 * directly where the real (in-kernel) versions would be entered
28 * via the driver framework (open, close, ioctl). Aside from that,
29 * the call sequences are intentionally the same (where possible).
30 * In particular, that makes it possible to debug startup/teardown
31 * problems in the user-space version of this code.
32 */
33
34 #include <sys/types.h>
35 #include <sys/stat.h>
36 #include <sys/ioccom.h>
37 #include <sys/param.h>
38 #include <stddef.h>
39 #include <stdio.h>
40 #include <string.h>
41 #include <strings.h>
42 #include <stdlib.h>
43 #include <unistd.h>
44 #include <fcntl.h>
45 #include <errno.h>
46 #include <note.h>
47
48 #include <smbsrv/smbinfo.h>
49 #include <smbsrv/smb_ioctl.h>
50 #include "smbd.h"
51
52 boolean_t smbdrv_opened = B_FALSE;
53
54 /*
55 * We want to adjust a few things in the standard configuration
56 * passed to the "fake" version of the smbsrv kernel module.
57 *
58 * Reduce the maximum number of connections and workers, just for
59 * convenience while debugging. (Don't want hundreds of threads.)
60 */
61 static void
fksmbd_adjust_config(smb_ioc_header_t * ioc_hdr)62 fksmbd_adjust_config(smb_ioc_header_t *ioc_hdr)
63 {
64 smb_ioc_cfg_t *ioc = (smb_ioc_cfg_t *)ioc_hdr;
65
66 ioc->maxconnections = 10;
67 ioc->maxworkers = 20;
68 smbd_report("maxconnections=%d, maxworkers=%d",
69 ioc->maxconnections, ioc->maxworkers);
70 }
71
72 boolean_t
smb_kmod_isbound(void)73 smb_kmod_isbound(void)
74 {
75 return (smbdrv_opened);
76 }
77
78 int
smb_kmod_bind(void)79 smb_kmod_bind(void)
80 {
81 int rc;
82
83 if (smbdrv_opened) {
84 smbdrv_opened = B_FALSE;
85 (void) fksmbsrv_drv_close();
86 }
87
88 rc = fksmbsrv_drv_open();
89 if (rc == 0)
90 smbdrv_opened = B_TRUE;
91
92 return (rc);
93 }
94
95 void
smb_kmod_unbind(void)96 smb_kmod_unbind(void)
97 {
98 if (smbdrv_opened) {
99 smbdrv_opened = B_FALSE;
100 (void) fksmbsrv_drv_close();
101 }
102 }
103
104 int
smb_kmod_ioctl(int cmd,smb_ioc_header_t * ioc,uint32_t len)105 smb_kmod_ioctl(int cmd, smb_ioc_header_t *ioc, uint32_t len)
106 {
107 int rc;
108
109 _NOTE(ARGUNUSED(len));
110
111 if (!smbdrv_opened)
112 return (EBADF);
113
114 if (cmd == SMB_IOC_CONFIG)
115 fksmbd_adjust_config(ioc);
116
117 rc = fksmbsrv_drv_ioctl(cmd, ioc);
118 return (rc);
119 }
120
121 /* ARGSUSED */
122 int
smb_kmod_start(int opipe,int lmshr,int udoor)123 smb_kmod_start(int opipe, int lmshr, int udoor)
124 {
125 smb_ioc_start_t ioc;
126 int rc;
127
128 bzero(&ioc, sizeof (ioc));
129
130 /* These three are unused */
131 ioc.opipe = -1;
132 ioc.lmshrd = -1;
133 ioc.udoor = -1;
134
135 /* These are the "door" dispatch callbacks */
136 ioc.lmshr_func = NULL; /* not used */
137 ioc.opipe_func = NULL; /* not used */
138 ioc.udoor_func = (void *)fksmbd_door_dispatch;
139
140 rc = smb_kmod_ioctl(SMB_IOC_START, &ioc.hdr, sizeof (ioc));
141 return (rc);
142 }
143
144 void
smb_kmod_stop(void)145 smb_kmod_stop(void)
146 {
147 smb_ioc_header_t ioc;
148
149 bzero(&ioc, sizeof (ioc));
150 (void) smb_kmod_ioctl(SMB_IOC_STOP, &ioc, sizeof (ioc));
151 }
152