From a834a73e341059be154426390304a42e4a011f72 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Wed, 25 Sep 2002 15:19:00 +0000 Subject: sync'ing up for 3.0alpha20 release (This used to be commit 65e7b5273bb58802bf0c389b77f7fcae0a1f6139) --- source3/rpc_client/cli_netlogon.c | 152 ++++++++++++++--- source3/rpc_client/cli_pipe.c | 2 +- source3/rpc_client/cli_spoolss.c | 283 +++++++++++++++++++++++++++----- source3/rpc_client/cli_spoolss_notify.c | 3 + 4 files changed, 371 insertions(+), 69 deletions(-) (limited to 'source3/rpc_client') diff --git a/source3/rpc_client/cli_netlogon.c b/source3/rpc_client/cli_netlogon.c index acc9135542..eaee3c26e7 100644 --- a/source3/rpc_client/cli_netlogon.c +++ b/source3/rpc_client/cli_netlogon.c @@ -152,11 +152,106 @@ password ?).\n", cli->desthost )); return result; } +/**************************************************************************** +LSA Authenticate 3 + +Send the client credential, receive back a server credential. +Ensure that the server credential returned matches the session key +encrypt of the server challenge originally received. JRA. +****************************************************************************/ + +NTSTATUS cli_net_auth3(struct cli_state *cli, + uint16 sec_chan, + uint32 *neg_flags, DOM_CHAL *srv_chal) +{ + prs_struct qbuf, rbuf; + NET_Q_AUTH_3 q; + NET_R_AUTH_3 r; + NTSTATUS result = NT_STATUS_UNSUCCESSFUL; + extern pstring global_myname; + + prs_init(&qbuf, MAX_PDU_FRAG_LEN, cli->mem_ctx, MARSHALL); + prs_init(&rbuf, 0, cli->mem_ctx, UNMARSHALL); + + /* 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", + cli->srv_name_slash, cli->mach_acct, sec_chan, global_myname, + credstr(cli->clnt_cred.challenge.data), *neg_flags)); + + /* store the parameters */ + init_q_auth_3(&q, cli->srv_name_slash, cli->mach_acct, + sec_chan, global_myname, &cli->clnt_cred.challenge, + *neg_flags); + + /* turn parameters into data stream */ + + if (!net_io_q_auth_3("", &q, &qbuf, 0) || + !rpc_api_pipe_req(cli, NET_AUTH3, &qbuf, &rbuf)) { + goto done; + } + + /* Unmarshall response */ + + if (!net_io_r_auth_3("", &r, &rbuf, 0)) { + goto done; + } + + result = r.status; + *neg_flags = r.srv_flgs.neg_flags; + + if (NT_STATUS_IS_OK(result)) { + UTIME zerotime; + + /* + * Check the returned value using the initial + * server received challenge. + */ + + zerotime.time = 0; + if (cred_assert( &r.srv_chal, cli->sess_key, srv_chal, + zerotime) == 0) { + + /* + * Server replied with bad credential. Fail. + */ + DEBUG(0,("cli_net_auth3: server %s replied with bad credential (bad machine \ +password ?).\n", cli->desthost )); + result = NT_STATUS_ACCESS_DENIED; + goto done; + } + } + + done: + prs_mem_free(&qbuf); + prs_mem_free(&rbuf); + + return result; +} + +/* Return the secure channel type depending on the server role. */ + +uint16 get_sec_chan(void) +{ + uint16 sec_chan = SEC_CHAN_WKSTA; + + switch (lp_server_role()) { + case ROLE_DOMAIN_PDC: + sec_chan = SEC_CHAN_DOMAIN; + break; + case ROLE_DOMAIN_BDC: + sec_chan = SEC_CHAN_BDC; + break; + } + + return sec_chan; +} + /* Initialize domain session credentials */ NTSTATUS cli_nt_setup_creds(struct cli_state *cli, uint16 sec_chan, - const unsigned char mach_pwd[16]) + const unsigned char mach_pwd[16], uint32 *neg_flags, int level) { DOM_CHAL clnt_chal; DOM_CHAL srv_chal; @@ -182,24 +277,30 @@ NTSTATUS cli_nt_setup_creds(struct cli_state *cli, cli->sess_key); memset((char *)cli->sess_key+8, '\0', 8); - /******************* Authenticate 2 ********************/ + /******************* Authenticate 2/3 ********************/ - /* calculate auth-2 credentials */ + /* calculate auth-2/3 credentials */ zerotime.time = 0; - cred_create(cli->sess_key, &clnt_chal, zerotime, - &cli->clnt_cred.challenge); + cred_create(cli->sess_key, &clnt_chal, zerotime, &cli->clnt_cred.challenge); /* - * Send client auth-2 challenge. - * Receive an auth-2 challenge response and check it. + * Send client auth-2/3 challenge. + * Receive an auth-2/3 challenge response and check it. */ - - result = cli_net_auth2(cli, sec_chan, 0x000001ff, &srv_chal); + switch (level) { + case 2: + result = cli_net_auth2(cli, sec_chan, *neg_flags, &srv_chal); + break; + case 3: + result = cli_net_auth3(cli, sec_chan, neg_flags, &srv_chal); + break; + default: + DEBUG(1,("cli_nt_setup_creds: unsupported auth level: %d\n", level)); + break; + } - if (!NT_STATUS_IS_OK(result)) { - DEBUG(1,("cli_nt_setup_creds: auth2 challenge failed %s\n", - nt_errstr(result))); - } + if (!NT_STATUS_IS_OK(result)) + DEBUG(1,("cli_nt_setup_creds: auth%d challenge failed %s\n", level, nt_errstr(result))); return result; } @@ -257,24 +358,23 @@ file. They should be combined at some stage. )-: static void gen_next_creds( struct cli_state *cli, DOM_CRED *new_clnt_cred) { - /* - * Create the new client credentials. - */ - - cli->clnt_cred.timestamp.time = time(NULL); - - memcpy(new_clnt_cred, &cli->clnt_cred, sizeof(*new_clnt_cred)); - - /* Calculate the new credentials. */ - cred_create(cli->sess_key, &(cli->clnt_cred.challenge), - new_clnt_cred->timestamp, &(new_clnt_cred->challenge)); + /* + * Create the new client credentials. + */ + + cli->clnt_cred.timestamp.time = time(NULL); + + memcpy(new_clnt_cred, &cli->clnt_cred, sizeof(*new_clnt_cred)); + /* Calculate the new credentials. */ + cred_create(cli->sess_key, &(cli->clnt_cred.challenge), + new_clnt_cred->timestamp, &(new_clnt_cred->challenge)); } /* Sam synchronisation */ NTSTATUS cli_netlogon_sam_sync(struct cli_state *cli, TALLOC_CTX *mem_ctx, DOM_CRED *ret_creds, - uint32 database_id, uint32 *num_deltas, + uint32 database_id, uint32 next_rid, uint32 *num_deltas, SAM_DELTA_HDR **hdr_deltas, SAM_DELTA_CTR **deltas) { @@ -297,7 +397,7 @@ NTSTATUS cli_netlogon_sam_sync(struct cli_state *cli, TALLOC_CTX *mem_ctx, DOM_C gen_next_creds(cli, &clnt_creds); init_net_q_sam_sync(&q, cli->srv_name_slash, cli->clnt_name_slash + 2, - &clnt_creds, ret_creds, database_id); + &clnt_creds, ret_creds, database_id, next_rid); /* Marshall data and send request */ diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index eae6be5128..0416ed3b9b 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -354,7 +354,7 @@ static BOOL rpc_api_pipe(struct cli_state *cli, uint16 cmd, prs_struct *data, pr if (!cli_api_pipe(cli, "\\PIPE\\", setup, 2, 0, /* Setup, length, max */ NULL, 0, 0, /* Params, length, max */ - pdata, data_len, data_len, /* data, length, max */ + pdata, data_len, 1024, /* data, length, max */ &rparam, &rparam_len, /* return params, len */ &prdata, &rdata_len)) /* return data, len */ { diff --git a/source3/rpc_client/cli_spoolss.c b/source3/rpc_client/cli_spoolss.c index 18e17758d6..ca24d95e33 100644 --- a/source3/rpc_client/cli_spoolss.c +++ b/source3/rpc_client/cli_spoolss.c @@ -393,7 +393,7 @@ WERROR cli_spoolss_close_printer(struct cli_state *cli, TALLOC_CTX *mem_ctx, WERROR cli_spoolss_enum_printers(struct cli_state *cli, TALLOC_CTX *mem_ctx, uint32 offered, uint32 *needed, - uint32 flags, uint32 level, + char *name, uint32 flags, uint32 level, uint32 *num_printers, PRINTER_INFO_CTR *ctr) { prs_struct qbuf, rbuf; @@ -401,14 +401,10 @@ WERROR cli_spoolss_enum_printers(struct cli_state *cli, TALLOC_CTX *mem_ctx, SPOOL_R_ENUMPRINTERS r; NEW_BUFFER buffer; WERROR result = W_ERROR(ERRgeneral); - fstring server; ZERO_STRUCT(q); ZERO_STRUCT(r); - slprintf (server, sizeof(fstring)-1, "\\\\%s", cli->desthost); - strupper (server); - /* Initialise input parameters */ init_buffer(&buffer, offered, mem_ctx); @@ -416,7 +412,7 @@ WERROR cli_spoolss_enum_printers(struct cli_state *cli, TALLOC_CTX *mem_ctx, prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); - make_spoolss_q_enumprinters(&q, flags, server, level, &buffer, + make_spoolss_q_enumprinters(&q, flags, name, level, &buffer, offered); /* Marshall data and send request */ @@ -665,7 +661,8 @@ WERROR cli_spoolss_setprinter(struct cli_state *cli, TALLOC_CTX *mem_ctx, prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); - make_spoolss_q_setprinter(mem_ctx, &q, pol, level, ctr, command); + if (!make_spoolss_q_setprinter(mem_ctx, &q, pol, level, ctr, command)) + goto done; /* Marshall data and send request */ @@ -771,6 +768,9 @@ WERROR cli_spoolss_getprinterdriver(struct cli_state *cli, case 3: decode_printer_driver_3(mem_ctx, r.buffer, 1, &ctr->info3); break; + default: + DEBUG(10, ("cli_spoolss_getprinterdriver: unknown info level %d", level)); + return WERR_UNKNOWN_LEVEL; } done: @@ -852,6 +852,10 @@ WERROR cli_spoolss_enumprinterdrivers (struct cli_state *cli, case 3: decode_printer_driver_3(mem_ctx, r.buffer, r.returned, &ctr->info3); break; + default: + DEBUG(10, ("cli_spoolss_enumprinterdrivers: unknown info level %d\n", + level)); + return WERR_UNKNOWN_LEVEL; } } @@ -1332,8 +1336,16 @@ WERROR cli_spoolss_getform(struct cli_state *cli, TALLOC_CTX *mem_ctx, if (needed) *needed = r.needed; - if (W_ERROR_IS_OK(result)) - smb_io_form_1("", r.buffer, form, 0); + if (W_ERROR_IS_OK(result)) { + switch(level) { + case 1: + smb_io_form_1("", r.buffer, form, 0); + break; + default: + DEBUG(10, ("cli_spoolss_getform: unknown info level %d", level)); + return WERR_UNKNOWN_LEVEL; + } + } done: prs_mem_free(&qbuf); @@ -1556,11 +1568,11 @@ WERROR cli_spoolss_enumjobs(struct cli_state *cli, TALLOC_CTX *mem_ctx, switch(level) { case 1: decode_jobs_1(mem_ctx, r.buffer, r.returned, - ctr->job.job_info_1); + &ctr->job.job_info_1); break; case 2: decode_jobs_2(mem_ctx, r.buffer, r.returned, - ctr->job.job_info_2); + &ctr->job.job_info_2); break; default: DEBUG(3, ("unsupported info level %d", level)); @@ -1669,10 +1681,10 @@ WERROR cli_spoolss_getjob(struct cli_state *cli, TALLOC_CTX *mem_ctx, switch(level) { case 1: - decode_jobs_1(mem_ctx, r.buffer, 1, ctr->job.job_info_1); + decode_jobs_1(mem_ctx, r.buffer, 1, &ctr->job.job_info_1); break; case 2: - decode_jobs_2(mem_ctx, r.buffer, 1, ctr->job.job_info_2); + decode_jobs_2(mem_ctx, r.buffer, 1, &ctr->job.job_info_2); break; default: DEBUG(3, ("unsupported info level %d", level)); @@ -1878,8 +1890,7 @@ WERROR cli_spoolss_enddocprinter(struct cli_state *cli, TALLOC_CTX *mem_ctx, WERROR cli_spoolss_getprinterdata(struct cli_state *cli, TALLOC_CTX *mem_ctx, uint32 offered, uint32 *needed, POLICY_HND *hnd, char *valuename, - uint32 *data_type, char **data, - uint32 *data_size) + REGISTRY_VALUE *value) { prs_struct qbuf, rbuf; SPOOL_Q_GETPRINTERDATA q; @@ -1919,16 +1930,63 @@ WERROR cli_spoolss_getprinterdata(struct cli_state *cli, TALLOC_CTX *mem_ctx, /* Return output parameters */ - if (data_type) - *data_type = r.type; + value->data_p = talloc_memdup(mem_ctx, r.data, r.needed); + value->type = r.type; + value->size = r.size; - if (data) { - *data = (char *)talloc(mem_ctx, r.needed); - memcpy(*data, r.data, r.needed); - } + done: + prs_mem_free(&qbuf); + prs_mem_free(&rbuf); + + return result; +} + +WERROR cli_spoolss_getprinterdataex(struct cli_state *cli, TALLOC_CTX *mem_ctx, + uint32 offered, uint32 *needed, + POLICY_HND *hnd, char *keyname, + char *valuename, REGISTRY_VALUE *value) +{ + prs_struct qbuf, rbuf; + SPOOL_Q_GETPRINTERDATAEX q; + SPOOL_R_GETPRINTERDATAEX r; + WERROR result = W_ERROR(ERRgeneral); + + ZERO_STRUCT(q); + ZERO_STRUCT(r); + + /* Initialise parse structures */ + + prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); + prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); + + /* Initialise input parameters */ + + make_spoolss_q_getprinterdataex(&q, hnd, keyname, valuename, offered); + + /* Marshall data and send request */ + + if (!spoolss_io_q_getprinterdataex("", &q, &qbuf, 0) || + !rpc_api_pipe_req(cli, SPOOLSS_GETPRINTERDATAEX, &qbuf, &rbuf)) + goto done; + + /* Unmarshall response */ + + if (!spoolss_io_r_getprinterdataex("", &r, &rbuf, 0)) + goto done; + + result = r.status; + + if (needed) + *needed = r.needed; - if (data_size) - *data_size = r.needed; + if (!W_ERROR_IS_OK(r.status)) + goto done; + + /* Return output parameters */ + + value->data_p = talloc_memdup(mem_ctx, r.data, r.needed); + value->type = r.type; + value->size = r.needed; done: prs_mem_free(&qbuf); @@ -1940,9 +1998,7 @@ WERROR cli_spoolss_getprinterdata(struct cli_state *cli, TALLOC_CTX *mem_ctx, /* Set printer data */ WERROR cli_spoolss_setprinterdata(struct cli_state *cli, TALLOC_CTX *mem_ctx, - POLICY_HND *hnd, char *value, - uint32 data_type, char *data, - uint32 data_size) + POLICY_HND *hnd, REGISTRY_VALUE *value) { prs_struct qbuf, rbuf; SPOOL_Q_SETPRINTERDATA q; @@ -1959,7 +2015,8 @@ WERROR cli_spoolss_setprinterdata(struct cli_state *cli, TALLOC_CTX *mem_ctx, /* Initialise input parameters */ - make_spoolss_q_setprinterdata(&q, hnd, value, data, data_size); + make_spoolss_q_setprinterdata( + &q, hnd, value->valuename, value->type, value->data_p, value->size); /* Marshall data and send request */ @@ -1984,14 +2041,59 @@ WERROR cli_spoolss_setprinterdata(struct cli_state *cli, TALLOC_CTX *mem_ctx, return result; } +WERROR cli_spoolss_setprinterdataex(struct cli_state *cli, TALLOC_CTX *mem_ctx, + POLICY_HND *hnd, char *keyname, + REGISTRY_VALUE *value) +{ + prs_struct qbuf, rbuf; + SPOOL_Q_SETPRINTERDATAEX q; + SPOOL_R_SETPRINTERDATAEX r; + WERROR result = W_ERROR(ERRgeneral); + + ZERO_STRUCT(q); + ZERO_STRUCT(r); + + /* Initialise parse structures */ + + prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); + prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); + + /* Initialise input parameters */ + + make_spoolss_q_setprinterdataex( + &q, hnd, keyname, value->valuename, value->type, value->data_p, + value->size); + + /* Marshall data and send request */ + + if (!spoolss_io_q_setprinterdataex("", &q, &qbuf, 0) || + !rpc_api_pipe_req(cli, SPOOLSS_SETPRINTERDATAEX, &qbuf, &rbuf)) + goto done; + + /* Unmarshall response */ + + if (!spoolss_io_r_setprinterdataex("", &r, &rbuf, 0)) + goto done; + + result = r.status; + + if (!W_ERROR_IS_OK(r.status)) + goto done; + + done: + prs_mem_free(&qbuf); + prs_mem_free(&rbuf); + + return result; +} + /* Enum printer data */ WERROR cli_spoolss_enumprinterdata(struct cli_state *cli, TALLOC_CTX *mem_ctx, POLICY_HND *hnd, uint32 ndx, uint32 value_offered, uint32 data_offered, uint32 *value_needed, uint32 *data_needed, - char **value, uint32 *data_type, char **data, - uint32 *data_size) + REGISTRY_VALUE *value) { prs_struct qbuf, rbuf; SPOOL_Q_ENUMPRINTERDATA q; @@ -2027,30 +2129,83 @@ WERROR cli_spoolss_enumprinterdata(struct cli_state *cli, TALLOC_CTX *mem_ctx, goto done; /* Return data */ - + if (value_needed) *value_needed = r.realvaluesize; if (data_needed) *data_needed = r.realdatasize; - if (data_type) - *data_type = r.type; - if (value) { - fstring the_value; - - rpcstr_pull(the_value, r.value, sizeof(the_value), -1, + rpcstr_pull(value->valuename, r.value, sizeof(value->valuename), -1, STR_TERMINATE); - - *value = talloc_strdup(mem_ctx, the_value); + value->data_p = talloc_memdup(mem_ctx, r.data, r.realdatasize); + value->type = r.type; + value->size = r.realdatasize; } - if (data) - *data = talloc_memdup(mem_ctx, r.data, r.realdatasize); + done: + prs_mem_free(&qbuf); + prs_mem_free(&rbuf); + + return result; +} + +WERROR cli_spoolss_enumprinterdataex(struct cli_state *cli, TALLOC_CTX *mem_ctx, + uint32 offered, uint32 *needed, + POLICY_HND *hnd, char *keyname, + REGVAL_CTR *ctr) +{ + prs_struct qbuf, rbuf; + SPOOL_Q_ENUMPRINTERDATAEX q; + SPOOL_R_ENUMPRINTERDATAEX r; + WERROR result = W_ERROR(ERRgeneral); + int i; + + ZERO_STRUCT(q); + ZERO_STRUCT(r); + + /* Initialise parse structures */ - if (data_size) - *data_size = r.realdatasize; + prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); + prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); + + /* Initialise input parameters */ + + make_spoolss_q_enumprinterdataex(&q, hnd, keyname, offered); + + /* Marshall data and send request */ + + if (!spoolss_io_q_enumprinterdataex("", &q, &qbuf, 0) || + !rpc_api_pipe_req(cli, SPOOLSS_ENUMPRINTERDATAEX, &qbuf, &rbuf)) + goto done; + + /* Unmarshall response */ + + if (!spoolss_io_r_enumprinterdataex("", &r, &rbuf, 0)) + goto done; + + result = r.status; + + if (needed) + *needed = r.needed; + + if (!W_ERROR_IS_OK(r.status)) + goto done; + + /* Return data */ + + ZERO_STRUCTP(ctr); + regval_ctr_init(ctr); + + for (i = 0; i < r.returned; i++) { + PRINTER_ENUM_VALUES *v = &r.ctr.values[i]; + fstring name; + + rpcstr_pull(name, v->valuename.buffer, sizeof(name), -1, + STR_TERMINATE); + regval_ctr_addvalue(ctr, name, v->type, v->data, v->data_len); + } done: prs_mem_free(&qbuf); @@ -2153,4 +2308,48 @@ WERROR cli_spoolss_deleteprinterdata(struct cli_state *cli, TALLOC_CTX *mem_ctx, return result; } +WERROR cli_spoolss_deleteprinterdataex(struct cli_state *cli, TALLOC_CTX *mem_ctx, + POLICY_HND *hnd, char *keyname, + char *valuename) +{ + prs_struct qbuf, rbuf; + SPOOL_Q_DELETEPRINTERDATAEX q; + SPOOL_R_DELETEPRINTERDATAEX r; + WERROR result = W_ERROR(ERRgeneral); + + ZERO_STRUCT(q); + ZERO_STRUCT(r); + + /* Initialise parse structures */ + + prs_init(&qbuf, MAX_PDU_FRAG_LEN, mem_ctx, MARSHALL); + prs_init(&rbuf, 0, mem_ctx, UNMARSHALL); + + /* Initialise input parameters */ + + make_spoolss_q_deleteprinterdataex(&q, hnd, keyname, valuename); + + /* Marshall data and send request */ + + if (!spoolss_io_q_deleteprinterdataex("", &q, &qbuf, 0) || + !rpc_api_pipe_req(cli, SPOOLSS_DELETEPRINTERDATAEX, &qbuf, &rbuf)) + goto done; + + /* Unmarshall response */ + + if (!spoolss_io_r_deleteprinterdataex("", &r, &rbuf, 0)) + goto done; + + result = r.status; + + if (!W_ERROR_IS_OK(r.status)) + goto done; + + done: + prs_mem_free(&qbuf); + prs_mem_free(&rbuf); + + return result; +} + /** @} **/ diff --git a/source3/rpc_client/cli_spoolss_notify.c b/source3/rpc_client/cli_spoolss_notify.c index f03046558e..d07ace8e0c 100644 --- a/source3/rpc_client/cli_spoolss_notify.c +++ b/source3/rpc_client/cli_spoolss_notify.c @@ -222,6 +222,9 @@ done: return result; } +/********************************************************************* + *********************************************************************/ + WERROR cli_spoolss_rffpcnex(struct cli_state *cli, TALLOC_CTX *mem_ctx, POLICY_HND *pol, uint32 flags, uint32 options, char *localmachine, uint32 printerlocal, -- cgit