mirror of
https://github.com/samba-team/samba.git
synced 2025-12-16 00:23:52 +03:00
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 commit is contained in:
@@ -545,31 +545,77 @@ BOOL spoolss_open_printer_ex( const char *printername,
|
|||||||
do a SPOOLSS AddPrinterEx()
|
do a SPOOLSS AddPrinterEx()
|
||||||
**ALWAYS** uses as PRINTER_INFO level 2 struct
|
**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 rbuf;
|
||||||
prs_struct buf;
|
prs_struct buf;
|
||||||
SPOOL_Q_ADDPRINTEREX q_o;
|
SPOOL_Q_ADDPRINTEREX q_o;
|
||||||
|
SPOOL_R_ADDPRINTEREX r_o;
|
||||||
BOOL valid_pol = False;
|
BOOL valid_pol = False;
|
||||||
fstring srv_name;
|
|
||||||
char *s = NULL;
|
char *s = NULL;
|
||||||
struct cli_connection *con = 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))
|
if (!cli_connection_init(srv_name, PIPE_SPOOLSS, &con))
|
||||||
return False;
|
return NT_STATUS_ACCESS_DENIED;
|
||||||
|
|
||||||
if (hnd == NULL) return False;
|
if (hnd == NULL)
|
||||||
|
return NT_STATUS_INVALID_PARAMETER;
|
||||||
|
|
||||||
prs_init(&buf , MAX_PDU_FRAG_LEN, 4, MARSHALL);
|
if ((mem_ctx=talloc_init()) == NULL)
|
||||||
prs_init(&rbuf, 0, 4, UNMARSHALL);
|
{
|
||||||
#endif
|
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);
|
||||||
|
|
||||||
return True;
|
/* 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(!rpc_con_pipe_req(con, SPOOLSS_ADDPRINTEREX, &buf, &rbuf)) {
|
||||||
|
prs_mem_free(&rbuf);
|
||||||
|
prs_mem_free(&buf );
|
||||||
|
|
||||||
|
cli_connection_unlink(con);
|
||||||
|
}
|
||||||
|
|
||||||
|
prs_mem_free(&buf );
|
||||||
|
ZERO_STRUCT(r_o);
|
||||||
|
|
||||||
|
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
|
|||||||
@@ -5,6 +5,7 @@
|
|||||||
* Copyright (C) Andrew Tridgell 1992-2000,
|
* Copyright (C) Andrew Tridgell 1992-2000,
|
||||||
* Copyright (C) Luke Kenneth Casson Leighton 1996-2000,
|
* Copyright (C) Luke Kenneth Casson Leighton 1996-2000,
|
||||||
* Copyright (C) Jean Fran<61>ois Micouleau 1998-2000.
|
* Copyright (C) Jean Fran<61>ois Micouleau 1998-2000.
|
||||||
|
* Copyright (C) Gerald Carter 2000
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* 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
|
* it under the terms of the GNU General Public License as published by
|
||||||
@@ -723,6 +724,112 @@ BOOL make_spoolss_q_open_printer_ex(SPOOL_Q_OPEN_PRINTER_EX *q_u,
|
|||||||
return True;
|
return True;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*******************************************************************
|
||||||
|
* 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.
|
* read a structure.
|
||||||
* called from spoolss_q_open_printer_ex (srv_spoolss.c)
|
* 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");
|
prs_debug(ps, depth, desc, "spoolss_io_q_addprinterex");
|
||||||
depth++;
|
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))
|
if(!prs_align(ps))
|
||||||
return False;
|
return False;
|
||||||
if(!prs_uint32("", ps, depth, &q_u->server_name_ptr))
|
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.
|
* et le security descriptor.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
if(!prs_align(ps))
|
||||||
|
return False;
|
||||||
if(!prs_uint32("unk0", ps, depth, &q_u->unk0))
|
if(!prs_uint32("unk0", ps, depth, &q_u->unk0))
|
||||||
return False;
|
return False;
|
||||||
if(!prs_uint32("unk1", ps, depth, &q_u->unk1))
|
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;
|
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");
|
prs_debug(ps, depth, desc, "spoolss_io_r_addprinterex");
|
||||||
depth++;
|
depth++;
|
||||||
|
|||||||
@@ -512,6 +512,7 @@ uint32 cmd_spoolss_addprinterex(struct client_info *info, int argc, char *argv[]
|
|||||||
fstring srv_port_name;
|
fstring srv_port_name;
|
||||||
BOOL valid_port = False;
|
BOOL valid_port = False;
|
||||||
TALLOC_CTX *mem_ctx = NULL;
|
TALLOC_CTX *mem_ctx = NULL;
|
||||||
|
uint32 result;
|
||||||
|
|
||||||
fstrcpy(srv_name, "\\\\");
|
fstrcpy(srv_name, "\\\\");
|
||||||
fstrcat(srv_name, info->dest_host);
|
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.
|
* Need to build the PRINTER_INFO_2 struct here.
|
||||||
* I think it would be better only to deal with a PRINTER_INFO_2
|
* 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
|
* 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...
|
* on the wire. We don't need the extra *_ptr fields, etc...
|
||||||
* here anyways. --jerry
|
* 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.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.portname, port_name);
|
||||||
init_unistr( &print_info_2.drivername, driver_name);
|
init_unistr( &print_info_2.drivername, driver_name);
|
||||||
init_unistr( &print_info_2.comment, "Created by rpcclient");
|
init_unistr( &print_info_2.comment, "Created by rpcclient");
|
||||||
init_unistr( &print_info_2.location, "");
|
/* init_unistr( &print_info_2.location, "");
|
||||||
init_unistr (&print_info_2.sepfile, "");
|
init_unistr( &print_info_2.sepfile, ""); */
|
||||||
init_unistr( &print_info_2.printprocessor, "winprint");
|
init_unistr( &print_info_2.printprocessor, "winprint");
|
||||||
init_unistr( &print_info_2.datatype, "RAW");
|
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.devmode = NULL;
|
||||||
print_info_2.secdesc = NULL;
|
print_info_2.secdesc = NULL;
|
||||||
print_info_2.attributes = 0;
|
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
|
/* if successful, spoolss_addprinterex() should return True and hnd
|
||||||
should be a valid handle to an open printer */
|
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 ))
|
if (!spoolss_closeprinter( &hnd ))
|
||||||
{
|
{
|
||||||
@@ -627,7 +629,7 @@ uint32 cmd_spoolss_addprinterex(struct client_info *info, int argc, char *argv[]
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
report (out_hnd, "cmd_spoolss_addprinterex: spoolss_addprinterex FAILED!\n");
|
report (out_hnd, "cmd_spoolss_addprinterex: spoolss_addprinterex FAILED! [%d]\n", result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user