From: Stefan Metzmacher Date: Wed, 2 Apr 2025 19:03:22 +0000 (+0200) Subject: docs-xml/smbdotconf: add 'client smb transports' option X-Git-Tag: tevent-0.17.0~293 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=da9cb652140481bfcc219441d7ee679954d5b3be;p=thirdparty%2Fsamba.git docs-xml/smbdotconf: add 'client smb transports' option This will replace the use of 'smb ports' for source4 clients. In future it will be used for all smb client connections and it will allow to add other transports as 'quic' or 'smbdirect. Signed-off-by: Stefan Metzmacher Reviewed-by: Volker Lendecke --- diff --git a/docs-xml/smbdotconf/protocol/clientsmbtransports.xml b/docs-xml/smbdotconf/protocol/clientsmbtransports.xml new file mode 100644 index 00000000000..18adad501d6 --- /dev/null +++ b/docs-xml/smbdotconf/protocol/clientsmbtransports.xml @@ -0,0 +1,33 @@ + + + Specifies which transports and ports the client should try to connect to for SMB traffic. + + The order matters as they are tried in order with short delays for the fallbacks. + + The transport 'tcp' uses raw tcp with a 4 byte length header per SMB PDU. + The default port for 'tcp' is 445. Other ports can be specified by adding it + after ':', e.g. 'tcp:1445'. + + + The transport 'nbt' uses netbios framing on top of tcp per SMB PDU. + The default port for 'nbt' is 139. Other ports can be specified by adding it + after ':', e.g. 'nbt:1139'. + + + Numerical ports are handled as 'tcp' except port '139' is handled as 'nbt'. + + + Note that's currently a limit of 10 unique transports, all others will + be ignored. + + +445 +tcp, tcp:1445 +8000, nbt:1139 + +tcp, nbt + diff --git a/lib/param/loadparm.c b/lib/param/loadparm.c index 30a45511cb8..49b12837f53 100644 --- a/lib/param/loadparm.c +++ b/lib/param/loadparm.c @@ -67,6 +67,7 @@ #include "lib/param/s3_param.h" #include "lib/util/bitmap.h" #include "libcli/smb/smb_constants.h" +#include "libcli/smb/smb_util.h" #include "tdb.h" #include "librpc/gen_ndr/nbt.h" #include "librpc/gen_ndr/dns.h" @@ -1383,6 +1384,142 @@ bool handle_smb_ports(struct loadparm_context *lp_ctx, struct loadparm_service * return true; } +bool smb_transport_parse(const char *_value, struct smb_transport *_t) +{ + size_t _value_len = strlen(_value); + char value[_value_len+1]; + const char *vparam = NULL; + const char *portstr = NULL; + char *p = NULL; + struct smb_transport t = { + .type = SMB_TRANSPORT_TYPE_UNKNOWN, + }; + bool invalid = false; + + memcpy(value, _value, sizeof(value)); + + p = strchr(value, ':'); + if (p != NULL) { + vparam = p + 1; + p[0] = '\0'; + } + + if (strcmp("tcp", value) == 0) { + t.type = SMB_TRANSPORT_TYPE_TCP; + t.port = 445; + } else if (strcmp("nbt", value) == 0) { + t.type = SMB_TRANSPORT_TYPE_NBT; + t.port = 139; + } else if (vparam != NULL) { + /* + * a port number should not have + * extra parameter! + */ + invalid = true; + } else { + /* + * Could a port number only + */ + portstr = value; + } + + if (!invalid && portstr == NULL) { + portstr = vparam; + } + + if (portstr != NULL) { + char *_end = NULL; + int _port = 0; + _port = strtol(portstr, &_end, 10); + if (*_end != '\0' || _port <= 0 || _port > 65535) { + invalid = true; + } else { + t.port = _port; + } + } + + if (invalid) { + t = (struct smb_transport) { + .type = SMB_TRANSPORT_TYPE_UNKNOWN, + }; + + *_t = t; + return false; + } + + if (t.type == SMB_TRANSPORT_TYPE_UNKNOWN) { + if (t.port == 139) { + t.type = SMB_TRANSPORT_TYPE_NBT; + } else { + t.type = SMB_TRANSPORT_TYPE_TCP; + } + } + + *_t = t; + return true; +} + +static bool handle_smb_transports(struct loadparm_context *lp_ctx, + struct loadparm_service *service, + const char *pszParmValue, + char **ptr, + const char *optname) +{ + const char **list = NULL; + static int parm_num = -1; + size_t i; + bool ok; + + if (!pszParmValue || !*pszParmValue) { + return false; + } + + if (parm_num == -1) { + parm_num = lpcfg_map_parameter(optname); + if (parm_num == -1) { + return false; + } + } + + ok = set_variable_helper(lp_ctx->globals->ctx, + parm_num, + ptr, + optname, + pszParmValue); + if (!ok) { + return false; + } + + list = *(const char ***)ptr; + + if (list == NULL) { + return false; + } + + /* Check that each transport is a valid */ + for (i = 0; list[i] != NULL; i++) { + struct smb_transport t = { + .type = SMB_TRANSPORT_TYPE_UNKNOWN, + }; + + ok = smb_transport_parse(list[i], &t); + if (!ok) { + return false; + } + } + + return true; +} + +bool handle_client_smb_transports(struct loadparm_context *lp_ctx, + struct loadparm_service *service, + const char *pszParmValue, + char **ptr) +{ + return handle_smb_transports(lp_ctx, service, pszParmValue, ptr, + "client smb transports"); +} + bool handle_rpc_server_dynamic_port_range(struct loadparm_context *lp_ctx, struct loadparm_service *service, const char *pszParmValue, @@ -2837,6 +2974,7 @@ struct loadparm_context *loadparm_init(TALLOC_CTX *mem_ctx) lpcfg_do_global_parameter(lp_ctx, "use mmap", "True"); + lpcfg_do_global_parameter(lp_ctx, "client smb transports", "tcp, nbt"); lpcfg_do_global_parameter(lp_ctx, "smb ports", "445 139"); lpcfg_do_global_parameter_var(lp_ctx, "nbt port", "%d", NBT_NAME_SERVICE_PORT); lpcfg_do_global_parameter_var(lp_ctx, "dgram port", "%d", NBT_DGRAM_SERVICE_PORT); diff --git a/lib/param/param.h b/lib/param/param.h index 02a21280d80..2b96c56067a 100644 --- a/lib/param/param.h +++ b/lib/param/param.h @@ -47,6 +47,7 @@ struct loadparm_context; struct loadparm_service; struct smbcli_options; struct smbcli_session_options; +struct smb_transport; struct gensec_settings; struct bitmap; struct file_lists; diff --git a/libcli/smb/util.c b/libcli/smb/util.c index 20020c897ff..297d463626c 100644 --- a/libcli/smb/util.c +++ b/libcli/smb/util.c @@ -725,81 +725,6 @@ NTSTATUS smb311_capabilities_check(const struct smb311_capabilities *c, return NT_STATUS_OK; } -static bool smb_transport_parse(const char *_value, struct smb_transport *_t) -{ - size_t _value_len = strlen(_value); - char value[_value_len+1]; - const char *vparam = NULL; - const char *portstr = NULL; - char *p = NULL; - struct smb_transport t = { - .type = SMB_TRANSPORT_TYPE_UNKNOWN, - }; - bool invalid = false; - - memcpy(value, _value, sizeof(value)); - - p = strchr(value, ':'); - if (p != NULL) { - vparam = p + 1; - p[0] = '\0'; - } - - if (strcmp("tcp", value) == 0) { - t.type = SMB_TRANSPORT_TYPE_TCP; - t.port = 445; - } else if (strcmp("nbt", value) == 0) { - t.type = SMB_TRANSPORT_TYPE_NBT; - t.port = 139; - } else if (vparam != NULL) { - /* - * a port number should not have - * extra parameter! - */ - invalid = true; - } else { - /* - * Could a port number only - */ - portstr = value; - } - - if (!invalid && portstr == NULL) { - portstr = vparam; - } - - if (portstr != NULL) { - char *_end = NULL; - int _port = 0; - _port = strtol(portstr, &_end, 10); - if (*_end != '\0' || _port <= 0 || _port > 65535) { - invalid = true; - } else { - t.port = _port; - } - } - - if (invalid) { - t = (struct smb_transport) { - .type = SMB_TRANSPORT_TYPE_UNKNOWN, - }; - - *_t = t; - return false; - } - - if (t.type == SMB_TRANSPORT_TYPE_UNKNOWN) { - if (t.port == 139) { - t.type = SMB_TRANSPORT_TYPE_NBT; - } else { - t.type = SMB_TRANSPORT_TYPE_TCP; - } - } - - *_t = t; - return true; -} - struct smb_transports smb_transports_parse(const char *param_name, const char * const *transports) { diff --git a/source3/param/loadparm.c b/source3/param/loadparm.c index 2bcd149c293..999c4f74d80 100644 --- a/source3/param/loadparm.c +++ b/source3/param/loadparm.c @@ -848,6 +848,7 @@ void loadparm_s3_init_globals(struct loadparm_context *lp_ctx, Globals.defer_sharing_violations = true; Globals.smb_ports = str_list_make_v3_const(NULL, SMB_PORTS, NULL); + Globals.client_smb_transports = str_list_make_v3_const(NULL, "tcp, nbt", NULL); Globals.enable_privileges = true; Globals.host_msdfs = true;