Example #1
0
static NTSTATUS ip_connect_complete(struct socket_context *sock, uint32_t flags)
{
	int error=0, ret;
	socklen_t len = sizeof(error);

	/* check for any errors that may have occurred - this is needed
	   for non-blocking connect */
	ret = getsockopt(sock->fd, SOL_SOCKET, SO_ERROR, &error, &len);
	if (ret == -1) {
		return map_nt_error_from_unix_common(errno);
	}
	if (error != 0) {
		return map_nt_error_from_unix_common(error);
	}

	if (!(flags & SOCKET_FLAG_BLOCK)) {
		ret = set_blocking(sock->fd, false);
		if (ret == -1) {
			return map_nt_error_from_unix_common(errno);
		}
	}

	sock->state = SOCKET_STATE_CLIENT_CONNECTED;

	return NT_STATUS_OK;
}
static NTSTATUS fsctl_qar_seek_fill(TALLOC_CTX *mem_ctx,
				    struct files_struct *fsp,
				    off_t curr_off,
				    off_t max_off,
				    DATA_BLOB *qar_array_blob)
{
	NTSTATUS status = NT_STATUS_NOT_SUPPORTED;

#ifdef HAVE_LSEEK_HOLE_DATA
	while (curr_off <= max_off) {
		off_t data_off;
		off_t hole_off;
		struct file_alloced_range_buf qar_buf;

		/* seek next data */
		data_off = SMB_VFS_LSEEK(fsp, curr_off, SEEK_DATA);
		if ((data_off == -1) && (errno == ENXIO)) {
			/* no data from curr_off to EOF */
			break;
		} else if (data_off == -1) {
			status = map_nt_error_from_unix_common(errno);
			DEBUG(1, ("lseek data failed: %s\n", strerror(errno)));
			return status;
		}

		if (data_off > max_off) {
			/* found something, but passed range of interest */
			break;
		}

		hole_off = SMB_VFS_LSEEK(fsp, data_off, SEEK_HOLE);
		if (hole_off == -1) {
			status = map_nt_error_from_unix_common(errno);
			DEBUG(1, ("lseek hole failed: %s\n", strerror(errno)));
			return status;
		}

		if (hole_off <= data_off) {
			DEBUG(1, ("lseek inconsistent: hole %lu at or before "
				  "data %lu\n", (unsigned long)hole_off,
				  (unsigned long)data_off));
			return NT_STATUS_INTERNAL_ERROR;
		}

		qar_buf.file_off = data_off;
		/* + 1 to convert maximum offset to length */
		qar_buf.len = MIN(hole_off, max_off + 1) - data_off;

		status = fsctl_qar_buf_push(mem_ctx, &qar_buf, qar_array_blob);
		if (!NT_STATUS_IS_OK(status)) {
			return NT_STATUS_NO_MEMORY;
		}

		curr_off = hole_off;
	}
	status = NT_STATUS_OK;
#endif

	return status;
}
Example #3
0
static NTSTATUS ipv6_tcp_connect(struct socket_context *sock,
				 const struct socket_address *my_address,
				 const struct socket_address *srv_address,
				 uint32_t flags)
{
	int ret;

	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_common(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_common(errno);
			}
		}
	}

	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));
	}
	if (ret == -1) {
		return map_nt_error_from_unix_common(errno);
	}

	return ip_connect_complete(sock, flags);
}
Example #4
0
static NTSTATUS ipv6_listen(struct socket_context *sock,
			    const struct socket_address *my_address,
			    int queue_size, uint32_t flags)
{
	struct sockaddr_in6 my_addr;
	struct in6_addr ip_addr;
	int ret;

	socket_set_option(sock, "SO_REUSEADDR=1", NULL);

	if (my_address->sockaddr) {
		ret = bind(sock->fd, my_address->sockaddr, my_address->sockaddrlen);
	} else {
		int one = 1;
		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;
		fix_scope_id(&my_addr, my_address->addr);

		/* when binding on ipv6 we always want to only bind on v6 */
		ret = setsockopt(sock->fd, IPPROTO_IPV6, IPV6_V6ONLY,
				 (const void *)&one, sizeof(one));
		if (ret != -1) {
			ret = bind(sock->fd, (struct sockaddr *)&my_addr, sizeof(my_addr));
		}
	}

	if (ret == -1) {
		return map_nt_error_from_unix_common(errno);
	}

	if (sock->type == SOCKET_TYPE_STREAM) {
		ret = listen(sock->fd, queue_size);
		if (ret == -1) {
			return map_nt_error_from_unix_common(errno);
		}
	}

	if (!(flags & SOCKET_FLAG_BLOCK)) {
		ret = set_blocking(sock->fd, false);
		if (ret == -1) {
			return map_nt_error_from_unix_common(errno);
		}
	}

	sock->state= SOCKET_STATE_SERVER_LISTEN;

	return NT_STATUS_OK;
}
Example #5
0
static NTSTATUS unixdom_sendto(struct socket_context *sock, 
			       const DATA_BLOB *blob, size_t *sendlen, 
			       const struct socket_address *dest)
{
	struct sockaddr_un srv_addr;
	const struct sockaddr *sa;
	socklen_t sa_len;
	ssize_t len;

	*sendlen = 0;

	if (dest->sockaddr) {
		sa = dest->sockaddr;
		sa_len = dest->sockaddrlen;
	} else {
		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;
		snprintf(srv_addr.sun_path, sizeof(srv_addr.sun_path), "%s",
			 dest->addr);
		sa = (struct sockaddr *) &srv_addr;
		sa_len = sizeof(srv_addr);
	}

	len = sendto(sock->fd, blob->data, blob->length, 0, sa, sa_len);

	/* retry once */
	if (len == -1 && errno == EMSGSIZE) {
		/* round up in 1K increments */
		int bufsize = ((blob->length + 1023) & (~1023));
		if (setsockopt(sock->fd, SOL_SOCKET, SO_SNDBUF, &bufsize,
			       sizeof(bufsize)) == -1)
		{
			return map_nt_error_from_unix_common(EMSGSIZE);
		}
		len = sendto(sock->fd, blob->data, blob->length, 0, sa, sa_len);
	}

	if (len == -1) {
		return map_nt_error_from_unix_common(errno);
	}	

	*sendlen = len;

	return NT_STATUS_OK;
}
Example #6
0
static NTSTATUS ipv6_tcp_accept(struct socket_context *sock, struct socket_context **new_sock)
{
	struct sockaddr_in6 cli_addr;
	socklen_t cli_addr_len = sizeof(cli_addr);
	int new_fd;
	
	if (sock->type != SOCKET_TYPE_STREAM) {
		return NT_STATUS_INVALID_PARAMETER;
	}

	new_fd = accept(sock->fd, (struct sockaddr *)&cli_addr, &cli_addr_len);
	if (new_fd == -1) {
		return map_nt_error_from_unix_common(errno);
	}

	if (!(sock->flags & SOCKET_FLAG_BLOCK)) {
		int ret = set_blocking(new_fd, false);
		if (ret == -1) {
			close(new_fd);
			return map_nt_error_from_unix_common(errno);
		}
	}

	/* TODO: we could add a 'accept_check' hook here
	 *	 which get the black/white lists via socket_set_accept_filter()
	 *	 or something like that
	 *	 --metze
	 */

	(*new_sock) = talloc(NULL, struct socket_context);
	if (!(*new_sock)) {
		close(new_fd);
		return NT_STATUS_NO_MEMORY;
	}

	/* copy the socket_context */
	(*new_sock)->type		= sock->type;
	(*new_sock)->state		= SOCKET_STATE_SERVER_CONNECTED;
	(*new_sock)->flags		= sock->flags;

	(*new_sock)->fd			= new_fd;

	(*new_sock)->private_data	= NULL;
	(*new_sock)->ops		= sock->ops;
	(*new_sock)->backend_name	= sock->backend_name;

	return NT_STATUS_OK;
}
Example #7
0
/*
  note that for simplicity of the API, socket_listen() is also
  use for DGRAM sockets, but in reality only a bind() is done
*/
static NTSTATUS ipv4_listen(struct socket_context *sock,
			    const struct socket_address *my_address, 
			    int queue_size, uint32_t flags)
{
	struct sockaddr_in my_addr;
	struct in_addr ip_addr;
	int ret;

	socket_set_option(sock, "SO_REUSEADDR=1", NULL);

	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);
