2008-05-08 13:23:38 +04:00
/*
Samba Unix / Linux SMB client library
Distributed SMB / CIFS Server Management Utility
2004-08-10 18:27:17 +04:00
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 .
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"
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
2009-02-25 00:23:56 +03:00
static void display_print_driver3 ( struct spoolss_DriverInfo3 * r )
{
int i ;
if ( ! r ) {
return ;
}
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 ) ;
for ( i = 0 ; r - > dependent_files [ i ] ! = NULL ; i + + ) {
printf ( " \t Dependentfiles: [%s] \n " , r - > dependent_files [ i ] ) ;
}
printf ( " \n " ) ;
printf ( " \t Monitorname: [%s] \n " , r - > monitor_name ) ;
printf ( " \t Defaultdatatype: [%s] \n \n " , r - > default_datatype ) ;
}
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 = " " ;
2008-05-08 13:23:38 +04:00
2004-08-10 18:27:17 +04:00
int length = 0 ;
2008-05-12 13:53:23 +04:00
bool valid = true ;
2008-05-08 13:23:38 +04:00
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 ) ;
2008-05-08 13:23:38 +04:00
2004-08-10 18:27:17 +04:00
length + = strlen ( dependentfiles ) + 1 ;
2008-05-08 13:23:38 +04:00
2004-08-10 18:27:17 +04:00
if ( strlen ( dependentfiles ) > 0 ) {
d_printf ( " \t Dependentfiles: [%s] \n " , dependentfiles ) ;
} else {
2008-05-12 13:53:23 +04:00
valid = false ;
2004-08-10 18:27:17 +04:00
}
}
2008-05-08 13:23:38 +04:00
2004-08-10 18:27:17 +04:00
printf ( " \n " ) ;
d_printf ( " \t Monitorname: [%s] \n " , monitorname ) ;
d_printf ( " \t Defaultdatatype: [%s] \n \n " , defaultdatatype ) ;
2008-05-08 13:23:38 +04:00
return ;
2004-08-10 18:27:17 +04:00
}
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 :
2008-05-08 13:23:38 +04:00
d_printf ( " \t [%s:%s]: REG_DWORD: 0x%08x \n " , subkey , value . valuename ,
2004-08-10 18:27:17 +04:00
* ( ( 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 :
2008-05-08 13:23:38 +04:00
d_printf ( " \t [%s:%s]: REG_BINARY: unknown length value not displayed \n " ,
2004-08-10 18:27:17 +04:00
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 ) ;
}
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 ;
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 */
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 ) ) ;
fnum_src = cli_nt_create ( cli_share_src , src_name , READ_CONTROL_ACCESS ) ;
if ( fnum_src = = - 1 ) {
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 */
2008-05-08 13:23:38 +04:00
if ( ! cli_getattrE ( cli_share_src , fnum_src , & attr , NULL ,
2004-11-19 22:45:03 +03:00
& 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
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 ) ) {
2008-05-08 13:23:38 +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 ;
}
if ( ! cli_close ( cli_share_dst , fnum_dst ) ) {
2008-05-08 13:23:38 +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 ;
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 )
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 )
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 ) ) ;
2008-05-08 13:23:38 +04:00
fnum_dst = cli_open ( cli_share_dst , dst_name ,
2004-08-10 18:27:17 +04:00
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
2008-05-10 01:22:12 +04:00
if ( c - > opt_verbose ) {
2004-08-10 18:27:17 +04:00
2004-08-21 00:13:05 +04:00
d_printf ( " copying [ \\ \\ %s \\ %s%s] => [ \\ \\ %s \\ %s%s] "
2008-05-08 13:23:38 +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 ,
2008-05-08 13:23:38 +04:00
copy_acls ? " with " : " without " ,
2004-08-21 00:13:05 +04:00
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 ) {
2008-05-08 13:23:38 +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
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 */
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 ) ) ;
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 ) ) {
2008-05-08 13:23:38 +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 ;
}
if ( is_file & & ! cli_close ( cli_share_dst , fnum_dst ) ) {
2008-05-08 13:23:38 +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
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
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
}
}
/* build source file name */
2008-05-08 13:23:38 +04:00
if ( asprintf ( & src_name , " \\ %s \\ %s \\ %s " , short_archi , version , filename ) < 0 )
2004-08-10 18:27:17 +04:00
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 */
2008-05-10 01:22:12 +04:00
nt_status = 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
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 ;
}
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 ) ) ;
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 ) ) {
2008-05-08 13:23:38 +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 )
2008-05-08 13:23:38 +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 ,
uint32 flags ,
2008-05-08 13:23:38 +04:00
uint32 level ,
2005-09-30 21:13:37 +04:00
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 ) ) {
2008-11-01 19:19:26 +03: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 ,
2008-05-08 13:23:38 +04:00
uint32 access_required ,
2005-09-30 21:13:37 +04:00
const char * username ,
POLICY_HND * 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 ) ) {
2008-05-08 13:23:38 +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 ) ) {
2008-05-08 13:23:38 +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 ,
POLICY_HND * hnd ,
2008-05-08 13:23:38 +04:00
uint32 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 ) ) {
2008-11-01 19:19:26 +03: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 ,
POLICY_HND * hnd ,
2008-05-08 13:23:38 +04:00
uint32 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 ;
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 :
info_ctr . info . info0 = ( struct spoolss_SetPrinterInfo0 * ) & info - > info0 ;
break ;
case 1 :
info_ctr . info . info1 = ( struct spoolss_SetPrinterInfo1 * ) & info - > info1 ;
break ;
case 2 :
info_ctr . info . info2 = ( struct spoolss_SetPrinterInfo2 * ) & info - > info2 ;
break ;
case 3 :
info_ctr . info . info3 = ( struct spoolss_SetPrinterInfo3 * ) & info - > info3 ;
break ;
case 4 :
info_ctr . info . info4 = ( struct spoolss_SetPrinterInfo4 * ) & info - > info4 ;
break ;
case 5 :
info_ctr . info . info5 = ( struct spoolss_SetPrinterInfo5 * ) & info - > info5 ;
break ;
case 6 :
info_ctr . info . info6 = ( struct spoolss_SetPrinterInfo6 * ) & info - > info6 ;
break ;
case 7 :
info_ctr . info . info7 = ( struct spoolss_SetPrinterInfo7 * ) & info - > info7 ;
break ;
#if 0 /* FIXME GD */
case 8 :
info_ctr . info . info8 = ( struct spoolss_SetPrinterInfo8 * ) & info - > info8 ;
break ;
case 9 :
info_ctr . info . info9 = ( struct spoolss_SetPrinterInfo9 * ) & info - > info9 ;
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 ) ) {
2008-11-01 19:19:26 +03: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 ,
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 ;
2008-05-08 13:23:38 +04:00
2004-08-10 18:27:17 +04:00
/* 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 ) ) {
2008-11-01 19:19:26 +03: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 ,
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 ) ;
2008-05-08 13:23:38 +04:00
2004-08-10 18:27:17 +04:00
if ( ! W_ERROR_IS_OK ( result ) ) {
2008-11-01 19:19:26 +03: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 ,
2008-05-08 13:23:38 +04:00
uint32 offered ,
2005-09-30 21:13:37 +04:00
POLICY_HND * hnd ,
2008-05-08 13:23:38 +04:00
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 ) ;
2008-05-08 13:23:38 +04:00
2004-08-10 18:27:17 +04:00
if ( ! W_ERROR_IS_OK ( result ) ) {
2008-11-01 19:19:26 +03: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 ,
POLICY_HND * hnd ,
2008-05-08 13:23:38 +04:00
char * keyname ,
2005-09-30 21:13:37 +04:00
REGISTRY_VALUE * 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 ,
value - > valuename ,
value - > type ,
value - > data_p ,
value - > size ,
& result ) ;
2008-05-08 13:23:38 +04:00
2004-08-10 18:27:17 +04:00
if ( ! W_ERROR_IS_OK ( result ) ) {
2008-11-01 19:19:26 +03: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 ,
POLICY_HND * hnd ,
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 ) ) {
2008-11-01 19:19:26 +03: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 ,
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 ) ) {
2008-11-01 19:19:26 +03: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 ,
POLICY_HND * hnd , uint32 level ,
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 ) ) {
2008-11-01 19:19:26 +03: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 ,
2004-08-10 18:27:17 +04:00
TALLOC_CTX * mem_ctx , uint32 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 :
info_ctr . info . info2 = ( struct spoolss_AddDriverInfo2 * ) & info - > info2 ;
break ;
case 3 :
info_ctr . info . info3 = ( struct spoolss_AddDriverInfo3 * ) & info - > info3 ;
break ;
default :
printf ( " unsupported info level: %d \n " , level ) ;
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 ) ) {
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 ) ) {
2008-11-01 19:19:26 +03: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
}
/**
2008-05-08 13:23:38 +04:00
* abstraction function to get uint32 num_printers and PRINTER_INFO_CTR ctr
* 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 ,
2005-09-30 21:13:37 +04:00
uint32 * num_printers ,
PRINTER_INFO_CTR * ctr )
2004-08-10 18:27:17 +04:00
{
POLICY_HND hnd ;
2009-02-25 12:58:53 +03:00
union spoolss_PrinterInfo info ;
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 ,
level , num_printers , ctr ) )
2008-05-12 13:53:23 +04:00
return false ;
2004-08-10 18:27:17 +04:00
goto out ;
}
2009-02-25 12:58:53 +03:00
/* FIXME GD */
return false ;
2004-08-10 18:27:17 +04:00
/* 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-02-25 12:58:53 +03:00
if ( ! net_spoolss_getprinter ( pipe_hnd , mem_ctx , & hnd , level , & info ) ) {
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 ,
const 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 ;
2008-05-08 13:23:38 +04:00
uint32 i , num_printers ;
2004-08-10 18:27:17 +04:00
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 ;
}
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 ,
const 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 ;
uint32 i ;
2008-05-08 13:23:38 +04:00
uint32 level = 3 ;
2004-08-10 18:27:17 +04:00
PRINTER_DRIVER_CTR drv_ctr_enum ;
int d ;
2008-05-08 13:23:38 +04:00
2004-08-10 18:27:17 +04:00
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 ,
2008-05-08 13:23:38 +04:00
archi_table [ i ] . long_archi ,
2004-08-10 18:27:17 +04:00
& num_drivers , & drv_ctr_enum ) ) {
nt_status = NT_STATUS_UNSUCCESSFUL ;
goto done ;
}
if ( num_drivers = = 0 ) {
2008-05-08 13:23:38 +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
}
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 + + ) {
display_print_driver_3 ( & ( drv_ctr_enum . info3 [ d ] ) ) ;
}
}
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 ,
uint32 action )
2004-10-13 05:40:35 +04:00
{
NTSTATUS nt_status = NT_STATUS_UNSUCCESSFUL ;
2008-05-08 13:23:38 +04:00
uint32 i , num_printers ;
2004-10-13 05:40:35 +04:00
uint32 level = 7 ;
2007-12-05 02:45:20 +03:00
char * printername , * sharename ;
2009-02-25 12:58:53 +03:00
PRINTER_INFO_CTR ctr ;
union spoolss_PrinterInfo info ;
struct spoolss_SetPrinterInfoCtr info_ctr ;
struct spoolss_DevmodeContainer devmode_ctr ;
struct sec_desc_buf secdesc_ctr ;
2004-10-13 05:40:35 +04:00
POLICY_HND hnd ;
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 ,
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 :
2004-10-13 05:40:35 +04:00
action_str = " published " ;
break ;
2009-02-27 01:40:58 +03:00
case DSPRINT_UPDATE :
2004-10-13 05:40:35 +04:00
action_str = " updated " ;
break ;
2009-02-27 01:40:58 +03:00
case DSPRINT_UNPUBLISH :
2004-10-13 05:40:35 +04:00
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 ;
}
2009-02-25 12:58:53 +03:00
info . info7 . action = action ;
info_ctr . level = 7 ;
info_ctr . info . info7 = ( struct spoolss_SetPrinterInfo7 * ) & info . info7 ;
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 ) ) ) {
2008-11-01 19:19:26 +03:00
printf ( " cannot set printer-info: %s \n " , win_errstr ( result ) ) ;
2004-10-13 05:40:35 +04:00
goto done ;
}
printf ( " successfully %s printer %s in Active Directory \n " , action_str , sharename ) ;
}
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 ,
const 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 ,
const 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 ,
const 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 ,
const 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 ;
2008-05-08 13:23:38 +04:00
uint32 i , num_printers ;
2004-10-13 05:40:35 +04:00
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 ;
2009-02-25 12:58:53 +03:00
union spoolss_PrinterInfo info ;
2004-10-13 05:40:35 +04:00
POLICY_HND hnd ;
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 ,
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 :
2004-10-13 05:40:35 +04:00
printf ( " printer [%s] is published " , sharename ) ;
2008-05-10 01:22:12 +04:00
if ( c - > opt_verbose )
2009-02-25 12:58:53 +03: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 :
2004-10-13 05:40:35 +04:00
printf ( " printer [%s] is unpublished \n " , sharename ) ;
break ;
2009-02-27 01:40:58 +03:00
case DSPRINT_UPDATE :
2004-10-13 05:40:35 +04:00
printf ( " printer [%s] is currently updating \n " , sharename ) ;
break ;
default :
printf ( " unkown state: %d \n " , state ) ;
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 ,
const 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 ;
uint32 i = 0 ;
uint32 num_printers ;
uint32 level = 2 ;
2007-12-05 02:45:20 +03:00
char * printername , * sharename ;
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 ;
2009-02-25 12:58:53 +03:00
PRINTER_INFO_CTR ctr_src , ctr_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
ZERO_STRUCT ( ctr_src ) ;
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 ,
& syntax_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
2008-05-08 13:23:38 +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 ,
const 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 ;
uint32 i , f ;
uint32 num_printers ;
uint32 level = 1 ;
2007-12-05 02:45:20 +03:00
char * printername , * sharename ;
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 ;
2009-02-25 12:58:53 +03:00
PRINTER_INFO_CTR ctr_enum ;
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
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 */
2008-07-20 20:44:32 +04:00
nt_status = connect_dst_pipe ( c , & cli_dst , & pipe_hnd_dst ,
& syntax_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 ,
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 )
2008-05-08 13:23:38 +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-03-06 13:02:27 +03:00
info . info1 = ( struct spoolss_AddFormInfo1 * ) & 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 ) ) {
2008-05-08 13:23:38 +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 ,
const 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 ;
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 ;
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 ;
2004-08-10 18:27:17 +04:00
POLICY_HND hnd_src , hnd_dst ;
2009-02-25 00:23:56 +03:00
union spoolss_DriverInfo drv_info_src ;
2004-08-10 18:27:17 +04:00
PRINTER_INFO_CTR info_ctr_enum , info_ctr_dst ;
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
ZERO_STRUCT ( info_ctr_enum ) ;
ZERO_STRUCT ( info_ctr_dst ) ;
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 ,
& syntax_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 */
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 */
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 ;
}
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 ;
2008-05-08 13:23:38 +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 ) ) ;
}
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 */
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 ,
const 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 ;
uint32 i = 0 , num_printers ;
uint32 level = 2 ;
2009-02-25 12:58:53 +03:00
PRINTER_INFO_CTR ctr_enum ;
union spoolss_PrinterInfo info_dst , info_src ;
2004-08-10 18:27:17 +04:00
struct cli_state * cli_dst = NULL ;
POLICY_HND hnd_dst , hnd_src ;
2007-12-05 02:45:20 +03:00
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 ,
& syntax_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
2008-05-08 13:23:38 +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 ) ) {
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. */
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 */
d_printf ( " creating printer: %s \n " , printername ) ;
2009-02-25 03:11:01 +03:00
info_ctr . level = level ;
info_ctr . info . info2 = ( struct spoolss_SetPrinterInfo2 * ) & info_src . info2 ;
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 ) )
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 ) )
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 */
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 ,
const 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 ;
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 ;
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 ;
2009-02-25 12:58:53 +03:00
PRINTER_INFO_CTR ctr_enum ;
union spoolss_PrinterInfo info_dst_publish , info_dst ;
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 ) ;
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 ,
& syntax_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 ;
}
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
2008-05-08 13:23:38 +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 ;
2009-02-25 12:58:53 +03:00
#if 0 /* FIXME GD */
2004-08-10 18:27:17 +04:00
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-02-25 12:58:53 +03:00
info_dst . info2 = & ctr_enum . printers_2 [ i ] ;
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 */
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 */
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
}
2005-04-26 16:26:32 +04:00
if ( ctr_enum . printers_2 [ i ] . devmode ! = NULL ) {
/* copy devmode (info level 2) */
2009-02-25 12:58:53 +03:00
info_dst . info2 . 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 ) */
2009-02-25 12:58:53 +03:00
info_dst . info2 . 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 ,
2008-05-08 13:23:38 +04:00
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 ,
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-02-25 12:58:53 +03:00
# endif
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 */
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 ) ) {
2008-05-08 13:23:38 +04:00
2004-08-10 18:27:17 +04:00
REGISTRY_VALUE value ;
2008-05-08 13:23:38 +04:00
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 */
2008-05-10 01:22:12 +04:00
if ( c - > 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 */
2008-05-08 13:23:38 +04:00
if ( ! net_spoolss_setprinterdata ( pipe_hnd_dst , mem_ctx ,
& hnd_dst , & value ) )
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 " ,
2004-08-10 18:27:17 +04:00
value . valuename ) ) ;
}
}
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 ) ) {
2004-08-10 18:27:17 +04:00
printf ( " got no key-data \n " ) ;
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 ;
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 */
2008-05-08 13:23:38 +04:00
if ( ! net_spoolss_enumprinterdataex ( pipe_hnd , mem_ctx , 0 ,
& hnd_src , subkey ,
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 + + ) {
2008-05-08 13:23:38 +04:00
2004-08-10 18:27:17 +04:00
REGISTRY_VALUE value ;
UNISTR2 data ;
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
if ( strequal ( reg_ctr - > values [ j ] - > valuename , SPOOL_REG_PORTNAME ) | |
2005-08-29 18:55:40 +04:00
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 ) ) {
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 */
init_unistr2 ( & data , SAMBA_PRINTER_PORT_NAME , UNI_STR_TERMINATE ) ;
fstrcpy ( value . valuename , SPOOL_REG_PORTNAME ) ;
}
2008-05-08 13:23:38 +04:00
2005-08-29 18:55:40 +04:00
if ( strequal ( reg_ctr - > values [ j ] - > valuename , 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 ;
}
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
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 ,
subkey , & value ) )
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
} else {
2008-05-10 01:22:12 +04:00
if ( c - > 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 */
2008-05-08 13:23:38 +04:00
if ( ! net_spoolss_setprinterdataex ( pipe_hnd_dst , mem_ctx , & hnd_dst ,
subkey , reg_ctr - > values [ j ] ) )
2004-08-10 18:27:17 +04:00
goto done ;
}
2008-05-08 13:23:38 +04:00
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
}
2008-10-19 15:06:14 +04:00
SAFE_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 ;
}