The branch, v4-1-test has been updated via 2bea37d libcli: SMB2: Pure SMB2-only negprot fix to make us behave as a Windows client does. via 192fa10 s3-smbstatus: Fix exit code of profile output. via 9c7b253 s3-smbclient: Return success if we listed the shares. via 6931f8d s4-rpc: dnsserver: Fix enumeration of IPv4 and IPv6 addresses via 05cace7 samba-tool: Fix the IP output of "samba-tool dns serverinfo <some_server>" via 1e02ce0 samba-tool: Fix enum values in dns.py from 7dfcd23 VERSION: Bump version up to 4.1.15...
https://git.samba.org/?p=samba.git;a=shortlog;h=v4-1-test - Log ----------------------------------------------------------------- commit 2bea37d47ab398bf282f62c9d59429ce54b4bb4e Author: Jeremy Allison <j...@samba.org> Date: Wed Nov 26 13:33:57 2014 -0800 libcli: SMB2: Pure SMB2-only negprot fix to make us behave as a Windows client does. Required as some servers return zero when asked for zero credits in an initial SMB2-only negprot. Back-port of c426f97238e4f664d1b13781101ca9c942aa7d0d from master. https://bugzilla.samba.org/show_bug.cgi?id=10966 Signed-off-by: Jeremy Allison <j...@samba.org> Autobuild-User(v4-1-test): Karolin Seeger <ksee...@samba.org> Autobuild-Date(v4-1-test): Thu Dec 4 21:55:16 CET 2014 on sn-devel-104 commit 192fa109640e1f9bbb7b1845580c6f812c6900a3 Author: Andreas Schneider <a...@samba.org> Date: Mon Nov 24 17:46:27 2014 +0100 s3-smbstatus: Fix exit code of profile output. BUG: https://bugzilla.samba.org/show_bug.cgi?id=10961 Signed-off-by: Andreas Schneider <a...@samba.org> Reviewed-by: Jeremy Allison <j...@samba.org> commit 9c7b2538e4b489edb532b77804cca697605a548a Author: Andreas Schneider <a...@samba.org> Date: Mon Nov 24 16:26:13 2014 +0100 s3-smbclient: Return success if we listed the shares. BUG: https://bugzilla.samba.org/show_bug.cgi?id=10960 Signed-off-by: Andreas Schneider <a...@samba.org> Reviewed-by: Jeremy Allison <j...@samba.org> commit 6931f8dac78c0ebd89ba1ef8031b0084e46aaa6e Author: Guenter Kukkukk <li...@kukkukk.com> Date: Fri Nov 21 16:57:45 2014 +0100 s4-rpc: dnsserver: Fix enumeration of IPv4 and IPv6 addresses In the initial implementation only IPv4 addresses were supported. Add IPv6 (and mixed IPv4/IPv6) support and all further needed conversion routines to support w2k, dotnet, longhorn clients. Signed-off-by: Guenter Kukkukk <li...@kukkukk.com> Reviewed-by: Amitay Isaacs <ami...@gmail.com> Autobuild-User(master): Amitay Isaacs <ami...@samba.org> Autobuild-Date(master): Wed Nov 26 03:44:07 CET 2014 on sn-devel-104 (cherry picked from commit 3ac4355f3e7f79bc0045c43bc818697dc6b08850) The last 3 patches address BUG: https://bugzilla.samba.org/show_bug.cgi?id=10952 samba-tool dns serverinfo <server> is broken for IPv6 - also in mixed IPv4/IPv6 environments. commit 05cace75c9fae6d4630a747726e305b20ce28917 Author: Guenter Kukkukk <li...@kukkukk.com> Date: Fri Nov 21 03:55:25 2014 +0100 samba-tool: Fix the IP output of "samba-tool dns serverinfo <some_server>" Avoid hardcoded IP-strings, use standard python IP functions to format IPv4 and IPv6 addresses correctly. I have removed the display of the port number. MS-DNSP 2.2.3.2.2.1 DNS_ADDR: (from May 15, 2014) Port Number (2bytes): Senders MUST set this to zero, and receivers MUST ignore it. Signed-off-by: Guenter Kukkukk <li...@kukkukk.com> Reviewed-by: Amitay Isaacs <ami...@gmail.com> (cherry picked from commit d5af53c5372866a33a0195cabbd64232ac53bad4) commit 1e02ce03a015278fd1aba30b0688f44819fcac45 Author: Guenter Kukkukk <li...@kukkukk.com> Date: Fri Nov 21 03:40:17 2014 +0100 samba-tool: Fix enum values in dns.py DNS_ZONE_UPDATE_SECURE was used twice, DNS_ZONE_UPDATE_UNSECURE was missing. Signed-off-by: Guenter Kukkukk <li...@kukkukk.com> Reviewed-by: Amitay Isaacs <ami...@gmail.com> (cherry picked from commit 4bda589c8e68cd66ca3b0ea9496cb1b11febcae6) ----------------------------------------------------------------------- Summary of changes: libcli/smb/smbXcli_base.c | 11 +++ python/samba/netcmd/dns.py | 15 ++-- source3/client/client.c | 2 +- source3/include/local.h | 2 + source3/utils/status.c | 7 +- source4/rpc_server/dnsserver/dcerpc_dnsserver.c | 20 +++-- source4/rpc_server/dnsserver/dnsdata.c | 56 +++++++++++++ source4/rpc_server/dnsserver/dnsserver.h | 7 +- source4/rpc_server/dnsserver/dnsutils.c | 106 ++++++++++++++++++------ 9 files changed, 179 insertions(+), 47 deletions(-) Changeset truncated at 500 lines: diff --git a/libcli/smb/smbXcli_base.c b/libcli/smb/smbXcli_base.c index 25fbabd..0ceb1dd 100644 --- a/libcli/smb/smbXcli_base.c +++ b/libcli/smb/smbXcli_base.c @@ -31,6 +31,7 @@ #include "../libcli/smb/read_smb.h" #include "smbXcli_base.h" #include "librpc/ndr/libndr.h" +#include "local.h" struct smbXcli_conn; struct smbXcli_req; @@ -3791,6 +3792,16 @@ struct tevent_req *smbXcli_negprot_send(TALLOC_CTX *mem_ctx, */ conn->dispatch_incoming = smb2cli_conn_dispatch_incoming; + /* + * As we're starting with an SMB2 negprot, emulate Windows + * and ask for 31 credits in the initial SMB2 negprot. + * If we don't and leave requested credits at + * zero, MacOSX servers return zero credits on + * the negprot reply and we fail to connect. + */ + smb2cli_conn_set_max_credits(conn, + WINDOWS_CLIENT_PURE_SMB2_NEGPROT_INITIAL_CREDIT_ASK); + subreq = smbXcli_negprot_smb2_subreq(state); if (tevent_req_nomem(subreq, req)) { return tevent_req_post(req, ev); diff --git a/python/samba/netcmd/dns.py b/python/samba/netcmd/dns.py index 137cd98..6dde9ec 100644 --- a/python/samba/netcmd/dns.py +++ b/python/samba/netcmd/dns.py @@ -19,6 +19,9 @@ import samba.getopt as options from struct import pack from socket import inet_ntoa +from socket import inet_ntop +from socket import AF_INET +from socket import AF_INET6 import shlex from samba.netcmd import ( @@ -89,7 +92,7 @@ def zone_type_string(zone_type): def zone_update_string(zone_update): - enum_defs = [ 'DNS_ZONE_UPDATE_OFF', 'DNS_ZONE_UPDATE_SECURE', + enum_defs = [ 'DNS_ZONE_UPDATE_OFF', 'DNS_ZONE_UPDATE_UNSECURE', 'DNS_ZONE_UPDATE_SECURE' ] return enum_string(dnsp, enum_defs, zone_update) @@ -126,7 +129,7 @@ def ip4_array_string(array): if not array: return ret for i in xrange(array.AddrCount): - addr = '%s' % inet_ntoa(pack('i', array.AddrArray[i])) + addr = inet_ntop(AF_INET, pack('I', array.AddrArray[i])) ret.append(addr) return ret @@ -137,11 +140,11 @@ def dns_addr_array_string(array): return ret for i in xrange(array.AddrCount): if array.AddrArray[i].MaxSa[0] == 0x02: - addr = '%d.%d.%d.%d (%d)' % \ - tuple(array.AddrArray[i].MaxSa[4:8] + [array.AddrArray[i].MaxSa[3]]) + x = "".join([chr(b) for b in array.AddrArray[i].MaxSa])[4:8] + addr = inet_ntop(AF_INET, x) elif array.AddrArray[i].MaxSa[0] == 0x17: - addr = '%x%x:%x%x:%x%x:%x%x:%x%x:%x%x:%x%x:%x%x (%d)' % \ - tuple(array.AddrArray[i].MaxSa[4:20] + [array.AddrArray[i].MaxSa[3]]) + x = "".join([chr(b) for b in array.AddrArray[i].MaxSa])[8:24] + addr = inet_ntop(AF_INET6, x) else: addr = 'UNKNOWN' ret.append(addr) diff --git a/source3/client/client.c b/source3/client/client.c index ab46cb8..20932cc 100644 --- a/source3/client/client.c +++ b/source3/client/client.c @@ -5307,7 +5307,7 @@ static int do_host_query(const char *query_host) if (cli == NULL) { d_printf("NetBIOS over TCP disabled -- no workgroup available\n"); - return 1; + return 0; } cli_set_timeout(cli, io_timeout*1000); diff --git a/source3/include/local.h b/source3/include/local.h index a87ab8f..5ea7960 100644 --- a/source3/include/local.h +++ b/source3/include/local.h @@ -217,4 +217,6 @@ #define DEFAULT_SMB2_MAX_TRANSACT (1024*1024) #define DEFAULT_SMB2_MAX_CREDITS 8192 +#define WINDOWS_CLIENT_PURE_SMB2_NEGPROT_INITIAL_CREDIT_ASK 31 + #endif diff --git a/source3/utils/status.c b/source3/utils/status.c index be7c52f..9ce92aa 100644 --- a/source3/utils/status.c +++ b/source3/utils/status.c @@ -363,6 +363,7 @@ static void print_notify_recs(const char *path, TALLOC_CTX *frame = talloc_stackframe(); int ret = 0; struct messaging_context *msg_ctx; + bool ok; sec_init(); load_case_tables(); @@ -462,10 +463,12 @@ static void print_notify_recs(const char *path, switch (profile_only) { case 'P': /* Dump profile data */ - return status_profile_dump(verbose); + ok = status_profile_dump(verbose); + return ok ? 0 : 1; case 'R': /* Continuously display rate-converted data */ - return status_profile_rates(verbose); + ok = status_profile_rates(verbose); + return ok ? 0 : 1; default: break; } diff --git a/source4/rpc_server/dnsserver/dcerpc_dnsserver.c b/source4/rpc_server/dnsserver/dcerpc_dnsserver.c index dee69fe..ab027ab 100644 --- a/source4/rpc_server/dnsserver/dcerpc_dnsserver.c +++ b/source4/rpc_server/dnsserver/dcerpc_dnsserver.c @@ -196,8 +196,10 @@ static WERROR dnsserver_query_server(struct dnsserver_state *dsstate, r->ServerInfoW2K->fDsAvailable = serverinfo->fDsAvailable; r->ServerInfoW2K->pszServerName = talloc_strdup(mem_ctx, serverinfo->pszServerName); r->ServerInfoW2K->pszDsContainer = talloc_strdup(mem_ctx, serverinfo->pszDsContainer); - r->ServerInfoW2K->aipServerAddrs = ip4_array_copy(mem_ctx, serverinfo->aipServerAddrs); - r->ServerInfoW2K->aipListenAddrs = ip4_array_copy(mem_ctx, serverinfo->aipListenAddrs); + r->ServerInfoW2K->aipServerAddrs = dns_addr_array_to_ip4_array(mem_ctx, + serverinfo->aipServerAddrs); + r->ServerInfoW2K->aipListenAddrs = dns_addr_array_to_ip4_array(mem_ctx, + serverinfo->aipListenAddrs); r->ServerInfoW2K->aipForwarders = ip4_array_copy(mem_ctx, serverinfo->aipForwarders); r->ServerInfoW2K->dwLogLevel = serverinfo->dwLogLevel; r->ServerInfoW2K->dwDebugLevel = serverinfo->dwDebugLevel; @@ -238,8 +240,10 @@ static WERROR dnsserver_query_server(struct dnsserver_state *dsstate, r->ServerInfoDotNet->fDsAvailable = serverinfo->fDsAvailable; r->ServerInfoDotNet->pszServerName = talloc_strdup(mem_ctx, serverinfo->pszServerName); r->ServerInfoDotNet->pszDsContainer = talloc_strdup(mem_ctx, serverinfo->pszDsContainer); - r->ServerInfoDotNet->aipServerAddrs = ip4_array_copy(mem_ctx, serverinfo->aipServerAddrs); - r->ServerInfoDotNet->aipListenAddrs = ip4_array_copy(mem_ctx, serverinfo->aipListenAddrs); + r->ServerInfoDotNet->aipServerAddrs = dns_addr_array_to_ip4_array(mem_ctx, + serverinfo->aipServerAddrs); + r->ServerInfoDotNet->aipListenAddrs = dns_addr_array_to_ip4_array(mem_ctx, + serverinfo->aipListenAddrs); r->ServerInfoDotNet->aipForwarders = ip4_array_copy(mem_ctx, serverinfo->aipForwarders); r->ServerInfoDotNet->aipLogFilter = ip4_array_copy(mem_ctx, serverinfo->aipLogFilter); r->ServerInfoDotNet->pwszLogFilePath = talloc_strdup(mem_ctx, serverinfo->pwszLogFilePath); @@ -293,8 +297,8 @@ static WERROR dnsserver_query_server(struct dnsserver_state *dsstate, r->ServerInfo->fDsAvailable = serverinfo->fDsAvailable; r->ServerInfo->pszServerName = talloc_strdup(mem_ctx, serverinfo->pszServerName); r->ServerInfo->pszDsContainer = talloc_strdup(mem_ctx, serverinfo->pszDsContainer); - r->ServerInfo->aipServerAddrs = ip4_array_to_dns_addr_array(mem_ctx, serverinfo->aipServerAddrs); - r->ServerInfo->aipListenAddrs = ip4_array_to_dns_addr_array(mem_ctx, serverinfo->aipListenAddrs); + r->ServerInfo->aipServerAddrs = serverinfo->aipServerAddrs; + r->ServerInfo->aipListenAddrs = serverinfo->aipListenAddrs; r->ServerInfo->aipForwarders = ip4_array_to_dns_addr_array(mem_ctx, serverinfo->aipForwarders); r->ServerInfo->aipLogFilter = ip4_array_to_dns_addr_array(mem_ctx, serverinfo->aipLogFilter); r->ServerInfo->pwszLogFilePath = talloc_strdup(mem_ctx, serverinfo->pwszLogFilePath); @@ -694,9 +698,9 @@ static WERROR dnsserver_query_server(struct dnsserver_state *dsstate, is_addresses = 1; } else if (strcasecmp(operation, "ListenAddresses") == 0) { if (client_version == DNS_CLIENT_VERSION_LONGHORN) { - answer_addrarray = ip4_array_to_dns_addr_array(mem_ctx, serverinfo->aipListenAddrs); + answer_addrarray = serverinfo->aipListenAddrs; } else { - answer_iparray = ip4_array_copy(mem_ctx, serverinfo->aipListenAddrs); + answer_iparray = dns_addr_array_to_ip4_array(mem_ctx, serverinfo->aipListenAddrs); } is_addresses = 1; } else if (strcasecmp(operation, "BreakOnReceiveFrom") == 0) { diff --git a/source4/rpc_server/dnsserver/dnsdata.c b/source4/rpc_server/dnsserver/dnsdata.c index f752490..63e35d9 100644 --- a/source4/rpc_server/dnsserver/dnsdata.c +++ b/source4/rpc_server/dnsserver/dnsdata.c @@ -91,6 +91,62 @@ struct DNS_ADDR_ARRAY *ip4_array_to_dns_addr_array(TALLOC_CTX *mem_ctx, return ret; } +struct IP4_ARRAY *dns_addr_array_to_ip4_array(TALLOC_CTX *mem_ctx, + struct DNS_ADDR_ARRAY *ip) +{ + struct IP4_ARRAY *ret; + int i, count, curr; + + if (ip == NULL) { + return NULL; + } + /* We must only return IPv4 addresses. + The passed DNS_ADDR_ARRAY may contain: + - only ipv4 addresses + - only ipv6 addresses + - a mixture of both + - an empty array + */ + ret = talloc_zero(mem_ctx, struct IP4_ARRAY); + if (!ret) { + return ret; + } + if (ip->AddrCount == 0 || ip->Family == AF_INET6) { + ret->AddrCount = 0; + return ret; + } + /* Now only ipv4 addresses or a mixture are left */ + count = 0; + for (i = 0; i < ip->AddrCount; i++) { + if (ip->AddrArray[i].MaxSa[0] == 0x02) { + /* Is ipv4 */ + count++; + } + } + if (count == 0) { + /* should not happen */ + ret->AddrCount = 0; + return ret; + } + ret->AddrArray = talloc_zero_array(mem_ctx, uint32_t, count); + if (ret->AddrArray) { + curr = 0; + for (i = 0; i < ip->AddrCount; i++) { + if (ip->AddrArray[i].MaxSa[0] == 0x02) { + /* Is ipv4 */ + memcpy(&ret->AddrArray[curr], + &ip->AddrArray[i].MaxSa[4], + sizeof(uint32_t)); + curr++; + } + } + } else { + talloc_free(ret); + return NULL; + } + ret->AddrCount = curr; + return ret; +} struct DNS_ADDR_ARRAY *dns_addr_array_copy(TALLOC_CTX *mem_ctx, struct DNS_ADDR_ARRAY *addr) diff --git a/source4/rpc_server/dnsserver/dnsserver.h b/source4/rpc_server/dnsserver/dnsserver.h index e3db0b2..cfe6d4e 100644 --- a/source4/rpc_server/dnsserver/dnsserver.h +++ b/source4/rpc_server/dnsserver/dnsserver.h @@ -46,8 +46,8 @@ struct dnsserver_serverinfo { char * pszDomainDirectoryPartition; char * pszForestDirectoryPartition; - struct IP4_ARRAY * aipServerAddrs; - struct IP4_ARRAY * aipListenAddrs; + struct DNS_ADDR_ARRAY * aipServerAddrs; + struct DNS_ADDR_ARRAY * aipListenAddrs; struct IP4_ARRAY * aipForwarders; struct IP4_ARRAY * aipLogFilter; @@ -179,6 +179,8 @@ struct dns_tree { struct IP4_ARRAY *ip4_array_copy(TALLOC_CTX *mem_ctx, struct IP4_ARRAY *ip4); struct DNS_ADDR_ARRAY *ip4_array_to_dns_addr_array(TALLOC_CTX *mem_ctx, struct IP4_ARRAY *ip4); +struct IP4_ARRAY *dns_addr_array_to_ip4_array(TALLOC_CTX *mem_ctx, + struct DNS_ADDR_ARRAY *ip); struct DNS_ADDR_ARRAY *dns_addr_array_copy(TALLOC_CTX *mem_ctx, struct DNS_ADDR_ARRAY *addr); int dns_split_name_components(TALLOC_CTX *mem_ctx, const char *name, char ***components); @@ -217,7 +219,6 @@ struct ldb_dn *dnsserver_name_to_dn(TALLOC_CTX *mem_ctx, struct dnsserver_zone * const char *name); uint32_t dnsserver_zone_to_request_filter(const char *zone); - /* Database functions from dnsdb.c */ struct dnsserver_partition *dnsserver_db_enumerate_partitions(TALLOC_CTX *mem_ctx, diff --git a/source4/rpc_server/dnsserver/dnsutils.c b/source4/rpc_server/dnsserver/dnsutils.c index 9f95646..72b47f7 100644 --- a/source4/rpc_server/dnsserver/dnsutils.c +++ b/source4/rpc_server/dnsserver/dnsutils.c @@ -24,7 +24,78 @@ #include "rpc_server/common/common.h" #include "dsdb/samdb/samdb.h" #include "lib/socket/netif.h" +#include "lib/util/util_net.h" +static struct DNS_ADDR_ARRAY *fill_dns_addr_array(TALLOC_CTX *mem_ctx, + struct loadparm_context *lp_ctx, + bool listen_only) +{ + struct interface *ifaces; + int num_interfaces, i; + struct DNS_ADDR_ARRAY *dns_addr_array; + const char *ipstr; + bool have_ipv4, have_ipv6; + uint16_t family; + + have_ipv4 = have_ipv6 = false; + + if (!listen_only) { + /* + Return all interfaces from kernel + Not implemented! + */ + return NULL; + } + + /* Only the used interfaces */ + load_interface_list(mem_ctx, lp_ctx, &ifaces); + num_interfaces = iface_list_count(ifaces); + + dns_addr_array = talloc_zero(mem_ctx, struct DNS_ADDR_ARRAY); + if (dns_addr_array == NULL) { + goto nomem; + } + dns_addr_array->MaxCount = num_interfaces; + dns_addr_array->AddrCount = num_interfaces; + if (num_interfaces == 0) { + goto nomem; + } + + dns_addr_array->AddrArray = talloc_zero_array(mem_ctx, struct DNS_ADDR, + num_interfaces); + if (!dns_addr_array->AddrArray) { + TALLOC_FREE(dns_addr_array); + goto nomem; + } + + for (i = 0; i < num_interfaces; i++) { + ipstr = iface_list_n_ip(ifaces, i); + if (is_ipaddress_v4(ipstr)) { + have_ipv4 = true; + dns_addr_array->AddrArray[i].MaxSa[0] = 0x02; + inet_pton(AF_INET, ipstr, + &dns_addr_array->AddrArray[i].MaxSa[4]); + } else { + have_ipv6 = true; + dns_addr_array->AddrArray[i].MaxSa[0] = 0x17; + inet_pton(AF_INET6, ipstr, + &dns_addr_array->AddrArray[i].MaxSa[8]); + } + } + + if (have_ipv4 && have_ipv6) { + family = 0; /* mixed: MS-DNSP */ + } else if (have_ipv4 && !have_ipv6) { + family = AF_INET; + } else { + family = AF_INET6; + } + dns_addr_array->Family = family; + +nomem: + talloc_free(ifaces); + return dns_addr_array; +} struct dnsserver_serverinfo *dnsserver_init_serverinfo(TALLOC_CTX *mem_ctx, struct loadparm_context *lp_ctx, @@ -33,8 +104,6 @@ struct dnsserver_serverinfo *dnsserver_init_serverinfo(TALLOC_CTX *mem_ctx, struct dnsserver_serverinfo *serverinfo; struct dcerpc_server_info *dinfo; struct ldb_dn *domain_dn, *forest_dn; - struct interface *ifaces; - int num_interfaces, i; serverinfo = talloc_zero(mem_ctx, struct dnsserver_serverinfo); if (serverinfo == NULL) { @@ -80,31 +149,14 @@ struct dnsserver_serverinfo *dnsserver_init_serverinfo(TALLOC_CTX *mem_ctx, serverinfo->pszForestDirectoryPartition = talloc_asprintf(mem_ctx, "DC=ForestDnsZones,%s", ldb_dn_get_linearized(forest_dn)); - - load_interface_list(mem_ctx, lp_ctx, &ifaces); - num_interfaces = iface_list_count(ifaces); - - serverinfo->aipServerAddrs = talloc_zero(mem_ctx, struct IP4_ARRAY); - - if (serverinfo->aipServerAddrs) { - serverinfo->aipServerAddrs->AddrCount = num_interfaces; - if (num_interfaces > 0) { - serverinfo->aipServerAddrs->AddrArray = talloc_zero_array(mem_ctx, - unsigned int, - num_interfaces); - if (serverinfo->aipServerAddrs->AddrArray) { - for (i=0; i<num_interfaces; i++) { - serverinfo->aipServerAddrs->AddrArray[i] = inet_addr(iface_list_n_ip(ifaces, i)); - } - } else { - serverinfo->aipServerAddrs->AddrCount = 0; - } - } - } - talloc_free(ifaces); - - /* Assume listen addresses are same as server addresses */ - serverinfo->aipListenAddrs = serverinfo->aipServerAddrs; + /* IP addresses on which the DNS server listens for DNS requests */ + serverinfo->aipListenAddrs = fill_dns_addr_array(mem_ctx, lp_ctx, true); + + /* All IP addresses available on the server + * Not implemented! + * Use same as listen addresses + */ + serverinfo->aipServerAddrs = serverinfo->aipListenAddrs; serverinfo->aipForwarders = NULL; -- Samba Shared Repository