diff options
Diffstat (limited to 'source3')
-rw-r--r-- | source3/rpc_client/cli_spoolss.c | 68 | ||||
-rw-r--r-- | source3/rpc_parse/parse_spoolss.c | 119 | ||||
-rw-r--r-- | source3/rpcclient/cmd_spoolss.c | 18 |
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); } |