#endif
		my_addr.sin_addr.s_addr	= ip_addr.s_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_common(errno);
	}

	if (sock->type == SOCKET_TYPE_STREAM) {
		ret = listen(sock->fd, queue_size);
		if (ret == -1) {
			return map_nt_error_from_unix_common(errno);
		}
	}

	if (!(flags & SOCKET_FLAG_BLOCK)) {
		ret = set_blocking(sock->fd, false);
		if (ret == -1) {
			return map_nt_error_from_unix_common(errno);
		}
	}

	sock->state= SOCKET_STATE_SERVER_LISTEN;

	return NT_STATUS_OK;
}
Example #8
0
static void unbecomeDC_send_cldap(struct libnet_UnbecomeDC_state *s)
{
	struct composite_context *c = s->creq;
	struct tevent_req *req;
	struct tsocket_address *dest_address;
	int ret;

	s->cldap.io.in.dest_address	= NULL;
	s->cldap.io.in.dest_port	= 0;
	s->cldap.io.in.realm		= s->domain.dns_name;
	s->cldap.io.in.host		= s->dest_dsa.netbios_name;
	s->cldap.io.in.user		= NULL;
	s->cldap.io.in.domain_guid	= NULL;
	s->cldap.io.in.domain_sid	= NULL;
	s->cldap.io.in.acct_control	= -1;
	s->cldap.io.in.version		= NETLOGON_NT_VERSION_5 | NETLOGON_NT_VERSION_5EX;
	s->cldap.io.in.map_response	= true;

	ret = tsocket_address_inet_from_strings(s, "ip",
						s->source_dsa.address,
						lpcfg_cldap_port(s->libnet->lp_ctx),
						&dest_address);
	if (ret != 0) {
		c->status = map_nt_error_from_unix_common(errno);
		if (!composite_is_ok(c)) return;
	}

	c->status = cldap_socket_init(s, NULL, dest_address, &s->cldap.sock);
	if (!composite_is_ok(c)) return;

	req = cldap_netlogon_send(s, s->libnet->event_ctx,
				  s->cldap.sock, &s->cldap.io);
	if (composite_nomem(req, c)) return;
	tevent_req_set_callback(req, unbecomeDC_recv_cldap, s);
}
Example #9
0
/*
  map a unix errno to a NTSTATUS
*/
NTSTATUS pvfs_map_errno(struct pvfs_state *pvfs, int unix_errno)
{
	NTSTATUS status;
	status = map_nt_error_from_unix_common(unix_errno);
	DEBUG(10,(__location__ " mapped unix errno %d -> %s\n", unix_errno, nt_errstr(status)));
	return status;
}
Example #10
0
static NTSTATUS unixdom_init(struct socket_context *sock)
{
	int type;

	switch (sock->type) {
	case SOCKET_TYPE_STREAM:
		type = SOCK_STREAM;
		break;
	case SOCKET_TYPE_DGRAM:
		type = SOCK_DGRAM;
		break;
	default:
		return NT_STATUS_INVALID_PARAMETER;
	}

	sock->fd = socket(PF_UNIX, type, 0);
	if (sock->fd == -1) {
		return map_nt_error_from_unix_common(errno);
	}
	sock->private_data = NULL;

	sock->backend_name = "unix";

	smb_set_close_on_exec(sock->fd);

	return NT_STATUS_OK;
}
Example #11
0
static NTSTATUS ipv6_sendto(struct socket_context *sock, 
			    const DATA_BLOB *blob, size_t *sendlen, 
			    const struct socket_address *dest_addr)
{
	ssize_t len;

	if (dest_addr->sockaddr) {
		len = sendto(sock->fd, blob->data, blob->length, 0, 
			     dest_addr->sockaddr, dest_addr->sockaddrlen);
	} else {
		struct sockaddr_in6 srv_addr;
		struct in6_addr addr;
		
		ZERO_STRUCT(srv_addr);
		addr                     = interpret_addr6(dest_addr->addr);
		if (addr.s6_addr == 0) {
			return NT_STATUS_HOST_UNREACHABLE;
		}
		srv_addr.sin6_addr = addr;
		srv_addr.sin6_port        = htons(dest_addr->port);
		srv_addr.sin6_family      = PF_INET6;
		
		*sendlen = 0;
		
		len = sendto(sock->fd, blob->data, blob->length, 0, 
			     (struct sockaddr *)&srv_addr, sizeof(srv_addr));
	}
	if (len == -1) {
		return map_nt_error_from_unix_common(errno);
	}	

	*sendlen = len;

	return NT_STATUS_OK;
}
Example #12
0
static NTSTATUS ipv6_init(struct socket_context *sock)
{
	int type;

	switch (sock->type) {
	case SOCKET_TYPE_STREAM:
		type = SOCK_STREAM;
		break;
	case SOCKET_TYPE_DGRAM:
		type = SOCK_DGRAM;
		break;
	default:
		return NT_STATUS_INVALID_PARAMETER;
	}

	sock->fd = socket(PF_INET6, type, 0);
	if (sock->fd == -1) {
		return map_nt_error_from_unix_common(errno);
	}

	smb_set_close_on_exec(sock->fd);

	sock->backend_name = "ipv6";
	sock->family = AF_INET6;

	return NT_STATUS_OK;
}
Example #13
0
NTSTATUS smbXsrv_tcon_global_init(void)
{
	char *global_path = NULL;
	struct db_context *db_ctx = NULL;

	if (smbXsrv_tcon_global_db_ctx != NULL) {
		return NT_STATUS_OK;
	}

	global_path = lock_path("smbXsrv_tcon_global.tdb");
	if (global_path == NULL) {
		return NT_STATUS_NO_MEMORY;
	}

	db_ctx = db_open(NULL, global_path,
			 0, /* hash_size */
			 TDB_DEFAULT |
			 TDB_CLEAR_IF_FIRST |
			 TDB_INCOMPATIBLE_HASH,
			 O_RDWR | O_CREAT, 0600,
			 DBWRAP_LOCK_ORDER_1,
			 DBWRAP_FLAG_NONE);
	TALLOC_FREE(global_path);
	if (db_ctx == NULL) {
		NTSTATUS status;

		status = map_nt_error_from_unix_common(errno);

		return status;
	}

	smbXsrv_tcon_global_db_ctx = db_ctx;

	return NT_STATUS_OK;
}
Example #14
0
NTSTATUS smbXsrv_session_global_init(void)
{
	const char *global_path = NULL;
	struct db_context *db_ctx = NULL;

	if (smbXsrv_session_global_db_ctx != NULL) {
		return NT_STATUS_OK;
	}

	/*
	 * This contains secret information like session keys!
	 */
	global_path = lock_path("smbXsrv_session_global.tdb");

	db_ctx = db_open(NULL, global_path,
			 0, /* hash_size */
			 TDB_DEFAULT |
			 TDB_CLEAR_IF_FIRST |
			 TDB_INCOMPATIBLE_HASH,
			 O_RDWR | O_CREAT, 0600,
			 DBWRAP_LOCK_ORDER_1);
	if (db_ctx == NULL) {
		NTSTATUS status;

		status = map_nt_error_from_unix_common(errno);

		return status;
	}

	smbXsrv_session_global_db_ctx = db_ctx;

	return NT_STATUS_OK;
}
Example #15
0
static NTSTATUS ip_pending(struct socket_context *sock, size_t *npending)
{
	int value = 0;
	if (ioctl(sock->fd, FIONREAD, &value) == 0) {
		*npending = value;
		return NT_STATUS_OK;
	}
	return map_nt_error_from_unix_common(errno);
}
Example #16
0
static NTSTATUS ipv6_recvfrom(struct socket_context *sock, void *buf, 
			      size_t wantlen, size_t *nread, 
			      TALLOC_CTX *addr_ctx, struct socket_address **_src)
{
	ssize_t gotlen;
	struct sockaddr_in6 *from_addr;
	socklen_t from_len = sizeof(*from_addr);
	struct socket_address *src;
	char addrstring[INET6_ADDRSTRLEN];
	
	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_in6);
	if (!from_addr) {
		talloc_free(src);
		return NT_STATUS_NO_MEMORY;
	}

	src->sockaddr = (struct sockaddr *)from_addr;

	*nread = 0;

	gotlen = recvfrom(sock->fd, buf, wantlen, 0, 
			  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_common(errno);
	}

	src->sockaddrlen = from_len;

	if (inet_ntop(AF_INET6, &from_addr->sin6_addr, addrstring, sizeof(addrstring)) == NULL) {
		DEBUG(0, ("Unable to convert address to string: %s\n", strerror(errno)));
		talloc_free(src);
	    	return NT_STATUS_INTERNAL_ERROR;
	}

	src->addr = talloc_strdup(src, addrstring);
	if (src->addr == NULL) {
		talloc_free(src);
		return NT_STATUS_NO_MEMORY;
	}
	src->port = ntohs(from_addr->sin6_port);

	*nread	= gotlen;
	*_src	= src;
	return NT_STATUS_OK;
}
NTSTATUS srvstr_push_fn(const char *base_ptr, uint16 smb_flags2, void *dest,
		      const char *src, int dest_len, int flags, size_t *ret_len)
{
	size_t len;
	int saved_errno;
	NTSTATUS status;

	if (dest_len < 0) {
		return NT_STATUS_INVALID_PARAMETER;
	}

	saved_errno = errno;
	errno = 0;

	/* 'normal' push into size-specified buffer */
	len = push_string_base(base_ptr, smb_flags2, dest, src,
				dest_len, flags);

	if (errno != 0) {
		/*
		 * Special case E2BIG, EILSEQ, EINVAL
		 * as they mean conversion errors here,
		 * but we don't generically map them as
		 * they can mean different things in
		 * generic filesystem calls (such as
		 * read xattrs).
		 */
		if (errno == E2BIG || errno == EILSEQ || errno == EINVAL) {
			status = NT_STATUS_ILLEGAL_CHARACTER;
		} else {
			status = map_nt_error_from_unix_common(errno);
			/*
			 * Paranoia - Filter out STATUS_MORE_ENTRIES.
			 * I don't think we can get this but it has a
			 * specific meaning to the client.
			 */
			if (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
				status = NT_STATUS_UNSUCCESSFUL;
			}
		}
		DEBUG(10,("character conversion failure "
			"on string (%s) (%s)\n",
			src, strerror(errno)));
	} else {
		/* Success - restore untouched errno. */
		errno = saved_errno;
		*ret_len = len;
		status = NT_STATUS_OK;
	}
	return status;
}
Example #18
0
/**
 create a temporary directory under the output dir
*/
_PUBLIC_ NTSTATUS torture_temp_dir(struct torture_context *tctx,
                                   const char *prefix, char **tempdir)
{
    SMB_ASSERT(tctx->outputdir != NULL);

    *tempdir = talloc_asprintf(tctx, "%s/%s.XXXXXX", tctx->outputdir,
                               prefix);
    NT_STATUS_HAVE_NO_MEMORY(*tempdir);

    if (mkdtemp(*tempdir) == NULL) {
        return map_nt_error_from_unix_common(errno);
    }

    return NT_STATUS_OK;
}
Example #19
0
NTSTATUS kerberos_pac_blob_to_user_info_dc(TALLOC_CTX *mem_ctx,
					   DATA_BLOB pac_blob,
					   krb5_context context,
					   struct auth_user_info_dc **user_info_dc,
					   struct PAC_SIGNATURE_DATA *pac_srv_sig,
					   struct PAC_SIGNATURE_DATA *pac_kdc_sig)
{
	krb5_error_code ret;
	krb5_pac pac;
	ret = krb5_pac_parse(context,
			     pac_blob.data, pac_blob.length,
			     &pac);
	if (ret) {
		return map_nt_error_from_unix_common(ret);
	}


