provision: BIND 9.15.x is not supported
[samba.git] / source4 / ntp_signd / ntp_signd.c
blob44096f71f494b73eed4dbc7ca92c4c356730040f
1 /*
2 Unix SMB/CIFS implementation.
4 NTP packet signing server
6 Copyright (C) Andrew Bartlett <abartlet@samba.org> 2005
7 Copyright (C) Andrew Tridgell 2005
8 Copyright (C) Stefan Metzmacher 2005
10 This program is free software; you can redistribute it and/or modify
11 it under the terms of the GNU General Public License as published by
12 the Free Software Foundation; either version 3 of the License, or
13 (at your option) any later version.
15 This program is distributed in the hope that it will be useful,
16 but WITHOUT ANY WARRANTY; without even the implied warranty of
17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 GNU General Public License for more details.
20 You should have received a copy of the GNU General Public License
21 along with this program. If not, see <http://www.gnu.org/licenses/>.
24 #include "includes.h"
25 #include "smbd/service_task.h"
26 #include "smbd/service.h"
27 #include "smbd/service_stream.h"
28 #include "smbd/process_model.h"
29 #include "lib/stream/packet.h"
30 #include "lib/tsocket/tsocket.h"
31 #include "libcli/util/tstream.h"
32 #include "librpc/gen_ndr/ndr_ntp_signd.h"
33 #include "param/param.h"
34 #include "dsdb/samdb/samdb.h"
35 #include "auth/auth.h"
36 #include "libcli/security/security.h"
37 #include "libcli/ldap/ldap_ndr.h"
38 #include <ldb.h>
39 #include <ldb_errors.h>
40 #include "system/network.h"
41 #include "system/passwd.h"
43 #include "lib/crypto/gnutls_helpers.h"
44 #include <gnutls/gnutls.h>
45 #include <gnutls/crypto.h>
47 NTSTATUS server_service_ntp_signd_init(TALLOC_CTX *);
50 top level context structure for the ntp_signd server
52 struct ntp_signd_server {
53 struct task_server *task;
54 struct ldb_context *samdb;
58 state of an open connection
60 struct ntp_signd_connection {
61 /* stream connection we belong to */
62 struct stream_connection *conn;
64 /* the ntp_signd_server the connection belongs to */
65 struct ntp_signd_server *ntp_signd;
67 struct tstream_context *tstream;
69 struct tevent_queue *send_queue;
72 static void ntp_signd_terminate_connection(struct ntp_signd_connection *ntp_signd_conn, const char *reason)
74 stream_terminate_connection(ntp_signd_conn->conn, reason);
77 static NTSTATUS signing_failure(struct ntp_signd_connection *ntp_signdconn,
78 TALLOC_CTX *mem_ctx,
79 DATA_BLOB *output,
80 uint32_t packet_id)
82 struct signed_reply signed_reply;
83 enum ndr_err_code ndr_err;
85 signed_reply.op = SIGNING_FAILURE;
86 signed_reply.packet_id = packet_id;
87 signed_reply.signed_packet = data_blob(NULL, 0);
89 ndr_err = ndr_push_struct_blob(output, mem_ctx, &signed_reply,
90 (ndr_push_flags_fn_t)ndr_push_signed_reply);
92 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
93 DEBUG(1,("failed to push ntp error reply\n"));
94 return ndr_map_error2ntstatus(ndr_err);
97 return NT_STATUS_OK;
101 receive a full packet on a NTP_SIGND connection
103 static NTSTATUS ntp_signd_process(struct ntp_signd_connection *ntp_signd_conn,
104 TALLOC_CTX *mem_ctx,
105 DATA_BLOB *input,
106 DATA_BLOB *output)
108 const struct dom_sid *domain_sid;
109 struct dom_sid *sid;
110 struct sign_request sign_request;
111 struct signed_reply signed_reply;
112 enum ndr_err_code ndr_err;
113 struct ldb_result *res;
114 const char *attrs[] = { "unicodePwd", "userAccountControl", "cn", NULL };
115 gnutls_hash_hd_t hash_hnd = NULL;
116 struct samr_Password *nt_hash;
117 uint32_t user_account_control;
118 struct dom_sid_buf buf;
119 int ret;
121 ndr_err = ndr_pull_struct_blob_all(input, mem_ctx,
122 &sign_request,
123 (ndr_pull_flags_fn_t)ndr_pull_sign_request);
125 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
126 DEBUG(1,("failed to parse ntp signing request\n"));
127 dump_data(1, input->data, input->length);
128 return ndr_map_error2ntstatus(ndr_err);
131 /* We need to implement 'check signature' and 'request server
132 * to sign' operations at some point */
133 if (sign_request.op != SIGN_TO_CLIENT) {
134 return signing_failure(ntp_signd_conn,
135 mem_ctx,
136 output,
137 sign_request.packet_id);
140 /* We need to implement 'check signature' and 'request server
141 * to sign' operations at some point */
142 if (sign_request.version != NTP_SIGND_PROTOCOL_VERSION_0) {
143 return signing_failure(ntp_signd_conn,
144 mem_ctx,
145 output,
146 sign_request.packet_id);
149 domain_sid = samdb_domain_sid(ntp_signd_conn->ntp_signd->samdb);
150 if (domain_sid == NULL) {
151 return signing_failure(ntp_signd_conn,
152 mem_ctx,
153 output,
154 sign_request.packet_id);
157 /* The top bit is a 'key selector' */
158 sid = dom_sid_add_rid(mem_ctx, domain_sid,
159 sign_request.key_id & 0x7FFFFFFF);
160 if (sid == NULL) {
161 talloc_free(mem_ctx);
162 return signing_failure(ntp_signd_conn,
163 mem_ctx,
164 output,
165 sign_request.packet_id);
168 ret = ldb_search(ntp_signd_conn->ntp_signd->samdb, mem_ctx,
169 &res,
170 ldb_get_default_basedn(ntp_signd_conn->ntp_signd->samdb),
171 LDB_SCOPE_SUBTREE,
172 attrs,
173 "(&(objectSid=%s)(objectClass=user))",
174 ldap_encode_ndr_dom_sid(mem_ctx, sid));
175 if (ret != LDB_SUCCESS) {
176 DEBUG(2, ("Failed to search for SID %s in SAM for NTP signing: "
177 "%s\n",
178 dom_sid_str_buf(sid, &buf),
179 ldb_errstring(ntp_signd_conn->ntp_signd->samdb)));
180 return signing_failure(ntp_signd_conn,
181 mem_ctx,
182 output,
183 sign_request.packet_id);
186 if (res->count == 0) {
187 DEBUG(2, ("Failed to find SID %s in SAM for NTP signing\n",
188 dom_sid_str_buf(sid, &buf)));
189 return signing_failure(ntp_signd_conn,
190 mem_ctx,
191 output,
192 sign_request.packet_id);
193 } else if (res->count != 1) {
194 DEBUG(1, ("Found SID %s %u times in SAM for NTP signing\n",
195 dom_sid_str_buf(sid, &buf),
196 res->count));
197 return signing_failure(ntp_signd_conn,
198 mem_ctx,
199 output,
200 sign_request.packet_id);
203 user_account_control = ldb_msg_find_attr_as_uint(res->msgs[0],
204 "userAccountControl",
207 if (user_account_control & UF_ACCOUNTDISABLE) {
208 DEBUG(1, ("Account %s for SID [%s] is disabled\n",
209 ldb_dn_get_linearized(res->msgs[0]->dn),
210 dom_sid_str_buf(sid, &buf)));
211 return NT_STATUS_ACCESS_DENIED;
214 if (!(user_account_control & (UF_INTERDOMAIN_TRUST_ACCOUNT|UF_SERVER_TRUST_ACCOUNT|UF_WORKSTATION_TRUST_ACCOUNT))) {
215 DEBUG(1, ("Account %s for SID [%s] is not a trust account\n",
216 ldb_dn_get_linearized(res->msgs[0]->dn),
217 dom_sid_str_buf(sid, &buf)));
218 return NT_STATUS_ACCESS_DENIED;
221 nt_hash = samdb_result_hash(mem_ctx, res->msgs[0], "unicodePwd");
222 if (!nt_hash) {
223 DEBUG(1, ("No unicodePwd found on record of SID %s "
224 "for NTP signing\n",
225 dom_sid_str_buf(sid, &buf)));
226 return signing_failure(ntp_signd_conn,
227 mem_ctx,
228 output,
229 sign_request.packet_id);
232 /* Generate the reply packet */
233 signed_reply.packet_id = sign_request.packet_id;
234 signed_reply.op = SIGNING_SUCCESS;
235 signed_reply.signed_packet = data_blob_talloc(mem_ctx,
236 NULL,
237 sign_request.packet_to_sign.length + 20);
239 if (!signed_reply.signed_packet.data) {
240 return signing_failure(ntp_signd_conn,
241 mem_ctx,
242 output,
243 sign_request.packet_id);
246 memcpy(signed_reply.signed_packet.data, sign_request.packet_to_sign.data, sign_request.packet_to_sign.length);
247 SIVAL(signed_reply.signed_packet.data, sign_request.packet_to_sign.length, sign_request.key_id);
249 /* Sign the NTP response with the unicodePwd */
250 ret = gnutls_hash_init(&hash_hnd, GNUTLS_DIG_MD5);
251 if (ret < 0) {
252 return gnutls_error_to_ntstatus(ret, NT_STATUS_HASH_NOT_SUPPORTED);
255 ret = gnutls_hash(hash_hnd,
256 nt_hash->hash,
257 sizeof(nt_hash->hash));
258 if (ret < 0) {
259 gnutls_hash_deinit(hash_hnd, NULL);
260 return gnutls_error_to_ntstatus(ret, NT_STATUS_HASH_NOT_SUPPORTED);
262 ret = gnutls_hash(hash_hnd,
263 sign_request.packet_to_sign.data,
264 sign_request.packet_to_sign.length);
265 if (ret < 0) {
266 gnutls_hash_deinit(hash_hnd, NULL);
267 return gnutls_error_to_ntstatus(ret, NT_STATUS_HASH_NOT_SUPPORTED);
270 gnutls_hash_deinit(hash_hnd,
271 signed_reply.signed_packet.data +
272 sign_request.packet_to_sign.length + 4);
274 /* Place it into the packet for the wire */
275 ndr_err = ndr_push_struct_blob(output, mem_ctx, &signed_reply,
276 (ndr_push_flags_fn_t)ndr_push_signed_reply);
278 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
279 DEBUG(1,("failed to push ntp error reply\n"));
280 return ndr_map_error2ntstatus(ndr_err);
283 return NT_STATUS_OK;
287 called on a tcp recv
289 static void ntp_signd_recv(struct stream_connection *conn, uint16_t flags)
291 struct ntp_signd_connection *ntp_signd_conn = talloc_get_type(conn->private_data,
292 struct ntp_signd_connection);
293 ntp_signd_terminate_connection(ntp_signd_conn,
294 "ntp_signd_recv: called");
298 called when we can write to a connection
300 static void ntp_signd_send(struct stream_connection *conn, uint16_t flags)
302 struct ntp_signd_connection *ntp_signd_conn = talloc_get_type(conn->private_data,
303 struct ntp_signd_connection);
304 /* this should never be triggered! */
305 ntp_signd_terminate_connection(ntp_signd_conn,
306 "ntp_signd_send: called");
309 struct ntp_signd_call {
310 struct ntp_signd_connection *ntp_signd_conn;
311 DATA_BLOB in;
312 DATA_BLOB out;
313 uint8_t out_hdr[4];
314 struct iovec out_iov[2];
317 static void ntp_signd_call_writev_done(struct tevent_req *subreq);
319 static void ntp_signd_call_loop(struct tevent_req *subreq)
321 struct ntp_signd_connection *ntp_signd_conn = tevent_req_callback_data(subreq,
322 struct ntp_signd_connection);
323 struct ntp_signd_call *call;
324 NTSTATUS status;
326 call = talloc(ntp_signd_conn, struct ntp_signd_call);
327 if (call == NULL) {
328 ntp_signd_terminate_connection(ntp_signd_conn,
329 "ntp_signd_call_loop: "
330 "no memory for ntp_signd_call");
331 return;
333 call->ntp_signd_conn = ntp_signd_conn;
335 status = tstream_read_pdu_blob_recv(subreq,
336 call,
337 &call->in);
338 TALLOC_FREE(subreq);
339 if (!NT_STATUS_IS_OK(status)) {
340 const char *reason;
342 reason = talloc_asprintf(call, "ntp_signd_call_loop: "
343 "tstream_read_pdu_blob_recv() - %s",
344 nt_errstr(status));
345 if (reason == NULL) {
346 reason = nt_errstr(status);
349 ntp_signd_terminate_connection(ntp_signd_conn, reason);
350 return;
353 DEBUG(10,("Received NTP TCP packet of length %lu from %s\n",
354 (long) call->in.length,
355 tsocket_address_string(ntp_signd_conn->conn->remote_address, call)));
357 /* skip length header */
358 call->in.data +=4;
359 call->in.length -= 4;
361 status = ntp_signd_process(ntp_signd_conn,
362 call,
363 &call->in,
364 &call->out);
365 if (! NT_STATUS_IS_OK(status)) {
366 const char *reason;
368 reason = talloc_asprintf(call, "ntp_signd_process failed: %s",
369 nt_errstr(status));
370 if (reason == NULL) {
371 reason = nt_errstr(status);
374 ntp_signd_terminate_connection(ntp_signd_conn, reason);
375 return;
378 /* First add the length of the out buffer */
379 RSIVAL(call->out_hdr, 0, call->out.length);
380 call->out_iov[0].iov_base = (char *) call->out_hdr;
381 call->out_iov[0].iov_len = 4;
383 call->out_iov[1].iov_base = (char *) call->out.data;
384 call->out_iov[1].iov_len = call->out.length;
386 subreq = tstream_writev_queue_send(call,
387 ntp_signd_conn->conn->event.ctx,
388 ntp_signd_conn->tstream,
389 ntp_signd_conn->send_queue,
390 call->out_iov, 2);
391 if (subreq == NULL) {
392 ntp_signd_terminate_connection(ntp_signd_conn, "ntp_signd_call_loop: "
393 "no memory for tstream_writev_queue_send");
394 return;
397 tevent_req_set_callback(subreq, ntp_signd_call_writev_done, call);
400 * The NTP tcp pdu's has the length as 4 byte (initial_read_size),
401 * packet_full_request_u32 provides the pdu length then.
403 subreq = tstream_read_pdu_blob_send(ntp_signd_conn,
404 ntp_signd_conn->conn->event.ctx,
405 ntp_signd_conn->tstream,
406 4, /* initial_read_size */
407 packet_full_request_u32,
408 ntp_signd_conn);
409 if (subreq == NULL) {
410 ntp_signd_terminate_connection(ntp_signd_conn, "ntp_signd_call_loop: "
411 "no memory for tstream_read_pdu_blob_send");
412 return;
414 tevent_req_set_callback(subreq, ntp_signd_call_loop, ntp_signd_conn);
417 static void ntp_signd_call_writev_done(struct tevent_req *subreq)
419 struct ntp_signd_call *call = tevent_req_callback_data(subreq,
420 struct ntp_signd_call);
421 int sys_errno;
422 int rc;
424 rc = tstream_writev_queue_recv(subreq, &sys_errno);
425 TALLOC_FREE(subreq);
426 if (rc == -1) {
427 const char *reason;
429 reason = talloc_asprintf(call, "ntp_signd_call_writev_done: "
430 "tstream_writev_queue_recv() - %d:%s",
431 sys_errno, strerror(sys_errno));
432 if (!reason) {
433 reason = "ntp_signd_call_writev_done: "
434 "tstream_writev_queue_recv() failed";
437 ntp_signd_terminate_connection(call->ntp_signd_conn, reason);
438 return;
441 /* We don't care about errors */
443 talloc_free(call);
447 called when we get a new connection
449 static void ntp_signd_accept(struct stream_connection *conn)
451 struct ntp_signd_server *ntp_signd = talloc_get_type(conn->private_data,
452 struct ntp_signd_server);
453 struct ntp_signd_connection *ntp_signd_conn;
454 struct tevent_req *subreq;
455 int rc;
457 ntp_signd_conn = talloc_zero(conn, struct ntp_signd_connection);
458 if (ntp_signd_conn == NULL) {
459 stream_terminate_connection(conn,
460 "ntp_signd_accept: out of memory");
461 return;
464 ntp_signd_conn->send_queue = tevent_queue_create(conn,
465 "ntp_signd_accept");
466 if (ntp_signd_conn->send_queue == NULL) {
467 stream_terminate_connection(conn,
468 "ntp_signd_accept: out of memory");
469 return;
472 TALLOC_FREE(conn->event.fde);
474 rc = tstream_bsd_existing_socket(ntp_signd_conn,
475 socket_get_fd(conn->socket),
476 &ntp_signd_conn->tstream);
477 if (rc < 0) {
478 stream_terminate_connection(conn,
479 "ntp_signd_accept: out of memory");
480 return;
483 ntp_signd_conn->conn = conn;
484 ntp_signd_conn->ntp_signd = ntp_signd;
485 conn->private_data = ntp_signd_conn;
488 * The NTP tcp pdu's has the length as 4 byte (initial_read_size),
489 * packet_full_request_u32 provides the pdu length then.
491 subreq = tstream_read_pdu_blob_send(ntp_signd_conn,
492 ntp_signd_conn->conn->event.ctx,
493 ntp_signd_conn->tstream,
494 4, /* initial_read_size */
495 packet_full_request_u32,
496 ntp_signd_conn);
497 if (subreq == NULL) {
498 ntp_signd_terminate_connection(ntp_signd_conn,
499 "ntp_signd_accept: "
500 "no memory for tstream_read_pdu_blob_send");
501 return;
503 tevent_req_set_callback(subreq, ntp_signd_call_loop, ntp_signd_conn);
506 static const struct stream_server_ops ntp_signd_stream_ops = {
507 .name = "ntp_signd",
508 .accept_connection = ntp_signd_accept,
509 .recv_handler = ntp_signd_recv,
510 .send_handler = ntp_signd_send
514 startup the ntp_signd task
516 static NTSTATUS ntp_signd_task_init(struct task_server *task)
518 struct ntp_signd_server *ntp_signd;
519 NTSTATUS status;
521 const char *address;
523 if (!directory_create_or_exist_strict(lpcfg_ntp_signd_socket_directory(task->lp_ctx), geteuid(), 0750)) {
524 char *error = talloc_asprintf(task, "Cannot create NTP signd pipe directory: %s",
525 lpcfg_ntp_signd_socket_directory(task->lp_ctx));
526 task_server_terminate(task,
527 error, true);
528 return NT_STATUS_UNSUCCESSFUL;
531 task_server_set_title(task, "task[ntp_signd]");
533 ntp_signd = talloc(task, struct ntp_signd_server);
534 if (ntp_signd == NULL) {
535 task_server_terminate(task, "ntp_signd: out of memory", true);
536 return NT_STATUS_NO_MEMORY;
539 ntp_signd->task = task;
541 /* Must be system to get at the password hashes */
542 ntp_signd->samdb = samdb_connect(ntp_signd,
543 task->event_ctx,
544 task->lp_ctx,
545 system_session(task->lp_ctx),
546 NULL,
548 if (ntp_signd->samdb == NULL) {
549 task_server_terminate(task, "ntp_signd failed to open samdb", true);
550 return NT_STATUS_UNSUCCESSFUL;
553 address = talloc_asprintf(ntp_signd, "%s/socket", lpcfg_ntp_signd_socket_directory(task->lp_ctx));
554 if (address == NULL) {
555 task_server_terminate(
556 task, "ntp_signd out of memory in talloc_asprintf()", true);
557 return NT_STATUS_NO_MEMORY;
560 status = stream_setup_socket(ntp_signd->task,
561 ntp_signd->task->event_ctx,
562 ntp_signd->task->lp_ctx,
563 task->model_ops,
564 &ntp_signd_stream_ops,
565 "unix", address, NULL,
566 lpcfg_socket_options(ntp_signd->task->lp_ctx),
567 ntp_signd,
568 ntp_signd->task->process_context);
569 if (!NT_STATUS_IS_OK(status)) {
570 DEBUG(0,("Failed to bind to %s - %s\n",
571 address, nt_errstr(status)));
572 return status;
575 return NT_STATUS_OK;
580 /* called at smbd startup - register ourselves as a server service */
581 NTSTATUS server_service_ntp_signd_init(TALLOC_CTX *ctx)
583 static const struct service_details details = {
584 .inhibit_fork_on_accept = true,
585 .inhibit_pre_fork = true,
586 .task_init = ntp_signd_task_init,
587 .post_fork = NULL
589 return register_server_service(ctx, "ntp_signd", &details);