diff options
Diffstat (limited to 'source3/rpc_client/cli_netlogon.c')
-rw-r--r-- | source3/rpc_client/cli_netlogon.c | 1175 |
1 files changed, 298 insertions, 877 deletions
diff --git a/source3/rpc_client/cli_netlogon.c b/source3/rpc_client/cli_netlogon.c index e192e4ca26..2af514320e 100644 --- a/source3/rpc_client/cli_netlogon.c +++ b/source3/rpc_client/cli_netlogon.c @@ -1,20 +1,21 @@ -/* +/* Unix SMB/CIFS implementation. NT Domain Authentication SMB / MSRPC client Copyright (C) Andrew Tridgell 1992-2000 Copyright (C) Jeremy Allison 1998. Largely re-written by Jeremy Allison (C) 2005. + Copyright (C) Guenther Deschner 2008. 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/>. */ @@ -27,57 +28,19 @@ private data. Only call this via rpccli_netlogon_setup_creds(). JRA. */ -static NTSTATUS rpccli_net_req_chal(struct rpc_pipe_client *cli, - TALLOC_CTX *mem_ctx, - const char *server_name, - const char *clnt_name, - const DOM_CHAL *clnt_chal_in, - DOM_CHAL *srv_chal_out) -{ - prs_struct qbuf, rbuf; - NET_Q_REQ_CHAL q; - NET_R_REQ_CHAL r; - NTSTATUS result = NT_STATUS_UNSUCCESSFUL; - - /* create and send a MSRPC command with api NET_REQCHAL */ - - DEBUG(4,("cli_net_req_chal: LSA Request Challenge from %s to %s\n", - clnt_name, server_name)); - - /* store the parameters */ - init_q_req_chal(&q, server_name, clnt_name, clnt_chal_in); - - /* Marshall data and send request */ - CLI_DO_RPC(cli, mem_ctx, PI_NETLOGON, NET_REQCHAL, - q, r, - qbuf, rbuf, - net_io_q_req_chal, - net_io_r_req_chal, - NT_STATUS_UNSUCCESSFUL); - - result = r.status; - - /* Return result */ - - if (NT_STATUS_IS_OK(result)) { - /* Store the returned server challenge. */ - *srv_chal_out = r.srv_chal; - } - - return result; -} +/* instead of rpccli_net_req_chal() we use rpccli_netr_ServerReqChallenge() now - gd */ #if 0 /**************************************************************************** LSA Authenticate 2 Send the client credential, receive back a server credential. -Ensure that the server credential returned matches the session key +Ensure that the server credential returned matches the session key encrypt of the server challenge originally received. JRA. ****************************************************************************/ - NTSTATUS rpccli_net_auth2(struct rpc_pipe_client *cli, - uint16 sec_chan, + NTSTATUS rpccli_net_auth2(struct rpc_pipe_client *cli, + uint16 sec_chan, uint32 *neg_flags, DOM_CHAL *srv_chal) { prs_struct qbuf, rbuf; @@ -90,7 +53,7 @@ encrypt of the server challenge originally received. JRA. fstr_sprintf( machine_acct, "%s$", lp_workgroup() ); else fstrcpy( machine_acct, cli->mach_acct ); - + /* create and send a MSRPC command with api NET_AUTH2 */ DEBUG(4,("cli_net_auth2: srv:%s acct:%s sc:%x mc: %s chal %s neg: %x\n", @@ -99,8 +62,8 @@ encrypt of the server challenge originally received. JRA. /* store the parameters */ - init_q_auth_2(&q, cli->srv_name_slash, machine_acct, - sec_chan, global_myname(), &cli->clnt_cred.challenge, + init_q_auth_2(&q, cli->srv_name_slash, machine_acct, + sec_chan, global_myname(), &cli->clnt_cred.challenge, *neg_flags); /* turn parameters into data stream */ @@ -116,7 +79,7 @@ encrypt of the server challenge originally received. JRA. if (NT_STATUS_IS_OK(result)) { UTIME zerotime; - + /* * Check the returned value using the initial * server received challenge. @@ -143,106 +106,12 @@ password ?).\n", cli->cli->desthost )); LSA Authenticate 2 Send the client credential, receive back a server credential. - The caller *must* ensure that the server credential returned matches the session key - encrypt of the server challenge originally received. JRA. -****************************************************************************/ - -static NTSTATUS rpccli_net_auth2(struct rpc_pipe_client *cli, - TALLOC_CTX *mem_ctx, - const char *server_name, - const char *account_name, - uint16 sec_chan_type, - const char *computer_name, - uint32 *neg_flags_inout, - const DOM_CHAL *clnt_chal_in, - DOM_CHAL *srv_chal_out) -{ - prs_struct qbuf, rbuf; - NET_Q_AUTH_2 q; - NET_R_AUTH_2 r; - NTSTATUS result = NT_STATUS_UNSUCCESSFUL; - - /* create and send a MSRPC command with api NET_AUTH2 */ - - DEBUG(4,("cli_net_auth2: srv:%s acct:%s sc:%x mc: %s neg: %x\n", - server_name, account_name, sec_chan_type, computer_name, - *neg_flags_inout)); - - /* store the parameters */ - - init_q_auth_2(&q, server_name, account_name, sec_chan_type, - computer_name, clnt_chal_in, *neg_flags_inout); - - /* turn parameters into data stream */ - - CLI_DO_RPC(cli, mem_ctx, PI_NETLOGON, NET_AUTH2, - q, r, - qbuf, rbuf, - net_io_q_auth_2, - net_io_r_auth_2, - NT_STATUS_UNSUCCESSFUL); - - result = r.status; - - if (NT_STATUS_IS_OK(result)) { - *srv_chal_out = r.srv_chal; - *neg_flags_inout = r.srv_flgs.neg_flags; - } - - return result; -} - -#if 0 /* not currebntly used */ -/**************************************************************************** - LSA Authenticate 3 - - Send the client credential, receive back a server credential. - The caller *must* ensure that the server credential returned matches the session key + The caller *must* ensure that the server credential returned matches the session key encrypt of the server challenge originally received. JRA. ****************************************************************************/ -static NTSTATUS rpccli_net_auth3(struct rpc_pipe_client *cli, - TALLOC_CTX *mem_ctx, - const char *server_name, - const char *account_name, - uint16 sec_chan_type, - const char *computer_name, - uint32 *neg_flags_inout, - const DOM_CHAL *clnt_chal_in, - DOM_CHAL *srv_chal_out) -{ - prs_struct qbuf, rbuf; - NET_Q_AUTH_3 q; - NET_R_AUTH_3 r; - NTSTATUS result = NT_STATUS_UNSUCCESSFUL; - - /* create and send a MSRPC command with api NET_AUTH2 */ - - DEBUG(4,("cli_net_auth3: srv:%s acct:%s sc:%x mc: %s chal %s neg: %x\n", - server_name, account_name, sec_chan_type, computer_name, - credstr(clnt_chal_in->data), *neg_flags_inout)); - - /* store the parameters */ - init_q_auth_3(&q, server_name, account_name, sec_chan_type, - computer_name, clnt_chal_in, *neg_flags_inout); - - /* turn parameters into data stream */ +/* instead of rpccli_net_auth2() we use rpccli_netr_ServerAuthenticate2() now - gd */ - CLI_DO_RPC(cli, mem_ctx, PI_NETLOGON, NET_AUTH3, - q, r, - qbuf, rbuf, - net_io_q_auth_3, - net_io_r_auth_3, - NT_STATUS_UNSUCCESSFUL); - - if (NT_STATUS_IS_OK(result)) { - *srv_chal_out = r.srv_chal; - *neg_flags_inout = r.srv_flgs.neg_flags; - } - - return result; -} -#endif /* not currebntly used */ /**************************************************************************** Wrapper function that uses the auth and auth2 calls to set up a NETLOGON @@ -251,17 +120,17 @@ static NTSTATUS rpccli_net_auth3(struct rpc_pipe_client *cli, ****************************************************************************/ NTSTATUS rpccli_netlogon_setup_creds(struct rpc_pipe_client *cli, - const char *server_name, - const char *domain, - const char *clnt_name, - const char *machine_account, - const unsigned char machine_pwd[16], - uint32 sec_chan_type, - uint32 *neg_flags_inout) + const char *server_name, + const char *domain, + const char *clnt_name, + const char *machine_account, + const unsigned char machine_pwd[16], + enum netr_SchannelType sec_chan_type, + uint32_t *neg_flags_inout) { NTSTATUS result = NT_STATUS_UNSUCCESSFUL; - DOM_CHAL clnt_chal_send; - DOM_CHAL srv_chal_recv; + struct netr_Credential clnt_chal_send; + struct netr_Credential srv_chal_recv; struct dcinfo *dc; SMB_ASSERT(cli->pipe_idx == PI_NETLOGON); @@ -288,13 +157,11 @@ NTSTATUS rpccli_netlogon_setup_creds(struct rpc_pipe_client *cli, generate_random_buffer(clnt_chal_send.data, 8); /* Get the server challenge. */ - result = rpccli_net_req_chal(cli, - cli->mem_ctx, - dc->remote_machine, - clnt_name, - &clnt_chal_send, - &srv_chal_recv); - + result = rpccli_netr_ServerReqChallenge(cli, cli->mem_ctx, + dc->remote_machine, + clnt_name, + &clnt_chal_send, + &srv_chal_recv); if (!NT_STATUS_IS_OK(result)) { return result; } @@ -307,20 +174,18 @@ NTSTATUS rpccli_netlogon_setup_creds(struct rpc_pipe_client *cli, machine_pwd, &clnt_chal_send); - /* - * Send client auth-2 challenge and receive server repy. - */ - - result = rpccli_net_auth2(cli, - cli->mem_ctx, - dc->remote_machine, - dc->mach_acct, - sec_chan_type, - clnt_name, - neg_flags_inout, - &clnt_chal_send, /* input. */ - &srv_chal_recv); /* output */ + /* + * Send client auth-2 challenge and receive server repy. + */ + result = rpccli_netr_ServerAuthenticate2(cli, cli->mem_ctx, + dc->remote_machine, + dc->mach_acct, + sec_chan_type, + clnt_name, + &clnt_chal_send, /* input. */ + &srv_chal_recv, /* output. */ + neg_flags_inout); if (!NT_STATUS_IS_OK(result)) { return result; } @@ -330,7 +195,7 @@ NTSTATUS rpccli_netlogon_setup_creds(struct rpc_pipe_client *cli, * server received challenge. */ - if (!creds_client_check(dc, &srv_chal_recv)) { + if (!netlogon_creds_client_check(dc, &srv_chal_recv)) { /* * Server replied with bad credential. Fail. */ @@ -347,502 +212,6 @@ NTSTATUS rpccli_netlogon_setup_creds(struct rpc_pipe_client *cli, return NT_STATUS_OK; } -/* Logon Control 2 */ - -NTSTATUS rpccli_netlogon_logon_ctrl2(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, - uint32 query_level) -{ - prs_struct qbuf, rbuf; - NET_Q_LOGON_CTRL2 q; - NET_R_LOGON_CTRL2 r; - NTSTATUS result = NT_STATUS_UNSUCCESSFUL; - fstring server; - - ZERO_STRUCT(q); - ZERO_STRUCT(r); - - /* Initialise input parameters */ - - slprintf(server, sizeof(fstring)-1, "\\\\%s", cli->cli->desthost); - init_net_q_logon_ctrl2(&q, server, query_level); - - /* Marshall data and send request */ - - CLI_DO_RPC(cli, mem_ctx, PI_NETLOGON, NET_LOGON_CTRL2, - q, r, - qbuf, rbuf, - net_io_q_logon_ctrl2, - net_io_r_logon_ctrl2, - NT_STATUS_UNSUCCESSFUL); - - result = r.status; - return result; -} - -/* GetAnyDCName */ - -WERROR rpccli_netlogon_getanydcname(struct rpc_pipe_client *cli, - TALLOC_CTX *mem_ctx, const char *mydcname, - const char *domainname, char **newdcname) -{ - prs_struct qbuf, rbuf; - NET_Q_GETANYDCNAME q; - NET_R_GETANYDCNAME r; - WERROR result; - fstring mydcname_slash; - - ZERO_STRUCT(q); - ZERO_STRUCT(r); - - /* Initialise input parameters */ - - slprintf(mydcname_slash, sizeof(fstring)-1, "\\\\%s", mydcname); - init_net_q_getanydcname(&q, mydcname_slash, domainname); - - /* Marshall data and send request */ - - CLI_DO_RPC_WERR(cli, mem_ctx, PI_NETLOGON, NET_GETANYDCNAME, - q, r, - qbuf, rbuf, - net_io_q_getanydcname, - net_io_r_getanydcname, - WERR_GENERAL_FAILURE); - - result = r.status; - - if (W_ERROR_IS_OK(result) && newdcname) { - *newdcname = rpcstr_pull_unistr2_talloc(mem_ctx, &r.uni_dcname); - W_ERROR_HAVE_NO_MEMORY(*newdcname); - } - - return result; -} - -/* GetDCName */ - -WERROR rpccli_netlogon_getdcname(struct rpc_pipe_client *cli, - TALLOC_CTX *mem_ctx, const char *mydcname, - const char *domainname, char **newdcname) -{ - prs_struct qbuf, rbuf; - NET_Q_GETDCNAME q; - NET_R_GETDCNAME r; - WERROR result; - fstring mydcname_slash; - - ZERO_STRUCT(q); - ZERO_STRUCT(r); - - /* Initialise input parameters */ - - slprintf(mydcname_slash, sizeof(fstring)-1, "\\\\%s", mydcname); - init_net_q_getdcname(&q, mydcname_slash, domainname); - - /* Marshall data and send request */ - - CLI_DO_RPC_WERR(cli, mem_ctx, PI_NETLOGON, NET_GETDCNAME, - q, r, - qbuf, rbuf, - net_io_q_getdcname, - net_io_r_getdcname, - WERR_GENERAL_FAILURE); - - result = r.status; - - if (W_ERROR_IS_OK(result) && newdcname) { - *newdcname = rpcstr_pull_unistr2_talloc(mem_ctx, &r.uni_dcname); - W_ERROR_HAVE_NO_MEMORY(*newdcname); - } - - return result; -} - -static WERROR pull_domain_controller_info_from_getdcname_reply(TALLOC_CTX *mem_ctx, - struct DS_DOMAIN_CONTROLLER_INFO **info_out, - NET_R_DSR_GETDCNAME *r) -{ - struct DS_DOMAIN_CONTROLLER_INFO *info; - - info = TALLOC_ZERO_P(mem_ctx, struct DS_DOMAIN_CONTROLLER_INFO); - if (!info) { - return WERR_NOMEM; - } - - if (&r->uni_dc_unc) { - - char *tmp; - tmp = rpcstr_pull_unistr2_talloc(mem_ctx, &r->uni_dc_unc); - if (tmp == NULL) { - return WERR_GENERAL_FAILURE; - } - if (*tmp == '\\') tmp += 1; - if (*tmp == '\\') tmp += 1; - - info->domain_controller_name = talloc_strdup(mem_ctx, tmp); - if (info->domain_controller_name == NULL) { - return WERR_GENERAL_FAILURE; - } - } - - if (&r->uni_dc_address) { - - char *tmp; - tmp = rpcstr_pull_unistr2_talloc(mem_ctx, &r->uni_dc_address); - if (tmp == NULL) { - return WERR_GENERAL_FAILURE; - } - if (*tmp == '\\') tmp += 1; - if (*tmp == '\\') tmp += 1; - - info->domain_controller_address = talloc_strdup(mem_ctx, tmp); - if (info->domain_controller_address == NULL) { - return WERR_GENERAL_FAILURE; - } - } - - info->domain_controller_address_type = r->dc_address_type; - - info->domain_guid = (struct GUID *)talloc_memdup( - mem_ctx, &r->domain_guid, sizeof(struct GUID)); - if (!info->domain_guid) { - return WERR_GENERAL_FAILURE; - } - - if (&r->uni_domain_name) { - info->domain_name = rpcstr_pull_unistr2_talloc(mem_ctx, &r->uni_domain_name); - if (!info->domain_name) { - return WERR_GENERAL_FAILURE; - } - } - - if (&r->uni_forest_name) { - info->dns_forest_name = rpcstr_pull_unistr2_talloc(mem_ctx, &r->uni_forest_name); - if (!info->dns_forest_name) { - return WERR_GENERAL_FAILURE; - } - } - - info->flags = r->dc_flags; - - if (&r->uni_dc_site_name) { - info->dc_site_name = rpcstr_pull_unistr2_talloc(mem_ctx, &r->uni_dc_site_name); - if (!info->dc_site_name) { - return WERR_GENERAL_FAILURE; - } - } - - if (&r->uni_client_site_name) { - info->client_site_name = rpcstr_pull_unistr2_talloc(mem_ctx, &r->uni_client_site_name); - if (!info->client_site_name) { - return WERR_GENERAL_FAILURE; - } - } - - *info_out = info; - - return WERR_OK; -} - -/* Dsr_GetDCName */ - -WERROR rpccli_netlogon_dsr_getdcname(struct rpc_pipe_client *cli, - TALLOC_CTX *mem_ctx, - const char *server_name, - const char *domain_name, - struct GUID *domain_guid, - struct GUID *site_guid, - uint32_t flags, - struct DS_DOMAIN_CONTROLLER_INFO **info_out) -{ - prs_struct qbuf, rbuf; - NET_Q_DSR_GETDCNAME q; - NET_R_DSR_GETDCNAME r; - char *tmp_str; - - ZERO_STRUCT(q); - ZERO_STRUCT(r); - - /* Initialize input parameters */ - - tmp_str = talloc_asprintf(mem_ctx, "\\\\%s", server_name); - if (tmp_str == NULL) { - return WERR_NOMEM; - } - - init_net_q_dsr_getdcname(&q, tmp_str, domain_name, domain_guid, - site_guid, flags); - - /* Marshall data and send request */ - - CLI_DO_RPC_WERR(cli, mem_ctx, PI_NETLOGON, NET_DSR_GETDCNAME, - q, r, - qbuf, rbuf, - net_io_q_dsr_getdcname, - net_io_r_dsr_getdcname, - WERR_GENERAL_FAILURE); - - if (!W_ERROR_IS_OK(r.result)) { - return r.result; - } - - r.result = pull_domain_controller_info_from_getdcname_reply(mem_ctx, info_out, &r); - if (!W_ERROR_IS_OK(r.result)) { - return r.result; - } - - return WERR_OK; -} - -/* Dsr_GetDCNameEx */ - -WERROR rpccli_netlogon_dsr_getdcnameex(struct rpc_pipe_client *cli, - TALLOC_CTX *mem_ctx, - const char *server_name, - const char *domain_name, - struct GUID *domain_guid, - const char *site_name, - uint32_t flags, - struct DS_DOMAIN_CONTROLLER_INFO **info_out) -{ - prs_struct qbuf, rbuf; - NET_Q_DSR_GETDCNAMEEX q; - NET_R_DSR_GETDCNAME r; - char *tmp_str; - - ZERO_STRUCT(q); - ZERO_STRUCT(r); - - /* Initialize input parameters */ - - tmp_str = talloc_asprintf(mem_ctx, "\\\\%s", server_name); - if (tmp_str == NULL) { - return WERR_NOMEM; - } - - init_net_q_dsr_getdcnameex(&q, server_name, domain_name, domain_guid, - site_name, flags); - - /* Marshall data and send request */ - - CLI_DO_RPC_WERR(cli, mem_ctx, PI_NETLOGON, NET_DSR_GETDCNAMEEX, - q, r, - qbuf, rbuf, - net_io_q_dsr_getdcnameex, - net_io_r_dsr_getdcname, - WERR_GENERAL_FAILURE); - - if (!W_ERROR_IS_OK(r.result)) { - return r.result; - } - - r.result = pull_domain_controller_info_from_getdcname_reply(mem_ctx, info_out, &r); - if (!W_ERROR_IS_OK(r.result)) { - return r.result; - } - - return WERR_OK; -} - -/* Dsr_GetDCNameEx */ - -WERROR rpccli_netlogon_dsr_getdcnameex2(struct rpc_pipe_client *cli, - TALLOC_CTX *mem_ctx, - const char *server_name, - const char *client_account, - uint32 mask, - const char *domain_name, - struct GUID *domain_guid, - const char *site_name, - uint32_t flags, - struct DS_DOMAIN_CONTROLLER_INFO **info_out) -{ - prs_struct qbuf, rbuf; - NET_Q_DSR_GETDCNAMEEX2 q; - NET_R_DSR_GETDCNAME r; - char *tmp_str; - - ZERO_STRUCT(q); - ZERO_STRUCT(r); - - /* Initialize input parameters */ - - tmp_str = talloc_asprintf(mem_ctx, "\\\\%s", server_name); - if (tmp_str == NULL) { - return WERR_NOMEM; - } - - init_net_q_dsr_getdcnameex2(&q, server_name, domain_name, client_account, - mask, domain_guid, site_name, flags); - - /* Marshall data and send request */ - - CLI_DO_RPC_WERR(cli, mem_ctx, PI_NETLOGON, NET_DSR_GETDCNAMEEX2, - q, r, - qbuf, rbuf, - net_io_q_dsr_getdcnameex2, - net_io_r_dsr_getdcname, - WERR_GENERAL_FAILURE); - - if (!W_ERROR_IS_OK(r.result)) { - return r.result; - } - - r.result = pull_domain_controller_info_from_getdcname_reply(mem_ctx, info_out, &r); - if (!W_ERROR_IS_OK(r.result)) { - return r.result; - } - - return WERR_OK; -} - - -/* Dsr_GetSiteName */ - -WERROR rpccli_netlogon_dsr_getsitename(struct rpc_pipe_client *cli, - TALLOC_CTX *mem_ctx, - const char *computer_name, - char **site_name) -{ - prs_struct qbuf, rbuf; - NET_Q_DSR_GETSITENAME q; - NET_R_DSR_GETSITENAME r; - - ZERO_STRUCT(q); - ZERO_STRUCT(r); - - /* Initialize input parameters */ - - init_net_q_dsr_getsitename(&q, computer_name); - - /* Marshall data and send request */ - - CLI_DO_RPC_WERR(cli, mem_ctx, PI_NETLOGON, NET_DSR_GETSITENAME, - q, r, - qbuf, rbuf, - net_io_q_dsr_getsitename, - net_io_r_dsr_getsitename, - WERR_GENERAL_FAILURE); - - if (!W_ERROR_IS_OK(r.result)) { - return r.result; - } - - if ((site_name != NULL) && - ((*site_name = rpcstr_pull_unistr2_talloc( - mem_ctx, &r.uni_site_name)) == NULL)) { - return WERR_GENERAL_FAILURE; - } - - return WERR_OK; -} - - - -/* Sam synchronisation */ - -NTSTATUS rpccli_netlogon_sam_sync(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, - uint32 database_id, uint32 next_rid, uint32 *num_deltas, - SAM_DELTA_HDR **hdr_deltas, - SAM_DELTA_CTR **deltas) -{ - prs_struct qbuf, rbuf; - NET_Q_SAM_SYNC q; - NET_R_SAM_SYNC r; - NTSTATUS result = NT_STATUS_UNSUCCESSFUL; - DOM_CRED clnt_creds; - DOM_CRED ret_creds; - - ZERO_STRUCT(q); - ZERO_STRUCT(r); - - ZERO_STRUCT(ret_creds); - - /* Initialise input parameters */ - - creds_client_step(cli->dc, &clnt_creds); - - init_net_q_sam_sync(&q, cli->dc->remote_machine, global_myname(), - &clnt_creds, &ret_creds, database_id, next_rid); - - /* Marshall data and send request */ - - CLI_DO_RPC_COPY_SESS_KEY(cli, mem_ctx, PI_NETLOGON, NET_SAM_SYNC, - q, r, - qbuf, rbuf, - net_io_q_sam_sync, - net_io_r_sam_sync, - NT_STATUS_UNSUCCESSFUL); - - /* Return results */ - - result = r.status; - *num_deltas = r.num_deltas2; - *hdr_deltas = r.hdr_deltas; - *deltas = r.deltas; - - if (!NT_STATUS_IS_ERR(result)) { - /* Check returned credentials. */ - if (!creds_client_check(cli->dc, &r.srv_creds.challenge)) { - DEBUG(0,("cli_netlogon_sam_sync: credentials chain check failed\n")); - return NT_STATUS_ACCESS_DENIED; - } - } - - return result; -} - -/* Sam synchronisation */ - -NTSTATUS rpccli_netlogon_sam_deltas(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, - uint32 database_id, uint64 seqnum, - uint32 *num_deltas, - SAM_DELTA_HDR **hdr_deltas, - SAM_DELTA_CTR **deltas) -{ - prs_struct qbuf, rbuf; - NET_Q_SAM_DELTAS q; - NET_R_SAM_DELTAS r; - NTSTATUS result = NT_STATUS_UNSUCCESSFUL; - DOM_CRED clnt_creds; - - ZERO_STRUCT(q); - ZERO_STRUCT(r); - - /* Initialise input parameters */ - - creds_client_step(cli->dc, &clnt_creds); - - init_net_q_sam_deltas(&q, cli->dc->remote_machine, - global_myname(), &clnt_creds, - database_id, seqnum); - - /* Marshall data and send request */ - - CLI_DO_RPC(cli, mem_ctx, PI_NETLOGON, NET_SAM_DELTAS, - q, r, - qbuf, rbuf, - net_io_q_sam_deltas, - net_io_r_sam_deltas, - NT_STATUS_UNSUCCESSFUL); - - /* Return results */ - - result = r.status; - *num_deltas = r.num_deltas2; - *hdr_deltas = r.hdr_deltas; - *deltas = r.deltas; - - if (!NT_STATUS_IS_ERR(result)) { - /* Check returned credentials. */ - if (!creds_client_check(cli->dc, &r.srv_creds.challenge)) { - DEBUG(0,("cli_netlogon_sam_sync: credentials chain check failed\n")); - return NT_STATUS_ACCESS_DENIED; - } - } - - return result; -} - /* Logon domain user */ NTSTATUS rpccli_netlogon_sam_logon(struct rpc_pipe_client *cli, @@ -854,20 +223,23 @@ NTSTATUS rpccli_netlogon_sam_logon(struct rpc_pipe_client *cli, const char *workstation, int logon_type) { - prs_struct qbuf, rbuf; - NET_Q_SAM_LOGON q; - NET_R_SAM_LOGON r; NTSTATUS result = NT_STATUS_UNSUCCESSFUL; - DOM_CRED clnt_creds; - DOM_CRED ret_creds; - NET_ID_INFO_CTR ctr; - NET_USER_INFO_3 user; - int validation_level = 3; + struct netr_Authenticator clnt_creds; + struct netr_Authenticator ret_creds; + union netr_LogonLevel *logon; + union netr_Validation validation; + uint8_t authoritative; + int validation_level = 3; fstring clnt_name_slash; + uint8 zeros[16]; - ZERO_STRUCT(q); - ZERO_STRUCT(r); ZERO_STRUCT(ret_creds); + ZERO_STRUCT(zeros); + + logon = TALLOC_ZERO_P(mem_ctx, union netr_LogonLevel); + if (!logon) { + return NT_STATUS_NO_MEMORY; + } if (workstation) { fstr_sprintf( clnt_name_slash, "\\\\%s", workstation ); @@ -875,85 +247,143 @@ NTSTATUS rpccli_netlogon_sam_logon(struct rpc_pipe_client *cli, fstr_sprintf( clnt_name_slash, "\\\\%s", global_myname() ); } - /* Initialise input parameters */ + /* Initialise input parameters */ - creds_client_step(cli->dc, &clnt_creds); + netlogon_creds_client_step(cli->dc, &clnt_creds); - q.validation_level = validation_level; + switch (logon_type) { + case INTERACTIVE_LOGON_TYPE: { - ctr.switch_value = logon_type; + struct netr_PasswordInfo *password_info; - switch (logon_type) { - case INTERACTIVE_LOGON_TYPE: { - unsigned char lm_owf_user_pwd[16], nt_owf_user_pwd[16]; + struct samr_Password lmpassword; + struct samr_Password ntpassword; - nt_lm_owf_gen(password, nt_owf_user_pwd, lm_owf_user_pwd); + unsigned char lm_owf_user_pwd[16], nt_owf_user_pwd[16]; - init_id_info1(&ctr.auth.id1, domain, - logon_parameters, /* param_ctrl */ - 0xdead, 0xbeef, /* LUID? */ - username, clnt_name_slash, - (const char *)cli->dc->sess_key, lm_owf_user_pwd, - nt_owf_user_pwd); + unsigned char lm_owf[16]; + unsigned char nt_owf[16]; + unsigned char key[16]; - break; - } - case NET_LOGON_TYPE: { - uint8 chal[8]; - unsigned char local_lm_response[24]; - unsigned char local_nt_response[24]; - - generate_random_buffer(chal, 8); - - SMBencrypt(password, chal, local_lm_response); - SMBNTencrypt(password, chal, local_nt_response); - - init_id_info2(&ctr.auth.id2, domain, - logon_parameters, /* param_ctrl */ - 0xdead, 0xbeef, /* LUID? */ - username, clnt_name_slash, chal, - local_lm_response, 24, local_nt_response, 24); - break; - } - default: - DEBUG(0, ("switch value %d not supported\n", - ctr.switch_value)); - return NT_STATUS_INVALID_INFO_CLASS; - } + password_info = TALLOC_ZERO_P(mem_ctx, struct netr_PasswordInfo); + if (!password_info) { + return NT_STATUS_NO_MEMORY; + } - r.user = &user; + nt_lm_owf_gen(password, nt_owf_user_pwd, lm_owf_user_pwd); - init_sam_info(&q.sam_id, cli->dc->remote_machine, global_myname(), - &clnt_creds, &ret_creds, logon_type, - &ctr); +#ifdef DEBUG_PASSWORD + DEBUG(100,("lm cypher:")); + dump_data(100, lm_owf_user_pwd, 16); - /* Marshall data and send request */ + DEBUG(100,("nt cypher:")); + dump_data(100, nt_owf_user_pwd, 16); +#endif + memset(key, 0, 16); + memcpy(key, cli->dc->sess_key, 8); - CLI_DO_RPC(cli, mem_ctx, PI_NETLOGON, NET_SAMLOGON, - q, r, - qbuf, rbuf, - net_io_q_sam_logon, - net_io_r_sam_logon, - NT_STATUS_UNSUCCESSFUL); + memcpy(lm_owf, lm_owf_user_pwd, 16); + SamOEMhash(lm_owf, key, 16); + memcpy(nt_owf, nt_owf_user_pwd, 16); + SamOEMhash(nt_owf, key, 16); - /* Return results */ +#ifdef DEBUG_PASSWORD + DEBUG(100,("encrypt of lm owf password:")); + dump_data(100, lm_owf, 16); - result = r.status; + DEBUG(100,("encrypt of nt owf password:")); + dump_data(100, nt_owf, 16); +#endif + memcpy(lmpassword.hash, lm_owf, 16); + memcpy(ntpassword.hash, nt_owf, 16); + + init_netr_PasswordInfo(password_info, + domain, + logon_parameters, + 0xdead, + 0xbeef, + username, + clnt_name_slash, + lmpassword, + ntpassword); + + logon->password = password_info; + + break; + } + case NET_LOGON_TYPE: { + struct netr_NetworkInfo *network_info; + uint8 chal[8]; + unsigned char local_lm_response[24]; + unsigned char local_nt_response[24]; + struct netr_ChallengeResponse lm; + struct netr_ChallengeResponse nt; + + ZERO_STRUCT(lm); + ZERO_STRUCT(nt); + + network_info = TALLOC_ZERO_P(mem_ctx, struct netr_NetworkInfo); + if (!network_info) { + return NT_STATUS_NO_MEMORY; + } - if (r.buffer_creds) { + generate_random_buffer(chal, 8); + + SMBencrypt(password, chal, local_lm_response); + SMBNTencrypt(password, chal, local_nt_response); + + lm.length = 24; + lm.data = local_lm_response; + + nt.length = 24; + nt.data = local_nt_response; + + init_netr_NetworkInfo(network_info, + domain, + logon_parameters, + 0xdead, + 0xbeef, + username, + clnt_name_slash, + chal, + nt, + lm); + + logon->network = network_info; + + break; + } + default: + DEBUG(0, ("switch value %d not supported\n", + logon_type)); + return NT_STATUS_INVALID_INFO_CLASS; + } + + result = rpccli_netr_LogonSamLogon(cli, mem_ctx, + cli->dc->remote_machine, + global_myname(), + &clnt_creds, + &ret_creds, + logon_type, + logon, + validation_level, + &validation, + &authoritative); + + if (memcmp(zeros, &ret_creds.cred.data, sizeof(ret_creds.cred.data)) != 0) { /* Check returned credentials if present. */ - if (!creds_client_check(cli->dc, &r.srv_creds.challenge)) { + if (!netlogon_creds_client_check(cli->dc, &ret_creds.cred)) { DEBUG(0,("rpccli_netlogon_sam_logon: credentials chain check failed\n")); return NT_STATUS_ACCESS_DENIED; } } - return result; + return result; } -/** - * Logon domain user with an 'network' SAM logon +/** + * Logon domain user with an 'network' SAM logon * * @param info3 Pointer to a NET_USER_INFO_3 already allocated by the caller. **/ @@ -964,31 +394,47 @@ NTSTATUS rpccli_netlogon_sam_network_logon(struct rpc_pipe_client *cli, const char *server, const char *username, const char *domain, - const char *workstation, - const uint8 chal[8], + const char *workstation, + const uint8 chal[8], DATA_BLOB lm_response, DATA_BLOB nt_response, - NET_USER_INFO_3 *info3) + struct netr_SamInfo3 **info3) { - prs_struct qbuf, rbuf; - NET_Q_SAM_LOGON q; - NET_R_SAM_LOGON r; NTSTATUS result = NT_STATUS_UNSUCCESSFUL; - NET_ID_INFO_CTR ctr; int validation_level = 3; const char *workstation_name_slash; const char *server_name_slash; uint8 zeros[16]; - DOM_CRED clnt_creds; - DOM_CRED ret_creds; - int i; + struct netr_Authenticator clnt_creds; + struct netr_Authenticator ret_creds; + union netr_LogonLevel *logon = NULL; + struct netr_NetworkInfo *network_info; + uint8_t authoritative; + union netr_Validation validation; + struct netr_ChallengeResponse lm; + struct netr_ChallengeResponse nt; + struct netr_UserSessionKey user_session_key; + struct netr_LMSessionKey lmsesskey; + + *info3 = NULL; ZERO_STRUCT(zeros); - ZERO_STRUCT(q); - ZERO_STRUCT(r); ZERO_STRUCT(ret_creds); - creds_client_step(cli->dc, &clnt_creds); + ZERO_STRUCT(lm); + ZERO_STRUCT(nt); + + logon = TALLOC_ZERO_P(mem_ctx, union netr_LogonLevel); + if (!logon) { + return NT_STATUS_NO_MEMORY; + } + + network_info = TALLOC_ZERO_P(mem_ctx, struct netr_NetworkInfo); + if (!network_info) { + return NT_STATUS_NO_MEMORY; + } + + netlogon_creds_client_step(cli->dc, &clnt_creds); if (server[0] != '\\' && server[1] != '\\') { server_name_slash = talloc_asprintf(mem_ctx, "\\\\%s", server); @@ -1009,60 +455,62 @@ NTSTATUS rpccli_netlogon_sam_network_logon(struct rpc_pipe_client *cli, /* Initialise input parameters */ - q.validation_level = validation_level; - - ctr.switch_value = NET_LOGON_TYPE; + lm.data = lm_response.data; + lm.length = lm_response.length; + nt.data = nt_response.data; + nt.length = nt_response.length; - init_id_info2(&ctr.auth.id2, domain, - logon_parameters, /* param_ctrl */ - 0xdead, 0xbeef, /* LUID? */ - username, workstation_name_slash, (const uchar*)chal, - lm_response.data, lm_response.length, nt_response.data, nt_response.length); - - init_sam_info(&q.sam_id, server_name_slash, global_myname(), - &clnt_creds, &ret_creds, NET_LOGON_TYPE, - &ctr); + init_netr_NetworkInfo(network_info, + domain, + logon_parameters, + 0xdead, + 0xbeef, + username, + workstation_name_slash, + (uint8_t *) chal, + nt, + lm); - r.user = info3; + logon->network = network_info; - /* Marshall data and send request */ - - CLI_DO_RPC(cli, mem_ctx, PI_NETLOGON, NET_SAMLOGON, - q, r, - qbuf, rbuf, - net_io_q_sam_logon, - net_io_r_sam_logon, - NT_STATUS_UNSUCCESSFUL); + /* Marshall data and send request */ - if (memcmp(zeros, info3->user_sess_key, 16) != 0) { - SamOEMhash(info3->user_sess_key, cli->dc->sess_key, 16); - } else { - memset(info3->user_sess_key, '\0', 16); + result = rpccli_netr_LogonSamLogon(cli, mem_ctx, + server_name_slash, + global_myname(), + &clnt_creds, + &ret_creds, + NET_LOGON_TYPE, + logon, + validation_level, + &validation, + &authoritative); + if (!NT_STATUS_IS_OK(result)) { + return result; } - if (memcmp(zeros, info3->lm_sess_key, 8) != 0) { - SamOEMhash(info3->lm_sess_key, cli->dc->sess_key, 8); - } else { - memset(info3->lm_sess_key, '\0', 8); - } + user_session_key = validation.sam3->base.key; + lmsesskey = validation.sam3->base.LMSessKey; - for (i=0; i < 7; i++) { - memset(&info3->unknown[i], '\0', 4); + if (memcmp(zeros, user_session_key.key, 16) != 0) { + SamOEMhash(user_session_key.key, cli->dc->sess_key, 16); } - /* Return results */ - - result = r.status; + if (memcmp(zeros, lmsesskey.key, 8) != 0) { + SamOEMhash(lmsesskey.key, cli->dc->sess_key, 8); + } - if (r.buffer_creds) { + if (memcmp(zeros, ret_creds.cred.data, sizeof(ret_creds.cred.data)) != 0) { /* Check returned credentials if present. */ - if (!creds_client_check(cli->dc, &r.srv_creds.challenge)) { + if (!netlogon_creds_client_check(cli->dc, &ret_creds.cred)) { DEBUG(0,("rpccli_netlogon_sam_network_logon: credentials chain check failed\n")); return NT_STATUS_ACCESS_DENIED; } } - return result; + *info3 = validation.sam3; + + return result; } NTSTATUS rpccli_netlogon_sam_network_logon_ex(struct rpc_pipe_client *cli, @@ -1071,26 +519,43 @@ NTSTATUS rpccli_netlogon_sam_network_logon_ex(struct rpc_pipe_client *cli, const char *server, const char *username, const char *domain, - const char *workstation, - const uint8 chal[8], + const char *workstation, + const uint8 chal[8], DATA_BLOB lm_response, DATA_BLOB nt_response, - NET_USER_INFO_3 *info3) + struct netr_SamInfo3 **info3) { - prs_struct qbuf, rbuf; - NET_Q_SAM_LOGON_EX q; - NET_R_SAM_LOGON_EX r; NTSTATUS result = NT_STATUS_UNSUCCESSFUL; - NET_ID_INFO_CTR ctr; int validation_level = 3; const char *workstation_name_slash; const char *server_name_slash; uint8 zeros[16]; - int i; + union netr_LogonLevel *logon = NULL; + struct netr_NetworkInfo *network_info; + uint8_t authoritative; + union netr_Validation validation; + struct netr_ChallengeResponse lm; + struct netr_ChallengeResponse nt; + struct netr_UserSessionKey user_session_key; + struct netr_LMSessionKey lmsesskey; + uint32_t flags = 0; + + *info3 = NULL; ZERO_STRUCT(zeros); - ZERO_STRUCT(q); - ZERO_STRUCT(r); + + ZERO_STRUCT(lm); + ZERO_STRUCT(nt); + + logon = TALLOC_ZERO_P(mem_ctx, union netr_LogonLevel); + if (!logon) { + return NT_STATUS_NO_MEMORY; + } + + network_info = TALLOC_ZERO_P(mem_ctx, struct netr_NetworkInfo); + if (!network_info) { + return NT_STATUS_NO_MEMORY; + } if (server[0] != '\\' && server[1] != '\\') { server_name_slash = talloc_asprintf(mem_ctx, "\\\\%s", server); @@ -1111,97 +576,53 @@ NTSTATUS rpccli_netlogon_sam_network_logon_ex(struct rpc_pipe_client *cli, /* Initialise input parameters */ - q.validation_level = validation_level; - - ctr.switch_value = NET_LOGON_TYPE; + lm.data = lm_response.data; + lm.length = lm_response.length; + nt.data = nt_response.data; + nt.length = nt_response.length; - init_id_info2(&ctr.auth.id2, domain, - logon_parameters, /* param_ctrl */ - 0xdead, 0xbeef, /* LUID? */ - username, workstation_name_slash, (const uchar*)chal, - lm_response.data, lm_response.length, nt_response.data, - nt_response.length); - - init_sam_info_ex(&q.sam_id, server_name_slash, global_myname(), - NET_LOGON_TYPE, &ctr); + init_netr_NetworkInfo(network_info, + domain, + logon_parameters, + 0xdead, + 0xbeef, + username, + workstation_name_slash, + (uint8_t *) chal, + nt, + lm); - r.user = info3; + logon->network = network_info; /* Marshall data and send request */ - CLI_DO_RPC(cli, mem_ctx, PI_NETLOGON, NET_SAMLOGON_EX, - q, r, qbuf, rbuf, - net_io_q_sam_logon_ex, - net_io_r_sam_logon_ex, - NT_STATUS_UNSUCCESSFUL); - - if (memcmp(zeros, info3->user_sess_key, 16) != 0) { - SamOEMhash(info3->user_sess_key, cli->dc->sess_key, 16); - } else { - memset(info3->user_sess_key, '\0', 16); + result = rpccli_netr_LogonSamLogonEx(cli, mem_ctx, + server_name_slash, + global_myname(), + NET_LOGON_TYPE, + logon, + validation_level, + &validation, + &authoritative, + &flags); + if (!NT_STATUS_IS_OK(result)) { + return result; } - if (memcmp(zeros, info3->lm_sess_key, 8) != 0) { - SamOEMhash(info3->lm_sess_key, cli->dc->sess_key, 8); - } else { - memset(info3->lm_sess_key, '\0', 8); - } + user_session_key = validation.sam3->base.key; + lmsesskey = validation.sam3->base.LMSessKey; - for (i=0; i < 7; i++) { - memset(&info3->unknown[i], '\0', 4); + if (memcmp(zeros, user_session_key.key, 16) != 0) { + SamOEMhash(user_session_key.key, cli->dc->sess_key, 16); } - /* Return results */ - - result = r.status; - - return result; -} - -/*************************************************************************** -LSA Server Password Set. -****************************************************************************/ - -NTSTATUS rpccli_net_srv_pwset(struct rpc_pipe_client *cli, TALLOC_CTX *mem_ctx, - const char *machine_name, const uint8 hashed_mach_pwd[16]) -{ - prs_struct rbuf; - prs_struct qbuf; - DOM_CRED clnt_creds; - NET_Q_SRV_PWSET q; - NET_R_SRV_PWSET r; - uint16 sec_chan_type = 2; - NTSTATUS result; - - creds_client_step(cli->dc, &clnt_creds); - - DEBUG(4,("cli_net_srv_pwset: srv:%s acct:%s sc: %d mc: %s\n", - cli->dc->remote_machine, cli->dc->mach_acct, sec_chan_type, machine_name)); - - /* store the parameters */ - init_q_srv_pwset(&q, cli->dc->remote_machine, (const char *)cli->dc->sess_key, - cli->dc->mach_acct, sec_chan_type, machine_name, - &clnt_creds, hashed_mach_pwd); - - CLI_DO_RPC(cli, mem_ctx, PI_NETLOGON, NET_SRVPWSET, - q, r, - qbuf, rbuf, - net_io_q_srv_pwset, - net_io_r_srv_pwset, - NT_STATUS_UNSUCCESSFUL); - - result = r.status; - - if (!NT_STATUS_IS_OK(result)) { - /* report error code */ - DEBUG(0,("cli_net_srv_pwset: %s\n", nt_errstr(result))); + if (memcmp(zeros, lmsesskey.key, 8) != 0) { + SamOEMhash(lmsesskey.key, cli->dc->sess_key, 8); } - /* Always check returned credentials. */ - if (!creds_client_check(cli->dc, &r.srv_cred.challenge)) { - DEBUG(0,("rpccli_net_srv_pwset: credentials chain check failed\n")); - return NT_STATUS_ACCESS_DENIED; - } + *info3 = validation.sam3; return result; + + return result; } |