1
0
mirror of https://github.com/samba-team/samba.git synced 2025-03-30 06:50:24 +03:00

r12804: This patch reworks the Samba4 sockets layer to use a socket_address

structure that is more generic than just 'IP/port'.

It now passes make test, and has been reviewed and updated by
metze. (Thankyou *very* much).

This passes 'make test' as well as kerberos use (not currently in the
testsuite).

The original purpose of this patch was to have Samba able to pass a
socket address stucture from the BSD layer into the kerberos routines
and back again.   It also removes nbt_peer_addr, which was being used
for a similar purpose.

It is a large change, but worthwhile I feel.

Andrew Bartlett
(This used to be commit 88198c4881d8620a37086f80e4da5a5b71c5bbb2)
This commit is contained in:
Andrew Bartlett 2006-01-09 22:12:53 +00:00 committed by Gerald (Jerry) Carter
parent 806b3fdbc1
commit f55ea8bb3d
68 changed files with 1378 additions and 876 deletions

View File

@ -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;

View File

@ -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

View File

@ -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 */

View File

@ -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,

View File

@ -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
#################################

View File

@ -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;

View File

@ -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);

View File

@ -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;

View File

@ -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);
}

View File

@ -144,6 +144,7 @@ struct ldb_map_objectclass;
struct param_context;
struct socket_address;
struct smbcli_request;
struct smbcli_tree;

View File

@ -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)));

View File

@ -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

View File

@ -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;

View File

@ -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);

View File

@ -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);

View File

@ -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);

View File

@ -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);
}

View File

@ -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);

View File

@ -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);
}

View File

@ -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,

View File

@ -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);
}
}
srv_ip = interpret_addr2(srv_address);
if (!srv_ip.addr) {
return NT_STATUS_BAD_NETWORK_NAME;
}
ZERO_STRUCT(srv_addr);
} 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
srv_addr.sin_len = sizeof(srv_addr);
my_addr.sin_len = sizeof(my_addr);
#endif
srv_addr.sin_addr.s_addr= srv_ip.addr;
srv_addr.sin_port = htons(srv_port);
srv_addr.sin_family = PF_INET;
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);
}
}
}
ret = connect(sock->fd, (const struct sockaddr *)&srv_addr, sizeof(srv_addr));
if (ret == -1) {
return map_nt_error_from_unix(errno);
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);
#endif
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);
}
}
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;
ret = getpeername(sock->fd, (struct sockaddr *)&peer_addr, &len);
if (ret == -1) {
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;
}
return talloc_strdup(mem_ctx, inet_ntoa(peer_addr.sin_addr));
}
peer->sockaddr = (struct sockaddr *)peer_addr;
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;
}
return ntohs(peer_addr.sin_port);
}
static char *ipv4_get_my_addr(struct socket_context *sock, TALLOC_CTX *mem_ctx)
{
struct sockaddr_in my_addr;
socklen_t len = sizeof(my_addr);
int ret;
ret = getsockname(sock->fd, (struct sockaddr *)&my_addr, &len);
ret = getpeername(sock->fd, peer->sockaddr, &len);
if (ret == -1) {
talloc_free(peer);
return NULL;
}
return talloc_strdup(mem_ctx, inet_ntoa(my_addr.sin_addr));
peer->sockaddrlen = len;
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 peer;
}
static int ipv4_get_my_port(struct socket_context *sock)
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;
ret = getsockname(sock->fd, (struct sockaddr *)&my_addr, &len);
if (ret == -1) {
return -1;
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;
}
return ntohs(my_addr.sin_port);
}
local->sockaddr = (struct sockaddr *)local_addr;
ret = getsockname(sock->fd, local->sockaddr, &len);
if (ret == -1) {
talloc_free(local);
return NULL;
}
local->sockaddrlen = len;
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 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
};

View File

