2007-12-06 17:16:33 -08:00
/*
2002-01-30 06:08:46 +00:00
Unix SMB / CIFS implementation .
1996-05-04 07:50:46 +00:00
SMB client
2005-02-23 17:29:28 +00:00
Copyright ( C ) Andrew Tridgell 1994 - 1998
Copyright ( C ) Simo Sorce 2001 - 2002
Copyright ( C ) Jelmer Vernooij 2003
Copyright ( C ) Gerald ( Jerry ) Carter 2004
2007-12-06 17:16:33 -08:00
Copyright ( C ) Jeremy Allison 1994 - 2007
1996-05-04 07:50:46 +00:00
This program is free software ; you can redistribute it and / or modify
it under the terms of the GNU General Public License as published by
2007-07-09 19:25:36 +00:00
the Free Software Foundation ; either version 3 of the License , or
1996-05-04 07:50:46 +00:00
( at your option ) any later version .
2007-12-06 17:16:33 -08:00
1996-05-04 07:50:46 +00: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 .
2007-12-06 17:16:33 -08:00
1996-05-04 07:50:46 +00:00
You should have received a copy of the GNU General Public License
2007-07-10 00:52:41 +00:00
along with this program . If not , see < http : //www.gnu.org/licenses/>.
1996-05-04 07:50:46 +00:00
*/
# include "includes.h"
2011-02-25 23:20:06 +01:00
# include "system/filesys.h"
2011-02-28 10:19:44 +01:00
# include "rpc_client/cli_pipe.h"
2004-10-07 04:01:18 +00:00
# include "client/client_proto.h"
2013-07-08 18:09:47 +02:00
# include "client/clitar_proto.h"
2011-01-12 12:56:55 +01:00
# include "../librpc/gen_ndr/ndr_srvsvc_c.h"
2010-10-01 10:08:15 +02:00
# include "../lib/util/select.h"
2010-10-01 10:34:14 +02:00
# include "system/readline.h"
# include "../libcli/smbreadline/smbreadline.h"
2010-10-12 15:27:50 +11:00
# include "../libcli/security/security.h"
2011-02-08 17:56:10 +01:00
# include "system/select.h"
2011-05-06 11:47:43 +02:00
# include "libsmb/libsmb.h"
2011-02-24 10:46:55 +01:00
# include "libsmb/clirap.h"
2011-02-25 00:03:01 +01:00
# include "trans2.h"
2011-03-23 14:18:59 +01:00
# include "libsmb/nmblib.h"
2011-06-23 16:54:50 +02:00
# include "include/ntioctl.h"
2012-05-19 17:31:50 +02:00
# include "../libcli/smb/smbXcli_base.h"
2019-12-01 09:01:20 +01:00
# include "lib/util/time_basic.h"
2020-08-07 11:17:34 -07:00
# include "lib/util/string_wrappers.h"
2020-08-18 16:58:19 +02:00
# include "lib/cmdline/cmdline.h"
2009-11-26 18:21:28 +01:00
1996-05-04 07:50:46 +00:00
# ifndef REGISTER
# define REGISTER 0
# endif
2007-12-17 22:09:09 -08:00
extern int do_smb_browse ( void ) ; /* mDNS browsing */
2001-08-24 20:11:09 +00:00
static int port = 0 ;
2007-12-06 17:16:33 -08:00
static char * service ;
static char * desthost ;
static bool grepable = false ;
2018-06-25 09:58:56 -04:00
static bool quiet = false ;
2003-04-14 04:05:48 +00:00
static char * cmdstr = NULL ;
2008-06-17 21:08:56 +02:00
const char * cmd_ptr = NULL ;
2003-04-14 04:05:48 +00:00
2013-08-14 10:46:28 +02:00
static int io_bufsize = 0 ; /* we use the default size */
2013-08-16 13:49:39 -07:00
static int io_timeout = ( CLIENT_TIMEOUT / 1000 ) ; /* Per operation timeout (in seconds). */
1996-05-04 07:50:46 +00:00
1998-11-09 03:45:49 +00:00
static int name_type = 0x20 ;
1996-05-04 07:50:46 +00:00
2007-12-06 17:16:33 -08:00
static int process_tok ( char * tok ) ;
2001-10-09 19:12:18 +00:00
static int cmd_help ( void ) ;
1998-09-05 05:07:05 +00:00
1996-05-04 07:50:46 +00:00
/* value for unused fid field in trans2 secondary request */
# define FID_UNUSED (0xFFFF)
time_t newer_than = 0 ;
2002-07-15 10:35:28 +00:00
static int archive_level = 0 ;
1996-05-04 07:50:46 +00:00
2007-12-06 17:16:33 -08:00
static bool translation = false ;
2007-10-18 17:40:25 -07:00
static bool have_ip ;
1996-06-04 06:42:03 +00:00
2007-12-06 17:16:33 -08:00
static bool prompt = true ;
1996-05-04 07:50:46 +00:00
2007-12-06 17:16:33 -08:00
static bool recurse = false ;
static bool showacls = false ;
bool lowercase = false ;
2011-12-01 13:47:12 -08:00
static bool backup_intent = false ;
1996-05-04 07:50:46 +00:00
2007-10-24 14:16:54 -07:00
static struct sockaddr_storage dest_ss ;
2009-01-02 12:49:49 -08:00
static char dest_ss_str [ INET6_ADDRSTRLEN ] ;
1996-05-04 07:50:46 +00:00
# define SEPARATORS " \t\n\r"
/* timing globals */
2008-10-14 01:59:36 +02:00
uint64_t get_total_size = 0 ;
2002-11-09 16:57:45 +00:00
unsigned int get_total_time_ms = 0 ;
2008-10-14 01:59:36 +02:00
static uint64_t put_total_size = 0 ;
2002-11-09 16:57:45 +00:00
static unsigned int put_total_time_ms = 0 ;
1996-05-04 07:50:46 +00:00
1997-07-28 18:59:57 +00:00
/* totals globals */
1999-03-30 10:25:20 +00:00
static double dir_total ;
1996-05-04 07:50:46 +00:00
2005-02-24 21:54:52 +00:00
/* root cli_state connection */
2005-02-22 03:31:22 +00:00
struct cli_state * cli ;
2006-07-12 03:20:53 +00:00
static char CLI_DIRSEP_CHAR = ' \\ ' ;
static char CLI_DIRSEP_STR [ ] = { ' \\ ' , ' \0 ' } ;
2005-02-23 17:29:28 +00:00
2007-12-06 17:16:33 -08:00
/* Accessor functions for directory paths. */
static char * fileselection ;
static const char * client_get_fileselection ( void )
{
if ( fileselection ) {
return fileselection ;
}
return " " ;
}
static const char * client_set_fileselection ( const char * new_fs )
{
SAFE_FREE ( fileselection ) ;
if ( new_fs ) {
fileselection = SMB_STRDUP ( new_fs ) ;
}
return client_get_fileselection ( ) ;
}
static char * cwd ;
static const char * client_get_cwd ( void )
{
if ( cwd ) {
return cwd ;
}
return CLI_DIRSEP_STR ;
}
static const char * client_set_cwd ( const char * new_cwd )
{
SAFE_FREE ( cwd ) ;
if ( new_cwd ) {
cwd = SMB_STRDUP ( new_cwd ) ;
}
return client_get_cwd ( ) ;
}
static char * cur_dir ;
const char * client_get_cur_dir ( void )
{
if ( cur_dir ) {
return cur_dir ;
}
return CLI_DIRSEP_STR ;
}
const char * client_set_cur_dir ( const char * newdir )
{
SAFE_FREE ( cur_dir ) ;
if ( newdir ) {
cur_dir = SMB_STRDUP ( newdir ) ;
}
return client_get_cur_dir ( ) ;
}
2010-01-21 12:57:07 +01:00
/****************************************************************************
Put up a yes / no prompt .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static bool yesno ( const char * p )
{
char ans [ 20 ] ;
printf ( " %s " , p ) ;
if ( ! fgets ( ans , sizeof ( ans ) - 1 , stdin ) )
return ( False ) ;
if ( * ans = = ' y ' | | * ans = = ' Y ' )
return ( True ) ;
return ( False ) ;
}
1996-05-04 07:50:46 +00:00
/****************************************************************************
2007-12-06 17:16:33 -08:00
Write to a local file with CR / LF - > LF translation if appropriate . Return the
2003-08-06 20:01:31 +00:00
number taken from the buffer . This may not equal the number written .
1996-05-04 07:50:46 +00:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2003-08-06 20:01:31 +00:00
2018-03-22 14:51:28 +01:00
static ssize_t writefile ( int f , char * b , size_t n )
1996-05-04 07:50:46 +00:00
{
2018-03-22 14:51:28 +01:00
size_t i = 0 ;
if ( n = = 0 ) {
errno = EINVAL ;
return - 1 ;
}
1996-05-04 07:50:46 +00:00
1998-11-09 03:45:49 +00:00
if ( ! translation ) {
return write ( f , b , n ) ;
1996-05-04 07:50:46 +00:00
}
1998-11-09 03:45:49 +00:00
2018-03-22 14:51:28 +01:00
do {
1998-11-09 03:45:49 +00:00
if ( * b = = ' \r ' & & ( i < ( n - 1 ) ) & & * ( b + 1 ) = = ' \n ' ) {
b + + ; i + + ;
}
if ( write ( f , b , 1 ) ! = 1 ) {
break ;
}
b + + ;
i + + ;
2018-03-22 14:51:28 +01:00
} while ( i < n ) ;
2007-12-06 17:16:33 -08:00
2018-03-22 14:51:28 +01:00
return ( ssize_t ) i ;
1996-05-04 07:50:46 +00:00
}
/****************************************************************************
2007-12-06 17:16:33 -08:00
Read from a file with LF - > CR / LF translation if appropriate . Return the
2003-08-06 20:01:31 +00:00
number read . read approx n bytes .
1996-05-04 07:50:46 +00:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2003-08-06 20:01:31 +00:00
2016-11-22 01:59:22 +01:00
static int readfile ( uint8_t * b , int n , FILE * f )
1996-05-04 07:50:46 +00:00
{
1998-11-09 03:45:49 +00:00
int i ;
int c ;
1996-05-04 07:50:46 +00:00
2001-09-09 03:18:23 +00:00
if ( ! translation )
2016-11-22 01:59:22 +01:00
return fread ( b , 1 , n , f ) ;
2007-12-06 17:16:33 -08:00
1998-11-09 03:45:49 +00:00
i = 0 ;
2014-02-19 13:57:28 +01:00
while ( i < ( n - 1 ) ) {
2016-11-22 01:59:22 +01:00
if ( ( c = getc ( f ) ) = = EOF ) {
1998-11-09 03:45:49 +00:00
break ;
}
2007-12-06 17:16:33 -08:00
1998-11-09 03:45:49 +00:00
if ( c = = ' \n ' ) { /* change all LFs to CR/LF */
b [ i + + ] = ' \r ' ;
}
2007-12-06 17:16:33 -08:00
1999-12-13 13:27:58 +00:00
b [ i + + ] = c ;
1998-11-09 03:45:49 +00:00
}
2007-12-06 17:16:33 -08:00
1998-11-09 03:45:49 +00:00
return ( i ) ;
1996-05-04 07:50:46 +00:00
}
2007-12-06 17:16:33 -08:00
2008-12-19 23:33:55 +01:00
struct push_state {
2016-11-22 01:59:22 +01:00
FILE * f ;
2012-04-05 14:53:08 +10:00
off_t nread ;
2008-12-19 23:33:55 +01:00
} ;
2009-03-12 09:02:02 +01:00
static size_t push_source ( uint8_t * buf , size_t n , void * priv )
2008-12-19 23:33:55 +01:00
{
struct push_state * state = ( struct push_state * ) priv ;
int result ;
2016-11-22 01:59:22 +01:00
if ( feof ( state - > f ) ) {
2008-12-19 23:33:55 +01:00
return 0 ;
}
2009-03-12 09:02:02 +01:00
result = readfile ( buf , n , state - > f ) ;
2008-12-19 23:33:55 +01:00
state - > nread + = result ;
return result ;
}
1996-05-04 07:50:46 +00:00
/****************************************************************************
2003-08-06 20:01:31 +00:00
Send a message .
1996-05-04 07:50:46 +00:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2003-08-06 20:01:31 +00:00
2008-12-14 13:06:19 +01:00
static void send_message ( const char * username )
1996-05-04 07:50:46 +00:00
{
2009-11-10 19:49:41 +01:00
char buf [ 1600 ] ;
NTSTATUS status ;
2020-06-05 07:56:27 +02:00
size_t i ;
1996-05-04 07:50:46 +00:00
2009-11-10 19:49:41 +01:00
d_printf ( " Type your message, ending it with a Control-D \n " ) ;
1996-05-04 07:50:46 +00:00
2009-11-10 19:49:41 +01:00
i = 0 ;
while ( i < sizeof ( buf ) - 2 ) {
int c = fgetc ( stdin ) ;
if ( c = = EOF ) {
2007-09-14 18:31:33 +00:00
break ;
}
2009-11-10 19:49:41 +01:00
if ( c = = ' \n ' ) {
buf [ i + + ] = ' \r ' ;
2007-12-06 17:16:33 -08:00
}
2009-11-10 19:49:41 +01:00
buf [ i + + ] = c ;
1996-05-04 07:50:46 +00:00
}
2009-11-10 19:49:41 +01:00
buf [ i ] = ' \0 ' ;
1996-05-04 07:50:46 +00:00
2009-11-10 19:49:41 +01:00
status = cli_message ( cli , desthost , username , buf ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
d_fprintf ( stderr , " cli_message returned %s \n " ,
nt_errstr ( status ) ) ;
2007-12-06 17:16:33 -08:00
}
1996-05-04 07:50:46 +00:00
}
/****************************************************************************
2003-08-06 20:01:31 +00:00
Check the space on a device .
1996-05-04 07:50:46 +00:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2003-08-06 20:01:31 +00:00
2001-10-09 19:12:18 +00:00
static int do_dskattr ( void )
1996-05-04 07:50:46 +00:00
{
2014-06-04 14:12:38 -07:00
uint64_t total , bsize , avail ;
2007-12-06 17:16:33 -08:00
struct cli_state * targetcli = NULL ;
char * targetpath = NULL ;
TALLOC_CTX * ctx = talloc_tos ( ) ;
2020-08-18 16:58:19 +02:00
struct cli_credentials * creds = samba_cmdline_get_creds ( ) ;
2010-08-13 15:08:38 +02:00
NTSTATUS status ;
2005-02-23 17:29:28 +00:00
2020-08-18 17:42:25 +02:00
status = cli_resolve_path ( ctx ,
" " ,
creds ,
cli ,
2011-07-03 20:53:55 +02:00
client_get_cur_dir ( ) , & targetcli ,
& targetpath ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
2011-07-05 19:42:46 +02:00
d_printf ( " Error in dskattr: %s \n " , nt_errstr ( status ) ) ;
2005-03-22 23:18:41 +00:00
return 1 ;
2005-02-23 17:29:28 +00:00
}
1996-05-04 07:50:46 +00:00
2016-01-06 00:08:25 +02:00
status = cli_disk_size ( targetcli , targetpath , & bsize , & total , & avail ) ;
2010-08-13 15:08:38 +02:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
d_printf ( " Error in dskattr: %s \n " , nt_errstr ( status ) ) ;
2001-10-09 19:12:18 +00:00
return 1 ;
1998-11-09 03:45:49 +00:00
}
1996-05-04 07:50:46 +00:00
2014-06-04 14:12:38 -07:00
d_printf ( " \n \t \t % " PRIu64
" blocks of size % " PRIu64
" . % " PRIu64 " blocks available \n " ,
total , bsize , avail ) ;
2001-10-09 19:12:18 +00:00
return 0 ;
1996-05-04 07:50:46 +00:00
}
/****************************************************************************
2003-08-06 20:01:31 +00:00
Show cd / pwd .
1996-05-04 07:50:46 +00:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2003-08-06 20:01:31 +00:00
2001-10-09 19:12:18 +00:00
static int cmd_pwd ( void )
1996-05-04 07:50:46 +00:00
{
2001-09-07 14:14:57 +00:00
d_printf ( " Current directory is %s " , service ) ;
2007-12-06 17:16:33 -08:00
d_printf ( " %s \n " , client_get_cur_dir ( ) ) ;
2001-10-09 19:12:18 +00:00
return 0 ;
1996-05-04 07:50:46 +00:00
}
2008-02-08 16:59:52 -08:00
/****************************************************************************
Ensure name has correct directory separators .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static void normalize_name ( char * newdir )
{
2010-04-13 18:41:14 -07:00
if ( ! ( cli - > requested_posix_capabilities & CIFS_UNIX_POSIX_PATHNAMES_CAP ) ) {
2008-02-08 16:59:52 -08:00
string_replace ( newdir , ' / ' , ' \\ ' ) ;
}
}
2017-10-21 00:08:08 +00:00
/****************************************************************************
Local name cleanup before sending to server . SMB1 allows relative pathnames ,
but SMB2 does not , so we need to resolve them locally .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
char * client_clean_name ( TALLOC_CTX * ctx , const char * name )
{
char * newname = NULL ;
if ( name = = NULL ) {
return NULL ;
}
/* First ensure any path separators are correct. */
newname = talloc_strdup ( ctx , name ) ;
if ( newname = = NULL ) {
return NULL ;
}
normalize_name ( newname ) ;
/* Now remove any relative (..) path components. */
if ( cli - > requested_posix_capabilities & CIFS_UNIX_POSIX_PATHNAMES_CAP ) {
newname = unix_clean_name ( ctx , newname ) ;
} else {
newname = clean_name ( ctx , newname ) ;
}
if ( newname = = NULL ) {
return NULL ;
}
return newname ;
}
1996-05-04 07:50:46 +00:00
/****************************************************************************
2003-08-06 20:01:31 +00:00
Change directory - inner section .
1996-05-04 07:50:46 +00:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2003-08-06 20:01:31 +00:00
2007-12-06 17:16:33 -08:00
static int do_cd ( const char * new_dir )
1996-05-04 07:50:46 +00:00
{
2007-12-06 17:16:33 -08:00
char * newdir = NULL ;
char * saved_dir = NULL ;
char * new_cd = NULL ;
char * targetpath = NULL ;
struct cli_state * targetcli = NULL ;
2005-04-15 00:39:03 +00:00
int ret = 1 ;
2007-12-06 17:16:33 -08:00
TALLOC_CTX * ctx = talloc_stackframe ( ) ;
2020-08-18 16:58:19 +02:00
struct cli_credentials * creds = samba_cmdline_get_creds ( ) ;
2011-07-03 20:53:55 +02:00
NTSTATUS status ;
2007-12-06 17:16:33 -08:00
newdir = talloc_strdup ( ctx , new_dir ) ;
if ( ! newdir ) {
TALLOC_FREE ( ctx ) ;
return 1 ;
}
2008-02-08 16:59:52 -08:00
normalize_name ( newdir ) ;
1998-11-09 03:45:49 +00:00
2005-02-23 17:29:28 +00:00
/* Save the current directory in case the new directory is invalid */
2007-12-06 17:16:33 -08:00
saved_dir = talloc_strdup ( ctx , client_get_cur_dir ( ) ) ;
if ( ! saved_dir ) {
TALLOC_FREE ( ctx ) ;
return 1 ;
}
2005-02-23 17:29:28 +00:00
2007-12-06 17:16:33 -08:00
if ( * newdir = = CLI_DIRSEP_CHAR ) {
client_set_cur_dir ( newdir ) ;
new_cd = newdir ;
2007-03-08 23:54:57 +00:00
} else {
2007-12-06 17:16:33 -08:00
new_cd = talloc_asprintf ( ctx , " %s%s " ,
client_get_cur_dir ( ) ,
newdir ) ;
if ( ! new_cd ) {
goto out ;
}
1998-11-09 03:45:49 +00:00
}
2008-02-08 16:59:52 -08:00
/* Ensure cur_dir ends in a DIRSEP */
if ( ( new_cd [ 0 ] ! = ' \0 ' ) & & ( * ( new_cd + strlen ( new_cd ) - 1 ) ! = CLI_DIRSEP_CHAR ) ) {
2008-12-31 16:30:11 -08:00
new_cd = talloc_asprintf_append ( new_cd , " %s " , CLI_DIRSEP_STR ) ;
2008-02-08 16:59:52 -08:00
if ( ! new_cd ) {
goto out ;
}
2007-12-06 17:16:33 -08:00
}
2008-02-08 16:59:52 -08:00
client_set_cur_dir ( new_cd ) ;
2007-12-06 17:16:33 -08:00
2017-10-20 15:09:38 -07:00
new_cd = client_clean_name ( ctx , new_cd ) ;
2007-12-06 17:16:33 -08:00
client_set_cur_dir ( new_cd ) ;
2020-08-18 17:42:25 +02:00
status = cli_resolve_path ( ctx , " " ,
creds ,
2017-04-25 17:03:10 -07:00
cli , new_cd , & targetcli , & targetpath ) ;
2011-07-03 20:53:55 +02:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
2011-07-05 19:42:46 +02:00
d_printf ( " cd %s: %s \n " , new_cd , nt_errstr ( status ) ) ;
2007-12-06 17:16:33 -08:00
client_set_cur_dir ( saved_dir ) ;
2005-02-24 19:10:28 +00:00
goto out ;
2005-02-23 17:29:28 +00:00
}
2007-03-08 23:54:57 +00:00
if ( strequal ( targetpath , CLI_DIRSEP_STR ) ) {
2007-12-06 17:16:33 -08:00
TALLOC_FREE ( ctx ) ;
2007-03-08 23:54:57 +00:00
return 0 ;
}
2007-12-06 17:16:33 -08:00
2021-10-26 10:14:28 +02:00
targetpath = talloc_asprintf (
ctx , " %s%s " , targetpath , CLI_DIRSEP_STR ) ;
if ( ! targetpath ) {
client_set_cur_dir ( saved_dir ) ;
goto out ;
}
targetpath = client_clean_name ( ctx , targetpath ) ;
if ( ! targetpath ) {
client_set_cur_dir ( saved_dir ) ;
goto out ;
}
2007-12-06 17:16:33 -08:00
2021-10-26 10:14:28 +02:00
status = cli_chkpath ( targetcli , targetpath ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
d_printf ( " cd %s: %s \n " , new_cd , nt_errstr ( status ) ) ;
client_set_cur_dir ( saved_dir ) ;
goto out ;
1998-11-09 03:45:49 +00:00
}
2005-02-23 17:29:28 +00:00
2005-04-15 00:39:03 +00:00
ret = 0 ;
2005-02-24 19:10:28 +00:00
out :
2007-12-06 17:16:33 -08:00
TALLOC_FREE ( ctx ) ;
2005-04-15 00:39:03 +00:00
return ret ;
1996-05-04 07:50:46 +00:00
}
/****************************************************************************
2003-08-06 20:01:31 +00:00
Change directory .
1996-05-04 07:50:46 +00:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2003-08-06 20:01:31 +00:00
2001-10-09 19:12:18 +00:00
static int cmd_cd ( void )
1996-05-04 07:50:46 +00:00
{
2007-12-06 17:16:33 -08:00
char * buf = NULL ;
2001-10-09 19:12:18 +00:00
int rc = 0 ;
2007-12-06 17:16:33 -08:00
2007-12-19 21:59:28 +01:00
if ( next_token_talloc ( talloc_tos ( ) , & cmd_ptr , & buf , NULL ) ) {
2001-10-09 19:12:18 +00:00
rc = do_cd ( buf ) ;
2007-12-06 17:16:33 -08:00
} else {
d_printf ( " Current directory is %s \n " , client_get_cur_dir ( ) ) ;
}
2001-10-09 19:12:18 +00:00
return rc ;
1996-05-04 07:50:46 +00:00
}
2007-07-11 08:43:08 +00:00
/****************************************************************************
Change directory .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static int cmd_cd_oneup ( void )
{
2007-12-06 17:16:33 -08:00
return do_cd ( " .. " ) ;
2007-07-11 08:43:08 +00:00
}
1998-11-09 03:45:49 +00:00
/*******************************************************************
2003-08-06 20:01:31 +00:00
Decide if a file should be operated on .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2010-07-27 10:59:55 +02:00
static bool do_this_one ( struct file_info * finfo )
1998-11-09 03:45:49 +00:00
{
2007-12-06 17:16:33 -08:00
if ( ! finfo - > name ) {
return false ;
}
1998-11-09 03:45:49 +00:00
2020-06-03 10:41:27 -07:00
if ( finfo - > attr & FILE_ATTRIBUTE_DIRECTORY ) {
2007-12-06 17:16:33 -08:00
return true ;
}
if ( * client_get_fileselection ( ) & &
2009-11-23 16:34:07 +01:00
! mask_match ( finfo - > name , client_get_fileselection ( ) , false ) ) {
2002-09-25 15:19:00 +00:00
DEBUG ( 3 , ( " mask_match %s failed \n " , finfo - > name ) ) ;
2007-12-06 17:16:33 -08:00
return false ;
1998-11-09 03:45:49 +00:00
}
2006-08-24 16:44:00 +00:00
if ( newer_than & & finfo - > mtime_ts . tv_sec < newer_than ) {
1998-11-09 03:45:49 +00:00
DEBUG ( 3 , ( " newer_than %s failed \n " , finfo - > name ) ) ;
2007-12-06 17:16:33 -08:00
return false ;
1998-11-09 03:45:49 +00:00
}
2020-06-03 10:41:27 -07:00
if ( ( archive_level = = 1 | | archive_level = = 2 ) & & ! ( finfo - > attr & FILE_ATTRIBUTE_ARCHIVE ) ) {
1998-11-09 03:45:49 +00:00
DEBUG ( 3 , ( " archive %s failed \n " , finfo - > name ) ) ;
2007-12-06 17:16:33 -08:00
return false ;
1998-11-09 03:45:49 +00:00
}
2007-12-06 17:16:33 -08:00
return true ;
1998-11-09 03:45:49 +00:00
}
1996-05-04 07:50:46 +00:00
/****************************************************************************
2003-08-06 20:01:31 +00:00
Display info about a file .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2010-10-29 11:56:51 -07:00
static NTSTATUS display_finfo ( struct cli_state * cli_state , struct file_info * finfo ,
2010-07-30 16:18:51 +02:00
const char * dir )
1996-05-04 07:50:46 +00:00
{
2007-12-06 17:16:33 -08:00
time_t t ;
TALLOC_CTX * ctx = talloc_tos ( ) ;
2010-10-29 11:56:51 -07:00
NTSTATUS status = NT_STATUS_OK ;
2006-11-01 17:18:08 +00:00
2007-12-06 17:16:33 -08:00
if ( ! do_this_one ( finfo ) ) {
2010-10-29 11:56:51 -07:00
return NT_STATUS_OK ;
2007-12-06 17:16:33 -08:00
}
t = finfo - > mtime_ts . tv_sec ; /* the time is assumed to be passed as GMT */
if ( ! showacls ) {
d_printf ( " %-30s%7.7s %8.0f %s " ,
finfo - > name ,
2020-06-03 10:41:27 -07:00
attrib_string ( talloc_tos ( ) , finfo - > attr ) ,
2007-12-06 17:16:33 -08:00
( double ) finfo - > size ,
time_to_asc ( t ) ) ;
dir_total + = finfo - > size ;
} else {
2020-10-19 09:37:03 +02:00
struct cli_state * targetcli = NULL ;
char * targetpath = NULL ;
2007-12-06 17:16:33 -08:00
char * afname = NULL ;
2009-04-30 15:26:43 -07:00
uint16_t fnum ;
2020-08-18 16:58:19 +02:00
struct cli_credentials * creds = samba_cmdline_get_creds ( ) ;
2007-12-06 17:16:33 -08:00
2022-03-12 12:40:29 +01:00
if ( ISDOT ( finfo - > name ) | | ISDOTDOT ( finfo - > name ) ) {
2010-10-29 11:56:51 -07:00
return NT_STATUS_OK ;
2022-03-12 12:40:29 +01:00
}
2009-04-30 15:26:43 -07:00
/* create absolute filename for cli_ntcreate() FIXME */
2007-12-06 17:16:33 -08:00
afname = talloc_asprintf ( ctx ,
" %s%s%s " ,
2008-09-11 16:20:59 -07:00
dir ,
2007-12-06 17:16:33 -08:00
CLI_DIRSEP_STR ,
finfo - > name ) ;
if ( ! afname ) {
2010-10-29 11:56:51 -07:00
return NT_STATUS_NO_MEMORY ;
2007-12-06 17:16:33 -08:00
}
/* print file meta date header */
2008-09-11 17:32:14 -07:00
d_printf ( " FILENAME:%s \n " , finfo - > name ) ;
2020-06-03 10:41:27 -07:00
d_printf ( " MODE:%s \n " , attrib_string ( talloc_tos ( ) , finfo - > attr ) ) ;
2007-12-06 17:16:33 -08:00
d_printf ( " SIZE:%.0f \n " , ( double ) finfo - > size ) ;
d_printf ( " MTIME:%s " , time_to_asc ( t ) ) ;
2020-10-19 09:37:03 +02:00
status = cli_resolve_path (
ctx ,
" " ,
2020-08-18 16:58:19 +02:00
creds ,
2020-10-19 09:37:03 +02:00
cli_state ,
afname ,
& targetcli ,
& targetpath ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
DBG_WARNING ( " display_finfo() Failed to resolve "
" %s: %s \n " ,
afname , nt_errstr ( status ) ) ;
return status ;
}
2020-05-26 08:01:33 +02:00
status = cli_ntcreate (
2020-10-19 09:37:03 +02:00
targetcli , /* cli */
targetpath , /* fname */
2020-05-26 08:01:33 +02:00
0 , /* CreatFlags */
2020-05-26 08:04:52 +02:00
READ_CONTROL_ACCESS , /* DesiredAccess */
2020-05-26 08:01:33 +02:00
0 , /* FileAttributes */
FILE_SHARE_READ |
FILE_SHARE_WRITE , /* ShareAccess */
FILE_OPEN , /* CreateDisposition */
0x0 , /* CreateOptions */
0x0 , /* SecurityFlags */
& fnum , /* pfid */
NULL ) ; /* cr */
2010-08-13 15:08:38 +02:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
2007-12-06 17:16:33 -08:00
DEBUG ( 0 , ( " display_finfo() Failed to open %s: %s \n " ,
2010-08-13 15:08:38 +02:00
afname , nt_errstr ( status ) ) ) ;
2007-12-06 17:16:33 -08:00
} else {
2010-05-18 10:29:34 +02:00
struct security_descriptor * sd = NULL ;
2020-10-19 09:37:03 +02:00
status = cli_query_secdesc ( targetcli , fnum ,
2011-07-22 16:51:10 +02:00
ctx , & sd ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
2007-12-06 17:16:33 -08:00
DEBUG ( 0 , ( " display_finfo() failed to "
2011-07-22 16:51:10 +02:00
" get security descriptor: %s " ,
nt_errstr ( status ) ) ) ;
2006-11-01 17:18:08 +00:00
} else {
2007-12-06 17:16:33 -08:00
display_sec_desc ( sd ) ;
2006-11-01 17:18:08 +00:00
}
2007-12-06 17:16:33 -08:00
TALLOC_FREE ( sd ) ;
2006-11-01 17:18:08 +00:00
}
2007-12-06 17:16:33 -08:00
TALLOC_FREE ( afname ) ;
1998-11-09 03:45:49 +00:00
}
2010-10-29 11:56:51 -07:00
return status ;
1996-05-04 07:50:46 +00:00
}
1998-09-21 08:45:11 +00:00
/****************************************************************************
2003-08-06 20:01:31 +00:00
Accumulate size of a file .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2010-10-29 11:56:51 -07:00
static NTSTATUS do_du ( struct cli_state * cli_state , struct file_info * finfo ,
2010-07-30 16:18:51 +02:00
const char * dir )
1998-09-21 08:45:11 +00:00
{
1998-11-09 03:45:49 +00:00
if ( do_this_one ( finfo ) ) {
dir_total + = finfo - > size ;
}
2010-10-29 11:56:51 -07:00
return NT_STATUS_OK ;
1998-09-21 08:45:11 +00:00
}
2020-06-05 07:57:36 +02:00
struct do_list_queue_entry {
struct do_list_queue_entry * prev , * next ;
char name [ ] ;
} ;
struct do_list_queue {
struct do_list_queue_entry * list ;
} ;
2007-10-18 17:40:25 -07:00
static bool do_list_recurse ;
static bool do_list_dirs ;
2020-06-05 07:57:36 +02:00
static struct do_list_queue * queue = NULL ;
2010-10-29 11:56:51 -07:00
static NTSTATUS ( * do_list_fn ) ( struct cli_state * cli_state , struct file_info * ,
2010-07-30 16:18:51 +02:00
const char * dir ) ;
1998-09-21 08:45:11 +00:00
1999-12-13 13:27:58 +00:00
/****************************************************************************
2003-08-06 20:01:31 +00:00
Functions for do_list_queue .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
1999-12-13 13:27:58 +00:00
static void reset_do_list_queue ( void )
{
2020-06-05 07:57:36 +02:00
TALLOC_FREE ( queue ) ;
1999-12-13 13:27:58 +00:00
}
static void init_do_list_queue ( void )
{
2020-06-05 07:57:36 +02:00
TALLOC_FREE ( queue ) ;
queue = talloc_zero ( NULL , struct do_list_queue ) ;
1999-12-13 13:27:58 +00:00
}
2020-06-05 07:57:36 +02:00
static void add_to_do_list_queue ( const char * entry )
1999-12-13 13:27:58 +00:00
{
2020-06-05 07:57:36 +02:00
struct do_list_queue_entry * e = NULL ;
size_t entry_str_len = strlen ( entry ) + 1 ;
size_t entry_len = offsetof ( struct do_list_queue_entry , name ) ;
2007-12-06 17:16:33 -08:00
2020-06-05 07:57:36 +02:00
entry_len + = entry_str_len ;
SMB_ASSERT ( entry_len > = entry_str_len ) ;
1999-12-13 13:27:58 +00:00
2020-06-05 07:57:36 +02:00
e = talloc_size ( queue , entry_len ) ;
if ( e = = NULL ) {
d_printf ( " talloc failed for entry %s \n " , entry ) ;
return ;
1999-12-13 13:27:58 +00:00
}
2020-06-05 07:57:36 +02:00
talloc_set_name_const ( e , " struct do_list_queue_entry " ) ;
memcpy ( e - > name , entry , entry_str_len ) ;
DLIST_ADD_END ( queue - > list , e ) ;
1999-12-13 13:27:58 +00:00
}
static char * do_list_queue_head ( void )
{
2020-06-05 07:57:36 +02:00
return queue - > list - > name ;
1999-12-13 13:27:58 +00:00
}
static void remove_do_list_queue_head ( void )
{
2020-06-05 07:57:36 +02:00
struct do_list_queue_entry * e = queue - > list ;
DLIST_REMOVE ( queue - > list , e ) ;
TALLOC_FREE ( e ) ;
1999-12-13 13:27:58 +00:00
}
static int do_list_queue_empty ( void )
{
2020-06-05 07:57:36 +02:00
return ( queue = = NULL ) | | ( queue - > list = = NULL ) ;
1999-12-13 13:27:58 +00:00
}
1996-06-04 06:42:03 +00:00
/****************************************************************************
2003-08-06 20:01:31 +00:00
A helper for do_list .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2020-10-11 07:41:01 +02:00
struct do_list_helper_state {
2020-10-18 18:39:17 +02:00
const char * mask ;
2020-10-11 07:41:01 +02:00
struct cli_state * cli ;
} ;
2020-10-11 07:35:52 +02:00
static NTSTATUS do_list_helper (
struct file_info * f ,
2020-10-19 10:09:23 +02:00
const char * _mask ,
2020-10-11 07:41:01 +02:00
void * private_data )
1996-06-04 06:42:03 +00:00
{
2020-10-11 07:41:01 +02:00
struct do_list_helper_state * state = private_data ;
2007-12-06 17:16:33 -08:00
TALLOC_CTX * ctx = talloc_tos ( ) ;
char * dir = NULL ;
char * dir_end = NULL ;
2010-10-29 11:56:51 -07:00
NTSTATUS status = NT_STATUS_OK ;
2020-06-05 15:07:08 +02:00
char * mask2 = NULL ;
2005-10-13 15:51:25 +00:00
2007-12-06 17:16:33 -08:00
/* Work out the directory. */
2020-10-18 18:39:17 +02:00
dir = talloc_strdup ( ctx , state - > mask ) ;
2007-12-06 17:16:33 -08:00
if ( ! dir ) {
2010-10-29 11:56:51 -07:00
return NT_STATUS_NO_MEMORY ;
2007-12-06 17:16:33 -08:00
}
if ( ( dir_end = strrchr ( dir , CLI_DIRSEP_CHAR ) ) ! = NULL ) {
2005-10-13 15:51:25 +00:00
* dir_end = ' \0 ' ;
}
2020-06-05 14:54:22 +02:00
if ( ! ( f - > attr & FILE_ATTRIBUTE_DIRECTORY ) ) {
if ( do_this_one ( f ) ) {
2020-10-11 07:41:01 +02:00
status = do_list_fn ( state - > cli , f , dir ) ;
1998-11-09 03:45:49 +00:00
}
2020-06-05 14:54:22 +02:00
TALLOC_FREE ( dir ) ;
return status ;
}
if ( do_list_dirs & & do_this_one ( f ) ) {
2020-10-11 07:41:01 +02:00
status = do_list_fn ( state - > cli , f , dir ) ;
2020-06-05 14:54:22 +02:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
return status ;
}
}
2020-06-05 15:07:08 +02:00
if ( ! do_list_recurse | |
( f - > name = = NULL ) | |
ISDOT ( f - > name ) | |
ISDOTDOT ( f - > name ) ) {
return NT_STATUS_OK ;
}
if ( ! f - > name [ 0 ] ) {
d_printf ( " Empty dir name returned. Possible server misconfiguration. \n " ) ;
TALLOC_FREE ( dir ) ;
return NT_STATUS_UNSUCCESSFUL ;
1996-06-04 06:42:03 +00:00
}
2020-06-05 15:07:08 +02:00
mask2 = talloc_asprintf ( ctx ,
2020-10-19 09:37:03 +02:00
" %s%c%s%c* " ,
dir ,
CLI_DIRSEP_CHAR ,
f - > name ,
CLI_DIRSEP_CHAR ) ;
2020-06-05 15:07:08 +02:00
if ( ! mask2 ) {
TALLOC_FREE ( dir ) ;
return NT_STATUS_NO_MEMORY ;
}
add_to_do_list_queue ( mask2 ) ;
TALLOC_FREE ( mask2 ) ;
2007-12-06 17:16:33 -08:00
TALLOC_FREE ( dir ) ;
2020-06-05 14:54:22 +02:00
return NT_STATUS_OK ;
1998-11-09 03:45:49 +00:00
}
1996-06-04 06:42:03 +00:00
1998-11-09 03:45:49 +00:00
/****************************************************************************
2003-08-06 20:01:31 +00:00
A wrapper around cli_list that adds recursion .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2010-10-29 11:56:51 -07:00
NTSTATUS do_list ( const char * mask ,
2020-06-03 14:25:50 -07:00
uint32_t attribute ,
2010-10-29 11:56:51 -07:00
NTSTATUS ( * fn ) ( struct cli_state * cli_state , struct file_info * ,
2010-07-30 16:18:51 +02:00
const char * dir ) ,
2007-12-06 17:16:33 -08:00
bool rec ,
bool dirs )
1998-11-09 03:45:49 +00:00
{
2020-10-19 09:37:03 +02:00
struct do_list_helper_state state = { . cli = cli , } ;
1999-12-13 13:27:58 +00:00
static int in_do_list = 0 ;
2007-12-06 17:16:33 -08:00
TALLOC_CTX * ctx = talloc_tos ( ) ;
2020-08-18 16:58:19 +02:00
struct cli_credentials * creds = samba_cmdline_get_creds ( ) ;
2010-10-29 11:56:51 -07:00
NTSTATUS ret_status = NT_STATUS_OK ;
NTSTATUS status = NT_STATUS_OK ;
1999-12-13 13:27:58 +00:00
2003-08-06 20:01:31 +00:00
if ( in_do_list & & rec ) {
1999-12-13 13:27:58 +00:00
fprintf ( stderr , " INTERNAL ERROR: do_list called recursively when the recursive flag is true \n " ) ;
exit ( 1 ) ;
}
in_do_list = 1 ;
1998-11-09 03:45:49 +00:00
do_list_recurse = rec ;
do_list_dirs = dirs ;
do_list_fn = fn ;
1996-06-04 06:42:03 +00:00
2020-06-05 07:58:35 +02:00
init_do_list_queue ( ) ;
add_to_do_list_queue ( mask ) ;
while ( ! do_list_queue_empty ( ) ) {
2020-10-19 09:37:03 +02:00
struct cli_state * targetcli = NULL ;
2020-10-29 21:32:21 +01:00
char * targetpath = NULL ;
2007-12-06 17:16:33 -08:00
2020-10-19 09:37:03 +02:00
state . mask = do_list_queue_head ( ) ;
2020-06-05 07:58:35 +02:00
/* check for dfs */
2007-12-06 17:16:33 -08:00
2020-10-11 07:35:52 +02:00
status = cli_resolve_path (
ctx ,
" " ,
creds ,
cli ,
2020-10-18 18:39:17 +02:00
state . mask ,
2020-10-19 09:37:03 +02:00
& targetcli ,
2020-10-11 07:35:52 +02:00
& targetpath ) ;
2020-06-05 07:58:35 +02:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
2020-10-18 18:39:17 +02:00
d_printf ( " do_list: [%s] %s \n " , state . mask ,
2020-06-05 07:58:35 +02:00
nt_errstr ( status ) ) ;
1999-12-13 13:27:58 +00:00
remove_do_list_queue_head ( ) ;
2020-06-05 07:58:35 +02:00
continue ;
}
2020-10-11 07:35:52 +02:00
status = cli_list (
2020-10-19 09:37:03 +02:00
targetcli ,
2020-10-11 07:35:52 +02:00
targetpath ,
attribute ,
do_list_helper ,
2020-10-11 07:41:01 +02:00
& state ) ;
2020-06-05 07:58:35 +02:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
d_printf ( " %s listing %s \n " ,
nt_errstr ( status ) , targetpath ) ;
ret_status = status ;
}
remove_do_list_queue_head ( ) ;
if ( ( ! do_list_queue_empty ( ) ) & & ( fn = = display_finfo ) ) {
char * next_file = do_list_queue_head ( ) ;
char * save_ch = 0 ;
if ( ( strlen ( next_file ) > = 2 ) & &
( next_file [ strlen ( next_file ) - 1 ] = = ' * ' ) & &
( next_file [ strlen ( next_file ) - 2 ] = = CLI_DIRSEP_CHAR ) ) {
save_ch = next_file +
strlen ( next_file ) - 2 ;
* save_ch = ' \0 ' ;
if ( showacls ) {
/* cwd is only used if showacls is on */
client_set_cwd ( next_file ) ;
1999-12-13 13:27:58 +00:00
}
}
2020-06-05 07:58:35 +02:00
if ( ! showacls ) /* don't disturbe the showacls output */
d_printf ( " \n %s \n " , next_file ) ;
if ( save_ch ) {
* save_ch = CLI_DIRSEP_CHAR ;
2007-12-06 17:16:33 -08:00
}
}
2020-06-05 07:58:35 +02:00
TALLOC_FREE ( targetpath ) ;
1999-12-13 13:27:58 +00:00
}
in_do_list = 0 ;
reset_do_list_queue ( ) ;
2010-10-29 11:56:51 -07:00
return ret_status ;
1998-11-09 03:45:49 +00:00
}
/****************************************************************************
2003-08-06 20:01:31 +00:00
Get a directory listing .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2001-10-09 19:12:18 +00:00
static int cmd_dir ( void )
1998-11-09 03:45:49 +00:00
{
2007-12-06 17:16:33 -08:00
TALLOC_CTX * ctx = talloc_tos ( ) ;
2020-06-03 14:25:50 -07:00
uint32_t attribute = FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN ;
2007-12-06 17:16:33 -08:00
char * mask = NULL ;
char * buf = NULL ;
int rc = 1 ;
2010-10-29 11:56:51 -07:00
NTSTATUS status ;
2007-12-06 17:16:33 -08:00
1998-11-09 03:45:49 +00:00
dir_total = 0 ;
2008-02-08 16:59:52 -08:00
mask = talloc_strdup ( ctx , client_get_cur_dir ( ) ) ;
2007-12-06 17:16:33 -08:00
if ( ! mask ) {
return 1 ;
}
2007-12-19 21:59:28 +01:00
if ( next_token_talloc ( ctx , & cmd_ptr , & buf , NULL ) ) {
2008-02-08 16:59:52 -08:00
normalize_name ( buf ) ;
2007-12-06 17:16:33 -08:00
if ( * buf = = CLI_DIRSEP_CHAR ) {
2008-02-08 16:59:52 -08:00
mask = talloc_strdup ( ctx , buf ) ;
2007-12-06 17:16:33 -08:00
} else {
2008-12-31 16:30:11 -08:00
mask = talloc_asprintf_append ( mask , " %s " , buf ) ;
2007-12-06 17:16:33 -08:00
}
2003-08-06 20:01:31 +00:00
} else {
2007-12-06 17:16:33 -08:00
mask = talloc_asprintf_append ( mask , " * " ) ;
}
if ( ! mask ) {
return 1 ;
1996-06-04 06:42:03 +00:00
}
2017-10-20 15:09:38 -07:00
mask = client_clean_name ( ctx , mask ) ;
if ( mask = = NULL ) {
return 1 ;
}
2007-03-07 02:27:54 +00:00
if ( showacls ) {
/* cwd is only used if showacls is on */
2007-12-06 17:16:33 -08:00
client_set_cwd ( client_get_cur_dir ( ) ) ;
2007-03-07 02:27:54 +00:00
}
2010-10-29 11:56:51 -07:00
status = do_list ( mask , attribute , display_finfo , recurse , true ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
return 1 ;
}
1996-06-04 06:42:03 +00:00
2001-10-09 19:12:18 +00:00
rc = do_dskattr ( ) ;
1996-06-04 06:42:03 +00:00
1999-03-30 10:25:20 +00:00
DEBUG ( 3 , ( " Total bytes listed: %.0f \n " , dir_total ) ) ;
2001-10-09 19:12:18 +00:00
return rc ;
1996-06-04 06:42:03 +00:00
}
/****************************************************************************
2003-08-06 20:01:31 +00:00
Get a directory listing .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2001-10-09 19:12:18 +00:00
static int cmd_du ( void )
1996-06-04 06:42:03 +00:00
{
2007-12-06 17:16:33 -08:00
TALLOC_CTX * ctx = talloc_tos ( ) ;
2020-06-03 14:25:50 -07:00
uint32_t attribute = FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN ;
2007-12-06 17:16:33 -08:00
char * mask = NULL ;
char * buf = NULL ;
2010-10-29 11:56:51 -07:00
NTSTATUS status ;
2007-12-06 17:16:33 -08:00
int rc = 1 ;
1998-11-09 03:45:49 +00:00
dir_total = 0 ;
2007-12-06 17:16:33 -08:00
mask = talloc_strdup ( ctx , client_get_cur_dir ( ) ) ;
if ( ! mask ) {
return 1 ;
}
if ( ( mask [ 0 ] ! = ' \0 ' ) & & ( mask [ strlen ( mask ) - 1 ] ! = CLI_DIRSEP_CHAR ) ) {
2008-12-31 16:30:11 -08:00
mask = talloc_asprintf_append ( mask , " %s " , CLI_DIRSEP_STR ) ;
2007-12-06 17:16:33 -08:00
if ( ! mask ) {
return 1 ;
}
}
2007-12-19 21:59:28 +01:00
if ( next_token_talloc ( ctx , & cmd_ptr , & buf , NULL ) ) {
2008-02-08 16:59:52 -08:00
normalize_name ( buf ) ;
2007-12-06 17:16:33 -08:00
if ( * buf = = CLI_DIRSEP_CHAR ) {
mask = talloc_strdup ( ctx , buf ) ;
} else {
2008-12-31 16:30:11 -08:00
mask = talloc_asprintf_append ( mask , " %s " , buf ) ;
2007-12-06 17:16:33 -08:00
}
1998-11-09 03:45:49 +00:00
} else {
2007-12-06 17:16:33 -08:00
mask = talloc_strdup ( ctx , " * " ) ;
1996-06-04 06:42:03 +00:00
}
2017-10-20 15:09:38 -07:00
if ( ! mask ) {
return 1 ;
}
mask = client_clean_name ( ctx , mask ) ;
if ( mask = = NULL ) {
return 1 ;
}
1996-06-04 06:42:03 +00:00
2010-10-29 11:56:51 -07:00
status = do_list ( mask , attribute , do_du , recurse , true ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
return 1 ;
}
1996-06-04 06:42:03 +00:00
2001-10-09 19:12:18 +00:00
rc = do_dskattr ( ) ;
1996-06-04 06:42:03 +00:00
2001-09-07 14:14:57 +00:00
d_printf ( " Total number of bytes: %.0f \n " , dir_total ) ;
2001-10-09 19:12:18 +00:00
return rc ;
1998-11-09 03:45:49 +00:00
}
1996-06-04 06:42:03 +00:00
2007-07-22 11:18:49 +00:00
static int cmd_echo ( void )
{
2007-12-06 17:16:33 -08:00
TALLOC_CTX * ctx = talloc_tos ( ) ;
char * num ;
char * data ;
2008-08-27 19:30:57 +02:00
NTSTATUS status ;
2007-07-22 11:18:49 +00:00
2007-12-19 21:59:28 +01:00
if ( ! next_token_talloc ( ctx , & cmd_ptr , & num , NULL )
| | ! next_token_talloc ( ctx , & cmd_ptr , & data , NULL ) ) {
2007-08-04 20:08:35 +00:00
d_printf ( " echo <num> <data> \n " ) ;
2007-07-22 11:18:49 +00:00
return 1 ;
}
2008-08-27 19:30:57 +02:00
status = cli_echo ( cli , atoi ( num ) , data_blob_const ( data , strlen ( data ) ) ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
d_printf ( " echo failed: %s \n " , nt_errstr ( status ) ) ;
2007-07-22 11:18:49 +00:00
return 1 ;
}
return 0 ;
}
1998-11-09 03:45:49 +00:00
/****************************************************************************
2003-08-06 20:01:31 +00:00
Get a file from rname to lname
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2008-02-28 15:21:33 +01:00
static NTSTATUS writefile_sink ( char * buf , size_t n , void * priv )
{
int * pfd = ( int * ) priv ;
2018-03-22 14:51:28 +01:00
ssize_t rc ;
rc = writefile ( * pfd , buf , n ) ;
if ( rc = = - 1 ) {
2008-02-28 15:21:33 +01:00
return map_nt_error_from_unix ( errno ) ;
}
return NT_STATUS_OK ;
}
2007-12-06 17:16:33 -08:00
static int do_get ( const char * rname , const char * lname_in , bool reget )
{
TALLOC_CTX * ctx = talloc_tos ( ) ;
2009-04-30 15:26:43 -07:00
int handle = 0 ;
uint16_t fnum ;
2007-12-06 17:16:33 -08:00
bool newhandle = false ;
2010-08-30 12:15:54 +02:00
struct timespec tp_start ;
2020-06-03 12:54:10 -07:00
uint32_t attr ;
2012-04-05 14:53:08 +10:00
off_t size ;
2002-09-25 15:19:00 +00:00
off_t start = 0 ;
2012-04-05 14:53:08 +10:00
off_t nread = 0 ;
2001-10-09 19:12:18 +00:00
int rc = 0 ;
2007-12-06 17:16:33 -08:00
struct cli_state * targetcli = NULL ;
char * targetname = NULL ;
char * lname = NULL ;
2020-08-18 16:58:19 +02:00
struct cli_credentials * creds = samba_cmdline_get_creds ( ) ;
2008-02-28 15:21:33 +01:00
NTSTATUS status ;
1998-11-09 03:45:49 +00:00
2007-12-06 17:16:33 -08:00
lname = talloc_strdup ( ctx , lname_in ) ;
if ( ! lname ) {
return 1 ;
}
1998-11-09 03:45:49 +00:00
if ( lowercase ) {
2012-08-08 17:01:00 -07:00
if ( ! strlower_m ( lname ) ) {
d_printf ( " strlower_m %s failed \n " , lname ) ;
return 1 ;
}
1998-11-09 03:45:49 +00:00
}
1996-06-04 06:42:03 +00:00
2020-08-18 17:42:25 +02:00
status = cli_resolve_path ( ctx , " " ,
creds ,
2017-04-25 17:03:10 -07:00
cli , rname , & targetcli , & targetname ) ;
2011-07-03 20:53:55 +02:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
2011-07-05 19:42:46 +02:00
d_printf ( " Failed to open %s: %s \n " , rname , nt_errstr ( status ) ) ;
2005-02-23 18:27:13 +00:00
return 1 ;
}
2010-08-30 12:15:54 +02:00
clock_gettime_mono ( & tp_start ) ;
2007-12-06 17:16:33 -08:00
2011-12-03 21:36:47 -08:00
status = cli_open ( targetcli , targetname , O_RDONLY , DENY_NONE , & fnum ) ;
2010-08-13 15:08:38 +02:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
d_printf ( " %s opening remote file %s \n " , nt_errstr ( status ) ,
rname ) ;
2001-10-09 19:12:18 +00:00
return 1 ;
1998-11-09 03:45:49 +00:00
}
1996-06-04 06:42:03 +00:00
1998-11-09 03:45:49 +00:00
if ( ! strcmp ( lname , " - " ) ) {
handle = fileno ( stdout ) ;
} else {
2002-09-25 15:19:00 +00:00
if ( reget ) {
2012-03-28 12:48:00 +11:00
handle = open ( lname , O_WRONLY | O_CREAT , 0644 ) ;
2002-09-25 15:19:00 +00:00
if ( handle > = 0 ) {
2012-03-28 12:37:04 +11:00
start = lseek ( handle , 0 , SEEK_END ) ;
2002-09-25 15:19:00 +00:00
if ( start = = - 1 ) {
d_printf ( " Error seeking local file \n " ) ;
2018-08-09 15:58:32 +02:00
close ( handle ) ;
2002-09-25 15:19:00 +00:00
return 1 ;
}
}
} else {
2012-03-28 12:48:00 +11:00
handle = open ( lname , O_WRONLY | O_CREAT | O_TRUNC , 0644 ) ;
2002-09-25 15:19:00 +00:00
}
2007-12-06 17:16:33 -08:00
newhandle = true ;
1998-11-09 03:45:49 +00:00
}
if ( handle < 0 ) {
2001-09-07 14:14:57 +00:00
d_printf ( " Error opening local file %s \n " , lname ) ;
2001-10-09 19:12:18 +00:00
return 1 ;
1998-11-09 03:45:49 +00:00
}
1996-06-04 06:42:03 +00:00
2011-01-20 14:38:30 +01:00
status = cli_qfileinfo_basic ( targetcli , fnum , & attr , & size , NULL , NULL ,
NULL , NULL , NULL ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
2020-06-04 08:43:49 +02:00
d_printf ( " getattrib: %s \n " , nt_errstr ( status ) ) ;
if ( newhandle ) {
close ( handle ) ;
2011-01-20 14:38:30 +01:00
}
2020-06-04 08:43:49 +02:00
return 1 ;
1998-11-09 03:45:49 +00:00
}
1996-06-04 06:42:03 +00:00
2007-12-06 17:16:33 -08:00
DEBUG ( 1 , ( " getting file %s of size %.0f as %s " ,
2002-09-25 15:19:00 +00:00
rname , ( double ) size , lname ) ) ;
1996-06-04 06:42:03 +00:00
2008-03-01 12:05:09 +01:00
status = cli_pull ( targetcli , fnum , start , size , io_bufsize ,
2008-02-28 15:21:33 +01:00
writefile_sink , ( void * ) & handle , & nread ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
d_fprintf ( stderr , " parallel_read returned %s \n " ,
nt_errstr ( status ) ) ;
2018-08-09 15:58:32 +02:00
if ( newhandle ) {
close ( handle ) ;
}
2005-02-23 18:27:13 +00:00
cli_close ( targetcli , fnum ) ;
2001-10-09 19:12:18 +00:00
return 1 ;
1999-12-13 13:27:58 +00:00
}
1996-06-04 06:42:03 +00:00
2010-08-13 15:08:38 +02:00
status = cli_close ( targetcli , fnum ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
d_printf ( " Error %s closing remote file \n " , nt_errstr ( status ) ) ;
2001-10-09 19:12:18 +00:00
rc = 1 ;
1998-11-09 03:45:49 +00:00
}
1996-06-04 06:42:03 +00:00
1998-11-09 03:45:49 +00:00
if ( newhandle ) {
close ( handle ) ;
}
1996-06-04 06:42:03 +00:00
2011-04-29 12:00:57 +10:00
if ( archive_level > = 2 & & ( attr & FILE_ATTRIBUTE_ARCHIVE ) ) {
2020-06-03 14:25:50 -07:00
cli_setatr ( cli , rname , attr & ~ ( uint32_t ) FILE_ATTRIBUTE_ARCHIVE , 0 ) ;
1998-11-09 03:45:49 +00:00
}
1996-06-04 06:42:03 +00:00
1998-11-09 03:45:49 +00:00
{
2010-08-30 12:15:54 +02:00
struct timespec tp_end ;
1998-11-09 03:45:49 +00:00
int this_time ;
2007-12-06 17:16:33 -08:00
2010-08-30 12:15:54 +02:00
clock_gettime_mono ( & tp_end ) ;
2010-09-17 13:47:05 +02:00
this_time = nsec_time_diff ( & tp_end , & tp_start ) / 1000000 ;
1998-11-09 03:45:49 +00:00
get_total_time_ms + = this_time ;
get_total_size + = nread ;
2007-12-06 17:16:33 -08:00
2008-08-28 16:06:23 -07:00
DEBUG ( 1 , ( " (%3.1f KiloBytes/sec) (average %3.1f KiloBytes/sec) \n " ,
1998-11-09 03:45:49 +00:00
nread / ( 1.024 * this_time + 1.0e-4 ) ,
get_total_size / ( 1.024 * get_total_time_ms ) ) ) ;
}
2007-12-06 17:16:33 -08:00
TALLOC_FREE ( targetname ) ;
2001-10-09 19:12:18 +00:00
return rc ;
1996-06-04 06:42:03 +00:00
}
1996-05-04 07:50:46 +00:00
/****************************************************************************
2003-08-06 20:01:31 +00:00
Get a file .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2001-10-09 19:12:18 +00:00
static int cmd_get ( void )
1996-05-04 07:50:46 +00:00
{
2007-12-06 17:16:33 -08:00
TALLOC_CTX * ctx = talloc_tos ( ) ;
char * lname = NULL ;
char * rname = NULL ;
char * fname = NULL ;
2008-02-08 16:59:52 -08:00
rname = talloc_strdup ( ctx , client_get_cur_dir ( ) ) ;
2007-12-06 17:16:33 -08:00
if ( ! rname ) {
return 1 ;
}
1996-05-04 07:50:46 +00:00
2007-12-19 21:59:28 +01:00
if ( ! next_token_talloc ( ctx , & cmd_ptr , & fname , NULL ) ) {
2007-12-06 17:16:33 -08:00
d_printf ( " get <filename> [localname] \n " ) ;
return 1 ;
}
2008-12-31 16:30:11 -08:00
rname = talloc_asprintf_append ( rname , " %s " , fname ) ;
2007-12-06 17:16:33 -08:00
if ( ! rname ) {
return 1 ;
}
2017-10-20 15:09:38 -07:00
rname = client_clean_name ( ctx , rname ) ;
2007-12-06 17:16:33 -08:00
if ( ! rname ) {
return 1 ;
}
2007-12-19 21:59:28 +01:00
next_token_talloc ( ctx , & cmd_ptr , & lname , NULL ) ;
2007-12-06 17:16:33 -08:00
if ( ! lname ) {
lname = fname ;
}
return do_get ( rname , lname , false ) ;
1996-05-04 07:50:46 +00:00
}
/****************************************************************************
2003-08-06 20:01:31 +00:00
Do an mget operation on one file .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2010-10-29 11:56:51 -07:00
static NTSTATUS do_mget ( struct cli_state * cli_state , struct file_info * finfo ,
2010-07-30 16:18:51 +02:00
const char * dir )
1996-05-04 07:50:46 +00:00
{
2007-12-06 17:16:33 -08:00
TALLOC_CTX * ctx = talloc_tos ( ) ;
2020-09-28 15:03:41 +02:00
const char * client_cwd = NULL ;
size_t client_cwd_len ;
char * path = NULL ;
char * local_path = NULL ;
2007-12-06 17:16:33 -08:00
if ( ! finfo - > name ) {
2010-10-29 11:56:51 -07:00
return NT_STATUS_OK ;
2007-12-06 17:16:33 -08:00
}
1996-05-04 07:50:46 +00:00
2022-03-12 12:40:29 +01:00
if ( ISDOT ( finfo - > name ) | | ISDOTDOT ( finfo - > name ) ) {
2010-10-29 11:56:51 -07:00
return NT_STATUS_OK ;
2022-03-12 12:40:29 +01:00
}
1996-05-04 07:50:46 +00:00
2020-09-28 15:03:41 +02:00
if ( ( finfo - > attr & FILE_ATTRIBUTE_DIRECTORY ) & & ! recurse ) {
return NT_STATUS_OK ;
}
2020-09-28 14:21:24 +02:00
if ( prompt ) {
const char * object = ( finfo - > attr & FILE_ATTRIBUTE_DIRECTORY ) ?
" directory " : " file " ;
char * quest = NULL ;
bool ok ;
quest = talloc_asprintf (
ctx , " Get %s %s? " , object , finfo - > name ) ;
if ( quest = = NULL ) {
2010-10-29 11:56:51 -07:00
return NT_STATUS_NO_MEMORY ;
2007-12-06 17:16:33 -08:00
}
1996-05-04 07:50:46 +00:00
2020-09-28 14:21:24 +02:00
ok = yesno ( quest ) ;
TALLOC_FREE ( quest ) ;
if ( ! ok ) {
return NT_STATUS_OK ;
}
2007-12-06 17:16:33 -08:00
}
1996-05-04 07:50:46 +00:00
2020-09-28 15:03:41 +02:00
path = talloc_asprintf (
ctx , " %s%c%s " , dir , CLI_DIRSEP_CHAR , finfo - > name ) ;
if ( path = = NULL ) {
2010-10-29 11:56:51 -07:00
return NT_STATUS_NO_MEMORY ;
2007-12-06 17:16:33 -08:00
}
2020-09-28 15:03:41 +02:00
path = client_clean_name ( ctx , path ) ;
if ( path = = NULL ) {
2017-10-20 15:09:38 -07:00
return NT_STATUS_NO_MEMORY ;
}
2007-12-06 17:16:33 -08:00
2020-09-28 15:03:41 +02:00
/*
* Skip the path prefix if we ' ve done a remote " cd " when
* creating the local path
*/
client_cwd = client_get_cur_dir ( ) ;
client_cwd_len = strlen ( client_cwd ) ;
2007-12-06 17:16:33 -08:00
2020-09-28 15:03:41 +02:00
local_path = talloc_strdup ( ctx , path + client_cwd_len ) ;
if ( local_path = = NULL ) {
TALLOC_FREE ( path ) ;
2010-10-29 11:56:51 -07:00
return NT_STATUS_NO_MEMORY ;
}
2020-09-28 15:03:41 +02:00
string_replace ( local_path , CLI_DIRSEP_CHAR , ' / ' ) ;
2010-10-29 11:56:51 -07:00
2020-09-28 15:03:41 +02:00
if ( finfo - > attr & FILE_ATTRIBUTE_DIRECTORY ) {
int ret = mkdir ( local_path , 0777 ) ;
1996-05-04 07:50:46 +00:00
2020-09-28 15:03:41 +02:00
if ( ( ret = = - 1 ) & & ( errno ! = EEXIST ) ) {
return map_nt_error_from_unix ( errno ) ;
}
} else {
do_get ( path , local_path , false ) ;
2008-12-31 16:30:11 -08:00
}
2020-09-28 15:03:41 +02:00
2010-10-29 11:56:51 -07:00
return NT_STATUS_OK ;
1996-06-04 06:42:03 +00:00
}
1996-05-04 07:50:46 +00:00
1998-11-09 03:45:49 +00:00
/****************************************************************************
2003-08-06 20:01:31 +00:00
View the file using the pager .
1998-11-09 03:45:49 +00:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2003-08-06 20:01:31 +00:00
2001-10-09 19:12:18 +00:00
static int cmd_more ( void )
1998-11-09 03:45:49 +00:00
{
2007-12-06 17:16:33 -08:00
TALLOC_CTX * ctx = talloc_tos ( ) ;
char * rname = NULL ;
char * fname = NULL ;
char * lname = NULL ;
char * pager_cmd = NULL ;
const char * pager ;
2001-04-11 23:19:08 +00:00
int fd ;
2001-10-09 19:12:18 +00:00
int rc = 0 ;
2013-02-25 17:34:21 +01:00
mode_t mask ;
1996-05-04 07:50:46 +00:00
2008-02-08 16:59:52 -08:00
rname = talloc_strdup ( ctx , client_get_cur_dir ( ) ) ;
2007-12-06 17:16:33 -08:00
if ( ! rname ) {
return 1 ;
}
lname = talloc_asprintf ( ctx , " %s/smbmore.XXXXXX " , tmpdir ( ) ) ;
if ( ! lname ) {
return 1 ;
}
2013-02-25 17:34:21 +01:00
mask = umask ( S_IRWXO | S_IRWXG ) ;
2009-04-20 23:58:26 +02:00
fd = mkstemp ( lname ) ;
2013-02-25 17:34:21 +01:00
umask ( mask ) ;
2001-04-11 23:19:08 +00:00
if ( fd = = - 1 ) {
2001-09-07 14:14:57 +00:00
d_printf ( " failed to create temporary file for more \n " ) ;
2001-10-09 19:12:18 +00:00
return 1 ;
2001-04-11 23:19:08 +00:00
}
close ( fd ) ;
2007-12-19 21:59:28 +01:00
if ( ! next_token_talloc ( ctx , & cmd_ptr , & fname , NULL ) ) {
2001-09-07 14:14:57 +00:00
d_printf ( " more <filename> \n " ) ;
2001-04-11 23:19:08 +00:00
unlink ( lname ) ;
2001-10-09 19:12:18 +00:00
return 1 ;
1998-11-09 03:45:49 +00:00
}
2008-12-31 16:30:11 -08:00
rname = talloc_asprintf_append ( rname , " %s " , fname ) ;
2007-12-06 17:16:33 -08:00
if ( ! rname ) {
return 1 ;
}
2017-10-20 15:09:38 -07:00
rname = client_clean_name ( ctx , rname ) ;
2007-12-06 17:16:33 -08:00
if ( ! rname ) {
return 1 ;
}
1996-05-04 07:50:46 +00:00
2007-12-06 17:16:33 -08:00
rc = do_get ( rname , lname , false ) ;
1998-04-11 07:52:13 +00:00
1998-11-09 03:45:49 +00:00
pager = getenv ( " PAGER " ) ;
1996-05-04 07:50:46 +00:00
2007-12-06 17:16:33 -08:00
pager_cmd = talloc_asprintf ( ctx ,
" %s %s " ,
( pager ? pager : PAGER ) ,
lname ) ;
if ( ! pager_cmd ) {
return 1 ;
}
2008-12-31 16:30:11 -08:00
if ( system ( pager_cmd ) = = - 1 ) {
d_printf ( " system command '%s' returned -1 \n " ,
pager_cmd ) ;
}
2001-04-11 23:19:08 +00:00
unlink ( lname ) ;
2007-12-06 17:16:33 -08:00
2001-10-09 19:12:18 +00:00
return rc ;
1998-11-09 03:45:49 +00:00
}
1998-04-11 07:52:13 +00:00
1998-11-09 03:45:49 +00:00
/****************************************************************************
2003-08-06 20:01:31 +00:00
Do a mget command .
1998-11-09 03:45:49 +00:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2003-08-06 20:01:31 +00:00
2001-10-09 19:12:18 +00:00
static int cmd_mget ( void )
1998-11-09 03:45:49 +00:00
{
2007-12-06 17:16:33 -08:00
TALLOC_CTX * ctx = talloc_tos ( ) ;
2020-06-03 14:25:50 -07:00
uint32_t attribute = FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN ;
2007-12-06 18:08:01 -08:00
char * mget_mask = NULL ;
char * buf = NULL ;
2010-10-29 11:56:51 -07:00
NTSTATUS status = NT_STATUS_OK ;
1996-05-04 07:50:46 +00:00
2007-12-06 17:16:33 -08:00
if ( recurse ) {
2011-04-29 11:57:02 +10:00
attribute | = FILE_ATTRIBUTE_DIRECTORY ;
2007-12-06 17:16:33 -08:00
}
2007-12-19 21:59:28 +01:00
while ( next_token_talloc ( ctx , & cmd_ptr , & buf , NULL ) ) {
2010-10-29 11:56:51 -07:00
2007-12-06 17:16:33 -08:00
mget_mask = talloc_strdup ( ctx , client_get_cur_dir ( ) ) ;
if ( ! mget_mask ) {
return 1 ;
}
if ( * buf = = CLI_DIRSEP_CHAR ) {
mget_mask = talloc_strdup ( ctx , buf ) ;
} else {
mget_mask = talloc_asprintf_append ( mget_mask ,
2008-12-31 16:30:11 -08:00
" %s " , buf ) ;
2007-12-06 17:16:33 -08:00
}
if ( ! mget_mask ) {
return 1 ;
}
2017-10-20 15:09:38 -07:00
mget_mask = client_clean_name ( ctx , mget_mask ) ;
if ( mget_mask = = NULL ) {
return 1 ;
}
2020-09-28 15:03:41 +02:00
status = do_list ( mget_mask , attribute , do_mget , recurse , true ) ;
2010-10-29 11:56:51 -07:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
return 1 ;
}
1996-06-04 06:42:03 +00:00
}
1998-11-09 03:45:49 +00:00
2009-01-05 15:47:19 +01:00
if ( mget_mask = = NULL ) {
d_printf ( " nothing to mget \n " ) ;
return 0 ;
}
1998-11-09 03:45:49 +00:00
if ( ! * mget_mask ) {
2008-02-08 16:59:52 -08:00
mget_mask = talloc_asprintf ( ctx ,
" %s* " ,
client_get_cur_dir ( ) ) ;
2007-12-06 17:16:33 -08:00
if ( ! mget_mask ) {
return 1 ;
}
2017-10-20 15:09:38 -07:00
mget_mask = client_clean_name ( ctx , mget_mask ) ;
if ( mget_mask = = NULL ) {
return 1 ;
}
2020-09-28 15:03:41 +02:00
status = do_list ( mget_mask , attribute , do_mget , recurse , true ) ;
2010-10-29 11:56:51 -07:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
return 1 ;
}
1996-06-04 06:42:03 +00:00
}
2007-12-06 17:16:33 -08:00
2001-10-09 19:12:18 +00:00
return 0 ;
1996-05-04 07:50:46 +00:00
}
/****************************************************************************
2003-08-06 20:01:31 +00:00
Make a directory of name " name " .
1998-11-09 03:45:49 +00:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2003-08-06 20:01:31 +00:00
2007-12-06 17:16:33 -08:00
static bool do_mkdir ( const char * name )
1996-05-04 07:50:46 +00:00
{
2007-12-06 17:16:33 -08:00
TALLOC_CTX * ctx = talloc_tos ( ) ;
2005-02-23 19:26:32 +00:00
struct cli_state * targetcli ;
2007-12-06 17:16:33 -08:00
char * targetname = NULL ;
2020-08-18 16:58:19 +02:00
struct cli_credentials * creds = samba_cmdline_get_creds ( ) ;
2010-08-13 15:08:38 +02:00
NTSTATUS status ;
2007-12-06 17:16:33 -08:00
2020-08-18 17:42:25 +02:00
status = cli_resolve_path ( ctx , " " ,
creds ,
2017-04-25 17:03:10 -07:00
cli , name , & targetcli , & targetname ) ;
2011-07-03 20:53:55 +02:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
2011-07-05 19:42:46 +02:00
d_printf ( " mkdir %s: %s \n " , name , nt_errstr ( status ) ) ;
2007-12-06 17:16:33 -08:00
return false ;
2005-02-23 19:26:32 +00:00
}
2010-08-13 15:08:38 +02:00
status = cli_mkdir ( targetcli , targetname ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
2001-09-07 14:14:57 +00:00
d_printf ( " %s making remote directory %s \n " ,
2010-08-13 15:08:38 +02:00
nt_errstr ( status ) , name ) ;
2007-12-06 17:16:33 -08:00
return false ;
1998-11-09 03:45:49 +00:00
}
2007-12-06 17:16:33 -08:00
return true ;
1996-05-04 07:50:46 +00:00
}
2001-10-11 07:42:52 +00:00
/****************************************************************************
2003-08-06 20:01:31 +00:00
Show 8.3 name of a file .
2001-10-11 07:42:52 +00:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2003-08-06 20:01:31 +00:00
2007-12-06 17:16:33 -08:00
static bool do_altname ( const char * name )
2001-10-11 07:42:52 +00:00
{
2007-12-06 17:16:33 -08:00
fstring altname ;
2010-08-13 15:08:38 +02:00
NTSTATUS status ;
2007-12-06 17:16:33 -08:00
2010-08-13 15:08:38 +02:00
status = cli_qpathinfo_alt_name ( cli , name , altname ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
2001-10-11 07:42:52 +00:00
d_printf ( " %s getting alt name for %s \n " ,
2010-08-13 15:08:38 +02:00
nt_errstr ( status ) , name ) ;
2007-12-06 17:16:33 -08:00
return false ;
2001-10-11 07:42:52 +00:00
}
d_printf ( " %s \n " , altname ) ;
2007-12-06 17:16:33 -08:00
return true ;
2001-10-11 07:42:52 +00:00
}
1998-09-21 08:45:11 +00:00
/****************************************************************************
1999-12-13 13:27:58 +00:00
Exit client .
1998-11-09 03:45:49 +00:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2003-08-06 20:01:31 +00:00
2001-10-09 19:12:18 +00:00
static int cmd_quit ( void )
1998-09-21 08:45:11 +00:00
{
2009-03-12 17:59:24 -07:00
cli_shutdown ( cli ) ;
1998-11-09 03:45:49 +00:00
exit ( 0 ) ;
2001-10-19 00:02:36 +00:00
/* NOTREACHED */
return 0 ;
1998-09-21 08:45:11 +00:00
}
1996-05-04 07:50:46 +00:00
/****************************************************************************
2003-08-06 20:01:31 +00:00
Make a directory .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2001-10-09 19:12:18 +00:00
static int cmd_mkdir ( void )
1998-11-09 03:45:49 +00:00
{
2007-12-06 17:16:33 -08:00
TALLOC_CTX * ctx = talloc_tos ( ) ;
char * mask = NULL ;
char * buf = NULL ;
2020-08-18 16:58:19 +02:00
struct cli_credentials * creds = samba_cmdline_get_creds ( ) ;
2011-07-03 20:53:55 +02:00
NTSTATUS status ;
2007-12-06 17:16:33 -08:00
mask = talloc_strdup ( ctx , client_get_cur_dir ( ) ) ;
if ( ! mask ) {
return 1 ;
}
2007-12-19 21:59:28 +01:00
if ( ! next_token_talloc ( ctx , & cmd_ptr , & buf , NULL ) ) {
2007-12-06 17:16:33 -08:00
if ( ! recurse ) {
2001-09-07 14:14:57 +00:00
d_printf ( " mkdir <dirname> \n " ) ;
2007-12-06 17:16:33 -08:00
}
return 1 ;
}
2008-12-31 16:30:11 -08:00
mask = talloc_asprintf_append ( mask , " %s " , buf ) ;
2007-12-06 17:16:33 -08:00
if ( ! mask ) {
2001-10-09 19:12:18 +00:00
return 1 ;
1998-10-24 02:49:09 +00:00
}
2017-10-20 15:09:38 -07:00
mask = client_clean_name ( ctx , mask ) ;
if ( mask = = NULL ) {
return 1 ;
}
1996-05-04 07:50:46 +00:00
1998-11-09 03:45:49 +00:00
if ( recurse ) {
2007-12-06 17:16:33 -08:00
char * ddir = NULL ;
char * ddir2 = NULL ;
2007-03-08 23:54:57 +00:00
struct cli_state * targetcli ;
2007-12-06 17:16:33 -08:00
char * targetname = NULL ;
char * p = NULL ;
2008-01-23 11:04:10 +01:00
char * saveptr ;
2007-12-06 17:16:33 -08:00
ddir2 = talloc_strdup ( ctx , " " ) ;
if ( ! ddir2 ) {
2007-03-08 23:54:57 +00:00
return 1 ;
}
2017-04-25 17:03:10 -07:00
status = cli_resolve_path ( ctx , " " ,
2020-08-18 17:42:25 +02:00
creds ,
cli , mask ,
2017-04-25 17:03:10 -07:00
& targetcli , & targetname ) ;
2011-07-03 20:53:55 +02:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
2007-12-06 17:16:33 -08:00
return 1 ;
}
ddir = talloc_strdup ( ctx , targetname ) ;
if ( ! ddir ) {
return 1 ;
}
2003-09-05 19:59:55 +00:00
trim_char ( ddir , ' . ' , ' \0 ' ) ;
2008-01-23 11:04:10 +01:00
p = strtok_r ( ddir , " / \\ " , & saveptr ) ;
1998-11-09 03:45:49 +00:00
while ( p ) {
2008-12-31 16:30:11 -08:00
ddir2 = talloc_asprintf_append ( ddir2 , " %s " , p ) ;
2007-12-06 17:16:33 -08:00
if ( ! ddir2 ) {
return 1 ;
}
2009-04-22 06:46:42 -07:00
if ( ! NT_STATUS_IS_OK ( cli_chkpath ( targetcli , ddir2 ) ) ) {
1998-11-09 03:45:49 +00:00
do_mkdir ( ddir2 ) ;
}
2008-12-31 16:30:11 -08:00
ddir2 = talloc_asprintf_append ( ddir2 , " %s " , CLI_DIRSEP_STR ) ;
2007-12-06 17:16:33 -08:00
if ( ! ddir2 ) {
return 1 ;
}
2008-01-23 11:04:10 +01:00
p = strtok_r ( NULL , " / \\ " , & saveptr ) ;
2007-12-06 17:16:33 -08:00
}
1998-11-09 03:45:49 +00:00
} else {
do_mkdir ( mask ) ;
}
2007-12-06 17:16:33 -08:00
2001-10-09 19:12:18 +00:00
return 0 ;
1998-11-09 03:45:49 +00:00
}
1996-05-04 07:50:46 +00:00
2001-10-11 07:42:52 +00:00
/****************************************************************************
2003-08-06 20:01:31 +00:00
Show alt name .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2001-10-11 08:40:42 +00:00
static int cmd_altname ( void )
2001-10-11 07:42:52 +00:00
{
2007-12-06 17:16:33 -08:00
TALLOC_CTX * ctx = talloc_tos ( ) ;
char * name ;
char * buf ;
2001-10-11 07:42:52 +00:00
2007-12-06 17:16:33 -08:00
name = talloc_strdup ( ctx , client_get_cur_dir ( ) ) ;
if ( ! name ) {
2001-10-11 08:40:42 +00:00
return 1 ;
2001-10-11 07:42:52 +00:00
}
2007-12-19 21:59:28 +01:00
if ( ! next_token_talloc ( ctx , & cmd_ptr , & buf , NULL ) ) {
2007-12-06 17:16:33 -08:00
d_printf ( " altname <file> \n " ) ;
return 1 ;
}
2008-12-31 16:30:11 -08:00
name = talloc_asprintf_append ( name , " %s " , buf ) ;
2007-12-06 17:16:33 -08:00
if ( ! name ) {
return 1 ;
}
2017-10-20 15:09:38 -07:00
name = client_clean_name ( ctx , name ) ;
if ( name = = NULL ) {
return 1 ;
}
2001-10-11 07:42:52 +00:00
do_altname ( name ) ;
2001-10-11 08:40:42 +00:00
return 0 ;
2001-10-11 07:42:52 +00:00
}
2020-06-03 14:25:50 -07:00
static char * attr_str ( TALLOC_CTX * mem_ctx , uint32_t attr )
2010-02-22 14:36:40 -08:00
{
2011-06-07 11:58:39 +10:00
char * attrs = talloc_zero_array ( mem_ctx , char , 17 ) ;
2010-02-22 14:36:40 -08:00
int i = 0 ;
2020-06-03 13:32:55 -07:00
if ( ! ( attr & FILE_ATTRIBUTE_NORMAL ) ) {
if ( attr & FILE_ATTRIBUTE_ENCRYPTED ) {
2011-03-02 09:55:31 -07:00
attrs [ i + + ] = ' E ' ;
}
2020-06-03 13:32:55 -07:00
if ( attr & FILE_ATTRIBUTE_NONINDEXED ) {
2011-03-02 09:55:31 -07:00
attrs [ i + + ] = ' N ' ;
}
2020-06-03 13:32:55 -07:00
if ( attr & FILE_ATTRIBUTE_OFFLINE ) {
2011-03-02 09:55:31 -07:00
attrs [ i + + ] = ' O ' ;
}
2020-06-03 13:32:55 -07:00
if ( attr & FILE_ATTRIBUTE_COMPRESSED ) {
2011-03-02 09:55:31 -07:00
attrs [ i + + ] = ' C ' ;
}
2020-06-03 13:32:55 -07:00
if ( attr & FILE_ATTRIBUTE_REPARSE_POINT ) {
2011-03-02 09:55:31 -07:00
attrs [ i + + ] = ' r ' ;
}
2020-06-03 13:32:55 -07:00
if ( attr & FILE_ATTRIBUTE_SPARSE ) {
2011-03-02 09:55:31 -07:00
attrs [ i + + ] = ' s ' ;
}
2020-06-03 13:32:55 -07:00
if ( attr & FILE_ATTRIBUTE_TEMPORARY ) {
2011-03-02 09:55:31 -07:00
attrs [ i + + ] = ' T ' ;
}
2020-06-03 13:32:55 -07:00
if ( attr & FILE_ATTRIBUTE_NORMAL ) {
2011-03-02 09:55:31 -07:00
attrs [ i + + ] = ' N ' ;
}
2020-06-03 13:32:55 -07:00
if ( attr & FILE_ATTRIBUTE_READONLY ) {
2010-02-22 14:36:40 -08:00
attrs [ i + + ] = ' R ' ;
}
2020-06-03 13:32:55 -07:00
if ( attr & FILE_ATTRIBUTE_HIDDEN ) {
2010-02-22 14:36:40 -08:00
attrs [ i + + ] = ' H ' ;
}
2020-06-03 13:32:55 -07:00
if ( attr & FILE_ATTRIBUTE_SYSTEM ) {
2010-02-22 14:36:40 -08:00
attrs [ i + + ] = ' S ' ;
}
2020-06-03 13:32:55 -07:00
if ( attr & FILE_ATTRIBUTE_DIRECTORY ) {
2010-02-22 14:36:40 -08:00
attrs [ i + + ] = ' D ' ;
}
2020-06-03 13:32:55 -07:00
if ( attr & FILE_ATTRIBUTE_ARCHIVE ) {
2010-02-22 14:36:40 -08:00
attrs [ i + + ] = ' A ' ;
}
}
return attrs ;
}
2008-01-18 11:08:17 +01:00
/****************************************************************************
Show all info we can get
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static int do_allinfo ( const char * name )
{
fstring altname ;
struct timespec b_time , a_time , m_time , c_time ;
2012-04-05 14:53:08 +10:00
off_t size ;
2020-06-03 13:36:05 -07:00
uint32_t attr ;
2008-01-18 11:08:17 +01:00
NTTIME tmp ;
2010-11-29 18:09:49 +01:00
uint16_t fnum ;
2008-01-18 11:08:17 +01:00
unsigned int num_streams ;
struct stream_struct * streams ;
2020-06-05 14:54:22 +02:00
int j , num_snapshots ;
2016-08-19 16:57:27 -07:00
char * * snapshots = NULL ;
2008-01-18 11:08:17 +01:00
unsigned int i ;
2010-07-26 09:21:17 +02:00
NTSTATUS status ;
2008-01-18 11:08:17 +01:00
2010-07-26 09:21:17 +02:00
status = cli_qpathinfo_alt_name ( cli , name , altname ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
d_printf ( " %s getting alt name for %s \n " , nt_errstr ( status ) ,
name ) ;
2013-09-17 11:24:05 -07:00
/*
2013-09-17 18:10:16 -07:00
* Ignore not supported or not implemented , it does not
* hurt if we can ' t list alternate names .
2013-09-17 11:24:05 -07:00
*/
2013-09-17 18:10:16 -07:00
if ( NT_STATUS_EQUAL ( status , NT_STATUS_NOT_SUPPORTED ) | |
NT_STATUS_EQUAL ( status , NT_STATUS_NOT_IMPLEMENTED ) ) {
2013-09-17 11:24:05 -07:00
altname [ 0 ] = ' \0 ' ;
} else {
return false ;
}
2008-01-18 11:08:17 +01:00
}
d_printf ( " altname: %s \n " , altname ) ;
2013-10-14 11:44:36 +02:00
status = cli_qpathinfo3 ( cli , name , & b_time , & a_time , & m_time , & c_time ,
2020-06-03 13:32:55 -07:00
& size , & attr , NULL ) ;
2010-07-26 09:27:11 +02:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
d_printf ( " %s getting pathinfo for %s \n " , nt_errstr ( status ) ,
name ) ;
2008-01-18 11:08:17 +01:00
return false ;
}
2019-12-03 18:36:38 +01:00
tmp = full_timespec_to_nt_time ( & b_time ) ;
2008-01-18 11:08:17 +01:00
d_printf ( " create_time: %s \n " , nt_time_string ( talloc_tos ( ) , tmp ) ) ;
2019-12-03 18:36:38 +01:00
tmp = full_timespec_to_nt_time ( & a_time ) ;
2008-01-18 11:08:17 +01:00
d_printf ( " access_time: %s \n " , nt_time_string ( talloc_tos ( ) , tmp ) ) ;
2019-12-03 18:36:38 +01:00
tmp = full_timespec_to_nt_time ( & m_time ) ;
2008-01-18 11:08:17 +01:00
d_printf ( " write_time: %s \n " , nt_time_string ( talloc_tos ( ) , tmp ) ) ;
2019-12-03 18:36:38 +01:00
tmp = full_timespec_to_nt_time ( & c_time ) ;
2008-01-18 11:08:17 +01:00
d_printf ( " change_time: %s \n " , nt_time_string ( talloc_tos ( ) , tmp ) ) ;
2020-06-03 13:32:55 -07:00
d_printf ( " attributes: %s (%x) \n " , attr_str ( talloc_tos ( ) , attr ) , attr ) ;
2010-02-22 14:36:40 -08:00
2010-07-26 10:35:15 +02:00
status = cli_qpathinfo_streams ( cli , name , talloc_tos ( ) , & num_streams ,
& streams ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
d_printf ( " %s getting streams for %s \n " , nt_errstr ( status ) ,
name ) ;
2008-01-18 11:08:17 +01:00
return false ;
}
for ( i = 0 ; i < num_streams ; i + + ) {
d_printf ( " stream: [%s], %lld bytes \n " , streams [ i ] . name ,
( unsigned long long ) streams [ i ] . size ) ;
}
2020-06-03 13:32:55 -07:00
if ( attr & FILE_ATTRIBUTE_REPARSE_POINT ) {
2011-06-30 15:26:21 +02:00
char * subst , * print ;
uint32_t flags ;
status = cli_readlink ( cli , name , talloc_tos ( ) , & subst , & print ,
& flags ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
d_fprintf ( stderr , " cli_readlink returned %s \n " ,
nt_errstr ( status ) ) ;
} else {
d_printf ( " symlink: subst=[%s], print=[%s], flags=%x \n " ,
subst , print , flags ) ;
TALLOC_FREE ( subst ) ;
TALLOC_FREE ( print ) ;
}
}
2011-03-30 13:19:46 +02:00
status = cli_ntcreate ( cli , name , 0 ,
2012-09-05 15:07:54 +02:00
SEC_FILE_READ_DATA | SEC_FILE_READ_ATTRIBUTE |
SEC_STD_SYNCHRONIZE , 0 ,
2011-03-30 13:19:46 +02:00
FILE_SHARE_READ | FILE_SHARE_WRITE
| FILE_SHARE_DELETE ,
2014-05-08 20:55:57 -07:00
FILE_OPEN , 0x0 , 0x0 , & fnum , NULL ) ;
2010-11-29 18:09:49 +01:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
/*
* Ignore failure , it does not hurt if we can ' t list
* snapshots
*/
return 0 ;
}
2016-08-18 14:36:50 -07:00
/*
* In order to get shadow copy data over SMB1 we
* must call twice , once with ' get_names = false '
* to get the size , then again with ' get_names = true '
* to get the data or a Windows server fails to return
* valid info . Samba doesn ' t have this bug . JRA .
*/
status = cli_shadow_copy_data ( talloc_tos ( ) , cli , fnum ,
false , & snapshots , & num_snapshots ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
cli_close ( cli , fnum ) ;
return 0 ;
}
2010-11-29 18:09:49 +01:00
status = cli_shadow_copy_data ( talloc_tos ( ) , cli , fnum ,
true , & snapshots , & num_snapshots ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
cli_close ( cli , fnum ) ;
return 0 ;
}
2020-06-05 14:54:22 +02:00
for ( j = 0 ; j < num_snapshots ; j + + ) {
2010-11-29 18:09:49 +01:00
char * snap_name ;
2020-06-05 14:54:22 +02:00
d_printf ( " %s \n " , snapshots [ j ] ) ;
2010-11-29 18:09:49 +01:00
snap_name = talloc_asprintf ( talloc_tos ( ) , " %s%s " ,
2020-06-05 14:54:22 +02:00
snapshots [ j ] , name ) ;
2013-10-14 11:44:36 +02:00
status = cli_qpathinfo3 ( cli , snap_name , & b_time , & a_time ,
2010-11-29 18:09:49 +01:00
& m_time , & c_time , & size ,
NULL , NULL ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
d_fprintf ( stderr , " pathinfo(%s) failed: %s \n " ,
snap_name , nt_errstr ( status ) ) ;
TALLOC_FREE ( snap_name ) ;
continue ;
}
2014-06-18 12:21:06 +00:00
tmp = unix_timespec_to_nt_time ( b_time ) ;
2010-11-29 18:09:49 +01:00
d_printf ( " create_time: %s \n " , nt_time_string ( talloc_tos ( ) , tmp ) ) ;
2014-06-18 12:21:06 +00:00
tmp = unix_timespec_to_nt_time ( a_time ) ;
2010-11-29 18:09:49 +01:00
d_printf ( " access_time: %s \n " , nt_time_string ( talloc_tos ( ) , tmp ) ) ;
2014-06-18 12:21:06 +00:00
tmp = unix_timespec_to_nt_time ( m_time ) ;
2010-11-29 18:09:49 +01:00
d_printf ( " write_time: %s \n " , nt_time_string ( talloc_tos ( ) , tmp ) ) ;
2014-06-18 12:21:06 +00:00
tmp = unix_timespec_to_nt_time ( c_time ) ;
2010-11-29 18:09:49 +01:00
d_printf ( " change_time: %s \n " , nt_time_string ( talloc_tos ( ) , tmp ) ) ;
d_printf ( " size: %d \n " , ( int ) size ) ;
}
TALLOC_FREE ( snapshots ) ;
2015-02-10 09:32:11 -08:00
cli_close ( cli , fnum ) ;
2010-11-29 18:09:49 +01:00
2008-01-18 11:08:17 +01:00
return 0 ;
}
/****************************************************************************
Show all info we can get
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static int cmd_allinfo ( void )
{
TALLOC_CTX * ctx = talloc_tos ( ) ;
char * name ;
char * buf ;
name = talloc_strdup ( ctx , client_get_cur_dir ( ) ) ;
if ( ! name ) {
return 1 ;
}
if ( ! next_token_talloc ( ctx , & cmd_ptr , & buf , NULL ) ) {
2008-01-18 13:47:10 -08:00
d_printf ( " allinfo <file> \n " ) ;
2008-01-18 11:08:17 +01:00
return 1 ;
}
2008-12-31 16:30:11 -08:00
name = talloc_asprintf_append ( name , " %s " , buf ) ;
2008-01-18 11:08:17 +01:00
if ( ! name ) {
return 1 ;
}
2017-10-20 15:09:38 -07:00
name = client_clean_name ( ctx , name ) ;
if ( name = = NULL ) {
return 1 ;
}
2008-01-18 11:08:17 +01:00
do_allinfo ( name ) ;
return 0 ;
}
1996-05-04 07:50:46 +00:00
/****************************************************************************
2003-08-06 20:01:31 +00:00
Put a single file .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2007-12-06 17:16:33 -08:00
static int do_put ( const char * rname , const char * lname , bool reput )
1996-05-04 07:50:46 +00:00
{
2007-12-06 17:16:33 -08:00
TALLOC_CTX * ctx = talloc_tos ( ) ;
2009-04-30 15:26:43 -07:00
uint16_t fnum ;
2016-11-22 01:59:22 +01:00
FILE * f ;
2012-04-05 14:53:08 +10:00
off_t start = 0 ;
2001-10-09 19:12:18 +00:00
int rc = 0 ;
2010-08-30 12:15:54 +02:00
struct timespec tp_start ;
2005-02-23 18:27:13 +00:00
struct cli_state * targetcli ;
2007-12-06 17:16:33 -08:00
char * targetname = NULL ;
2008-12-19 23:33:55 +01:00
struct push_state state ;
2020-08-18 16:58:19 +02:00
struct cli_credentials * creds = samba_cmdline_get_creds ( ) ;
2008-12-19 23:33:55 +01:00
NTSTATUS status ;
2007-12-06 17:16:33 -08:00
2020-08-18 17:42:25 +02:00
status = cli_resolve_path ( ctx , " " ,
creds ,
2017-04-25 17:03:10 -07:00
cli , rname , & targetcli , & targetname ) ;
2011-07-03 20:53:55 +02:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
2011-07-05 19:42:46 +02:00
d_printf ( " Failed to open %s: %s \n " , rname , nt_errstr ( status ) ) ;
2005-02-23 18:27:13 +00:00
return 1 ;
}
2007-12-06 17:16:33 -08:00
2010-08-30 12:15:54 +02:00
clock_gettime_mono ( & tp_start ) ;
1996-05-04 07:50:46 +00:00
2002-09-25 15:19:00 +00:00
if ( reput ) {
2011-12-03 21:36:47 -08:00
status = cli_open ( targetcli , targetname , O_RDWR | O_CREAT , DENY_NONE , & fnum ) ;
2009-04-30 15:26:43 -07:00
if ( NT_STATUS_IS_OK ( status ) ) {
2011-03-27 11:50:55 +02:00
if ( ! NT_STATUS_IS_OK ( status = cli_qfileinfo_basic (
2010-10-23 22:37:16 +02:00
targetcli , fnum , NULL ,
& start , NULL , NULL ,
2020-06-04 08:43:49 +02:00
NULL , NULL , NULL ) ) ) {
2011-03-27 11:50:55 +02:00
d_printf ( " getattrib: %s \n " , nt_errstr ( status ) ) ;
2002-09-25 15:19:00 +00:00
return 1 ;
}
}
} else {
2011-12-03 21:36:47 -08:00
status = cli_open ( targetcli , targetname , O_RDWR | O_CREAT | O_TRUNC , DENY_NONE , & fnum ) ;
2002-09-25 15:19:00 +00:00
}
2007-12-06 17:16:33 -08:00
2009-04-30 15:26:43 -07:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
2011-03-27 11:50:55 +02:00
d_printf ( " %s opening remote file %s \n " , nt_errstr ( status ) ,
rname ) ;
2001-10-09 19:12:18 +00:00
return 1 ;
1998-11-09 03:45:49 +00:00
}
1996-05-04 07:50:46 +00:00
1998-11-09 03:45:49 +00:00
/* allow files to be piped into smbclient
2002-01-29 05:34:16 +00:00
jdblair 24. jun .98
Note that in this case this function will exit ( 0 ) rather
than returning . */
1998-11-09 03:45:49 +00:00
if ( ! strcmp ( lname , " - " ) ) {
2016-11-22 01:59:22 +01:00
f = stdin ;
1998-11-09 03:45:49 +00:00
/* size of file is not known */
} else {
2016-11-22 01:59:22 +01:00
f = fopen ( lname , " r " ) ;
2002-09-25 15:19:00 +00:00
if ( f & & reput ) {
2016-11-22 01:59:22 +01:00
if ( fseek ( f , start , SEEK_SET ) = = - 1 ) {
2002-09-25 15:19:00 +00:00
d_printf ( " Error seeking local file \n " ) ;
2016-11-22 01:59:22 +01:00
fclose ( f ) ;
2002-09-25 15:19:00 +00:00
return 1 ;
}
}
1998-11-09 03:45:49 +00:00
}
1996-05-04 07:50:46 +00:00
1998-11-09 03:45:49 +00:00
if ( ! f ) {
2001-09-07 14:14:57 +00:00
d_printf ( " Error opening local file %s \n " , lname ) ;
2001-10-09 19:12:18 +00:00
return 1 ;
1998-11-09 03:45:49 +00:00
}
2007-12-06 17:16:33 -08:00
1998-11-09 03:45:49 +00:00
DEBUG ( 1 , ( " putting file %s as %s " , lname ,
2000-01-05 19:59:42 +00:00
rname ) ) ;
2007-12-06 17:16:33 -08:00
2016-11-22 01:59:22 +01:00
setvbuf ( f , NULL , _IOFBF , io_bufsize ) ;
2008-10-23 17:42:45 +02:00
2008-12-19 23:33:55 +01:00
state . f = f ;
state . nread = 0 ;
2008-10-23 17:42:45 +02:00
2009-03-12 09:02:02 +01:00
status = cli_push ( targetcli , fnum , 0 , 0 , io_bufsize , push_source ,
& state ) ;
2008-12-19 23:33:55 +01:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
d_fprintf ( stderr , " cli_push returned %s \n " , nt_errstr ( status ) ) ;
2010-07-15 16:06:11 -07:00
rc = 1 ;
1998-11-09 03:45:49 +00:00
}
1996-05-04 07:50:46 +00:00
2010-08-13 15:08:38 +02:00
status = cli_close ( targetcli , fnum ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
d_printf ( " %s closing remote file %s \n " , nt_errstr ( status ) ,
rname ) ;
2016-11-22 01:59:22 +01:00
if ( f ! = stdin ) {
fclose ( f ) ;
2009-06-19 17:26:53 -07:00
}
2001-10-09 19:12:18 +00:00
return 1 ;
1998-11-09 03:45:49 +00:00
}
1996-05-04 07:50:46 +00:00
2016-11-22 01:59:22 +01:00
if ( f ! = stdin ) {
fclose ( f ) ;
2002-07-15 10:35:28 +00:00
}
1998-11-09 03:45:49 +00:00
{
2010-08-30 12:15:54 +02:00
struct timespec tp_end ;
1998-11-09 03:45:49 +00:00
int this_time ;
2007-12-06 17:16:33 -08:00
2010-08-30 12:15:54 +02:00
clock_gettime_mono ( & tp_end ) ;
2010-09-17 13:47:05 +02:00
this_time = nsec_time_diff ( & tp_end , & tp_start ) / 1000000 ;
1998-11-09 03:45:49 +00:00
put_total_time_ms + = this_time ;
2008-12-19 23:33:55 +01:00
put_total_size + = state . nread ;
2007-12-06 17:16:33 -08:00
1999-12-21 09:54:24 +00:00
DEBUG ( 1 , ( " (%3.1f kb/s) (average %3.1f kb/s) \n " ,
2008-12-19 23:33:55 +01:00
state . nread / ( 1.024 * this_time + 1.0e-4 ) ,
1998-11-09 03:45:49 +00:00
put_total_size / ( 1.024 * put_total_time_ms ) ) ) ;
}
1996-05-04 07:50:46 +00:00
2016-11-22 01:59:22 +01:00
if ( f = = stdin ) {
2009-03-12 17:59:24 -07:00
cli_shutdown ( cli ) ;
2011-09-29 11:28:03 +02:00
exit ( rc ) ;
1998-11-09 03:45:49 +00:00
}
2007-12-06 17:16:33 -08:00
2001-10-09 19:12:18 +00:00
return rc ;
1996-05-04 07:50:46 +00:00
}
/****************************************************************************
2003-08-06 20:01:31 +00:00
Put a file .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2001-10-09 19:12:18 +00:00
static int cmd_put ( void )
1998-11-09 03:45:49 +00:00
{
2007-12-06 17:16:33 -08:00
TALLOC_CTX * ctx = talloc_tos ( ) ;
char * lname ;
char * rname ;
char * buf ;
2008-02-08 16:59:52 -08:00
rname = talloc_strdup ( ctx , client_get_cur_dir ( ) ) ;
2007-12-06 17:16:33 -08:00
if ( ! rname ) {
return 1 ;
}
2007-12-19 21:59:28 +01:00
if ( ! next_token_talloc ( ctx , & cmd_ptr , & lname , NULL ) ) {
2001-09-07 14:14:57 +00:00
d_printf ( " put <filename> \n " ) ;
2001-10-09 19:12:18 +00:00
return 1 ;
1998-11-09 03:45:49 +00:00
}
2007-12-06 17:16:33 -08:00
2007-12-19 21:59:28 +01:00
if ( next_token_talloc ( ctx , & cmd_ptr , & buf , NULL ) ) {
2008-12-31 16:30:11 -08:00
rname = talloc_asprintf_append ( rname , " %s " , buf ) ;
2007-12-06 17:16:33 -08:00
} else {
2008-12-31 16:30:11 -08:00
rname = talloc_asprintf_append ( rname , " %s " , lname ) ;
2007-12-06 17:16:33 -08:00
}
if ( ! rname ) {
return 1 ;
}
2017-10-20 15:09:38 -07:00
rname = client_clean_name ( ctx , rname ) ;
2007-12-06 17:16:33 -08:00
if ( ! rname ) {
return 1 ;
}
1996-05-04 07:50:46 +00:00
{
1998-11-09 03:45:49 +00:00
SMB_STRUCT_STAT st ;
/* allow '-' to represent stdin
jdblair , 24. jun .98 */
2009-11-27 13:17:05 +01:00
if ( ! file_exist_stat ( lname , & st , false ) & &
1998-11-09 03:45:49 +00:00
( strcmp ( lname , " - " ) ) ) {
2001-09-07 14:14:57 +00:00
d_printf ( " %s does not exist \n " , lname ) ;
2001-10-09 19:12:18 +00:00
return 1 ;
1998-11-09 03:45:49 +00:00
}
}
1996-05-04 07:50:46 +00:00
2007-12-06 17:16:33 -08:00
return do_put ( rname , lname , false ) ;
1998-08-11 02:13:01 +00:00
}
1996-05-04 07:50:46 +00:00
2001-05-07 01:51:56 +00:00
/*************************************
2003-08-06 20:01:31 +00:00
File list structure .
2001-05-07 01:51:56 +00:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static struct file_list {
struct file_list * prev , * next ;
char * file_path ;
2007-10-18 17:40:25 -07:00
bool isdir ;
2001-05-07 01:51:56 +00:00
} * file_list ;
/****************************************************************************
2003-08-06 20:01:31 +00:00
Free a file_list structure .
2001-05-07 01:51:56 +00:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2009-02-23 16:22:43 -08:00
static void free_file_list ( struct file_list * l_head )
2001-05-07 01:51:56 +00:00
{
2006-03-13 23:58:58 +00:00
struct file_list * list , * next ;
2007-12-06 17:16:33 -08:00
2009-02-23 16:22:43 -08:00
for ( list = l_head ; list ; list = next ) {
2006-03-13 23:58:58 +00:00
next = list - > next ;
2009-02-23 16:22:43 -08:00
DLIST_REMOVE ( l_head , list ) ;
2017-07-05 15:53:07 -07:00
TALLOC_FREE ( list ) ;
2001-05-07 01:51:56 +00:00
}
}
1996-05-04 07:50:46 +00:00
/****************************************************************************
2003-08-06 20:01:31 +00:00
Seek in a directory / file list until you get something that doesn ' t start with
the specified name .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2007-10-18 17:40:25 -07:00
static bool seek_list ( struct file_list * list , char * name )
1996-05-04 07:50:46 +00:00
{
2001-05-07 01:51:56 +00:00
while ( list ) {
trim_string ( list - > file_path , " ./ " , " \n " ) ;
if ( strncmp ( list - > file_path , name , strlen ( name ) ) ! = 0 ) {
2007-12-06 17:16:33 -08:00
return true ;
1998-11-09 03:45:49 +00:00
}
2001-05-07 01:51:56 +00:00
list = list - > next ;
1996-05-04 07:50:46 +00:00
}
2007-12-06 17:16:33 -08:00
return false ;
1996-05-04 07:50:46 +00:00
}
/****************************************************************************
2003-08-06 20:01:31 +00:00
Set the file selection mask .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2001-10-09 19:12:18 +00:00
static int cmd_select ( void )
1996-05-04 07:50:46 +00:00
{
2007-12-06 17:16:33 -08:00
TALLOC_CTX * ctx = talloc_tos ( ) ;
char * new_fs = NULL ;
2007-12-19 21:59:28 +01:00
next_token_talloc ( ctx , & cmd_ptr , & new_fs , NULL )
2007-12-06 17:16:33 -08:00
;
if ( new_fs ) {
client_set_fileselection ( new_fs ) ;
} else {
client_set_fileselection ( " " ) ;
}
2001-10-09 19:12:18 +00:00
return 0 ;
1996-05-04 07:50:46 +00:00
}
2001-05-07 01:51:56 +00:00
/****************************************************************************
Recursive file matching function act as find
2007-12-06 17:16:33 -08:00
match must be always set to true when calling this function
2001-05-07 01:51:56 +00:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2003-08-06 20:01:31 +00:00
2017-07-05 15:53:07 -07:00
static int file_find ( TALLOC_CTX * ctx ,
struct file_list * * list ,
const char * directory ,
const char * expression ,
bool match )
2001-05-07 01:51:56 +00:00
{
2012-03-28 13:22:03 +11:00
DIR * dir ;
2001-05-07 01:51:56 +00:00
struct file_list * entry ;
struct stat statbuf ;
2001-05-07 05:19:52 +00:00
int ret ;
2001-05-07 01:51:56 +00:00
char * path ;
2007-10-18 17:40:25 -07:00
bool isdir ;
2003-03-18 09:43:00 +00:00
const char * dname ;
2001-05-07 01:51:56 +00:00
2012-03-28 13:01:19 +11:00
dir = opendir ( directory ) ;
2003-08-06 20:01:31 +00:00
if ( ! dir )
return - 1 ;
2007-12-06 17:16:33 -08:00
2001-05-07 05:19:52 +00:00
while ( ( dname = readdirname ( dir ) ) ) {
2022-03-12 12:40:29 +01:00
if ( ISDOT ( dname ) | | ISDOTDOT ( dname ) ) {
2003-08-06 20:01:31 +00:00
continue ;
2022-03-12 12:40:29 +01:00
}
2007-12-06 17:16:33 -08:00
2017-07-05 15:53:07 -07:00
path = talloc_asprintf ( ctx , " %s/%s " , directory , dname ) ;
if ( path = = NULL ) {
2001-05-07 01:51:56 +00:00
continue ;
}
2007-12-06 17:16:33 -08:00
isdir = false ;
2001-08-20 05:15:26 +00:00
if ( ! match | | ! gen_fnmatch ( expression , dname ) ) {
2001-05-07 01:51:56 +00:00
if ( recurse ) {
ret = stat ( path , & statbuf ) ;
2001-05-07 05:19:52 +00:00
if ( ret = = 0 ) {
2001-05-07 01:51:56 +00:00
if ( S_ISDIR ( statbuf . st_mode ) ) {
2007-12-06 17:16:33 -08:00
isdir = true ;
2017-07-05 15:53:07 -07:00
ret = file_find ( ctx ,
list ,
path ,
expression ,
false ) ;
2001-05-07 01:51:56 +00:00
}
} else {
2001-09-07 14:14:57 +00:00
d_printf ( " file_find: cannot stat file %s \n " , path ) ;
2001-05-07 01:51:56 +00:00
}
2007-12-06 17:16:33 -08:00
2001-05-07 05:19:52 +00:00
if ( ret = = - 1 ) {
2017-07-05 15:53:07 -07:00
TALLOC_FREE ( path ) ;
2012-03-28 13:08:27 +11:00
closedir ( dir ) ;
2001-05-07 05:19:52 +00:00
return - 1 ;
2001-05-07 01:51:56 +00:00
}
}
2017-07-05 15:53:07 -07:00
entry = talloc_zero ( ctx , struct file_list ) ;
2001-05-07 01:51:56 +00:00
if ( ! entry ) {
2001-09-07 14:14:57 +00:00
d_printf ( " Out of memory in file_find \n " ) ;
2012-03-28 13:08:27 +11:00
closedir ( dir ) ;
2001-05-07 05:19:52 +00:00
return - 1 ;
2001-05-07 01:51:56 +00:00
}
2017-07-05 15:53:07 -07:00
entry - > file_path = talloc_move ( entry , & path ) ;
2001-05-07 01:51:56 +00:00
entry - > isdir = isdir ;
DLIST_ADD ( * list , entry ) ;
} else {
2017-07-05 15:53:07 -07:00
TALLOC_FREE ( path ) ;
2001-05-07 01:51:56 +00:00
}
}
2001-05-07 05:19:52 +00:00
2012-03-28 13:08:27 +11:00
closedir ( dir ) ;
2001-05-07 01:51:56 +00:00
return 0 ;
}
1996-05-04 07:50:46 +00:00
/****************************************************************************
2003-08-06 20:01:31 +00:00
mput some files .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2001-10-09 19:12:18 +00:00
static int cmd_mput ( void )
1996-05-04 07:50:46 +00:00
{
2007-12-06 17:16:33 -08:00
TALLOC_CTX * ctx = talloc_tos ( ) ;
char * p = NULL ;
2007-12-19 21:59:28 +01:00
while ( next_token_talloc ( ctx , & cmd_ptr , & p , NULL ) ) {
2001-05-07 01:51:56 +00:00
int ret ;
struct file_list * temp_list ;
char * quest , * lname , * rname ;
2007-12-06 17:16:33 -08:00
2001-05-07 01:51:56 +00:00
file_list = NULL ;
2001-04-11 23:19:08 +00:00
2017-07-05 15:53:07 -07:00
ret = file_find ( ctx , & file_list , " . " , p , true ) ;
2001-05-07 01:51:56 +00:00
if ( ret ) {
free_file_list ( file_list ) ;
2001-04-11 23:19:08 +00:00
continue ;
}
2007-12-06 17:16:33 -08:00
2001-05-07 01:51:56 +00:00
quest = NULL ;
lname = NULL ;
rname = NULL ;
2007-12-06 17:16:33 -08:00
for ( temp_list = file_list ; temp_list ;
2001-05-07 01:51:56 +00:00
temp_list = temp_list - > next ) {
1998-11-09 03:45:49 +00:00
2001-09-17 00:47:40 +00:00
SAFE_FREE ( lname ) ;
2007-12-06 17:16:33 -08:00
if ( asprintf ( & lname , " %s/ " , temp_list - > file_path ) < = 0 ) {
2001-05-07 01:51:56 +00:00
continue ;
2007-12-06 17:16:33 -08:00
}
2001-05-07 01:51:56 +00:00
trim_string ( lname , " ./ " , " / " ) ;
2007-12-06 17:16:33 -08:00
1998-11-09 03:45:49 +00:00
/* check if it's a directory */
2001-05-07 01:51:56 +00:00
if ( temp_list - > isdir ) {
/* if (!recurse) continue; */
2007-12-06 17:16:33 -08:00
2001-09-17 00:47:40 +00:00
SAFE_FREE ( quest ) ;
2007-12-06 17:16:33 -08:00
if ( asprintf ( & quest , " Put directory %s? " , lname ) < 0 ) {
break ;
}
2001-05-07 01:51:56 +00:00
if ( prompt & & ! yesno ( quest ) ) { /* No */
/* Skip the directory */
lname [ strlen ( lname ) - 1 ] = ' / ' ;
if ( ! seek_list ( temp_list , lname ) )
2007-12-06 17:16:33 -08:00
break ;
2001-05-07 01:51:56 +00:00
} else { /* Yes */
2001-09-17 00:47:40 +00:00
SAFE_FREE ( rname ) ;
2008-02-08 16:59:52 -08:00
if ( asprintf ( & rname , " %s%s " , client_get_cur_dir ( ) , lname ) < 0 ) {
2007-12-06 17:16:33 -08:00
break ;
}
2008-02-08 16:59:52 -08:00
normalize_name ( rname ) ;
2017-10-20 15:09:38 -07:00
{
char * tmp_rname =
client_clean_name ( ctx , rname ) ;
if ( tmp_rname = = NULL ) {
break ;
}
SAFE_FREE ( rname ) ;
rname = smb_xstrdup ( tmp_rname ) ;
TALLOC_FREE ( tmp_rname ) ;
if ( rname = = NULL ) {
break ;
}
}
2009-04-22 06:46:42 -07:00
if ( ! NT_STATUS_IS_OK ( cli_chkpath ( cli , rname ) ) & &
2001-05-07 01:51:56 +00:00
! do_mkdir ( rname ) ) {
DEBUG ( 0 , ( " Unable to make dir, skipping... " ) ) ;
/* Skip the directory */
lname [ strlen ( lname ) - 1 ] = ' / ' ;
2007-12-06 17:16:33 -08:00
if ( ! seek_list ( temp_list , lname ) ) {
2001-05-07 01:51:56 +00:00
break ;
2007-12-06 17:16:33 -08:00
}
2001-05-07 01:51:56 +00:00
}
1998-11-09 03:45:49 +00:00
}
continue ;
} else {
2001-09-17 00:47:40 +00:00
SAFE_FREE ( quest ) ;
2007-12-06 17:16:33 -08:00
if ( asprintf ( & quest , " Put file %s? " , lname ) < 0 ) {
break ;
}
if ( prompt & & ! yesno ( quest ) ) {
/* No */
2001-05-07 01:51:56 +00:00
continue ;
2007-12-06 17:16:33 -08:00
}
2001-05-07 01:51:56 +00:00
/* Yes */
2001-09-17 00:47:40 +00:00
SAFE_FREE ( rname ) ;
2008-02-08 16:59:52 -08:00
if ( asprintf ( & rname , " %s%s " , client_get_cur_dir ( ) , lname ) < 0 ) {
2007-12-06 17:16:33 -08:00
break ;
}
1998-11-09 03:45:49 +00:00
}
1996-05-04 07:50:46 +00:00
2008-02-08 16:59:52 -08:00
normalize_name ( rname ) ;
1996-05-04 07:50:46 +00:00
2017-10-20 15:09:38 -07:00
{
char * tmp_rname = client_clean_name ( ctx , rname ) ;
if ( tmp_rname = = NULL ) {
break ;
}
SAFE_FREE ( rname ) ;
rname = smb_xstrdup ( tmp_rname ) ;
TALLOC_FREE ( tmp_rname ) ;
if ( rname = = NULL ) {
break ;
}
}
2007-12-06 17:16:33 -08:00
do_put ( rname , lname , false ) ;
1996-05-04 07:50:46 +00:00
}
2001-05-07 01:51:56 +00:00
free_file_list ( file_list ) ;
2001-09-17 00:47:40 +00:00
SAFE_FREE ( quest ) ;
SAFE_FREE ( lname ) ;
SAFE_FREE ( rname ) ;
1996-05-04 07:50:46 +00:00
}
2001-10-09 19:12:18 +00:00
return 0 ;
1996-05-04 07:50:46 +00:00
}
/****************************************************************************
2003-08-06 20:01:31 +00:00
Cancel a print job .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2001-10-09 19:12:18 +00:00
static int do_cancel ( int job )
1996-05-04 07:50:46 +00:00
{
1998-11-09 03:45:49 +00:00
if ( cli_printjob_del ( cli , job ) ) {
2001-09-07 14:14:57 +00:00
d_printf ( " Job %d cancelled \n " , job ) ;
2001-10-09 19:12:18 +00:00
return 0 ;
1998-11-09 03:45:49 +00:00
} else {
2011-07-08 09:29:29 +02:00
NTSTATUS status = cli_nt_error ( cli ) ;
d_printf ( " Error cancelling job %d : %s \n " ,
job , nt_errstr ( status ) ) ;
2001-10-09 19:12:18 +00:00
return 1 ;
1998-11-09 03:45:49 +00:00
}
1996-05-04 07:50:46 +00:00
}
/****************************************************************************
2003-08-06 20:01:31 +00:00
Cancel a print job .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2001-10-09 19:12:18 +00:00
static int cmd_cancel ( void )
1996-05-04 07:50:46 +00:00
{
2007-12-06 17:16:33 -08:00
TALLOC_CTX * ctx = talloc_tos ( ) ;
char * buf = NULL ;
int job ;
1996-05-04 07:50:46 +00:00
2007-12-19 21:59:28 +01:00
if ( ! next_token_talloc ( ctx , & cmd_ptr , & buf , NULL ) ) {
2001-09-07 14:14:57 +00:00
d_printf ( " cancel <jobid> ... \n " ) ;
2001-10-09 19:12:18 +00:00
return 1 ;
1998-11-09 03:45:49 +00:00
}
do {
job = atoi ( buf ) ;
do_cancel ( job ) ;
2007-12-19 21:59:28 +01:00
} while ( next_token_talloc ( ctx , & cmd_ptr , & buf , NULL ) ) ;
2007-12-06 17:16:33 -08:00
2001-10-09 19:12:18 +00:00
return 0 ;
1998-11-09 03:45:49 +00:00
}
1996-05-04 07:50:46 +00:00
/****************************************************************************
2003-08-06 20:01:31 +00:00
Print a file .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2001-10-09 19:12:18 +00:00
static int cmd_print ( void )
1996-05-04 07:50:46 +00:00
{
2007-12-06 17:16:33 -08:00
TALLOC_CTX * ctx = talloc_tos ( ) ;
char * lname = NULL ;
char * rname = NULL ;
char * p = NULL ;
1996-05-04 07:50:46 +00:00
2007-12-19 21:59:28 +01:00
if ( ! next_token_talloc ( ctx , & cmd_ptr , & lname , NULL ) ) {
2001-09-07 14:14:57 +00:00
d_printf ( " print <filename> \n " ) ;
2001-10-10 07:51:20 +00:00
return 1 ;
1996-05-04 07:50:46 +00:00
}
2007-12-06 17:16:33 -08:00
rname = talloc_strdup ( ctx , lname ) ;
if ( ! rname ) {
return 1 ;
}
2001-07-04 07:36:09 +00:00
p = strrchr_m ( rname , ' / ' ) ;
1998-11-09 03:45:49 +00:00
if ( p ) {
2007-12-06 17:16:33 -08:00
rname = talloc_asprintf ( ctx ,
" %s-%d " ,
p + 1 ,
2012-03-24 20:17:08 +01:00
( int ) getpid ( ) ) ;
1996-05-04 07:50:46 +00:00
}
1998-11-09 03:45:49 +00:00
if ( strequal ( lname , " - " ) ) {
2007-12-06 17:16:33 -08:00
rname = talloc_asprintf ( ctx ,
" stdin-%d " ,
2012-03-24 20:17:08 +01:00
( int ) getpid ( ) ) ;
2007-12-06 17:16:33 -08:00
}
if ( ! rname ) {
return 1 ;
1998-11-09 03:45:49 +00:00
}
1996-05-04 07:50:46 +00:00
2007-12-06 17:16:33 -08:00
return do_put ( rname , lname , false ) ;
1996-05-04 07:50:46 +00:00
}
1997-07-01 01:19:13 +00:00
/****************************************************************************
2003-08-06 20:01:31 +00:00
Show a print queue entry .
1997-07-01 01:19:13 +00:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2003-08-06 20:01:31 +00:00
1998-11-09 03:45:49 +00:00
static void queue_fn ( struct print_job_info * p )
1997-07-01 01:19:13 +00:00
{
2001-09-07 14:14:57 +00:00
d_printf ( " %-6d %-9d %s \n " , ( int ) p - > id , ( int ) p - > size , p - > name ) ;
1997-07-01 01:19:13 +00:00
}
1996-08-13 08:57:55 +00:00
/****************************************************************************
2003-08-06 20:01:31 +00:00
Show a print queue .
1996-08-13 08:57:55 +00:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2003-08-06 20:01:31 +00:00
2001-10-09 19:12:18 +00:00
static int cmd_queue ( void )
1996-08-13 08:57:55 +00:00
{
2001-10-09 19:12:18 +00:00
cli_print_queue ( cli , queue_fn ) ;
return 0 ;
1996-08-13 08:57:55 +00:00
}
1996-05-04 07:50:46 +00:00
/****************************************************************************
2003-08-06 20:01:31 +00:00
Delete some files .
1996-05-04 07:50:46 +00:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2003-08-06 20:01:31 +00:00
2010-10-29 11:56:51 -07:00
static NTSTATUS do_del ( struct cli_state * cli_state , struct file_info * finfo ,
2010-07-30 16:18:51 +02:00
const char * dir )
1996-05-04 07:50:46 +00:00
{
2007-12-06 17:16:33 -08:00
TALLOC_CTX * ctx = talloc_tos ( ) ;
char * mask = NULL ;
2022-06-16 15:12:05 +01:00
struct cli_state * targetcli = NULL ;
char * targetname = NULL ;
struct cli_credentials * creds = samba_cmdline_get_creds ( ) ;
2010-08-13 15:08:38 +02:00
NTSTATUS status ;
2007-12-06 17:16:33 -08:00
mask = talloc_asprintf ( ctx ,
" %s%c%s " ,
dir ,
CLI_DIRSEP_CHAR ,
finfo - > name ) ;
if ( ! mask ) {
2010-10-29 11:56:51 -07:00
return NT_STATUS_NO_MEMORY ;
2007-12-06 17:16:33 -08:00
}
1996-05-04 07:50:46 +00:00
2020-06-03 10:41:27 -07:00
if ( finfo - > attr & FILE_ATTRIBUTE_DIRECTORY ) {
2007-12-06 17:16:33 -08:00
TALLOC_FREE ( mask ) ;
2010-10-29 11:56:51 -07:00
return NT_STATUS_OK ;
2007-12-06 17:16:33 -08:00
}
1996-05-04 07:50:46 +00:00
2022-06-16 15:12:05 +01:00
status = cli_resolve_path ( ctx , " " ,
creds ,
cli , mask , & targetcli , & targetname ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
goto out ;
}
status = cli_unlink ( targetcli , targetname , FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN ) ;
out :
2010-08-13 15:08:38 +02:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
2007-12-06 17:16:33 -08:00
d_printf ( " %s deleting remote file %s \n " ,
2010-08-13 15:08:38 +02:00
nt_errstr ( status ) , mask ) ;
1998-11-09 03:45:49 +00:00
}
2007-12-06 17:16:33 -08:00
TALLOC_FREE ( mask ) ;
2010-10-29 11:56:51 -07:00
return status ;
1996-05-04 07:50:46 +00:00
}
/****************************************************************************
2003-08-06 20:01:31 +00:00
Delete some files .
1996-05-04 07:50:46 +00:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2003-08-06 20:01:31 +00:00
2001-10-09 19:12:18 +00:00
static int cmd_del ( void )
1996-05-04 07:50:46 +00:00
{
2007-12-06 17:16:33 -08:00
TALLOC_CTX * ctx = talloc_tos ( ) ;
char * mask = NULL ;
char * buf = NULL ;
2010-10-29 11:56:51 -07:00
NTSTATUS status = NT_STATUS_OK ;
2020-06-03 14:25:50 -07:00
uint32_t attribute = FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN ;
1996-05-04 07:50:46 +00:00
2007-12-06 17:16:33 -08:00
if ( recurse ) {
2011-04-29 11:57:02 +10:00
attribute | = FILE_ATTRIBUTE_DIRECTORY ;
2007-12-06 17:16:33 -08:00
}
mask = talloc_strdup ( ctx , client_get_cur_dir ( ) ) ;
if ( ! mask ) {
return 1 ;
}
2007-12-19 21:59:28 +01:00
if ( ! next_token_talloc ( ctx , & cmd_ptr , & buf , NULL ) ) {
2001-09-07 14:14:57 +00:00
d_printf ( " del <filename> \n " ) ;
2001-10-10 07:51:20 +00:00
return 1 ;
1998-11-09 03:45:49 +00:00
}
2008-12-31 16:30:11 -08:00
mask = talloc_asprintf_append ( mask , " %s " , buf ) ;
2007-12-06 17:16:33 -08:00
if ( ! mask ) {
return 1 ;
}
2017-10-20 15:09:38 -07:00
mask = client_clean_name ( ctx , mask ) ;
if ( mask = = NULL ) {
return 1 ;
}
1998-11-09 03:45:49 +00:00
2010-10-29 11:56:51 -07:00
status = do_list ( mask , attribute , do_del , false , false ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
return 1 ;
}
2001-10-09 19:12:18 +00:00
return 0 ;
1996-05-04 07:50:46 +00:00
}
2017-07-05 17:21:18 -07:00
/****************************************************************************
Delete some files .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static NTSTATUS delete_remote_files_list ( struct cli_state * cli_state ,
struct file_list * flist )
{
NTSTATUS status = NT_STATUS_OK ;
struct file_list * deltree_list_iter = NULL ;
2022-06-16 17:17:45 +01:00
char * targetname = NULL ;
struct cli_state * targetcli = NULL ;
struct cli_credentials * creds = samba_cmdline_get_creds ( ) ;
TALLOC_CTX * ctx = talloc_tos ( ) ;
2017-07-05 17:21:18 -07:00
for ( deltree_list_iter = flist ;
deltree_list_iter ! = NULL ;
deltree_list_iter = deltree_list_iter - > next ) {
2022-06-16 17:17:45 +01:00
status = cli_resolve_path ( ctx ,
" " ,
creds ,
cli_state ,
deltree_list_iter - > file_path ,
& targetcli ,
& targetname ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
d_printf ( " delete_remote_files %s: %s \n " ,
deltree_list_iter - > file_path ,
nt_errstr ( status ) ) ;
return status ;
}
2017-07-05 17:21:18 -07:00
if ( CLI_DIRSEP_CHAR = = ' / ' ) {
/* POSIX. */
2022-06-16 17:17:45 +01:00
status = cli_posix_unlink ( targetcli ,
targetname ) ;
2017-07-05 17:21:18 -07:00
} else if ( deltree_list_iter - > isdir ) {
2022-06-16 17:17:45 +01:00
status = cli_rmdir ( targetcli ,
targetname ) ;
2017-07-05 17:21:18 -07:00
} else {
2022-06-16 17:17:45 +01:00
status = cli_unlink ( targetcli ,
targetname ,
2017-07-05 17:21:18 -07:00
FILE_ATTRIBUTE_SYSTEM |
FILE_ATTRIBUTE_HIDDEN ) ;
}
if ( ! NT_STATUS_IS_OK ( status ) ) {
d_printf ( " %s deleting remote %s %s \n " ,
nt_errstr ( status ) ,
deltree_list_iter - > isdir ?
" directory " : " file " ,
deltree_list_iter - > file_path ) ;
return status ;
}
}
return NT_STATUS_OK ;
}
/****************************************************************************
Save a list of files to delete .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static struct file_list * deltree_list_head ;
static NTSTATUS do_deltree_list ( struct cli_state * cli_state ,
struct file_info * finfo ,
const char * dir )
{
struct file_list * * file_list_head_pp = & deltree_list_head ;
struct file_list * dt = NULL ;
if ( ! do_this_one ( finfo ) ) {
return NT_STATUS_OK ;
}
/* skip if this is . or .. */
if ( ISDOT ( finfo - > name ) | | ISDOTDOT ( finfo - > name ) ) {
return NT_STATUS_OK ;
}
dt = talloc_zero ( NULL , struct file_list ) ;
if ( dt = = NULL ) {
return NT_STATUS_NO_MEMORY ;
}
/* create absolute filename for cli_ntcreate() */
dt - > file_path = talloc_asprintf ( dt ,
" %s%s%s " ,
dir ,
CLI_DIRSEP_STR ,
finfo - > name ) ;
if ( dt - > file_path = = NULL ) {
TALLOC_FREE ( dt ) ;
return NT_STATUS_NO_MEMORY ;
}
2020-06-03 10:41:27 -07:00
if ( finfo - > attr & FILE_ATTRIBUTE_DIRECTORY ) {
2017-07-05 17:21:18 -07:00
dt - > isdir = true ;
}
DLIST_ADD ( * file_list_head_pp , dt ) ;
return NT_STATUS_OK ;
}
static int cmd_deltree ( void )
{
TALLOC_CTX * ctx = talloc_tos ( ) ;
char * buf = NULL ;
NTSTATUS status = NT_STATUS_OK ;
struct file_list * deltree_list_norecurse = NULL ;
struct file_list * deltree_list_iter = NULL ;
2020-06-03 14:25:50 -07:00
uint32_t attribute = FILE_ATTRIBUTE_SYSTEM |
2017-07-05 17:21:18 -07:00
FILE_ATTRIBUTE_HIDDEN |
FILE_ATTRIBUTE_DIRECTORY ;
bool ok ;
char * mask = talloc_strdup ( ctx , client_get_cur_dir ( ) ) ;
if ( mask = = NULL ) {
return 1 ;
}
ok = next_token_talloc ( ctx , & cmd_ptr , & buf , NULL ) ;
if ( ! ok ) {
d_printf ( " deltree <filename> \n " ) ;
return 1 ;
}
mask = talloc_asprintf_append ( mask , " %s " , buf ) ;
if ( mask = = NULL ) {
return 1 ;
}
2017-10-20 15:09:38 -07:00
mask = client_clean_name ( ctx , mask ) ;
if ( mask = = NULL ) {
return 1 ;
}
2017-07-05 17:21:18 -07:00
deltree_list_head = NULL ;
/*
* Get the list of directories to
* delete ( in case mask has a wildcard ) .
*/
status = do_list ( mask , attribute , do_deltree_list , false , true ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
goto err ;
}
deltree_list_norecurse = deltree_list_head ;
deltree_list_head = NULL ;
for ( deltree_list_iter = deltree_list_norecurse ;
deltree_list_iter ! = NULL ;
deltree_list_iter = deltree_list_iter - > next ) {
if ( deltree_list_iter - > isdir = = false ) {
2022-06-16 17:17:45 +01:00
char * targetname = NULL ;
struct cli_state * targetcli = NULL ;
struct cli_credentials * creds = samba_cmdline_get_creds ( ) ;
status = cli_resolve_path ( ctx ,
" " ,
creds ,
cli ,
deltree_list_iter - > file_path ,
& targetcli ,
& targetname ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
goto err ;
}
2017-07-05 17:21:18 -07:00
/* Just a regular file. */
if ( CLI_DIRSEP_CHAR = = ' / ' ) {
/* POSIX. */
2022-06-16 17:17:45 +01:00
status = cli_posix_unlink ( targetcli ,
targetname ) ;
2017-07-05 17:21:18 -07:00
} else {
2022-06-16 17:17:45 +01:00
status = cli_unlink ( targetcli ,
targetname ,
2017-07-05 17:21:18 -07:00
FILE_ATTRIBUTE_SYSTEM |
FILE_ATTRIBUTE_HIDDEN ) ;
}
if ( ! NT_STATUS_IS_OK ( status ) ) {
goto err ;
}
continue ;
}
/*
* Get the list of files or directories to
* delete in depth order .
*/
status = do_list ( deltree_list_iter - > file_path ,
attribute ,
do_deltree_list ,
true ,
true ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
goto err ;
}
status = delete_remote_files_list ( cli , deltree_list_head ) ;
free_file_list ( deltree_list_head ) ;
deltree_list_head = NULL ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
goto err ;
}
}
free_file_list ( deltree_list_norecurse ) ;
free_file_list ( deltree_list_head ) ;
return 0 ;
err :
free_file_list ( deltree_list_norecurse ) ;
free_file_list ( deltree_list_head ) ;
deltree_list_head = NULL ;
return 1 ;
}
2007-03-07 19:45:22 +00:00
/****************************************************************************
Wildcard delete some files .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static int cmd_wdel ( void )
{
2007-12-06 17:16:33 -08:00
TALLOC_CTX * ctx = talloc_tos ( ) ;
char * mask = NULL ;
char * buf = NULL ;
2020-06-03 14:25:50 -07:00
uint32_t attribute ;
2007-03-08 23:54:57 +00:00
struct cli_state * targetcli ;
2007-12-06 17:16:33 -08:00
char * targetname = NULL ;
2020-08-18 16:58:19 +02:00
struct cli_credentials * creds = samba_cmdline_get_creds ( ) ;
2010-08-13 15:08:38 +02:00
NTSTATUS status ;
2007-03-07 19:45:22 +00:00
2007-12-19 21:59:28 +01:00
if ( ! next_token_talloc ( ctx , & cmd_ptr , & buf , NULL ) ) {
2007-03-07 19:45:22 +00:00
d_printf ( " wdel 0x<attrib> <wcard> \n " ) ;
return 1 ;
}
2020-06-03 14:25:50 -07:00
attribute = ( uint32_t ) strtol ( buf , ( char * * ) NULL , 16 ) ;
2007-03-07 19:45:22 +00:00
2007-12-19 21:59:28 +01:00
if ( ! next_token_talloc ( ctx , & cmd_ptr , & buf , NULL ) ) {
2007-03-07 19:45:22 +00:00
d_printf ( " wdel 0x<attrib> <wcard> \n " ) ;
return 1 ;
}
2007-12-06 17:16:33 -08:00
mask = talloc_asprintf ( ctx , " %s%s " ,
client_get_cur_dir ( ) ,
buf ) ;
if ( ! mask ) {
return 1 ;
}
2017-10-20 15:09:38 -07:00
mask = client_clean_name ( ctx , mask ) ;
if ( mask = = NULL ) {
return 1 ;
}
2007-03-07 19:45:22 +00:00
2020-08-18 17:42:25 +02:00
status = cli_resolve_path ( ctx , " " ,
creds ,
2017-04-25 17:03:10 -07:00
cli , mask , & targetcli , & targetname ) ;
2011-07-03 20:53:55 +02:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
2011-07-05 19:42:46 +02:00
d_printf ( " cmd_wdel %s: %s \n " , mask , nt_errstr ( status ) ) ;
2007-03-08 23:54:57 +00:00
return 1 ;
}
2007-12-06 17:16:33 -08:00
2010-08-13 15:08:38 +02:00
status = cli_unlink ( targetcli , targetname , attribute ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
d_printf ( " %s deleting remote files %s \n " , nt_errstr ( status ) ,
targetname ) ;
2007-03-07 19:45:22 +00:00
}
return 0 ;
}
1999-12-13 13:27:58 +00:00
/****************************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2003-08-06 20:01:31 +00:00
2001-10-09 19:12:18 +00:00
static int cmd_open ( void )
1999-12-13 13:27:58 +00:00
{
2007-12-06 17:16:33 -08:00
TALLOC_CTX * ctx = talloc_tos ( ) ;
char * mask = NULL ;
char * buf = NULL ;
char * targetname = NULL ;
2005-02-23 19:26:32 +00:00
struct cli_state * targetcli ;
2009-04-30 15:26:43 -07:00
uint16_t fnum = ( uint16_t ) - 1 ;
2020-08-18 16:58:19 +02:00
struct cli_credentials * creds = samba_cmdline_get_creds ( ) ;
2011-07-03 20:53:55 +02:00
NTSTATUS status ;
2006-07-12 00:21:14 +00:00
2007-12-19 21:59:28 +01:00
if ( ! next_token_talloc ( ctx , & cmd_ptr , & buf , NULL ) ) {
2001-10-09 19:12:18 +00:00
d_printf ( " open <filename> \n " ) ;
return 1 ;
1999-12-13 13:27:58 +00:00
}
2007-12-06 17:16:33 -08:00
mask = talloc_asprintf ( ctx ,
" %s%s " ,
client_get_cur_dir ( ) ,
buf ) ;
if ( ! mask ) {
return 1 ;
}
1999-12-13 13:27:58 +00:00
2017-10-20 15:09:38 -07:00
mask = client_clean_name ( ctx , mask ) ;
if ( mask = = NULL ) {
return 1 ;
}
2020-08-18 17:42:25 +02:00
status = cli_resolve_path ( ctx , " " ,
creds ,
2017-04-25 17:03:10 -07:00
cli , mask , & targetcli , & targetname ) ;
2011-07-03 20:53:55 +02:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
2011-07-05 19:42:46 +02:00
d_printf ( " open %s: %s \n " , mask , nt_errstr ( status ) ) ;
2005-02-23 19:26:32 +00:00
return 1 ;
}
2007-12-06 17:16:33 -08:00
2011-07-08 09:16:20 +02:00
status = cli_ntcreate ( targetcli , targetname , 0 ,
2009-04-30 15:26:43 -07:00
FILE_READ_DATA | FILE_WRITE_DATA , 0 ,
2011-07-08 09:16:20 +02:00
FILE_SHARE_READ | FILE_SHARE_WRITE , FILE_OPEN ,
2014-05-08 20:55:57 -07:00
0x0 , 0x0 , & fnum , NULL ) ;
2011-07-08 09:16:20 +02:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
status = cli_ntcreate ( targetcli , targetname , 0 ,
2009-04-30 15:26:43 -07:00
FILE_READ_DATA , 0 ,
2011-07-08 09:16:20 +02:00
FILE_SHARE_READ | FILE_SHARE_WRITE , FILE_OPEN ,
2014-05-08 20:55:57 -07:00
0x0 , 0x0 , & fnum , NULL ) ;
2011-07-08 09:16:20 +02:00
if ( NT_STATUS_IS_OK ( status ) ) {
2006-07-12 03:20:53 +00:00
d_printf ( " open file %s: for read/write fnum %d \n " , targetname , fnum ) ;
} else {
2011-07-08 09:16:20 +02:00
d_printf ( " Failed to open file %s. %s \n " ,
targetname , nt_errstr ( status ) ) ;
2006-07-12 03:20:53 +00:00
}
} else {
d_printf ( " open file %s: for read/write fnum %d \n " , targetname , fnum ) ;
}
2006-07-12 00:21:14 +00:00
return 0 ;
}
2007-12-26 17:12:36 -08:00
static int cmd_posix_encrypt ( void )
{
TALLOC_CTX * ctx = talloc_tos ( ) ;
NTSTATUS status = NT_STATUS_UNSUCCESSFUL ;
2016-11-03 14:50:28 +01:00
char * domain = NULL ;
char * user = NULL ;
char * password = NULL ;
struct cli_credentials * creds = NULL ;
struct cli_credentials * lcreds = NULL ;
2007-12-26 17:12:36 -08:00
2016-11-03 14:50:28 +01:00
if ( next_token_talloc ( ctx , & cmd_ptr , & domain , NULL ) ) {
2007-12-26 17:12:36 -08:00
2016-11-03 14:50:28 +01:00
if ( ! next_token_talloc ( ctx , & cmd_ptr , & user , NULL ) ) {
2007-12-26 17:12:36 -08:00
d_printf ( " posix_encrypt domain user password \n " ) ;
return 1 ;
}
2016-11-03 14:50:28 +01:00
if ( ! next_token_talloc ( ctx , & cmd_ptr , & password , NULL ) ) {
2007-12-26 17:12:36 -08:00
d_printf ( " posix_encrypt domain user password \n " ) ;
return 1 ;
}
2016-11-03 14:50:28 +01:00
lcreds = cli_session_creds_init ( ctx ,
user ,
domain ,
NULL , /* realm */
password ,
false , /* use_kerberos */
false , /* fallback_after_kerberos */
false , /* use_ccache */
false ) ; /* password_is_nt_hash */
if ( lcreds = = NULL ) {
d_printf ( " cli_session_creds_init() failed. \n " ) ;
return - 1 ;
}
creds = lcreds ;
} else {
bool auth_requested = false ;
2020-08-18 16:58:19 +02:00
creds = samba_cmdline_get_creds ( ) ;
2016-11-03 14:50:28 +01:00
auth_requested = cli_credentials_authentication_requested ( creds ) ;
if ( ! auth_requested ) {
2007-12-26 17:12:36 -08:00
d_printf ( " posix_encrypt domain user password \n " ) ;
return 1 ;
}
}
2016-11-03 14:50:28 +01:00
status = cli_smb1_setup_encryption ( cli , creds ) ;
/* gensec currently references the creds so we can't free them here */
talloc_unlink ( ctx , lcreds ) ;
2007-12-26 17:12:36 -08:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
d_printf ( " posix_encrypt failed with error %s \n " , nt_errstr ( status ) ) ;
} else {
2020-08-18 16:58:19 +02:00
bool ok ;
2007-12-26 17:12:36 -08:00
d_printf ( " encryption on \n " ) ;
2020-08-18 16:58:19 +02:00
ok = cli_credentials_set_smb_encryption ( creds ,
SMB_ENCRYPTION_REQUIRED ,
CRED_SPECIFIED ) ;
SMB_ASSERT ( ok ) ;
2007-12-26 17:12:36 -08:00
}
return 0 ;
}
2007-03-01 21:56:54 +00:00
/****************************************************************************
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static int cmd_posix_open ( void )
{
2007-12-06 17:16:33 -08:00
TALLOC_CTX * ctx = talloc_tos ( ) ;
char * mask = NULL ;
char * buf = NULL ;
char * targetname = NULL ;
2007-03-01 21:56:54 +00:00
struct cli_state * targetcli ;
mode_t mode ;
2009-05-20 18:31:36 -07:00
uint16_t fnum ;
2020-08-18 16:58:19 +02:00
struct cli_credentials * creds = samba_cmdline_get_creds ( ) ;
2011-07-03 20:53:55 +02:00
NTSTATUS status ;
2007-03-01 21:56:54 +00:00
2007-12-19 21:59:28 +01:00
if ( ! next_token_talloc ( ctx , & cmd_ptr , & buf , NULL ) ) {
2007-03-01 21:56:54 +00:00
d_printf ( " posix_open <filename> 0<mode> \n " ) ;
return 1 ;
}
2007-12-06 17:16:33 -08:00
mask = talloc_asprintf ( ctx ,
" %s%s " ,
client_get_cur_dir ( ) ,
buf ) ;
if ( ! mask ) {
return 1 ;
}
2017-10-20 15:09:38 -07:00
mask = client_clean_name ( ctx , mask ) ;
if ( mask = = NULL ) {
return 1 ;
}
2007-12-06 17:16:33 -08:00
2007-12-19 21:59:28 +01:00
if ( ! next_token_talloc ( ctx , & cmd_ptr , & buf , NULL ) ) {
2007-03-01 21:56:54 +00:00
d_printf ( " posix_open <filename> 0<mode> \n " ) ;
return 1 ;
}
2021-11-20 20:17:11 -08:00
if ( CLI_DIRSEP_CHAR ! = ' / ' ) {
d_printf ( " Command \" posix \" must be issued before "
" the \" posix_open \" command can be used. \n " ) ;
return 1 ;
}
2007-03-01 21:56:54 +00:00
mode = ( mode_t ) strtol ( buf , ( char * * ) NULL , 8 ) ;
2020-08-18 17:42:25 +02:00
status = cli_resolve_path ( ctx , " " ,
creds ,
2017-04-25 17:03:10 -07:00
cli , mask , & targetcli , & targetname ) ;
2011-07-03 20:53:55 +02:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
2011-07-05 19:42:46 +02:00
d_printf ( " posix_open %s: %s \n " , mask , nt_errstr ( status ) ) ;
2007-03-01 21:56:54 +00:00
return 1 ;
}
2007-12-06 17:16:33 -08:00
2011-07-05 19:55:25 +02:00
status = cli_posix_open ( targetcli , targetname , O_CREAT | O_RDWR , mode ,
& fnum ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
status = cli_posix_open ( targetcli , targetname ,
O_CREAT | O_RDONLY , mode , & fnum ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
d_printf ( " Failed to open file %s. %s \n " , targetname ,
nt_errstr ( status ) ) ;
2011-07-05 19:51:09 +02:00
} else {
2011-07-05 19:55:25 +02:00
d_printf ( " posix_open file %s: for readonly fnum %d \n " ,
targetname , fnum ) ;
2007-03-01 21:56:54 +00:00
}
} else {
2011-07-05 19:55:25 +02:00
d_printf ( " posix_open file %s: for read/write fnum %d \n " ,
targetname , fnum ) ;
2007-03-01 21:56:54 +00:00
}
return 0 ;
}
static int cmd_posix_mkdir ( void )
{
2007-12-06 17:16:33 -08:00
TALLOC_CTX * ctx = talloc_tos ( ) ;
char * mask = NULL ;
char * buf = NULL ;
char * targetname = NULL ;
2007-03-01 21:56:54 +00:00
struct cli_state * targetcli ;
mode_t mode ;
2020-08-18 16:58:19 +02:00
struct cli_credentials * creds = samba_cmdline_get_creds ( ) ;
2011-07-03 20:53:55 +02:00
NTSTATUS status ;
2007-03-01 21:56:54 +00:00
2007-12-19 21:59:28 +01:00
if ( ! next_token_talloc ( ctx , & cmd_ptr , & buf , NULL ) ) {
2007-03-01 21:56:54 +00:00
d_printf ( " posix_mkdir <filename> 0<mode> \n " ) ;
return 1 ;
}
2007-12-06 17:16:33 -08:00
mask = talloc_asprintf ( ctx ,
" %s%s " ,
client_get_cur_dir ( ) ,
buf ) ;
if ( ! mask ) {
return 1 ;
}
2017-10-20 15:09:38 -07:00
mask = client_clean_name ( ctx , mask ) ;
if ( mask = = NULL ) {
return 1 ;
}
2007-12-06 17:16:33 -08:00
2007-12-19 21:59:28 +01:00
if ( ! next_token_talloc ( ctx , & cmd_ptr , & buf , NULL ) ) {
2007-03-01 21:56:54 +00:00
d_printf ( " posix_mkdir <filename> 0<mode> \n " ) ;
return 1 ;
}
2021-11-20 20:17:11 -08:00
if ( CLI_DIRSEP_CHAR ! = ' / ' ) {
d_printf ( " Command \" posix \" must be issued before "
" the \" posix_mkdir \" command can be used. \n " ) ;
return 1 ;
}
2007-03-01 21:56:54 +00:00
mode = ( mode_t ) strtol ( buf , ( char * * ) NULL , 8 ) ;
2020-08-18 17:42:25 +02:00
status = cli_resolve_path ( ctx , " " ,
creds ,
2017-04-25 17:03:10 -07:00
cli , mask , & targetcli , & targetname ) ;
2011-07-03 20:53:55 +02:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
2011-07-05 19:42:46 +02:00
d_printf ( " posix_mkdir %s: %s \n " , mask , nt_errstr ( status ) ) ;
2007-03-01 21:56:54 +00:00
return 1 ;
}
2007-03-08 23:54:57 +00:00
2011-07-08 09:16:20 +02:00
status = cli_posix_mkdir ( targetcli , targetname , mode ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
d_printf ( " Failed to open file %s. %s \n " ,
targetname , nt_errstr ( status ) ) ;
2007-03-01 21:56:54 +00:00
} else {
d_printf ( " posix_mkdir created directory %s \n " , targetname ) ;
}
return 0 ;
}
static int cmd_posix_unlink ( void )
{
2007-12-06 17:16:33 -08:00
TALLOC_CTX * ctx = talloc_tos ( ) ;
char * mask = NULL ;
char * buf = NULL ;
char * targetname = NULL ;
2007-03-01 21:56:54 +00:00
struct cli_state * targetcli ;
2020-08-18 16:58:19 +02:00
struct cli_credentials * creds = samba_cmdline_get_creds ( ) ;
2011-07-03 20:53:55 +02:00
NTSTATUS status ;
2007-03-01 21:56:54 +00:00
2007-12-19 21:59:28 +01:00
if ( ! next_token_talloc ( ctx , & cmd_ptr , & buf , NULL ) ) {
2007-03-01 21:56:54 +00:00
d_printf ( " posix_unlink <filename> \n " ) ;
return 1 ;
}
2021-11-20 20:17:11 -08:00
if ( CLI_DIRSEP_CHAR ! = ' / ' ) {
d_printf ( " Command \" posix \" must be issued before "
" the \" posix_unlink \" command can be used. \n " ) ;
return 1 ;
}
2007-12-06 17:16:33 -08:00
mask = talloc_asprintf ( ctx ,
" %s%s " ,
client_get_cur_dir ( ) ,
buf ) ;
if ( ! mask ) {
return 1 ;
}
2017-10-20 15:09:38 -07:00
mask = client_clean_name ( ctx , mask ) ;
if ( mask = = NULL ) {
return 1 ;
}
2007-03-01 21:56:54 +00:00
2020-08-18 17:42:25 +02:00
status = cli_resolve_path ( ctx , " " ,
creds ,
2017-04-25 17:03:10 -07:00
cli , mask , & targetcli , & targetname ) ;
2011-07-03 20:53:55 +02:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
2011-07-05 19:42:46 +02:00
d_printf ( " posix_unlink %s: %s \n " , mask , nt_errstr ( status ) ) ;
2007-03-01 21:56:54 +00:00
return 1 ;
}
2007-12-06 17:16:33 -08:00
2011-07-08 09:16:20 +02:00
status = cli_posix_unlink ( targetcli , targetname ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
d_printf ( " Failed to unlink file %s. %s \n " ,
targetname , nt_errstr ( status ) ) ;
2007-03-01 21:56:54 +00:00
} else {
d_printf ( " posix_unlink deleted file %s \n " , targetname ) ;
}
return 0 ;
}
static int cmd_posix_rmdir ( void )
{
2007-12-06 17:16:33 -08:00
TALLOC_CTX * ctx = talloc_tos ( ) ;
char * mask = NULL ;
char * buf = NULL ;
char * targetname = NULL ;
2007-03-01 21:56:54 +00:00
struct cli_state * targetcli ;
2020-08-18 16:58:19 +02:00
struct cli_credentials * creds = samba_cmdline_get_creds ( ) ;
2011-07-03 20:53:55 +02:00
NTSTATUS status ;
2007-03-01 21:56:54 +00:00
2007-12-19 21:59:28 +01:00
if ( ! next_token_talloc ( ctx , & cmd_ptr , & buf , NULL ) ) {
2007-03-01 21:56:54 +00:00
d_printf ( " posix_rmdir <filename> \n " ) ;
return 1 ;
}
2021-11-20 20:17:11 -08:00
if ( CLI_DIRSEP_CHAR ! = ' / ' ) {
d_printf ( " Command \" posix \" must be issued before "
" the \" posix_rmdir \" command can be used. \n " ) ;
return 1 ;
}
2007-12-06 17:16:33 -08:00
mask = talloc_asprintf ( ctx ,
" %s%s " ,
client_get_cur_dir ( ) ,
buf ) ;
if ( ! mask ) {
return 1 ;
}
2017-10-20 15:09:38 -07:00
mask = client_clean_name ( ctx , mask ) ;
if ( mask = = NULL ) {
return 1 ;
}
2007-03-01 21:56:54 +00:00
2020-08-18 17:42:25 +02:00
status = cli_resolve_path ( ctx , " " ,
creds ,
2017-04-25 17:03:10 -07:00
cli , mask , & targetcli , & targetname ) ;
2011-07-03 20:53:55 +02:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
2011-07-05 19:42:46 +02:00
d_printf ( " posix_rmdir %s: %s \n " , mask , nt_errstr ( status ) ) ;
2007-03-01 21:56:54 +00:00
return 1 ;
}
2007-12-06 17:16:33 -08:00
2011-07-08 09:16:20 +02:00
status = cli_posix_rmdir ( targetcli , targetname ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
d_printf ( " Failed to unlink directory %s. %s \n " ,
targetname , nt_errstr ( status ) ) ;
2007-03-01 21:56:54 +00:00
} else {
d_printf ( " posix_rmdir deleted directory %s \n " , targetname ) ;
}
return 0 ;
}
2006-07-12 00:21:14 +00:00
static int cmd_close ( void )
{
2007-12-06 17:16:33 -08:00
TALLOC_CTX * ctx = talloc_tos ( ) ;
char * buf = NULL ;
2006-07-12 00:21:14 +00:00
int fnum ;
2011-07-08 09:16:20 +02:00
NTSTATUS status ;
2001-10-09 19:12:18 +00:00
2007-12-19 21:59:28 +01:00
if ( ! next_token_talloc ( ctx , & cmd_ptr , & buf , NULL ) ) {
2006-07-12 00:21:14 +00:00
d_printf ( " close <fnum> \n " ) ;
return 1 ;
}
fnum = atoi ( buf ) ;
/* We really should use the targetcli here.... */
2011-07-08 09:16:20 +02:00
status = cli_close ( cli , fnum ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
d_printf ( " close %d: %s \n " , fnum , nt_errstr ( status ) ) ;
2006-07-12 00:21:14 +00:00
return 1 ;
}
2001-10-09 19:12:18 +00:00
return 0 ;
1999-12-13 13:27:58 +00:00
}
2006-07-12 00:21:14 +00:00
static int cmd_posix ( void )
{
2007-12-06 17:16:33 -08:00
TALLOC_CTX * ctx = talloc_tos ( ) ;
2015-05-09 19:49:09 -07:00
uint16_t major , minor ;
uint32_t caplow , caphigh ;
2007-12-06 17:16:33 -08:00
char * caps ;
2009-11-12 23:07:21 +01:00
NTSTATUS status ;
2006-07-12 00:21:14 +00:00
if ( ! SERVER_HAS_UNIX_CIFS ( cli ) ) {
d_printf ( " Server doesn't support UNIX CIFS extensions. \n " ) ;
return 1 ;
}
2009-11-12 23:07:21 +01:00
status = cli_unix_extensions_version ( cli , & major , & minor , & caplow ,
& caphigh ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
d_printf ( " Can't get UNIX CIFS extensions version from "
" server: %s \n " , nt_errstr ( status ) ) ;
2006-07-12 00:21:14 +00:00
return 1 ;
}
d_printf ( " Server supports CIFS extensions %u.%u \n " , ( unsigned int ) major , ( unsigned int ) minor ) ;
2007-12-06 17:16:33 -08:00
caps = talloc_strdup ( ctx , " " ) ;
if ( ! caps ) {
return 1 ;
}
2006-07-12 00:21:14 +00:00
if ( caplow & CIFS_UNIX_FCNTL_LOCKS_CAP ) {
2007-12-06 17:16:33 -08:00
caps = talloc_asprintf_append ( caps , " locks " ) ;
if ( ! caps ) {
return 1 ;
}
2006-07-12 00:21:14 +00:00
}
if ( caplow & CIFS_UNIX_POSIX_ACLS_CAP ) {
2007-12-06 17:16:33 -08:00
caps = talloc_asprintf_append ( caps , " acls " ) ;
if ( ! caps ) {
return 1 ;
}
2006-07-12 00:21:14 +00:00
}
if ( caplow & CIFS_UNIX_XATTTR_CAP ) {
2007-12-06 17:16:33 -08:00
caps = talloc_asprintf_append ( caps , " eas " ) ;
if ( ! caps ) {
return 1 ;
}
2006-07-12 00:21:14 +00:00
}
if ( caplow & CIFS_UNIX_POSIX_PATHNAMES_CAP ) {
2007-12-06 17:16:33 -08:00
caps = talloc_asprintf_append ( caps , " pathnames " ) ;
if ( ! caps ) {
return 1 ;
}
2006-07-12 00:21:14 +00:00
}
2007-03-01 21:56:54 +00:00
if ( caplow & CIFS_UNIX_POSIX_PATH_OPERATIONS_CAP ) {
2007-12-06 17:16:33 -08:00
caps = talloc_asprintf_append ( caps , " posix_path_operations " ) ;
if ( ! caps ) {
return 1 ;
}
2007-03-01 21:56:54 +00:00
}
2007-10-31 14:12:50 -07:00
if ( caplow & CIFS_UNIX_LARGE_READ_CAP ) {
2007-12-06 17:16:33 -08:00
caps = talloc_asprintf_append ( caps , " large_read " ) ;
if ( ! caps ) {
return 1 ;
}
2007-10-31 14:12:50 -07:00
}
if ( caplow & CIFS_UNIX_LARGE_WRITE_CAP ) {
2007-12-06 17:16:33 -08:00
caps = talloc_asprintf_append ( caps , " large_write " ) ;
if ( ! caps ) {
return 1 ;
}
2007-10-31 14:12:50 -07:00
}
2007-12-27 23:51:03 -08:00
if ( caplow & CIFS_UNIX_TRANSPORT_ENCRYPTION_CAP ) {
caps = talloc_asprintf_append ( caps , " posix_encrypt " ) ;
if ( ! caps ) {
return 1 ;
}
}
if ( caplow & CIFS_UNIX_TRANSPORT_ENCRYPTION_MANDATORY_CAP ) {
caps = talloc_asprintf_append ( caps , " mandatory_posix_encrypt " ) ;
if ( ! caps ) {
return 1 ;
}
}
2006-07-12 00:21:14 +00:00
2007-12-06 17:16:33 -08:00
if ( * caps & & caps [ strlen ( caps ) - 1 ] = = ' ' ) {
2006-07-12 00:21:14 +00:00
caps [ strlen ( caps ) - 1 ] = ' \0 ' ;
}
2007-12-27 23:51:03 -08:00
d_printf ( " Server supports CIFS capabilities %s \n " , caps ) ;
2009-11-14 00:40:21 +01:00
status = cli_set_unix_extensions_capabilities ( cli , major , minor ,
caplow , caphigh ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
d_printf ( " Can't set UNIX CIFS extensions capabilities. %s. \n " ,
nt_errstr ( status ) ) ;
2006-07-12 00:21:14 +00:00
return 1 ;
}
2006-07-12 03:20:53 +00:00
if ( caplow & CIFS_UNIX_POSIX_PATHNAMES_CAP ) {
CLI_DIRSEP_CHAR = ' / ' ;
* CLI_DIRSEP_STR = ' / ' ;
2007-12-06 17:16:33 -08:00
client_set_cur_dir ( CLI_DIRSEP_STR ) ;
2006-07-12 03:20:53 +00:00
}
return 0 ;
}
static int cmd_lock ( void )
{
2007-12-06 17:16:33 -08:00
TALLOC_CTX * ctx = talloc_tos ( ) ;
char * buf = NULL ;
2008-10-14 01:59:36 +02:00
uint64_t start , len ;
2006-07-12 03:20:53 +00:00
enum brl_type lock_type ;
int fnum ;
2011-07-08 09:16:20 +02:00
NTSTATUS status ;
2006-07-12 03:20:53 +00:00
2007-12-19 21:59:28 +01:00
if ( ! next_token_talloc ( ctx , & cmd_ptr , & buf , NULL ) ) {
2006-07-12 03:20:53 +00:00
d_printf ( " lock <fnum> [r|w] <hex-start> <hex-len> \n " ) ;
return 1 ;
}
fnum = atoi ( buf ) ;
2007-12-19 21:59:28 +01:00
if ( ! next_token_talloc ( ctx , & cmd_ptr , & buf , NULL ) ) {
2006-07-12 03:20:53 +00:00
d_printf ( " lock <fnum> [r|w] <hex-start> <hex-len> \n " ) ;
return 1 ;
}
if ( * buf = = ' r ' | | * buf = = ' R ' ) {
lock_type = READ_LOCK ;
} else if ( * buf = = ' w ' | | * buf = = ' W ' ) {
lock_type = WRITE_LOCK ;
} else {
d_printf ( " lock <fnum> [r|w] <hex-start> <hex-len> \n " ) ;
return 1 ;
}
2007-12-19 21:59:28 +01:00
if ( ! next_token_talloc ( ctx , & cmd_ptr , & buf , NULL ) ) {
2006-07-12 03:20:53 +00:00
d_printf ( " lock <fnum> [r|w] <hex-start> <hex-len> \n " ) ;
return 1 ;
}
2008-10-14 01:59:36 +02:00
start = ( uint64_t ) strtol ( buf , ( char * * ) NULL , 16 ) ;
2006-07-12 03:20:53 +00:00
2007-12-19 21:59:28 +01:00
if ( ! next_token_talloc ( ctx , & cmd_ptr , & buf , NULL ) ) {
2006-07-12 03:20:53 +00:00
d_printf ( " lock <fnum> [r|w] <hex-start> <hex-len> \n " ) ;
return 1 ;
}
2021-11-20 20:17:11 -08:00
if ( CLI_DIRSEP_CHAR ! = ' / ' ) {
d_printf ( " Command \" posix \" must be issued before "
" the \" lock \" command can be used. \n " ) ;
return 1 ;
}
2008-10-14 01:59:36 +02:00
len = ( uint64_t ) strtol ( buf , ( char * * ) NULL , 16 ) ;
2006-07-12 03:20:53 +00:00
2011-07-08 09:16:20 +02:00
status = cli_posix_lock ( cli , fnum , start , len , true , lock_type ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
d_printf ( " lock failed %d: %s \n " , fnum , nt_errstr ( status ) ) ;
2006-07-12 03:20:53 +00:00
}
2006-07-12 00:21:14 +00:00
return 0 ;
}
1996-05-04 07:50:46 +00:00
2006-07-12 03:20:53 +00:00
static int cmd_unlock ( void )
{
2007-12-06 17:16:33 -08:00
TALLOC_CTX * ctx = talloc_tos ( ) ;
char * buf = NULL ;
2008-10-14 01:59:36 +02:00
uint64_t start , len ;
2006-07-12 03:20:53 +00:00
int fnum ;
2011-07-08 09:16:20 +02:00
NTSTATUS status ;
2006-07-12 03:20:53 +00:00
2007-12-19 21:59:28 +01:00
if ( ! next_token_talloc ( ctx , & cmd_ptr , & buf , NULL ) ) {
2006-07-12 03:20:53 +00:00
d_printf ( " unlock <fnum> <hex-start> <hex-len> \n " ) ;
return 1 ;
}
fnum = atoi ( buf ) ;
2007-12-19 21:59:28 +01:00
if ( ! next_token_talloc ( ctx , & cmd_ptr , & buf , NULL ) ) {
2006-07-12 03:20:53 +00:00
d_printf ( " unlock <fnum> <hex-start> <hex-len> \n " ) ;
return 1 ;
}
2008-10-14 01:59:36 +02:00
start = ( uint64_t ) strtol ( buf , ( char * * ) NULL , 16 ) ;
2006-07-12 03:20:53 +00:00
2007-12-19 21:59:28 +01:00
if ( ! next_token_talloc ( ctx , & cmd_ptr , & buf , NULL ) ) {
2006-07-12 03:20:53 +00:00
d_printf ( " unlock <fnum> <hex-start> <hex-len> \n " ) ;
return 1 ;
}
2021-11-20 20:17:11 -08:00
if ( CLI_DIRSEP_CHAR ! = ' / ' ) {
d_printf ( " Command \" posix \" must be issued before "
" the \" unlock \" command can be used. \n " ) ;
return 1 ;
}
2008-10-14 01:59:36 +02:00
len = ( uint64_t ) strtol ( buf , ( char * * ) NULL , 16 ) ;
2006-07-12 03:20:53 +00:00
2011-07-08 09:16:20 +02:00
status = cli_posix_unlock ( cli , fnum , start , len ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
d_printf ( " unlock failed %d: %s \n " , fnum , nt_errstr ( status ) ) ;
2006-07-12 03:20:53 +00:00
}
return 0 ;
}
2016-05-25 09:15:13 -07:00
static int cmd_posix_whoami ( void )
{
TALLOC_CTX * ctx = talloc_tos ( ) ;
NTSTATUS status = NT_STATUS_UNSUCCESSFUL ;
uint64_t uid = 0 ;
uint64_t gid = 0 ;
uint32_t num_gids = 0 ;
uint32_t num_sids = 0 ;
uint64_t * gids = NULL ;
struct dom_sid * sids = NULL ;
bool guest = false ;
uint32_t i ;
2021-11-20 20:17:11 -08:00
if ( CLI_DIRSEP_CHAR ! = ' / ' ) {
d_printf ( " Command \" posix \" must be issued before "
" the \" posix_whoami \" command can be used. \n " ) ;
return 1 ;
}
2016-05-25 09:15:13 -07:00
status = cli_posix_whoami ( cli ,
ctx ,
& uid ,
& gid ,
& num_gids ,
& gids ,
& num_sids ,
& sids ,
& guest ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
d_printf ( " posix_whoami failed with error %s \n " , nt_errstr ( status ) ) ;
return 1 ;
}
d_printf ( " GUEST:%s \n " , guest ? " True " : " False " ) ;
d_printf ( " UID:% " PRIu64 " \n " , uid ) ;
d_printf ( " GID:% " PRIu64 " \n " , gid ) ;
d_printf ( " NUM_GIDS:% " PRIu32 " \n " , num_gids ) ;
for ( i = 0 ; i < num_gids ; i + + ) {
d_printf ( " GIDS[% " PRIu32 " ]:% " PRIu64 " \n " , i , gids [ i ] ) ;
}
d_printf ( " NUM_SIDS:% " PRIu32 " \n " , num_sids ) ;
for ( i = 0 ; i < num_sids ; i + + ) {
2018-12-21 09:30:58 +01:00
struct dom_sid_buf buf ;
d_printf ( " SIDS[% " PRIu32 " ]:%s \n " ,
i ,
dom_sid_str_buf ( & sids [ i ] , & buf ) ) ;
2016-05-25 09:15:13 -07:00
}
return 0 ;
}
2006-07-12 03:20:53 +00:00
1996-05-04 07:50:46 +00:00
/****************************************************************************
2003-08-06 20:01:31 +00:00
Remove a directory .
1996-05-04 07:50:46 +00:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2003-08-06 20:01:31 +00:00
2001-10-09 19:12:18 +00:00
static int cmd_rmdir ( void )
1996-05-04 07:50:46 +00:00
{
2007-12-06 17:16:33 -08:00
TALLOC_CTX * ctx = talloc_tos ( ) ;
char * mask = NULL ;
char * buf = NULL ;
char * targetname = NULL ;
2005-02-23 19:26:32 +00:00
struct cli_state * targetcli ;
2020-08-18 16:58:19 +02:00
struct cli_credentials * creds = samba_cmdline_get_creds ( ) ;
2011-07-03 20:53:55 +02:00
NTSTATUS status ;
2007-12-06 17:16:33 -08:00
2007-12-19 21:59:28 +01:00
if ( ! next_token_talloc ( ctx , & cmd_ptr , & buf , NULL ) ) {
2001-09-07 14:14:57 +00:00
d_printf ( " rmdir <dirname> \n " ) ;
2001-10-09 19:12:18 +00:00
return 1 ;
1998-11-09 03:45:49 +00:00
}
2007-12-06 17:16:33 -08:00
mask = talloc_asprintf ( ctx ,
" %s%s " ,
client_get_cur_dir ( ) ,
buf ) ;
if ( ! mask ) {
return 1 ;
}
2017-10-20 15:09:38 -07:00
mask = client_clean_name ( ctx , mask ) ;
if ( mask = = NULL ) {
return 1 ;
}
1996-05-04 07:50:46 +00:00
2020-08-18 17:42:25 +02:00
status = cli_resolve_path ( ctx , " " ,
creds ,
2017-04-25 17:03:10 -07:00
cli , mask , & targetcli , & targetname ) ;
2011-07-03 20:53:55 +02:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
2011-07-05 19:42:46 +02:00
d_printf ( " rmdir %s: %s \n " , mask , nt_errstr ( status ) ) ;
2005-02-23 19:26:32 +00:00
return 1 ;
}
2007-12-06 17:16:33 -08:00
2011-07-08 09:16:20 +02:00
status = cli_rmdir ( targetcli , targetname ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
2001-09-07 14:14:57 +00:00
d_printf ( " %s removing remote directory file %s \n " ,
2011-07-08 09:16:20 +02:00
nt_errstr ( status ) , mask ) ;
2001-10-09 19:12:18 +00:00
}
2007-12-06 17:16:33 -08:00
2001-10-09 19:12:18 +00:00
return 0 ;
1996-05-04 07:50:46 +00:00
}
2002-01-16 20:13:28 +00:00
/****************************************************************************
UNIX hardlink .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static int cmd_link ( void )
{
2007-12-06 17:16:33 -08:00
TALLOC_CTX * ctx = talloc_tos ( ) ;
char * oldname = NULL ;
char * newname = NULL ;
char * buf = NULL ;
char * buf2 = NULL ;
char * targetname = NULL ;
2005-02-23 19:26:32 +00:00
struct cli_state * targetcli ;
2020-08-18 16:58:19 +02:00
struct cli_credentials * creds = samba_cmdline_get_creds ( ) ;
2011-07-03 20:53:55 +02:00
NTSTATUS status ;
2007-12-06 17:16:33 -08:00
2007-12-19 21:59:28 +01:00
if ( ! next_token_talloc ( ctx , & cmd_ptr , & buf , NULL ) | |
! next_token_talloc ( ctx , & cmd_ptr , & buf2 , NULL ) ) {
2004-04-06 23:01:09 +00:00
d_printf ( " link <oldname> <newname> \n " ) ;
2002-01-16 20:13:28 +00:00
return 1 ;
}
2007-12-06 17:16:33 -08:00
oldname = talloc_asprintf ( ctx ,
" %s%s " ,
client_get_cur_dir ( ) ,
buf ) ;
if ( ! oldname ) {
return 1 ;
}
2017-10-20 15:09:38 -07:00
oldname = client_clean_name ( ctx , oldname ) ;
if ( oldname = = NULL ) {
return 1 ;
}
2007-12-06 17:16:33 -08:00
newname = talloc_asprintf ( ctx ,
" %s%s " ,
client_get_cur_dir ( ) ,
buf2 ) ;
if ( ! newname ) {
return 1 ;
}
2017-10-20 15:09:38 -07:00
newname = client_clean_name ( ctx , newname ) ;
if ( newname = = NULL ) {
return 1 ;
}
2002-01-16 20:13:28 +00:00
2020-08-18 17:42:25 +02:00
status = cli_resolve_path ( ctx , " " ,
creds ,
2017-04-25 17:03:10 -07:00
cli , oldname , & targetcli , & targetname ) ;
2011-07-03 20:53:55 +02:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
2011-07-05 19:42:46 +02:00
d_printf ( " link %s: %s \n " , oldname , nt_errstr ( status ) ) ;
2005-02-23 19:26:32 +00:00
return 1 ;
}
2007-12-06 17:16:33 -08:00
2005-02-23 19:26:32 +00:00
if ( ! SERVER_HAS_UNIX_CIFS ( targetcli ) ) {
d_printf ( " Server doesn't support UNIX CIFS calls. \n " ) ;
return 1 ;
}
2007-12-06 17:16:33 -08:00
2021-11-20 20:17:11 -08:00
if ( CLI_DIRSEP_CHAR ! = ' / ' ) {
d_printf ( " Command \" posix \" must be issued before "
" the \" link \" command can be used. \n " ) ;
return 1 ;
}
2011-07-08 09:16:20 +02:00
status = cli_posix_hardlink ( targetcli , targetname , newname ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
d_printf ( " %s linking files (%s -> %s) \n " ,
nt_errstr ( status ) , newname , oldname ) ;
2002-01-16 20:13:28 +00:00
return 1 ;
2007-12-06 17:16:33 -08:00
}
2002-01-16 20:13:28 +00:00
return 0 ;
}
2009-05-27 22:02:20 -07:00
/****************************************************************************
UNIX readlink .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static int cmd_readlink ( void )
{
TALLOC_CTX * ctx = talloc_tos ( ) ;
char * name = NULL ;
char * buf = NULL ;
char * targetname = NULL ;
2019-03-26 09:48:16 +01:00
char * linkname = NULL ;
2022-10-12 20:38:14 +02:00
char * printname = NULL ;
uint32_t flags ;
2009-05-27 22:02:20 -07:00
struct cli_state * targetcli ;
2020-08-18 16:58:19 +02:00
struct cli_credentials * creds = samba_cmdline_get_creds ( ) ;
2011-07-03 20:53:55 +02:00
NTSTATUS status ;
2009-05-27 22:02:20 -07:00
if ( ! next_token_talloc ( ctx , & cmd_ptr , & buf , NULL ) ) {
d_printf ( " readlink <name> \n " ) ;
return 1 ;
}
name = talloc_asprintf ( ctx ,
" %s%s " ,
client_get_cur_dir ( ) ,
buf ) ;
if ( ! name ) {
return 1 ;
}
2017-10-20 15:09:38 -07:00
name = client_clean_name ( ctx , name ) ;
if ( name = = NULL ) {
return 1 ;
}
2009-05-27 22:02:20 -07:00
2020-08-18 17:42:25 +02:00
status = cli_resolve_path ( ctx , " " ,
creds ,
2017-04-25 17:03:10 -07:00
cli , name , & targetcli , & targetname ) ;
2011-07-03 20:53:55 +02:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
2011-07-05 19:42:46 +02:00
d_printf ( " readlink %s: %s \n " , name , nt_errstr ( status ) ) ;
2009-05-27 22:02:20 -07:00
return 1 ;
}
2022-10-12 20:38:14 +02:00
status = cli_readlink (
cli , name , talloc_tos ( ) , & linkname , & printname , & flags ) ;
2011-07-08 09:16:20 +02:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
2009-05-27 22:02:20 -07:00
d_printf ( " %s readlink on file %s \n " ,
2011-07-08 09:16:20 +02:00
nt_errstr ( status ) , name ) ;
2009-05-27 22:02:20 -07:00
return 1 ;
}
d_printf ( " %s -> %s \n " , name , linkname ) ;
2019-03-26 09:48:16 +01:00
TALLOC_FREE ( linkname ) ;
2009-05-27 22:02:20 -07:00
return 0 ;
}
2002-01-16 20:13:28 +00:00
/****************************************************************************
UNIX symlink .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static int cmd_symlink ( void )
{
2007-12-06 17:16:33 -08:00
TALLOC_CTX * ctx = talloc_tos ( ) ;
2017-11-29 13:10:25 -08:00
char * link_target = NULL ;
2007-12-06 17:16:33 -08:00
char * newname = NULL ;
char * buf = NULL ;
char * buf2 = NULL ;
2010-08-16 16:31:33 -07:00
struct cli_state * newcli ;
2020-08-18 16:58:19 +02:00
struct cli_credentials * creds = samba_cmdline_get_creds ( ) ;
2011-06-23 16:52:34 +02:00
NTSTATUS status ;
2002-01-16 20:13:28 +00:00
2007-12-19 21:59:28 +01:00
if ( ! next_token_talloc ( ctx , & cmd_ptr , & buf , NULL ) | |
! next_token_talloc ( ctx , & cmd_ptr , & buf2 , NULL ) ) {
2017-11-29 13:10:25 -08:00
d_printf ( " symlink <link_target> <newname> \n " ) ;
2002-01-16 20:13:28 +00:00
return 1 ;
}
2010-08-16 16:31:33 -07:00
/* Oldname (link target) must be an untouched blob. */
2017-11-29 13:10:25 -08:00
link_target = buf ;
2010-08-16 16:31:33 -07:00
2011-06-23 16:54:50 +02:00
if ( SERVER_HAS_UNIX_CIFS ( cli ) ) {
2021-11-20 20:17:11 -08:00
if ( CLI_DIRSEP_CHAR ! = ' / ' ) {
d_printf ( " Command \" posix \" must be issued before "
" the \" symlink \" command can be used. \n " ) ;
return 1 ;
}
2011-06-23 16:54:50 +02:00
newname = talloc_asprintf ( ctx , " %s%s " , client_get_cur_dir ( ) ,
buf2 ) ;
if ( ! newname ) {
return 1 ;
}
2017-10-20 15:09:38 -07:00
newname = client_clean_name ( ctx , newname ) ;
if ( newname = = NULL ) {
return 1 ;
}
2011-06-23 16:54:50 +02:00
/* New name must be present in share namespace. */
2017-04-25 17:03:10 -07:00
status = cli_resolve_path ( ctx , " " ,
2020-08-18 17:42:25 +02:00
creds ,
cli , newname ,
2017-04-25 17:03:10 -07:00
& newcli , & newname ) ;
2011-07-03 20:53:55 +02:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
2017-11-29 13:10:25 -08:00
d_printf ( " link %s: %s \n " , newname ,
nt_errstr ( status ) ) ;
2011-06-23 16:54:50 +02:00
return 1 ;
}
2017-11-29 13:10:25 -08:00
status = cli_posix_symlink ( newcli , link_target , newname ) ;
2011-06-23 16:54:50 +02:00
} else {
status = cli_symlink (
2017-11-29 13:10:25 -08:00
cli , link_target , buf2 ,
2011-06-23 16:54:50 +02:00
buf2 [ 0 ] = = ' \\ ' ? 0 : SYMLINK_FLAG_RELATIVE ) ;
2007-12-06 17:16:33 -08:00
}
2011-06-23 16:52:34 +02:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
2002-01-16 20:13:28 +00:00
d_printf ( " %s symlinking files (%s -> %s) \n " ,
2017-11-29 13:10:25 -08:00
nt_errstr ( status ) , newname , link_target ) ;
2002-01-16 20:13:28 +00:00
return 1 ;
2007-12-06 17:16:33 -08:00
}
2002-01-16 20:13:28 +00:00
return 0 ;
}
/****************************************************************************
UNIX chmod .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static int cmd_chmod ( void )
{
2007-12-06 17:16:33 -08:00
TALLOC_CTX * ctx = talloc_tos ( ) ;
char * src = NULL ;
char * buf = NULL ;
char * buf2 = NULL ;
char * targetname = NULL ;
2005-02-23 19:26:32 +00:00
struct cli_state * targetcli ;
2007-12-06 17:16:33 -08:00
mode_t mode ;
2020-08-18 16:58:19 +02:00
struct cli_credentials * creds = samba_cmdline_get_creds ( ) ;
2011-07-03 20:53:55 +02:00
NTSTATUS status ;
2007-12-06 17:16:33 -08:00
2007-12-19 21:59:28 +01:00
if ( ! next_token_talloc ( ctx , & cmd_ptr , & buf , NULL ) | |
! next_token_talloc ( ctx , & cmd_ptr , & buf2 , NULL ) ) {
2002-01-16 20:13:28 +00:00
d_printf ( " chmod mode file \n " ) ;
return 1 ;
}
2007-12-06 17:16:33 -08:00
src = talloc_asprintf ( ctx ,
" %s%s " ,
client_get_cur_dir ( ) ,
buf2 ) ;
if ( ! src ) {
return 1 ;
}
2017-10-20 15:09:38 -07:00
src = client_clean_name ( ctx , src ) ;
if ( src = = NULL ) {
return 1 ;
}
2002-01-16 20:13:28 +00:00
mode = ( mode_t ) strtol ( buf , NULL , 8 ) ;
2020-08-18 17:42:25 +02:00
status = cli_resolve_path ( ctx , " " ,
creds ,
2017-04-25 17:03:10 -07:00
cli , src , & targetcli , & targetname ) ;
2011-07-03 20:53:55 +02:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
2011-07-05 19:42:46 +02:00
d_printf ( " chmod %s: %s \n " , src , nt_errstr ( status ) ) ;
2005-02-23 19:26:32 +00:00
return 1 ;
}
2007-12-06 17:16:33 -08:00
2005-02-23 19:26:32 +00:00
if ( ! SERVER_HAS_UNIX_CIFS ( targetcli ) ) {
d_printf ( " Server doesn't support UNIX CIFS calls. \n " ) ;
return 1 ;
}
2007-12-06 17:16:33 -08:00
2021-11-20 20:17:11 -08:00
if ( CLI_DIRSEP_CHAR ! = ' / ' ) {
d_printf ( " Command \" posix \" must be issued before "
" the \" chmod \" command can be used. \n " ) ;
return 1 ;
}
2011-07-08 09:16:20 +02:00
status = cli_posix_chmod ( targetcli , targetname , mode ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
2002-01-16 20:13:28 +00:00
d_printf ( " %s chmod file %s 0%o \n " ,
2011-07-08 09:16:20 +02:00
nt_errstr ( status ) , src , ( unsigned int ) mode ) ;
2002-01-16 20:13:28 +00:00
return 1 ;
2007-12-06 17:16:33 -08:00
}
2002-01-16 20:13:28 +00:00
return 0 ;
}
2004-09-26 06:27:54 +00:00
static const char * filetype_to_str ( mode_t mode )
{
if ( S_ISREG ( mode ) ) {
return " regular file " ;
} else if ( S_ISDIR ( mode ) ) {
return " directory " ;
2007-12-06 17:16:33 -08:00
} else
2004-09-26 06:27:54 +00:00
# ifdef S_ISCHR
if ( S_ISCHR ( mode ) ) {
return " character device " ;
} else
# endif
# ifdef S_ISBLK
if ( S_ISBLK ( mode ) ) {
return " block device " ;
} else
# endif
# ifdef S_ISFIFO
if ( S_ISFIFO ( mode ) ) {
return " fifo " ;
} else
# endif
# ifdef S_ISLNK
if ( S_ISLNK ( mode ) ) {
return " symbolic link " ;
} else
# endif
# ifdef S_ISSOCK
if ( S_ISSOCK ( mode ) ) {
return " socket " ;
} else
# endif
return " " ;
}
static char rwx_to_str ( mode_t m , mode_t bt , char ret )
{
if ( m & bt ) {
return ret ;
} else {
return ' - ' ;
}
}
static char * unix_mode_to_str ( char * s , mode_t m )
{
char * p = s ;
const char * str = filetype_to_str ( m ) ;
switch ( str [ 0 ] ) {
case ' d ' :
* p + + = ' d ' ;
break ;
case ' c ' :
* p + + = ' c ' ;
break ;
case ' b ' :
* p + + = ' b ' ;
break ;
case ' f ' :
* p + + = ' p ' ;
break ;
case ' s ' :
* p + + = str [ 1 ] = = ' y ' ? ' l ' : ' s ' ;
break ;
case ' r ' :
default :
* p + + = ' - ' ;
break ;
}
* p + + = rwx_to_str ( m , S_IRUSR , ' r ' ) ;
* p + + = rwx_to_str ( m , S_IWUSR , ' w ' ) ;
* p + + = rwx_to_str ( m , S_IXUSR , ' x ' ) ;
* p + + = rwx_to_str ( m , S_IRGRP , ' r ' ) ;
* p + + = rwx_to_str ( m , S_IWGRP , ' w ' ) ;
* p + + = rwx_to_str ( m , S_IXGRP , ' x ' ) ;
* p + + = rwx_to_str ( m , S_IROTH , ' r ' ) ;
* p + + = rwx_to_str ( m , S_IWOTH , ' w ' ) ;
* p + + = rwx_to_str ( m , S_IXOTH , ' x ' ) ;
* p + + = ' \0 ' ;
return s ;
}
2004-11-13 00:35:31 +00:00
/****************************************************************************
Utility function for UNIX getfacl .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static char * perms_to_string ( fstring permstr , unsigned char perms )
{
fstrcpy ( permstr , " --- " ) ;
if ( perms & SMB_POSIX_ACL_READ ) {
permstr [ 0 ] = ' r ' ;
}
if ( perms & SMB_POSIX_ACL_WRITE ) {
permstr [ 1 ] = ' w ' ;
}
if ( perms & SMB_POSIX_ACL_EXECUTE ) {
permstr [ 2 ] = ' x ' ;
}
return permstr ;
}
2004-11-12 23:42:12 +00:00
/****************************************************************************
UNIX getfacl .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static int cmd_getfacl ( void )
{
2007-12-06 17:16:33 -08:00
TALLOC_CTX * ctx = talloc_tos ( ) ;
char * src = NULL ;
char * name = NULL ;
char * targetname = NULL ;
struct cli_state * targetcli ;
2015-05-09 19:49:09 -07:00
uint16_t major , minor ;
uint32_t caplow , caphigh ;
2004-11-12 23:42:12 +00:00
char * retbuf = NULL ;
2004-11-13 00:35:31 +00:00
size_t rb_size = 0 ;
SMB_STRUCT_STAT sbuf ;
2020-06-05 14:04:08 +02:00
size_t num_file_acls = 0 ;
size_t num_dir_acls = 0 ;
size_t expected_buflen ;
2015-05-09 19:49:09 -07:00
uint16_t i ;
2020-08-18 16:58:19 +02:00
struct cli_credentials * creds = samba_cmdline_get_creds ( ) ;
2009-11-12 23:07:21 +01:00
NTSTATUS status ;
2007-12-06 17:16:33 -08:00
2007-12-19 21:59:28 +01:00
if ( ! next_token_talloc ( ctx , & cmd_ptr , & name , NULL ) ) {
2007-12-06 17:16:33 -08:00
d_printf ( " getfacl filename \n " ) ;
return 1 ;
}
src = talloc_asprintf ( ctx ,
" %s%s " ,
client_get_cur_dir ( ) ,
name ) ;
if ( ! src ) {
2004-11-12 23:42:12 +00:00
return 1 ;
}
2017-10-20 15:09:38 -07:00
src = client_clean_name ( ctx , src ) ;
if ( src = = NULL ) {
return 1 ;
}
2004-11-12 23:42:12 +00:00
2020-08-18 17:42:25 +02:00
status = cli_resolve_path ( ctx , " " ,
creds ,
2017-04-25 17:03:10 -07:00
cli , src , & targetcli , & targetname ) ;
2011-07-03 20:53:55 +02:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
2011-07-05 19:42:46 +02:00
d_printf ( " stat %s: %s \n " , src , nt_errstr ( status ) ) ;
2005-02-23 19:26:32 +00:00
return 1 ;
}
2007-12-06 17:16:33 -08:00
2005-02-23 19:26:32 +00:00
if ( ! SERVER_HAS_UNIX_CIFS ( targetcli ) ) {
d_printf ( " Server doesn't support UNIX CIFS calls. \n " ) ;
return 1 ;
}
2007-12-06 17:16:33 -08:00
2021-11-20 20:17:11 -08:00
if ( CLI_DIRSEP_CHAR ! = ' / ' ) {
d_printf ( " Command \" posix \" must be issued before "
" the \" getfacl \" command can be used. \n " ) ;
return 1 ;
}
2009-11-12 23:07:21 +01:00
status = cli_unix_extensions_version ( targetcli , & major , & minor ,
& caplow , & caphigh ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
d_printf ( " Can't get UNIX CIFS version from server: %s. \n " ,
nt_errstr ( status ) ) ;
2004-11-12 23:42:12 +00:00
return 1 ;
}
if ( ! ( caplow & CIFS_UNIX_POSIX_ACLS_CAP ) ) {
2007-12-06 17:16:33 -08:00
d_printf ( " This server supports UNIX extensions "
" but doesn't support POSIX ACLs. \n " ) ;
2004-11-12 23:42:12 +00:00
return 1 ;
}
2011-07-08 09:16:20 +02:00
status = cli_posix_stat ( targetcli , targetname , & sbuf ) ;
2020-02-07 14:11:13 +02:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
2004-11-13 00:35:31 +00:00
d_printf ( " %s getfacl doing a stat on file %s \n " ,
2011-07-08 09:16:20 +02:00
nt_errstr ( status ) , src ) ;
2004-11-13 00:35:31 +00:00
return 1 ;
2007-12-06 17:16:33 -08:00
}
2004-11-13 00:35:31 +00:00
2016-01-06 17:17:24 -08:00
status = cli_posix_getacl ( targetcli , targetname , ctx , & rb_size , & retbuf ) ;
2011-07-08 09:16:20 +02:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
2004-11-12 23:42:12 +00:00
d_printf ( " %s getfacl file %s \n " ,
2011-07-08 09:16:20 +02:00
nt_errstr ( status ) , src ) ;
2004-11-12 23:42:12 +00:00
return 1 ;
2007-12-06 17:16:33 -08:00
}
2004-11-12 23:42:12 +00:00
/* ToDo : Print out the ACL values. */
2009-05-28 13:05:50 -07:00
if ( rb_size < 6 | | SVAL ( retbuf , 0 ) ! = SMB_POSIX_ACL_VERSION ) {
2004-11-13 00:35:31 +00:00
d_printf ( " getfacl file %s, unknown POSIX acl version %u. \n " ,
src , ( unsigned int ) CVAL ( retbuf , 0 ) ) ;
return 1 ;
}
num_file_acls = SVAL ( retbuf , 2 ) ;
num_dir_acls = SVAL ( retbuf , 4 ) ;
2020-06-05 14:04:08 +02:00
/*
* No overflow check , num_ * _acls comes from a 16 - bit value ,
* and we expect expected_buflen ( size_t ) to be of at least 32
* bit .
*/
expected_buflen = SMB_POSIX_ACL_HEADER_SIZE +
SMB_POSIX_ACL_ENTRY_SIZE * ( num_file_acls + num_dir_acls ) ;
if ( rb_size ! = expected_buflen ) {
d_printf ( " getfacl file %s, incorrect POSIX acl buffer size "
" (should be %zu, was %zu). \n " ,
src ,
expected_buflen ,
rb_size ) ;
2004-11-13 00:35:31 +00:00
return 1 ;
}
d_printf ( " # file: %s \n " , src ) ;
2009-05-14 15:34:42 +02:00
d_printf ( " # owner: %u \n # group: %u \n " , ( unsigned int ) sbuf . st_ex_uid , ( unsigned int ) sbuf . st_ex_gid ) ;
2004-11-13 00:35:31 +00:00
if ( num_file_acls = = 0 & & num_dir_acls = = 0 ) {
d_printf ( " No acls found. \n " ) ;
}
for ( i = 0 ; i < num_file_acls ; i + + ) {
2015-05-09 19:49:09 -07:00
uint32_t uorg ;
2004-11-13 00:35:31 +00:00
fstring permstring ;
unsigned char tagtype = CVAL ( retbuf , SMB_POSIX_ACL_HEADER_SIZE + ( i * SMB_POSIX_ACL_ENTRY_SIZE ) ) ;
unsigned char perms = CVAL ( retbuf , SMB_POSIX_ACL_HEADER_SIZE + ( i * SMB_POSIX_ACL_ENTRY_SIZE ) + 1 ) ;
switch ( tagtype ) {
case SMB_POSIX_ACL_USER_OBJ :
d_printf ( " user:: " ) ;
break ;
case SMB_POSIX_ACL_USER :
uorg = IVAL ( retbuf , SMB_POSIX_ACL_HEADER_SIZE + ( i * SMB_POSIX_ACL_ENTRY_SIZE ) + 2 ) ;
d_printf ( " user:%u: " , uorg ) ;
break ;
case SMB_POSIX_ACL_GROUP_OBJ :
d_printf ( " group:: " ) ;
break ;
case SMB_POSIX_ACL_GROUP :
uorg = IVAL ( retbuf , SMB_POSIX_ACL_HEADER_SIZE + ( i * SMB_POSIX_ACL_ENTRY_SIZE ) + 2 ) ;
2008-09-15 18:25:15 -07:00
d_printf ( " group:%u: " , uorg ) ;
2004-11-13 00:35:31 +00:00
break ;
case SMB_POSIX_ACL_MASK :
d_printf ( " mask:: " ) ;
break ;
case SMB_POSIX_ACL_OTHER :
d_printf ( " other:: " ) ;
break ;
default :
d_printf ( " getfacl file %s, incorrect POSIX acl tagtype (%u). \n " ,
src , ( unsigned int ) tagtype ) ;
SAFE_FREE ( retbuf ) ;
return 1 ;
}
d_printf ( " %s \n " , perms_to_string ( permstring , perms ) ) ;
}
for ( i = 0 ; i < num_dir_acls ; i + + ) {
2015-05-09 19:49:09 -07:00
uint32_t uorg ;
2004-11-13 00:35:31 +00:00
fstring permstring ;
unsigned char tagtype = CVAL ( retbuf , SMB_POSIX_ACL_HEADER_SIZE + ( ( i + num_file_acls ) * SMB_POSIX_ACL_ENTRY_SIZE ) ) ;
unsigned char perms = CVAL ( retbuf , SMB_POSIX_ACL_HEADER_SIZE + ( ( i + num_file_acls ) * SMB_POSIX_ACL_ENTRY_SIZE ) + 1 ) ;
switch ( tagtype ) {
case SMB_POSIX_ACL_USER_OBJ :
d_printf ( " default:user:: " ) ;
break ;
case SMB_POSIX_ACL_USER :
uorg = IVAL ( retbuf , SMB_POSIX_ACL_HEADER_SIZE + ( ( i + num_file_acls ) * SMB_POSIX_ACL_ENTRY_SIZE ) + 2 ) ;
d_printf ( " default:user:%u: " , uorg ) ;
break ;
case SMB_POSIX_ACL_GROUP_OBJ :
d_printf ( " default:group:: " ) ;
break ;
case SMB_POSIX_ACL_GROUP :
uorg = IVAL ( retbuf , SMB_POSIX_ACL_HEADER_SIZE + ( ( i + num_file_acls ) * SMB_POSIX_ACL_ENTRY_SIZE ) + 2 ) ;
2008-09-15 18:25:15 -07:00
d_printf ( " default:group:%u: " , uorg ) ;
2004-11-13 00:35:31 +00:00
break ;
case SMB_POSIX_ACL_MASK :
d_printf ( " default:mask:: " ) ;
break ;
case SMB_POSIX_ACL_OTHER :
d_printf ( " default:other:: " ) ;
break ;
default :
d_printf ( " getfacl file %s, incorrect POSIX acl tagtype (%u). \n " ,
src , ( unsigned int ) tagtype ) ;
SAFE_FREE ( retbuf ) ;
return 1 ;
}
d_printf ( " %s \n " , perms_to_string ( permstring , perms ) ) ;
}
2004-11-12 23:42:12 +00:00
return 0 ;
}
2010-10-24 13:32:30 +02:00
/****************************************************************************
Get the EA list of a file
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static int cmd_geteas ( void )
{
TALLOC_CTX * ctx = talloc_tos ( ) ;
char * src = NULL ;
char * name = NULL ;
char * targetname = NULL ;
struct cli_state * targetcli ;
NTSTATUS status ;
size_t i , num_eas ;
struct ea_struct * eas ;
2020-08-18 16:58:19 +02:00
struct cli_credentials * creds = samba_cmdline_get_creds ( ) ;
2010-10-24 13:32:30 +02:00
if ( ! next_token_talloc ( ctx , & cmd_ptr , & name , NULL ) ) {
d_printf ( " geteas filename \n " ) ;
return 1 ;
}
src = talloc_asprintf ( ctx ,
" %s%s " ,
client_get_cur_dir ( ) ,
name ) ;
if ( ! src ) {
return 1 ;
}
2017-10-20 15:09:38 -07:00
src = client_clean_name ( ctx , src ) ;
if ( src = = NULL ) {
return 1 ;
}
2010-10-24 13:32:30 +02:00
2020-08-18 17:42:25 +02:00
status = cli_resolve_path ( ctx , " " ,
creds ,
2017-04-25 17:03:10 -07:00
cli , src , & targetcli , & targetname ) ;
2011-07-03 20:53:55 +02:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
2011-07-05 19:42:46 +02:00
d_printf ( " stat %s: %s \n " , src , nt_errstr ( status ) ) ;
2010-10-24 13:32:30 +02:00
return 1 ;
}
status = cli_get_ea_list_path ( targetcli , targetname , talloc_tos ( ) ,
& num_eas , & eas ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
d_printf ( " cli_get_ea_list_path: %s \n " , nt_errstr ( status ) ) ;
return 1 ;
}
for ( i = 0 ; i < num_eas ; i + + ) {
d_printf ( " %s (%d) = \n " , eas [ i ] . name , ( int ) eas [ i ] . flags ) ;
2012-01-25 09:10:04 +01:00
dump_data_file ( eas [ i ] . value . data , eas [ i ] . value . length , false ,
stdout ) ;
2010-10-24 13:32:30 +02:00
d_printf ( " \n " ) ;
}
TALLOC_FREE ( eas ) ;
return 0 ;
}
2010-10-24 15:43:34 +02:00
/****************************************************************************
Set an EA of a file
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static int cmd_setea ( void )
{
TALLOC_CTX * ctx = talloc_tos ( ) ;
char * src = NULL ;
char * name = NULL ;
char * eaname = NULL ;
char * eavalue = NULL ;
char * targetname = NULL ;
struct cli_state * targetcli ;
2020-08-18 16:58:19 +02:00
struct cli_credentials * creds = samba_cmdline_get_creds ( ) ;
2010-11-11 15:51:46 +01:00
NTSTATUS status ;
2010-10-24 15:43:34 +02:00
if ( ! next_token_talloc ( ctx , & cmd_ptr , & name , NULL )
| | ! next_token_talloc ( ctx , & cmd_ptr , & eaname , NULL ) ) {
d_printf ( " setea filename eaname value \n " ) ;
return 1 ;
}
if ( ! next_token_talloc ( ctx , & cmd_ptr , & eavalue , NULL ) ) {
eavalue = talloc_strdup ( ctx , " " ) ;
}
src = talloc_asprintf ( ctx ,
" %s%s " ,
client_get_cur_dir ( ) ,
name ) ;
if ( ! src ) {
return 1 ;
}
2017-10-20 15:09:38 -07:00
src = client_clean_name ( ctx , src ) ;
if ( src = = NULL ) {
return 1 ;
}
2010-10-24 15:43:34 +02:00
2020-08-18 17:42:25 +02:00
status = cli_resolve_path ( ctx , " " ,
creds ,
2017-04-25 17:03:10 -07:00
cli , src , & targetcli , & targetname ) ;
2011-07-03 20:53:55 +02:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
2011-07-05 19:42:46 +02:00
d_printf ( " stat %s: %s \n " , src , nt_errstr ( status ) ) ;
2010-10-24 15:43:34 +02:00
return 1 ;
}
2010-11-11 15:51:46 +01:00
status = cli_set_ea_path ( targetcli , targetname , eaname , eavalue ,
strlen ( eavalue ) ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
d_printf ( " set_ea %s: %s \n " , src , nt_errstr ( status ) ) ;
2010-10-24 15:43:34 +02:00
return 1 ;
}
return 0 ;
}
2004-09-26 06:27:54 +00:00
/****************************************************************************
UNIX stat .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static int cmd_stat ( void )
{
2007-12-06 17:16:33 -08:00
TALLOC_CTX * ctx = talloc_tos ( ) ;
char * src = NULL ;
char * name = NULL ;
char * targetname = NULL ;
struct cli_state * targetcli ;
2004-09-26 06:27:54 +00:00
fstring mode_str ;
SMB_STRUCT_STAT sbuf ;
2006-06-14 21:36:49 +00:00
struct tm * lt ;
2009-05-14 15:34:42 +02:00
time_t tmp_time ;
2020-08-18 16:58:19 +02:00
struct cli_credentials * creds = samba_cmdline_get_creds ( ) ;
2011-07-03 20:53:55 +02:00
NTSTATUS status ;
2004-09-26 06:27:54 +00:00
2007-12-19 21:59:28 +01:00
if ( ! next_token_talloc ( ctx , & cmd_ptr , & name , NULL ) ) {
2004-09-26 06:27:54 +00:00
d_printf ( " stat file \n " ) ;
return 1 ;
}
2007-12-06 17:16:33 -08:00
src = talloc_asprintf ( ctx ,
" %s%s " ,
client_get_cur_dir ( ) ,
name ) ;
if ( ! src ) {
return 1 ;
}
2017-10-20 15:09:38 -07:00
src = client_clean_name ( ctx , src ) ;
if ( src = = NULL ) {
return 1 ;
}
2004-09-26 06:27:54 +00:00
2020-08-18 17:42:25 +02:00
status = cli_resolve_path ( ctx , " " ,
creds ,
2017-04-25 17:03:10 -07:00
cli , src , & targetcli , & targetname ) ;
2011-07-03 20:53:55 +02:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
2011-07-05 19:42:46 +02:00
d_printf ( " stat %s: %s \n " , src , nt_errstr ( status ) ) ;
2005-02-23 19:26:32 +00:00
return 1 ;
}
2007-12-06 17:16:33 -08:00
if ( ! SERVER_HAS_UNIX_CIFS ( targetcli ) ) {
d_printf ( " Server doesn't support UNIX CIFS calls. \n " ) ;
return 1 ;
}
2021-11-20 20:17:11 -08:00
if ( CLI_DIRSEP_CHAR ! = ' / ' ) {
d_printf ( " Command \" posix \" must be issued before "
" the \" stat \" command can be used. \n " ) ;
return 1 ;
}
2011-07-08 09:16:20 +02:00
status = cli_posix_stat ( targetcli , targetname , & sbuf ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
2004-09-26 06:27:54 +00:00
d_printf ( " %s stat file %s \n " ,
2011-07-08 09:16:20 +02:00
nt_errstr ( status ) , src ) ;
2004-09-26 06:27:54 +00:00
return 1 ;
2007-12-06 17:16:33 -08:00
}
2004-09-26 06:27:54 +00:00
/* Print out the stat values. */
d_printf ( " File: %s \n " , src ) ;
d_printf ( " Size: %-12.0f \t Blocks: %u \t %s \n " ,
2009-05-14 15:34:42 +02:00
( double ) sbuf . st_ex_size ,
( unsigned int ) sbuf . st_ex_blocks ,
filetype_to_str ( sbuf . st_ex_mode ) ) ;
2004-09-26 06:27:54 +00:00
# if defined(S_ISCHR) && defined(S_ISBLK)
2009-05-14 15:34:42 +02:00
if ( S_ISCHR ( sbuf . st_ex_mode ) | | S_ISBLK ( sbuf . st_ex_mode ) ) {
2004-09-26 06:27:54 +00:00
d_printf ( " Inode: %.0f \t Links: %u \t Device type: %u,%u \n " ,
2009-05-14 15:34:42 +02:00
( double ) sbuf . st_ex_ino ,
( unsigned int ) sbuf . st_ex_nlink ,
unix_dev_major ( sbuf . st_ex_rdev ) ,
unix_dev_minor ( sbuf . st_ex_rdev ) ) ;
2007-12-06 17:16:33 -08:00
} else
2004-09-26 06:27:54 +00:00
# endif
d_printf ( " Inode: %.0f \t Links: %u \n " ,
2009-05-14 15:34:42 +02:00
( double ) sbuf . st_ex_ino ,
( unsigned int ) sbuf . st_ex_nlink ) ;
2004-09-26 06:27:54 +00:00
d_printf ( " Access: (0%03o/%s) \t Uid: %u \t Gid: %u \n " ,
2009-05-14 15:34:42 +02:00
( ( int ) sbuf . st_ex_mode & 0777 ) ,
unix_mode_to_str ( mode_str , sbuf . st_ex_mode ) ,
( unsigned int ) sbuf . st_ex_uid ,
( unsigned int ) sbuf . st_ex_gid ) ;
2004-09-26 06:27:54 +00:00
2009-05-14 15:34:42 +02:00
tmp_time = convert_timespec_to_time_t ( sbuf . st_ex_atime ) ;
lt = localtime ( & tmp_time ) ;
2006-06-14 21:36:49 +00:00
if ( lt ) {
2007-03-02 15:08:09 +00:00
strftime ( mode_str , sizeof ( mode_str ) , " %Y-%m-%d %T %z " , lt ) ;
2006-06-14 21:36:49 +00:00
} else {
fstrcpy ( mode_str , " unknown " ) ;
}
2004-09-26 06:27:54 +00:00
d_printf ( " Access: %s \n " , mode_str ) ;
2009-05-14 15:34:42 +02:00
tmp_time = convert_timespec_to_time_t ( sbuf . st_ex_mtime ) ;
lt = localtime ( & tmp_time ) ;
2006-06-14 21:36:49 +00:00
if ( lt ) {
2007-03-02 15:08:09 +00:00
strftime ( mode_str , sizeof ( mode_str ) , " %Y-%m-%d %T %z " , lt ) ;
2006-06-14 21:36:49 +00:00
} else {
fstrcpy ( mode_str , " unknown " ) ;
}
2004-09-26 06:27:54 +00:00
d_printf ( " Modify: %s \n " , mode_str ) ;
2009-05-14 15:34:42 +02:00
tmp_time = convert_timespec_to_time_t ( sbuf . st_ex_ctime ) ;
lt = localtime ( & tmp_time ) ;
2006-06-14 21:36:49 +00:00
if ( lt ) {
2007-03-02 15:08:09 +00:00
strftime ( mode_str , sizeof ( mode_str ) , " %Y-%m-%d %T %z " , lt ) ;
2006-06-14 21:36:49 +00:00
} else {
fstrcpy ( mode_str , " unknown " ) ;
}
2004-09-26 06:27:54 +00:00
d_printf ( " Change: %s \n " , mode_str ) ;
2007-12-06 17:16:33 -08:00
2004-09-26 06:27:54 +00:00
return 0 ;
}
2002-01-16 20:13:28 +00:00
/****************************************************************************
UNIX chown .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static int cmd_chown ( void )
{
2007-12-06 17:16:33 -08:00
TALLOC_CTX * ctx = talloc_tos ( ) ;
char * src = NULL ;
2002-01-16 20:13:28 +00:00
uid_t uid ;
gid_t gid ;
2007-12-06 17:16:33 -08:00
char * buf , * buf2 , * buf3 ;
2005-02-23 19:26:32 +00:00
struct cli_state * targetcli ;
2007-12-06 17:16:33 -08:00
char * targetname = NULL ;
2020-08-18 16:58:19 +02:00
struct cli_credentials * creds = samba_cmdline_get_creds ( ) ;
2011-07-03 20:53:55 +02:00
NTSTATUS status ;
2007-12-06 17:16:33 -08:00
2007-12-19 21:59:28 +01:00
if ( ! next_token_talloc ( ctx , & cmd_ptr , & buf , NULL ) | |
! next_token_talloc ( ctx , & cmd_ptr , & buf2 , NULL ) | |
! next_token_talloc ( ctx , & cmd_ptr , & buf3 , NULL ) ) {
2002-01-16 20:13:28 +00:00
d_printf ( " chown uid gid file \n " ) ;
return 1 ;
}
uid = ( uid_t ) atoi ( buf ) ;
gid = ( gid_t ) atoi ( buf2 ) ;
2007-12-06 17:16:33 -08:00
src = talloc_asprintf ( ctx ,
" %s%s " ,
client_get_cur_dir ( ) ,
buf3 ) ;
if ( ! src ) {
return 1 ;
}
2017-10-20 15:09:38 -07:00
src = client_clean_name ( ctx , src ) ;
if ( src = = NULL ) {
return 1 ;
}
2020-08-18 17:42:25 +02:00
status = cli_resolve_path ( ctx , " " ,
creds ,
2017-04-25 17:03:10 -07:00
cli , src , & targetcli , & targetname ) ;
2011-07-03 20:53:55 +02:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
2011-07-05 19:42:46 +02:00
d_printf ( " chown %s: %s \n " , src , nt_errstr ( status ) ) ;
2005-02-23 19:26:32 +00:00
return 1 ;
}
if ( ! SERVER_HAS_UNIX_CIFS ( targetcli ) ) {
d_printf ( " Server doesn't support UNIX CIFS calls. \n " ) ;
return 1 ;
}
2007-12-06 17:16:33 -08:00
2021-11-20 20:17:11 -08:00
if ( CLI_DIRSEP_CHAR ! = ' / ' ) {
d_printf ( " Command \" posix \" must be issued before "
" the \" chown \" command can be used. \n " ) ;
return 1 ;
}
2011-07-08 09:16:20 +02:00
status = cli_posix_chown ( targetcli , targetname , uid , gid ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
2002-01-16 20:13:28 +00:00
d_printf ( " %s chown file %s uid=%d, gid=%d \n " ,
2011-07-08 09:16:20 +02:00
nt_errstr ( status ) , src , ( int ) uid , ( int ) gid ) ;
2002-01-16 20:13:28 +00:00
return 1 ;
2007-12-06 17:16:33 -08:00
}
2002-01-16 20:13:28 +00:00
return 0 ;
}
1996-05-04 07:50:46 +00:00
/****************************************************************************
2003-08-06 20:01:31 +00:00
Rename some file .
1996-05-04 07:50:46 +00:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2003-08-06 20:01:31 +00:00
2001-10-09 19:12:18 +00:00
static int cmd_rename ( void )
1996-05-04 07:50:46 +00:00
{
2007-12-06 17:16:33 -08:00
TALLOC_CTX * ctx = talloc_tos ( ) ;
char * src , * dest ;
char * buf , * buf2 ;
2007-03-08 23:54:57 +00:00
struct cli_state * targetcli ;
2007-12-06 17:16:33 -08:00
char * targetsrc ;
char * targetdest ;
2020-08-18 16:58:19 +02:00
struct cli_credentials * creds = samba_cmdline_get_creds ( ) ;
2011-07-03 20:53:55 +02:00
NTSTATUS status ;
2017-03-21 23:26:05 +02:00
bool replace = false ;
2007-12-06 17:16:33 -08:00
2007-12-19 21:59:28 +01:00
if ( ! next_token_talloc ( ctx , & cmd_ptr , & buf , NULL ) | |
! next_token_talloc ( ctx , & cmd_ptr , & buf2 , NULL ) ) {
2017-03-21 23:26:05 +02:00
d_printf ( " rename <src> <dest> [-f] \n " ) ;
2001-10-09 19:12:18 +00:00
return 1 ;
1998-11-09 03:45:49 +00:00
}
2007-12-06 17:16:33 -08:00
src = talloc_asprintf ( ctx ,
" %s%s " ,
client_get_cur_dir ( ) ,
buf ) ;
if ( ! src ) {
return 1 ;
}
2017-10-20 15:09:38 -07:00
src = client_clean_name ( ctx , src ) ;
if ( src = = NULL ) {
return 1 ;
}
2007-12-06 17:16:33 -08:00
dest = talloc_asprintf ( ctx ,
" %s%s " ,
client_get_cur_dir ( ) ,
buf2 ) ;
if ( ! dest ) {
return 1 ;
}
2017-10-20 15:09:38 -07:00
dest = client_clean_name ( ctx , dest ) ;
if ( dest = = NULL ) {
return 1 ;
}
1998-11-09 03:45:49 +00:00
2017-03-21 23:26:05 +02:00
if ( next_token_talloc ( ctx , & cmd_ptr , & buf , NULL ) & &
strcsequal ( buf , " -f " ) ) {
replace = true ;
}
2020-08-18 17:42:25 +02:00
status = cli_resolve_path ( ctx , " " ,
creds ,
2017-04-25 17:03:10 -07:00
cli , src , & targetcli , & targetsrc ) ;
2011-07-03 20:53:55 +02:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
2011-07-05 19:42:46 +02:00
d_printf ( " rename %s: %s \n " , src , nt_errstr ( status ) ) ;
2007-07-24 22:28:19 +00:00
return 1 ;
}
2020-08-18 17:42:25 +02:00
status = cli_resolve_path ( ctx , " " ,
creds ,
2017-04-25 17:03:10 -07:00
cli , dest , & targetcli , & targetdest ) ;
2011-07-03 20:53:55 +02:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
2011-07-05 19:42:46 +02:00
d_printf ( " rename %s: %s \n " , dest , nt_errstr ( status ) ) ;
2007-03-08 23:54:57 +00:00
return 1 ;
}
2017-03-21 23:26:05 +02:00
status = cli_rename ( targetcli , targetsrc , targetdest , replace ) ;
2011-07-08 09:16:20 +02:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
2007-07-24 22:28:19 +00:00
d_printf ( " %s renaming files %s -> %s \n " ,
2011-07-08 09:16:20 +02:00
nt_errstr ( status ) ,
2007-07-24 22:28:19 +00:00
targetsrc ,
targetdest ) ;
2001-10-09 19:12:18 +00:00
return 1 ;
}
2007-12-06 17:16:33 -08:00
2001-10-09 19:12:18 +00:00
return 0 ;
1996-05-04 07:50:46 +00:00
}
2015-06-25 11:37:18 +05:30
struct scopy_timing {
struct timespec tp_start ;
} ;
static int scopy_status ( off_t written , void * priv )
{
struct timespec tp_end ;
unsigned int scopy_total_time_ms ;
struct scopy_timing * st = priv ;
clock_gettime_mono ( & tp_end ) ;
scopy_total_time_ms = nsec_time_diff ( & tp_end , & st - > tp_start ) / 1000000 ;
DEBUG ( 5 , ( " Copied %jd bytes at an average %3.1f kb/s \n " ,
( intmax_t ) written , written / ( 1.024 * scopy_total_time_ms ) ) ) ;
return true ;
}
/****************************************************************************
Server - Side copy some file .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static int cmd_scopy ( void )
{
TALLOC_CTX * ctx = talloc_tos ( ) ;
char * src , * dest ;
char * buf , * buf2 ;
struct cli_state * targetcli ;
char * targetsrc ;
char * targetdest ;
uint32_t DesiredAccess , ShareAccess , CreateDisposition , CreateOptions ;
struct smb_create_returns cr ;
uint16_t destfnum = ( uint16_t ) - 1 ;
uint16_t srcfnum = ( uint16_t ) - 1 ;
off_t written = 0 ;
struct scopy_timing st ;
int rc = 0 ;
2020-08-18 16:58:19 +02:00
struct cli_credentials * creds = samba_cmdline_get_creds ( ) ;
2015-06-25 11:37:18 +05:30
NTSTATUS status ;
if ( ! next_token_talloc ( ctx , & cmd_ptr , & buf , NULL ) | |
! next_token_talloc ( ctx , & cmd_ptr , & buf2 , NULL ) ) {
d_printf ( " scopy <src> <dest> \n " ) ;
return 1 ;
}
src = talloc_asprintf ( ctx ,
" %s%s " ,
client_get_cur_dir ( ) ,
buf ) ;
if ( ! src ) {
return 1 ;
}
2017-10-20 15:09:38 -07:00
src = client_clean_name ( ctx , src ) ;
if ( src = = NULL ) {
return 1 ;
}
2015-06-25 11:37:18 +05:30
dest = talloc_asprintf ( ctx ,
" %s%s " ,
client_get_cur_dir ( ) ,
buf2 ) ;
if ( ! dest ) {
return 1 ;
}
2017-10-20 15:09:38 -07:00
dest = client_clean_name ( ctx , dest ) ;
if ( dest = = NULL ) {
return 1 ;
}
2015-06-25 11:37:18 +05:30
2020-08-18 17:42:25 +02:00
status = cli_resolve_path ( ctx , " " ,
creds ,
2017-04-25 17:03:10 -07:00
cli , src , & targetcli , & targetsrc ) ;
2015-06-25 11:37:18 +05:30
if ( ! NT_STATUS_IS_OK ( status ) ) {
d_printf ( " scopy %s: %s \n " , src , nt_errstr ( status ) ) ;
return 1 ;
}
2020-08-18 17:42:25 +02:00
status = cli_resolve_path ( ctx , " " ,
creds ,
2017-04-25 17:03:10 -07:00
cli , dest , & targetcli , & targetdest ) ;
2015-06-25 11:37:18 +05:30
if ( ! NT_STATUS_IS_OK ( status ) ) {
d_printf ( " scopy %s: %s \n " , dest , nt_errstr ( status ) ) ;
return 1 ;
}
DesiredAccess = ( FILE_READ_DATA | FILE_READ_EA | FILE_READ_ATTRIBUTES |
READ_CONTROL_ACCESS | SYNCHRONIZE_ACCESS ) ;
ShareAccess = FILE_SHARE_READ | FILE_SHARE_DELETE ;
CreateDisposition = FILE_OPEN ;
CreateOptions = ( FILE_SEQUENTIAL_ONLY | FILE_NON_DIRECTORY_FILE |
FILE_OPEN_REPARSE_POINT ) ;
status = cli_ntcreate ( targetcli , targetsrc , 0 , DesiredAccess , 0 ,
ShareAccess , CreateDisposition , CreateOptions , 0x0 ,
& srcfnum , & cr ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
d_printf ( " Failed to open file %s. %s \n " ,
targetsrc , nt_errstr ( status ) ) ;
return 1 ;
}
DesiredAccess = ( FILE_READ_DATA | FILE_WRITE_DATA | FILE_APPEND_DATA | FILE_READ_EA |
FILE_WRITE_EA | FILE_READ_ATTRIBUTES | FILE_WRITE_ATTRIBUTES |
DELETE_ACCESS | READ_CONTROL_ACCESS | WRITE_DAC_ACCESS | SYNCHRONIZE_ACCESS ) ;
ShareAccess = FILE_SHARE_NONE ;
CreateDisposition = FILE_CREATE ;
CreateOptions = FILE_SEQUENTIAL_ONLY | FILE_NON_DIRECTORY_FILE ;
status = cli_ntcreate ( targetcli , targetdest , 0 , DesiredAccess ,
FILE_ATTRIBUTE_ARCHIVE , ShareAccess , CreateDisposition ,
CreateOptions , 0x0 , & destfnum , NULL ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
d_printf ( " Failed to create file %s. %s \n " ,
targetdest , nt_errstr ( status ) ) ;
cli_close ( targetcli , srcfnum ) ;
return 1 ;
}
clock_gettime_mono ( & st . tp_start ) ;
status = cli_splice ( targetcli , targetcli , srcfnum , destfnum ,
cr . end_of_file , 0 , 0 , & written , scopy_status , & st ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
d_printf ( " %s copying file %s -> %s \n " ,
nt_errstr ( status ) ,
targetsrc ,
targetdest ) ;
rc = 1 ;
}
status = cli_close ( targetcli , srcfnum ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
d_printf ( " Error %s closing remote source file \n " , nt_errstr ( status ) ) ;
rc = 1 ;
}
status = cli_close ( targetcli , destfnum ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
d_printf ( " Error %s closing remote dest file \n " , nt_errstr ( status ) ) ;
rc = 1 ;
}
return rc ;
}
2005-03-30 00:47:57 +00:00
/****************************************************************************
Print the volume name .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static int cmd_volume ( void )
{
2011-07-06 13:57:20 +02:00
char * volname ;
uint32_t serial_num ;
2005-03-30 00:47:57 +00:00
time_t create_date ;
2010-02-07 12:08:39 +01:00
NTSTATUS status ;
2007-12-06 17:16:33 -08:00
2011-07-06 13:57:20 +02:00
status = cli_get_fs_volume_info ( cli , talloc_tos ( ) ,
& volname , & serial_num ,
2010-02-07 12:08:39 +01:00
& create_date ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
d_printf ( " Error %s getting volume info \n " , nt_errstr ( status ) ) ;
2005-03-30 00:47:57 +00:00
return 1 ;
}
2007-12-06 17:16:33 -08:00
d_printf ( " Volume: |%s| serial number 0x%x \n " ,
volname , ( unsigned int ) serial_num ) ;
2005-03-30 00:47:57 +00:00
return 0 ;
}
2004-03-03 20:55:59 +00:00
/****************************************************************************
2004-03-03 23:14:23 +00:00
Hard link files using the NT call .
2004-03-03 20:55:59 +00:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2004-03-03 23:14:23 +00:00
static int cmd_hardlink ( void )
2004-03-03 20:55:59 +00:00
{
2007-12-06 17:16:33 -08:00
TALLOC_CTX * ctx = talloc_tos ( ) ;
char * src , * dest ;
char * buf , * buf2 ;
2005-02-23 19:26:32 +00:00
struct cli_state * targetcli ;
2007-12-06 17:16:33 -08:00
char * targetname ;
2020-08-18 16:58:19 +02:00
struct cli_credentials * creds = samba_cmdline_get_creds ( ) ;
2011-07-03 20:53:55 +02:00
NTSTATUS status ;
2007-12-06 17:16:33 -08:00
2007-12-19 21:59:28 +01:00
if ( ! next_token_talloc ( ctx , & cmd_ptr , & buf , NULL ) | |
! next_token_talloc ( ctx , & cmd_ptr , & buf2 , NULL ) ) {
2004-03-03 23:14:23 +00:00
d_printf ( " hardlink <src> <dest> \n " ) ;
2004-03-03 20:55:59 +00:00
return 1 ;
}
2007-12-06 17:16:33 -08:00
src = talloc_asprintf ( ctx ,
" %s%s " ,
client_get_cur_dir ( ) ,
buf ) ;
if ( ! src ) {
return 1 ;
}
2017-10-20 15:09:38 -07:00
src = client_clean_name ( ctx , src ) ;
if ( src = = NULL ) {
return 1 ;
}
2004-03-03 20:55:59 +00:00
2007-12-06 17:16:33 -08:00
dest = talloc_asprintf ( ctx ,
" %s%s " ,
client_get_cur_dir ( ) ,
buf2 ) ;
if ( ! dest ) {
2005-02-23 19:26:32 +00:00
return 1 ;
}
2017-10-20 15:09:38 -07:00
dest = client_clean_name ( ctx , dest ) ;
if ( dest = = NULL ) {
return 1 ;
}
2007-12-06 17:16:33 -08:00
2020-08-18 17:42:25 +02:00
status = cli_resolve_path ( ctx , " " ,
creds ,
2017-04-25 17:03:10 -07:00
cli , src , & targetcli , & targetname ) ;
2011-07-03 20:53:55 +02:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
2011-07-05 19:42:46 +02:00
d_printf ( " hardlink %s: %s \n " , src , nt_errstr ( status ) ) ;
2005-02-23 19:26:32 +00:00
return 1 ;
}
2007-12-06 17:16:33 -08:00
2019-03-18 11:00:50 +01:00
status = cli_hardlink ( targetcli , targetname , dest ) ;
2011-07-08 09:16:20 +02:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
d_printf ( " %s doing an NT hard link of files \n " ,
nt_errstr ( status ) ) ;
2004-03-03 20:55:59 +00:00
return 1 ;
}
2007-12-06 17:16:33 -08:00
2004-03-03 20:55:59 +00:00
return 0 ;
}
1996-05-04 07:50:46 +00:00
/****************************************************************************
2003-08-06 20:01:31 +00:00
Toggle the prompt flag .
1996-05-04 07:50:46 +00:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2003-08-06 20:01:31 +00:00
2001-10-09 19:12:18 +00:00
static int cmd_prompt ( void )
1996-05-04 07:50:46 +00:00
{
1998-11-09 03:45:49 +00:00
prompt = ! prompt ;
DEBUG ( 2 , ( " prompting is now %s \n " , prompt ? " on " : " off " ) ) ;
2001-10-10 07:51:20 +00:00
return 1 ;
1996-05-04 07:50:46 +00:00
}
/****************************************************************************
2003-08-06 20:01:31 +00:00
Set the newer than time .
1996-05-04 07:50:46 +00:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2003-08-06 20:01:31 +00:00
2001-10-09 19:12:18 +00:00
static int cmd_newer ( void )
1996-05-04 07:50:46 +00:00
{
2007-12-06 17:16:33 -08:00
TALLOC_CTX * ctx = talloc_tos ( ) ;
char * buf ;
2007-10-18 17:40:25 -07:00
bool ok ;
1998-11-09 03:45:49 +00:00
SMB_STRUCT_STAT sbuf ;
2007-12-19 21:59:28 +01:00
ok = next_token_talloc ( ctx , & cmd_ptr , & buf , NULL ) ;
2009-11-27 12:44:33 +01:00
if ( ok & & ( sys_stat ( buf , & sbuf , false ) = = 0 ) ) {
2009-05-14 15:34:42 +02:00
newer_than = convert_timespec_to_time_t ( sbuf . st_ex_mtime ) ;
1998-11-09 03:45:49 +00:00
DEBUG ( 1 , ( " Getting files newer than %s " ,
2007-03-05 23:40:03 +00:00
time_to_asc ( newer_than ) ) ) ;
1998-11-09 03:45:49 +00:00
} else {
newer_than = 0 ;
}
2001-10-09 19:12:18 +00:00
if ( ok & & newer_than = = 0 ) {
2001-09-07 14:14:57 +00:00
d_printf ( " Error setting newer-than time \n " ) ;
2001-10-09 19:12:18 +00:00
return 1 ;
}
return 0 ;
1996-05-04 07:50:46 +00:00
}
2012-03-22 12:17:26 +01:00
/****************************************************************************
Watch directory changes
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static int cmd_notify ( void )
{
TALLOC_CTX * frame = talloc_stackframe ( ) ;
char * name , * buf ;
NTSTATUS status ;
uint16_t fnum ;
name = talloc_strdup ( talloc_tos ( ) , client_get_cur_dir ( ) ) ;
if ( name = = NULL ) {
goto fail ;
}
if ( ! next_token_talloc ( talloc_tos ( ) , & cmd_ptr , & buf , NULL ) ) {
goto usage ;
}
name = talloc_asprintf_append ( name , " %s " , buf ) ;
if ( name = = NULL ) {
goto fail ;
}
2017-10-20 15:09:38 -07:00
name = client_clean_name ( talloc_tos ( ) , name ) ;
if ( name = = NULL ) {
return 1 ;
}
2012-03-22 12:17:26 +01:00
status = cli_ntcreate (
2012-04-16 16:21:15 +02:00
cli , name , 0 , FILE_READ_DATA , 0 ,
2012-03-22 12:17:26 +01:00
FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE ,
2014-05-08 20:55:57 -07:00
FILE_OPEN , 0 , 0 , & fnum , NULL ) ;
2012-03-22 12:17:26 +01:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
d_printf ( " Could not open file: %s \n " , nt_errstr ( status ) ) ;
goto fail ;
}
while ( 1 ) {
2017-10-30 16:15:03 +01:00
uint32_t i ;
uint32_t num_changes = 0 ;
struct notify_change * changes = NULL ;
2012-03-22 12:17:26 +01:00
status = cli_notify ( cli , fnum , 1000 , FILE_NOTIFY_CHANGE_ALL ,
true ,
talloc_tos ( ) , & num_changes , & changes ) ;
2020-06-19 12:43:54 -07:00
if ( NT_STATUS_EQUAL ( status , NT_STATUS_NOTIFY_ENUM_DIR ) ) {
2017-10-30 16:15:03 +01:00
printf ( " NOTIFY_ENUM_DIR \n " ) ;
status = NT_STATUS_OK ;
}
2012-03-22 12:17:26 +01:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
d_printf ( " notify returned %s \n " ,
nt_errstr ( status ) ) ;
goto fail ;
}
for ( i = 0 ; i < num_changes ; i + + ) {
printf ( " %4.4x %s \n " , changes [ i ] . action ,
changes [ i ] . name ) ;
}
TALLOC_FREE ( changes ) ;
}
usage :
2016-11-04 16:00:05 +01:00
d_printf ( " notify <dir name> \n " ) ;
2012-03-22 12:17:26 +01:00
fail :
TALLOC_FREE ( frame ) ;
return 1 ;
}
1996-05-04 07:50:46 +00:00
/****************************************************************************
2003-08-06 20:01:31 +00:00
Set the archive level .
1996-05-04 07:50:46 +00:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2003-08-06 20:01:31 +00:00
2001-10-09 19:12:18 +00:00
static int cmd_archive ( void )
1996-05-04 07:50:46 +00:00
{
2007-12-06 17:16:33 -08:00
TALLOC_CTX * ctx = talloc_tos ( ) ;
char * buf ;
1996-05-04 07:50:46 +00:00
2007-12-19 21:59:28 +01:00
if ( next_token_talloc ( ctx , & cmd_ptr , & buf , NULL ) ) {
1998-11-09 03:45:49 +00:00
archive_level = atoi ( buf ) ;
2007-12-06 17:16:33 -08:00
} else {
2001-09-07 14:14:57 +00:00
d_printf ( " Archive level is %d \n " , archive_level ) ;
2007-12-06 17:16:33 -08:00
}
2001-10-09 19:12:18 +00:00
return 0 ;
1996-05-04 07:50:46 +00:00
}
2011-12-01 13:47:12 -08:00
/****************************************************************************
Toggle the backup_intent state .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static int cmd_backup ( void )
{
backup_intent = ! backup_intent ;
cli_set_backup_intent ( cli , backup_intent ) ;
DEBUG ( 2 , ( " backup intent is now %s \n " , backup_intent ? " on " : " off " ) ) ;
return 1 ;
}
1996-05-04 07:50:46 +00:00
/****************************************************************************
2003-08-06 20:01:31 +00:00
Toggle the lowercaseflag .
1996-05-04 07:50:46 +00:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2003-08-06 20:01:31 +00:00
2001-10-09 19:12:18 +00:00
static int cmd_lowercase ( void )
1996-05-04 07:50:46 +00:00
{
1998-11-09 03:45:49 +00:00
lowercase = ! lowercase ;
DEBUG ( 2 , ( " filename lowercasing is now %s \n " , lowercase ? " on " : " off " ) ) ;
2001-10-09 19:12:18 +00:00
return 0 ;
1996-05-04 07:50:46 +00:00
}
2004-06-15 18:36:45 +00:00
/****************************************************************************
Toggle the case sensitive flag .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static int cmd_setcase ( void )
{
2007-12-06 17:16:33 -08:00
bool orig_case_sensitive = cli_set_case_sensitive ( cli , false ) ;
2004-06-15 18:36:45 +00:00
cli_set_case_sensitive ( cli , ! orig_case_sensitive ) ;
DEBUG ( 2 , ( " filename case sensitivity is now %s \n " , ! orig_case_sensitive ?
" on " : " off " ) ) ;
return 0 ;
}
2006-11-01 17:18:08 +00:00
/****************************************************************************
Toggle the showacls flag .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static int cmd_showacls ( void )
{
showacls = ! showacls ;
DEBUG ( 2 , ( " showacls is now %s \n " , showacls ? " on " : " off " ) ) ;
return 0 ;
}
1996-05-04 07:50:46 +00:00
/****************************************************************************
2003-08-06 20:01:31 +00:00
Toggle the recurse flag .
1996-05-04 07:50:46 +00:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2003-08-06 20:01:31 +00:00
2001-10-09 19:12:18 +00:00
static int cmd_recurse ( void )
1996-05-04 07:50:46 +00:00
{
1998-11-09 03:45:49 +00:00
recurse = ! recurse ;
DEBUG ( 2 , ( " directory recursion is now %s \n " , recurse ? " on " : " off " ) ) ;
2001-10-09 19:12:18 +00:00
return 0 ;
1996-05-04 07:50:46 +00:00
}
/****************************************************************************
2003-08-06 20:01:31 +00:00
Toggle the translate flag .
1996-05-04 07:50:46 +00:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2003-08-06 20:01:31 +00:00
2001-10-09 19:12:18 +00:00
static int cmd_translate ( void )
1996-05-04 07:50:46 +00:00
{
1998-11-09 03:45:49 +00:00
translation = ! translation ;
DEBUG ( 2 , ( " CR/LF<->LF and print text translation now %s \n " ,
translation ? " on " : " off " ) ) ;
2001-10-09 19:12:18 +00:00
return 0 ;
1996-05-04 07:50:46 +00:00
}
/****************************************************************************
2003-08-06 20:01:31 +00:00
Do the lcd command .
2002-09-25 15:19:00 +00:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2003-08-06 20:01:31 +00:00
2001-10-09 19:12:18 +00:00
static int cmd_lcd ( void )
1996-05-04 07:50:46 +00:00
{
2007-12-06 17:16:33 -08:00
TALLOC_CTX * ctx = talloc_tos ( ) ;
char * buf ;
char * d ;
2007-12-19 21:59:28 +01:00
if ( next_token_talloc ( ctx , & cmd_ptr , & buf , NULL ) ) {
2008-12-31 16:30:11 -08:00
if ( chdir ( buf ) = = - 1 ) {
d_printf ( " chdir to %s failed (%s) \n " ,
buf , strerror ( errno ) ) ;
}
2007-12-06 17:16:33 -08:00
}
2011-05-31 16:14:04 -07:00
d = sys_getwd ( ) ;
2007-12-06 17:16:33 -08:00
if ( ! d ) {
return 1 ;
}
2011-05-31 16:14:04 -07:00
DEBUG ( 2 , ( " the local directory is now %s \n " , d ) ) ;
SAFE_FREE ( d ) ;
2001-10-09 19:12:18 +00:00
return 0 ;
1998-11-09 03:45:49 +00:00
}
1996-05-04 07:50:46 +00:00
1998-11-09 03:45:49 +00:00
/****************************************************************************
2003-08-06 20:01:31 +00:00
Get a file restarting at end of local file .
2002-09-25 15:19:00 +00:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2003-08-06 20:01:31 +00:00
2002-09-25 15:19:00 +00:00
static int cmd_reget ( void )
{
2007-12-06 17:16:33 -08:00
TALLOC_CTX * ctx = talloc_tos ( ) ;
char * local_name = NULL ;
char * remote_name = NULL ;
char * fname = NULL ;
char * p = NULL ;
2008-02-08 16:59:52 -08:00
remote_name = talloc_strdup ( ctx , client_get_cur_dir ( ) ) ;
2007-12-06 17:16:33 -08:00
if ( ! remote_name ) {
return 1 ;
}
2002-09-25 15:19:00 +00:00
2007-12-19 21:59:28 +01:00
if ( ! next_token_talloc ( ctx , & cmd_ptr , & fname , NULL ) ) {
2002-09-25 15:19:00 +00:00
d_printf ( " reget <filename> \n " ) ;
return 1 ;
}
2008-12-31 16:30:11 -08:00
remote_name = talloc_asprintf_append ( remote_name , " %s " , fname ) ;
2007-12-06 17:16:33 -08:00
if ( ! remote_name ) {
return 1 ;
}
2017-10-20 15:09:38 -07:00
remote_name = client_clean_name ( ctx , remote_name ) ;
2007-12-06 17:16:33 -08:00
if ( ! remote_name ) {
return 1 ;
}
local_name = fname ;
2007-12-19 21:59:28 +01:00
next_token_talloc ( ctx , & cmd_ptr , & p , NULL ) ;
2007-12-06 17:16:33 -08:00
if ( p ) {
local_name = p ;
}
return do_get ( remote_name , local_name , true ) ;
2002-09-25 15:19:00 +00:00
}
/****************************************************************************
2003-08-06 20:01:31 +00:00
Put a file restarting at end of local file .
2002-09-25 15:19:00 +00:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2003-08-06 20:01:31 +00:00
2002-09-25 15:19:00 +00:00
static int cmd_reput ( void )
{
2007-12-06 17:16:33 -08:00
TALLOC_CTX * ctx = talloc_tos ( ) ;
char * local_name = NULL ;
char * remote_name = NULL ;
char * buf ;
2002-09-25 15:19:00 +00:00
SMB_STRUCT_STAT st ;
2007-12-06 17:16:33 -08:00
2008-02-08 16:59:52 -08:00
remote_name = talloc_strdup ( ctx , client_get_cur_dir ( ) ) ;
2007-12-06 17:16:33 -08:00
if ( ! remote_name ) {
return 1 ;
}
2007-12-19 21:59:28 +01:00
if ( ! next_token_talloc ( ctx , & cmd_ptr , & local_name , NULL ) ) {
2002-09-25 15:19:00 +00:00
d_printf ( " reput <filename> \n " ) ;
return 1 ;
}
2007-12-06 17:16:33 -08:00
2009-11-27 13:17:05 +01:00
if ( ! file_exist_stat ( local_name , & st , false ) ) {
2002-09-25 15:19:00 +00:00
d_printf ( " %s does not exist \n " , local_name ) ;
return 1 ;
}
2007-12-19 21:59:28 +01:00
if ( next_token_talloc ( ctx , & cmd_ptr , & buf , NULL ) ) {
2007-12-06 17:16:33 -08:00
remote_name = talloc_asprintf_append ( remote_name ,
2008-12-31 16:30:11 -08:00
" %s " , buf ) ;
2007-12-06 17:16:33 -08:00
} else {
remote_name = talloc_asprintf_append ( remote_name ,
2008-12-31 16:30:11 -08:00
" %s " , local_name ) ;
2007-12-06 17:16:33 -08:00
}
if ( ! remote_name ) {
return 1 ;
}
2017-10-20 15:09:38 -07:00
remote_name = client_clean_name ( ctx , remote_name ) ;
2007-12-06 17:16:33 -08:00
if ( ! remote_name ) {
return 1 ;
}
2002-09-25 15:19:00 +00:00
2007-12-06 17:16:33 -08:00
return do_put ( remote_name , local_name , true ) ;
2002-09-25 15:19:00 +00:00
}
/****************************************************************************
2003-08-06 20:01:31 +00:00
List a share name .
2002-09-25 15:19:00 +00:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2003-08-06 20:01:31 +00:00
2015-05-09 19:49:09 -07:00
static void browse_fn ( const char * name , uint32_t m ,
2001-01-04 11:35:55 +00:00
const char * comment , void * state )
1998-11-09 03:45:49 +00:00
{
2007-12-06 17:16:33 -08:00
const char * typestr = " " ;
switch ( m & 7 ) {
case STYPE_DISKTREE :
typestr = " Disk " ;
break ;
case STYPE_PRINTQ :
typestr = " Printer " ;
break ;
case STYPE_DEVICE :
typestr = " Device " ;
break ;
case STYPE_IPC :
typestr = " IPC " ;
break ;
1998-06-04 18:49:13 +00:00
}
2002-01-10 03:53:06 +00:00
/* FIXME: If the remote machine returns non-ascii characters
in any of these fields , they can corrupt the output . We
should remove them . */
2004-01-16 15:01:09 +00:00
if ( ! grepable ) {
2004-03-01 17:40:40 +00:00
d_printf ( " \t %-15s %-10.10s%s \n " ,
2004-01-16 15:01:09 +00:00
name , typestr , comment ) ;
} else {
d_printf ( " %s|%s|%s \n " , typestr , name , comment ) ;
}
1996-05-04 07:50:46 +00:00
}
2007-10-18 17:40:25 -07:00
static bool browse_host_rpc ( bool sort )
2006-04-16 11:47:26 +00:00
{
NTSTATUS status ;
2009-11-12 13:56:33 -08:00
struct rpc_pipe_client * pipe_hnd = NULL ;
2007-12-06 17:16:33 -08:00
TALLOC_CTX * frame = talloc_stackframe ( ) ;
2007-10-10 15:34:30 -05:00
WERROR werr ;
2008-03-10 04:33:06 +01:00
struct srvsvc_NetShareInfoCtr info_ctr ;
struct srvsvc_NetShareCtr1 ctr1 ;
uint32_t resume_handle = 0 ;
uint32_t total_entries = 0 ;
2020-06-05 07:56:27 +02:00
uint32_t i ;
2011-01-12 12:56:55 +01:00
struct dcerpc_binding_handle * b ;
2006-04-16 11:47:26 +00:00
2013-05-24 13:29:28 +02:00
status = cli_rpc_pipe_open_noauth ( cli , & ndr_table_srvsvc ,
2008-07-20 11:04:31 +02:00
& pipe_hnd ) ;
2006-04-16 11:47:26 +00:00
2008-07-20 11:04:31 +02:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
2006-04-16 11:47:26 +00:00
DEBUG ( 10 , ( " Could not connect to srvsvc pipe: %s \n " ,
nt_errstr ( status ) ) ) ;
2007-12-06 17:16:33 -08:00
TALLOC_FREE ( frame ) ;
return false ;
2006-04-16 11:47:26 +00:00
}
2011-01-12 12:56:55 +01:00
b = pipe_hnd - > binding_handle ;
2008-03-10 04:33:06 +01:00
ZERO_STRUCT ( info_ctr ) ;
ZERO_STRUCT ( ctr1 ) ;
info_ctr . level = 1 ;
info_ctr . ctr . ctr1 = & ctr1 ;
2011-01-12 12:56:55 +01:00
status = dcerpc_srvsvc_NetShareEnumAll ( b , frame ,
2008-04-19 21:56:43 +02:00
pipe_hnd - > desthost ,
2008-03-10 04:33:06 +01:00
& info_ctr ,
0xffffffff ,
& total_entries ,
& resume_handle ,
& werr ) ;
2006-04-16 11:47:26 +00:00
2008-03-10 04:33:06 +01:00
if ( ! NT_STATUS_IS_OK ( status ) | | ! W_ERROR_IS_OK ( werr ) ) {
2008-04-20 13:51:46 +02:00
TALLOC_FREE ( pipe_hnd ) ;
2007-12-06 17:16:33 -08:00
TALLOC_FREE ( frame ) ;
return false ;
2006-04-16 11:47:26 +00:00
}
2008-03-10 04:33:06 +01:00
for ( i = 0 ; i < info_ctr . ctr . ctr1 - > count ; i + + ) {
struct srvsvc_NetShareInfo1 info = info_ctr . ctr . ctr1 - > array [ i ] ;
browse_fn ( info . name , info . type , info . comment , NULL ) ;
2006-04-16 11:47:26 +00:00
}
2008-04-20 13:51:46 +02:00
TALLOC_FREE ( pipe_hnd ) ;
2007-12-06 17:16:33 -08:00
TALLOC_FREE ( frame ) ;
return true ;
2006-04-16 11:47:26 +00:00
}
1996-05-04 07:50:46 +00:00
/****************************************************************************
2003-08-06 20:01:31 +00:00
Try and browse available connections on a host .
1996-05-04 07:50:46 +00:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2003-08-06 20:01:31 +00:00
2007-10-18 17:40:25 -07:00
static bool browse_host ( bool sort )
1996-05-04 07:50:46 +00:00
{
2000-02-25 22:25:25 +00:00
int ret ;
2018-09-04 11:11:49 +02:00
2004-01-16 15:01:09 +00:00
if ( ! grepable ) {
2004-03-01 17:40:40 +00:00
d_printf ( " \n \t Sharename Type Comment \n " ) ;
d_printf ( " \t --------- ---- ------- \n " ) ;
2004-01-16 15:01:09 +00:00
}
1996-05-04 07:50:46 +00:00
2006-04-16 11:47:26 +00:00
if ( browse_host_rpc ( sort ) ) {
2007-12-06 17:16:33 -08:00
return true ;
2006-04-16 11:47:26 +00:00
}
2019-10-03 14:02:13 -07:00
if ( smbXcli_conn_protocol ( cli - > conn ) > PROTOCOL_NT1 ) {
return false ;
}
2018-09-04 11:11:49 +02:00
ret = cli_RNetShareEnum ( cli , browse_fn , NULL ) ;
if ( ret = = - 1 ) {
2011-07-08 09:29:29 +02:00
NTSTATUS status = cli_nt_error ( cli ) ;
d_printf ( " Error returning browse list: %s \n " ,
nt_errstr ( status ) ) ;
}
2000-02-25 22:25:25 +00:00
return ( ret ! = - 1 ) ;
1996-05-04 07:50:46 +00:00
}
1998-11-09 03:45:49 +00:00
/****************************************************************************
2003-08-06 20:01:31 +00:00
List a server name .
1998-11-09 03:45:49 +00:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2003-08-06 20:01:31 +00:00
2015-05-09 19:49:09 -07:00
static void server_fn ( const char * name , uint32_t m ,
2001-01-04 11:35:55 +00:00
const char * comment , void * state )
1998-11-09 03:45:49 +00:00
{
2007-12-06 17:16:33 -08:00
2004-01-16 15:01:09 +00:00
if ( ! grepable ) {
2004-03-01 17:40:40 +00:00
d_printf ( " \t %-16s %s \n " , name , comment ) ;
2004-01-16 15:01:09 +00:00
} else {
d_printf ( " %s|%s|%s \n " , ( char * ) state , name , comment ) ;
}
1998-11-09 03:45:49 +00:00
}
1996-05-04 07:50:46 +00:00
/****************************************************************************
2003-08-06 20:01:31 +00:00
Try and browse available connections on a host .
1996-05-04 07:50:46 +00:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2003-08-06 20:01:31 +00:00
2007-10-18 17:40:25 -07:00
static bool list_servers ( const char * wk_grp )
1996-05-04 07:50:46 +00:00
{
2005-02-22 03:31:22 +00:00
fstring state ;
2003-08-06 20:01:31 +00:00
if ( ! cli - > server_domain )
2007-12-06 17:16:33 -08:00
return false ;
1998-11-09 03:45:49 +00:00
2004-01-16 15:01:09 +00:00
if ( ! grepable ) {
d_printf ( " \n \t Server Comment \n " ) ;
d_printf ( " \t --------- ------- \n " ) ;
} ;
2005-02-22 03:31:22 +00:00
fstrcpy ( state , " Server " ) ;
2004-01-16 15:01:09 +00:00
cli_NetServerEnum ( cli , cli - > server_domain , SV_TYPE_ALL , server_fn ,
2005-02-22 03:31:22 +00:00
state ) ;
1998-11-09 03:45:49 +00:00
2004-01-16 15:01:09 +00:00
if ( ! grepable ) {
d_printf ( " \n \t Workgroup Master \n " ) ;
d_printf ( " \t --------- ------- \n " ) ;
2007-12-06 17:16:33 -08:00
} ;
1998-11-09 03:45:49 +00:00
2005-02-22 03:31:22 +00:00
fstrcpy ( state , " Workgroup " ) ;
2004-01-16 15:01:09 +00:00
cli_NetServerEnum ( cli , cli - > server_domain , SV_TYPE_DOMAIN_ENUM ,
2005-02-22 03:31:22 +00:00
server_fn , state ) ;
2007-12-06 17:16:33 -08:00
return true ;
1996-05-04 07:50:46 +00:00
}
2004-02-12 17:26:34 +00:00
/****************************************************************************
Print or set current VUID
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static int cmd_vuid ( void )
{
2007-12-06 17:16:33 -08:00
TALLOC_CTX * ctx = talloc_tos ( ) ;
char * buf ;
2007-12-19 21:59:28 +01:00
if ( ! next_token_talloc ( ctx , & cmd_ptr , & buf , NULL ) ) {
2011-07-21 09:20:43 +02:00
d_printf ( " Current VUID is %d \n " ,
cli_state_get_uid ( cli ) ) ;
2004-02-12 17:26:34 +00:00
return 0 ;
}
2011-07-21 09:20:43 +02:00
cli_state_set_uid ( cli , atoi ( buf ) ) ;
2004-02-12 17:26:34 +00:00
return 0 ;
}
/****************************************************************************
Setup a new VUID , by issuing a session setup
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static int cmd_logon ( void )
{
2007-12-06 17:16:33 -08:00
TALLOC_CTX * ctx = talloc_tos ( ) ;
char * l_username , * l_password ;
2016-10-28 13:33:58 +02:00
struct cli_credentials * creds = NULL ;
2011-01-17 12:02:39 +01:00
NTSTATUS nt_status ;
2007-12-06 17:16:33 -08:00
2007-12-19 21:59:28 +01:00
if ( ! next_token_talloc ( ctx , & cmd_ptr , & l_username , NULL ) ) {
2004-02-12 17:26:34 +00:00
d_printf ( " logon <username> [<password>] \n " ) ;
return 0 ;
}
2007-12-19 21:59:28 +01:00
if ( ! next_token_talloc ( ctx , & cmd_ptr , & l_password , NULL ) ) {
2012-11-22 15:33:52 +01:00
char pwd [ 256 ] = { 0 } ;
int rc ;
rc = samba_getpass ( " Password: " , pwd , sizeof ( pwd ) , false , false ) ;
if ( rc = = 0 ) {
l_password = talloc_strdup ( ctx , pwd ) ;
2007-12-06 17:16:33 -08:00
}
}
if ( ! l_password ) {
return 1 ;
}
2004-02-12 17:26:34 +00:00
2016-10-28 13:33:58 +02:00
creds = cli_session_creds_init ( ctx ,
l_username ,
lp_workgroup ( ) ,
NULL , /* realm */
l_password ,
false , /* use_kerberos */
false , /* fallback_after_kerberos */
false , /* use_ccache */
false ) ; /* password_is_nt_hash */
if ( creds = = NULL ) {
d_printf ( " cli_session_creds_init() failed. \n " ) ;
return - 1 ;
}
nt_status = cli_session_setup_creds ( cli , creds ) ;
TALLOC_FREE ( creds ) ;
2011-01-17 12:02:39 +01:00
if ( ! NT_STATUS_IS_OK ( nt_status ) ) {
d_printf ( " session setup failed: %s \n " , nt_errstr ( nt_status ) ) ;
2004-02-12 17:26:34 +00:00
return - 1 ;
}
2011-07-21 09:20:43 +02:00
d_printf ( " Current VUID is %d \n " , cli_state_get_uid ( cli ) ) ;
2004-02-12 17:26:34 +00:00
return 0 ;
}
2011-07-22 14:08:03 +02:00
/**
* close the session
*/
static int cmd_logoff ( void )
{
NTSTATUS status ;
status = cli_ulogoff ( cli ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
d_printf ( " logoff failed: %s \n " , nt_errstr ( status ) ) ;
return - 1 ;
}
d_printf ( " logoff successful \n " ) ;
return 0 ;
}
2005-02-22 03:31:22 +00:00
2011-07-22 14:10:38 +02:00
/**
* tree connect ( connect to a share )
*/
static int cmd_tcon ( void )
{
TALLOC_CTX * ctx = talloc_tos ( ) ;
char * sharename ;
NTSTATUS status ;
if ( ! next_token_talloc ( ctx , & cmd_ptr , & sharename , NULL ) ) {
d_printf ( " tcon <sharename> \n " ) ;
return 0 ;
}
if ( ! sharename ) {
return 1 ;
}
2016-12-08 07:13:57 +01:00
status = cli_tree_connect ( cli , sharename , " ????? " , NULL ) ;
2011-07-22 14:10:38 +02:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
d_printf ( " tcon failed: %s \n " , nt_errstr ( status ) ) ;
return - 1 ;
}
d_printf ( " tcon to %s successful, tid: %u \n " , sharename ,
cli_state_get_tid ( cli ) ) ;
2022-12-22 10:31:11 +01:00
talloc_free ( sharename ) ;
2011-07-22 14:10:38 +02:00
return 0 ;
}
2011-07-22 14:11:34 +02:00
/**
* tree disconnect ( disconnect from a share )
*/
static int cmd_tdis ( void )
{
NTSTATUS status ;
status = cli_tdis ( cli ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
d_printf ( " tdis failed: %s \n " , nt_errstr ( status ) ) ;
return - 1 ;
}
d_printf ( " tdis successful \n " ) ;
return 0 ;
}
2011-07-22 14:10:38 +02:00
2011-07-22 14:12:13 +02:00
/**
* get or set tid
*/
static int cmd_tid ( void )
{
TALLOC_CTX * ctx = talloc_tos ( ) ;
char * tid_str ;
if ( ! next_token_talloc ( ctx , & cmd_ptr , & tid_str , NULL ) ) {
if ( cli_state_has_tcon ( cli ) ) {
d_printf ( " current tid is %d \n " , cli_state_get_tid ( cli ) ) ;
} else {
d_printf ( " no tcon currently \n " ) ;
}
} else {
2017-06-13 16:26:00 -07:00
uint32_t tid = atoi ( tid_str ) ;
if ( ! cli_state_has_tcon ( cli ) ) {
d_printf ( " no tcon currently \n " ) ;
}
2011-07-22 14:12:13 +02:00
cli_state_set_tid ( cli , tid ) ;
}
return 0 ;
}
2005-02-22 03:31:22 +00:00
/****************************************************************************
list active connections
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static int cmd_list_connect ( void )
{
2009-03-12 17:59:24 -07:00
cli_cm_display ( cli ) ;
2005-02-22 03:31:22 +00:00
return 0 ;
}
/****************************************************************************
2005-02-23 17:29:28 +00:00
display the current active client connection
2005-02-22 03:31:22 +00:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2005-02-23 17:29:28 +00:00
static int cmd_show_connect ( void )
2005-02-22 03:31:22 +00:00
{
2007-12-06 17:16:33 -08:00
TALLOC_CTX * ctx = talloc_tos ( ) ;
2005-02-23 17:29:28 +00:00
struct cli_state * targetcli ;
2007-12-06 17:16:33 -08:00
char * targetpath ;
2020-08-18 16:58:19 +02:00
struct cli_credentials * creds = samba_cmdline_get_creds ( ) ;
2011-07-03 20:53:55 +02:00
NTSTATUS status ;
2007-12-06 17:16:33 -08:00
2020-08-18 17:42:25 +02:00
status = cli_resolve_path ( ctx , " " ,
creds ,
cli ,
2011-07-03 20:53:55 +02:00
client_get_cur_dir ( ) , & targetcli ,
& targetpath ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
2011-07-05 19:42:46 +02:00
d_printf ( " showconnect %s: %s \n " , cur_dir , nt_errstr ( status ) ) ;
2005-02-22 03:31:22 +00:00
return 1 ;
}
2007-12-06 17:16:33 -08:00
2012-05-19 17:31:50 +02:00
d_printf ( " //%s/%s \n " , smbXcli_conn_remote_name ( targetcli - > conn ) , targetcli - > share ) ;
2005-02-22 03:31:22 +00:00
return 0 ;
}
2017-10-16 13:51:51 -07:00
/**
* cmd_utimes - interactive command to set the four times
*
* Read a filename and four times from the client command line and update
* the file times . A value of - 1 for a time means don ' t change .
*/
static int cmd_utimes ( void )
{
char * buf ;
char * fname = NULL ;
2019-12-01 09:01:20 +01:00
struct timespec times [ 4 ] = { { 0 } } ;
struct timeval_buf tbuf [ 4 ] ;
2017-10-16 13:51:51 -07:00
int time_count = 0 ;
int err = 0 ;
bool ok ;
TALLOC_CTX * ctx = talloc_new ( NULL ) ;
2020-03-26 14:24:14 +01:00
NTSTATUS status ;
2017-10-16 13:51:51 -07:00
if ( ctx = = NULL ) {
return 1 ;
}
ok = next_token_talloc ( ctx , & cmd_ptr , & buf , NULL ) ;
if ( ! ok ) {
d_printf ( " utimes <filename> <create-time> <access-time> "
" <write-time> <change-time> \n " ) ;
d_printf ( " Dates should be in YY:MM:DD-HH:MM:SS format "
" or -1 for no change \n " ) ;
err = 1 ;
goto out ;
}
fname = talloc_asprintf ( ctx ,
" %s%s " ,
client_get_cur_dir ( ) ,
buf ) ;
if ( fname = = NULL ) {
err = 1 ;
goto out ;
}
2017-10-20 15:09:38 -07:00
fname = client_clean_name ( ctx , fname ) ;
if ( fname = = NULL ) {
err = 1 ;
goto out ;
}
2017-10-16 13:51:51 -07:00
while ( next_token_talloc ( ctx , & cmd_ptr , & buf , NULL ) & &
time_count < 4 ) {
const char * s = buf ;
struct tm tm = { 0 , } ;
2019-12-01 09:01:20 +01:00
time_t t ;
2017-10-16 13:51:51 -07:00
char * ret ;
if ( strlen ( s ) = = 2 & & strcmp ( s , " -1 " ) = = 0 ) {
2019-12-01 09:01:20 +01:00
times [ time_count ] = make_omit_timespec ( ) ;
2017-10-16 13:51:51 -07:00
time_count + + ;
continue ;
}
2020-04-14 16:38:03 -07:00
ret = strptime ( s , " %y:%m:%d-%H:%M:%S " , & tm ) ;
2020-04-14 16:40:55 -07:00
if ( ret = = NULL ) {
ret = strptime ( s , " %Y:%m:%d-%H:%M:%S " , & tm ) ;
}
2017-10-16 13:51:51 -07:00
/* We could not match all the chars, so print error */
if ( ret = = NULL | | * ret ! = 0 ) {
d_printf ( " Invalid date format: %s \n " , s ) ;
d_printf ( " utimes <filename> <create-time> "
" <access-time> <write-time> <change-time> \n " ) ;
2020-04-14 16:40:55 -07:00
d_printf ( " Dates should be in [YY]YY:MM:DD-HH:MM:SS "
" format or -1 for no change \n " ) ;
2017-10-16 13:51:51 -07:00
err = 1 ;
goto out ;
}
/* Convert tm to a time_t */
2019-12-01 09:01:20 +01:00
t = mktime ( & tm ) ;
times [ time_count ] = ( struct timespec ) { . tv_sec = t } ;
2017-10-16 13:51:51 -07:00
time_count + + ;
}
if ( time_count < 4 ) {
d_printf ( " Insufficient dates: %d \n " , time_count ) ;
d_printf ( " utimes <filename> <create-time> <access-time> "
" <write-time> <change-time> \n " ) ;
d_printf ( " Dates should be in YY:MM:DD-HH:MM:SS format "
" or -1 for no change \n " ) ;
err = 1 ;
goto out ;
}
DEBUG ( 10 , ( " times \n Create: %sAccess: %s Write: %sChange: %s \n " ,
2019-12-01 09:01:20 +01:00
timespec_string_buf ( & times [ 0 ] , false , & tbuf [ 0 ] ) ,
timespec_string_buf ( & times [ 1 ] , false , & tbuf [ 1 ] ) ,
timespec_string_buf ( & times [ 2 ] , false , & tbuf [ 2 ] ) ,
timespec_string_buf ( & times [ 3 ] , false , & tbuf [ 3 ] ) ) ) ;
2017-10-16 13:51:51 -07:00
2020-03-26 14:24:14 +01:00
status = cli_setpathinfo_ext (
2020-06-03 20:48:23 -07:00
cli , fname , times [ 0 ] , times [ 1 ] , times [ 2 ] , times [ 3 ] ,
( uint32_t ) - 1 ) ;
2020-03-26 14:24:14 +01:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
d_printf ( " cli_setpathinfo_ext failed: %s \n " ,
nt_errstr ( status ) ) ;
err = 1 ;
goto out ;
}
2017-10-16 13:51:51 -07:00
out :
talloc_free ( ctx ) ;
return err ;
}
2015-09-17 15:54:40 -07:00
/**
* set_remote_attr - set DOS attributes of a remote file
* @ filename : path to the file name
* @ new_attr : attribute bit mask to use
* @ mode : one of ATTR_SET or ATTR_UNSET
*
* Update the file attributes with the one provided .
*/
2020-06-03 14:25:50 -07:00
int set_remote_attr ( const char * filename , uint32_t new_attr , int mode )
2015-09-17 15:54:40 -07:00
{
extern struct cli_state * cli ;
2020-06-03 13:15:17 -07:00
uint32_t old_attr ;
2015-09-17 15:54:40 -07:00
NTSTATUS status ;
status = cli_getatr ( cli , filename , & old_attr , NULL , NULL ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
d_printf ( " cli_getatr failed: %s \n " , nt_errstr ( status ) ) ;
return 1 ;
}
if ( mode = = ATTR_SET ) {
new_attr | = old_attr ;
} else {
new_attr = old_attr & ~ new_attr ;
}
2017-07-17 10:38:36 -07:00
2015-09-17 15:54:40 -07:00
status = cli_setatr ( cli , filename , new_attr , 0 ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
d_printf ( " cli_setatr failed: %s \n " , nt_errstr ( status ) ) ;
return 1 ;
}
return 0 ;
}
/**
* cmd_setmode - interactive command to set DOS attributes
*
* Read a filename and mode from the client command line and update
* the file DOS attributes .
*/
int cmd_setmode ( void )
{
char * buf ;
char * fname = NULL ;
2020-06-03 14:25:50 -07:00
uint32_t attr [ 2 ] = { 0 } ;
2015-09-17 15:54:40 -07:00
int mode = ATTR_SET ;
int err = 0 ;
bool ok ;
TALLOC_CTX * ctx = talloc_new ( NULL ) ;
if ( ctx = = NULL ) {
return 1 ;
}
ok = next_token_talloc ( ctx , & cmd_ptr , & buf , NULL ) ;
if ( ! ok ) {
d_printf ( " setmode <filename> <[+|-]rsha> \n " ) ;
err = 1 ;
goto out ;
}
fname = talloc_asprintf ( ctx ,
" %s%s " ,
client_get_cur_dir ( ) ,
buf ) ;
if ( fname = = NULL ) {
err = 1 ;
goto out ;
}
2017-10-20 15:09:38 -07:00
fname = client_clean_name ( ctx , fname ) ;
if ( fname = = NULL ) {
err = 1 ;
goto out ;
}
2015-09-17 15:54:40 -07:00
while ( next_token_talloc ( ctx , & cmd_ptr , & buf , NULL ) ) {
const char * s = buf ;
while ( * s ) {
switch ( * s + + ) {
case ' + ' :
mode = ATTR_SET ;
break ;
case ' - ' :
mode = ATTR_UNSET ;
break ;
case ' r ' :
attr [ mode ] | = FILE_ATTRIBUTE_READONLY ;
break ;
case ' h ' :
attr [ mode ] | = FILE_ATTRIBUTE_HIDDEN ;
break ;
case ' s ' :
attr [ mode ] | = FILE_ATTRIBUTE_SYSTEM ;
break ;
case ' a ' :
attr [ mode ] | = FILE_ATTRIBUTE_ARCHIVE ;
break ;
default :
d_printf ( " setmode <filename> <perm=[+|-]rsha> \n " ) ;
err = 1 ;
goto out ;
}
}
}
if ( attr [ ATTR_SET ] = = 0 & & attr [ ATTR_UNSET ] = = 0 ) {
d_printf ( " setmode <filename> <[+|-]rsha> \n " ) ;
err = 1 ;
goto out ;
}
DEBUG ( 2 , ( " perm set %d %d \n " , attr [ ATTR_SET ] , attr [ ATTR_UNSET ] ) ) ;
/* ignore return value: server might not store DOS attributes */
2017-07-17 10:38:36 -07:00
set_remote_attr ( fname , attr [ ATTR_SET ] , ATTR_SET ) ;
set_remote_attr ( fname , attr [ ATTR_UNSET ] , ATTR_UNSET ) ;
2015-09-17 15:54:40 -07:00
out :
talloc_free ( ctx ) ;
return err ;
}
2007-11-02 12:21:34 -07:00
/****************************************************************************
iosize command
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
int cmd_iosize ( void )
{
2007-12-06 17:16:33 -08:00
TALLOC_CTX * ctx = talloc_tos ( ) ;
char * buf ;
2007-11-02 12:21:34 -07:00
int iosize ;
2020-08-18 16:58:19 +02:00
struct cli_credentials * creds = samba_cmdline_get_creds ( ) ;
2020-08-27 15:19:27 +02:00
bool smb_encrypt =
2020-08-18 16:58:19 +02:00
( cli_credentials_get_smb_encryption ( creds ) = =
SMB_ENCRYPTION_REQUIRED ) ;
2007-11-02 12:21:34 -07:00
2007-12-19 21:59:28 +01:00
if ( ! next_token_talloc ( ctx , & cmd_ptr , & buf , NULL ) ) {
2013-08-16 11:45:43 -07:00
if ( smbXcli_conn_protocol ( cli - > conn ) < PROTOCOL_SMB2_02 ) {
if ( ! smb_encrypt ) {
d_printf ( " iosize <n> or iosize 0x<n>. "
" Minimum is 0 (default), "
" max is 16776960 (0xFFFF00) \n " ) ;
} else {
d_printf ( " iosize <n> or iosize 0x<n>. "
" (Encrypted connection) , "
" Minimum is 0 (default), "
" max is 130048 (0x1FC00) \n " ) ;
}
2007-12-29 22:39:52 -08:00
} else {
2013-08-16 11:45:43 -07:00
d_printf ( " iosize <n> or iosize 0x<n>. \n " ) ;
2007-12-29 22:39:52 -08:00
}
2007-11-02 12:21:34 -07:00
return 1 ;
}
iosize = strtol ( buf , NULL , 0 ) ;
2013-08-16 11:45:43 -07:00
if ( smbXcli_conn_protocol ( cli - > conn ) < PROTOCOL_SMB2_02 ) {
if ( smb_encrypt & & ( iosize < 0 | | iosize > 0xFC00 ) ) {
d_printf ( " iosize out of range for encrypted "
" connection (min = 0 (default), "
2013-08-21 16:12:30 +02:00
" max = 130048 (0x1FC00) \n " ) ;
2013-08-16 11:45:43 -07:00
return 1 ;
} else if ( ! smb_encrypt & & ( iosize < 0 | | iosize > 0xFFFF00 ) ) {
d_printf ( " iosize out of range (min = 0 (default), "
2013-08-21 16:12:30 +02:00
" max = 16776960 (0xFFFF00) \n " ) ;
2013-08-16 11:45:43 -07:00
return 1 ;
}
2007-11-02 12:21:34 -07:00
}
io_bufsize = iosize ;
d_printf ( " iosize is now %d \n " , io_bufsize ) ;
return 0 ;
}
2013-08-16 13:49:39 -07:00
/****************************************************************************
timeout command
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static int cmd_timeout ( void )
{
TALLOC_CTX * ctx = talloc_tos ( ) ;
char * buf ;
if ( ! next_token_talloc ( ctx , & cmd_ptr , & buf , NULL ) ) {
unsigned int old_timeout = cli_set_timeout ( cli , 0 ) ;
cli_set_timeout ( cli , old_timeout ) ;
d_printf ( " timeout <n> (per-operation timeout "
" in seconds - currently %u). \n " ,
old_timeout / 1000 ) ;
return 1 ;
}
io_timeout = strtol ( buf , NULL , 0 ) ;
cli_set_timeout ( cli , io_timeout * 1000 ) ;
d_printf ( " io_timeout per operation is now %d \n " , io_timeout ) ;
return 0 ;
}
2010-10-01 10:33:32 +02:00
/****************************************************************************
history
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
static int cmd_history ( void )
{
# if defined(HAVE_LIBREADLINE) && defined(HAVE_HISTORY_LIST)
HIST_ENTRY * * hlist ;
int i ;
hlist = history_list ( ) ;
for ( i = 0 ; hlist & & hlist [ i ] ; i + + ) {
DEBUG ( 0 , ( " %d: %s \n " , i , hlist [ i ] - > line ) ) ;
}
# else
DEBUG ( 0 , ( " no history without readline support \n " ) ) ;
# endif
return 0 ;
}
2007-11-02 12:21:34 -07:00
1998-09-18 12:47:46 +00:00
/* Some constants for completing filename arguments */
# define COMPL_NONE 0 /* No completions */
# define COMPL_REMOTE 1 /* Complete remote filename */
# define COMPL_LOCAL 2 /* Complete local filename */
2001-09-30 06:49:44 +00:00
/* This defines the commands supported by this client.
* NOTE : The " ! " must be the last one in the list because it ' s fn pointer
* field is NULL , and NULL in that field is used in process_tok ( )
* ( below ) to indicate the end of the list . crh
*/
2007-12-06 17:16:33 -08:00
static struct {
const char * name ;
int ( * fn ) ( void ) ;
const char * description ;
char compl_args [ 2 ] ; /* Completion argument info */
2003-08-06 20:01:31 +00:00
} commands [ ] = {
2002-01-16 20:25:23 +00:00
{ " ? " , cmd_help , " [command] give help on a command " , { COMPL_NONE , COMPL_NONE } } ,
2008-01-18 11:08:17 +01:00
{ " allinfo " , cmd_allinfo , " <file> show all available info " ,
2018-05-07 16:02:29 +02:00
{ COMPL_REMOTE , COMPL_NONE } } ,
{ " altname " , cmd_altname , " <file> show alt name " , { COMPL_REMOTE , COMPL_NONE } } ,
2001-09-30 06:49:44 +00:00
{ " archive " , cmd_archive , " <level> \n 0=ignore archive bit \n 1=only get archive files \n 2=only get archive files and reset archive bit \n 3=get all files and reset archive bit " , { COMPL_NONE , COMPL_NONE } } ,
2013-07-08 18:07:19 +02:00
{ " backup " , cmd_backup , " toggle backup intent state " , { COMPL_NONE , COMPL_NONE } } ,
2001-09-30 06:49:44 +00:00
{ " blocksize " , cmd_block , " blocksize <number> (default 20) " , { COMPL_NONE , COMPL_NONE } } ,
{ " cancel " , cmd_cancel , " <jobid> cancel a print queue entry " , { COMPL_NONE , COMPL_NONE } } ,
2004-06-15 18:36:45 +00:00
{ " case_sensitive " , cmd_setcase , " toggle the case sensitive flag to server " , { COMPL_NONE , COMPL_NONE } } ,
2001-09-30 06:49:44 +00:00
{ " cd " , cmd_cd , " [directory] change/report the remote directory " , { COMPL_REMOTE , COMPL_NONE } } ,
2013-05-22 12:17:23 +02:00
{ " chmod " , cmd_chmod , " <src> <mode> chmod a file using UNIX permission " , { COMPL_REMOTE , COMPL_NONE } } ,
{ " chown " , cmd_chown , " <src> <uid> <gid> chown a file using UNIX uids and gids " , { COMPL_REMOTE , COMPL_NONE } } ,
{ " close " , cmd_close , " <fid> close a file given a fid " , { COMPL_REMOTE , COMPL_NONE } } ,
2001-09-30 06:49:44 +00:00
{ " del " , cmd_del , " <mask> delete all matching files " , { COMPL_REMOTE , COMPL_NONE } } ,
2017-07-05 17:21:18 -07:00
{ " deltree " , cmd_deltree , " <mask> recursively delete all matching files and directories " , { COMPL_REMOTE , COMPL_NONE } } ,
1998-09-23 00:57:34 +00:00
{ " dir " , cmd_dir , " <mask> list the contents of the current directory " , { COMPL_REMOTE , COMPL_NONE } } ,
{ " du " , cmd_du , " <mask> computes the total size of the current directory " , { COMPL_REMOTE , COMPL_NONE } } ,
2007-07-22 11:18:49 +00:00
{ " echo " , cmd_echo , " ping the server " , { COMPL_NONE , COMPL_NONE } } ,
2001-09-30 06:49:44 +00:00
{ " exit " , cmd_quit , " logoff the server " , { COMPL_NONE , COMPL_NONE } } ,
1998-09-23 00:57:34 +00:00
{ " get " , cmd_get , " <remote name> [local name] get a file " , { COMPL_REMOTE , COMPL_LOCAL } } ,
2013-05-22 12:17:23 +02:00
{ " getfacl " , cmd_getfacl , " <file name> get the POSIX ACL on a file (UNIX extensions only) " , { COMPL_REMOTE , COMPL_NONE } } ,
2010-10-24 13:32:30 +02:00
{ " geteas " , cmd_geteas , " <file name> get the EA list of a file " ,
2013-05-22 12:17:23 +02:00
{ COMPL_REMOTE , COMPL_NONE } } ,
2004-03-03 23:14:23 +00:00
{ " hardlink " , cmd_hardlink , " <src> <dest> create a Windows hard link " , { COMPL_REMOTE , COMPL_REMOTE } } ,
2001-09-30 06:49:44 +00:00
{ " help " , cmd_help , " [command] give help on a command " , { COMPL_NONE , COMPL_NONE } } ,
{ " history " , cmd_history , " displays the command history " , { COMPL_NONE , COMPL_NONE } } ,
2007-11-02 12:21:34 -07:00
{ " iosize " , cmd_iosize , " iosize <number> (default 64512) " , { COMPL_NONE , COMPL_NONE } } ,
2001-09-30 06:49:44 +00:00
{ " lcd " , cmd_lcd , " [directory] change/report the local current working directory " , { COMPL_LOCAL , COMPL_NONE } } ,
2004-04-06 23:01:09 +00:00
{ " link " , cmd_link , " <oldname> <newname> create a UNIX hard link " , { COMPL_REMOTE , COMPL_REMOTE } } ,
2006-07-12 03:20:53 +00:00
{ " lock " , cmd_lock , " lock <fnum> [r|w] <hex-start> <hex-len> : set a POSIX lock " , { COMPL_REMOTE , COMPL_REMOTE } } ,
2013-07-08 18:07:19 +02:00
{ " lowercase " , cmd_lowercase , " toggle lowercasing of filenames for get " , { COMPL_NONE , COMPL_NONE } } ,
2001-09-30 06:49:44 +00:00
{ " ls " , cmd_dir , " <mask> list the contents of the current directory " , { COMPL_REMOTE , COMPL_NONE } } ,
2007-07-11 08:31:03 +00:00
{ " l " , cmd_dir , " <mask> list the contents of the current directory " , { COMPL_REMOTE , COMPL_NONE } } ,
2001-09-30 06:49:44 +00:00
{ " mask " , cmd_select , " <mask> mask all filenames against this " , { COMPL_REMOTE , COMPL_NONE } } ,
{ " md " , cmd_mkdir , " <directory> make a directory " , { COMPL_NONE , COMPL_NONE } } ,
1998-09-23 00:57:34 +00:00
{ " mget " , cmd_mget , " <mask> get all the matching files " , { COMPL_REMOTE , COMPL_NONE } } ,
2001-09-30 06:49:44 +00:00
{ " mkdir " , cmd_mkdir , " <directory> make a directory " , { COMPL_NONE , COMPL_NONE } } ,
2013-07-08 18:07:19 +02:00
{ " more " , cmd_more , " <remote name> view a remote file with your pager " , { COMPL_REMOTE , COMPL_NONE } } ,
2001-09-30 06:49:44 +00:00
{ " mput " , cmd_mput , " <mask> put all matching files " , { COMPL_REMOTE , COMPL_NONE } } ,
{ " newer " , cmd_newer , " <file> only mget files newer than the specified local file " , { COMPL_LOCAL , COMPL_NONE } } ,
2012-03-22 16:49:30 +01:00
{ " notify " , cmd_notify , " <file>Get notified of dir changes " , { COMPL_REMOTE , COMPL_NONE } } ,
1999-12-13 13:27:58 +00:00
{ " open " , cmd_open , " <mask> open a file " , { COMPL_REMOTE , COMPL_NONE } } ,
2006-07-12 00:21:14 +00:00
{ " posix " , cmd_posix , " turn on all POSIX capabilities " , { COMPL_REMOTE , COMPL_NONE } } ,
2007-12-26 17:12:36 -08:00
{ " posix_encrypt " , cmd_posix_encrypt , " <domain> <user> <password> start up transport encryption " , { COMPL_REMOTE , COMPL_NONE } } ,
2007-03-01 21:56:54 +00:00
{ " posix_open " , cmd_posix_open , " <name> 0<mode> open_flags mode open a file using POSIX interface " , { COMPL_REMOTE , COMPL_NONE } } ,
{ " posix_mkdir " , cmd_posix_mkdir , " <name> 0<mode> creates a directory using POSIX interface " , { COMPL_REMOTE , COMPL_NONE } } ,
{ " posix_rmdir " , cmd_posix_rmdir , " <name> removes a directory using POSIX interface " , { COMPL_REMOTE , COMPL_NONE } } ,
{ " posix_unlink " , cmd_posix_unlink , " <name> removes a file using POSIX interface " , { COMPL_REMOTE , COMPL_NONE } } ,
2018-05-04 22:23:45 +02:00
{ " posix_whoami " , cmd_posix_whoami , " return logged on user information "
2016-05-25 09:15:13 -07:00
" using POSIX interface " , { COMPL_REMOTE , COMPL_NONE } } ,
1998-09-23 00:57:34 +00:00
{ " print " , cmd_print , " <file name> print a file " , { COMPL_NONE , COMPL_NONE } } ,
2013-07-08 18:07:19 +02:00
{ " prompt " , cmd_prompt , " toggle prompting for filenames for mget and mput " , { COMPL_NONE , COMPL_NONE } } ,
2001-09-30 06:49:44 +00:00
{ " put " , cmd_put , " <local name> [remote name] put a file " , { COMPL_LOCAL , COMPL_REMOTE } } ,
{ " pwd " , cmd_pwd , " show current remote directory (same as 'cd' with no args) " , { COMPL_NONE , COMPL_NONE } } ,
{ " q " , cmd_quit , " logoff the server " , { COMPL_NONE , COMPL_NONE } } ,
1998-09-23 00:57:34 +00:00
{ " queue " , cmd_queue , " show the print queue " , { COMPL_NONE , COMPL_NONE } } ,
1998-11-09 03:45:49 +00:00
{ " quit " , cmd_quit , " logoff the server " , { COMPL_NONE , COMPL_NONE } } ,
2009-05-27 22:02:20 -07:00
{ " readlink " , cmd_readlink , " filename Do a UNIX extensions readlink call on a symlink " , { COMPL_REMOTE , COMPL_REMOTE } } ,
2001-09-30 06:49:44 +00:00
{ " rd " , cmd_rmdir , " <directory> remove a directory " , { COMPL_NONE , COMPL_NONE } } ,
2013-07-08 18:07:19 +02:00
{ " recurse " , cmd_recurse , " toggle directory recursion for mget and mput " , { COMPL_NONE , COMPL_NONE } } ,
2002-09-25 15:19:00 +00:00
{ " reget " , cmd_reget , " <remote name> [local name] get a file restarting at end of local file " , { COMPL_REMOTE , COMPL_LOCAL } } ,
2001-09-30 06:49:44 +00:00
{ " rename " , cmd_rename , " <src> <dest> rename some files " , { COMPL_REMOTE , COMPL_REMOTE } } ,
2002-09-25 15:19:00 +00:00
{ " reput " , cmd_reput , " <local name> [remote name] put a file restarting at end of remote file " , { COMPL_LOCAL , COMPL_REMOTE } } ,
2001-09-30 06:49:44 +00:00
{ " rm " , cmd_del , " <mask> delete all matching files " , { COMPL_REMOTE , COMPL_NONE } } ,
2013-05-22 12:17:23 +02:00
{ " rmdir " , cmd_rmdir , " <directory> remove a directory " , { COMPL_REMOTE , COMPL_NONE } } ,
2013-07-08 18:07:19 +02:00
{ " showacls " , cmd_showacls , " toggle if ACLs are shown or not " , { COMPL_NONE , COMPL_NONE } } ,
2010-10-24 15:43:34 +02:00
{ " setea " , cmd_setea , " <file name> <eaname> <eaval> Set an EA of a file " ,
{ COMPL_REMOTE , COMPL_LOCAL } } ,
2013-05-22 12:17:23 +02:00
{ " setmode " , cmd_setmode , " <file name> <setmode string> change modes of file " , { COMPL_REMOTE , COMPL_NONE } } ,
2015-06-25 11:37:18 +05:30
{ " scopy " , cmd_scopy , " <src> <dest> server-side copy file " , { COMPL_REMOTE , COMPL_REMOTE } } ,
2013-05-22 12:17:23 +02:00
{ " stat " , cmd_stat , " <file name> Do a UNIX extensions stat call on a file " , { COMPL_REMOTE , COMPL_NONE } } ,
2004-04-06 23:01:09 +00:00
{ " symlink " , cmd_symlink , " <oldname> <newname> create a UNIX symlink " , { COMPL_REMOTE , COMPL_REMOTE } } ,
2020-01-04 21:47:59 +01:00
{ " tar " , cmd_tar , " tar <c|x>[IXFvbgNan] current directory to/from <file name> " , { COMPL_NONE , COMPL_NONE } } ,
2001-09-30 06:49:44 +00:00
{ " tarmode " , cmd_tarmode , " <full|inc|reset|noreset> tar's behaviour towards archive bits " , { COMPL_NONE , COMPL_NONE } } ,
2013-08-16 13:49:39 -07:00
{ " timeout " , cmd_timeout , " timeout <number> - set the per-operation timeout in seconds (default 20) " , { COMPL_NONE , COMPL_NONE } } ,
2001-09-30 06:49:44 +00:00
{ " translate " , cmd_translate , " toggle text translation for printing " , { COMPL_NONE , COMPL_NONE } } ,
2006-07-12 03:20:53 +00:00
{ " unlock " , cmd_unlock , " unlock <fnum> <hex-start> <hex-len> : remove a POSIX lock " , { COMPL_REMOTE , COMPL_REMOTE } } ,
2005-03-30 00:47:57 +00:00
{ " volume " , cmd_volume , " print the volume name " , { COMPL_NONE , COMPL_NONE } } ,
2004-02-12 17:26:34 +00:00
{ " vuid " , cmd_vuid , " change current vuid " , { COMPL_NONE , COMPL_NONE } } ,
2007-03-07 19:45:22 +00:00
{ " wdel " , cmd_wdel , " <attrib> <mask> wildcard delete all matching files " , { COMPL_REMOTE , COMPL_NONE } } ,
2004-02-12 17:26:34 +00:00
{ " logon " , cmd_logon , " establish new logon " , { COMPL_NONE , COMPL_NONE } } ,
2005-02-22 03:31:22 +00:00
{ " listconnect " , cmd_list_connect , " list open connections " , { COMPL_NONE , COMPL_NONE } } ,
2005-02-23 17:29:28 +00:00
{ " showconnect " , cmd_show_connect , " display the current active connection " , { COMPL_NONE , COMPL_NONE } } ,
2011-07-22 14:10:38 +02:00
{ " tcon " , cmd_tcon , " connect to a share " , { COMPL_NONE , COMPL_NONE } } ,
2011-07-22 14:11:34 +02:00
{ " tdis " , cmd_tdis , " disconnect from a share " , { COMPL_NONE , COMPL_NONE } } ,
2011-07-22 14:12:13 +02:00
{ " tid " , cmd_tid , " show or set the current tid (tree-id) " , { COMPL_NONE , COMPL_NONE } } ,
2017-10-16 13:51:51 -07:00
{ " utimes " , cmd_utimes , " <file name> <create_time> <access_time> <mod_time> "
" <ctime> set times " , { COMPL_REMOTE , COMPL_NONE } } ,
2011-07-22 14:08:03 +02:00
{ " logoff " , cmd_logoff , " log off (close the session) " , { COMPL_NONE , COMPL_NONE } } ,
2007-07-11 08:43:08 +00:00
{ " .. " , cmd_cd_oneup , " change the remote directory (up one level) " , { COMPL_REMOTE , COMPL_NONE } } ,
2002-01-17 07:14:21 +00:00
/* Yes, this must be here, see crh's comment above. */
{ " ! " , NULL , " run a shell command on the local system " , { COMPL_NONE , COMPL_NONE } } ,
2003-06-11 06:23:53 +00:00
{ NULL , NULL , NULL , { COMPL_NONE , COMPL_NONE } }
1996-05-04 07:50:46 +00:00
} ;
/*******************************************************************
2007-12-06 17:16:33 -08:00
Lookup a command string in the list of commands , including
2003-08-06 20:01:31 +00:00
abbreviations .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2007-12-06 17:16:33 -08:00
static int process_tok ( char * tok )
1996-05-04 07:50:46 +00:00
{
2017-12-07 18:47:18 +01:00
size_t i = 0 , matches = 0 ;
size_t cmd = 0 ;
size_t tok_len = strlen ( tok ) ;
2007-12-06 17:16:33 -08:00
1998-11-09 03:45:49 +00:00
while ( commands [ i ] . fn ! = NULL ) {
if ( strequal ( commands [ i ] . name , tok ) ) {
matches = 1 ;
cmd = i ;
break ;
} else if ( strnequal ( commands [ i ] . name , tok , tok_len ) ) {
matches + + ;
cmd = i ;
}
i + + ;
1996-05-04 07:50:46 +00:00
}
2007-12-06 17:16:33 -08:00
1998-11-09 03:45:49 +00:00
if ( matches = = 0 )
return ( - 1 ) ;
else if ( matches = = 1 )
return ( cmd ) ;
else
return ( - 2 ) ;
1996-05-04 07:50:46 +00:00
}
/****************************************************************************
2003-08-06 20:01:31 +00:00
Help .
1996-05-04 07:50:46 +00:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2003-08-06 20:01:31 +00:00
2001-10-09 19:12:18 +00:00
static int cmd_help ( void )
1996-05-04 07:50:46 +00:00
{
2007-12-06 17:16:33 -08:00
TALLOC_CTX * ctx = talloc_tos ( ) ;
1998-11-09 03:45:49 +00:00
int i = 0 , j ;
2007-12-06 17:16:33 -08:00
char * buf ;
2007-12-19 21:59:28 +01:00
if ( next_token_talloc ( ctx , & cmd_ptr , & buf , NULL ) ) {
1998-11-09 03:45:49 +00:00
if ( ( i = process_tok ( buf ) ) > = 0 )
2007-12-06 17:16:33 -08:00
d_printf ( " HELP %s: \n \t %s \n \n " ,
commands [ i ] . name , commands [ i ] . description ) ;
1998-11-09 03:45:49 +00:00
} else {
while ( commands [ i ] . description ) {
for ( j = 0 ; commands [ i ] . description & & ( j < 5 ) ; j + + ) {
2001-09-07 14:14:57 +00:00
d_printf ( " %-15s " , commands [ i ] . name ) ;
1998-11-09 03:45:49 +00:00
i + + ;
}
2001-09-07 14:14:57 +00:00
d_printf ( " \n " ) ;
1998-11-09 03:45:49 +00:00
}
1996-05-04 07:50:46 +00:00
}
2001-10-09 19:12:18 +00:00
return 0 ;
1996-05-04 07:50:46 +00:00
}
1998-09-18 12:47:46 +00:00
/****************************************************************************
2003-08-06 20:01:31 +00:00
Process a - c command string .
1998-09-18 12:47:46 +00:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2003-08-06 20:01:31 +00:00
2007-12-06 17:16:33 -08:00
static int process_command_string ( const char * cmd_in )
1998-09-18 12:47:46 +00:00
{
2007-12-06 17:16:33 -08:00
TALLOC_CTX * ctx = talloc_tos ( ) ;
char * cmd = talloc_strdup ( ctx , cmd_in ) ;
2001-10-09 19:12:18 +00:00
int rc = 0 ;
2020-08-18 16:58:19 +02:00
struct cli_credentials * creds = samba_cmdline_get_creds ( ) ;
1998-09-18 12:47:46 +00:00
2007-12-06 17:16:33 -08:00
if ( ! cmd ) {
return 1 ;
}
2002-07-15 10:35:28 +00:00
/* establish the connection if not already */
2007-12-06 17:16:33 -08:00
2002-07-15 10:35:28 +00:00
if ( ! cli ) {
2011-07-03 19:59:37 +02:00
NTSTATUS status ;
status = cli_cm_open ( talloc_tos ( ) , NULL ,
2018-08-23 09:21:41 +02:00
desthost ,
2020-08-18 17:26:54 +02:00
service ,
creds ,
2018-08-23 09:21:41 +02:00
have_ip ? & dest_ss : NULL , port ,
name_type ,
2011-07-03 19:59:37 +02:00
& cli ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
2007-12-06 17:16:33 -08:00
return 1 ;
}
2013-08-16 13:49:39 -07:00
cli_set_timeout ( cli , io_timeout * 1000 ) ;
2002-07-15 10:35:28 +00:00
}
2007-12-06 17:16:33 -08:00
1998-11-09 03:45:49 +00:00
while ( cmd [ 0 ] ! = ' \0 ' ) {
2007-12-06 17:16:33 -08:00
char * line ;
1998-11-09 03:45:49 +00:00
char * p ;
2007-12-06 17:16:33 -08:00
char * tok ;
1998-11-09 03:45:49 +00:00
int i ;
2007-12-06 17:16:33 -08:00
2001-07-04 07:36:09 +00:00
if ( ( p = strchr_m ( cmd , ' ; ' ) ) = = 0 ) {
2007-12-06 17:16:33 -08:00
line = cmd ;
1998-11-09 03:45:49 +00:00
cmd + = strlen ( cmd ) ;
} else {
2007-12-06 17:16:33 -08:00
* p = ' \0 ' ;
line = cmd ;
1998-11-09 03:45:49 +00:00
cmd = p + 1 ;
}
2007-12-06 17:16:33 -08:00
1998-11-09 03:45:49 +00:00
/* and get the first part of the command */
2007-12-19 21:59:28 +01:00
cmd_ptr = line ;
if ( ! next_token_talloc ( ctx , & cmd_ptr , & tok , NULL ) ) {
2007-12-06 17:16:33 -08:00
continue ;
}
1998-11-09 03:45:49 +00:00
if ( ( i = process_tok ( tok ) ) > = 0 ) {
2001-10-09 19:12:18 +00:00
rc = commands [ i ] . fn ( ) ;
1998-11-09 03:45:49 +00:00
} else if ( i = = - 2 ) {
2001-09-07 14:14:57 +00:00
d_printf ( " %s: command abbreviation ambiguous \n " , tok ) ;
1998-11-09 03:45:49 +00:00
} else {
2001-09-07 14:14:57 +00:00
d_printf ( " %s: command not found \n " , tok ) ;
1998-11-09 03:45:49 +00:00
}
}
2007-12-06 17:16:33 -08:00
2001-10-09 19:12:18 +00:00
return rc ;
2007-12-06 17:16:33 -08:00
}
1998-09-18 12:47:46 +00:00
2001-03-19 00:22:52 +00:00
# define MAX_COMPLETIONS 100
2010-02-15 23:53:18 +01:00
struct completion_remote {
2007-12-06 17:16:33 -08:00
char * dirmask ;
2003-05-12 18:12:31 +00:00
char * * matches ;
int count , samelen ;
const char * text ;
int len ;
2010-02-15 23:53:18 +01:00
} ;
2001-03-19 00:22:52 +00:00
2020-10-19 10:09:23 +02:00
static NTSTATUS completion_remote_filter ( struct file_info * f ,
2007-12-06 17:16:33 -08:00
const char * mask ,
void * state )
2003-05-12 18:12:31 +00:00
{
2010-02-15 23:53:18 +01:00
struct completion_remote * info = ( struct completion_remote * ) state ;
2001-03-19 00:22:52 +00:00
2010-02-18 22:52:41 +01:00
if ( info - > count > = MAX_COMPLETIONS - 1 ) {
2010-10-29 11:56:51 -07:00
return NT_STATUS_OK ;
2010-02-18 22:52:41 +01:00
}
if ( strncmp ( info - > text , f - > name , info - > len ) ! = 0 ) {
2010-10-29 11:56:51 -07:00
return NT_STATUS_OK ;
2010-02-18 22:52:41 +01:00
}
if ( ISDOT ( f - > name ) | | ISDOTDOT ( f - > name ) ) {
2010-10-29 11:56:51 -07:00
return NT_STATUS_OK ;
2010-02-18 22:52:41 +01:00
}
2020-06-03 10:41:27 -07:00
if ( ( info - > dirmask [ 0 ] = = 0 ) & & ! ( f - > attr & FILE_ATTRIBUTE_DIRECTORY ) )
2010-02-18 22:52:41 +01:00
info - > matches [ info - > count ] = SMB_STRDUP ( f - > name ) ;
else {
TALLOC_CTX * ctx = talloc_stackframe ( ) ;
char * tmp ;
tmp = talloc_strdup ( ctx , info - > dirmask ) ;
if ( ! tmp ) {
2007-12-06 17:16:33 -08:00
TALLOC_FREE ( ctx ) ;
2010-10-29 11:56:51 -07:00
return NT_STATUS_NO_MEMORY ;
2001-03-19 00:22:52 +00:00
}
2010-02-18 22:52:41 +01:00
tmp = talloc_asprintf_append ( tmp , " %s " , f - > name ) ;
if ( ! tmp ) {
TALLOC_FREE ( ctx ) ;
2010-10-29 11:56:51 -07:00
return NT_STATUS_NO_MEMORY ;
2007-12-06 17:16:33 -08:00
}
2020-06-03 10:41:27 -07:00
if ( f - > attr & FILE_ATTRIBUTE_DIRECTORY ) {
2010-02-18 22:52:41 +01:00
tmp = talloc_asprintf_append ( tmp , " %s " ,
CLI_DIRSEP_STR ) ;
2007-12-06 17:16:33 -08:00
}
2010-02-18 22:52:41 +01:00
if ( ! tmp ) {
TALLOC_FREE ( ctx ) ;
2010-10-29 11:56:51 -07:00
return NT_STATUS_NO_MEMORY ;
2010-02-18 22:52:41 +01:00
}
info - > matches [ info - > count ] = SMB_STRDUP ( tmp ) ;
TALLOC_FREE ( ctx ) ;
}
if ( info - > matches [ info - > count ] = = NULL ) {
2010-10-29 11:56:51 -07:00
return NT_STATUS_OK ;
2010-02-18 22:52:41 +01:00
}
2020-06-03 10:41:27 -07:00
if ( f - > attr & FILE_ATTRIBUTE_DIRECTORY ) {
2010-02-18 22:52:41 +01:00
smb_readline_ca_char ( 0 ) ;
}
if ( info - > count = = 1 ) {
info - > samelen = strlen ( info - > matches [ info - > count ] ) ;
} else {
while ( strncmp ( info - > matches [ info - > count ] ,
info - > matches [ info - > count - 1 ] ,
info - > samelen ) ! = 0 ) {
info - > samelen - - ;
2007-12-06 17:16:33 -08:00
}
2001-03-19 00:22:52 +00:00
}
2010-02-18 22:52:41 +01:00
info - > count + + ;
2010-10-29 11:56:51 -07:00
return NT_STATUS_OK ;
2003-05-12 18:12:31 +00:00
}
2001-03-19 00:22:52 +00:00
2003-05-12 18:12:31 +00:00
static char * * remote_completion ( const char * text , int len )
{
2007-12-06 17:16:33 -08:00
TALLOC_CTX * ctx = talloc_stackframe ( ) ;
char * dirmask = NULL ;
char * targetpath = NULL ;
struct cli_state * targetcli = NULL ;
2003-05-12 18:12:31 +00:00
int i ;
2010-02-15 23:53:18 +01:00
struct completion_remote info = { NULL , NULL , 1 , 0 , NULL , 0 } ;
2020-08-18 16:58:19 +02:00
struct cli_credentials * creds = samba_cmdline_get_creds ( ) ;
2010-08-02 19:22:22 +02:00
NTSTATUS status ;
2003-05-12 18:12:31 +00:00
2010-02-15 23:52:51 +01:00
/* can't have non-static initialisation on Sun CC, so do it
2003-05-13 06:13:36 +00:00
at run time here */
info . samelen = len ;
info . text = text ;
info . len = len ;
2003-05-12 18:12:31 +00:00
2004-12-07 18:25:53 +00:00
info . matches = SMB_MALLOC_ARRAY ( char * , MAX_COMPLETIONS ) ;
2006-03-13 22:49:56 +00:00
if ( ! info . matches ) {
2007-12-06 17:16:33 -08:00
TALLOC_FREE ( ctx ) ;
2006-03-13 22:49:56 +00:00
return NULL ;
}
2006-09-11 21:33:53 +00:00
/*
* We ' re leaving matches [ 0 ] free to fill it later with the text to
* display : Either the one single match or the longest common subset
* of the matches .
*/
2003-05-12 18:12:31 +00:00
info . matches [ 0 ] = NULL ;
2006-09-11 21:33:53 +00:00
info . count = 1 ;
2003-05-12 18:12:31 +00:00
2006-03-13 22:49:56 +00:00
for ( i = len - 1 ; i > = 0 ; i - - ) {
2006-07-12 03:20:53 +00:00
if ( ( text [ i ] = = ' / ' ) | | ( text [ i ] = = CLI_DIRSEP_CHAR ) ) {
2003-05-12 18:12:31 +00:00
break ;
2006-03-13 22:49:56 +00:00
}
}
2003-05-12 18:12:31 +00:00
info . text = text + i + 1 ;
info . samelen = info . len = len - i - 1 ;
if ( i > 0 ) {
2007-12-08 11:21:08 +01:00
info . dirmask = SMB_MALLOC_ARRAY ( char , i + 2 ) ;
2007-12-06 17:16:33 -08:00
if ( ! info . dirmask ) {
goto cleanup ;
}
2003-05-12 18:12:31 +00:00
strncpy ( info . dirmask , text , i + 1 ) ;
info . dirmask [ i + 1 ] = 0 ;
2007-12-06 17:16:33 -08:00
dirmask = talloc_asprintf ( ctx ,
" %s%*s* " ,
client_get_cur_dir ( ) ,
i - 1 ,
text ) ;
2006-03-13 22:49:56 +00:00
} else {
2007-12-06 17:16:33 -08:00
info . dirmask = SMB_STRDUP ( " " ) ;
if ( ! info . dirmask ) {
goto cleanup ;
}
dirmask = talloc_asprintf ( ctx ,
" %s* " ,
client_get_cur_dir ( ) ) ;
}
if ( ! dirmask ) {
goto cleanup ;
2006-03-13 22:49:56 +00:00
}
2017-10-20 15:09:38 -07:00
dirmask = client_clean_name ( ctx , dirmask ) ;
if ( dirmask = = NULL ) {
goto cleanup ;
}
2003-05-12 18:12:31 +00:00
2020-08-18 17:42:25 +02:00
status = cli_resolve_path ( ctx , " " ,
creds ,
2017-04-25 17:03:10 -07:00
cli , dirmask , & targetcli , & targetpath ) ;
2011-07-03 20:53:55 +02:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
2007-12-06 17:16:33 -08:00
goto cleanup ;
}
2011-04-29 11:57:02 +10:00
status = cli_list ( targetcli , targetpath , FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_SYSTEM | FILE_ATTRIBUTE_HIDDEN ,
2010-08-02 19:22:22 +02:00
completion_remote_filter , ( void * ) & info ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
2003-05-12 18:12:31 +00:00
goto cleanup ;
2007-12-06 17:16:33 -08:00
}
2003-05-12 18:12:31 +00:00
2006-09-11 21:33:53 +00:00
if ( info . count = = 1 ) {
/*
* No matches at all , NULL indicates there is nothing
*/
SAFE_FREE ( info . matches [ 0 ] ) ;
SAFE_FREE ( info . matches ) ;
2007-12-06 17:16:33 -08:00
TALLOC_FREE ( ctx ) ;
2006-09-11 21:33:53 +00:00
return NULL ;
}
if ( info . count = = 2 ) {
/*
* Exactly one match in matches [ 1 ] , indicate this is the one
* in matches [ 0 ] .
*/
info . matches [ 0 ] = info . matches [ 1 ] ;
info . matches [ 1 ] = NULL ;
info . count - = 1 ;
2007-12-06 17:16:33 -08:00
TALLOC_FREE ( ctx ) ;
2006-09-11 21:33:53 +00:00
return info . matches ;
2001-03-19 00:22:52 +00:00
}
2006-09-11 21:33:53 +00:00
/*
* We got more than one possible match , set the result to the maximum
* common subset
*/
info . matches [ 0 ] = SMB_STRNDUP ( info . matches [ 1 ] , info . samelen ) ;
2003-05-12 18:12:31 +00:00
info . matches [ info . count ] = NULL ;
2012-09-25 10:41:05 +10:00
TALLOC_FREE ( ctx ) ;
2003-05-12 18:12:31 +00:00
return info . matches ;
cleanup :
2007-12-06 17:16:33 -08:00
for ( i = 0 ; i < info . count ; i + + ) {
SAFE_FREE ( info . matches [ i ] ) ;
}
SAFE_FREE ( info . matches ) ;
SAFE_FREE ( info . dirmask ) ;
TALLOC_FREE ( ctx ) ;
2003-05-12 18:12:31 +00:00
return NULL ;
2001-03-19 00:22:52 +00:00
}
2003-05-12 18:12:31 +00:00
static char * * completion_fn ( const char * text , int start , int end )
{
smb_readline_ca_char ( ' ' ) ;
if ( start ) {
const char * buf , * sp ;
int i ;
char compl_type ;
buf = smb_readline_get_line_buffer ( ) ;
if ( buf = = NULL )
return NULL ;
2007-12-06 17:16:33 -08:00
2003-05-12 18:12:31 +00:00
sp = strchr ( buf , ' ' ) ;
if ( sp = = NULL )
return NULL ;
2006-09-11 21:33:53 +00:00
for ( i = 0 ; commands [ i ] . name ; i + + ) {
if ( ( strncmp ( commands [ i ] . name , buf , sp - buf ) = = 0 ) & &
( commands [ i ] . name [ sp - buf ] = = 0 ) ) {
2003-05-12 18:12:31 +00:00
break ;
2006-09-11 21:33:53 +00:00
}
}
2003-05-12 18:12:31 +00:00
if ( commands [ i ] . name = = NULL )
return NULL ;
while ( * sp = = ' ' )
sp + + ;
if ( sp = = ( buf + start ) )
compl_type = commands [ i ] . compl_args [ 0 ] ;
else
compl_type = commands [ i ] . compl_args [ 1 ] ;
if ( compl_type = = COMPL_REMOTE )
return remote_completion ( text , end - start ) ;
else /* fall back to local filename completion */
return NULL ;
} else {
char * * matches ;
2018-03-22 14:51:28 +01:00
size_t i , len , samelen = 0 , count = 1 ;
2003-05-12 18:12:31 +00:00
2004-12-07 18:25:53 +00:00
matches = SMB_MALLOC_ARRAY ( char * , MAX_COMPLETIONS ) ;
2004-11-24 01:03:23 +00:00
if ( ! matches ) {
return NULL ;
}
2003-05-12 18:12:31 +00:00
matches [ 0 ] = NULL ;
len = strlen ( text ) ;
for ( i = 0 ; commands [ i ] . fn & & count < MAX_COMPLETIONS - 1 ; i + + ) {
if ( strncmp ( text , commands [ i ] . name , len ) = = 0 ) {
2004-12-07 18:25:53 +00:00
matches [ count ] = SMB_STRDUP ( commands [ i ] . name ) ;
2003-05-12 18:12:31 +00:00
if ( ! matches [ count ] )
goto cleanup ;
if ( count = = 1 )
samelen = strlen ( matches [ count ] ) ;
else
while ( strncmp ( matches [ count ] , matches [ count - 1 ] , samelen ) ! = 0 )
samelen - - ;
count + + ;
}
}
switch ( count ) {
case 0 : /* should never happen */
case 1 :
goto cleanup ;
case 2 :
2004-12-07 18:25:53 +00:00
matches [ 0 ] = SMB_STRDUP ( matches [ 1 ] ) ;
2003-05-12 18:12:31 +00:00
break ;
default :
2006-08-16 17:14:16 +00:00
matches [ 0 ] = ( char * ) SMB_MALLOC ( samelen + 1 ) ;
2003-05-12 18:12:31 +00:00
if ( ! matches [ 0 ] )
goto cleanup ;
strncpy ( matches [ 0 ] , matches [ 1 ] , samelen ) ;
matches [ 0 ] [ samelen ] = 0 ;
}
matches [ count ] = NULL ;
return matches ;
cleanup :
2003-11-04 22:38:58 +00:00
for ( i = 0 ; i < count ; i + + )
2003-05-12 18:12:31 +00:00
free ( matches [ i ] ) ;
2003-11-04 22:38:58 +00:00
2003-05-12 18:12:31 +00:00
free ( matches ) ;
return NULL ;
}
}
2001-03-18 13:24:57 +00:00
2008-10-03 14:58:41 -07:00
static bool finished ;
2001-03-18 23:41:53 +00:00
/****************************************************************************
2003-08-06 20:01:31 +00:00
Make sure we swallow keepalives during idle time .
2001-03-18 23:41:53 +00:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2003-08-06 20:01:31 +00:00
2001-03-18 23:41:53 +00:00
static void readline_callback ( void )
{
static time_t last_t ;
2010-08-30 12:15:54 +02:00
struct timespec now ;
2001-03-18 23:41:53 +00:00
time_t t ;
2011-07-11 13:19:47 +02:00
NTSTATUS status ;
unsigned char garbage [ 16 ] ;
2001-03-18 23:41:53 +00:00
2010-08-30 12:15:54 +02:00
clock_gettime_mono ( & now ) ;
t = now . tv_sec ;
2001-03-18 23:41:53 +00:00
2003-08-06 20:01:31 +00:00
if ( t - last_t < 5 )
return ;
2001-03-18 23:41:53 +00:00
last_t = t ;
2005-11-30 17:53:21 +00:00
/* Ping the server to keep the connection alive using SMBecho. */
2011-07-11 13:19:47 +02:00
memset ( garbage , 0xf0 , sizeof ( garbage ) ) ;
status = cli_echo ( cli , 1 , data_blob_const ( garbage , sizeof ( garbage ) ) ) ;
2017-09-08 16:20:34 -07:00
if ( NT_STATUS_IS_OK ( status ) | |
NT_STATUS_EQUAL ( status , NT_STATUS_INVALID_PARAMETER ) ) {
/*
* Even if server returns NT_STATUS_INVALID_PARAMETER
* it still responded .
* BUG : https : //bugzilla.samba.org/show_bug.cgi?id=13007
*/
2012-01-31 08:47:38 +01:00
return ;
}
if ( ! cli_state_is_connected ( cli ) ) {
DEBUG ( 0 , ( " SMBecho failed (%s). The connection is "
" disconnected now \n " , nt_errstr ( status ) ) ) ;
2011-07-11 13:19:47 +02:00
finished = true ;
smb_readline_done ( ) ;
2005-11-30 17:53:21 +00:00
}
2001-03-18 23:41:53 +00:00
}
1998-11-09 03:45:49 +00:00
/****************************************************************************
2003-08-06 20:01:31 +00:00
Process commands on stdin .
1998-11-09 03:45:49 +00:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2003-08-06 20:01:31 +00:00
2004-07-01 20:20:06 +00:00
static int process_stdin ( void )
1998-09-18 12:47:46 +00:00
{
2004-07-01 20:20:06 +00:00
int rc = 0 ;
1998-09-18 12:47:46 +00:00
2018-06-25 09:58:56 -04:00
if ( ! quiet ) {
d_printf ( " Try \" help \" to get a list of possible commands. \n " ) ;
}
2017-06-23 16:58:42 +02:00
2008-10-03 14:58:41 -07:00
while ( ! finished ) {
2007-11-29 17:25:41 -08:00
TALLOC_CTX * frame = talloc_stackframe ( ) ;
2007-12-06 17:16:33 -08:00
char * tok = NULL ;
char * the_prompt = NULL ;
char * line = NULL ;
1998-11-09 03:45:49 +00:00
int i ;
2007-11-29 17:25:41 -08:00
2001-03-18 13:24:57 +00:00
/* display a prompt */
2007-12-06 17:16:33 -08:00
if ( asprintf ( & the_prompt , " smb: %s> " , client_get_cur_dir ( ) ) < 0 ) {
TALLOC_FREE ( frame ) ;
break ;
}
line = smb_readline ( the_prompt , readline_callback , completion_fn ) ;
SAFE_FREE ( the_prompt ) ;
if ( ! line ) {
2007-11-29 17:25:41 -08:00
TALLOC_FREE ( frame ) ;
break ;
}
1999-12-13 13:27:58 +00:00
1998-11-09 03:45:49 +00:00
/* special case - first char is ! */
2001-03-18 23:41:53 +00:00
if ( * line = = ' ! ' ) {
2008-12-31 16:30:11 -08:00
if ( system ( line + 1 ) = = - 1 ) {
d_printf ( " system() command %s failed. \n " ,
line + 1 ) ;
}
2007-12-06 17:16:33 -08:00
SAFE_FREE ( line ) ;
2007-11-29 17:25:41 -08:00
TALLOC_FREE ( frame ) ;
1998-11-09 03:45:49 +00:00
continue ;
}
2007-11-29 17:25:41 -08:00
1998-11-09 03:45:49 +00:00
/* and get the first part of the command */
2007-12-19 21:59:28 +01:00
cmd_ptr = line ;
if ( ! next_token_talloc ( frame , & cmd_ptr , & tok , NULL ) ) {
2007-11-29 17:25:41 -08:00
TALLOC_FREE ( frame ) ;
2007-12-06 17:16:33 -08:00
SAFE_FREE ( line ) ;
2007-11-29 17:25:41 -08:00
continue ;
}
1998-11-09 03:45:49 +00:00
if ( ( i = process_tok ( tok ) ) > = 0 ) {
2004-07-01 20:20:06 +00:00
rc = commands [ i ] . fn ( ) ;
1998-11-09 03:45:49 +00:00
} else if ( i = = - 2 ) {
2001-09-07 14:14:57 +00:00
d_printf ( " %s: command abbreviation ambiguous \n " , tok ) ;
1998-11-09 03:45:49 +00:00
} else {
2001-09-07 14:14:57 +00:00
d_printf ( " %s: command not found \n " , tok ) ;
1998-11-09 03:45:49 +00:00
}
2007-12-06 17:16:33 -08:00
SAFE_FREE ( line ) ;
2007-11-29 17:25:41 -08:00
TALLOC_FREE ( frame ) ;
1998-11-09 03:45:49 +00:00
}
2004-07-01 20:20:06 +00:00
return rc ;
1998-09-18 12:47:46 +00:00
}
1996-05-04 07:50:46 +00:00
/****************************************************************************
2003-08-06 20:01:31 +00:00
Process commands from the client .
1996-05-04 07:50:46 +00:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2003-08-06 20:01:31 +00:00
2007-12-06 17:16:33 -08:00
static int process ( const char * base_directory )
1996-05-04 07:50:46 +00:00
{
2001-10-09 19:12:18 +00:00
int rc = 0 ;
2011-07-03 19:59:37 +02:00
NTSTATUS status ;
2020-08-18 16:58:19 +02:00
struct cli_credentials * creds = samba_cmdline_get_creds ( ) ;
2001-10-09 19:12:18 +00:00
2011-07-03 19:59:37 +02:00
status = cli_cm_open ( talloc_tos ( ) , NULL ,
2018-08-23 09:21:41 +02:00
desthost ,
2020-08-18 17:26:54 +02:00
service ,
creds ,
2018-08-23 09:21:41 +02:00
have_ip ? & dest_ss : NULL , port ,
2017-04-25 17:03:10 -07:00
name_type , & cli ) ;
2011-07-03 19:59:37 +02:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
2001-11-02 11:31:49 +00:00
return 1 ;
1996-05-31 15:13:29 +00:00
}
1998-11-12 22:17:51 +00:00
2013-08-16 13:49:39 -07:00
cli_set_timeout ( cli , io_timeout * 1000 ) ;
2007-12-07 14:43:31 -08:00
if ( base_directory & & * base_directory ) {
2005-04-15 00:39:03 +00:00
rc = do_cd ( base_directory ) ;
if ( rc ) {
2009-03-12 17:59:24 -07:00
cli_shutdown ( cli ) ;
2005-04-15 00:39:03 +00:00
return rc ;
}
}
2007-12-06 17:16:33 -08:00
1998-11-09 03:45:49 +00:00
if ( cmdstr ) {
2001-10-09 19:12:18 +00:00
rc = process_command_string ( cmdstr ) ;
1998-11-09 03:45:49 +00:00
} else {
process_stdin ( ) ;
1996-05-04 07:50:46 +00:00
}
2007-12-06 17:16:33 -08:00
2009-03-12 17:59:24 -07:00
cli_shutdown ( cli ) ;
2001-10-09 19:12:18 +00:00
return rc ;
1996-05-04 07:50:46 +00:00
}
1998-11-09 03:45:49 +00:00
/****************************************************************************
2003-08-06 20:01:31 +00:00
Handle a - L query .
1998-11-09 03:45:49 +00:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2003-08-06 20:01:31 +00:00
2007-12-06 17:16:33 -08:00
static int do_host_query ( const char * query_host )
1998-11-09 03:45:49 +00:00
{
2011-07-03 19:59:37 +02:00
NTSTATUS status ;
2020-08-18 16:58:19 +02:00
struct cli_credentials * creds = samba_cmdline_get_creds ( ) ;
2011-07-03 19:59:37 +02:00
status = cli_cm_open ( talloc_tos ( ) , NULL ,
2018-08-23 09:21:41 +02:00
query_host ,
2020-08-18 17:26:54 +02:00
" IPC$ " ,
creds ,
2018-08-23 09:21:41 +02:00
have_ip ? & dest_ss : NULL , port ,
2017-04-25 17:03:10 -07:00
name_type , & cli ) ;
2011-07-03 19:59:37 +02:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
1998-11-17 01:44:25 +00:00
return 1 ;
2011-07-03 19:59:37 +02:00
}
1998-11-09 03:45:49 +00:00
2013-08-16 13:49:39 -07:00
cli_set_timeout ( cli , io_timeout * 1000 ) ;
2007-12-06 17:16:33 -08:00
browse_host ( true ) ;
2003-08-10 21:43:28 +00:00
2009-05-15 16:13:59 -07:00
/* Ensure that the host can do IPv4 */
if ( ! interpret_addr ( query_host ) ) {
struct sockaddr_storage ss ;
if ( interpret_string_addr ( & ss , query_host , 0 ) & &
( ss . ss_family ! = AF_INET ) ) {
d_printf ( " %s is an IPv6 address -- no workgroup available \n " ,
query_host ) ;
return 1 ;
}
2008-04-17 09:24:54 -07:00
}
2017-08-16 08:56:39 +02:00
if ( lp_client_min_protocol ( ) > PROTOCOL_NT1 ) {
d_printf ( " SMB1 disabled -- no workgroup available \n " ) ;
goto out ;
}
2016-11-10 08:27:57 +00:00
if ( lp_disable_netbios ( ) ) {
2017-08-16 08:55:43 +02:00
d_printf ( " NetBIOS over TCP disabled -- no workgroup available \n " ) ;
2016-11-10 08:27:57 +00:00
goto out ;
}
2017-06-19 08:49:05 +02:00
if ( port ! = NBT_SMB_PORT | |
smbXcli_conn_protocol ( cli - > conn ) > PROTOCOL_NT1 )
{
/*
* Workgroups simply don ' t make sense over anything
* else but port 139 and SMB1 .
*/
2003-08-10 21:43:28 +00:00
2009-03-12 17:59:24 -07:00
cli_shutdown ( cli ) ;
2017-08-16 08:55:43 +02:00
d_printf ( " Reconnecting with SMB1 for workgroup listing. \n " ) ;
2022-01-03 16:52:25 -08:00
lp_set_cmdline ( " client max protocol " , " NT1 " ) ;
2011-07-03 19:59:37 +02:00
status = cli_cm_open ( talloc_tos ( ) , NULL ,
2018-08-23 09:21:41 +02:00
query_host ,
2020-08-18 17:26:54 +02:00
" IPC$ " ,
creds ,
2018-08-23 09:21:41 +02:00
have_ip ? & dest_ss : NULL , NBT_SMB_PORT ,
name_type , & cli ) ;
2011-07-03 19:59:37 +02:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
2018-09-03 12:11:39 +02:00
d_printf ( " Unable to connect with SMB1 "
2017-08-16 08:55:43 +02:00
" -- no workgroup available \n " ) ;
return 0 ;
2011-07-03 19:59:37 +02:00
}
2003-08-10 21:43:28 +00:00
}
2013-08-16 13:49:39 -07:00
cli_set_timeout ( cli , io_timeout * 1000 ) ;
2003-04-28 06:54:49 +00:00
list_servers ( lp_workgroup ( ) ) ;
2016-11-10 08:27:57 +00:00
out :
2009-03-12 17:59:24 -07:00
cli_shutdown ( cli ) ;
2007-12-06 17:16:33 -08:00
1998-11-09 03:45:49 +00:00
return ( 0 ) ;
}
/****************************************************************************
2003-08-06 20:01:31 +00:00
Handle a tar operation .
1998-11-09 03:45:49 +00:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2003-08-06 20:01:31 +00:00
2007-12-06 17:16:33 -08:00
static int do_tar_op ( const char * base_directory )
1998-11-09 03:45:49 +00:00
{
2014-02-14 17:16:14 +01:00
struct tar * tar_ctx = tar_get_ctx ( ) ;
2013-07-11 00:57:40 +02:00
int ret = 0 ;
2020-08-18 16:58:19 +02:00
struct cli_credentials * creds = samba_cmdline_get_creds ( ) ;
2002-07-15 10:35:28 +00:00
/* do we already have a connection? */
if ( ! cli ) {
2011-07-03 19:59:37 +02:00
NTSTATUS status ;
status = cli_cm_open ( talloc_tos ( ) , NULL ,
2018-08-23 09:21:41 +02:00
desthost ,
2020-08-18 17:26:54 +02:00
service ,
creds ,
2018-08-23 09:21:41 +02:00
have_ip ? & dest_ss : NULL , port ,
name_type , & cli ) ;
2011-07-03 19:59:37 +02:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
2013-07-11 00:57:40 +02:00
ret = 1 ;
goto out ;
2011-07-03 19:59:37 +02:00
}
2013-08-16 13:49:39 -07:00
cli_set_timeout ( cli , io_timeout * 1000 ) ;
2002-07-15 10:35:28 +00:00
}
1998-11-09 03:45:49 +00:00
2013-07-11 00:57:40 +02:00
recurse = true ;
1998-11-09 03:45:49 +00:00
2007-12-07 14:43:31 -08:00
if ( base_directory & & * base_directory ) {
2005-04-15 00:39:03 +00:00
ret = do_cd ( base_directory ) ;
if ( ret ) {
2013-07-11 00:57:40 +02:00
goto out_cli ;
2005-04-15 00:39:03 +00:00
}
}
2007-12-06 17:16:33 -08:00
2014-02-14 17:16:14 +01:00
ret = tar_process ( tar_ctx ) ;
1998-11-09 03:45:49 +00:00
2013-07-11 00:57:40 +02:00
out_cli :
2009-03-12 17:59:24 -07:00
cli_shutdown ( cli ) ;
2013-07-11 00:57:40 +02:00
out :
return ret ;
1998-11-09 03:45:49 +00:00
}
/****************************************************************************
2003-08-06 20:01:31 +00:00
Handle a message operation .
1998-11-09 03:45:49 +00:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2003-08-06 20:01:31 +00:00
2020-08-18 16:58:19 +02:00
static int do_message_op ( struct cli_credentials * creds )
1998-11-09 03:45:49 +00:00
{
2007-06-20 17:38:42 +00:00
NTSTATUS status ;
1998-11-09 03:45:49 +00:00
2016-11-10 08:27:57 +00:00
if ( lp_disable_netbios ( ) ) {
d_printf ( " NetBIOS over TCP disabled. \n " ) ;
return 1 ;
}
2011-05-29 00:59:12 +02:00
status = cli_connect_nb ( desthost , have_ip ? & dest_ss : NULL ,
2012-02-14 21:51:35 -06:00
port ? port : NBT_SMB_PORT , name_type ,
2020-05-28 18:11:31 +02:00
lp_netbios_name ( ) ,
SMB_SIGNING_OFF ,
0 ,
& cli ) ;
2007-06-20 17:38:42 +00:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
d_printf ( " Connection to %s failed. Error %s \n " , desthost , nt_errstr ( status ) ) ;
return 1 ;
1998-11-09 03:45:49 +00:00
}
2013-08-16 13:49:39 -07:00
cli_set_timeout ( cli , io_timeout * 1000 ) ;
2020-08-18 16:58:19 +02:00
send_message ( cli_credentials_get_username ( creds ) ) ;
2009-03-12 17:59:24 -07:00
cli_shutdown ( cli ) ;
1998-11-09 03:45:49 +00:00
return 0 ;
}
1996-05-04 07:50:46 +00:00
/****************************************************************************
main program
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2003-08-06 20:01:31 +00:00
2013-07-09 15:10:44 +02:00
int main ( int argc , char * argv [ ] )
1996-05-04 07:50:46 +00:00
{
2013-08-14 10:47:11 +02:00
const char * * const_argv = discard_const_p ( const char * , argv ) ;
2007-12-06 17:16:33 -08:00
char * base_directory = NULL ;
1998-11-09 03:45:49 +00:00
int opt ;
2007-12-06 17:16:33 -08:00
char * query_host = NULL ;
bool message = false ;
2003-04-14 04:05:48 +00:00
static const char * new_name_resolve_order = NULL ;
poptContext pc ;
1998-11-09 03:45:49 +00:00
char * p ;
2001-10-09 19:12:18 +00:00
int rc = 0 ;
2007-12-06 17:16:33 -08:00
bool tar_opt = false ;
bool service_opt = false ;
2014-02-14 17:16:14 +01:00
struct tar * tar_ctx = tar_get_ctx ( ) ;
2020-08-18 16:58:19 +02:00
bool ok ;
2013-07-09 15:10:44 +02:00
2003-04-14 04:05:48 +00:00
struct poptOption long_options [ ] = {
POPT_AUTOHELP
2019-01-08 12:18:23 +01:00
{
. longName = " message " ,
. shortName = ' M ' ,
. argInfo = POPT_ARG_STRING ,
. arg = NULL ,
. val = ' M ' ,
. descrip = " Send message " ,
. argDescrip = " HOST " ,
} ,
{
. longName = " ip-address " ,
. shortName = ' I ' ,
. argInfo = POPT_ARG_STRING ,
. arg = NULL ,
. val = ' I ' ,
. descrip = " Use this IP to connect to " ,
. argDescrip = " IP " ,
} ,
{
. longName = " stderr " ,
. shortName = ' E ' ,
. argInfo = POPT_ARG_NONE ,
. arg = NULL ,
. val = ' E ' ,
. descrip = " Write messages to stderr instead of stdout " ,
} ,
{
. longName = " list " ,
. shortName = ' L ' ,
. argInfo = POPT_ARG_STRING ,
. arg = NULL ,
. val = ' L ' ,
. descrip = " Get a list of shares available on a host " ,
. argDescrip = " HOST " ,
} ,
{
. longName = " tar " ,
. shortName = ' T ' ,
. argInfo = POPT_ARG_STRING ,
. arg = NULL ,
. val = ' T ' ,
. descrip = " Command line tar " ,
2020-01-04 21:47:59 +01:00
. argDescrip = " <c|x>IXFvgbNan " ,
2019-01-08 12:18:23 +01:00
} ,
{
. longName = " directory " ,
. shortName = ' D ' ,
. argInfo = POPT_ARG_STRING ,
. arg = NULL ,
. val = ' D ' ,
. descrip = " Start from directory " ,
. argDescrip = " DIR " ,
} ,
{
. longName = " command " ,
. shortName = ' c ' ,
. argInfo = POPT_ARG_STRING ,
. arg = & cmdstr ,
. val = ' c ' ,
. descrip = " Execute semicolon separated commands " ,
} ,
{
. longName = " send-buffer " ,
. shortName = ' b ' ,
. argInfo = POPT_ARG_INT ,
. arg = & io_bufsize ,
. val = ' b ' ,
. descrip = " Changes the transmit/send buffer " ,
. argDescrip = " BYTES " ,
} ,
{
. longName = " timeout " ,
. shortName = ' t ' ,
. argInfo = POPT_ARG_INT ,
. arg = & io_timeout ,
. val = ' b ' ,
. descrip = " Changes the per-operation timeout " ,
. argDescrip = " SECONDS " ,
} ,
{
. longName = " port " ,
. shortName = ' p ' ,
. argInfo = POPT_ARG_INT ,
. arg = & port ,
. val = ' p ' ,
. descrip = " Port to connect to " ,
. argDescrip = " PORT " ,
} ,
{
. longName = " grepable " ,
. shortName = ' g ' ,
. argInfo = POPT_ARG_NONE ,
. arg = NULL ,
. val = ' g ' ,
. descrip = " Produce grepable output " ,
} ,
{
. longName = " quiet " ,
. shortName = ' q ' ,
. argInfo = POPT_ARG_NONE ,
. arg = NULL ,
. val = ' q ' ,
. descrip = " Suppress help message " ,
} ,
{
. longName = " browse " ,
. shortName = ' B ' ,
. argInfo = POPT_ARG_NONE ,
. arg = NULL ,
. val = ' B ' ,
. descrip = " Browse SMB servers using DNS " ,
} ,
2003-04-14 04:05:48 +00:00
POPT_COMMON_SAMBA
POPT_COMMON_CONNECTION
POPT_COMMON_CREDENTIALS
2020-08-18 16:58:19 +02:00
POPT_LEGACY_S3
POPT_COMMON_VERSION
2003-04-14 04:05:48 +00:00
POPT_TABLEEND
} ;
2007-11-15 14:19:52 -08:00
TALLOC_CTX * frame = talloc_stackframe ( ) ;
2020-08-18 16:58:19 +02:00
struct cli_credentials * creds = NULL ;
2007-11-29 17:25:41 -08:00
2007-12-06 17:16:33 -08:00
if ( ! client_set_cur_dir ( " \\ " ) ) {
exit ( ENOMEM ) ;
}
1997-09-11 20:17:32 +00:00
2015-03-21 20:00:06 +01:00
smb_init_locale ( ) ;
2007-12-09 13:22:19 -08:00
2020-08-18 16:58:19 +02:00
ok = samba_cmdline_init ( frame ,
SAMBA_CMDLINE_CONFIG_CLIENT ,
false /* require_smbconf */ ) ;
if ( ! ok ) {
DBG_ERR ( " Failed to init cmdline parser! \n " ) ;
exit ( ENOMEM ) ;
}
2010-10-29 21:10:31 +11:00
lp_set_cmdline ( " log level " , " 1 " ) ;
2007-03-28 14:16:34 +00:00
/* skip argv(0) */
2020-11-11 09:56:41 +01:00
pc = samba_popt_get_context ( getprogname ( ) ,
argc ,
const_argv ,
long_options ,
0 ) ;
if ( pc = = NULL ) {
DBG_ERR ( " Failed to setup popt context! \n " ) ;
exit ( 1 ) ;
}
2020-08-18 16:58:19 +02:00
poptSetOtherOptionHelp ( pc , " [OPTIONS] service <password> " ) ;
1998-09-29 04:43:40 +00:00
2020-08-18 16:58:19 +02:00
creds = samba_cmdline_get_creds ( ) ;
2003-04-14 04:05:48 +00:00
while ( ( opt = poptGetNextOpt ( pc ) ) ! = - 1 ) {
2007-03-28 14:16:34 +00:00
2020-01-15 13:11:20 +01:00
/*
* if the tar option has been called previously , now
* we need to eat out the leftovers
*/
2007-03-28 14:16:34 +00:00
/* I see no other way to keep things sane --SSS */
2007-12-06 17:16:33 -08:00
if ( tar_opt = = true ) {
2007-03-28 14:16:34 +00:00
while ( poptPeekArg ( pc ) ) {
poptGetArg ( pc ) ;
}
2007-12-06 17:16:33 -08:00
tar_opt = false ;
2007-03-28 14:16:34 +00:00
}
/* if the service has not yet been specified lets see if it is available in the popt stack */
if ( ! service_opt & & poptPeekArg ( pc ) ) {
2007-12-06 17:16:33 -08:00
service = talloc_strdup ( frame , poptGetArg ( pc ) ) ;
if ( ! service ) {
exit ( ENOMEM ) ;
}
service_opt = true ;
2007-03-28 14:16:34 +00:00
}
/* if the service has already been retrieved then check if we have also a password */
2020-08-18 16:58:19 +02:00
if ( service_opt & &
cli_credentials_get_password ( creds ) = = NULL & &
poptPeekArg ( pc ) ) {
cli_credentials_set_password ( creds ,
poptGetArg ( pc ) ,
CRED_SPECIFIED ) ;
2007-03-28 14:16:34 +00:00
}
2007-12-06 17:16:33 -08:00
2012-11-06 09:27:43 +01:00
1998-11-09 03:45:49 +00:00
switch ( opt ) {
case ' M ' :
2003-01-07 04:26:37 +00:00
/* Messages are sent to NetBIOS name type 0x3
* ( Messenger Service ) . Make sure we default
* to port 139 instead of port 445. srl , crh
*/
2007-12-06 17:16:33 -08:00
name_type = 0x03 ;
desthost = talloc_strdup ( frame , poptGetOptArg ( pc ) ) ;
if ( ! desthost ) {
exit ( ENOMEM ) ;
}
2005-02-24 21:54:52 +00:00
if ( ! port )
2012-02-14 21:51:35 -06:00
port = NBT_SMB_PORT ;
2007-12-06 17:16:33 -08:00
message = true ;
2003-01-14 08:53:59 +00:00
break ;
1998-11-09 03:45:49 +00:00
case ' I ' :
1998-10-29 02:18:17 +00:00
{
2007-10-24 14:16:54 -07:00
if ( ! interpret_string_addr ( & dest_ss , poptGetOptArg ( pc ) , 0 ) ) {
1998-11-09 03:45:49 +00:00
exit ( 1 ) ;
2007-10-24 14:16:54 -07:00
}
2007-12-06 17:16:33 -08:00
have_ip = true ;
2009-01-02 12:49:49 -08:00
print_sockaddr ( dest_ss_str , sizeof ( dest_ss_str ) , & dest_ss ) ;
1998-10-29 02:18:17 +00:00
}
1998-11-09 03:45:49 +00:00
break ;
2022-05-23 17:23:41 +01:00
case ' E ' :
setup_logging ( " smbclient " , DEBUG_STDERR ) ;
display_set_stderr ( ) ;
break ;
1998-11-09 03:45:49 +00:00
case ' L ' :
2007-12-06 17:16:33 -08:00
query_host = talloc_strdup ( frame , poptGetOptArg ( pc ) ) ;
if ( ! query_host ) {
exit ( ENOMEM ) ;
}
1998-11-09 03:45:49 +00:00
break ;
case ' T ' :
2003-08-01 21:09:10 +00:00
/* We must use old option processing for this. Find the
* position of the - T option in the raw argv [ ] . */
{
2007-04-10 18:21:37 +00:00
int i ;
2013-07-08 18:09:47 +02:00
2003-08-01 21:09:10 +00:00
for ( i = 1 ; i < argc ; i + + ) {
if ( strncmp ( " -T " , argv [ i ] , 2 ) = = 0 )
break ;
}
i + + ;
2014-02-14 17:16:14 +01:00
if ( tar_parse_args ( tar_ctx , poptGetOptArg ( pc ) ,
2014-02-14 18:08:28 +01:00
const_argv + i , argc - i ) ) {
2003-08-01 21:09:10 +00:00
poptPrintUsage ( pc , stderr , 0 ) ;
exit ( 1 ) ;
}
1998-11-09 03:45:49 +00:00
}
2007-03-28 14:16:34 +00:00
/* this must be the last option, mark we have parsed it so that we know we have */
2007-12-06 17:16:33 -08:00
tar_opt = true ;
1998-11-09 03:45:49 +00:00
break ;
case ' D ' :
2007-12-06 17:16:33 -08:00
base_directory = talloc_strdup ( frame , poptGetOptArg ( pc ) ) ;
if ( ! base_directory ) {
exit ( ENOMEM ) ;
}
1998-11-09 03:45:49 +00:00
break ;
2004-01-16 15:01:09 +00:00
case ' g ' :
2007-12-06 17:16:33 -08:00
grepable = true ;
2004-01-16 15:01:09 +00:00
break ;
2018-06-25 09:58:56 -04:00
case ' q ' :
quiet = true ;
break ;
2007-12-17 22:09:09 -08:00
case ' B ' :
return ( do_smb_browse ( ) ) ;
2021-09-09 16:45:37 +02:00
case POPT_ERROR_BADOPT :
fprintf ( stderr , " \n Invalid option %s: %s \n \n " ,
poptBadOption ( pc , 0 ) , poptStrerror ( opt ) ) ;
poptPrintUsage ( pc , stderr , 0 ) ;
exit ( 1 ) ;
2003-04-14 04:05:48 +00:00
}
}
2007-03-28 14:16:34 +00:00
/* We may still have some leftovers after the last popt option has been called */
2007-12-06 17:16:33 -08:00
if ( tar_opt = = true ) {
2007-03-28 14:16:34 +00:00
while ( poptPeekArg ( pc ) ) {
poptGetArg ( pc ) ;
}
2007-12-06 17:16:33 -08:00
tar_opt = false ;
2007-03-28 14:16:34 +00:00
}
/* if the service has not yet been specified lets see if it is available in the popt stack */
if ( ! service_opt & & poptPeekArg ( pc ) ) {
2007-12-06 17:16:33 -08:00
service = talloc_strdup ( frame , poptGetArg ( pc ) ) ;
if ( ! service ) {
exit ( ENOMEM ) ;
}
service_opt = true ;
2007-03-28 14:16:34 +00:00
}
2005-02-24 21:54:52 +00:00
2007-03-28 14:16:34 +00:00
/* if the service has already been retrieved then check if we have also a password */
2020-08-18 16:58:19 +02:00
if ( service_opt & &
cli_credentials_get_password ( creds ) = = NULL & &
poptPeekArg ( pc ) ) {
cli_credentials_set_password ( creds ,
poptGetArg ( pc ) ,
CRED_SPECIFIED ) ;
2007-03-28 14:16:34 +00:00
}
2007-12-06 17:16:33 -08:00
2007-12-07 14:43:31 -08:00
if ( service_opt & & service ) {
2007-12-06 17:16:33 -08:00
size_t len ;
2007-06-21 17:05:59 +00:00
/* Convert any '/' characters in the service name to '\' characters */
string_replace ( service , ' / ' , ' \\ ' ) ;
if ( count_chars ( service , ' \\ ' ) < 3 ) {
d_printf ( " \n %s: Not enough ' \\ ' characters in service \n " , service ) ;
poptPrintUsage ( pc , stderr , 0 ) ;
exit ( 1 ) ;
}
2007-12-06 12:29:52 +01:00
/* Remove trailing slashes */
len = strlen ( service ) ;
while ( len > 0 & & service [ len - 1 ] = = ' \\ ' ) {
- - len ;
service [ len ] = ' \0 ' ;
}
2007-06-21 17:05:59 +00:00
}
2007-12-06 17:16:33 -08:00
2003-04-14 04:05:48 +00:00
if ( new_name_resolve_order )
2012-07-18 15:19:15 +10:00
lp_set_cmdline ( " name resolve order " , new_name_resolve_order ) ;
1998-09-18 12:47:46 +00:00
2014-02-14 17:16:14 +01:00
if ( ! tar_to_process ( tar_ctx ) & & ! query_host & & ! service & & ! message ) {
2003-04-14 04:05:48 +00:00
poptPrintUsage ( pc , stderr , 0 ) ;
1998-11-09 03:45:49 +00:00
exit ( 1 ) ;
}
1996-05-04 07:50:46 +00:00
2003-04-14 04:05:48 +00:00
poptFreeContext ( pc ) ;
2020-08-18 16:58:19 +02:00
samba_cmdline_burn ( argc , argv ) ;
2003-04-14 04:05:48 +00:00
2009-01-15 22:27:52 +01:00
DEBUG ( 3 , ( " Client started (version %s). \n " , samba_version_string ( ) ) ) ;
1996-05-04 07:50:46 +00:00
2014-02-14 17:16:14 +01:00
if ( tar_to_process ( tar_ctx ) ) {
2000-11-22 23:06:29 +00:00
if ( cmdstr )
process_command_string ( cmdstr ) ;
2012-07-18 04:59:31 +09:30
rc = do_tar_op ( base_directory ) ;
} else if ( query_host & & * query_host ) {
2004-03-11 14:39:32 +00:00
char * qhost = query_host ;
char * slash ;
while ( * qhost = = ' \\ ' | | * qhost = = ' / ' )
qhost + + ;
if ( ( slash = strchr_m ( qhost , ' / ' ) )
| | ( slash = strchr_m ( qhost , ' \\ ' ) ) ) {
* slash = 0 ;
}
if ( ( p = strchr_m ( qhost , ' # ' ) ) ) {
* p = 0 ;
p + + ;
sscanf ( p , " %x " , & name_type ) ;
}
2005-02-24 21:54:52 +00:00
2012-07-18 04:59:31 +09:30
rc = do_host_query ( qhost ) ;
} else if ( message ) {
2020-08-18 16:58:19 +02:00
rc = do_message_op ( creds ) ;
2012-07-18 04:59:31 +09:30
} else if ( process ( base_directory ) ) {
rc = 1 ;
1996-05-04 07:50:46 +00:00
}
2007-12-06 17:16:33 -08:00
TALLOC_FREE ( frame ) ;
2001-10-09 19:12:18 +00:00
return rc ;
1996-05-04 07:50:46 +00:00
}