	ret = kerberos_pac_to_user_info_dc(mem_ctx, pac, context, user_info_dc, pac_srv_sig, pac_kdc_sig);
	krb5_pac_free(context, pac);
	if (ret) {
		return map_nt_error_from_unix_common(ret);
	}
	return NT_STATUS_OK;
}
Example #20
0
/*
  call dup() on a socket, and close the old fd. This is used to change
  the fd to the lowest available number, to make select() more
  efficient (select speed depends on the maxiumum fd number passed to
  it)
*/
_PUBLIC_ NTSTATUS socket_dup(struct socket_context *sock)
{
	int fd;
	if (sock->fd == -1) {
		return NT_STATUS_INVALID_HANDLE;
	}
	fd = dup(sock->fd);
	if (fd == -1) {
		return map_nt_error_from_unix_common(errno);
	}
	close(sock->fd);
	sock->fd = fd;
	return NT_STATUS_OK;
	
}
Example #21
0
static NTSTATUS ip_send(struct socket_context *sock, 
			      const DATA_BLOB *blob, size_t *sendlen)
{
	ssize_t len;

	*sendlen = 0;

	len = send(sock->fd, blob->data, blob->length, 0);
	if (len == -1) {
		return map_nt_error_from_unix_common(errno);
	}	

	*sendlen = len;

	return NT_STATUS_OK;
}
Example #22
0
static NTSTATUS unixdom_accept(struct socket_context *sock, 
			       struct socket_context **new_sock)
{
	struct sockaddr_un cli_addr;
	socklen_t cli_addr_len = sizeof(cli_addr);
	int new_fd;

