diff options
68 files changed, 1356 insertions, 854 deletions
diff --git a/source4/auth/auth.h b/source4/auth/auth.h index 9aa6d29c6e..80360a7cb4 100644 --- a/source4/auth/auth.h +++ b/source4/auth/auth.h @@ -50,7 +50,7 @@ enum auth_password_state { struct auth_usersupplied_info { const char *workstation_name; - const char *remote_host; + struct socket_address *remote_host; uint32_t logon_parameters; diff --git a/source4/auth/gensec/gensec.c b/source4/auth/gensec/gensec.c index 65bc5d2450..fa5c877363 100644 --- a/source4/auth/gensec/gensec.c +++ b/source4/auth/gensec/gensec.c @@ -864,39 +864,34 @@ const char *gensec_get_target_hostname(struct gensec_security *gensec_security) } /** - * Set local and peer socket addresses onto a socket context on the GENSEC context + * Set (and talloc_reference) local and peer socket addresses onto a socket context on the GENSEC context * * This is so that kerberos can include these addresses in * cryptographic tokens, to avoid certain attacks. */ -NTSTATUS gensec_set_my_addr(struct gensec_security *gensec_security, const char *my_addr, int port) +NTSTATUS gensec_set_my_addr(struct gensec_security *gensec_security, struct socket_address *my_addr) { - gensec_security->my_addr.addr = talloc_strdup(gensec_security, my_addr); - if (my_addr && !gensec_security->my_addr.addr) { + gensec_security->my_addr = my_addr; + if (my_addr && !talloc_reference(gensec_security, my_addr)) { return NT_STATUS_NO_MEMORY; } - gensec_security->my_addr.port = port; return NT_STATUS_OK; } -NTSTATUS gensec_set_peer_addr(struct gensec_security *gensec_security, const char *peer_addr, int port) +NTSTATUS gensec_set_peer_addr(struct gensec_security *gensec_security, struct socket_address *peer_addr) { - gensec_security->peer_addr.addr = talloc_strdup(gensec_security, peer_addr); - if (peer_addr && !gensec_security->peer_addr.addr) { + gensec_security->peer_addr = peer_addr; + if (peer_addr && !talloc_reference(gensec_security, peer_addr)) { return NT_STATUS_NO_MEMORY; } - gensec_security->peer_addr.port = port; return NT_STATUS_OK; } -const char *gensec_get_my_addr(struct gensec_security *gensec_security, int *port) +struct socket_address *gensec_get_my_addr(struct gensec_security *gensec_security) { - if (gensec_security->my_addr.addr) { - if (port) { - *port = gensec_security->my_addr.port; - } - return gensec_security->my_addr.addr; + if (gensec_security->my_addr) { + return gensec_security->my_addr; } /* We could add a 'set sockaddr' call, and do a lookup. This @@ -904,13 +899,10 @@ const char *gensec_get_my_addr(struct gensec_security *gensec_security, int *por return NULL; } -const char *gensec_get_peer_addr(struct gensec_security *gensec_security, int *port) +struct socket_address *gensec_get_peer_addr(struct gensec_security *gensec_security) { - if (gensec_security->peer_addr.addr) { - if (port) { - *port = gensec_security->peer_addr.port; - } - return gensec_security->peer_addr.addr; + if (gensec_security->peer_addr) { + return gensec_security->peer_addr; } /* We could add a 'set sockaddr' call, and do a lookup. This diff --git a/source4/auth/gensec/gensec.h b/source4/auth/gensec/gensec.h index 67bec3a0f5..6821d7f2db 100644 --- a/source4/auth/gensec/gensec.h +++ b/source4/auth/gensec/gensec.h @@ -34,11 +34,6 @@ struct gensec_target { const char *service; }; -struct gensec_addr { - const char *addr; - int port; -}; - #define GENSEC_FEATURE_SESSION_KEY 0x00000001 #define GENSEC_FEATURE_SIGN 0x00000002 #define GENSEC_FEATURE_SEAL 0x00000004 @@ -118,7 +113,7 @@ struct gensec_security { BOOL subcontext; uint32_t want_features; struct event_context *event_ctx; - struct gensec_addr my_addr, peer_addr; + struct socket_address *my_addr, *peer_addr; }; /* this structure is used by backends to determine the size of some critical types */ diff --git a/source4/auth/gensec/gensec_krb5.c b/source4/auth/gensec/gensec_krb5.c index 478ebcfbf0..98f7e726cc 100644 --- a/source4/auth/gensec/gensec_krb5.c +++ b/source4/auth/gensec/gensec_krb5.c @@ -87,8 +87,7 @@ static NTSTATUS gensec_krb5_start(struct gensec_security *gensec_security) krb5_error_code ret; struct gensec_krb5_state *gensec_krb5_state; struct cli_credentials *creds; - const char *my_addr, *peer_addr; - int my_port, peer_port; + const struct socket_address *my_addr, *peer_addr; krb5_address my_krb5_addr, peer_krb5_addr; creds = gensec_get_credentials(gensec_security); @@ -138,23 +137,10 @@ static NTSTATUS gensec_krb5_start(struct gensec_security *gensec_security) return NT_STATUS_INTERNAL_ERROR; } - my_addr = gensec_get_my_addr(gensec_security, &my_port); - if (my_addr) { - struct sockaddr_in sock_addr; - struct ipv4_addr addr; - - /* TODO: This really should be in a utility function somewhere */ - ZERO_STRUCT(sock_addr); -#ifdef HAVE_SOCK_SIN_LEN - sock_addr.sin_len = sizeof(sock_addr); -#endif - addr = interpret_addr2(my_addr); - sock_addr.sin_addr.s_addr = addr.addr; - sock_addr.sin_port = htons(my_port); - sock_addr.sin_family = PF_INET; - + my_addr = gensec_get_my_addr(gensec_security); + if (my_addr && my_addr->sockaddr) { ret = krb5_sockaddr2address(gensec_krb5_state->smb_krb5_context->krb5_context, - (struct sockaddr *)&sock_addr, &my_krb5_addr); + my_addr->sockaddr, &my_krb5_addr); if (ret) { DEBUG(1,("gensec_krb5_start: krb5_sockaddr2address (local) failed (%s)\n", smb_get_krb5_error_message(gensec_krb5_state->smb_krb5_context->krb5_context, @@ -164,23 +150,10 @@ static NTSTATUS gensec_krb5_start(struct gensec_security *gensec_security) } } - peer_addr = gensec_get_my_addr(gensec_security, &peer_port); - if (peer_addr) { - struct sockaddr_in sock_addr; - struct ipv4_addr addr; - - /* TODO: This really should be in a utility function somewhere */ - ZERO_STRUCT(sock_addr); -#ifdef HAVE_SOCK_SIN_LEN - sock_addr.sin_len = sizeof(sock_addr); -#endif - addr = interpret_addr2(peer_addr); - sock_addr.sin_addr.s_addr = addr.addr; - sock_addr.sin_port = htons(peer_port); - sock_addr.sin_family = PF_INET; - + peer_addr = gensec_get_my_addr(gensec_security); + if (peer_addr && peer_addr->sockaddr) { ret = krb5_sockaddr2address(gensec_krb5_state->smb_krb5_context->krb5_context, - (struct sockaddr *)&sock_addr, &peer_krb5_addr); + peer_addr->sockaddr, &peer_krb5_addr); if (ret) { DEBUG(1,("gensec_krb5_start: krb5_sockaddr2address (local) failed (%s)\n", smb_get_krb5_error_message(gensec_krb5_state->smb_krb5_context->krb5_context, diff --git a/source4/auth/kerberos/config.mk b/source4/auth/kerberos/config.mk index 93b45ddedc..ebd527c74b 100644 --- a/source4/auth/kerberos/config.mk +++ b/source4/auth/kerberos/config.mk @@ -8,6 +8,6 @@ OBJ_FILES = kerberos.o \ kerberos_pac.o \ gssapi_parse.o \ krb5_init_context.o -REQUIRED_SUBSYSTEMS = HEIMDAL_KRB5 NDR_KRB5PAC +REQUIRED_SUBSYSTEMS = HEIMDAL_KRB5 NDR_KRB5PAC SOCKET # End SUBSYSTEM KERBEROS ################################# diff --git a/source4/auth/kerberos/krb5_init_context.c b/source4/auth/kerberos/krb5_init_context.c index 895553ccee..fe6ff2f12a 100644 --- a/source4/auth/kerberos/krb5_init_context.c +++ b/source4/auth/kerberos/krb5_init_context.c @@ -235,11 +235,10 @@ static krb5_error_code smb_krb5_send_and_recv_func(krb5_context context, { krb5_error_code ret; NTSTATUS status; - char *remote_addr; + struct socket_address *remote_addr; const char *name; struct addrinfo *ai, *a; struct smb_krb5_socket *smb_krb5; - int port; struct event_context *ev = talloc_get_type(data, struct event_context); @@ -292,31 +291,13 @@ static krb5_error_code smb_krb5_send_and_recv_func(krb5_context context, talloc_steal(smb_krb5, smb_krb5->sock); - switch (a->ai_family) { - case PF_INET: - remote_addr = talloc_strdup(smb_krb5, inet_ntoa(((struct sockaddr_in *)a->ai_addr)->sin_addr)); - port = ntohs(((struct sockaddr_in *)a->ai_addr)->sin_port); - break; - case PF_INET6: - { - char addr[128]; - const char *ret_addr; - ret_addr = inet_ntop(AF_INET6, &((struct sockaddr_in6 *)a->ai_addr)->sin6_addr, addr, sizeof(addr)); - if (ret_addr == NULL) { - talloc_free(smb_krb5); - return EINVAL; - } - - remote_addr = talloc_strdup(smb_krb5, ret_addr); - port = ntohs(((struct sockaddr_in6 *)a->ai_addr)->sin6_port); - break; - } - default: + remote_addr = socket_address_from_sockaddr(smb_krb5, a->ai_addr, a->ai_addrlen); + if (!remote_addr) { talloc_free(smb_krb5); - return EINVAL; + continue; } - - status = socket_connect_ev(smb_krb5->sock, NULL, 0, remote_addr, port, 0, ev); + + status = socket_connect_ev(smb_krb5->sock, NULL, remote_addr, 0, ev); if (!NT_STATUS_IS_OK(status)) { talloc_free(smb_krb5); continue; diff --git a/source4/auth/ntlmssp/ntlmssp_server.c b/source4/auth/ntlmssp/ntlmssp_server.c index ec3c9ba188..dac1f48f4b 100644 --- a/source4/auth/ntlmssp/ntlmssp_server.c +++ b/source4/auth/ntlmssp/ntlmssp_server.c @@ -695,7 +695,8 @@ static NTSTATUS auth_ntlmssp_check_password(struct gensec_ntlmssp_state *gensec_ user_info->client.account_name = gensec_ntlmssp_state->user; user_info->client.domain_name = gensec_ntlmssp_state->domain; user_info->workstation_name = gensec_ntlmssp_state->workstation; - + user_info->remote_host = gensec_get_peer_addr(gensec_ntlmssp_state->gensec_security); + user_info->password_state = AUTH_PASSWORD_RESPONSE; user_info->password.response.lanman = gensec_ntlmssp_state->lm_resp; user_info->password.response.lanman.data = talloc_steal(user_info, gensec_ntlmssp_state->lm_resp.data); diff --git a/source4/cldap_server/cldap_server.c b/source4/cldap_server/cldap_server.c index e112d7a33b..7270e01a4d 100644 --- a/source4/cldap_server/cldap_server.c +++ b/source4/cldap_server/cldap_server.c @@ -32,12 +32,12 @@ */ static void cldapd_request_handler(struct cldap_socket *cldap, struct ldap_message *ldap_msg, - const char *src_address, int src_port) + struct socket_address *src) { struct ldap_SearchRequest *search; if (ldap_msg->type != LDAP_TAG_SearchRequest) { DEBUG(0,("Invalid CLDAP request type %d from %s:%d\n", - ldap_msg->type, src_address, src_port)); + ldap_msg->type, src->addr, src->port)); return; } @@ -46,12 +46,12 @@ static void cldapd_request_handler(struct cldap_socket *cldap, if (search->num_attributes == 1 && strcasecmp(search->attributes[0], "netlogon") == 0) { cldapd_netlogon_request(cldap, ldap_msg->messageid, - search->tree, src_address, src_port); + search->tree, src); } else { DEBUG(0,("Unknown CLDAP search for '%s'\n", ldb_filter_from_tree(ldap_msg, ldap_msg->r.SearchRequest.tree))); - cldap_empty_reply(cldap, ldap_msg->messageid, src_address, src_port); + cldap_empty_reply(cldap, ldap_msg->messageid, src); } } @@ -62,13 +62,21 @@ static void cldapd_request_handler(struct cldap_socket *cldap, static NTSTATUS cldapd_add_socket(struct cldapd_server *cldapd, const char *address) { struct cldap_socket *cldapsock; + struct socket_address *socket_address; NTSTATUS status; /* listen for unicasts on the CLDAP port (389) */ cldapsock = cldap_socket_init(cldapd, cldapd->task->event_ctx); NT_STATUS_HAVE_NO_MEMORY(cldapsock); - status = socket_listen(cldapsock->sock, address, lp_cldap_port(), 0, 0); + socket_address = socket_address_from_strings(cldapsock, cldapsock->sock->backend_name, + address, lp_cldap_port()); + if (!socket_address) { + talloc_free(cldapsock); + return NT_STATUS_NO_MEMORY; + } + + status = socket_listen(cldapsock->sock, socket_address, 0, 0); if (!NT_STATUS_IS_OK(status)) { DEBUG(0,("Failed to bind to %s:%d - %s\n", address, lp_cldap_port(), nt_errstr(status))); @@ -76,6 +84,8 @@ static NTSTATUS cldapd_add_socket(struct cldapd_server *cldapd, const char *addr return status; } + talloc_free(socket_address); + cldap_set_incoming_handler(cldapsock, cldapd_request_handler, cldapd); return NT_STATUS_OK; diff --git a/source4/cldap_server/netlogon.c b/source4/cldap_server/netlogon.c index e58907d69f..476b9dfed5 100644 --- a/source4/cldap_server/netlogon.c +++ b/source4/cldap_server/netlogon.c @@ -193,7 +193,7 @@ static NTSTATUS cldapd_netlogon_fill(struct cldapd_server *cldapd, void cldapd_netlogon_request(struct cldap_socket *cldap, uint32_t message_id, struct ldb_parse_tree *tree, - const char *src_address, int src_port) + struct socket_address *src) { struct cldapd_server *cldapd = talloc_get_type(cldap->incoming.private, struct cldapd_server); int i; @@ -266,13 +266,13 @@ void cldapd_netlogon_request(struct cldap_socket *cldap, domain, host, user, version, domain_guid)); status = cldapd_netlogon_fill(cldapd, tmp_ctx, domain, domain_guid, - user, src_address, + user, src->addr, version, &netlogon); if (!NT_STATUS_IS_OK(status)) { goto failed; } - status = cldap_netlogon_reply(cldap, message_id, src_address, src_port, version, + status = cldap_netlogon_reply(cldap, message_id, src, version, &netlogon); if (!NT_STATUS_IS_OK(status)) { goto failed; @@ -285,5 +285,5 @@ failed: DEBUG(2,("cldap netlogon query failed domain=%s host=%s version=%d - %s\n", domain, host, version, nt_errstr(status))); talloc_free(tmp_ctx); - cldap_empty_reply(cldap, message_id, src_address, src_port); + cldap_empty_reply(cldap, message_id, src); } diff --git a/source4/include/structs.h b/source4/include/structs.h index e68786ed78..60ec1eae67 100644 --- a/source4/include/structs.h +++ b/source4/include/structs.h @@ -144,6 +144,7 @@ struct ldb_map_objectclass; struct param_context; +struct socket_address; struct smbcli_request; struct smbcli_tree; diff --git a/source4/kdc/kdc.c b/source4/kdc/kdc.c index 6dcce3254d..12672bee53 100644 --- a/source4/kdc/kdc.c +++ b/source4/kdc/kdc.c @@ -36,8 +36,7 @@ /* hold all the info needed to send a reply */ struct kdc_reply { struct kdc_reply *next, *prev; - const char *dest_address; - int dest_port; + struct socket_address *dest; DATA_BLOB packet; }; @@ -45,8 +44,8 @@ typedef BOOL (*kdc_process_fn_t)(struct kdc_server *kdc, TALLOC_CTX *mem_ctx, DATA_BLOB *input, DATA_BLOB *reply, - const char *peer_address, int peer_port, - const char *my_address, int my_port); + struct socket_address *peer_addr, + struct socket_address *my_addr); /* hold information about one kdc socket */ struct kdc_socket { @@ -85,7 +84,7 @@ static void kdc_send_handler(struct kdc_socket *kdc_socket) size_t sendlen; status = socket_sendto(kdc_socket->sock, &rep->packet, &sendlen, 0, - rep->dest_address, rep->dest_port); + rep->dest); if (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) { break; } @@ -114,10 +113,8 @@ static void kdc_recv_handler(struct kdc_socket *kdc_socket) struct kdc_reply *rep; DATA_BLOB reply; size_t nread, dsize; - const char *src_addr; - int src_port; - const char *my_addr; - int my_port; + struct socket_address *src; + struct socket_address *my_addr; int ret; status = socket_pending(kdc_socket->sock, &dsize); @@ -134,23 +131,21 @@ static void kdc_recv_handler(struct kdc_socket *kdc_socket) } status = socket_recvfrom(kdc_socket->sock, blob.data, blob.length, &nread, 0, - &src_addr, &src_port); + tmp_ctx, &src); if (!NT_STATUS_IS_OK(status)) { talloc_free(tmp_ctx); return; } - talloc_steal(tmp_ctx, src_addr); blob.length = nread; DEBUG(10,("Received krb5 UDP packet of length %lu from %s:%u\n", - (long)blob.length, src_addr, (uint16_t)src_port)); + (long)blob.length, src->addr, (uint16_t)src->port)); my_addr = socket_get_my_addr(kdc_socket->sock, tmp_ctx); if (!my_addr) { talloc_free(tmp_ctx); return; } - my_port = socket_get_my_port(kdc_socket->sock); /* Call krb5 */ @@ -158,8 +153,7 @@ static void kdc_recv_handler(struct kdc_socket *kdc_socket) tmp_ctx, &blob, &reply, - src_addr, src_port, - my_addr, my_port); + src, my_addr); if (!ret) { talloc_free(tmp_ctx); return; @@ -171,8 +165,7 @@ static void kdc_recv_handler(struct kdc_socket *kdc_socket) talloc_free(tmp_ctx); return; } - rep->dest_address = talloc_steal(rep, src_addr); - rep->dest_port = src_port; + rep->dest = talloc_steal(rep, src); rep->packet = reply; talloc_steal(rep, reply.data); @@ -218,10 +211,8 @@ static NTSTATUS kdc_tcp_recv(void *private, DATA_BLOB blob) TALLOC_CTX *tmp_ctx = talloc_new(kdcconn); int ret; DATA_BLOB input, reply; - const char *src_addr; - int src_port; - const char *my_addr; - int my_port; + struct socket_address *src_addr; + struct socket_address *my_addr; talloc_steal(tmp_ctx, blob.data); @@ -230,14 +221,12 @@ static NTSTATUS kdc_tcp_recv(void *private, DATA_BLOB blob) talloc_free(tmp_ctx); return NT_STATUS_NO_MEMORY; } - src_port = socket_get_my_port(kdcconn->conn->socket); my_addr = socket_get_my_addr(kdcconn->conn->socket, tmp_ctx); if (!my_addr) { talloc_free(tmp_ctx); return NT_STATUS_NO_MEMORY; } - my_port = socket_get_my_port(kdcconn->conn->socket); /* Call krb5 */ input = data_blob_const(blob.data + 4, blob.length - 4); @@ -246,8 +235,8 @@ static NTSTATUS kdc_tcp_recv(void *private, DATA_BLOB blob) tmp_ctx, &input, &reply, - src_addr, src_port, - my_addr, my_port); + src_addr, + my_addr); if (!ret) { talloc_free(tmp_ctx); return NT_STATUS_INTERNAL_ERROR; @@ -312,35 +301,21 @@ static BOOL kdc_process(struct kdc_server *kdc, TALLOC_CTX *mem_ctx, DATA_BLOB *input, DATA_BLOB *reply, - const char *peer_addr, - int peer_port, - const char *my_addr, - int my_port) + struct socket_address *peer_addr, + struct socket_address *my_addr) { int ret; krb5_data k5_reply; - struct ipv4_addr addr; - struct sockaddr_in peer_sock_addr; - - /* TODO: This really should be in a utility function somewhere */ - ZERO_STRUCT(peer_sock_addr); -#ifdef HAVE_SOCK_SIN_LEN - peer_sock_addr.sin_len = sizeof(peer_sock_addr); -#endif - addr = interpret_addr2(peer_addr); - peer_sock_addr.sin_addr.s_addr = addr.addr; - peer_sock_addr.sin_port = htons(peer_port); - peer_sock_addr.sin_family = PF_INET; - - DEBUG(10,("Received KDC packet of length %lu from %s\n", - (long)input->length - 4, peer_addr)); + + DEBUG(10,("Received KDC packet of length %lu from %s:%d\n", + (long)input->length - 4, peer_addr->addr, peer_addr->port)); ret = krb5_kdc_process_krb5_request(kdc->smb_krb5_context->krb5_context, kdc->config, input->data, input->length, &k5_reply, - peer_addr, - (struct sockaddr *)&peer_sock_addr); + peer_addr->addr, + peer_addr->sockaddr); if (ret == -1) { *reply = data_blob(NULL, 0); return False; @@ -415,6 +390,7 @@ static NTSTATUS kdc_add_socket(struct kdc_server *kdc, const char *address) const struct model_ops *model_ops; struct kdc_socket *kdc_socket; struct kdc_socket *kpasswd_socket; + struct socket_address *kdc_address, *kpasswd_address; NTSTATUS status; uint16_t kdc_port = lp_krb5_port(); uint16_t kpasswd_port = lp_kpasswd_port(); @@ -447,7 +423,11 @@ static NTSTATUS kdc_add_socket(struct kdc_server *kdc, const char *address) socket_get_fd(kdc_socket->sock), EVENT_FD_READ, kdc_socket_handler, kdc_socket); - status = socket_listen(kdc_socket->sock, address, kdc_port, 0, 0); + kdc_address = socket_address_from_strings(kdc_socket, kdc_socket->sock->backend_name, + address, kdc_port); + NT_STATUS_HAVE_NO_MEMORY(kdc_address); + + status = socket_listen(kdc_socket->sock, kdc_address, 0, 0); if (!NT_STATUS_IS_OK(status)) { DEBUG(0,("Failed to bind to %s:%d UDP for kdc - %s\n", address, kdc_port, nt_errstr(status))); @@ -465,7 +445,11 @@ static NTSTATUS kdc_add_socket(struct kdc_server *kdc, const char *address) socket_get_fd(kpasswd_socket->sock), EVENT_FD_READ, kdc_socket_handler, kpasswd_socket); - status = socket_listen(kpasswd_socket->sock, address, kpasswd_port, 0, 0); + kpasswd_address = socket_address_from_strings(kpasswd_socket, kpasswd_socket->sock->backend_name, + address, kpasswd_port); + NT_STATUS_HAVE_NO_MEMORY(kpasswd_address); + + status = socket_listen(kpasswd_socket->sock, kpasswd_address, 0, 0); if (!NT_STATUS_IS_OK(status)) { DEBUG(0,("Failed to bind to %s:%d UDP for kpasswd - %s\n", address, kpasswd_port, nt_errstr(status))); diff --git a/source4/kdc/kdc.h b/source4/kdc/kdc.h index 9356879415..1038c7df95 100644 --- a/source4/kdc/kdc.h +++ b/source4/kdc/kdc.h @@ -35,10 +35,8 @@ BOOL kpasswdd_process(struct kdc_server *kdc, TALLOC_CTX *mem_ctx, DATA_BLOB *input, DATA_BLOB *reply, - const char *peer_addr, - int peer_port, - const char *my_addr, - int my_port); + struct socket_address *peer_addr, + struct socket_address *my_addr); /* top level context structure for the kdc server diff --git a/source4/kdc/kpasswdd.c b/source4/kdc/kpasswdd.c index 7ae9a9f961..05aced904d 100644 --- a/source4/kdc/kpasswdd.c +++ b/source4/kdc/kpasswdd.c @@ -398,10 +398,8 @@ BOOL kpasswdd_process(struct kdc_server *kdc, TALLOC_CTX *mem_ctx, DATA_BLOB *input, DATA_BLOB *reply, - const char *peer_addr, - int peer_port, - const char *my_addr, - int my_port) + struct socket_address *peer_addr, + struct socket_address *my_addr) { BOOL ret; const uint16_t header_len = 6; @@ -485,12 +483,12 @@ BOOL kpasswdd_process(struct kdc_server *kdc, /* The kerberos PRIV packets include these addresses. MIT * clients check that they are present */ - nt_status = gensec_set_peer_addr(gensec_security, peer_addr, peer_port); + nt_status = gensec_set_peer_addr(gensec_security, peer_addr); if (!NT_STATUS_IS_OK(nt_status)) { talloc_free(tmp_ctx); return False; } - nt_status = gensec_set_my_addr(gensec_security, my_addr, my_port); + nt_status = gensec_set_my_addr(gensec_security, my_addr); if (!NT_STATUS_IS_OK(nt_status)) { talloc_free(tmp_ctx); return False; diff --git a/source4/ldap_server/ldap_server.c b/source4/ldap_server/ldap_server.c index d573652143..28995f6eb2 100644 --- a/source4/ldap_server/ldap_server.c +++ b/source4/ldap_server/ldap_server.c @@ -268,6 +268,7 @@ static void ldapsrv_accept(struct stream_connection *c) talloc_get_type(c->private, struct ldapsrv_service); struct ldapsrv_connection *conn; struct cli_credentials *server_credentials; + struct socket_address *socket_address; NTSTATUS status; int port; @@ -301,7 +302,13 @@ static void ldapsrv_accept(struct stream_connection *c) c->private = conn; - port = socket_get_my_port(c->socket); + socket_address = socket_get_my_addr(c->socket, conn); + if (!socket_address) { + ldapsrv_terminate_connection(conn, "ldapsrv_accept: failed to obtain local socket address!"); + return; + } + port = socket_address->port; + talloc_free(socket_address); conn->tls = tls_init_server(ldapsrv_service->tls_params, c->socket, c->event.fde, NULL, port != 389); diff --git a/source4/lib/messaging/messaging.c b/source4/lib/messaging/messaging.c index aa2fe0b150..df15928235 100644 --- a/source4/lib/messaging/messaging.c +++ b/source4/lib/messaging/messaging.c @@ -147,10 +147,20 @@ static NTSTATUS try_send(struct messaging_rec *rec) size_t nsent; void *priv; NTSTATUS status; + struct socket_address *path; + + /* rec->path is the path of the *other* socket, where we want + * this to end up */ + path = socket_address_from_strings(msg, msg->sock->backend_name, + rec->path, 0); + if (!path) { + return NT_STATUS_NO_MEMORY; + } /* we send with privileges so messages work from any context */ priv = root_privileges(); - status = socket_sendto(msg->sock, &rec->packet, &nsent, 0, rec->path, 0); + status = socket_sendto(msg->sock, &rec->packet, &nsent, 0, path); + talloc_free(path); talloc_free(priv); return status; @@ -382,7 +392,8 @@ struct messaging_context *messaging_init(TALLOC_CTX *mem_ctx, uint32_t server_id { struct messaging_context *msg; NTSTATUS status; - char *path; + struct socket_address *path; + char *dir; msg = talloc(mem_ctx, struct messaging_context); if (msg == NULL) { @@ -394,9 +405,9 @@ struct messaging_context *messaging_init(TALLOC_CTX *mem_ctx, uint32_t server_id } /* create the messaging directory if needed */ - path = smbd_tmp_path(msg, "messaging"); - mkdir(path, 0700); - talloc_free(path); + dir = smbd_tmp_path(msg, "messaging"); + mkdir(dir, 0700); + talloc_free(dir); msg->base_path = smbd_tmp_path(msg, "messaging"); msg->path = messaging_path(msg, server_id); @@ -418,7 +429,14 @@ struct messaging_context *messaging_init(TALLOC_CTX *mem_ctx, uint32_t server_id deleted) on exit */ talloc_steal(msg, msg->sock); - status = socket_listen(msg->sock, msg->path, 0, 50, 0); + path = socket_address_from_strings(msg, msg->sock->backend_name, + msg->path, 0); + if (!path) { + talloc_free(msg); + return NULL; + } + + status = socket_listen(msg->sock, path, 50, 0); if (!NT_STATUS_IS_OK(status)) { DEBUG(0,("Unable to setup messaging listener for '%s':%s\n", msg->path, nt_errstr(status))); talloc_free(msg); diff --git a/source4/lib/socket/access.c b/source4/lib/socket/access.c index 1d0a90f1ee..8e57ca5aff 100644 --- a/source4/lib/socket/access.c +++ b/source4/lib/socket/access.c @@ -310,7 +310,8 @@ BOOL socket_check_access(struct socket_context *sock, const char **allow_list, const char **deny_list) { BOOL ret; - const char *name="", *addr; + const char *name=""; + struct socket_address *addr; TALLOC_CTX *mem_ctx; if ((!deny_list || *deny_list==0) && @@ -324,13 +325,18 @@ BOOL socket_check_access(struct socket_context *sock, } addr = socket_get_peer_addr(sock, mem_ctx); + if (!addr) { + DEBUG(0,("socket_check_access: Denied connection from unknown host: could not get peer address from kernel\n")); + talloc_free(mem_ctx); + return False; + } /* bypass gethostbyaddr() calls if the lists only contain IP addrs */ if (!only_ipaddrs_in_list(allow_list) || !only_ipaddrs_in_list(deny_list)) { name = socket_get_peer_name(sock, mem_ctx); if (!name) { - name = addr; + name = addr->addr; } } @@ -340,14 +346,14 @@ BOOL socket_check_access(struct socket_context *sock, return False; } - ret = allow_access(mem_ctx, deny_list, allow_list, name, addr); + ret = allow_access(mem_ctx, deny_list, allow_list, name, addr->addr); if (ret) { DEBUG(2,("socket_check_access: Allowed connection to '%s' from %s (%s)\n", - service_name, name, addr)); + service_name, name, addr->addr)); } else { DEBUG(0,("socket_check_access: Denied connection to '%s' from %s (%s)\n", - service_name, name, addr)); + service_name, name, addr->addr)); } talloc_free(mem_ctx); diff --git a/source4/lib/socket/connect.c b/source4/lib/socket/connect.c index dd3a6047a6..dc64198caa 100644 --- a/source4/lib/socket/connect.c +++ b/source4/lib/socket/connect.c @@ -30,10 +30,8 @@ struct connect_state { struct socket_context *sock; - const char *my_address; - int my_port; - const char *server_address; - int server_port; + const struct socket_address *my_address; + const struct socket_address *server_address; uint32_t flags; }; @@ -62,9 +60,7 @@ static void socket_send_connect(struct composite_context *result) result->status = socket_connect(state->sock, state->my_address, - state->my_port, state->server_address, - state->server_port, state->flags); if (NT_STATUS_IS_ERR(result->status) && !NT_STATUS_EQUAL(result->status, @@ -85,10 +81,8 @@ static void socket_send_connect(struct composite_context *result) send a socket connect, potentially doing some name resolution first */ struct composite_context *socket_connect_send(struct socket_context *sock, - const char *my_address, - int my_port, - const char *server_address, - int server_port, + struct socket_address *my_address, + struct socket_address *server_address, uint32_t flags, struct event_context *event_ctx) { @@ -101,33 +95,39 @@ struct composite_context *socket_connect_send(struct socket_context *sock, result->event_ctx = event_ctx; state = talloc_zero(result, struct connect_state); - if (composite_nomem(state, result)) goto failed; + if (composite_nomem(state, result)) return result; result->private_data = state; state->sock = talloc_reference(state, sock); - if (composite_nomem(state->sock, result)) goto failed; + if (composite_nomem(state->sock, result)) return result; if (my_address) { - state->my_address = talloc_strdup(state, my_address); - if (composite_nomem(state->my_address, result)) goto failed; + void *ref = talloc_reference(state, my_address); + if (composite_nomem(ref, result)) { + return result; + } + state->my_address = my_address; } - state->my_port = my_port; - state->server_address = talloc_strdup(state, server_address); - if (composite_nomem(state->server_address, result)) goto failed; + { + void *ref = talloc_reference(state, server_address); + if (composite_nomem(ref, result)) { + return result; + } + state->server_address = server_address; + } - state->server_port = server_port; state->flags = flags; set_blocking(socket_get_fd(sock), False); - if (strcmp(sock->backend_name, "ipv4") == 0) { + if (server_address->addr && strcmp(sock->backend_name, "ipv4") == 0) { struct nbt_name name; struct composite_context *creq; - make_nbt_name_client(&name, server_address); + make_nbt_name_client(&name, server_address->addr); creq = resolve_name_send(&name, result->event_ctx, lp_name_resolve_order()); - if (composite_nomem(creq, result)) goto failed; + if (composite_nomem(creq, result)) return result; composite_continue(result, creq, continue_resolve_name, result); return result; } @@ -135,10 +135,6 @@ struct composite_context *socket_connect_send(struct socket_context *sock, socket_send_connect(result); return result; - -failed: - composite_error(result, result->status); - return result; } /* @@ -172,7 +168,9 @@ static void continue_resolve_name(struct composite_context *creq) result->status = resolve_name_recv(creq, state, &addr); if (!composite_is_ok(result)) return; - state->server_address = addr; + state->server_address = socket_address_from_strings(state, state->sock->backend_name, + addr, state->server_address->port); + if (composite_nomem(state->server_address, result)) return; socket_send_connect(result); } @@ -205,12 +203,12 @@ NTSTATUS socket_connect_recv(struct composite_context *result) like socket_connect() but takes an event context, doing a semi-async connect */ NTSTATUS socket_connect_ev(struct socket_context *sock, - const char *my_address, int my_port, - const char *server_address, int server_port, + struct socket_address *my_address, + struct socket_address *server_address, uint32_t flags, struct event_context *ev) { struct composite_context *ctx; - ctx = socket_connect_send(sock, my_address, my_port, - server_address, server_port, flags, ev); + ctx = socket_connect_send(sock, my_address, + server_address, flags, ev); return socket_connect_recv(ctx); } diff --git a/source4/lib/socket/connect_multi.c b/source4/lib/socket/connect_multi.c index 6a90ef9a05..7396435075 100644 --- a/source4/lib/socket/connect_multi.c +++ b/source4/lib/socket/connect_multi.c @@ -49,7 +49,7 @@ struct connect_multi_state { struct connect_one_state { struct composite_context *result; struct socket_context *sock; - uint16_t port; + struct socket_address *addr; }; static void continue_resolve_name(struct composite_context *creq); @@ -144,15 +144,18 @@ static void connect_multi_next_socket(struct composite_context *result) if (composite_nomem(state, result)) return; state->result = result; - state->port = multi->ports[next]; - result->status = socket_create("ipv4", SOCKET_TYPE_STREAM, &state->sock, 0); if (!composite_is_ok(result)) return; + /* Form up the particular address we are interested in */ + state->addr = socket_address_from_strings(state, state->sock->backend_name, + multi->server_address, multi->ports[next]); + if (composite_nomem(state->addr, result)) return; + talloc_steal(state, state->sock); - creq = socket_connect_send(state->sock, NULL, 0, - multi->server_address, state->port, 0, result->event_ctx); + creq = socket_connect_send(state->sock, NULL, + state->addr, 0, result->event_ctx); if (composite_nomem(creq, result)) return; talloc_steal(state, creq); @@ -220,7 +223,7 @@ static void continue_one(struct composite_context *creq) if (NT_STATUS_IS_OK(status)) { multi->sock = talloc_steal(multi, state->sock); - multi->result_port = state->port; + multi->result_port = state->addr->port; } talloc_free(state); diff --git a/source4/lib/socket/socket.c b/source4/lib/socket/socket.c index 380071f46d..23117f2fa9 100644 --- a/source4/lib/socket/socket.c +++ b/source4/lib/socket/socket.c @@ -95,8 +95,8 @@ NTSTATUS socket_create(const char *name, enum socket_type type, } NTSTATUS socket_connect(struct socket_context *sock, - const char *my_address, int my_port, - const char *server_address, int server_port, + const struct socket_address *my_address, + const struct socket_address *server_address, uint32_t flags) { if (sock == NULL) { @@ -110,7 +110,7 @@ NTSTATUS socket_connect(struct socket_context *sock, return NT_STATUS_NOT_IMPLEMENTED; } - return sock->ops->fn_connect(sock, my_address, my_port, server_address, server_port, flags); + return sock->ops->fn_connect(sock, my_address, server_address, flags); } NTSTATUS socket_connect_complete(struct socket_context *sock, uint32_t flags) @@ -121,7 +121,9 @@ NTSTATUS socket_connect_complete(struct socket_context *sock, uint32_t flags) return sock->ops->fn_connect_complete(sock, flags); } -NTSTATUS socket_listen(struct socket_context *sock, const char *my_address, int port, int queue_size, uint32_t flags) +NTSTATUS socket_listen(struct socket_context *sock, + const struct socket_address *my_address, + int queue_size, uint32_t flags) { if (sock == NULL) { return NT_STATUS_CONNECTION_DISCONNECTED; @@ -134,7 +136,7 @@ NTSTATUS socket_listen(struct socket_context *sock, const char *my_address, int return NT_STATUS_NOT_IMPLEMENTED; } - return sock->ops->fn_listen(sock, my_address, port, queue_size, flags); + return sock->ops->fn_listen(sock, my_address, queue_size, flags); } NTSTATUS socket_accept(struct socket_context *sock, struct socket_context **new_sock) @@ -194,7 +196,7 @@ NTSTATUS socket_recv(struct socket_context *sock, void *buf, NTSTATUS socket_recvfrom(struct socket_context *sock, void *buf, size_t wantlen, size_t *nread, uint32_t flags, - const char **src_addr, int *src_port) + TALLOC_CTX *mem_ctx, struct socket_address **src_addr) { if (sock == NULL) { return NT_STATUS_CONNECTION_DISCONNECTED; @@ -208,7 +210,7 @@ NTSTATUS socket_recvfrom(struct socket_context *sock, void *buf, } return sock->ops->fn_recvfrom(sock, buf, wantlen, nread, flags, - src_addr, src_port); + mem_ctx, src_addr); } NTSTATUS socket_send(struct socket_context *sock, @@ -242,7 +244,7 @@ NTSTATUS socket_send(struct socket_context *sock, NTSTATUS socket_sendto(struct socket_context *sock, const DATA_BLOB *blob, size_t *sendlen, uint32_t flags, - const char *dest_addr, int dest_port) + const struct socket_address *dest_addr) { if (sock == NULL) { return NT_STATUS_CONNECTION_DISCONNECTED; @@ -260,7 +262,7 @@ NTSTATUS socket_sendto(struct socket_context *sock, return NT_STATUS_NOT_IMPLEMENTED; } - return sock->ops->fn_sendto(sock, blob, sendlen, flags, dest_addr, dest_port); + return sock->ops->fn_sendto(sock, blob, sendlen, flags, dest_addr); } @@ -300,7 +302,7 @@ char *socket_get_peer_name(struct socket_context *sock, TALLOC_CTX *mem_ctx) return sock->ops->fn_get_peer_name(sock, mem_ctx); } -char *socket_get_peer_addr(struct socket_context *sock, TALLOC_CTX *mem_ctx) +struct socket_address *socket_get_peer_addr(struct socket_context *sock, TALLOC_CTX *mem_ctx) { if (!sock->ops->fn_get_peer_addr) { return NULL; @@ -309,16 +311,7 @@ char *socket_get_peer_addr(struct socket_context *sock, TALLOC_CTX *mem_ctx) return sock->ops->fn_get_peer_addr(sock, mem_ctx); } -int socket_get_peer_port(struct socket_context *sock) -{ - if (!sock->ops->fn_get_peer_port) { - return -1; - } - - return sock->ops->fn_get_peer_port(sock); -} - -char *socket_get_my_addr(struct socket_context *sock, TALLOC_CTX *mem_ctx) +struct socket_address *socket_get_my_addr(struct socket_context *sock, TALLOC_CTX *mem_ctx) { if (!sock->ops->fn_get_my_addr) { return NULL; @@ -327,15 +320,6 @@ char *socket_get_my_addr(struct socket_context *sock, TALLOC_CTX *mem_ctx) return sock->ops->fn_get_my_addr(sock, mem_ctx); } -int socket_get_my_port(struct socket_context *sock) -{ - if (!sock->ops->fn_get_my_port) { - return -1; - } - - return sock->ops->fn_get_my_port(sock); -} - int socket_get_fd(struct socket_context *sock) { if (!sock->ops->fn_get_fd) { @@ -367,19 +351,70 @@ NTSTATUS socket_dup(struct socket_context *sock) } -const struct socket_ops *socket_getops_byname(const char *name, enum socket_type type) +/* Create a new socket_address. The type must match the socket type. + * The host parameter may be an IP or a hostname + */ + +struct socket_address *socket_address_from_strings(TALLOC_CTX *mem_ctx, + const char *family, + const char *host, + int port) +{ + struct socket_address *addr = talloc(mem_ctx, struct socket_address); + if (!addr) { + return NULL; + } + + addr->family = family; + addr->addr = talloc_strdup(addr, host); + if (!addr->addr) { + talloc_free(addr); + return NULL; + } + addr->port = port; + addr->sockaddr = NULL; + addr->sockaddrlen = 0; + + return addr; +} + +/* Create a new socket_address. Copy the struct sockaddr into the new + * structure. Used for hooks in the kerberos libraries, where they + * supply only a struct sockaddr */ + +struct socket_address *socket_address_from_sockaddr(TALLOC_CTX *mem_ctx, + struct sockaddr *sockaddr, + size_t sockaddrlen) +{ + struct socket_address *addr = talloc(mem_ctx, struct socket_address); + if (!addr) { + return NULL; + } + addr->family = NULL; + addr->addr = NULL; + addr->port = 0; + addr->sockaddr = talloc_memdup(addr, sockaddr, sockaddrlen); + if (!addr->sockaddr) { + talloc_free(addr); + return NULL; + } + addr->sockaddrlen = sockaddrlen; + return addr; +} + +const struct socket_ops *socket_getops_byname(const char *family, enum socket_type type) { extern const struct socket_ops *socket_ipv4_ops(enum socket_type ); extern const struct socket_ops *socket_ipv6_ops(enum socket_type ); extern const struct socket_ops *socket_unixdom_ops(enum socket_type ); - if (strcmp("ip", name) == 0 || - strcmp("ipv4", name) == 0) { + if (strcmp("ip", family) == 0 || + strcmp("ipv4", family) == 0) { return socket_ipv4_ops(type); } #if HAVE_SOCKET_IPV6 - if (strcmp("ipv6", name) == 0) { + if (strcmp("ipv6", family) == 0) { if (lp_parm_bool(-1, "socket", "noipv6", False)) { DEBUG(3, ("IPv6 support was disabled in smb.conf")); return NULL; @@ -388,7 +423,7 @@ const struct socket_ops *socket_getops_byname(const char *name, enum socket_type } #endif - if (strcmp("unix", name) == 0) { + if (strcmp("unix", family) == 0) { return socket_unixdom_ops(type); } diff --git a/source4/lib/socket/socket.h b/source4/lib/socket/socket.h index 165fbb6377..f3e3ba8341 100644 --- a/source4/lib/socket/socket.h +++ b/source4/lib/socket/socket.h @@ -28,6 +28,14 @@ enum socket_type { SOCKET_TYPE_DGRAM }; +struct socket_address { + const char *family; + char *addr; + int port; + struct sockaddr *sockaddr; + size_t sockaddrlen; +}; + struct socket_ops { const char *name; @@ -35,9 +43,9 @@ struct socket_ops { /* client ops */ NTSTATUS (*fn_connect)(struct socket_context *sock, - const char *my_address, int my_port, - const char *server_address, int server_port, - uint32_t flags); + const struct socket_address *my_address, + const struct socket_address *server_address, + uint32_t flags); /* complete a non-blocking connect */ NTSTATUS (*fn_connect_complete)(struct socket_context *sock, @@ -45,8 +53,10 @@ struct socket_ops { /* server ops */ NTSTATUS (*fn_listen)(struct socket_context *sock, - const char *my_address, int port, int queue_size, uint32_t flags); - NTSTATUS (*fn_accept)(struct socket_context *sock, struct socket_context **new_sock); + const struct socket_address *my_address, + int queue_size, uint32_t flags); + NTSTATUS (*fn_accept)(struct socket_context *sock, + struct socket_context **new_sock); /* general ops */ NTSTATUS (*fn_recv)(struct socket_context *sock, void *buf, @@ -56,10 +66,10 @@ struct socket_ops { NTSTATUS (*fn_sendto)(struct socket_context *sock, const DATA_BLOB *blob, size_t *sendlen, uint32_t flags, - const char *dest_addr, int dest_port); + const struct socket_address *dest_addr); NTSTATUS (*fn_recvfrom)(struct socket_context *sock, void *buf, size_t wantlen, size_t *nread, uint32_t flags, - const char **src_addr, int *src_port); + TALLOC_CTX *addr_ctx, struct socket_address **src_addr); NTSTATUS (*fn_pending)(struct socket_context *sock, size_t *npending); void (*fn_close)(struct socket_context *sock); @@ -67,10 +77,8 @@ struct socket_ops { NTSTATUS (*fn_set_option)(struct socket_context *sock, const char *option, const char *val); char *(*fn_get_peer_name)(struct socket_context *sock, TALLOC_CTX *mem_ctx); - char *(*fn_get_peer_addr)(struct socket_context *sock, TALLOC_CTX *mem_ctx); - int (*fn_get_peer_port)(struct socket_context *sock); - char *(*fn_get_my_addr)(struct socket_context *sock, TALLOC_CTX *mem_ctx); - int (*fn_get_my_port)(struct socket_context *sock); + struct socket_address *(*fn_get_peer_addr)(struct socket_context *sock, TALLOC_CTX *mem_ctx); + struct socket_address *(*fn_get_my_addr)(struct socket_context *sock, TALLOC_CTX *mem_ctx); int (*fn_get_fd)(struct socket_context *sock); }; @@ -110,31 +118,38 @@ struct socket_context { NTSTATUS socket_create(const char *name, enum socket_type type, struct socket_context **new_sock, uint32_t flags); NTSTATUS socket_connect(struct socket_context *sock, - const char *my_address, int my_port, - const char *server_address, int server_port, + const struct socket_address *my_address, + const struct socket_address *server_address, uint32_t flags); NTSTATUS socket_connect_complete(struct socket_context *sock, uint32_t flags); -NTSTATUS socket_listen(struct socket_context *sock, const char *my_address, int port, int queue_size, uint32_t flags); +NTSTATUS socket_listen(struct socket_context *sock, + const struct socket_address *my_address, + int queue_size, uint32_t flags); NTSTATUS socket_accept(struct socket_context *sock, struct socket_context **new_sock); NTSTATUS socket_recv(struct socket_context *sock, void *buf, size_t wantlen, size_t *nread, uint32_t flags); NTSTATUS socket_recvfrom(struct socket_context *sock, void *buf, size_t wantlen, size_t *nread, uint32_t flags, - const char **src_addr, int *src_port); + TALLOC_CTX *addr_ctx, struct socket_address **src_addr); NTSTATUS socket_send(struct socket_context *sock, const DATA_BLOB *blob, size_t *sendlen, uint32_t flags); NTSTATUS socket_sendto(struct socket_context *sock, const DATA_BLOB *blob, size_t *sendlen, uint32_t flags, - const char *dest_addr, int dest_port); + const struct socket_address *dest_addr); NTSTATUS socket_pending(struct socket_context *sock, size_t *npending); NTSTATUS socket_set_option(struct socket_context *sock, const char *option, const char *val); char *socket_get_peer_name(struct socket_context *sock, TALLOC_CTX *mem_ctx); -char *socket_get_peer_addr(struct socket_context *sock, TALLOC_CTX *mem_ctx); -int socket_get_peer_port(struct socket_context *sock); -char *socket_get_my_addr(struct socket_context *sock, TALLOC_CTX *mem_ctx); -int socket_get_my_port(struct socket_context *sock); +struct socket_address *socket_get_peer_addr(struct socket_context *sock, TALLOC_CTX *mem_ctx); +struct socket_address *socket_get_my_addr(struct socket_context *sock, TALLOC_CTX *mem_ctx); int socket_get_fd(struct socket_context *sock); NTSTATUS socket_dup(struct socket_context *sock); +struct socket_address *socket_address_from_strings(TALLOC_CTX *mem_ctx, + const char *type, + const char *host, + int port); +struct socket_address *socket_address_from_sockaddr(TALLOC_CTX *mem_ctx, + struct sockaddr *sockaddr, + size_t addrlen); const struct socket_ops *socket_getops_byname(const char *name, enum socket_type type); BOOL allow_access(TALLOC_CTX *mem_ctx, const char **deny_list, const char **allow_list, @@ -144,16 +159,14 @@ BOOL socket_check_access(struct socket_context *sock, const char **allow_list, const char **deny_list); struct composite_context *socket_connect_send(struct socket_context *sock, - const char *my_address, - int my_port, - const char *server_address, - int server_port, + struct socket_address *my_address, + struct socket_address *server_address, uint32_t flags, struct event_context *event_ctx); NTSTATUS socket_connect_recv(struct composite_context *ctx); NTSTATUS socket_connect_ev(struct socket_context *sock, - const char *my_address, int my_port, - const char *server_address, int server_port, + struct socket_address *my_address, + struct socket_address *server_address, uint32_t flags, struct event_context *ev); struct composite_context *socket_connect_multi_send(TALLOC_CTX *mem_ctx, diff --git a/source4/lib/socket/socket_ipv4.c b/source4/lib/socket/socket_ipv4.c index 34ae0b2b73..9e1f60d40a 100644 --- a/source4/lib/socket/socket_ipv4.c +++ b/source4/lib/socket/socket_ipv4.c @@ -85,49 +85,63 @@ static NTSTATUS ipv4_connect_complete(struct socket_context *sock, uint32_t flag static NTSTATUS ipv4_connect(struct socket_context *sock, - const char *my_address, int my_port, - const char *srv_address, int srv_port, - uint32_t flags) + const struct socket_address *my_address, + const struct socket_address *srv_address, + uint32_t flags) { struct sockaddr_in srv_addr; struct ipv4_addr my_ip; struct ipv4_addr srv_ip; int ret; - my_ip = interpret_addr2(my_address); - - if (my_ip.addr != 0 || my_port != 0) { - struct sockaddr_in my_addr; - ZERO_STRUCT(my_addr); -#ifdef HAVE_SOCK_SIN_LEN - my_addr.sin_len = sizeof(my_addr); -#endif - my_addr.sin_addr.s_addr = my_ip.addr; - my_addr.sin_port = htons(my_port); - my_addr.sin_family = PF_INET; - - ret = bind(sock->fd, (struct sockaddr *)&my_addr, sizeof(my_addr)); + if (my_address && my_address->sockaddr) { + ret = bind(sock->fd, my_address->sockaddr, my_address->sockaddrlen); if (ret == -1) { return map_nt_error_from_unix(errno); } + } else if (my_address) { + my_ip = interpret_addr2(my_address->addr); + + if (my_ip.addr != 0 || my_address->port != 0) { + struct sockaddr_in my_addr; + ZERO_STRUCT(my_addr); +#ifdef HAVE_SOCK_SIN_LEN + my_addr.sin_len = sizeof(my_addr); +#endif + my_addr.sin_addr.s_addr = my_ip.addr; + my_addr.sin_port = htons(my_address->port); + my_addr.sin_family = PF_INET; + + ret = bind(sock->fd, (struct sockaddr *)&my_addr, sizeof(my_addr)); + if (ret == -1) { + return map_nt_error_from_unix(errno); + } + } } - srv_ip = interpret_addr2(srv_address); - if (!srv_ip.addr) { - return NT_STATUS_BAD_NETWORK_NAME; - } - - ZERO_STRUCT(srv_addr); + if (srv_address->sockaddr) { + ret = connect(sock->fd, srv_address->sockaddr, srv_address->sockaddrlen); + if (ret == -1) { + return map_nt_error_from_unix(errno); + } + } else { + srv_ip = interpret_addr2(srv_address->addr); + if (!srv_ip.addr) { + return NT_STATUS_BAD_NETWORK_NAME; + } + + ZERO_STRUCT(srv_addr); #ifdef HAVE_SOCK_SIN_LEN - srv_addr.sin_len = sizeof(srv_addr); + srv_addr.sin_len = sizeof(srv_addr); #endif - srv_addr.sin_addr.s_addr= srv_ip.addr; - srv_addr.sin_port = htons(srv_port); - srv_addr.sin_family = PF_INET; + srv_addr.sin_addr.s_addr= srv_ip.addr; + srv_addr.sin_port = htons(srv_address->port); + srv_addr.sin_family = PF_INET; - ret = connect(sock->fd, (const struct sockaddr *)&srv_addr, sizeof(srv_addr)); - if (ret == -1) { - return map_nt_error_from_unix(errno); + ret = connect(sock->fd, (const struct sockaddr *)&srv_addr, sizeof(srv_addr)); + if (ret == -1) { + return map_nt_error_from_unix(errno); + } } return ipv4_connect_complete(sock, flags); @@ -139,7 +153,7 @@ static NTSTATUS ipv4_connect(struct socket_context *sock, use for DGRAM sockets, but in reality only a bind() is done */ static NTSTATUS ipv4_listen(struct socket_context *sock, - const char *my_address, int port, + const struct socket_address *my_address, int queue_size, uint32_t flags) { struct sockaddr_in my_addr; @@ -148,17 +162,22 @@ static NTSTATUS ipv4_listen(struct socket_context *sock, socket_set_option(sock, "SO_REUSEADDR=1", NULL); - ip_addr = interpret_addr2(my_address); - - ZERO_STRUCT(my_addr); + if (my_address->sockaddr) { + ret = bind(sock->fd, my_address->sockaddr, my_address->sockaddrlen); + } else { + ip_addr = interpret_addr2(my_address->addr); + + ZERO_STRUCT(my_addr); #ifdef HAVE_SOCK_SIN_LEN - my_addr.sin_len = sizeof(my_addr); + my_addr.sin_len = sizeof(my_addr); #endif - my_addr.sin_addr.s_addr = ip_addr.addr; - my_addr.sin_port = htons(port); - my_addr.sin_family = PF_INET; + my_addr.sin_addr.s_addr = ip_addr.addr; + my_addr.sin_port = htons(my_address->port); + my_addr.sin_family = PF_INET; + + ret = bind(sock->fd, (struct sockaddr *)&my_addr, sizeof(my_addr)); + } - ret = bind(sock->fd, (struct sockaddr *)&my_addr, sizeof(my_addr)); if (ret == -1) { return map_nt_error_from_unix(errno); } @@ -263,14 +282,29 @@ static NTSTATUS ipv4_recv(struct socket_context *sock, void *buf, static NTSTATUS ipv4_recvfrom(struct socket_context *sock, void *buf, size_t wantlen, size_t *nread, uint32_t flags, - const char **src_addr, int *src_port) + TALLOC_CTX *addr_ctx, struct socket_address **_src) { ssize_t gotlen; int flgs = 0; - struct sockaddr_in from_addr; - socklen_t from_len = sizeof(from_addr); + struct sockaddr_in *from_addr; + socklen_t from_len = sizeof(*from_addr); + struct socket_address *src; const char *addr; + + src = talloc(addr_ctx, struct socket_address); + if (!src) { + return NT_STATUS_NO_MEMORY; + } + + src->family = sock->backend_name; + from_addr = talloc(src, struct sockaddr_in); + if (!from_addr) { + talloc_free(src); + return NT_STATUS_NO_MEMORY; + } + + src->sockaddr = (struct sockaddr *)from_addr; if (flags & SOCKET_FLAG_PEEK) { flgs |= MSG_PEEK; } @@ -282,23 +316,31 @@ static NTSTATUS ipv4_recvfrom(struct socket_context *sock, void *buf, *nread = 0; gotlen = recvfrom(sock->fd, buf, wantlen, flgs, - (struct sockaddr *)&from_addr, &from_len); + src->sockaddr, &from_len); if (gotlen == 0) { + talloc_free(src); return NT_STATUS_END_OF_FILE; } else if (gotlen == -1) { + talloc_free(src); return map_nt_error_from_unix(errno); } - addr = inet_ntoa(from_addr.sin_addr); + src->sockaddrlen = from_len; + + addr = inet_ntoa(from_addr->sin_addr); if (addr == NULL) { + talloc_free(src); return NT_STATUS_INTERNAL_ERROR; } - *src_addr = talloc_strdup(sock, addr); - NT_STATUS_HAVE_NO_MEMORY(*src_addr); - *src_port = ntohs(from_addr.sin_port); - - *nread = gotlen; + src->addr = talloc_strdup(src, addr); + if (src->addr == NULL) { + talloc_free(src); + return NT_STATUS_NO_MEMORY; + } + src->port = ntohs(from_addr->sin_port); + *nread = gotlen; + *_src = src; return NT_STATUS_OK; } @@ -322,26 +364,32 @@ static NTSTATUS ipv4_send(struct socket_context *sock, static NTSTATUS ipv4_sendto(struct socket_context *sock, const DATA_BLOB *blob, size_t *sendlen, uint32_t flags, - const char *dest_addr, int dest_port) + const struct socket_address *dest_addr) { ssize_t len; int flgs = 0; - struct sockaddr_in srv_addr; - struct ipv4_addr addr; - ZERO_STRUCT(srv_addr); + if (dest_addr->sockaddr) { + len = sendto(sock->fd, blob->data, blob->length, flgs, + dest_addr->sockaddr, dest_addr->sockaddrlen); + } else { + struct sockaddr_in srv_addr; + struct ipv4_addr addr; + + ZERO_STRUCT(srv_addr); #ifdef HAVE_SOCK_SIN_LEN - srv_addr.sin_len = sizeof(srv_addr); + srv_addr.sin_len = sizeof(srv_addr); #endif - addr = interpret_addr2(dest_addr); - srv_addr.sin_addr.s_addr = addr.addr; - srv_addr.sin_port = htons(dest_port); - srv_addr.sin_family = PF_INET; - - *sendlen = 0; - - len = sendto(sock->fd, blob->data, blob->length, flgs, - (struct sockaddr *)&srv_addr, sizeof(srv_addr)); + addr = interpret_addr2(dest_addr->addr); + srv_addr.sin_addr.s_addr = addr.addr; + srv_addr.sin_port = htons(dest_addr->port); + srv_addr.sin_family = PF_INET; + + *sendlen = 0; + + len = sendto(sock->fd, blob->data, blob->length, flgs, + (struct sockaddr *)&srv_addr, sizeof(srv_addr)); + } if (len == -1) { return map_nt_error_from_unix(errno); } @@ -377,62 +425,95 @@ static char *ipv4_get_peer_name(struct socket_context *sock, TALLOC_CTX *mem_ctx return talloc_strdup(mem_ctx, he->h_name); } -static char *ipv4_get_peer_addr(struct socket_context *sock, TALLOC_CTX *mem_ctx) +static struct socket_address *ipv4_get_peer_addr(struct socket_context *sock, TALLOC_CTX *mem_ctx) { - struct sockaddr_in peer_addr; - socklen_t len = sizeof(peer_addr); + struct sockaddr_in *peer_addr; + socklen_t len = sizeof(*peer_addr); + const char *addr; + struct socket_address *peer; int ret; + + peer = talloc(mem_ctx, struct socket_address); + if (!peer) { + return NULL; + } + + peer->family = sock->backend_name; + peer_addr = talloc(peer, struct sockaddr_in); + if (!peer_addr) { + talloc_free(peer); + return NULL; + } - ret = getpeername(sock->fd, (struct sockaddr *)&peer_addr, &len); + peer->sockaddr = (struct sockaddr *)peer_addr; + + ret = getpeername(sock->fd, peer->sockaddr, &len); if (ret == -1) { + talloc_free(peer); return NULL; } - return talloc_strdup(mem_ctx, inet_ntoa(peer_addr.sin_addr)); -} + peer->sockaddrlen = len; -static int ipv4_get_peer_port(struct socket_context *sock) -{ - struct sockaddr_in peer_addr; - socklen_t len = sizeof(peer_addr); - int ret; - - ret = getpeername(sock->fd, (struct sockaddr *)&peer_addr, &len); - if (ret == -1) { - return -1; + addr = inet_ntoa(peer_addr->sin_addr); + if (addr == NULL) { + talloc_free(peer); + return NULL; + } + peer->addr = talloc_strdup(peer, addr); + if (!peer->addr) { + talloc_free(peer); + return NULL; } + peer->port = ntohs(peer_addr->sin_port); - return ntohs(peer_addr.sin_port); + return peer; } -static char *ipv4_get_my_addr(struct socket_context *sock, TALLOC_CTX *mem_ctx) +static struct socket_address *ipv4_get_my_addr(struct socket_context *sock, TALLOC_CTX *mem_ctx) { - struct sockaddr_in my_addr; - socklen_t len = sizeof(my_addr); + struct sockaddr_in *local_addr; + socklen_t len = sizeof(*local_addr); + const char *addr; + struct socket_address *local; int ret; + + local = talloc(mem_ctx, struct socket_address); + if (!local) { + return NULL; + } + + local->family = sock->backend_name; + local_addr = talloc(local, struct sockaddr_in); + if (!local_addr) { + talloc_free(local); + return NULL; + } - ret = getsockname(sock->fd, (struct sockaddr *)&my_addr, &len); + local->sockaddr = (struct sockaddr *)local_addr; + + ret = getsockname(sock->fd, local->sockaddr, &len); if (ret == -1) { + talloc_free(local); return NULL; } - return talloc_strdup(mem_ctx, inet_ntoa(my_addr.sin_addr)); -} - -static int ipv4_get_my_port(struct socket_context *sock) -{ - struct sockaddr_in my_addr; - socklen_t len = sizeof(my_addr); - int ret; + local->sockaddrlen = len; - ret = getsockname(sock->fd, (struct sockaddr *)&my_addr, &len); - if (ret == -1) { - return -1; + addr = inet_ntoa(local_addr->sin_addr); + if (addr == NULL) { + talloc_free(local); + return NULL; + } + local->addr = talloc_strdup(local, addr); + if (!local->addr) { + talloc_free(local); + return NULL; } + local->port = ntohs(local_addr->sin_port); - return ntohs(my_addr.sin_port); + return local; } - static int ipv4_get_fd(struct socket_context *sock) { return sock->fd; @@ -466,10 +547,7 @@ static const struct socket_ops ipv4_ops = { .fn_get_peer_name = ipv4_get_peer_name, .fn_get_peer_addr = ipv4_get_peer_addr, - .fn_get_peer_port = ipv4_get_peer_port, .fn_get_my_addr = ipv4_get_my_addr, - .fn_get_my_port = ipv4_get_my_port, - .fn_get_fd = ipv4_get_fd }; diff --git a/source4/lib/socket/socket_ipv6.c b/source4/lib/socket/socket_ipv6.c index bc47d4f554..90eb27b811 100644 --- a/source4/lib/socket/socket_ipv6.c +++ b/source4/lib/socket/socket_ipv6.c @@ -81,41 +81,52 @@ static NTSTATUS ipv6_tcp_connect_complete(struct socket_context *sock, uint32_t } static NTSTATUS ipv6_tcp_connect(struct socket_context *sock, - const char *my_address, int my_port, - const char *srv_address, int srv_port, + const struct socket_address *my_address, + const struct socket_address *srv_address, uint32_t flags) { - struct sockaddr_in6 srv_addr; - struct in6_addr my_ip; - struct in6_addr srv_ip; int ret; - my_ip = interpret_addr6(my_address); - - if (memcmp(&my_ip, &in6addr_any, sizeof(my_ip)) || my_port != 0) { - struct sockaddr_in6 my_addr; - ZERO_STRUCT(my_addr); - my_addr.sin6_addr = my_ip; - my_addr.sin6_port = htons(my_port); - my_addr.sin6_family = PF_INET6; - - ret = bind(sock->fd, (struct sockaddr *)&my_addr, sizeof(my_addr)); + if (my_address && my_address->sockaddr) { + ret = bind(sock->fd, my_address->sockaddr, my_address->sockaddrlen); if (ret == -1) { return map_nt_error_from_unix(errno); } + } else if (my_address) { + struct in6_addr my_ip; + my_ip = interpret_addr6(my_address->addr); + + if (memcmp(&my_ip, &in6addr_any, sizeof(my_ip)) || my_address->port != 0) { + struct sockaddr_in6 my_addr; + ZERO_STRUCT(my_addr); + my_addr.sin6_addr = my_ip; + my_addr.sin6_port = htons(my_address->port); + my_addr.sin6_family = PF_INET6; + + ret = bind(sock->fd, (struct sockaddr *)&my_addr, sizeof(my_addr)); + if (ret == -1) { + return map_nt_error_from_unix(errno); + } + } } - srv_ip = interpret_addr6(srv_address); - if (memcmp(&srv_ip, &in6addr_any, sizeof(srv_ip)) == 0) { - return NT_STATUS_BAD_NETWORK_NAME; + if (srv_address->sockaddr) { + ret = connect(sock->fd, srv_address->sockaddr, srv_address->sockaddrlen); + } else { + struct in6_addr srv_ip; + struct sockaddr_in6 srv_addr; + srv_ip = interpret_addr6(srv_address->addr); + if (memcmp(&srv_ip, &in6addr_any, sizeof(srv_ip)) == 0) { + return NT_STATUS_BAD_NETWORK_NAME; + } + + ZERO_STRUCT(srv_addr); + srv_addr.sin6_addr = srv_ip; + srv_addr.sin6_port = htons(srv_address->port); + srv_addr.sin6_family = PF_INET6; + + ret = connect(sock->fd, (const struct sockaddr *)&srv_addr, sizeof(srv_addr)); } - - ZERO_STRUCT(srv_addr); - srv_addr.sin6_addr = srv_ip; - srv_addr.sin6_port = htons(srv_port); - srv_addr.sin6_family = PF_INET6; - - ret = connect(sock->fd, (const struct sockaddr *)&srv_addr, sizeof(srv_addr)); if (ret == -1) { return map_nt_error_from_unix(errno); } @@ -124,8 +135,8 @@ static NTSTATUS ipv6_tcp_connect(struct socket_context *sock, } static NTSTATUS ipv6_tcp_listen(struct socket_context *sock, - const char *my_address, int port, - int queue_size, uint32_t flags) + const struct socket_address *my_address, + int queue_size, uint32_t flags) { struct sockaddr_in6 my_addr; struct in6_addr ip_addr; @@ -133,14 +144,19 @@ static NTSTATUS ipv6_tcp_listen(struct socket_context *sock, socket_set_option(sock, "SO_REUSEADDR=1", NULL); - ip_addr = interpret_addr6(my_address); - - ZERO_STRUCT(my_addr); - my_addr.sin6_addr = ip_addr; - my_addr.sin6_port = htons(port); - my_addr.sin6_family = PF_INET6; + if (my_address->sockaddr) { + ret = bind(sock->fd, my_address->sockaddr, my_address->sockaddrlen); + } else { + ip_addr = interpret_addr6(my_address->addr); + + ZERO_STRUCT(my_addr); + my_addr.sin6_addr = ip_addr; + my_addr.sin6_port = htons(my_address->port); + my_addr.sin6_family = PF_INET6; + + ret = bind(sock->fd, (struct sockaddr *)&my_addr, sizeof(my_addr)); + } - ret = bind(sock->fd, (struct sockaddr *)&my_addr, sizeof(my_addr)); if (ret == -1) { return map_nt_error_from_unix(errno); } @@ -280,73 +296,98 @@ static char *ipv6_tcp_get_peer_name(struct socket_context *sock, TALLOC_CTX *mem return talloc_strdup(mem_ctx, he->h_name); } -static char *ipv6_tcp_get_peer_addr(struct socket_context *sock, TALLOC_CTX *mem_ctx) +static struct socket_address *ipv6_tcp_get_peer_addr(struct socket_context *sock, TALLOC_CTX *mem_ctx) { - struct sockaddr_in6 peer_addr; - socklen_t len = sizeof(peer_addr); + struct sockaddr_in6 *peer_addr; + socklen_t len = sizeof(*peer_addr); + struct socket_address *peer; int ret; struct hostent *he; + + peer = talloc(mem_ctx, struct socket_address); + if (!peer) { + return NULL; + } + + peer->family = sock->backend_name; + peer_addr = talloc(peer, struct sockaddr_in6); + if (!peer_addr) { + talloc_free(peer); + return NULL; + } - ret = getpeername(sock->fd, (struct sockaddr *)&peer_addr, &len); + peer->sockaddr = (struct sockaddr *)peer_addr; + + ret = getpeername(sock->fd, peer->sockaddr, &len); if (ret == -1) { + talloc_free(peer); return NULL; } - he = gethostbyaddr((char *)&peer_addr.sin6_addr, sizeof(peer_addr.sin6_addr), AF_INET6); + peer->sockaddrlen = len; + + he = gethostbyaddr((char *)&peer_addr->sin6_addr, len, AF_INET6); if (!he || !he->h_name) { + talloc_free(peer); return NULL; } - return talloc_strdup(mem_ctx, he->h_name); -} - -static int ipv6_tcp_get_peer_port(struct socket_context *sock) -{ - struct sockaddr_in6 peer_addr; - socklen_t len = sizeof(peer_addr); - int ret; - - ret = getpeername(sock->fd, (struct sockaddr *)&peer_addr, &len); - if (ret == -1) { - return -1; + peer->addr = talloc_strdup(mem_ctx, he->h_name); + if (!peer->addr) { + talloc_free(peer); + return NULL; } + peer->port = ntohs(peer_addr->sin6_port); - return ntohs(peer_addr.sin6_port); + return peer; } -static char *ipv6_tcp_get_my_addr(struct socket_context *sock, TALLOC_CTX *mem_ctx) +static struct socket_address *ipv6_tcp_get_my_addr(struct socket_context *sock, TALLOC_CTX *mem_ctx) { - struct sockaddr_in6 my_addr; - socklen_t len = sizeof(my_addr); + struct sockaddr_in6 *local_addr; + socklen_t len = sizeof(*local_addr); + struct socket_address *local; int ret; struct hostent *he; - - ret = getsockname(sock->fd, (struct sockaddr *)&my_addr, &len); - if (ret == -1) { + + local = talloc(mem_ctx, struct socket_address); + if (!local) { + return NULL; + } + + local->family = sock->backend_name; + local_addr = talloc(local, struct sockaddr_in6); + if (!local_addr) { + talloc_free(local); return NULL; } - he = gethostbyaddr((char *)&my_addr.sin6_addr, sizeof(my_addr.sin6_addr), AF_INET6); - if (he == NULL) { + local->sockaddr = (struct sockaddr *)local_addr; + + ret = getsockname(sock->fd, local->sockaddr, &len); + if (ret == -1) { + talloc_free(local); return NULL; } - return talloc_strdup(mem_ctx, he->h_name); -} + local->sockaddrlen = len; -static int ipv6_tcp_get_my_port(struct socket_context *sock) -{ - struct sockaddr_in6 my_addr; - socklen_t len = sizeof(my_addr); - int ret; + he = gethostbyaddr((char *)&local_addr->sin6_addr, len, AF_INET6); - ret = getsockname(sock->fd, (struct sockaddr *)&my_addr, &len); - if (ret == -1) { - return -1; + if (!he || !he->h_name) { + talloc_free(local); + return NULL; + } + + local->addr = talloc_strdup(mem_ctx, he->h_name); + if (!local->addr) { + talloc_free(local); + return NULL; } + local->port = ntohs(local_addr->sin6_port); - return ntohs(my_addr.sin6_port); + return local; } static int ipv6_tcp_get_fd(struct socket_context *sock) @@ -369,9 +410,7 @@ static const struct socket_ops ipv6_tcp_ops = { .fn_get_peer_name = ipv6_tcp_get_peer_name, .fn_get_peer_addr = ipv6_tcp_get_peer_addr, - .fn_get_peer_port = ipv6_tcp_get_peer_port, .fn_get_my_addr = ipv6_tcp_get_my_addr, - .fn_get_my_port = ipv6_tcp_get_my_port, .fn_get_fd = ipv6_tcp_get_fd }; diff --git a/source4/lib/socket/socket_unix.c b/source4/lib/socket/socket_unix.c index 0c65bb46fb..5e04ce0d4c 100644 --- a/source4/lib/socket/socket_unix.c +++ b/source4/lib/socket/socket_unix.c @@ -95,22 +95,26 @@ static NTSTATUS unixdom_connect_complete(struct socket_context *sock, uint32_t f } static NTSTATUS unixdom_connect(struct socket_context *sock, - const char *my_address, int my_port, - const char *srv_address, int srv_port, + const struct socket_address *my_address, + const struct socket_address *srv_address, uint32_t flags) { - struct sockaddr_un srv_addr; int ret; - if (strlen(srv_address)+1 > sizeof(srv_addr.sun_path)) { - return NT_STATUS_OBJECT_PATH_INVALID; - } - - ZERO_STRUCT(srv_addr); - srv_addr.sun_family = AF_UNIX; - strncpy(srv_addr.sun_path, srv_address, sizeof(srv_addr.sun_path)); + if (srv_address->sockaddr) { + ret = connect(sock->fd, srv_address->sockaddr, srv_address->sockaddrlen); + } else { + struct sockaddr_un srv_addr; + if (strlen(srv_address->addr)+1 > sizeof(srv_addr.sun_path)) { + return NT_STATUS_OBJECT_PATH_INVALID; + } + + ZERO_STRUCT(srv_addr); + srv_addr.sun_family = AF_UNIX; + strncpy(srv_addr.sun_path, srv_address->addr, sizeof(srv_addr.sun_path)); - ret = connect(sock->fd, (const struct sockaddr *)&srv_addr, sizeof(srv_addr)); + ret = connect(sock->fd, (const struct sockaddr *)&srv_addr, sizeof(srv_addr)); + } if (ret == -1) { return unixdom_error(errno); } @@ -119,24 +123,32 @@ static NTSTATUS unixdom_connect(struct socket_context *sock, } static NTSTATUS unixdom_listen(struct socket_context *sock, - const char *my_address, int port, + const struct socket_address *my_address, int queue_size, uint32_t flags) { struct sockaddr_un my_addr; int ret; - if (strlen(my_address)+1 > sizeof(my_addr.sun_path)) { - return NT_STATUS_OBJECT_PATH_INVALID; - } - /* delete if it already exists */ - unlink(my_address); - - ZERO_STRUCT(my_addr); - my_addr.sun_family = AF_UNIX; - strncpy(my_addr.sun_path, my_address, sizeof(my_addr.sun_path)); + if (my_address->addr) { + unlink(my_address->addr); + } - ret = bind(sock->fd, (struct sockaddr *)&my_addr, sizeof(my_addr)); + if (my_address && my_address->sockaddr) { + ret = bind(sock->fd, (struct sockaddr *)&my_addr, sizeof(my_addr)); + } else { + + if (strlen(my_address->addr)+1 > sizeof(my_addr.sun_path)) { + return NT_STATUS_OBJECT_PATH_INVALID; + } + + + ZERO_STRUCT(my_addr); + my_addr.sun_family = AF_UNIX; + strncpy(my_addr.sun_path, my_address->addr, sizeof(my_addr.sun_path)); + + ret = bind(sock->fd, (struct sockaddr *)&my_addr, sizeof(my_addr)); + } if (ret == -1) { return unixdom_error(errno); } @@ -156,7 +168,7 @@ static NTSTATUS unixdom_listen(struct socket_context *sock, } sock->state = SOCKET_STATE_SERVER_LISTEN; - sock->private_data = (void *)talloc_strdup(sock, my_address); + sock->private_data = (void *)talloc_strdup(sock, my_address->addr); return NT_STATUS_OK; } @@ -255,24 +267,29 @@ static NTSTATUS unixdom_send(struct socket_context *sock, static NTSTATUS unixdom_sendto(struct socket_context *sock, const DATA_BLOB *blob, size_t *sendlen, uint32_t flags, - const char *dest_addr, int dest_port) + const struct socket_address *dest) { ssize_t len; int flgs = 0; - struct sockaddr_un srv_addr; - - if (strlen(dest_addr)+1 > sizeof(srv_addr.sun_path)) { - return NT_STATUS_OBJECT_PATH_INVALID; - } - - ZERO_STRUCT(srv_addr); - srv_addr.sun_family = AF_UNIX; - strncpy(srv_addr.sun_path, dest_addr, sizeof(srv_addr.sun_path)); - *sendlen = 0; - - len = sendto(sock->fd, blob->data, blob->length, flgs, - (struct sockaddr *)&srv_addr, sizeof(srv_addr)); + + if (dest->sockaddr) { + len = sendto(sock->fd, blob->data, blob->length, flgs, + dest->sockaddr, dest->sockaddrlen); + } else { + struct sockaddr_un srv_addr; + + if (strlen(dest->addr)+1 > sizeof(srv_addr.sun_path)) { + return NT_STATUS_OBJECT_PATH_INVALID; + } + + ZERO_STRUCT(srv_addr); + srv_addr.sun_family = AF_UNIX; + strncpy(srv_addr.sun_path, dest->addr, sizeof(srv_addr.sun_path)); + + len = sendto(sock->fd, blob->data, blob->length, flgs, + (struct sockaddr *)&srv_addr, sizeof(srv_addr)); + } if (len == -1) { return map_nt_error_from_unix(errno); } @@ -294,24 +311,82 @@ static char *unixdom_get_peer_name(struct socket_context *sock, TALLOC_CTX *mem_ return talloc_strdup(mem_ctx, "LOCAL/unixdom"); } -static char *unixdom_get_peer_addr(struct socket_context *sock, TALLOC_CTX *mem_ctx) +static struct socket_address *unixdom_get_peer_addr(struct socket_context *sock, TALLOC_CTX *mem_ctx) { - return talloc_strdup(mem_ctx, "LOCAL/unixdom"); -} + struct sockaddr_in *peer_addr; + socklen_t len = sizeof(*peer_addr); + struct socket_address *peer; + int ret; -static int unixdom_get_peer_port(struct socket_context *sock) -{ - return 0; -} + peer = talloc(mem_ctx, struct socket_address); + if (!peer) { + return NULL; + } + + peer->family = sock->backend_name; + peer_addr = talloc(peer, struct sockaddr_in); + if (!peer_addr) { + talloc_free(peer); + return NULL; + } -static char *unixdom_get_my_addr(struct socket_context *sock, TALLOC_CTX *mem_ctx) -{ - return talloc_strdup(mem_ctx, "LOCAL/unixdom"); + peer->sockaddr = (struct sockaddr *)peer_addr; + + ret = getpeername(sock->fd, peer->sockaddr, &len); + if (ret == -1) { + talloc_free(peer); + return NULL; + } + + peer->sockaddrlen = len; + + peer->port = 0; + peer->addr = talloc_strdup(peer, "LOCAL/unixdom"); + if (!peer->addr) { + talloc_free(peer); + return NULL; + } + + return peer; } -static int unixdom_get_my_port(struct socket_context *sock) +static struct socket_address *unixdom_get_my_addr(struct socket_context *sock, TALLOC_CTX *mem_ctx) { - return 0; + struct sockaddr_in *local_addr; + socklen_t len = sizeof(*local_addr); + struct socket_address *local; + int ret; + + local = talloc(mem_ctx, struct socket_address); + if (!local) { + return NULL; + } + + local->family = sock->backend_name; + local_addr = talloc(local, struct sockaddr_in); + if (!local_addr) { + talloc_free(local); + return NULL; + } + + local->sockaddr = (struct sockaddr *)local_addr; + + ret = getsockname(sock->fd, local->sockaddr, &len); + if (ret == -1) { + talloc_free(local); + return NULL; + } + + local->sockaddrlen = len; + + local->port = 0; + local->addr = talloc_strdup(local, "LOCAL/unixdom"); + if (!local->addr) { + talloc_free(local); + return NULL; + } + + return local; } static int unixdom_get_fd(struct socket_context *sock) @@ -346,9 +421,7 @@ static const struct socket_ops unixdom_ops = { .fn_get_peer_name = unixdom_get_peer_name, .fn_get_peer_addr = unixdom_get_peer_addr, - .fn_get_peer_port = unixdom_get_peer_port, .fn_get_my_addr = unixdom_get_my_addr, - .fn_get_my_port = unixdom_get_my_port, .fn_get_fd = unixdom_get_fd }; diff --git a/source4/libcli/cldap/cldap.c b/source4/libcli/cldap/cldap.c index a6710cf32c..490a03d50e 100644 --- a/source4/libcli/cldap/cldap.c +++ b/source4/libcli/cldap/cldap.c @@ -62,8 +62,7 @@ static void cldap_socket_recv(struct cldap_socket *cldap) { TALLOC_CTX *tmp_ctx = talloc_new(cldap); NTSTATUS status; - const char *src_addr; - int src_port; + struct socket_address *src; DATA_BLOB blob; size_t nread, dsize; struct asn1_data asn1; @@ -83,16 +82,15 @@ static void cldap_socket_recv(struct cldap_socket *cldap) } status = socket_recvfrom(cldap->sock, blob.data, blob.length, &nread, 0, - &src_addr, &src_port); + tmp_ctx, &src); if (!NT_STATUS_IS_OK(status)) { talloc_free(tmp_ctx); return; } - talloc_steal(tmp_ctx, src_addr); blob.length = nread; DEBUG(2,("Received cldap packet of length %d from %s:%d\n", - (int)blob.length, src_addr, src_port)); + (int)blob.length, src->addr, src->port)); if (!asn1_load(&asn1, blob)) { DEBUG(2,("Failed to setup for asn.1 decode\n")); @@ -118,10 +116,10 @@ static void cldap_socket_recv(struct cldap_socket *cldap) req = idr_find(cldap->idr, ldap_msg->messageid); if (req == NULL) { if (cldap->incoming.handler) { - cldap->incoming.handler(cldap, ldap_msg, src_addr, src_port); + cldap->incoming.handler(cldap, ldap_msg, src); } else { DEBUG(2,("Mismatched cldap reply %u from %s:%d\n", - ldap_msg->messageid, src_addr, src_port)); + ldap_msg->messageid, src->addr, src->port)); } talloc_free(tmp_ctx); return; @@ -157,7 +155,7 @@ static void cldap_request_timeout(struct event_context *event_ctx, req->num_retries--; socket_sendto(req->cldap->sock, &req->encoded, &len, 0, - req->dest_addr, req->dest_port); + req->dest); req->te = event_add_timed(req->cldap->event_ctx, req, timeval_current_ofs(req->timeout, 0), @@ -184,10 +182,10 @@ static void cldap_socket_send(struct cldap_socket *cldap) len = req->encoded.length; status = socket_sendto(cldap->sock, &req->encoded, &len, 0, - req->dest_addr, req->dest_port); + req->dest); if (NT_STATUS_IS_ERR(status)) { DEBUG(3,("Failed to send cldap request of length %u to %s:%d\n", - (unsigned)req->encoded.length, req->dest_addr, req->dest_port)); + (unsigned)req->encoded.length, req->dest->addr, req->dest->port)); DLIST_REMOVE(cldap->send_queue, req); talloc_free(req); continue; @@ -278,7 +276,7 @@ failed: */ NTSTATUS cldap_set_incoming_handler(struct cldap_socket *cldap, void (*handler)(struct cldap_socket *, struct ldap_message *, - const char *, int ), + struct socket_address *), void *private) { cldap->incoming.handler = handler; @@ -306,9 +304,9 @@ struct cldap_request *cldap_search_send(struct cldap_socket *cldap, req->num_retries = io->in.retries; req->is_reply = False; - req->dest_addr = talloc_strdup(req, io->in.dest_address); - if (req->dest_addr == NULL) goto failed; - req->dest_port = lp_cldap_port(); + req->dest = socket_address_from_strings(req, cldap->sock->backend_name, + io->in.dest_address, lp_cldap_port()); + if (!req->dest) goto failed; req->message_id = idr_get_new_random(cldap->idr, req, UINT16_MAX); if (req->message_id == -1) goto failed; @@ -337,7 +335,7 @@ struct cldap_request *cldap_search_send(struct cldap_socket *cldap, if (!ldap_encode(msg, &req->encoded, req)) { DEBUG(0,("Failed to encode cldap message to %s:%d\n", - req->dest_addr, req->dest_port)); + req->dest->addr, req->dest->port)); goto failed; } @@ -370,9 +368,8 @@ NTSTATUS cldap_reply_send(struct cldap_socket *cldap, struct cldap_reply *io) req->state = CLDAP_REQUEST_SEND; req->is_reply = True; - req->dest_addr = talloc_strdup(req, io->dest_address); - if (req->dest_addr == NULL) goto failed; - req->dest_port = io->dest_port; + req->dest = io->dest; + if (talloc_reference(req, io->dest) == NULL) goto failed; talloc_set_destructor(req, cldap_request_destructor); @@ -387,7 +384,7 @@ NTSTATUS cldap_reply_send(struct cldap_socket *cldap, struct cldap_reply *io) if (!ldap_encode(msg, &blob1, req)) { DEBUG(0,("Failed to encode cldap message to %s:%d\n", - req->dest_addr, req->dest_port)); + req->dest->addr, req->dest->port)); status = NT_STATUS_INVALID_PARAMETER; goto failed; } @@ -400,7 +397,7 @@ NTSTATUS cldap_reply_send(struct cldap_socket *cldap, struct cldap_reply *io) if (!ldap_encode(msg, &blob2, req)) { DEBUG(0,("Failed to encode cldap message to %s:%d\n", - req->dest_addr, req->dest_port)); + req->dest->addr, req->dest->port)); status = NT_STATUS_INVALID_PARAMETER; goto failed; } @@ -620,15 +617,14 @@ NTSTATUS cldap_netlogon(struct cldap_socket *cldap, */ NTSTATUS cldap_empty_reply(struct cldap_socket *cldap, uint32_t message_id, - const char *src_address, int src_port) + struct socket_address *src) { NTSTATUS status; struct cldap_reply reply; struct ldap_Result result; reply.messageid = message_id; - reply.dest_address = src_address; - reply.dest_port = src_port; + reply.dest = src; reply.response = NULL; reply.result = &result; @@ -645,7 +641,7 @@ NTSTATUS cldap_empty_reply(struct cldap_socket *cldap, */ NTSTATUS cldap_netlogon_reply(struct cldap_socket *cldap, uint32_t message_id, - const char *src_address, int src_port, + struct socket_address *src, uint32_t version, union nbt_cldap_netlogon *netlogon) { @@ -664,8 +660,7 @@ NTSTATUS cldap_netlogon_reply(struct cldap_socket *cldap, } reply.messageid = message_id; - reply.dest_address = src_address; - reply.dest_port = src_port; + reply.dest = src; reply.response = &response; reply.result = &result; diff --git a/source4/libcli/cldap/cldap.h b/source4/libcli/cldap/cldap.h index 0baaec02df..944510077b 100644 --- a/source4/libcli/cldap/cldap.h +++ b/source4/libcli/cldap/cldap.h @@ -41,8 +41,7 @@ struct cldap_request { enum cldap_request_state state; /* where to send the request */ - const char *dest_addr; - int dest_port; + struct socket_address *dest; /* timeout between retries (seconds) */ int timeout; @@ -87,7 +86,7 @@ struct cldap_socket { /* what to do with incoming request packets */ struct { void (*handler)(struct cldap_socket *, struct ldap_message *, - const char *, int ); + struct socket_address *); void *private; } incoming; }; @@ -114,7 +113,7 @@ struct cldap_socket *cldap_socket_init(TALLOC_CTX *mem_ctx, struct event_context *event_ctx); NTSTATUS cldap_set_incoming_handler(struct cldap_socket *cldap, void (*handler)(struct cldap_socket *, struct ldap_message *, - const char *, int ), + struct socket_address *), void *private); struct cldap_request *cldap_search_send(struct cldap_socket *cldap, struct cldap_search *io); @@ -129,8 +128,7 @@ NTSTATUS cldap_search(struct cldap_socket *cldap, TALLOC_CTX *mem_ctx, */ struct cldap_reply { uint32_t messageid; - const char *dest_address; - int dest_port; + struct socket_address *dest; struct ldap_SearchResEntry *response; struct ldap_Result *result; }; @@ -167,9 +165,9 @@ NTSTATUS cldap_netlogon(struct cldap_socket *cldap, NTSTATUS cldap_empty_reply(struct cldap_socket *cldap, uint32_t message_id, - const char *src_address, int src_port); + struct socket_address *src); NTSTATUS cldap_netlogon_reply(struct cldap_socket *cldap, uint32_t message_id, - const char *src_address, int src_port, + struct socket_address *src, uint32_t version, union nbt_cldap_netlogon *netlogon); diff --git a/source4/libcli/dgram/browse.c b/source4/libcli/dgram/browse.c index 821bf9d815..433d1c1971 100644 --- a/source4/libcli/dgram/browse.c +++ b/source4/libcli/dgram/browse.c @@ -23,9 +23,10 @@ #include "includes.h" #include "libcli/dgram/libdgram.h" +#include "lib/socket/socket.h" NTSTATUS dgram_mailslot_browse_send(struct nbt_dgram_socket *dgmsock, - struct nbt_name *dest_name, const struct nbt_peer_socket *dest, + struct nbt_name *dest_name, struct socket_address *dest, struct nbt_name *src_name, struct nbt_browse_packet *request) { NTSTATUS status; @@ -55,7 +56,7 @@ NTSTATUS dgram_mailslot_browse_reply(struct nbt_dgram_socket *dgmsock, DATA_BLOB blob; TALLOC_CTX *tmp_ctx = talloc_new(dgmsock); struct nbt_name myname; - struct nbt_peer_socket dest; + struct socket_address *dest; status = ndr_push_struct_blob(&blob, tmp_ctx, reply, (ndr_push_flags_fn_t)ndr_push_nbt_browse_packet); @@ -66,12 +67,17 @@ NTSTATUS dgram_mailslot_browse_reply(struct nbt_dgram_socket *dgmsock, make_nbt_name_client(&myname, lp_netbios_name()); - dest.port = request->src_port; - dest.addr = request->src_addr; + dest = socket_address_from_strings(tmp_ctx, dgmsock->sock->backend_name, + request->src_addr, request->src_port); + if (!dest) { + talloc_free(tmp_ctx); + return NT_STATUS_NO_MEMORY; + } + status = dgram_mailslot_send(dgmsock, DGRAM_DIRECT_UNIQUE, mailslot_name, &request->data.msg.source_name, - &dest, + dest, &myname, &blob); talloc_free(tmp_ctx); return status; diff --git a/source4/libcli/dgram/dgramsocket.c b/source4/libcli/dgram/dgramsocket.c index 143b9c309b..326ec7e908 100644 --- a/source4/libcli/dgram/dgramsocket.c +++ b/source4/libcli/dgram/dgramsocket.c @@ -34,7 +34,7 @@ static void dgm_socket_recv(struct nbt_dgram_socket *dgmsock) { TALLOC_CTX *tmp_ctx = talloc_new(dgmsock); NTSTATUS status; - struct nbt_peer_socket src; + struct socket_address *src; DATA_BLOB blob; size_t nread, dsize; struct nbt_dgram_packet *packet; @@ -53,16 +53,15 @@ static void dgm_socket_recv(struct nbt_dgram_socket *dgmsock) } status = socket_recvfrom(dgmsock->sock, blob.data, blob.length, &nread, 0, - &src.addr, &src.port); + tmp_ctx, &src); if (!NT_STATUS_IS_OK(status)) { talloc_free(tmp_ctx); return; } - talloc_steal(tmp_ctx, src.addr); blob.length = nread; DEBUG(2,("Received dgram packet of length %d from %s:%d\n", - (int)blob.length, src.addr, src.port)); + (int)blob.length, src->addr, src->port)); packet = talloc(tmp_ctx, struct nbt_dgram_packet); if (packet == NULL) { @@ -86,14 +85,14 @@ static void dgm_socket_recv(struct nbt_dgram_socket *dgmsock) struct dgram_mailslot_handler *dgmslot; dgmslot = dgram_mailslot_find(dgmsock, mailslot_name); if (dgmslot) { - dgmslot->handler(dgmslot, packet, &src); + dgmslot->handler(dgmslot, packet, src); } else { DEBUG(2,("No mailslot handler for '%s'\n", mailslot_name)); } } else { /* dispatch if there is a general handler */ if (dgmsock->incoming.handler) { - dgmsock->incoming.handler(dgmsock, packet, &src); + dgmsock->incoming.handler(dgmsock, packet, src); } } @@ -114,10 +113,10 @@ static void dgm_socket_send(struct nbt_dgram_socket *dgmsock) len = req->encoded.length; status = socket_sendto(dgmsock->sock, &req->encoded, &len, 0, - req->dest.addr, req->dest.port); + req->dest); if (NT_STATUS_IS_ERR(status)) { DEBUG(3,("Failed to send datagram of length %u to %s:%d: %s\n", - (unsigned)req->encoded.length, req->dest.addr, req->dest.port, + (unsigned)req->encoded.length, req->dest->addr, req->dest->port, nt_errstr(status))); DLIST_REMOVE(dgmsock->send_queue, req); talloc_free(req); @@ -200,7 +199,7 @@ failed: NTSTATUS dgram_set_incoming_handler(struct nbt_dgram_socket *dgmsock, void (*handler)(struct nbt_dgram_socket *, struct nbt_dgram_packet *, - const struct nbt_peer_socket *), + struct socket_address *), void *private) { dgmsock->incoming.handler = handler; @@ -215,7 +214,7 @@ NTSTATUS dgram_set_incoming_handler(struct nbt_dgram_socket *dgmsock, */ NTSTATUS nbt_dgram_send(struct nbt_dgram_socket *dgmsock, struct nbt_dgram_packet *packet, - const struct nbt_peer_socket *dest) + struct socket_address *dest) { struct nbt_dgram_request *req; NTSTATUS status = NT_STATUS_NO_MEMORY; @@ -223,9 +222,8 @@ NTSTATUS nbt_dgram_send(struct nbt_dgram_socket *dgmsock, req = talloc(dgmsock, struct nbt_dgram_request); if (req == NULL) goto failed; - req->dest.port = dest->port; - req->dest.addr = talloc_strdup(req, dest->addr); - if (req->dest.addr == NULL) goto failed; + req->dest = dest; + if (talloc_reference(req, dest) == NULL) goto failed; status = ndr_push_struct_blob(&req->encoded, req, packet, (ndr_push_flags_fn_t)ndr_push_nbt_dgram_packet); diff --git a/source4/libcli/dgram/libdgram.h b/source4/libcli/dgram/libdgram.h index f913e90d88..d5e28ed03d 100644 --- a/source4/libcli/dgram/libdgram.h +++ b/source4/libcli/dgram/libdgram.h @@ -29,7 +29,7 @@ struct nbt_dgram_request { struct nbt_dgram_request *next, *prev; /* where to send the request */ - struct nbt_peer_socket dest; + struct socket_address *dest; /* the encoded request */ DATA_BLOB encoded; @@ -54,7 +54,7 @@ struct nbt_dgram_socket { /* what to do with incoming request packets */ struct { void (*handler)(struct nbt_dgram_socket *, struct nbt_dgram_packet *, - const struct nbt_peer_socket *src); + struct socket_address *src); void *private; } incoming; }; @@ -70,7 +70,7 @@ struct nbt_dgram_socket { typedef void (*dgram_mailslot_handler_t)(struct dgram_mailslot_handler *, struct nbt_dgram_packet *, - const struct nbt_peer_socket *src); + struct socket_address *src); struct dgram_mailslot_handler { struct dgram_mailslot_handler *next, *prev; @@ -86,11 +86,11 @@ struct dgram_mailslot_handler { /* prototypes */ NTSTATUS nbt_dgram_send(struct nbt_dgram_socket *dgmsock, struct nbt_dgram_packet *packet, - const struct nbt_peer_socket *dest); + struct socket_address *dest); NTSTATUS dgram_set_incoming_handler(struct nbt_dgram_socket *dgmsock, void (*handler)(struct nbt_dgram_socket *, struct nbt_dgram_packet *, - const struct nbt_peer_socket *), + struct socket_address *), void *private); struct nbt_dgram_socket *nbt_dgram_socket_init(TALLOC_CTX *mem_ctx, struct event_context *event_ctx); @@ -113,13 +113,13 @@ NTSTATUS dgram_mailslot_send(struct nbt_dgram_socket *dgmsock, enum dgram_msg_type msg_type, const char *mailslot_name, struct nbt_name *dest_name, - const struct nbt_peer_socket *dest, + struct socket_address *dest, struct nbt_name *src_name, DATA_BLOB *request); NTSTATUS dgram_mailslot_netlogon_send(struct nbt_dgram_socket *dgmsock, struct nbt_name *dest_name, - const struct nbt_peer_socket *dest, + struct socket_address *dest, struct nbt_name *src_name, struct nbt_netlogon_packet *request); NTSTATUS dgram_mailslot_netlogon_reply(struct nbt_dgram_socket *dgmsock, @@ -132,11 +132,11 @@ NTSTATUS dgram_mailslot_netlogon_parse(struct dgram_mailslot_handler *dgmslot, struct nbt_netlogon_packet *netlogon); NTSTATUS dgram_mailslot_ntlogon_send(struct nbt_dgram_socket *dgmsock, - enum dgram_msg_type msg_type, - struct nbt_name *dest_name, - const struct nbt_peer_socket *dest, - struct nbt_name *src_name, - struct nbt_ntlogon_packet *request); + enum dgram_msg_type msg_type, + struct nbt_name *dest_name, + struct socket_address *dest, + struct nbt_name *src_name, + struct nbt_ntlogon_packet *request); NTSTATUS dgram_mailslot_ntlogon_reply(struct nbt_dgram_socket *dgmsock, struct nbt_dgram_packet *request, const char *mailslot_name, diff --git a/source4/libcli/dgram/mailslot.c b/source4/libcli/dgram/mailslot.c index 0e6b99c3e3..33bca166ce 100644 --- a/source4/libcli/dgram/mailslot.c +++ b/source4/libcli/dgram/mailslot.c @@ -151,28 +151,39 @@ NTSTATUS dgram_mailslot_send(struct nbt_dgram_socket *dgmsock, enum dgram_msg_type msg_type, const char *mailslot_name, struct nbt_name *dest_name, - const struct nbt_peer_socket *_dest, + struct socket_address *_dest, struct nbt_name *src_name, DATA_BLOB *request) { TALLOC_CTX *tmp_ctx = talloc_new(dgmsock); struct nbt_dgram_packet packet; - struct nbt_peer_socket dest = *_dest; + struct socket_address *dest; struct dgram_message *msg; struct dgram_smb_packet *smb; struct smb_trans_body *trans; + struct socket_address *src; NTSTATUS status; - if (dest.port == 0) { - dest.port = lp_dgram_port(); + if (_dest->port == 0) { + dest = socket_address_from_strings(tmp_ctx, _dest->family, + _dest->addr, lp_dgram_port()); + } else { + dest = _dest; + } + if (!dest) { + return NT_STATUS_NO_MEMORY; } ZERO_STRUCT(packet); packet.msg_type = msg_type; packet.flags = DGRAM_FLAG_FIRST | DGRAM_NODE_NBDD; packet.dgram_id = generate_random() % UINT16_MAX; - packet.src_addr = socket_get_my_addr(dgmsock->sock, tmp_ctx); - packet.src_port = socket_get_my_port(dgmsock->sock); + src = socket_get_my_addr(dgmsock->sock, tmp_ctx); + if (!src) { + return NT_STATUS_NO_MEMORY; + } + packet.src_addr = src->addr; + packet.src_port = src->port; msg = &packet.data.msg; /* this length calculation is very crude - it should be based on gensize @@ -198,7 +209,7 @@ NTSTATUS dgram_mailslot_send(struct nbt_dgram_socket *dgmsock, trans->mailslot_name = mailslot_name; trans->data = *request; - status = nbt_dgram_send(dgmsock, &packet, &dest); + status = nbt_dgram_send(dgmsock, &packet, dest); talloc_free(tmp_ctx); diff --git a/source4/libcli/dgram/netlogon.c b/source4/libcli/dgram/netlogon.c index dffeae2007..6ad4c28811 100644 --- a/source4/libcli/dgram/netlogon.c +++ b/source4/libcli/dgram/netlogon.c @@ -22,13 +22,14 @@ #include "includes.h" #include "libcli/dgram/libdgram.h" +#include "lib/socket/socket.h" /* send a netlogon mailslot request */ NTSTATUS dgram_mailslot_netlogon_send(struct nbt_dgram_socket *dgmsock, struct nbt_name *dest_name, - const struct nbt_peer_socket *dest, + struct socket_address *dest, struct nbt_name *src_name, struct nbt_netlogon_packet *request) { @@ -65,7 +66,7 @@ NTSTATUS dgram_mailslot_netlogon_reply(struct nbt_dgram_socket *dgmsock, DATA_BLOB blob; TALLOC_CTX *tmp_ctx = talloc_new(dgmsock); struct nbt_name myname; - struct nbt_peer_socket dest; + struct socket_address *dest; status = ndr_push_struct_blob(&blob, tmp_ctx, reply, (ndr_push_flags_fn_t)ndr_push_nbt_netlogon_packet); @@ -76,12 +77,17 @@ NTSTATUS dgram_mailslot_netlogon_reply(struct nbt_dgram_socket *dgmsock, make_nbt_name_client(&myname, lp_netbios_name()); - dest.port = request->src_port; - dest.addr = request->src_addr; + dest = socket_address_from_strings(tmp_ctx, dgmsock->sock->backend_name, + request->src_addr, request->src_port); + if (!dest) { + talloc_free(tmp_ctx); + return NT_STATUS_NO_MEMORY; + } + status = dgram_mailslot_send(dgmsock, DGRAM_DIRECT_UNIQUE, mailslot_name, &request->data.msg.source_name, - &dest, + dest, &myname, &blob); talloc_free(tmp_ctx); return status; diff --git a/source4/libcli/dgram/ntlogon.c b/source4/libcli/dgram/ntlogon.c index 3205416cea..ecd6bd4587 100644 --- a/source4/libcli/dgram/ntlogon.c +++ b/source4/libcli/dgram/ntlogon.c @@ -22,6 +22,7 @@ #include "includes.h" #include "libcli/dgram/libdgram.h" +#include "lib/socket/socket.h" /* send a ntlogon mailslot request @@ -29,7 +30,7 @@ NTSTATUS dgram_mailslot_ntlogon_send(struct nbt_dgram_socket *dgmsock, enum dgram_msg_type msg_type, struct nbt_name *dest_name, - const struct nbt_peer_socket *dest, + struct socket_address *dest, struct nbt_name *src_name, struct nbt_ntlogon_packet *request) { @@ -66,7 +67,7 @@ NTSTATUS dgram_mailslot_ntlogon_reply(struct nbt_dgram_socket *dgmsock, DATA_BLOB blob; TALLOC_CTX *tmp_ctx = talloc_new(dgmsock); struct nbt_name myname; - struct nbt_peer_socket dest; + struct socket_address *dest; status = ndr_push_struct_blob(&blob, tmp_ctx, reply, (ndr_push_flags_fn_t)ndr_push_nbt_ntlogon_packet); @@ -77,12 +78,18 @@ NTSTATUS dgram_mailslot_ntlogon_reply(struct nbt_dgram_socket *dgmsock, make_nbt_name_client(&myname, lp_netbios_name()); - dest.port = request->src_port; - dest.addr = request->src_addr; + dest = socket_address_from_strings(tmp_ctx, + dgmsock->sock->backend_name, + request->src_addr, request->src_port); + if (!dest) { + talloc_free(tmp_ctx); + return NT_STATUS_NO_MEMORY; + } + status = dgram_mailslot_send(dgmsock, DGRAM_DIRECT_UNIQUE, mailslot_name, &request->data.msg.source_name, - &dest, + dest, &myname, &blob); talloc_free(tmp_ctx); return status; diff --git a/source4/libcli/nbt/libnbt.h b/source4/libcli/nbt/libnbt.h index 7c9e3e9651..b4411d6fe6 100644 --- a/source4/libcli/nbt/libnbt.h +++ b/source4/libcli/nbt/libnbt.h @@ -34,12 +34,6 @@ enum nbt_request_state {NBT_REQUEST_SEND, NBT_REQUEST_TIMEOUT, NBT_REQUEST_ERROR}; -/* where to send the request/replies */ -struct nbt_peer_socket { - const char *addr; - int port; -}; - /* a nbt name request */ @@ -54,7 +48,7 @@ struct nbt_name_request { struct nbt_name_socket *nbtsock; /* where to send the request */ - struct nbt_peer_socket dest; + struct socket_address *dest; /* timeout between retries */ int timeout; @@ -83,7 +77,7 @@ struct nbt_name_request { uint_t num_replies; struct nbt_name_reply { struct nbt_name_packet *packet; - struct nbt_peer_socket dest; + struct socket_address *dest; } *replies; /* information on what to do on completion */ @@ -117,14 +111,14 @@ struct nbt_name_socket { /* what to do with incoming request packets */ struct { void (*handler)(struct nbt_name_socket *, struct nbt_name_packet *, - const struct nbt_peer_socket *); + struct socket_address *); void *private; } incoming; /* what to do with unexpected replies */ struct { void (*handler)(struct nbt_name_socket *, struct nbt_name_packet *, - const struct nbt_peer_socket *); + struct socket_address *); void *private; } unexpected; }; diff --git a/source4/libcli/nbt/namequery.c b/source4/libcli/nbt/namequery.c index 38fb2f966d..6566e48a5a 100644 --- a/source4/libcli/nbt/namequery.c +++ b/source4/libcli/nbt/namequery.c @@ -22,7 +22,7 @@ #include "includes.h" #include "libcli/nbt/libnbt.h" - +#include "lib/socket/socket.h" /* send a nbt name query */ @@ -31,7 +31,7 @@ struct nbt_name_request *nbt_name_query_send(struct nbt_name_socket *nbtsock, { struct nbt_name_request *req; struct nbt_name_packet *packet; - struct nbt_peer_socket dest; + struct socket_address *dest; packet = talloc_zero(nbtsock, struct nbt_name_packet); if (packet == NULL) return NULL; @@ -52,9 +52,10 @@ struct nbt_name_request *nbt_name_query_send(struct nbt_name_socket *nbtsock, packet->questions[0].question_type = NBT_QTYPE_NETBIOS; packet->questions[0].question_class = NBT_QCLASS_IP; - dest.port = lp_nbt_port(); - dest.addr = io->in.dest_addr; - req = nbt_name_request_send(nbtsock, &dest, packet, + dest = socket_address_from_strings(packet, nbtsock->sock->backend_name, + io->in.dest_addr, lp_nbt_port()); + if (dest == NULL) goto failed; + req = nbt_name_request_send(nbtsock, dest, packet, io->in.timeout, io->in.retries, False); if (req == NULL) goto failed; @@ -84,7 +85,7 @@ NTSTATUS nbt_name_query_recv(struct nbt_name_request *req, } packet = req->replies[0].packet; - io->out.reply_from = talloc_steal(mem_ctx, req->replies[0].dest.addr); + io->out.reply_from = talloc_steal(mem_ctx, req->replies[0].dest->addr); if ((packet->operation & NBT_RCODE) != 0) { status = nbt_rcode_to_ntstatus(packet->operation & NBT_RCODE); @@ -140,7 +141,7 @@ struct nbt_name_request *nbt_name_status_send(struct nbt_name_socket *nbtsock, { struct nbt_name_request *req; struct nbt_name_packet *packet; - struct nbt_peer_socket dest; + struct socket_address *dest; packet = talloc_zero(nbtsock, struct nbt_name_packet); if (packet == NULL) return NULL; @@ -155,9 +156,10 @@ struct nbt_name_request *nbt_name_status_send(struct nbt_name_socket *nbtsock, packet->questions[0].question_type = NBT_QTYPE_STATUS; packet->questions[0].question_class = NBT_QCLASS_IP; - dest.port = lp_nbt_port(); - dest.addr = io->in.dest_addr; - req = nbt_name_request_send(nbtsock, &dest, packet, + dest = socket_address_from_strings(packet, nbtsock->sock->backend_name, + io->in.dest_addr, lp_nbt_port()); + if (dest == NULL) goto failed; + req = nbt_name_request_send(nbtsock, dest, packet, io->in.timeout, io->in.retries, False); if (req == NULL) goto failed; @@ -187,7 +189,7 @@ NTSTATUS nbt_name_status_recv(struct nbt_name_request *req, } packet = req->replies[0].packet; - io->out.reply_from = talloc_steal(mem_ctx, req->replies[0].dest.addr); + io->out.reply_from = talloc_steal(mem_ctx, req->replies[0].dest->addr); if ((packet->operation & NBT_RCODE) != 0) { status = nbt_rcode_to_ntstatus(packet->operation & NBT_RCODE); diff --git a/source4/libcli/nbt/namerefresh.c b/source4/libcli/nbt/namerefresh.c index e6464885f7..8940fbb95e 100644 --- a/source4/libcli/nbt/namerefresh.c +++ b/source4/libcli/nbt/namerefresh.c @@ -23,6 +23,7 @@ #include "includes.h" #include "libcli/nbt/libnbt.h" #include "libcli/composite/composite.h" +#include "lib/socket/socket.h" /* send a nbt name refresh request @@ -32,7 +33,7 @@ struct nbt_name_request *nbt_name_refresh_send(struct nbt_name_socket *nbtsock, { struct nbt_name_request *req; struct nbt_name_packet *packet; - struct nbt_peer_socket dest; + struct socket_address *dest; packet = talloc_zero(nbtsock, struct nbt_name_packet); if (packet == NULL) return NULL; @@ -66,9 +67,10 @@ struct nbt_name_request *nbt_name_refresh_send(struct nbt_name_socket *nbtsock, packet->additional[0].rdata.netbios.addresses[0].ipaddr = talloc_strdup(packet->additional, io->in.address); - dest.port = lp_nbt_port(); - dest.addr = io->in.dest_addr; - req = nbt_name_request_send(nbtsock, &dest, packet, + dest = socket_address_from_strings(nbtsock, nbtsock->sock->backend_name, + io->in.dest_addr, lp_nbt_port()); + if (dest == NULL) goto failed; + req = nbt_name_request_send(nbtsock, dest, packet, io->in.timeout, io->in.retries, False); if (req == NULL) goto failed; @@ -97,7 +99,7 @@ NTSTATUS nbt_name_refresh_recv(struct nbt_name_request *req, } packet = req->replies[0].packet; - io->out.reply_from = talloc_steal(mem_ctx, req->replies[0].dest.addr); + io->out.reply_from = talloc_steal(mem_ctx, req->replies[0].dest->addr); if (packet->ancount != 1 || packet->answers[0].rr_type != NBT_QTYPE_NETBIOS || diff --git a/source4/libcli/nbt/nameregister.c b/source4/libcli/nbt/nameregister.c index 4f3e046274..5c7e86367f 100644 --- a/source4/libcli/nbt/nameregister.c +++ b/source4/libcli/nbt/nameregister.c @@ -23,6 +23,7 @@ #include "includes.h" #include "libcli/nbt/libnbt.h" #include "libcli/composite/composite.h" +#include "lib/socket/socket.h" /* send a nbt name registration request @@ -32,7 +33,7 @@ struct nbt_name_request *nbt_name_register_send(struct nbt_name_socket *nbtsock, { struct nbt_name_request *req; struct nbt_name_packet *packet; - struct nbt_peer_socket dest; + struct socket_address *dest; packet = talloc_zero(nbtsock, struct nbt_name_packet); if (packet == NULL) return NULL; @@ -74,9 +75,10 @@ struct nbt_name_request *nbt_name_register_send(struct nbt_name_socket *nbtsock, talloc_strdup(packet->additional, io->in.address); if (packet->additional[0].rdata.netbios.addresses[0].ipaddr == NULL) goto failed; - dest.port = lp_nbt_port(); - dest.addr = io->in.dest_addr; - req = nbt_name_request_send(nbtsock, &dest, packet, + dest = socket_address_from_strings(packet, nbtsock->sock->backend_name, + io->in.dest_addr, lp_nbt_port()); + if (dest == NULL) goto failed; + req = nbt_name_request_send(nbtsock, dest, packet, io->in.timeout, io->in.retries, False); if (req == NULL) goto failed; @@ -105,7 +107,7 @@ NTSTATUS nbt_name_register_recv(struct nbt_name_request *req, } packet = req->replies[0].packet; - io->out.reply_from = talloc_steal(mem_ctx, req->replies[0].dest.addr); + io->out.reply_from = talloc_steal(mem_ctx, req->replies[0].dest->addr); if (packet->ancount != 1 || packet->answers[0].rr_type != NBT_QTYPE_NETBIOS || diff --git a/source4/libcli/nbt/namerelease.c b/source4/libcli/nbt/namerelease.c index 0a0cd45276..e8dc175b36 100644 --- a/source4/libcli/nbt/namerelease.c +++ b/source4/libcli/nbt/namerelease.c @@ -22,6 +22,7 @@ #include "includes.h" #include "libcli/nbt/libnbt.h" +#include "lib/socket/socket.h" /* send a nbt name release request @@ -31,7 +32,7 @@ struct nbt_name_request *nbt_name_release_send(struct nbt_name_socket *nbtsock, { struct nbt_name_request *req; struct nbt_name_packet *packet; - struct nbt_peer_socket dest; + struct socket_address *dest; packet = talloc_zero(nbtsock, struct nbt_name_packet); if (packet == NULL) return NULL; @@ -65,9 +66,10 @@ struct nbt_name_request *nbt_name_release_send(struct nbt_name_socket *nbtsock, packet->additional[0].rdata.netbios.addresses[0].ipaddr = talloc_strdup(packet->additional, io->in.address); - dest.port = lp_nbt_port(); - dest.addr = io->in.dest_addr; - req = nbt_name_request_send(nbtsock, &dest, packet, + dest = socket_address_from_strings(packet, nbtsock->sock->backend_name, + io->in.dest_addr, lp_nbt_port()); + if (dest == NULL) goto failed; + req = nbt_name_request_send(nbtsock, dest, packet, io->in.timeout, io->in.retries, False); if (req == NULL) goto failed; @@ -96,7 +98,7 @@ NTSTATUS nbt_name_release_recv(struct nbt_name_request *req, } packet = req->replies[0].packet; - io->out.reply_from = talloc_steal(mem_ctx, req->replies[0].dest.addr); + io->out.reply_from = talloc_steal(mem_ctx, req->replies[0].dest->addr); if (packet->ancount != 1 || packet->answers[0].rr_type != NBT_QTYPE_NETBIOS || diff --git a/source4/libcli/nbt/nbtsocket.c b/source4/libcli/nbt/nbtsocket.c index 1c41b80fdb..42b92b14cc 100644 --- a/source4/libcli/nbt/nbtsocket.c +++ b/source4/libcli/nbt/nbtsocket.c @@ -73,7 +73,7 @@ static void nbt_name_socket_send(struct nbt_name_socket *nbtsock) len = req->encoded.length; status = socket_sendto(nbtsock->sock, &req->encoded, &len, 0, - req->dest.addr, req->dest.port); + req->dest); if (NT_STATUS_IS_ERR(status)) goto failed; if (!NT_STATUS_IS_OK(status)) { @@ -153,7 +153,7 @@ static void nbt_name_socket_recv(struct nbt_name_socket *nbtsock) { TALLOC_CTX *tmp_ctx = talloc_new(nbtsock); NTSTATUS status; - struct nbt_peer_socket src; + struct socket_address *src; DATA_BLOB blob; size_t nread, dsize; struct nbt_name_packet *packet; @@ -172,13 +172,11 @@ static void nbt_name_socket_recv(struct nbt_name_socket *nbtsock) } status = socket_recvfrom(nbtsock->sock, blob.data, blob.length, &nread, 0, - &src.addr, &src.port); + tmp_ctx, &src); if (!NT_STATUS_IS_OK(status)) { talloc_free(tmp_ctx); return; } - talloc_steal(tmp_ctx, src.addr); - blob.length = nread; packet = talloc(tmp_ctx, struct nbt_name_packet); if (packet == NULL) { @@ -198,7 +196,7 @@ static void nbt_name_socket_recv(struct nbt_name_socket *nbtsock) if (DEBUGLVL(10)) { DEBUG(10,("Received nbt packet of length %d from %s:%d\n", - (int)blob.length, src.addr, src.port)); + (int)blob.length, src->addr, src->port)); NDR_PRINT_DEBUG(nbt_name_packet, packet); } @@ -206,7 +204,7 @@ static void nbt_name_socket_recv(struct nbt_name_socket *nbtsock) handler, if any */ if (!(packet->operation & NBT_FLAG_REPLY)) { if (nbtsock->incoming.handler) { - nbtsock->incoming.handler(nbtsock, packet, &src); + nbtsock->incoming.handler(nbtsock, packet, src); } talloc_free(tmp_ctx); return; @@ -216,7 +214,7 @@ static void nbt_name_socket_recv(struct nbt_name_socket *nbtsock) req = idr_find(nbtsock->idr, packet->name_trn_id); if (req == NULL) { if (nbtsock->unexpected.handler) { - nbtsock->unexpected.handler(nbtsock, packet, &src); + nbtsock->unexpected.handler(nbtsock, packet, src); } else { DEBUG(2,("Failed to match request for incoming name packet id 0x%04x on %p\n", packet->name_trn_id, nbtsock)); @@ -258,9 +256,10 @@ static void nbt_name_socket_recv(struct nbt_name_socket *nbtsock) goto done; } - req->replies[req->num_replies].dest.addr = talloc_steal(req, src.addr); - req->replies[req->num_replies].dest.port = src.port; - req->replies[req->num_replies].packet = talloc_steal(req, packet); + talloc_steal(req, src); + req->replies[req->num_replies].dest = src; + talloc_steal(req, packet); + req->replies[req->num_replies].packet = packet; req->num_replies++; /* if we don't want multiple replies then we are done */ @@ -348,7 +347,7 @@ failed: send off a nbt name request */ struct nbt_name_request *nbt_name_request_send(struct nbt_name_socket *nbtsock, - const struct nbt_peer_socket *dest, + struct socket_address *dest, struct nbt_name_packet *request, int timeout, int retries, BOOL allow_multiple_replies) @@ -366,9 +365,8 @@ struct nbt_name_request *nbt_name_request_send(struct nbt_name_socket *nbtsock, req->is_reply = False; req->timeout = timeout; req->num_retries = retries; - req->dest.port = dest->port; - req->dest.addr = talloc_strdup(req, dest->addr); - if (req->dest.addr == NULL) goto failed; + req->dest = dest; + if (talloc_reference(req, dest) == NULL) goto failed; /* we select a random transaction id unless the user supplied one */ if (request->name_trn_id == 0) { @@ -397,7 +395,7 @@ struct nbt_name_request *nbt_name_request_send(struct nbt_name_socket *nbtsock, if (DEBUGLVL(10)) { DEBUG(10,("Queueing nbt packet to %s:%d\n", - req->dest.addr, req->dest.port)); + req->dest->addr, req->dest->port)); NDR_PRINT_DEBUG(nbt_name_packet, request); } @@ -415,7 +413,7 @@ failed: send off a nbt name reply */ NTSTATUS nbt_name_reply_send(struct nbt_name_socket *nbtsock, - const struct nbt_peer_socket *dest, + struct socket_address *dest, struct nbt_name_packet *request) { struct nbt_name_request *req; @@ -425,9 +423,8 @@ NTSTATUS nbt_name_reply_send(struct nbt_name_socket *nbtsock, NT_STATUS_HAVE_NO_MEMORY(req); req->nbtsock = nbtsock; - req->dest.port = dest->port; - req->dest.addr = talloc_strdup(req, dest->addr); - if (req->dest.addr == NULL) goto failed; + req->dest = dest; + if (talloc_reference(req, dest) == NULL) goto failed; req->state = NBT_REQUEST_SEND; req->is_reply = True; @@ -480,7 +477,7 @@ NTSTATUS nbt_name_request_recv(struct nbt_name_request *req) */ NTSTATUS nbt_set_incoming_handler(struct nbt_name_socket *nbtsock, void (*handler)(struct nbt_name_socket *, struct nbt_name_packet *, - const struct nbt_peer_socket *), + struct socket_address *), void *private) { nbtsock->incoming.handler = handler; diff --git a/source4/libcli/wrepl/winsrepl.c b/source4/libcli/wrepl/winsrepl.c index 0409607aa9..909bedf530 100644 --- a/source4/libcli/wrepl/winsrepl.c +++ b/source4/libcli/wrepl/winsrepl.c @@ -311,6 +311,7 @@ struct composite_context *wrepl_connect_send(struct wrepl_socket *wrepl_socket, { struct composite_context *result; struct wrepl_connect_state *state; + struct socket_address *peer, *us; result = talloc_zero(wrepl_socket, struct composite_context); if (!result) return NULL; @@ -328,8 +329,15 @@ struct composite_context *wrepl_connect_send(struct wrepl_socket *wrepl_socket, our_ip = iface_best_ip(peer_ip); } - state->creq = socket_connect_send(wrepl_socket->sock, our_ip, 0, - peer_ip, WINS_REPLICATION_PORT, + us = socket_address_from_strings(state, wrepl_socket->sock->backend_name, + our_ip, 0); + if (composite_nomem(us, result)) return result; + + peer = socket_address_from_strings(state, wrepl_socket->sock->backend_name, + peer_ip, WINS_REPLICATION_PORT); + if (composite_nomem(peer, result)) return result; + + state->creq = socket_connect_send(wrepl_socket->sock, us, peer, 0, wrepl_socket->event.ctx); composite_continue(result, state->creq, wrepl_connect_handler, state); return result; diff --git a/source4/librpc/rpc/dcerpc_sock.c b/source4/librpc/rpc/dcerpc_sock.c index 2867a8eacc..75684aaf8a 100644 --- a/source4/librpc/rpc/dcerpc_sock.c +++ b/source4/librpc/rpc/dcerpc_sock.c @@ -194,8 +194,7 @@ struct pipe_open_socket_state { struct dcerpc_connection *conn; struct socket_context *socket_ctx; struct sock_private *sock; - const char *server; - uint32_t port; + struct socket_address *server; enum dcerpc_transport_t transport; }; @@ -215,7 +214,8 @@ static void continue_socket_connect(struct composite_context *ctx) c->status = socket_connect_recv(ctx); if (!NT_STATUS_IS_OK(c->status)) { - DEBUG(0, ("Failed to connect host %s on port %d - %s\n", s->server, s->port, + DEBUG(0, ("Failed to connect host %s on port %d - %s\n", + s->server->addr, s->server->port, nt_errstr(c->status))); composite_error(c, c->status); return; @@ -236,7 +236,7 @@ static void continue_socket_connect(struct composite_context *ctx) sock->sock = s->socket_ctx; sock->pending_reads = 0; - sock->server_name = strupper_talloc(sock, s->server); + sock->server_name = strupper_talloc(sock, s->server->addr); sock->fde = event_add_fd(conn->event_ctx, sock->sock, socket_get_fd(sock->sock), 0, sock_io_handler, conn); @@ -270,9 +270,7 @@ static void continue_socket_connect(struct composite_context *ctx) struct composite_context *dcerpc_pipe_open_socket_send(TALLOC_CTX *mem_ctx, struct dcerpc_connection *cn, - const char *server, - uint32_t port, - const char *type, + struct socket_address *server, enum dcerpc_transport_t transport) { NTSTATUS status; @@ -295,8 +293,7 @@ struct composite_context *dcerpc_pipe_open_socket_send(TALLOC_CTX *mem_ctx, s->conn = cn; s->transport = transport; - s->port = port; - s->server = talloc_strdup(c, server); + s->server = talloc_reference(c, server); if (s->server == NULL) { composite_error(c, NT_STATUS_NO_MEMORY); goto done; @@ -308,7 +305,7 @@ struct composite_context *dcerpc_pipe_open_socket_send(TALLOC_CTX *mem_ctx, goto done; } - status = socket_create(type, SOCKET_TYPE_STREAM, &s->socket_ctx, 0); + status = socket_create(server->family, SOCKET_TYPE_STREAM, &s->socket_ctx, 0); if (!NT_STATUS_IS_OK(status)) { composite_error(c, status); talloc_free(s->sock); @@ -316,7 +313,7 @@ struct composite_context *dcerpc_pipe_open_socket_send(TALLOC_CTX *mem_ctx, } talloc_steal(s->sock, s->socket_ctx); - conn_req = socket_connect_send(s->socket_ctx, NULL, 0, s->server, s->port, 0, c->event_ctx); + conn_req = socket_connect_send(s->socket_ctx, NULL, s->server, 0, c->event_ctx); if (conn_req == NULL) { composite_error(c, NT_STATUS_NO_MEMORY); goto done; @@ -341,15 +338,12 @@ NTSTATUS dcerpc_pipe_open_socket_recv(struct composite_context *c) open a rpc connection using the generic socket library */ NTSTATUS dcerpc_pipe_open_socket(struct dcerpc_connection *conn, - const char *server, - uint32_t port, - const char *type, + struct socket_address *server, enum dcerpc_transport_t transport) { struct composite_context *c; - c = dcerpc_pipe_open_socket_send(conn, conn, server, port, - type, transport); + c = dcerpc_pipe_open_socket_send(conn, conn, server, transport); return dcerpc_pipe_open_socket_recv(c); } @@ -360,14 +354,26 @@ NTSTATUS dcerpc_pipe_open_socket(struct dcerpc_connection *conn, NTSTATUS dcerpc_pipe_open_tcp(struct dcerpc_connection *c, const char *server, uint32_t port) { NTSTATUS status; + struct socket_address *srvaddr; + + srvaddr = socket_address_from_strings(c, "ipv6", server, port); + if (!srvaddr) { + return NT_STATUS_NO_MEMORY; + } /* Try IPv6 first */ - status = dcerpc_pipe_open_socket(c, server, port, "ipv6", NCACN_IP_TCP); + status = dcerpc_pipe_open_socket(c, srvaddr, NCACN_IP_TCP); if (NT_STATUS_IS_OK(status)) { return status; } + + talloc_free(srvaddr); + srvaddr = socket_address_from_strings(c, "ipv4", server, port); + if (!srvaddr) { + return NT_STATUS_NO_MEMORY; + } - return dcerpc_pipe_open_socket(c, server, port, "ipv4", NCACN_IP_TCP); + return dcerpc_pipe_open_socket(c, srvaddr, NCACN_IP_TCP); } /* @@ -375,7 +381,14 @@ NTSTATUS dcerpc_pipe_open_tcp(struct dcerpc_connection *c, const char *server, u */ NTSTATUS dcerpc_pipe_open_unix_stream(struct dcerpc_connection *c, const char *path) { - return dcerpc_pipe_open_socket(c, path, 0, "unix", NCACN_UNIX_STREAM); + struct socket_address *srvaddr; + + srvaddr = socket_address_from_strings(c, "unix", path, 0); + if (!srvaddr) { + return NT_STATUS_NO_MEMORY; + } + + return dcerpc_pipe_open_socket(c, srvaddr, NCALRPC); } /* @@ -385,13 +398,19 @@ NTSTATUS dcerpc_pipe_open_pipe(struct dcerpc_connection *c, const char *identifi { NTSTATUS status; char *canon, *full_path; + struct socket_address *srvaddr; canon = talloc_strdup(NULL, identifier); string_replace(canon, '/', '\\'); full_path = talloc_asprintf(canon, "%s/%s", lp_ncalrpc_dir(), canon); - status = dcerpc_pipe_open_socket(c, full_path, 0, "unix", NCALRPC); + srvaddr = socket_address_from_strings(c, "unix", full_path, 0); + if (!srvaddr) { + return NT_STATUS_NO_MEMORY; + } + + status = dcerpc_pipe_open_socket(c, srvaddr, NCALRPC); talloc_free(canon); return status; diff --git a/source4/nbt_server/defense.c b/source4/nbt_server/defense.c index 7811c254c0..86b3eb968b 100644 --- a/source4/nbt_server/defense.c +++ b/source4/nbt_server/defense.c @@ -25,6 +25,7 @@ #include "system/network.h" #include "nbt_server/nbt_server.h" #include "nbt_server/wins/winsserver.h" +#include "lib/socket/socket.h" /* @@ -33,7 +34,7 @@ */ void nbtd_request_defense(struct nbt_name_socket *nbtsock, struct nbt_name_packet *packet, - const struct nbt_peer_socket *src) + struct socket_address *src) { struct nbtd_iface_name *iname; struct nbt_name *name; diff --git a/source4/nbt_server/dgram/browse.c b/source4/nbt_server/dgram/browse.c index 49e43eeb68..2486354052 100644 --- a/source4/nbt_server/dgram/browse.c +++ b/source4/nbt_server/dgram/browse.c @@ -22,13 +22,14 @@ #include "includes.h" #include "nbt_server/nbt_server.h" +#include "lib/socket/socket.h" /* handle incoming browse mailslot requests */ void nbtd_mailslot_browse_handler(struct dgram_mailslot_handler *dgmslot, struct nbt_dgram_packet *packet, - const struct nbt_peer_socket *src) + struct socket_address *src) { DEBUG(2,("Browse request on '%s' from %s:%d\n", dgmslot->mailslot_name, src->addr, src->port)); diff --git a/source4/nbt_server/dgram/netlogon.c b/source4/nbt_server/dgram/netlogon.c index 858b290957..5ba826cc33 100644 --- a/source4/nbt_server/dgram/netlogon.c +++ b/source4/nbt_server/dgram/netlogon.c @@ -32,7 +32,7 @@ */ static void nbtd_netlogon_getdc(struct dgram_mailslot_handler *dgmslot, struct nbt_dgram_packet *packet, - const struct nbt_peer_socket *src, + const struct socket_address *src, struct nbt_netlogon_packet *netlogon) { struct nbt_name *name = &packet->data.msg.dest_name; @@ -90,7 +90,7 @@ static void nbtd_netlogon_getdc(struct dgram_mailslot_handler *dgmslot, */ static void nbtd_netlogon_getdc2(struct dgram_mailslot_handler *dgmslot, struct nbt_dgram_packet *packet, - const struct nbt_peer_socket *src, + const struct socket_address *src, struct nbt_netlogon_packet *netlogon) { struct nbt_name *name = &packet->data.msg.dest_name; @@ -102,6 +102,11 @@ static void nbtd_netlogon_getdc2(struct dgram_mailslot_handler *dgmslot, struct ldb_message **ref_res, **dom_res; int ret; const char **services = lp_server_services(); + struct socket_address *my_ip = socket_get_my_addr(dgmslot->dgmsock->sock, packet); + if (!my_ip) { + DEBUG(0, ("Could not obtain own IP address for datagram socket\n")); + return; + } /* only answer getdc requests on the PDC or LOGON names */ if (name->type != NBT_NAME_PDC && name->type != NBT_NAME_LOGON) { @@ -181,7 +186,7 @@ static void nbtd_netlogon_getdc2(struct dgram_mailslot_handler *dgmslot, pdc->site_name2 = "Default-First-Site-Name"; pdc->unknown = 0x10; /* what is this? */ pdc->unknown2 = 2; /* and this ... */ - pdc->pdc_ip = socket_get_my_addr(dgmslot->dgmsock->sock, packet); + pdc->pdc_ip = my_ip->addr; pdc->nt_version = 13; pdc->lmnt_token = 0xFFFF; pdc->lm20_token = 0xFFFF; @@ -200,7 +205,7 @@ static void nbtd_netlogon_getdc2(struct dgram_mailslot_handler *dgmslot, */ void nbtd_mailslot_netlogon_handler(struct dgram_mailslot_handler *dgmslot, struct nbt_dgram_packet *packet, - const struct nbt_peer_socket *src) + struct socket_address *src) { NTSTATUS status = NT_STATUS_NO_MEMORY; struct nbtd_interface *iface = diff --git a/source4/nbt_server/dgram/ntlogon.c b/source4/nbt_server/dgram/ntlogon.c index 191bac8a54..dad80fbe7d 100644 --- a/source4/nbt_server/dgram/ntlogon.c +++ b/source4/nbt_server/dgram/ntlogon.c @@ -22,14 +22,14 @@ #include "includes.h" #include "nbt_server/nbt_server.h" - +#include "lib/socket/socket.h" /* reply to a SAM LOGON request */ static void nbtd_ntlogon_sam_logon(struct dgram_mailslot_handler *dgmslot, struct nbt_dgram_packet *packet, - const struct nbt_peer_socket *src, + const struct socket_address *src, struct nbt_ntlogon_packet *ntlogon) { struct nbt_name *name = &packet->data.msg.dest_name; @@ -66,7 +66,7 @@ static void nbtd_ntlogon_sam_logon(struct dgram_mailslot_handler *dgmslot, */ void nbtd_mailslot_ntlogon_handler(struct dgram_mailslot_handler *dgmslot, struct nbt_dgram_packet *packet, - const struct nbt_peer_socket *src) + struct socket_address *src) { NTSTATUS status = NT_STATUS_NO_MEMORY; struct nbtd_interface *iface = diff --git a/source4/nbt_server/dgram/request.c b/source4/nbt_server/dgram/request.c index 25b08eb5cf..7a1f7c42d8 100644 --- a/source4/nbt_server/dgram/request.c +++ b/source4/nbt_server/dgram/request.c @@ -44,7 +44,7 @@ static const struct { */ void dgram_request_handler(struct nbt_dgram_socket *dgmsock, struct nbt_dgram_packet *packet, - const struct nbt_peer_socket *src) + struct socket_address *src) { DEBUG(0,("General datagram request from %s:%d\n", src->addr, src->port)); NDR_PRINT_DEBUG(nbt_dgram_packet, packet); @@ -58,37 +58,62 @@ NTSTATUS nbtd_dgram_setup(struct nbtd_interface *iface, const char *bind_address { struct nbt_dgram_socket *bcast_dgmsock; struct nbtd_server *nbtsrv = iface->nbtsrv; + struct socket_address *bcast_addr, *bind_addr; NTSTATUS status; + TALLOC_CTX *tmp_ctx = talloc_new(iface); /* the list of mailslots that we are interested in */ int i; + if (!tmp_ctx) { + return NT_STATUS_NO_MEMORY; + } + /* listen for broadcasts on port 138 */ bcast_dgmsock = nbt_dgram_socket_init(iface, nbtsrv->task->event_ctx); - NT_STATUS_HAVE_NO_MEMORY(bcast_dgmsock); + if (!bcast_dgmsock) { + talloc_free(tmp_ctx); + return NT_STATUS_NO_MEMORY; + } - status = socket_listen(bcast_dgmsock->sock, iface->bcast_address, - lp_dgram_port(), 0, 0); + bcast_addr = socket_address_from_strings(tmp_ctx, bcast_dgmsock->sock->backend_name, + iface->bcast_address, + lp_dgram_port()); + + status = socket_listen(bcast_dgmsock->sock, bcast_addr, 0, 0); if (!NT_STATUS_IS_OK(status)) { + talloc_free(tmp_ctx); DEBUG(0,("Failed to bind to %s:%d - %s\n", iface->bcast_address, lp_dgram_port(), nt_errstr(status))); return status; } + talloc_free(bcast_addr); dgram_set_incoming_handler(bcast_dgmsock, dgram_request_handler, iface); + bind_addr = socket_address_from_strings(tmp_ctx, bcast_dgmsock->sock->backend_name, + bind_address, + lp_dgram_port()); + /* listen for unicasts on port 138 */ iface->dgmsock = nbt_dgram_socket_init(iface, nbtsrv->task->event_ctx); - NT_STATUS_HAVE_NO_MEMORY(iface->dgmsock); + if (!iface->dgmsock) { + talloc_free(tmp_ctx); + return NT_STATUS_NO_MEMORY; + } - status = socket_listen(iface->dgmsock->sock, bind_address, - lp_dgram_port(), 0, 0); + status = socket_listen(iface->dgmsock->sock, bind_addr, 0, 0); if (!NT_STATUS_IS_OK(status)) { + talloc_free(tmp_ctx); DEBUG(0,("Failed to bind to %s:%d - %s\n", bind_address, lp_dgram_port(), nt_errstr(status))); return status; } + talloc_free(bind_addr); + dgram_set_incoming_handler(iface->dgmsock, dgram_request_handler, iface); + talloc_free(tmp_ctx); + for (i=0;i<ARRAY_SIZE(mailslot_handlers);i++) { /* note that we don't need to keep the pointer diff --git a/source4/nbt_server/interfaces.c b/source4/nbt_server/interfaces.c index 41a27fdeb0..10bdc0bb14 100644 --- a/source4/nbt_server/interfaces.c +++ b/source4/nbt_server/interfaces.c @@ -33,7 +33,7 @@ */ static void nbtd_request_handler(struct nbt_name_socket *nbtsock, struct nbt_name_packet *packet, - const struct nbt_peer_socket *src) + struct socket_address *src) { struct nbtd_interface *iface = talloc_get_type(nbtsock->incoming.private, struct nbtd_interface); @@ -102,6 +102,8 @@ static NTSTATUS nbtd_add_socket(struct nbtd_server *nbtsrv, { struct nbtd_interface *iface; NTSTATUS status; + struct socket_address *bcast_address; + struct socket_address *unicast_address; /* we actually create two sockets. One listens on the broadcast address @@ -125,30 +127,49 @@ static NTSTATUS nbtd_add_socket(struct nbtd_server *nbtsrv, /* listen for broadcasts on port 137 */ bcast_nbtsock = nbt_name_socket_init(iface, nbtsrv->task->event_ctx); - NT_STATUS_HAVE_NO_MEMORY(bcast_nbtsock); + if (!bcast_nbtsock) { + talloc_free(iface); + return NT_STATUS_NO_MEMORY; + } + + bcast_address = socket_address_from_strings(bcast_nbtsock, bcast_nbtsock->sock->backend_name, + bcast, lp_nbt_port()); + if (!bcast_address) { + talloc_free(iface); + return NT_STATUS_NO_MEMORY; + } - status = socket_listen(bcast_nbtsock->sock, bcast, lp_nbt_port(), 0, 0); + status = socket_listen(bcast_nbtsock->sock, bcast_address, 0, 0); if (!NT_STATUS_IS_OK(status)) { DEBUG(0,("Failed to bind to %s:%d - %s\n", bcast, lp_nbt_port(), nt_errstr(status))); talloc_free(iface); return status; } + talloc_free(bcast_address); nbt_set_incoming_handler(bcast_nbtsock, nbtd_request_handler, iface); } /* listen for unicasts on port 137 */ iface->nbtsock = nbt_name_socket_init(iface, nbtsrv->task->event_ctx); - NT_STATUS_HAVE_NO_MEMORY(iface->nbtsock); + if (!iface->nbtsock) { + talloc_free(iface); + return NT_STATUS_NO_MEMORY; + } - status = socket_listen(iface->nbtsock->sock, bind_address, lp_nbt_port(), 0, 0); + unicast_address = socket_address_from_strings(iface->nbtsock, iface->nbtsock->sock->backend_name, + bind_address, lp_nbt_port()); + + status = socket_listen(iface->nbtsock->sock, unicast_address, 0, 0); if (!NT_STATUS_IS_OK(status)) { DEBUG(0,("Failed to bind to %s:%d - %s\n", bind_address, lp_nbt_port(), nt_errstr(status))); talloc_free(iface); return status; } + talloc_free(unicast_address); + nbt_set_incoming_handler(iface->nbtsock, nbtd_request_handler, iface); /* also setup the datagram listeners */ diff --git a/source4/nbt_server/irpc.c b/source4/nbt_server/irpc.c index b3b168a8c0..8b9c4cfcaa 100644 --- a/source4/nbt_server/irpc.c +++ b/source4/nbt_server/irpc.c @@ -25,6 +25,7 @@ #include "smbd/service_task.h" #include "nbt_server/nbt_server.h" #include "nbt_server/wins/winsserver.h" +#include "lib/socket/socket.h" /* serve out the nbt statistics @@ -57,7 +58,7 @@ struct getdc_state { static void getdc_recv_ntlogon_reply(struct dgram_mailslot_handler *dgmslot, struct nbt_dgram_packet *packet, - const struct nbt_peer_socket *src) + struct socket_address *src) { struct getdc_state *s = talloc_get_type(dgmslot->private, struct getdc_state); @@ -120,7 +121,7 @@ static NTSTATUS nbtd_getdcname(struct irpc_message *msg, struct nbt_ntlogon_packet p; struct nbt_ntlogon_sam_logon *r; struct nbt_name src, dst; - struct nbt_peer_socket dest; + struct socket_address *dest; struct dgram_mailslot_handler *handler; NTSTATUS status = NT_STATUS_UNSUCCESSFUL; @@ -152,10 +153,12 @@ static NTSTATUS nbtd_getdcname(struct irpc_message *msg, make_nbt_name_client(&src, req->in.my_computername); make_nbt_name(&dst, req->in.domainname, 0x1c); - dest.addr = req->in.ip_address; - dest.port = 138; + dest = socket_address_from_strings(msg, iface->dgmsock->sock->backend_name, + req->in.ip_address, 138); + NT_STATUS_HAVE_NO_MEMORY(dest); + status = dgram_mailslot_ntlogon_send(iface->dgmsock, DGRAM_DIRECT_GROUP, - &dst, &dest, + &dst, dest, &src, &p); if (!NT_STATUS_IS_OK(status)) { DEBUG(0, ("dgram_mailslot_ntlogon_send failed: %s\n", diff --git a/source4/nbt_server/nodestatus.c b/source4/nbt_server/nodestatus.c index efd4720790..140451d74a 100644 --- a/source4/nbt_server/nodestatus.c +++ b/source4/nbt_server/nodestatus.c @@ -24,13 +24,14 @@ #include "dlinklist.h" #include "system/network.h" #include "nbt_server/nbt_server.h" +#include "lib/socket/socket.h" /* send a name status reply */ static void nbtd_node_status_reply(struct nbt_name_socket *nbtsock, struct nbt_name_packet *request_packet, - const struct nbt_peer_socket *src, + struct socket_address *src, struct nbt_name *name, struct nbtd_interface *iface) { @@ -99,7 +100,7 @@ failed: */ void nbtd_query_status(struct nbt_name_socket *nbtsock, struct nbt_name_packet *packet, - const struct nbt_peer_socket *src) + struct socket_address *src) { struct nbt_name *name; struct nbtd_iface_name *iname; diff --git a/source4/nbt_server/packet.c b/source4/nbt_server/packet.c index d7211c8ca4..8909d7bbc4 100644 --- a/source4/nbt_server/packet.c +++ b/source4/nbt_server/packet.c @@ -22,12 +22,13 @@ #include "includes.h" #include "nbt_server/nbt_server.h" +#include "lib/socket/socket.h" /* we received a badly formed packet - log it */ void nbtd_bad_packet(struct nbt_name_packet *packet, - const struct nbt_peer_socket *src, const char *reason) + const struct socket_address *src, const char *reason) { DEBUG(2,("nbtd: bad packet '%s' from %s:%d\n", reason, src->addr, src->port)); if (DEBUGLVL(5)) { @@ -42,7 +43,7 @@ void nbtd_bad_packet(struct nbt_name_packet *packet, */ BOOL nbtd_self_packet(struct nbt_name_socket *nbtsock, struct nbt_name_packet *packet, - const struct nbt_peer_socket *src) + const struct socket_address *src) { struct nbtd_interface *iface = talloc_get_type(nbtsock->incoming.private, struct nbtd_interface); @@ -82,7 +83,7 @@ BOOL nbtd_self_packet(struct nbt_name_socket *nbtsock, */ void nbtd_name_query_reply(struct nbt_name_socket *nbtsock, struct nbt_name_packet *request_packet, - const struct nbt_peer_socket *src, + struct socket_address *src, struct nbt_name *name, uint32_t ttl, uint16_t nb_flags, const char **addresses) { @@ -146,7 +147,7 @@ failed: */ void nbtd_negative_name_query_reply(struct nbt_name_socket *nbtsock, struct nbt_name_packet *request_packet, - const struct nbt_peer_socket *src) + struct socket_address *src) { struct nbt_name_packet *packet; struct nbt_name *name = &request_packet->questions[0].name; @@ -189,7 +190,7 @@ failed: */ void nbtd_name_registration_reply(struct nbt_name_socket *nbtsock, struct nbt_name_packet *request_packet, - const struct nbt_peer_socket *src, + struct socket_address *src, uint8_t rcode) { struct nbt_name_packet *packet; @@ -237,7 +238,7 @@ failed: */ void nbtd_name_release_reply(struct nbt_name_socket *nbtsock, struct nbt_name_packet *request_packet, - const struct nbt_peer_socket *src, + struct socket_address *src, uint8_t rcode) { struct nbt_name_packet *packet; @@ -283,7 +284,7 @@ failed: */ void nbtd_wack_reply(struct nbt_name_socket *nbtsock, struct nbt_name_packet *request_packet, - const struct nbt_peer_socket *src, + struct socket_address *src, uint32_t ttl) { struct nbt_name_packet *packet; diff --git a/source4/nbt_server/query.c b/source4/nbt_server/query.c index 793e4671d5..078a876c8e 100644 --- a/source4/nbt_server/query.c +++ b/source4/nbt_server/query.c @@ -25,13 +25,14 @@ #include "system/network.h" #include "nbt_server/nbt_server.h" #include "nbt_server/wins/winsserver.h" +#include "lib/socket/socket.h" /* answer a name query */ void nbtd_request_query(struct nbt_name_socket *nbtsock, struct nbt_name_packet *packet, - const struct nbt_peer_socket *src) + struct socket_address *src) { struct nbtd_iface_name *iname; struct nbt_name *name; diff --git a/source4/nbt_server/wins/wins_dns_proxy.c b/source4/nbt_server/wins/wins_dns_proxy.c index 23dfa19cc6..540f4e2c38 100644 --- a/source4/nbt_server/wins/wins_dns_proxy.c +++ b/source4/nbt_server/wins/wins_dns_proxy.c @@ -31,7 +31,7 @@ struct wins_dns_proxy_state { struct nbt_name_socket *nbtsock; struct nbt_name_packet *packet; - struct nbt_peer_socket src; + struct socket_address *src; }; static void nbtd_wins_dns_proxy_handler(struct composite_context *creq) @@ -53,11 +53,11 @@ static void nbtd_wins_dns_proxy_handler(struct composite_context *creq) talloc_steal(s->packet, addresses); if (!addresses) goto notfound; - nbtd_name_query_reply(s->nbtsock, s->packet, &s->src, name, + nbtd_name_query_reply(s->nbtsock, s->packet, s->src, name, 0, nb_flags, addresses); return; notfound: - nbtd_negative_name_query_reply(s->nbtsock, s->packet, &s->src); + nbtd_negative_name_query_reply(s->nbtsock, s->packet, s->src); } /* @@ -65,7 +65,7 @@ notfound: */ void nbtd_wins_dns_proxy_query(struct nbt_name_socket *nbtsock, struct nbt_name_packet *packet, - const struct nbt_peer_socket *src) + struct socket_address *src) { struct nbt_name *name = &packet->questions[0].name; struct nbtd_interface *iface = talloc_get_type(nbtsock->incoming.private, @@ -81,8 +81,10 @@ void nbtd_wins_dns_proxy_query(struct nbt_name_socket *nbtsock, if (!s) goto failed; s->nbtsock = nbtsock; s->packet = talloc_steal(s, packet); - s->src = *src; - talloc_steal(s, src->addr); + s->src = src; + if (!talloc_reference(s, src)) { + goto failed; + } creq = resolve_name_send(name, iface->nbtsrv->task->event_ctx, methods); if (!creq) goto failed; diff --git a/source4/nbt_server/wins/winsserver.c b/source4/nbt_server/wins/winsserver.c index 98ae613905..8760ffe922 100644 --- a/source4/nbt_server/wins/winsserver.c +++ b/source4/nbt_server/wins/winsserver.c @@ -28,6 +28,7 @@ #include "system/time.h" #include "libcli/composite/composite.h" #include "smbd/service_task.h" +#include "lib/socket/socket.h" /* work out the ttl we will use given a client requested ttl @@ -59,7 +60,7 @@ static enum wrepl_name_type wrepl_type(uint16_t nb_flags, struct nbt_name *name, */ static uint8_t wins_register_new(struct nbt_name_socket *nbtsock, struct nbt_name_packet *packet, - const struct nbt_peer_socket *src, + const struct socket_address *src, enum wrepl_name_type type) { struct nbtd_interface *iface = talloc_get_type(nbtsock->incoming.private, @@ -109,7 +110,7 @@ static uint8_t wins_update_ttl(struct nbt_name_socket *nbtsock, struct nbt_name_packet *packet, struct winsdb_record *rec, struct winsdb_addr *winsdb_addr, - const struct nbt_peer_socket *src) + const struct socket_address *src) { struct nbtd_interface *iface = talloc_get_type(nbtsock->incoming.private, struct nbtd_interface); @@ -143,7 +144,7 @@ static uint8_t wins_sgroup_merge(struct nbt_name_socket *nbtsock, struct nbt_name_packet *packet, struct winsdb_record *rec, const char *address, - const struct nbt_peer_socket *src) + const struct socket_address *src) { struct nbtd_interface *iface = talloc_get_type(nbtsock->incoming.private, struct nbtd_interface); @@ -170,7 +171,7 @@ struct wack_state { struct nbt_name_socket *nbtsock; struct nbt_name_packet *request_packet; struct winsdb_record *rec; - struct nbt_peer_socket src; + struct socket_address *src; const char *reg_address; enum wrepl_name_type new_type; struct wins_challenge_io io; @@ -183,9 +184,9 @@ struct wack_state { static void wins_wack_deny(struct wack_state *s) { nbtd_name_registration_reply(s->nbtsock, s->request_packet, - &s->src, NBT_RCODE_ACT); + s->src, NBT_RCODE_ACT); DEBUG(4,("WINS: denied name registration request for %s from %s:%d\n", - nbt_name_string(s, s->rec->name), s->src.addr, s->src.port)); + nbt_name_string(s, s->rec->name), s->src->addr, s->src->port)); talloc_free(s); } @@ -217,7 +218,7 @@ static void wins_wack_allow(struct wack_state *s) uint8_t rcode; winsdb_delete(s->winssrv->wins_db, rec); - rcode = wins_register_new(s->nbtsock, s->request_packet, &s->src, s->new_type); + rcode = wins_register_new(s->nbtsock, s->request_packet, s->src, s->new_type); if (rcode != NBT_RCODE_OK) { DEBUG(1,("WINS: record %s failed to register as new during WACK\n", nbt_name_string(s, rec->name))); @@ -228,7 +229,7 @@ static void wins_wack_allow(struct wack_state *s) } rec->expire_time = time(NULL) + ttl; - rec->registered_by = s->src.addr; + rec->registered_by = s->src->addr; /* * now remove all addresses that're the client doesn't hold anymore @@ -269,7 +270,7 @@ static void wins_wack_allow(struct wack_state *s) done: nbtd_name_registration_reply(s->nbtsock, s->request_packet, - &s->src, NBT_RCODE_OK); + s->src, NBT_RCODE_OK); failed: talloc_free(s); } @@ -332,7 +333,7 @@ static void wack_wins_challenge_handler(struct composite_context *c_req) static void wins_register_wack(struct nbt_name_socket *nbtsock, struct nbt_name_packet *packet, struct winsdb_record *rec, - const struct nbt_peer_socket *src, + struct socket_address *src, enum wrepl_name_type new_type) { struct nbtd_interface *iface = talloc_get_type(nbtsock->incoming.private, @@ -352,9 +353,8 @@ static void wins_register_wack(struct nbt_name_socket *nbtsock, s->rec = talloc_steal(s, rec); s->reg_address = packet->additional[0].rdata.netbios.addresses[0].ipaddr; s->new_type = new_type; - s->src.port = src->port; - s->src.addr = talloc_strdup(s, src->addr); - if (s->src.addr == NULL) goto failed; + s->src = src; + if (talloc_reference(s, src) == NULL) goto failed; s->io.in.nbtd_server = iface->nbtsrv; s->io.in.event_ctx = iface->nbtsrv->task->event_ctx; @@ -390,7 +390,7 @@ failed: */ static void nbtd_winsserver_register(struct nbt_name_socket *nbtsock, struct nbt_name_packet *packet, - const struct nbt_peer_socket *src) + struct socket_address *src) { NTSTATUS status; struct nbtd_interface *iface = talloc_get_type(nbtsock->incoming.private, @@ -548,7 +548,7 @@ done: */ static void nbtd_winsserver_query(struct nbt_name_socket *nbtsock, struct nbt_name_packet *packet, - const struct nbt_peer_socket *src) + struct socket_address *src) { NTSTATUS status; struct nbtd_interface *iface = talloc_get_type(nbtsock->incoming.private, @@ -656,7 +656,7 @@ notfound: */ static void nbtd_winsserver_release(struct nbt_name_socket *nbtsock, struct nbt_name_packet *packet, - const struct nbt_peer_socket *src) + struct socket_address *src) { NTSTATUS status; struct nbtd_interface *iface = talloc_get_type(nbtsock->incoming.private, @@ -699,6 +699,12 @@ static void nbtd_winsserver_release(struct nbt_name_socket *nbtsock, * silently ignored */ if (!winsdb_addr_list_check(rec->addresses, src->addr)) { + int i; + DEBUG(4,("WINS: silently ignoring attempted name release on %s from %s\n", nbt_name_string(rec, rec->name), src->addr)); + DEBUGADD(4, ("Registered Addressss: \n")); + for (i=0; rec->addresses && rec->addresses[i]; i++) { + DEBUGADD(4, ("%s\n", rec->addresses[i]->address)); + } goto done; } @@ -766,7 +772,7 @@ done: */ void nbtd_winsserver_request(struct nbt_name_socket *nbtsock, struct nbt_name_packet *packet, - const struct nbt_peer_socket *src) + struct socket_address *src) { struct nbtd_interface *iface = talloc_get_type(nbtsock->incoming.private, struct nbtd_interface); diff --git a/source4/rpc_server/spoolss/dcesrv_spoolss.c b/source4/rpc_server/spoolss/dcesrv_spoolss.c index 6936866fcc..e5bcc35081 100644 --- a/source4/rpc_server/spoolss/dcesrv_spoolss.c +++ b/source4/rpc_server/spoolss/dcesrv_spoolss.c @@ -144,7 +144,7 @@ static WERROR spoolss_check_server_name(struct dcesrv_call_state *dce_call, const char *server_name) { BOOL ret; - char *str; + struct socket_address *myaddr; /* NULL is ok */ if (!server_name) return WERR_OK; @@ -173,6 +173,8 @@ static WERROR spoolss_check_server_name(struct dcesrv_call_state *dce_call, * TODO: we need to check if aliases are also ok */ if (lp_realm()) { + char *str; + str = talloc_asprintf(mem_ctx, "%s.%s", lp_netbios_name(), lp_realm()); @@ -183,11 +185,11 @@ static WERROR spoolss_check_server_name(struct dcesrv_call_state *dce_call, if (ret) return WERR_OK; } - str = socket_get_my_addr(dce_call->conn->srv_conn->socket, mem_ctx); - W_ERROR_HAVE_NO_MEMORY(str); + myaddr = socket_get_my_addr(dce_call->conn->srv_conn->socket, mem_ctx); + W_ERROR_HAVE_NO_MEMORY(myaddr); - ret = strequal(str, server_name); - talloc_free(str); + ret = strequal(myaddr->addr, server_name); + talloc_free(myaddr); if (ret) return WERR_OK; return WERR_INVALID_PRINTER_NAME; diff --git a/source4/scripting/ejs/smbcalls_auth.c b/source4/scripting/ejs/smbcalls_auth.c index 3ec376f4fe..c79f2af0ac 100644 --- a/source4/scripting/ejs/smbcalls_auth.c +++ b/source4/scripting/ejs/smbcalls_auth.c @@ -28,7 +28,7 @@ static int ejs_doauth(MprVarHandle eid, TALLOC_CTX *tmp_ctx, struct MprVar *auth, const char *username, - const char *password, const char *domain, const char *remote_host, + const char *password, const char *domain, const char *workstation, const char *authtype) { struct auth_usersupplied_info *user_info = NULL; @@ -61,9 +61,9 @@ static int ejs_doauth(MprVarHandle eid, user_info->client.domain_name = domain; user_info->mapped.domain_name = domain; - user_info->workstation_name = remote_host; + user_info->workstation_name = workstation; - user_info->remote_host = remote_host; + user_info->remote_host = NULL; user_info->password_state = AUTH_PASSWORD_PLAIN; user_info->password.plaintext = talloc_strdup(user_info, password); @@ -101,13 +101,6 @@ done: /* perform user authentication, returning an array of results - syntax: - var authinfo = new Object(); - authinfo.username = myname; - authinfo.password = mypass; - authinfo.domain = mydom; - authinfo.rhost = request['REMOTE_HOST']; - auth = userAuth(authinfo); */ static int ejs_userAuth(MprVarHandle eid, int argc, struct MprVar **argv) { @@ -115,7 +108,7 @@ static int ejs_userAuth(MprVarHandle eid, int argc, struct MprVar **argv) const char *username; const char *password; const char *domain; - const char *remote_host; + const char *workstation; struct MprVar auth; struct cli_credentials *creds; @@ -136,7 +129,7 @@ static int ejs_userAuth(MprVarHandle eid, int argc, struct MprVar **argv) username = cli_credentials_get_username(creds); password = cli_credentials_get_password(creds); domain = cli_credentials_get_domain(creds); - remote_host = cli_credentials_get_workstation(creds); + workstation = cli_credentials_get_workstation(creds); if (username == NULL || password == NULL || domain == NULL) { mpr_Return(eid, mprCreateUndefinedVar()); @@ -147,9 +140,9 @@ static int ejs_userAuth(MprVarHandle eid, int argc, struct MprVar **argv) auth = mprObject("auth"); if (domain && (strcmp("System User", domain) == 0)) { - ejs_doauth(eid, tmp_ctx, &auth, username, password, domain, remote_host, "unix"); + ejs_doauth(eid, tmp_ctx, &auth, username, password, domain, workstation, "unix"); } else { - ejs_doauth(eid, tmp_ctx, &auth, username, password, domain, remote_host, "sam"); + ejs_doauth(eid, tmp_ctx, &auth, username, password, domain, workstation, "sam"); } mpr_Return(eid, auth); diff --git a/source4/smb_server/management.c b/source4/smb_server/management.c index 19e2090682..bb153d3c5e 100644 --- a/source4/smb_server/management.c +++ b/source4/smb_server/management.c @@ -48,10 +48,19 @@ static NTSTATUS smbsrv_session_information(struct irpc_message *msg, for (sess=smb_conn->sessions.list; sess; sess=sess->next) { struct smbsrv_session_info *info = &r->out.info.sessions.sessions[i]; + struct socket_address *client_addr; + client_addr = socket_get_peer_addr(smb_conn->connection->socket, r); + + if (client_addr) { + info->client_ip = client_addr->addr; + } else { + info->client_ip = NULL; + } + info->vuid = sess->vuid; info->account_name = sess->session_info->server_info->account_name; info->domain_name = sess->session_info->server_info->domain_name; - info->client_ip = socket_get_peer_addr(smb_conn->connection->socket, r); + info->connect_time = timeval_to_nttime(&sess->statistics.connect_time); info->auth_time = timeval_to_nttime(&sess->statistics.auth_time); i++; @@ -81,10 +90,18 @@ static NTSTATUS smbsrv_tcon_information(struct irpc_message *msg, for (tcon=smb_conn->smb_tcons.list; tcon; tcon=tcon->next) { struct smbsrv_tcon_info *info = &r->out.info.tcons.tcons[i]; + struct socket_address *client_addr; + client_addr = socket_get_peer_addr(smb_conn->connection->socket, r); + + if (client_addr) { + info->client_ip = client_addr->addr; + } else { + info->client_ip = NULL; + } + info->tid = tcon->tid; info->share_name = lp_servicename(tcon->service); info->connect_time = timeval_to_nttime(&tcon->statistics.connect_time); - info->client_ip = socket_get_peer_addr(smb_conn->connection->socket, r); i++; } diff --git a/source4/smb_server/smb/sesssetup.c b/source4/smb_server/smb/sesssetup.c index 4bafc6cbf4..225f0f7c47 100644 --- a/source4/smb_server/smb/sesssetup.c +++ b/source4/smb_server/smb/sesssetup.c @@ -1,3 +1,4 @@ + /* Unix SMB/CIFS implementation. handle SMBsessionsetup @@ -50,6 +51,7 @@ static NTSTATUS sesssetup_old(struct smbsrv_request *req, union smb_sesssetup *s struct auth_serversupplied_info *server_info = NULL; struct auth_session_info *session_info; struct smbsrv_session *smb_sess; + struct socket_address *remote_address; const char *remote_machine = NULL; sess->old.out.vuid = 0; @@ -63,8 +65,11 @@ static NTSTATUS sesssetup_old(struct smbsrv_request *req, union smb_sesssetup *s remote_machine = req->smb_conn->negotiate.calling_name->name; } + remote_address = socket_get_peer_addr(req->smb_conn->connection->socket, req); + NT_STATUS_HAVE_NO_MEMORY(remote_address); + if (!remote_machine) { - remote_machine = socket_get_peer_addr(req->smb_conn->connection->socket, req); + remote_machine = remote_address->addr; } user_info = talloc(req, struct auth_usersupplied_info); @@ -76,7 +81,7 @@ static NTSTATUS sesssetup_old(struct smbsrv_request *req, union smb_sesssetup *s user_info->client.account_name = sess->old.in.user; user_info->client.domain_name = sess->old.in.domain; user_info->workstation_name = remote_machine; - user_info->remote_host = socket_get_peer_addr(req->smb_conn->connection->socket, user_info); + user_info->remote_host = talloc_steal(user_info, remote_address); user_info->password_state = AUTH_PASSWORD_RESPONSE; user_info->password.response.lanman = sess->old.in.password; @@ -133,6 +138,7 @@ static NTSTATUS sesssetup_nt1(struct smbsrv_request *req, union smb_sesssetup *s struct auth_serversupplied_info *server_info = NULL; struct auth_session_info *session_info; struct smbsrv_session *smb_sess; + struct socket_address *remote_address; const char *remote_machine = NULL; sess->nt1.out.vuid = 0; @@ -163,10 +169,13 @@ static NTSTATUS sesssetup_nt1(struct smbsrv_request *req, union smb_sesssetup *s remote_machine = req->smb_conn->negotiate.calling_name->name; } + remote_address = socket_get_peer_addr(req->smb_conn->connection->socket, req); + NT_STATUS_HAVE_NO_MEMORY(remote_address); + if (!remote_machine) { - remote_machine = socket_get_peer_addr(req->smb_conn->connection->socket, req); + remote_machine = remote_address->addr; } - + user_info = talloc(req, struct auth_usersupplied_info); NT_STATUS_HAVE_NO_MEMORY(user_info); @@ -176,7 +185,7 @@ static NTSTATUS sesssetup_nt1(struct smbsrv_request *req, union smb_sesssetup *s user_info->client.account_name = sess->nt1.in.user; user_info->client.domain_name = sess->nt1.in.domain; user_info->workstation_name = remote_machine; - user_info->remote_host = socket_get_peer_addr(req->smb_conn->connection->socket, user_info); + user_info->remote_host = talloc_steal(user_info, remote_address); user_info->password_state = AUTH_PASSWORD_RESPONSE; user_info->password.response.lanman = sess->nt1.in.password1; diff --git a/source4/smb_server/tcon.c b/source4/smb_server/tcon.c index 1c934baf8c..e0def0ab3f 100644 --- a/source4/smb_server/tcon.c +++ b/source4/smb_server/tcon.c @@ -94,8 +94,10 @@ static int smbsrv_tcon_destructor(void *ptr) struct smbsrv_tcon *tcon = talloc_get_type(ptr, struct smbsrv_tcon); struct smbsrv_tcons_context *tcons_ctx; + struct socket_address *client_addr; + client_addr = socket_get_peer_addr(tcon->smb_conn->connection->socket, ptr); DEBUG(3,("%s closed connection to service %s\n", - socket_get_peer_addr(tcon->smb_conn->connection->socket, tcon), + client_addr ? client_addr->addr : "(unknown)", lp_servicename(tcon->service))); /* tell the ntvfs backend that we are disconnecting */ diff --git a/source4/smbd/service_stream.c b/source4/smbd/service_stream.c index b3d5fefb99..13cb570e0c 100644 --- a/source4/smbd/service_stream.c +++ b/source4/smbd/service_stream.c @@ -210,6 +210,7 @@ NTSTATUS stream_setup_socket(struct event_context *event_context, { NTSTATUS status; struct stream_socket *stream_socket; + struct socket_address *socket_address; int i; stream_socket = talloc_zero(event_context, struct stream_socket); @@ -231,15 +232,25 @@ NTSTATUS stream_setup_socket(struct event_context *event_context, if (*port == 0) { for (i=SERVER_TCP_LOW_PORT;i<= SERVER_TCP_HIGH_PORT;i++) { - status = socket_listen(stream_socket->sock, sock_addr, i, + socket_address = socket_address_from_strings(stream_socket, + stream_socket->sock->backend_name, + sock_addr, i); + NT_STATUS_HAVE_NO_MEMORY(socket_address); + status = socket_listen(stream_socket->sock, socket_address, SERVER_LISTEN_BACKLOG, 0); + talloc_free(socket_address); if (NT_STATUS_IS_OK(status)) { *port = i; break; } } } else { - status = socket_listen(stream_socket->sock, sock_addr, *port, SERVER_LISTEN_BACKLOG, 0); + socket_address = socket_address_from_strings(stream_socket, + stream_socket->sock->backend_name, + sock_addr, *port); + NT_STATUS_HAVE_NO_MEMORY(socket_address); + status = socket_listen(stream_socket->sock, socket_address, SERVER_LISTEN_BACKLOG, 0); + talloc_free(socket_address); } if (!NT_STATUS_IS_OK(status)) { diff --git a/source4/torture/local/messaging.c b/source4/torture/local/messaging.c index faba8304d7..0d4dfc49a8 100644 --- a/source4/torture/local/messaging.c +++ b/source4/torture/local/messaging.c @@ -56,8 +56,8 @@ static void exit_message(struct messaging_context *msg, void *private, static BOOL test_ping_speed(TALLOC_CTX *mem_ctx) { struct event_context *ev; - struct messaging_context *msg_ctx; - struct messaging_context *msg_ctx2; + struct messaging_context *msg_client_ctx; + struct messaging_context *msg_server_ctx; int ping_count = 0; int pong_count = 0; BOOL ret = True; @@ -68,23 +68,25 @@ static BOOL test_ping_speed(TALLOC_CTX *mem_ctx) ev = event_context_init(mem_ctx); - msg_ctx2 = messaging_init(mem_ctx, 1, ev); + msg_server_ctx = messaging_init(mem_ctx, 1, ev); - if (!msg_ctx2) { - exit(1); + if (!msg_server_ctx) { + printf("Failed to init ping messaging context\n"); + talloc_free(mem_ctx); + return False; } - messaging_register(msg_ctx2, NULL, MY_PING, ping_message); - messaging_register(msg_ctx2, mem_ctx, MY_EXIT, exit_message); + messaging_register(msg_server_ctx, NULL, MY_PING, ping_message); + messaging_register(msg_server_ctx, mem_ctx, MY_EXIT, exit_message); - msg_ctx = messaging_init(mem_ctx, 2, ev); + msg_client_ctx = messaging_init(mem_ctx, 2, ev); - if (!msg_ctx) { - printf("messaging_init() failed\n"); + if (!msg_client_ctx) { + printf("msg_client_ctx messaging_init() failed\n"); return False; } - messaging_register(msg_ctx, &pong_count, MY_PONG, pong_message); + messaging_register(msg_client_ctx, &pong_count, MY_PONG, pong_message); tv = timeval_current(); @@ -96,8 +98,8 @@ static BOOL test_ping_speed(TALLOC_CTX *mem_ctx) data.data = discard_const_p(uint8_t, "testing"); data.length = strlen((const char *)data.data); - status1 = messaging_send(msg_ctx, 1, MY_PING, &data); - status2 = messaging_send(msg_ctx, 1, MY_PING, NULL); + status1 = messaging_send(msg_client_ctx, 1, MY_PING, &data); + status2 = messaging_send(msg_client_ctx, 1, MY_PING, NULL); if (!NT_STATUS_IS_OK(status1)) { printf("msg1 failed - %s\n", nt_errstr(status1)); @@ -123,7 +125,7 @@ static BOOL test_ping_speed(TALLOC_CTX *mem_ctx) } printf("sending exit\n"); - messaging_send(msg_ctx, 1, MY_EXIT, NULL); + messaging_send(msg_client_ctx, 1, MY_EXIT, NULL); if (ping_count != pong_count) { printf("ping test failed! received %d, sent %d\n", @@ -134,7 +136,8 @@ static BOOL test_ping_speed(TALLOC_CTX *mem_ctx) printf("ping rate of %.0f messages/sec\n", (ping_count+pong_count)/timeval_elapsed(&tv)); - talloc_free(msg_ctx); + talloc_free(msg_client_ctx); + talloc_free(msg_server_ctx); talloc_free(ev); diff --git a/source4/torture/local/socket.c b/source4/torture/local/socket.c index 4a3a339333..195354611f 100644 --- a/source4/torture/local/socket.c +++ b/source4/torture/local/socket.c @@ -40,8 +40,7 @@ static BOOL test_udp(TALLOC_CTX *mem_ctx) { struct socket_context *sock1, *sock2; NTSTATUS status; - int srv_port, from_port; - const char *srv_addr, *from_addr; + struct socket_address *srv_addr, *from_addr, *localhost; size_t size = 100 + (random() % 100); DATA_BLOB blob, blob2; size_t sent, nread; @@ -57,33 +56,38 @@ static BOOL test_udp(TALLOC_CTX *mem_ctx) CHECK_STATUS(status, NT_STATUS_OK); talloc_steal(mem_ctx, sock2); - status = socket_listen(sock1, iface_best_ip("127.0.0.1"), 0, 0, 0); + localhost = socket_address_from_strings(sock1, sock1->backend_name, + iface_best_ip("127.0.0.1"), 0); + if (!localhost) { + return False; + } + + status = socket_listen(sock1, localhost, 0, 0); CHECK_STATUS(status, NT_STATUS_OK); srv_addr = socket_get_my_addr(sock1, mem_ctx); - if (srv_addr == NULL || strcmp(srv_addr, iface_best_ip("127.0.0.1")) != 0) { + if (srv_addr == NULL || strcmp(srv_addr->addr, iface_best_ip("127.0.0.1")) != 0) { printf("Expected server address of %s but got %s\n", - iface_best_ip("127.0.0.1"), srv_addr); + iface_best_ip("127.0.0.1"), srv_addr ? srv_addr->addr : NULL); return False; } - srv_port = socket_get_my_port(sock1); - printf("server port is %d\n", srv_port); + printf("server port is %d\n", srv_addr->port); blob = data_blob_talloc(mem_ctx, NULL, size); blob2 = data_blob_talloc(mem_ctx, NULL, size); generate_random_buffer(blob.data, blob.length); sent = size; - status = socket_sendto(sock2, &blob, &sent, 0, srv_addr, srv_port); + status = socket_sendto(sock2, &blob, &sent, 0, srv_addr); CHECK_STATUS(status, NT_STATUS_OK); status = socket_recvfrom(sock1, blob2.data, size, &nread, 0, - &from_addr, &from_port); + sock1, &from_addr); CHECK_STATUS(status, NT_STATUS_OK); - if (strcmp(from_addr, srv_addr) != 0) { - printf("Unexpected recvfrom addr %s\n", from_addr); + if (strcmp(from_addr->addr, srv_addr->addr) != 0) { + printf("Unexpected recvfrom addr %s\n", from_addr->addr); ret = False; } if (nread != size) { @@ -97,23 +101,23 @@ static BOOL test_udp(TALLOC_CTX *mem_ctx) } generate_random_buffer(blob.data, blob.length); - status = socket_sendto(sock1, &blob, &sent, 0, from_addr, from_port); + status = socket_sendto(sock1, &blob, &sent, 0, from_addr); CHECK_STATUS(status, NT_STATUS_OK); status = socket_recvfrom(sock2, blob2.data, size, &nread, 0, - &from_addr, &from_port); + sock2, &from_addr); CHECK_STATUS(status, NT_STATUS_OK); - if (strcmp(from_addr, srv_addr) != 0) { - printf("Unexpected recvfrom addr %s\n", from_addr); + if (strcmp(from_addr->addr, srv_addr->addr) != 0) { + printf("Unexpected recvfrom addr %s\n", from_addr->addr); ret = False; } if (nread != size) { printf("Unexpected recvfrom size %d should be %d\n", (int)nread, (int)size); ret = False; } - if (from_port != srv_port) { + if (from_addr->port != srv_addr->port) { printf("Unexpected recvfrom port %d should be %d\n", - from_port, srv_port); + from_addr->port, srv_addr->port); ret = False; } if (memcmp(blob2.data, blob.data, size) != 0) { @@ -135,8 +139,7 @@ static BOOL test_tcp(TALLOC_CTX *mem_ctx) { struct socket_context *sock1, *sock2, *sock3; NTSTATUS status; - int srv_port, from_port; - const char *srv_addr, *from_addr; + struct socket_address *srv_addr, *from_addr, *localhost; size_t size = 100 + (random() % 100); DATA_BLOB blob, blob2; size_t sent, nread; @@ -153,20 +156,30 @@ static BOOL test_tcp(TALLOC_CTX *mem_ctx) CHECK_STATUS(status, NT_STATUS_OK); talloc_steal(mem_ctx, sock2); - status = socket_listen(sock1, iface_best_ip("127.0.0.1"), 0, 0, 0); + localhost = socket_address_from_strings(sock1, sock1->backend_name, + iface_best_ip("127.0.0.1"), 0); + if (!localhost) { + return False; + } + + status = socket_listen(sock1, localhost, 0, 0); CHECK_STATUS(status, NT_STATUS_OK); srv_addr = socket_get_my_addr(sock1, mem_ctx); - if (srv_addr == NULL || strcmp(srv_addr, iface_best_ip("127.0.0.1")) != 0) { + if (srv_addr == NULL || !srv_addr->addr) { + printf("Unexpected socket_get_my_addr NULL\n"); + return False; + } + + if (strcmp(srv_addr->addr, iface_best_ip("127.0.0.1")) != 0) { printf("Expected server address of %s but got %s\n", - iface_best_ip("127.0.0.1"), srv_addr); + iface_best_ip("127.0.0.1"), srv_addr ? srv_addr->addr : NULL); return False; } - srv_port = socket_get_my_port(sock1); - printf("server port is %d\n", srv_port); + printf("server port is %d\n", srv_addr->port); - status = socket_connect_ev(sock2, NULL, 0, srv_addr, srv_port, 0, ev); + status = socket_connect_ev(sock2, NULL, srv_addr, 0, ev); CHECK_STATUS(status, NT_STATUS_OK); status = socket_accept(sock1, &sock3); @@ -186,10 +199,13 @@ static BOOL test_tcp(TALLOC_CTX *mem_ctx) CHECK_STATUS(status, NT_STATUS_OK); from_addr = socket_get_peer_addr(sock3, mem_ctx); - from_port = socket_get_peer_port(sock3); - if (strcmp(from_addr, srv_addr) != 0) { - printf("Unexpected recvfrom addr %s\n", from_addr); + if (!from_addr || !from_addr->addr) { + printf("Unexpected recvfrom addr NULL\n"); + return False; + } + if (strcmp(from_addr->addr, srv_addr->addr) != 0) { + printf("Unexpected recvfrom addr %s\n", from_addr ? from_addr->addr : NULL); ret = False; } if (nread != size) { @@ -210,19 +226,22 @@ static BOOL test_tcp(TALLOC_CTX *mem_ctx) CHECK_STATUS(status, NT_STATUS_OK); from_addr = socket_get_peer_addr(sock2, mem_ctx); - from_port = socket_get_peer_port(sock2); - if (strcmp(from_addr, srv_addr) != 0) { - printf("Unexpected recvfrom addr %s\n", from_addr); + if (!from_addr || !from_addr->addr) { + printf("Unexpected recvfrom addr NULL\n"); + return False; + } + if (strcmp(from_addr->addr, srv_addr->addr) != 0) { + printf("Unexpected recvfrom addr %s\n", from_addr ? from_addr->addr : NULL); ret = False; } if (nread != size) { printf("Unexpected recvfrom size %d should be %d\n", (int)nread, (int)size); ret = False; } - if (from_port != srv_port) { + if (from_addr->port != srv_addr->port) { printf("Unexpected recvfrom port %d should be %d\n", - from_port, srv_port); + from_addr->port, srv_addr->port); ret = False; } if (memcmp(blob2.data, blob.data, size) != 0) { diff --git a/source4/torture/nbt/dgram.c b/source4/torture/nbt/dgram.c index 64d4825edc..821a169314 100644 --- a/source4/torture/nbt/dgram.c +++ b/source4/torture/nbt/dgram.c @@ -33,7 +33,7 @@ */ static void netlogon_handler(struct dgram_mailslot_handler *dgmslot, struct nbt_dgram_packet *packet, - const struct nbt_peer_socket *src) + struct socket_address *src) { NTSTATUS status; struct nbt_netlogon_packet netlogon; @@ -60,7 +60,7 @@ static BOOL nbt_test_netlogon(TALLOC_CTX *mem_ctx, { struct dgram_mailslot_handler *dgmslot; struct nbt_dgram_socket *dgmsock = nbt_dgram_socket_init(mem_ctx, NULL); - struct nbt_peer_socket dest; + struct socket_address *dest; const char *myaddress = talloc_strdup(dgmsock, iface_best_ip(address)); struct nbt_netlogon_packet logon; struct nbt_name myname; @@ -68,13 +68,28 @@ static BOOL nbt_test_netlogon(TALLOC_CTX *mem_ctx, struct timeval tv = timeval_current(); int replies = 0; + struct socket_address *socket_address; + + socket_address = socket_address_from_strings(dgmsock, dgmsock->sock->backend_name, + myaddress, lp_dgram_port()); + if (!socket_address) { + return False; + } + /* try receiving replies on port 138 first, which will only work if we are root and smbd/nmbd are not running - fall back to listening on any port, which means replies from some windows versions won't be seen */ - status = socket_listen(dgmsock->sock, myaddress, lp_dgram_port(), 0, 0); + status = socket_listen(dgmsock->sock, socket_address, 0, 0); if (!NT_STATUS_IS_OK(status)) { - socket_listen(dgmsock->sock, myaddress, 0, 0, 0); + talloc_free(socket_address); + socket_address = socket_address_from_strings(dgmsock, dgmsock->sock->backend_name, + myaddress, 0); + if (!socket_address) { + return False; + } + + socket_listen(dgmsock->sock, socket_address, 0, 0); } /* setup a temporary mailslot listener for replies */ @@ -92,9 +107,13 @@ static BOOL nbt_test_netlogon(TALLOC_CTX *mem_ctx, make_nbt_name_client(&myname, TEST_NAME); - dest.port = 0; - dest.addr = address; - status = dgram_mailslot_netlogon_send(dgmsock, &name, &dest, + dest = socket_address_from_strings(dgmsock, dgmsock->sock->backend_name, + address, 0); + if (!dest) { + return False; + } + + status = dgram_mailslot_netlogon_send(dgmsock, &name, dest, &myname, &logon); if (!NT_STATUS_IS_OK(status)) { printf("Failed to send netlogon request - %s\n", nt_errstr(status)); @@ -120,7 +139,7 @@ static BOOL nbt_test_netlogon2(TALLOC_CTX *mem_ctx, { struct dgram_mailslot_handler *dgmslot; struct nbt_dgram_socket *dgmsock = nbt_dgram_socket_init(mem_ctx, NULL); - struct nbt_peer_socket dest; + struct socket_address *dest; const char *myaddress = talloc_strdup(dgmsock, iface_best_ip(address)); struct nbt_netlogon_packet logon; struct nbt_name myname; @@ -128,13 +147,28 @@ static BOOL nbt_test_netlogon2(TALLOC_CTX *mem_ctx, struct timeval tv = timeval_current(); int replies = 0; + struct socket_address *socket_address; + + socket_address = socket_address_from_strings(dgmsock, dgmsock->sock->backend_name, + myaddress, lp_dgram_port()); + if (!socket_address) { + return False; + } + /* try receiving replies on port 138 first, which will only work if we are root and smbd/nmbd are not running - fall back to listening on any port, which means replies from some windows versions won't be seen */ - status = socket_listen(dgmsock->sock, myaddress, lp_dgram_port(), 0, 0); + status = socket_listen(dgmsock->sock, socket_address, 0, 0); if (!NT_STATUS_IS_OK(status)) { - socket_listen(dgmsock->sock, myaddress, 0, 0, 0); + talloc_free(socket_address); + socket_address = socket_address_from_strings(dgmsock, dgmsock->sock->backend_name, + myaddress, 0); + if (!socket_address) { + return False; + } + + socket_listen(dgmsock->sock, socket_address, 0, 0); } /* setup a temporary mailslot listener for replies */ @@ -154,9 +188,12 @@ static BOOL nbt_test_netlogon2(TALLOC_CTX *mem_ctx, make_nbt_name_client(&myname, TEST_NAME); - dest.port = 0; - dest.addr = address; - status = dgram_mailslot_netlogon_send(dgmsock, &name, &dest, + dest = socket_address_from_strings(dgmsock, dgmsock->sock->backend_name, + address, 0); + if (!dest) { + goto failed; + } + status = dgram_mailslot_netlogon_send(dgmsock, &name, dest, &myname, &logon); if (!NT_STATUS_IS_OK(status)) { printf("Failed to send netlogon request - %s\n", nt_errstr(status)); @@ -182,7 +219,7 @@ failed: */ static void ntlogon_handler(struct dgram_mailslot_handler *dgmslot, struct nbt_dgram_packet *packet, - const struct nbt_peer_socket *src) + struct socket_address *src) { NTSTATUS status; struct nbt_ntlogon_packet ntlogon; @@ -209,36 +246,52 @@ static BOOL nbt_test_ntlogon(TALLOC_CTX *mem_ctx, { struct dgram_mailslot_handler *dgmslot; struct nbt_dgram_socket *dgmsock = nbt_dgram_socket_init(mem_ctx, NULL); - struct nbt_peer_socket dest; + struct socket_address *dest; + struct test_join *join_ctx; + struct cli_credentials *machine_credentials; + const char *dom_sid; + const char *myaddress = talloc_strdup(dgmsock, iface_best_ip(address)); struct nbt_ntlogon_packet logon; struct nbt_name myname; NTSTATUS status; struct timeval tv = timeval_current(); int replies = 0; - struct test_join *join_ctx; - struct cli_credentials *machine_credentials; - const char *dom_sid; - join_ctx = torture_join_domain(TEST_NAME, - ACB_WSTRUST, &machine_credentials); - if (join_ctx == NULL) { - printf("Failed to join domain %s as %s\n", lp_workgroup(), TEST_NAME); - talloc_free(dgmsock); + struct socket_address *socket_address; + + socket_address = socket_address_from_strings(dgmsock, dgmsock->sock->backend_name, + myaddress, lp_dgram_port()); + if (!socket_address) { return False; } - dom_sid = torture_join_sid(join_ctx); - /* try receiving replies on port 138 first, which will only work if we are root and smbd/nmbd are not running - fall back to listening on any port, which means replies from some windows versions won't be seen */ - status = socket_listen(dgmsock->sock, myaddress, lp_dgram_port(), 0, 0); + status = socket_listen(dgmsock->sock, socket_address, 0, 0); if (!NT_STATUS_IS_OK(status)) { - socket_listen(dgmsock->sock, myaddress, 0, 0, 0); + talloc_free(socket_address); + socket_address = socket_address_from_strings(dgmsock, dgmsock->sock->backend_name, + myaddress, 0); + if (!socket_address) { + return False; + } + + socket_listen(dgmsock->sock, socket_address, 0, 0); + } + + join_ctx = torture_join_domain(TEST_NAME, + ACB_WSTRUST, &machine_credentials); + if (join_ctx == NULL) { + printf("Failed to join domain %s as %s\n", lp_workgroup(), TEST_NAME); + talloc_free(dgmsock); + return False; } + dom_sid = torture_join_sid(join_ctx); + /* setup a temporary mailslot listener for replies */ dgmslot = dgram_mailslot_temp(dgmsock, NBT_MAILSLOT_GETDC, ntlogon_handler, &replies); @@ -258,10 +311,13 @@ static BOOL nbt_test_ntlogon(TALLOC_CTX *mem_ctx, make_nbt_name_client(&myname, TEST_NAME); - dest.port = 0; - dest.addr = address; + dest = socket_address_from_strings(dgmsock, dgmsock->sock->backend_name, + address, 0); + if (!dest) { + goto failed; + } status = dgram_mailslot_ntlogon_send(dgmsock, DGRAM_DIRECT_UNIQUE, - &name, &dest, &myname, &logon); + &name, dest, &myname, &logon); if (!NT_STATUS_IS_OK(status)) { printf("Failed to send ntlogon request - %s\n", nt_errstr(status)); goto failed; diff --git a/source4/torture/nbt/register.c b/source4/torture/nbt/register.c index 8cbceb8e30..cd7d3c7624 100644 --- a/source4/torture/nbt/register.c +++ b/source4/torture/nbt/register.c @@ -48,8 +48,19 @@ static BOOL nbt_register_own(TALLOC_CTX *mem_ctx, struct nbt_name *name, struct nbt_name_socket *nbtsock = nbt_name_socket_init(mem_ctx, NULL); BOOL ret = True; const char *myaddress = iface_best_ip(address); + struct socket_address *socket_address; - socket_listen(nbtsock->sock, myaddress, 0, 0, 0); + socket_address = socket_address_from_strings(mem_ctx, nbtsock->sock->backend_name, + myaddress, 0); + if (!socket_address) { + return False; + } + + status = socket_listen(nbtsock->sock, socket_address, 0, 0); + if (!NT_STATUS_IS_OK(status)) { + printf("socket_listen for nbt_register_own failed: %s\n", nt_errstr(status)); + return False; + } printf("Testing name defense to name registration\n"); @@ -85,11 +96,11 @@ static BOOL nbt_register_own(TALLOC_CTX *mem_ctx, struct nbt_name *name, status = nbt_name_register(nbtsock, mem_ctx, &io); if (NT_STATUS_EQUAL(status, NT_STATUS_IO_TIMEOUT)) { - printf("No response from %s for name register\n", address); + printf("No response from %s for name register demand\n", address); return False; } if (!NT_STATUS_IS_OK(status)) { - printf("Bad response from %s for name register - %s\n", + printf("Bad response from %s for name register demand - %s\n", address, nt_errstr(status)); return False; } @@ -113,8 +124,19 @@ static BOOL nbt_refresh_own(TALLOC_CTX *mem_ctx, struct nbt_name *name, struct nbt_name_socket *nbtsock = nbt_name_socket_init(mem_ctx, NULL); BOOL ret = True; const char *myaddress = iface_best_ip(address); + struct socket_address *socket_address; + + socket_address = socket_address_from_strings(mem_ctx, nbtsock->sock->backend_name, + myaddress, 0); + if (!socket_address) { + return False; + } - socket_listen(nbtsock->sock, myaddress, 0, 0, 0); + status = socket_listen(nbtsock->sock, socket_address, 0, 0); + if (!NT_STATUS_IS_OK(status)) { + printf("socket_listen for nbt_referesh_own failed: %s\n", nt_errstr(status)); + return False; + } printf("Testing name defense to name refresh\n"); diff --git a/source4/torture/nbt/wins.c b/source4/torture/nbt/wins.c index 37e9688a60..bcb52dc9b8 100644 --- a/source4/torture/nbt/wins.c +++ b/source4/torture/nbt/wins.c @@ -59,10 +59,23 @@ static BOOL nbt_test_wins_name(TALLOC_CTX *mem_ctx, const char *address, struct nbt_name_socket *nbtsock = nbt_name_socket_init(mem_ctx, NULL); BOOL ret = True; const char *myaddress = talloc_strdup(mem_ctx, iface_best_ip(address)); + struct socket_address *socket_address; + + socket_address = socket_address_from_strings(mem_ctx, + nbtsock->sock->backend_name, + myaddress, 0); + if (!socket_address) { + return False; + } /* we do the listen here to ensure the WINS server receives the packets from the right IP */ - socket_listen(nbtsock->sock, myaddress, 0, 0, 0); + status = socket_listen(nbtsock->sock, socket_address, 0, 0); + if (!NT_STATUS_IS_OK(status)) { + printf("socket_listen for WINS failed: %s\n", nt_errstr(status)); + return False; + } + talloc_free(socket_address); printf("Testing name registration to WINS with name %s at %s nb_flags=0x%x\n", nbt_name_string(mem_ctx, name), myaddress, nb_flags); diff --git a/source4/torture/nbt/winsbench.c b/source4/torture/nbt/winsbench.c index 65f494184f..5aa97f9ade 100644 --- a/source4/torture/nbt/winsbench.c +++ b/source4/torture/nbt/winsbench.c @@ -223,6 +223,7 @@ static BOOL bench_wins(TALLOC_CTX *mem_ctx, struct nbt_name *name, const char *a int timelimit = lp_parm_int(-1, "torture", "timelimit", 10); struct wins_state *state; extern int torture_entries; + struct socket_address *my_ip; state = talloc_zero(nbtsock, struct wins_state); @@ -232,7 +233,10 @@ static BOOL bench_wins(TALLOC_CTX *mem_ctx, struct nbt_name *name, const char *a state->my_ip = talloc_strdup(mem_ctx, iface_best_ip(address)); state->ttl = timelimit; - socket_listen(nbtsock->sock, state->my_ip, 0, 0, 0); + my_ip = socket_address_from_strings(nbtsock, nbtsock->sock->backend_name, + state->my_ip, 0); + + socket_listen(nbtsock->sock, my_ip, 0, 0); printf("Running for %d seconds\n", timelimit); while (timeval_elapsed(&tv) < timelimit) { diff --git a/source4/torture/nbt/winsreplication.c b/source4/torture/nbt/winsreplication.c index f7f9665a6d..a6089fc2db 100644 --- a/source4/torture/nbt/winsreplication.c +++ b/source4/torture/nbt/winsreplication.c @@ -338,8 +338,8 @@ struct test_wrepl_conflict_conn { struct wrepl_wins_owner a, b, c, x; - const char *myaddr; - const char *myaddr2; + struct socket_address *myaddr; + struct socket_address *myaddr2; struct nbt_name_socket *nbtsock; struct nbt_name_socket *nbtsock2; @@ -551,6 +551,7 @@ static struct test_wrepl_conflict_conn *test_create_conflict_ctx(TALLOC_CTX *mem struct test_wrepl_conflict_conn *ctx; struct wrepl_associate associate; struct wrepl_pull_table pull_table; + struct socket_address *nbt_srv_addr; NTSTATUS status; uint32_t i; @@ -615,27 +616,34 @@ static struct test_wrepl_conflict_conn *test_create_conflict_ctx(TALLOC_CTX *mem talloc_free(pull_table.out.partners); - ctx->myaddr = talloc_strdup(mem_ctx, iface_best_ip(address)); + ctx->nbtsock = nbt_name_socket_init(ctx, NULL); + if (!ctx->nbtsock) return NULL; + + ctx->myaddr = socket_address_from_strings(mem_ctx, ctx->nbtsock->sock->backend_name, iface_best_ip(address), 0); if (!ctx->myaddr) return NULL; for (i = 0; i < iface_count(); i++) { - if (strcmp(ctx->myaddr, iface_n_ip(i)) == 0) continue; - ctx->myaddr2 = talloc_strdup(mem_ctx, iface_n_ip(i)); + if (strcmp(ctx->myaddr->addr, iface_n_ip(i)) == 0) continue; + ctx->myaddr2 = socket_address_from_strings(mem_ctx, ctx->nbtsock->sock->backend_name, iface_n_ip(i), 0); if (!ctx->myaddr2) return NULL; break; } - ctx->nbtsock = nbt_name_socket_init(ctx, NULL); - if (!ctx->nbtsock) return NULL; - - status = socket_listen(ctx->nbtsock->sock, ctx->myaddr, 0, 0, 0); + status = socket_listen(ctx->nbtsock->sock, ctx->myaddr, 0, 0); if (!NT_STATUS_IS_OK(status)) return NULL; ctx->nbtsock_srv = nbt_name_socket_init(ctx, NULL); if (!ctx->nbtsock_srv) return NULL; - status = socket_listen(ctx->nbtsock_srv->sock, ctx->myaddr, lp_nbt_port(), 0, 0); + /* Make a port 137 version of ctx->myaddr */ + nbt_srv_addr = socket_address_from_strings(mem_ctx, ctx->nbtsock_srv->sock->backend_name, ctx->myaddr->addr, lp_nbt_port()); + if (!nbt_srv_addr) return NULL; + + /* And if possible, bind to it. This won't work unless we are root or in sockewrapper */ + status = socket_listen(ctx->nbtsock_srv->sock, nbt_srv_addr, 0, 0); + talloc_free(nbt_srv_addr); if (!NT_STATUS_IS_OK(status)) { + /* this isn't fatal */ talloc_free(ctx->nbtsock_srv); ctx->nbtsock_srv = NULL; } @@ -644,14 +652,23 @@ static struct test_wrepl_conflict_conn *test_create_conflict_ctx(TALLOC_CTX *mem ctx->nbtsock2 = nbt_name_socket_init(ctx, NULL); if (!ctx->nbtsock2) return NULL; - status = socket_listen(ctx->nbtsock2->sock, ctx->myaddr2, 0, 0, 0); + status = socket_listen(ctx->nbtsock2->sock, ctx->myaddr2, 0, 0); if (!NT_STATUS_IS_OK(status)) return NULL; ctx->nbtsock_srv2 = nbt_name_socket_init(ctx, ctx->nbtsock_srv->event_ctx); if (!ctx->nbtsock_srv2) return NULL; - status = socket_listen(ctx->nbtsock_srv2->sock, ctx->myaddr2, lp_nbt_port(), 0, 0); + /* Make a port 137 version of ctx->myaddr2 */ + nbt_srv_addr = socket_address_from_strings(mem_ctx, + ctx->nbtsock_srv->sock->backend_name, + ctx->myaddr2->addr, lp_nbt_port()); + if (!nbt_srv_addr) return NULL; + + /* And if possible, bind to it. This won't work unless we are root or in sockewrapper */ + status = socket_listen(ctx->nbtsock_srv2->sock, ctx->myaddr2, 0, 0); + talloc_free(nbt_srv_addr); if (!NT_STATUS_IS_OK(status)) { + /* this isn't fatal */ talloc_free(ctx->nbtsock_srv2); ctx->nbtsock_srv2 = NULL; } @@ -661,7 +678,7 @@ static struct test_wrepl_conflict_conn *test_create_conflict_ctx(TALLOC_CTX *mem ctx->addresses_best = talloc_array(ctx, struct wrepl_ip, ctx->addresses_best_num); if (!ctx->addresses_best) return NULL; ctx->addresses_best[0].owner = ctx->b.address; - ctx->addresses_best[0].ip = ctx->myaddr; + ctx->addresses_best[0].ip = ctx->myaddr->addr; ctx->addresses_all_num = iface_count(); ctx->addresses_all = talloc_array(ctx, struct wrepl_ip, ctx->addresses_all_num); @@ -677,15 +694,15 @@ static struct test_wrepl_conflict_conn *test_create_conflict_ctx(TALLOC_CTX *mem ctx->addresses_best2 = talloc_array(ctx, struct wrepl_ip, ctx->addresses_best2_num); if (!ctx->addresses_best2) return NULL; ctx->addresses_best2[0].owner = ctx->b.address; - ctx->addresses_best2[0].ip = ctx->myaddr2; + ctx->addresses_best2[0].ip = ctx->myaddr2->addr; ctx->addresses_mhomed_num = 2; ctx->addresses_mhomed = talloc_array(ctx, struct wrepl_ip, ctx->addresses_mhomed_num); if (!ctx->addresses_mhomed) return NULL; ctx->addresses_mhomed[0].owner = ctx->b.address; - ctx->addresses_mhomed[0].ip = ctx->myaddr; + ctx->addresses_mhomed[0].ip = ctx->myaddr->addr; ctx->addresses_mhomed[1].owner = ctx->b.address; - ctx->addresses_mhomed[1].ip = ctx->myaddr2; + ctx->addresses_mhomed[1].ip = ctx->myaddr2->addr; } return ctx; @@ -6545,7 +6562,7 @@ struct test_conflict_owned_active_vs_replica_struct { static void test_conflict_owned_active_vs_replica_handler(struct nbt_name_socket *nbtsock, struct nbt_name_packet *req_packet, - const struct nbt_peer_socket *src); + struct socket_address *src); static BOOL test_conflict_owned_active_vs_replica(struct test_wrepl_conflict_conn *ctx) { @@ -9220,7 +9237,7 @@ static BOOL test_conflict_owned_active_vs_replica(struct test_wrepl_conflict_con for (j=0; j < count; j++) { struct nbt_name_socket *nbtsock = ctx->nbtsock; - if (ctx->myaddr2 && strcmp(records[i].wins.ips[j].ip, ctx->myaddr2) == 0) { + if (ctx->myaddr2 && strcmp(records[i].wins.ips[j].ip, ctx->myaddr2->addr) == 0) { nbtsock = ctx->nbtsock2; } @@ -9312,7 +9329,7 @@ done: static void test_conflict_owned_active_vs_replica_handler_query(struct nbt_name_socket *nbtsock, struct nbt_name_packet *req_packet, - const struct nbt_peer_socket *src) + struct socket_address *src) { struct nbt_name *name; struct nbt_name_packet *rep_packet; @@ -9407,7 +9424,7 @@ static void test_conflict_owned_active_vs_replica_handler_query(struct nbt_name_ static void test_conflict_owned_active_vs_replica_handler_release(struct nbt_name_socket *nbtsock, struct nbt_name_packet *req_packet, - const struct nbt_peer_socket *src) + struct socket_address *src) { struct nbt_name *name; struct nbt_name_packet *rep_packet; @@ -9460,7 +9477,7 @@ static void test_conflict_owned_active_vs_replica_handler_release(struct nbt_nam static void test_conflict_owned_active_vs_replica_handler(struct nbt_name_socket *nbtsock, struct nbt_name_packet *req_packet, - const struct nbt_peer_socket *src) + struct socket_address *src) { struct test_conflict_owned_active_vs_replica_struct *rec = nbtsock->incoming.private; diff --git a/source4/utils/nmblookup.c b/source4/utils/nmblookup.c index eaad3203e5..b0bedab01e 100644 --- a/source4/utils/nmblookup.c +++ b/source4/utils/nmblookup.c @@ -178,6 +178,7 @@ static BOOL process_one(const char *name) TALLOC_CTX *tmp_ctx = talloc_new(NULL); enum nbt_name_type node_type = NBT_NAME_CLIENT; char *node_name, *p; + struct socket_address *all_zero_addr; struct nbt_name_socket *nbtsock; NTSTATUS status = NT_STATUS_OK; BOOL ret = True; @@ -203,9 +204,17 @@ static BOOL process_one(const char *name) } nbtsock = nbt_name_socket_init(tmp_ctx, NULL); - + if (options.root_port) { - status = socket_listen(nbtsock->sock, "0.0.0.0", NBT_NAME_SERVICE_PORT, 0, 0); + all_zero_addr = socket_address_from_strings(tmp_ctx, nbtsock->sock->backend_name, + "0.0.0.0", NBT_NAME_SERVICE_PORT); + + if (!all_zero_addr) { + talloc_free(tmp_ctx); + return False; + } + + status = socket_listen(nbtsock->sock, all_zero_addr, 0, 0); if (!NT_STATUS_IS_OK(status)) { printf("Failed to bind to local port 137 - %s\n", nt_errstr(status)); talloc_free(tmp_ctx); diff --git a/source4/web_server/http.c b/source4/web_server/http.c index 18a1f61c1c..8779007f86 100644 --- a/source4/web_server/http.c +++ b/source4/web_server/http.c @@ -225,9 +225,10 @@ static void http_redirect(EspHandle handle, int code, char *url) /* form the full url, unless it already looks like a url */ if (strchr(url, ':') == NULL) { if (host == NULL) { + struct socket_address *socket_address = socket_get_my_addr(web->conn->socket, web); + if (socket_address == NULL) goto internal_error; host = talloc_asprintf(web, "%s:%u", - socket_get_my_addr(web->conn->socket, web), - socket_get_my_port(web->conn->socket)); + socket_address->addr, socket_address->port); } if (host == NULL) goto internal_error; if (url[0] != '/') { @@ -399,6 +400,8 @@ static void http_setup_arrays(struct esp_state *esp) struct websrv_context *web = esp->web; struct esp_data *edata = talloc_get_type(web->task->private, struct esp_data); struct EspRequest *req = esp->req; + struct socket_address *socket_address = socket_get_my_addr(web->conn->socket, esp); + struct socket_address *peer_address = socket_get_my_addr(web->conn->socket, esp); char *p; #define SETVAR(type, name, value) do { \ @@ -414,8 +417,9 @@ static void http_setup_arrays(struct esp_state *esp) p = strrchr(web->input.url, '/'); SETVAR(ESP_REQUEST_OBJ, "SCRIPT_NAME", p+1); SETVAR(ESP_REQUEST_OBJ, "SCRIPT_FILENAME", web->input.url); - p = socket_get_peer_addr(web->conn->socket, esp); - SETVAR(ESP_REQUEST_OBJ, "REMOTE_ADDR", p); + if (peer_address) { + SETVAR(ESP_REQUEST_OBJ, "REMOTE_ADDR", peer_address->addr); + } p = socket_get_peer_name(web->conn->socket, esp); SETVAR(ESP_REQUEST_OBJ, "REMOTE_HOST", p); SETVAR(ESP_REQUEST_OBJ, "REMOTE_USER", ""); @@ -433,12 +437,15 @@ static void http_setup_arrays(struct esp_state *esp) SETVAR(ESP_HEADERS_OBJ, "COOKIE", web->input.cookie); SETVAR(ESP_HEADERS_OBJ, "USER_AGENT", web->input.user_agent); - SETVAR(ESP_SERVER_OBJ, "SERVER_ADDR", socket_get_my_addr(web->conn->socket, esp)); - SETVAR(ESP_SERVER_OBJ, "SERVER_NAME", socket_get_my_addr(web->conn->socket, esp)); - SETVAR(ESP_SERVER_OBJ, "SERVER_HOST", socket_get_my_addr(web->conn->socket, esp)); + if (socket_address) { + SETVAR(ESP_SERVER_OBJ, "SERVER_ADDR", socket_address->addr); + SETVAR(ESP_SERVER_OBJ, "SERVER_NAME", socket_address->addr); + SETVAR(ESP_SERVER_OBJ, "SERVER_HOST", socket_address->addr); + SETVAR(ESP_SERVER_OBJ, "SERVER_PORT", + talloc_asprintf(esp, "%u", socket_address->port)); + } + SETVAR(ESP_SERVER_OBJ, "DOCUMENT_ROOT", lp_swat_directory()); - SETVAR(ESP_SERVER_OBJ, "SERVER_PORT", - talloc_asprintf(esp, "%u", socket_get_my_port(web->conn->socket))); SETVAR(ESP_SERVER_OBJ, "SERVER_PROTOCOL", tls_enabled(web->tls)?"https":"http"); SETVAR(ESP_SERVER_OBJ, "SERVER_SOFTWARE", "SWAT"); SETVAR(ESP_SERVER_OBJ, "GATEWAY_INTERFACE", "CGI/1.1"); diff --git a/source4/wrepl_server/wrepl_in_call.c b/source4/wrepl_server/wrepl_in_call.c index 8dabc2ee86..46ee25b7ad 100644 --- a/source4/wrepl_server/wrepl_in_call.c +++ b/source4/wrepl_server/wrepl_in_call.c @@ -401,8 +401,9 @@ static NTSTATUS wreplsrv_in_replication(struct wreplsrv_in_call *call) } if (!call->wreplconn->partner) { + struct socket_address *partner_ip = socket_get_peer_addr(call->wreplconn->conn->socket, call); DEBUG(1,("Failing WINS replication from non-partner %s\n", - socket_get_peer_addr(call->wreplconn->conn->socket, call))); + partner_ip ? partner_ip->addr : NULL)); return wreplsrv_in_stop_assoc_ctx(call); } diff --git a/source4/wrepl_server/wrepl_in_connection.c b/source4/wrepl_server/wrepl_in_connection.c index 4e93ebf7a3..80e443ace7 100644 --- a/source4/wrepl_server/wrepl_in_connection.c +++ b/source4/wrepl_server/wrepl_in_connection.c @@ -143,7 +143,7 @@ static void wreplsrv_accept(struct stream_connection *conn) { struct wreplsrv_service *service = talloc_get_type(conn->private, struct wreplsrv_service); struct wreplsrv_in_connection *wreplconn; - const char *peer_ip; + struct socket_address *peer_ip; wreplconn = talloc_zero(conn, struct wreplsrv_in_connection); if (!wreplconn) { @@ -170,11 +170,11 @@ static void wreplsrv_accept(struct stream_connection *conn) peer_ip = socket_get_peer_addr(conn->socket, wreplconn); if (!peer_ip) { - wreplsrv_terminate_in_connection(wreplconn, "wreplsrv_accept: out of memory"); + wreplsrv_terminate_in_connection(wreplconn, "wreplsrv_accept: could not obtain peer IP from kernel"); return; } - wreplconn->partner = wreplsrv_find_partner(service, peer_ip); + wreplconn->partner = wreplsrv_find_partner(service, peer_ip->addr); conn->private = wreplconn; |