@ -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);
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));
}
ZERO_STRUCT(my_addr);
my_addr.sin6_addr = ip_addr;
my_addr.sin6_port = htons(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);
}
@ -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;
ret = getpeername(sock->fd, (struct sockaddr *)&peer_addr, &len);
if (ret == -1) {
return NULL;
}
he = gethostbyaddr((char *)&peer_addr.sin6_addr, sizeof(peer_addr.sin6_addr), AF_INET6);
if (!he || !he->h_name) {
peer = talloc(mem_ctx, struct socket_address);
if (!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->family = sock->backend_name;
peer_addr = talloc(peer, struct sockaddr_in6);
if (!peer_addr) {
talloc_free(peer);
return NULL;
}
return ntohs(peer_addr.sin6_port);
peer->sockaddr = (struct sockaddr *)peer_addr;
ret = getpeername(sock->fd, peer->sockaddr, &len);
if (ret == -1) {
talloc_free(peer);
return NULL;
}
peer->sockaddrlen = len;
he = gethostbyaddr((char *)&peer_addr->sin6_addr, len, AF_INET6);
if (!he || !he->h_name) {
talloc_free(peer);
return NULL;
}
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 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
};

View File

@ -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;
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));
}
ZERO_STRUCT(srv_addr);
srv_addr.sun_family = AF_UNIX;
strncpy(srv_addr.sun_path, srv_address, sizeof(srv_addr.sun_path));
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 */
if (my_address->addr) {
unlink(my_address->addr);
}
/* 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));
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;
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;
}
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_peer_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;
}
static char *unixdom_get_my_addr(struct socket_context *sock, TALLOC_CTX *mem_ctx)
{
return talloc_strdup(mem_ctx, "LOCAL/unixdom");
}
local->sockaddr = (struct sockaddr *)local_addr;
static int unixdom_get_my_port(struct socket_context *sock)
{
return 0;
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
};

View File

@ -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;

View File

@ -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);

View File

@ -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;

View File

@ -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);

View File

@ -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,

View File

@ -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);

View File

@ -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;

View File

@ -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;

View File

@ -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;
};

View File

@ -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);

View File

@ -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 ||

View File

@ -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 ||

View File

@ -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 ||

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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));

View File

@ -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 =

View File

@ -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 =

View File

@ -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

View File

@ -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;
}
status = socket_listen(bcast_nbtsock->sock, bcast, lp_nbt_port(), 0, 0);
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_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 */

View File

@ -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",

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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);

View File

@ -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;

View File

@ -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);

View File

@ -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++;
}

View File

@ -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;

View File

@ -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 */

View File

@ -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)) {

View File

@ -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);

View File

@ -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);
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) {
printf("Expected server address of %s but got %s\n",
iface_best_ip("127.0.0.1"), srv_addr);
localhost = socket_address_from_strings(sock1, sock1->backend_name,
iface_best_ip("127.0.0.1"), 0);
if (!localhost) {
return False;
}
srv_port = socket_get_my_port(sock1);
printf("server port is %d\n", srv_port);
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->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 ? srv_addr->addr : NULL);
return False;
}
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);
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) {
printf("Expected server address of %s but got %s\n",
iface_best_ip("127.0.0.1"), srv_addr);
localhost = socket_address_from_strings(sock1, sock1->backend_name,
iface_best_ip("127.0.0.1"), 0);
if (!localhost) {
return False;
}
srv_port = socket_get_my_port(sock1);
printf("server port is %d\n", srv_port);
status = socket_listen(sock1, localhost, 0, 0);
CHECK_STATUS(status, NT_STATUS_OK);
status = socket_connect_ev(sock2, NULL, 0, srv_addr, srv_port, 0, ev);
srv_addr = socket_get_my_addr(sock1, mem_ctx);
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 ? srv_addr->addr : NULL);
return False;
}
printf("server port is %d\n", srv_addr->port);
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) {

View File

@ -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,16 +246,41 @@ 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;
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, socket_address, 0, 0);
if (!NT_STATUS_IS_OK(status)) {
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);
@ -230,15 +292,6 @@ static BOOL nbt_test_ntlogon(TALLOC_CTX *mem_ctx,
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);
if (!NT_STATUS_IS_OK(status)) {
socket_listen(dgmsock->sock, myaddress, 0, 0, 0);
}
/* 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;

View File

@ -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_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_referesh_own failed: %s\n", nt_errstr(status));
return False;
}
printf("Testing name defense to name refresh\n");

View File

@ -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);

View File

@ -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) {

View File

@ -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;

View File

@ -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);

View File

@ -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");

View File

@ -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);
}

View File

@ -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;