The Samba-Bugzilla – Attachment 18315 Details for
Bug 15620
s4:nbt_server: does not provide unexpected handling, so winbindd can't use nmb requests instead cldap
Home
|
New
|
Browse
|
Search
|
[?]
|
Reports
|
Requests
|
Help
|
New Account
|
Log In
[x]
|
Forgot Password
Login:
[x]
Patches for v4-19-test
bfixes-tmp419.txt (text/plain), 59.90 KB, created by
Stefan Metzmacher
on 2024-05-30 11:54:47 UTC
(
hide
)
Description:
Patches for v4-19-test
Filename:
MIME Type:
Creator:
Stefan Metzmacher
Created:
2024-05-30 11:54:47 UTC
Size:
59.90 KB
patch
obsolete
>From 9a0ec3e67f5cdde976bd2717f3edafcfb814f436 Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Wed, 14 Feb 2024 14:15:47 +0100 >Subject: [PATCH 01/11] s3:include: let nameserv.h be useable on its own > >A lot of stuff is private to nmbd and can >be moved from nameserv.h. > >This allows move required types from smb.h to >nameserv.h, so that this can be standalone. >Including it from smb.h is not a huge problem >as nmbd internals are gone from nameserv.h. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=15620 > >Signed-off-by: Stefan Metzmacher <metze@samba.org> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >(cherry picked from commit 7f96c21029e3b94d38bd871c79cabf872ad77fae) >--- > source3/include/nameserv.h | 380 ++---------------------------------- > source3/include/smb.h | 26 +-- > source3/nmbd/nmbd.h | 382 +++++++++++++++++++++++++++++++++++++ > 3 files changed, 403 insertions(+), 385 deletions(-) > >diff --git a/source3/include/nameserv.h b/source3/include/nameserv.h >index 8fbe5a33a29d..51efe82d0611 100644 >--- a/source3/include/nameserv.h >+++ b/source3/include/nameserv.h >@@ -20,18 +20,6 @@ > > */ > >-#define INFO_VERSION "INFO/version" >-#define INFO_COUNT "INFO/num_entries" >-#define INFO_ID_HIGH "INFO/id_high" >-#define INFO_ID_LOW "INFO/id_low" >-#define ENTRY_PREFIX "ENTRY/" >- >-#define PERMANENT_TTL 0 >- >-/* NTAS uses 2, NT uses 1, WfWg uses 0 */ >-#define MAINTAIN_LIST 2 >-#define ELECTION_VERSION 1 >- > #define MAX_DGRAM_SIZE (576) /* tcp/ip datagram limit is 576 bytes */ > #define MIN_DGRAM_SIZE 12 > >@@ -140,12 +128,6 @@ enum netbios_reply_type_code { NMB_QUERY, NMB_STATUS, NMB_REG, NMB_REG_REFRESH, > #define NAME_POLL_REFRESH_TIME (5*60) > #define NAME_POLL_INTERVAL 15 > >-/* Workgroup state identifiers. */ >-#define AM_POTENTIAL_MASTER_BROWSER(work) ((work)->mst_state == MST_POTENTIAL) >-#define AM_LOCAL_MASTER_BROWSER(work) ((work)->mst_state == MST_BROWSER) >-#define AM_DOMAIN_MASTER_BROWSER(work) ((work)->dom_state == DOMAIN_MST) >-#define AM_DOMAIN_MEMBER(work) ((work)->log_state == LOGON_SRV) >- > /* Microsoft browser NetBIOS name. */ > #define MSBROWSE "\001\002__MSBROWSE__\002" > >@@ -159,293 +141,33 @@ enum netbios_reply_type_code { NMB_QUERY, NMB_STATUS, NMB_REG, NMB_REG_REFRESH, > #define FIND_ANY_NAME 0 > #define FIND_SELF_NAME 1 > >-/* >- * The different name types that can be in namelists. >- * >- * SELF_NAME should only be on the broadcast and unicast subnets. >- * LMHOSTS_NAME should only be in the remote_broadcast_subnet. >- * REGISTER_NAME, DNS_NAME, DNSFAIL_NAME should only be in the wins_server_subnet. >- * WINS_PROXY_NAME should only be on the broadcast subnets. >- * PERMANENT_NAME can be on all subnets except remote_broadcast_subnet. >- * >- */ >- >-enum name_source {LMHOSTS_NAME, REGISTER_NAME, SELF_NAME, DNS_NAME, >- DNSFAIL_NAME, PERMANENT_NAME, WINS_PROXY_NAME}; > enum node_type {B_NODE=0, P_NODE=1, M_NODE=2, NBDD_NODE=3}; > enum packet_type {NMB_PACKET, DGRAM_PACKET}; > >-enum master_state { >- MST_NONE, >- MST_POTENTIAL, >- MST_BACKUP, >- MST_MSB, >- MST_BROWSER, >- MST_UNBECOMING_MASTER >-}; >- >-enum domain_state { >- DOMAIN_NONE, >- DOMAIN_WAIT, >- DOMAIN_MST >-}; >- >-enum logon_state { >- LOGON_NONE, >- LOGON_WAIT, >- LOGON_SRV >-}; >- >-struct subnet_record; >- >-struct nmb_data { >- uint16_t nb_flags; /* Netbios flags. */ >- int num_ips; /* Number of ip entries. */ >- struct in_addr *ip; /* The ip list for this name. */ >- >- enum name_source source; /* Where the name came from. */ >- >- time_t death_time; /* The time the record must be removed (do not remove if 0). */ >- time_t refresh_time; /* The time the record should be refreshed. */ >- >- uint64_t id; /* unique id */ >- struct in_addr wins_ip; /* the address of the wins server this record comes from */ >- >- int wins_flags; /* similar to the netbios flags but different ! */ >-}; >- >-/* This structure represents an entry in a local netbios name list. */ >-struct name_record { >- struct name_record *prev, *next; >- struct subnet_record *subnet; >- struct nmb_name name; /* The netbios name. */ >- struct nmb_data data; /* The netbios data. */ >-}; >- >-/* Browser cache for synchronising browse lists. */ >-struct browse_cache_record { >- struct browse_cache_record *prev, *next; >- unstring lmb_name; >- unstring work_group; >- struct in_addr ip; >- time_t sync_time; >- time_t death_time; /* The time the record must be removed. */ >-}; >- >-/* used for server information: client, nameserv and ipc */ >-struct server_info_struct { >- fstring name; >- uint32_t type; >- fstring comment; >- fstring domain; /* used ONLY in ipc.c NOT namework.c */ >- bool server_added; /* used ONLY in ipc.c NOT namework.c */ >-}; >- >-/* This is used to hold the list of servers in my domain, and is >- contained within lists of domains. */ >- >-struct server_record { >- struct server_record *next; >- struct server_record *prev; >- >- struct subnet_record *subnet; >- >- struct server_info_struct serv; >- time_t death_time; >-}; >- >-/* A workgroup structure. It contains a list of servers. */ >-struct work_record { >- struct work_record *next; >- struct work_record *prev; >- >- struct subnet_record *subnet; >- >- struct server_record *serverlist; >- >- /* Stage of development from non-local-master up to local-master browser. */ >- enum master_state mst_state; >- >- /* Stage of development from non-domain-master to domain-master browser. */ >- enum domain_state dom_state; >- >- /* Stage of development from non-logon-server to logon server. */ >- enum logon_state log_state; >- >- /* Work group info. */ >- unstring work_group; >- int token; /* Used when communicating with backup browsers. */ >- unstring local_master_browser_name; /* Current local master browser. */ >- >- /* Announce info. */ >- time_t lastannounce_time; >- int announce_interval; >- bool needannounce; >- >- /* Timeout time for this workgroup. 0 means permanent. */ >- time_t death_time; >- >- /* Election info */ >- bool RunningElection; >- bool needelection; >- int ElectionCount; >- uint32_t ElectionCriterion; >- >- /* Domain master browser info. Used for efficient syncs. */ >- struct nmb_name dmb_name; >- struct in_addr dmb_addr; >-}; >- >-/* typedefs needed to define copy & free functions for userdata. */ >-struct userdata_struct; >- >-typedef struct userdata_struct * (*userdata_copy_fn)(struct userdata_struct *); >-typedef void (*userdata_free_fn)(struct userdata_struct *); >- >-/* Structure to define any userdata passed around. */ >- >-struct userdata_struct { >- userdata_copy_fn copy_fn; >- userdata_free_fn free_fn; >- unsigned int userdata_len; >- char data[16]; /* 16 is to ensure alignment/padding on all systems */ >+#define MAX_NETBIOSNAME_LEN 16 >+/* DOS character, NetBIOS namestring. Type used on the wire. */ >+typedef char nstring[MAX_NETBIOSNAME_LEN]; >+/* Unix character, NetBIOS namestring. Type used to manipulate name in nmbd. */ >+typedef char unstring[MAX_NETBIOSNAME_LEN*4]; >+ >+/* A netbios name structure. */ >+struct nmb_name { >+ nstring name; >+ char scope[64]; >+ unsigned int name_type; > }; > >-struct response_record; >-struct packet_struct; >-struct res_rec; >- >-/* typedef to define the function called when this response packet comes in. */ >-typedef void (*response_function)(struct subnet_record *, struct response_record *, >- struct packet_struct *); >- >-/* typedef to define the function called when this response record times out. */ >-typedef void (*timeout_response_function)(struct subnet_record *, >- struct response_record *); >- >-/* typedef to define the function called when the request that caused this >- response record to be created is successful. */ >-typedef void (*success_function)(struct subnet_record *, struct userdata_struct *, ...); >- >-/* typedef to define the function called when the request that caused this >- response record to be created is unsuccessful. */ >-typedef void (*fail_function)(struct subnet_record *, struct response_record *, ...); >- >-/* List of typedefs for success and fail functions of the different query >- types. Used to catch any compile time prototype errors. */ >- >-typedef void (*register_name_success_function)( struct subnet_record *, >- struct userdata_struct *, >- struct nmb_name *, >- uint16_t, >- int, >- struct in_addr); >-typedef void (*register_name_fail_function)( struct subnet_record *, >- struct response_record *, >- struct nmb_name *); >- >-typedef void (*release_name_success_function)( struct subnet_record *, >- struct userdata_struct *, >- struct nmb_name *, >- struct in_addr); >-typedef void (*release_name_fail_function)( struct subnet_record *, >- struct response_record *, >- struct nmb_name *); >- >-typedef void (*refresh_name_success_function)( struct subnet_record *, >- struct userdata_struct *, >- struct nmb_name *, >- uint16_t, >- int, >- struct in_addr); >-typedef void (*refresh_name_fail_function)( struct subnet_record *, >- struct response_record *, >- struct nmb_name *); >- >-typedef void (*query_name_success_function)( struct subnet_record *, >- struct userdata_struct *, >- struct nmb_name *, >- struct in_addr, >- struct res_rec *answers); >- >-typedef void (*query_name_fail_function)( struct subnet_record *, >- struct response_record *, >- struct nmb_name *, >- int); >- >-typedef void (*node_status_success_function)( struct subnet_record *, >- struct userdata_struct *, >- struct res_rec *, >- struct in_addr); >-typedef void (*node_status_fail_function)( struct subnet_record *, >- struct response_record *); >- >-/* Initiated name queries are recorded in this list to track any responses. */ >- >-struct response_record { >- struct response_record *next; >- struct response_record *prev; >- >- uint16_t response_id; >- >- /* Callbacks for packets received or not. */ >- response_function resp_fn; >- timeout_response_function timeout_fn; >- >- /* Callbacks for the request succeeding or not. */ >- success_function success_fn; >- fail_function fail_fn; >- >- struct packet_struct *packet; >- >- struct userdata_struct *userdata; >- >- int num_msgs; >- >- time_t repeat_time; >- time_t repeat_interval; >- int repeat_count; >- >- /* Recursion protection. */ >- bool in_expiration_processing; >+/* A netbios node status array element. */ >+struct node_status { >+ nstring name; >+ unsigned char type; >+ unsigned char flags; > }; > >-/* A subnet structure. It contains a list of workgroups and netbios names. */ >- >-/* >- B nodes will have their own, totally separate subnet record, with their >- own netbios name set. These do NOT interact with other subnet records' >- netbios names. >-*/ >- >-enum subnet_type { >- NORMAL_SUBNET = 0, /* Subnet listed in interfaces list. */ >- UNICAST_SUBNET = 1, /* Subnet for unicast packets. */ >- REMOTE_BROADCAST_SUBNET = 2, /* Subnet for remote broadcasts. */ >- WINS_SERVER_SUBNET = 3 /* Only created if we are a WINS server. */ >-}; >- >-struct subnet_record { >- struct subnet_record *next; >- struct subnet_record *prev; >- >- char *subnet_name; /* For Debug identification. */ >- enum subnet_type type; /* To catagorize the subnet. */ >- >- struct work_record *workgrouplist; /* List of workgroups. */ >- struct name_record *namelist; /* List of netbios names. */ >- struct response_record *responselist; /* List of responses expected. */ >- >- bool namelist_changed; >- bool work_changed; >- >- struct in_addr bcast_ip; >- struct in_addr mask_ip; >- struct in_addr myip; >- int nmb_sock; /* socket to listen for unicast 137. */ >- int nmb_bcast; /* socket to listen for broadcast 137. */ >- int dgram_sock; /* socket to listen for unicast 138. */ >- int dgram_bcast; /* socket to listen for broadcast 138. */ >+/* The extra info from a NetBIOS node status query */ >+struct node_status_extra { >+ unsigned char mac_addr[6]; >+ /* There really is more here ... */ > }; > > /* A resource record. */ >@@ -564,66 +286,4 @@ struct packet_struct > #define ANN_ResetBrowserState 14 > #define ANN_LocalMasterAnnouncement 15 > >- >-/* Broadcast packet announcement intervals, in minutes. */ >- >-/* Attempt to add domain logon and domain master names. */ >-#define CHECK_TIME_ADD_DOM_NAMES 5 >- >-/* Search for master browsers of workgroups samba knows about, >- except default. */ >-#define CHECK_TIME_MST_BROWSE 5 >- >-/* Request backup browser announcements from other servers. */ >-#define CHECK_TIME_ANNOUNCE_BACKUP 15 >- >-/* Request host announcements from other servers: min and max of interval. */ >-#define CHECK_TIME_MIN_HOST_ANNCE 3 >-#define CHECK_TIME_MAX_HOST_ANNCE 12 >- >-/* Announce as master to WINS server and any Primary Domain Controllers. */ >-#define CHECK_TIME_MST_ANNOUNCE 15 >- >-/* Time between syncs from domain master browser to local master browsers. */ >-#define CHECK_TIME_DMB_TO_LMB_SYNC 15 >- >-/* Do all remote announcements this often. */ >-#define REMOTE_ANNOUNCE_INTERVAL 180 >- >-/* what is the maximum period between name refreshes. Note that this only >- affects non-permanent self names (in seconds) */ >-#define MAX_REFRESH_TIME (60*20) >- >-/* The Extinction interval: 4 days, time a node will stay in released state */ >-#define EXTINCTION_INTERVAL (4*24*60*60) >- >-/* The Extinction time-out: 1 day, time a node will stay in deleted state */ >-#define EXTINCTION_TIMEOUT (24*60*60) >- >-/* Macro's to enumerate subnets either with or without >- the UNICAST subnet. */ >- >-extern struct subnet_record *subnetlist; >-extern struct subnet_record *unicast_subnet; >-extern struct subnet_record *wins_server_subnet; >-extern struct subnet_record *remote_broadcast_subnet; >- >-#define FIRST_SUBNET subnetlist >-#define NEXT_SUBNET_EXCLUDING_UNICAST(x) ((x)->next) >-#define NEXT_SUBNET_INCLUDING_UNICAST(x) (get_next_subnet_maybe_unicast((x))) >- >-/* wins replication record used between nmbd and wrepld */ >-typedef struct _WINS_RECORD { >- char name[17]; >- char type; >- int nb_flags; >- int wins_flags; >- uint64_t id; >- int num_ips; >- struct in_addr ip[25]; >- struct in_addr wins_ip; >-} WINS_RECORD; >- >-/* To be removed. */ >-enum state_type { TEST }; > #endif /* _NAMESERV_H_ */ >diff --git a/source3/include/smb.h b/source3/include/smb.h >index 81d761d2280a..ce188721ceb0 100644 >--- a/source3/include/smb.h >+++ b/source3/include/smb.h >@@ -625,31 +625,7 @@ struct kernel_oplocks_ops { > > #include "smb_macros.h" > >-#define MAX_NETBIOSNAME_LEN 16 >-/* DOS character, NetBIOS namestring. Type used on the wire. */ >-typedef char nstring[MAX_NETBIOSNAME_LEN]; >-/* Unix character, NetBIOS namestring. Type used to manipulate name in nmbd. */ >-typedef char unstring[MAX_NETBIOSNAME_LEN*4]; >- >-/* A netbios name structure. */ >-struct nmb_name { >- nstring name; >- char scope[64]; >- unsigned int name_type; >-}; >- >-/* A netbios node status array element. */ >-struct node_status { >- nstring name; >- unsigned char type; >- unsigned char flags; >-}; >- >-/* The extra info from a NetBIOS node status query */ >-struct node_status_extra { >- unsigned char mac_addr[6]; >- /* There really is more here ... */ >-}; >+#include "nameserv.h" > > #define SAFE_NETBIOS_CHARS ". -_" > >diff --git a/source3/nmbd/nmbd.h b/source3/nmbd/nmbd.h >index f207eb9304eb..0a8e345ddaef 100644 >--- a/source3/nmbd/nmbd.h >+++ b/source3/nmbd/nmbd.h >@@ -26,6 +26,388 @@ > #endif > > #include "libsmb/nmblib.h" >+ >+#define INFO_VERSION "INFO/version" >+#define INFO_COUNT "INFO/num_entries" >+#define INFO_ID_HIGH "INFO/id_high" >+#define INFO_ID_LOW "INFO/id_low" >+#define ENTRY_PREFIX "ENTRY/" >+ >+#define PERMANENT_TTL 0 >+ >+/* NTAS uses 2, NT uses 1, WfWg uses 0 */ >+#define MAINTAIN_LIST 2 >+#define ELECTION_VERSION 1 >+ >+#define REFRESH_TIME (15*60) >+#define NAME_POLL_REFRESH_TIME (5*60) >+#define NAME_POLL_INTERVAL 15 >+ >+/* Workgroup state identifiers. */ >+#define AM_POTENTIAL_MASTER_BROWSER(work) ((work)->mst_state == MST_POTENTIAL) >+#define AM_LOCAL_MASTER_BROWSER(work) ((work)->mst_state == MST_BROWSER) >+#define AM_DOMAIN_MASTER_BROWSER(work) ((work)->dom_state == DOMAIN_MST) >+#define AM_DOMAIN_MEMBER(work) ((work)->log_state == LOGON_SRV) >+ >+/* Microsoft browser NetBIOS name. */ >+#define MSBROWSE "\001\002__MSBROWSE__\002" >+ >+/* Mail slots. */ >+#define BROWSE_MAILSLOT "\\MAILSLOT\\BROWSE" >+#define NET_LOGON_MAILSLOT "\\MAILSLOT\\NET\\NETLOGON" >+#define NT_LOGON_MAILSLOT "\\MAILSLOT\\NET\\NTLOGON" >+#define LANMAN_MAILSLOT "\\MAILSLOT\\LANMAN" >+ >+/* Samba definitions for find_name_on_subnet(). */ >+#define FIND_ANY_NAME 0 >+#define FIND_SELF_NAME 1 >+ >+/* >+ * The different name types that can be in namelists. >+ * >+ * SELF_NAME should only be on the broadcast and unicast subnets. >+ * LMHOSTS_NAME should only be in the remote_broadcast_subnet. >+ * REGISTER_NAME, DNS_NAME, DNSFAIL_NAME should only be in the wins_server_subnet. >+ * WINS_PROXY_NAME should only be on the broadcast subnets. >+ * PERMANENT_NAME can be on all subnets except remote_broadcast_subnet. >+ * >+ */ >+ >+enum name_source {LMHOSTS_NAME, REGISTER_NAME, SELF_NAME, DNS_NAME, >+ DNSFAIL_NAME, PERMANENT_NAME, WINS_PROXY_NAME}; >+ >+enum master_state { >+ MST_NONE, >+ MST_POTENTIAL, >+ MST_BACKUP, >+ MST_MSB, >+ MST_BROWSER, >+ MST_UNBECOMING_MASTER >+}; >+ >+enum domain_state { >+ DOMAIN_NONE, >+ DOMAIN_WAIT, >+ DOMAIN_MST >+}; >+ >+enum logon_state { >+ LOGON_NONE, >+ LOGON_WAIT, >+ LOGON_SRV >+}; >+ >+struct subnet_record; >+ >+struct nmb_data { >+ uint16_t nb_flags; /* Netbios flags. */ >+ int num_ips; /* Number of ip entries. */ >+ struct in_addr *ip; /* The ip list for this name. */ >+ >+ enum name_source source; /* Where the name came from. */ >+ >+ time_t death_time; /* The time the record must be removed (do not remove if 0). */ >+ time_t refresh_time; /* The time the record should be refreshed. */ >+ >+ uint64_t id; /* unique id */ >+ struct in_addr wins_ip; /* the address of the wins server this record comes from */ >+ >+ int wins_flags; /* similar to the netbios flags but different ! */ >+}; >+ >+/* This structure represents an entry in a local netbios name list. */ >+struct name_record { >+ struct name_record *prev, *next; >+ struct subnet_record *subnet; >+ struct nmb_name name; /* The netbios name. */ >+ struct nmb_data data; /* The netbios data. */ >+}; >+ >+/* Browser cache for synchronising browse lists. */ >+struct browse_cache_record { >+ struct browse_cache_record *prev, *next; >+ unstring lmb_name; >+ unstring work_group; >+ struct in_addr ip; >+ time_t sync_time; >+ time_t death_time; /* The time the record must be removed. */ >+}; >+ >+/* used for server information: client, nameserv and ipc */ >+struct server_info_struct { >+ fstring name; >+ uint32_t type; >+ fstring comment; >+ fstring domain; /* used ONLY in ipc.c NOT namework.c */ >+ bool server_added; /* used ONLY in ipc.c NOT namework.c */ >+}; >+ >+/* This is used to hold the list of servers in my domain, and is >+ contained within lists of domains. */ >+ >+struct server_record { >+ struct server_record *next; >+ struct server_record *prev; >+ >+ struct subnet_record *subnet; >+ >+ struct server_info_struct serv; >+ time_t death_time; >+}; >+ >+/* A workgroup structure. It contains a list of servers. */ >+struct work_record { >+ struct work_record *next; >+ struct work_record *prev; >+ >+ struct subnet_record *subnet; >+ >+ struct server_record *serverlist; >+ >+ /* Stage of development from non-local-master up to local-master browser. */ >+ enum master_state mst_state; >+ >+ /* Stage of development from non-domain-master to domain-master browser. */ >+ enum domain_state dom_state; >+ >+ /* Stage of development from non-logon-server to logon server. */ >+ enum logon_state log_state; >+ >+ /* Work group info. */ >+ unstring work_group; >+ int token; /* Used when communicating with backup browsers. */ >+ unstring local_master_browser_name; /* Current local master browser. */ >+ >+ /* Announce info. */ >+ time_t lastannounce_time; >+ int announce_interval; >+ bool needannounce; >+ >+ /* Timeout time for this workgroup. 0 means permanent. */ >+ time_t death_time; >+ >+ /* Election info */ >+ bool RunningElection; >+ bool needelection; >+ int ElectionCount; >+ uint32_t ElectionCriterion; >+ >+ /* Domain master browser info. Used for efficient syncs. */ >+ struct nmb_name dmb_name; >+ struct in_addr dmb_addr; >+}; >+ >+/* typedefs needed to define copy & free functions for userdata. */ >+struct userdata_struct; >+ >+typedef struct userdata_struct * (*userdata_copy_fn)(struct userdata_struct *); >+typedef void (*userdata_free_fn)(struct userdata_struct *); >+ >+/* Structure to define any userdata passed around. */ >+ >+struct userdata_struct { >+ userdata_copy_fn copy_fn; >+ userdata_free_fn free_fn; >+ unsigned int userdata_len; >+ char data[16]; /* 16 is to ensure alignment/padding on all systems */ >+}; >+ >+struct response_record; >+struct packet_struct; >+struct res_rec; >+ >+/* typedef to define the function called when this response packet comes in. */ >+typedef void (*response_function)(struct subnet_record *, struct response_record *, >+ struct packet_struct *); >+ >+/* typedef to define the function called when this response record times out. */ >+typedef void (*timeout_response_function)(struct subnet_record *, >+ struct response_record *); >+ >+/* typedef to define the function called when the request that caused this >+ response record to be created is successful. */ >+typedef void (*success_function)(struct subnet_record *, struct userdata_struct *, ...); >+ >+/* typedef to define the function called when the request that caused this >+ response record to be created is unsuccessful. */ >+typedef void (*fail_function)(struct subnet_record *, struct response_record *, ...); >+ >+/* List of typedefs for success and fail functions of the different query >+ types. Used to catch any compile time prototype errors. */ >+ >+typedef void (*register_name_success_function)( struct subnet_record *, >+ struct userdata_struct *, >+ struct nmb_name *, >+ uint16_t, >+ int, >+ struct in_addr); >+typedef void (*register_name_fail_function)( struct subnet_record *, >+ struct response_record *, >+ struct nmb_name *); >+ >+typedef void (*release_name_success_function)( struct subnet_record *, >+ struct userdata_struct *, >+ struct nmb_name *, >+ struct in_addr); >+typedef void (*release_name_fail_function)( struct subnet_record *, >+ struct response_record *, >+ struct nmb_name *); >+ >+typedef void (*refresh_name_success_function)( struct subnet_record *, >+ struct userdata_struct *, >+ struct nmb_name *, >+ uint16_t, >+ int, >+ struct in_addr); >+typedef void (*refresh_name_fail_function)( struct subnet_record *, >+ struct response_record *, >+ struct nmb_name *); >+ >+typedef void (*query_name_success_function)( struct subnet_record *, >+ struct userdata_struct *, >+ struct nmb_name *, >+ struct in_addr, >+ struct res_rec *answers); >+ >+typedef void (*query_name_fail_function)( struct subnet_record *, >+ struct response_record *, >+ struct nmb_name *, >+ int); >+ >+typedef void (*node_status_success_function)( struct subnet_record *, >+ struct userdata_struct *, >+ struct res_rec *, >+ struct in_addr); >+typedef void (*node_status_fail_function)( struct subnet_record *, >+ struct response_record *); >+ >+/* Initiated name queries are recorded in this list to track any responses. */ >+ >+struct response_record { >+ struct response_record *next; >+ struct response_record *prev; >+ >+ uint16_t response_id; >+ >+ /* Callbacks for packets received or not. */ >+ response_function resp_fn; >+ timeout_response_function timeout_fn; >+ >+ /* Callbacks for the request succeeding or not. */ >+ success_function success_fn; >+ fail_function fail_fn; >+ >+ struct packet_struct *packet; >+ >+ struct userdata_struct *userdata; >+ >+ int num_msgs; >+ >+ time_t repeat_time; >+ time_t repeat_interval; >+ int repeat_count; >+ >+ /* Recursion protection. */ >+ bool in_expiration_processing; >+}; >+ >+/* A subnet structure. It contains a list of workgroups and netbios names. */ >+ >+/* >+ B nodes will have their own, totally separate subnet record, with their >+ own netbios name set. These do NOT interact with other subnet records' >+ netbios names. >+*/ >+ >+enum subnet_type { >+ NORMAL_SUBNET = 0, /* Subnet listed in interfaces list. */ >+ UNICAST_SUBNET = 1, /* Subnet for unicast packets. */ >+ REMOTE_BROADCAST_SUBNET = 2, /* Subnet for remote broadcasts. */ >+ WINS_SERVER_SUBNET = 3 /* Only created if we are a WINS server. */ >+}; >+ >+struct subnet_record { >+ struct subnet_record *next; >+ struct subnet_record *prev; >+ >+ char *subnet_name; /* For Debug identification. */ >+ enum subnet_type type; /* To catagorize the subnet. */ >+ >+ struct work_record *workgrouplist; /* List of workgroups. */ >+ struct name_record *namelist; /* List of netbios names. */ >+ struct response_record *responselist; /* List of responses expected. */ >+ >+ bool namelist_changed; >+ bool work_changed; >+ >+ struct in_addr bcast_ip; >+ struct in_addr mask_ip; >+ struct in_addr myip; >+ int nmb_sock; /* socket to listen for unicast 137. */ >+ int nmb_bcast; /* socket to listen for broadcast 137. */ >+ int dgram_sock; /* socket to listen for unicast 138. */ >+ int dgram_bcast; /* socket to listen for broadcast 138. */ >+}; >+ >+/* Broadcast packet announcement intervals, in minutes. */ >+ >+/* Attempt to add domain logon and domain master names. */ >+#define CHECK_TIME_ADD_DOM_NAMES 5 >+ >+/* Search for master browsers of workgroups samba knows about, >+ except default. */ >+#define CHECK_TIME_MST_BROWSE 5 >+ >+/* Request backup browser announcements from other servers. */ >+#define CHECK_TIME_ANNOUNCE_BACKUP 15 >+ >+/* Request host announcements from other servers: min and max of interval. */ >+#define CHECK_TIME_MIN_HOST_ANNCE 3 >+#define CHECK_TIME_MAX_HOST_ANNCE 12 >+ >+/* Announce as master to WINS server and any Primary Domain Controllers. */ >+#define CHECK_TIME_MST_ANNOUNCE 15 >+ >+/* Time between syncs from domain master browser to local master browsers. */ >+#define CHECK_TIME_DMB_TO_LMB_SYNC 15 >+ >+/* Do all remote announcements this often. */ >+#define REMOTE_ANNOUNCE_INTERVAL 180 >+ >+/* what is the maximum period between name refreshes. Note that this only >+ affects non-permanent self names (in seconds) */ >+#define MAX_REFRESH_TIME (60*20) >+ >+/* The Extinction interval: 4 days, time a node will stay in released state */ >+#define EXTINCTION_INTERVAL (4*24*60*60) >+ >+/* The Extinction time-out: 1 day, time a node will stay in deleted state */ >+#define EXTINCTION_TIMEOUT (24*60*60) >+ >+/* Macro's to enumerate subnets either with or without >+ the UNICAST subnet. */ >+ >+extern struct subnet_record *subnetlist; >+extern struct subnet_record *unicast_subnet; >+extern struct subnet_record *wins_server_subnet; >+extern struct subnet_record *remote_broadcast_subnet; >+ >+#define FIRST_SUBNET subnetlist >+#define NEXT_SUBNET_EXCLUDING_UNICAST(x) ((x)->next) >+#define NEXT_SUBNET_INCLUDING_UNICAST(x) (get_next_subnet_maybe_unicast((x))) >+ >+/* wins replication record used between nmbd and wrepld */ >+typedef struct _WINS_RECORD { >+ char name[17]; >+ char type; >+ int nb_flags; >+ int wins_flags; >+ uint64_t id; >+ int num_ips; >+ struct in_addr ip[25]; >+ struct in_addr wins_ip; >+} WINS_RECORD; >+ > #include "nmbd/nmbd_proto.h" > > #define NMBD_WAIT_INTERFACES_TIME_USEC (250 * 1000) >-- >2.34.1 > > >From 3d8e3e2e84c040a8a7dbfe0ec6a329d80013d4a1 Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Thu, 15 Feb 2024 16:53:29 +0100 >Subject: [PATCH 02/11] s3:include: split out fstring.h > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=15620 > >Signed-off-by: Stefan Metzmacher <metze@samba.org> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >(cherry picked from commit 105247c90007474947e2314b63be72fb21f09811) >--- > source3/include/fstring.h | 27 +++++++++++++++++++++++++++ > source3/include/includes.h | 5 +---- > 2 files changed, 28 insertions(+), 4 deletions(-) > create mode 100644 source3/include/fstring.h > >diff --git a/source3/include/fstring.h b/source3/include/fstring.h >new file mode 100644 >index 000000000000..dfc8f17a8f33 >--- /dev/null >+++ b/source3/include/fstring.h >@@ -0,0 +1,27 @@ >+/* >+ Unix SMB/CIFS implementation. >+ Copyright (C) 2002 by Martin Pool <mbp@samba.org> >+ >+ This program is free software; you can redistribute it and/or modify >+ it under the terms of the GNU General Public License as published by >+ the Free Software Foundation; either version 3 of the License, or >+ (at your option) any later version. >+ >+ This program is distributed in the hope that it will be useful, >+ but WITHOUT ANY WARRANTY; without even the implied warranty of >+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the >+ GNU General Public License for more details. >+ >+ You should have received a copy of the GNU General Public License >+ along with this program. If not, see <http://www.gnu.org/licenses/>. >+*/ >+ >+#ifndef _SAMBA_FSTRING_H >+#define _SAMBA_FSTRING_H >+ >+#ifndef FSTRING_LEN >+#define FSTRING_LEN 256 >+typedef char fstring[FSTRING_LEN]; >+#endif >+ >+#endif /* _SAMBA_FSTRING_H */ >diff --git a/source3/include/includes.h b/source3/include/includes.h >index 02beb0a0c88e..8e8bffad8806 100644 >--- a/source3/include/includes.h >+++ b/source3/include/includes.h >@@ -237,10 +237,7 @@ enum timestamp_set_resolution { > _________)/\\_//(\/(/\)/\//\/\///|_)_______ > */ > >-#ifndef FSTRING_LEN >-#define FSTRING_LEN 256 >-typedef char fstring[FSTRING_LEN]; >-#endif >+#include "fstring.h" > > /* debug.h need to be included before samba_util.h for the macro SMB_ASSERT */ > #include "../lib/util/debug.h" >-- >2.34.1 > > >From b3981ea7f2c5ea403463b1db7ccb74975bc26501 Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Thu, 15 Feb 2024 16:37:34 +0100 >Subject: [PATCH 03/11] s3:wscript: LIBNMB requires lp_ functions > >We need to make this explicit in order to let LIBNMB be used >in source4 code. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=15620 > >Signed-off-by: Stefan Metzmacher <metze@samba.org> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >(cherry picked from commit 011f68ae5ddc3fae8b453744aeb95766d885915e) >--- > source3/wscript_build | 1 + > 1 file changed, 1 insertion(+) > >diff --git a/source3/wscript_build b/source3/wscript_build >index 092fa4bf796f..1188c782122e 100644 >--- a/source3/wscript_build >+++ b/source3/wscript_build >@@ -902,6 +902,7 @@ bld.SAMBA3_SUBSYSTEM('LIBNMB', > LIBTSOCKET > LIBCLI_NETLOGON > samba3util >+ smbconf > addns > lmhosts > resolv >-- >2.34.1 > > >From 555fc0ea17807a86af6c4ca9ab672a58c6a3a528 Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Wed, 14 Feb 2024 13:49:43 +0100 >Subject: [PATCH 04/11] s3:libsmb/unexpected: don't use talloc_tos() in async > code > >It's not needed and it requires the caller to setup a >stackframe... > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=15620 > >Signed-off-by: Stefan Metzmacher <metze@samba.org> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >(cherry picked from commit f90cf0822d6e66426d72f92bd585119066e2a9c3) >--- > source3/libsmb/unexpected.c | 6 ++++-- > 1 file changed, 4 insertions(+), 2 deletions(-) > >diff --git a/source3/libsmb/unexpected.c b/source3/libsmb/unexpected.c >index ced46969b886..dbcbc04b2d68 100644 >--- a/source3/libsmb/unexpected.c >+++ b/source3/libsmb/unexpected.c >@@ -246,7 +246,7 @@ static void nb_packet_got_query(struct tevent_req *req) > ssize_t nread; > int err; > >- nread = tstream_read_packet_recv(req, talloc_tos(), &buf, &err); >+ nread = tstream_read_packet_recv(req, client, &buf, &err); > TALLOC_FREE(req); > if (nread < (ssize_t)sizeof(struct nb_packet_query)) { > DEBUG(10, ("read_packet_recv returned %d (%s)\n", >@@ -278,6 +278,8 @@ static void nb_packet_got_query(struct tevent_req *req) > } > } > >+ TALLOC_FREE(buf); >+ > client->ack.byte = 0; > client->ack.iov[0].iov_base = &client->ack.byte; > client->ack.iov[0].iov_len = 1; >@@ -331,7 +333,7 @@ static void nb_packet_client_read_done(struct tevent_req *req) > uint8_t *buf; > int err; > >- nread = tstream_read_packet_recv(req, talloc_tos(), &buf, &err); >+ nread = tstream_read_packet_recv(req, client, &buf, &err); > TALLOC_FREE(req); > if (nread == 1) { > DEBUG(10, ("Protocol error, received data on write-only " >-- >2.34.1 > > >From 356dd8353a56b26c56b8e39f95834da2bc848158 Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Wed, 14 Feb 2024 11:38:19 +0100 >Subject: [PATCH 05/11] s3:libsmb/unexpected: pass nmbd_socket_dir from the > callers of nb_packet_{server_create,reader_send}() > >This will allow source4/nbt_server to make use of >nb_packet_server_create(). > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=15620 > >Signed-off-by: Stefan Metzmacher <metze@samba.org> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >(cherry picked from commit 696505a1efbcc9803a287d8c267fed9d04bf8885) >--- > source3/libsmb/clidgram.c | 6 +++++- > source3/libsmb/namequery.c | 7 ++++++- > source3/libsmb/nmblib.c | 6 ++++++ > source3/libsmb/nmblib.h | 2 ++ > source3/libsmb/unexpected.c | 12 ++++-------- > source3/libsmb/unexpected.h | 2 ++ > source3/nmbd/nmbd_packets.c | 1 + > 7 files changed, 26 insertions(+), 10 deletions(-) > >diff --git a/source3/libsmb/clidgram.c b/source3/libsmb/clidgram.c >index ec0b1efa8ce1..137b454acbba 100644 >--- a/source3/libsmb/clidgram.c >+++ b/source3/libsmb/clidgram.c >@@ -349,7 +349,11 @@ struct tevent_req *nbt_getdc_send(TALLOC_CTX *mem_ctx, > return tevent_req_post(req, ev); > } > >- subreq = nb_packet_reader_send(state, ev, DGRAM_PACKET, -1, >+ subreq = nb_packet_reader_send(state, >+ ev, >+ global_nmbd_socket_dir(), >+ DGRAM_PACKET, >+ -1, > state->my_mailslot); > if (tevent_req_nomem(subreq, req)) { > return tevent_req_post(req, ev); >diff --git a/source3/libsmb/namequery.c b/source3/libsmb/namequery.c >index e6c0c7d2a095..73a552a553ae 100644 >--- a/source3/libsmb/namequery.c >+++ b/source3/libsmb/namequery.c >@@ -644,7 +644,12 @@ static struct tevent_req *nb_trans_send( > return tevent_req_post(req, ev); > } > >- subreq = nb_packet_reader_send(state, ev, type, state->trn_id, NULL); >+ subreq = nb_packet_reader_send(state, >+ ev, >+ global_nmbd_socket_dir(), >+ type, >+ state->trn_id, >+ NULL); > if (tevent_req_nomem(subreq, req)) { > return tevent_req_post(req, ev); > } >diff --git a/source3/libsmb/nmblib.c b/source3/libsmb/nmblib.c >index c90e92ebb697..232b80039734 100644 >--- a/source3/libsmb/nmblib.c >+++ b/source3/libsmb/nmblib.c >@@ -23,6 +23,12 @@ > #include "libsmb/nmblib.h" > #include "lib/util/string_wrappers.h" > >+const char *global_nmbd_socket_dir(void) >+{ >+ return lp_parm_const_string(-1, "nmbd", "socket dir", >+ get_dyn_NMBDSOCKETDIR()); >+} >+ > static const struct opcode_names { > const char *nmb_opcode_name; > int opcode; >diff --git a/source3/libsmb/nmblib.h b/source3/libsmb/nmblib.h >index 52600a41e575..5171a26ec0f3 100644 >--- a/source3/libsmb/nmblib.h >+++ b/source3/libsmb/nmblib.h >@@ -29,6 +29,8 @@ > > /* The following definitions come from libsmb/nmblib.c */ > >+const char *global_nmbd_socket_dir(void); >+ > void debug_nmb_packet(struct packet_struct *p); > void put_name(char *dest, const char *name, int pad, unsigned int name_type); > char *nmb_namestr(const struct nmb_name *n); >diff --git a/source3/libsmb/unexpected.c b/source3/libsmb/unexpected.c >index dbcbc04b2d68..bbad054c3865 100644 >--- a/source3/libsmb/unexpected.c >+++ b/source3/libsmb/unexpected.c >@@ -26,12 +26,6 @@ > #include "lib/tsocket/tsocket.h" > #include "lib/util/sys_rw.h" > >-static const char *nmbd_socket_dir(void) >-{ >- return lp_parm_const_string(-1, "nmbd", "socket dir", >- get_dyn_NMBDSOCKETDIR()); >-} >- > struct nb_packet_query { > enum packet_type type; > size_t mailslot_namelen; >@@ -74,6 +68,7 @@ static void nb_packet_server_listener(struct tevent_context *ev, > > NTSTATUS nb_packet_server_create(TALLOC_CTX *mem_ctx, > struct tevent_context *ev, >+ const char *nmbd_socket_dir, > int max_clients, > struct nb_packet_server **presult) > { >@@ -90,7 +85,7 @@ NTSTATUS nb_packet_server_create(TALLOC_CTX *mem_ctx, > result->max_clients = max_clients; > > result->listen_sock = create_pipe_sock( >- nmbd_socket_dir(), "unexpected", 0755); >+ nmbd_socket_dir, "unexpected", 0755); > if (result->listen_sock == -1) { > status = map_nt_error_from_unix(errno); > goto fail; >@@ -495,6 +490,7 @@ static void nb_packet_reader_got_ack(struct tevent_req *subreq); > > struct tevent_req *nb_packet_reader_send(TALLOC_CTX *mem_ctx, > struct tevent_context *ev, >+ const char *nmbd_socket_dir, > enum packet_type type, > int trn_id, > const char *mailslot_name) >@@ -530,7 +526,7 @@ struct tevent_req *nb_packet_reader_send(TALLOC_CTX *mem_ctx, > tevent_req_nterror(req, map_nt_error_from_unix(errno)); > return tevent_req_post(req, ev); > } >- rpath = talloc_asprintf(state, "%s/%s", nmbd_socket_dir(), >+ rpath = talloc_asprintf(state, "%s/%s", nmbd_socket_dir, > "unexpected"); > if (tevent_req_nomem(rpath, req)) { > return tevent_req_post(req, ev); >diff --git a/source3/libsmb/unexpected.h b/source3/libsmb/unexpected.h >index 270976b7f650..4ae9b2090620 100644 >--- a/source3/libsmb/unexpected.h >+++ b/source3/libsmb/unexpected.h >@@ -29,12 +29,14 @@ struct nb_packet_reader; > > NTSTATUS nb_packet_server_create(TALLOC_CTX *mem_ctx, > struct tevent_context *ev, >+ const char *nmbd_socket_dir, > int max_clients, > struct nb_packet_server **presult); > void nb_packet_dispatch(struct nb_packet_server *server, > struct packet_struct *p); > struct tevent_req *nb_packet_reader_send(TALLOC_CTX *mem_ctx, > struct tevent_context *ev, >+ const char *nmbd_socket_dir, > enum packet_type type, > int trn_id, > const char *mailslot_name); >diff --git a/source3/nmbd/nmbd_packets.c b/source3/nmbd/nmbd_packets.c >index a1d8deec0f32..1da365762e65 100644 >--- a/source3/nmbd/nmbd_packets.c >+++ b/source3/nmbd/nmbd_packets.c >@@ -43,6 +43,7 @@ bool nmbd_init_packet_server(void) > > status = nb_packet_server_create( > NULL, nmbd_event_context(), >+ global_nmbd_socket_dir(), > lp_parm_int(-1, "nmbd", "unexpected_clients", 200), > &packet_server); > if (!NT_STATUS_IS_OK(status)) { >-- >2.34.1 > > >From 3682090ccdee9db38d7bf8248de9dd4db6546a96 Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Thu, 15 Feb 2024 17:29:46 +0100 >Subject: [PATCH 06/11] s3:libsmb/dsgetdcname: use > NETLOGON_NT_VERSION_AVOID_NT4EMUL > >In 2024 we always want an active directory response... > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=15620 > >Signed-off-by: Stefan Metzmacher <metze@samba.org> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >(cherry picked from commit 2b66663c75cdb3bc1b6bc5b1736dd9d35b094b42) >--- > source3/libsmb/dsgetdcname.c | 5 +++++ > 1 file changed, 5 insertions(+) > >diff --git a/source3/libsmb/dsgetdcname.c b/source3/libsmb/dsgetdcname.c >index 864d58ad150b..da173e7bbb07 100644 >--- a/source3/libsmb/dsgetdcname.c >+++ b/source3/libsmb/dsgetdcname.c >@@ -952,6 +952,11 @@ static NTSTATUS process_dc_netbios(TALLOC_CTX *mem_ctx, > name_type = NBT_NAME_PDC; > } > >+ /* >+ * It's 2024 we always want an AD style response! >+ */ >+ nt_version |= NETLOGON_NT_VERSION_AVOID_NT4EMUL; >+ > nt_version |= map_ds_flags_to_nt_version(flags); > > snprintf(my_acct_name, >-- >2.34.1 > > >From 92e18ccedc1ce39909159e6a95d199ef0684229d Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Thu, 15 Feb 2024 17:47:13 +0100 >Subject: [PATCH 07/11] libcli/nbt: add nbt_name_send_raw() > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=15620 > >Signed-off-by: Stefan Metzmacher <metze@samba.org> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >(cherry picked from commit cca373b806e01fc57bd5316d3f8a17578b4b6531) >--- > libcli/nbt/libnbt.h | 3 +++ > libcli/nbt/nbtsocket.c | 44 ++++++++++++++++++++++++++++++++++++++++++ > 2 files changed, 47 insertions(+) > >diff --git a/libcli/nbt/libnbt.h b/libcli/nbt/libnbt.h >index 204484be73f6..6a30c9fedb51 100644 >--- a/libcli/nbt/libnbt.h >+++ b/libcli/nbt/libnbt.h >@@ -331,6 +331,9 @@ NTSTATUS nbt_set_unexpected_handler(struct nbt_name_socket *nbtsock, > void (*handler)(struct nbt_name_socket *, struct nbt_name_packet *, > struct socket_address *), > void *private_data); >+NTSTATUS nbt_name_send_raw(struct nbt_name_socket *nbtsock, >+ struct socket_address *dest, >+ const DATA_BLOB pkt_blob); > NTSTATUS nbt_name_reply_send(struct nbt_name_socket *nbtsock, > struct socket_address *dest, > struct nbt_name_packet *request); >diff --git a/libcli/nbt/nbtsocket.c b/libcli/nbt/nbtsocket.c >index 47e73cf2e8d2..b2945ad912f9 100644 >--- a/libcli/nbt/nbtsocket.c >+++ b/libcli/nbt/nbtsocket.c >@@ -448,6 +448,50 @@ failed: > return NULL; > } > >+/* >+ send off a nbt name packet >+*/ >+_PUBLIC_ NTSTATUS nbt_name_send_raw(struct nbt_name_socket *nbtsock, >+ struct socket_address *dest, >+ const DATA_BLOB pkt_blob) >+{ >+ struct nbt_name_request *req; >+ >+ req = talloc_zero(nbtsock, struct nbt_name_request); >+ NT_STATUS_HAVE_NO_MEMORY(req); >+ >+ req->nbtsock = nbtsock; >+ req->dest = socket_address_copy(req, dest); >+ if (req->dest == NULL) { >+ goto failed; >+ } >+ req->state = NBT_REQUEST_SEND; >+ /* >+ * We don't expect a response so >+ * just pretent it is a request, >+ * but we really don't care about the >+ * content. >+ */ >+ req->is_reply = true; >+ >+ req->encoded = data_blob_dup_talloc(req, pkt_blob); >+ if (req->encoded.length != pkt_blob.length) { >+ goto failed; >+ } >+ >+ talloc_set_destructor(req, nbt_name_request_destructor); >+ >+ DLIST_ADD_END(nbtsock->send_queue, req); >+ >+ TEVENT_FD_WRITEABLE(nbtsock->fde); >+ >+ return NT_STATUS_OK; >+ >+failed: >+ talloc_free(req); >+ return NT_STATUS_NO_MEMORY; >+} >+ > > /* > send off a nbt name reply >-- >2.34.1 > > >From 470ea2ce798fbcd422e38772f4b021a6022871ef Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Thu, 15 Feb 2024 16:42:16 +0100 >Subject: [PATCH 08/11] s4:libcli/dgram: let the generic incoming handler also > get unexpected mailslot messages > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=15620 > >Signed-off-by: Stefan Metzmacher <metze@samba.org> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >(cherry picked from commit 11861bcfc3054894bc445e631ae03befb4865db8) >--- > source4/libcli/dgram/dgramsocket.c | 4 ++++ > 1 file changed, 4 insertions(+) > >diff --git a/source4/libcli/dgram/dgramsocket.c b/source4/libcli/dgram/dgramsocket.c >index 154a66709482..dc5dd796bc0f 100644 >--- a/source4/libcli/dgram/dgramsocket.c >+++ b/source4/libcli/dgram/dgramsocket.c >@@ -90,6 +90,10 @@ static void dgm_socket_recv(struct nbt_dgram_socket *dgmsock) > dgmslot->handler(dgmslot, packet, src); > } else { > DEBUG(2,("No mailslot handler for '%s'\n", mailslot_name)); >+ /* dispatch if there is a general handler */ >+ if (dgmsock->incoming.handler) { >+ dgmsock->incoming.handler(dgmsock, packet, src); >+ } > } > } else { > /* dispatch if there is a general handler */ >-- >2.34.1 > > >From 54da2c4abf67742e569c64a3aab4a8e934df777f Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Thu, 15 Feb 2024 17:47:45 +0100 >Subject: [PATCH 09/11] s4:libcli/dgram: make use of socket_address_copy() > >This avoids talloc_reference... > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=15620 > >Signed-off-by: Stefan Metzmacher <metze@samba.org> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >(cherry picked from commit 77f4f1c7dbaa2bb04d59d908923f6d11fd514da2) >--- > source4/libcli/dgram/dgramsocket.c | 4 ++-- > 1 file changed, 2 insertions(+), 2 deletions(-) > >diff --git a/source4/libcli/dgram/dgramsocket.c b/source4/libcli/dgram/dgramsocket.c >index dc5dd796bc0f..cd0628ac8349 100644 >--- a/source4/libcli/dgram/dgramsocket.c >+++ b/source4/libcli/dgram/dgramsocket.c >@@ -224,8 +224,8 @@ NTSTATUS nbt_dgram_send(struct nbt_dgram_socket *dgmsock, > req = talloc(dgmsock, struct nbt_dgram_request); > if (req == NULL) goto failed; > >- req->dest = dest; >- if (talloc_reference(req, dest) == NULL) goto failed; >+ req->dest = socket_address_copy(req, dest); >+ if (req->dest == NULL) goto failed; > > ndr_err = ndr_push_struct_blob(&req->encoded, req, packet, > (ndr_push_flags_fn_t)ndr_push_nbt_dgram_packet); >-- >2.34.1 > > >From ecf43c15c8dfad45a3c69c78671c42a7d64f9347 Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Wed, 14 Feb 2024 13:49:21 +0100 >Subject: [PATCH 10/11] s4:libcli/dgram: add nbt_dgram_send_raw() to send raw > blobs > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=15620 > >Signed-off-by: Stefan Metzmacher <metze@samba.org> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >(cherry picked from commit bfb10774b65af65f9c438a5d3e87529b1fcf46a1) >--- > source4/libcli/dgram/dgramsocket.c | 32 ++++++++++++++++++++++++++++++ > source4/libcli/dgram/libdgram.h | 3 +++ > 2 files changed, 35 insertions(+) > >diff --git a/source4/libcli/dgram/dgramsocket.c b/source4/libcli/dgram/dgramsocket.c >index cd0628ac8349..2a98792ab37e 100644 >--- a/source4/libcli/dgram/dgramsocket.c >+++ b/source4/libcli/dgram/dgramsocket.c >@@ -209,6 +209,38 @@ NTSTATUS dgram_set_incoming_handler(struct nbt_dgram_socket *dgmsock, > return NT_STATUS_OK; > } > >+NTSTATUS nbt_dgram_send_raw(struct nbt_dgram_socket *dgmsock, >+ struct socket_address *dest, >+ const DATA_BLOB pkt_blob) >+{ >+ struct nbt_dgram_request *req; >+ NTSTATUS status = NT_STATUS_NO_MEMORY; >+ >+ req = talloc(dgmsock, struct nbt_dgram_request); >+ if (req == NULL) { >+ goto failed; >+ } >+ >+ req->dest = socket_address_copy(req, dest); >+ if (req->dest == NULL) { >+ goto failed; >+ } >+ >+ req->encoded = data_blob_dup_talloc(req, pkt_blob); >+ if (req->encoded.length != pkt_blob.length) { >+ goto failed; >+ } >+ >+ DLIST_ADD_END(dgmsock->send_queue, req); >+ >+ TEVENT_FD_WRITEABLE(dgmsock->fde); >+ >+ return NT_STATUS_OK; >+ >+failed: >+ talloc_free(req); >+ return status; >+} > > /* > queue a datagram for send >diff --git a/source4/libcli/dgram/libdgram.h b/source4/libcli/dgram/libdgram.h >index 0f313a67cf56..7e57a944a977 100644 >--- a/source4/libcli/dgram/libdgram.h >+++ b/source4/libcli/dgram/libdgram.h >@@ -83,6 +83,9 @@ struct dgram_mailslot_handler { > > > /* prototypes */ >+NTSTATUS nbt_dgram_send_raw(struct nbt_dgram_socket *dgmsock, >+ struct socket_address *dest, >+ const DATA_BLOB pkt_blob); > NTSTATUS nbt_dgram_send(struct nbt_dgram_socket *dgmsock, > struct nbt_dgram_packet *packet, > struct socket_address *dest); >-- >2.34.1 > > >From f9a4dab729112e318dd3a008a9aa33d86841ea94 Mon Sep 17 00:00:00 2001 >From: Stefan Metzmacher <metze@samba.org> >Date: Wed, 14 Feb 2024 12:34:48 +0100 >Subject: [PATCH 11/11] s4:nbt_server: simulate nmbd and provide unexpected > handling > >This is needed in order to let nbt_getdc() work against >another AD DC and get back a modern response with >DNS based names. Instead of falling back to >the ugly name_status_find() that simulates just >an NETLOGON_SAM_LOGON_RESPONSE_NT40 response. > >This way dsgetdcname() can work with just the netbios >domain name given and still return an active directory >response. > >BUG: https://bugzilla.samba.org/show_bug.cgi?id=15620 > >Signed-off-by: Stefan Metzmacher <metze@samba.org> >Reviewed-by: Andrew Bartlett <abartlet@samba.org> >(cherry picked from commit 796f33c05a0ca337b675b5d4d127f7c53b22528f) >--- > selftest/target/Samba4.pm | 2 + > source4/nbt_server/dgram/request.c | 56 ++++++++++- > source4/nbt_server/interfaces.c | 29 ++++++ > source4/nbt_server/nbt_server.c | 143 +++++++++++++++++++++++++++++ > source4/nbt_server/nbt_server.h | 2 + > source4/nbt_server/wscript_build | 2 +- > 6 files changed, 231 insertions(+), 3 deletions(-) > >diff --git a/selftest/target/Samba4.pm b/selftest/target/Samba4.pm >index cbaacce48da1..364806e71fec 100755 >--- a/selftest/target/Samba4.pm >+++ b/selftest/target/Samba4.pm >@@ -618,6 +618,7 @@ sub provision_raw_prepare($$$$$$$$$$$$$$) > $ctx->{statedir} = "$prefix_abs/statedir"; > $ctx->{cachedir} = "$prefix_abs/cachedir"; > $ctx->{winbindd_socket_dir} = "$prefix_abs/wbsock"; >+ $ctx->{nmbd_socket_dir} = "$prefix_abs/nmbsock"; > $ctx->{ntp_signd_socket_dir} = "$prefix_abs/ntp_signd_socket"; > $ctx->{nsswrap_passwd} = "$ctx->{etcdir}/passwd"; > $ctx->{nsswrap_group} = "$ctx->{etcdir}/group"; >@@ -774,6 +775,7 @@ sub provision_raw_step1($$) > state directory = $ctx->{statedir} > cache directory = $ctx->{cachedir} > winbindd socket directory = $ctx->{winbindd_socket_dir} >+ nmbd:socket dir = $ctx->{nmbd_socket_dir} > ntp signd socket directory = $ctx->{ntp_signd_socket_dir} > winbind separator = / > interfaces = $interfaces >diff --git a/source4/nbt_server/dgram/request.c b/source4/nbt_server/dgram/request.c >index ea2b6e8b98ac..76145147ad0c 100644 >--- a/source4/nbt_server/dgram/request.c >+++ b/source4/nbt_server/dgram/request.c >@@ -27,6 +27,11 @@ > #include "nbt_server/dgram/proto.h" > #include "librpc/gen_ndr/ndr_nbt.h" > #include "param/param.h" >+#include "lib/util/util_str_escape.h" >+#include "lib/util/util_net.h" >+#include "../source3/include/fstring.h" >+#include "../source3/libsmb/nmblib.h" >+#include "../source3/libsmb/unexpected.h" > > /* > a list of mailslots that we have static handlers for >@@ -51,8 +56,55 @@ void dgram_request_handler(struct nbt_dgram_socket *dgmsock, > struct nbt_dgram_packet *packet, > struct socket_address *src) > { >- DEBUG(0,("General datagram request from %s:%d\n", src->addr, src->port)); >- NDR_PRINT_DEBUG(nbt_dgram_packet, packet); >+ struct nbtd_interface *iface = >+ talloc_get_type_abort(dgmsock->incoming.private_data, >+ struct nbtd_interface); >+ struct nbtd_server *nbtsrv = iface->nbtsrv; >+ const char *mailslot_name = NULL; >+ struct packet_struct *pstruct = NULL; >+ DATA_BLOB blob = { .length = 0, }; >+ enum ndr_err_code ndr_err; >+ >+ mailslot_name = dgram_mailslot_name(packet); >+ if (mailslot_name != NULL) { >+ DBG_DEBUG("Unexpected mailslot[%s] datagram request from %s:%d\n", >+ log_escape(packet, mailslot_name), >+ src->addr, src->port); >+ } else { >+ DBG_DEBUG("Unexpected general datagram request from %s:%d\n", >+ src->addr, src->port); >+ } >+ >+ if (CHECK_DEBUGLVL(DBGLVL_DEBUG)) { >+ NDR_PRINT_DEBUG(nbt_dgram_packet, packet); >+ } >+ >+ /* >+ * For now we only pass DGRAM_DIRECT_UNIQUE >+ * messages via nb_packet_dispatch() to >+ * nbtsrv->unexpected_server >+ */ >+ if (packet->msg_type != DGRAM_DIRECT_UNIQUE) { >+ return; >+ } >+ >+ ndr_err = ndr_push_struct_blob(&blob, packet, packet, >+ (ndr_push_flags_fn_t)ndr_push_nbt_dgram_packet); >+ if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { >+ DBG_ERR("ndr_push_nbt_dgram_packet - %s\n", >+ ndr_errstr(ndr_err)); >+ return; >+ } >+ >+ pstruct = parse_packet((char *)blob.data, >+ blob.length, >+ DGRAM_PACKET, >+ interpret_addr2(src->addr), >+ src->port); >+ if (pstruct != NULL) { >+ nb_packet_dispatch(nbtsrv->unexpected_server, pstruct); >+ free_packet(pstruct); >+ } > } > > >diff --git a/source4/nbt_server/interfaces.c b/source4/nbt_server/interfaces.c >index b946a1dedf40..0888c1b54a65 100644 >--- a/source4/nbt_server/interfaces.c >+++ b/source4/nbt_server/interfaces.c >@@ -31,6 +31,9 @@ > #include "param/param.h" > #include "lib/util/util_net.h" > #include "lib/util/idtree.h" >+#include "../source3/include/fstring.h" >+#include "../source3/libsmb/nmblib.h" >+#include "../source3/libsmb/unexpected.h" > > /* > receive an incoming request and dispatch it to the right place >@@ -115,7 +118,33 @@ static void nbtd_unexpected_handler(struct nbt_name_socket *nbtsock, > } > > if (!req) { >+ struct packet_struct *pstruct = NULL; >+ DATA_BLOB blob = { .length = 0, }; >+ enum ndr_err_code ndr_err; >+ >+ /* >+ * Here we have NBT_FLAG_REPLY >+ */ > DEBUG(10,("unexpected from src[%s] unable to redirected\n", src->addr)); >+ >+ ndr_err = ndr_push_struct_blob(&blob, packet, packet, >+ (ndr_push_flags_fn_t)ndr_push_nbt_name_packet); >+ if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { >+ DBG_ERR("ndr_push_nbt_name_packet - %s\n", >+ ndr_errstr(ndr_err)); >+ return; >+ } >+ >+ pstruct = parse_packet((char *)blob.data, >+ blob.length, >+ NMB_PACKET, >+ interpret_addr2(src->addr), >+ src->port); >+ if (pstruct != NULL) { >+ nb_packet_dispatch(nbtsrv->unexpected_server, pstruct); >+ free_packet(pstruct); >+ } >+ > return; > } > >diff --git a/source4/nbt_server/nbt_server.c b/source4/nbt_server/nbt_server.c >index 6d28bbdbdad1..c3f9fac40fae 100644 >--- a/source4/nbt_server/nbt_server.c >+++ b/source4/nbt_server/nbt_server.c >@@ -29,9 +29,113 @@ > #include "auth/auth.h" > #include "dsdb/samdb/samdb.h" > #include "param/param.h" >+#include "dynconfig/dynconfig.h" >+#include "lib/util/pidfile.h" >+#include "lib/util/util_net.h" >+#include "lib/socket/socket.h" >+#include "../source3/include/fstring.h" >+#include "../source3/libsmb/nmblib.h" >+#include "../source3/libsmb/unexpected.h" >+#include "../source3/lib/util_procid.h" > > NTSTATUS server_service_nbtd_init(TALLOC_CTX *); > >+static void nbtd_server_msg_send_packet(struct imessaging_context *msg, >+ void *private_data, >+ uint32_t msg_type, >+ struct server_id src, >+ size_t num_fds, >+ int *fds, >+ DATA_BLOB *data) >+{ >+ TALLOC_CTX *frame = talloc_stackframe(); >+ struct nbtd_server *nbtsrv = >+ talloc_get_type_abort(private_data, >+ struct nbtd_server); >+ struct packet_struct *p = (struct packet_struct *)data->data; >+ struct sockaddr_storage ss; >+ struct socket_address *dst = NULL; >+ struct nbtd_interface *iface = NULL; >+ char buf[1024] = { 0, }; >+ DATA_BLOB blob = { .length = 0, }; >+ >+ DBG_DEBUG("Received send_packet from %u\n", (unsigned int)procid_to_pid(&src)); >+ >+ if (data->length != sizeof(struct packet_struct)) { >+ DBG_WARNING("Discarding invalid packet length from %u\n", >+ (unsigned int)procid_to_pid(&src)); >+ TALLOC_FREE(frame); >+ return; >+ } >+ >+ if ((p->packet_type != NMB_PACKET) && >+ (p->packet_type != DGRAM_PACKET)) { >+ DBG_WARNING("Discarding invalid packet type from %u: %d\n", >+ (unsigned int)procid_to_pid(&src), p->packet_type); >+ TALLOC_FREE(frame); >+ return; >+ } >+ >+ if (p->packet_type == DGRAM_PACKET) { >+ p->port = 138; >+ } >+ >+ in_addr_to_sockaddr_storage(&ss, p->ip); >+ dst = socket_address_from_sockaddr_storage(frame, &ss, p->port); >+ if (dst == NULL) { >+ TALLOC_FREE(frame); >+ return; >+ } >+ if (p->port == 0) { >+ DBG_WARNING("Discarding packet with missing port for addr[%s] " >+ "from %u\n", >+ dst->addr, (unsigned int)procid_to_pid(&src)); >+ TALLOC_FREE(frame); >+ return; >+ } >+ >+ iface = nbtd_find_request_iface(nbtsrv, dst->addr, true); >+ if (iface == NULL) { >+ DBG_WARNING("Could not find iface for packet to addr[%s] " >+ "from %u\n", >+ dst->addr, (unsigned int)procid_to_pid(&src)); >+ TALLOC_FREE(frame); >+ return; >+ } >+ >+ p->recv_fd = -1; >+ p->send_fd = -1; >+ >+ if (p->packet_type == DGRAM_PACKET) { >+ p->packet.dgram.header.source_ip.s_addr = interpret_addr(iface->ip_address); >+ p->packet.dgram.header.source_port = 138; >+ } >+ >+ blob.length = build_packet(buf, sizeof(buf), p); >+ if (blob.length == 0) { >+ TALLOC_FREE(frame); >+ return; >+ } >+ blob.data = (uint8_t *)buf; >+ >+ if (p->packet_type == DGRAM_PACKET) { >+ nbt_dgram_send_raw(iface->dgmsock, dst, blob); >+ } else { >+ nbt_name_send_raw(iface->nbtsock, dst, blob); >+ } >+ >+ TALLOC_FREE(frame); >+} >+ >+static int nbtd_server_destructor(struct nbtd_server *nbtsrv) >+{ >+ struct task_server *task = nbtsrv->task; >+ >+ pidfile_unlink(lpcfg_pid_directory(task->lp_ctx), "nmbd"); >+ >+ return 0; >+} >+ > /* > startup the nbtd task > */ >@@ -40,6 +144,8 @@ static NTSTATUS nbtd_task_init(struct task_server *task) > struct nbtd_server *nbtsrv; > NTSTATUS status; > struct interface *ifaces; >+ const char *nmbd_socket_dir = NULL; >+ int unexpected_clients; > > load_interface_list(task, task->lp_ctx, &ifaces); > >@@ -66,6 +172,8 @@ static NTSTATUS nbtd_task_init(struct task_server *task) > nbtsrv->bcast_interface = NULL; > nbtsrv->wins_interface = NULL; > >+ talloc_set_destructor(nbtsrv, nbtd_server_destructor); >+ > /* start listening on the configured network interfaces */ > status = nbtd_startup_interfaces(nbtsrv, task->lp_ctx, ifaces); > if (!NT_STATUS_IS_OK(status)) { >@@ -73,6 +181,30 @@ static NTSTATUS nbtd_task_init(struct task_server *task) > return status; > } > >+ nmbd_socket_dir = lpcfg_parm_string(task->lp_ctx, >+ NULL, >+ "nmbd", >+ "socket dir"); >+ if (nmbd_socket_dir == NULL) { >+ nmbd_socket_dir = get_dyn_NMBDSOCKETDIR(); >+ } >+ >+ unexpected_clients = lpcfg_parm_int(task->lp_ctx, >+ NULL, >+ "nmbd", >+ "unexpected_clients", >+ 200); >+ >+ status = nb_packet_server_create(nbtsrv, >+ nbtsrv->task->event_ctx, >+ nmbd_socket_dir, >+ unexpected_clients, >+ &nbtsrv->unexpected_server); >+ if (!NT_STATUS_IS_OK(status)) { >+ task_server_terminate(task, "nbtd failed to start unexpected_server", true); >+ return status; >+ } >+ > nbtsrv->sam_ctx = samdb_connect(nbtsrv, > task->event_ctx, > task->lp_ctx, >@@ -93,11 +225,22 @@ static NTSTATUS nbtd_task_init(struct task_server *task) > > nbtd_register_irpc(nbtsrv); > >+ status = imessaging_register(task->msg_ctx, >+ nbtsrv, >+ MSG_SEND_PACKET, >+ nbtd_server_msg_send_packet); >+ if (!NT_STATUS_IS_OK(status)) { >+ task_server_terminate(task, "nbtd failed imessaging_register(MSG_SEND_PACKET)", true); >+ return status; >+ } >+ > /* start the process of registering our names on all interfaces */ > nbtd_register_names(nbtsrv); > > irpc_add_name(task->msg_ctx, "nbt_server"); > >+ pidfile_create(lpcfg_pid_directory(task->lp_ctx), "nmbd"); >+ > return NT_STATUS_OK; > } > >diff --git a/source4/nbt_server/nbt_server.h b/source4/nbt_server/nbt_server.h >index c80e5bfca078..cbad3e96213b 100644 >--- a/source4/nbt_server/nbt_server.h >+++ b/source4/nbt_server/nbt_server.h >@@ -78,6 +78,8 @@ struct nbtd_server { > struct nbtd_statistics stats; > > struct ldb_context *sam_ctx; >+ >+ struct nb_packet_server *unexpected_server; > }; > > >diff --git a/source4/nbt_server/wscript_build b/source4/nbt_server/wscript_build >index 9d0c24a14e20..ce436e801065 100644 >--- a/source4/nbt_server/wscript_build >+++ b/source4/nbt_server/wscript_build >@@ -38,7 +38,7 @@ bld.SAMBA_SUBSYSTEM('NBTD_DGRAM', > bld.SAMBA_SUBSYSTEM('NBT_SERVER', > source='interfaces.c register.c query.c nodestatus.c defense.c packet.c irpc.c', > autoproto='nbt_server_proto.h', >- deps='cli-nbt NBTD_WINS NBTD_DGRAM service', >+ deps='cli-nbt NBTD_WINS NBTD_DGRAM service LIBNMB', > enabled=bld.AD_DC_BUILD_IS_ENABLED() > ) > >-- >2.34.1 >
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Raw
Flags:
slow
:
review+
Actions:
View
Attachments on
bug 15620
:
18314
| 18315