2010-05-13 02:05:40 +04:00
/*
Samba Unix / Linux SMB client library
Distributed SMB / CIFS Server Management Utility
Local printing tdb migration interface
Copyright ( C ) Guenther Deschner 2010
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
the Free Software Foundation ; either version 3 of the License , or
( at your option ) any later version .
This program is distributed in the hope that it will be useful ,
but WITHOUT ANY WARRANTY ; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
GNU General Public License for more details .
You should have received a copy of the GNU General Public License
along with this program . If not , see < http : //www.gnu.org/licenses/>.
*/
# include "includes.h"
2011-02-26 01:20:06 +03:00
# include "system/filesys.h"
2010-05-13 02:05:40 +04:00
# include "utils/net.h"
2011-04-13 16:32:16 +04:00
# include "rpc_client/rpc_client.h"
2011-07-01 17:39:11 +04:00
# include "rpc_client/cli_pipe.h"
2010-05-13 02:05:40 +04:00
# include "librpc/gen_ndr/ndr_ntprinting.h"
2011-07-01 17:02:26 +04:00
# include "librpc/gen_ndr/ndr_spoolss.h"
2010-10-12 08:27:50 +04:00
# include "../libcli/security/security.h"
2010-05-28 04:19:32 +04:00
# include "../librpc/gen_ndr/ndr_security.h"
2011-07-01 17:39:11 +04:00
# include "../librpc/gen_ndr/ndr_winreg.h"
2011-05-05 13:25:29 +04:00
# include "util_tdb.h"
2011-07-01 17:02:26 +04:00
# include "printing/nt_printing_migrate.h"
2010-05-13 02:05:40 +04:00
# define FORMS_PREFIX "FORMS / "
2016-05-18 18:04:38 +03:00
# define FORMS_PREFIX_LEN 6
2010-05-13 02:05:40 +04:00
# define DRIVERS_PREFIX "DRIVERS / "
2016-05-18 18:04:38 +03:00
# define DRIVERS_PREFIX_LEN 8
2010-05-13 02:05:40 +04:00
# define PRINTERS_PREFIX "PRINTERS / "
2016-05-18 18:04:38 +03:00
# define PRINTERS_PREFIX_LEN 9
2010-05-18 17:32:47 +04:00
# define SECDESC_PREFIX "SECDESC / "
2016-05-18 18:04:38 +03:00
# define SECDESC_PREFIX_LEN 8
2010-05-13 02:05:40 +04:00
2013-03-12 14:39:08 +04:00
# define ARG_ENCODING "encoding="
struct printing_opts {
const char * encoding ;
const char * tdb ;
} ;
static NTSTATUS printing_parse_args ( TALLOC_CTX * mem_ctx ,
struct printing_opts * * popts ,
int argc , const char * * argv )
{
size_t c ;
struct printing_opts * o ;
if ( argc = = 0 ) {
return NT_STATUS_INVALID_PARAMETER ;
}
o = talloc_zero ( mem_ctx , struct printing_opts ) ;
if ( o = = NULL ) {
return NT_STATUS_INVALID_PARAMETER ;
}
for ( c = 0 ; c < argc ; c + + ) {
if ( strnequal ( argv [ c ] , ARG_ENCODING , sizeof ( ARG_ENCODING ) - 1 ) ) {
o - > encoding = talloc_strdup ( o ,
argv [ c ] + sizeof ( ARG_ENCODING ) - 1 ) ;
if ( o - > encoding = = NULL ) {
return NT_STATUS_NO_MEMORY ;
}
} else {
o - > tdb = talloc_strdup ( o , argv [ c ] ) ;
if ( o - > tdb = = NULL ) {
return NT_STATUS_NO_MEMORY ;
}
}
}
* popts = o ;
return NT_STATUS_OK ;
}
2010-05-13 02:05:40 +04:00
static void dump_form ( TALLOC_CTX * mem_ctx ,
const char * key_name ,
unsigned char * data ,
size_t length )
{
enum ndr_err_code ndr_err ;
DATA_BLOB blob ;
char * s ;
struct ntprinting_form r ;
printf ( " found form: %s \n " , key_name ) ;
blob = data_blob_const ( data , length ) ;
ZERO_STRUCT ( r ) ;
ndr_err = ndr_pull_struct_blob ( & blob , mem_ctx , & r ,
( ndr_pull_flags_fn_t ) ndr_pull_ntprinting_form ) ;
if ( ! NDR_ERR_CODE_IS_SUCCESS ( ndr_err ) ) {
d_fprintf ( stderr , _ ( " form pull failed: %s \n " ) ,
ndr_errstr ( ndr_err ) ) ;
return ;
}
s = NDR_PRINT_STRUCT_STRING ( mem_ctx , ntprinting_form , & r ) ;
if ( s ) {
printf ( " %s \n " , s ) ;
}
}
static void dump_driver ( TALLOC_CTX * mem_ctx ,
const char * key_name ,
unsigned char * data ,
2013-03-12 21:42:02 +04:00
size_t length ,
bool do_string_conversion )
2010-05-13 02:05:40 +04:00
{
enum ndr_err_code ndr_err ;
DATA_BLOB blob ;
char * s ;
struct ntprinting_driver r ;
printf ( " found driver: %s \n " , key_name ) ;
blob = data_blob_const ( data , length ) ;
ZERO_STRUCT ( r ) ;
2013-03-12 21:42:02 +04:00
if ( do_string_conversion ) {
r . string_flags = LIBNDR_FLAG_STR_ASCII ;
}
2010-05-13 02:05:40 +04:00
ndr_err = ndr_pull_struct_blob ( & blob , mem_ctx , & r ,
( ndr_pull_flags_fn_t ) ndr_pull_ntprinting_driver ) ;
if ( ! NDR_ERR_CODE_IS_SUCCESS ( ndr_err ) ) {
d_fprintf ( stderr , _ ( " driver pull failed: %s \n " ) ,
ndr_errstr ( ndr_err ) ) ;
return ;
}
s = NDR_PRINT_STRUCT_STRING ( mem_ctx , ntprinting_driver , & r ) ;
if ( s ) {
printf ( " %s \n " , s ) ;
}
}
static void dump_printer ( TALLOC_CTX * mem_ctx ,
const char * key_name ,
unsigned char * data ,
2013-03-12 21:42:02 +04:00
size_t length ,
bool do_string_conversion )
2010-05-13 02:05:40 +04:00
{
enum ndr_err_code ndr_err ;
DATA_BLOB blob ;
char * s ;
struct ntprinting_printer r ;
printf ( " found printer: %s \n " , key_name ) ;
blob = data_blob_const ( data , length ) ;
ZERO_STRUCT ( r ) ;
2013-03-12 21:42:02 +04:00
if ( do_string_conversion ) {
r . info . string_flags = LIBNDR_FLAG_STR_ASCII ;
}
2010-05-13 02:05:40 +04:00
ndr_err = ndr_pull_struct_blob ( & blob , mem_ctx , & r ,
( ndr_pull_flags_fn_t ) ndr_pull_ntprinting_printer ) ;
if ( ! NDR_ERR_CODE_IS_SUCCESS ( ndr_err ) ) {
d_fprintf ( stderr , _ ( " printer pull failed: %s \n " ) ,
ndr_errstr ( ndr_err ) ) ;
return ;
}
s = NDR_PRINT_STRUCT_STRING ( mem_ctx , ntprinting_printer , & r ) ;
if ( s ) {
printf ( " %s \n " , s ) ;
}
}
2010-05-18 17:32:47 +04:00
static void dump_sd ( TALLOC_CTX * mem_ctx ,
const char * key_name ,
unsigned char * data ,
size_t length )
{
enum ndr_err_code ndr_err ;
DATA_BLOB blob ;
char * s ;
struct sec_desc_buf r ;
printf ( " found security descriptor: %s \n " , key_name ) ;
blob = data_blob_const ( data , length ) ;
ZERO_STRUCT ( r ) ;
ndr_err = ndr_pull_struct_blob ( & blob , mem_ctx , & r ,
( ndr_pull_flags_fn_t ) ndr_pull_sec_desc_buf ) ;
if ( ! NDR_ERR_CODE_IS_SUCCESS ( ndr_err ) ) {
d_fprintf ( stderr , _ ( " security descriptor pull failed: %s \n " ) ,
ndr_errstr ( ndr_err ) ) ;
return ;
}
s = NDR_PRINT_STRUCT_STRING ( mem_ctx , sec_desc_buf , & r ) ;
if ( s ) {
printf ( " %s \n " , s ) ;
}
}
2010-05-13 02:05:40 +04:00
static int net_printing_dump ( struct net_context * c , int argc ,
const char * * argv )
{
int ret = - 1 ;
TALLOC_CTX * ctx = talloc_stackframe ( ) ;
TDB_CONTEXT * tdb ;
2015-03-12 17:14:24 +03:00
TDB_DATA kbuf , newkey , dbuf ;
2013-03-12 21:42:02 +04:00
struct printing_opts * o ;
const char * save_dos_charset = lp_dos_charset ( ) ;
bool do_string_conversion = false ;
NTSTATUS status ;
2010-05-13 02:05:40 +04:00
if ( argc < 1 | | c - > display_usage ) {
2013-03-12 21:42:02 +04:00
d_printf ( " %s \n "
" net printing dump [options] <file.tdb> \n "
" %s \n " ,
_ ( " Usage: " ) ,
2018-05-04 23:20:57 +03:00
_ ( " Dump formatted printer information of the tdb. " ) ) ;
2013-03-12 21:42:02 +04:00
d_printf ( _ ( " Valid options: \n " ) ) ;
d_printf ( _ ( " encoding=<CP> Set the Code Page of the tdb file. \n "
" See iconv -l for the list of CP values \n "
" (CP1252 is Western latin1, CP1251 is Cyrillic). \n " ) ) ;
2010-05-13 02:05:40 +04:00
goto done ;
}
2013-03-12 21:42:02 +04:00
status = printing_parse_args ( ctx , & o , argc , argv ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
d_fprintf ( stderr , _ ( " failed to parse arguments \n " ) ) ;
goto done ;
}
tdb = tdb_open_log ( o - > tdb , 0 , TDB_DEFAULT , O_RDONLY , 0600 ) ;
2010-05-13 02:05:40 +04:00
if ( ! tdb ) {
2013-03-12 21:42:02 +04:00
d_fprintf ( stderr , _ ( " failed to open tdb file: %s \n " ) , o - > tdb ) ;
2010-05-13 02:05:40 +04:00
goto done ;
}
2013-03-12 21:42:02 +04:00
if ( o - > encoding ! = NULL ) {
lp_set_cmdline ( " dos charset " , o - > encoding ) ;
d_fprintf ( stderr , _ ( " do string conversion from %s to %s \n " ) ,
lp_dos_charset ( ) , lp_unix_charset ( ) ) ;
do_string_conversion = true ;
}
2015-03-12 17:14:24 +03:00
for ( kbuf = tdb_firstkey ( tdb ) ;
2010-05-13 02:05:40 +04:00
kbuf . dptr ;
2015-03-12 17:14:24 +03:00
newkey = tdb_nextkey ( tdb , kbuf ) , free ( kbuf . dptr ) , kbuf = newkey )
2010-05-13 02:05:40 +04:00
{
2016-05-18 18:04:38 +03:00
int cmp ;
2015-03-12 17:23:17 +03:00
dbuf = tdb_fetch ( tdb , kbuf ) ;
2010-05-13 02:05:40 +04:00
if ( ! dbuf . dptr ) {
continue ;
}
2016-05-18 18:04:38 +03:00
cmp = strncmp ( ( const char * ) kbuf . dptr ,
FORMS_PREFIX ,
FORMS_PREFIX_LEN ) ;
if ( cmp = = 0 ) {
2016-05-18 17:51:45 +03:00
char * key_name = NULL ;
size_t converted_size = 0 ;
bool ok ;
ok = pull_ascii_talloc ( ctx ,
& key_name ,
( const char * ) kbuf . dptr + strlen ( FORMS_PREFIX ) ,
& converted_size ) ;
if ( ! ok ) {
continue ;
}
dump_form ( ctx , key_name , dbuf . dptr , dbuf . dsize ) ;
TALLOC_FREE ( key_name ) ;
2010-05-13 02:05:40 +04:00
SAFE_FREE ( dbuf . dptr ) ;
continue ;
}
2016-05-18 18:04:38 +03:00
cmp = strncmp ( ( const char * ) kbuf . dptr ,
DRIVERS_PREFIX ,
DRIVERS_PREFIX_LEN ) ;
if ( cmp = = 0 ) {
2016-05-18 17:51:45 +03:00
char * key_name = NULL ;
size_t converted_size = 0 ;
bool ok ;
ok = pull_ascii_talloc ( ctx ,
& key_name ,
( const char * ) kbuf . dptr + strlen ( DRIVERS_PREFIX ) ,
& converted_size ) ;
if ( ! ok ) {
continue ;
}
2013-03-12 21:42:02 +04:00
dump_driver ( ctx ,
2016-05-18 17:51:45 +03:00
key_name ,
2013-03-12 21:42:02 +04:00
dbuf . dptr ,
dbuf . dsize ,
do_string_conversion ) ;
2016-05-18 17:51:45 +03:00
TALLOC_FREE ( key_name ) ;
2010-05-13 02:05:40 +04:00
SAFE_FREE ( dbuf . dptr ) ;
continue ;
}
2016-05-18 18:04:38 +03:00
cmp = strncmp ( ( const char * ) kbuf . dptr ,
PRINTERS_PREFIX ,
PRINTERS_PREFIX_LEN ) ;
if ( cmp = = 0 ) {
2016-05-18 17:51:45 +03:00
char * key_name = NULL ;
size_t converted_size = 0 ;
bool ok ;
ok = pull_ascii_talloc ( ctx ,
& key_name ,
( const char * ) kbuf . dptr + strlen ( PRINTERS_PREFIX ) ,
& converted_size ) ;
if ( ! ok ) {
continue ;
}
2013-03-12 21:42:02 +04:00
dump_printer ( ctx ,
2016-05-18 17:51:45 +03:00
key_name ,
2013-03-12 21:42:02 +04:00
dbuf . dptr ,
dbuf . dsize ,
do_string_conversion ) ;
2016-05-18 17:51:45 +03:00
TALLOC_FREE ( key_name ) ;
2010-05-13 02:05:40 +04:00
SAFE_FREE ( dbuf . dptr ) ;
continue ;
}
2010-05-18 17:32:47 +04:00
2016-05-18 18:04:38 +03:00
cmp = strncmp ( ( const char * ) kbuf . dptr ,
SECDESC_PREFIX ,
SECDESC_PREFIX_LEN ) ;
if ( cmp = = 0 ) {
2010-05-18 17:32:47 +04:00
dump_sd ( ctx , ( const char * ) kbuf . dptr + strlen ( SECDESC_PREFIX ) , dbuf . dptr , dbuf . dsize ) ;
SAFE_FREE ( dbuf . dptr ) ;
continue ;
}
2010-05-13 02:05:40 +04:00
}
ret = 0 ;
done :
2013-03-12 21:42:02 +04:00
lp_set_cmdline ( " dos charset " , save_dos_charset ) ;
2010-05-13 02:05:40 +04:00
talloc_free ( ctx ) ;
return ret ;
}
2010-05-17 16:01:18 +04:00
static NTSTATUS printing_migrate_internal ( struct net_context * c ,
2010-05-21 05:25:01 +04:00
const struct dom_sid * domain_sid ,
2010-05-17 16:01:18 +04:00
const char * domain_name ,
struct cli_state * cli ,
2011-07-05 04:33:23 +04:00
struct rpc_pipe_client * winreg_pipe ,
2010-05-17 16:01:18 +04:00
TALLOC_CTX * mem_ctx ,
int argc ,
const char * * argv )
{
2013-03-12 14:39:08 +04:00
struct printing_opts * o ;
2010-05-17 16:01:18 +04:00
TALLOC_CTX * tmp_ctx ;
TDB_CONTEXT * tdb ;
2015-03-12 17:14:24 +03:00
TDB_DATA kbuf , newkey , dbuf ;
2010-05-17 16:01:18 +04:00
NTSTATUS status ;
2013-03-12 14:39:08 +04:00
const char * save_dos_charset = lp_dos_charset ( ) ;
bool do_string_conversion = false ;
2010-05-17 16:01:18 +04:00
tmp_ctx = talloc_new ( mem_ctx ) ;
if ( tmp_ctx = = NULL ) {
return NT_STATUS_NO_MEMORY ;
}
2013-03-12 14:39:08 +04:00
status = printing_parse_args ( tmp_ctx , & o , argc , argv ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
d_fprintf ( stderr , _ ( " failed to parse arguments \n " ) ) ;
goto done ;
}
tdb = tdb_open_log ( o - > tdb , 0 , TDB_DEFAULT , O_RDONLY , 0600 ) ;
2010-05-17 16:01:18 +04:00
if ( tdb = = NULL ) {
2013-03-12 14:39:08 +04:00
d_fprintf ( stderr , _ ( " failed to open tdb file: %s \n " ) , o - > tdb ) ;
2010-05-17 16:01:18 +04:00
status = NT_STATUS_NO_SUCH_FILE ;
goto done ;
}
2013-03-12 14:39:08 +04:00
if ( o - > encoding ! = NULL ) {
lp_set_cmdline ( " dos charset " , o - > encoding ) ;
d_fprintf ( stderr , _ ( " do string conversion from %s to %s \n " ) ,
lp_dos_charset ( ) , lp_unix_charset ( ) ) ;
do_string_conversion = true ;
}
2015-03-12 17:14:24 +03:00
for ( kbuf = tdb_firstkey ( tdb ) ;
2010-05-17 16:01:18 +04:00
kbuf . dptr ;
2015-03-12 17:14:24 +03:00
newkey = tdb_nextkey ( tdb , kbuf ) , free ( kbuf . dptr ) , kbuf = newkey )
2010-05-17 16:01:18 +04:00
{
2016-05-18 18:04:38 +03:00
int cmp ;
2015-03-12 17:23:17 +03:00
dbuf = tdb_fetch ( tdb , kbuf ) ;
2010-05-17 16:01:18 +04:00
if ( ! dbuf . dptr ) {
continue ;
}
2016-05-18 18:04:38 +03:00
cmp = strncmp ( ( const char * ) kbuf . dptr ,
FORMS_PREFIX ,
FORMS_PREFIX_LEN ) ;
if ( cmp = = 0 ) {
2016-05-18 17:51:45 +03:00
char * key_name = NULL ;
size_t converted_size = 0 ;
bool ok ;
ok = pull_ascii_talloc ( tmp_ctx ,
& key_name ,
( const char * ) kbuf . dptr + strlen ( FORMS_PREFIX ) ,
& converted_size ) ;
if ( ! ok ) {
continue ;
}
2011-07-01 17:02:26 +04:00
printing_tdb_migrate_form ( tmp_ctx ,
2011-07-01 17:39:11 +04:00
winreg_pipe ,
2016-05-18 17:51:45 +03:00
key_name ,
2010-05-17 16:01:18 +04:00
dbuf . dptr ,
dbuf . dsize ) ;
2016-05-18 17:51:45 +03:00
TALLOC_FREE ( key_name ) ;
2010-05-17 16:01:18 +04:00
SAFE_FREE ( dbuf . dptr ) ;
continue ;
}
2016-05-18 18:04:38 +03:00
cmp = strncmp ( ( const char * ) kbuf . dptr ,
DRIVERS_PREFIX ,
DRIVERS_PREFIX_LEN ) ;
if ( cmp = = 0 ) {
2016-05-18 17:51:45 +03:00
char * key_name = NULL ;
size_t converted_size = 0 ;
bool ok ;
ok = pull_ascii_talloc ( tmp_ctx ,
& key_name ,
( const char * ) kbuf . dptr + strlen ( DRIVERS_PREFIX ) ,
& converted_size ) ;
if ( ! ok ) {
continue ;
}
2011-07-01 17:02:26 +04:00
printing_tdb_migrate_driver ( tmp_ctx ,
2011-07-01 17:39:11 +04:00
winreg_pipe ,
2016-05-18 17:51:45 +03:00
key_name ,
2010-05-17 16:01:18 +04:00
dbuf . dptr ,
2013-03-12 14:39:08 +04:00
dbuf . dsize ,
do_string_conversion ) ;
2016-05-18 17:51:45 +03:00
TALLOC_FREE ( key_name ) ;
2010-05-17 16:01:18 +04:00
SAFE_FREE ( dbuf . dptr ) ;
continue ;
}
2016-05-18 18:04:38 +03:00
cmp = strncmp ( ( const char * ) kbuf . dptr ,
PRINTERS_PREFIX ,
PRINTERS_PREFIX_LEN ) ;
if ( cmp = = 0 ) {
2016-05-18 17:51:45 +03:00
char * key_name = NULL ;
size_t converted_size = 0 ;
bool ok ;
ok = pull_ascii_talloc ( tmp_ctx ,
& key_name ,
( const char * ) kbuf . dptr + strlen ( PRINTERS_PREFIX ) ,
& converted_size ) ;
if ( ! ok ) {
continue ;
}
2011-07-01 17:02:26 +04:00
printing_tdb_migrate_printer ( tmp_ctx ,
2011-07-01 17:39:11 +04:00
winreg_pipe ,
2016-05-18 17:51:45 +03:00
key_name ,
2010-05-17 16:01:18 +04:00
dbuf . dptr ,
2013-03-12 14:39:08 +04:00
dbuf . dsize ,
do_string_conversion ) ;
2016-05-18 17:51:45 +03:00
TALLOC_FREE ( key_name ) ;
2010-05-17 16:01:18 +04:00
SAFE_FREE ( dbuf . dptr ) ;
continue ;
}
2011-07-05 16:01:40 +04:00
SAFE_FREE ( dbuf . dptr ) ;
}
2015-03-12 17:14:24 +03:00
for ( kbuf = tdb_firstkey ( tdb ) ;
2011-07-05 16:01:40 +04:00
kbuf . dptr ;
2015-03-12 17:14:24 +03:00
newkey = tdb_nextkey ( tdb , kbuf ) , free ( kbuf . dptr ) , kbuf = newkey )
2011-07-05 16:01:40 +04:00
{
2015-03-12 17:23:17 +03:00
dbuf = tdb_fetch ( tdb , kbuf ) ;
2011-07-05 16:01:40 +04:00
if ( ! dbuf . dptr ) {
continue ;
}
2010-05-17 16:01:18 +04:00
if ( strncmp ( ( const char * ) kbuf . dptr , SECDESC_PREFIX , strlen ( SECDESC_PREFIX ) ) = = 0 ) {
2011-07-01 17:02:26 +04:00
printing_tdb_migrate_secdesc ( tmp_ctx ,
2011-07-01 17:39:11 +04:00
winreg_pipe ,
2010-05-17 16:01:18 +04:00
( const char * ) kbuf . dptr + strlen ( SECDESC_PREFIX ) ,
dbuf . dptr ,
dbuf . dsize ) ;
SAFE_FREE ( dbuf . dptr ) ;
continue ;
}
2011-07-05 16:01:40 +04:00
SAFE_FREE ( dbuf . dptr ) ;
2010-05-17 16:01:18 +04:00
}
status = NT_STATUS_OK ;
done :
2013-03-12 14:39:08 +04:00
lp_set_cmdline ( " dos charset " , save_dos_charset ) ;
2010-05-17 16:01:18 +04:00
talloc_free ( tmp_ctx ) ;
return status ;
}
static int net_printing_migrate ( struct net_context * c ,
int argc ,
const char * * argv )
{
if ( argc < 1 | | c - > display_usage ) {
d_printf ( " %s \n "
2013-03-12 14:39:08 +04:00
" net printing migrate [options] <file.tdb> \n "
2010-05-17 16:01:18 +04:00
" %s \n " ,
_ ( " Usage: " ) ,
_ ( " Migrate tdb printing files to new storage " ) ) ;
2013-03-12 14:39:08 +04:00
d_printf ( _ ( " Valid options: \n " ) ) ;
d_printf ( _ ( " encoding=<CP> Set the Code Page of the tdb file. \n "
" See iconv -l for the list of CP values \n "
" (CP1252 is Western latin1, CP1251 is Cyrillic). \n " ) ) ;
2010-05-17 16:01:18 +04:00
return 0 ;
}
return run_rpc_command ( c ,
NULL ,
2012-01-10 14:53:42 +04:00
& ndr_table_winreg ,
2010-05-17 16:01:18 +04:00
0 ,
printing_migrate_internal ,
argc ,
argv ) ;
}
2010-05-13 02:05:40 +04:00
/**
* ' net printing ' entrypoint .
* @ param argc Standard main ( ) style argc .
* @ param argv Standard main ( ) style argv . Initial components are already
* stripped .
* */
int net_printing ( struct net_context * c , int argc , const char * * argv )
{
int ret = - 1 ;
struct functable func [ ] = {
{
" dump " ,
net_printing_dump ,
NET_TRANSPORT_LOCAL ,
2010-08-06 19:38:15 +04:00
N_ ( " Dump printer databases " ) ,
2010-05-13 02:05:40 +04:00
N_ ( " net printing dump \n "
" Dump tdb printing file " )
} ,
2010-05-17 16:01:18 +04:00
{
" migrate " ,
net_printing_migrate ,
NET_TRANSPORT_LOCAL | NET_TRANSPORT_RPC ,
N_ ( " Migrate printer databases " ) ,
N_ ( " net printing migrate \n "
" Migrate tdb printing files to new storage " )
} ,
2010-05-13 02:05:40 +04:00
{ NULL , NULL , 0 , NULL , NULL }
} ;
ret = net_run_function ( c , argc , argv , " net printing " , func ) ;
return ret ;
}