Exemplo n.º 1
0
static void wbsrv_accept(struct stream_connection *conn)
{
	struct wbsrv_listen_socket *listen_socket = talloc_get_type(conn->private_data,
								    struct wbsrv_listen_socket);
	struct wbsrv_connection *wbconn;

	wbconn = talloc_zero(conn, struct wbsrv_connection);
	if (!wbconn) {
		stream_terminate_connection(conn, "wbsrv_accept: out of memory");
		return;
	}
	wbconn->conn	      = conn;
	wbconn->listen_socket = listen_socket;
	wbconn->lp_ctx        = listen_socket->service->task->lp_ctx;
	conn->private_data    = wbconn;

	wbconn->packet = packet_init(wbconn);
	if (wbconn->packet == NULL) {
		wbsrv_terminate_connection(wbconn, "wbsrv_accept: out of memory");
		return;
	}
	packet_set_private(wbconn->packet, wbconn);
	packet_set_socket(wbconn->packet, conn->socket);
	packet_set_callback(wbconn->packet, wbsrv_samba3_process);
	packet_set_full_request(wbconn->packet, wbsrv_samba3_packet_full_request);
	packet_set_error_handler(wbconn->packet, wbsrv_recv_error);
	packet_set_event_context(wbconn->packet, conn->event.ctx);
	packet_set_fde(wbconn->packet, conn->event.fde);
	packet_set_serialise(wbconn->packet);
}
Exemplo n.º 2
0
/*
  create a transport structure based on an established socket
*/
struct smbcli_transport *smbcli_transport_init(struct smbcli_socket *sock,
					       TALLOC_CTX *parent_ctx, 
					       bool primary, 
					       struct smbcli_options *options)
{
	struct smbcli_transport *transport;

	transport = talloc_zero(parent_ctx, struct smbcli_transport);
	if (!transport) return NULL;

	if (primary) {
		transport->socket = talloc_steal(transport, sock);
	} else {
		transport->socket = talloc_reference(transport, sock);
	}
	transport->negotiate.protocol = PROTOCOL_NT1;
	transport->options = *options;
	transport->negotiate.max_xmit = transport->options.max_xmit;

	/* setup the stream -> packet parser */
	transport->packet = packet_init(transport);
	if (transport->packet == NULL) {
		talloc_free(transport);
		return NULL;
	}
	packet_set_private(transport->packet, transport);
	packet_set_socket(transport->packet, transport->socket->sock);
	packet_set_callback(transport->packet, smbcli_transport_finish_recv);
	packet_set_full_request(transport->packet, packet_full_request_nbt);
	packet_set_error_handler(transport->packet, smbcli_transport_error);
	packet_set_event_context(transport->packet, transport->socket->event.ctx);
	packet_set_nofree(transport->packet);
	packet_set_initial_read(transport->packet, 4);

	smbcli_init_signing(transport);

	ZERO_STRUCT(transport->called);

	/* take over event handling from the socket layer - it only
	   handles events up until we are connected */
	talloc_free(transport->socket->event.fde);
	transport->socket->event.fde = event_add_fd(transport->socket->event.ctx,
						    transport->socket->sock,
						    socket_get_fd(transport->socket->sock),
						    EVENT_FD_READ,
						    smbcli_transport_event_handler,
						    transport);

	packet_set_fde(transport->packet, transport->socket->event.fde);
	packet_set_serialise(transport->packet);
	talloc_set_destructor(transport, transport_destructor);

	return transport;
}
Exemplo n.º 3
0
/*
  initialise a wrepl_socket from an already existing connection
*/
struct wrepl_socket *wrepl_socket_merge(TALLOC_CTX *mem_ctx,
                                        struct tevent_context *event_ctx,
                                        struct socket_context *sock,
                                        struct packet_context *pack)
{
    struct wrepl_socket *wrepl_socket;

    wrepl_socket = talloc_zero(mem_ctx, struct wrepl_socket);
    if (wrepl_socket == NULL) goto failed;

    wrepl_socket->event.ctx = talloc_reference(wrepl_socket, event_ctx);
    if (wrepl_socket->event.ctx == NULL) goto failed;

    wrepl_socket->sock = sock;
    talloc_steal(wrepl_socket, wrepl_socket->sock);


    wrepl_socket->request_timeout	= WREPL_SOCKET_REQUEST_TIMEOUT;

    wrepl_socket->event.fde = event_add_fd(wrepl_socket->event.ctx, wrepl_socket,
                                           socket_get_fd(wrepl_socket->sock),
                                           EVENT_FD_READ,
                                           wrepl_handler, wrepl_socket);
    if (wrepl_socket->event.fde == NULL) {
        goto failed;
    }

