From 9d055846f225bea4953822f40fab1d2f1a2e2d07 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 27 Oct 2004 03:15:42 +0000 Subject: r3278: - rewrote the client side rpc connection code to use lib/socket/ rather than doing everything itself. This greatly simplifies the code, although I really don't like the socket_recv() interface (it always allocates memory for you, which means an extra memcpy in this code) - fixed several bugs in the socket_ipv4.c code, in particular client side code used a non-blocking connect but didn't handle EINPROGRESS, so it had no chance of working. Also fixed the error codes, using map_nt_error_from_unix() - cleaned up and expanded map_nt_error_from_unix() - changed interpret_addr2() to not take a mem_ctx. It makes absolutely no sense to allocate a fixed size 4 byte structure like this. Dozens of places in the code were also using interpret_addr2() incorrectly (precisely because the allocation made no sense) (This used to be commit 7f2c771b0e0e98c5c9e5cf662592d64d34ff1205) --- source4/auth/auth_domain.c | 2 +- source4/client/smbmount.c | 2 +- source4/ldap_server/ldap_server.c | 8 +- source4/lib/interface.c | 10 +- source4/lib/socket/socket.c | 2 +- source4/lib/socket/socket_ipv4.c | 105 ++++--------- source4/lib/socket/socket_unix.c | 26 +--- source4/lib/util.c | 24 ++- source4/lib/util_sock.c | 8 +- source4/lib/wins_srv.c | 4 +- source4/libads/ldap.c | 2 +- source4/libcli/namequery.c | 6 +- source4/libcli/util/errormap.c | 73 ++++----- source4/librpc/rpc/dcerpc_sock.c | 302 ++++++++++---------------------------- source4/librpc/rpc/dcerpc_util.c | 9 +- source4/ntvfs/posix/pvfs_wait.c | 4 +- source4/rpc_server/dcerpc_sock.c | 7 +- source4/smb_server/smb_server.c | 14 +- source4/torture/rpc/epmapper.c | 4 +- source4/utils/nmblookup.c | 6 +- 20 files changed, 198 insertions(+), 420 deletions(-) (limited to 'source4') diff --git a/source4/auth/auth_domain.c b/source4/auth/auth_domain.c index 831bb4cfe0..028bfc550b 100644 --- a/source4/auth/auth_domain.c +++ b/source4/auth/auth_domain.c @@ -79,7 +79,7 @@ static NTSTATUS rpc_resolve_dc(const char *server, struct in_addr *dest_ip) { if (is_ipaddress(server)) { - struct in_addr to_ip = *interpret_addr2(server); + struct in_addr to_ip = interpret_addr2(server); /* we need to know the machines netbios name - this is a lousy way to find it, but until we have a RPC call that does this diff --git a/source4/client/smbmount.c b/source4/client/smbmount.c index 795bd50812..dd72672bbb 100644 --- a/source4/client/smbmount.c +++ b/source4/client/smbmount.c @@ -787,7 +787,7 @@ static void parse_mount_smb(int argc, char **argv) } else if(!strcmp(opts, "debug")) { DEBUGLEVEL = val; } else if(!strcmp(opts, "ip")) { - dest_ip = *interpret_addr2(opteq+1); + dest_ip = interpret_addr2(opteq+1); if (is_zero_ip(dest_ip)) { fprintf(stderr,"Can't resolve address %s\n", opteq+1); exit(1); diff --git a/source4/ldap_server/ldap_server.c b/source4/ldap_server/ldap_server.c index dcce32874d..6ce2dfdd79 100644 --- a/source4/ldap_server/ldap_server.c +++ b/source4/ldap_server/ldap_server.c @@ -110,13 +110,11 @@ static void ldapsrv_init(struct server_service *service, add_socket(service, model_ops, ifip); } } else { - struct in_addr *ifip; + struct in_addr ifip; /* Just bind to lp_socket_address() (usually 0.0.0.0) */ - ifip = interpret_addr2(service, lp_socket_address()); - add_socket(service, model_ops, ifip); - - talloc_destroy(ifip); + ifip = interpret_addr2(lp_socket_address()); + add_socket(service, model_ops, &ifip); } } diff --git a/source4/lib/interface.c b/source4/lib/interface.c index 14abfbd09a..b842fbb292 100644 --- a/source4/lib/interface.c +++ b/source4/lib/interface.c @@ -116,7 +116,7 @@ static void interpret_interface(TALLOC_CTX *mem_ctx, const char *token) /* maybe it is a DNS name */ p = strchr_m(token,'/'); if (!p) { - ip = *interpret_addr2(mem_ctx, token); + ip = interpret_addr2(token); for (i=0;i 2) { - nmask = *interpret_addr2(mem_ctx, p); + nmask = interpret_addr2(p); } else { nmask.s_addr = htonl(((ALLONES >> atoi(p)) ^ ALLONES)); } @@ -174,8 +174,8 @@ void load_interfaces(void) return; } - allones_ip = *interpret_addr2(mem_ctx, "255.255.255.255"); - loopback_ip = *interpret_addr2(mem_ctx, "127.0.0.1"); + allones_ip = interpret_addr2("255.255.255.255"); + loopback_ip = interpret_addr2("127.0.0.1"); SAFE_FREE(probed_ifaces); diff --git a/source4/lib/socket/socket.c b/source4/lib/socket/socket.c index f70a76262b..f5ee84a7cc 100644 --- a/source4/lib/socket/socket.c +++ b/source4/lib/socket/socket.c @@ -134,7 +134,7 @@ NTSTATUS socket_accept(struct socket_context *sock, struct socket_context **new_ } NTSTATUS socket_recv(struct socket_context *sock, TALLOC_CTX *mem_ctx, - DATA_BLOB *blob, size_t wantlen, uint32_t flags) + DATA_BLOB *blob, size_t wantlen, uint32_t flags) { if (sock->type != SOCKET_TYPE_STREAM) { return NT_STATUS_INVALID_PARAMETER; diff --git a/source4/lib/socket/socket_ipv4.c b/source4/lib/socket/socket_ipv4.c index 23e34dd39b..20dfd3c92f 100644 --- a/source4/lib/socket/socket_ipv4.c +++ b/source4/lib/socket/socket_ipv4.c @@ -24,8 +24,7 @@ static NTSTATUS ipv4_tcp_init(struct socket_context *sock) { sock->fd = socket(PF_INET, SOCK_STREAM, 0); if (sock->fd == -1) { - /* TODO: we need to map from errno to NTSTATUS here! */ - return NT_STATUS_FOOBAR; + return map_nt_error_from_unix(errno); } return NT_STATUS_OK; @@ -37,41 +36,34 @@ static void ipv4_tcp_close(struct socket_context *sock) } static NTSTATUS ipv4_tcp_connect(struct socket_context *sock, - const char *my_address, int my_port, - const char *srv_address, int srv_port, - uint32_t flags) + const char *my_address, int my_port, + const char *srv_address, int srv_port, + uint32_t flags) { - struct sockaddr_in my_addr; struct sockaddr_in srv_addr; struct in_addr my_ip; struct in_addr srv_ip; int ret; - ret = inet_aton(my_address, &my_ip); - if (ret == 0) { - /* not a valid ipv4 address */ - return NT_STATUS_FOOBAR; - } + my_ip = interpret_addr2(my_address); - ZERO_STRUCT(my_addr); + if (my_ip.s_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); + my_addr.sin_len = sizeof(my_addr); #endif - my_addr.sin_addr = my_ip; - my_addr.sin_port = htons(my_port); - my_addr.sin_family = PF_INET; - - ret = inet_aton(srv_address, &srv_ip); - if (ret == 0) { - /* not a valid ipv4 address */ - return NT_STATUS_FOOBAR; + my_addr.sin_addr = my_ip; + 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 (ret == -1) { + return map_nt_error_from_unix(errno); + } } - ret = bind(sock->fd, (struct sockaddr *)&my_addr, sizeof(my_addr)); - if (ret == -1) { - /* TODO: we need to map from errno to NTSTATUS here! */ - return NT_STATUS_FOOBAR; - } + srv_ip = interpret_addr2(srv_address); ZERO_STRUCT(srv_addr); #ifdef HAVE_SOCK_SIN_LEN @@ -81,20 +73,18 @@ static NTSTATUS ipv4_tcp_connect(struct socket_context *sock, srv_addr.sin_port = htons(srv_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); + } + if (!(flags & SOCKET_FLAG_BLOCK)) { ret = set_blocking(sock->fd, False); if (ret == -1) { - /* TODO: we need to map from errno to NTSTATUS here! */ - return NT_STATUS_FOOBAR; + return map_nt_error_from_unix(errno); } } - ret = connect(sock->fd, (const struct sockaddr *)&srv_addr, sizeof(srv_addr)); - if (ret == -1) { - /* TODO: we need to map from errno to NTSTATUS here! */ - return NT_STATUS_FOOBAR; - } - sock->state = SOCKET_STATE_CLIENT_CONNECTED; return NT_STATUS_OK; @@ -108,11 +98,7 @@ static NTSTATUS ipv4_tcp_listen(struct socket_context *sock, struct in_addr ip_addr; int ret; - ret = inet_aton(my_address, &ip_addr); - if (ret == 0) { - /* not a valid ipv4 address */ - return NT_STATUS_FOOBAR; - } + ip_addr = interpret_addr2(my_address); ZERO_STRUCT(my_addr); #ifdef HAVE_SOCK_SIN_LEN @@ -124,21 +110,18 @@ static NTSTATUS ipv4_tcp_listen(struct socket_context *sock, ret = bind(sock->fd, (struct sockaddr *)&my_addr, sizeof(my_addr)); if (ret == -1) { - /* TODO: we need to map from errno to NTSTATUS here! */ - return NT_STATUS_FOOBAR; + return map_nt_error_from_unix(errno); } ret = listen(sock->fd, queue_size); if (ret == -1) { - /* TODO: we need to map from errno to NTSTATUS here! */ - return NT_STATUS_FOOBAR; + return map_nt_error_from_unix(errno); } if (!(flags & SOCKET_FLAG_BLOCK)) { ret = set_blocking(sock->fd, False); if (ret == -1) { - /* TODO: we need to map from errno to NTSTATUS here! */ - return NT_STATUS_FOOBAR; + return map_nt_error_from_unix(errno); } } @@ -155,8 +138,7 @@ static NTSTATUS ipv4_tcp_accept(struct socket_context *sock, struct socket_conte new_fd = accept(sock->fd, (struct sockaddr *)&cli_addr, &cli_addr_len); if (new_fd == -1) { - /* TODO: we need to map from errno to NTSTATUS here! */ - return NT_STATUS_FOOBAR; + return map_nt_error_from_unix(errno); } /* TODO: we could add a 'accept_check' hook here @@ -257,34 +239,7 @@ static NTSTATUS ipv4_tcp_send(struct socket_context *sock, TALLOC_CTX *mem_ctx, len = send(sock->fd, blob->data, blob->length, flgs); if (len == -1) { - NTSTATUS status = NT_STATUS_UNSUCCESSFUL; - switch (errno) { - case EBADF: - case ENOTSOCK: - case EFAULT: - case EINVAL: - status = NT_STATUS_INVALID_PARAMETER; - break; - case EMSGSIZE: - status = NT_STATUS_INVALID_BUFFER_SIZE; - break; - case EAGAIN: - /*case EWOULDBLOCK: this is an alis of EAGAIN --metze */ - case EINTR: - *sendlen = 0; - status = STATUS_MORE_ENTRIES; - break; - case ENOBUFS: - status = NT_STATUS_FOOBAR; - break; - case ENOMEM: - status = NT_STATUS_NO_MEMORY; - break; - case EPIPE: - status = NT_STATUS_CONNECTION_DISCONNECTED; - break; - } - return status; + return map_nt_error_from_unix(errno); } *sendlen = len; diff --git a/source4/lib/socket/socket_unix.c b/source4/lib/socket/socket_unix.c index d75bb973fc..90802eae66 100644 --- a/source4/lib/socket/socket_unix.c +++ b/source4/lib/socket/socket_unix.c @@ -30,31 +30,7 @@ */ static NTSTATUS unixdom_error(int ernum) { - switch (ernum) { - case EBADF: - case ENOTCONN: - case ENOTSOCK: - case EFAULT: - case EINVAL: - return NT_STATUS_INVALID_PARAMETER; - case EAGAIN: - case EINTR: - return STATUS_MORE_ENTRIES; - case ECONNREFUSED: - return NT_STATUS_CONNECTION_REFUSED; - case ENOBUFS: - case ENOMEM: - return NT_STATUS_NO_MEMORY; - case ENFILE: - case EMFILE: - return NT_STATUS_INSUFFICIENT_RESOURCES; - case EPIPE: - return NT_STATUS_CONNECTION_DISCONNECTED; - case EMSGSIZE: - return NT_STATUS_INVALID_BUFFER_SIZE; - } - - return NT_STATUS_UNSUCCESSFUL; + return map_nt_error_from_unix(ernum); } static NTSTATUS unixdom_init(struct socket_context *sock) diff --git a/source4/lib/util.c b/source4/lib/util.c index 0982694823..d7c5661f7d 100644 --- a/source4/lib/util.c +++ b/source4/lib/util.c @@ -406,16 +406,18 @@ BOOL is_ipaddress(const char *str) /**************************************************************************** Interpret an internet address or name into an IP address in 4 byte form. ****************************************************************************/ - uint32_t interpret_addr(const char *str) { struct hostent *hp; uint32_t res; - if (strcmp(str,"0.0.0.0") == 0) - return(0); - if (strcmp(str,"255.255.255.255") == 0) - return(0xFFFFFFFF); + if (str == NULL || + strcmp(str,"0.0.0.0") == 0) { + return 0; + } + if (strcmp(str,"255.255.255.255") == 0) { + return 0xFFFFFFFF; + } /* if it's in the form of an IP address then get the lib to interpret it */ if (is_ipaddress(str)) { @@ -444,16 +446,12 @@ uint32_t interpret_addr(const char *str) /******************************************************************* A convenient addition to interpret_addr(). ******************************************************************/ - -struct in_addr *interpret_addr2(TALLOC_CTX *mem_ctx, const char *str) +struct in_addr interpret_addr2(const char *str) { - struct in_addr *ret; + struct in_addr ret; uint32_t a = interpret_addr(str); - - ret = talloc(mem_ctx, sizeof(struct in_addr)); - if (!ret) return NULL; - ret->s_addr = a; - return(ret); + ret.s_addr = a; + return ret; } /******************************************************************* diff --git a/source4/lib/util_sock.c b/source4/lib/util_sock.c index 387c72599a..638c44f705 100644 --- a/source4/lib/util_sock.c +++ b/source4/lib/util_sock.c @@ -408,14 +408,14 @@ int open_udp_socket(const char *host, int port) int type = SOCK_DGRAM; struct sockaddr_in sock_out; int res; - struct in_addr *addr; + struct in_addr addr; TALLOC_CTX *mem_ctx; mem_ctx = talloc_init("open_udp_socket"); if (!mem_ctx) { return -1; } - addr = interpret_addr2(mem_ctx, host); + addr = interpret_addr2(host); res = socket(PF_INET, type, 0); if (res == -1) { @@ -423,7 +423,7 @@ int open_udp_socket(const char *host, int port) } memset((char *)&sock_out,'\0',sizeof(sock_out)); - putip((char *)&sock_out.sin_addr,(char *)addr); + putip((char *)&sock_out.sin_addr,(char *)&addr); sock_out.sin_port = htons(port); sock_out.sin_family = PF_INET; @@ -508,7 +508,7 @@ char *get_socket_name(TALLOC_CTX *mem_ctx, int fd, BOOL force_lookup) name_buf = talloc_strdup(mem_ctx, "UNKNOWN"); if (fd == -1) return name_buf; - addr = *interpret_addr2(mem_ctx, p); + addr = interpret_addr2(p); /* Look up the remote host name. */ if ((hp = gethostbyaddr((char *)&addr.s_addr, sizeof(addr.s_addr), AF_INET)) == 0) { diff --git a/source4/lib/wins_srv.c b/source4/lib/wins_srv.c index 71368658b0..eb7f280e6f 100644 --- a/source4/lib/wins_srv.c +++ b/source4/lib/wins_srv.c @@ -174,11 +174,11 @@ static void parse_ip(TALLOC_CTX *mem_ctx, struct tagged_ip *ip, const char *str) char *s = strchr(str, ':'); if (!s) { fstrcpy(ip->tag, "*"); - ip->ip = *interpret_addr2(mem_ctx, str); + ip->ip = interpret_addr2(str); return; } - ip->ip = *interpret_addr2(mem_ctx, s+1); + ip->ip = interpret_addr2(s+1); fstrcpy(ip->tag, str); s = strchr(ip->tag, ':'); if (s) *s = 0; diff --git a/source4/libads/ldap.c b/source4/libads/ldap.c index 9ada5acd77..9de73fcd0a 100644 --- a/source4/libads/ldap.c +++ b/source4/libads/ldap.c @@ -64,7 +64,7 @@ static BOOL ads_try_connect(ADS_STRUCT *ads, const char *server, uint_t port) return False; } ads->ldap_port = port; - ads->ldap_ip = *interpret_addr2(srv); + ads->ldap_ip = interpret_addr2(srv); free(srv); return True; diff --git a/source4/libcli/namequery.c b/source4/libcli/namequery.c index de0f406209..0f21e33b85 100644 --- a/source4/libcli/namequery.c +++ b/source4/libcli/namequery.c @@ -522,7 +522,7 @@ BOOL getlmhostsent( TALLOC_CTX *mem_ctx, continue; } - *ipaddr = *interpret_addr2(mem_ctx, ip); + *ipaddr = interpret_addr2(ip); /* Extra feature. If the name ends in '#XX', where XX is a hex number, then only add that name type. */ @@ -643,7 +643,7 @@ BOOL resolve_wins(TALLOC_CTX *mem_ctx, const char *name, int name_type, } /* the address we will be sending from */ - src_ip = *interpret_addr2(mem_ctx, lp_socket_address()); + src_ip = interpret_addr2(lp_socket_address()); /* in the worst case we will try every wins server with every tag! */ @@ -900,7 +900,7 @@ BOOL resolve_name(TALLOC_CTX *mem_ctx, const char *name, struct in_addr *return_ int count = 0; if (is_ipaddress(name)) { - *return_ip = *interpret_addr2(mem_ctx, name); + *return_ip = interpret_addr2(name); return True; } diff --git a/source4/libcli/util/errormap.c b/source4/libcli/util/errormap.c index 91ebddc181..46e4831f89 100644 --- a/source4/libcli/util/errormap.c +++ b/source4/libcli/util/errormap.c @@ -1490,66 +1490,69 @@ WERROR ntstatus_to_werror(NTSTATUS error) struct unix_error_map { int unix_error; - int dos_class; - int dos_code; NTSTATUS nt_error; }; -const struct unix_error_map unix_dos_nt_errmap[] = { - { EPERM, ERRDOS, ERRnoaccess, NT_STATUS_ACCESS_DENIED }, - { EACCES, ERRDOS, ERRnoaccess, NT_STATUS_ACCESS_DENIED }, - { ENOENT, ERRDOS, ERRbadfile, NT_STATUS_OBJECT_NAME_NOT_FOUND }, - { ENOTDIR, ERRDOS, ERRbadpath, NT_STATUS_NOT_A_DIRECTORY }, - { EIO, ERRHRD, ERRgeneral, NT_STATUS_IO_DEVICE_ERROR }, - { EBADF, ERRSRV, ERRsrverror, NT_STATUS_INVALID_HANDLE }, - { EINVAL, ERRSRV, ERRsrverror, NT_STATUS_INVALID_HANDLE }, - { EEXIST, ERRDOS, ERRfilexists, NT_STATUS_OBJECT_NAME_COLLISION}, - { ENFILE, ERRDOS, ERRnofids, NT_STATUS_TOO_MANY_OPENED_FILES }, - { EMFILE, ERRDOS, ERRnofids, NT_STATUS_TOO_MANY_OPENED_FILES }, - { ENOSPC, ERRHRD, ERRdiskfull, NT_STATUS_DISK_FULL }, - { EISDIR, ERRDOS, ERRbadpath, NT_STATUS_FILE_IS_A_DIRECTORY }, +const struct unix_error_map unix_nt_errmap[] = { + { EAGAIN, STATUS_MORE_ENTRIES }, + { EINTR, STATUS_MORE_ENTRIES }, + { EINPROGRESS, STATUS_MORE_ENTRIES }, + { EPERM, NT_STATUS_ACCESS_DENIED }, + { EACCES, NT_STATUS_ACCESS_DENIED }, + { ENOENT, NT_STATUS_OBJECT_NAME_NOT_FOUND }, + { ENOTDIR, NT_STATUS_NOT_A_DIRECTORY }, + { EIO, NT_STATUS_IO_DEVICE_ERROR }, + { EBADF, NT_STATUS_INVALID_HANDLE }, + { EINVAL, NT_STATUS_INVALID_PARAMETER }, + { EEXIST, NT_STATUS_OBJECT_NAME_COLLISION}, + { ENFILE, NT_STATUS_TOO_MANY_OPENED_FILES }, + { EMFILE, NT_STATUS_TOO_MANY_OPENED_FILES }, + { ENOSPC, NT_STATUS_DISK_FULL }, + { EISDIR, NT_STATUS_FILE_IS_A_DIRECTORY }, + { ENOTSOCK, NT_STATUS_INVALID_HANDLE }, + { EFAULT, NT_STATUS_INVALID_PARAMETER }, + { EMSGSIZE, NT_STATUS_INVALID_BUFFER_SIZE }, + { ENOBUFS, NT_STATUS_NO_MEMORY }, + { ENOMEM, NT_STATUS_NO_MEMORY }, + { EPIPE, NT_STATUS_CONNECTION_DISCONNECTED }, + { ECONNREFUSED, NT_STATUS_CONNECTION_REFUSED }, + { EBUSY, NT_STATUS_SHARING_VIOLATION }, #ifdef EDQUOT - { EDQUOT, ERRHRD, ERRdiskfull, NT_STATUS_DISK_FULL }, + { EDQUOT, NT_STATUS_QUOTA_EXCEEDED }, #endif #ifdef ENOTEMPTY - { ENOTEMPTY, ERRDOS, ERRnoaccess, NT_STATUS_DIRECTORY_NOT_EMPTY }, + { ENOTEMPTY, NT_STATUS_DIRECTORY_NOT_EMPTY }, #endif #ifdef EXDEV - { EXDEV, ERRDOS, ERRdiffdevice, NT_STATUS_NOT_SAME_DEVICE }, + { EXDEV, NT_STATUS_NOT_SAME_DEVICE }, #endif #ifdef EROFS - { EROFS, ERRHRD, ERRnowrite, NT_STATUS_ACCESS_DENIED }, + { EROFS, NT_STATUS_MEDIA_WRITE_PROTECTED }, #endif #ifdef ENAMETOOLONG - { ENAMETOOLONG, ERRDOS, 206, NT_STATUS_OBJECT_NAME_INVALID }, + { ENAMETOOLONG, NT_STATUS_NAME_TOO_LONG }, #endif #ifdef EFBIG - { EFBIG, ERRHRD, ERRdiskfull, NT_STATUS_DISK_FULL }, + { EFBIG, NT_STATUS_DISK_FULL }, #endif -#ifdef EFBIG - { EBUSY, ERRDOS, ERRbadshare, NT_STATUS_SHARING_VIOLATION }, -#endif - { 0, 0, 0, NT_STATUS_OK } + { 0, NT_STATUS_UNSUCCESSFUL } }; + /********************************************************************* Map an NT error code from a Unix error code. *********************************************************************/ NTSTATUS map_nt_error_from_unix(int unix_error) { - int i = 0; - - if (unix_error == 0) { - return NT_STATUS_UNSUCCESSFUL; - } + int i; /* Look through list */ - while(unix_dos_nt_errmap[i].unix_error != 0) { - if (unix_dos_nt_errmap[i].unix_error == unix_error) - return unix_dos_nt_errmap[i].nt_error; - i++; + for (i=0;itransport.private; - if (sock && sock->fd != -1) { - close(sock->fd); - sock->fd = -1; + if (sock && sock->sock != NULL) { + talloc_free(sock->sock); + sock->sock = NULL; } /* wipe any pending sends */ @@ -81,20 +81,19 @@ static void sock_process_send(struct dcerpc_pipe *p) while (sock->pending_send) { struct sock_blob *blob = sock->pending_send; - ssize_t ret = write(sock->fd, blob->data.data, blob->data.length); - if (ret == -1) { - if (errno != EAGAIN && errno != EINTR) { - sock_dead(p, NT_STATUS_NET_WRITE_FAULT); - } + NTSTATUS status; + size_t sent; + status = socket_send(sock->sock, blob, &blob->data, &sent, 0); + if (NT_STATUS_IS_ERR(status)) { + sock_dead(p, NT_STATUS_NET_WRITE_FAULT); break; } - if (ret == 0) { - sock_dead(p, NT_STATUS_NET_WRITE_FAULT); + if (sent == 0) { break; } - blob->data.data += ret; - blob->data.length -= ret; + blob->data.data += sent; + blob->data.length -= sent; if (blob->data.length != 0) { break; @@ -116,7 +115,8 @@ static void sock_process_send(struct dcerpc_pipe *p) static void sock_process_recv(struct dcerpc_pipe *p) { struct sock_private *sock = p->transport.private; - ssize_t ret; + NTSTATUS status; + DATA_BLOB blob; if (sock->recv.data.data == NULL) { sock->recv.data = data_blob_talloc(sock, NULL, MIN_HDR_SIZE); @@ -126,20 +126,19 @@ static void sock_process_recv(struct dcerpc_pipe *p) if (sock->recv.received < MIN_HDR_SIZE) { uint32_t frag_length; - ret = read(sock->fd, sock->recv.data.data, - MIN_HDR_SIZE - sock->recv.received); - if (ret == -1) { - if (errno != EAGAIN && errno != EINTR) { - sock_dead(p, NT_STATUS_NET_WRITE_FAULT); - } + status = socket_recv(sock->sock, sock, &blob, MIN_HDR_SIZE - sock->recv.received, 0); + if (NT_STATUS_IS_ERR(status)) { + sock_dead(p, NT_STATUS_NET_WRITE_FAULT); return; } - if (ret == 0) { - sock_dead(p, NT_STATUS_NET_WRITE_FAULT); + if (blob.length == 0) { return; } - - sock->recv.received += ret; + + memcpy(sock->recv.data.data + sock->recv.received, + blob.data, blob.length); + sock->recv.received += blob.length; + talloc_free(blob.data); if (sock->recv.received != MIN_HDR_SIZE) { return; @@ -156,20 +155,18 @@ static void sock_process_recv(struct dcerpc_pipe *p) } /* read in the rest of the packet */ - ret = read(sock->fd, sock->recv.data.data + sock->recv.received, - sock->recv.data.length - sock->recv.received); - if (ret == -1) { - if (errno != EAGAIN && errno != EINTR) { - sock_dead(p, NT_STATUS_NET_WRITE_FAULT); - } + status = socket_recv(sock->sock, sock, &blob, sock->recv.data.length - sock->recv.received, 0); + if (NT_STATUS_IS_ERR(status)) { + sock_dead(p, NT_STATUS_NET_WRITE_FAULT); return; } - if (ret == 0) { - sock_dead(p, NT_STATUS_NET_WRITE_FAULT); + if (blob.length == 0) { return; } - - sock->recv.received += ret; + memcpy(sock->recv.data.data + sock->recv.received, + blob.data, blob.length); + sock->recv.received += blob.length; + talloc_free(blob.data); if (sock->recv.received != sock->recv.data.length) { return; @@ -199,7 +196,7 @@ static void sock_io_handler(struct event_context *ev, struct fd_event *fde, sock_process_send(p); } - if (sock->fd == -1) { + if (sock->sock == NULL) { return; } @@ -282,67 +279,50 @@ static const char *sock_peer_name(struct dcerpc_pipe *p) } /* - open a rpc connection to a named pipe + open a rpc connection using the generic socket library */ -NTSTATUS dcerpc_pipe_open_tcp(struct dcerpc_pipe **p, - const char *server, - uint32_t port, - int family) +static NTSTATUS dcerpc_pipe_open_socket(struct dcerpc_pipe **p, + const char *server, + uint32_t port, + const char *type, + enum dcerpc_transport_t transport) { struct sock_private *sock; - int fd, gai_err; + struct socket_context *socket_ctx; struct fd_event fde; - struct addrinfo hints, *res, *tmpres; - char portname[16]; + NTSTATUS status; if (port == 0) { port = EPMAPPER_PORT; } - memset(&hints, 0, sizeof(struct addrinfo)); - - hints.ai_family = family; - hints.ai_socktype = SOCK_STREAM; - - snprintf(portname, sizeof(portname)-1, "%d", port); - - gai_err = getaddrinfo(server, portname, &hints, &res); - if (gai_err < 0) - { - DEBUG(0, ("Unable to connect to %s:%d : %s\n", server, port, gai_strerror(gai_err))); - return NT_STATUS_BAD_NETWORK_NAME; + if (!(*p = dcerpc_pipe_init())) { + return NT_STATUS_NO_MEMORY; } - - tmpres = res; - - while (tmpres) { - fd = socket(tmpres->ai_family, tmpres->ai_socktype, tmpres->ai_protocol); - - if(fd >= 0) { - if (connect(fd, tmpres->ai_addr, tmpres->ai_addrlen) == 0) - break; - fd = -1; - } - - tmpres = tmpres->ai_next; + + sock = talloc_p((*p), struct sock_private); + if (!sock) { + talloc_free(*p); + return NT_STATUS_NO_MEMORY; } - freeaddrinfo(res); - - if (fd == -1) { - return NT_STATUS_PORT_CONNECTION_REFUSED; + status = socket_create(type, SOCKET_TYPE_STREAM, &socket_ctx, 0); + if (!NT_STATUS_IS_OK(status)) { + talloc_free(*p); + return status; } + talloc_steal(sock, socket_ctx); - set_socket_options(fd, lp_socket_options()); - - if (!(*p = dcerpc_pipe_init())) { - return NT_STATUS_NO_MEMORY; + status = socket_connect(socket_ctx, NULL, 0, server, port, 0); + if (!NT_STATUS_IS_OK(status)) { + talloc_free(*p); + return status; } - + /* fill in the transport methods */ - (*p)->transport.transport = NCACN_IP_TCP; + (*p)->transport.transport = transport; (*p)->transport.private = NULL; (*p)->transport.send_request = sock_send_request; @@ -353,13 +333,7 @@ NTSTATUS dcerpc_pipe_open_tcp(struct dcerpc_pipe **p, (*p)->transport.shutdown_pipe = sock_shutdown_pipe; (*p)->transport.peer_name = sock_peer_name; - sock = talloc((*p), sizeof(*sock)); - if (!sock) { - dcerpc_pipe_close(*p); - return NT_STATUS_NO_MEMORY; - } - - sock->fd = fd; + sock->sock = socket_ctx; sock->server_name = talloc_strdup((*p), server); sock->event_ctx = event_context_init(sock); sock->pending_send = NULL; @@ -367,7 +341,7 @@ NTSTATUS dcerpc_pipe_open_tcp(struct dcerpc_pipe **p, sock->recv.data = data_blob(NULL, 0); sock->recv.pending_count = 0; - fde.fd = fd; + fde.fd = socket_get_fd(sock->sock); fde.flags = 0; fde.handler = sock_io_handler; fde.private = *p; @@ -379,160 +353,40 @@ NTSTATUS dcerpc_pipe_open_tcp(struct dcerpc_pipe **p, /* ensure we don't get SIGPIPE */ BlockSignals(True,SIGPIPE); - return NT_STATUS_OK; + return NT_STATUS_OK; } /* - open a rpc connection to a unix socket + open a rpc connection using tcp */ -NTSTATUS dcerpc_pipe_open_unix_stream(struct dcerpc_pipe **p, - const char *path) +NTSTATUS dcerpc_pipe_open_tcp(struct dcerpc_pipe **p, const char *server, uint32_t port) { - struct sock_private *sock; - int fd; - struct fd_event fde; - struct sockaddr_un sa; - - fd = socket(PF_UNIX, SOCK_STREAM, 0); - - if (fd < 0) { - return NT_STATUS_NOT_SUPPORTED; - } - - sa.sun_family = AF_UNIX; - strncpy(sa.sun_path, path, sizeof(sa.sun_path)); - - if (connect(fd, &sa, sizeof(sa)) < 0) { - DEBUG(0, ("Unable to connect to unix socket %s: %s\n", path, strerror(errno))); - return NT_STATUS_BAD_NETWORK_NAME; - } - - set_socket_options(fd, lp_socket_options()); - - if (!(*p = dcerpc_pipe_init())) { - return NT_STATUS_NO_MEMORY; - } - - /* - fill in the transport methods - */ - (*p)->transport.transport = NCACN_UNIX_STREAM; - (*p)->transport.private = NULL; - - (*p)->transport.send_request = sock_send_request; - (*p)->transport.send_read = sock_send_read; - (*p)->transport.event_context = sock_event_context; - (*p)->transport.recv_data = NULL; - - (*p)->transport.shutdown_pipe = sock_shutdown_pipe; - (*p)->transport.peer_name = sock_peer_name; - - sock = talloc((*p), sizeof(*sock)); - if (!sock) { - dcerpc_pipe_close(*p); - return NT_STATUS_NO_MEMORY; - } - - sock->fd = fd; - sock->server_name = talloc_strdup((*p), path); - sock->event_ctx = event_context_init(sock); - sock->pending_send = NULL; - sock->recv.received = 0; - sock->recv.data = data_blob(NULL, 0); - sock->recv.pending_count = 0; - - fde.fd = fd; - fde.flags = 0; - fde.handler = sock_io_handler; - fde.private = *p; - - sock->fde = event_add_fd(sock->event_ctx, &fde); - - (*p)->transport.private = sock; - - /* ensure we don't get SIGPIPE */ - BlockSignals(True,SIGPIPE); + return dcerpc_pipe_open_socket(p, server, port, "ip", NCACN_IP_TCP); +} - return NT_STATUS_OK; +/* + open a rpc connection to a unix socket +*/ +NTSTATUS dcerpc_pipe_open_unix_stream(struct dcerpc_pipe **p, const char *path) +{ + return dcerpc_pipe_open_socket(p, path, 0, "unix", NCACN_UNIX_STREAM); } /* open a rpc connection to a named pipe */ -NTSTATUS dcerpc_pipe_open_pipe(struct dcerpc_pipe **p, - const char *identifier) +NTSTATUS dcerpc_pipe_open_pipe(struct dcerpc_pipe **p, const char *identifier) { - struct sock_private *sock; - int fd; - struct fd_event fde; - struct sockaddr_un sa; + NTSTATUS status; char *canon, *full_path; - if (!(*p = dcerpc_pipe_init())) { - return NT_STATUS_NO_MEMORY; - } - - canon = talloc_strdup(*p, identifier); + canon = talloc_strdup(NULL, identifier); string_replace(canon, '/', '\\'); + full_path = talloc_asprintf(canon, "%s/%s", lp_ncalrpc_dir(), canon); - full_path = talloc_asprintf(*p, "%s/%s", lp_ncalrpc_dir(), canon); - - fd = socket(PF_UNIX, SOCK_STREAM, 0); - - if (fd < 0) { - return NT_STATUS_NOT_SUPPORTED; - } - - sa.sun_family = AF_UNIX; - strncpy(sa.sun_path, full_path, sizeof(sa.sun_path)); - - if (connect(fd, &sa, sizeof(sa)) < 0) { - DEBUG(0, ("Unable to connect to unix socket %s (%s): %s\n", full_path, identifier, strerror(errno))); - return NT_STATUS_BAD_NETWORK_NAME; - } - - set_socket_options(fd, lp_socket_options()); - - /* - fill in the transport methods - */ - (*p)->transport.transport = NCALRPC; - (*p)->transport.private = NULL; - - (*p)->transport.send_request = sock_send_request; - (*p)->transport.send_read = sock_send_read; - (*p)->transport.event_context = sock_event_context; - (*p)->transport.recv_data = NULL; - - (*p)->transport.shutdown_pipe = sock_shutdown_pipe; - (*p)->transport.peer_name = sock_peer_name; - - sock = talloc((*p), sizeof(*sock)); - if (!sock) { - dcerpc_pipe_close(*p); - return NT_STATUS_NO_MEMORY; - } - - sock->fd = fd; - sock->server_name = full_path; - sock->event_ctx = event_context_init(sock); - sock->pending_send = NULL; - sock->recv.received = 0; - sock->recv.data = data_blob(NULL, 0); - sock->recv.pending_count = 0; - - fde.fd = fd; - fde.flags = 0; - fde.handler = sock_io_handler; - fde.private = *p; - - sock->fde = event_add_fd(sock->event_ctx, &fde); - - (*p)->transport.private = sock; - - /* ensure we don't get SIGPIPE */ - BlockSignals(True,SIGPIPE); + status = dcerpc_pipe_open_socket(p, full_path, 0, "unix", NCALRPC); + talloc_free(canon); - return NT_STATUS_OK; + return status; } diff --git a/source4/librpc/rpc/dcerpc_util.c b/source4/librpc/rpc/dcerpc_util.c index cbdb0f2069..8fd99eef04 100644 --- a/source4/librpc/rpc/dcerpc_util.c +++ b/source4/librpc/rpc/dcerpc_util.c @@ -865,7 +865,7 @@ static NTSTATUS dcerpc_pipe_connect_ncalrpc(struct dcerpc_pipe **p, status = dcerpc_pipe_open_pipe(p, binding->endpoint); if (!NT_STATUS_IS_OK(status)) { - DEBUG(0,("Failed to open ncalrpc pipe '%s'\n", binding->endpoint)); + DEBUG(0,("Failed to open ncalrpc pipe '%s' - %s\n", binding->endpoint, nt_errstr(status))); talloc_destroy(mem_ctx); return status; } @@ -918,9 +918,10 @@ static NTSTATUS dcerpc_pipe_connect_ncacn_unix_stream(struct dcerpc_pipe **p, status = dcerpc_pipe_open_unix_stream(p, binding->endpoint); if (!NT_STATUS_IS_OK(status)) { - DEBUG(0,("Failed to open unix socket %s\n", binding->endpoint)); + DEBUG(0,("Failed to open unix socket %s - %s\n", + binding->endpoint, nt_errstr(status))); return status; - } + } (*p)->flags = binding->flags; @@ -974,7 +975,7 @@ static NTSTATUS dcerpc_pipe_connect_ncacn_ip_tcp(struct dcerpc_pipe **p, port = atoi(binding->endpoint); - status = dcerpc_pipe_open_tcp(p, binding->host, port, AF_UNSPEC); + status = dcerpc_pipe_open_tcp(p, binding->host, port); if (!NT_STATUS_IS_OK(status)) { DEBUG(0,("Failed to connect to %s:%d\n", binding->host, port)); return status; diff --git a/source4/ntvfs/posix/pvfs_wait.c b/source4/ntvfs/posix/pvfs_wait.c index 2a4a1d286b..071ecbce15 100644 --- a/source4/ntvfs/posix/pvfs_wait.c +++ b/source4/ntvfs/posix/pvfs_wait.c @@ -29,7 +29,7 @@ struct pvfs_wait { void *private; struct timed_event *te; int msg_type; - void *msg_ctx; + struct messaging_context *msg_ctx; struct event_context *ev; struct smbsrv_request *req; BOOL timed_out; @@ -51,7 +51,7 @@ NTSTATUS pvfs_async_setup(struct ntvfs_module_context *ntvfs, /* receive a completion message for a wait */ -static void pvfs_wait_dispatch(void *msg_ctx, void *private, uint32_t msg_type, +static void pvfs_wait_dispatch(struct messaging_context *msg, void *private, uint32_t msg_type, servid_t src, DATA_BLOB *data) { struct pvfs_wait *pwait = private; diff --git a/source4/rpc_server/dcerpc_sock.c b/source4/rpc_server/dcerpc_sock.c index bffa5cffd8..79d1f5a3bb 100644 --- a/source4/rpc_server/dcerpc_sock.c +++ b/source4/rpc_server/dcerpc_sock.c @@ -180,10 +180,9 @@ static void add_socket_rpc_tcp(struct server_service *service, add_socket_rpc_tcp_iface(service, model_ops, dce_ctx, e, ifip); } } else { - struct in_addr *ifip; - ifip = interpret_addr2(dce_ctx, lp_socket_address()); - add_socket_rpc_tcp_iface(service, model_ops, dce_ctx, e, ifip); - talloc_free(ifip); + struct in_addr ifip; + ifip = interpret_addr2(lp_socket_address()); + add_socket_rpc_tcp_iface(service, model_ops, dce_ctx, e, &ifip); } return; diff --git a/source4/smb_server/smb_server.c b/source4/smb_server/smb_server.c index 920f56d334..b7d54c8dee 100644 --- a/source4/smb_server/smb_server.c +++ b/source4/smb_server/smb_server.c @@ -725,18 +725,10 @@ static void smbsrv_init(struct server_service *service, const struct model_ops * add_socket(service, model_ops, NULL, ifip); } } else { - struct in_addr *ifip; - TALLOC_CTX *mem_ctx = talloc_init("open_sockets_smbd"); - - if (!mem_ctx) { - smb_panic("No memory"); - } - + struct in_addr ifip; /* Just bind to lp_socket_address() (usually 0.0.0.0) */ - ifip = interpret_addr2(mem_ctx, lp_socket_address()); - add_socket(service, model_ops, NULL, ifip); - - talloc_free(mem_ctx); + ifip = interpret_addr2(lp_socket_address()); + add_socket(service, model_ops, NULL, &ifip); } } diff --git a/source4/torture/rpc/epmapper.c b/source4/torture/rpc/epmapper.c index dae5a396f2..d55355cb31 100644 --- a/source4/torture/rpc/epmapper.c +++ b/source4/torture/rpc/epmapper.c @@ -231,7 +231,9 @@ static BOOL test_Lookup(struct dcerpc_pipe *p, TALLOC_CTX *mem_ctx) for (i=0;itower); - test_Map(p, mem_ctx, r.out.entries[i].tower); + if (r.out.entries[i].tower->tower.num_floors == 5) { + test_Map(p, mem_ctx, r.out.entries[i].tower); + } } } while (NT_STATUS_IS_OK(status) && r.out.result == 0 && diff --git a/source4/utils/nmblookup.c b/source4/utils/nmblookup.c index 6505e6df3c..8c9eccf424 100644 --- a/source4/utils/nmblookup.c +++ b/source4/utils/nmblookup.c @@ -228,7 +228,7 @@ int main(int argc,char *argv[]) switch (opt) { case 'B': - bcast_addr = *interpret_addr2(optarg); + bcast_addr = interpret_addr2(optarg); got_bcast = True; use_bcast = True; break; @@ -236,7 +236,7 @@ int main(int argc,char *argv[]) give_flags = True; break; case 'U': - bcast_addr = *interpret_addr2(optarg); + bcast_addr = interpret_addr2(optarg); got_bcast = True; use_bcast = False; break; @@ -306,7 +306,7 @@ int main(int argc,char *argv[]) if(lookup_by_ip) { fstrcpy(lookup,"*"); - ip = *interpret_addr2(argv[i]); + ip = interpret_addr2(argv[i]); do_node_status(ServerFD, lookup, lookup_type, ip); continue; } -- cgit