summaryrefslogtreecommitdiff
path: root/source4/winbind/wb_samba3_cmd.c
diff options
context:
space:
mode:
authorVolker Lendecke <vlendec@samba.org>2005-10-03 13:46:11 +0000
committerGerald (Jerry) Carter <jerry@samba.org>2007-10-10 13:39:18 -0500
commite5c6a3e36147103e87d1c55173f4b54ba6134904 (patch)
treeb50938eff14034f7b6db53caf76dd2cd9e8cd10c /source4/winbind/wb_samba3_cmd.c
parent28bc38de2ab3a408702cd7d6b69d6549a1fea71a (diff)
downloadsamba-e5c6a3e36147103e87d1c55173f4b54ba6134904.tar.gz
samba-e5c6a3e36147103e87d1c55173f4b54ba6134904.tar.bz2
samba-e5c6a3e36147103e87d1c55173f4b54ba6134904.zip
r10683: Samba3's wbinfo -t should give the correct answer now.
Tridge, if you have time, you might want to look at the segfault I was still seeing. Now I store the handle to the netlogon pipe in the global winbind state and free it on the next entry into check_machacc. The problem seems to be that talloc_free()ing a pipe struct from within a callback function on that pipe is not possible. I think I can live with that, but it has been not really obvious. To reproduce the segfault you might want to look at putting a talloc_free(state->getcreds->out.netlogon) into wbsrv_samba3_check_machacc_receive_creds. This is called from a dcerpc callback function. In particular if the check failed it would be nice if I could delete the pipe directly and not post a different event to some winbind queue. I tried to delete the pipe from a timed event triggered immediately, but this also fails because the inner loop seems to hit the same event again, calling it twice. Volker (This used to be commit 5436d7764812bb632ba865e633005ed07923b57f)
Diffstat (limited to 'source4/winbind/wb_samba3_cmd.c')
-rw-r--r--source4/winbind/wb_samba3_cmd.c177
1 files changed, 129 insertions, 48 deletions
diff --git a/source4/winbind/wb_samba3_cmd.c b/source4/winbind/wb_samba3_cmd.c
index 7b3cd79cf4..570a166532 100644
--- a/source4/winbind/wb_samba3_cmd.c
+++ b/source4/winbind/wb_samba3_cmd.c
@@ -32,6 +32,8 @@
#include "libcli/composite/composite.h"
#include "libcli/smb_composite/smb_composite.h"
#include "include/version.h"
+#include "librpc/rpc/dcerpc_composite.h"
+#include "lib/events/events.h"
NTSTATUS wbsrv_samba3_interface_version(struct wbsrv_samba3_call *s3call)
{
@@ -77,46 +79,53 @@ NTSTATUS wbsrv_samba3_ping(struct wbsrv_samba3_call *s3call)
return NT_STATUS_OK;
}
+#define null_no_memory_done(x) do { \
+ if ((x) == NULL) { status = NT_STATUS_NO_MEMORY; goto done; } \
+ } while (0)
+
struct check_machacc_state {
struct wb_finddcs *io;
struct smb_composite_connect *conn;
+ struct wb_get_schannel_creds *getcreds;
};
-static void wbsrv_samba3_check_machacc_receive_tree(struct composite_context *action)
+static void wbsrv_samba3_check_machacc_receive_creds(struct composite_context *action);
+static void wbsrv_samba3_check_machacc_receive_tree(struct composite_context *action);
+static void wbsrv_samba3_check_machacc_receive_dcs(struct composite_context *action);
+
+NTSTATUS wbsrv_samba3_check_machacc(struct wbsrv_samba3_call *s3call)
{
- struct wbsrv_samba3_call *s3call =
- talloc_get_type(action->async.private_data,
- struct wbsrv_samba3_call);
- struct check_machacc_state *state =
- talloc_get_type(s3call->private_data,
- struct check_machacc_state);
- NTSTATUS status;
+ struct composite_context *resolve_req;
+ struct check_machacc_state *state;
+ struct wbsrv_service *service =
+ s3call->call->wbconn->listen_socket->service;
- status = smb_composite_connect_recv(action, state);
- WBSRV_SAMBA3_SET_STRING(s3call->response.data.auth.nt_status_string,
- nt_errstr(status));
- WBSRV_SAMBA3_SET_STRING(s3call->response.data.auth.error_string,
- nt_errstr(status));
- s3call->response.data.auth.pam_error = nt_status_to_pam(status);
+ DEBUG(5, ("check_machacc called\n"));
- if (!NT_STATUS_IS_OK(status)) {
- DEBUG(5, ("Connect failed: %s\n", nt_errstr(status)));
- goto done;
+ if (service->netlogon != NULL) {
+ talloc_free(service->netlogon);
}
- s3call->response.result = WINBINDD_OK;
-
- done:
- if (!NT_STATUS_IS_OK(status)) {
- s3call->response.result = WINBINDD_ERROR;
- }
+ state = talloc(s3call, struct check_machacc_state);
+ NT_STATUS_HAVE_NO_MEMORY(state);
- status = wbsrv_send_reply(s3call->call);
- if (!NT_STATUS_IS_OK(status)) {
- wbsrv_terminate_connection(s3call->call->wbconn,
- "wbsrv_queue_reply() failed");
- return;
- }
+ state->io = talloc(s3call, struct wb_finddcs);
+ NT_STATUS_HAVE_NO_MEMORY(state->io);
+ s3call->private_data = state;
+
+ state->io->in.msg_ctx = s3call->call->wbconn->conn->msg_ctx;
+ state->io->in.domain = lp_workgroup();
+
+ resolve_req = wb_finddcs_send(state->io, s3call->call->event_ctx);
+ NT_STATUS_HAVE_NO_MEMORY(resolve_req);
+
+ /* setup the callbacks */
+ resolve_req->async.fn = wbsrv_samba3_check_machacc_receive_dcs;
+ resolve_req->async.private_data = s3call;
+
+ /* tell the caller we reply later */
+ s3call->call->flags |= WBSRV_CALL_FLAGS_REPLY_ASYNC;
+ return NT_STATUS_OK;
}
static void wbsrv_samba3_check_machacc_receive_dcs(struct composite_context *action)
@@ -188,31 +197,103 @@ static void wbsrv_samba3_check_machacc_receive_dcs(struct composite_context *act
}
}
-NTSTATUS wbsrv_samba3_check_machacc(struct wbsrv_samba3_call *s3call)
+static void wbsrv_samba3_check_machacc_receive_tree(struct composite_context *action)
{
- struct composite_context *resolve_req;
- struct check_machacc_state *state;
+ struct wbsrv_samba3_call *s3call =
+ talloc_get_type(action->async.private_data,
+ struct wbsrv_samba3_call);
+ struct check_machacc_state *state =
+ talloc_get_type(s3call->private_data,
+ struct check_machacc_state);
+ struct composite_context *ctx;
+ NTSTATUS status;
+ struct cli_credentials *creds;
- DEBUG(5, ("check_machacc called\n"));
+ status = smb_composite_connect_recv(action, state);
+ if (!NT_STATUS_IS_OK(status)) {
+ DEBUG(5, ("Connect failed: %s\n", nt_errstr(status)));
+ goto done;
+ }
- state = talloc(s3call, struct check_machacc_state);
- NT_STATUS_HAVE_NO_MEMORY(state);
+ state->getcreds = talloc(state, struct wb_get_schannel_creds);
+ null_no_memory_done(state->getcreds);
- state->io = talloc(s3call, struct wb_finddcs);
- NT_STATUS_HAVE_NO_MEMORY(state->io);
- s3call->private_data = state;
+ creds = cli_credentials_init(state);
+ null_no_memory_done(creds);
+ cli_credentials_set_conf(creds);
+ status = cli_credentials_set_machine_account(creds);
+ if (!NT_STATUS_IS_OK(status)) goto done;
- state->io->in.msg_ctx = s3call->call->wbconn->conn->msg_ctx;
- state->io->in.domain = lp_workgroup();
+ state->getcreds->in.tree = state->conn->out.tree;
+ state->getcreds->in.creds = creds;
- resolve_req = wb_finddcs_send(state->io, s3call->call->event_ctx);
- NT_STATUS_HAVE_NO_MEMORY(resolve_req);
+ ctx = wb_get_schannel_creds_send(state->getcreds,
+ s3call->call->event_ctx);
+ null_no_memory_done(ctx);
- /* setup the callbacks */
- resolve_req->async.fn = wbsrv_samba3_check_machacc_receive_dcs;
- resolve_req->async.private_data = s3call;
+ ctx->async.fn = wbsrv_samba3_check_machacc_receive_creds;
+ ctx->async.private_data = s3call;
- /* tell the caller we reply later */
- s3call->call->flags |= WBSRV_CALL_FLAGS_REPLY_ASYNC;
- return NT_STATUS_OK;
+ return;
+
+ done:
+ s3call->response.result = WINBINDD_OK;
+
+ if (!NT_STATUS_IS_OK(status)) {
+ s3call->response.result = WINBINDD_ERROR;
+ WBSRV_SAMBA3_SET_STRING(s3call->response.data.auth.nt_status_string,
+ nt_errstr(status));
+ WBSRV_SAMBA3_SET_STRING(s3call->response.data.auth.error_string,
+ nt_errstr(status));
+ s3call->response.data.auth.pam_error = nt_status_to_pam(status);
+
+ }
+
+ status = wbsrv_send_reply(s3call->call);
+ if (!NT_STATUS_IS_OK(status)) {
+ wbsrv_terminate_connection(s3call->call->wbconn,
+ "wbsrv_queue_reply() failed");
+ return;
+ }
+}
+
+static void wbsrv_samba3_check_machacc_receive_creds(struct composite_context *action)
+{
+ struct wbsrv_samba3_call *s3call =
+ talloc_get_type(action->async.private_data,
+ struct wbsrv_samba3_call);
+ struct check_machacc_state *state =
+ talloc_get_type(s3call->private_data,
+ struct check_machacc_state);
+ struct wbsrv_service *service =
+ s3call->call->wbconn->listen_socket->service;
+
+ NTSTATUS status;
+
+ status = wb_get_schannel_creds_recv(action, service);
+ service->netlogon = state->getcreds->out.netlogon;
+
+ talloc_unlink(state, state->conn->out.tree); /* The pipe owns it now */
+ state->conn->out.tree = NULL;
+
+ if (!NT_STATUS_IS_OK(status)) goto done;
+
+ s3call->response.result = WINBINDD_OK;
+ done:
+ if (!NT_STATUS_IS_OK(status)) {
+ s3call->response.result = WINBINDD_ERROR;
+ WBSRV_SAMBA3_SET_STRING(s3call->response.data.auth.nt_status_string,
+ nt_errstr(status));
+ WBSRV_SAMBA3_SET_STRING(s3call->response.data.auth.error_string,
+ nt_errstr(status));
+ s3call->response.data.auth.pam_error = nt_status_to_pam(status);
+
+ }
+
+ status = wbsrv_send_reply(s3call->call);
+ if (!NT_STATUS_IS_OK(status)) {
+ wbsrv_terminate_connection(s3call->call->wbconn,
+ "wbsrv_queue_reply() failed");
+ return;
+ }
}