LCOV - code coverage report
Current view: top level - source4/ntp_signd - ntp_signd.c (source / functions) Hit Total Coverage
Test: coverage report for master 98b443d9 Lines: 122 234 52.1 %
Date: 2024-05-31 13:13:24 Functions: 7 10 70.0 %

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

Generated by: LCOV version 1.14