2004-08-10 18:27:17 +04:00
/*
Samba Unix / Linux SMB client library
Distributed SMB / CIFS Server Management Utility
Copyright ( C ) 2004 Guenther Deschner ( gd @ samba . org )
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 .
This program is distributed in the hope that it will be useful ,
but WITHOUT ANY WARRANTY ; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
GNU General Public License for more details .
You should have received a copy of the GNU General Public License
2007-07-10 04:52:41 +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"
2004-08-10 18:27:17 +04:00
struct table_node {
const char * long_archi ;
const char * short_archi ;
int version ;
} ;
/* support itanium as well */
static const struct table_node archi_table [ ] = {
{ " 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
2004-08-10 18:27:17 +04:00
static void display_print_driver_3 ( DRIVER_INFO_3 * i1 )
{
fstring name = " " ;
fstring architecture = " " ;
fstring driverpath = " " ;
fstring datafile = " " ;
fstring configfile = " " ;
fstring helpfile = " " ;
fstring dependentfiles = " " ;
fstring monitorname = " " ;
fstring defaultdatatype = " " ;
int length = 0 ;
2007-10-19 04:40:25 +04:00
bool valid = True ;
2004-08-10 18:27:17 +04:00
if ( i1 = = NULL )
return ;
rpcstr_pull ( name , i1 - > name . buffer , sizeof ( name ) , - 1 , STR_TERMINATE ) ;
rpcstr_pull ( architecture , i1 - > architecture . buffer , sizeof ( architecture ) , - 1 , STR_TERMINATE ) ;
rpcstr_pull ( driverpath , i1 - > driverpath . buffer , sizeof ( driverpath ) , - 1 , STR_TERMINATE ) ;
rpcstr_pull ( datafile , i1 - > datafile . buffer , sizeof ( datafile ) , - 1 , STR_TERMINATE ) ;
rpcstr_pull ( configfile , i1 - > configfile . buffer , sizeof ( configfile ) , - 1 , STR_TERMINATE ) ;
rpcstr_pull ( helpfile , i1 - > helpfile . buffer , sizeof ( helpfile ) , - 1 , STR_TERMINATE ) ;
rpcstr_pull ( monitorname , i1 - > monitorname . buffer , sizeof ( monitorname ) , - 1 , STR_TERMINATE ) ;
rpcstr_pull ( defaultdatatype , i1 - > defaultdatatype . buffer , sizeof ( defaultdatatype ) , - 1 , STR_TERMINATE ) ;
d_printf ( " Printer Driver Info 3: \n " ) ;
d_printf ( " \t Version: [%x] \n " , i1 - > version ) ;
d_printf ( " \t Driver Name: [%s] \n " , name ) ;
d_printf ( " \t Architecture: [%s] \n " , architecture ) ;
d_printf ( " \t Driver Path: [%s] \n " , driverpath ) ;
d_printf ( " \t Datafile: [%s] \n " , datafile ) ;
d_printf ( " \t Configfile: [%s] \n " , configfile ) ;
d_printf ( " \t Helpfile: [%s] \n \n " , helpfile ) ;
while ( valid ) {
rpcstr_pull ( dependentfiles , i1 - > dependentfiles + length , sizeof ( dependentfiles ) , - 1 , STR_TERMINATE ) ;
length + = strlen ( dependentfiles ) + 1 ;
if ( strlen ( dependentfiles ) > 0 ) {
d_printf ( " \t Dependentfiles: [%s] \n " , dependentfiles ) ;
} else {
valid = False ;
}
}
printf ( " \n " ) ;
d_printf ( " \t Monitorname: [%s] \n " , monitorname ) ;
d_printf ( " \t Defaultdatatype: [%s] \n \n " , defaultdatatype ) ;
return ;
}
2005-02-25 02:30:47 +03:00
static void display_reg_value ( const char * subkey , REGISTRY_VALUE value )
2004-08-10 18:27:17 +04:00
{
2007-12-05 02:45:20 +03:00
char * text ;
2004-08-10 18:27:17 +04:00
switch ( value . type ) {
case REG_DWORD :
d_printf ( " \t [%s:%s]: REG_DWORD: 0x%08x \n " , subkey , value . valuename ,
* ( ( uint32 * ) value . data_p ) ) ;
break ;
case REG_SZ :
2007-12-05 02:45:20 +03:00
rpcstr_pull_talloc ( talloc_tos ( ) ,
& text ,
value . data_p ,
value . size ,
STR_TERMINATE ) ;
if ( ! text ) {
break ;
}
2004-08-10 18:27:17 +04:00
d_printf ( " \t [%s:%s]: REG_SZ: %s \n " , subkey , value . valuename , text ) ;
break ;
2007-12-05 02:45:20 +03:00
case REG_BINARY :
2004-08-10 18:27:17 +04:00
d_printf ( " \t [%s:%s]: REG_BINARY: unknown length value not displayed \n " ,
subkey , value . valuename ) ;
break ;
case REG_MULTI_SZ : {
2006-11-21 05:21:45 +03:00
uint32 i , num_values ;
2006-07-11 22:01:26 +04:00
char * * values ;
2006-12-01 23:01:09 +03:00
if ( ! W_ERROR_IS_OK ( reg_pull_multi_sz ( NULL , value . data_p ,
value . size , & num_values ,
& values ) ) ) {
2006-07-11 22:01:26 +04:00
d_printf ( " reg_pull_multi_sz failed \n " ) ;
break ;
2004-08-10 18:27:17 +04:00
}
2006-07-11 22:01:26 +04:00
for ( i = 0 ; i < num_values ; i + + ) {
d_printf ( " %s \n " , values [ i ] ) ;
}
TALLOC_FREE ( values ) ;
break ;
2004-08-10 18:27:17 +04:00
}
default :
d_printf ( " \t %s: unknown type %d \n " , value . valuename , value . type ) ;
}
}
2004-08-25 00:52:56 +04:00
/**
* Copies ACLs , DOS - attributes and timestamps from one
* file or directory from one connected share to another connected share
*
* @ param mem_ctx A talloc - context
* @ param cli_share_src A connected cli_state
* @ param cli_share_dst A connected cli_state
* @ 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 .
* */
2005-09-30 21:13:37 +04:00
2005-06-15 18:24:11 +04:00
NTSTATUS net_copy_fileattr ( TALLOC_CTX * mem_ctx ,
2004-08-25 00:52:56 +04:00
struct cli_state * cli_share_src ,
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 ;
int fnum_src = 0 ;
int fnum_dst = 0 ;
SEC_DESC * sd = NULL ;
uint16 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 */
DEBUGADD ( 3 , ( " opening %s %s on originating server \n " ,
is_file ? " file " : " dir " , src_name ) ) ;
fnum_src = cli_nt_create ( cli_share_src , src_name , READ_CONTROL_ACCESS ) ;
if ( fnum_src = = - 1 ) {
DEBUGADD ( 0 , ( " cannot open %s %s on originating server %s \n " ,
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 ;
}
if ( opt_verbose & & DEBUGLEVEL > = 3 )
display_sec_desc ( sd ) ;
}
if ( copy_attrs | | copy_timestamps ) {
/* get file attributes */
if ( ! cli_getattrE ( cli_share_src , fnum_src , & attr , NULL ,
2004-11-19 22:45:03 +03:00
& f_ctime , & f_atime , & f_mtime ) ) {
2004-08-25 00:52:56 +04:00
DEBUG ( 0 , ( " failed to get file-attrs: %s \n " ,
cli_errstr ( cli_share_src ) ) ) ;
nt_status = cli_nt_error ( cli_share_src ) ;
goto out ;
}
}
/* open the file/dir on the destination server */
fnum_dst = cli_nt_create ( cli_share_dst , dst_name , WRITE_DAC_ACCESS | WRITE_OWNER_ACCESS ) ;
if ( fnum_dst = = - 1 ) {
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 */
2004-11-19 22:45:03 +03:00
if ( ! 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 */
if ( ! cli_setatr ( cli_share_dst , dst_name , attr , 0 ) ) {
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 */
if ( ! cli_close ( cli_share_src , fnum_src ) ) {
2006-01-18 00:22:00 +03: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 ;
}
if ( ! cli_close ( cli_share_dst , fnum_dst ) ) {
2006-01-18 00:22:00 +03: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
/**
* Copy a file or directory from a connected share to another connected share
*
* @ param mem_ctx A talloc - context
* @ param cli_share_src A connected cli_state
* @ param cli_share_dst A connected cli_state
* @ 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 .
* */
2005-09-30 21:13:37 +04:00
2004-08-10 18:27:17 +04:00
NTSTATUS net_copy_file ( TALLOC_CTX * mem_ctx ,
struct cli_state * cli_share_src ,
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 ;
int fnum_src = 0 ;
int fnum_dst = 0 ;
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 )
2004-08-25 00:52:56 +04:00
goto out ;
2004-08-10 18:27:17 +04:00
/* open on the originating server */
DEBUGADD ( 3 , ( " opening %s %s on originating server \n " ,
is_file ? " file " : " dir " , src_name ) ) ;
if ( is_file )
2004-08-25 00:52:56 +04:00
fnum_src = cli_open ( cli_share_src , src_name , O_RDONLY , DENY_NONE ) ;
2004-08-10 18:27:17 +04:00
else
2004-08-25 00:52:56 +04:00
fnum_src = cli_nt_create ( cli_share_src , src_name , READ_CONTROL_ACCESS ) ;
2004-08-10 18:27:17 +04:00
if ( fnum_src = = - 1 ) {
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
nt_status = cli_nt_error ( cli_share_src ) ;
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 ) ) ;
fnum_dst = cli_open ( cli_share_dst , dst_name ,
O_RDWR | O_CREAT | O_TRUNC , DENY_NONE ) ;
2004-08-25 00:52:56 +04:00
if ( fnum_dst = = - 1 ) {
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-25 00:52:56 +04:00
nt_status = cli_nt_error ( 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 ) ) ) {
2006-01-18 00:22:00 +03: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
2004-08-10 18:27:17 +04:00
if ( opt_verbose ) {
2004-08-21 00:13:05 +04:00
d_printf ( " copying [ \\ \\ %s \\ %s%s] => [ \\ \\ %s \\ %s%s] "
2004-08-25 00:52:56 +04:00
" %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 ,
2004-08-21 00:13:05 +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 ;
2007-08-29 18:08:29 +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 ;
2004-08-10 20:42:58 +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 ) {
2006-01-18 00:22:00 +03: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
2004-08-10 18:27:17 +04:00
if ( ! is_file & & ! cli_chkpath ( cli_share_dst , dst_name ) ) {
2004-08-25 00:52:56 +04:00
/* creating dir */
2004-08-21 00:13:05 +04:00
DEBUGADD ( 3 , ( " creating dir %s on the destination server \n " ,
2004-08-10 18:27:17 +04:00
dst_name ) ) ;
if ( ! 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
2004-08-25 00:52:56 +04:00
if ( ! cli_chkpath ( cli_share_dst , dst_name ) ) {
2006-01-18 00:22:00 +03: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 */
if ( ! cli_close ( cli_share_src , fnum_src ) ) {
2006-01-18 00:22:00 +03: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 ;
}
if ( is_file & & ! cli_close ( cli_share_dst , fnum_dst ) ) {
2006-01-18 00:22:00 +03: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 */
nt_status = net_copy_fileattr ( mem_ctx , cli_share_src , cli_share_dst ,
src_name , dst_name , copy_acls ,
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 ;
}
/**
* Copy a driverfile from on connected share to another connected share
* This silently assumes that a driver - file is picked up from
*
* \ \ src_server \ print $ \ { arch } \ { version } \ file
*
* and copied to
*
* \ \ dst_server \ print $ \ { arch } \ file
*
* to be added via setdriver - calls later .
* @ 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
* @ param file The file - name to be copied
* @ param short_archi The name of the driver - architecture ( short form )
*
* @ return Normal NTSTATUS return .
* */
2005-09-30 21:13:37 +04:00
2004-08-10 18:27:17 +04:00
static NTSTATUS net_copy_driverfile ( TALLOC_CTX * mem_ctx ,
struct cli_state * cli_share_src ,
struct cli_state * cli_share_dst ,
char * file , const char * short_archi ) {
NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL ;
const char * p ;
char * src_name ;
char * dst_name ;
2007-12-08 04:32:32 +03:00
char * version ;
char * filename ;
char * tok ;
2004-08-10 18:27:17 +04:00
/* scroll through the file until we have the part
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
}
}
/* build source file name */
if ( asprintf ( & src_name , " \\ %s \\ %s \\ %s " , short_archi , version , filename ) < 0 )
return NT_STATUS_NO_MEMORY ;
/* create destination file name */
if ( asprintf ( & dst_name , " \\ %s \\ %s " , short_archi , filename ) < 0 )
return NT_STATUS_NO_MEMORY ;
/* finally copy the file */
nt_status = net_copy_file ( mem_ctx , cli_share_src , cli_share_dst ,
2004-08-21 00:13:05 +04:00
src_name , dst_name , False , False , False , True ) ;
2004-08-10 18:27:17 +04:00
if ( ! NT_STATUS_IS_OK ( nt_status ) )
goto out ;
nt_status = NT_STATUS_OK ;
out :
SAFE_FREE ( src_name ) ;
SAFE_FREE ( dst_name ) ;
return nt_status ;
}
/**
* 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 ;
}
DEBUG ( 10 , ( " creating print-driver dir for architecture: %s \n " ,
short_archi ) ) ;
if ( ! cli_mkdir ( cli_share , dir ) ) {
DEBUG ( 1 , ( " cannot create directory %s: %s \n " ,
dir , cli_errstr ( cli_share ) ) ) ;
nt_status = NT_STATUS_NO_SUCH_FILE ;
}
if ( ! cli_chkpath ( cli_share , dir ) ) {
2006-01-18 00:22:00 +03: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 ;
}
/**
* Copy a print - driver ( level 3 ) from one connected print $ - share to another
* connected print $ - share
*
* @ 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
static NTSTATUS copy_print_driver_3 ( TALLOC_CTX * mem_ctx ,
2004-08-10 18:27:17 +04:00
struct cli_state * cli_share_src ,
struct cli_state * cli_share_dst ,
const char * short_archi , DRIVER_INFO_3 * i1 )
{
NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL ;
int length = 0 ;
2007-10-19 04:40:25 +04:00
bool valid = True ;
2004-08-10 18:27:17 +04:00
fstring name = " " ;
fstring driverpath = " " ;
fstring datafile = " " ;
fstring configfile = " " ;
fstring helpfile = " " ;
fstring dependentfiles = " " ;
if ( i1 = = NULL )
return nt_status ;
rpcstr_pull ( name , i1 - > name . buffer , sizeof ( name ) , - 1 , STR_TERMINATE ) ;
rpcstr_pull ( driverpath , i1 - > driverpath . buffer , sizeof ( driverpath ) , - 1 , STR_TERMINATE ) ;
rpcstr_pull ( datafile , i1 - > datafile . buffer , sizeof ( datafile ) , - 1 , STR_TERMINATE ) ;
rpcstr_pull ( configfile , i1 - > configfile . buffer , sizeof ( configfile ) , - 1 , STR_TERMINATE ) ;
rpcstr_pull ( helpfile , i1 - > helpfile . buffer , sizeof ( helpfile ) , - 1 , STR_TERMINATE ) ;
if ( opt_verbose )
d_printf ( " copying driver: [%s], for architecture: [%s], version: [%d] \n " ,
name , short_archi , i1 - > version ) ;
nt_status = net_copy_driverfile ( mem_ctx , cli_share_src , cli_share_dst ,
driverpath , short_archi ) ;
if ( ! NT_STATUS_IS_OK ( nt_status ) )
return nt_status ;
nt_status = net_copy_driverfile ( mem_ctx , cli_share_src , cli_share_dst ,
datafile , short_archi ) ;
if ( ! NT_STATUS_IS_OK ( nt_status ) )
return nt_status ;
nt_status = net_copy_driverfile ( mem_ctx , cli_share_src , cli_share_dst ,
configfile , short_archi ) ;
if ( ! NT_STATUS_IS_OK ( nt_status ) )
return nt_status ;
nt_status = net_copy_driverfile ( mem_ctx , cli_share_src , cli_share_dst ,
helpfile , short_archi ) ;
if ( ! NT_STATUS_IS_OK ( nt_status ) )
return nt_status ;
while ( valid ) {
2005-08-02 10:24:45 +04:00
2004-08-10 18:27:17 +04:00
rpcstr_pull ( dependentfiles , i1 - > dependentfiles + length , sizeof ( dependentfiles ) , - 1 , STR_TERMINATE ) ;
2005-08-02 10:24:45 +04:00
length + = strlen ( dependentfiles ) + 1 ;
2004-08-10 18:27:17 +04:00
if ( strlen ( dependentfiles ) > 0 ) {
nt_status = net_copy_driverfile ( mem_ctx ,
cli_share_src , cli_share_dst ,
dependentfiles , short_archi ) ;
if ( ! NT_STATUS_IS_OK ( nt_status ) )
return nt_status ;
} else {
valid = False ;
}
}
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
* error - codes , etc .
*
* 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 ,
2005-09-30 21:13:37 +04:00
TALLOC_CTX * mem_ctx ,
char * name ,
uint32 flags ,
uint32 level ,
uint32 * num_printers ,
PRINTER_INFO_CTR * ctr )
2004-08-10 18:27:17 +04:00
{
WERROR result ;
/* enum printers */
2005-09-30 21:13:37 +04:00
result = rpccli_spoolss_enum_printers ( pipe_hnd , mem_ctx , name , flags ,
2004-08-10 18:27:17 +04:00
level , num_printers , ctr ) ;
if ( ! W_ERROR_IS_OK ( result ) ) {
printf ( " cannot enum printers: %s \n " , dos_errstr ( result ) ) ;
return False ;
}
return True ;
}
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 ,
uint32 access_required ,
const char * username ,
POLICY_HND * hnd )
2004-08-10 18:27:17 +04:00
{
WERROR result ;
2004-10-07 15:01:13 +04:00
fstring servername , printername2 ;
2004-08-10 18:27:17 +04:00
2005-09-30 21:13:37 +04:00
slprintf ( servername , sizeof ( servername ) - 1 , " \\ \\ %s " , pipe_hnd - > cli - > desthost ) ;
2004-10-07 15:01:13 +04:00
fstrcpy ( printername2 , servername ) ;
fstrcat ( printername2 , " \\ " ) ;
fstrcat ( printername2 , printername ) ;
2004-08-10 18:27:17 +04:00
DEBUG ( 10 , ( " connecting to: %s as %s for %s and access: %x \n " ,
2004-10-07 15:01:13 +04:00
servername , username , printername2 , access_required ) ) ;
2004-08-10 18:27:17 +04:00
/* open printer */
2005-09-30 21:13:37 +04:00
result = rpccli_spoolss_open_printer_ex ( pipe_hnd , mem_ctx , printername2 ,
2004-08-10 18:27:17 +04:00
" " , access_required ,
2004-10-07 15:01:13 +04:00
servername , username , hnd ) ;
2004-08-10 18:27:17 +04:00
/* be more verbose */
if ( W_ERROR_V ( result ) = = W_ERROR_V ( WERR_ACCESS_DENIED ) ) {
2006-01-18 00:22:00 +03:00
d_fprintf ( stderr , " no access to printer [%s] on [%s] for user [%s] granted \n " ,
2004-10-07 15:01:13 +04:00
printername2 , servername , username ) ;
2004-08-10 18:27:17 +04:00
return False ;
}
if ( ! W_ERROR_IS_OK ( result ) ) {
2006-01-18 00:22:00 +03:00
d_fprintf ( stderr , " cannot open printer %s on server %s: %s \n " ,
2004-10-07 15:01:13 +04:00
printername2 , servername , dos_errstr ( result ) ) ;
2004-08-10 18:27:17 +04:00
return False ;
}
DEBUG ( 2 , ( " got printer handle for printer: %s, server: %s \n " ,
2004-10-07 15:01:13 +04:00
printername2 , servername ) ) ;
2004-08-10 18:27:17 +04:00
return True ;
}
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 ,
POLICY_HND * hnd ,
uint32 level ,
PRINTER_INFO_CTR * ctr )
2004-08-10 18:27:17 +04:00
{
WERROR result ;
/* getprinter call */
2005-09-30 21:13:37 +04:00
result = rpccli_spoolss_getprinter ( pipe_hnd , mem_ctx , hnd , level , ctr ) ;
2004-08-10 18:27:17 +04:00
if ( ! W_ERROR_IS_OK ( result ) ) {
printf ( " cannot get printer-info: %s \n " , dos_errstr ( result ) ) ;
return False ;
}
return True ;
}
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 ,
POLICY_HND * hnd ,
uint32 level ,
PRINTER_INFO_CTR * ctr )
2004-08-10 18:27:17 +04:00
{
WERROR result ;
/* setprinter call */
2005-09-30 21:13:37 +04:00
result = rpccli_spoolss_setprinter ( pipe_hnd , mem_ctx , hnd , level , ctr , 0 ) ;
2004-08-10 18:27:17 +04:00
if ( ! W_ERROR_IS_OK ( result ) ) {
printf ( " cannot set printer-info: %s \n " , dos_errstr ( result ) ) ;
return False ;
}
return True ;
}
2007-10-19 04:40:25 +04:00
static bool net_spoolss_setprinterdata ( struct rpc_pipe_client * pipe_hnd ,
2005-09-30 21:13:37 +04:00
TALLOC_CTX * mem_ctx ,
POLICY_HND * hnd ,
REGISTRY_VALUE * value )
2004-08-10 18:27:17 +04:00
{
WERROR result ;
/* setprinterdata call */
2005-09-30 21:13:37 +04:00
result = rpccli_spoolss_setprinterdata ( pipe_hnd , mem_ctx , hnd , value ) ;
2004-08-10 18:27:17 +04:00
if ( ! W_ERROR_IS_OK ( result ) ) {
printf ( " unable to set printerdata: %s \n " , dos_errstr ( result ) ) ;
return False ;
}
return True ;
}
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 ,
POLICY_HND * hnd ,
const char * keyname ,
uint16 * * keylist )
2004-08-10 18:27:17 +04:00
{
WERROR result ;
/* enumprinterkey call */
2005-09-30 21:13:37 +04:00
result = rpccli_spoolss_enumprinterkey ( pipe_hnd , mem_ctx , hnd , keyname , keylist , NULL ) ;
2004-08-10 18:27:17 +04:00
if ( ! W_ERROR_IS_OK ( result ) ) {
printf ( " enumprinterkey failed: %s \n " , dos_errstr ( result ) ) ;
return False ;
}
return True ;
}
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 ,
uint32 offered ,
POLICY_HND * hnd ,
const char * keyname ,
REGVAL_CTR * ctr )
2004-08-10 18:27:17 +04:00
{
WERROR result ;
/* enumprinterdataex call */
2005-09-30 21:13:37 +04:00
result = rpccli_spoolss_enumprinterdataex ( pipe_hnd , mem_ctx , hnd , keyname , ctr ) ;
2004-08-10 18:27:17 +04:00
if ( ! W_ERROR_IS_OK ( result ) ) {
printf ( " enumprinterdataex failed: %s \n " , dos_errstr ( result ) ) ;
return False ;
}
return True ;
}
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 ,
POLICY_HND * hnd ,
char * keyname ,
REGISTRY_VALUE * value )
2004-08-10 18:27:17 +04:00
{
WERROR result ;
/* setprinterdataex call */
2005-09-30 21:13:37 +04:00
result = rpccli_spoolss_setprinterdataex ( pipe_hnd , mem_ctx , hnd ,
2004-08-10 18:27:17 +04:00
keyname , value ) ;
if ( ! W_ERROR_IS_OK ( result ) ) {
printf ( " could not set printerdataex: %s \n " , dos_errstr ( result ) ) ;
return False ;
}
return True ;
}
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 ,
POLICY_HND * hnd ,
int level ,
uint32 * num_forms ,
FORM_1 * * forms )
2004-08-10 18:27:17 +04:00
{
WERROR result ;
/* enumforms call */
2005-09-30 21:13:37 +04:00
result = rpccli_spoolss_enumforms ( pipe_hnd , mem_ctx , hnd , level , num_forms , forms ) ;
2004-08-10 18:27:17 +04:00
if ( ! W_ERROR_IS_OK ( result ) ) {
printf ( " could not enum forms: %s \n " , dos_errstr ( result ) ) ;
return False ;
}
return True ;
}
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 ,
uint32 level , const char * env ,
uint32 * num_drivers ,
PRINTER_DRIVER_CTR * ctr )
2004-08-10 18:27:17 +04:00
{
WERROR result ;
/* enumprinterdrivers call */
2005-09-30 21:13:37 +04:00
result = rpccli_spoolss_enumprinterdrivers (
pipe_hnd , mem_ctx , level ,
2004-08-10 18:27:17 +04:00
env , num_drivers , ctr ) ;
if ( ! W_ERROR_IS_OK ( result ) ) {
printf ( " cannot enum drivers: %s \n " , dos_errstr ( result ) ) ;
return False ;
}
return True ;
}
2007-10-19 04:40:25 +04:00
static bool net_spoolss_getprinterdriver ( struct rpc_pipe_client * pipe_hnd ,
2004-08-10 18:27:17 +04:00
TALLOC_CTX * mem_ctx ,
POLICY_HND * hnd , uint32 level ,
const char * env , int version ,
PRINTER_DRIVER_CTR * ctr )
{
WERROR result ;
/* getprinterdriver call */
2005-09-30 21:13:37 +04:00
result = rpccli_spoolss_getprinterdriver (
pipe_hnd , mem_ctx , hnd , level ,
2004-08-10 18:27:17 +04:00
env , version , ctr ) ;
if ( ! W_ERROR_IS_OK ( result ) ) {
DEBUG ( 1 , ( " cannot get driver (for architecture: %s): %s \n " ,
env , dos_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 ) ) {
2004-08-10 18:27:17 +04:00
printf ( " cannot get driver: %s \n " , dos_errstr ( result ) ) ;
}
return False ;
}
return True ;
}
2007-10-19 04:40:25 +04:00
static bool net_spoolss_addprinterdriver ( struct rpc_pipe_client * pipe_hnd ,
2004-08-10 18:27:17 +04:00
TALLOC_CTX * mem_ctx , uint32 level ,
PRINTER_DRIVER_CTR * ctr )
{
WERROR result ;
/* addprinterdriver call */
2005-09-30 21:13:37 +04:00
result = rpccli_spoolss_addprinterdriver ( pipe_hnd , mem_ctx , level , ctr ) ;
2004-08-10 18:27:17 +04:00
/* be more verbose */
if ( W_ERROR_V ( result ) = = W_ERROR_V ( WERR_ACCESS_DENIED ) ) {
printf ( " You are not allowed to add drivers \n " ) ;
return False ;
}
if ( ! W_ERROR_IS_OK ( result ) ) {
printf ( " cannot add driver: %s \n " , dos_errstr ( result ) ) ;
return False ;
}
return True ;
}
/**
* abstraction function to get uint32 num_printers and PRINTER_INFO_CTR ctr
* for a single printer or for all printers depending on argc / argv
* */
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 ,
2005-09-30 21:13:37 +04:00
TALLOC_CTX * mem_ctx ,
int level ,
int argc ,
const char * * argv ,
uint32 * num_printers ,
PRINTER_INFO_CTR * ctr )
2004-08-10 18:27:17 +04:00
{
POLICY_HND hnd ;
/* no arguments given, enumerate all printers */
if ( argc = = 0 ) {
2005-09-30 21:13:37 +04:00
if ( ! net_spoolss_enum_printers ( pipe_hnd , mem_ctx , NULL ,
2004-08-10 18:27:17 +04:00
PRINTER_ENUM_LOCAL | PRINTER_ENUM_SHARED ,
level , num_printers , ctr ) )
return False ;
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 ] ,
MAXIMUM_ALLOWED_ACCESS , pipe_hnd - > cli - > user_name , & hnd ) )
2004-08-10 18:27:17 +04:00
return False ;
2005-09-30 21:13:37 +04:00
if ( ! net_spoolss_getprinter ( pipe_hnd , mem_ctx , & hnd , level , ctr ) ) {
rpccli_spoolss_close_printer ( pipe_hnd , mem_ctx , & hnd ) ;
2004-08-10 18:27:17 +04:00
return False ;
}
2005-09-30 21:13:37 +04:00
rpccli_spoolss_close_printer ( pipe_hnd , mem_ctx , & hnd ) ;
2004-08-10 18:27:17 +04:00
* num_printers = 1 ;
out :
DEBUG ( 3 , ( " got %d printers \n " , * num_printers ) ) ;
return True ;
}
/**
* List print - queues ( including local printers that are not shared )
*
* All parameters are provided by the run_rpc_command function , except for
* argc , argv which are passed through .
*
* @ 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
NTSTATUS rpc_printer_list_internals ( const DOM_SID * domain_sid ,
const char * domain_name ,
struct cli_state * cli ,
struct rpc_pipe_client * pipe_hnd ,
TALLOC_CTX * mem_ctx ,
int argc ,
const char * * argv )
2004-08-10 18:27:17 +04:00
{
NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL ;
uint32 i , num_printers ;
uint32 level = 2 ;
2007-12-05 02:45:20 +03:00
char * printername , * sharename ;
2004-08-10 18:27:17 +04:00
PRINTER_INFO_CTR ctr ;
printf ( " listing printers \n " ) ;
2005-09-30 21:13:37 +04:00
if ( ! get_printer_info ( pipe_hnd , mem_ctx , level , argc , argv , & num_printers , & ctr ) )
2004-08-10 18:27:17 +04:00
return nt_status ;
for ( i = 0 ; i < num_printers ; i + + ) {
/* do some initialization */
2007-12-05 02:45:20 +03:00
rpcstr_pull_talloc ( mem_ctx ,
& printername ,
ctr . printers_2 [ i ] . printername . buffer ,
- 1 ,
STR_TERMINATE ) ;
rpcstr_pull_talloc ( mem_ctx ,
& sharename ,
ctr . printers_2 [ i ] . sharename . buffer ,
- 1 ,
STR_TERMINATE ) ;
if ( printername & & sharename ) {
d_printf ( " printer %d: %s, shared as: %s \n " ,
i + 1 , printername , sharename ) ;
}
2004-08-10 18:27:17 +04:00
}
return NT_STATUS_OK ;
}
/**
* List printer - drivers from a server
*
* All parameters are provided by the run_rpc_command function , except for
* argc , argv which are passed through .
*
* @ 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
NTSTATUS rpc_printer_driver_list_internals ( const DOM_SID * domain_sid ,
const char * domain_name ,
struct cli_state * cli ,
struct rpc_pipe_client * pipe_hnd ,
TALLOC_CTX * mem_ctx ,
int argc ,
const char * * argv )
2004-08-10 18:27:17 +04:00
{
NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL ;
uint32 i ;
uint32 level = 3 ;
PRINTER_DRIVER_CTR drv_ctr_enum ;
int d ;
ZERO_STRUCT ( drv_ctr_enum ) ;
printf ( " listing printer-drivers \n " ) ;
for ( i = 0 ; archi_table [ i ] . long_archi ! = NULL ; i + + ) {
2005-06-15 17:01:19 +04:00
uint32 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 ,
2004-08-10 18:27:17 +04:00
archi_table [ i ] . long_archi ,
& num_drivers , & drv_ctr_enum ) ) {
nt_status = NT_STATUS_UNSUCCESSFUL ;
goto done ;
}
if ( num_drivers = = 0 ) {
d_printf ( " no drivers found on server for architecture: [%s]. \n " ,
archi_table [ i ] . long_archi ) ;
continue ;
}
d_printf ( " got %d printer-drivers for architecture: [%s] \n " ,
num_drivers , archi_table [ i ] . long_archi ) ;
/* do something for all drivers for architecture */
for ( d = 0 ; d < num_drivers ; d + + ) {
display_print_driver_3 ( & ( drv_ctr_enum . info3 [ d ] ) ) ;
}
}
nt_status = NT_STATUS_OK ;
done :
return nt_status ;
}
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 ,
TALLOC_CTX * mem_ctx ,
int argc ,
const char * * argv ,
uint32 action )
2004-10-13 05:40:35 +04:00
{
NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL ;
uint32 i , num_printers ;
uint32 level = 7 ;
2007-12-05 02:45:20 +03:00
char * printername , * sharename ;
2004-10-13 05:40:35 +04:00
PRINTER_INFO_CTR ctr , ctr_pub ;
POLICY_HND hnd ;
2007-10-19 04:40:25 +04:00
bool got_hnd = False ;
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
2005-09-30 21:13:37 +04:00
if ( ! get_printer_info ( pipe_hnd , mem_ctx , 2 , argc , argv , & num_printers , & ctr ) )
2004-10-13 05:40:35 +04:00
return nt_status ;
for ( i = 0 ; i < num_printers ; i + + ) {
/* do some initialization */
2007-12-05 02:45:20 +03:00
rpcstr_pull_talloc ( mem_ctx ,
& printername ,
ctr . printers_2 [ i ] . printername . buffer ,
- 1 ,
STR_TERMINATE ) ;
rpcstr_pull_talloc ( mem_ctx ,
& sharename ,
ctr . printers_2 [ i ] . sharename . buffer ,
- 1 ,
STR_TERMINATE ) ;
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 ,
PRINTER_ALL_ACCESS , pipe_hnd - > cli - > user_name , & hnd ) )
2004-10-13 05:40:35 +04:00
goto done ;
got_hnd = True ;
/* check for existing dst printer */
2005-09-30 21:13:37 +04:00
if ( ! net_spoolss_getprinter ( pipe_hnd , mem_ctx , & hnd , level , & ctr_pub ) )
2004-10-13 05:40:35 +04:00
goto done ;
/* check action and set string */
switch ( action ) {
case SPOOL_DS_PUBLISH :
action_str = " published " ;
break ;
case SPOOL_DS_UPDATE :
action_str = " updated " ;
break ;
case SPOOL_DS_UNPUBLISH :
action_str = " unpublished " ;
break ;
default :
2004-11-19 22:45:03 +03:00
action_str = " unknown action " ;
2004-10-13 05:40:35 +04:00
printf ( " unkown action: %d \n " , action ) ;
break ;
}
ctr_pub . printers_7 - > action = action ;
2005-09-30 21:13:37 +04:00
result = rpccli_spoolss_setprinter ( pipe_hnd , mem_ctx , & hnd , level , & ctr_pub , 0 ) ;
2005-07-19 13:37:42 +04:00
if ( ! W_ERROR_IS_OK ( result ) & & ( W_ERROR_V ( result ) ! = W_ERROR_V ( WERR_IO_PENDING ) ) ) {
2004-10-13 05:40:35 +04:00
printf ( " cannot set printer-info: %s \n " , dos_errstr ( result ) ) ;
goto done ;
}
printf ( " successfully %s printer %s in Active Directory \n " , action_str , sharename ) ;
}
nt_status = NT_STATUS_OK ;
done :
if ( got_hnd )
2005-09-30 21:13:37 +04:00
rpccli_spoolss_close_printer ( pipe_hnd , mem_ctx , & hnd ) ;
2004-10-13 05:40:35 +04:00
return nt_status ;
}
2005-09-30 21:13:37 +04:00
NTSTATUS rpc_printer_publish_publish_internals ( const DOM_SID * domain_sid ,
const char * domain_name ,
struct cli_state * cli ,
struct rpc_pipe_client * pipe_hnd ,
TALLOC_CTX * mem_ctx ,
int argc ,
const char * * argv )
2004-10-13 05:40:35 +04:00
{
2005-09-30 21:13:37 +04:00
return rpc_printer_publish_internals_args ( pipe_hnd , mem_ctx , argc , argv , SPOOL_DS_PUBLISH ) ;
2004-10-13 05:40:35 +04:00
}
2005-09-30 21:13:37 +04:00
NTSTATUS rpc_printer_publish_unpublish_internals ( const DOM_SID * domain_sid ,
const char * domain_name ,
struct cli_state * cli ,
struct rpc_pipe_client * pipe_hnd ,
TALLOC_CTX * mem_ctx ,
int argc ,
const char * * argv )
2004-10-13 05:40:35 +04:00
{
2005-09-30 21:13:37 +04:00
return rpc_printer_publish_internals_args ( pipe_hnd , mem_ctx , argc , argv , SPOOL_DS_UNPUBLISH ) ;
2004-10-13 05:40:35 +04:00
}
2005-09-30 21:13:37 +04:00
NTSTATUS rpc_printer_publish_update_internals ( const DOM_SID * domain_sid ,
const char * domain_name ,
struct cli_state * cli ,
struct rpc_pipe_client * pipe_hnd ,
TALLOC_CTX * mem_ctx ,
int argc ,
const char * * argv )
2004-10-13 05:40:35 +04:00
{
2005-09-30 21:13:37 +04:00
return rpc_printer_publish_internals_args ( pipe_hnd , mem_ctx , argc , argv , SPOOL_DS_UPDATE ) ;
2004-10-13 05:40:35 +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
* argc , argv which are passed through .
*
* @ 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
NTSTATUS rpc_printer_publish_list_internals ( const DOM_SID * domain_sid ,
const char * domain_name ,
struct cli_state * cli ,
struct rpc_pipe_client * pipe_hnd ,
TALLOC_CTX * mem_ctx ,
int argc ,
const char * * argv )
2004-10-13 05:40:35 +04:00
{
NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL ;
uint32 i , num_printers ;
uint32 level = 7 ;
2007-12-05 02:45:20 +03:00
char * printername , * sharename ;
char * guid ;
2004-10-13 05:40:35 +04:00
PRINTER_INFO_CTR ctr , ctr_pub ;
POLICY_HND hnd ;
2007-10-19 04:40:25 +04:00
bool got_hnd = False ;
2004-10-13 05:40:35 +04:00
int state ;
2005-09-30 21:13:37 +04:00
if ( ! get_printer_info ( pipe_hnd , mem_ctx , 2 , argc , argv , & num_printers , & ctr ) )
2004-10-13 05:40:35 +04:00
return nt_status ;
for ( i = 0 ; i < num_printers ; i + + ) {
ZERO_STRUCT ( ctr_pub ) ;
/* do some initialization */
2007-12-05 02:45:20 +03:00
rpcstr_pull_talloc ( mem_ctx ,
& printername ,
ctr . printers_2 [ i ] . printername . buffer ,
- 1 ,
STR_TERMINATE ) ;
rpcstr_pull_talloc ( mem_ctx ,
& sharename ,
ctr . printers_2 [ i ] . sharename . buffer ,
- 1 ,
STR_TERMINATE ) ;
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 ,
2004-10-13 05:40:35 +04:00
PRINTER_ALL_ACCESS , cli - > user_name , & hnd ) )
goto done ;
got_hnd = True ;
/* check for existing dst printer */
2005-09-30 21:13:37 +04:00
if ( ! net_spoolss_getprinter ( pipe_hnd , mem_ctx , & hnd , level , & ctr_pub ) )
2004-10-13 05:40:35 +04:00
goto done ;
2007-12-05 02:45:20 +03:00
rpcstr_pull_talloc ( mem_ctx ,
& guid ,
ctr_pub . printers_7 - > guid . buffer ,
- 1 ,
STR_TERMINATE ) ;
if ( ! guid ) {
goto done ;
}
2004-10-13 05:40:35 +04:00
state = ctr_pub . printers_7 - > action ;
switch ( state ) {
case SPOOL_DS_PUBLISH :
printf ( " printer [%s] is published " , sharename ) ;
if ( opt_verbose )
printf ( " , guid: %s " , guid ) ;
printf ( " \n " ) ;
break ;
case SPOOL_DS_UNPUBLISH :
printf ( " printer [%s] is unpublished \n " , sharename ) ;
break ;
case SPOOL_DS_UPDATE :
printf ( " printer [%s] is currently updating \n " , sharename ) ;
break ;
default :
printf ( " unkown state: %d \n " , state ) ;
break ;
}
}
nt_status = NT_STATUS_OK ;
done :
if ( got_hnd )
2005-09-30 21:13:37 +04:00
rpccli_spoolss_close_printer ( pipe_hnd , mem_ctx , & hnd ) ;
2004-10-13 05:40:35 +04:00
return nt_status ;
}
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
* argc , argv which are passed through .
*
* @ 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
NTSTATUS rpc_printer_migrate_security_internals ( const DOM_SID * domain_sid ,
const char * domain_name ,
struct cli_state * cli ,
struct rpc_pipe_client * pipe_hnd ,
TALLOC_CTX * mem_ctx ,
int argc ,
const char * * argv )
2004-08-10 18:27:17 +04:00
{
/* TODO: what now, info2 or info3 ?
convince jerry that we should add clientside setacls level 3 at least
*/
NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL ;
uint32 i = 0 ;
uint32 num_printers ;
uint32 level = 2 ;
2007-12-05 02:45:20 +03:00
char * printername , * sharename ;
2007-10-19 04:40:25 +04:00
bool got_hnd_src = False ;
bool got_hnd_dst = False ;
2005-09-30 21:13:37 +04:00
struct rpc_pipe_client * pipe_hnd_dst = NULL ;
2004-08-10 18:27:17 +04:00
POLICY_HND hnd_src , hnd_dst ;
PRINTER_INFO_CTR ctr_src , ctr_dst , ctr_enum ;
struct cli_state * cli_dst = NULL ;
ZERO_STRUCT ( ctr_src ) ;
DEBUG ( 3 , ( " copying printer ACLs \n " ) ) ;
2004-08-27 01:37:20 +04:00
/* connect destination PI_SPOOLSS */
2005-09-30 21:13:37 +04:00
nt_status = connect_dst_pipe ( & cli_dst , & pipe_hnd_dst , PI_SPOOLSS ) ;
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 */
2005-09-30 21:13:37 +04:00
if ( ! get_printer_info ( pipe_hnd , mem_ctx , level , argc , argv , & num_printers , & ctr_enum ) ) {
2004-08-10 18:27:17 +04:00
nt_status = NT_STATUS_UNSUCCESSFUL ;
goto done ;
}
if ( ! num_printers ) {
printf ( " no printers found on server. \n " ) ;
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 + + ) {
/* do some initialization */
2007-12-05 02:45:20 +03:00
rpcstr_pull_talloc ( mem_ctx ,
& printername ,
ctr_enum . printers_2 [ i ] . printername . buffer ,
- 1 ,
STR_TERMINATE ) ;
rpcstr_pull_talloc ( mem_ctx ,
& sharename ,
ctr_enum . printers_2 [ i ] . sharename . buffer ,
- 1 ,
STR_TERMINATE ) ;
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
2004-08-10 18:27:17 +04:00
d_printf ( " migrating printer ACLs for: [%s] / [%s] \n " ,
printername , sharename ) ;
/* according to msdn you have specify these access-rights
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 ,
2004-10-07 15:01:13 +04:00
MAXIMUM_ALLOWED_ACCESS , cli - > user_name , & hnd_src ) )
2004-08-10 18:27:17 +04:00
goto done ;
got_hnd_src = True ;
/* open dst printer handle */
2005-09-30 21:13:37 +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_dst - > user_name , & hnd_dst ) )
2004-08-10 18:27:17 +04:00
goto done ;
got_hnd_dst = True ;
/* check for existing dst printer */
2005-09-30 21:13:37 +04:00
if ( ! net_spoolss_getprinter ( pipe_hnd_dst , mem_ctx , & hnd_dst , level , & ctr_dst ) )
2004-08-10 18:27:17 +04:00
goto done ;
/* check for existing src printer */
2005-09-30 21:13:37 +04:00
if ( ! net_spoolss_getprinter ( pipe_hnd , mem_ctx , & hnd_src , 3 , & ctr_src ) )
2004-08-10 18:27:17 +04:00
goto done ;
/* Copy Security Descriptor */
/* copy secdesc (info level 2) */
ctr_dst . printers_2 - > devmode = NULL ;
ctr_dst . printers_2 - > secdesc = dup_sec_desc ( mem_ctx , ctr_src . printers_3 - > secdesc ) ;
if ( opt_verbose )
display_sec_desc ( ctr_dst . printers_2 - > secdesc ) ;
2005-09-30 21:13:37 +04:00
if ( ! net_spoolss_setprinter ( pipe_hnd_dst , mem_ctx , & hnd_dst , 2 , & ctr_dst ) )
2004-08-10 18:27:17 +04:00
goto done ;
DEBUGADD ( 1 , ( " \t SetPrinter of SECDESC succeeded \n " ) ) ;
/* close printer handles here */
if ( got_hnd_src ) {
2005-09-30 21:13:37 +04:00
rpccli_spoolss_close_printer ( pipe_hnd , mem_ctx , & hnd_src ) ;
2004-08-10 18:27:17 +04:00
got_hnd_src = False ;
}
if ( got_hnd_dst ) {
2005-09-30 21:13:37 +04:00
rpccli_spoolss_close_printer ( pipe_hnd_dst , mem_ctx , & hnd_dst ) ;
2004-08-10 18:27:17 +04:00
got_hnd_dst = False ;
}
}
nt_status = NT_STATUS_OK ;
done :
2005-09-30 21:13:37 +04:00
if ( got_hnd_src ) {
rpccli_spoolss_close_printer ( pipe_hnd , mem_ctx , & hnd_src ) ;
}
2004-08-10 18:27:17 +04:00
2005-09-30 21:13:37 +04:00
if ( got_hnd_dst ) {
rpccli_spoolss_close_printer ( pipe_hnd_dst , mem_ctx , & hnd_dst ) ;
}
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 ;
}
/**
* Migrate printer - forms from a src server to the dst server
*
* All parameters are provided by the run_rpc_command function , except for
* argc , argv which are passed through .
*
* @ 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
NTSTATUS rpc_printer_migrate_forms_internals ( const DOM_SID * domain_sid ,
const char * domain_name ,
struct cli_state * cli ,
struct rpc_pipe_client * pipe_hnd ,
TALLOC_CTX * mem_ctx ,
int argc ,
const char * * argv )
2004-08-10 18:27:17 +04:00
{
NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL ;
WERROR result ;
uint32 i , f ;
uint32 num_printers ;
uint32 level = 1 ;
2007-12-05 02:45:20 +03:00
char * printername , * sharename ;
2007-10-19 04:40:25 +04:00
bool got_hnd_src = False ;
bool got_hnd_dst = False ;
2005-09-30 21:13:37 +04:00
struct rpc_pipe_client * pipe_hnd_dst = NULL ;
2004-08-10 18:27:17 +04:00
POLICY_HND hnd_src , hnd_dst ;
PRINTER_INFO_CTR ctr_enum , ctr_dst ;
uint32 num_forms ;
FORM_1 * forms ;
struct cli_state * cli_dst = NULL ;
2007-12-05 02:45:20 +03:00
2004-08-10 18:27:17 +04:00
ZERO_STRUCT ( ctr_enum ) ;
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 */
2005-09-30 21:13:37 +04:00
nt_status = connect_dst_pipe ( & cli_dst , & pipe_hnd_dst , PI_SPOOLSS ) ;
2004-08-10 18:27:17 +04:00
if ( ! NT_STATUS_IS_OK ( nt_status ) )
return nt_status ;
/* enum src printers */
2005-09-30 21:13:37 +04:00
if ( ! get_printer_info ( pipe_hnd , mem_ctx , 2 , argc , argv , & num_printers , & ctr_enum ) ) {
2004-08-10 18:27:17 +04:00
nt_status = NT_STATUS_UNSUCCESSFUL ;
goto done ;
}
if ( ! num_printers ) {
printf ( " no printers found on server. \n " ) ;
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 + + ) {
/* do some initialization */
2007-12-05 02:45:20 +03:00
rpcstr_pull_talloc ( mem_ctx ,
& printername ,
ctr_enum . printers_2 [ i ] . printername . buffer ,
- 1 ,
STR_TERMINATE ) ;
rpcstr_pull_talloc ( mem_ctx ,
& sharename ,
ctr_enum . printers_2 [ i ] . sharename . buffer ,
- 1 ,
STR_TERMINATE ) ;
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
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 ,
2004-10-07 15:01:13 +04:00
MAXIMUM_ALLOWED_ACCESS , cli - > user_name , & hnd_src ) )
2004-08-10 18:27:17 +04:00
goto done ;
got_hnd_src = True ;
/* open dst printer handle */
2005-09-30 21:13:37 +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 ) )
2004-08-10 18:27:17 +04:00
goto done ;
got_hnd_dst = True ;
/* check for existing dst printer */
2005-09-30 21:13:37 +04:00
if ( ! net_spoolss_getprinter ( pipe_hnd_dst , mem_ctx , & hnd_dst , level , & ctr_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 + + ) {
FORM form ;
fstring form_name ;
/* only migrate FORM_PRINTER types, according to jerry
FORM_BUILTIN - types are hard - coded in samba */
if ( forms [ f ] . flag ! = FORM_PRINTER )
continue ;
if ( forms [ f ] . name . buffer )
rpcstr_pull ( form_name , forms [ f ] . name . buffer ,
sizeof ( form_name ) , - 1 , STR_TERMINATE ) ;
if ( opt_verbose )
d_printf ( " \t migrating form # %d [%s] of type [%d] \n " ,
f , form_name , forms [ f ] . flag ) ;
/* is there a more elegant way to do that ? */
form . flags = FORM_PRINTER ;
form . size_x = forms [ f ] . width ;
form . size_y = forms [ f ] . length ;
form . left = forms [ f ] . left ;
form . top = forms [ f ] . top ;
form . right = forms [ f ] . right ;
form . bottom = forms [ f ] . bottom ;
init_unistr2 ( & form . name , form_name , UNI_STR_TERMINATE ) ;
/* FIXME: there might be something wrong with samba's
builtin - forms */
2005-09-30 21:13:37 +04:00
result = rpccli_spoolss_addform ( pipe_hnd_dst , mem_ctx ,
2004-08-10 18:27:17 +04:00
& hnd_dst , 1 , & form ) ;
if ( ! W_ERROR_IS_OK ( result ) ) {
d_printf ( " \t AddForm form %d: [%s] refused. \n " ,
f , form_name ) ;
continue ;
}
DEBUGADD ( 1 , ( " \t AddForm of [%s] succeeded \n " , form_name ) ) ;
}
/* close printer handles here */
if ( got_hnd_src ) {
2005-09-30 21:13:37 +04:00
rpccli_spoolss_close_printer ( pipe_hnd , mem_ctx , & hnd_src ) ;
2004-08-10 18:27:17 +04:00
got_hnd_src = False ;
}
if ( got_hnd_dst ) {
2005-09-30 21:13:37 +04:00
rpccli_spoolss_close_printer ( pipe_hnd_dst , mem_ctx , & hnd_dst ) ;
2004-08-10 18:27:17 +04:00
got_hnd_dst = False ;
}
}
nt_status = NT_STATUS_OK ;
done :
if ( got_hnd_src )
2005-09-30 21:13:37 +04:00
rpccli_spoolss_close_printer ( pipe_hnd , mem_ctx , & hnd_src ) ;
2004-08-10 18:27:17 +04:00
if ( got_hnd_dst )
2005-09-30 21:13:37 +04:00
rpccli_spoolss_close_printer ( pipe_hnd_dst , mem_ctx , & hnd_dst ) ;
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 ;
}
/**
* Migrate printer - drivers from a src server to the dst server
*
* All parameters are provided by the run_rpc_command function , except for
* argc , argv which are passed through .
*
* @ 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
NTSTATUS rpc_printer_migrate_drivers_internals ( const DOM_SID * domain_sid ,
const char * domain_name ,
struct cli_state * cli ,
struct rpc_pipe_client * pipe_hnd ,
TALLOC_CTX * mem_ctx ,
int argc ,
const char * * argv )
2004-08-10 18:27:17 +04:00
{
NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL ;
uint32 i , p ;
uint32 num_printers ;
2007-10-25 01:16:54 +04:00
uint32 level = 3 ;
2007-12-05 02:45:20 +03:00
char * printername , * sharename ;
2007-10-19 04:40:25 +04:00
bool got_hnd_src = False ;
bool got_hnd_dst = False ;
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 ;
2004-08-10 18:27:17 +04:00
POLICY_HND hnd_src , hnd_dst ;
PRINTER_DRIVER_CTR drv_ctr_src , drv_ctr_dst ;
PRINTER_INFO_CTR info_ctr_enum , info_ctr_dst ;
struct cli_state * cli_dst = NULL ;
struct cli_state * cli_share_src = NULL ;
struct cli_state * cli_share_dst = NULL ;
fstring drivername = " " ;
2007-10-25 01:16:54 +04:00
2004-08-10 18:27:17 +04:00
ZERO_STRUCT ( drv_ctr_src ) ;
ZERO_STRUCT ( drv_ctr_dst ) ;
ZERO_STRUCT ( info_ctr_enum ) ;
ZERO_STRUCT ( info_ctr_dst ) ;
DEBUG ( 3 , ( " copying printer-drivers \n " ) ) ;
2005-09-30 21:13:37 +04:00
nt_status = connect_dst_pipe ( & cli_dst , & pipe_hnd_dst , PI_SPOOLSS ) ;
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 */
2007-10-25 01:16:54 +04:00
nt_status = connect_to_service ( & 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
got_src_driver_share = True ;
/* open print$-share on the dst server */
2007-10-25 01:16:54 +04:00
nt_status = connect_to_service ( & 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 ;
got_dst_driver_share = True ;
/* enum src printers */
2005-09-30 21:13:37 +04:00
if ( ! get_printer_info ( pipe_hnd , mem_ctx , 2 , argc , argv , & num_printers , & info_ctr_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 ) {
2004-08-10 18:27:17 +04:00
printf ( " no printers found on server. \n " ) ;
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 + + ) {
/* do some initialization */
2007-12-05 02:45:20 +03:00
rpcstr_pull_talloc ( mem_ctx ,
& printername ,
info_ctr_enum . printers_2 [ p ] . printername . buffer ,
- 1 ,
STR_TERMINATE ) ;
rpcstr_pull_talloc ( mem_ctx ,
& sharename ,
info_ctr_enum . printers_2 [ p ] . sharename . buffer ,
- 1 ,
STR_TERMINATE ) ;
if ( ! printername | | ! sharename ) {
nt_status = NT_STATUS_UNSUCCESSFUL ;
goto done ;
}
2004-08-10 18:27:17 +04:00
/* we can reset NT_STATUS here because we do not
get any real NT_STATUS - codes anymore from now on */
nt_status = NT_STATUS_UNSUCCESSFUL ;
d_printf ( " migrating printer driver for: [%s] / [%s] \n " ,
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 ,
2004-10-07 15:01:13 +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
got_hnd_dst = True ;
/* check for existing dst printer */
2005-09-30 21:13:37 +04:00
if ( ! net_spoolss_getprinter ( pipe_hnd_dst , mem_ctx , & hnd_dst , 2 , & info_ctr_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 ,
MAXIMUM_ALLOWED_ACCESS , pipe_hnd - > cli - > user_name , & hnd_src ) )
2004-08-10 18:27:17 +04:00
goto done ;
got_hnd_src = True ;
/* in a first step call getdriver for each shared printer (per arch)
to get a list of all files that have to be copied */
for ( i = 0 ; archi_table [ i ] . long_archi ! = NULL ; i + + ) {
/* getdriver src */
2005-09-30 21:13:37 +04:00
if ( ! net_spoolss_getprinterdriver ( pipe_hnd , mem_ctx , & hnd_src ,
2004-08-10 18:27:17 +04:00
level , archi_table [ i ] . long_archi ,
archi_table [ i ] . version , & drv_ctr_src ) )
continue ;
rpcstr_pull ( drivername , drv_ctr_src . info3 - > name . buffer ,
sizeof ( drivername ) , - 1 , STR_TERMINATE ) ;
if ( opt_verbose )
display_print_driver_3 ( drv_ctr_src . info3 ) ;
/* 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 */
nt_status = copy_print_driver_3 ( mem_ctx , cli_share_src , cli_share_dst ,
archi_table [ i ] . short_archi ,
drv_ctr_src . info3 ) ;
if ( ! NT_STATUS_IS_OK ( nt_status ) )
goto done ;
/* adddriver dst */
2005-09-30 21:13:37 +04:00
if ( ! net_spoolss_addprinterdriver ( pipe_hnd_dst , mem_ctx , level , & drv_ctr_src ) ) {
2004-08-10 18:27:17 +04:00
nt_status = NT_STATUS_UNSUCCESSFUL ;
goto done ;
}
DEBUGADD ( 1 , ( " Sucessfully added driver [%s] for printer [%s] \n " ,
drivername , printername ) ) ;
}
2005-04-26 16:26:32 +04:00
if ( strlen ( drivername ) = = 0 ) {
DEBUGADD ( 1 , ( " Did not get driver for printer %s \n " ,
printername ) ) ;
goto done ;
}
2004-08-10 18:27:17 +04:00
/* setdriver dst */
init_unistr ( & info_ctr_dst . printers_2 - > drivername , drivername ) ;
2005-09-30 21:13:37 +04:00
if ( ! net_spoolss_setprinter ( pipe_hnd_dst , mem_ctx , & hnd_dst , 2 , & info_ctr_dst ) ) {
2004-08-10 18:27:17 +04:00
nt_status = NT_STATUS_UNSUCCESSFUL ;
goto done ;
}
DEBUGADD ( 1 , ( " Sucessfully set driver %s for printer %s \n " ,
drivername , printername ) ) ;
/* close dst */
if ( got_hnd_dst ) {
2005-09-30 21:13:37 +04:00
rpccli_spoolss_close_printer ( pipe_hnd_dst , mem_ctx , & hnd_dst ) ;
2004-08-10 18:27:17 +04:00
got_hnd_dst = False ;
}
/* close src */
if ( got_hnd_src ) {
2005-09-30 21:13:37 +04:00
rpccli_spoolss_close_printer ( pipe_hnd , mem_ctx , & hnd_src ) ;
2004-08-10 18:27:17 +04:00
got_hnd_src = False ;
}
}
nt_status = NT_STATUS_OK ;
done :
if ( got_hnd_src )
2005-09-30 21:13:37 +04:00
rpccli_spoolss_close_printer ( pipe_hnd , mem_ctx , & hnd_src ) ;
2004-08-10 18:27:17 +04:00
if ( got_hnd_dst )
2005-09-30 21:13:37 +04:00
rpccli_spoolss_close_printer ( pipe_hnd_dst , mem_ctx , & hnd_dst ) ;
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 ;
}
/**
* 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
* argc , argv which are passed through .
*
* @ 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
NTSTATUS rpc_printer_migrate_printers_internals ( const DOM_SID * domain_sid ,
const char * domain_name ,
struct cli_state * cli ,
struct rpc_pipe_client * pipe_hnd ,
TALLOC_CTX * mem_ctx ,
int argc ,
const char * * argv )
2004-08-10 18:27:17 +04:00
{
WERROR result ;
NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL ;
uint32 i = 0 , num_printers ;
uint32 level = 2 ;
PRINTER_INFO_CTR ctr_src , ctr_dst , ctr_enum ;
struct cli_state * cli_dst = NULL ;
POLICY_HND hnd_dst , hnd_src ;
2007-12-05 02:45:20 +03:00
char * printername , * sharename ;
2007-10-19 04:40:25 +04:00
bool got_hnd_src = False ;
bool got_hnd_dst = False ;
2005-09-30 21:13:37 +04:00
struct rpc_pipe_client * pipe_hnd_dst = NULL ;
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 */
2005-09-30 21:13:37 +04:00
nt_status = connect_dst_pipe ( & cli_dst , & pipe_hnd_dst , PI_SPOOLSS ) ;
2004-08-10 18:27:17 +04:00
if ( ! NT_STATUS_IS_OK ( nt_status ) )
return nt_status ;
/* enum printers */
2005-09-30 21:13:37 +04:00
if ( ! get_printer_info ( pipe_hnd , mem_ctx , level , argc , argv , & num_printers , & ctr_enum ) ) {
2004-08-10 18:27:17 +04:00
nt_status = NT_STATUS_UNSUCCESSFUL ;
goto done ;
}
if ( ! num_printers ) {
printf ( " no printers found on server. \n " ) ;
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 + + ) {
/* do some initialization */
2007-12-05 02:45:20 +03:00
rpcstr_pull_talloc ( mem_ctx ,
& printername ,
ctr_enum . printers_2 [ i ] . printername . buffer ,
- 1 ,
STR_TERMINATE ) ;
rpcstr_pull_talloc ( mem_ctx ,
& sharename ,
ctr_enum . printers_2 [ i ] . sharename . buffer ,
- 1 ,
STR_TERMINATE ) ;
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
2004-08-10 18:27:17 +04:00
d_printf ( " migrating printer queue for: [%s] / [%s] \n " ,
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 ,
2004-10-07 15:01:13 +04:00
PRINTER_ALL_ACCESS , cli - > user_name , & hnd_dst ) ) {
2004-08-10 18:27:17 +04:00
DEBUG ( 1 , ( " could not open printer: %s \n " , sharename ) ) ;
} else {
got_hnd_dst = True ;
}
/* check for existing dst printer */
2005-09-30 21:13:37 +04:00
if ( ! net_spoolss_getprinter ( pipe_hnd_dst , mem_ctx , & hnd_dst , level , & ctr_dst ) ) {
2004-08-10 18:27:17 +04:00
printf ( " could not get printer, creating printer. \n " ) ;
} 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. */
2004-08-10 18:27:17 +04:00
if ( got_hnd_dst ) {
2005-09-30 21:13:37 +04:00
rpccli_spoolss_close_printer ( pipe_hnd_dst , mem_ctx , & hnd_dst ) ;
2004-08-10 18:27:17 +04:00
got_hnd_dst = False ;
}
continue ;
}
/* now get again src printer ctr via getprinter,
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 ,
2004-10-07 15:01:13 +04:00
MAXIMUM_ALLOWED_ACCESS , cli - > user_name , & hnd_src ) )
2004-08-10 18:27:17 +04:00
goto done ;
got_hnd_src = True ;
/* getprinter on the src server */
2005-09-30 21:13:37 +04:00
if ( ! net_spoolss_getprinter ( pipe_hnd , mem_ctx , & hnd_src , level , & ctr_src ) )
2004-08-10 18:27:17 +04:00
goto done ;
/* copy each src printer to a dst printer 1:1,
maybe some values have to be changed though */
d_printf ( " creating printer: %s \n " , printername ) ;
2005-09-30 21:13:37 +04:00
result = rpccli_spoolss_addprinterex ( pipe_hnd_dst , mem_ctx , level , & ctr_src ) ;
2004-08-10 18:27:17 +04:00
if ( W_ERROR_IS_OK ( result ) )
d_printf ( " printer [%s] successfully added. \n " , printername ) ;
else if ( W_ERROR_V ( result ) = = W_ERROR_V ( WERR_PRINTER_ALREADY_EXISTS ) )
2006-01-18 00:22:00 +03:00
d_fprintf ( stderr , " printer [%s] already exists. \n " , printername ) ;
2004-08-10 18:27:17 +04:00
else {
2006-01-18 00:22:00 +03: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 */
if ( got_hnd_src ) {
2005-09-30 21:13:37 +04:00
rpccli_spoolss_close_printer ( pipe_hnd , mem_ctx , & hnd_src ) ;
2004-08-10 18:27:17 +04:00
got_hnd_src = False ;
}
if ( got_hnd_dst ) {
2005-09-30 21:13:37 +04:00
rpccli_spoolss_close_printer ( pipe_hnd_dst , mem_ctx , & hnd_dst ) ;
2004-08-10 18:27:17 +04:00
got_hnd_dst = False ;
}
}
nt_status = NT_STATUS_OK ;
done :
if ( got_hnd_src )
2005-09-30 21:13:37 +04:00
rpccli_spoolss_close_printer ( pipe_hnd , mem_ctx , & hnd_src ) ;
2004-08-10 18:27:17 +04:00
if ( got_hnd_dst )
2005-09-30 21:13:37 +04:00
rpccli_spoolss_close_printer ( pipe_hnd_dst , mem_ctx , & hnd_dst ) ;
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 ;
}
/**
* 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
* argc , argv which are passed through .
*
* @ 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
NTSTATUS rpc_printer_migrate_settings_internals ( const DOM_SID * domain_sid ,
const char * domain_name ,
struct cli_state * cli ,
struct rpc_pipe_client * pipe_hnd ,
TALLOC_CTX * mem_ctx ,
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 ;
uint32 i = 0 , p = 0 , j = 0 ;
uint32 num_printers , val_needed , data_needed ;
uint32 level = 2 ;
2007-12-05 02:45:20 +03:00
char * printername , * sharename ;
2007-10-19 04:40:25 +04:00
bool got_hnd_src = False ;
bool got_hnd_dst = False ;
2005-09-30 21:13:37 +04:00
struct rpc_pipe_client * pipe_hnd_dst = NULL ;
2004-08-10 18:27:17 +04:00
POLICY_HND hnd_src , hnd_dst ;
2004-09-21 17:31:57 +04:00
PRINTER_INFO_CTR ctr_enum , ctr_dst , ctr_dst_publish ;
2005-08-29 18:55:40 +04:00
REGVAL_CTR * reg_ctr ;
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 ;
2004-08-10 18:27:17 +04:00
uint16 * keylist = NULL , * curkey ;
ZERO_STRUCT ( ctr_enum ) ;
DEBUG ( 3 , ( " copying printer settings \n " ) ) ;
2004-08-27 01:37:20 +04:00
/* connect destination PI_SPOOLSS */
2005-09-30 21:13:37 +04:00
nt_status = connect_dst_pipe ( & cli_dst , & pipe_hnd_dst , PI_SPOOLSS ) ;
2004-08-10 18:27:17 +04:00
if ( ! NT_STATUS_IS_OK ( nt_status ) )
return nt_status ;
/* enum src printers */
2005-09-30 21:13:37 +04:00
if ( ! get_printer_info ( pipe_hnd , mem_ctx , level , argc , argv , & num_printers , & ctr_enum ) ) {
2004-08-10 18:27:17 +04:00
nt_status = NT_STATUS_UNSUCCESSFUL ;
goto done ;
}
if ( ! num_printers ) {
printf ( " no printers found on server. \n " ) ;
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 + + ) {
/* do some initialization */
2007-12-05 02:45:20 +03:00
rpcstr_pull_talloc ( mem_ctx ,
& printername ,
ctr_enum . printers_2 [ i ] . printername . buffer ,
- 1 ,
STR_TERMINATE ) ;
rpcstr_pull_talloc ( mem_ctx ,
& sharename ,
ctr_enum . printers_2 [ i ] . sharename . buffer ,
- 1 ,
STR_TERMINATE ) ;
if ( ! printername | | ! sharename ) {
nt_status = NT_STATUS_UNSUCCESSFUL ;
goto done ;
}
2004-08-10 18:27:17 +04:00
/* we can reset NT_STATUS here because we do not
get any real NT_STATUS - codes anymore from now on */
nt_status = NT_STATUS_UNSUCCESSFUL ;
2007-12-05 02:45:20 +03:00
2004-08-10 18:27:17 +04:00
d_printf ( " migrating printer settings for: [%s] / [%s] \n " ,
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 ,
2004-10-07 15:01:13 +04:00
MAXIMUM_ALLOWED_ACCESS , cli - > user_name , & hnd_src ) )
2004-08-10 18:27:17 +04:00
goto done ;
got_hnd_src = True ;
/* open dst printer handle */
2005-09-30 21:13:37 +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_dst - > user_name , & hnd_dst ) )
2004-08-10 18:27:17 +04:00
goto done ;
got_hnd_dst = True ;
/* check for existing dst printer */
2005-09-30 21:13:37 +04:00
if ( ! net_spoolss_getprinter ( pipe_hnd_dst , mem_ctx , & hnd_dst ,
2004-08-10 18:27:17 +04:00
level , & ctr_dst ) )
goto done ;
/* STEP 1: COPY DEVICE-MODE and other
PRINTER_INFO_2 - attributes
*/
ctr_dst . printers_2 = & ctr_enum . printers_2 [ i ] ;
/* why is the port always disconnected when the printer
is correctly installed ( incl . driver ? ? ? ) */
init_unistr ( & ctr_dst . printers_2 - > portname , SAMBA_PRINTER_PORT_NAME ) ;
2004-09-21 17:31:57 +04:00
/* check if printer is published */
2004-08-27 01:32:49 +04:00
if ( ctr_enum . printers_2 [ i ] . attributes & PRINTER_ATTRIBUTE_PUBLISHED ) {
2004-09-21 17:31:57 +04:00
/* check for existing dst printer */
2005-09-30 21:13:37 +04:00
if ( ! net_spoolss_getprinter ( pipe_hnd_dst , mem_ctx , & hnd_dst , 7 , & ctr_dst_publish ) )
2004-09-21 17:31:57 +04:00
goto done ;
ctr_dst_publish . printers_7 - > action = SPOOL_DS_PUBLISH ;
/* ignore False from setprinter due to WERR_IO_PENDING */
2005-09-30 21:13:37 +04:00
net_spoolss_setprinter ( pipe_hnd_dst , mem_ctx , & hnd_dst , 7 , & ctr_dst_publish ) ;
2004-09-21 17:31:57 +04:00
DEBUG ( 3 , ( " republished printer \n " ) ) ;
2004-08-27 01:32:49 +04:00
}
2005-04-26 16:26:32 +04:00
if ( ctr_enum . printers_2 [ i ] . devmode ! = NULL ) {
/* copy devmode (info level 2) */
2007-05-16 15:57:37 +04:00
ctr_dst . printers_2 - > devmode = ( DEVICEMODE * )
2005-04-26 16:26:32 +04:00
TALLOC_MEMDUP ( mem_ctx ,
ctr_enum . printers_2 [ i ] . devmode ,
sizeof ( DEVICEMODE ) ) ;
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 ) */
ctr_dst . printers_2 - > secdesc = NULL ;
2004-08-10 18:27:17 +04:00
#if 0
2005-04-26 16:26:32 +04:00
if ( asprintf ( & devicename , " \\ \\ %s \\ %s " , longname ,
printername ) < 0 ) {
nt_status = NT_STATUS_NO_MEMORY ;
goto done ;
}
2004-08-10 18:27:17 +04:00
2005-04-26 16:26:32 +04:00
init_unistr ( & ctr_dst . printers_2 - > devmode - > devicename ,
devicename ) ;
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 ,
2005-04-26 16:26:32 +04:00
level , & ctr_dst ) )
goto done ;
2004-08-10 18:27:17 +04:00
2005-04-26 16:26:32 +04:00
DEBUGADD ( 1 , ( " \t SetPrinter of DEVICEMODE succeeded \n " ) ) ;
}
2004-08-10 18:27:17 +04:00
/* STEP 2: COPY REGISTRY VALUES */
/* please keep in mind that samba parse_spools gives horribly
2005-09-30 21:13:37 +04:00
crippled results when used to rpccli_spoolss_enumprinterdataex
2005-02-25 02:25:35 +03:00
a win2k3 - server . ( Bugzilla # 1851 )
2004-08-10 18:27:17 +04:00
FIXME : IIRC I ' ve seen it too on a win2k - server
*/
/* enumerate data on src handle */
2005-09-30 21:13:37 +04:00
result = rpccli_spoolss_enumprinterdata ( pipe_hnd , mem_ctx , & hnd_src , p , 0 , 0 ,
2004-08-10 18:27:17 +04:00
& val_needed , & data_needed , NULL ) ;
2005-02-25 02:25:35 +03:00
/* loop for all printerdata of "PrinterDriverData" */
2004-08-10 18:27:17 +04:00
while ( W_ERROR_IS_OK ( result ) ) {
REGISTRY_VALUE value ;
2005-09-30 21:13:37 +04:00
result = rpccli_spoolss_enumprinterdata (
pipe_hnd , mem_ctx , & hnd_src , p + + , val_needed ,
2004-08-10 18:27:17 +04:00
data_needed , 0 , 0 , & value ) ;
/* loop for all reg_keys */
if ( W_ERROR_IS_OK ( result ) ) {
/* display_value */
if ( opt_verbose )
2005-02-25 02:25:35 +03:00
display_reg_value ( SPOOL_PRINTERDATA_KEY , value ) ;
2004-08-10 18:27:17 +04:00
/* set_value */
2005-09-30 21:13:37 +04:00
if ( ! net_spoolss_setprinterdata ( pipe_hnd_dst , mem_ctx ,
2004-08-10 18:27:17 +04:00
& hnd_dst , & value ) )
goto done ;
DEBUGADD ( 1 , ( " \t SetPrinterData of [%s] succeeded \n " ,
value . valuename ) ) ;
}
}
/* STEP 3: COPY SUBKEY VALUES */
/* here we need to enum all printer_keys and then work
on the result with enum_printer_key_ex . nt4 does not
respond to enumprinterkey , win2k does , so continue
in case of an error */
2005-09-30 21:13:37 +04:00
if ( ! net_spoolss_enumprinterkey ( pipe_hnd , mem_ctx , & hnd_src , " " , & keylist ) ) {
2004-08-10 18:27:17 +04:00
printf ( " got no key-data \n " ) ;
continue ;
}
/* work on a list of printer keys
each key has to be enumerated to get all required
information . information is then set via setprinterdataex - calls */
if ( keylist = = NULL )
continue ;
curkey = keylist ;
while ( * curkey ! = 0 ) {
2007-12-05 02:45:20 +03:00
char * subkey ;
rpcstr_pull_talloc ( mem_ctx ,
& subkey ,
curkey ,
- 1 ,
STR_TERMINATE ) ;
if ( ! subkey ) {
return NT_STATUS_NO_MEMORY ;
}
2004-08-10 18:27:17 +04:00
curkey + = strlen ( subkey ) + 1 ;
2005-08-29 18:55:40 +04:00
if ( ! ( reg_ctr = TALLOC_ZERO_P ( mem_ctx , REGVAL_CTR ) ) )
return NT_STATUS_NO_MEMORY ;
2004-08-10 18:27:17 +04:00
/* enumerate all src subkeys */
2005-09-30 21:13:37 +04:00
if ( ! net_spoolss_enumprinterdataex ( pipe_hnd , mem_ctx , 0 ,
2004-08-10 18:27:17 +04:00
& hnd_src , subkey ,
2005-08-29 18:55:40 +04:00
reg_ctr ) )
2004-08-10 18:27:17 +04:00
goto done ;
2005-08-29 18:55:40 +04:00
for ( j = 0 ; j < reg_ctr - > num_values ; j + + ) {
2004-08-10 18:27:17 +04:00
REGISTRY_VALUE value ;
UNISTR2 data ;
/* although samba replies with sane data in most cases we
should try to avoid writing wrong registry data */
2005-08-29 18:55:40 +04:00
if ( strequal ( reg_ctr - > values [ j ] - > valuename , SPOOL_REG_PORTNAME ) | |
strequal ( reg_ctr - > values [ j ] - > valuename , SPOOL_REG_UNCNAME ) | |
strequal ( reg_ctr - > values [ j ] - > valuename , SPOOL_REG_URL ) | |
strequal ( reg_ctr - > values [ j ] - > valuename , SPOOL_REG_SHORTSERVERNAME ) | |
strequal ( reg_ctr - > values [ j ] - > valuename , SPOOL_REG_SERVERNAME ) ) {
2004-08-10 18:27:17 +04:00
2005-08-29 18:55:40 +04:00
if ( strequal ( reg_ctr - > values [ j ] - > valuename , SPOOL_REG_PORTNAME ) ) {
2004-08-10 18:27:17 +04:00
/* although windows uses a multi-sz, we use a sz */
init_unistr2 ( & data , SAMBA_PRINTER_PORT_NAME , UNI_STR_TERMINATE ) ;
fstrcpy ( value . valuename , SPOOL_REG_PORTNAME ) ;
}
2005-08-29 18:55:40 +04:00
if ( strequal ( reg_ctr - > values [ j ] - > valuename , SPOOL_REG_UNCNAME ) ) {
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 ;
}
init_unistr2 ( & data , unc_name , UNI_STR_TERMINATE ) ;
fstrcpy ( value . valuename , SPOOL_REG_UNCNAME ) ;
}
2005-08-29 18:55:40 +04:00
if ( strequal ( reg_ctr - > values [ j ] - > valuename , 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 ;
}
init_unistr2 ( & data , url , UNI_STR_TERMINATE ) ;
fstrcpy ( value . valuename , SPOOL_REG_URL ) ;
# endif
}
2005-08-29 18:55:40 +04:00
if ( strequal ( reg_ctr - > values [ j ] - > valuename , SPOOL_REG_SERVERNAME ) ) {
2004-08-10 18:27:17 +04:00
init_unistr2 ( & data , longname , UNI_STR_TERMINATE ) ;
fstrcpy ( value . valuename , SPOOL_REG_SERVERNAME ) ;
}
2005-08-29 18:55:40 +04:00
if ( strequal ( reg_ctr - > values [ j ] - > valuename , SPOOL_REG_SHORTSERVERNAME ) ) {
2004-08-10 18:27:17 +04:00
init_unistr2 ( & data , global_myname ( ) , UNI_STR_TERMINATE ) ;
fstrcpy ( value . valuename , SPOOL_REG_SHORTSERVERNAME ) ;
}
value . type = REG_SZ ;
value . size = data . uni_str_len * 2 ;
2007-04-30 05:34:28 +04:00
if ( value . size ) {
value . data_p = ( uint8 * ) TALLOC_MEMDUP ( mem_ctx , data . buffer , value . size ) ;
} else {
value . data_p = NULL ;
}
2004-08-10 18:27:17 +04:00
if ( opt_verbose )
display_reg_value ( subkey , value ) ;
/* here we have to set all subkeys on the dst server */
2005-09-30 21:13:37 +04:00
if ( ! net_spoolss_setprinterdataex ( pipe_hnd_dst , mem_ctx , & hnd_dst ,
2004-08-10 18:27:17 +04:00
subkey , & value ) )
goto done ;
} else {
if ( opt_verbose )
2005-08-29 18:55:40 +04:00
display_reg_value ( subkey , * ( reg_ctr - > values [ j ] ) ) ;
2004-08-10 18:27:17 +04:00
/* here we have to set all subkeys on the dst server */
2005-09-30 21:13:37 +04:00
if ( ! net_spoolss_setprinterdataex ( pipe_hnd_dst , mem_ctx , & hnd_dst ,
2005-08-29 18:55:40 +04:00
subkey , reg_ctr - > values [ j ] ) )
2004-08-10 18:27:17 +04:00
goto done ;
}
DEBUGADD ( 1 , ( " \t SetPrinterDataEx of key [%s \\ %s] succeeded \n " ,
2005-08-29 18:55:40 +04:00
subkey , reg_ctr - > values [ j ] - > valuename ) ) ;
2004-08-10 18:27:17 +04:00
}
2005-09-30 21:13:37 +04:00
2005-08-29 18:55:40 +04:00
TALLOC_FREE ( reg_ctr ) ;
2004-08-10 18:27:17 +04:00
}
safe_free ( keylist ) ;
/* close printer handles here */
if ( got_hnd_src ) {
2005-09-30 21:13:37 +04:00
rpccli_spoolss_close_printer ( pipe_hnd , mem_ctx , & hnd_src ) ;
2004-08-10 18:27:17 +04:00
got_hnd_src = False ;
}
if ( got_hnd_dst ) {
2005-09-30 21:13:37 +04:00
rpccli_spoolss_close_printer ( pipe_hnd_dst , mem_ctx , & hnd_dst ) ;
2004-08-10 18:27:17 +04:00
got_hnd_dst = False ;
}
}
nt_status = NT_STATUS_OK ;
done :
SAFE_FREE ( devicename ) ;
SAFE_FREE ( url ) ;
SAFE_FREE ( unc_name ) ;
if ( got_hnd_src )
2005-09-30 21:13:37 +04:00
rpccli_spoolss_close_printer ( pipe_hnd , mem_ctx , & hnd_src ) ;
2004-08-10 18:27:17 +04:00
if ( got_hnd_dst )
2005-09-30 21:13:37 +04:00
rpccli_spoolss_close_printer ( pipe_hnd_dst , mem_ctx , & hnd_dst ) ;
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 ;
}