4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21 /*
22 * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
23 * Copyright 2018 Nexenta Systems, Inc. All rights reserved.
24 */
25
26 /*
27 * CIFS configuration management library
28 */
29
30 #include <stdio.h>
31 #include <stdlib.h>
32 #include <unistd.h>
33 #include <synch.h>
34 #include <string.h>
35 #include <strings.h>
36 #include <syslog.h>
37 #include <netdb.h>
38 #include <ctype.h>
39 #include <sys/types.h>
40 #include <libscf.h>
41 #include <assert.h>
42 #include <uuid/uuid.h>
43 #include <smbsrv/libsmb.h>
133 {SMB_CI_MACHINE_UUID, "machine_uuid", SCF_TYPE_ASTRING, 0},
134 {SMB_CI_KPASSWD_SRV, "kpasswd_server", SCF_TYPE_ASTRING, 0},
135 {SMB_CI_KPASSWD_DOMAIN, "kpasswd_domain", SCF_TYPE_ASTRING, 0},
136 {SMB_CI_KPASSWD_SEQNUM, "kpasswd_seqnum", SCF_TYPE_INTEGER, 0},
137 {SMB_CI_NETLOGON_SEQNUM, "netlogon_seqnum", SCF_TYPE_INTEGER, 0},
138 {SMB_CI_IPV6_ENABLE, "ipv6_enable", SCF_TYPE_BOOLEAN, 0},
139 {SMB_CI_PRINT_ENABLE, "print_enable", SCF_TYPE_BOOLEAN, 0},
140 {SMB_CI_MAP, "map", SCF_TYPE_ASTRING, SMB_CF_EXEC},
141 {SMB_CI_UNMAP, "unmap", SCF_TYPE_ASTRING, SMB_CF_EXEC},
142 {SMB_CI_DISPOSITION, "disposition", SCF_TYPE_ASTRING, SMB_CF_EXEC},
143 {SMB_CI_DFS_STDROOT_NUM, "dfs_stdroot_num", SCF_TYPE_INTEGER, 0},
144 {SMB_CI_TRAVERSE_MOUNTS, "traverse_mounts", SCF_TYPE_BOOLEAN, 0},
145 {SMB_CI_SMB2_ENABLE_OLD, "smb2_enable", SCF_TYPE_BOOLEAN, 0},
146 {SMB_CI_INITIAL_CREDITS, "initial_credits", SCF_TYPE_INTEGER, 0},
147 {SMB_CI_MAXIMUM_CREDITS, "maximum_credits", SCF_TYPE_INTEGER, 0},
148 {SMB_CI_MAX_PROTOCOL, "max_protocol", SCF_TYPE_ASTRING, 0},
149 {SMB_CI_ENCRYPT, "encrypt", SCF_TYPE_ASTRING, 0},
150 {SMB_CI_MIN_PROTOCOL, "min_protocol", SCF_TYPE_ASTRING, 0},
151 {SMB_CI_BYPASS_TRAVERSE_CHECKING,
152 "bypass_traverse_checking", SCF_TYPE_BOOLEAN, 0},
153
154 /* SMB_CI_MAX */
155 };
156
157 /*
158 * We store the max SMB protocol version in SMF as a string,
159 * (for convenience of svccfg etc) but the programmatic get/set
160 * interfaces use the numeric form.
161 *
162 * The numeric values are as defined in the [MS-SMB2] spec.
163 * except for how we represent "1" (for SMB1) which is an
164 * arbitrary value below SMB2_VERS_BASE.
165 */
166 static struct str_val
167 smb_versions[] = {
168 { "3.02", SMB_VERS_3_02 },
169 { "3.0", SMB_VERS_3_0 },
170 { "2.1", SMB_VERS_2_1 },
171 { "2.002", SMB_VERS_2_002 },
172 { "1", SMB_VERS_1 },
173 { NULL, 0 }
174 };
175
176 static smb_cfg_param_t *smb_config_getent(smb_cfg_id_t);
177
178 static boolean_t smb_is_base64(unsigned char c);
179 static char *smb_base64_encode(char *str_to_encode);
180 static char *smb_base64_decode(char *encoded_str);
181 static int smb_config_get_idmap_preferred_dc(char *, int);
182 static int smb_config_set_idmap_preferred_dc(char *);
183 static int smb_config_get_idmap_site_name(char *, int);
184 static int smb_config_set_idmap_site_name(char *);
185
186 static uint32_t
187 smb_convert_version_str(const char *version)
188 {
189 uint32_t dialect = 0;
190 int i;
191
192 for (i = 0; smb_versions[i].str != NULL; i++) {
193 if (strcmp(version, smb_versions[i].str) == 0)
194 dialect = smb_versions[i].val;
195 }
1207 rc = smb_config_getstr(id, str, sizeof (str));
1208 if (rc == SMBD_SMF_OK) {
1209 val = smb_convert_version_str(str);
1210 if (val != 0)
1211 return (val);
1212 if (str[0] != '\0') {
1213 syslog(LOG_ERR, "smbd/%s value invalid: %s", name, str);
1214 }
1215 }
1216
1217 return (default_val);
1218 }
1219
1220 /*
1221 * The service manifest has empty values by default for min_protocol and
1222 * max_protocol. The expectation is that when those values are empty, we don't
1223 * constrain the range of supported protocol versions (and allow use of the
1224 * whole range that we implement). For that reason, this should usually be the
1225 * highest protocol version we implement.
1226 */
1227 uint32_t max_protocol_default = SMB_VERS_3_02;
1228
1229 uint32_t
1230 smb_config_get_max_protocol(void)
1231 {
1232 uint32_t max;
1233
1234 max = smb_config_get_protocol(SMB_CI_MAX_PROTOCOL, "max_protocol",
1235 max_protocol_default);
1236
1237 return (max);
1238 }
1239
1240 /*
1241 * This should eventually be SMB_VERS_2_BASE
1242 */
1243 uint32_t min_protocol_default = SMB_VERS_1;
1244
1245 uint32_t
1246 smb_config_get_min_protocol(void)
1247 {
1248 uint32_t min;
1249
1250 min = smb_config_get_protocol(SMB_CI_MIN_PROTOCOL, "min_protocol",
1251 min_protocol_default);
1252
1253 return (min);
1254 }
1255
1256 int
1257 smb_config_check_protocol(char *value)
1258 {
1259 if (smb_convert_version_str(value) != 0)
1260 return (0);
1261
1262 return (-1);
1263 }
1264
1265 /*
1266 * If smb2_enable is present and max_protocol is empty,
1267 * set max_protocol. Delete smb2_enable.
1268 */
1269 static void
1270 upgrade_smb2_enable()
1271 {
1272 smb_scfhandle_t *handle;
1273 char *s2e_name = "smb2_enable";
1274 char *s2e_sval;
1275 uint8_t s2e_bval;
1276 char *maxp_name = "max_protocol";
1277 char *maxp_sval;
1278 char verstr[SMB_VERSTR_LEN];
1279 int rc;
1280
1281 handle = smb_smf_scf_init(SMBD_FMRI_PREFIX);
1282 if (handle == NULL)
|
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21 /*
22 * Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
23 * Copyright 2018 Nexenta Systems, Inc. All rights reserved.
24 * Copyright 2020 RackTop Systems, Inc.
25 */
26
27 /*
28 * CIFS configuration management library
29 */
30
31 #include <stdio.h>
32 #include <stdlib.h>
33 #include <unistd.h>
34 #include <synch.h>
35 #include <string.h>
36 #include <strings.h>
37 #include <syslog.h>
38 #include <netdb.h>
39 #include <ctype.h>
40 #include <sys/types.h>
41 #include <libscf.h>
42 #include <assert.h>
43 #include <uuid/uuid.h>
44 #include <smbsrv/libsmb.h>
134 {SMB_CI_MACHINE_UUID, "machine_uuid", SCF_TYPE_ASTRING, 0},
135 {SMB_CI_KPASSWD_SRV, "kpasswd_server", SCF_TYPE_ASTRING, 0},
136 {SMB_CI_KPASSWD_DOMAIN, "kpasswd_domain", SCF_TYPE_ASTRING, 0},
137 {SMB_CI_KPASSWD_SEQNUM, "kpasswd_seqnum", SCF_TYPE_INTEGER, 0},
138 {SMB_CI_NETLOGON_SEQNUM, "netlogon_seqnum", SCF_TYPE_INTEGER, 0},
139 {SMB_CI_IPV6_ENABLE, "ipv6_enable", SCF_TYPE_BOOLEAN, 0},
140 {SMB_CI_PRINT_ENABLE, "print_enable", SCF_TYPE_BOOLEAN, 0},
141 {SMB_CI_MAP, "map", SCF_TYPE_ASTRING, SMB_CF_EXEC},
142 {SMB_CI_UNMAP, "unmap", SCF_TYPE_ASTRING, SMB_CF_EXEC},
143 {SMB_CI_DISPOSITION, "disposition", SCF_TYPE_ASTRING, SMB_CF_EXEC},
144 {SMB_CI_DFS_STDROOT_NUM, "dfs_stdroot_num", SCF_TYPE_INTEGER, 0},
145 {SMB_CI_TRAVERSE_MOUNTS, "traverse_mounts", SCF_TYPE_BOOLEAN, 0},
146 {SMB_CI_SMB2_ENABLE_OLD, "smb2_enable", SCF_TYPE_BOOLEAN, 0},
147 {SMB_CI_INITIAL_CREDITS, "initial_credits", SCF_TYPE_INTEGER, 0},
148 {SMB_CI_MAXIMUM_CREDITS, "maximum_credits", SCF_TYPE_INTEGER, 0},
149 {SMB_CI_MAX_PROTOCOL, "max_protocol", SCF_TYPE_ASTRING, 0},
150 {SMB_CI_ENCRYPT, "encrypt", SCF_TYPE_ASTRING, 0},
151 {SMB_CI_MIN_PROTOCOL, "min_protocol", SCF_TYPE_ASTRING, 0},
152 {SMB_CI_BYPASS_TRAVERSE_CHECKING,
153 "bypass_traverse_checking", SCF_TYPE_BOOLEAN, 0},
154 {SMB_CI_ENCRYPT_CIPHER, "encrypt_cipher", SCF_TYPE_ASTRING, 0},
155
156 /* SMB_CI_MAX */
157 };
158
159 /*
160 * We store the max SMB protocol version in SMF as a string,
161 * (for convenience of svccfg etc) but the programmatic get/set
162 * interfaces use the numeric form.
163 *
164 * The numeric values are as defined in the [MS-SMB2] spec.
165 * except for how we represent "1" (for SMB1) which is an
166 * arbitrary value below SMB2_VERS_BASE.
167 */
168 static struct str_val
169 smb_versions[] = {
170 { "3.11", SMB_VERS_3_11 },
171 { "3.02", SMB_VERS_3_02 },
172 { "3.0", SMB_VERS_3_0 },
173 { "2.1", SMB_VERS_2_1 },
174 { "2.002", SMB_VERS_2_002 },
175 { "1", SMB_VERS_1 },
176 { NULL, 0 }
177 };
178
179 /*
180 * Supported encryption ciphers.
181 */
182 static struct str_val
183 smb31_encrypt_ciphers[] = {
184 { "aes128-ccm", SMB3_CIPHER_AES128_CCM }, /* SMB 3.x */
185 { "aes128-gcm", SMB3_CIPHER_AES128_GCM }, /* SMB 3.1.1 */
186 { NULL, 0 }
187 };
188
189 static smb_cfg_param_t *smb_config_getent(smb_cfg_id_t);
190
191 static boolean_t smb_is_base64(unsigned char c);
192 static char *smb_base64_encode(char *str_to_encode);
193 static char *smb_base64_decode(char *encoded_str);
194 static int smb_config_get_idmap_preferred_dc(char *, int);
195 static int smb_config_set_idmap_preferred_dc(char *);
196 static int smb_config_get_idmap_site_name(char *, int);
197 static int smb_config_set_idmap_site_name(char *);
198
199 static uint32_t
200 smb_convert_version_str(const char *version)
201 {
202 uint32_t dialect = 0;
203 int i;
204
205 for (i = 0; smb_versions[i].str != NULL; i++) {
206 if (strcmp(version, smb_versions[i].str) == 0)
207 dialect = smb_versions[i].val;
208 }
1220 rc = smb_config_getstr(id, str, sizeof (str));
1221 if (rc == SMBD_SMF_OK) {
1222 val = smb_convert_version_str(str);
1223 if (val != 0)
1224 return (val);
1225 if (str[0] != '\0') {
1226 syslog(LOG_ERR, "smbd/%s value invalid: %s", name, str);
1227 }
1228 }
1229
1230 return (default_val);
1231 }
1232
1233 /*
1234 * The service manifest has empty values by default for min_protocol and
1235 * max_protocol. The expectation is that when those values are empty, we don't
1236 * constrain the range of supported protocol versions (and allow use of the
1237 * whole range that we implement). For that reason, this should usually be the
1238 * highest protocol version we implement.
1239 */
1240 uint32_t max_protocol_default = SMB_VERS_3_11;
1241
1242 uint32_t
1243 smb_config_get_max_protocol(void)
1244 {
1245 uint32_t max;
1246
1247 max = smb_config_get_protocol(SMB_CI_MAX_PROTOCOL, "max_protocol",
1248 max_protocol_default);
1249
1250 return (max);
1251 }
1252
1253 /*
1254 * This should eventually be SMB_VERS_2_BASE
1255 */
1256 uint32_t min_protocol_default = SMB_VERS_1;
1257
1258 uint32_t
1259 smb_config_get_min_protocol(void)
1260 {
1261 uint32_t min;
1262
1263 min = smb_config_get_protocol(SMB_CI_MIN_PROTOCOL, "min_protocol",
1264 min_protocol_default);
1265
1266 return (min);
1267 }
1268
1269 int
1270 smb_config_check_protocol(char *value)
1271 {
1272 if (smb_convert_version_str(value) != 0)
1273 return (0);
1274
1275 return (-1);
1276 }
1277
1278 /*
1279 * Only SMB 3.x supports encryption.
1280 * SMB 3.0.2 uses AES128-CCM only.
1281 * SMB 3.1.1 - AES128-CCM or AES128-GCM.
1282 */
1283 uint16_t
1284 smb31_config_get_encrypt_cipher(void)
1285 {
1286 uint32_t max_proto = smb_config_get_max_protocol();
1287 uint16_t cipher = SMB3_CIPHER_AES128_GCM; /* by default AES128-GCM */
1288 char str[12];
1289 int i;
1290
1291 if (max_proto < SMB_VERS_3_11)
1292 return (SMB3_CIPHER_NONE);
1293
1294 /* SMB 3.1.1 */
1295 if (smb_config_getstr(SMB_CI_ENCRYPT_CIPHER, str, sizeof (str))
1296 == SMBD_SMF_OK) {
1297 for (i = 0; smb31_encrypt_ciphers[i].str != NULL; i++) {
1298 if (strcmp(str, smb31_encrypt_ciphers[i].str) == 0)
1299 cipher = smb31_encrypt_ciphers[i].val;
1300 }
1301 }
1302
1303 return (cipher);
1304 }
1305
1306 /*
1307 * If smb2_enable is present and max_protocol is empty,
1308 * set max_protocol. Delete smb2_enable.
1309 */
1310 static void
1311 upgrade_smb2_enable()
1312 {
1313 smb_scfhandle_t *handle;
1314 char *s2e_name = "smb2_enable";
1315 char *s2e_sval;
1316 uint8_t s2e_bval;
1317 char *maxp_name = "max_protocol";
1318 char *maxp_sval;
1319 char verstr[SMB_VERSTR_LEN];
1320 int rc;
1321
1322 handle = smb_smf_scf_init(SMBD_FMRI_PREFIX);
1323 if (handle == NULL)
|