summaryrefslogtreecommitdiff
path: root/source3/rpc_client
diff options
context:
space:
mode:
Diffstat (limited to 'source3/rpc_client')
-rw-r--r--source3/rpc_client/cli_login.c173
-rw-r--r--source3/rpc_client/cli_netlogon.c152
-rw-r--r--source3/rpc_client/cli_pipe.c2
-rw-r--r--source3/rpc_client/cli_spoolss.c283
-rw-r--r--source3/rpc_client/cli_spoolss_notify.c3
-rw-r--r--source3/rpc_client/msrpc_spoolss.c812
-rw-r--r--source3/rpc_client/ntclienttrust.c157
7 files changed, 1211 insertions, 371 deletions
diff --git a/source3/rpc_client/cli_login.c b/source3/rpc_client/cli_login.c
new file mode 100644
index 0000000000..7b5bf90c5d
--- /dev/null
+++ b/source3/rpc_client/cli_login.c
@@ -0,0 +1,173 @@
+/*
+ Unix SMB/CIFS implementation.
+ NT Domain Authentication SMB / MSRPC client
+ Copyright (C) Andrew Tridgell 1994-1997
+ Copyright (C) Luke Kenneth Casson Leighton 1996-1997
+ Copyright (C) Jeremy Allison 1999.
+
+ 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 2 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, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#include "includes.h"
+
+extern fstring global_myworkgroup;
+extern pstring global_myname;
+
+/****************************************************************************
+Initialize domain session credentials.
+****************************************************************************/
+
+NTSTATUS cli_nt_setup_creds(struct cli_state *cli, unsigned char mach_pwd[16])
+{
+ NTSTATUS result;
+ DOM_CHAL clnt_chal;
+ DOM_CHAL srv_chal;
+
+ UTIME zerotime;
+
+ /******************* Request Challenge ********************/
+
+ generate_random_buffer( clnt_chal.data, 8, False);
+
+ /* send a client challenge; receive a server challenge */
+ if (!cli_net_req_chal(cli, &clnt_chal, &srv_chal))
+ {
+ DEBUG(0,("cli_nt_setup_creds: request challenge failed\n"));
+ return NT_STATUS_UNSUCCESSFUL;
+ }
+
+ /**************** Long-term Session key **************/
+
+ /* calculate the session key */
+ cred_session_key(&clnt_chal, &srv_chal, (char *)mach_pwd, cli->sess_key);
+ memset((char *)cli->sess_key+8, '\0', 8);
+
+ /******************* Authenticate 2 ********************/
+
+ /* calculate auth-2 credentials */
+ zerotime.time = 0;
+ 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.
+ */
+
+ result = cli_net_auth2(cli, (lp_server_role() == ROLE_DOMAIN_MEMBER) ?
+ SEC_CHAN_WKSTA : SEC_CHAN_BDC, 0x000001ff, &srv_chal);
+
+ if (!NT_STATUS_IS_OK(result))
+ {
+ DEBUG(0,("cli_nt_setup_creds: auth2 challenge failed\n"));
+ return result;
+ }
+
+ return NT_STATUS_OK;
+}
+
+/****************************************************************************
+NT login - interactive.
+*NEVER* use this code. This method of doing a logon (sending the cleartext
+password equivalents, protected by the session key) is inherently insecure
+given the current design of the NT Domain system. JRA.
+ ****************************************************************************/
+NTSTATUS cli_nt_login_interactive(struct cli_state *cli, char *domain, char *username,
+ uint32 smb_userid_low, char *password,
+ NET_ID_INFO_CTR *ctr, NET_USER_INFO_3 *user_info3)
+{
+ uchar lm_owf_user_pwd[16];
+ uchar nt_owf_user_pwd[16];
+ NTSTATUS ret;
+
+ DEBUG(5,("cli_nt_login_interactive: %d\n", __LINE__));
+
+ nt_lm_owf_gen(password, nt_owf_user_pwd, lm_owf_user_pwd);
+
+#ifdef DEBUG_PASSWORD
+
+ DEBUG(100,("nt owf of user password: "));
+ dump_data(100, (char *)lm_owf_user_pwd, 16);
+
+ DEBUG(100,("nt owf of user password: "));
+ dump_data(100, (char *)nt_owf_user_pwd, 16);
+
+#endif
+
+ DEBUG(5,("cli_nt_login_interactive: %d\n", __LINE__));
+
+ /* indicate an "interactive" login */
+ ctr->switch_value = INTERACTIVE_LOGON_TYPE;
+
+ /* Create the structure needed for SAM logon. */
+ init_id_info1(&ctr->auth.id1, domain, 0,
+ smb_userid_low, 0,
+ username, cli->clnt_name_slash,
+ (char *)cli->sess_key, lm_owf_user_pwd, nt_owf_user_pwd);
+
+ /* Ensure we overwrite all the plaintext password
+ equivalents. */
+ memset(lm_owf_user_pwd, '\0', sizeof(lm_owf_user_pwd));
+ memset(nt_owf_user_pwd, '\0', sizeof(nt_owf_user_pwd));
+
+ /* Send client sam-logon request - update credentials on success. */
+ ret = cli_net_sam_logon(cli, ctr, user_info3);
+
+ memset(ctr->auth.id1.lm_owf.data, '\0', sizeof(lm_owf_user_pwd));
+ memset(ctr->auth.id1.nt_owf.data, '\0', sizeof(nt_owf_user_pwd));
+
+ return ret;
+}
+
+/****************************************************************************
+NT login - network.
+*ALWAYS* use this call to validate a user as it does not expose plaintext
+password equivalents over the network. JRA.
+****************************************************************************/
+
+NTSTATUS cli_nt_login_network(struct cli_state *cli,
+ const auth_usersupplied_info *user_info,
+ uchar chal[8],
+ uint32 smb_userid_low, NET_ID_INFO_CTR *ctr,
+ NET_USER_INFO_3 *user_info3)
+{
+ DEBUG(5,("cli_nt_login_network: %d\n", __LINE__));
+ /* indicate a "network" login */
+ ctr->switch_value = NET_LOGON_TYPE;
+
+ /* Create the structure needed for SAM logon. */
+ init_id_info2(&ctr->auth.id2, user_info->domain.str, 0, smb_userid_low, 0,
+ user_info->smb_name.str,
+ /* Send our cleint's workstaion name if we have it, otherwise ours */
+ ((user_info->wksta_name.len > 0) ?
+ user_info->wksta_name.str :
+ cli->clnt_name_slash),
+ chal,
+ user_info->lm_resp.data, user_info->lm_resp.length,
+ user_info->nt_resp.data, user_info->nt_resp.length);
+
+ /* Send client sam-logon request - update credentials on success. */
+ return cli_net_sam_logon(cli, ctr, user_info3);
+}
+
+/****************************************************************************
+NT Logoff.
+****************************************************************************/
+BOOL cli_nt_logoff(struct cli_state *cli, NET_ID_INFO_CTR *ctr)
+{
+ DEBUG(5,("cli_nt_logoff: %d\n", __LINE__));
+
+ /* Send client sam-logoff request - update credentials on success. */
+ return cli_net_sam_logoff(cli, ctr);
+}
diff --git a/source3/rpc_client/cli_netlogon.c b/source3/rpc_client/cli_netlogon.c
index eaee3c26e7..acc9135542 100644
--- a/source3/rpc_client/cli_netlogon.c
+++ b/source3/rpc_client/cli_netlogon.c
@@ -152,106 +152,11 @@ 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], uint32 *neg_flags, int level)
+ const unsigned char mach_pwd[16])
{
DOM_CHAL clnt_chal;
DOM_CHAL srv_chal;
@@ -277,30 +182,24 @@ NTSTATUS cli_nt_setup_creds(struct cli_state *cli,
cli->sess_key);
memset((char *)cli->sess_key+8, '\0', 8);
- /******************* Authenticate 2/3 ********************/
+ /******************* Authenticate 2 ********************/
- /* calculate auth-2/3 credentials */
+ /* calculate auth-2 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/3 challenge.
- * Receive an auth-2/3 challenge response and check it.
+ * Send client auth-2 challenge.
+ * Receive an auth-2 challenge response and check it.
*/
- 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;
- }
+
+ result = cli_net_auth2(cli, sec_chan, 0x000001ff, &srv_chal);
- if (!NT_STATUS_IS_OK(result))
- DEBUG(1,("cli_nt_setup_creds: auth%d challenge failed %s\n", level, nt_errstr(result)));
+ if (!NT_STATUS_IS_OK(result)) {
+ DEBUG(1,("cli_nt_setup_creds: auth2 challenge failed %s\n",
+ nt_errstr(result)));
+ }
return result;
}
@@ -358,23 +257,24 @@ 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));
+ /*
+ * 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));
- /* 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 next_rid, uint32 *num_deltas,
+ uint32 database_id, uint32 *num_deltas,
SAM_DELTA_HDR **hdr_deltas,
SAM_DELTA_CTR **deltas)
{
@@ -397,7 +297,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, next_rid);
+ &clnt_creds, ret_creds, database_id);
/* Marshall data and send request */
diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c
index 0416ed3b9b..eae6be5128 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, 1024, /* data, length, max */
+ pdata, data_len, data_len, /* 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 ca24d95e33..18e17758d6 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,
- char *name, uint32 flags, uint32 level,
+ uint32 flags, uint32 level,
uint32 *num_printers, PRINTER_INFO_CTR *ctr)
{
prs_struct qbuf, rbuf;
@@ -401,10 +401,14 @@ 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);
@@ -412,7 +416,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, name, level, &buffer,
+ make_spoolss_q_enumprinters(&q, flags, server, level, &buffer,
offered);
/* Marshall data and send request */
@@ -661,8 +665,7 @@ 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);
- if (!make_spoolss_q_setprinter(mem_ctx, &q, pol, level, ctr, command))
- goto done;
+ make_spoolss_q_setprinter(mem_ctx, &q, pol, level, ctr, command);
/* Marshall data and send request */
@@ -768,9 +771,6 @@ 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,10 +852,6 @@ 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;
}
}
@@ -1336,16 +1332,8 @@ WERROR cli_spoolss_getform(struct cli_state *cli, TALLOC_CTX *mem_ctx,
if (needed)
*needed = r.needed;
- 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;
- }
- }
+ if (W_ERROR_IS_OK(result))
+ smb_io_form_1("", r.buffer, form, 0);
done:
prs_mem_free(&qbuf);
@@ -1568,11 +1556,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));
@@ -1681,10 +1669,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));
@@ -1890,7 +1878,8 @@ 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,
- REGISTRY_VALUE *value)
+ uint32 *data_type, char **data,
+ uint32 *data_size)
{
prs_struct qbuf, rbuf;
SPOOL_Q_GETPRINTERDATA q;
@@ -1930,63 +1919,16 @@ WERROR cli_spoolss_getprinterdata(struct cli_state *cli, TALLOC_CTX *mem_ctx,
/* Return output parameters */
- value->data_p = talloc_memdup(mem_ctx, r.data, r.needed);
- value->type = r.type;
- value->size = r.size;
-
- 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_type)
+ *data_type = r.type;
- if (!W_ERROR_IS_OK(r.status))
- goto done;
-
- /* Return output parameters */
+ if (data) {
+ *data = (char *)talloc(mem_ctx, r.needed);
+ memcpy(*data, r.data, r.needed);
+ }
- value->data_p = talloc_memdup(mem_ctx, r.data, r.needed);
- value->type = r.type;
- value->size = r.needed;
+ if (data_size)
+ *data_size = r.needed;
done:
prs_mem_free(&qbuf);
@@ -1998,7 +1940,9 @@ WERROR cli_spoolss_getprinterdataex(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, REGISTRY_VALUE *value)
+ POLICY_HND *hnd, char *value,
+ uint32 data_type, char *data,
+ uint32 data_size)
{
prs_struct qbuf, rbuf;
SPOOL_Q_SETPRINTERDATA q;
@@ -2015,8 +1959,7 @@ WERROR cli_spoolss_setprinterdata(struct cli_state *cli, TALLOC_CTX *mem_ctx,
/* Initialise input parameters */
- make_spoolss_q_setprinterdata(
- &q, hnd, value->valuename, value->type, value->data_p, value->size);
+ make_spoolss_q_setprinterdata(&q, hnd, value, data, data_size);
/* Marshall data and send request */
@@ -2041,59 +1984,14 @@ 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,
- REGISTRY_VALUE *value)
+ char **value, uint32 *data_type, char **data,
+ uint32 *data_size)
{
prs_struct qbuf, rbuf;
SPOOL_Q_ENUMPRINTERDATA q;
@@ -2129,83 +2027,30 @@ 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) {
- rpcstr_pull(value->valuename, r.value, sizeof(value->valuename), -1,
+ fstring the_value;
+
+ rpcstr_pull(the_value, r.value, sizeof(the_value), -1,
STR_TERMINATE);
- value->data_p = talloc_memdup(mem_ctx, r.data, r.realdatasize);
- value->type = r.type;
- value->size = r.realdatasize;
+
+ *value = talloc_strdup(mem_ctx, the_value);
}
- 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)
+ *data = talloc_memdup(mem_ctx, r.data, 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);
- }
+ if (data_size)
+ *data_size = r.realdatasize;
done:
prs_mem_free(&qbuf);
@@ -2308,48 +2153,4 @@ 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 d07ace8e0c..f03046558e 100644
--- a/source3/rpc_client/cli_spoolss_notify.c
+++ b/source3/rpc_client/cli_spoolss_notify.c
@@ -222,9 +222,6 @@ 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,
diff --git a/source3/rpc_client/msrpc_spoolss.c b/source3/rpc_client/msrpc_spoolss.c
new file mode 100644
index 0000000000..56c70730ba
--- /dev/null
+++ b/source3/rpc_client/msrpc_spoolss.c
@@ -0,0 +1,812 @@
+/*
+ Unix SMB/CIFS implementation.
+ NT Domain Authentication SMB / MSRPC client
+ Copyright (C) Andrew Tridgell 1994-2000
+ Copyright (C) Luke Kenneth Casson Leighton 1996-2000
+ Copyright (C) Jean-Francois Micouleau 1999-2000
+
+ 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 2 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, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#include "includes.h"
+#include "nterr.h"
+#include "rpc_parse.h"
+#include "rpcclient.h"
+
+#undef DBGC_CLASS
+#define DBGC_CLASS DBGC_RPC_CLI
+
+#define DEBUG_TESTING
+
+extern FILE* out_hnd;
+
+extern struct user_creds *usr_creds;
+
+/********************************************************************
+initialize a spoolss NEW_BUFFER.
+********************************************************************/
+void init_buffer(NEW_BUFFER *buffer, uint32 size, TALLOC_CTX *ctx)
+{
+ buffer->ptr = (size!=0)? 1:0;
+ buffer->size=size;
+ buffer->string_at_end=size;
+ prs_init(&buffer->prs, size, ctx, MARSHALL);
+ buffer->struct_start = prs_offset(&buffer->prs);
+}
+
+static void decode_printer_info_0(NEW_BUFFER *buffer, uint32 returned,
+ PRINTER_INFO_0 **info)
+{
+ uint32 i;
+ PRINTER_INFO_0 *inf;
+
+ inf=(PRINTER_INFO_0 *)malloc(returned*sizeof(PRINTER_INFO_0));
+
+ buffer->prs.data_offset=0;
+
+ for (i=0; i<returned; i++) {
+ new_smb_io_printer_info_0("", buffer, &(inf[i]), 0);
+ }
+
+ *info=inf;
+}
+
+static void decode_printer_info_1(NEW_BUFFER *buffer, uint32 returned,
+ PRINTER_INFO_1 **info)
+{
+ uint32 i;
+ PRINTER_INFO_1 *inf;
+
+ inf=(PRINTER_INFO_1 *)malloc(returned*sizeof(PRINTER_INFO_1));
+
+ buffer->prs.data_offset=0;
+
+ for (i=0; i<returned; i++) {
+ new_smb_io_printer_info_1("", buffer, &(inf[i]), 0);
+ }
+
+ *info=inf;
+}
+
+static void decode_printer_info_2(NEW_BUFFER *buffer, uint32 returned,
+ PRINTER_INFO_2 **info)
+{
+ uint32 i;
+ PRINTER_INFO_2 *inf;
+
+ inf=(PRINTER_INFO_2 *)malloc(returned*sizeof(PRINTER_INFO_2));
+
+ buffer->prs.data_offset=0;
+
+ for (i=0; i<returned; i++) {
+ /* a little initialization as we go */
+ inf[i].secdesc = NULL;
+ new_smb_io_printer_info_2("", buffer, &(inf[i]), 0);
+ }
+
+ *info=inf;
+}
+
+static void decode_printer_info_3(NEW_BUFFER *buffer, uint32 returned,
+ PRINTER_INFO_3 **info)
+{
+ uint32 i;
+ PRINTER_INFO_3 *inf;
+
+ inf=(PRINTER_INFO_3 *)malloc(returned*sizeof(PRINTER_INFO_3));
+
+ buffer->prs.data_offset=0;
+
+ for (i=0; i<returned; i++) {
+ new_smb_io_printer_info_3("", buffer, &(inf[i]), 0);
+ }
+
+ *info=inf;
+}
+
+static void decode_printer_driver_1(NEW_BUFFER *buffer, uint32 returned,
+ DRIVER_INFO_1 **info)
+{
+ uint32 i;
+ DRIVER_INFO_1 *inf;
+
+ inf=(DRIVER_INFO_1 *)malloc(returned*sizeof(DRIVER_INFO_1));
+
+ buffer->prs.data_offset=0;
+
+ for (i=0; i<returned; i++) {
+ new_smb_io_printer_driver_info_1("", buffer, &(inf[i]), 0);
+ }
+
+ *info=inf;
+}
+
+static void decode_printer_driver_2(NEW_BUFFER *buffer, uint32 returned,
+ DRIVER_INFO_2 **info)
+{
+ uint32 i;
+ DRIVER_INFO_2 *inf;
+
+ inf=(DRIVER_INFO_2 *)malloc(returned*sizeof(DRIVER_INFO_2));
+
+ buffer->prs.data_offset=0;
+
+ for (i=0; i<returned; i++) {
+ new_smb_io_printer_driver_info_2("", buffer, &(inf[i]), 0);
+ }
+
+ *info=inf;
+}
+
+static void decode_printer_driver_3(NEW_BUFFER *buffer, uint32 returned,
+ DRIVER_INFO_3 **info)
+{
+ uint32 i;
+ DRIVER_INFO_3 *inf;
+
+ inf=(DRIVER_INFO_3 *)malloc(returned*sizeof(DRIVER_INFO_3));
+
+ buffer->prs.data_offset=0;
+
+ for (i=0; i<returned; i++) {
+ new_smb_io_printer_driver_info_3("", buffer, &(inf[i]), 0);
+ }
+
+ *info=inf;
+}
+
+static void decode_printerdriverdir_info_1(NEW_BUFFER *buffer, DRIVER_DIRECTORY_1 *info)
+{
+/* DRIVER_DIRECTORY_1 *inf;
+
+ inf=(DRIVER_DIRECTORY_1 *)malloc(returned*sizeof(DRIVER_DIRECTORY_1));
+*/
+ prs_set_offset(&buffer->prs, 0);
+
+ new_smb_io_driverdir_1("", buffer, info, 0);
+
+/* *info=inf;*/
+}
+
+/**********************************************************************
+ Decode a PORT_INFO_1 struct from a NEW_BUFFER
+**********************************************************************/
+void decode_port_info_1(NEW_BUFFER *buffer, uint32 returned,
+ PORT_INFO_1 **info)
+{
+ uint32 i;
+ PORT_INFO_1 *inf;
+
+ inf=(PORT_INFO_1*)malloc(returned*sizeof(PORT_INFO_1));
+
+ prs_set_offset(&buffer->prs, 0);
+
+ for (i=0; i<returned; i++) {
+ new_smb_io_port_info_1("", buffer, &(inf[i]), 0);
+ }
+
+ *info=inf;
+}
+
+/**********************************************************************
+ Decode a PORT_INFO_2 struct from a NEW_BUFFER
+**********************************************************************/
+void decode_port_info_2(NEW_BUFFER *buffer, uint32 returned,
+ PORT_INFO_2 **info)
+{
+ uint32 i;
+ PORT_INFO_2 *inf;
+
+ inf=(PORT_INFO_2*)malloc(returned*sizeof(PORT_INFO_2));
+
+ prs_set_offset(&buffer->prs, 0);
+
+ for (i=0; i<returned; i++) {
+ new_smb_io_port_info_2("", buffer, &(inf[i]), 0);
+ }
+
+ *info=inf;
+}
+
+
+/****************************************************************************
+nt spoolss query
+****************************************************************************/
+BOOL msrpc_spoolss_enum_printers(char* srv_name, uint32 flags,
+ uint32 level, PRINTER_INFO_CTR ctr)
+{
+ NTSTATUS status;
+ NEW_BUFFER buffer;
+ uint32 needed;
+ uint32 returned;
+ TALLOC_CTX *mem_ctx = NULL;
+
+ if ((mem_ctx=talloc_init()) == NULL)
+ {
+ DEBUG(0,("msrpc_spoolss_enum_printers: talloc_init failed!\n"));
+ return False;
+ }
+ init_buffer(&buffer, 0, mem_ctx);
+
+ /* send a NULL buffer first */
+ status=spoolss_enum_printers(flags, srv_name, level, &buffer, 0,
+ &needed, &returned);
+
+ if (status==ERROR_INSUFFICIENT_BUFFER) {
+ init_buffer(&buffer, needed, mem_ctx);
+ status=spoolss_enum_printers(flags, srv_name, level, &buffer,
+ needed, &needed, &returned);
+ }
+
+ if (status!=NT_STATUS_OK)
+ {
+ DEBUG(0,("spoolss_enum_printers: %s\n", nt_errstr(status)));
+ if (mem_ctx)
+ talloc_destroy(mem_ctx);
+ return False;
+ }
+
+ /* is there anything to process? */
+ if (returned != 0)
+ {
+ switch (level) {
+ case 1:
+ decode_printer_info_1(&buffer, returned, &(ctr.printers_1));
+ break;
+ case 2:
+ decode_printer_info_2(&buffer, returned, &(ctr.printers_2));
+ break;
+ case 3:
+ decode_printer_info_3(&buffer, returned, &(ctr.printers_3));
+ break;
+ }
+
+ display_printer_info_ctr(out_hnd, ACTION_HEADER , level, returned, ctr);
+ display_printer_info_ctr(out_hnd, ACTION_ENUMERATE, level, returned, ctr);
+ display_printer_info_ctr(out_hnd, ACTION_FOOTER , level, returned, ctr);
+ }
+
+ if (mem_ctx)
+ talloc_destroy(mem_ctx);
+
+ return True;
+}
+
+/****************************************************************************
+nt spoolss query
+****************************************************************************/
+BOOL msrpc_spoolss_enum_ports(char* srv_name,
+ uint32 level, PORT_INFO_CTR *ctr)
+{
+ NTSTATUS status;
+ NEW_BUFFER buffer;
+ uint32 needed;
+ uint32 returned;
+ TALLOC_CTX *mem_ctx = NULL;
+
+ if ((mem_ctx=talloc_init()) == NULL)
+ {
+ DEBUG(0,("msrpc_spoolss_enum_ports: talloc_init failed!\n"));
+ return False;
+ }
+
+ init_buffer(&buffer, 0, mem_ctx);
+
+ /* send a NULL buffer first */
+ status=spoolss_enum_ports(srv_name, level, &buffer, 0,
+ &needed, &returned);
+
+ if (status==ERROR_INSUFFICIENT_BUFFER) {
+ init_buffer(&buffer, needed, mem_ctx);
+ status=spoolss_enum_ports(srv_name, level, &buffer,
+ needed, &needed, &returned);
+ }
+
+ report(out_hnd, "\tstatus:[%d (%x)]\n", status, status);
+
+ if (status!=NT_STATUS_OK)
+ {
+ if (mem_ctx)
+ talloc_destroy(mem_ctx);
+ return False;
+ }
+
+ /* is there anything to process? */
+ if (returned != 0)
+ {
+ switch (level) {
+ case 1:
+ decode_port_info_1(&buffer, returned, &ctr->port.info_1);
+ break;
+ case 2:
+ decode_port_info_2(&buffer, returned, &ctr->port.info_2);
+ break;
+ default:
+ DEBUG(0,("Unable to decode unknown PORT_INFO_%d\n", level));
+ break;
+ }
+
+ display_port_info_ctr(out_hnd, ACTION_HEADER , level, returned, ctr);
+ display_port_info_ctr(out_hnd, ACTION_ENUMERATE, level, returned, ctr);
+ display_port_info_ctr(out_hnd, ACTION_FOOTER , level, returned, ctr);
+ }
+ if (mem_ctx)
+ talloc_destroy(mem_ctx);
+
+
+
+ return True;
+}
+
+/****************************************************************************
+nt spoolss query
+****************************************************************************/
+uint32 msrpc_spoolss_getprinterdata( const char* printer_name,
+ const char* station,
+ const char* user_name,
+ const char* value_name,
+ uint32 *type,
+ NEW_BUFFER *buffer,
+ void *fn)
+{
+ POLICY_HND hnd;
+ NTSTATUS status;
+ uint32 needed;
+ uint32 size;
+ char *data;
+ UNISTR2 uni_val_name;
+ TALLOC_CTX *mem_ctx = NULL;
+
+ DEBUG(4,("spoolgetdata - printer: %s server: %s user: %s value: %s\n",
+ printer_name, station, user_name, value_name));
+
+ if(!spoolss_open_printer_ex( printer_name, 0, 0, station, user_name,
+ &hnd))
+ {
+ return NT_STATUS_ACCESS_DENIED;
+ }
+
+ init_unistr2(&uni_val_name, value_name, 0);
+ size = 0;
+ data = NULL;
+
+ if ((mem_ctx=talloc_init()) == NULL)
+ {
+ DEBUG(0,("msrpc_spoolss_getprinterdata: talloc_init failed!\n"));
+ return False;
+ }
+ init_buffer(buffer, size, mem_ctx);
+
+ status = spoolss_getprinterdata(&hnd, &uni_val_name, size, type, &size,
+ (unsigned char *)data, &needed);
+
+ if (status == ERROR_INSUFFICIENT_BUFFER)
+ {
+ size = needed;
+ init_buffer(buffer, size, mem_ctx);
+ data = prs_data_p(&buffer->prs);
+ status = spoolss_getprinterdata(&hnd, &uni_val_name,
+ size, type, &size,
+ (unsigned char *)data, &needed);
+ }
+
+ if (mem_ctx)
+ talloc_destroy(mem_ctx);
+
+ if (status != NT_STATUS_OK)
+ {
+ if (!spoolss_closeprinter(&hnd))
+ return NT_STATUS_ACCESS_DENIED;
+ return status;
+ }
+
+#if 0
+ if (fn != NULL)
+ fn(printer_name, station, level, returned, *ctr);
+#endif
+
+ return status;
+}
+
+/****************************************************************************
+nt spoolss query
+****************************************************************************/
+BOOL msrpc_spoolss_enum_jobs( const char* printer_name,
+ const char* station, const char* user_name,
+ uint32 level,
+ void ***ctr, JOB_INFO_FN(fn))
+{
+ POLICY_HND hnd;
+ NTSTATUS status;
+ NEW_BUFFER buffer;
+ uint32 needed;
+ uint32 returned;
+ uint32 firstjob=0;
+ uint32 numofjobs=0xffff;
+ TALLOC_CTX *mem_ctx = NULL;
+
+ DEBUG(4,("spoolopen - printer: %s server: %s user: %s\n",
+ printer_name, station, user_name));
+
+ if(!spoolss_open_printer_ex( printer_name, 0, 0, station, user_name, &hnd))
+ return False;
+
+ if ((mem_ctx=talloc_init()) == NULL)
+ {
+ DEBUG(0,("msrpc_spoolss_enum_jobs: talloc_init failed!\n"));
+ return False;
+ }
+ init_buffer(&buffer, 0, mem_ctx);
+ status = spoolss_enum_jobs(&hnd, firstjob, numofjobs, level,
+ &buffer, 0, &needed, &returned);
+
+ if (status == ERROR_INSUFFICIENT_BUFFER)
+ {
+ init_buffer(&buffer, needed, mem_ctx);
+ status = spoolss_enum_jobs( &hnd, firstjob, numofjobs, level,
+ &buffer, needed, &needed, &returned);
+ }
+
+ if (mem_ctx)
+ talloc_destroy(mem_ctx);
+
+ if (status!=NT_STATUS_OK) {
+ if (!spoolss_closeprinter(&hnd))
+ return False;
+ return False;
+ }
+
+ if (fn != NULL)
+ fn(printer_name, station, level, returned, *ctr);
+
+ return True;
+}
+
+
+/****************************************************************************
+nt spoolss query
+****************************************************************************/
+BOOL msrpc_spoolss_enum_printerdata( const char* printer_name,
+ const char* station, const char* user_name )
+{
+ POLICY_HND hnd;
+ NTSTATUS status;
+ uint32 idx;
+ uint32 valuelen;
+ uint16 *value;
+ uint32 rvaluelen;
+ uint32 type;
+ uint32 datalen;
+ uint8 *data;
+ uint32 rdatalen;
+ uint32 maxvaluelen;
+ uint32 maxdatalen;
+
+ DEBUG(4,("msrpc_spoolss_enum_printerdata - printer: %s\n", printer_name));
+
+ if(!spoolss_open_printer_ex( printer_name, 0, 0, station, user_name, &hnd))
+ return False;
+
+
+ idx=0;
+ valuelen=0;
+ rvaluelen=0;
+ type=0;
+ datalen=0;
+ rdatalen=0;
+
+ status = spoolss_enum_printerdata(&hnd, idx, &valuelen, value,
+ &rvaluelen, &type, &datalen,
+ data, &rdatalen);
+
+ DEBUG(4,("spoolenum_printerdata - got size: biggest value:[%d], biggest data:[%d]\n", rvaluelen, rdatalen));
+
+ maxvaluelen=valuelen=rvaluelen;
+ maxdatalen=datalen=rdatalen;
+
+ value=(uint16 *)malloc(valuelen*sizeof(uint16));
+ data=(uint8 *)malloc(datalen*sizeof(uint8));
+
+ display_printer_enumdata(out_hnd, ACTION_HEADER, idx, valuelen,
+ value, rvaluelen, type, datalen, data, rdatalen);
+
+ do {
+ valuelen=maxvaluelen;
+ datalen=maxdatalen;
+
+ status = spoolss_enum_printerdata(&hnd, idx, &valuelen,
+ value, &rvaluelen, &type,
+ &datalen, data, &rdatalen);
+ display_printer_enumdata(out_hnd, ACTION_ENUMERATE, idx,
+ valuelen, value, rvaluelen, type,
+ datalen, data, rdatalen);
+ idx++;
+
+ } while (status != 0x0103); /* NO_MORE_ITEMS */
+
+ display_printer_enumdata(out_hnd, ACTION_FOOTER, idx, valuelen,
+ value, rvaluelen, type, datalen, data, rdatalen);
+
+
+ if (status!=NT_STATUS_OK) {
+ /*
+ * the check on this if statement is redundant
+ * since is the status is bad we're going to
+ * return False anyways. The caller will be
+ * unable to determine if there really was a problem
+ * with the spoolss_closeprinter() call --jerry
+ */
+ spoolss_closeprinter(&hnd);
+ return False;
+ }
+
+ return True;
+}
+
+/****************************************************************************
+nt spoolss query
+****************************************************************************/
+BOOL msrpc_spoolss_getprinter( const char* printer_name, const uint32 level,
+ const char* station, const char* user_name,
+ PRINTER_INFO_CTR ctr)
+{
+ POLICY_HND hnd;
+ NTSTATUS status=0;
+ NEW_BUFFER buffer;
+ uint32 needed=1000;
+ TALLOC_CTX *mem_ctx = NULL;
+
+ DEBUG(4,("spoolenum_getprinter - printer: %s\n", printer_name));
+
+ if(!spoolss_open_printer_ex( printer_name, "", PRINTER_ALL_ACCESS, station, user_name, &hnd))
+ return False;
+
+ if ((mem_ctx=talloc_init()) == NULL)
+ {
+ DEBUG(0,("msrpc_spoolss_getprinter: talloc_init failed!\n"));
+ return False;
+ }
+ init_buffer(&buffer, needed, mem_ctx);
+
+ status = spoolss_getprinter(&hnd, level, &buffer, needed, &needed);
+
+ if (status==ERROR_INSUFFICIENT_BUFFER) {
+ init_buffer(&buffer, needed, mem_ctx);
+ status = spoolss_getprinter(&hnd, level, &buffer, needed, &needed);
+ }
+
+ report(out_hnd, "\tstatus:[%d (%x)]\n", status, status);
+
+ if (status!=NT_STATUS_OK)
+ {
+ if (mem_ctx)
+ talloc_destroy(mem_ctx);
+ return False;
+ }
+
+ switch (level) {
+ case 0:
+ decode_printer_info_0(&buffer, 1, &(ctr.printers_0));
+ break;
+ case 1:
+ decode_printer_info_1(&buffer, 1, &(ctr.printers_1));
+ break;
+ case 2:
+ decode_printer_info_2(&buffer, 1, &(ctr.printers_2));
+ break;
+ case 3:
+ decode_printer_info_3(&buffer, 1, &(ctr.printers_3));
+ break;
+ }
+
+ display_printer_info_ctr(out_hnd, ACTION_HEADER , level, 1, ctr);
+ display_printer_info_ctr(out_hnd, ACTION_ENUMERATE, level, 1, ctr);
+ display_printer_info_ctr(out_hnd, ACTION_FOOTER , level, 1, ctr);
+
+ if (mem_ctx)
+ talloc_destroy(mem_ctx);
+
+ if (status!=NT_STATUS_OK) {
+ if (!spoolss_closeprinter(&hnd))
+ return False;
+ return False;
+ }
+
+ return True;
+}
+
+/****************************************************************************
+nt spoolss query
+****************************************************************************/
+BOOL msrpc_spoolss_getprinterdriver( const char* printer_name,
+ const char *environment, const uint32 level,
+ const char* station, const char* user_name,
+ PRINTER_DRIVER_CTR ctr)
+{
+ POLICY_HND hnd;
+ NTSTATUS status=0;
+ NEW_BUFFER buffer;
+ uint32 needed;
+ TALLOC_CTX *mem_ctx = NULL;
+
+ DEBUG(4,("msrpc_spoolss_enum_getprinterdriver - printer: %s\n", printer_name));
+
+ if(!spoolss_open_printer_ex( printer_name, "", PRINTER_ALL_ACCESS, station, user_name, &hnd))
+ return False;
+
+ if ((mem_ctx=talloc_init()) == NULL)
+ {
+ DEBUG(0,("msrpc_spoolss_getprinterdriver: talloc_init failed!\n"));
+ return False;
+ }
+ init_buffer(&buffer, 0, mem_ctx);
+
+ status = spoolss_getprinterdriver(&hnd, environment, level, &buffer, 0, &needed);
+
+ if (status==ERROR_INSUFFICIENT_BUFFER) {
+ init_buffer(&buffer, needed, mem_ctx);
+ status = spoolss_getprinterdriver(&hnd, environment, level, &buffer, needed, &needed);
+ }
+
+ /* report(out_hnd, "\tstatus:[%d (%x)]\n", status, status); */
+
+ if (status!=NT_STATUS_OK)
+ {
+ if (mem_ctx)
+ talloc_destroy(mem_ctx);
+ return False;
+ }
+
+ switch (level) {
+ case 1:
+ decode_printer_driver_1(&buffer, 1, &(ctr.info1));
+ break;
+ case 2:
+ decode_printer_driver_2(&buffer, 1, &(ctr.info2));
+ break;
+ case 3:
+ decode_printer_driver_3(&buffer, 1, &(ctr.info3));
+ break;
+ }
+
+ display_printer_driver_ctr(out_hnd, ACTION_HEADER , level, 1, ctr);
+ display_printer_driver_ctr(out_hnd, ACTION_ENUMERATE, level, 1, ctr);
+ display_printer_driver_ctr(out_hnd, ACTION_FOOTER , level, 1, ctr);
+
+ if (mem_ctx)
+ talloc_destroy(mem_ctx);
+
+ if (status!=NT_STATUS_OK) {
+ if (!spoolss_closeprinter(&hnd))
+ return False;
+ return False;
+ }
+
+ return True;
+}
+
+/****************************************************************************
+nt spoolss query
+****************************************************************************/
+BOOL msrpc_spoolss_enumprinterdrivers( const char* srv_name,
+ const char *environment, const uint32 level,
+ PRINTER_DRIVER_CTR ctr)
+{
+ NTSTATUS status=0;
+ NEW_BUFFER buffer;
+ uint32 needed;
+ uint32 returned;
+ TALLOC_CTX *mem_ctx = NULL;
+
+ DEBUG(4,("msrpc_spoolss_enum_enumprinterdrivers - server: %s\n", srv_name));
+
+ if ((mem_ctx=talloc_init()) == NULL)
+ {
+ DEBUG(0,("msrpc_spoolss_enumprinterdrivers: talloc_init failed!\n"));
+ return False;
+ }
+ init_buffer(&buffer, 0, mem_ctx);
+
+ status = spoolss_enum_printerdrivers(srv_name, environment,
+ level, &buffer, 0, &needed, &returned);
+
+ if (status == ERROR_INSUFFICIENT_BUFFER)
+ {
+ init_buffer(&buffer, needed, mem_ctx);
+ status = spoolss_enum_printerdrivers( srv_name, environment,
+ level, &buffer, needed, &needed, &returned);
+ }
+
+ report(out_hnd, "\tstatus:[%d (%x)]\n", status, status);
+
+ if (status!=NT_STATUS_OK)
+ {
+ if (mem_ctx)
+ talloc_destroy(mem_ctx);
+ return False;
+ }
+
+ switch (level)
+ {
+ case 1:
+ decode_printer_driver_1(&buffer, returned, &(ctr.info1));
+ break;
+ case 2:
+ decode_printer_driver_2(&buffer, returned, &(ctr.info2));
+ break;
+ case 3:
+ decode_printer_driver_3(&buffer, returned, &(ctr.info3));
+ break;
+ }
+
+ display_printer_driver_ctr(out_hnd, ACTION_HEADER , level, returned, ctr);
+ display_printer_driver_ctr(out_hnd, ACTION_ENUMERATE, level, returned, ctr);
+ display_printer_driver_ctr(out_hnd, ACTION_FOOTER , level, returned, ctr);
+
+ if (mem_ctx)
+ talloc_destroy(mem_ctx);
+
+ return True;
+}
+
+/****************************************************************************
+nt spoolss query
+****************************************************************************/
+BOOL msrpc_spoolss_getprinterdriverdir(char* srv_name, char* env_name, uint32 level, DRIVER_DIRECTORY_CTR ctr)
+{
+ NTSTATUS status;
+ NEW_BUFFER buffer;
+ uint32 needed;
+ TALLOC_CTX *mem_ctx = NULL;
+
+ if ((mem_ctx=talloc_init()) == NULL)
+ {
+ DEBUG(0,("msrpc_spoolss_getprinterdriverdir: talloc_init failed!\n"));
+ return False;
+ }
+ init_buffer(&buffer, 0, mem_ctx);
+
+ /* send a NULL buffer first */
+ status=spoolss_getprinterdriverdir(srv_name, env_name, level, &buffer, 0, &needed);
+
+ if (status==ERROR_INSUFFICIENT_BUFFER) {
+ init_buffer(&buffer, needed, mem_ctx);
+ status=spoolss_getprinterdriverdir(srv_name, env_name, level, &buffer, needed, &needed);
+ }
+
+ report(out_hnd, "\tstatus:[%d (%x)]\n", status, status);
+
+ if (status!=NT_STATUS_OK)
+ {
+ if (mem_ctx)
+ talloc_destroy(mem_ctx);
+ return False;
+ }
+
+ switch (level) {
+ case 1:
+ decode_printerdriverdir_info_1(&buffer, &(ctr.driver.info_1));
+ break;
+ }
+
+ display_printerdriverdir_info_ctr(out_hnd, ACTION_HEADER , level, ctr);
+ display_printerdriverdir_info_ctr(out_hnd, ACTION_ENUMERATE, level, ctr);
+ display_printerdriverdir_info_ctr(out_hnd, ACTION_FOOTER , level, ctr);
+
+ if (mem_ctx)
+ talloc_destroy(mem_ctx);
+
+ return True;
+}
diff --git a/source3/rpc_client/ntclienttrust.c b/source3/rpc_client/ntclienttrust.c
new file mode 100644
index 0000000000..284fd491f8
--- /dev/null
+++ b/source3/rpc_client/ntclienttrust.c
@@ -0,0 +1,157 @@
+/*
+ Unix SMB/CIFS implementation.
+ NT Domain Authentication SMB / MSRPC client
+ Copyright (C) Andrew Tridgell 1994-1997
+ Copyright (C) Luke Kenneth Casson Leighton 1996-1997
+
+ 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 2 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, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#include "includes.h"
+
+
+/************************************************************************
+ check workstation trust account status
+ ************************************************************************/
+BOOL trust_account_check(struct in_addr dest_ip, char *dest_host,
+ char *hostname, char *domain, fstring mach_acct,
+ fstring new_mach_pwd)
+{
+ pstring tmp;
+ fstring mach_pwd;
+ struct cli_state cli_trust;
+ uchar lm_owf_mach_pwd[16];
+ uchar nt_owf_mach_pwd[16];
+ uchar lm_sess_pwd[24];
+ uchar nt_sess_pwd[24];
+
+ BOOL right_error_code = False;
+ uint8 err_cls;
+ uint32 err_num;
+
+ char *start_mach_pwd;
+ char *change_mach_pwd;
+
+ /* initial machine password */
+ fstrcpy(mach_pwd, hostname);
+ strlower(mach_pwd);
+
+ slprintf(tmp, sizeof(tmp) - 1,"Enter Workstation Trust Account password for [%s].\nDefault is [%s].\nPassword:",
+ mach_acct, mach_pwd);
+
+ start_mach_pwd = (char*)getpass(tmp);
+
+ if (start_mach_pwd[0] != 0)
+ {
+ fstrcpy(mach_pwd, start_mach_pwd);
+ }
+
+ slprintf(tmp, sizeof(tmp)-1, "Enter new Workstation Trust Account password for [%s]\nPress Return to leave at old value.\nNew Password:",
+ mach_acct);
+
+ change_mach_pwd = (char*)getpass(tmp);
+
+ if (change_mach_pwd[0] != 0)
+ {
+ fstrcpy(new_mach_pwd, change_mach_pwd);
+ }
+ else
+ {
+ DEBUG(1,("trust_account_check: password change not requested\n"));
+ change_mach_pwd[0] = 0;
+ }
+
+ DEBUG(1,("initialise cli_trust connection\n"));
+
+ if (!cli_initialise(&cli_trust))
+ {
+ DEBUG(1,("cli_initialise failed for cli_trust\n"));
+ return False;
+ }
+
+ DEBUG(1,("server connect for cli_trust\n"));
+
+ if (!server_connect_init(&cli_trust, hostname, dest_ip, dest_host))
+ {
+ cli_error(&cli_trust, &err_cls, &err_num, NULL);
+ DEBUG(1,("server_connect_init failed (%s)\n", cli_errstr(&cli_trust)));
+
+ cli_shutdown(&cli_trust);
+ return False;
+ }
+
+ DEBUG(1,("server connect cli_trust succeeded\n"));
+
+ nt_lm_owf_gen(mach_pwd, nt_owf_mach_pwd, lm_owf_mach_pwd);
+
+ DEBUG(5,("generating nt owf from initial machine pwd: %s\n", mach_pwd));
+
+#ifdef DEBUG_PASSWORD
+ DEBUG(100,("client cryptkey: "));
+ dump_data(100, cli_trust.cryptkey, sizeof(cli_trust.cryptkey));
+#endif
+
+ SMBencrypt(nt_owf_mach_pwd, cli_trust.cryptkey, nt_sess_pwd);
+
+#ifdef DEBUG_PASSWORD
+ DEBUG(100,("nt_owf_mach_pwd: "));
+ dump_data(100, nt_owf_mach_pwd, sizeof(lm_owf_mach_pwd));
+ DEBUG(100,("nt_sess_pwd: "));
+ dump_data(100, nt_sess_pwd, sizeof(nt_sess_pwd));
+#endif
+
+ SMBencrypt(lm_owf_mach_pwd, cli_trust.cryptkey, lm_sess_pwd);
+
+#ifdef DEBUG_PASSWORD
+ DEBUG(100,("lm_owf_mach_pwd: "));
+ dump_data(100, lm_owf_mach_pwd, sizeof(lm_owf_mach_pwd));
+ DEBUG(100,("lm_sess_pwd: "));
+ dump_data(100, lm_sess_pwd, sizeof(lm_sess_pwd));
+#endif
+
+ right_error_code = False;
+
+ if (cli_session_setup(&cli_trust, mach_acct,
+ nt_owf_mach_pwd, sizeof(nt_owf_mach_pwd),
+ nt_owf_mach_pwd, sizeof(nt_owf_mach_pwd), domain))
+ {
+ DEBUG(0,("cli_session_setup: NO ERROR! AAAGH! BUG IN SERVER DETECTED!!!\n"));
+ cli_shutdown(&cli_trust);
+
+ return False;
+ }
+
+ cli_error(&cli_trust, &err_cls, &err_num, NULL);
+
+ if (err_num == (0xC0000000 | NT_STATUS_NOLOGON_WORKSTATION_TRUST_ACCOUNT))
+ {
+ DEBUG(1,("cli_send_tconX: valid workstation trust account exists\n"));
+ right_error_code = True;
+ }
+
+ if (err_num == (0xC0000000 | NT_STATUS_NO_SUCH_USER))
+ {
+ DEBUG(1,("cli_send_tconX: workstation trust account does not exist\n"));
+ right_error_code = False;
+ }
+
+ if (!right_error_code)
+ {
+ DEBUG(1,("server_validate failed (%s)\n", cli_errstr(&cli_trust)));
+ }
+
+ cli_shutdown(&cli_trust);
+ return right_error_code;
+}