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

Generated by: LCOV version 1.14