2008-05-27 10:20:18 +04:00
/*
Unix SMB / CIFS implementation .
NTP packet signing server
Copyright ( C ) Andrew Bartlett < abartlet @ samba . org > 2005
Copyright ( C ) Andrew Tridgell 2005
Copyright ( C ) Stefan Metzmacher 2005
This program is free software ; you can redistribute it and / or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation ; either version 3 of the License , or
( at your option ) any later version .
This program is distributed in the hope that it will be useful ,
but WITHOUT ANY WARRANTY ; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
GNU General Public License for more details .
You should have received a copy of the GNU General Public License
along with this program . If not , see < http : //www.gnu.org/licenses/>.
*/
# include "includes.h"
2020-11-20 17:27:17 +03:00
# include "samba/service_task.h"
# include "samba/service.h"
# include "samba/service_stream.h"
# include "samba/process_model.h"
2008-05-27 10:20:18 +04:00
# include "lib/stream/packet.h"
2010-01-12 19:30:04 +03:00
# include "lib/tsocket/tsocket.h"
# include "libcli/util/tstream.h"
2008-05-28 07:21:26 +04:00
# include "librpc/gen_ndr/ndr_ntp_signd.h"
2008-05-27 10:20:18 +04:00
# include "param/param.h"
2024-04-15 02:42:50 +03:00
# include "dsdb/common/util.h"
2008-05-27 10:20:18 +04:00
# include "dsdb/samdb/samdb.h"
# include "auth/auth.h"
2008-05-28 07:21:26 +04:00
# include "libcli/security/security.h"
2010-09-14 00:41:06 +04:00
# include "libcli/ldap/ldap_ndr.h"
2011-02-10 06:12:51 +03:00
# include <ldb.h>
# include <ldb_errors.h>
2010-01-12 19:30:04 +03:00
# include "system/network.h"
2008-05-29 09:20:58 +04:00
# include "system/passwd.h"
2008-05-27 10:20:18 +04:00
2019-06-26 07:41:05 +03:00
# include "lib/crypto/gnutls_helpers.h"
2018-11-06 18:25:00 +03:00
# include <gnutls/gnutls.h>
# include <gnutls/crypto.h>
2017-04-20 22:24:43 +03:00
NTSTATUS server_service_ntp_signd_init ( TALLOC_CTX * ) ;
2011-03-19 02:45:45 +03:00
2008-05-27 10:20:18 +04:00
/*
top level context structure for the ntp_signd server
*/
struct ntp_signd_server {
struct task_server * task ;
struct ldb_context * samdb ;
} ;
/*
state of an open connection
*/
struct ntp_signd_connection {
/* stream connection we belong to */
struct stream_connection * conn ;
/* the ntp_signd_server the connection belongs to */
struct ntp_signd_server * ntp_signd ;
2010-01-12 19:30:04 +03:00
struct tstream_context * tstream ;
struct tevent_queue * send_queue ;
2008-05-27 10:20:18 +04:00
} ;
2010-01-12 19:30:04 +03:00
static void ntp_signd_terminate_connection ( struct ntp_signd_connection * ntp_signd_conn , const char * reason )
2008-05-27 10:20:18 +04:00
{
2010-01-12 19:30:04 +03:00
stream_terminate_connection ( ntp_signd_conn - > conn , reason ) ;
2008-05-27 10:20:18 +04:00
}
2008-05-29 05:16:03 +04:00
static NTSTATUS signing_failure ( struct ntp_signd_connection * ntp_signdconn ,
2010-01-12 19:30:04 +03:00
TALLOC_CTX * mem_ctx ,
DATA_BLOB * output ,
uint32_t packet_id )
2008-05-29 05:16:03 +04:00
{
struct signed_reply signed_reply ;
enum ndr_err_code ndr_err ;
signed_reply . op = SIGNING_FAILURE ;
signed_reply . packet_id = packet_id ;
signed_reply . signed_packet = data_blob ( NULL , 0 ) ;
2010-05-09 19:20:01 +04:00
ndr_err = ndr_push_struct_blob ( output , mem_ctx , & signed_reply ,
2008-05-29 05:16:03 +04:00
( ndr_push_flags_fn_t ) ndr_push_signed_reply ) ;
if ( ! NDR_ERR_CODE_IS_SUCCESS ( ndr_err ) ) {
DEBUG ( 1 , ( " failed to push ntp error reply \n " ) ) ;
return ndr_map_error2ntstatus ( ndr_err ) ;
}
2010-01-12 19:30:04 +03:00
return NT_STATUS_OK ;
2008-05-29 05:16:03 +04:00
}
2008-05-27 10:20:18 +04:00
/*
receive a full packet on a NTP_SIGND connection
*/
2010-01-12 19:30:04 +03:00
static NTSTATUS ntp_signd_process ( struct ntp_signd_connection * ntp_signd_conn ,
TALLOC_CTX * mem_ctx ,
DATA_BLOB * input ,
DATA_BLOB * output )
2008-05-27 10:20:18 +04:00
{
const struct dom_sid * domain_sid ;
struct dom_sid * sid ;
struct sign_request sign_request ;
2008-05-29 05:16:03 +04:00
struct signed_reply signed_reply ;
2008-05-27 10:20:18 +04:00
enum ndr_err_code ndr_err ;
struct ldb_result * res ;
2024-04-15 02:42:50 +03:00
static const char * attrs [ ] = {
" unicodePwd " ,
" userAccountControl " ,
" cn " ,
/* Required for Group Managed Service Accounts. */
" msDS-ManagedPasswordId " ,
" msDS-ManagedPasswordInterval " ,
" objectClass " ,
" objectSid " ,
" whenCreated " ,
NULL } ;
2018-11-06 18:25:00 +03:00
gnutls_hash_hd_t hash_hnd = NULL ;
2008-05-29 05:16:03 +04:00
struct samr_Password * nt_hash ;
2008-06-19 03:34:04 +04:00
uint32_t user_account_control ;
2018-12-16 19:02:54 +03:00
struct dom_sid_buf buf ;
2008-05-28 07:21:26 +04:00
int ret ;
2008-05-27 10:20:18 +04:00
2010-01-12 19:30:04 +03:00
ndr_err = ndr_pull_struct_blob_all ( input , mem_ctx ,
2008-05-27 10:20:18 +04:00
& sign_request ,
( ndr_pull_flags_fn_t ) ndr_pull_sign_request ) ;
if ( ! NDR_ERR_CODE_IS_SUCCESS ( ndr_err ) ) {
DEBUG ( 1 , ( " failed to parse ntp signing request \n " ) ) ;
2010-01-12 19:30:04 +03:00
dump_data ( 1 , input - > data , input - > length ) ;
2008-05-27 10:20:18 +04:00
return ndr_map_error2ntstatus ( ndr_err ) ;
}
2008-05-29 09:20:58 +04:00
/* We need to implement 'check signature' and 'request server
* to sign ' operations at some point */
2008-05-29 05:16:03 +04:00
if ( sign_request . op ! = SIGN_TO_CLIENT ) {
2010-01-12 19:30:04 +03:00
return signing_failure ( ntp_signd_conn ,
mem_ctx ,
output ,
sign_request . packet_id ) ;
2008-05-29 05:16:03 +04:00
}
2009-08-11 12:20:39 +04:00
/* We need to implement 'check signature' and 'request server
* to sign ' operations at some point */
2009-08-22 05:09:30 +04:00
if ( sign_request . version ! = NTP_SIGND_PROTOCOL_VERSION_0 ) {
2010-01-12 19:30:04 +03:00
return signing_failure ( ntp_signd_conn ,
mem_ctx ,
output ,
sign_request . packet_id ) ;
2009-08-11 12:20:39 +04:00
}
2010-01-12 19:30:04 +03:00
domain_sid = samdb_domain_sid ( ntp_signd_conn - > ntp_signd - > samdb ) ;
if ( domain_sid = = NULL ) {
return signing_failure ( ntp_signd_conn ,
mem_ctx ,
output ,
sign_request . packet_id ) ;
2008-05-27 10:20:18 +04:00
}
2008-05-29 09:20:58 +04:00
/* The top bit is a 'key selector' */
2010-01-12 19:30:04 +03:00
sid = dom_sid_add_rid ( mem_ctx , domain_sid ,
sign_request . key_id & 0x7FFFFFFF ) ;
if ( sid = = NULL ) {
talloc_free ( mem_ctx ) ;
return signing_failure ( ntp_signd_conn ,
mem_ctx ,
output ,
sign_request . packet_id ) ;
2008-05-27 10:20:18 +04:00
}
2024-04-15 02:42:50 +03:00
ret = dsdb_search ( ntp_signd_conn - > ntp_signd - > samdb , mem_ctx ,
& res ,
ldb_get_default_basedn ( ntp_signd_conn - > ntp_signd - > samdb ) ,
LDB_SCOPE_SUBTREE ,
attrs ,
DSDB_SEARCH_UPDATE_MANAGED_PASSWORDS ,
" (&(objectSid=%s)(objectClass=user)) " ,
ldap_encode_ndr_dom_sid ( mem_ctx , sid ) ) ;
2008-05-27 10:20:18 +04:00
if ( ret ! = LDB_SUCCESS ) {
2010-01-12 19:30:04 +03:00
DEBUG ( 2 , ( " Failed to search for SID %s in SAM for NTP signing: "
" %s \n " ,
2018-12-16 19:02:54 +03:00
dom_sid_str_buf ( sid , & buf ) ,
2010-01-12 19:30:04 +03:00
ldb_errstring ( ntp_signd_conn - > ntp_signd - > samdb ) ) ) ;
return signing_failure ( ntp_signd_conn ,
mem_ctx ,
output ,
sign_request . packet_id ) ;
2008-05-27 10:20:18 +04:00
}
2008-05-29 05:16:03 +04:00
if ( res - > count = = 0 ) {
2012-08-14 16:16:54 +04:00
DEBUG ( 2 , ( " Failed to find SID %s in SAM for NTP signing \n " ,
2018-12-16 19:02:54 +03:00
dom_sid_str_buf ( sid , & buf ) ) ) ;
2012-08-14 16:16:54 +04:00
return signing_failure ( ntp_signd_conn ,
mem_ctx ,
output ,
sign_request . packet_id ) ;
2008-05-29 05:16:03 +04:00
} else if ( res - > count ! = 1 ) {
2010-01-12 19:30:04 +03:00
DEBUG ( 1 , ( " Found SID %s %u times in SAM for NTP signing \n " ,
2018-12-16 19:02:54 +03:00
dom_sid_str_buf ( sid , & buf ) ,
res - > count ) ) ;
2010-01-12 19:30:04 +03:00
return signing_failure ( ntp_signd_conn ,
mem_ctx ,
output ,
sign_request . packet_id ) ;
2008-05-29 05:16:03 +04:00
}
2010-01-12 19:30:04 +03:00
user_account_control = ldb_msg_find_attr_as_uint ( res - > msgs [ 0 ] ,
" userAccountControl " ,
0 ) ;
2008-06-19 03:34:04 +04:00
if ( user_account_control & UF_ACCOUNTDISABLE ) {
2010-01-12 19:30:04 +03:00
DEBUG ( 1 , ( " Account %s for SID [%s] is disabled \n " ,
ldb_dn_get_linearized ( res - > msgs [ 0 ] - > dn ) ,
2018-12-16 19:02:54 +03:00
dom_sid_str_buf ( sid , & buf ) ) ) ;
2008-08-11 05:45:45 +04:00
return NT_STATUS_ACCESS_DENIED ;
}
if ( ! ( user_account_control & ( UF_INTERDOMAIN_TRUST_ACCOUNT | UF_SERVER_TRUST_ACCOUNT | UF_WORKSTATION_TRUST_ACCOUNT ) ) ) {
2010-01-12 19:30:04 +03:00
DEBUG ( 1 , ( " Account %s for SID [%s] is not a trust account \n " ,
ldb_dn_get_linearized ( res - > msgs [ 0 ] - > dn ) ,
2018-12-16 19:02:54 +03:00
dom_sid_str_buf ( sid , & buf ) ) ) ;
2008-06-19 03:34:04 +04:00
return NT_STATUS_ACCESS_DENIED ;
}
2010-01-12 19:30:04 +03:00
nt_hash = samdb_result_hash ( mem_ctx , res - > msgs [ 0 ] , " unicodePwd " ) ;
2008-05-29 05:16:03 +04:00
if ( ! nt_hash ) {
2010-01-12 19:30:04 +03:00
DEBUG ( 1 , ( " No unicodePwd found on record of SID %s "
2018-12-16 19:02:54 +03:00
" for NTP signing \n " ,
dom_sid_str_buf ( sid , & buf ) ) ) ;
2010-01-12 19:30:04 +03:00
return signing_failure ( ntp_signd_conn ,
mem_ctx ,
output ,
sign_request . packet_id ) ;
2008-05-27 10:20:18 +04:00
}
2008-05-29 09:20:58 +04:00
/* Generate the reply packet */
2008-05-29 05:16:03 +04:00
signed_reply . packet_id = sign_request . packet_id ;
signed_reply . op = SIGNING_SUCCESS ;
2010-01-12 19:30:04 +03:00
signed_reply . signed_packet = data_blob_talloc ( mem_ctx ,
2008-05-29 05:16:03 +04:00
NULL ,
sign_request . packet_to_sign . length + 20 ) ;
if ( ! signed_reply . signed_packet . data ) {
2010-01-12 19:30:04 +03:00
return signing_failure ( ntp_signd_conn ,
mem_ctx ,
output ,
sign_request . packet_id ) ;
2008-05-29 05:16:03 +04:00
}
memcpy ( signed_reply . signed_packet . data , sign_request . packet_to_sign . data , sign_request . packet_to_sign . length ) ;
SIVAL ( signed_reply . signed_packet . data , sign_request . packet_to_sign . length , sign_request . key_id ) ;
2008-05-27 10:20:18 +04:00
/* Sign the NTP response with the unicodePwd */
2018-11-06 18:25:00 +03:00
ret = gnutls_hash_init ( & hash_hnd , GNUTLS_DIG_MD5 ) ;
if ( ret < 0 ) {
2019-06-13 12:30:55 +03:00
return gnutls_error_to_ntstatus ( ret , NT_STATUS_HASH_NOT_SUPPORTED ) ;
2018-11-06 18:25:00 +03:00
}
ret = gnutls_hash ( hash_hnd ,
nt_hash - > hash ,
sizeof ( nt_hash - > hash ) ) ;
if ( ret < 0 ) {
gnutls_hash_deinit ( hash_hnd , NULL ) ;
2019-06-13 12:30:55 +03:00
return gnutls_error_to_ntstatus ( ret , NT_STATUS_HASH_NOT_SUPPORTED ) ;
2018-11-06 18:25:00 +03:00
}
ret = gnutls_hash ( hash_hnd ,
sign_request . packet_to_sign . data ,
sign_request . packet_to_sign . length ) ;
if ( ret < 0 ) {
gnutls_hash_deinit ( hash_hnd , NULL ) ;
2019-06-13 12:30:55 +03:00
return gnutls_error_to_ntstatus ( ret , NT_STATUS_HASH_NOT_SUPPORTED ) ;
2018-11-06 18:25:00 +03:00
}
2008-05-27 10:20:18 +04:00
2018-11-06 18:25:00 +03:00
gnutls_hash_deinit ( hash_hnd ,
signed_reply . signed_packet . data +
sign_request . packet_to_sign . length + 4 ) ;
2008-05-27 10:20:18 +04:00
2008-05-29 09:20:58 +04:00
/* Place it into the packet for the wire */
2010-05-09 19:20:01 +04:00
ndr_err = ndr_push_struct_blob ( output , mem_ctx , & signed_reply ,
2008-05-29 05:16:03 +04:00
( ndr_push_flags_fn_t ) ndr_push_signed_reply ) ;
if ( ! NDR_ERR_CODE_IS_SUCCESS ( ndr_err ) ) {
DEBUG ( 1 , ( " failed to push ntp error reply \n " ) ) ;
return ndr_map_error2ntstatus ( ndr_err ) ;
}
2010-01-12 19:30:04 +03:00
return NT_STATUS_OK ;
2008-05-27 10:20:18 +04:00
}
/*
2010-01-12 19:30:04 +03:00
called on a tcp recv
2008-05-27 10:20:18 +04:00
*/
2010-01-12 19:30:04 +03:00
static void ntp_signd_recv ( struct stream_connection * conn , uint16_t flags )
2008-05-27 10:20:18 +04:00
{
2010-01-12 19:30:04 +03:00
struct ntp_signd_connection * ntp_signd_conn = talloc_get_type ( conn - > private_data ,
struct ntp_signd_connection ) ;
ntp_signd_terminate_connection ( ntp_signd_conn ,
" ntp_signd_recv: called " ) ;
2008-05-27 10:20:18 +04:00
}
/*
2010-01-12 19:30:04 +03:00
called when we can write to a connection
2008-05-27 10:20:18 +04:00
*/
2010-01-12 19:30:04 +03:00
static void ntp_signd_send ( struct stream_connection * conn , uint16_t flags )
2008-05-27 10:20:18 +04:00
{
2010-01-12 19:30:04 +03:00
struct ntp_signd_connection * ntp_signd_conn = talloc_get_type ( conn - > private_data ,
struct ntp_signd_connection ) ;
/* this should never be triggered! */
ntp_signd_terminate_connection ( ntp_signd_conn ,
" ntp_signd_send: called " ) ;
2008-05-27 10:20:18 +04:00
}
2010-01-12 19:30:04 +03:00
struct ntp_signd_call {
struct ntp_signd_connection * ntp_signd_conn ;
DATA_BLOB in ;
DATA_BLOB out ;
uint8_t out_hdr [ 4 ] ;
struct iovec out_iov [ 2 ] ;
} ;
static void ntp_signd_call_writev_done ( struct tevent_req * subreq ) ;
static void ntp_signd_call_loop ( struct tevent_req * subreq )
2008-05-27 10:20:18 +04:00
{
2010-01-12 19:30:04 +03:00
struct ntp_signd_connection * ntp_signd_conn = tevent_req_callback_data ( subreq ,
struct ntp_signd_connection ) ;
struct ntp_signd_call * call ;
NTSTATUS status ;
call = talloc ( ntp_signd_conn , struct ntp_signd_call ) ;
if ( call = = NULL ) {
ntp_signd_terminate_connection ( ntp_signd_conn ,
" ntp_signd_call_loop: "
" no memory for ntp_signd_call " ) ;
return ;
}
call - > ntp_signd_conn = ntp_signd_conn ;
status = tstream_read_pdu_blob_recv ( subreq ,
call ,
& call - > in ) ;
TALLOC_FREE ( subreq ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
const char * reason ;
reason = talloc_asprintf ( call , " ntp_signd_call_loop: "
" tstream_read_pdu_blob_recv() - %s " ,
nt_errstr ( status ) ) ;
if ( reason = = NULL ) {
reason = nt_errstr ( status ) ;
}
ntp_signd_terminate_connection ( ntp_signd_conn , reason ) ;
return ;
}
DEBUG ( 10 , ( " Received NTP TCP packet of length %lu from %s \n " ,
( long ) call - > in . length ,
tsocket_address_string ( ntp_signd_conn - > conn - > remote_address , call ) ) ) ;
/* skip length header */
call - > in . data + = 4 ;
call - > in . length - = 4 ;
status = ntp_signd_process ( ntp_signd_conn ,
call ,
& call - > in ,
& call - > out ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
const char * reason ;
reason = talloc_asprintf ( call , " ntp_signd_process failed: %s " ,
nt_errstr ( status ) ) ;
if ( reason = = NULL ) {
reason = nt_errstr ( status ) ;
}
ntp_signd_terminate_connection ( ntp_signd_conn , reason ) ;
return ;
}
/* First add the length of the out buffer */
RSIVAL ( call - > out_hdr , 0 , call - > out . length ) ;
2010-06-30 00:33:32 +04:00
call - > out_iov [ 0 ] . iov_base = ( char * ) call - > out_hdr ;
2010-01-12 19:30:04 +03:00
call - > out_iov [ 0 ] . iov_len = 4 ;
2010-06-30 00:33:32 +04:00
call - > out_iov [ 1 ] . iov_base = ( char * ) call - > out . data ;
2010-01-12 19:30:04 +03:00
call - > out_iov [ 1 ] . iov_len = call - > out . length ;
subreq = tstream_writev_queue_send ( call ,
ntp_signd_conn - > conn - > event . ctx ,
ntp_signd_conn - > tstream ,
ntp_signd_conn - > send_queue ,
call - > out_iov , 2 ) ;
if ( subreq = = NULL ) {
ntp_signd_terminate_connection ( ntp_signd_conn , " ntp_signd_call_loop: "
" no memory for tstream_writev_queue_send " ) ;
return ;
}
tevent_req_set_callback ( subreq , ntp_signd_call_writev_done , call ) ;
/*
* The NTP tcp pdu ' s has the length as 4 byte ( initial_read_size ) ,
2016-09-22 00:24:45 +03:00
* tstream_full_request_u32 provides the pdu length then .
2010-01-12 19:30:04 +03:00
*/
subreq = tstream_read_pdu_blob_send ( ntp_signd_conn ,
ntp_signd_conn - > conn - > event . ctx ,
ntp_signd_conn - > tstream ,
4 , /* initial_read_size */
2016-09-22 00:24:45 +03:00
tstream_full_request_u32 ,
2010-01-12 19:30:04 +03:00
ntp_signd_conn ) ;
if ( subreq = = NULL ) {
ntp_signd_terminate_connection ( ntp_signd_conn , " ntp_signd_call_loop: "
" no memory for tstream_read_pdu_blob_send " ) ;
return ;
}
tevent_req_set_callback ( subreq , ntp_signd_call_loop , ntp_signd_conn ) ;
}
static void ntp_signd_call_writev_done ( struct tevent_req * subreq )
{
struct ntp_signd_call * call = tevent_req_callback_data ( subreq ,
struct ntp_signd_call ) ;
int sys_errno ;
int rc ;
rc = tstream_writev_queue_recv ( subreq , & sys_errno ) ;
TALLOC_FREE ( subreq ) ;
if ( rc = = - 1 ) {
const char * reason ;
reason = talloc_asprintf ( call , " ntp_signd_call_writev_done: "
" tstream_writev_queue_recv() - %d:%s " ,
sys_errno , strerror ( sys_errno ) ) ;
if ( ! reason ) {
reason = " ntp_signd_call_writev_done: "
" tstream_writev_queue_recv() failed " ;
}
ntp_signd_terminate_connection ( call - > ntp_signd_conn , reason ) ;
return ;
}
/* We don't care about errors */
talloc_free ( call ) ;
2008-05-27 10:20:18 +04:00
}
/*
called when we get a new connection
*/
static void ntp_signd_accept ( struct stream_connection * conn )
{
2010-01-12 19:30:04 +03:00
struct ntp_signd_server * ntp_signd = talloc_get_type ( conn - > private_data ,
struct ntp_signd_server ) ;
struct ntp_signd_connection * ntp_signd_conn ;
struct tevent_req * subreq ;
int rc ;
ntp_signd_conn = talloc_zero ( conn , struct ntp_signd_connection ) ;
if ( ntp_signd_conn = = NULL ) {
stream_terminate_connection ( conn ,
" ntp_signd_accept: out of memory " ) ;
return ;
}
ntp_signd_conn - > send_queue = tevent_queue_create ( conn ,
" ntp_signd_accept " ) ;
if ( ntp_signd_conn - > send_queue = = NULL ) {
stream_terminate_connection ( conn ,
" ntp_signd_accept: out of memory " ) ;
return ;
}
TALLOC_FREE ( conn - > event . fde ) ;
2008-05-27 10:20:18 +04:00
2010-02-26 12:19:55 +03:00
rc = tstream_bsd_existing_socket ( ntp_signd_conn ,
2010-01-12 19:30:04 +03:00
socket_get_fd ( conn - > socket ) ,
& ntp_signd_conn - > tstream ) ;
if ( rc < 0 ) {
stream_terminate_connection ( conn ,
" ntp_signd_accept: out of memory " ) ;
2008-05-27 10:20:18 +04:00
return ;
}
2023-01-12 12:42:14 +03:00
/* as server we want to fail early */
tstream_bsd_fail_readv_first_error ( ntp_signd_conn - > tstream , true ) ;
2008-05-27 10:20:18 +04:00
2010-01-12 19:30:04 +03:00
ntp_signd_conn - > conn = conn ;
ntp_signd_conn - > ntp_signd = ntp_signd ;
conn - > private_data = ntp_signd_conn ;
/*
* The NTP tcp pdu ' s has the length as 4 byte ( initial_read_size ) ,
2016-09-22 00:24:45 +03:00
* tstream_full_request_u32 provides the pdu length then .
2010-01-12 19:30:04 +03:00
*/
subreq = tstream_read_pdu_blob_send ( ntp_signd_conn ,
ntp_signd_conn - > conn - > event . ctx ,
ntp_signd_conn - > tstream ,
4 , /* initial_read_size */
2016-09-22 00:24:45 +03:00
tstream_full_request_u32 ,
2010-01-12 19:30:04 +03:00
ntp_signd_conn ) ;
if ( subreq = = NULL ) {
ntp_signd_terminate_connection ( ntp_signd_conn ,
" ntp_signd_accept: "
" no memory for tstream_read_pdu_blob_send " ) ;
2008-05-27 10:20:18 +04:00
return ;
}
2010-01-12 19:30:04 +03:00
tevent_req_set_callback ( subreq , ntp_signd_call_loop , ntp_signd_conn ) ;
2008-05-27 10:20:18 +04:00
}
static const struct stream_server_ops ntp_signd_stream_ops = {
. name = " ntp_signd " ,
. accept_connection = ntp_signd_accept ,
2010-01-12 19:30:04 +03:00
. recv_handler = ntp_signd_recv ,
2008-05-27 10:20:18 +04:00
. send_handler = ntp_signd_send
} ;
/*
startup the ntp_signd task
*/
2018-08-23 00:35:52 +03:00
static NTSTATUS ntp_signd_task_init ( struct task_server * task )
2008-05-27 10:20:18 +04:00
{
struct ntp_signd_server * ntp_signd ;
NTSTATUS status ;
2008-05-29 09:20:58 +04:00
const char * address ;
2013-01-08 17:21:23 +04:00
if ( ! directory_create_or_exist_strict ( lpcfg_ntp_signd_socket_directory ( task - > lp_ctx ) , geteuid ( ) , 0750 ) ) {
2008-05-29 09:20:58 +04:00
char * error = talloc_asprintf ( task , " Cannot create NTP signd pipe directory: %s " ,
2010-07-16 08:32:42 +04:00
lpcfg_ntp_signd_socket_directory ( task - > lp_ctx ) ) ;
2008-05-29 09:20:58 +04:00
task_server_terminate ( task ,
2009-09-19 05:05:55 +04:00
error , true ) ;
2018-08-23 00:35:52 +03:00
return NT_STATUS_UNSUCCESSFUL ;
2008-05-29 09:20:58 +04:00
}
2008-05-27 10:20:18 +04:00
task_server_set_title ( task , " task[ntp_signd] " ) ;
ntp_signd = talloc ( task , struct ntp_signd_server ) ;
if ( ntp_signd = = NULL ) {
2009-09-19 05:05:55 +04:00
task_server_terminate ( task , " ntp_signd: out of memory " , true ) ;
2018-08-23 00:35:52 +03:00
return NT_STATUS_NO_MEMORY ;
2008-05-27 10:20:18 +04:00
}
ntp_signd - > task = task ;
2008-05-29 05:16:03 +04:00
/* Must be system to get at the password hashes */
2018-04-11 21:41:30 +03:00
ntp_signd - > samdb = samdb_connect ( ntp_signd ,
task - > event_ctx ,
task - > lp_ctx ,
system_session ( task - > lp_ctx ) ,
NULL ,
0 ) ;
2008-05-27 10:20:18 +04:00
if ( ntp_signd - > samdb = = NULL ) {
2009-09-19 05:05:55 +04:00
task_server_terminate ( task , " ntp_signd failed to open samdb " , true ) ;
2018-08-23 00:35:52 +03:00
return NT_STATUS_UNSUCCESSFUL ;
2008-05-27 10:20:18 +04:00
}
2010-07-16 08:32:42 +04:00
address = talloc_asprintf ( ntp_signd , " %s/socket " , lpcfg_ntp_signd_socket_directory ( task - > lp_ctx ) ) ;
2018-08-23 00:35:52 +03:00
if ( address = = NULL ) {
task_server_terminate (
task , " ntp_signd out of memory in talloc_asprintf() " , true ) ;
return NT_STATUS_NO_MEMORY ;
}
2008-05-29 09:20:58 +04:00
2010-11-15 02:12:22 +03:00
status = stream_setup_socket ( ntp_signd - > task ,
ntp_signd - > task - > event_ctx ,
2008-05-28 07:21:26 +04:00
ntp_signd - > task - > lp_ctx ,
2017-09-18 04:05:24 +03:00
task - > model_ops ,
2008-05-28 07:21:26 +04:00
& ntp_signd_stream_ops ,
" unix " , address , NULL ,
2010-07-16 08:32:42 +04:00
lpcfg_socket_options ( ntp_signd - > task - > lp_ctx ) ,
2017-09-14 22:09:23 +03:00
ntp_signd ,
ntp_signd - > task - > process_context ) ;
2008-05-28 07:21:26 +04:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
DEBUG ( 0 , ( " Failed to bind to %s - %s \n " ,
address , nt_errstr ( status ) ) ) ;
2018-08-23 00:35:52 +03:00
return status ;
2008-05-28 07:21:26 +04:00
}
2018-08-23 00:35:52 +03:00
return NT_STATUS_OK ;
2008-05-27 10:20:18 +04:00
}
/* called at smbd startup - register ourselves as a server service */
2017-04-20 22:24:43 +03:00
NTSTATUS server_service_ntp_signd_init ( TALLOC_CTX * ctx )
2008-05-27 10:20:18 +04:00
{
2018-08-23 00:29:56 +03:00
static const struct service_details details = {
2017-09-14 22:09:23 +03:00
. inhibit_fork_on_accept = true ,
2018-08-23 00:35:52 +03:00
. inhibit_pre_fork = true ,
. task_init = ntp_signd_task_init ,
. post_fork = NULL
2017-09-14 22:09:23 +03:00
} ;
2018-08-23 00:35:52 +03:00
return register_server_service ( ctx , " ntp_signd " , & details ) ;
2008-05-27 10:20:18 +04:00
}