    wrepl_socket->packet = pack;
    talloc_steal(wrepl_socket, wrepl_socket->packet);
    packet_set_private(wrepl_socket->packet, wrepl_socket);
    packet_set_socket(wrepl_socket->packet, wrepl_socket->sock);
    packet_set_callback(wrepl_socket->packet, wrepl_finish_recv);
    packet_set_full_request(wrepl_socket->packet, packet_full_request_u32);
    packet_set_error_handler(wrepl_socket->packet, wrepl_error);
    packet_set_event_context(wrepl_socket->packet, wrepl_socket->event.ctx);
    packet_set_fde(wrepl_socket->packet, wrepl_socket->event.fde);
    packet_set_serialise(wrepl_socket->packet);

    talloc_set_destructor(wrepl_socket, wrepl_socket_destructor);

    return wrepl_socket;

failed:
    talloc_free(wrepl_socket);
    return NULL;
}
Exemplo n.º 4
0
NTSTATUS gensec_socket_init(struct gensec_security *gensec_security,
			    TALLOC_CTX *mem_ctx,
			    struct socket_context *current_socket,
			    struct tevent_context *ev,
			    void (*recv_handler)(void *, uint16_t),
			    void *recv_private,
			    struct socket_context **new_socket)
{
	struct gensec_socket *gensec_socket;
	struct socket_context *new_sock;
	NTSTATUS nt_status;

	nt_status = socket_create_with_ops(mem_ctx, &gensec_socket_ops, &new_sock, 
					   SOCKET_TYPE_STREAM, current_socket->flags | SOCKET_FLAG_ENCRYPT);
	if (!NT_STATUS_IS_OK(nt_status)) {
		*new_socket = NULL;
		return nt_status;
	}

	new_sock->state = current_socket->state;

	gensec_socket = talloc(new_sock, struct gensec_socket);
	if (gensec_socket == NULL) {
		*new_socket = NULL;
		talloc_free(new_sock);
		return NT_STATUS_NO_MEMORY;
	}

	new_sock->private_data       = gensec_socket;
	gensec_socket->socket        = current_socket;

	/* Nothing to do here, if we are not actually wrapping on this socket */
	if (!gensec_have_feature(gensec_security, GENSEC_FEATURE_SEAL) &&
	    !gensec_have_feature(gensec_security, GENSEC_FEATURE_SIGN)) {
		
		gensec_socket->wrap = false;
		talloc_steal(gensec_socket, current_socket);
		*new_socket = new_sock;
		return NT_STATUS_OK;
	}

	gensec_socket->gensec_security = gensec_security;

	gensec_socket->wrap          = true;
	gensec_socket->eof           = false;
	gensec_socket->error         = NT_STATUS_OK;
	gensec_socket->interrupted   = false;
	gensec_socket->in_extra_read = 0;

	gensec_socket->read_buffer   = data_blob(NULL, 0);

	gensec_socket->recv_handler  = recv_handler;
	gensec_socket->recv_private  = recv_private;
	gensec_socket->ev            = ev;

	gensec_socket->packet = packet_init(gensec_socket);
	if (gensec_socket->packet == NULL) {
		*new_socket = NULL;
		talloc_free(new_sock);
		return NT_STATUS_NO_MEMORY;
	}

	packet_set_private(gensec_socket->packet, gensec_socket);
	packet_set_socket(gensec_socket->packet, gensec_socket->socket);
	packet_set_callback(gensec_socket->packet, gensec_socket_unwrap);
	packet_set_full_request(gensec_socket->packet, gensec_socket_full_request);
	packet_set_error_handler(gensec_socket->packet, gensec_socket_error_handler);
	packet_set_serialise(gensec_socket->packet);

	/* TODO: full-request that knows about maximum packet size */

	talloc_steal(gensec_socket, current_socket);
	*new_socket = new_sock;
	return NT_STATUS_OK;
}
Exemplo n.º 5
0
/*
  initialise a server_context from a open socket and register a event handler
  for reading from that socket
*/
static void ldapsrv_accept(struct stream_connection *c,
			   struct auth_session_info *session_info)
{
	struct ldapsrv_service *ldapsrv_service = 
		talloc_get_type(c->private_data, struct ldapsrv_service);
	struct ldapsrv_connection *conn;
	struct cli_credentials *server_credentials;
	struct socket_address *socket_address;
	NTSTATUS status;
	int port;

	conn = talloc_zero(c, struct ldapsrv_connection);
	if (!conn) {
		stream_terminate_connection(c, "ldapsrv_accept: out of memory");
		return;
	}

	conn->packet      = NULL;
	conn->connection  = c;
	conn->service     = ldapsrv_service;
	conn->sockets.raw = c->socket;
	conn->lp_ctx      = ldapsrv_service->task->lp_ctx;

	c->private_data   = conn;

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

	if (port == 636) {
		struct socket_context *tls_socket = tls_init_server(ldapsrv_service->tls_params, c->socket, 
								    c->event.fde, NULL);
		if (!tls_socket) {
			ldapsrv_terminate_connection(conn, "ldapsrv_accept: tls_init_server() failed");
			return;
		}
		talloc_steal(c, tls_socket);
		c->socket = tls_socket;
		conn->sockets.tls = tls_socket;

	} else if (port == 3268) /* Global catalog */ {
		conn->global_catalog = true;
	}
	conn->packet = packet_init(conn);
	if (conn->packet == NULL) {
		ldapsrv_terminate_connection(conn, "out of memory");
		return;
	}

