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/common/util.h"
35 #include "dsdb/samdb/samdb.h"
36 #include "auth/auth.h"
37 #include "libcli/security/security.h"
38 #include "libcli/ldap/ldap_ndr.h"
40 #include <ldb_errors.h>
41 #include "system/network.h"
42 #include "system/passwd.h"
44 #include "lib/crypto/gnutls_helpers.h"
45 #include <gnutls/gnutls.h>
46 #include <gnutls/crypto.h>
48 NTSTATUS
server_service_ntp_signd_init(TALLOC_CTX
*);
51 top level context structure for the ntp_signd server
53 struct ntp_signd_server
{
54 struct task_server
*task
;
55 struct ldb_context
*samdb
;
59 state of an open connection
61 struct ntp_signd_connection
{
62 /* stream connection we belong to */
63 struct stream_connection
*conn
;
65 /* the ntp_signd_server the connection belongs to */
66 struct ntp_signd_server
*ntp_signd
;
68 struct tstream_context
*tstream
;
70 struct tevent_queue
*send_queue
;
73 static void ntp_signd_terminate_connection(struct ntp_signd_connection
*ntp_signd_conn
, const char *reason
)
75 stream_terminate_connection(ntp_signd_conn
->conn
, reason
);
78 static NTSTATUS
signing_failure(struct ntp_signd_connection
*ntp_signdconn
,
83 struct signed_reply signed_reply
;
84 enum ndr_err_code ndr_err
;
86 signed_reply
.op
= SIGNING_FAILURE
;
87 signed_reply
.packet_id
= packet_id
;
88 signed_reply
.signed_packet
= data_blob(NULL
, 0);
90 ndr_err
= ndr_push_struct_blob(output
, mem_ctx
, &signed_reply
,
91 (ndr_push_flags_fn_t
)ndr_push_signed_reply
);
93 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err
)) {
94 DEBUG(1,("failed to push ntp error reply\n"));
95 return ndr_map_error2ntstatus(ndr_err
);
102 receive a full packet on a NTP_SIGND connection
104 static NTSTATUS
ntp_signd_process(struct ntp_signd_connection
*ntp_signd_conn
,
109 const struct dom_sid
*domain_sid
;
111 struct sign_request sign_request
;
112 struct signed_reply signed_reply
;
113 enum ndr_err_code ndr_err
;
114 struct ldb_result
*res
;
115 static const char *attrs
[] = {
117 "userAccountControl",
119 /* Required for Group Managed Service Accounts. */
120 "msDS-ManagedPasswordId",
121 "msDS-ManagedPasswordInterval",
126 gnutls_hash_hd_t hash_hnd
= NULL
;
127 struct samr_Password
*nt_hash
;
128 uint32_t user_account_control
;
129 struct dom_sid_buf buf
;
132 ndr_err
= ndr_pull_struct_blob_all(input
, mem_ctx
,
134 (ndr_pull_flags_fn_t
)ndr_pull_sign_request
);
136 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err
)) {
137 DEBUG(1,("failed to parse ntp signing request\n"));
138 dump_data(1, input
->data
, input
->length
);
139 return ndr_map_error2ntstatus(ndr_err
);
142 /* We need to implement 'check signature' and 'request server
143 * to sign' operations at some point */
144 if (sign_request
.op
!= SIGN_TO_CLIENT
) {
145 return signing_failure(ntp_signd_conn
,
148 sign_request
.packet_id
);
151 /* We need to implement 'check signature' and 'request server
152 * to sign' operations at some point */
153 if (sign_request
.version
!= NTP_SIGND_PROTOCOL_VERSION_0
) {
154 return signing_failure(ntp_signd_conn
,
157 sign_request
.packet_id
);
160 domain_sid
= samdb_domain_sid(ntp_signd_conn
->ntp_signd
->samdb
);
161 if (domain_sid
== NULL
) {
162 return signing_failure(ntp_signd_conn
,
165 sign_request
.packet_id
);
168 /* The top bit is a 'key selector' */
169 sid
= dom_sid_add_rid(mem_ctx
, domain_sid
,
170 sign_request
.key_id
& 0x7FFFFFFF);
172 talloc_free(mem_ctx
);
173 return signing_failure(ntp_signd_conn
,
176 sign_request
.packet_id
);
179 ret
= dsdb_search(ntp_signd_conn
->ntp_signd
->samdb
, mem_ctx
,
181 ldb_get_default_basedn(ntp_signd_conn
->ntp_signd
->samdb
),
184 DSDB_SEARCH_UPDATE_MANAGED_PASSWORDS
,
185 "(&(objectSid=%s)(objectClass=user))",
186 ldap_encode_ndr_dom_sid(mem_ctx
, sid
));
187 if (ret
!= LDB_SUCCESS
) {
188 DEBUG(2, ("Failed to search for SID %s in SAM for NTP signing: "
190 dom_sid_str_buf(sid
, &buf
),
191 ldb_errstring(ntp_signd_conn
->ntp_signd
->samdb
)));
192 return signing_failure(ntp_signd_conn
,
195 sign_request
.packet_id
);
198 if (res
->count
== 0) {
199 DEBUG(2, ("Failed to find SID %s in SAM for NTP signing\n",
200 dom_sid_str_buf(sid
, &buf
)));
201 return signing_failure(ntp_signd_conn
,
204 sign_request
.packet_id
);
205 } else if (res
->count
!= 1) {
206 DEBUG(1, ("Found SID %s %u times in SAM for NTP signing\n",
207 dom_sid_str_buf(sid
, &buf
),
209 return signing_failure(ntp_signd_conn
,
212 sign_request
.packet_id
);
215 user_account_control
= ldb_msg_find_attr_as_uint(res
->msgs
[0],
216 "userAccountControl",
219 if (user_account_control
& UF_ACCOUNTDISABLE
) {
220 DEBUG(1, ("Account %s for SID [%s] is disabled\n",
221 ldb_dn_get_linearized(res
->msgs
[0]->dn
),
222 dom_sid_str_buf(sid
, &buf
)));
223 return NT_STATUS_ACCESS_DENIED
;
226 if (!(user_account_control
& (UF_INTERDOMAIN_TRUST_ACCOUNT
|UF_SERVER_TRUST_ACCOUNT
|UF_WORKSTATION_TRUST_ACCOUNT
))) {
227 DEBUG(1, ("Account %s for SID [%s] is not a trust account\n",
228 ldb_dn_get_linearized(res
->msgs
[0]->dn
),
229 dom_sid_str_buf(sid
, &buf
)));
230 return NT_STATUS_ACCESS_DENIED
;
233 nt_hash
= samdb_result_hash(mem_ctx
, res
->msgs
[0], "unicodePwd");
235 DEBUG(1, ("No unicodePwd found on record of SID %s "
237 dom_sid_str_buf(sid
, &buf
)));
238 return signing_failure(ntp_signd_conn
,
241 sign_request
.packet_id
);
244 /* Generate the reply packet */
245 signed_reply
.packet_id
= sign_request
.packet_id
;
246 signed_reply
.op
= SIGNING_SUCCESS
;
247 signed_reply
.signed_packet
= data_blob_talloc(mem_ctx
,
249 sign_request
.packet_to_sign
.length
+ 20);
251 if (!signed_reply
.signed_packet
.data
) {
252 return signing_failure(ntp_signd_conn
,
255 sign_request
.packet_id
);
258 memcpy(signed_reply
.signed_packet
.data
, sign_request
.packet_to_sign
.data
, sign_request
.packet_to_sign
.length
);
259 SIVAL(signed_reply
.signed_packet
.data
, sign_request
.packet_to_sign
.length
, sign_request
.key_id
);
261 /* Sign the NTP response with the unicodePwd */
262 ret
= gnutls_hash_init(&hash_hnd
, GNUTLS_DIG_MD5
);
264 return gnutls_error_to_ntstatus(ret
, NT_STATUS_HASH_NOT_SUPPORTED
);
267 ret
= gnutls_hash(hash_hnd
,
269 sizeof(nt_hash
->hash
));
271 gnutls_hash_deinit(hash_hnd
, NULL
);
272 return gnutls_error_to_ntstatus(ret
, NT_STATUS_HASH_NOT_SUPPORTED
);
274 ret
= gnutls_hash(hash_hnd
,
275 sign_request
.packet_to_sign
.data
,
276 sign_request
.packet_to_sign
.length
);
278 gnutls_hash_deinit(hash_hnd
, NULL
);
279 return gnutls_error_to_ntstatus(ret
, NT_STATUS_HASH_NOT_SUPPORTED
);
282 gnutls_hash_deinit(hash_hnd
,
283 signed_reply
.signed_packet
.data
+
284 sign_request
.packet_to_sign
.length
+ 4);
286 /* Place it into the packet for the wire */
287 ndr_err
= ndr_push_struct_blob(output
, mem_ctx
, &signed_reply
,
288 (ndr_push_flags_fn_t
)ndr_push_signed_reply
);
290 if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err
)) {
291 DEBUG(1,("failed to push ntp error reply\n"));
292 return ndr_map_error2ntstatus(ndr_err
);
301 static void ntp_signd_recv(struct stream_connection
*conn
, uint16_t flags
)
303 struct ntp_signd_connection
*ntp_signd_conn
= talloc_get_type(conn
->private_data
,
304 struct ntp_signd_connection
);
305 ntp_signd_terminate_connection(ntp_signd_conn
,
306 "ntp_signd_recv: called");
310 called when we can write to a connection
312 static void ntp_signd_send(struct stream_connection
*conn
, uint16_t flags
)
314 struct ntp_signd_connection
*ntp_signd_conn
= talloc_get_type(conn
->private_data
,
315 struct ntp_signd_connection
);
316 /* this should never be triggered! */
317 ntp_signd_terminate_connection(ntp_signd_conn
,
318 "ntp_signd_send: called");
321 struct ntp_signd_call
{
322 struct ntp_signd_connection
*ntp_signd_conn
;
326 struct iovec out_iov
[2];
329 static void ntp_signd_call_writev_done(struct tevent_req
*subreq
);
331 static void ntp_signd_call_loop(struct tevent_req
*subreq
)
333 struct ntp_signd_connection
*ntp_signd_conn
= tevent_req_callback_data(subreq
,
334 struct ntp_signd_connection
);
335 struct ntp_signd_call
*call
;
338 call
= talloc(ntp_signd_conn
, struct ntp_signd_call
);
340 ntp_signd_terminate_connection(ntp_signd_conn
,
341 "ntp_signd_call_loop: "
342 "no memory for ntp_signd_call");
345 call
->ntp_signd_conn
= ntp_signd_conn
;
347 status
= tstream_read_pdu_blob_recv(subreq
,
351 if (!NT_STATUS_IS_OK(status
)) {
354 reason
= talloc_asprintf(call
, "ntp_signd_call_loop: "
355 "tstream_read_pdu_blob_recv() - %s",
357 if (reason
== NULL
) {
358 reason
= nt_errstr(status
);
361 ntp_signd_terminate_connection(ntp_signd_conn
, reason
);
365 DEBUG(10,("Received NTP TCP packet of length %lu from %s\n",
366 (long) call
->in
.length
,
367 tsocket_address_string(ntp_signd_conn
->conn
->remote_address
, call
)));
369 /* skip length header */
371 call
->in
.length
-= 4;
373 status
= ntp_signd_process(ntp_signd_conn
,
377 if (! NT_STATUS_IS_OK(status
)) {
380 reason
= talloc_asprintf(call
, "ntp_signd_process failed: %s",
382 if (reason
== NULL
) {
383 reason
= nt_errstr(status
);
386 ntp_signd_terminate_connection(ntp_signd_conn
, reason
);
390 /* First add the length of the out buffer */
391 RSIVAL(call
->out_hdr
, 0, call
->out
.length
);
392 call
->out_iov
[0].iov_base
= (char *) call
->out_hdr
;
393 call
->out_iov
[0].iov_len
= 4;
395 call
->out_iov
[1].iov_base
= (char *) call
->out
.data
;
396 call
->out_iov
[1].iov_len
= call
->out
.length
;
398 subreq
= tstream_writev_queue_send(call
,
399 ntp_signd_conn
->conn
->event
.ctx
,
400 ntp_signd_conn
->tstream
,
401 ntp_signd_conn
->send_queue
,
403 if (subreq
== NULL
) {
404 ntp_signd_terminate_connection(ntp_signd_conn
, "ntp_signd_call_loop: "
405 "no memory for tstream_writev_queue_send");
409 tevent_req_set_callback(subreq
, ntp_signd_call_writev_done
, call
);
412 * The NTP tcp pdu's has the length as 4 byte (initial_read_size),
413 * tstream_full_request_u32 provides the pdu length then.
415 subreq
= tstream_read_pdu_blob_send(ntp_signd_conn
,
416 ntp_signd_conn
->conn
->event
.ctx
,
417 ntp_signd_conn
->tstream
,
418 4, /* initial_read_size */
419 tstream_full_request_u32
,
421 if (subreq
== NULL
) {
422 ntp_signd_terminate_connection(ntp_signd_conn
, "ntp_signd_call_loop: "
423 "no memory for tstream_read_pdu_blob_send");
426 tevent_req_set_callback(subreq
, ntp_signd_call_loop
, ntp_signd_conn
);
429 static void ntp_signd_call_writev_done(struct tevent_req
*subreq
)
431 struct ntp_signd_call
*call
= tevent_req_callback_data(subreq
,
432 struct ntp_signd_call
);
436 rc
= tstream_writev_queue_recv(subreq
, &sys_errno
);
441 reason
= talloc_asprintf(call
, "ntp_signd_call_writev_done: "
442 "tstream_writev_queue_recv() - %d:%s",
443 sys_errno
, strerror(sys_errno
));
445 reason
= "ntp_signd_call_writev_done: "
446 "tstream_writev_queue_recv() failed";
449 ntp_signd_terminate_connection(call
->ntp_signd_conn
, reason
);
453 /* We don't care about errors */
459 called when we get a new connection
461 static void ntp_signd_accept(struct stream_connection
*conn
)
463 struct ntp_signd_server
*ntp_signd
= talloc_get_type(conn
->private_data
,
464 struct ntp_signd_server
);
465 struct ntp_signd_connection
*ntp_signd_conn
;
466 struct tevent_req
*subreq
;
469 ntp_signd_conn
= talloc_zero(conn
, struct ntp_signd_connection
);
470 if (ntp_signd_conn
== NULL
) {
471 stream_terminate_connection(conn
,
472 "ntp_signd_accept: out of memory");
476 ntp_signd_conn
->send_queue
= tevent_queue_create(conn
,
478 if (ntp_signd_conn
->send_queue
== NULL
) {
479 stream_terminate_connection(conn
,
480 "ntp_signd_accept: out of memory");
484 TALLOC_FREE(conn
->event
.fde
);
486 rc
= tstream_bsd_existing_socket(ntp_signd_conn
,
487 socket_get_fd(conn
->socket
),
488 &ntp_signd_conn
->tstream
);
490 stream_terminate_connection(conn
,
491 "ntp_signd_accept: out of memory");
494 /* as server we want to fail early */
495 tstream_bsd_fail_readv_first_error(ntp_signd_conn
->tstream
, true);
497 ntp_signd_conn
->conn
= conn
;
498 ntp_signd_conn
->ntp_signd
= ntp_signd
;
499 conn
->private_data
= ntp_signd_conn
;
502 * The NTP tcp pdu's has the length as 4 byte (initial_read_size),
503 * tstream_full_request_u32 provides the pdu length then.
505 subreq
= tstream_read_pdu_blob_send(ntp_signd_conn
,
506 ntp_signd_conn
->conn
->event
.ctx
,
507 ntp_signd_conn
->tstream
,
508 4, /* initial_read_size */
509 tstream_full_request_u32
,
511 if (subreq
== NULL
) {
512 ntp_signd_terminate_connection(ntp_signd_conn
,
514 "no memory for tstream_read_pdu_blob_send");
517 tevent_req_set_callback(subreq
, ntp_signd_call_loop
, ntp_signd_conn
);
520 static const struct stream_server_ops ntp_signd_stream_ops
= {
522 .accept_connection
= ntp_signd_accept
,
523 .recv_handler
= ntp_signd_recv
,
524 .send_handler
= ntp_signd_send
528 startup the ntp_signd task
530 static NTSTATUS
ntp_signd_task_init(struct task_server
*task
)
532 struct ntp_signd_server
*ntp_signd
;
537 if (!directory_create_or_exist_strict(lpcfg_ntp_signd_socket_directory(task
->lp_ctx
), geteuid(), 0750)) {
538 char *error
= talloc_asprintf(task
, "Cannot create NTP signd pipe directory: %s",
539 lpcfg_ntp_signd_socket_directory(task
->lp_ctx
));
540 task_server_terminate(task
,
542 return NT_STATUS_UNSUCCESSFUL
;
545 task_server_set_title(task
, "task[ntp_signd]");
547 ntp_signd
= talloc(task
, struct ntp_signd_server
);
548 if (ntp_signd
== NULL
) {
549 task_server_terminate(task
, "ntp_signd: out of memory", true);
550 return NT_STATUS_NO_MEMORY
;
553 ntp_signd
->task
= task
;
555 /* Must be system to get at the password hashes */
556 ntp_signd
->samdb
= samdb_connect(ntp_signd
,
559 system_session(task
->lp_ctx
),
562 if (ntp_signd
->samdb
== NULL
) {
563 task_server_terminate(task
, "ntp_signd failed to open samdb", true);
564 return NT_STATUS_UNSUCCESSFUL
;
567 address
= talloc_asprintf(ntp_signd
, "%s/socket", lpcfg_ntp_signd_socket_directory(task
->lp_ctx
));
568 if (address
== NULL
) {
569 task_server_terminate(
570 task
, "ntp_signd out of memory in talloc_asprintf()", true);
571 return NT_STATUS_NO_MEMORY
;
574 status
= stream_setup_socket(ntp_signd
->task
,
575 ntp_signd
->task
->event_ctx
,
576 ntp_signd
->task
->lp_ctx
,
578 &ntp_signd_stream_ops
,
579 "unix", address
, NULL
,
580 lpcfg_socket_options(ntp_signd
->task
->lp_ctx
),
582 ntp_signd
->task
->process_context
);
583 if (!NT_STATUS_IS_OK(status
)) {
584 DEBUG(0,("Failed to bind to %s - %s\n",
585 address
, nt_errstr(status
)));
594 /* called at smbd startup - register ourselves as a server service */
595 NTSTATUS
server_service_ntp_signd_init(TALLOC_CTX
*ctx
)
597 static const struct service_details details
= {
598 .inhibit_fork_on_accept
= true,
599 .inhibit_pre_fork
= true,
600 .task_init
= ntp_signd_task_init
,
603 return register_server_service(ctx
, "ntp_signd", &details
);