2008-05-08 13:23:38 +04:00
/*
Samba Unix / Linux SMB client library
Distributed SMB / CIFS Server Management Utility
2009-02-25 16:33:59 +03:00
Copyright ( C ) 2004 , 2009 Guenther Deschner ( gd @ samba . org )
2004-08-10 18:27:17 +04:00
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
2007-07-09 23:25:36 +04:00
the Free Software Foundation ; either version 3 of the License , or
2004-08-10 18:27:17 +04:00
( at your option ) any later version .
2008-05-08 13:23:38 +04:00
2004-08-10 18:27:17 +04:00
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 .
2008-05-08 13:23:38 +04:00
2004-08-10 18:27:17 +04:00
You should have received a copy of the GNU General Public License
2008-05-10 01:22:12 +04:00
along with this program . If not , see < http : //www.gnu.org/licenses/>.
*/
2004-08-10 18:27:17 +04:00
# include "includes.h"
2004-10-07 08:01:18 +04:00
# include "utils/net.h"
2009-11-26 20:21:28 +03:00
# include "../librpc/gen_ndr/cli_spoolss.h"
2010-05-18 20:26:48 +04:00
# include "rpc_client/cli_spoolss.h"
2010-06-03 18:30:55 +04:00
# include "rpc_client/init_spoolss.h"
2010-07-31 02:47:20 +04:00
# include "nt_printing.h"
2009-10-02 02:17:06 +04:00
# include "registry.h"
2010-05-25 03:00:37 +04:00
# include "registry/reg_objects.h"
2004-08-10 18:27:17 +04:00
/* support itanium as well */
2009-05-12 16:15:01 +04:00
static const struct print_architecture_table_node archi_table [ ] = {
2004-08-10 18:27:17 +04:00
{ " Windows 4.0 " , " WIN40 " , 0 } ,
{ " Windows NT x86 " , " W32X86 " , 2 } ,
2004-10-07 18:47:53 +04:00
{ " Windows NT x86 " , " W32X86 " , 3 } ,
2004-08-10 18:27:17 +04:00
{ " Windows NT R4000 " , " W32MIPS " , 2 } ,
{ " Windows NT Alpha_AXP " , " W32ALPHA " , 2 } ,
{ " Windows NT PowerPC " , " W32PPC " , 2 } ,
2004-10-05 02:13:57 +04:00
{ " Windows IA64 " , " IA64 " , 3 } ,
{ " Windows x64 " , " x64 " , 3 } ,
2004-08-10 18:27:17 +04:00
{ NULL , " " , - 1 }
} ;
/**
* This display - printdriver - functions was borrowed from rpcclient / cmd_spoolss . c .
* It is here for debugging purpose and should be removed later on .
* */
/****************************************************************************
2005-09-30 21:13:37 +04:00
Printer info level 3 display function .
2004-08-10 18:27:17 +04:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2005-09-30 21:13:37 +04:00
2009-02-25 00:23:56 +03:00
static void display_print_driver3 ( struct spoolss_DriverInfo3 * r )
{
int i ;
if ( ! r ) {
return ;
}
2009-08-10 20:24:57 +04:00
printf ( _ ( " Printer Driver Info 3: \n " ) ) ;
printf ( _ ( " \t Version: [%x] \n " ) , r - > version ) ;
printf ( _ ( " \t Driver Name: [%s] \n " ) , r - > driver_name ) ;
printf ( _ ( " \t Architecture: [%s] \n " ) , r - > architecture ) ;
printf ( _ ( " \t Driver Path: [%s] \n " ) , r - > driver_path ) ;
printf ( _ ( " \t Datafile: [%s] \n " ) , r - > data_file ) ;
printf ( _ ( " \t Configfile: [%s] \n \n " ) , r - > config_file ) ;
printf ( _ ( " \t Helpfile: [%s] \n \n " ) , r - > help_file ) ;
2009-02-25 00:23:56 +03:00
for ( i = 0 ; r - > dependent_files [ i ] ! = NULL ; i + + ) {
2009-08-10 20:24:57 +04:00
printf ( _ ( " \t Dependentfiles: [%s] \n " ) , r - > dependent_files [ i ] ) ;
2009-02-25 00:23:56 +03:00
}
printf ( " \n " ) ;
2009-08-10 20:24:57 +04:00
printf ( _ ( " \t Monitorname: [%s] \n " ) , r - > monitor_name ) ;
printf ( _ ( " \t Defaultdatatype: [%s] \n \n " ) , r - > default_datatype ) ;
2009-02-25 00:23:56 +03:00
}
2010-05-24 16:48:31 +04:00
static void display_reg_value ( const char * subkey , struct regval_blob * value )
2004-08-10 18:27:17 +04:00
{
2009-09-30 22:00:52 +04:00
const char * text ;
DATA_BLOB blob ;
2004-08-10 18:27:17 +04:00
2010-05-24 16:48:31 +04:00
switch ( regval_type ( value ) ) {
2004-08-10 18:27:17 +04:00
case REG_DWORD :
2009-08-10 20:24:57 +04:00
d_printf ( _ ( " \t [%s:%s]: REG_DWORD: 0x%08x \n " ) , subkey ,
2010-05-24 16:48:31 +04:00
regval_name ( value ) , * ( ( uint32_t * ) regval_data_p ( value ) ) ) ;
2004-08-10 18:27:17 +04:00
break ;
case REG_SZ :
2010-05-24 16:48:31 +04:00
blob = data_blob_const ( regval_data_p ( value ) , regval_size ( value ) ) ;
2010-05-10 02:42:06 +04:00
pull_reg_sz ( talloc_tos ( ) , & blob , & text ) ;
2007-12-05 02:45:20 +03:00
if ( ! text ) {
break ;
}
2010-05-24 16:48:31 +04:00
d_printf ( _ ( " \t [%s:%s]: REG_SZ: %s \n " ) , subkey , regval_name ( value ) ,
2009-08-10 20:24:57 +04:00
text ) ;
2004-08-10 18:27:17 +04:00
break ;
2007-12-05 02:45:20 +03:00
case REG_BINARY :
2009-08-10 20:24:57 +04:00
d_printf ( _ ( " \t [%s:%s]: REG_BINARY: unknown length value not "
" displayed \n " ) ,
2010-05-24 16:48:31 +04:00
subkey , regval_name ( value ) ) ;
2004-08-10 18:27:17 +04:00
break ;
case REG_MULTI_SZ : {
2009-09-30 01:22:46 +04:00
uint32_t i ;
const char * * values ;
2010-05-24 16:48:31 +04:00
blob = data_blob_const ( regval_data_p ( value ) , regval_size ( value ) ) ;
2006-07-11 22:01:26 +04:00
2010-05-10 02:42:06 +04:00
if ( ! pull_reg_multi_sz ( NULL , & blob , & values ) ) {
2009-09-30 01:22:46 +04:00
d_printf ( " pull_reg_multi_sz failed \n " ) ;
2006-07-11 22:01:26 +04:00
break ;
2004-08-10 18:27:17 +04:00
}
2006-07-11 22:01:26 +04:00
2010-05-24 16:48:31 +04:00
printf ( " %s: REG_MULTI_SZ: \n " , regval_name ( value ) ) ;
2009-09-30 01:22:46 +04:00
for ( i = 0 ; values [ i ] ! = NULL ; i + + ) {
2006-07-11 22:01:26 +04:00
d_printf ( " %s \n " , values [ i ] ) ;
}
TALLOC_FREE ( values ) ;
break ;
2004-08-10 18:27:17 +04:00
}
default :
2010-05-24 16:48:31 +04:00
d_printf ( _ ( " \t %s: unknown type %d \n " ) , regval_name ( value ) ,
regval_type ( value ) ) ;
2004-08-10 18:27:17 +04:00
}
2008-05-08 13:23:38 +04:00
2004-08-10 18:27:17 +04:00
}
2004-08-25 00:52:56 +04:00
/**
2008-05-08 13:23:38 +04:00
* Copies ACLs , DOS - attributes and timestamps from one
* file or directory from one connected share to another connected share
2004-08-25 00:52:56 +04:00
*
2008-05-10 01:22:12 +04:00
* @ param c A net_context structure
2004-08-25 00:52:56 +04:00
* @ param mem_ctx A talloc - context
2008-05-08 13:23:38 +04:00
* @ param cli_share_src A connected cli_state
* @ param cli_share_dst A connected cli_state
2004-08-25 00:52:56 +04:00
* @ param src_file The source file - name
* @ param dst_file The destination file - name
* @ param copy_acls Whether to copy acls
* @ param copy_attrs Whether to copy DOS attributes
* @ param copy_timestamps Whether to preserve timestamps
* @ param is_file Whether this file is a file or a dir
*
* @ return Normal NTSTATUS return .
2008-05-08 13:23:38 +04:00
* */
2005-09-30 21:13:37 +04:00
2008-05-10 01:22:12 +04:00
NTSTATUS net_copy_fileattr ( struct net_context * c ,
TALLOC_CTX * mem_ctx ,
2004-08-25 00:52:56 +04:00
struct cli_state * cli_share_src ,
2008-05-08 13:23:38 +04:00
struct cli_state * cli_share_dst ,
2005-06-15 17:01:19 +04:00
const char * src_name , const char * dst_name ,
2007-10-19 04:40:25 +04:00
bool copy_acls , bool copy_attrs ,
bool copy_timestamps , bool is_file )
2004-08-25 00:52:56 +04:00
{
NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL ;
2009-05-01 02:26:43 +04:00
uint16_t fnum_src = 0 ;
uint16_t fnum_dst = 0 ;
2010-05-18 12:29:34 +04:00
struct security_descriptor * sd = NULL ;
2009-03-19 14:53:01 +03:00
uint16_t attr ;
2004-11-19 22:45:03 +03:00
time_t f_atime , f_ctime , f_mtime ;
2004-08-25 00:52:56 +04:00
if ( ! copy_timestamps & & ! copy_acls & & ! copy_attrs )
return NT_STATUS_OK ;
/* open file/dir on the originating server */
2008-05-08 13:23:38 +04:00
DEBUGADD ( 3 , ( " opening %s %s on originating server \n " ,
2004-08-25 00:52:56 +04:00
is_file ? " file " : " dir " , src_name ) ) ;
2009-05-01 02:26:43 +04:00
if ( ! NT_STATUS_IS_OK ( cli_ntcreate ( cli_share_src , src_name , 0 , READ_CONTROL_ACCESS , 0 ,
FILE_SHARE_READ | FILE_SHARE_WRITE , FILE_OPEN , 0x0 , 0x0 , & fnum_src ) ) ) {
2008-05-08 13:23:38 +04:00
DEBUGADD ( 0 , ( " cannot open %s %s on originating server %s \n " ,
2004-08-25 00:52:56 +04:00
is_file ? " file " : " dir " , src_name , cli_errstr ( cli_share_src ) ) ) ;
nt_status = cli_nt_error ( cli_share_src ) ;
goto out ;
}
if ( copy_acls ) {
/* get the security descriptor */
sd = cli_query_secdesc ( cli_share_src , fnum_src , mem_ctx ) ;
if ( ! sd ) {
DEBUG ( 0 , ( " failed to get security descriptor: %s \n " ,
cli_errstr ( cli_share_src ) ) ) ;
nt_status = cli_nt_error ( cli_share_src ) ;
goto out ;
}
2008-05-10 01:22:12 +04:00
if ( c - > opt_verbose & & DEBUGLEVEL > = 3 )
2004-08-25 00:52:56 +04:00
display_sec_desc ( sd ) ;
}
if ( copy_attrs | | copy_timestamps ) {
/* get file attributes */
2009-05-06 03:28:44 +04:00
if ( ! NT_STATUS_IS_OK ( cli_getattrE ( cli_share_src , fnum_src , & attr , NULL ,
& f_ctime , & f_atime , & f_mtime ) ) ) {
2008-05-08 13:23:38 +04:00
DEBUG ( 0 , ( " failed to get file-attrs: %s \n " ,
2004-08-25 00:52:56 +04:00
cli_errstr ( cli_share_src ) ) ) ;
nt_status = cli_nt_error ( cli_share_src ) ;
goto out ;
}
}
2008-05-08 13:23:38 +04:00
/* open the file/dir on the destination server */
2004-08-25 00:52:56 +04:00
2009-05-01 02:26:43 +04:00
if ( ! NT_STATUS_IS_OK ( cli_ntcreate ( cli_share_dst , dst_name , 0 , WRITE_DAC_ACCESS | WRITE_OWNER_ACCESS , 0 ,
FILE_SHARE_READ | FILE_SHARE_WRITE , FILE_OPEN , 0x0 , 0x0 , & fnum_dst ) ) ) {
2004-08-25 00:52:56 +04:00
DEBUG ( 0 , ( " failed to open %s on the destination server: %s: %s \n " ,
is_file ? " file " : " dir " , dst_name , cli_errstr ( cli_share_dst ) ) ) ;
nt_status = cli_nt_error ( cli_share_dst ) ;
goto out ;
}
if ( copy_timestamps ) {
/* set timestamps */
2009-05-07 02:07:05 +04:00
if ( ! NT_STATUS_IS_OK ( cli_setattrE ( cli_share_dst , fnum_dst , f_ctime , f_atime , f_mtime ) ) ) {
2004-08-25 00:52:56 +04:00
DEBUG ( 0 , ( " failed to set file-attrs (timestamps): %s \n " ,
cli_errstr ( cli_share_dst ) ) ) ;
nt_status = cli_nt_error ( cli_share_dst ) ;
goto out ;
}
}
if ( copy_acls ) {
/* set acls */
if ( ! cli_set_secdesc ( cli_share_dst , fnum_dst , sd ) ) {
DEBUG ( 0 , ( " could not set secdesc on %s: %s \n " ,
dst_name , cli_errstr ( cli_share_dst ) ) ) ;
nt_status = cli_nt_error ( cli_share_dst ) ;
goto out ;
}
}
if ( copy_attrs ) {
/* set attrs */
2009-05-07 03:13:42 +04:00
if ( ! NT_STATUS_IS_OK ( cli_setatr ( cli_share_dst , dst_name , attr , 0 ) ) ) {
2004-08-25 00:52:56 +04:00
DEBUG ( 0 , ( " failed to set file-attrs: %s \n " ,
cli_errstr ( cli_share_dst ) ) ) ;
nt_status = cli_nt_error ( cli_share_dst ) ;
goto out ;
}
}
/* closing files */
2009-05-01 03:57:42 +04:00
if ( ! NT_STATUS_IS_OK ( cli_close ( cli_share_src , fnum_src ) ) ) {
2009-08-10 20:24:57 +04:00
d_fprintf ( stderr ,
_ ( " could not close %s on originating server: %s \n " ) ,
2004-08-25 00:52:56 +04:00
is_file ? " file " : " dir " , cli_errstr ( cli_share_src ) ) ;
nt_status = cli_nt_error ( cli_share_src ) ;
goto out ;
}
2009-05-01 03:57:42 +04:00
if ( ! NT_STATUS_IS_OK ( cli_close ( cli_share_dst , fnum_dst ) ) ) {
2009-08-10 20:24:57 +04:00
d_fprintf ( stderr ,
_ ( " could not close %s on destination server: %s \n " ) ,
2004-08-25 00:52:56 +04:00
is_file ? " file " : " dir " , cli_errstr ( cli_share_dst ) ) ;
nt_status = cli_nt_error ( cli_share_dst ) ;
goto out ;
}
nt_status = NT_STATUS_OK ;
out :
/* cleaning up */
if ( fnum_src )
cli_close ( cli_share_src , fnum_src ) ;
if ( fnum_dst )
cli_close ( cli_share_dst , fnum_dst ) ;
return nt_status ;
}
2004-08-10 18:27:17 +04:00
/**
2008-05-08 13:23:38 +04:00
* Copy a file or directory from a connected share to another connected share
2004-08-10 18:27:17 +04:00
*
2008-05-10 01:22:12 +04:00
* @ param c A net_context structure
2004-08-10 18:27:17 +04:00
* @ param mem_ctx A talloc - context
2008-05-08 13:23:38 +04:00
* @ param cli_share_src A connected cli_state
* @ param cli_share_dst A connected cli_state
2004-08-10 18:27:17 +04:00
* @ param src_file The source file - name
* @ param dst_file The destination file - name
* @ param copy_acls Whether to copy acls
2004-08-21 00:13:05 +04:00
* @ param copy_attrs Whether to copy DOS attributes
* @ param copy_timestamps Whether to preserve timestamps
2004-08-10 18:27:17 +04:00
* @ param is_file Whether this file is a file or a dir
*
* @ return Normal NTSTATUS return .
2008-05-08 13:23:38 +04:00
* */
2005-09-30 21:13:37 +04:00
2008-05-10 01:22:12 +04:00
NTSTATUS net_copy_file ( struct net_context * c ,
TALLOC_CTX * mem_ctx ,
2004-08-10 18:27:17 +04:00
struct cli_state * cli_share_src ,
2008-05-08 13:23:38 +04:00
struct cli_state * cli_share_dst ,
2005-06-15 17:01:19 +04:00
const char * src_name , const char * dst_name ,
2007-10-19 04:40:25 +04:00
bool copy_acls , bool copy_attrs ,
bool copy_timestamps , bool is_file )
2004-08-10 18:27:17 +04:00
{
NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL ;
2009-05-01 02:26:43 +04:00
uint16_t fnum_src = 0 ;
uint16_t fnum_dst = 0 ;
2004-08-10 18:27:17 +04:00
static int io_bufsize = 64512 ;
int read_size = io_bufsize ;
char * data = NULL ;
off_t nread = 0 ;
2004-08-25 00:52:56 +04:00
if ( ! src_name | | ! dst_name )
goto out ;
2005-03-23 00:24:16 +03:00
if ( cli_share_src = = NULL | | cli_share_dst = = NULL )
2008-05-08 13:23:38 +04:00
goto out ;
2004-08-10 18:27:17 +04:00
/* open on the originating server */
2008-05-08 13:23:38 +04:00
DEBUGADD ( 3 , ( " opening %s %s on originating server \n " ,
2004-08-10 18:27:17 +04:00
is_file ? " file " : " dir " , src_name ) ) ;
if ( is_file )
2009-05-01 02:26:43 +04:00
nt_status = cli_open ( cli_share_src , src_name , O_RDONLY , DENY_NONE , & fnum_src ) ;
2004-08-10 18:27:17 +04:00
else
2009-05-01 02:26:43 +04:00
nt_status = cli_ntcreate ( cli_share_src , src_name , 0 , READ_CONTROL_ACCESS , 0 ,
FILE_SHARE_READ | FILE_SHARE_WRITE , FILE_OPEN , 0x0 , 0x0 , & fnum_src ) ;
2004-08-10 18:27:17 +04:00
2009-05-01 02:26:43 +04:00
if ( ! NT_STATUS_IS_OK ( nt_status ) ) {
2005-06-13 01:18:16 +04:00
DEBUGADD ( 0 , ( " cannot open %s %s on originating server %s \n " ,
is_file ? " file " : " dir " ,
2004-08-25 00:52:56 +04:00
src_name , cli_errstr ( cli_share_src ) ) ) ;
2004-08-10 18:27:17 +04:00
goto out ;
}
2004-08-25 00:52:56 +04:00
2004-08-10 18:27:17 +04:00
if ( is_file ) {
2004-08-25 00:52:56 +04:00
/* open file on the destination server */
2004-08-10 18:27:17 +04:00
DEBUGADD ( 3 , ( " opening file %s on destination server \n " , dst_name ) ) ;
2009-05-01 02:26:43 +04:00
nt_status = cli_open ( cli_share_dst , dst_name ,
O_RDWR | O_CREAT | O_TRUNC , DENY_NONE , & fnum_dst ) ;
2004-08-10 18:27:17 +04:00
2009-05-01 02:26:43 +04:00
if ( ! NT_STATUS_IS_OK ( nt_status ) ) {
2004-08-25 00:52:56 +04:00
DEBUGADD ( 1 , ( " cannot create file %s on destination server: %s \n " ,
2004-08-10 18:27:17 +04:00
dst_name , cli_errstr ( cli_share_dst ) ) ) ;
2004-08-21 00:13:05 +04:00
goto out ;
}
2004-08-25 00:52:56 +04:00
/* allocate memory */
2004-12-07 21:25:53 +03:00
if ( ! ( data = ( char * ) SMB_MALLOC ( read_size ) ) ) {
2009-08-10 20:24:57 +04:00
d_fprintf ( stderr , _ ( " malloc fail for size %d \n " ) ,
read_size ) ;
2004-08-25 00:52:56 +04:00
nt_status = NT_STATUS_NO_MEMORY ;
2004-08-10 18:27:17 +04:00
goto out ;
}
2004-08-25 00:52:56 +04:00
2004-08-10 18:27:17 +04:00
}
2004-08-25 00:52:56 +04:00
2008-05-10 01:22:12 +04:00
if ( c - > opt_verbose ) {
2004-08-10 18:27:17 +04:00
2009-08-10 20:24:57 +04:00
d_printf ( _ ( " copying [ \\ \\ %s \\ %s%s] => [ \\ \\ %s \\ %s%s] "
" %s ACLs and %s DOS Attributes %s \n " ) ,
2004-08-21 00:13:05 +04:00
cli_share_src - > desthost , cli_share_src - > share , src_name ,
2004-08-10 18:27:17 +04:00
cli_share_dst - > desthost , cli_share_dst - > share , dst_name ,
2009-08-10 20:24:57 +04:00
copy_acls ? _ ( " with " ) : _ ( " without " ) ,
copy_attrs ? _ ( " with " ) : _ ( " without " ) ,
copy_timestamps ? _ ( " (preserving timestamps) " ) : " " ) ;
2004-08-10 18:27:17 +04:00
}
2004-08-25 00:52:56 +04:00
2004-08-10 18:27:17 +04:00
while ( is_file ) {
2004-08-25 00:52:56 +04:00
/* copying file */
2004-08-10 20:42:58 +04:00
int n , ret ;
2008-05-08 13:23:38 +04:00
n = cli_read ( cli_share_src , fnum_src , data , nread ,
2004-08-10 18:27:17 +04:00
read_size ) ;
if ( n < = 0 )
break ;
2008-05-08 13:23:38 +04:00
ret = cli_write ( cli_share_dst , fnum_dst , 0 , data ,
2007-08-29 18:08:29 +04:00
nread , n ) ;
2004-08-10 18:27:17 +04:00
2004-08-25 00:52:56 +04:00
if ( n ! = ret ) {
2009-08-10 20:24:57 +04:00
d_fprintf ( stderr , _ ( " Error writing file: %s \n " ) ,
2004-08-10 18:27:17 +04:00
cli_errstr ( cli_share_dst ) ) ;
nt_status = cli_nt_error ( cli_share_dst ) ;
2004-08-25 00:52:56 +04:00
goto out ;
}
2004-08-10 18:27:17 +04:00
nread + = n ;
}
2004-08-25 00:52:56 +04:00
2009-04-22 17:46:42 +04:00
if ( ! is_file & & ! NT_STATUS_IS_OK ( cli_chkpath ( cli_share_dst , dst_name ) ) ) {
2004-08-10 18:27:17 +04:00
2004-08-25 00:52:56 +04:00
/* creating dir */
2008-05-08 13:23:38 +04:00
DEBUGADD ( 3 , ( " creating dir %s on the destination server \n " ,
2004-08-10 18:27:17 +04:00
dst_name ) ) ;
2009-04-21 16:52:34 +04:00
if ( ! NT_STATUS_IS_OK ( cli_mkdir ( cli_share_dst , dst_name ) ) ) {
2004-08-25 00:52:56 +04:00
DEBUG ( 0 , ( " cannot create directory %s: %s \n " ,
dst_name , cli_errstr ( cli_share_dst ) ) ) ;
nt_status = NT_STATUS_NO_SUCH_FILE ;
}
2004-08-10 18:27:17 +04:00
2009-04-22 17:46:42 +04:00
if ( ! NT_STATUS_IS_OK ( cli_chkpath ( cli_share_dst , dst_name ) ) ) {
2009-08-10 20:24:57 +04:00
d_fprintf ( stderr ,
_ ( " cannot check for directory %s: %s \n " ) ,
2004-08-10 18:27:17 +04:00
dst_name , cli_errstr ( cli_share_dst ) ) ;
goto out ;
}
2004-08-21 00:13:05 +04:00
}
2004-08-10 18:27:17 +04:00
2004-08-21 00:13:05 +04:00
/* closing files */
2009-05-01 03:57:42 +04:00
if ( ! NT_STATUS_IS_OK ( cli_close ( cli_share_src , fnum_src ) ) ) {
2009-08-10 20:24:57 +04:00
d_fprintf ( stderr ,
_ ( " could not close file on originating server: %s \n " ) ,
2004-08-21 00:13:05 +04:00
cli_errstr ( cli_share_src ) ) ;
nt_status = cli_nt_error ( cli_share_src ) ;
goto out ;
}
2009-05-01 03:57:42 +04:00
if ( is_file & & ! NT_STATUS_IS_OK ( cli_close ( cli_share_dst , fnum_dst ) ) ) {
2009-08-10 20:24:57 +04:00
d_fprintf ( stderr ,
_ ( " could not close file on destination server: %s \n " ) ,
2004-08-21 00:13:05 +04:00
cli_errstr ( cli_share_dst ) ) ;
nt_status = cli_nt_error ( cli_share_dst ) ;
goto out ;
}
2004-08-25 00:52:56 +04:00
/* possibly we have to copy some file-attributes / acls / sd */
2008-05-10 01:22:12 +04:00
nt_status = net_copy_fileattr ( c , mem_ctx , cli_share_src , cli_share_dst ,
2008-05-08 13:23:38 +04:00
src_name , dst_name , copy_acls ,
2004-08-25 00:52:56 +04:00
copy_attrs , copy_timestamps , is_file ) ;
if ( ! NT_STATUS_IS_OK ( nt_status ) )
goto out ;
2004-08-21 00:13:05 +04:00
2004-08-10 18:27:17 +04:00
nt_status = NT_STATUS_OK ;
out :
/* cleaning up */
if ( fnum_src )
cli_close ( cli_share_src , fnum_src ) ;
if ( fnum_dst )
cli_close ( cli_share_dst , fnum_dst ) ;
SAFE_FREE ( data ) ;
return nt_status ;
}
/**
2008-05-08 13:23:38 +04:00
* Copy a driverfile from on connected share to another connected share
* This silently assumes that a driver - file is picked up from
2004-08-10 18:27:17 +04:00
*
2008-05-08 13:23:38 +04:00
* \ \ src_server \ print $ \ { arch } \ { version } \ file
2004-08-10 18:27:17 +04:00
*
* and copied to
*
2008-05-08 13:23:38 +04:00
* \ \ dst_server \ print $ \ { arch } \ file
*
2004-08-10 18:27:17 +04:00
* to be added via setdriver - calls later .
2008-05-10 01:22:12 +04:00
* @ param c A net_context structure
2004-08-10 18:27:17 +04:00
* @ param mem_ctx A talloc - context
* @ param cli_share_src A cli_state connected to source print $ - share
* @ param cli_share_dst A cli_state connected to destination print $ - share
2008-05-08 13:23:38 +04:00
* @ param file The file - name to be copied
2004-08-10 18:27:17 +04:00
* @ param short_archi The name of the driver - architecture ( short form )
*
* @ return Normal NTSTATUS return .
2008-05-08 13:23:38 +04:00
* */
2005-09-30 21:13:37 +04:00
2008-05-10 01:22:12 +04:00
static NTSTATUS net_copy_driverfile ( struct net_context * c ,
TALLOC_CTX * mem_ctx ,
2004-08-10 18:27:17 +04:00
struct cli_state * cli_share_src ,
2008-05-08 13:23:38 +04:00
struct cli_state * cli_share_dst ,
2009-02-25 00:23:56 +03:00
const char * file , const char * short_archi ) {
2004-08-10 18:27:17 +04:00
const char * p ;
char * src_name ;
char * dst_name ;
2010-06-28 15:20:18 +04:00
char * version = NULL ;
char * filename = NULL ;
2007-12-08 04:32:32 +03:00
char * tok ;
2004-08-10 18:27:17 +04:00
2009-02-25 00:23:56 +03:00
if ( ! file ) {
return NT_STATUS_OK ;
}
2008-05-08 13:23:38 +04:00
/* scroll through the file until we have the part
2004-08-10 18:27:17 +04:00
beyond archi_table . short_archi */
p = file ;
2007-12-08 04:32:32 +03:00
while ( next_token_talloc ( mem_ctx , & p , & tok , " \\ " ) ) {
2004-08-10 18:27:17 +04:00
if ( strequal ( tok , short_archi ) ) {
2007-12-08 04:32:32 +03:00
next_token_talloc ( mem_ctx , & p , & version , " \\ " ) ;
next_token_talloc ( mem_ctx , & p , & filename , " \\ " ) ;
2004-08-10 18:27:17 +04:00
}
}
2010-06-28 15:20:18 +04:00
if ( version = = NULL | | filename = = NULL ) {
return NT_STATUS_UNSUCCESSFUL ;
}
2004-08-10 18:27:17 +04:00
/* build source file name */
2010-06-28 15:20:18 +04:00
src_name = talloc_asprintf ( mem_ctx , " \\ %s \\ %s \\ %s " ,
short_archi , version , filename ) ;
if ( src_name = = NULL ) {
2004-08-10 18:27:17 +04:00
return NT_STATUS_NO_MEMORY ;
2010-06-28 15:20:18 +04:00
}
2004-08-10 18:27:17 +04:00
/* create destination file name */
2010-06-28 15:20:18 +04:00
dst_name = talloc_asprintf ( mem_ctx , " \\ %s \\ %s " , short_archi , filename ) ;
if ( dst_name = = NULL ) {
return NT_STATUS_NO_MEMORY ;
}
2004-08-10 18:27:17 +04:00
/* finally copy the file */
2010-06-28 15:20:18 +04:00
return net_copy_file ( c , mem_ctx , cli_share_src , cli_share_dst ,
src_name , dst_name , false , false , false , true ) ;
2004-08-10 18:27:17 +04:00
}
/**
* Check for existing Architecture directory on a given server
*
* @ param cli_share A cli_state connected to a print $ - share
* @ param short_archi The Architecture for the print - driver
*
* @ return Normal NTSTATUS return .
* */
2005-09-30 21:13:37 +04:00
static NTSTATUS check_arch_dir ( struct cli_state * cli_share , const char * short_archi )
2004-08-10 18:27:17 +04:00
{
NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL ;
char * dir ;
if ( asprintf ( & dir , " \\ %s " , short_archi ) < 0 ) {
return NT_STATUS_NO_MEMORY ;
}
2008-05-08 13:23:38 +04:00
DEBUG ( 10 , ( " creating print-driver dir for architecture: %s \n " ,
2004-08-10 18:27:17 +04:00
short_archi ) ) ;
2009-04-21 16:52:34 +04:00
if ( ! NT_STATUS_IS_OK ( cli_mkdir ( cli_share , dir ) ) ) {
2004-08-10 18:27:17 +04:00
DEBUG ( 1 , ( " cannot create directory %s: %s \n " ,
dir , cli_errstr ( cli_share ) ) ) ;
nt_status = NT_STATUS_NO_SUCH_FILE ;
}
2009-04-22 17:46:42 +04:00
if ( ! NT_STATUS_IS_OK ( cli_chkpath ( cli_share , dir ) ) ) {
2009-08-10 20:24:57 +04:00
d_fprintf ( stderr , _ ( " cannot check %s: %s \n " ) ,
2004-08-10 18:27:17 +04:00
dir , cli_errstr ( cli_share ) ) ;
goto out ;
}
nt_status = NT_STATUS_OK ;
out :
SAFE_FREE ( dir ) ;
return nt_status ;
}
/**
2008-05-08 13:23:38 +04:00
* Copy a print - driver ( level 3 ) from one connected print $ - share to another
2004-08-10 18:27:17 +04:00
* connected print $ - share
*
2008-05-10 01:22:12 +04:00
* @ param c A net_context structure
2004-08-10 18:27:17 +04:00
* @ param mem_ctx A talloc - context
* @ param cli_share_src A cli_state connected to a print $ - share
* @ param cli_share_dst A cli_state connected to a print $ - share
* @ param short_archi The Architecture for the print - driver
* @ param i1 The DRIVER_INFO_3 - struct
*
* @ return Normal NTSTATUS return .
* */
2005-09-30 21:13:37 +04:00
2008-05-10 01:22:12 +04:00
static NTSTATUS copy_print_driver_3 ( struct net_context * c ,
TALLOC_CTX * mem_ctx ,
2008-05-08 13:23:38 +04:00
struct cli_state * cli_share_src ,
struct cli_state * cli_share_dst ,
2009-02-25 00:23:56 +03:00
const char * short_archi ,
struct spoolss_DriverInfo3 * r )
2004-08-10 18:27:17 +04:00
{
NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL ;
2009-02-25 00:23:56 +03:00
int i ;
2008-05-08 13:23:38 +04:00
2009-02-25 00:23:56 +03:00
if ( r = = NULL ) {
2004-08-10 18:27:17 +04:00
return nt_status ;
2009-02-25 00:23:56 +03:00
}
2004-08-10 18:27:17 +04:00
2008-05-10 01:22:12 +04:00
if ( c - > opt_verbose )
2009-08-10 20:24:57 +04:00
d_printf ( _ ( " copying driver: [%s], for architecture: [%s], "
" version: [%d] \n " ) ,
2009-02-25 00:23:56 +03:00
r - > driver_name , short_archi , r - > version ) ;
2008-05-08 13:23:38 +04:00
2008-05-10 01:22:12 +04:00
nt_status = net_copy_driverfile ( c , mem_ctx , cli_share_src , cli_share_dst ,
2009-02-25 00:23:56 +03:00
r - > driver_path , short_archi ) ;
2004-08-10 18:27:17 +04:00
if ( ! NT_STATUS_IS_OK ( nt_status ) )
return nt_status ;
2008-05-08 13:23:38 +04:00
2008-05-10 01:22:12 +04:00
nt_status = net_copy_driverfile ( c , mem_ctx , cli_share_src , cli_share_dst ,
2009-02-25 00:23:56 +03:00
r - > data_file , short_archi ) ;
2004-08-10 18:27:17 +04:00
if ( ! NT_STATUS_IS_OK ( nt_status ) )
return nt_status ;
2008-05-08 13:23:38 +04:00
2008-05-10 01:22:12 +04:00
nt_status = net_copy_driverfile ( c , mem_ctx , cli_share_src , cli_share_dst ,
2009-02-25 00:23:56 +03:00
r - > config_file , short_archi ) ;
2004-08-10 18:27:17 +04:00
if ( ! NT_STATUS_IS_OK ( nt_status ) )
return nt_status ;
2008-05-08 13:23:38 +04:00
2008-05-10 01:22:12 +04:00
nt_status = net_copy_driverfile ( c , mem_ctx , cli_share_src , cli_share_dst ,
2009-02-25 00:23:56 +03:00
r - > help_file , short_archi ) ;
2004-08-10 18:27:17 +04:00
if ( ! NT_STATUS_IS_OK ( nt_status ) )
return nt_status ;
2009-02-25 00:23:56 +03:00
for ( i = 0 ; r - > dependent_files [ i ] ! = NULL ; i + + ) {
2008-05-08 13:23:38 +04:00
2009-02-25 00:23:56 +03:00
nt_status = net_copy_driverfile ( c , mem_ctx ,
cli_share_src , cli_share_dst ,
r - > dependent_files [ i ] , short_archi ) ;
if ( ! NT_STATUS_IS_OK ( nt_status ) ) {
return nt_status ;
2004-08-10 18:27:17 +04:00
}
}
return NT_STATUS_OK ;
}
/**
* net_spoolss - functions
* = = = = = = = = = = = = = = = = = = = = =
*
* the net_spoolss - functions aim to simplify spoolss - client - functions
* required during the migration - process wrt buffer - sizes , returned
2008-05-08 13:23:38 +04:00
* error - codes , etc .
2004-08-10 18:27:17 +04:00
*
* this greatly reduces the complexitiy of the migrate - functions .
*
* */
2007-10-19 04:40:25 +04:00
static bool net_spoolss_enum_printers ( struct rpc_pipe_client * pipe_hnd ,
2008-05-08 13:23:38 +04:00
TALLOC_CTX * mem_ctx ,
2005-09-30 21:13:37 +04:00
char * name ,
2009-03-19 14:53:01 +03:00
uint32_t flags ,
uint32_t level ,
uint32_t * num_printers ,
2009-03-10 00:42:30 +03:00
union spoolss_PrinterInfo * * info )
2004-08-10 18:27:17 +04:00
{
WERROR result ;
/* enum printers */
2009-03-10 00:42:30 +03:00
result = rpccli_spoolss_enumprinters ( pipe_hnd , mem_ctx ,
flags ,
name ,
level ,
0 ,
num_printers ,
info ) ;
2004-08-10 18:27:17 +04:00
if ( ! W_ERROR_IS_OK ( result ) ) {
2009-08-10 20:24:57 +04:00
printf ( _ ( " cannot enum printers: %s \n " ) , win_errstr ( result ) ) ;
2008-05-12 13:53:23 +04:00
return false ;
2004-08-10 18:27:17 +04:00
}
2008-05-12 13:53:23 +04:00
return true ;
2004-08-10 18:27:17 +04:00
}
2007-10-19 04:40:25 +04:00
static bool net_spoolss_open_printer_ex ( struct rpc_pipe_client * pipe_hnd ,
2005-09-30 21:13:37 +04:00
TALLOC_CTX * mem_ctx ,
const char * printername ,
2009-03-19 14:53:01 +03:00
uint32_t access_required ,
2005-09-30 21:13:37 +04:00
const char * username ,
2009-03-19 00:49:41 +03:00
struct policy_handle * hnd )
2004-08-10 18:27:17 +04:00
{
WERROR result ;
2009-02-09 20:10:18 +03:00
fstring printername2 ;
2004-08-10 18:27:17 +04:00
2009-02-09 20:10:18 +03:00
fstrcpy ( printername2 , pipe_hnd - > srv_name_slash ) ;
2004-10-07 15:01:13 +04:00
fstrcat ( printername2 , " \\ " ) ;
fstrcat ( printername2 , printername ) ;
2004-08-10 18:27:17 +04:00
2008-05-08 13:23:38 +04:00
DEBUG ( 10 , ( " connecting to: %s as %s for %s and access: %x \n " ,
2009-02-09 20:10:18 +03:00
pipe_hnd - > srv_name_slash , username , printername2 , access_required ) ) ;
2004-08-10 18:27:17 +04:00
/* open printer */
2009-02-09 20:49:34 +03:00
result = rpccli_spoolss_openprinter_ex ( pipe_hnd , mem_ctx ,
printername2 ,
access_required ,
hnd ) ;
2004-08-10 18:27:17 +04:00
/* be more verbose */
if ( W_ERROR_V ( result ) = = W_ERROR_V ( WERR_ACCESS_DENIED ) ) {
2009-08-10 20:24:57 +04:00
d_fprintf ( stderr ,
_ ( " no access to printer [%s] on [%s] for user [%s] "
" granted \n " ) ,
2009-02-09 22:18:57 +03:00
printername2 , pipe_hnd - > srv_name_slash , username ) ;
2008-05-12 13:53:23 +04:00
return false ;
2004-08-10 18:27:17 +04:00
}
if ( ! W_ERROR_IS_OK ( result ) ) {
2009-08-10 20:24:57 +04:00
d_fprintf ( stderr , _ ( " cannot open printer %s on server %s: %s \n " ) ,
2009-02-09 22:18:57 +03:00
printername2 , pipe_hnd - > srv_name_slash , win_errstr ( result ) ) ;
2008-05-12 13:53:23 +04:00
return false ;
2004-08-10 18:27:17 +04:00
}
2008-05-08 13:23:38 +04:00
DEBUG ( 2 , ( " got printer handle for printer: %s, server: %s \n " ,
2009-02-09 22:18:57 +03:00
printername2 , pipe_hnd - > srv_name_slash ) ) ;
2004-08-10 18:27:17 +04:00
2008-05-12 13:53:23 +04:00
return true ;
2004-08-10 18:27:17 +04:00
}
2007-10-19 04:40:25 +04:00
static bool net_spoolss_getprinter ( struct rpc_pipe_client * pipe_hnd ,
2005-09-30 21:13:37 +04:00
TALLOC_CTX * mem_ctx ,
2009-03-19 00:49:41 +03:00
struct policy_handle * hnd ,
2009-03-19 14:53:01 +03:00
uint32_t level ,
2009-02-25 12:58:53 +03:00
union spoolss_PrinterInfo * info )
2004-08-10 18:27:17 +04:00
{
WERROR result ;
/* getprinter call */
2009-02-25 12:58:53 +03:00
result = rpccli_spoolss_getprinter ( pipe_hnd , mem_ctx ,
hnd ,
level ,
0 , /* offered */
info ) ;
2004-08-10 18:27:17 +04:00
if ( ! W_ERROR_IS_OK ( result ) ) {
2009-08-10 20:24:57 +04:00
printf ( _ ( " cannot get printer-info: %s \n " ) , win_errstr ( result ) ) ;
2008-05-12 13:53:23 +04:00
return false ;
2004-08-10 18:27:17 +04:00
}
2008-05-12 13:53:23 +04:00
return true ;
2004-08-10 18:27:17 +04:00
}
2007-10-19 04:40:25 +04:00
static bool net_spoolss_setprinter ( struct rpc_pipe_client * pipe_hnd ,
2005-09-30 21:13:37 +04:00
TALLOC_CTX * mem_ctx ,
2009-03-19 00:49:41 +03:00
struct policy_handle * hnd ,
2009-03-19 14:53:01 +03:00
uint32_t level ,
2009-02-25 12:58:53 +03:00
union spoolss_PrinterInfo * info )
2004-08-10 18:27:17 +04:00
{
WERROR result ;
2009-02-25 12:58:53 +03:00
NTSTATUS status ;
struct spoolss_SetPrinterInfoCtr info_ctr ;
2010-06-03 18:30:55 +04:00
struct spoolss_SetPrinterInfo2 info2 ;
2009-02-25 12:58:53 +03:00
struct spoolss_DevmodeContainer devmode_ctr ;
struct sec_desc_buf secdesc_ctr ;
ZERO_STRUCT ( devmode_ctr ) ;
ZERO_STRUCT ( secdesc_ctr ) ;
2004-08-10 18:27:17 +04:00
/* setprinter call */
2009-02-25 12:58:53 +03:00
info_ctr . level = level ;
switch ( level ) {
case 0 :
2009-05-04 00:44:36 +04:00
info_ctr . info . info0 = ( struct spoolss_SetPrinterInfo0 * )
( void * ) & info - > info0 ;
2009-02-25 12:58:53 +03:00
break ;
case 1 :
2009-05-04 00:44:36 +04:00
info_ctr . info . info1 = ( struct spoolss_SetPrinterInfo1 * )
( void * ) & info - > info1 ;
2009-02-25 12:58:53 +03:00
break ;
case 2 :
2010-06-03 18:30:55 +04:00
spoolss_printerinfo2_to_setprinterinfo2 ( & info - > info2 , & info2 ) ;
info_ctr . info . info2 = & info2 ;
2009-02-25 12:58:53 +03:00
break ;
case 3 :
2009-05-04 00:44:36 +04:00
info_ctr . info . info3 = ( struct spoolss_SetPrinterInfo3 * )
( void * ) & info - > info3 ;
2009-02-25 12:58:53 +03:00
break ;
case 4 :
2009-05-04 00:44:36 +04:00
info_ctr . info . info4 = ( struct spoolss_SetPrinterInfo4 * )
( void * ) & info - > info4 ;
2009-02-25 12:58:53 +03:00
break ;
case 5 :
2009-05-04 00:44:36 +04:00
info_ctr . info . info5 = ( struct spoolss_SetPrinterInfo5 * )
( void * ) & info - > info5 ;
2009-02-25 12:58:53 +03:00
break ;
case 6 :
2009-05-04 00:44:36 +04:00
info_ctr . info . info6 = ( struct spoolss_SetPrinterInfo6 * )
( void * ) & info - > info6 ;
2009-02-25 12:58:53 +03:00
break ;
case 7 :
2009-05-04 00:44:36 +04:00
info_ctr . info . info7 = ( struct spoolss_SetPrinterInfo7 * )
( void * ) & info - > info7 ;
2009-02-25 12:58:53 +03:00
break ;
#if 0 /* FIXME GD */
case 8 :
2009-05-04 00:44:36 +04:00
info_ctr . info . info8 = ( struct spoolss_SetPrinterInfo8 * )
( void * ) & info - > info8 ;
2009-02-25 12:58:53 +03:00
break ;
case 9 :
2009-05-04 00:44:36 +04:00
info_ctr . info . info9 = ( struct spoolss_SetPrinterInfo9 * )
( void * ) & info - > info9 ;
2009-02-25 12:58:53 +03:00
break ;
# endif
default :
break ; /* FIXME */
}
status = rpccli_spoolss_SetPrinter ( pipe_hnd , mem_ctx ,
hnd ,
& info_ctr ,
& devmode_ctr ,
& secdesc_ctr ,
0 , /* command */
& result ) ;
2004-08-10 18:27:17 +04:00
if ( ! W_ERROR_IS_OK ( result ) ) {
2009-08-10 20:24:57 +04:00
printf ( _ ( " cannot set printer-info: %s \n " ) , win_errstr ( result ) ) ;
2008-05-12 13:53:23 +04:00
return false ;
2004-08-10 18:27:17 +04:00
}
2008-05-12 13:53:23 +04:00
return true ;
2004-08-10 18:27:17 +04:00
}
2007-10-19 04:40:25 +04:00
static bool net_spoolss_setprinterdata ( struct rpc_pipe_client * pipe_hnd ,
2009-03-17 02:34:59 +03:00
TALLOC_CTX * mem_ctx ,
struct policy_handle * hnd ,
const char * value_name ,
enum winreg_Type type ,
2010-03-04 17:34:22 +03:00
uint8_t * data ,
uint32_t offered )
2004-08-10 18:27:17 +04:00
{
WERROR result ;
2009-03-17 02:34:59 +03:00
NTSTATUS status ;
2009-03-17 14:01:29 +03:00
2004-08-10 18:27:17 +04:00
/* setprinterdata call */
2009-03-17 02:34:59 +03:00
status = rpccli_spoolss_SetPrinterData ( pipe_hnd , mem_ctx ,
hnd ,
value_name ,
type ,
data ,
2010-03-04 17:34:22 +03:00
offered ,
2009-03-17 02:34:59 +03:00
& result ) ;
2004-08-10 18:27:17 +04:00
if ( ! W_ERROR_IS_OK ( result ) ) {
2009-08-10 20:24:57 +04:00
printf ( _ ( " unable to set printerdata: %s \n " ) ,
win_errstr ( result ) ) ;
2008-05-12 13:53:23 +04:00
return false ;
2004-08-10 18:27:17 +04:00
}
2008-05-12 13:53:23 +04:00
return true ;
2004-08-10 18:27:17 +04:00
}
2007-10-19 04:40:25 +04:00
static bool net_spoolss_enumprinterkey ( struct rpc_pipe_client * pipe_hnd ,
2005-09-30 21:13:37 +04:00
TALLOC_CTX * mem_ctx ,
2009-03-19 00:49:41 +03:00
struct policy_handle * hnd ,
2005-09-30 21:13:37 +04:00
const char * keyname ,
2009-03-17 01:38:05 +03:00
const char * * * keylist )
2004-08-10 18:27:17 +04:00
{
WERROR result ;
/* enumprinterkey call */
2009-03-17 01:38:05 +03:00
result = rpccli_spoolss_enumprinterkey ( pipe_hnd , mem_ctx , hnd , keyname , keylist , 0 ) ;
2008-05-08 13:23:38 +04:00
2004-08-10 18:27:17 +04:00
if ( ! W_ERROR_IS_OK ( result ) ) {
2009-08-10 20:24:57 +04:00
printf ( _ ( " enumprinterkey failed: %s \n " ) , win_errstr ( result ) ) ;
2008-05-12 13:53:23 +04:00
return false ;
2004-08-10 18:27:17 +04:00
}
2008-05-08 13:23:38 +04:00
2008-05-12 13:53:23 +04:00
return true ;
2004-08-10 18:27:17 +04:00
}
2007-10-19 04:40:25 +04:00
static bool net_spoolss_enumprinterdataex ( struct rpc_pipe_client * pipe_hnd ,
2005-09-30 21:13:37 +04:00
TALLOC_CTX * mem_ctx ,
2009-03-19 14:53:01 +03:00
uint32_t offered ,
2009-03-19 00:49:41 +03:00
struct policy_handle * hnd ,
2008-05-08 13:23:38 +04:00
const char * keyname ,
2009-03-18 03:06:22 +03:00
uint32_t * count ,
struct spoolss_PrinterEnumValues * * info )
2004-08-10 18:27:17 +04:00
{
WERROR result ;
/* enumprinterdataex call */
2009-03-18 03:06:22 +03:00
result = rpccli_spoolss_enumprinterdataex ( pipe_hnd , mem_ctx ,
hnd ,
keyname ,
0 , /* offered */
count ,
info ) ;
2008-05-08 13:23:38 +04:00
2004-08-10 18:27:17 +04:00
if ( ! W_ERROR_IS_OK ( result ) ) {
2009-08-10 20:24:57 +04:00
printf ( _ ( " enumprinterdataex failed: %s \n " ) , win_errstr ( result ) ) ;
2008-05-12 13:53:23 +04:00
return false ;
2004-08-10 18:27:17 +04:00
}
2008-05-08 13:23:38 +04:00
2008-05-12 13:53:23 +04:00
return true ;
2004-08-10 18:27:17 +04:00
}
2007-10-19 04:40:25 +04:00
static bool net_spoolss_setprinterdataex ( struct rpc_pipe_client * pipe_hnd ,
2005-09-30 21:13:37 +04:00
TALLOC_CTX * mem_ctx ,
2009-03-19 00:49:41 +03:00
struct policy_handle * hnd ,
2009-03-17 02:29:13 +03:00
const char * keyname ,
2009-03-24 00:27:59 +03:00
struct regval_blob * value )
2004-08-10 18:27:17 +04:00
{
WERROR result ;
2009-02-13 00:28:10 +03:00
NTSTATUS status ;
2004-08-10 18:27:17 +04:00
/* setprinterdataex call */
2009-02-13 00:28:10 +03:00
status = rpccli_spoolss_SetPrinterDataEx ( pipe_hnd , mem_ctx ,
hnd ,
keyname ,
2010-05-24 16:48:31 +04:00
regval_name ( value ) ,
regval_type ( value ) ,
regval_data_p ( value ) ,
regval_size ( value ) ,
2009-02-13 00:28:10 +03:00
& result ) ;
2008-05-08 13:23:38 +04:00
2004-08-10 18:27:17 +04:00
if ( ! W_ERROR_IS_OK ( result ) ) {
2009-08-10 20:24:57 +04:00
printf ( _ ( " could not set printerdataex: %s \n " ) ,
win_errstr ( result ) ) ;
2008-05-12 13:53:23 +04:00
return false ;
2004-08-10 18:27:17 +04:00
}
2008-05-08 13:23:38 +04:00
2008-05-12 13:53:23 +04:00
return true ;
2004-08-10 18:27:17 +04:00
}
2007-10-19 04:40:25 +04:00
static bool net_spoolss_enumforms ( struct rpc_pipe_client * pipe_hnd ,
2005-09-30 21:13:37 +04:00
TALLOC_CTX * mem_ctx ,
2009-03-19 00:49:41 +03:00
struct policy_handle * hnd ,
2005-09-30 21:13:37 +04:00
int level ,
2009-03-06 13:02:27 +03:00
uint32_t * num_forms ,
union spoolss_FormInfo * * forms )
2004-08-10 18:27:17 +04:00
{
WERROR result ;
/* enumforms call */
2009-03-06 13:02:27 +03:00
result = rpccli_spoolss_enumforms ( pipe_hnd , mem_ctx ,
hnd ,
level ,
0 ,
num_forms ,
forms ) ;
2004-08-10 18:27:17 +04:00
if ( ! W_ERROR_IS_OK ( result ) ) {
2009-08-10 20:24:57 +04:00
printf ( _ ( " could not enum forms: %s \n " ) , win_errstr ( result ) ) ;
2008-05-12 13:53:23 +04:00
return false ;
2004-08-10 18:27:17 +04:00
}
2008-05-08 13:23:38 +04:00
2008-05-12 13:53:23 +04:00
return true ;
2004-08-10 18:27:17 +04:00
}
2007-10-19 04:40:25 +04:00
static bool net_spoolss_enumprinterdrivers ( struct rpc_pipe_client * pipe_hnd ,
2005-09-30 21:13:37 +04:00
TALLOC_CTX * mem_ctx ,
2009-03-19 14:53:01 +03:00
uint32_t level , const char * env ,
uint32_t * count ,
2009-03-09 17:58:11 +03:00
union spoolss_DriverInfo * * info )
2004-08-10 18:27:17 +04:00
{
WERROR result ;
/* enumprinterdrivers call */
2009-03-09 17:58:11 +03:00
result = rpccli_spoolss_enumprinterdrivers ( pipe_hnd , mem_ctx ,
pipe_hnd - > srv_name_slash ,
env ,
level ,
0 ,
count ,
info ) ;
2004-08-10 18:27:17 +04:00
if ( ! W_ERROR_IS_OK ( result ) ) {
2009-08-10 20:24:57 +04:00
printf ( _ ( " cannot enum drivers: %s \n " ) , win_errstr ( result ) ) ;
2008-05-12 13:53:23 +04:00
return false ;
2004-08-10 18:27:17 +04:00
}
2008-05-12 13:53:23 +04:00
return true ;
2004-08-10 18:27:17 +04:00
}
2007-10-19 04:40:25 +04:00
static bool net_spoolss_getprinterdriver ( struct rpc_pipe_client * pipe_hnd ,
2008-05-08 13:23:38 +04:00
TALLOC_CTX * mem_ctx ,
2009-03-19 14:53:01 +03:00
struct policy_handle * hnd , uint32_t level ,
2008-05-08 13:23:38 +04:00
const char * env , int version ,
2009-02-25 00:23:56 +03:00
union spoolss_DriverInfo * info )
2004-08-10 18:27:17 +04:00
{
WERROR result ;
2009-02-25 00:23:56 +03:00
uint32_t server_major_version ;
uint32_t server_minor_version ;
2008-05-08 13:23:38 +04:00
2004-08-10 18:27:17 +04:00
/* getprinterdriver call */
2009-02-25 00:23:56 +03:00
result = rpccli_spoolss_getprinterdriver2 ( pipe_hnd , mem_ctx ,
hnd ,
env ,
level ,
0 ,
version ,
2 ,
info ,
& server_major_version ,
& server_minor_version ) ;
2004-08-10 18:27:17 +04:00
if ( ! W_ERROR_IS_OK ( result ) ) {
2008-05-08 13:23:38 +04:00
DEBUG ( 1 , ( " cannot get driver (for architecture: %s): %s \n " ,
2008-11-01 19:19:26 +03:00
env , win_errstr ( result ) ) ) ;
2004-10-07 15:01:13 +04:00
if ( W_ERROR_V ( result ) ! = W_ERROR_V ( WERR_UNKNOWN_PRINTER_DRIVER ) & &
W_ERROR_V ( result ) ! = W_ERROR_V ( WERR_INVALID_ENVIRONMENT ) ) {
2009-08-10 20:24:57 +04:00
printf ( _ ( " cannot get driver: %s \n " ) ,
win_errstr ( result ) ) ;
2004-08-10 18:27:17 +04:00
}
2008-05-12 13:53:23 +04:00
return false ;
2004-08-10 18:27:17 +04:00
}
2008-05-12 13:53:23 +04:00
return true ;
2004-08-10 18:27:17 +04:00
}
2007-10-19 04:40:25 +04:00
static bool net_spoolss_addprinterdriver ( struct rpc_pipe_client * pipe_hnd ,
2009-03-19 14:53:01 +03:00
TALLOC_CTX * mem_ctx , uint32_t level ,
2009-02-25 00:23:56 +03:00
union spoolss_DriverInfo * info )
2004-08-10 18:27:17 +04:00
{
WERROR result ;
2009-02-25 00:23:56 +03:00
NTSTATUS status ;
struct spoolss_AddDriverInfoCtr info_ctr ;
2004-08-10 18:27:17 +04:00
2009-02-25 00:23:56 +03:00
info_ctr . level = level ;
switch ( level ) {
case 2 :
2009-05-04 00:44:36 +04:00
info_ctr . info . info2 = ( struct spoolss_AddDriverInfo2 * )
( void * ) & info - > info2 ;
2009-02-25 00:23:56 +03:00
break ;
case 3 :
2009-05-04 00:44:36 +04:00
info_ctr . info . info3 = ( struct spoolss_AddDriverInfo3 * )
( void * ) & info - > info3 ;
2009-02-25 00:23:56 +03:00
break ;
default :
2009-08-10 20:24:57 +04:00
printf ( _ ( " unsupported info level: %d \n " ) , level ) ;
2009-02-25 00:23:56 +03:00
return false ;
}
2004-08-10 18:27:17 +04:00
2009-02-25 00:23:56 +03:00
/* addprinterdriver call */
status = rpccli_spoolss_AddPrinterDriver ( pipe_hnd , mem_ctx ,
pipe_hnd - > srv_name_slash ,
& info_ctr ,
& result ) ;
2004-08-10 18:27:17 +04:00
/* be more verbose */
if ( W_ERROR_V ( result ) = = W_ERROR_V ( WERR_ACCESS_DENIED ) ) {
2009-08-10 20:24:57 +04:00
printf ( _ ( " You are not allowed to add drivers \n " ) ) ;
2008-05-12 13:53:23 +04:00
return false ;
2004-08-10 18:27:17 +04:00
}
if ( ! W_ERROR_IS_OK ( result ) ) {
2009-08-10 20:24:57 +04:00
printf ( _ ( " cannot add driver: %s \n " ) , win_errstr ( result ) ) ;
2008-05-12 13:53:23 +04:00
return false ;
2004-08-10 18:27:17 +04:00
}
2008-05-12 13:53:23 +04:00
return true ;
2004-08-10 18:27:17 +04:00
}
/**
2009-03-19 14:53:01 +03:00
* abstraction function to get uint32_t num_printers and PRINTER_INFO_CTR ctr
2008-05-08 13:23:38 +04:00
* for a single printer or for all printers depending on argc / argv
2004-08-10 18:27:17 +04:00
* */
2005-09-30 21:13:37 +04:00
2007-10-19 04:40:25 +04:00
static bool get_printer_info ( struct rpc_pipe_client * pipe_hnd ,
2008-05-08 13:23:38 +04:00
TALLOC_CTX * mem_ctx ,
2005-09-30 21:13:37 +04:00
int level ,
int argc ,
2008-05-08 13:23:38 +04:00
const char * * argv ,
2009-03-19 14:53:01 +03:00
uint32_t * num_printers ,
2009-03-10 00:42:30 +03:00
union spoolss_PrinterInfo * * info_p )
2004-08-10 18:27:17 +04:00
{
2009-03-19 00:49:41 +03:00
struct policy_handle hnd ;
2004-08-10 18:27:17 +04:00
/* no arguments given, enumerate all printers */
if ( argc = = 0 ) {
2008-05-08 13:23:38 +04:00
if ( ! net_spoolss_enum_printers ( pipe_hnd , mem_ctx , NULL ,
PRINTER_ENUM_LOCAL | PRINTER_ENUM_SHARED ,
2009-03-10 00:42:30 +03:00
level , num_printers , info_p ) )
2008-05-12 13:53:23 +04:00
return false ;
2004-08-10 18:27:17 +04:00
goto out ;
}
/* argument given, get a single printer by name */
2005-09-30 21:13:37 +04:00
if ( ! net_spoolss_open_printer_ex ( pipe_hnd , mem_ctx , argv [ 0 ] ,
2008-04-22 00:27:29 +04:00
MAXIMUM_ALLOWED_ACCESS ,
pipe_hnd - > auth - > user_name ,
& hnd ) )
2008-05-12 13:53:23 +04:00
return false ;
2004-08-10 18:27:17 +04:00
2009-03-10 00:42:30 +03:00
if ( ! net_spoolss_getprinter ( pipe_hnd , mem_ctx , & hnd , level , * info_p ) ) {
2008-11-15 01:58:26 +03:00
rpccli_spoolss_ClosePrinter ( pipe_hnd , mem_ctx , & hnd , NULL ) ;
2008-05-12 13:53:23 +04:00
return false ;
2004-08-10 18:27:17 +04:00
}
2008-11-15 01:58:26 +03:00
rpccli_spoolss_ClosePrinter ( pipe_hnd , mem_ctx , & hnd , NULL ) ;
2004-08-10 18:27:17 +04:00
* num_printers = 1 ;
out :
DEBUG ( 3 , ( " got %d printers \n " , * num_printers ) ) ;
2008-05-12 13:53:23 +04:00
return true ;
2004-08-10 18:27:17 +04:00
}
2008-05-08 13:23:38 +04:00
/**
2004-08-10 18:27:17 +04:00
* List print - queues ( including local printers that are not shared )
*
* All parameters are provided by the run_rpc_command function , except for
2008-05-08 13:23:38 +04:00
* argc , argv which are passed through .
2004-08-10 18:27:17 +04:00
*
2008-05-10 01:22:12 +04:00
* @ param c A net_context structure
2004-08-10 18:27:17 +04:00
* @ param domain_sid The domain sid aquired from the remote server
* @ param cli A cli_state connected to the server .
* @ param mem_ctx Talloc context , destoyed on compleation of the function .
* @ param argc Standard main ( ) style argc
* @ param argv Standard main ( ) style argv . Initial components are already
* stripped
*
* @ return Normal NTSTATUS return .
* */
2005-09-30 21:13:37 +04:00
2008-05-10 01:22:12 +04:00
NTSTATUS rpc_printer_list_internals ( struct net_context * c ,
2010-05-21 05:25:01 +04:00
const struct dom_sid * domain_sid ,
2008-05-08 13:23:38 +04:00
const char * domain_name ,
2005-09-30 21:13:37 +04:00
struct cli_state * cli ,
struct rpc_pipe_client * pipe_hnd ,
2008-05-08 13:23:38 +04:00
TALLOC_CTX * mem_ctx ,
2005-09-30 21:13:37 +04:00
int argc ,
const char * * argv )
2004-08-10 18:27:17 +04:00
{
NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL ;
2009-03-19 14:53:01 +03:00
uint32_t i , num_printers ;
uint32_t level = 2 ;
2009-03-10 00:42:30 +03:00
const char * printername , * sharename ;
union spoolss_PrinterInfo * info ;
2004-08-10 18:27:17 +04:00
printf ( " listing printers \n " ) ;
2009-03-10 00:42:30 +03:00
if ( ! get_printer_info ( pipe_hnd , mem_ctx , level , argc , argv , & num_printers , & info ) )
2004-08-10 18:27:17 +04:00
return nt_status ;
for ( i = 0 ; i < num_printers ; i + + ) {
2009-03-10 00:42:30 +03:00
2004-08-10 18:27:17 +04:00
/* do some initialization */
2009-03-10 00:42:30 +03:00
printername = info [ i ] . info2 . printername ;
sharename = info [ i ] . info2 . sharename ;
2007-12-05 02:45:20 +03:00
if ( printername & & sharename ) {
2009-08-10 20:24:57 +04:00
d_printf ( _ ( " printer %d: %s, shared as: %s \n " ) ,
2007-12-05 02:45:20 +03:00
i + 1 , printername , sharename ) ;
}
2004-08-10 18:27:17 +04:00
}
return NT_STATUS_OK ;
}
2008-05-08 13:23:38 +04:00
/**
* List printer - drivers from a server
2004-08-10 18:27:17 +04:00
*
* All parameters are provided by the run_rpc_command function , except for
2008-05-08 13:23:38 +04:00
* argc , argv which are passed through .
2004-08-10 18:27:17 +04:00
*
2008-05-10 01:22:12 +04:00
* @ param c A net_context structure
2004-08-10 18:27:17 +04:00
* @ param domain_sid The domain sid aquired from the remote server
* @ param cli A cli_state connected to the server .
* @ param mem_ctx Talloc context , destoyed on compleation of the function .
* @ param argc Standard main ( ) style argc
* @ param argv Standard main ( ) style argv . Initial components are already
* stripped
*
* @ return Normal NTSTATUS return .
* */
2005-09-30 21:13:37 +04:00
2008-05-10 01:22:12 +04:00
NTSTATUS rpc_printer_driver_list_internals ( struct net_context * c ,
2010-05-21 05:25:01 +04:00
const struct dom_sid * domain_sid ,
2008-05-08 13:23:38 +04:00
const char * domain_name ,
2005-09-30 21:13:37 +04:00
struct cli_state * cli ,
struct rpc_pipe_client * pipe_hnd ,
2008-05-08 13:23:38 +04:00
TALLOC_CTX * mem_ctx ,
2005-09-30 21:13:37 +04:00
int argc ,
const char * * argv )
2004-08-10 18:27:17 +04:00
{
NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL ;
2009-03-19 14:53:01 +03:00
uint32_t i ;
uint32_t level = 3 ;
2009-03-09 17:58:11 +03:00
union spoolss_DriverInfo * info ;
2004-08-10 18:27:17 +04:00
int d ;
2008-05-08 13:23:38 +04:00
2009-08-10 20:24:57 +04:00
printf ( _ ( " listing printer-drivers \n " ) ) ;
2004-08-10 18:27:17 +04:00
for ( i = 0 ; archi_table [ i ] . long_archi ! = NULL ; i + + ) {
2009-03-19 14:53:01 +03:00
uint32_t num_drivers ;
2004-08-10 18:27:17 +04:00
/* enum remote drivers */
2005-09-30 21:13:37 +04:00
if ( ! net_spoolss_enumprinterdrivers ( pipe_hnd , mem_ctx , level ,
2008-05-08 13:23:38 +04:00
archi_table [ i ] . long_archi ,
2009-03-09 17:58:11 +03:00
& num_drivers , & info ) ) {
2004-08-10 18:27:17 +04:00
nt_status = NT_STATUS_UNSUCCESSFUL ;
goto done ;
}
if ( num_drivers = = 0 ) {
2009-08-10 20:24:57 +04:00
d_printf ( _ ( " no drivers found on server for "
" architecture: [%s]. \n " ) ,
2004-08-10 18:27:17 +04:00
archi_table [ i ] . long_archi ) ;
continue ;
2008-05-08 13:23:38 +04:00
}
2009-08-10 20:24:57 +04:00
d_printf ( _ ( " got %d printer-drivers for architecture: [%s] \n " ) ,
2004-08-10 18:27:17 +04:00
num_drivers , archi_table [ i ] . long_archi ) ;
/* do something for all drivers for architecture */
for ( d = 0 ; d < num_drivers ; d + + ) {
2009-03-09 17:58:11 +03:00
display_print_driver3 ( & info [ d ] . info3 ) ;
2004-08-10 18:27:17 +04:00
}
}
2008-05-08 13:23:38 +04:00
2004-08-10 18:27:17 +04:00
nt_status = NT_STATUS_OK ;
done :
return nt_status ;
}
2008-05-08 13:23:38 +04:00
/**
2004-10-13 05:40:35 +04:00
* Publish print - queues with args - wrapper
*
* @ param cli A cli_state connected to the server .
* @ param mem_ctx Talloc context , destoyed on compleation of the function .
* @ param argc Standard main ( ) style argc
* @ param argv Standard main ( ) style argv . Initial components are already
* stripped
* @ param action
*
* @ return Normal NTSTATUS return .
* */
2005-09-30 21:13:37 +04:00
static NTSTATUS rpc_printer_publish_internals_args ( struct rpc_pipe_client * pipe_hnd ,
2008-05-08 13:23:38 +04:00
TALLOC_CTX * mem_ctx ,
2005-09-30 21:13:37 +04:00
int argc ,
const char * * argv ,
2009-03-19 14:53:01 +03:00
uint32_t action )
2004-10-13 05:40:35 +04:00
{
NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL ;
2009-03-19 14:53:01 +03:00
uint32_t i , num_printers ;
uint32_t level = 7 ;
2009-03-10 00:42:30 +03:00
const char * printername , * sharename ;
union spoolss_PrinterInfo * info_enum ;
2009-02-25 12:58:53 +03:00
union spoolss_PrinterInfo info ;
struct spoolss_SetPrinterInfoCtr info_ctr ;
struct spoolss_DevmodeContainer devmode_ctr ;
struct sec_desc_buf secdesc_ctr ;
2009-03-19 00:49:41 +03:00
struct policy_handle hnd ;
2004-10-13 05:40:35 +04:00
WERROR result ;
2004-11-19 22:45:03 +03:00
const char * action_str ;
2004-10-13 05:40:35 +04:00
2009-03-10 00:42:30 +03:00
if ( ! get_printer_info ( pipe_hnd , mem_ctx , 2 , argc , argv , & num_printers , & info_enum ) )
2004-10-13 05:40:35 +04:00
return nt_status ;
for ( i = 0 ; i < num_printers ; i + + ) {
2009-03-10 00:42:30 +03:00
2004-10-13 05:40:35 +04:00
/* do some initialization */
2009-03-10 00:42:30 +03:00
printername = info_enum [ i ] . info2 . printername ;
sharename = info_enum [ i ] . info2 . sharename ;
2007-12-05 02:45:20 +03:00
if ( ! printername | | ! sharename ) {
goto done ;
}
2004-10-13 05:40:35 +04:00
/* open printer handle */
2005-09-30 21:13:37 +04:00
if ( ! net_spoolss_open_printer_ex ( pipe_hnd , mem_ctx , sharename ,
2008-04-22 00:27:29 +04:00
PRINTER_ALL_ACCESS , pipe_hnd - > auth - > user_name , & hnd ) )
2004-10-13 05:40:35 +04:00
goto done ;
/* check for existing dst printer */
2009-02-25 12:58:53 +03:00
if ( ! net_spoolss_getprinter ( pipe_hnd , mem_ctx , & hnd , level , & info ) )
2004-10-13 05:40:35 +04:00
goto done ;
/* check action and set string */
switch ( action ) {
2009-02-27 01:40:58 +03:00
case DSPRINT_PUBLISH :
2009-08-10 20:24:57 +04:00
action_str = N_ ( " published " ) ;
2004-10-13 05:40:35 +04:00
break ;
2009-02-27 01:40:58 +03:00
case DSPRINT_UPDATE :
2009-08-10 20:24:57 +04:00
action_str = N_ ( " updated " ) ;
2004-10-13 05:40:35 +04:00
break ;
2009-02-27 01:40:58 +03:00
case DSPRINT_UNPUBLISH :
2009-08-10 20:24:57 +04:00
action_str = N_ ( " unpublished " ) ;
2004-10-13 05:40:35 +04:00
break ;
default :
2009-08-10 20:24:57 +04:00
action_str = N_ ( " unknown action " ) ;
printf ( _ ( " unkown action: %d \n " ) , action ) ;
2004-10-13 05:40:35 +04:00
break ;
}
2009-02-25 12:58:53 +03:00
info . info7 . action = action ;
info_ctr . level = 7 ;
2009-05-04 00:44:36 +04:00
info_ctr . info . info7 = ( struct spoolss_SetPrinterInfo7 * )
( void * ) & info . info7 ;
2009-02-25 12:58:53 +03:00
ZERO_STRUCT ( devmode_ctr ) ;
ZERO_STRUCT ( secdesc_ctr ) ;
nt_status = rpccli_spoolss_SetPrinter ( pipe_hnd , mem_ctx ,
& hnd ,
& info_ctr ,
& devmode_ctr ,
& secdesc_ctr ,
0 , /* command */
& result ) ;
2004-10-13 05:40:35 +04:00
2005-07-19 13:37:42 +04:00
if ( ! W_ERROR_IS_OK ( result ) & & ( W_ERROR_V ( result ) ! = W_ERROR_V ( WERR_IO_PENDING ) ) ) {
2009-08-10 20:24:57 +04:00
printf ( _ ( " cannot set printer-info: %s \n " ) ,
win_errstr ( result ) ) ;
2004-10-13 05:40:35 +04:00
goto done ;
}
2009-08-10 20:24:57 +04:00
printf ( _ ( " successfully %s printer %s in Active Directory \n " ) ,
action_str , sharename ) ;
2004-10-13 05:40:35 +04:00
}
nt_status = NT_STATUS_OK ;
done :
2009-02-25 14:09:15 +03:00
if ( is_valid_policy_hnd ( & hnd ) )
2008-11-15 01:58:26 +03:00
rpccli_spoolss_ClosePrinter ( pipe_hnd , mem_ctx , & hnd , NULL ) ;
2008-05-08 13:23:38 +04:00
2004-10-13 05:40:35 +04:00
return nt_status ;
}
2008-05-10 01:22:12 +04:00
NTSTATUS rpc_printer_publish_publish_internals ( struct net_context * c ,
2010-05-21 05:25:01 +04:00
const struct dom_sid * domain_sid ,
2008-05-08 13:23:38 +04:00
const char * domain_name ,
2005-09-30 21:13:37 +04:00
struct cli_state * cli ,
struct rpc_pipe_client * pipe_hnd ,
2008-05-08 13:23:38 +04:00
TALLOC_CTX * mem_ctx ,
2005-09-30 21:13:37 +04:00
int argc ,
const char * * argv )
2004-10-13 05:40:35 +04:00
{
2009-02-27 01:40:58 +03:00
return rpc_printer_publish_internals_args ( pipe_hnd , mem_ctx , argc , argv , DSPRINT_PUBLISH ) ;
2004-10-13 05:40:35 +04:00
}
2008-05-10 01:22:12 +04:00
NTSTATUS rpc_printer_publish_unpublish_internals ( struct net_context * c ,
2010-05-21 05:25:01 +04:00
const struct dom_sid * domain_sid ,
2008-05-08 13:23:38 +04:00
const char * domain_name ,
2005-09-30 21:13:37 +04:00
struct cli_state * cli ,
struct rpc_pipe_client * pipe_hnd ,
2008-05-08 13:23:38 +04:00
TALLOC_CTX * mem_ctx ,
2005-09-30 21:13:37 +04:00
int argc ,
const char * * argv )
2004-10-13 05:40:35 +04:00
{
2009-02-27 01:40:58 +03:00
return rpc_printer_publish_internals_args ( pipe_hnd , mem_ctx , argc , argv , DSPRINT_UNPUBLISH ) ;
2004-10-13 05:40:35 +04:00
}
2008-05-10 01:22:12 +04:00
NTSTATUS rpc_printer_publish_update_internals ( struct net_context * c ,
2010-05-21 05:25:01 +04:00
const struct dom_sid * domain_sid ,
2008-05-08 13:23:38 +04:00
const char * domain_name ,
2005-09-30 21:13:37 +04:00
struct cli_state * cli ,
struct rpc_pipe_client * pipe_hnd ,
2008-05-08 13:23:38 +04:00
TALLOC_CTX * mem_ctx ,
2005-09-30 21:13:37 +04:00
int argc ,
const char * * argv )
2004-10-13 05:40:35 +04:00
{
2009-02-27 01:40:58 +03:00
return rpc_printer_publish_internals_args ( pipe_hnd , mem_ctx , argc , argv , DSPRINT_UPDATE ) ;
2004-10-13 05:40:35 +04:00
}
2008-05-08 13:23:38 +04:00
/**
2005-06-15 17:01:19 +04:00
* List print - queues w . r . t . their publishing state
2004-10-13 05:40:35 +04:00
*
* All parameters are provided by the run_rpc_command function , except for
2008-05-08 13:23:38 +04:00
* argc , argv which are passed through .
2004-10-13 05:40:35 +04:00
*
2008-05-10 01:22:12 +04:00
* @ param c A net_context structure
2004-10-13 05:40:35 +04:00
* @ param domain_sid The domain sid aquired from the remote server
* @ param cli A cli_state connected to the server .
* @ param mem_ctx Talloc context , destoyed on compleation of the function .
* @ param argc Standard main ( ) style argc
* @ param argv Standard main ( ) style argv . Initial components are already
* stripped
*
* @ return Normal NTSTATUS return .
* */
2005-09-30 21:13:37 +04:00
2008-05-10 01:22:12 +04:00
NTSTATUS rpc_printer_publish_list_internals ( struct net_context * c ,
2010-05-21 05:25:01 +04:00
const struct dom_sid * domain_sid ,
2008-05-08 13:23:38 +04:00
const char * domain_name ,
2005-09-30 21:13:37 +04:00
struct cli_state * cli ,
struct rpc_pipe_client * pipe_hnd ,
2008-05-08 13:23:38 +04:00
TALLOC_CTX * mem_ctx ,
2005-09-30 21:13:37 +04:00
int argc ,
const char * * argv )
2004-10-13 05:40:35 +04:00
{
NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL ;
2009-03-19 14:53:01 +03:00
uint32_t i , num_printers ;
uint32_t level = 7 ;
2009-03-10 00:42:30 +03:00
const char * printername , * sharename ;
union spoolss_PrinterInfo * info_enum ;
2009-02-25 12:58:53 +03:00
union spoolss_PrinterInfo info ;
2009-03-19 00:49:41 +03:00
struct policy_handle hnd ;
2004-10-13 05:40:35 +04:00
int state ;
2009-03-10 00:42:30 +03:00
if ( ! get_printer_info ( pipe_hnd , mem_ctx , 2 , argc , argv , & num_printers , & info_enum ) )
2004-10-13 05:40:35 +04:00
return nt_status ;
for ( i = 0 ; i < num_printers ; i + + ) {
/* do some initialization */
2009-03-10 00:42:30 +03:00
printername = info_enum [ i ] . info2 . printername ;
sharename = info_enum [ i ] . info2 . sharename ;
2007-12-05 02:45:20 +03:00
if ( ! printername | | ! sharename ) {
goto done ;
}
2004-10-13 05:40:35 +04:00
/* open printer handle */
2005-09-30 21:13:37 +04:00
if ( ! net_spoolss_open_printer_ex ( pipe_hnd , mem_ctx , sharename ,
2008-05-08 13:23:38 +04:00
PRINTER_ALL_ACCESS , cli - > user_name , & hnd ) )
2004-10-13 05:40:35 +04:00
goto done ;
/* check for existing dst printer */
2009-02-25 12:58:53 +03:00
if ( ! net_spoolss_getprinter ( pipe_hnd , mem_ctx , & hnd , level , & info ) )
2004-10-13 05:40:35 +04:00
goto done ;
2009-02-25 12:58:53 +03:00
if ( ! info . info7 . guid ) {
2007-12-05 02:45:20 +03:00
goto done ;
}
2009-02-25 12:58:53 +03:00
state = info . info7 . action ;
2004-10-13 05:40:35 +04:00
switch ( state ) {
2009-02-27 01:40:58 +03:00
case DSPRINT_PUBLISH :
2009-08-10 20:24:57 +04:00
printf ( _ ( " printer [%s] is published " ) ,
sharename ) ;
2008-05-10 01:22:12 +04:00
if ( c - > opt_verbose )
2009-08-10 20:24:57 +04:00
printf ( _ ( " , guid: %s " ) , info . info7 . guid ) ;
2004-10-13 05:40:35 +04:00
printf ( " \n " ) ;
break ;
2009-02-27 01:40:58 +03:00
case DSPRINT_UNPUBLISH :
2009-08-10 20:24:57 +04:00
printf ( _ ( " printer [%s] is unpublished \n " ) ,
sharename ) ;
2004-10-13 05:40:35 +04:00
break ;
2009-02-27 01:40:58 +03:00
case DSPRINT_UPDATE :
2009-08-10 20:24:57 +04:00
printf ( _ ( " printer [%s] is currently updating \n " ) ,
sharename ) ;
2004-10-13 05:40:35 +04:00
break ;
default :
2009-08-10 20:24:57 +04:00
printf ( _ ( " unkown state: %d \n " ) , state ) ;
2004-10-13 05:40:35 +04:00
break ;
}
}
nt_status = NT_STATUS_OK ;
done :
2009-02-25 14:09:15 +03:00
if ( is_valid_policy_hnd ( & hnd ) )
2008-11-15 01:58:26 +03:00
rpccli_spoolss_ClosePrinter ( pipe_hnd , mem_ctx , & hnd , NULL ) ;
2008-05-08 13:23:38 +04:00
2004-10-13 05:40:35 +04:00
return nt_status ;
}
2004-08-10 18:27:17 +04:00
2008-05-08 13:23:38 +04:00
/**
2004-08-10 18:27:17 +04:00
* Migrate Printer - ACLs from a source server to the destination server
*
* All parameters are provided by the run_rpc_command function , except for
2008-05-08 13:23:38 +04:00
* argc , argv which are passed through .
2004-08-10 18:27:17 +04:00
*
2008-05-10 01:22:12 +04:00
* @ param c A net_context structure
2004-08-10 18:27:17 +04:00
* @ param domain_sid The domain sid aquired from the remote server
* @ param cli A cli_state connected to the server .
* @ param mem_ctx Talloc context , destoyed on compleation of the function .
* @ param argc Standard main ( ) style argc
* @ param argv Standard main ( ) style argv . Initial components are already
* stripped
*
* @ return Normal NTSTATUS return .
* */
2005-09-30 21:13:37 +04:00
2008-05-10 01:22:12 +04:00
NTSTATUS rpc_printer_migrate_security_internals ( struct net_context * c ,
2010-05-21 05:25:01 +04:00
const struct dom_sid * domain_sid ,
2008-05-08 13:23:38 +04:00
const char * domain_name ,
2005-09-30 21:13:37 +04:00
struct cli_state * cli ,
struct rpc_pipe_client * pipe_hnd ,
2008-05-08 13:23:38 +04:00
TALLOC_CTX * mem_ctx ,
2005-09-30 21:13:37 +04:00
int argc ,
const char * * argv )
2004-08-10 18:27:17 +04:00
{
2008-05-08 13:23:38 +04:00
/* TODO: what now, info2 or info3 ?
2004-08-10 18:27:17 +04:00
convince jerry that we should add clientside setacls level 3 at least
*/
NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL ;
2009-03-19 14:53:01 +03:00
uint32_t i = 0 ;
uint32_t num_printers ;
uint32_t level = 2 ;
2009-03-10 00:42:30 +03:00
const char * printername , * sharename ;
2005-09-30 21:13:37 +04:00
struct rpc_pipe_client * pipe_hnd_dst = NULL ;
2009-03-19 00:49:41 +03:00
struct policy_handle hnd_src , hnd_dst ;
2009-03-10 00:42:30 +03:00
union spoolss_PrinterInfo * info_enum ;
2004-08-10 18:27:17 +04:00
struct cli_state * cli_dst = NULL ;
2009-02-25 12:58:53 +03:00
union spoolss_PrinterInfo info_src , info_dst ;
2004-08-10 18:27:17 +04:00
DEBUG ( 3 , ( " copying printer ACLs \n " ) ) ;
2004-08-27 01:37:20 +04:00
/* connect destination PI_SPOOLSS */
2008-07-20 20:44:32 +04:00
nt_status = connect_dst_pipe ( c , & cli_dst , & pipe_hnd_dst ,
2009-03-18 15:22:51 +03:00
& ndr_table_spoolss . syntax_id ) ;
2004-08-10 18:27:17 +04:00
if ( ! NT_STATUS_IS_OK ( nt_status ) )
return nt_status ;
2004-08-27 01:37:20 +04:00
/* enum source printers */
2009-03-10 00:42:30 +03:00
if ( ! get_printer_info ( pipe_hnd , mem_ctx , level , argc , argv , & num_printers , & info_enum ) ) {
2004-08-10 18:27:17 +04:00
nt_status = NT_STATUS_UNSUCCESSFUL ;
goto done ;
}
if ( ! num_printers ) {
2009-08-10 20:24:57 +04:00
printf ( _ ( " no printers found on server. \n " ) ) ;
2004-08-10 18:27:17 +04:00
nt_status = NT_STATUS_OK ;
goto done ;
2007-12-05 02:45:20 +03:00
}
2004-08-10 18:27:17 +04:00
/* do something for all printers */
for ( i = 0 ; i < num_printers ; i + + ) {
2009-03-10 00:42:30 +03:00
2004-08-10 18:27:17 +04:00
/* do some initialization */
2009-03-10 00:42:30 +03:00
printername = info_enum [ i ] . info2 . printername ;
sharename = info_enum [ i ] . info2 . sharename ;
2007-12-05 02:45:20 +03:00
if ( ! printername | | ! sharename ) {
nt_status = NT_STATUS_UNSUCCESSFUL ;
goto done ;
}
/* we can reset NT_STATUS here because we do not
2004-08-10 18:27:17 +04:00
get any real NT_STATUS - codes anymore from now on */
nt_status = NT_STATUS_UNSUCCESSFUL ;
2007-12-05 02:45:20 +03:00
2009-08-10 20:24:57 +04:00
d_printf ( _ ( " migrating printer ACLs for: [%s] / [%s] \n " ) ,
2004-08-10 18:27:17 +04:00
printername , sharename ) ;
2008-05-08 13:23:38 +04:00
/* according to msdn you have specify these access-rights
2004-08-10 18:27:17 +04:00
to see the security descriptor
- READ_CONTROL ( DACL )
- ACCESS_SYSTEM_SECURITY ( SACL )
*/
/* open src printer handle */
2005-09-30 21:13:37 +04:00
if ( ! net_spoolss_open_printer_ex ( pipe_hnd , mem_ctx , sharename ,
2008-05-08 13:23:38 +04:00
MAXIMUM_ALLOWED_ACCESS , cli - > user_name , & hnd_src ) )
2004-08-10 18:27:17 +04:00
goto done ;
/* open dst printer handle */
2005-09-30 21:13:37 +04:00
if ( ! net_spoolss_open_printer_ex ( pipe_hnd_dst , mem_ctx , sharename ,
2008-05-08 13:23:38 +04:00
PRINTER_ALL_ACCESS , cli_dst - > user_name , & hnd_dst ) )
2004-08-10 18:27:17 +04:00
goto done ;
/* check for existing dst printer */
2009-02-25 12:58:53 +03:00
if ( ! net_spoolss_getprinter ( pipe_hnd_dst , mem_ctx , & hnd_dst , level , & info_dst ) )
2004-08-10 18:27:17 +04:00
goto done ;
/* check for existing src printer */
2009-02-25 12:58:53 +03:00
if ( ! net_spoolss_getprinter ( pipe_hnd , mem_ctx , & hnd_src , 3 , & info_src ) )
2004-08-10 18:27:17 +04:00
goto done ;
/* Copy Security Descriptor */
/* copy secdesc (info level 2) */
2009-02-25 12:58:53 +03:00
info_dst . info2 . devmode = NULL ;
info_dst . info2 . secdesc = dup_sec_desc ( mem_ctx , info_src . info3 . secdesc ) ;
2004-08-10 18:27:17 +04:00
2008-05-10 01:22:12 +04:00
if ( c - > opt_verbose )
2009-02-25 12:58:53 +03:00
display_sec_desc ( info_dst . info2 . secdesc ) ;
2008-05-08 13:23:38 +04:00
2009-02-25 12:58:53 +03:00
if ( ! net_spoolss_setprinter ( pipe_hnd_dst , mem_ctx , & hnd_dst , 2 , & info_dst ) )
2004-08-10 18:27:17 +04:00
goto done ;
2008-05-08 13:23:38 +04:00
2004-08-10 18:27:17 +04:00
DEBUGADD ( 1 , ( " \t SetPrinter of SECDESC succeeded \n " ) ) ;
/* close printer handles here */
2009-02-25 14:09:15 +03:00
if ( is_valid_policy_hnd ( & hnd_src ) ) {
2008-11-15 01:58:26 +03:00
rpccli_spoolss_ClosePrinter ( pipe_hnd , mem_ctx , & hnd_src , NULL ) ;
2004-08-10 18:27:17 +04:00
}
2009-02-25 14:09:15 +03:00
if ( is_valid_policy_hnd ( & hnd_dst ) ) {
2008-11-15 01:58:26 +03:00
rpccli_spoolss_ClosePrinter ( pipe_hnd_dst , mem_ctx , & hnd_dst , NULL ) ;
2004-08-10 18:27:17 +04:00
}
}
2008-05-08 13:23:38 +04:00
2004-08-10 18:27:17 +04:00
nt_status = NT_STATUS_OK ;
done :
2009-02-25 14:09:15 +03:00
if ( is_valid_policy_hnd ( & hnd_src ) ) {
2008-11-15 01:58:26 +03:00
rpccli_spoolss_ClosePrinter ( pipe_hnd , mem_ctx , & hnd_src , NULL ) ;
2005-09-30 21:13:37 +04:00
}
2004-08-10 18:27:17 +04:00
2009-02-25 14:09:15 +03:00
if ( is_valid_policy_hnd ( & hnd_dst ) ) {
2008-11-15 01:58:26 +03:00
rpccli_spoolss_ClosePrinter ( pipe_hnd_dst , mem_ctx , & hnd_dst , NULL ) ;
2005-09-30 21:13:37 +04:00
}
2004-08-10 18:27:17 +04:00
2005-09-30 21:13:37 +04:00
if ( cli_dst ) {
2004-08-10 18:27:17 +04:00
cli_shutdown ( cli_dst ) ;
}
return nt_status ;
}
2008-05-08 13:23:38 +04:00
/**
2004-08-10 18:27:17 +04:00
* Migrate printer - forms from a src server to the dst server
*
* All parameters are provided by the run_rpc_command function , except for
2008-05-08 13:23:38 +04:00
* argc , argv which are passed through .
2004-08-10 18:27:17 +04:00
*
2008-05-10 01:22:12 +04:00
* @ param c A net_context structure
2004-08-10 18:27:17 +04:00
* @ param domain_sid The domain sid aquired from the remote server
* @ param cli A cli_state connected to the server .
* @ param mem_ctx Talloc context , destoyed on compleation of the function .
* @ param argc Standard main ( ) style argc
* @ param argv Standard main ( ) style argv . Initial components are already
* stripped
*
* @ return Normal NTSTATUS return .
* */
2005-09-30 21:13:37 +04:00
2008-05-10 01:22:12 +04:00
NTSTATUS rpc_printer_migrate_forms_internals ( struct net_context * c ,
2010-05-21 05:25:01 +04:00
const struct dom_sid * domain_sid ,
2008-05-08 13:23:38 +04:00
const char * domain_name ,
2005-09-30 21:13:37 +04:00
struct cli_state * cli ,
struct rpc_pipe_client * pipe_hnd ,
2008-05-08 13:23:38 +04:00
TALLOC_CTX * mem_ctx ,
2005-09-30 21:13:37 +04:00
int argc ,
const char * * argv )
2004-08-10 18:27:17 +04:00
{
NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL ;
WERROR result ;
2009-03-19 14:53:01 +03:00
uint32_t i , f ;
uint32_t num_printers ;
uint32_t level = 1 ;
2009-03-10 00:42:30 +03:00
const char * printername , * sharename ;
2005-09-30 21:13:37 +04:00
struct rpc_pipe_client * pipe_hnd_dst = NULL ;
2009-03-19 00:49:41 +03:00
struct policy_handle hnd_src , hnd_dst ;
2009-03-10 00:42:30 +03:00
union spoolss_PrinterInfo * info_enum ;
2009-02-25 12:58:53 +03:00
union spoolss_PrinterInfo info_dst ;
2009-03-06 13:02:27 +03:00
uint32_t num_forms ;
union spoolss_FormInfo * forms ;
2004-08-10 18:27:17 +04:00
struct cli_state * cli_dst = NULL ;
2007-12-05 02:45:20 +03:00
2004-08-10 18:27:17 +04:00
DEBUG ( 3 , ( " copying forms \n " ) ) ;
2007-12-05 02:45:20 +03:00
2004-08-27 01:37:20 +04:00
/* connect destination PI_SPOOLSS */
2008-07-20 20:44:32 +04:00
nt_status = connect_dst_pipe ( c , & cli_dst , & pipe_hnd_dst ,
2009-03-18 15:22:51 +03:00
& ndr_table_spoolss . syntax_id ) ;
2004-08-10 18:27:17 +04:00
if ( ! NT_STATUS_IS_OK ( nt_status ) )
return nt_status ;
/* enum src printers */
2009-03-10 00:42:30 +03:00
if ( ! get_printer_info ( pipe_hnd , mem_ctx , 2 , argc , argv , & num_printers , & info_enum ) ) {
2004-08-10 18:27:17 +04:00
nt_status = NT_STATUS_UNSUCCESSFUL ;
goto done ;
}
if ( ! num_printers ) {
2009-08-10 20:24:57 +04:00
printf ( _ ( " no printers found on server. \n " ) ) ;
2004-08-10 18:27:17 +04:00
nt_status = NT_STATUS_OK ;
goto done ;
2007-12-05 02:45:20 +03:00
}
2004-08-10 18:27:17 +04:00
/* do something for all printers */
for ( i = 0 ; i < num_printers ; i + + ) {
2009-03-10 00:42:30 +03:00
2004-08-10 18:27:17 +04:00
/* do some initialization */
2009-03-10 00:42:30 +03:00
printername = info_enum [ i ] . info2 . printername ;
sharename = info_enum [ i ] . info2 . sharename ;
2007-12-05 02:45:20 +03:00
if ( ! printername | | ! sharename ) {
nt_status = NT_STATUS_UNSUCCESSFUL ;
goto done ;
}
/* we can reset NT_STATUS here because we do not
2004-08-10 18:27:17 +04:00
get any real NT_STATUS - codes anymore from now on */
nt_status = NT_STATUS_UNSUCCESSFUL ;
2007-12-05 02:45:20 +03:00
2009-08-10 20:24:57 +04:00
d_printf ( _ ( " migrating printer forms for: [%s] / [%s] \n " ) ,
2004-08-10 18:27:17 +04:00
printername , sharename ) ;
/* open src printer handle */
2005-09-30 21:13:37 +04:00
if ( ! net_spoolss_open_printer_ex ( pipe_hnd , mem_ctx , sharename ,
2008-05-08 13:23:38 +04:00
MAXIMUM_ALLOWED_ACCESS , cli - > user_name , & hnd_src ) )
2004-08-10 18:27:17 +04:00
goto done ;
/* open dst printer handle */
2005-09-30 21:13:37 +04:00
if ( ! net_spoolss_open_printer_ex ( pipe_hnd_dst , mem_ctx , sharename ,
2008-05-08 13:23:38 +04:00
PRINTER_ALL_ACCESS , cli - > user_name , & hnd_dst ) )
2004-08-10 18:27:17 +04:00
goto done ;
/* check for existing dst printer */
2009-02-25 12:58:53 +03:00
if ( ! net_spoolss_getprinter ( pipe_hnd_dst , mem_ctx , & hnd_dst , level , & info_dst ) )
2004-08-10 18:27:17 +04:00
goto done ;
/* finally migrate forms */
2005-09-30 21:13:37 +04:00
if ( ! net_spoolss_enumforms ( pipe_hnd , mem_ctx , & hnd_src , level , & num_forms , & forms ) )
2004-08-10 18:27:17 +04:00
goto done ;
DEBUG ( 1 , ( " got %d forms for printer \n " , num_forms ) ) ;
for ( f = 0 ; f < num_forms ; f + + ) {
2009-02-08 02:03:00 +03:00
union spoolss_AddFormInfo info ;
NTSTATUS status ;
2008-05-08 13:23:38 +04:00
/* only migrate FORM_PRINTER types, according to jerry
2004-08-10 18:27:17 +04:00
FORM_BUILTIN - types are hard - coded in samba */
2009-03-06 14:01:54 +03:00
if ( forms [ f ] . info1 . flags ! = SPOOLSS_FORM_PRINTER )
2004-08-10 18:27:17 +04:00
continue ;
2008-05-10 01:22:12 +04:00
if ( c - > opt_verbose )
2009-08-10 20:24:57 +04:00
d_printf ( _ ( " \t migrating form # %d [%s] of type "
" [%d] \n " ) ,
2009-03-06 13:02:27 +03:00
f , forms [ f ] . info1 . form_name ,
forms [ f ] . info1 . flags ) ;
2008-05-08 13:23:38 +04:00
2009-05-04 00:44:36 +04:00
info . info1 = ( struct spoolss_AddFormInfo1 * )
( void * ) & forms [ f ] . info1 ;
2004-08-10 18:27:17 +04:00
2008-05-08 13:23:38 +04:00
/* FIXME: there might be something wrong with samba's
2004-08-10 18:27:17 +04:00
builtin - forms */
2009-02-08 02:03:00 +03:00
status = rpccli_spoolss_AddForm ( pipe_hnd_dst , mem_ctx ,
& hnd_dst ,
1 ,
info ,
& result ) ;
2004-08-10 18:27:17 +04:00
if ( ! W_ERROR_IS_OK ( result ) ) {
2009-08-10 20:24:57 +04:00
d_printf ( _ ( " \t AddForm form %d: [%s] refused. \n " ) ,
2009-03-06 13:02:27 +03:00
f , forms [ f ] . info1 . form_name ) ;
2004-08-10 18:27:17 +04:00
continue ;
}
2008-05-08 13:23:38 +04:00
2009-03-06 13:02:27 +03:00
DEBUGADD ( 1 , ( " \t AddForm of [%s] succeeded \n " ,
forms [ f ] . info1 . form_name ) ) ;
2004-08-10 18:27:17 +04:00
}
/* close printer handles here */
2009-02-25 14:09:15 +03:00
if ( is_valid_policy_hnd ( & hnd_src ) ) {
2008-11-15 01:58:26 +03:00
rpccli_spoolss_ClosePrinter ( pipe_hnd , mem_ctx , & hnd_src , NULL ) ;
2004-08-10 18:27:17 +04:00
}
2009-02-25 14:09:15 +03:00
if ( is_valid_policy_hnd ( & hnd_dst ) ) {
2008-11-15 01:58:26 +03:00
rpccli_spoolss_ClosePrinter ( pipe_hnd_dst , mem_ctx , & hnd_dst , NULL ) ;
2004-08-10 18:27:17 +04:00
}
}
nt_status = NT_STATUS_OK ;
done :
2009-02-25 14:09:15 +03:00
if ( is_valid_policy_hnd ( & hnd_src ) )
2008-11-15 01:58:26 +03:00
rpccli_spoolss_ClosePrinter ( pipe_hnd , mem_ctx , & hnd_src , NULL ) ;
2004-08-10 18:27:17 +04:00
2009-02-25 14:09:15 +03:00
if ( is_valid_policy_hnd ( & hnd_dst ) )
2008-11-15 01:58:26 +03:00
rpccli_spoolss_ClosePrinter ( pipe_hnd_dst , mem_ctx , & hnd_dst , NULL ) ;
2004-08-10 18:27:17 +04:00
2005-09-30 21:13:37 +04:00
if ( cli_dst ) {
2004-08-10 18:27:17 +04:00
cli_shutdown ( cli_dst ) ;
}
return nt_status ;
}
2008-05-08 13:23:38 +04:00
/**
2004-08-10 18:27:17 +04:00
* Migrate printer - drivers from a src server to the dst server
*
* All parameters are provided by the run_rpc_command function , except for
2008-05-08 13:23:38 +04:00
* argc , argv which are passed through .
2004-08-10 18:27:17 +04:00
*
2008-05-10 01:22:12 +04:00
* @ param c A net_context structure
2004-08-10 18:27:17 +04:00
* @ param domain_sid The domain sid aquired from the remote server
* @ param cli A cli_state connected to the server .
* @ param mem_ctx Talloc context , destoyed on compleation of the function .
* @ param argc Standard main ( ) style argc
* @ param argv Standard main ( ) style argv . Initial components are already
* stripped
*
* @ return Normal NTSTATUS return .
* */
2005-09-30 21:13:37 +04:00
2008-05-10 01:22:12 +04:00
NTSTATUS rpc_printer_migrate_drivers_internals ( struct net_context * c ,
2010-05-21 05:25:01 +04:00
const struct dom_sid * domain_sid ,
2008-05-08 13:23:38 +04:00
const char * domain_name ,
2005-09-30 21:13:37 +04:00
struct cli_state * cli ,
struct rpc_pipe_client * pipe_hnd ,
2008-05-08 13:23:38 +04:00
TALLOC_CTX * mem_ctx ,
2005-09-30 21:13:37 +04:00
int argc ,
const char * * argv )
2004-08-10 18:27:17 +04:00
{
NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL ;
2009-03-19 14:53:01 +03:00
uint32_t i , p ;
uint32_t num_printers ;
uint32_t level = 3 ;
2009-03-10 00:42:30 +03:00
const char * printername , * sharename ;
2008-05-12 13:53:23 +04:00
bool got_src_driver_share = false ;
bool got_dst_driver_share = false ;
2005-09-30 21:13:37 +04:00
struct rpc_pipe_client * pipe_hnd_dst = NULL ;
2009-03-19 00:49:41 +03:00
struct policy_handle hnd_src , hnd_dst ;
2009-02-25 00:23:56 +03:00
union spoolss_DriverInfo drv_info_src ;
2009-03-10 00:42:30 +03:00
union spoolss_PrinterInfo * info_enum ;
2009-02-25 12:58:53 +03:00
union spoolss_PrinterInfo info_dst ;
2004-08-10 18:27:17 +04:00
struct cli_state * cli_dst = NULL ;
struct cli_state * cli_share_src = NULL ;
struct cli_state * cli_share_dst = NULL ;
2009-02-25 00:23:56 +03:00
const char * drivername = NULL ;
2007-10-25 01:16:54 +04:00
2004-08-10 18:27:17 +04:00
DEBUG ( 3 , ( " copying printer-drivers \n " ) ) ;
2008-07-20 20:44:32 +04:00
nt_status = connect_dst_pipe ( c , & cli_dst , & pipe_hnd_dst ,
2009-03-18 15:22:51 +03:00
& ndr_table_spoolss . syntax_id ) ;
2004-08-10 18:27:17 +04:00
if ( ! NT_STATUS_IS_OK ( nt_status ) )
return nt_status ;
/* open print$-share on the src server */
2008-05-10 01:22:12 +04:00
nt_status = connect_to_service ( c , & cli_share_src , & cli - > dest_ss ,
2004-08-10 18:27:17 +04:00
cli - > desthost , " print$ " , " A: " ) ;
2007-10-25 01:16:54 +04:00
if ( ! NT_STATUS_IS_OK ( nt_status ) )
2005-08-02 10:24:45 +04:00
goto done ;
2004-08-10 18:27:17 +04:00
2008-05-12 13:53:23 +04:00
got_src_driver_share = true ;
2004-08-10 18:27:17 +04:00
/* open print$-share on the dst server */
2008-05-10 01:22:12 +04:00
nt_status = connect_to_service ( c , & cli_share_dst , & cli_dst - > dest_ss ,
2004-08-10 18:27:17 +04:00
cli_dst - > desthost , " print$ " , " A: " ) ;
2007-10-25 01:16:54 +04:00
if ( ! NT_STATUS_IS_OK ( nt_status ) )
2004-08-10 18:27:17 +04:00
return nt_status ;
2008-05-12 13:53:23 +04:00
got_dst_driver_share = true ;
2004-08-10 18:27:17 +04:00
/* enum src printers */
2009-03-10 00:42:30 +03:00
if ( ! get_printer_info ( pipe_hnd , mem_ctx , 2 , argc , argv , & num_printers , & info_enum ) ) {
2004-08-10 18:27:17 +04:00
nt_status = NT_STATUS_UNSUCCESSFUL ;
goto done ;
}
2005-08-02 10:24:45 +04:00
if ( num_printers = = 0 ) {
2009-08-10 20:24:57 +04:00
printf ( _ ( " no printers found on server. \n " ) ) ;
2004-08-10 18:27:17 +04:00
nt_status = NT_STATUS_OK ;
goto done ;
2007-12-05 02:45:20 +03:00
}
2004-08-10 18:27:17 +04:00
/* do something for all printers */
for ( p = 0 ; p < num_printers ; p + + ) {
2009-03-10 00:42:30 +03:00
2004-08-10 18:27:17 +04:00
/* do some initialization */
2009-03-10 00:42:30 +03:00
printername = info_enum [ p ] . info2 . printername ;
sharename = info_enum [ p ] . info2 . sharename ;
2007-12-05 02:45:20 +03:00
if ( ! printername | | ! sharename ) {
nt_status = NT_STATUS_UNSUCCESSFUL ;
goto done ;
}
2008-05-08 13:23:38 +04:00
/* we can reset NT_STATUS here because we do not
2004-08-10 18:27:17 +04:00
get any real NT_STATUS - codes anymore from now on */
nt_status = NT_STATUS_UNSUCCESSFUL ;
2009-08-10 20:24:57 +04:00
d_printf ( _ ( " migrating printer driver for: [%s] / [%s] \n " ) ,
2004-08-10 18:27:17 +04:00
printername , sharename ) ;
/* open dst printer handle */
2005-09-30 21:13:37 +04:00
if ( ! net_spoolss_open_printer_ex ( pipe_hnd_dst , mem_ctx , sharename ,
2008-05-08 13:23:38 +04:00
PRINTER_ALL_ACCESS , cli - > user_name , & hnd_dst ) )
2004-08-10 18:27:17 +04:00
goto done ;
2007-12-05 02:45:20 +03:00
2004-08-10 18:27:17 +04:00
/* check for existing dst printer */
2009-02-25 12:58:53 +03:00
if ( ! net_spoolss_getprinter ( pipe_hnd_dst , mem_ctx , & hnd_dst , 2 , & info_dst ) )
2004-08-10 18:27:17 +04:00
goto done ;
/* open src printer handle */
2005-09-30 21:13:37 +04:00
if ( ! net_spoolss_open_printer_ex ( pipe_hnd , mem_ctx , sharename ,
2008-04-22 00:27:29 +04:00
MAXIMUM_ALLOWED_ACCESS ,
pipe_hnd - > auth - > user_name ,
& hnd_src ) )
2004-08-10 18:27:17 +04:00
goto done ;
/* in a first step call getdriver for each shared printer (per arch)
to get a list of all files that have to be copied */
2008-05-08 13:23:38 +04:00
2004-08-10 18:27:17 +04:00
for ( i = 0 ; archi_table [ i ] . long_archi ! = NULL ; i + + ) {
/* getdriver src */
2008-05-08 13:23:38 +04:00
if ( ! net_spoolss_getprinterdriver ( pipe_hnd , mem_ctx , & hnd_src ,
level , archi_table [ i ] . long_archi ,
2009-02-25 00:23:56 +03:00
archi_table [ i ] . version , & drv_info_src ) )
2004-08-10 18:27:17 +04:00
continue ;
2009-02-25 00:23:56 +03:00
drivername = drv_info_src . info3 . driver_name ;
2004-08-10 18:27:17 +04:00
2008-05-10 01:22:12 +04:00
if ( c - > opt_verbose )
2009-02-25 00:23:56 +03:00
display_print_driver3 ( & drv_info_src . info3 ) ;
2004-08-10 18:27:17 +04:00
/* check arch dir */
nt_status = check_arch_dir ( cli_share_dst , archi_table [ i ] . short_archi ) ;
if ( ! NT_STATUS_IS_OK ( nt_status ) )
goto done ;
/* copy driver-files */
2008-05-10 01:22:12 +04:00
nt_status = copy_print_driver_3 ( c , mem_ctx , cli_share_src , cli_share_dst ,
2008-05-08 13:23:38 +04:00
archi_table [ i ] . short_archi ,
2009-02-25 00:23:56 +03:00
& drv_info_src . info3 ) ;
2004-08-10 18:27:17 +04:00
if ( ! NT_STATUS_IS_OK ( nt_status ) )
goto done ;
/* adddriver dst */
2009-02-25 00:23:56 +03:00
if ( ! net_spoolss_addprinterdriver ( pipe_hnd_dst , mem_ctx , level , & drv_info_src ) ) {
2004-08-10 18:27:17 +04:00
nt_status = NT_STATUS_UNSUCCESSFUL ;
goto done ;
}
2008-05-08 13:23:38 +04:00
DEBUGADD ( 1 , ( " Sucessfully added driver [%s] for printer [%s] \n " ,
2004-08-10 18:27:17 +04:00
drivername , printername ) ) ;
}
2009-03-19 18:18:29 +03:00
if ( ! drivername | | strlen ( drivername ) = = 0 ) {
2005-04-26 16:26:32 +04:00
DEBUGADD ( 1 , ( " Did not get driver for printer %s \n " ,
printername ) ) ;
goto done ;
}
2004-08-10 18:27:17 +04:00
/* setdriver dst */
2009-02-25 12:58:53 +03:00
info_dst . info2 . drivername = drivername ;
2008-05-08 13:23:38 +04:00
2009-02-25 12:58:53 +03:00
if ( ! net_spoolss_setprinter ( pipe_hnd_dst , mem_ctx , & hnd_dst , 2 , & info_dst ) ) {
2004-08-10 18:27:17 +04:00
nt_status = NT_STATUS_UNSUCCESSFUL ;
goto done ;
}
2008-05-08 13:23:38 +04:00
DEBUGADD ( 1 , ( " Sucessfully set driver %s for printer %s \n " ,
2004-08-10 18:27:17 +04:00
drivername , printername ) ) ;
/* close dst */
2009-02-25 14:09:15 +03:00
if ( is_valid_policy_hnd ( & hnd_dst ) ) {
2008-11-15 01:58:26 +03:00
rpccli_spoolss_ClosePrinter ( pipe_hnd_dst , mem_ctx , & hnd_dst , NULL ) ;
2004-08-10 18:27:17 +04:00
}
/* close src */
2009-02-25 14:09:15 +03:00
if ( is_valid_policy_hnd ( & hnd_src ) ) {
2008-11-15 01:58:26 +03:00
rpccli_spoolss_ClosePrinter ( pipe_hnd , mem_ctx , & hnd_src , NULL ) ;
2004-08-10 18:27:17 +04:00
}
}
nt_status = NT_STATUS_OK ;
done :
2009-02-25 14:09:15 +03:00
if ( is_valid_policy_hnd ( & hnd_src ) )
2008-11-15 01:58:26 +03:00
rpccli_spoolss_ClosePrinter ( pipe_hnd , mem_ctx , & hnd_src , NULL ) ;
2004-08-10 18:27:17 +04:00
2009-02-25 14:09:15 +03:00
if ( is_valid_policy_hnd ( & hnd_dst ) )
2008-11-15 01:58:26 +03:00
rpccli_spoolss_ClosePrinter ( pipe_hnd_dst , mem_ctx , & hnd_dst , NULL ) ;
2004-08-10 18:27:17 +04:00
2005-09-30 21:13:37 +04:00
if ( cli_dst ) {
2004-08-10 18:27:17 +04:00
cli_shutdown ( cli_dst ) ;
}
if ( got_src_driver_share )
cli_shutdown ( cli_share_src ) ;
if ( got_dst_driver_share )
cli_shutdown ( cli_share_dst ) ;
return nt_status ;
}
2008-05-08 13:23:38 +04:00
/**
2004-08-10 18:27:17 +04:00
* Migrate printer - queues from a src to the dst server
* ( requires a working " addprinter command " to be installed for the local smbd )
*
* All parameters are provided by the run_rpc_command function , except for
2008-05-08 13:23:38 +04:00
* argc , argv which are passed through .
2004-08-10 18:27:17 +04:00
*
2008-05-10 01:22:12 +04:00
* @ param c A net_context structure
2004-08-10 18:27:17 +04:00
* @ param domain_sid The domain sid aquired from the remote server
* @ param cli A cli_state connected to the server .
* @ param mem_ctx Talloc context , destoyed on compleation of the function .
* @ param argc Standard main ( ) style argc
* @ param argv Standard main ( ) style argv . Initial components are already
* stripped
*
* @ return Normal NTSTATUS return .
* */
2005-09-30 21:13:37 +04:00
2008-05-10 01:22:12 +04:00
NTSTATUS rpc_printer_migrate_printers_internals ( struct net_context * c ,
2010-05-21 05:25:01 +04:00
const struct dom_sid * domain_sid ,
2008-05-08 13:23:38 +04:00
const char * domain_name ,
2005-09-30 21:13:37 +04:00
struct cli_state * cli ,
struct rpc_pipe_client * pipe_hnd ,
2008-05-08 13:23:38 +04:00
TALLOC_CTX * mem_ctx ,
2005-09-30 21:13:37 +04:00
int argc ,
const char * * argv )
2004-08-10 18:27:17 +04:00
{
WERROR result ;
NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL ;
2009-03-19 14:53:01 +03:00
uint32_t i = 0 , num_printers ;
uint32_t level = 2 ;
2009-02-25 12:58:53 +03:00
union spoolss_PrinterInfo info_dst , info_src ;
2009-03-10 00:42:30 +03:00
union spoolss_PrinterInfo * info_enum ;
2004-08-10 18:27:17 +04:00
struct cli_state * cli_dst = NULL ;
2009-03-19 00:49:41 +03:00
struct policy_handle hnd_dst , hnd_src ;
2009-03-10 00:42:30 +03:00
const char * printername , * sharename ;
2005-09-30 21:13:37 +04:00
struct rpc_pipe_client * pipe_hnd_dst = NULL ;
2009-02-25 03:11:01 +03:00
struct spoolss_SetPrinterInfoCtr info_ctr ;
2004-08-10 18:27:17 +04:00
DEBUG ( 3 , ( " copying printers \n " ) ) ;
2004-08-27 01:37:20 +04:00
/* connect destination PI_SPOOLSS */
2008-07-20 20:44:32 +04:00
nt_status = connect_dst_pipe ( c , & cli_dst , & pipe_hnd_dst ,
2009-03-18 15:22:51 +03:00
& ndr_table_spoolss . syntax_id ) ;
2004-08-10 18:27:17 +04:00
if ( ! NT_STATUS_IS_OK ( nt_status ) )
return nt_status ;
/* enum printers */
2009-03-10 00:42:30 +03:00
if ( ! get_printer_info ( pipe_hnd , mem_ctx , level , argc , argv , & num_printers , & info_enum ) ) {
2004-08-10 18:27:17 +04:00
nt_status = NT_STATUS_UNSUCCESSFUL ;
goto done ;
}
if ( ! num_printers ) {
2009-08-10 20:24:57 +04:00
printf ( _ ( " no printers found on server. \n " ) ) ;
2004-08-10 18:27:17 +04:00
nt_status = NT_STATUS_OK ;
goto done ;
2007-12-05 02:45:20 +03:00
}
2004-08-10 18:27:17 +04:00
/* do something for all printers */
for ( i = 0 ; i < num_printers ; i + + ) {
2009-03-10 00:42:30 +03:00
2010-06-03 18:30:55 +04:00
struct spoolss_SetPrinterInfo2 info2 ;
2004-08-10 18:27:17 +04:00
/* do some initialization */
2009-03-10 00:42:30 +03:00
printername = info_enum [ i ] . info2 . printername ;
sharename = info_enum [ i ] . info2 . sharename ;
2007-12-05 02:45:20 +03:00
if ( ! printername | | ! sharename ) {
nt_status = NT_STATUS_UNSUCCESSFUL ;
goto done ;
}
/* we can reset NT_STATUS here because we do not
2004-08-10 18:27:17 +04:00
get any real NT_STATUS - codes anymore from now on */
nt_status = NT_STATUS_UNSUCCESSFUL ;
2007-12-05 02:45:20 +03:00
2009-08-10 20:24:57 +04:00
d_printf ( _ ( " migrating printer queue for: [%s] / [%s] \n " ) ,
2004-08-10 18:27:17 +04:00
printername , sharename ) ;
/* open dst printer handle */
2008-05-08 13:23:38 +04:00
if ( ! net_spoolss_open_printer_ex ( pipe_hnd_dst , mem_ctx , sharename ,
2004-10-07 15:01:13 +04:00
PRINTER_ALL_ACCESS , cli - > user_name , & hnd_dst ) ) {
2008-05-08 13:23:38 +04:00
2004-08-10 18:27:17 +04:00
DEBUG ( 1 , ( " could not open printer: %s \n " , sharename ) ) ;
}
/* check for existing dst printer */
2009-02-25 12:58:53 +03:00
if ( ! net_spoolss_getprinter ( pipe_hnd_dst , mem_ctx , & hnd_dst , level , & info_dst ) ) {
2009-08-10 20:24:57 +04:00
printf ( _ ( " could not get printer, creating printer. \n " ) ) ;
2004-08-10 18:27:17 +04:00
} else {
DEBUG ( 1 , ( " printer already exists: %s \n " , sharename ) ) ;
2006-03-15 06:00:49 +03:00
/* close printer handle here - dst only, not got src yet. */
2009-02-25 14:09:15 +03:00
if ( is_valid_policy_hnd ( & hnd_dst ) ) {
2008-11-15 01:58:26 +03:00
rpccli_spoolss_ClosePrinter ( pipe_hnd_dst , mem_ctx , & hnd_dst , NULL ) ;
2004-08-10 18:27:17 +04:00
}
continue ;
}
2008-05-08 13:23:38 +04:00
/* now get again src printer ctr via getprinter,
2004-08-10 18:27:17 +04:00
we first need a handle for that */
/* open src printer handle */
2005-09-30 21:13:37 +04:00
if ( ! net_spoolss_open_printer_ex ( pipe_hnd , mem_ctx , sharename ,
2008-05-08 13:23:38 +04:00
MAXIMUM_ALLOWED_ACCESS , cli - > user_name , & hnd_src ) )
2004-08-10 18:27:17 +04:00
goto done ;
/* getprinter on the src server */
2009-02-25 12:58:53 +03:00
if ( ! net_spoolss_getprinter ( pipe_hnd , mem_ctx , & hnd_src , level , & info_src ) )
2004-08-10 18:27:17 +04:00
goto done ;
2008-05-08 13:23:38 +04:00
/* copy each src printer to a dst printer 1:1,
2004-08-10 18:27:17 +04:00
maybe some values have to be changed though */
2009-08-10 20:24:57 +04:00
d_printf ( _ ( " creating printer: %s \n " ) , printername ) ;
2009-02-25 03:11:01 +03:00
info_ctr . level = level ;
2010-06-03 18:30:55 +04:00
spoolss_printerinfo2_to_setprinterinfo2 ( & info_src . info2 , & info2 ) ;
info_ctr . info . info2 = & info2 ;
2009-02-25 03:11:01 +03:00
result = rpccli_spoolss_addprinterex ( pipe_hnd_dst ,
mem_ctx ,
& info_ctr ) ;
2004-08-10 18:27:17 +04:00
if ( W_ERROR_IS_OK ( result ) )
2009-08-10 20:24:57 +04:00
d_printf ( _ ( " printer [%s] successfully added. \n " ) ,
printername ) ;
2008-05-08 13:23:38 +04:00
else if ( W_ERROR_V ( result ) = = W_ERROR_V ( WERR_PRINTER_ALREADY_EXISTS ) )
2009-08-10 20:24:57 +04:00
d_fprintf ( stderr , _ ( " printer [%s] already exists. \n " ) ,
printername ) ;
2004-08-10 18:27:17 +04:00
else {
2009-08-10 20:24:57 +04:00
d_fprintf ( stderr , _ ( " could not create printer [%s] \n " ) ,
printername ) ;
2004-08-10 18:27:17 +04:00
goto done ;
}
/* close printer handles here */
2009-02-25 14:09:15 +03:00
if ( is_valid_policy_hnd ( & hnd_src ) ) {
2008-11-15 01:58:26 +03:00
rpccli_spoolss_ClosePrinter ( pipe_hnd , mem_ctx , & hnd_src , NULL ) ;
2004-08-10 18:27:17 +04:00
}
2009-02-25 14:09:15 +03:00
if ( is_valid_policy_hnd ( & hnd_dst ) ) {
2008-11-15 01:58:26 +03:00
rpccli_spoolss_ClosePrinter ( pipe_hnd_dst , mem_ctx , & hnd_dst , NULL ) ;
2004-08-10 18:27:17 +04:00
}
}
nt_status = NT_STATUS_OK ;
done :
2009-02-25 14:09:15 +03:00
if ( is_valid_policy_hnd ( & hnd_src ) )
2008-11-15 01:58:26 +03:00
rpccli_spoolss_ClosePrinter ( pipe_hnd , mem_ctx , & hnd_src , NULL ) ;
2004-08-10 18:27:17 +04:00
2009-02-25 14:09:15 +03:00
if ( is_valid_policy_hnd ( & hnd_dst ) )
2008-11-15 01:58:26 +03:00
rpccli_spoolss_ClosePrinter ( pipe_hnd_dst , mem_ctx , & hnd_dst , NULL ) ;
2004-08-10 18:27:17 +04:00
2005-09-30 21:13:37 +04:00
if ( cli_dst ) {
2004-08-10 18:27:17 +04:00
cli_shutdown ( cli_dst ) ;
}
return nt_status ;
}
2008-05-08 13:23:38 +04:00
/**
2004-08-10 18:27:17 +04:00
* Migrate Printer - Settings from a src server to the dst server
* ( for this to work , printers and drivers already have to be migrated earlier )
*
* All parameters are provided by the run_rpc_command function , except for
2008-05-08 13:23:38 +04:00
* argc , argv which are passed through .
2004-08-10 18:27:17 +04:00
*
2008-05-10 01:22:12 +04:00
* @ param c A net_context structure
2004-08-10 18:27:17 +04:00
* @ param domain_sid The domain sid aquired from the remote server
* @ param cli A cli_state connected to the server .
* @ param mem_ctx Talloc context , destoyed on compleation of the function .
* @ param argc Standard main ( ) style argc
* @ param argv Standard main ( ) style argv . Initial components are already
* stripped
*
* @ return Normal NTSTATUS return .
* */
2005-09-30 21:13:37 +04:00
2008-05-10 01:22:12 +04:00
NTSTATUS rpc_printer_migrate_settings_internals ( struct net_context * c ,
2010-05-21 05:25:01 +04:00
const struct dom_sid * domain_sid ,
2008-05-08 13:23:38 +04:00
const char * domain_name ,
2005-09-30 21:13:37 +04:00
struct cli_state * cli ,
struct rpc_pipe_client * pipe_hnd ,
2008-05-08 13:23:38 +04:00
TALLOC_CTX * mem_ctx ,
2005-09-30 21:13:37 +04:00
int argc ,
const char * * argv )
2004-08-10 18:27:17 +04:00
{
/* FIXME: Here the nightmare begins */
WERROR result ;
NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL ;
2009-03-19 14:53:01 +03:00
uint32_t i = 0 , p = 0 , j = 0 ;
uint32_t num_printers ;
uint32_t level = 2 ;
2009-03-10 00:42:30 +03:00
const char * printername , * sharename ;
2005-09-30 21:13:37 +04:00
struct rpc_pipe_client * pipe_hnd_dst = NULL ;
2009-03-19 00:49:41 +03:00
struct policy_handle hnd_src , hnd_dst ;
2009-03-10 00:42:30 +03:00
union spoolss_PrinterInfo * info_enum ;
union spoolss_PrinterInfo info_dst_publish ;
union spoolss_PrinterInfo info_dst ;
2004-08-10 18:27:17 +04:00
struct cli_state * cli_dst = NULL ;
char * devicename = NULL , * unc_name = NULL , * url = NULL ;
2007-11-09 04:25:45 +03:00
const char * longname ;
2009-03-17 01:38:05 +03:00
const char * * keylist = NULL ;
2004-08-10 18:27:17 +04:00
2009-02-25 12:58:53 +03:00
/* FIXME GD */
ZERO_STRUCT ( info_dst_publish ) ;
2004-08-10 18:27:17 +04:00
DEBUG ( 3 , ( " copying printer settings \n " ) ) ;
2004-08-27 01:37:20 +04:00
/* connect destination PI_SPOOLSS */
2008-07-20 20:44:32 +04:00
nt_status = connect_dst_pipe ( c , & cli_dst , & pipe_hnd_dst ,
2009-03-18 15:22:51 +03:00
& ndr_table_spoolss . syntax_id ) ;
2004-08-10 18:27:17 +04:00
if ( ! NT_STATUS_IS_OK ( nt_status ) )
return nt_status ;
/* enum src printers */
2009-03-10 00:42:30 +03:00
if ( ! get_printer_info ( pipe_hnd , mem_ctx , level , argc , argv , & num_printers , & info_enum ) ) {
2004-08-10 18:27:17 +04:00
nt_status = NT_STATUS_UNSUCCESSFUL ;
goto done ;
}
if ( ! num_printers ) {
2009-08-10 20:24:57 +04:00
printf ( _ ( " no printers found on server. \n " ) ) ;
2004-08-10 18:27:17 +04:00
nt_status = NT_STATUS_OK ;
goto done ;
2007-11-09 04:25:45 +03:00
}
2004-08-10 18:27:17 +04:00
/* needed for dns-strings in regkeys */
2007-11-09 04:25:45 +03:00
longname = get_mydnsfullname ( ) ;
if ( ! longname ) {
nt_status = NT_STATUS_UNSUCCESSFUL ;
goto done ;
}
2004-08-10 18:27:17 +04:00
/* do something for all printers */
for ( i = 0 ; i < num_printers ; i + + ) {
2009-03-10 00:42:30 +03:00
2009-03-17 03:47:40 +03:00
uint32_t value_offered = 0 , value_needed ;
uint32_t data_offered = 0 , data_needed ;
enum winreg_Type type ;
uint8_t * buffer = NULL ;
const char * value_name = NULL ;
2004-08-10 18:27:17 +04:00
/* do some initialization */
2009-03-10 00:42:30 +03:00
printername = info_enum [ i ] . info2 . printername ;
sharename = info_enum [ i ] . info2 . sharename ;
2007-12-05 02:45:20 +03:00
if ( ! printername | | ! sharename ) {
nt_status = NT_STATUS_UNSUCCESSFUL ;
goto done ;
}
2008-05-08 13:23:38 +04:00
/* we can reset NT_STATUS here because we do not
2004-08-10 18:27:17 +04:00
get any real NT_STATUS - codes anymore from now on */
nt_status = NT_STATUS_UNSUCCESSFUL ;
2007-12-05 02:45:20 +03:00
2009-08-10 20:24:57 +04:00
d_printf ( _ ( " migrating printer settings for: [%s] / [%s] \n " ) ,
2004-08-10 18:27:17 +04:00
printername , sharename ) ;
/* open src printer handle */
2005-09-30 21:13:37 +04:00
if ( ! net_spoolss_open_printer_ex ( pipe_hnd , mem_ctx , sharename ,
2008-05-08 13:23:38 +04:00
MAXIMUM_ALLOWED_ACCESS , cli - > user_name , & hnd_src ) )
2004-08-10 18:27:17 +04:00
goto done ;
/* open dst printer handle */
2005-09-30 21:13:37 +04:00
if ( ! net_spoolss_open_printer_ex ( pipe_hnd_dst , mem_ctx , sharename ,
2008-05-08 13:23:38 +04:00
PRINTER_ALL_ACCESS , cli_dst - > user_name , & hnd_dst ) )
2004-08-10 18:27:17 +04:00
goto done ;
/* check for existing dst printer */
2008-05-08 13:23:38 +04:00
if ( ! net_spoolss_getprinter ( pipe_hnd_dst , mem_ctx , & hnd_dst ,
2009-02-25 12:58:53 +03:00
level , & info_dst ) )
2004-08-10 18:27:17 +04:00
goto done ;
2008-05-08 13:23:38 +04:00
/* STEP 1: COPY DEVICE-MODE and other
2004-08-10 18:27:17 +04:00
PRINTER_INFO_2 - attributes
*/
2009-03-10 00:42:30 +03:00
info_dst . info2 = info_enum [ i ] . info2 ;
2004-08-10 18:27:17 +04:00
2008-05-08 13:23:38 +04:00
/* why is the port always disconnected when the printer
2004-08-10 18:27:17 +04:00
is correctly installed ( incl . driver ? ? ? ) */
2009-02-25 12:58:53 +03:00
info_dst . info2 . portname = SAMBA_PRINTER_PORT_NAME ;
2004-08-10 18:27:17 +04:00
2008-05-08 13:23:38 +04:00
/* check if printer is published */
2009-03-10 00:42:30 +03:00
if ( info_enum [ i ] . info2 . attributes & PRINTER_ATTRIBUTE_PUBLISHED ) {
2004-09-21 17:31:57 +04:00
/* check for existing dst printer */
2009-02-25 12:58:53 +03:00
if ( ! net_spoolss_getprinter ( pipe_hnd_dst , mem_ctx , & hnd_dst , 7 , & info_dst_publish ) )
2004-09-21 17:31:57 +04:00
goto done ;
2009-02-27 01:40:58 +03:00
info_dst_publish . info7 . action = DSPRINT_PUBLISH ;
2004-09-21 17:31:57 +04:00
2008-05-12 13:53:23 +04:00
/* ignore false from setprinter due to WERR_IO_PENDING */
2009-02-25 12:58:53 +03:00
net_spoolss_setprinter ( pipe_hnd_dst , mem_ctx , & hnd_dst , 7 , & info_dst_publish ) ;
2004-09-21 17:31:57 +04:00
DEBUG ( 3 , ( " republished printer \n " ) ) ;
2004-08-27 01:32:49 +04:00
}
2009-03-10 00:42:30 +03:00
if ( info_enum [ i ] . info2 . devmode ! = NULL ) {
2005-04-26 16:26:32 +04:00
/* copy devmode (info level 2) */
2009-03-10 00:42:30 +03:00
info_dst . info2 . devmode = info_enum [ i ] . info2 . devmode ;
2004-08-10 18:27:17 +04:00
2005-04-26 16:26:32 +04:00
/* do not copy security descriptor (we have another
* command for that ) */
2009-02-25 12:58:53 +03:00
info_dst . info2 . secdesc = NULL ;
2004-08-10 18:27:17 +04:00
#if 0
2009-03-26 01:23:06 +03:00
info_dst . info2 . devmode . devicename =
talloc_asprintf ( mem_ctx , " \\ \\ %s \\ %s " ,
longname , printername ) ;
if ( ! info_dst . info2 . devmode . devicename ) {
2005-04-26 16:26:32 +04:00
nt_status = NT_STATUS_NO_MEMORY ;
goto done ;
}
2004-08-10 18:27:17 +04:00
# endif
2005-09-30 21:13:37 +04:00
if ( ! net_spoolss_setprinter ( pipe_hnd_dst , mem_ctx , & hnd_dst ,
2009-02-25 12:58:53 +03:00
level , & info_dst ) )
2005-04-26 16:26:32 +04:00
goto done ;
2008-05-08 13:23:38 +04:00
2005-04-26 16:26:32 +04:00
DEBUGADD ( 1 , ( " \t SetPrinter of DEVICEMODE succeeded \n " ) ) ;
}
2009-03-10 00:42:30 +03:00
2004-08-10 18:27:17 +04:00
/* STEP 2: COPY REGISTRY VALUES */
2008-05-08 13:23:38 +04:00
/* please keep in mind that samba parse_spools gives horribly
crippled results when used to rpccli_spoolss_enumprinterdataex
2005-02-25 02:25:35 +03:00
a win2k3 - server . ( Bugzilla # 1851 )
2008-05-08 13:23:38 +04:00
FIXME : IIRC I ' ve seen it too on a win2k - server
2004-08-10 18:27:17 +04:00
*/
/* enumerate data on src handle */
2009-03-17 03:47:40 +03:00
nt_status = rpccli_spoolss_EnumPrinterData ( pipe_hnd , mem_ctx ,
& hnd_src ,
p ,
value_name ,
value_offered ,
& value_needed ,
& type ,
buffer ,
data_offered ,
& data_needed ,
& result ) ;
data_offered = data_needed ;
value_offered = value_needed ;
buffer = talloc_zero_array ( mem_ctx , uint8_t , data_needed ) ;
value_name = talloc_zero_array ( mem_ctx , char , value_needed ) ;
2004-08-10 18:27:17 +04:00
2005-02-25 02:25:35 +03:00
/* loop for all printerdata of "PrinterDriverData" */
2009-03-17 03:47:40 +03:00
while ( NT_STATUS_IS_OK ( nt_status ) & & W_ERROR_IS_OK ( result ) ) {
nt_status = rpccli_spoolss_EnumPrinterData ( pipe_hnd , mem_ctx ,
& hnd_src ,
p + + ,
value_name ,
value_offered ,
& value_needed ,
& type ,
buffer ,
data_offered ,
& data_needed ,
& result ) ;
2004-08-10 18:27:17 +04:00
/* loop for all reg_keys */
2009-03-17 03:47:40 +03:00
if ( NT_STATUS_IS_OK ( nt_status ) & & W_ERROR_IS_OK ( result ) ) {
2004-08-10 18:27:17 +04:00
/* display_value */
2009-03-17 03:47:40 +03:00
if ( c - > opt_verbose ) {
2010-05-24 16:48:31 +04:00
struct regval_blob * v ;
v = regval_compose ( talloc_tos ( ) ,
value_name ,
type ,
buffer ,
data_offered ) ;
if ( v = = NULL ) {
nt_status = NT_STATUS_NO_MEMORY ;
goto done ;
}
2009-03-17 03:47:40 +03:00
display_reg_value ( SPOOL_PRINTERDATA_KEY , v ) ;
2010-05-24 16:48:31 +04:00
talloc_free ( v ) ;
2009-03-17 03:47:40 +03:00
}
2004-08-10 18:27:17 +04:00
/* set_value */
2008-05-08 13:23:38 +04:00
if ( ! net_spoolss_setprinterdata ( pipe_hnd_dst , mem_ctx ,
2009-03-17 03:47:40 +03:00
& hnd_dst , value_name ,
2010-03-04 17:34:22 +03:00
type , buffer , data_offered ) )
2004-08-10 18:27:17 +04:00
goto done ;
2008-05-08 13:23:38 +04:00
DEBUGADD ( 1 , ( " \t SetPrinterData of [%s] succeeded \n " ,
2010-05-24 16:18:21 +04:00
value_name ) ) ;
2004-08-10 18:27:17 +04:00
}
}
2008-05-08 13:23:38 +04:00
2004-08-10 18:27:17 +04:00
/* STEP 3: COPY SUBKEY VALUES */
2008-05-08 13:23:38 +04:00
/* here we need to enum all printer_keys and then work
2004-08-10 18:27:17 +04:00
on the result with enum_printer_key_ex . nt4 does not
2008-05-08 13:23:38 +04:00
respond to enumprinterkey , win2k does , so continue
2004-08-10 18:27:17 +04:00
in case of an error */
2005-09-30 21:13:37 +04:00
if ( ! net_spoolss_enumprinterkey ( pipe_hnd , mem_ctx , & hnd_src , " " , & keylist ) ) {
2009-08-10 20:24:57 +04:00
printf ( _ ( " got no key-data \n " ) ) ;
2004-08-10 18:27:17 +04:00
continue ;
}
2008-05-08 13:23:38 +04:00
/* work on a list of printer keys
2004-08-10 18:27:17 +04:00
each key has to be enumerated to get all required
2008-05-08 13:23:38 +04:00
information . information is then set via setprinterdataex - calls */
2004-08-10 18:27:17 +04:00
if ( keylist = = NULL )
continue ;
2009-03-17 01:38:05 +03:00
for ( i = 0 ; keylist & & keylist [ i ] ! = NULL ; i + + ) {
2004-08-10 18:27:17 +04:00
2009-03-17 01:38:05 +03:00
const char * subkey = keylist [ i ] ;
2009-03-18 03:06:22 +03:00
uint32_t count ;
struct spoolss_PrinterEnumValues * info ;
2005-08-29 18:55:40 +04:00
2004-08-10 18:27:17 +04:00
/* enumerate all src subkeys */
2008-05-08 13:23:38 +04:00
if ( ! net_spoolss_enumprinterdataex ( pipe_hnd , mem_ctx , 0 ,
& hnd_src , subkey ,
2009-03-18 03:06:22 +03:00
& count , & info ) ) {
2004-08-10 18:27:17 +04:00
goto done ;
2009-03-18 03:06:22 +03:00
}
2004-08-10 18:27:17 +04:00
2009-03-18 03:06:22 +03:00
for ( j = 0 ; j < count ; j + + ) {
2008-05-08 13:23:38 +04:00
2010-05-24 16:48:31 +04:00
struct regval_blob * value ;
2009-09-23 22:46:08 +04:00
DATA_BLOB blob ;
2008-05-08 13:23:38 +04:00
2010-06-28 14:54:11 +04:00
ZERO_STRUCT ( blob ) ;
2008-05-08 13:23:38 +04:00
/* although samba replies with sane data in most cases we
2004-08-10 18:27:17 +04:00
should try to avoid writing wrong registry data */
2008-05-08 13:23:38 +04:00
2009-03-18 03:06:22 +03:00
if ( strequal ( info [ j ] . value_name , SPOOL_REG_PORTNAME ) | |
strequal ( info [ j ] . value_name , SPOOL_REG_UNCNAME ) | |
strequal ( info [ j ] . value_name , SPOOL_REG_URL ) | |
strequal ( info [ j ] . value_name , SPOOL_REG_SHORTSERVERNAME ) | |
strequal ( info [ j ] . value_name , SPOOL_REG_SERVERNAME ) ) {
2004-08-10 18:27:17 +04:00
2009-03-18 03:06:22 +03:00
if ( strequal ( info [ j ] . value_name , SPOOL_REG_PORTNAME ) ) {
2008-05-08 13:23:38 +04:00
2004-08-10 18:27:17 +04:00
/* although windows uses a multi-sz, we use a sz */
2010-05-10 02:42:06 +04:00
push_reg_sz ( mem_ctx , & blob , SAMBA_PRINTER_PORT_NAME ) ;
2004-08-10 18:27:17 +04:00
}
2008-05-08 13:23:38 +04:00
2009-03-18 03:06:22 +03:00
if ( strequal ( info [ j ] . value_name , SPOOL_REG_UNCNAME ) ) {
2008-05-08 13:23:38 +04:00
2004-08-10 18:27:17 +04:00
if ( asprintf ( & unc_name , " \\ \\ %s \\ %s " , longname , sharename ) < 0 ) {
nt_status = NT_STATUS_NO_MEMORY ;
goto done ;
}
2010-05-10 02:42:06 +04:00
push_reg_sz ( mem_ctx , & blob , unc_name ) ;
2004-08-10 18:27:17 +04:00
}
2009-03-18 03:06:22 +03:00
if ( strequal ( info [ j ] . value_name , SPOOL_REG_URL ) ) {
2004-08-10 18:27:17 +04:00
continue ;
#if 0
/* FIXME: should we really do that ??? */
if ( asprintf ( & url , " http://%s:631/printers/%s " , longname , sharename ) < 0 ) {
nt_status = NT_STATUS_NO_MEMORY ;
goto done ;
}
2010-04-09 18:47:45 +04:00
push_reg_sz ( mem_ctx , NULL , & blob , url ) ;
2004-08-10 18:27:17 +04:00
fstrcpy ( value . valuename , SPOOL_REG_URL ) ;
# endif
}
2009-03-18 03:06:22 +03:00
if ( strequal ( info [ j ] . value_name , SPOOL_REG_SERVERNAME ) ) {
2004-08-10 18:27:17 +04:00
2010-05-10 02:42:06 +04:00
push_reg_sz ( mem_ctx , & blob , longname ) ;
2004-08-10 18:27:17 +04:00
}
2009-03-18 03:06:22 +03:00
if ( strequal ( info [ j ] . value_name , SPOOL_REG_SHORTSERVERNAME ) ) {
2004-08-10 18:27:17 +04:00
2010-05-10 02:42:06 +04:00
push_reg_sz ( mem_ctx , & blob , global_myname ( ) ) ;
2004-08-10 18:27:17 +04:00
}
2010-05-24 16:48:31 +04:00
value = regval_compose ( talloc_tos ( ) ,
info [ j ] . value_name ,
REG_SZ ,
blob . length = = 0 ? NULL : blob . data ,
blob . length ) ;
if ( value = = NULL ) {
nt_status = NT_STATUS_NO_MEMORY ;
goto done ;
2007-04-30 05:34:28 +04:00
}
2004-08-10 18:27:17 +04:00
2008-05-10 01:22:12 +04:00
if ( c - > opt_verbose )
2004-08-10 18:27:17 +04:00
display_reg_value ( subkey , value ) ;
/* here we have to set all subkeys on the dst server */
2008-05-08 13:23:38 +04:00
if ( ! net_spoolss_setprinterdataex ( pipe_hnd_dst , mem_ctx , & hnd_dst ,
2010-05-24 16:48:31 +04:00
subkey , value ) )
{
talloc_free ( value ) ;
2004-08-10 18:27:17 +04:00
goto done ;
2010-05-24 16:48:31 +04:00
}
2008-05-08 13:23:38 +04:00
2010-05-24 16:48:31 +04:00
talloc_free ( value ) ;
2004-08-10 18:27:17 +04:00
} else {
2010-05-24 16:48:31 +04:00
struct regval_blob * v ;
2009-03-18 03:06:22 +03:00
2010-05-24 16:48:31 +04:00
v = regval_compose ( talloc_tos ( ) ,
info [ j ] . value_name ,
info [ j ] . type ,
info [ j ] . data - > data ,
info [ j ] . data - > length ) ;
if ( v = = NULL ) {
nt_status = NT_STATUS_NO_MEMORY ;
goto done ;
}
2009-03-18 03:06:22 +03:00
if ( c - > opt_verbose ) {
display_reg_value ( subkey , v ) ;
}
2004-08-10 18:27:17 +04:00
/* here we have to set all subkeys on the dst server */
2008-05-08 13:23:38 +04:00
if ( ! net_spoolss_setprinterdataex ( pipe_hnd_dst , mem_ctx , & hnd_dst ,
2010-05-24 16:48:31 +04:00
subkey , v ) ) {
2004-08-10 18:27:17 +04:00
goto done ;
2009-03-18 03:06:22 +03:00
}
2004-08-10 18:27:17 +04:00
2010-05-24 16:48:31 +04:00
talloc_free ( v ) ;
2004-08-10 18:27:17 +04:00
}
2008-05-08 13:23:38 +04:00
DEBUGADD ( 1 , ( " \t SetPrinterDataEx of key [%s \\ %s] succeeded \n " ,
2009-03-18 03:06:22 +03:00
subkey , info [ j ] . value_name ) ) ;
2004-08-10 18:27:17 +04:00
}
}
2009-03-17 01:38:05 +03:00
TALLOC_FREE ( keylist ) ;
2004-08-10 18:27:17 +04:00
/* close printer handles here */
2009-02-25 14:09:15 +03:00
if ( is_valid_policy_hnd ( & hnd_src ) ) {
2008-11-15 01:58:26 +03:00
rpccli_spoolss_ClosePrinter ( pipe_hnd , mem_ctx , & hnd_src , NULL ) ;
2004-08-10 18:27:17 +04:00
}
2009-02-25 14:09:15 +03:00
if ( is_valid_policy_hnd ( & hnd_dst ) ) {
2008-11-15 01:58:26 +03:00
rpccli_spoolss_ClosePrinter ( pipe_hnd_dst , mem_ctx , & hnd_dst , NULL ) ;
2004-08-10 18:27:17 +04:00
}
}
2008-05-08 13:23:38 +04:00
2004-08-10 18:27:17 +04:00
nt_status = NT_STATUS_OK ;
done :
SAFE_FREE ( devicename ) ;
SAFE_FREE ( url ) ;
SAFE_FREE ( unc_name ) ;
2009-02-25 14:09:15 +03:00
if ( is_valid_policy_hnd ( & hnd_src ) )
2008-11-15 01:58:26 +03:00
rpccli_spoolss_ClosePrinter ( pipe_hnd , mem_ctx , & hnd_src , NULL ) ;
2004-08-10 18:27:17 +04:00
2009-02-25 14:09:15 +03:00
if ( is_valid_policy_hnd ( & hnd_dst ) )
2008-11-15 01:58:26 +03:00
rpccli_spoolss_ClosePrinter ( pipe_hnd_dst , mem_ctx , & hnd_dst , NULL ) ;
2004-08-10 18:27:17 +04:00
2005-09-30 21:13:37 +04:00
if ( cli_dst ) {
2004-08-10 18:27:17 +04:00
cli_shutdown ( cli_dst ) ;
}
return nt_status ;
}