	packet_set_private(conn->packet, conn);
	packet_set_socket(conn->packet, c->socket);
	packet_set_callback(conn->packet, ldapsrv_decode);
	packet_set_full_request(conn->packet, ldap_full_packet);
	packet_set_error_handler(conn->packet, ldapsrv_error_handler);
	packet_set_event_context(conn->packet, c->event.ctx);
	packet_set_fde(conn->packet, c->event.fde);
	packet_set_serialise(conn->packet);

	if (conn->sockets.tls) {
		packet_set_unreliable_select(conn->packet);
	}

	/* Ensure we don't get packets until the database is ready below */
	packet_recv_disable(conn->packet);

	server_credentials = cli_credentials_init(conn);
	if (!server_credentials) {
		stream_terminate_connection(c, "Failed to init server credentials\n");
		return;
	}

	cli_credentials_set_conf(server_credentials, conn->lp_ctx);
	status = cli_credentials_set_machine_account(server_credentials, conn->lp_ctx);
	if (!NT_STATUS_IS_OK(status)) {
		stream_terminate_connection(c, talloc_asprintf(conn, "Failed to obtain server credentials, perhaps a standalone server?: %s\n", nt_errstr(status)));
		return;
	}
	conn->server_credentials = server_credentials;

	conn->session_info = talloc_move(conn, &session_info);

	if (!NT_STATUS_IS_OK(ldapsrv_backend_Init(conn))) {
		ldapsrv_terminate_connection(conn, "backend Init failed");
		return;
	}

	/* load limits from the conf partition */
	ldapsrv_load_limits(conn); /* should we fail on error ? */

	/* register the server */	
	irpc_add_name(c->msg_ctx, "ldap_server");

	/* set connections limits */
	conn->limits.ite = event_add_timed(c->event.ctx, conn, 
					   timeval_current_ofs(conn->limits.initial_timeout, 0),
					   ldapsrv_conn_init_timeout, conn);

	packet_recv_enable(conn->packet);

}
Exemplo n.º 6
0
/*
  called when we get a new connection
*/
static void kdc_tcp_accept(struct stream_connection *conn)
{
 	struct kdc_socket *kdc_socket = talloc_get_type(conn->private_data, struct kdc_socket);
	struct kdc_tcp_connection *kdcconn;
	struct socket_address *src_addr;
	struct socket_address *my_addr;
	int ret;

	kdcconn = talloc_zero(conn, struct kdc_tcp_connection);
	if (!kdcconn) {
		stream_terminate_connection(conn, "kdc_tcp_accept: out of memory");
		return;
	}
	kdcconn->conn		= conn;
	kdcconn->kdc_socket	= kdc_socket;
	conn->private_data    = kdcconn;

	src_addr = socket_get_peer_addr(kdcconn->conn->socket, kdcconn);
	if (!src_addr) {
		kdc_tcp_terminate_connection(kdcconn, "kdc_tcp_accept: out of memory");
		return;
	}

	my_addr = socket_get_my_addr(kdcconn->conn->socket, kdcconn);
	if (!my_addr) {
		kdc_tcp_terminate_connection(kdcconn, "kdc_tcp_accept: out of memory");
		return;
	}

	ret = tsocket_address_bsd_from_sockaddr(kdcconn,
						src_addr->sockaddr,
						src_addr->sockaddrlen,
						&kdcconn->remote_address);
	if (ret < 0) {
		kdc_tcp_terminate_connection(kdcconn, "kdc_tcp_accept: out of memory");
		return;
	}

	ret = tsocket_address_bsd_from_sockaddr(kdcconn,
						my_addr->sockaddr,
						my_addr->sockaddrlen,
						&kdcconn->local_address);
	if (ret < 0) {
		kdc_tcp_terminate_connection(kdcconn, "kdc_tcp_accept: out of memory");
		return;
	}

	TALLOC_FREE(src_addr);
	TALLOC_FREE(my_addr);

	kdcconn->packet = packet_init(kdcconn);
	if (kdcconn->packet == NULL) {
		kdc_tcp_terminate_connection(kdcconn, "kdc_tcp_accept: out of memory");
		return;
	}
	packet_set_private(kdcconn->packet, kdcconn);
	packet_set_socket(kdcconn->packet, conn->socket);
	packet_set_callback(kdcconn->packet, kdc_tcp_recv);
	packet_set_full_request(kdcconn->packet, packet_full_request_u32);
	packet_set_error_handler(kdcconn->packet, kdc_tcp_recv_error);
	packet_set_event_context(kdcconn->packet, conn->event.ctx);
	packet_set_fde(kdcconn->packet, conn->event.fde);
	packet_set_serialise(kdcconn->packet);
}