ntpd: Use dom_sid_str_buf
[samba.git] / source4 / ntp_signd / ntp_signd.c
1 /* 
2    Unix SMB/CIFS implementation.
3
4    NTP packet signing server
5
6    Copyright (C) Andrew Bartlett <abartlet@samba.org> 2005
7    Copyright (C) Andrew Tridgell        2005
8    Copyright (C) Stefan Metzmacher      2005
9
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.
14    
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.
19    
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/>.
22 */
23
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 "../lib/crypto/md5.h"
41 #include "system/network.h"
42 #include "system/passwd.h"
43
44 NTSTATUS server_service_ntp_signd_init(TALLOC_CTX *);
45
46 /*
47   top level context structure for the ntp_signd server
48 */
49 struct ntp_signd_server {
50         struct task_server *task;
51         struct ldb_context *samdb;
52 };
53
54 /*
55   state of an open connection
56 */
57 struct ntp_signd_connection {
58         /* stream connection we belong to */
59         struct stream_connection *conn;
60
61         /* the ntp_signd_server the connection belongs to */
62         struct ntp_signd_server *ntp_signd;
63
64         struct tstream_context *tstream;
65
66         struct tevent_queue *send_queue;
67 };
68
69 static void ntp_signd_terminate_connection(struct ntp_signd_connection *ntp_signd_conn, const char *reason)
70 {
71         stream_terminate_connection(ntp_signd_conn->conn, reason);
72 }
73
74 static NTSTATUS signing_failure(struct ntp_signd_connection *ntp_signdconn,
75                                 TALLOC_CTX *mem_ctx,
76                                 DATA_BLOB *output,
77                                 uint32_t packet_id)
78 {
79         struct signed_reply signed_reply;
80         enum ndr_err_code ndr_err;
81
82         signed_reply.op = SIGNING_FAILURE;
83         signed_reply.packet_id = packet_id;
84         signed_reply.signed_packet = data_blob(NULL, 0);
85         
86         ndr_err = ndr_push_struct_blob(output, mem_ctx, &signed_reply,
87                                        (ndr_push_flags_fn_t)ndr_push_signed_reply);
88
89         if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
90                 DEBUG(1,("failed to push ntp error reply\n"));
91                 return ndr_map_error2ntstatus(ndr_err);
92         }
93
94         return NT_STATUS_OK;
95 }
96
97 /*
98   receive a full packet on a NTP_SIGND connection
99 */
100 static NTSTATUS ntp_signd_process(struct ntp_signd_connection *ntp_signd_conn,
101                                   TALLOC_CTX *mem_ctx,
102                                   DATA_BLOB *input,
103                                   DATA_BLOB *output)
104 {
105         const struct dom_sid *domain_sid;
106         struct dom_sid *sid;
107         struct sign_request sign_request;
108         struct signed_reply signed_reply;
109         enum ndr_err_code ndr_err;
110         struct ldb_result *res;
111         const char *attrs[] = { "unicodePwd", "userAccountControl", "cn", NULL };
112         MD5_CTX ctx;
113         struct samr_Password *nt_hash;
114         uint32_t user_account_control;
115         struct dom_sid_buf buf;
116         int ret;
117
118         ndr_err = ndr_pull_struct_blob_all(input, mem_ctx,
119                                            &sign_request,
120                                            (ndr_pull_flags_fn_t)ndr_pull_sign_request);
121
122         if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
123                 DEBUG(1,("failed to parse ntp signing request\n"));
124                 dump_data(1, input->data, input->length);
125                 return ndr_map_error2ntstatus(ndr_err);
126         }
127
128         /* We need to implement 'check signature' and 'request server
129          * to sign' operations at some point */
130         if (sign_request.op != SIGN_TO_CLIENT) {
131                 return signing_failure(ntp_signd_conn,
132                                        mem_ctx,
133                                        output,
134                                        sign_request.packet_id);
135         }
136
137         /* We need to implement 'check signature' and 'request server
138          * to sign' operations at some point */
139         if (sign_request.version != NTP_SIGND_PROTOCOL_VERSION_0) {
140                 return signing_failure(ntp_signd_conn,
141                                        mem_ctx,
142                                        output,
143                                        sign_request.packet_id);
144         }
145
146         domain_sid = samdb_domain_sid(ntp_signd_conn->ntp_signd->samdb);
147         if (domain_sid == NULL) {
148                 return signing_failure(ntp_signd_conn,
149                                        mem_ctx,
150                                        output,
151                                        sign_request.packet_id);
152         }
153         
154         /* The top bit is a 'key selector' */
155         sid = dom_sid_add_rid(mem_ctx, domain_sid,
156                               sign_request.key_id & 0x7FFFFFFF);
157         if (sid == NULL) {
158                 talloc_free(mem_ctx);
159                 return signing_failure(ntp_signd_conn,
160                                        mem_ctx,
161                                        output,
162                                        sign_request.packet_id);
163         }
164
165         ret = ldb_search(ntp_signd_conn->ntp_signd->samdb, mem_ctx,
166                                  &res,
167                                  ldb_get_default_basedn(ntp_signd_conn->ntp_signd->samdb),
168                                  LDB_SCOPE_SUBTREE,
169                                  attrs,
170                                  "(&(objectSid=%s)(objectClass=user))",
171                                  ldap_encode_ndr_dom_sid(mem_ctx, sid));
172         if (ret != LDB_SUCCESS) {
173                 DEBUG(2, ("Failed to search for SID %s in SAM for NTP signing: "
174                           "%s\n",
175                           dom_sid_str_buf(sid, &buf),
176                           ldb_errstring(ntp_signd_conn->ntp_signd->samdb)));
177                 return signing_failure(ntp_signd_conn,
178                                        mem_ctx,
179                                        output,
180                                        sign_request.packet_id);
181         }
182
183         if (res->count == 0) {
184                 DEBUG(2, ("Failed to find SID %s in SAM for NTP signing\n",
185                           dom_sid_str_buf(sid, &buf)));
186                 return signing_failure(ntp_signd_conn,
187                                        mem_ctx,
188                                        output,
189                                        sign_request.packet_id);
190         } else if (res->count != 1) {
191                 DEBUG(1, ("Found SID %s %u times in SAM for NTP signing\n",
192                           dom_sid_str_buf(sid, &buf),
193                           res->count));
194                 return signing_failure(ntp_signd_conn,
195                                        mem_ctx,
196                                        output,
197                                        sign_request.packet_id);
198         }
199
200         user_account_control = ldb_msg_find_attr_as_uint(res->msgs[0],
201                                                          "userAccountControl",
202                                                          0);
203
204         if (user_account_control & UF_ACCOUNTDISABLE) {
205                 DEBUG(1, ("Account %s for SID [%s] is disabled\n",
206                           ldb_dn_get_linearized(res->msgs[0]->dn),
207                           dom_sid_str_buf(sid, &buf)));
208                 return NT_STATUS_ACCESS_DENIED;
209         }
210
211         if (!(user_account_control & (UF_INTERDOMAIN_TRUST_ACCOUNT|UF_SERVER_TRUST_ACCOUNT|UF_WORKSTATION_TRUST_ACCOUNT))) {
212                 DEBUG(1, ("Account %s for SID [%s] is not a trust account\n",
213                           ldb_dn_get_linearized(res->msgs[0]->dn),
214                           dom_sid_str_buf(sid, &buf)));
215                 return NT_STATUS_ACCESS_DENIED;
216         }
217
218         nt_hash = samdb_result_hash(mem_ctx, res->msgs[0], "unicodePwd");
219         if (!nt_hash) {
220                 DEBUG(1, ("No unicodePwd found on record of SID %s "
221                           "for NTP signing\n",
222                           dom_sid_str_buf(sid, &buf)));
223                 return signing_failure(ntp_signd_conn,
224                                        mem_ctx,
225                                        output,
226                                        sign_request.packet_id);
227         }
228
229         /* Generate the reply packet */
230         signed_reply.packet_id = sign_request.packet_id;
231         signed_reply.op = SIGNING_SUCCESS;
232         signed_reply.signed_packet = data_blob_talloc(mem_ctx,
233                                                       NULL,
234                                                       sign_request.packet_to_sign.length + 20);
235
236         if (!signed_reply.signed_packet.data) {
237                 return signing_failure(ntp_signd_conn,
238                                        mem_ctx,
239                                        output,
240                                        sign_request.packet_id);
241         }
242
243         memcpy(signed_reply.signed_packet.data, sign_request.packet_to_sign.data, sign_request.packet_to_sign.length);
244         SIVAL(signed_reply.signed_packet.data, sign_request.packet_to_sign.length, sign_request.key_id);
245
246         /* Sign the NTP response with the unicodePwd */
247         MD5Init(&ctx);
248         MD5Update(&ctx, nt_hash->hash, sizeof(nt_hash->hash));
249         MD5Update(&ctx, sign_request.packet_to_sign.data, sign_request.packet_to_sign.length);
250         MD5Final(signed_reply.signed_packet.data + sign_request.packet_to_sign.length + 4, &ctx);
251
252
253         /* Place it into the packet for the wire */
254         ndr_err = ndr_push_struct_blob(output, mem_ctx, &signed_reply,
255                                        (ndr_push_flags_fn_t)ndr_push_signed_reply);
256
257         if (!NDR_ERR_CODE_IS_SUCCESS(ndr_err)) {
258                 DEBUG(1,("failed to push ntp error reply\n"));
259                 return ndr_map_error2ntstatus(ndr_err);
260         }
261
262         return NT_STATUS_OK;
263 }
264
265 /*
266   called on a tcp recv
267 */
268 static void ntp_signd_recv(struct stream_connection *conn, uint16_t flags)
269 {
270         struct ntp_signd_connection *ntp_signd_conn = talloc_get_type(conn->private_data,
271                                                         struct ntp_signd_connection);
272         ntp_signd_terminate_connection(ntp_signd_conn,
273                                        "ntp_signd_recv: called");
274 }
275
276 /*
277   called when we can write to a connection
278 */
279 static void ntp_signd_send(struct stream_connection *conn, uint16_t flags)
280 {
281         struct ntp_signd_connection *ntp_signd_conn = talloc_get_type(conn->private_data,
282                                                         struct ntp_signd_connection);
283         /* this should never be triggered! */
284         ntp_signd_terminate_connection(ntp_signd_conn,
285                                        "ntp_signd_send: called");
286 }
287
288 struct ntp_signd_call {
289         struct ntp_signd_connection *ntp_signd_conn;
290         DATA_BLOB in;
291         DATA_BLOB out;
292         uint8_t out_hdr[4];
293         struct iovec out_iov[2];
294 };
295
296 static void ntp_signd_call_writev_done(struct tevent_req *subreq);
297
298 static void ntp_signd_call_loop(struct tevent_req *subreq)
299 {
300         struct ntp_signd_connection *ntp_signd_conn = tevent_req_callback_data(subreq,
301                                       struct ntp_signd_connection);
302         struct ntp_signd_call *call;
303         NTSTATUS status;
304
305         call = talloc(ntp_signd_conn, struct ntp_signd_call);
306         if (call == NULL) {
307                 ntp_signd_terminate_connection(ntp_signd_conn,
308                                 "ntp_signd_call_loop: "
309                                 "no memory for ntp_signd_call");
310                 return;
311         }
312         call->ntp_signd_conn = ntp_signd_conn;
313
314         status = tstream_read_pdu_blob_recv(subreq,
315                                             call,
316                                             &call->in);
317         TALLOC_FREE(subreq);
318         if (!NT_STATUS_IS_OK(status)) {
319                 const char *reason;
320
321                 reason = talloc_asprintf(call, "ntp_signd_call_loop: "
322                                          "tstream_read_pdu_blob_recv() - %s",
323                                          nt_errstr(status));
324                 if (reason == NULL) {
325                         reason = nt_errstr(status);
326                 }
327
328                 ntp_signd_terminate_connection(ntp_signd_conn, reason);
329                 return;
330         }
331
332         DEBUG(10,("Received NTP TCP packet of length %lu from %s\n",
333                  (long) call->in.length,
334                  tsocket_address_string(ntp_signd_conn->conn->remote_address, call)));
335
336         /* skip length header */
337         call->in.data +=4;
338         call->in.length -= 4;
339
340         status = ntp_signd_process(ntp_signd_conn,
341                                      call,
342                                      &call->in,
343                                      &call->out);
344         if (! NT_STATUS_IS_OK(status)) {
345                 const char *reason;
346
347                 reason = talloc_asprintf(call, "ntp_signd_process failed: %s",
348                                          nt_errstr(status));
349                 if (reason == NULL) {
350                         reason = nt_errstr(status);
351                 }
352
353                 ntp_signd_terminate_connection(ntp_signd_conn, reason);
354                 return;
355         }
356
357         /* First add the length of the out buffer */
358         RSIVAL(call->out_hdr, 0, call->out.length);
359         call->out_iov[0].iov_base = (char *) call->out_hdr;
360         call->out_iov[0].iov_len = 4;
361
362         call->out_iov[1].iov_base = (char *) call->out.data;
363         call->out_iov[1].iov_len = call->out.length;
364
365         subreq = tstream_writev_queue_send(call,
366                                            ntp_signd_conn->conn->event.ctx,
367                                            ntp_signd_conn->tstream,
368                                            ntp_signd_conn->send_queue,
369                                            call->out_iov, 2);
370         if (subreq == NULL) {
371                 ntp_signd_terminate_connection(ntp_signd_conn, "ntp_signd_call_loop: "
372                                 "no memory for tstream_writev_queue_send");
373                 return;
374         }
375
376         tevent_req_set_callback(subreq, ntp_signd_call_writev_done, call);
377
378         /*
379          * The NTP tcp pdu's has the length as 4 byte (initial_read_size),
380          * packet_full_request_u32 provides the pdu length then.
381          */
382         subreq = tstream_read_pdu_blob_send(ntp_signd_conn,
383                                             ntp_signd_conn->conn->event.ctx,
384                                             ntp_signd_conn->tstream,
385                                             4, /* initial_read_size */
386                                             packet_full_request_u32,
387                                             ntp_signd_conn);
388         if (subreq == NULL) {
389                 ntp_signd_terminate_connection(ntp_signd_conn, "ntp_signd_call_loop: "
390                                 "no memory for tstream_read_pdu_blob_send");
391                 return;
392         }
393         tevent_req_set_callback(subreq, ntp_signd_call_loop, ntp_signd_conn);
394 }
395
396 static void ntp_signd_call_writev_done(struct tevent_req *subreq)
397 {
398         struct ntp_signd_call *call = tevent_req_callback_data(subreq,
399                         struct ntp_signd_call);
400         int sys_errno;
401         int rc;
402
403         rc = tstream_writev_queue_recv(subreq, &sys_errno);
404         TALLOC_FREE(subreq);
405         if (rc == -1) {
406                 const char *reason;
407
408                 reason = talloc_asprintf(call, "ntp_signd_call_writev_done: "
409                                          "tstream_writev_queue_recv() - %d:%s",
410                                          sys_errno, strerror(sys_errno));
411                 if (!reason) {
412                         reason = "ntp_signd_call_writev_done: "
413                                  "tstream_writev_queue_recv() failed";
414                 }
415
416                 ntp_signd_terminate_connection(call->ntp_signd_conn, reason);
417                 return;
418         }
419
420         /* We don't care about errors */
421
422         talloc_free(call);
423 }
424
425 /*
426   called when we get a new connection
427 */
428 static void ntp_signd_accept(struct stream_connection *conn)
429 {
430         struct ntp_signd_server *ntp_signd = talloc_get_type(conn->private_data,
431                                                 struct ntp_signd_server);
432         struct ntp_signd_connection *ntp_signd_conn;
433         struct tevent_req *subreq;
434         int rc;
435
436         ntp_signd_conn = talloc_zero(conn, struct ntp_signd_connection);
437         if (ntp_signd_conn == NULL) {
438                 stream_terminate_connection(conn,
439                                 "ntp_signd_accept: out of memory");
440                 return;
441         }
442
443         ntp_signd_conn->send_queue = tevent_queue_create(conn,
444                         "ntp_signd_accept");
445         if (ntp_signd_conn->send_queue == NULL) {
446                 stream_terminate_connection(conn,
447                                 "ntp_signd_accept: out of memory");
448                 return;
449         }
450
451         TALLOC_FREE(conn->event.fde);
452
453         rc = tstream_bsd_existing_socket(ntp_signd_conn,
454                         socket_get_fd(conn->socket),
455                         &ntp_signd_conn->tstream);
456         if (rc < 0) {
457                 stream_terminate_connection(conn,
458                                 "ntp_signd_accept: out of memory");
459                 return;
460         }
461
462         ntp_signd_conn->conn = conn;
463         ntp_signd_conn->ntp_signd = ntp_signd;
464         conn->private_data = ntp_signd_conn;
465
466         /*
467          * The NTP tcp pdu's has the length as 4 byte (initial_read_size),
468          * packet_full_request_u32 provides the pdu length then.
469          */
470         subreq = tstream_read_pdu_blob_send(ntp_signd_conn,
471                                             ntp_signd_conn->conn->event.ctx,
472                                             ntp_signd_conn->tstream,
473                                             4, /* initial_read_size */
474                                             packet_full_request_u32,
475                                             ntp_signd_conn);
476         if (subreq == NULL) {
477                 ntp_signd_terminate_connection(ntp_signd_conn,
478                                 "ntp_signd_accept: "
479                                 "no memory for tstream_read_pdu_blob_send");
480                 return;
481         }
482         tevent_req_set_callback(subreq, ntp_signd_call_loop, ntp_signd_conn);
483 }
484
485 static const struct stream_server_ops ntp_signd_stream_ops = {
486         .name                   = "ntp_signd",
487         .accept_connection      = ntp_signd_accept,
488         .recv_handler           = ntp_signd_recv,
489         .send_handler           = ntp_signd_send
490 };
491
492 /*
493   startup the ntp_signd task
494 */
495 static NTSTATUS ntp_signd_task_init(struct task_server *task)
496 {
497         struct ntp_signd_server *ntp_signd;
498         NTSTATUS status;
499
500         const char *address;
501
502         if (!directory_create_or_exist_strict(lpcfg_ntp_signd_socket_directory(task->lp_ctx), geteuid(), 0750)) {
503                 char *error = talloc_asprintf(task, "Cannot create NTP signd pipe directory: %s", 
504                                               lpcfg_ntp_signd_socket_directory(task->lp_ctx));
505                 task_server_terminate(task,
506                                       error, true);
507                 return NT_STATUS_UNSUCCESSFUL;
508         }
509
510         task_server_set_title(task, "task[ntp_signd]");
511
512         ntp_signd = talloc(task, struct ntp_signd_server);
513         if (ntp_signd == NULL) {
514                 task_server_terminate(task, "ntp_signd: out of memory", true);
515                 return NT_STATUS_NO_MEMORY;
516         }
517
518         ntp_signd->task = task;
519
520         /* Must be system to get at the password hashes */
521         ntp_signd->samdb = samdb_connect(ntp_signd,
522                                          task->event_ctx,
523                                          task->lp_ctx,
524                                          system_session(task->lp_ctx),
525                                          NULL,
526                                          0);
527         if (ntp_signd->samdb == NULL) {
528                 task_server_terminate(task, "ntp_signd failed to open samdb", true);
529                 return NT_STATUS_UNSUCCESSFUL;
530         }
531
532         address = talloc_asprintf(ntp_signd, "%s/socket", lpcfg_ntp_signd_socket_directory(task->lp_ctx));
533         if (address == NULL) {
534                 task_server_terminate(
535                     task, "ntp_signd out of memory in talloc_asprintf()", true);
536                 return NT_STATUS_NO_MEMORY;
537         }
538
539         status = stream_setup_socket(ntp_signd->task,
540                                      ntp_signd->task->event_ctx,
541                                      ntp_signd->task->lp_ctx,
542                                      task->model_ops,
543                                      &ntp_signd_stream_ops, 
544                                      "unix", address, NULL,
545                                      lpcfg_socket_options(ntp_signd->task->lp_ctx),
546                                      ntp_signd,
547                                      ntp_signd->task->process_context);
548         if (!NT_STATUS_IS_OK(status)) {
549                 DEBUG(0,("Failed to bind to %s - %s\n",
550                          address, nt_errstr(status)));
551                 return status;
552         }
553
554         return NT_STATUS_OK;
555
556 }
557
558
559 /* called at smbd startup - register ourselves as a server service */
560 NTSTATUS server_service_ntp_signd_init(TALLOC_CTX *ctx)
561 {
562         static const struct service_details details = {
563                 .inhibit_fork_on_accept = true,
564                 .inhibit_pre_fork = true,
565                 .task_init = ntp_signd_task_init,
566                 .post_fork = NULL
567         };
568         return register_server_service(ctx, "ntp_signd", &details);
569 }