#include "../lib/util/tevent_ntstatus.h"
#include "../lib/tsocket/tsocket.h"
-const char *client_name(int fd)
-{
- return get_peer_name(fd,false);
-}
-
const char *client_addr(int fd, char *addr, size_t addrlen)
{
return get_peer_addr(fd,addr,addrlen);
return read_fd_with_timeout(fd, buffer, N, N, 0, NULL);
}
+ssize_t iov_buflen(const struct iovec *iov, int iovcnt)
+{
+ size_t buflen = 0;
+ int i;
+
+ for (i=0; i<iovcnt; i++) {
+ size_t thislen = iov[i].iov_len;
+ size_t tmp = buflen + thislen;
+
+ if ((tmp < buflen) || (tmp < thislen)) {
+ /* overflow */
+ return -1;
+ }
+ buflen = tmp;
+ }
+ return buflen;
+}
+
/****************************************************************************
Write all data from an iov array
NB. This can be called with a non-socket fd, don't add dependencies
ssize_t write_data_iov(int fd, const struct iovec *orig_iov, int iovcnt)
{
- int i;
- size_t to_send;
+ ssize_t to_send;
ssize_t thistime;
size_t sent;
struct iovec *iov_copy, *iov;
- to_send = 0;
- for (i=0; i<iovcnt; i++) {
- to_send += orig_iov[i].iov_len;
+ to_send = iov_buflen(orig_iov, iovcnt);
+ if (to_send == -1) {
+ errno = EINVAL;
+ return -1;
}
thistime = sys_writev(fd, orig_iov, iovcnt);
struct open_socket_out_state {
int fd;
- struct event_context *ev;
+ struct tevent_context *ev;
struct sockaddr_storage ss;
socklen_t salen;
uint16_t port;
**************************************************************************/
struct tevent_req *open_socket_out_send(TALLOC_CTX *mem_ctx,
- struct event_context *ev,
+ struct tevent_context *ev,
const struct sockaddr_storage *pss,
uint16_t port,
int timeout)
subreq = async_connect_send(state, state->ev, state->fd,
(struct sockaddr *)&state->ss,
- state->salen);
+ state->salen, NULL, NULL, NULL);
if ((subreq == NULL)
|| !tevent_req_set_endtime(
subreq, state->ev,
subreq = async_connect_send(state, state->ev, state->fd,
(struct sockaddr *)&state->ss,
- state->salen);
+ state->salen, NULL, NULL, NULL);
if (tevent_req_nomem(subreq, req)) {
return;
}
int timeout, int *pfd)
{
TALLOC_CTX *frame = talloc_stackframe();
- struct event_context *ev;
+ struct tevent_context *ev;
struct tevent_req *req;
NTSTATUS status = NT_STATUS_NO_MEMORY;
- ev = event_context_init(frame);
+ ev = samba_tevent_context_init(frame);
if (ev == NULL) {
goto fail;
}
}
struct open_socket_out_defer_state {
- struct event_context *ev;
+ struct tevent_context *ev;
struct sockaddr_storage ss;
uint16_t port;
int timeout;
static void open_socket_out_defer_connected(struct tevent_req *subreq);
struct tevent_req *open_socket_out_defer_send(TALLOC_CTX *mem_ctx,
- struct event_context *ev,
+ struct tevent_context *ev,
struct timeval wait_time,
const struct sockaddr_storage *pss,
uint16_t port,
{
struct sockaddr_storage ss;
int res;
+ socklen_t salen;
if (!interpret_string_addr(&ss, host, 0)) {
DEBUG(10,("open_udp_socket: can't resolve name %s\n",
setup_linklocal_scope_id(
(struct sockaddr *)&ss);
}
- }
+ salen = sizeof(struct sockaddr_in6);
+ } else
#endif
- if (ss.ss_family == AF_INET) {
- struct sockaddr_in *psa;
- psa = (struct sockaddr_in *)&ss;
- psa->sin_port = htons(port);
- }
+ if (ss.ss_family == AF_INET) {
+ struct sockaddr_in *psa;
+ psa = (struct sockaddr_in *)&ss;
+ psa->sin_port = htons(port);
+ salen = sizeof(struct sockaddr_in);
+ } else {
+ DEBUG(1, ("unknown socket family %d", ss.ss_family));
+ close(res);
+ return -1;
+ }
- if (sys_connect(res,(struct sockaddr *)&ss)) {
+ if (connect(res, (struct sockaddr *)&ss, salen)) {
close(res);
return -1;
}
data_blob_free(&tmp);
}
-/*******************************************************************
- Return the DNS name of the remote end of a socket.
-******************************************************************/
-
-const char *get_peer_name(int fd, bool force_lookup)
-{
- struct name_addr_pair nc;
- char addr_buf[INET6_ADDRSTRLEN];
- struct sockaddr_storage ss;
- socklen_t length = sizeof(ss);
- const char *p;
- int ret;
- char name_buf[MAX_DNS_NAME_LENGTH];
- char tmp_name[MAX_DNS_NAME_LENGTH];
-
- /* reverse lookups can be *very* expensive, and in many
- situations won't work because many networks don't link dhcp
- with dns. To avoid the delay we avoid the lookup if
- possible */
- if (!lp_hostname_lookups() && (force_lookup == false)) {
- length = sizeof(nc.ss);
- nc.name = get_peer_addr_internal(fd, addr_buf, sizeof(addr_buf),
- (struct sockaddr *)&nc.ss, &length);
- store_nc(&nc);
- lookup_nc(&nc);
- return nc.name ? nc.name : "UNKNOWN";
- }
-
- lookup_nc(&nc);
-
- memset(&ss, '\0', sizeof(ss));
- p = get_peer_addr_internal(fd, addr_buf, sizeof(addr_buf), (struct sockaddr *)&ss, &length);
-
- /* it might be the same as the last one - save some DNS work */
- if (sockaddr_equal((struct sockaddr *)&ss, (struct sockaddr *)&nc.ss)) {
- return nc.name ? nc.name : "UNKNOWN";
- }
-
- /* Not the same. We need to lookup. */
- if (fd == -1) {
- return "UNKNOWN";
- }
-
- /* Look up the remote host name. */
- ret = sys_getnameinfo((struct sockaddr *)&ss,
- length,
- name_buf,
- sizeof(name_buf),
- NULL,
- 0,
- 0);
-
- if (ret) {
- DEBUG(1,("get_peer_name: getnameinfo failed "
- "for %s with error %s\n",
- p,
- gai_strerror(ret)));
- strlcpy(name_buf, p, sizeof(name_buf));
- } else {
- if (!matchname(name_buf, (struct sockaddr *)&ss, length)) {
- DEBUG(0,("Matchname failed on %s %s\n",name_buf,p));
- strlcpy(name_buf,"UNKNOWN",sizeof(name_buf));
- }
- }
-
- strlcpy(tmp_name, name_buf, sizeof(tmp_name));
- alpha_strcpy(name_buf, tmp_name, "_-.", sizeof(name_buf));
- if (strstr(name_buf,"..")) {
- strlcpy(name_buf, "UNKNOWN", sizeof(name_buf));
- }
-
- nc.name = name_buf;
- nc.ss = ss;
-
- store_nc(&nc);
- lookup_nc(&nc);
- return nc.name ? nc.name : "UNKNOWN";
-}
-
/*******************************************************************
Return the IP addr of the remote end of a socket as a string.
******************************************************************/
{
#ifdef HAVE_UNIXSOCKET
struct sockaddr_un sunaddr;
- struct stat st;
- int sock;
+ bool ok;
+ int sock = -1;
mode_t old_umask;
char *path = NULL;
old_umask = umask(0);
- /* Create the socket directory or reuse the existing one */
-
- if (lstat(socket_dir, &st) == -1) {
- if (errno == ENOENT) {
- /* Create directory */
- if (mkdir(socket_dir, dir_perms) == -1) {
- DEBUG(0, ("error creating socket directory "
- "%s: %s\n", socket_dir,
- strerror(errno)));
- goto out_umask;
- }
- } else {
- DEBUG(0, ("lstat failed on socket directory %s: %s\n",
- socket_dir, strerror(errno)));
- goto out_umask;
- }
- } else {
- /* Check ownership and permission on existing directory */
- if (!S_ISDIR(st.st_mode)) {
- DEBUG(0, ("socket directory '%s' isn't a directory\n",
- socket_dir));
- goto out_umask;
- }
- if (st.st_uid != sec_initial_uid()) {
- DEBUG(0, ("invalid ownership on directory "
- "'%s'\n", socket_dir));
- umask(old_umask);
- goto out_umask;
- }
- if ((st.st_mode & 0777) != dir_perms) {
- DEBUG(0, ("invalid permissions on directory "
- "'%s': has 0%o should be 0%o\n", socket_dir,
- (st.st_mode & 0777), dir_perms));
- umask(old_umask);
- goto out_umask;
- }
+ ok = directory_create_or_exist_strict(socket_dir,
+ sec_initial_uid(),
+ dir_perms);
+ if (!ok) {
+ goto out_close;
}
/* Create the socket file */
-
sock = socket(AF_UNIX, SOCK_STREAM, 0);
if (sock == -1) {
if (sock != -1)
close(sock);
-out_umask:
umask(old_umask);
return -1;
int poll_one_fd(int fd, int events, int timeout, int *revents)
{
- struct pollfd *fds;
+ struct pollfd pfd;
int ret;
- int saved_errno;
- fds = talloc_zero_array(talloc_tos(), struct pollfd, 1);
- if (fds == NULL) {
- errno = ENOMEM;
- return -1;
- }
- fds[0].fd = fd;
- fds[0].events = events;
+ pfd.fd = fd;
+ pfd.events = events;
- ret = poll(fds, 1, timeout);
+ ret = poll(&pfd, 1, timeout);
/*
* Assign whatever poll did, even in the ret<=0 case.
*/
- *revents = fds[0].revents;
- saved_errno = errno;
- TALLOC_FREE(fds);
- errno = saved_errno;
+ *revents = pfd.revents;
return ret;
}