	if (sock->type != SOCKET_TYPE_STREAM) {
		return NT_STATUS_INVALID_PARAMETER;
	}

	new_fd = accept(sock->fd, (struct sockaddr *)&cli_addr, &cli_addr_len);
	if (new_fd == -1) {
		return unixdom_error(errno);
	}

	if (!(sock->flags & SOCKET_FLAG_BLOCK)) {
		int ret = set_blocking(new_fd, false);
		if (ret == -1) {
			close(new_fd);
			return map_nt_error_from_unix_common(errno);
		}
	}

	smb_set_close_on_exec(new_fd);

	(*new_sock) = talloc(NULL, struct socket_context);
	if (!(*new_sock)) {
		close(new_fd);
		return NT_STATUS_NO_MEMORY;
	}

	/* copy the socket_context */
	(*new_sock)->type		= sock->type;
	(*new_sock)->state		= SOCKET_STATE_SERVER_CONNECTED;
	(*new_sock)->flags		= sock->flags;

	(*new_sock)->fd			= new_fd;

	(*new_sock)->private_data	= NULL;
	(*new_sock)->ops		= sock->ops;
	(*new_sock)->backend_name	= sock->backend_name;

	return NT_STATUS_OK;
}
Example #23
0
NTSTATUS smbXsrv_session_global_init(struct messaging_context *msg_ctx)
{
	char *global_path = NULL;
	struct db_context *backend = NULL;
	struct db_context *db_ctx = NULL;

	if (smbXsrv_session_global_db_ctx != NULL) {
		return NT_STATUS_OK;
	}

	/*
	 * This contains secret information like session keys!
	 */
	global_path = lock_path("smbXsrv_session_global.tdb");
	if (global_path == NULL) {
		return NT_STATUS_NO_MEMORY;
	}

	backend = db_open(NULL, global_path,
			  0, /* hash_size */
			  TDB_DEFAULT |
			  TDB_CLEAR_IF_FIRST |
			  TDB_INCOMPATIBLE_HASH,
			  O_RDWR | O_CREAT, 0600,
			  DBWRAP_LOCK_ORDER_1,
			  DBWRAP_FLAG_NONE);
	TALLOC_FREE(global_path);
	if (backend == NULL) {
		NTSTATUS status;

		status = map_nt_error_from_unix_common(errno);

		return status;
	}

	db_ctx = db_open_watched(NULL, backend, server_messaging_context());
	if (db_ctx == NULL) {
		TALLOC_FREE(backend);
		return NT_STATUS_NO_MEMORY;
	}

	smbXsrv_session_global_db_ctx = db_ctx;

	return NT_STATUS_OK;
}
Example #24
0
_PUBLIC_ NTSTATUS torture_deltree_outputdir(struct torture_context *tctx)
{
    if (tctx->outputdir == NULL) {
        return NT_STATUS_OK;
    }
    if ((strcmp(tctx->outputdir, "/") == 0)
            || (strcmp(tctx->outputdir, "") == 0)) {
        return NT_STATUS_INVALID_PARAMETER;
    }

    if (local_deltree(tctx->outputdir) == -1) {
        if (errno != 0) {
            return map_nt_error_from_unix_common(errno);
        }
        return NT_STATUS_UNSUCCESSFUL;
    }
    return NT_STATUS_OK;
}
Example #25
0
static NTSTATUS ip_recv(struct socket_context *sock, void *buf, 
			      size_t wantlen, size_t *nread)
{
	ssize_t gotlen;

	*nread = 0;

	gotlen = recv(sock->fd, buf, wantlen, 0);
	if (gotlen == 0) {
		return NT_STATUS_END_OF_FILE;
	} else if (gotlen == -1) {
		return map_nt_error_from_unix_common(errno);
	}

	*nread = gotlen;

	return NT_STATUS_OK;
}
Example #26
0
/*
  start listening on the given address
*/
static NTSTATUS cldapd_add_socket(struct cldapd_server *cldapd, struct loadparm_context *lp_ctx,
				  const char *address)
{
	struct cldap_socket *cldapsock;
	struct tsocket_address *socket_address;
	NTSTATUS status;
	int ret;

	ret = tsocket_address_inet_from_strings(cldapd,
						"ip",
						address,
						lpcfg_cldap_port(lp_ctx),
						&socket_address);
	if (ret != 0) {
		status = map_nt_error_from_unix_common(errno);
		DEBUG(0,("invalid address %s:%d - %s:%s\n",
			 address, lpcfg_cldap_port(lp_ctx),
			 gai_strerror(ret), nt_errstr(status)));
		return status;
	}

	/* listen for unicasts on the CLDAP port (389) */
	status = cldap_socket_init(cldapd,
				   cldapd->task->event_ctx,
				   socket_address,
				   NULL,
				   &cldapsock);
	if (!NT_STATUS_IS_OK(status)) {
		DEBUG(0,("Failed to bind to %s - %s\n", 
			 tsocket_address_string(socket_address, socket_address),
			 nt_errstr(status)));
		talloc_free(socket_address);
		return status;
	}
	talloc_free(socket_address);

	cldap_set_incoming_handler(cldapsock, cldapd_request_handler, cldapd);

	return NT_STATUS_OK;
}
Example #27
0
static NTSTATUS ipv4_sendto(struct socket_context *sock, 
			    const DATA_BLOB *blob, size_t *sendlen, 
			    const struct socket_address *dest_addr)
{
	ssize_t len;

	if (dest_addr->sockaddr) {
		len = sendto(sock->fd, blob->data, blob->length, 0, 
			     dest_addr->sockaddr, dest_addr->sockaddrlen);
	} else {
		struct sockaddr_in srv_addr;
		struct in_addr addr;

		SMB_ASSERT(dest_addr->port != 0);
		
		ZERO_STRUCT(srv_addr);
#ifdef HAVE_SOCK_SIN_LEN
		srv_addr.sin_len         = sizeof(srv_addr);
#endif
		addr                     = interpret_addr2(dest_addr->addr);
		if (addr.s_addr == 0) {
			return NT_STATUS_HOST_UNREACHABLE;
		}
		srv_addr.sin_addr.s_addr = addr.s_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, 0, 
			     (struct sockaddr *)&srv_addr, sizeof(srv_addr));
	}
	if (len == -1) {
		return map_nt_error_from_unix_common(errno);
	}	

	*sendlen = len;

	return NT_STATUS_OK;
}
Example #28
0
NTSTATUS smb1cli_trans(TALLOC_CTX *mem_ctx, struct smbXcli_conn *conn,
		uint8_t trans_cmd,
		uint8_t additional_flags, uint8_t clear_flags,
		uint16_t additional_flags2, uint16_t clear_flags2,
		uint32_t timeout_msec,
		uint32_t pid, uint16_t tid, uint16_t uid,
		const char *pipe_name, uint16_t fid, uint16_t function,
		int flags,
		uint16_t *setup, uint8_t num_setup, uint8_t max_setup,
		uint8_t *param, uint32_t num_param, uint32_t max_param,
		uint8_t *data, uint32_t num_data, uint32_t max_data,
		uint16_t *recv_flags2,
		uint16_t **rsetup, uint8_t min_rsetup, uint8_t *num_rsetup,
		uint8_t **rparam, uint32_t min_rparam, uint32_t *num_rparam,
		uint8_t **rdata, uint32_t min_rdata, uint32_t *num_rdata)
{
	TALLOC_CTX *frame = talloc_stackframe();
	struct tevent_context *ev;
	struct tevent_req *req;
	NTSTATUS status = NT_STATUS_OK;

	if (smbXcli_conn_has_async_calls(conn)) {
		/*
		 * Can't use sync call while an async call is in flight
		 */
		status = NT_STATUS_INVALID_PARAMETER_MIX;
		goto fail;
	}

	ev = tevent_context_init(frame);
	if (ev == NULL) {
		status = NT_STATUS_NO_MEMORY;
		goto fail;
	}

	req = smb1cli_trans_send(frame, ev, conn, trans_cmd,
				 additional_flags, clear_flags,
				 additional_flags2, clear_flags2,
				 timeout_msec,
				 pid, tid, uid,
				 pipe_name, fid, function, flags,
				 setup, num_setup, max_setup,
				 param, num_param, max_param,
				 data, num_data, max_data);
	if (req == NULL) {
		status = NT_STATUS_NO_MEMORY;
		goto fail;
	}

	if (!tevent_req_poll(req, ev)) {
		status = map_nt_error_from_unix_common(errno);
		goto fail;
	}

	status = smb1cli_trans_recv(req, mem_ctx, recv_flags2,
				    rsetup, min_rsetup, num_rsetup,
				    rparam, min_rparam, num_rparam,
				    rdata, min_rdata, num_rdata);
 fail:
	TALLOC_FREE(frame);
	return status;
}
Example #29
0
static NTSTATUS ipv4_connect(struct socket_context *sock,
			     const struct socket_address *my_address, 
			     const struct socket_address *srv_address,
			     uint32_t flags)
{
	struct sockaddr_in srv_addr;
	struct in_addr my_ip;
	struct in_addr srv_ip;
	int ret;

	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_common(errno);
		}
	} else if (my_address) {
		my_ip = interpret_addr2(my_address->addr);
		
		if (my_ip.s_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.s_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_common(errno);
			}
		}
	}

	if (srv_address->sockaddr) {
		ret = connect(sock->fd, srv_address->sockaddr, srv_address->sockaddrlen);
		if (ret == -1) {
			return map_nt_error_from_unix_common(errno);
		}
	} else {
		srv_ip = interpret_addr2(srv_address->addr);
		if (!srv_ip.s_addr) {
			return NT_STATUS_BAD_NETWORK_NAME;
		}

		SMB_ASSERT(srv_address->port != 0);
		
		ZERO_STRUCT(srv_addr);
#ifdef HAVE_SOCK_SIN_LEN
		srv_addr.sin_len	= sizeof(srv_addr);
#endif
		srv_addr.sin_addr.s_addr= srv_ip.s_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_common(errno);
		}
	}

	return ip_connect_complete(sock, flags);
}
Example #30
0
NTSTATUS tstream_setup_named_pipe(TALLOC_CTX *mem_ctx,
				  struct tevent_context *event_context,
				  struct loadparm_context *lp_ctx,
				  const struct model_ops *model_ops,
				  const struct stream_server_ops *stream_ops,
				  const char *pipe_name,
				  void *private_data,
				  void *process_context)
{
	char *dirname;
	struct named_pipe_socket *pipe_sock;
	NTSTATUS status = NT_STATUS_NO_MEMORY;;

	pipe_sock = talloc(mem_ctx, struct named_pipe_socket);
	if (pipe_sock == NULL) {
		goto fail;
	}

	/* remember the details about the pipe */
	pipe_sock->pipe_name	= strlower_talloc(pipe_sock, pipe_name);
	if (pipe_sock->pipe_name == NULL) {
		goto fail;
	}

	if (!directory_create_or_exist(lpcfg_ncalrpc_dir(lp_ctx), 0755)) {
		status = map_nt_error_from_unix_common(errno);
		DBG_ERR("Failed to create ncalrpc pipe directory '%s' - %s\n",
			lpcfg_ncalrpc_dir(lp_ctx), nt_errstr(status));
		goto fail;
	}

	dirname = talloc_asprintf(pipe_sock, "%s/np", lpcfg_ncalrpc_dir(lp_ctx));
	if (dirname == NULL) {
		goto fail;
	}

	if (!directory_create_or_exist_strict(dirname, geteuid(), 0700)) {
		status = map_nt_error_from_unix_common(errno);
		DBG_ERR("Failed to create stream pipe directory '%s' - %s\n",
			dirname, nt_errstr(status));
		goto fail;
	}

	if (strncmp(pipe_name, "\\pipe\\", 6) == 0) {
		pipe_name += 6;
	}

	pipe_sock->pipe_path = talloc_asprintf(pipe_sock, "%s/%s", dirname,
					       pipe_name);
	if (pipe_sock->pipe_path == NULL) {
		goto fail;
	}

	talloc_free(dirname);

	pipe_sock->ops = stream_ops;
	pipe_sock->private_data	= private_data;

	status = stream_setup_socket(pipe_sock,
				     event_context,
				     lp_ctx,
				     model_ops,
				     &named_pipe_stream_ops,
				     "unix",
				     pipe_sock->pipe_path,
				     NULL,
				     NULL,
				     pipe_sock,
				     process_context);
	if (!NT_STATUS_IS_OK(status)) {
		goto fail;
	}
	return NT_STATUS_OK;

 fail:
	talloc_free(pipe_sock);
	return status;
}