summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGerald Carter <jerry@samba.org>2000-08-04 12:46:36 +0000
committerGerald Carter <jerry@samba.org>2000-08-04 12:46:36 +0000
commit4003a1c55bda51fa418ec7c077bfad775ac88ba5 (patch)
tree1ef984627787836e253cdbede8c9b5551210158a
parent394795e28b00eb95759938770cd24ee7c75ed39d (diff)
downloadsamba-4003a1c55bda51fa418ec7c077bfad775ac88ba5.tar.gz
samba-4003a1c55bda51fa418ec7c077bfad775ac88ba5.tar.bz2
samba-4003a1c55bda51fa418ec7c077bfad775ac88ba5.zip
clunky support for calling AddPrinterEx(). The code currently reports
that the call failed, but the printer shows up on the remote NT client. (note this is the client side call). I've botched the return value somewhere and will fix that today. jerry (This used to be commit e15d9befd24cf5f3410c4be819b2a1fcf68048fb)
-rw-r--r--source3/rpc_client/cli_spoolss.c68
-rw-r--r--source3/rpc_parse/parse_spoolss.c119
-rw-r--r--source3/rpcclient/cmd_spoolss.c18
3 files changed, 178 insertions, 27 deletions
diff --git a/source3/rpc_client/cli_spoolss.c b/source3/rpc_client/cli_spoolss.c
index 5dda49b4b5..902f6e2bfe 100644
--- a/source3/rpc_client/cli_spoolss.c
+++ b/source3/rpc_client/cli_spoolss.c
@@ -545,31 +545,77 @@ BOOL spoolss_open_printer_ex( const char *printername,
do a SPOOLSS AddPrinterEx()
**ALWAYS** uses as PRINTER_INFO level 2 struct
****************************************************************************/
-BOOL spoolss_addprinterex(POLICY_HND *hnd, PRINTER_INFO_2 *info2)
+uint32 spoolss_addprinterex(POLICY_HND *hnd,const char* srv_name, PRINTER_INFO_2 *info2)
{
-#if 0
prs_struct rbuf;
prs_struct buf;
SPOOL_Q_ADDPRINTEREX q_o;
+ SPOOL_R_ADDPRINTEREX r_o;
BOOL valid_pol = False;
- fstring srv_name;
char *s = NULL;
struct cli_connection *con = NULL;
+ TALLOC_CTX *mem_ctx = NULL;
+ fstring client_name;
- memset(srv_name, 0, sizeof(srv_name));
- unistr_to_ascii(srv_name, info2->servername.buffer, sizeof(srv_name));
+
+ /* memset(srv_name, 0, sizeof(srv_name));
+ unistr_to_ascii(srv_name, info2->servername.buffer, sizeof(srv_name)); */
if (!cli_connection_init(srv_name, PIPE_SPOOLSS, &con))
- return False;
+ return NT_STATUS_ACCESS_DENIED;
+
+ if (hnd == NULL)
+ return NT_STATUS_INVALID_PARAMETER;
+
+ if ((mem_ctx=talloc_init()) == NULL)
+ {
+ DEBUG(0,("spoolss_addprinterex: talloc_init() failed!\n"));
+ return NT_STATUS_ACCESS_DENIED;
+ }
+ prs_init(&buf , MAX_PDU_FRAG_LEN, 4, mem_ctx, MARSHALL);
+ prs_init(&rbuf, 0, 4, mem_ctx, UNMARSHALL);
+
+ /* create and send a MSRPC command with api SPOOLSS_ENUMPORTS */
+ DEBUG(5,("SPOOLSS Add Printer Ex (Server: %s)\n", srv_name));
+
+ fstrcpy(client_name, "\\\\");
+ fstrcat(client_name, con->pCli_state->desthost);
+ strupper(client_name);
+
+
+ make_spoolss_q_addprinterex(&q_o, srv_name, client_name,
+ "Administrator", 2, info2);
+
+ /* turn parameters into data stream */
+ if (!spoolss_io_q_addprinterex("", &q_o, &buf, 0) ) {
+ prs_mem_free(&rbuf);
+ prs_mem_free(&buf );
+
+ cli_connection_unlink(con);
+ }
- if (hnd == NULL) return False;
+ if(!rpc_con_pipe_req(con, SPOOLSS_ADDPRINTEREX, &buf, &rbuf)) {
+ prs_mem_free(&rbuf);
+ prs_mem_free(&buf );
- prs_init(&buf , MAX_PDU_FRAG_LEN, 4, MARSHALL);
- prs_init(&rbuf, 0, 4, UNMARSHALL);
-#endif
+ cli_connection_unlink(con);
+ }
+
+ prs_mem_free(&buf );
+ ZERO_STRUCT(r_o);
- return True;
+ if(!spoolss_io_r_addprinterex("", &r_o, &rbuf, 0)) {
+ prs_mem_free(&rbuf);
+ cli_connection_unlink(con);
+ }
+
+ prs_mem_free(&rbuf);
+ prs_mem_free(&buf );
+
+ cli_connection_unlink(con);
+
+ return r_o.status;
}
/****************************************************************************
diff --git a/source3/rpc_parse/parse_spoolss.c b/source3/rpc_parse/parse_spoolss.c
index bd33b634f8..033b680e64 100644
--- a/source3/rpc_parse/parse_spoolss.c
+++ b/source3/rpc_parse/parse_spoolss.c
@@ -5,6 +5,7 @@
* Copyright (C) Andrew Tridgell 1992-2000,
* Copyright (C) Luke Kenneth Casson Leighton 1996-2000,
* Copyright (C) Jean François Micouleau 1998-2000.
+ * Copyright (C) Gerald Carter 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
@@ -724,6 +725,112 @@ BOOL make_spoolss_q_open_printer_ex(SPOOL_Q_OPEN_PRINTER_EX *q_u,
}
/*******************************************************************
+ * init a structure.
+ ********************************************************************/
+BOOL make_spoolss_q_addprinterex(SPOOL_Q_ADDPRINTEREX *q_u, const char *srv_name,
+ const char* clientname, const char* user_name,
+ uint32 level, PRINTER_INFO_2 *info)
+{
+ DEBUG(5,("make_spoolss_q_addprinterex\n"));
+
+ q_u->server_name_ptr = (srv_name!=NULL)?1:0;
+ init_unistr2(&q_u->server_name, srv_name, strlen(srv_name));
+
+ q_u->level = level;
+
+ q_u->info.level = level;
+ q_u->info.info_ptr = (info!=NULL)?1:0;
+ switch (level)
+ {
+ case 2:
+ /* init q_u->info.info2 from *info */
+ if (!make_spool_printer_info_2( &q_u->info.info_2, info))
+ {
+ DEBUG(0,("make_spoolss_q_addprinterex: Unable to fill SPOOL_Q_ADDPRINTEREX struct!\n"));
+ return False;
+ }
+ break;
+ default :
+ break;
+ }
+
+ q_u->unk0 = q_u->unk1 = q_u->unk2 = q_u->unk3 = 0;
+
+ q_u->user_switch=1;
+
+ q_u->user_ctr.level=1;
+ q_u->user_ctr.ptr=1;
+ q_u->user_ctr.user1.size=strlen(clientname)+strlen(user_name)+8;
+ q_u->user_ctr.user1.client_name_ptr = (clientname!=NULL)?1:0;
+ q_u->user_ctr.user1.user_name_ptr = (user_name!=NULL)?1:0;
+ q_u->user_ctr.user1.build=1381;
+ q_u->user_ctr.user1.major=2;
+ q_u->user_ctr.user1.minor=0;
+ q_u->user_ctr.user1.processor=0;
+ init_unistr2(&q_u->user_ctr.user1.client_name, clientname, strlen(clientname));
+ init_unistr2(&q_u->user_ctr.user1.user_name, user_name, strlen(user_name));
+
+ return True;
+}
+/*******************************************************************
+create a SPOOL_PRINTER_INFO_2 stuct from a PRINTER_INFO_2 struct
+*******************************************************************/
+BOOL make_spool_printer_info_2(SPOOL_PRINTER_INFO_LEVEL_2 **spool_info2,
+ PRINTER_INFO_2 *info)
+{
+
+ SPOOL_PRINTER_INFO_LEVEL_2 *inf;
+
+ /* allocate the necessary memory */
+ inf = (SPOOL_PRINTER_INFO_LEVEL_2*)malloc(sizeof(SPOOL_PRINTER_INFO_LEVEL_2));
+ if (spool_info2 == NULL)
+ {
+ DEBUG(0,("make_spool_printer_info_2: Unable to malloc SPOOL_PRINTER_INFO_LEVEL_2 sruct!\n"));
+ return False;
+ }
+
+ ZERO_STRUCTP(inf);
+
+ inf->servername_ptr = (info->servername.buffer!=NULL)?1:0;
+ inf->printername_ptr = (info->printername.buffer!=NULL)?1:0;
+ inf->sharename_ptr = (info->sharename.buffer!=NULL)?1:0;
+ inf->portname_ptr = (info->portname.buffer!=NULL)?1:0;
+ inf->drivername_ptr = (info->drivername.buffer!=NULL)?1:0;
+ inf->comment_ptr = (info->comment.buffer!=NULL)?1:0;
+ inf->location_ptr = (info->location.buffer!=NULL)?1:0;
+ inf->devmode_ptr = (info->devmode!=NULL)?1:0;
+ inf->sepfile_ptr = (info->sepfile.buffer!=NULL)?1:0;
+ inf->printprocessor_ptr = (info->printprocessor.buffer!=NULL)?1:0;
+ inf->datatype_ptr = (info->datatype.buffer!=NULL)?1:0;
+ inf->parameters_ptr = (info->parameters.buffer!=NULL)?1:0;
+ inf->secdesc_ptr = (info->secdesc!=NULL)?1:0;
+ inf->attributes = info->attributes;
+ inf->priority = info->priority;
+ inf->default_priority = info->defaultpriority;
+ inf->starttime = info->starttime;
+ inf->untiltime = info->untiltime;
+ inf->cjobs = info->cjobs;
+ inf->averageppm = info->averageppm;
+ init_unistr2_from_unistr(&inf->servername, &info->servername);
+ init_unistr2_from_unistr(&inf->printername, &info->printername);
+ init_unistr2_from_unistr(&inf->sharename, &info->sharename);
+ init_unistr2_from_unistr(&inf->portname, &info->portname);
+ init_unistr2_from_unistr(&inf->drivername, &info->drivername);
+ init_unistr2_from_unistr(&inf->comment, &info->comment);
+ init_unistr2_from_unistr(&inf->location, &info->location);
+ init_unistr2_from_unistr(&inf->sepfile, &info->sepfile);
+ init_unistr2_from_unistr(&inf->printprocessor, &info->printprocessor);
+ init_unistr2_from_unistr(&inf->datatype, &info->datatype);
+ init_unistr2_from_unistr(&inf->parameters, &info->parameters);
+ init_unistr2_from_unistr(&inf->datatype, &info->datatype);
+ inf->secdesc = NULL;
+
+ *spool_info2 = inf;
+
+ return True;
+}
+
+/*******************************************************************
* read a structure.
* called from spoolss_q_open_printer_ex (srv_spoolss.c)
********************************************************************/
@@ -3741,12 +3848,6 @@ BOOL spoolss_io_q_addprinterex(char *desc, SPOOL_Q_ADDPRINTEREX *q_u, prs_struct
prs_debug(ps, depth, desc, "spoolss_io_q_addprinterex");
depth++;
- /*
- * I think that's one of the few well written functions.
- * the sub-structures are correctly parsed and analysed
- * the info level are handled in a nice way.
- */
-
if(!prs_align(ps))
return False;
if(!prs_uint32("", ps, depth, &q_u->server_name_ptr))
@@ -3772,6 +3873,8 @@ BOOL spoolss_io_q_addprinterex(char *desc, SPOOL_Q_ADDPRINTEREX *q_u, prs_struct
* et le security descriptor.
*/
+ if(!prs_align(ps))
+ return False;
if(!prs_uint32("unk0", ps, depth, &q_u->unk0))
return False;
if(!prs_uint32("unk1", ps, depth, &q_u->unk1))
@@ -3789,10 +3892,10 @@ BOOL spoolss_io_q_addprinterex(char *desc, SPOOL_Q_ADDPRINTEREX *q_u, prs_struct
return True;
}
-
/*******************************************************************
********************************************************************/
-BOOL spoolss_io_r_addprinterex(char *desc, SPOOL_R_ADDPRINTEREX *r_u, prs_struct *ps, int depth)
+BOOL spoolss_io_r_addprinterex(char *desc, SPOOL_R_ADDPRINTEREX *r_u,
+ prs_struct *ps, int depth)
{
prs_debug(ps, depth, desc, "spoolss_io_r_addprinterex");
depth++;
diff --git a/source3/rpcclient/cmd_spoolss.c b/source3/rpcclient/cmd_spoolss.c
index 5a614a38b5..058c6db457 100644
--- a/source3/rpcclient/cmd_spoolss.c
+++ b/source3/rpcclient/cmd_spoolss.c
@@ -512,6 +512,7 @@ uint32 cmd_spoolss_addprinterex(struct client_info *info, int argc, char *argv[]
fstring srv_port_name;
BOOL valid_port = False;
TALLOC_CTX *mem_ctx = NULL;
+ uint32 result;
fstrcpy(srv_name, "\\\\");
fstrcat(srv_name, info->dest_host);
@@ -589,21 +590,22 @@ uint32 cmd_spoolss_addprinterex(struct client_info *info, int argc, char *argv[]
* Need to build the PRINTER_INFO_2 struct here.
* I think it would be better only to deal with a PRINTER_INFO_2
* and the abstract the creation of a SPOOL_PRINTER_INFO_LEVEL_2
- * from that rather than dealing with the struct passed dircetly
+ * from that rather than dealing with the struct passed directly
* on the wire. We don't need the extra *_ptr fields, etc...
* here anyways. --jerry
*/
- init_unistr( &print_info_2.servername, srv_name);
+ ZERO_STRUCTP(&print_info_2);
+ /* init_unistr( &print_info_2.servername, srv_name); */
init_unistr( &print_info_2.printername, printer_name);
- init_unistr( &print_info_2.sharename, printer_name);
+ /* init_unistr( &print_info_2.sharename, share_name); */
init_unistr( &print_info_2.portname, port_name);
init_unistr( &print_info_2.drivername, driver_name);
init_unistr( &print_info_2.comment, "Created by rpcclient");
- init_unistr( &print_info_2.location, "");
- init_unistr (&print_info_2.sepfile, "");
+ /* init_unistr( &print_info_2.location, "");
+ init_unistr( &print_info_2.sepfile, ""); */
init_unistr( &print_info_2.printprocessor, "winprint");
init_unistr( &print_info_2.datatype, "RAW");
- init_unistr( &print_info_2.parameters, "");
+ /* init_unistr( &print_info_2.parameters, ""); */
print_info_2.devmode = NULL;
print_info_2.secdesc = NULL;
print_info_2.attributes = 0;
@@ -618,7 +620,7 @@ uint32 cmd_spoolss_addprinterex(struct client_info *info, int argc, char *argv[]
/* if successful, spoolss_addprinterex() should return True and hnd
should be a valid handle to an open printer */
- if (spoolss_addprinterex(&hnd, &print_info_2))
+ if ((result = spoolss_addprinterex(&hnd, srv_name, &print_info_2)) == NT_STATUS_NOPROBLEMO)
{
if (!spoolss_closeprinter( &hnd ))
{
@@ -627,7 +629,7 @@ uint32 cmd_spoolss_addprinterex(struct client_info *info, int argc, char *argv[]
}
else
{
- report (out_hnd, "cmd_spoolss_addprinterex: spoolss_addprinterex FAILED!\n");
+ report (out_hnd, "cmd_spoolss_addprinterex: spoolss_addprinterex FAILED! [%d]\n", result);
}