summaryrefslogtreecommitdiff
path: root/source4/nbt_server/nbt_server.c
diff options
context:
space:
mode:
Diffstat (limited to 'source4/nbt_server/nbt_server.c')
-rw-r--r--source4/nbt_server/nbt_server.c119
1 files changed, 119 insertions, 0 deletions
diff --git a/source4/nbt_server/nbt_server.c b/source4/nbt_server/nbt_server.c
index 2119610988..83a7ae8a2f 100644
--- a/source4/nbt_server/nbt_server.c
+++ b/source4/nbt_server/nbt_server.c
@@ -43,6 +43,116 @@ static NTSTATUS nbtd_information(struct irpc_message *msg,
return NT_STATUS_OK;
}
+struct getdc_state {
+ struct irpc_message *msg;
+ struct nbtd_getdcname *req;
+};
+
+static void getdc_recv_ntlogon_reply(struct dgram_mailslot_handler *dgmslot,
+ struct nbt_dgram_packet *packet,
+ const char *src_address, int src_port)
+{
+ struct getdc_state *s =
+ talloc_get_type(dgmslot->private, struct getdc_state);
+
+ struct nbt_ntlogon_packet ntlogon;
+ NTSTATUS status;
+
+ status = dgram_mailslot_ntlogon_parse(dgmslot, packet, packet,
+ &ntlogon);
+ if (!NT_STATUS_IS_OK(status)) {
+ DEBUG(5, ("dgram_mailslot_ntlogon_parse failed: %s\n",
+ nt_errstr(status)));
+ goto done;
+ }
+
+ status = NT_STATUS_NO_LOGON_SERVERS;
+
+ DEBUG(10, ("reply: command=%d\n", ntlogon.command));
+
+ switch (ntlogon.command) {
+ case NTLOGON_SAM_LOGON:
+ DEBUG(0, ("Huh -- got NTLOGON_SAM_LOGON as reply\n"));
+ break;
+ case NTLOGON_SAM_LOGON_REPLY:
+ DEBUG(10, ("NTLOGON_SAM_LOGON_REPLY: server: %s, user: %s, "
+ "domain: %s\n", ntlogon.req.reply.server,
+ ntlogon.req.reply.user_name,
+ ntlogon.req.reply.domain));
+ s->req->out.dcname =
+ talloc_strdup(s->req, ntlogon.req.reply.server);
+ if (s->req->out.dcname == NULL) {
+ DEBUG(0, ("talloc failed\n"));
+ status = NT_STATUS_NO_MEMORY;
+ goto done;
+ }
+ status = NT_STATUS_OK;
+ break;
+ default:
+ DEBUG(0, ("Got unknown packet: %d\n", ntlogon.command));
+ break;
+ }
+
+ done:
+ irpc_send_reply(s->msg, status);
+}
+
+static NTSTATUS nbtd_getdcname(struct irpc_message *msg,
+ struct nbtd_getdcname *req)
+{
+ struct nbtd_server *server =
+ talloc_get_type(msg->private, struct nbtd_server);
+
+ struct getdc_state *s;
+ struct nbt_ntlogon_packet p;
+ struct nbt_ntlogon_sam_logon *r;
+ struct nbt_dgram_socket *sock;
+ struct nbt_name src, dst;
+ struct dgram_mailslot_handler *handler;
+ NTSTATUS status = NT_STATUS_UNSUCCESSFUL;
+
+ DEBUG(0, ("nbtd_getdcname called\n"));
+
+ sock = server->interfaces[0].dgmsock;
+
+ s = talloc(msg, struct getdc_state);
+ NT_STATUS_HAVE_NO_MEMORY(s);
+
+ s->msg = msg;
+ s->req = req;
+
+ handler = dgram_mailslot_temp(sock, NBT_MAILSLOT_GETDC,
+ getdc_recv_ntlogon_reply, s);
+ NT_STATUS_HAVE_NO_MEMORY(handler);
+
+ ZERO_STRUCT(p);
+ p.command = NTLOGON_SAM_LOGON;
+ r = &p.req.logon;
+ r->request_count = 0;
+ r->computer_name = req->in.my_computername;
+ r->user_name = req->in.my_accountname;
+ r->mailslot_name = handler->mailslot_name;
+ r->acct_control = req->in.account_control;
+ r->sid = *req->in.domain_sid;
+ r->nt_version = 1;
+ r->lmnt_token = 0xffff;
+ r->lm20_token = 0xffff;
+
+ make_nbt_name_client(&src, req->in.my_computername);
+ make_nbt_name(&dst, req->in.domainname, 0x1c);
+
+ status = dgram_mailslot_ntlogon_send(sock, DGRAM_DIRECT_GROUP,
+ &dst, req->in.ip_address, 138,
+ &src, &p);
+ if (!NT_STATUS_IS_OK(status)) {
+ DEBUG(0, ("dgram_mailslot_ntlogon_send failed: %s\n",
+ nt_errstr(status)));
+ return status;
+ }
+
+ msg->defer_reply = True;
+ return NT_STATUS_OK;
+}
/*
@@ -91,6 +201,15 @@ static void nbtd_task_init(struct task_server *task)
return;
}
+ /* Setup handler for getdcname call */
+ status = IRPC_REGISTER(task->msg_ctx, irpc, NBTD_GETDCNAME,
+ nbtd_getdcname, nbtsrv);
+ if (!NT_STATUS_IS_OK(status)) {
+ task_server_terminate(task, "nbtd failed to setup getdcname "
+ "handler");
+ return;
+ }
+
/* start the process of registering our names on all interfaces */
nbtd_register_names(nbtsrv);