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 2015 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 62 fksmbd_adjust_config(smb_ioc_header_t *ioc_hdr) 63 { 64 smb_ioc_cfg_t *ioc = (smb_ioc_cfg_t *)ioc_hdr; 65 char *s; 66 67 ioc->maxconnections = 10; 68 ioc->maxworkers = 20; 69 smbd_report("maxconnections=%d, maxworkers=%d", 70 ioc->maxconnections, ioc->maxworkers); 71 72 if ((s = getenv("SMB_MAX_PROTOCOL")) != NULL) { 73 switch (s[0]) { 74 case '1': 75 ioc->max_protocol = SMB_VERS_1; 76 break; 77 case '2': 78 ioc->max_protocol = SMB_VERS_2_1; 79 break; 80 case '3': 81 ioc->max_protocol = SMB_VERS_3_0; 82 break; 83 default: 84 smbd_report("env SMB_MAX_PROTOCOL invalid"); 85 break; 86 } 87 } 88 smbd_report("max_protocol=0x%x", ioc->max_protocol); 89 90 if ((s = getenv("SMB_SIGNING")) != NULL) { 91 ioc->signing_enable = 0; 92 ioc->signing_required = 0; 93 switch (s[0]) { 94 case 'e': 95 ioc->signing_enable = 1; 96 break; 97 case 'r': 98 ioc->signing_enable = 1; 99 ioc->signing_required = 1; 100 break; 101 default: 102 smbd_report("env SMB_SIGNING invalid"); 103 break; 104 } 105 } 106 smbd_report("signing: enable=%d, required=%d", 107 ioc->signing_enable, ioc->signing_required); 108 } 109 110 boolean_t 111 smb_kmod_isbound(void) 112 { 113 return (smbdrv_opened); 114 } 115 116 int 117 smb_kmod_bind(void) 118 { 119 int rc; 120 121 if (smbdrv_opened) { 122 smbdrv_opened = B_FALSE; 123 (void) fksmbsrv_drv_close(); 124 } 125 126 rc = fksmbsrv_drv_open(); 127 if (rc == 0) 128 smbdrv_opened = B_TRUE; 129 130 return (rc); 131 } 132 133 void 134 smb_kmod_unbind(void) 135 { 136 if (smbdrv_opened) { 137 smbdrv_opened = B_FALSE; 138 (void) fksmbsrv_drv_close(); 139 } 140 } 141 142 int 143 smb_kmod_ioctl(int cmd, smb_ioc_header_t *ioc, uint32_t len) 144 { 145 int rc; 146 147 _NOTE(ARGUNUSED(len)); 148 149 if (!smbdrv_opened) 150 return (EBADF); 151 152 if (cmd == SMB_IOC_CONFIG) 153 fksmbd_adjust_config(ioc); 154 155 rc = fksmbsrv_drv_ioctl(cmd, ioc); 156 return (rc); 157 } 158 159 /* ARGSUSED */ 160 int 161 smb_kmod_start(int opipe, int lmshr, int udoor) 162 { 163 smb_ioc_start_t ioc; 164 int rc; 165 166 bzero(&ioc, sizeof (ioc)); 167 168 /* These three are unused */ 169 ioc.opipe = -1; 170 ioc.lmshrd = -1; 171 ioc.udoor = -1; 172 173 /* These are the "door" dispatch callbacks */ 174 ioc.lmshr_func = NULL; /* not used */ 175 ioc.opipe_func = NULL; /* not used */ 176 ioc.udoor_func = (void *)fksmbd_door_dispatch; 177 178 rc = smb_kmod_ioctl(SMB_IOC_START, &ioc.hdr, sizeof (ioc)); 179 return (rc); 180 } 181 182 void 183 smb_kmod_stop(void) 184 { 185 smb_ioc_header_t ioc; 186 187 bzero(&ioc, sizeof (ioc)); 188 (void) smb_kmod_ioctl(SMB_IOC_STOP, &ioc, sizeof (ioc)); 189 } 190