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/>.
25 #include "samba/service_task.h"
26 #include "samba/service.h"
27 #include "samba/service_stream.h"
28 #include "samba/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"
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
,
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
);
101 receive a full packet on a NTP_SIGND connection
103 static NTSTATUS
ntp_signd_process(struct ntp_signd_connection
*ntp_signd_conn
,
108 const struct dom_sid
*domain_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
;
121 ndr_err
= ndr_pull_struct_blob_all(input
, mem_ctx
,
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
,
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
,
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
,
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);
161 talloc_free(mem_ctx
);
162 return signing_failure(ntp_signd_conn
,
165 sign_request
.packet_id
);
168 ret
= ldb_search(ntp_signd_conn
->ntp_signd
->samdb
, mem_ctx
,
170 ldb_get_default_basedn(ntp_signd_conn
->ntp_signd
->samdb
),
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: "
178 dom_sid_str_buf(sid
, &buf
),
179 ldb_errstring(ntp_signd_conn
->ntp_signd
->samdb
)));
180 return signing_failure(ntp_signd_conn
,
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
,
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
),
197 return signing_failure(ntp_signd_conn
,
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");
223 DEBUG(1, ("No unicodePwd found on record of SID %s "
225 dom_sid_str_buf(sid
, &buf
)));
226 return signing_failure(ntp_signd_conn
,
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
,
237 sign_request
.packet_to_sign
.length
+ 20);
239 if (!signed_reply
.signed_packet
.data
) {
240 return signing_failure(ntp_signd_conn
,
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
);
252 return gnutls_error_to_ntstatus(ret
, NT_STATUS_HASH_NOT_SUPPORTED
);
255 ret
= gnutls_hash(hash_hnd
,
257 sizeof(nt_hash
->hash
));
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
);
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
);
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
;
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
;
326 call
= talloc(ntp_signd_conn
, struct ntp_signd_call
);
328 ntp_signd_terminate_connection(ntp_signd_conn
,
329 "ntp_signd_call_loop: "
330 "no memory for ntp_signd_call");
333 call
->ntp_signd_conn
= ntp_signd_conn
;
335 status
= tstream_read_pdu_blob_recv(subreq
,
339 if (!NT_STATUS_IS_OK(status
)) {
342 reason
= talloc_asprintf(call
, "ntp_signd_call_loop: "
343 "tstream_read_pdu_blob_recv() - %s",
345 if (reason
== NULL
) {
346 reason
= nt_errstr(status
);
349 ntp_signd_terminate_connection(ntp_signd_conn
, reason
);
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 */
359 call
->in
.length
-= 4;
361 status
= ntp_signd_process(ntp_signd_conn
,
365 if (! NT_STATUS_IS_OK(status
)) {
368 reason
= talloc_asprintf(call
, "ntp_signd_process failed: %s",
370 if (reason
== NULL
) {
371 reason
= nt_errstr(status
);
374 ntp_signd_terminate_connection(ntp_signd_conn
, reason
);
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
,
391 if (subreq
== NULL
) {
392 ntp_signd_terminate_connection(ntp_signd_conn
, "ntp_signd_call_loop: "
393 "no memory for tstream_writev_queue_send");
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
,
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");
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
);
424 rc
= tstream_writev_queue_recv(subreq
, &sys_errno
);
429 reason
= talloc_asprintf(call
, "ntp_signd_call_writev_done: "
430 "tstream_writev_queue_recv() - %d:%s",
431 sys_errno
, strerror(sys_errno
));
433 reason
= "ntp_signd_call_writev_done: "
434 "tstream_writev_queue_recv() failed";
437 ntp_signd_terminate_connection(call
->ntp_signd_conn
, reason
);
441 /* We don't care about errors */
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
;
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");
464 ntp_signd_conn
->send_queue
= tevent_queue_create(conn
,
466 if (ntp_signd_conn
->send_queue
== NULL
) {
467 stream_terminate_connection(conn
,
468 "ntp_signd_accept: out of memory");
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
);
478 stream_terminate_connection(conn
,
479 "ntp_signd_accept: out of memory");
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
,
497 if (subreq
== NULL
) {
498 ntp_signd_terminate_connection(ntp_signd_conn
,
500 "no memory for tstream_read_pdu_blob_send");
503 tevent_req_set_callback(subreq
, ntp_signd_call_loop
, ntp_signd_conn
);
506 static const struct stream_server_ops ntp_signd_stream_ops
= {
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
;
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
,
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
,
545 system_session(task
->lp_ctx
),
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
,
564 &ntp_signd_stream_ops
,
565 "unix", address
, NULL
,
566 lpcfg_socket_options(ntp_signd
->task
->lp_ctx
),
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
)));
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
,
589 return register_server_service(ctx
, "ntp_signd", &details
);