struct auth_usersupplied_info
{
const char *workstation_name;
- const char *remote_host;
+ struct socket_address *remote_host;
uint32_t logon_parameters;
}
/**
- * 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
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
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
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 */
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);
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,
}
}
- 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,
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
#################################
{
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);
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;
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);
*/
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;
}
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);
}
}
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)));
return status;
}
+ talloc_free(socket_address);
+
cldap_set_incoming_handler(cldapsock, cldapd_request_handler, cldapd);
return NT_STATUS_OK;
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;
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;
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);
}
struct param_context;
+struct socket_address;
struct smbcli_request;
struct smbcli_tree;
/* 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;
};
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 {
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;
}
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);
}
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 */
tmp_ctx,
&blob,
&reply,
- src_addr, src_port,
- my_addr, my_port);
+ src, my_addr);
if (!ret) {
talloc_free(tmp_ctx);
return;
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);
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);
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);
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;
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;
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();
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)));
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)));
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
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;
/* 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;
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;
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);
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;
{
struct messaging_context *msg;
NTSTATUS status;
- char *path;
+ struct socket_address *path;
+ char *dir;
msg = talloc(mem_ctx, struct messaging_context);
if (msg == NULL) {
}
/* 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);
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);
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) &&
}
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;
}
}
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);
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;
};
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,
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)
{
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;
}
socket_send_connect(result);
return result;
-
-failed:
- composite_error(result, result->status);
- return result;
}
/*
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);
}
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);
}
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);
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);
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);
}
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) {
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)
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;
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)
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;
}
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,
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;
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);
}
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;
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;
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) {
}
-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;
}
#endif
- if (strcmp("unix", name) == 0) {
+ if (strcmp("unix", family) == 0) {
return socket_unixdom_ops(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;
/* 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,
/* 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,
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);
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);
};
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,
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,
static NTSTATUS ipv4_connect(struct socket_context *sock,
- const char *my_address, int my_port,
- const char *srv_address, int srv_port,
- uint32_t flags)
+ const struct socket_address *my_address,
+ const struct socket_address *srv_address,
+ uint32_t flags)
{
struct sockaddr_in srv_addr;
struct ipv4_addr my_ip;
struct ipv4_addr srv_ip;
int ret;
- my_ip = interpret_addr2(my_address);
-
- if (my_ip.addr != 0 || my_port != 0) {
- struct sockaddr_in my_addr;
- ZERO_STRUCT(my_addr);
-#ifdef HAVE_SOCK_SIN_LEN
- my_addr.sin_len = sizeof(my_addr);
-#endif
- my_addr.sin_addr.s_addr = my_ip.addr;
- my_addr.sin_port = htons(my_port);
- my_addr.sin_family = PF_INET;
-
- ret = bind(sock->fd, (struct sockaddr *)&my_addr, sizeof(my_addr));
+ if (my_address && my_address->sockaddr) {
+ ret = bind(sock->fd, my_address->sockaddr, my_address->sockaddrlen);
if (ret == -1) {
return map_nt_error_from_unix(errno);
}
+ } else if (my_address) {
+ my_ip = interpret_addr2(my_address->addr);
+
+ if (my_ip.addr != 0 || my_address->port != 0) {
+ struct sockaddr_in my_addr;
+ ZERO_STRUCT(my_addr);
+#ifdef HAVE_SOCK_SIN_LEN
+ my_addr.sin_len = sizeof(my_addr);
+#endif
+ my_addr.sin_addr.s_addr = my_ip.addr;
+ my_addr.sin_port = htons(my_address->port);
+ my_addr.sin_family = PF_INET;
+
+ ret = bind(sock->fd, (struct sockaddr *)&my_addr, sizeof(my_addr));
+ if (ret == -1) {
+ return map_nt_error_from_unix(errno);
+ }
+ }
}
- srv_ip = interpret_addr2(srv_address);
- if (!srv_ip.addr) {
- return NT_STATUS_BAD_NETWORK_NAME;
- }
-
- ZERO_STRUCT(srv_addr);
+ if (srv_address->sockaddr) {
+ ret = connect(sock->fd, srv_address->sockaddr, srv_address->sockaddrlen);
+ if (ret == -1) {
+ return map_nt_error_from_unix(errno);
+ }
+ } else {
+ srv_ip = interpret_addr2(srv_address->addr);
+ if (!srv_ip.addr) {
+ return NT_STATUS_BAD_NETWORK_NAME;
+ }
+
+ ZERO_STRUCT(srv_addr);
#ifdef HAVE_SOCK_SIN_LEN
- srv_addr.sin_len = sizeof(srv_addr);
+ srv_addr.sin_len = sizeof(srv_addr);
#endif
- srv_addr.sin_addr.s_addr= srv_ip.addr;
- srv_addr.sin_port = htons(srv_port);
- srv_addr.sin_family = PF_INET;
+ srv_addr.sin_addr.s_addr= srv_ip.addr;
+ srv_addr.sin_port = htons(srv_address->port);
+ srv_addr.sin_family = PF_INET;
- ret = connect(sock->fd, (const struct sockaddr *)&srv_addr, sizeof(srv_addr));
- if (ret == -1) {
- return map_nt_error_from_unix(errno);
+ ret = connect(sock->fd, (const struct sockaddr *)&srv_addr, sizeof(srv_addr));
+ if (ret == -1) {
+ return map_nt_error_from_unix(errno);
+ }
}
return ipv4_connect_complete(sock, flags);
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;
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);
}
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;
}
*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;
}
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);
}
return talloc_strdup(mem_ctx, he->h_name);
}
-static char *ipv4_get_peer_addr(struct socket_context *sock, TALLOC_CTX *mem_ctx)
+static struct socket_address *ipv4_get_peer_addr(struct socket_context *sock, TALLOC_CTX *mem_ctx)
{
- struct sockaddr_in peer_addr;
- socklen_t len = sizeof(peer_addr);
+ struct sockaddr_in *peer_addr;
+ socklen_t len = sizeof(*peer_addr);
+ const char *addr;
+ struct socket_address *peer;
int ret;
+
+ peer = talloc(mem_ctx, struct socket_address);
+ if (!peer) {
+ return NULL;
+ }
+
+ peer->family = sock->backend_name;
+ peer_addr = talloc(peer, struct sockaddr_in);
+ if (!peer_addr) {
+ talloc_free(peer);
+ return NULL;
+ }
- ret = getpeername(sock->fd, (struct sockaddr *)&peer_addr, &len);
+ peer->sockaddr = (struct sockaddr *)peer_addr;
+
+ ret = getpeername(sock->fd, peer->sockaddr, &len);
if (ret == -1) {
+ talloc_free(peer);
return NULL;
}
- return talloc_strdup(mem_ctx, inet_ntoa(peer_addr.sin_addr));
-}
+ peer->sockaddrlen = len;
-static int ipv4_get_peer_port(struct socket_context *sock)
-{
- struct sockaddr_in peer_addr;
- socklen_t len = sizeof(peer_addr);
- int ret;
-
- ret = getpeername(sock->fd, (struct sockaddr *)&peer_addr, &len);
- if (ret == -1) {
- return -1;
+ addr = inet_ntoa(peer_addr->sin_addr);
+ if (addr == NULL) {
+ talloc_free(peer);
+ return NULL;
+ }
+ peer->addr = talloc_strdup(peer, addr);
+ if (!peer->addr) {
+ talloc_free(peer);
+ return NULL;
}
+ peer->port = ntohs(peer_addr->sin_port);
- return ntohs(peer_addr.sin_port);
+ return peer;
}
-static char *ipv4_get_my_addr(struct socket_context *sock, TALLOC_CTX *mem_ctx)
+static struct socket_address *ipv4_get_my_addr(struct socket_context *sock, TALLOC_CTX *mem_ctx)
{
- struct sockaddr_in my_addr;
- socklen_t len = sizeof(my_addr);
+ struct sockaddr_in *local_addr;
+ socklen_t len = sizeof(*local_addr);
+ const char *addr;
+ struct socket_address *local;
int ret;
+
+ local = talloc(mem_ctx, struct socket_address);
+ if (!local) {
+ return NULL;
+ }
+
+ local->family = sock->backend_name;
+ local_addr = talloc(local, struct sockaddr_in);
+ if (!local_addr) {
+ talloc_free(local);
+ return NULL;
+ }
- ret = getsockname(sock->fd, (struct sockaddr *)&my_addr, &len);
+ local->sockaddr = (struct sockaddr *)local_addr;
+
+ ret = getsockname(sock->fd, local->sockaddr, &len);
if (ret == -1) {
+ talloc_free(local);
return NULL;
}
- return talloc_strdup(mem_ctx, inet_ntoa(my_addr.sin_addr));
-}
-
-static int ipv4_get_my_port(struct socket_context *sock)
-{
- struct sockaddr_in my_addr;
- socklen_t len = sizeof(my_addr);
- int ret;
+ local->sockaddrlen = len;
- ret = getsockname(sock->fd, (struct sockaddr *)&my_addr, &len);
- if (ret == -1) {
- return -1;
+ addr = inet_ntoa(local_addr->sin_addr);
+ if (addr == NULL) {
+ talloc_free(local);
+ return NULL;
+ }
+ local->addr = talloc_strdup(local, addr);
+ if (!local->addr) {
+ talloc_free(local);
+ return NULL;
}
+ local->port = ntohs(local_addr->sin_port);
- return ntohs(my_addr.sin_port);
+ return local;
}
-
static int ipv4_get_fd(struct socket_context *sock)
{
return sock->fd;
.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
};
}
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);
}
}
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;
socket_set_option(sock, "SO_REUSEADDR=1", NULL);
- ip_addr = interpret_addr6(my_address);
-
- ZERO_STRUCT(my_addr);
- my_addr.sin6_addr = ip_addr;
- my_addr.sin6_port = htons(port);
- my_addr.sin6_family = PF_INET6;
+ if (my_address->sockaddr) {
+ ret = bind(sock->fd, my_address->sockaddr, my_address->sockaddrlen);
+ } else {
+ ip_addr = interpret_addr6(my_address->addr);
+
+ ZERO_STRUCT(my_addr);
+ my_addr.sin6_addr = ip_addr;
+ my_addr.sin6_port = htons(my_address->port);
+ my_addr.sin6_family = PF_INET6;
+
+ ret = bind(sock->fd, (struct sockaddr *)&my_addr, sizeof(my_addr));
+ }
- ret = bind(sock->fd, (struct sockaddr *)&my_addr, sizeof(my_addr));
if (ret == -1) {
return map_nt_error_from_unix(errno);
}
return talloc_strdup(mem_ctx, he->h_name);
}
-static char *ipv6_tcp_get_peer_addr(struct socket_context *sock, TALLOC_CTX *mem_ctx)
+static struct socket_address *ipv6_tcp_get_peer_addr(struct socket_context *sock, TALLOC_CTX *mem_ctx)
{
- struct sockaddr_in6 peer_addr;
- socklen_t len = sizeof(peer_addr);
+ struct sockaddr_in6 *peer_addr;
+ socklen_t len = sizeof(*peer_addr);
+ struct socket_address *peer;
int ret;
struct hostent *he;
+
+ peer = talloc(mem_ctx, struct socket_address);
+ if (!peer) {
+ return NULL;
+ }
+
+ peer->family = sock->backend_name;
+ peer_addr = talloc(peer, struct sockaddr_in6);
+ if (!peer_addr) {
+ talloc_free(peer);
+ return NULL;
+ }
- ret = getpeername(sock->fd, (struct sockaddr *)&peer_addr, &len);
+ peer->sockaddr = (struct sockaddr *)peer_addr;
+
+ ret = getpeername(sock->fd, peer->sockaddr, &len);
if (ret == -1) {
+ talloc_free(peer);
return NULL;
}
- he = gethostbyaddr((char *)&peer_addr.sin6_addr, sizeof(peer_addr.sin6_addr), AF_INET6);
+ peer->sockaddrlen = len;
+
+ he = gethostbyaddr((char *)&peer_addr->sin6_addr, len, AF_INET6);
if (!he || !he->h_name) {
+ talloc_free(peer);
return NULL;
}
- return talloc_strdup(mem_ctx, he->h_name);
-}
-
-static int ipv6_tcp_get_peer_port(struct socket_context *sock)
-{
- struct sockaddr_in6 peer_addr;
- socklen_t len = sizeof(peer_addr);
- int ret;
-
- ret = getpeername(sock->fd, (struct sockaddr *)&peer_addr, &len);
- if (ret == -1) {
- return -1;
+ peer->addr = talloc_strdup(mem_ctx, he->h_name);
+ if (!peer->addr) {
+ talloc_free(peer);
+ return NULL;
}
+ peer->port = ntohs(peer_addr->sin6_port);
- return ntohs(peer_addr.sin6_port);
+ return peer;
}
-static char *ipv6_tcp_get_my_addr(struct socket_context *sock, TALLOC_CTX *mem_ctx)
+static struct socket_address *ipv6_tcp_get_my_addr(struct socket_context *sock, TALLOC_CTX *mem_ctx)
{
- struct sockaddr_in6 my_addr;
- socklen_t len = sizeof(my_addr);
+ struct sockaddr_in6 *local_addr;
+ socklen_t len = sizeof(*local_addr);
+ struct socket_address *local;
int ret;
struct hostent *he;
-
- ret = getsockname(sock->fd, (struct sockaddr *)&my_addr, &len);
- if (ret == -1) {
+
+ local = talloc(mem_ctx, struct socket_address);
+ if (!local) {
+ return NULL;
+ }
+
+ local->family = sock->backend_name;
+ local_addr = talloc(local, struct sockaddr_in6);
+ if (!local_addr) {
+ talloc_free(local);
return NULL;
}
- he = gethostbyaddr((char *)&my_addr.sin6_addr, sizeof(my_addr.sin6_addr), AF_INET6);
- if (he == NULL) {
+ local->sockaddr = (struct sockaddr *)local_addr;
+
+ ret = getsockname(sock->fd, local->sockaddr, &len);
+ if (ret == -1) {
+ talloc_free(local);
return NULL;
}
- return talloc_strdup(mem_ctx, he->h_name);
-}
+ local->sockaddrlen = len;
-static int ipv6_tcp_get_my_port(struct socket_context *sock)
-{
- struct sockaddr_in6 my_addr;
- socklen_t len = sizeof(my_addr);
- int ret;
+ he = gethostbyaddr((char *)&local_addr->sin6_addr, len, AF_INET6);
- ret = getsockname(sock->fd, (struct sockaddr *)&my_addr, &len);
- if (ret == -1) {
- return -1;
+ if (!he || !he->h_name) {
+ talloc_free(local);
+ return NULL;
+ }
+
+ local->addr = talloc_strdup(mem_ctx, he->h_name);
+ if (!local->addr) {
+ talloc_free(local);
+ return NULL;
}
+ local->port = ntohs(local_addr->sin6_port);
- return ntohs(my_addr.sin6_port);
+ return local;
}
static int ipv6_tcp_get_fd(struct socket_context *sock)
.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
};
}
static NTSTATUS unixdom_connect(struct socket_context *sock,
- const char *my_address, int my_port,
- const char *srv_address, int srv_port,
+ const struct socket_address *my_address,
+ const struct socket_address *srv_address,
uint32_t flags)
{
- struct sockaddr_un srv_addr;
int ret;
- if (strlen(srv_address)+1 > sizeof(srv_addr.sun_path)) {
- return NT_STATUS_OBJECT_PATH_INVALID;
- }
-
- ZERO_STRUCT(srv_addr);
- srv_addr.sun_family = AF_UNIX;
- strncpy(srv_addr.sun_path, srv_address, sizeof(srv_addr.sun_path));
+ if (srv_address->sockaddr) {
+ ret = connect(sock->fd, srv_address->sockaddr, srv_address->sockaddrlen);
+ } else {
+ struct sockaddr_un srv_addr;
+ if (strlen(srv_address->addr)+1 > sizeof(srv_addr.sun_path)) {
+ return NT_STATUS_OBJECT_PATH_INVALID;
+ }
+
+ ZERO_STRUCT(srv_addr);
+ srv_addr.sun_family = AF_UNIX;
+ strncpy(srv_addr.sun_path, srv_address->addr, sizeof(srv_addr.sun_path));
- ret = connect(sock->fd, (const struct sockaddr *)&srv_addr, sizeof(srv_addr));
+ ret = connect(sock->fd, (const struct sockaddr *)&srv_addr, sizeof(srv_addr));
+ }
if (ret == -1) {
return unixdom_error(errno);
}
}
static NTSTATUS unixdom_listen(struct socket_context *sock,
- const char *my_address, int port,
+ const struct socket_address *my_address,
int queue_size, uint32_t flags)
{
struct sockaddr_un my_addr;
int ret;
- if (strlen(my_address)+1 > sizeof(my_addr.sun_path)) {
- return NT_STATUS_OBJECT_PATH_INVALID;
- }
-
/* delete if it already exists */
- unlink(my_address);
-
- ZERO_STRUCT(my_addr);
- my_addr.sun_family = AF_UNIX;
- strncpy(my_addr.sun_path, my_address, sizeof(my_addr.sun_path));
+ if (my_address->addr) {
+ unlink(my_address->addr);
+ }
- ret = bind(sock->fd, (struct sockaddr *)&my_addr, sizeof(my_addr));
+ if (my_address && my_address->sockaddr) {
+ ret = bind(sock->fd, (struct sockaddr *)&my_addr, sizeof(my_addr));
+ } else {
+
+ if (strlen(my_address->addr)+1 > sizeof(my_addr.sun_path)) {
+ return NT_STATUS_OBJECT_PATH_INVALID;
+ }
+
+
+ ZERO_STRUCT(my_addr);
+ my_addr.sun_family = AF_UNIX;
+ strncpy(my_addr.sun_path, my_address->addr, sizeof(my_addr.sun_path));
+
+ ret = bind(sock->fd, (struct sockaddr *)&my_addr, sizeof(my_addr));
+ }
if (ret == -1) {
return unixdom_error(errno);
}
}
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;
}
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);
}
return talloc_strdup(mem_ctx, "LOCAL/unixdom");
}
-static char *unixdom_get_peer_addr(struct socket_context *sock, TALLOC_CTX *mem_ctx)
+static struct socket_address *unixdom_get_peer_addr(struct socket_context *sock, TALLOC_CTX *mem_ctx)
{
- return talloc_strdup(mem_ctx, "LOCAL/unixdom");
-}
+ struct sockaddr_in *peer_addr;
+ socklen_t len = sizeof(*peer_addr);
+ struct socket_address *peer;
+ int ret;
-static int unixdom_get_peer_port(struct socket_context *sock)
-{
- return 0;
-}
+ peer = talloc(mem_ctx, struct socket_address);
+ if (!peer) {
+ return NULL;
+ }
+
+ peer->family = sock->backend_name;
+ peer_addr = talloc(peer, struct sockaddr_in);
+ if (!peer_addr) {
+ talloc_free(peer);
+ return NULL;
+ }
-static char *unixdom_get_my_addr(struct socket_context *sock, TALLOC_CTX *mem_ctx)
-{
- return talloc_strdup(mem_ctx, "LOCAL/unixdom");
+ peer->sockaddr = (struct sockaddr *)peer_addr;
+
+ ret = getpeername(sock->fd, peer->sockaddr, &len);
+ if (ret == -1) {
+ talloc_free(peer);
+ return NULL;
+ }
+
+ peer->sockaddrlen = len;
+
+ peer->port = 0;
+ peer->addr = talloc_strdup(peer, "LOCAL/unixdom");
+ if (!peer->addr) {
+ talloc_free(peer);
+ return NULL;
+ }
+
+ return peer;
}
-static int unixdom_get_my_port(struct socket_context *sock)
+static struct socket_address *unixdom_get_my_addr(struct socket_context *sock, TALLOC_CTX *mem_ctx)
{
- return 0;
+ struct sockaddr_in *local_addr;
+ socklen_t len = sizeof(*local_addr);
+ struct socket_address *local;
+ int ret;
+
+ local = talloc(mem_ctx, struct socket_address);
+ if (!local) {
+ return NULL;
+ }
+
+ local->family = sock->backend_name;
+ local_addr = talloc(local, struct sockaddr_in);
+ if (!local_addr) {
+ talloc_free(local);
+ return NULL;
+ }
+
+ local->sockaddr = (struct sockaddr *)local_addr;
+
+ ret = getsockname(sock->fd, local->sockaddr, &len);
+ if (ret == -1) {
+ talloc_free(local);
+ return NULL;
+ }
+
+ local->sockaddrlen = len;
+
+ local->port = 0;
+ local->addr = talloc_strdup(local, "LOCAL/unixdom");
+ if (!local->addr) {
+ talloc_free(local);
+ return NULL;
+ }
+
+ return local;
}
static int unixdom_get_fd(struct socket_context *sock)
.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
};
{
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;
}
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"));
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;
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),
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;
*/
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;
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;
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;
}
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);
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;
}
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;
}
*/
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;
*/
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)
{
}
reply.messageid = message_id;
- reply.dest_address = src_address;
- reply.dest_port = src_port;
+ reply.dest = src;
reply.response = &response;
reply.result = &result;
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;
/* 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;
};
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);
*/
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;
};
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);
#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;
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);
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;
{
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;
}
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) {
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);
}
}
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);
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;
*/
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;
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);
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;
/* 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;
};
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;
/* 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);
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,
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,
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
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);
#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)
{
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);
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;
#include "includes.h"
#include "libcli/dgram/libdgram.h"
+#include "lib/socket/socket.h"
/*
send a ntlogon mailslot request
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)
{
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);
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;
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
*/
struct nbt_name_socket *nbtsock;
/* where to send the request */
- struct nbt_peer_socket dest;
+ struct socket_address *dest;
/* timeout between retries */
int timeout;
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 */
/* 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;
};
#include "includes.h"
#include "libcli/nbt/libnbt.h"
-
+#include "lib/socket/socket.h"
/*
send a nbt name query
*/
{
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;
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;
}
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);
{
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;
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;
}
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);
#include "includes.h"
#include "libcli/nbt/libnbt.h"
#include "libcli/composite/composite.h"
+#include "lib/socket/socket.h"
/*
send a nbt name refresh request
{
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;
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;
}
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 ||
#include "includes.h"
#include "libcli/nbt/libnbt.h"
#include "libcli/composite/composite.h"
+#include "lib/socket/socket.h"
/*
send a nbt name registration request
{
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;
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;
}
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 ||
#include "includes.h"
#include "libcli/nbt/libnbt.h"
+#include "lib/socket/socket.h"
/*
send a nbt name release request
{
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;
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;
}
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 ||
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)) {
{
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;
}
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) {
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);
}
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;
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));
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 */
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)
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) {
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);
}
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;
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;
*/
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;
{
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;
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;
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;
};
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;
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);
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;
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;
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);
}
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;
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);
}
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);
}
/*
*/
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);
}
/*
{
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;
#include "system/network.h"
#include "nbt_server/nbt_server.h"
#include "nbt_server/wins/winsserver.h"
+#include "lib/socket/socket.h"
/*
*/
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;
#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));
*/
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;
*/
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;
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) {
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;
*/
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 =
#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;
*/
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 =
*/
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);
{
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
*/
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);
{
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
/* listen for broadcasts on port 137 */
bcast_nbtsock = nbt_name_socket_init(iface, nbtsrv->task->event_ctx);
- NT_STATUS_HAVE_NO_MEMORY(bcast_nbtsock);
+ if (!bcast_nbtsock) {
+ talloc_free(iface);
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ bcast_address = socket_address_from_strings(bcast_nbtsock, bcast_nbtsock->sock->backend_name,
+ bcast, lp_nbt_port());
+ if (!bcast_address) {
+ talloc_free(iface);
+ return NT_STATUS_NO_MEMORY;
+ }
- status = socket_listen(bcast_nbtsock->sock, bcast, lp_nbt_port(), 0, 0);
+ status = socket_listen(bcast_nbtsock->sock, bcast_address, 0, 0);
if (!NT_STATUS_IS_OK(status)) {
DEBUG(0,("Failed to bind to %s:%d - %s\n",
bcast, lp_nbt_port(), nt_errstr(status)));
talloc_free(iface);
return status;
}
+ talloc_free(bcast_address);
nbt_set_incoming_handler(bcast_nbtsock, nbtd_request_handler, iface);
}
/* listen for unicasts on port 137 */
iface->nbtsock = nbt_name_socket_init(iface, nbtsrv->task->event_ctx);
- NT_STATUS_HAVE_NO_MEMORY(iface->nbtsock);
+ if (!iface->nbtsock) {
+ talloc_free(iface);
+ return NT_STATUS_NO_MEMORY;
+ }
- status = socket_listen(iface->nbtsock->sock, bind_address, lp_nbt_port(), 0, 0);
+ unicast_address = socket_address_from_strings(iface->nbtsock, iface->nbtsock->sock->backend_name,
+ bind_address, lp_nbt_port());
+
+ status = socket_listen(iface->nbtsock->sock, unicast_address, 0, 0);
if (!NT_STATUS_IS_OK(status)) {
DEBUG(0,("Failed to bind to %s:%d - %s\n",
bind_address, lp_nbt_port(), nt_errstr(status)));
talloc_free(iface);
return status;
}
+ talloc_free(unicast_address);
+
nbt_set_incoming_handler(iface->nbtsock, nbtd_request_handler, iface);
/* also setup the datagram listeners */
#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
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);
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;
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",
#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)
{
*/
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;
#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)) {
*/
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);
*/
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)
{
*/
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;
*/
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;
*/
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;
*/
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;
#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;
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)
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);
}
/*
*/
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,
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;
#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
*/
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,
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);
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);
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;
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);
}
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)));
}
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
done:
nbtd_name_registration_reply(s->nbtsock, s->request_packet,
- &s->src, NBT_RCODE_OK);
+ s->src, NBT_RCODE_OK);
failed:
talloc_free(s);
}
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,
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;
*/
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,
*/
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,
*/
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,
* 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;
}
*/
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);
const char *server_name)
{
BOOL ret;
- char *str;
+ struct socket_address *myaddr;
/* NULL is ok */
if (!server_name) return WERR_OK;
* 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());
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;
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;
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);
/*
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)
{
const char *username;
const char *password;
const char *domain;
- const char *remote_host;
+ const char *workstation;
struct MprVar auth;
struct cli_credentials *creds;
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());
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);
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++;
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++;
}
+
/*
Unix SMB/CIFS implementation.
handle SMBsessionsetup
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;
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);
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;
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;
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);
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;
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 */
{
NTSTATUS status;
struct stream_socket *stream_socket;
+ struct socket_address *socket_address;
int i;
stream_socket = talloc_zero(event_context, struct stream_socket);
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)) {
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;
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();
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));
}
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",
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);
{
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;
CHECK_STATUS(status, NT_STATUS_OK);
talloc_steal(mem_ctx, sock2);
- status = socket_listen(sock1, iface_best_ip("127.0.0.1"), 0, 0, 0);
+ localhost = socket_address_from_strings(sock1, sock1->backend_name,
+ iface_best_ip("127.0.0.1"), 0);
+ if (!localhost) {
+ return False;
+ }
+
+ status = socket_listen(sock1, localhost, 0, 0);
CHECK_STATUS(status, NT_STATUS_OK);
srv_addr = socket_get_my_addr(sock1, mem_ctx);
- if (srv_addr == NULL || strcmp(srv_addr, iface_best_ip("127.0.0.1")) != 0) {
+ if (srv_addr == NULL || strcmp(srv_addr->addr, iface_best_ip("127.0.0.1")) != 0) {
printf("Expected server address of %s but got %s\n",
- iface_best_ip("127.0.0.1"), srv_addr);
+ iface_best_ip("127.0.0.1"), srv_addr ? srv_addr->addr : NULL);
return False;
}
- srv_port = socket_get_my_port(sock1);
- printf("server port is %d\n", srv_port);
+ printf("server port is %d\n", srv_addr->port);
blob = data_blob_talloc(mem_ctx, NULL, size);
blob2 = data_blob_talloc(mem_ctx, NULL, size);
generate_random_buffer(blob.data, blob.length);
sent = size;
- status = socket_sendto(sock2, &blob, &sent, 0, srv_addr, srv_port);
+ status = socket_sendto(sock2, &blob, &sent, 0, srv_addr);
CHECK_STATUS(status, NT_STATUS_OK);
status = socket_recvfrom(sock1, blob2.data, size, &nread, 0,
- &from_addr, &from_port);
+ sock1, &from_addr);
CHECK_STATUS(status, NT_STATUS_OK);
- if (strcmp(from_addr, srv_addr) != 0) {
- printf("Unexpected recvfrom addr %s\n", from_addr);
+ if (strcmp(from_addr->addr, srv_addr->addr) != 0) {
+ printf("Unexpected recvfrom addr %s\n", from_addr->addr);
ret = False;
}
if (nread != size) {
}
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) {
{
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;
CHECK_STATUS(status, NT_STATUS_OK);
talloc_steal(mem_ctx, sock2);
- status = socket_listen(sock1, iface_best_ip("127.0.0.1"), 0, 0, 0);
+ localhost = socket_address_from_strings(sock1, sock1->backend_name,
+ iface_best_ip("127.0.0.1"), 0);
+ if (!localhost) {
+ return False;
+ }
+
+ status = socket_listen(sock1, localhost, 0, 0);
CHECK_STATUS(status, NT_STATUS_OK);
srv_addr = socket_get_my_addr(sock1, mem_ctx);
- if (srv_addr == NULL || strcmp(srv_addr, iface_best_ip("127.0.0.1")) != 0) {
+ if (srv_addr == NULL || !srv_addr->addr) {
+ printf("Unexpected socket_get_my_addr NULL\n");
+ return False;
+ }
+
+ if (strcmp(srv_addr->addr, iface_best_ip("127.0.0.1")) != 0) {
printf("Expected server address of %s but got %s\n",
- iface_best_ip("127.0.0.1"), srv_addr);
+ iface_best_ip("127.0.0.1"), srv_addr ? srv_addr->addr : NULL);
return False;
}
- srv_port = socket_get_my_port(sock1);
- printf("server port is %d\n", srv_port);
+ printf("server port is %d\n", srv_addr->port);
- status = socket_connect_ev(sock2, NULL, 0, srv_addr, srv_port, 0, ev);
+ status = socket_connect_ev(sock2, NULL, srv_addr, 0, ev);
CHECK_STATUS(status, NT_STATUS_OK);
status = socket_accept(sock1, &sock3);
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) {
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) {
*/
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;
{
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;
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 */
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));
{
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;
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 */
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));
*/
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;
{
struct dgram_mailslot_handler *dgmslot;
struct nbt_dgram_socket *dgmsock = nbt_dgram_socket_init(mem_ctx, NULL);
- struct nbt_peer_socket dest;
+ struct socket_address *dest;
+ struct test_join *join_ctx;
+ struct cli_credentials *machine_credentials;
+ const char *dom_sid;
+
const char *myaddress = talloc_strdup(dgmsock, iface_best_ip(address));
struct nbt_ntlogon_packet logon;
struct nbt_name myname;
NTSTATUS status;
struct timeval tv = timeval_current();
int replies = 0;
- struct test_join *join_ctx;
- struct cli_credentials *machine_credentials;
- const char *dom_sid;
- join_ctx = torture_join_domain(TEST_NAME,
- ACB_WSTRUST, &machine_credentials);
- if (join_ctx == NULL) {
- printf("Failed to join domain %s as %s\n", lp_workgroup(), TEST_NAME);
- talloc_free(dgmsock);
+ struct socket_address *socket_address;
+
+ socket_address = socket_address_from_strings(dgmsock, dgmsock->sock->backend_name,
+ myaddress, lp_dgram_port());
+ if (!socket_address) {
return False;
}
- dom_sid = torture_join_sid(join_ctx);
-
/* try receiving replies on port 138 first, which will only
work if we are root and smbd/nmbd are not running - fall
back to listening on any port, which means replies from
some windows versions won't be seen */
- status = socket_listen(dgmsock->sock, myaddress, lp_dgram_port(), 0, 0);
+ status = socket_listen(dgmsock->sock, socket_address, 0, 0);
if (!NT_STATUS_IS_OK(status)) {
- socket_listen(dgmsock->sock, myaddress, 0, 0, 0);
+ talloc_free(socket_address);
+ socket_address = socket_address_from_strings(dgmsock, dgmsock->sock->backend_name,
+ myaddress, 0);
+ if (!socket_address) {
+ return False;
+ }
+
+ socket_listen(dgmsock->sock, socket_address, 0, 0);
+ }
+
+ join_ctx = torture_join_domain(TEST_NAME,
+ ACB_WSTRUST, &machine_credentials);
+ if (join_ctx == NULL) {
+ printf("Failed to join domain %s as %s\n", lp_workgroup(), TEST_NAME);
+ talloc_free(dgmsock);
+ return False;
}
+ dom_sid = torture_join_sid(join_ctx);
+
/* setup a temporary mailslot listener for replies */
dgmslot = dgram_mailslot_temp(dgmsock, NBT_MAILSLOT_GETDC,
ntlogon_handler, &replies);
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;
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");
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;
}
struct nbt_name_socket *nbtsock = nbt_name_socket_init(mem_ctx, NULL);
BOOL ret = True;
const char *myaddress = iface_best_ip(address);
+ struct socket_address *socket_address;
+
+ socket_address = socket_address_from_strings(mem_ctx, nbtsock->sock->backend_name,
+ myaddress, 0);
+ if (!socket_address) {
+ return False;
+ }
- socket_listen(nbtsock->sock, myaddress, 0, 0, 0);
+ status = socket_listen(nbtsock->sock, socket_address, 0, 0);
+ if (!NT_STATUS_IS_OK(status)) {
+ printf("socket_listen for nbt_referesh_own failed: %s\n", nt_errstr(status));
+ return False;
+ }
printf("Testing name defense to name refresh\n");
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);
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);
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) {
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;
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;
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;
}
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;
}
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);
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;
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)
{
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;
}
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;
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;
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;
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;
}
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);
/* 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] != '/') {
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 { \
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", "");
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");
}
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);
}
{
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) {
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;