summaryrefslogtreecommitdiff
path: root/source4/winbind
diff options
context:
space:
mode:
authorAndrew Bartlett <abartlet@samba.org>2006-01-12 09:38:35 +0000
committerGerald (Jerry) Carter <jerry@samba.org>2007-10-10 13:50:55 -0500
commitf18194edae4289a75955ef3b0fb9943a7a63f9d4 (patch)
treedbdeefda275da1b63a1d44dd24953a27ade52d7d /source4/winbind
parenta5a79e8b8cbdf24d5c2db45ece4110ed5d85e58f (diff)
downloadsamba-f18194edae4289a75955ef3b0fb9943a7a63f9d4.tar.gz
samba-f18194edae4289a75955ef3b0fb9943a7a63f9d4.tar.bz2
samba-f18194edae4289a75955ef3b0fb9943a7a63f9d4.zip
r12866: This removes the abstraction layer in winbindd intended to deal with
multiple protocols, replacing it with the packet handling subsystem. We don't have multiple protocols at present, and the abstraction layer only serves to confuse matters. Also, the new packet subsystem removes the need to handle partial reads. We can easily add new protocols from the socket up instead, becaue the difficult bits are done by the packet layer. Andrew Bartlett (This used to be commit acf9dc8fe9e66f1dd3f18c0245375f502f03a24c)
Diffstat (limited to 'source4/winbind')
-rw-r--r--source4/winbind/wb_samba3_cmd.c44
-rw-r--r--source4/winbind/wb_samba3_protocol.c127
-rw-r--r--source4/winbind/wb_samba3_protocol.h39
-rw-r--r--source4/winbind/wb_server.c215
-rw-r--r--source4/winbind/wb_server.h49
5 files changed, 165 insertions, 309 deletions
diff --git a/source4/winbind/wb_samba3_cmd.c b/source4/winbind/wb_samba3_cmd.c
index 101a1d857d..8113de35b6 100644
--- a/source4/winbind/wb_samba3_cmd.c
+++ b/source4/winbind/wb_samba3_cmd.c
@@ -51,11 +51,7 @@ static void wbsrv_samba3_async_auth_epilogue(NTSTATUS status,
resp->data.auth.pam_error = nt_status_to_pam(status);
resp->data.auth.nt_status = NT_STATUS_V(status);
- status = wbsrv_send_reply(s3call->call);
- if (!NT_STATUS_IS_OK(status)) {
- wbsrv_terminate_connection(s3call->call->wbconn,
- "wbsrv_queue_reply() failed");
- }
+ wbsrv_samba3_send_reply(s3call);
}
/*
@@ -72,11 +68,7 @@ static void wbsrv_samba3_async_epilogue(NTSTATUS status,
resp->result = WINBINDD_ERROR;
}
- status = wbsrv_send_reply(s3call->call);
- if (!NT_STATUS_IS_OK(status)) {
- wbsrv_terminate_connection(s3call->call->wbconn,
- "wbsrv_queue_reply() failed");
- }
+ wbsrv_samba3_send_reply(s3call);
}
/*
@@ -177,7 +169,7 @@ NTSTATUS wbsrv_samba3_getdcname(struct wbsrv_samba3_call *s3call)
{
struct composite_context *ctx;
struct wbsrv_service *service =
- s3call->call->wbconn->listen_socket->service;
+ s3call->wbconn->listen_socket->service;
DEBUG(5, ("wbsrv_samba3_getdcname called\n"));
@@ -187,7 +179,7 @@ NTSTATUS wbsrv_samba3_getdcname(struct wbsrv_samba3_call *s3call)
ctx->async.fn = getdcname_recv_dc;
ctx->async.private_data = s3call;
- s3call->call->flags |= WBSRV_CALL_FLAGS_REPLY_ASYNC;
+ s3call->flags |= WBSRV_CALL_FLAGS_REPLY_ASYNC;
return NT_STATUS_OK;
}
@@ -230,12 +222,12 @@ NTSTATUS wbsrv_samba3_userdomgroups(struct wbsrv_samba3_call *s3call)
}
ctx = wb_cmd_userdomgroups_send(
- s3call, s3call->call->wbconn->listen_socket->service, sid);
+ s3call, s3call->wbconn->listen_socket->service, sid);
NT_STATUS_HAVE_NO_MEMORY(ctx);
ctx->async.fn = userdomgroups_recv_groups;
ctx->async.private_data = s3call;
- s3call->call->flags |= WBSRV_CALL_FLAGS_REPLY_ASYNC;
+ s3call->flags |= WBSRV_CALL_FLAGS_REPLY_ASYNC;
return NT_STATUS_OK;
}
@@ -297,12 +289,12 @@ NTSTATUS wbsrv_samba3_usersids(struct wbsrv_samba3_call *s3call)
}
ctx = wb_cmd_usersids_send(
- s3call, s3call->call->wbconn->listen_socket->service, sid);
+ s3call, s3call->wbconn->listen_socket->service, sid);
NT_STATUS_HAVE_NO_MEMORY(ctx);
ctx->async.fn = usersids_recv_sids;
ctx->async.private_data = s3call;
- s3call->call->flags |= WBSRV_CALL_FLAGS_REPLY_ASYNC;
+ s3call->flags |= WBSRV_CALL_FLAGS_REPLY_ASYNC;
return NT_STATUS_OK;
}
@@ -363,7 +355,7 @@ NTSTATUS wbsrv_samba3_lookupname(struct wbsrv_samba3_call *s3call)
{
struct composite_context *ctx;
struct wbsrv_service *service =
- s3call->call->wbconn->listen_socket->service;
+ s3call->wbconn->listen_socket->service;
DEBUG(5, ("wbsrv_samba3_lookupname called\n"));
@@ -375,7 +367,7 @@ NTSTATUS wbsrv_samba3_lookupname(struct wbsrv_samba3_call *s3call)
/* setup the callbacks */
ctx->async.fn = lookupname_recv_sid;
ctx->async.private_data = s3call;
- s3call->call->flags |= WBSRV_CALL_FLAGS_REPLY_ASYNC;
+ s3call->flags |= WBSRV_CALL_FLAGS_REPLY_ASYNC;
return NT_STATUS_OK;
}
@@ -409,7 +401,7 @@ NTSTATUS wbsrv_samba3_lookupsid(struct wbsrv_samba3_call *s3call)
{
struct composite_context *ctx;
struct wbsrv_service *service =
- s3call->call->wbconn->listen_socket->service;
+ s3call->wbconn->listen_socket->service;
struct dom_sid *sid;
DEBUG(5, ("wbsrv_samba3_lookupsid called\n"));
@@ -427,7 +419,7 @@ NTSTATUS wbsrv_samba3_lookupsid(struct wbsrv_samba3_call *s3call)
/* setup the callbacks */
ctx->async.fn = lookupsid_recv_name;
ctx->async.private_data = s3call;
- s3call->call->flags |= WBSRV_CALL_FLAGS_REPLY_ASYNC;
+ s3call->flags |= WBSRV_CALL_FLAGS_REPLY_ASYNC;
return NT_STATUS_OK;
}
@@ -468,7 +460,7 @@ NTSTATUS wbsrv_samba3_pam_auth_crap(struct wbsrv_samba3_call *s3call)
{
struct composite_context *ctx;
struct wbsrv_service *service =
- s3call->call->wbconn->listen_socket->service;
+ s3call->wbconn->listen_socket->service;
DATA_BLOB chal, nt_resp, lm_resp;
DEBUG(5, ("wbsrv_samba3_pam_auth_crap called\n"));
@@ -491,7 +483,7 @@ NTSTATUS wbsrv_samba3_pam_auth_crap(struct wbsrv_samba3_call *s3call)
ctx->async.fn = pam_auth_crap_recv;
ctx->async.private_data = s3call;
- s3call->call->flags |= WBSRV_CALL_FLAGS_REPLY_ASYNC;
+ s3call->flags |= WBSRV_CALL_FLAGS_REPLY_ASYNC;
return NT_STATUS_OK;
}
@@ -570,7 +562,7 @@ NTSTATUS wbsrv_samba3_pam_auth(struct wbsrv_samba3_call *s3call)
{
struct composite_context *ctx;
struct wbsrv_service *service =
- s3call->call->wbconn->listen_socket->service;
+ s3call->wbconn->listen_socket->service;
char *user, *domain;
if (!samba3_parse_domuser(s3call,
@@ -585,7 +577,7 @@ NTSTATUS wbsrv_samba3_pam_auth(struct wbsrv_samba3_call *s3call)
ctx->async.fn = pam_auth_recv;
ctx->async.private_data = s3call;
- s3call->call->flags |= WBSRV_CALL_FLAGS_REPLY_ASYNC;
+ s3call->flags |= WBSRV_CALL_FLAGS_REPLY_ASYNC;
return NT_STATUS_OK;
}
@@ -614,7 +606,7 @@ NTSTATUS wbsrv_samba3_list_trustdom(struct wbsrv_samba3_call *s3call)
{
struct composite_context *ctx;
struct wbsrv_service *service =
- s3call->call->wbconn->listen_socket->service;
+ s3call->wbconn->listen_socket->service;
DEBUG(5, ("wbsrv_samba3_list_trustdom called\n"));
@@ -623,7 +615,7 @@ NTSTATUS wbsrv_samba3_list_trustdom(struct wbsrv_samba3_call *s3call)
ctx->async.fn = list_trustdom_recv_doms;
ctx->async.private_data = s3call;
- s3call->call->flags |= WBSRV_CALL_FLAGS_REPLY_ASYNC;
+ s3call->flags |= WBSRV_CALL_FLAGS_REPLY_ASYNC;
return NT_STATUS_OK;
}
diff --git a/source4/winbind/wb_samba3_protocol.c b/source4/winbind/wb_samba3_protocol.c
index 8fffdbd0a7..35e4c65d13 100644
--- a/source4/winbind/wb_samba3_protocol.c
+++ b/source4/winbind/wb_samba3_protocol.c
@@ -23,48 +23,55 @@
#include "includes.h"
#include "nsswitch/winbindd_nss.h"
#include "winbind/wb_server.h"
-#include "winbind/wb_samba3_protocol.h"
+#include "smbd/service_stream.h"
+#include "lib/stream/packet.h"
-uint32_t wbsrv_samba3_packet_length(DATA_BLOB blob)
+/*
+ work out if a packet is complete for protocols that use a 32 bit network byte
+ order length
+*/
+NTSTATUS wbsrv_samba3_packet_full_request(void *private, DATA_BLOB blob, size_t *size)
{
- uint32_t *len = (uint32_t *)blob.data;
- return *len;
+ uint32_t *len;
+ if (blob.length < 4) {
+ return STATUS_MORE_ENTRIES;
+ }
+ len = (uint32_t *)blob.data;
+ *size = (*len);
+ if (*size > blob.length) {
+ return STATUS_MORE_ENTRIES;
+ }
+ return NT_STATUS_OK;
}
-NTSTATUS wbsrv_samba3_pull_request(DATA_BLOB blob, TALLOC_CTX *mem_ctx,
- struct wbsrv_call **_call)
+
+NTSTATUS wbsrv_samba3_pull_request(DATA_BLOB blob, struct wbsrv_connection *wbconn,
+ struct wbsrv_samba3_call **_call)
{
- struct wbsrv_call *call;
- struct wbsrv_samba3_call *s3_call;
+ struct wbsrv_samba3_call *call;
- if (blob.length != sizeof(s3_call->request)) {
+ if (blob.length != sizeof(call->request)) {
DEBUG(0,("wbsrv_samba3_pull_request: invalid blob length %lu should be %lu\n"
" make sure you use the correct winbind client tools!\n",
- (long)blob.length, (long)sizeof(s3_call->request)));
+ (long)blob.length, (long)sizeof(call->request)));
return NT_STATUS_INVALID_PARAMETER;
}
- call = talloc_zero(mem_ctx, struct wbsrv_call);
+ call = talloc_zero(wbconn, struct wbsrv_samba3_call);
NT_STATUS_HAVE_NO_MEMORY(call);
- s3_call = talloc_zero(call, struct wbsrv_samba3_call);
- NT_STATUS_HAVE_NO_MEMORY(s3_call);
- s3_call->call = call;
-
/* the packet layout is the same as the in memory layout of the request, so just copy it */
- memcpy(&s3_call->request, blob.data, sizeof(s3_call->request));
-
- call->private_data = s3_call;
+ memcpy(&call->request, blob.data, sizeof(call->request));
+ call->wbconn = wbconn;
+ call->event_ctx = call->wbconn->conn->event.ctx;
+
*_call = call;
return NT_STATUS_OK;
}
-NTSTATUS wbsrv_samba3_handle_call(struct wbsrv_call *call)
+NTSTATUS wbsrv_samba3_handle_call(struct wbsrv_samba3_call *s3call)
{
- struct wbsrv_samba3_call *s3call = talloc_get_type(call->private_data,
- struct wbsrv_samba3_call);
-
DEBUG(10, ("Got winbind samba3 request %d\n", s3call->request.cmd));
s3call->response.length = sizeof(s3call->response);
@@ -165,35 +172,89 @@ NTSTATUS wbsrv_samba3_handle_call(struct wbsrv_call *call)
return NT_STATUS_OK;
}
-NTSTATUS wbsrv_samba3_push_reply(struct wbsrv_call *call, TALLOC_CTX *mem_ctx, DATA_BLOB *_blob)
+static NTSTATUS wbsrv_samba3_push_reply(struct wbsrv_samba3_call *call, TALLOC_CTX *mem_ctx, DATA_BLOB *_blob)
{
- struct wbsrv_samba3_call *s3call = talloc_get_type(call->private_data,
- struct wbsrv_samba3_call);
DATA_BLOB blob;
uint8_t *extra_data;
size_t extra_data_len = 0;
- extra_data = s3call->response.extra_data;
+ extra_data = call->response.extra_data;
if (extra_data) {
- extra_data_len = s3call->response.length -
- sizeof(s3call->response);
+ extra_data_len = call->response.length -
+ sizeof(call->response);
}
- blob = data_blob_talloc(mem_ctx, NULL, s3call->response.length);
+ blob = data_blob_talloc(mem_ctx, NULL, call->response.length);
NT_STATUS_HAVE_NO_MEMORY(blob.data);
/* don't push real pointer values into sockets */
if (extra_data) {
- s3call->response.extra_data = (void *)0xFFFFFFFF;
+ call->response.extra_data = (void *)0xFFFFFFFF;
}
- memcpy(blob.data, &s3call->response, sizeof(s3call->response));
+ memcpy(blob.data, &call->response, sizeof(call->response));
/* set back the pointer */
- s3call->response.extra_data = extra_data;
+ call->response.extra_data = extra_data;
if (extra_data) {
- memcpy(blob.data + sizeof(s3call->response), extra_data, extra_data_len);
+ memcpy(blob.data + sizeof(call->response), extra_data, extra_data_len);
}
*_blob = blob;
return NT_STATUS_OK;
}
+
+/*
+ * queue a wbsrv_call reply on a wbsrv_connection
+ * NOTE: that this implies talloc_free(call),
+ * use talloc_reference(call) if you need it after
+ * calling wbsrv_queue_reply
+ */
+NTSTATUS wbsrv_samba3_send_reply(struct wbsrv_samba3_call *call)
+{
+ struct wbsrv_connection *wbconn = call->wbconn;
+ DATA_BLOB rep;
+ NTSTATUS status;
+
+ status = wbsrv_samba3_push_reply(call, call, &rep);
+ NT_STATUS_NOT_OK_RETURN(status);
+
+ status = packet_send(call->wbconn->packet, rep);
+
+ talloc_free(call);
+
+ if (!NT_STATUS_IS_OK(status)) {
+ wbsrv_terminate_connection(wbconn,
+ "failed to packet_send winbindd reply");
+ return status;
+ }
+ /* the call isn't needed any more */
+ return status;
+}
+
+NTSTATUS wbsrv_samba3_process(void *private, DATA_BLOB blob)
+{
+ NTSTATUS status;
+ struct wbsrv_connection *wbconn = talloc_get_type(private,
+ struct wbsrv_connection);
+ struct wbsrv_samba3_call *call;
+ status = wbsrv_samba3_pull_request(blob, wbconn, &call);
+
+ if (!NT_STATUS_IS_OK(status)) {
+ return status;
+ }
+
+ status = wbsrv_samba3_handle_call(call);
+
+ if (!NT_STATUS_IS_OK(status)) {
+ talloc_free(call);
+ return status;
+ }
+
+ if (call->flags & WBSRV_CALL_FLAGS_REPLY_ASYNC) {
+ return NT_STATUS_OK;
+ }
+
+ status = wbsrv_samba3_send_reply(call);
+ return status;
+}
+
diff --git a/source4/winbind/wb_samba3_protocol.h b/source4/winbind/wb_samba3_protocol.h
deleted file mode 100644
index 9a13210187..0000000000
--- a/source4/winbind/wb_samba3_protocol.h
+++ /dev/null
@@ -1,39 +0,0 @@
-/*
- Unix SMB/CIFS implementation.
- Main winbindd samba3 server routines
-
- Copyright (C) Stefan Metzmacher 2005
- Copyright (C) Volker Lendecke 2005
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
-
- This program is distributed in the hope that it will be useful,
- but WITHOUT ANY WARRANTY; without even the implied warranty of
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- GNU General Public License for more details.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-*/
-
-struct wbsrv_samba3_call {
- /* pointer back to the generic winbind call */
- struct wbsrv_call *call;
-
- /* here the backend can store stuff like composite_context's ... */
- void *private_data;
-
- /* the request structure of the samba3 protocol */
- struct winbindd_request request;
-
- /* the response structure of the samba3 protocol*/
- struct winbindd_response response;
-};
-
-#define WBSRV_SAMBA3_SET_STRING(dest, src) do { \
- strncpy(dest, src, sizeof(dest)-1);\
-} while(0)
diff --git a/source4/winbind/wb_server.c b/source4/winbind/wb_server.c
index 6bd60d209e..a08b080334 100644
--- a/source4/winbind/wb_server.c
+++ b/source4/winbind/wb_server.c
@@ -28,6 +28,7 @@
#include "smbd/service_stream.h"
#include "nsswitch/winbind_nss_config.h"
#include "winbind/wb_server.h"
+#include "lib/stream/packet.h"
void wbsrv_terminate_connection(struct wbsrv_connection *wbconn, const char *reason)
{
@@ -35,167 +36,53 @@ void wbsrv_terminate_connection(struct wbsrv_connection *wbconn, const char *rea
}
/*
- called when we get a new connection
+ called on a tcp recv error
*/
+static void wbsrv_recv_error(void *private, NTSTATUS status)
+{
+ struct wbsrv_connection *wbconn = talloc_get_type(private, struct wbsrv_connection);
+ wbsrv_terminate_connection(wbconn, nt_errstr(status));
+}
+
static void wbsrv_accept(struct stream_connection *conn)
{
- struct wbsrv_listen_socket *listen_socket =
- talloc_get_type(conn->private, struct wbsrv_listen_socket);
+ struct wbsrv_listen_socket *listen_socket = talloc_get_type(conn->private,
+ 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;
- conn->private = wbconn;
-}
-
-/*
- receive some data on a winbind connection
-*/
-static void wbsrv_recv(struct stream_connection *conn, uint16_t flags)
-{
- struct wbsrv_connection *wbconn =
- talloc_get_type(conn->private, struct wbsrv_connection);
- const struct wbsrv_protocol_ops *ops = wbconn->listen_socket->ops;
- struct wbsrv_call *call;
- NTSTATUS status = NT_STATUS_UNSUCCESSFUL;
- size_t nread;
-
- /* avoid recursion, because of half async code */
- if (wbconn->processing) {
- EVENT_FD_NOT_READABLE(conn->event.fde);
- return;
- }
-
- /* if the used protocol doesn't support pending requests disallow
- * them */
- if (wbconn->pending_calls && !ops->allow_pending_calls) {
- EVENT_FD_NOT_READABLE(conn->event.fde);
+ stream_terminate_connection(conn, "wbsrv_accept: out of memory");
return;
}
+ wbconn->conn = conn;
+ wbconn->listen_socket = listen_socket;
+ conn->private = wbconn;
- if (wbconn->partial.length == 0) {
- wbconn->partial = data_blob_talloc(wbconn, NULL, 4);
- if (!wbconn->partial.data) goto nomem;
-
- wbconn->partial_read = 0;
- }
-
- /* read in the packet length */
- if (wbconn->partial_read < 4) {
- uint32_t packet_length;
-
- status = socket_recv(conn->socket,
- wbconn->partial.data+wbconn->partial_read,
- 4 - wbconn->partial_read,
- &nread, 0);
- if (NT_STATUS_IS_ERR(status)) goto failed;
- if (!NT_STATUS_IS_OK(status)) return;
-
- wbconn->partial_read += nread;
- if (wbconn->partial_read != 4) return;
-
- packet_length = ops->packet_length(wbconn->partial);
-
- wbconn->partial.data =
- talloc_realloc(wbconn, wbconn->partial.data, uint8_t,
- packet_length);
- if (!wbconn->partial.data) goto nomem;
-
- wbconn->partial.length = packet_length;
- }
-
- /* read in the body */
- status = socket_recv(conn->socket,
- wbconn->partial.data + wbconn->partial_read,
- wbconn->partial.length - wbconn->partial_read,
- &nread, 0);
- if (NT_STATUS_IS_ERR(status)) goto failed;
- if (!NT_STATUS_IS_OK(status)) return;
-
- wbconn->partial_read += nread;
- if (wbconn->partial_read != wbconn->partial.length) return;
-
- /* we have a full request - parse it */
- status = ops->pull_request(wbconn->partial, wbconn, &call);
- if (!NT_STATUS_IS_OK(status)) goto failed;
- call->wbconn = wbconn;
- call->event_ctx = conn->event.ctx;
-
- /*
- * we have parsed the request, so we can reset the
- * wbconn->partial_read, maybe we could also free wbconn->partial, but
- * for now we keep it, and overwrite it the next time
- */
- wbconn->partial_read = 0;
-
- /* actually process the request */
- wbconn->pending_calls++;
- wbconn->processing = True;
- status = ops->handle_call(call);
- wbconn->processing = False;
- if (!NT_STATUS_IS_OK(status)) goto failed;
-
- /* if the backend want to reply later just return here */
- if (call->flags & WBSRV_CALL_FLAGS_REPLY_ASYNC) {
+ wbconn->packet = packet_init(wbconn);
+ if (wbconn->packet == NULL) {
+ wbsrv_terminate_connection(wbconn, "wbsrv_accept: out of memory");
return;
}
-
- /*
- * and queue the reply, this implies talloc_free(call),
- * and set the socket to readable again
- */
- status = wbsrv_send_reply(call);
- if (!NT_STATUS_IS_OK(status)) goto failed;
-
- return;
-nomem:
- status = NT_STATUS_NO_MEMORY;
-failed:
- wbsrv_terminate_connection(wbconn, nt_errstr(status));
+ 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);
}
/*
- * queue a wbsrv_call reply on a wbsrv_connection
- * NOTE: that this implies talloc_free(call),
- * use talloc_reference(call) if you need it after
- * calling wbsrv_queue_reply
- * NOTE: if this function desn't return NT_STATUS_OK,
- * the caller needs to call
- * wbsrv_terminate_connection(call->wbconn, "reason...");
- * return;
- * to drop the connection
- */
-NTSTATUS wbsrv_send_reply(struct wbsrv_call *call)
+ receive some data on a winbind connection
+*/
+static void wbsrv_recv(struct stream_connection *conn, uint16_t flags)
{
- struct wbsrv_connection *wbconn = call->wbconn;
- const struct wbsrv_protocol_ops *ops = wbconn->listen_socket->ops;
- struct data_blob_list_item *rep;
- NTSTATUS status;
-
- /* and now encode the reply */
- rep = talloc(wbconn, struct data_blob_list_item);
- NT_STATUS_HAVE_NO_MEMORY(rep);
-
- status = ops->push_reply(call, rep, &rep->blob);
- NT_STATUS_NOT_OK_RETURN(status);
-
- if (!wbconn->send_queue) {
- EVENT_FD_WRITEABLE(wbconn->conn->event.fde);
- }
- DLIST_ADD_END(wbconn->send_queue, rep, struct data_blob_list_item *);
-
- EVENT_FD_READABLE(wbconn->conn->event.fde);
+ struct wbsrv_connection *wbconn = talloc_get_type(conn->private,
+ struct wbsrv_connection);
+ packet_recv(wbconn->packet);
- /* the call isn't needed any more */
- wbconn->pending_calls--;
- talloc_free(call);
- return NT_STATUS_OK;
}
/*
@@ -203,48 +90,18 @@ NTSTATUS wbsrv_send_reply(struct wbsrv_call *call)
*/
static void wbsrv_send(struct stream_connection *conn, uint16_t flags)
{
- struct wbsrv_connection *wbconn = talloc_get_type(conn->private, struct wbsrv_connection);
- NTSTATUS status;
-
- while (wbconn->send_queue) {
- struct data_blob_list_item *q = wbconn->send_queue;
- size_t sendlen;
-
- status = socket_send(conn->socket, &q->blob, &sendlen, 0);
- if (NT_STATUS_IS_ERR(status)) goto failed;
- if (!NT_STATUS_IS_OK(status)) return;
-
- q->blob.length -= sendlen;
- q->blob.data += sendlen;
-
- if (q->blob.length == 0) {
- DLIST_REMOVE(wbconn->send_queue, q);
- talloc_free(q);
- }
- }
-
- EVENT_FD_NOT_WRITEABLE(conn->event.fde);
- return;
-failed:
- wbsrv_terminate_connection(wbconn, nt_errstr(status));
+ struct wbsrv_connection *wbconn = talloc_get_type(conn->private,
+ struct wbsrv_connection);
+ packet_queue_run(wbconn->packet);
}
static const struct stream_server_ops wbsrv_ops = {
- .name = "winbind",
+ .name = "winbind samba3 protocol",
.accept_connection = wbsrv_accept,
.recv_handler = wbsrv_recv,
.send_handler = wbsrv_send
};
-static const struct wbsrv_protocol_ops wbsrv_samba3_protocol_ops = {
- .name = "winbind samba3 protocol",
- .allow_pending_calls = False,
- .packet_length = wbsrv_samba3_packet_length,
- .pull_request = wbsrv_samba3_pull_request,
- .handle_call = wbsrv_samba3_handle_call,
- .push_reply = wbsrv_samba3_push_reply
-};
-
/*
startup the winbind task
*/
@@ -290,7 +147,6 @@ static void winbind_task_init(struct task_server *task)
if (!listen_socket->socket_path) goto nomem;
listen_socket->service = service;
listen_socket->privileged = False;
- listen_socket->ops = &wbsrv_samba3_protocol_ops;
status = stream_setup_socket(task->event_ctx, model_ops,
&wbsrv_ops, "unix",
listen_socket->socket_path, &port,
@@ -306,7 +162,6 @@ static void winbind_task_init(struct task_server *task)
if (!listen_socket->socket_path) goto nomem;
listen_socket->service = service;
listen_socket->privileged = True;
- listen_socket->ops = &wbsrv_samba3_protocol_ops;
status = stream_setup_socket(task->event_ctx, model_ops,
&wbsrv_ops, "unix",
listen_socket->socket_path, &port,
diff --git a/source4/winbind/wb_server.h b/source4/winbind/wb_server.h
index 8e044a003b..15fee0853c 100644
--- a/source4/winbind/wb_server.h
+++ b/source4/winbind/wb_server.h
@@ -20,6 +20,8 @@
Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*/
+#include "nsswitch/winbindd_nss.h"
+
#define WINBINDD_DIR "/tmp/.winbindd/"
#define WINBINDD_SOCKET WINBINDD_DIR"socket"
/* the privileged socket is in smbd_tmp_dir() */
@@ -74,20 +76,6 @@ struct wbsrv_domain {
struct cli_credentials *schannel_creds;
};
-/*
- this is an abstraction for the actual protocol being used,
- so that we can listen on different sockets with different protocols
- e.g. the old samba3 protocol on one socket and a new protocol on another socket
-*/
-struct wbsrv_protocol_ops {
- const char *name;
- BOOL allow_pending_calls;
- uint32_t (*packet_length)(DATA_BLOB blob);
- NTSTATUS (*pull_request)(DATA_BLOB blob, TALLOC_CTX *mem_ctx, struct wbsrv_call **call);
- NTSTATUS (*handle_call)(struct wbsrv_call *call);
- NTSTATUS (*push_reply)(struct wbsrv_call *call, TALLOC_CTX *mem_ctx, DATA_BLOB *blob);
-};
-
/*
state of a listen socket and it's protocol information
*/
@@ -95,7 +83,6 @@ struct wbsrv_listen_socket {
const char *socket_path;
struct wbsrv_service *service;
BOOL privileged;
- const struct wbsrv_protocol_ops *ops;
};
/*
@@ -111,21 +98,16 @@ struct wbsrv_connection {
/* storage for protocol specific data */
void *protocol_private_data;
- /* the partial data we've receiced yet */
- DATA_BLOB partial;
-
- /* the amount that we used yet from the partial buffer */
- uint32_t partial_read;
-
- /* prevent loops when we use half async code, while processing a requuest */
- BOOL processing;
-
/* how many calls are pending */
uint32_t pending_calls;
- struct data_blob_list_item *send_queue;
+ struct packet_context *packet;
};
+#define WBSRV_SAMBA3_SET_STRING(dest, src) do { \
+ strncpy(dest, src, sizeof(dest)-1);\
+} while(0)
+
/*
state of one request
@@ -144,21 +126,26 @@ struct wbsrv_connection {
return;
*/
-struct wbsrv_call {
+struct wbsrv_samba3_call {
#define WBSRV_CALL_FLAGS_REPLY_ASYNC 0x00000001
uint32_t flags;
- /* the backend should use this event context */
- struct event_context *event_ctx;
-
/* the connection the call belongs to */
struct wbsrv_connection *wbconn;
- /* storage for protocol specific data */
+ /* the backend should use this event context */
+ struct event_context *event_ctx;
+
+ /* here the backend can store stuff like composite_context's ... */
void *private_data;
+
+ /* the request structure of the samba3 protocol */
+ struct winbindd_request request;
+
+ /* the response structure of the samba3 protocol*/
+ struct winbindd_response response;
};
-struct wbsrv_samba3_call;
struct netr_LMSessionKey;
struct netr_UserSessionKey;