The branch, v3-6-test has been updated via 4e72d9b s3: Make nmbd socket dir configurable via 082040d s3: Remove some unused code via 84e4835 s3: Limit the number of unexpected clients to 200 via b2d10b7 s3: Limit the number of unexpected packets per client to 10 via ef77aa7 s3: Use the new nbt_getdc in winbindd_cm via 8ba9767 s3: Use the new nbt_getdc in dsgetdcname() via 01f60a6 s3: Add nbt_getdc via 4934d84 s3: Fix a valgrind error via cdaf2f8 s3: Factor out parse_getdc_response via c070a39 s3: Lift my_mailslot from prep_getdc_request via 6e32aac s3: Make name_query use /tmp/.nmbd/unexpected via f40375e s3: Make node_status_query use /tmp/.nmbd/unexpected via 063f50a s3: Add nb_trans_send/recv via 9abeeae s3: Add sock_packet_read via 6bbba0a s3: Add packet_trn_id() via 71ade76 s3: Make nmbd listen on the unexpected socket via 60ef871 s3: Basic infrastructure for /tmp/.nmbd/unexpected from fb58d94 s3-nmbd: Fix bug #7875
http://gitweb.samba.org/?p=samba.git;a=shortlog;h=v3-6-test - Log ----------------------------------------------------------------- commit 4e72d9bdb3b737b3e13b65a863515ba840e1daab Author: Volker Lendecke <v...@samba.org> Date: Thu Jan 6 12:33:44 2011 +0100 s3: Make nmbd socket dir configurable Autobuild-User: Volker Lendecke <vlen...@samba.org> Autobuild-Date: Fri Jan 7 14:14:19 CET 2011 on sn-devel-104 commit 082040d4ee69763e0355bc87b23d51dfff87bce0 Author: Volker Lendecke <v...@samba.org> Date: Wed Jan 5 14:50:21 2011 +0100 s3: Remove some unused code commit 84e48356790a3c5390e6a97c5e36f9b5c4546d75 Author: Volker Lendecke <v...@samba.org> Date: Wed Jan 5 14:35:11 2011 +0100 s3: Limit the number of unexpected clients to 200 DoS protection like the max winbind clients. Settable by nmbd:unexpected_clients commit b2d10b7e295fd298cbcd997b67656f064c6c9ab5 Author: Volker Lendecke <v...@samba.org> Date: Wed Jan 5 14:34:04 2011 +0100 s3: Limit the number of unexpected packets per client to 10 Non-reading clients could maliciously make nmbd allocate memory commit ef77aa754852c7c6e1694c4aa669c5df210bc298 Author: Volker Lendecke <v...@samba.org> Date: Wed Jan 5 14:13:00 2011 +0100 s3: Use the new nbt_getdc in winbindd_cm commit 8ba97675dbfde418352e2b2fbca77974391285e5 Author: Volker Lendecke <v...@samba.org> Date: Wed Jan 5 14:12:44 2011 +0100 s3: Use the new nbt_getdc in dsgetdcname() commit 01f60a6d9fae0214133431280acb062530bd7f24 Author: Volker Lendecke <v...@samba.org> Date: Sun Jan 2 12:49:08 2011 +0100 s3: Add nbt_getdc This is a getdc version that uses /tmp/.nmbd/unexpected commit 4934d841bd4af3553c0ea00ca4e054a1ca3cafc6 Author: Volker Lendecke <v...@samba.org> Date: Thu Jan 6 02:12:00 2011 +0100 s3: Fix a valgrind error commit cdaf2f8cfe65c8be92593de47ce555fff71d8e38 Author: Volker Lendecke <v...@samba.org> Date: Sun Jan 2 14:43:18 2011 +0100 s3: Factor out parse_getdc_response commit c070a3956dbee29003d9720d7fc0a025ff124d94 Author: Volker Lendecke <v...@samba.org> Date: Sun Jan 2 12:42:47 2011 +0100 s3: Lift my_mailslot from prep_getdc_request commit 6e32aac073a1527ac2f30bc861002d7a947114a6 Author: Volker Lendecke <v...@samba.org> Date: Tue Jan 4 18:48:47 2011 +0100 s3: Make name_query use /tmp/.nmbd/unexpected commit f40375e955140f5d1fa59c4ef6ceda386eeaa7fc Author: Volker Lendecke <v...@samba.org> Date: Tue Jan 4 18:34:38 2011 +0100 s3: Make node_status_query use /tmp/.nmbd/unexpected commit 063f50a0c06fe268c8ec38d91946fa3128adc665 Author: Volker Lendecke <v...@samba.org> Date: Tue Jan 4 18:22:38 2011 +0100 s3: Add nb_trans_send/recv This does an async port 137 transaction: It connects to /tmp/.nmbd/unexpected, sends out the query and then waits for a reply on both the socket as well as data from /tmp/.nmbd/unexpected. Every packet is passed through a validator. If that returns true, the packet received is finally accepted. commit 9abeeae58a259a7a623176f2af4e44ce5252b2b2 Author: Volker Lendecke <v...@samba.org> Date: Tue Jan 4 18:17:33 2011 +0100 s3: Add sock_packet_read Read packets from both a socket and from /tmp/.nmbd/unexpected simultaneously commit 6bbba0a80673cd3bab3d589f828e87a2805a4c07 Author: Volker Lendecke <v...@samba.org> Date: Tue Jan 4 18:07:12 2011 +0100 s3: Add packet_trn_id() commit 71ade76c304ba8412a8be28a059279e2e5a1d129 Author: Volker Lendecke <v...@samba.org> Date: Tue Jan 4 17:58:12 2011 +0100 s3: Make nmbd listen on the unexpected socket commit 60ef871acee2342445d420c7f96642683c0061b6 Author: Volker Lendecke <v...@samba.org> Date: Tue Jan 4 17:12:17 2011 +0100 s3: Basic infrastructure for /tmp/.nmbd/unexpected This provides the framework to replace the unexpected.tdb file. Nmbd will listen on /tmp/.nmbd/unexpected. A client interested in unexpected packets connects there. It sends a nb_packet_query plus a potential mailslot name for dgram packets. It waits for a single ack byte to avoid races. After that has happened, nmbd will pass down all matching packets through that socket. nb_packet_server_create and nb_packet_dispatch are the nmbd routines, nb_packet_reader_send/recv and nb_packet_read_send/recv are the client ones. ----------------------------------------------------------------------- Summary of changes: nsswitch/wins.c | 13 +- source3/Makefile.in | 6 + source3/dynconfig.c | 1 + source3/include/dynconfig.h | 4 + source3/include/proto.h | 72 ++- source3/libsmb/clidgram.c | 316 ++++++++---- source3/libsmb/clidgram.h | 32 +- source3/libsmb/dsgetdcname.c | 27 +- source3/libsmb/namequery.c | 1096 ++++++++++++++++++++++++++++---------- source3/libsmb/nmblib.c | 56 +-- source3/libsmb/unexpected.c | 813 +++++++++++++++++++++-------- source3/m4/check_path.m4 | 18 + source3/nmbd/nmbd.c | 15 +- source3/nmbd/nmbd_packets.c | 32 +- source3/nmbd/nmbd_proto.h | 2 + source3/utils/nmblookup.c | 21 +- source3/web/diagnose.c | 22 +- source3/winbindd/winbindd_cm.c | 32 +- source3/winbindd/winbindd_wins.c | 65 +--- 19 files changed, 1822 insertions(+), 821 deletions(-) Changeset truncated at 500 lines: diff --git a/nsswitch/wins.c b/nsswitch/wins.c index 6e3c84b..51b78fb 100644 --- a/nsswitch/wins.c +++ b/nsswitch/wins.c @@ -103,10 +103,9 @@ static void nss_wins_init(void) static struct in_addr *lookup_byname_backend(const char *name, int *count) { - int fd = -1; struct ip_service *address = NULL; struct in_addr *ret = NULL; - int j, flags = 0; + int j; if (!initialised) { nss_wins_init(); @@ -131,11 +130,6 @@ static struct in_addr *lookup_byname_backend(const char *name, int *count) return ret; } - fd = wins_lookup_open_socket_in(); - if (fd == -1) { - return NULL; - } - /* uggh, we have to broadcast to each interface in turn */ for (j=iface_count() - 1;j >= 0;j--) { const struct in_addr *bcast = iface_n_bcast_v4(j); @@ -147,8 +141,8 @@ static struct in_addr *lookup_byname_backend(const char *name, int *count) continue; } in_addr_to_sockaddr_storage(&ss, *bcast); - status = name_query(fd, name, 0x00, True, True, &ss, - NULL, &pss, count, &flags, NULL); + status = name_query(name, 0x00, True, True, &ss, + NULL, &pss, count, NULL); if (pss) { if ((ret = SMB_MALLOC_P(struct in_addr)) == NULL) { return NULL; @@ -159,7 +153,6 @@ static struct in_addr *lookup_byname_backend(const char *name, int *count) } } - close(fd); return ret; } diff --git a/source3/Makefile.in b/source3/Makefile.in index 7151df9..7c52f04 100644 --- a/source3/Makefile.in +++ b/source3/Makefile.in @@ -177,6 +177,9 @@ CODEPAGEDIR = @codepagedir@ # the directory where pid files go PIDDIR = @piddir@ +# the directory where nmbd listens on the unexpected socket +NMBDSOCKETDIR = @nmbdsocketdir@ + FLAGS = -I. \ -I$(srcdir) \ @FLAGS1@ \ @@ -206,6 +209,7 @@ PATH_FLAGS = -DSMB_PASSWD_FILE=\"$(SMB_PASSWD_FILE)\" \ -DCODEPAGEDIR=\"$(CODEPAGEDIR)\" \ -DCACHEDIR=\"$(CACHEDIR)\" \ -DSTATEDIR=\"$(STATEDIR)\" \ + -DNMBDSOCKETDIR=\"$(NMBDSOCKETDIR)\" \ -DLOCALEDIR=\"$(LOCALEDIR)\" # Note that all executable programs now provide for an optional executable suffix. @@ -3150,6 +3154,7 @@ installdirs:: @$(SHELL) $(srcdir)/script/installdirs.sh $(INSTALLPERMS_BIN) \ $(DESTDIR) $(prefix) $(BINDIR) $(SBINDIR) $(LIBDIR) \ $(VARDIR) $(PRIVATEDIR) $(PIDDIR) $(LOCKDIR) $(STATEDIR) \ + $(NMBDSOCKETDIR) \ $(CACHEDIR) $(MANDIR) $(CODEPAGEDIR) $(MODULESDIR) $(LOCALEDIR) installservers:: all installdirs @@ -3228,6 +3233,7 @@ showlayout:: @echo " statedir: $(STATEDIR)" @echo " cachedir: $(CACHEDIR)" @echo " piddir: $(PIDDIR)" + @echo " nmbdsocketdir: $(NMBSOCKETDIR)" @echo " swatdir: $(SWATDIR)" @echo " datadir: ${DATADIR}" @echo " codepagedir: $(CODEPAGEDIR)" diff --git a/source3/dynconfig.c b/source3/dynconfig.c index dfec0c3..c3ecae5 100644 --- a/source3/dynconfig.c +++ b/source3/dynconfig.c @@ -79,6 +79,7 @@ DEFINE_DYN_CONFIG_PARAM(LOCKDIR) DEFINE_DYN_CONFIG_PARAM(STATEDIR) /** Persistent state files. Default LOCKDIR */ DEFINE_DYN_CONFIG_PARAM(CACHEDIR) /** Temporary cache files. Default LOCKDIR */ DEFINE_DYN_CONFIG_PARAM(PIDDIR) +DEFINE_DYN_CONFIG_PARAM(NMBDSOCKETDIR) DEFINE_DYN_CONFIG_PARAM(NCALRPCDIR) DEFINE_DYN_CONFIG_PARAM(SMB_PASSWD_FILE) DEFINE_DYN_CONFIG_PARAM(PRIVATE_DIR) diff --git a/source3/include/dynconfig.h b/source3/include/dynconfig.h index 850ef1e..cd6dcb7 100644 --- a/source3/include/dynconfig.h +++ b/source3/include/dynconfig.h @@ -79,6 +79,10 @@ const char *get_dyn_PIDDIR(void); const char *set_dyn_PIDDIR(const char *newpath); bool is_default_dyn_PIDDIR(void); +const char *get_dyn_NMBDSOCKETDIR(void); +const char *set_dyn_NMBDSOCKETDIR(const char *newpath); +bool is_default_dyn_NMBDSOCKETDIR(void); + const char *get_dyn_NCALRPCDIR(void); const char *set_dyn_NCALRPCDIR(const char *newpath); bool is_default_dyn_NCALRPCDIR(void); diff --git a/source3/include/proto.h b/source3/include/proto.h index 385a537..0775acd 100644 --- a/source3/include/proto.h +++ b/source3/include/proto.h @@ -2699,12 +2699,18 @@ bool saf_store( const char *domain, const char *servername ); bool saf_join_store( const char *domain, const char *servername ); bool saf_delete( const char *domain ); char *saf_fetch( const char *domain ); -NTSTATUS node_status_query(int fd, - struct nmb_name *name, - const struct sockaddr_storage *to_ss, - TALLOC_CTX *mem_ctx, - struct node_status **names, - int *num_names, +struct tevent_req *node_status_query_send(TALLOC_CTX *mem_ctx, + struct tevent_context *ev, + struct nmb_name *name, + const struct sockaddr_storage *addr); +NTSTATUS node_status_query_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx, + struct node_status **pnode_status, + int *pnum_names, + struct node_status_extra *extra); +NTSTATUS node_status_query(TALLOC_CTX *mem_ctx, struct nmb_name *name, + const struct sockaddr_storage *addr, + struct node_status **pnode_status, + int *pnum_names, struct node_status_extra *extra); bool name_status_find(const char *q_name, int q_type, @@ -2712,17 +2718,20 @@ bool name_status_find(const char *q_name, const struct sockaddr_storage *to_ss, fstring name); int ip_service_compare(struct ip_service *ss1, struct ip_service *ss2); -NTSTATUS name_query(int fd, - const char *name, - int name_type, - bool bcast, - bool recurse, - const struct sockaddr_storage *to_ss, - TALLOC_CTX *mem_ctx, - struct sockaddr_storage **addrs, - int *count, - int *flags, - bool *timed_out); +struct tevent_req *name_query_send(TALLOC_CTX *mem_ctx, + struct tevent_context *ev, + const char *name, int name_type, + bool bcast, bool recurse, + const struct sockaddr_storage *addr); +NTSTATUS name_query_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx, + struct sockaddr_storage **addrs, int *num_addrs, + uint8_t *flags); +NTSTATUS name_query(const char *name, int name_type, + bool bcast, bool recurse, + const struct sockaddr_storage *to_ss, + TALLOC_CTX *mem_ctx, + struct sockaddr_storage **addrs, + int *num_addrs, uint8_t *flags); NTSTATUS name_resolve_bcast(const char *name, int name_type, struct ip_service **return_iplist, @@ -2772,6 +2781,7 @@ void put_name(char *dest, const char *name, int pad, unsigned int name_type); char *nmb_namestr(const struct nmb_name *n); struct packet_struct *copy_packet(struct packet_struct *packet); void free_packet(struct packet_struct *packet); +int packet_trn_id(struct packet_struct *p); struct packet_struct *parse_packet(char *buf,int length, enum packet_type packet_type, struct in_addr ip, @@ -2782,9 +2792,6 @@ bool nmb_name_equal(struct nmb_name *n1, struct nmb_name *n2); int build_packet(char *buf, size_t buflen, struct packet_struct *p); bool send_packet(struct packet_struct *p); struct packet_struct *receive_packet(int fd,enum packet_type type,int t); -struct packet_struct *receive_nmb_packet(int fd, int t, int trn_id); -struct packet_struct *receive_dgram_packet(int fd, int t, - const char *mailslot_name); bool match_mailslot_name(struct packet_struct *p, const char *mailslot_name); int matching_len_bits(unsigned char *p1, unsigned char *p2, size_t len); void sort_query_replies(char *data, int n, struct in_addr ip); @@ -2926,12 +2933,27 @@ NTSTATUS change_trust_account_password( const char *domain, const char *remote_m /* The following definitions come from libsmb/unexpected.c */ -bool is_requested_send_packet(struct packet_struct *p); -bool store_outstanding_send_packet(struct packet_struct *p); -void unexpected_packet(struct packet_struct *p); -void clear_unexpected(time_t t); -struct packet_struct *receive_unexpected(enum packet_type packet_type, int id, +struct nb_packet_server; +struct nb_packet_reader; + +NTSTATUS nb_packet_server_create(TALLOC_CTX *mem_ctx, + struct tevent_context *ev, + 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, + enum packet_type type, + int trn_id, const char *mailslot_name); +NTSTATUS nb_packet_reader_recv(struct tevent_req *req, TALLOC_CTX *mem_ctx, + struct nb_packet_reader **preader); +struct tevent_req *nb_packet_read_send(TALLOC_CTX *mem_ctx, + struct tevent_context *ev, + struct nb_packet_reader *reader); +NTSTATUS nb_packet_read_recv(struct tevent_req *req, + struct packet_struct **ppacket); /* The following definitions come from locking/brlock.c */ diff --git a/source3/libsmb/clidgram.c b/source3/libsmb/clidgram.c index c9592a1..d46aadc 100644 --- a/source3/libsmb/clidgram.c +++ b/source3/libsmb/clidgram.c @@ -117,13 +117,12 @@ static bool prep_getdc_request(const struct sockaddr_storage *dc_ss, const char *domain_name, const struct dom_sid *sid, uint32_t nt_version, + const char *my_mailslot, int dgm_id, struct packet_struct *p) { TALLOC_CTX *frame = talloc_stackframe(); - struct in_addr dc_ip; const char *my_acct_name; - const char *my_mailslot; struct nbt_netlogon_packet packet; struct NETLOGON_SAM_LOGON_REQUEST *s; enum ndr_err_code ndr_err; @@ -131,10 +130,6 @@ static bool prep_getdc_request(const struct sockaddr_storage *dc_ss, struct dom_sid my_sid; bool ret = false; - if (dc_ss->ss_family != AF_INET) { - goto fail; - } - ZERO_STRUCT(packet); ZERO_STRUCT(my_sid); @@ -142,13 +137,6 @@ static bool prep_getdc_request(const struct sockaddr_storage *dc_ss, my_sid = *sid; } - dc_ip = ((struct sockaddr_in *)dc_ss)->sin_addr; - - my_mailslot = mailslot_name(talloc_tos(), dc_ip); - if (my_mailslot == NULL) { - goto fail; - } - my_acct_name = talloc_asprintf(talloc_tos(), "%s$", global_myname()); if (my_acct_name == NULL) { goto fail; @@ -186,45 +174,16 @@ fail: return ret; } -bool send_getdc_request(struct messaging_context *msg_ctx, - const struct sockaddr_storage *dc_ss, - const char *domain_name, - const struct dom_sid *sid, - uint32_t nt_version, - int dgm_id) -{ - struct packet_struct p; - pid_t nmbd_pid; - - if ((nmbd_pid = pidfile_pid("nmbd")) == 0) { - DEBUG(3, ("No nmbd found\n")); - return False; - } - - if (!prep_getdc_request(dc_ss, domain_name, sid, nt_version, - dgm_id, &p)) { - return false; - } - - return NT_STATUS_IS_OK(messaging_send_buf(msg_ctx, - pid_to_procid(nmbd_pid), - MSG_SEND_PACKET, - (uint8 *)&p, sizeof(p))); -} - -bool receive_getdc_response(TALLOC_CTX *mem_ctx, - const struct sockaddr_storage *dc_ss, - const char *domain_name, - int dgm_id, - uint32_t *nt_version, - const char **dc_name, - struct netlogon_samlogon_response **samlogon_response) +static bool parse_getdc_response( + struct packet_struct *packet, + TALLOC_CTX *mem_ctx, + const char *domain_name, + uint32_t *nt_version, + const char **dc_name, + struct netlogon_samlogon_response **samlogon_response) { - struct packet_struct *packet = NULL; - char *my_mailslot = NULL; - struct in_addr dc_ip; DATA_BLOB blob; - struct netlogon_samlogon_response *r = NULL; + struct netlogon_samlogon_response *r; union dgram_message_body p; enum ndr_err_code ndr_err; NTSTATUS status; @@ -232,37 +191,16 @@ bool receive_getdc_response(TALLOC_CTX *mem_ctx, const char *returned_dc = NULL; const char *returned_domain = NULL; - if (dc_ss->ss_family != AF_INET) { - return false; - } - - dc_ip = ((struct sockaddr_in *)dc_ss)->sin_addr; - - my_mailslot = mailslot_name(mem_ctx, dc_ip); - if (!my_mailslot) { - return false; - } - - packet = receive_unexpected(DGRAM_PACKET, dgm_id, my_mailslot); - - if (packet == NULL) { - DEBUG(5, ("Did not receive packet for %s\n", my_mailslot)); - return False; - } - - DEBUG(5, ("Received packet for %s\n", my_mailslot)); - blob = data_blob_const(packet->packet.dgram.data, packet->packet.dgram.datasize); - if (blob.length < 4) { - DEBUG(0,("invalid length: %d\n", (int)blob.length)); - goto fail; + DEBUG(1, ("invalid length: %d\n", (int)blob.length)); + return false; } if (RIVAL(blob.data,0) != DGRAM_SMB) { - DEBUG(0,("invalid packet\n")); - goto fail; + DEBUG(1, ("invalid packet\n")); + return false; } blob.data += 4; @@ -271,13 +209,13 @@ bool receive_getdc_response(TALLOC_CTX *mem_ctx, ndr_err = ndr_pull_union_blob_all(&blob, mem_ctx, &p, DGRAM_SMB, (ndr_pull_flags_fn_t)ndr_pull_dgram_smb_packet); if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) { - DEBUG(0,("failed to parse packet\n")); - goto fail; + DEBUG(1, ("failed to parse packet\n")); + return false; } if (p.smb.smb_command != SMB_TRANSACTION) { - DEBUG(0,("invalid smb_command: %d\n", p.smb.smb_command)); - goto fail; + DEBUG(1, ("invalid smb_command: %d\n", p.smb.smb_command)); + return false; } if (DEBUGLEVEL >= 10) { @@ -288,12 +226,13 @@ bool receive_getdc_response(TALLOC_CTX *mem_ctx, r = TALLOC_ZERO_P(mem_ctx, struct netlogon_samlogon_response); if (!r) { - goto fail; + return false; } - status = pull_netlogon_samlogon_response(&blob, mem_ctx, r); + status = pull_netlogon_samlogon_response(&blob, r, r); if (!NT_STATUS_IS_OK(status)) { - goto fail; + TALLOC_FREE(r); + return false; } map_netlogon_samlogon_response(r); @@ -307,17 +246,19 @@ bool receive_getdc_response(TALLOC_CTX *mem_ctx, if (!strequal(returned_domain, domain_name)) { DEBUG(3, ("GetDC: Expected domain %s, got %s\n", domain_name, returned_domain)); - goto fail; + TALLOC_FREE(r); + return false; } + if (*returned_dc == '\\') returned_dc += 1; + if (*returned_dc == '\\') returned_dc += 1; + *dc_name = talloc_strdup(mem_ctx, returned_dc); if (!*dc_name) { - goto fail; + TALLOC_FREE(r); + return false; } - if (**dc_name == '\\') *dc_name += 1; - if (**dc_name == '\\') *dc_name += 1; - if (samlogon_response) { *samlogon_response = r; } else { @@ -327,15 +268,200 @@ bool receive_getdc_response(TALLOC_CTX *mem_ctx, DEBUG(10, ("GetDC gave name %s for domain %s\n", *dc_name, returned_domain)); - free_packet(packet); - TALLOC_FREE(my_mailslot); return True; +} -fail: - TALLOC_FREE(my_mailslot); - TALLOC_FREE(r); - if (packet != NULL) { - free_packet(packet); +struct nbt_getdc_state { + struct tevent_context *ev; + struct messaging_context *msg_ctx; + struct nb_packet_reader *reader; + const char *my_mailslot; + pid_t nmbd_pid; + + const struct sockaddr_storage *dc_addr; + const char *domain_name; + const struct dom_sid *sid; + uint32_t nt_version; + const char *dc_name; + struct netlogon_samlogon_response *samlogon_response; + + struct packet_struct p; +}; + +static void nbt_getdc_got_reader(struct tevent_req *subreq); +static void nbt_getdc_got_response(struct tevent_req *subreq); + +struct tevent_req *nbt_getdc_send(TALLOC_CTX *mem_ctx, + struct tevent_context *ev, + struct messaging_context *msg_ctx, + const struct sockaddr_storage *dc_addr, + const char *domain_name, + const struct dom_sid *sid, + uint32_t nt_version) +{ + struct tevent_req *req, *subreq; + struct nbt_getdc_state *state; + uint16_t dgm_id; + + req = tevent_req_create(mem_ctx, &state, struct nbt_getdc_state); + if (req == NULL) { + return NULL; + } + state->ev = ev; + state->msg_ctx = msg_ctx; + state->dc_addr = dc_addr; + state->domain_name = domain_name; + state->sid = sid; + state->nt_version = nt_version; + + if (dc_addr->ss_family != AF_INET) { + tevent_req_nterror(req, NT_STATUS_NOT_SUPPORTED); + return tevent_req_post(req, ev); + } + state->my_mailslot = mailslot_name( + state, ((struct sockaddr_in *)dc_addr)->sin_addr); + if (tevent_req_nomem(state->my_mailslot, req)) { + return tevent_req_post(req, ev); + } + state->nmbd_pid = pidfile_pid("nmbd"); + if (state->nmbd_pid == 0) { + DEBUG(3, ("No nmbd found\n")); + tevent_req_nterror(req, NT_STATUS_NOT_SUPPORTED); + return tevent_req_post(req, ev); + } + + generate_random_buffer((uint8_t *)(void *)&dgm_id, sizeof(dgm_id)); + + if (!prep_getdc_request(dc_addr, domain_name, sid, nt_version, -- Samba Shared Repository