2000-12-26 05:57:10 +00:00
/*
2002-07-15 10:35:28 +00:00
Unix SMB / Netbios implementation .
2000-12-26 05:57:10 +00:00
SMB client library implementation
Copyright ( C ) Andrew Tridgell 1998
2002-07-15 10:35:28 +00:00
Copyright ( C ) Richard Sharpe 2000 , 2002
2000-12-26 05:57:10 +00:00
Copyright ( C ) John Terpstra 2000
2002-07-15 10:35:28 +00:00
Copyright ( C ) Tom Jansen ( Ninja ISD ) 2002
2005-03-10 23:41:19 +00:00
Copyright ( C ) Derrell Lipman 2003 , 2004
2000-12-26 05:57:10 +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
2000-12-26 05:57:10 +00:00
( at your option ) any later version .
This program is distributed in the hope that it will be useful ,
but WITHOUT ANY WARRANTY ; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
GNU General Public License for more details .
You should have received a copy of the GNU General Public License
2007-07-10 00:52:41 +00:00
along with this program . If not , see < http : //www.gnu.org/licenses/>.
2000-12-26 05:57:10 +00:00
*/
# include "includes.h"
2002-07-15 10:35:28 +00:00
2004-10-07 04:01:18 +00:00
# include "include/libsmb_internal.h"
2000-12-26 05:57:10 +00:00
2006-12-20 01:10:04 +00:00
struct smbc_dirent * smbc_readdir_ctx ( SMBCCTX * context , SMBCFILE * dir ) ;
struct smbc_dir_list * smbc_check_dir_ent ( struct smbc_dir_list * list ,
struct smbc_dirent * dirent ) ;
2005-03-10 23:41:19 +00:00
/*
* DOS Attribute values ( used internally )
*/
2005-10-21 22:48:27 +00:00
typedef struct DOS_ATTR_DESC {
int mode ;
SMB_OFF_T size ;
r18009: Fixes bug 4026.
This completes the work Jeremy began last week, disambiguating the meaning of
c_time. (In POSIX terminology, c_time means "status Change time", not "create
time".) All uses of c_time, a_time and m_time have now been replaced with
change_time, access_time, and write_time, and when creation time is intended,
create_time is used.
Additionally, the capability of setting and retrieving the create time have
been added to the smbc_setxattr() and smbc_getxattr() functions. An example
of setting all four times can be seen with the program
examples/libsmbclient/testacl
with the following command line similar to:
testacl -f -S "system.*:CREATE_TIME:1000000000,ACCESS_TIME:1000000060,WRITE_TIME:1000000120,CHANGE_TIME:1000000180" 'smb://server/share/testfile.txt'
The -f option turns on the new mode which uses full time names in the
attribute specification (e.g. ACCESS_TIME vs A_TIME).
(This used to be commit 8e119b64f1d92026dda855d904be09912a40601c)
2006-09-02 21:47:56 +00:00
time_t create_time ;
time_t access_time ;
time_t write_time ;
time_t change_time ;
2005-10-21 22:48:27 +00:00
SMB_INO_T inode ;
2005-03-10 23:41:19 +00:00
} DOS_ATTR_DESC ;
2003-10-24 17:01:19 +00:00
/*
* Internal flags for extended attributes
*/
/* internal mode values */
# define SMBC_XATTR_MODE_ADD 1
# define SMBC_XATTR_MODE_REMOVE 2
# define SMBC_XATTR_MODE_REMOVE_ALL 3
# define SMBC_XATTR_MODE_SET 4
# define SMBC_XATTR_MODE_CHOWN 5
# define SMBC_XATTR_MODE_CHGRP 6
# define CREATE_ACCESS_READ READ_CONTROL_ACCESS
2003-10-25 04:13:32 +00:00
/*We should test for this in configure ... */
# ifndef ENOTSUP
# define ENOTSUP EOPNOTSUPP
# endif
2003-10-24 17:01:19 +00:00
2002-07-15 10:35:28 +00:00
/*
* Functions exported by libsmb_cache . c that we need here
2000-12-26 05:57:10 +00:00
*/
2002-07-15 10:35:28 +00:00
int smbc_default_cache_functions ( SMBCCTX * context ) ;
2000-12-26 05:57:10 +00:00
2002-07-15 10:35:28 +00:00
/*
* check if an element is part of the list .
* FIXME : Does not belong here !
* Can anyone put this in a macro in dlinklist . h ?
* - - Tom
*/
static int DLIST_CONTAINS ( SMBCFILE * list , SMBCFILE * p ) {
if ( ! p | | ! list ) return False ;
do {
if ( p = = list ) return True ;
list = list - > next ;
} while ( list ) ;
return False ;
}
2001-02-26 11:53:22 +00:00
2005-09-30 17:13:37 +00:00
/*
* Find an lsa pipe handle associated with a cli struct .
*/
2005-12-29 15:06:53 +00:00
static struct rpc_pipe_client *
find_lsa_pipe_hnd ( struct cli_state * ipc_cli )
2005-09-30 17:13:37 +00:00
{
struct rpc_pipe_client * pipe_hnd ;
2005-12-29 15:06:53 +00:00
for ( pipe_hnd = ipc_cli - > pipe_list ;
pipe_hnd ;
pipe_hnd = pipe_hnd - > next ) {
2005-09-30 17:13:37 +00:00
if ( pipe_hnd - > pipe_idx = = PI_LSARPC ) {
return pipe_hnd ;
}
}
return NULL ;
}
2005-12-29 15:06:53 +00:00
static int
smbc_close_ctx ( SMBCCTX * context ,
SMBCFILE * file ) ;
static off_t
smbc_lseek_ctx ( SMBCCTX * context ,
SMBCFILE * file ,
off_t offset ,
int whence ) ;
2005-03-28 19:52:23 +00:00
2007-10-18 17:40:25 -07:00
extern bool in_client ;
2002-07-15 10:35:28 +00:00
/*
* Is the logging working / configfile read ?
*/
2000-12-26 05:57:10 +00:00
static int smbc_initialized = 0 ;
2003-04-16 14:45:11 +00:00
static int
hex2int ( unsigned int _char )
{
if ( _char > = ' A ' & & _char < = ' F ' )
return _char - ' A ' + 10 ;
if ( _char > = ' a ' & & _char < = ' f ' )
return _char - ' a ' + 10 ;
if ( _char > = ' 0 ' & & _char < = ' 9 ' )
return _char - ' 0 ' ;
return - 1 ;
}
2005-03-10 23:41:19 +00:00
/*
* smbc_urldecode ( )
2007-11-30 13:09:04 -08:00
* and smbc_urldecode_talloc ( ) ( internal fn . )
2005-03-10 23:41:19 +00:00
*
* Convert strings of % xx to their single character equivalent . Each ' x ' must
* be a valid hexadecimal digit , or that % sequence is left undecoded .
*
* dest may , but need not be , the same pointer as src .
*
* Returns the number of % sequences which could not be converted due to lack
* of two following hexadecimal digits .
*/
2007-11-30 13:09:04 -08:00
static int
smbc_urldecode_talloc ( TALLOC_CTX * ctx , char * * pp_dest , const char * src )
2003-04-16 14:45:11 +00:00
{
2007-11-30 13:09:04 -08:00
int old_length = strlen ( src ) ;
int i = 0 ;
int err_count = 0 ;
size_t newlen = 1 ;
char * p , * dest ;
if ( old_length = = 0 ) {
return 0 ;
}
2003-04-16 14:45:11 +00:00
2007-11-30 14:19:55 -08:00
* pp_dest = NULL ;
2007-11-30 13:09:04 -08:00
for ( i = 0 ; i < old_length ; ) {
unsigned char character = src [ i + + ] ;
if ( character = = ' % ' ) {
int a = i + 1 < old_length ? hex2int ( src [ i ] ) : - 1 ;
int b = i + 1 < old_length ? hex2int ( src [ i + 1 ] ) : - 1 ;
2005-03-10 23:41:19 +00:00
2007-11-30 13:09:04 -08:00
/* Replace valid sequence */
if ( a ! = - 1 & & b ! = - 1 ) {
/* Replace valid %xx sequence with %dd */
character = ( a * 16 ) + b ;
if ( character = = ' \0 ' ) {
break ; /* Stop at %00 */
}
i + = 2 ;
} else {
err_count + + ;
}
}
newlen + + ;
}
dest = TALLOC_ARRAY ( ctx , char , newlen ) ;
if ( ! dest ) {
return err_count ;
}
err_count = 0 ;
for ( p = dest , i = 0 ; i < old_length ; ) {
unsigned char character = src [ i + + ] ;
2003-04-16 14:45:11 +00:00
2005-03-10 23:41:19 +00:00
if ( character = = ' % ' ) {
2007-11-30 13:09:04 -08:00
int a = i + 1 < old_length ? hex2int ( src [ i ] ) : - 1 ;
int b = i + 1 < old_length ? hex2int ( src [ i + 1 ] ) : - 1 ;
2003-04-16 14:45:11 +00:00
2005-03-10 23:41:19 +00:00
/* Replace valid sequence */
if ( a ! = - 1 & & b ! = - 1 ) {
/* Replace valid %xx sequence with %dd */
character = ( a * 16 ) + b ;
if ( character = = ' \0 ' ) {
break ; /* Stop at %00 */
}
i + = 2 ;
} else {
err_count + + ;
}
}
* p + + = character ;
}
* p = ' \0 ' ;
2007-11-30 13:09:04 -08:00
* pp_dest = dest ;
return err_count ;
}
2005-03-10 23:41:19 +00:00
2007-11-30 13:09:04 -08:00
int
smbc_urldecode ( char * dest , char * src , size_t max_dest_len )
{
TALLOC_CTX * frame = talloc_stackframe ( ) ;
char * pdest ;
int ret = smbc_urldecode_talloc ( frame , & pdest , src ) ;
2005-03-10 23:41:19 +00:00
2007-11-30 13:09:04 -08:00
if ( pdest ) {
strlcpy ( dest , pdest , max_dest_len ) ;
}
TALLOC_FREE ( frame ) ;
return ret ;
2005-03-10 23:41:19 +00:00
}
/*
* smbc_urlencode ( )
*
* Convert any characters not specifically allowed in a URL into their % xx
* equivalent .
*
* Returns the remaining buffer length .
*/
int
2007-11-30 13:09:04 -08:00
smbc_urlencode ( char * dest , char * src , int max_dest_len )
2005-03-10 23:41:19 +00:00
{
char hex [ ] = " 0123456789ABCDEF " ;
for ( ; * src ! = ' \0 ' & & max_dest_len > = 3 ; src + + ) {
if ( ( * src < ' 0 ' & &
* src ! = ' - ' & &
* src ! = ' . ' ) | |
( * src > ' 9 ' & &
* src < ' A ' ) | |
( * src > ' Z ' & &
* src < ' a ' & &
* src ! = ' _ ' ) | |
( * src > ' z ' ) ) {
* dest + + = ' % ' ;
* dest + + = hex [ ( * src > > 4 ) & 0x0f ] ;
* dest + + = hex [ * src & 0x0f ] ;
max_dest_len - = 3 ;
} else {
* dest + + = * src ;
max_dest_len - - ;
}
}
2003-04-16 14:45:11 +00:00
2005-03-10 23:41:19 +00:00
* dest + + = ' \0 ' ;
max_dest_len - - ;
2007-11-30 13:09:04 -08:00
2005-03-10 23:41:19 +00:00
return max_dest_len ;
2003-04-16 14:45:11 +00:00
}
2000-12-26 05:57:10 +00:00
/*
* Function to parse a path and turn it into components
*
2004-03-19 16:22:47 +00:00
* The general format of an SMB URI is explain in Christopher Hertel ' s CIFS
* book , at http : //ubiqx.org/cifs/Appendix-D.html. We accept a subset of the
2005-03-10 23:41:19 +00:00
* general format ( " smb: " only ; we do not look for " cifs: " ) .
2004-03-19 16:22:47 +00:00
*
*
* We accept :
2006-06-27 02:30:58 +00:00
* smb : //[[[domain;]user[:password]@]server[/share[/path[/file]]]][?options]
2004-03-19 16:22:47 +00:00
*
* Meaning of URLs :
*
2005-03-10 23:41:19 +00:00
* smb : // Show all workgroups.
2004-03-19 16:22:47 +00:00
*
2005-03-10 23:41:19 +00:00
* The method of locating the list of workgroups varies
* depending upon the setting of the context variable
* context - > options . browse_max_lmb_count . This value
* determine the maximum number of local master browsers to
* query for the list of workgroups . In order to ensure that
* a complete list of workgroups is obtained , all master
* browsers must be queried , but if there are many
* workgroups , the time spent querying can begin to add up .
* For small networks ( not many workgroups ) , it is suggested
* that this variable be set to 0 , indicating query all local
* master browsers . When the network has many workgroups , a
* reasonable setting for this variable might be around 3.
2004-03-19 16:22:47 +00:00
*
* smb : //name/ if name<1D> or name<1B> exists, list servers in
* workgroup , else , if name < 20 > exists , list all shares
* for server . . .
*
2005-03-10 23:41:19 +00:00
* If " options " are provided , this function returns the entire option list as a
* string , for later parsing by the caller . Note that currently , no options
* are supported .
2000-12-26 05:57:10 +00:00
*/
static const char * smbc_prefix = " smb: " ;
static int
2007-11-30 13:09:04 -08:00
smbc_parse_path ( TALLOC_CTX * ctx ,
SMBCCTX * context ,
2004-03-19 16:22:47 +00:00
const char * fname ,
2007-11-30 13:09:04 -08:00
char * * pp_workgroup ,
char * * pp_server ,
char * * pp_share ,
char * * pp_path ,
char * * pp_user ,
char * * pp_password ,
char * * pp_options )
2000-12-26 05:57:10 +00:00
{
2007-11-30 13:09:04 -08:00
char * s ;
2003-01-13 20:04:40 +00:00
const char * p ;
2001-11-21 03:55:59 +00:00
char * q , * r ;
int len ;
2000-12-26 05:57:10 +00:00
2007-11-30 13:09:04 -08:00
/* Ensure these returns are at least valid pointers. */
* pp_server = talloc_strdup ( ctx , " " ) ;
* pp_share = talloc_strdup ( ctx , " " ) ;
* pp_path = talloc_strdup ( ctx , " " ) ;
* pp_user = talloc_strdup ( ctx , " " ) ;
* pp_password = talloc_strdup ( ctx , " " ) ;
if ( ! * pp_server | | ! * pp_share | | ! * pp_path | |
! * pp_user | | ! * pp_password ) {
return - 1 ;
}
2006-01-29 00:11:34 +00:00
/*
* Assume we wont find an authentication domain to parse , so default
* to the workgroup in the provided context .
*/
2007-11-30 13:09:04 -08:00
if ( pp_workgroup ! = NULL ) {
* pp_workgroup = talloc_strdup ( ctx , context - > workgroup ) ;
}
2006-01-29 00:11:34 +00:00
2007-11-30 13:09:04 -08:00
if ( pp_options ) {
* pp_options = talloc_strdup ( ctx , " " ) ;
}
s = talloc_strdup ( ctx , fname ) ;
2000-12-26 05:57:10 +00:00
2001-11-21 03:55:59 +00:00
/* see if it has the right prefix */
len = strlen ( smbc_prefix ) ;
2003-10-24 17:01:19 +00:00
if ( strncmp ( s , smbc_prefix , len ) | | ( s [ len ] ! = ' / ' & & s [ len ] ! = 0 ) ) {
return - 1 ; /* What about no smb: ? */
}
2000-12-26 05:57:10 +00:00
2001-11-21 03:55:59 +00:00
p = s + len ;
2000-12-26 05:57:10 +00:00
2001-11-21 03:55:59 +00:00
/* Watch the test below, we are testing to see if we should exit */
2000-12-26 05:57:10 +00:00
2001-11-21 03:55:59 +00:00
if ( strncmp ( p , " // " , 2 ) & & strncmp ( p , " \\ \\ " , 2 ) ) {
2004-03-19 16:22:47 +00:00
DEBUG ( 1 , ( " Invalid path (does not begin with smb:// " ) ) ;
2001-11-21 03:55:59 +00:00
return - 1 ;
}
2001-01-05 13:43:19 +00:00
2004-03-19 16:22:47 +00:00
p + = 2 ; /* Skip the double slash */
/* See if any options were specified */
2005-03-10 23:41:19 +00:00
if ( ( q = strrchr ( p , ' ? ' ) ) ! = NULL ) {
2004-03-19 16:22:47 +00:00
/* There are options. Null terminate here and point to them */
* q + + = ' \0 ' ;
2007-11-30 13:09:04 -08:00
2004-03-19 16:22:47 +00:00
DEBUG ( 4 , ( " Found options '%s' " , q ) ) ;
2007-11-30 13:09:04 -08:00
/* Copy the options */
if ( * pp_options ! = NULL ) {
TALLOC_FREE ( * pp_options ) ;
* pp_options = talloc_strdup ( ctx , q ) ;
}
}
2000-12-26 05:57:10 +00:00
2007-11-30 13:09:04 -08:00
if ( * p = = ' \0 ' ) {
goto decoding ;
}
2001-01-06 12:15:46 +00:00
2001-11-21 03:55:59 +00:00
if ( * p = = ' / ' ) {
2007-02-08 14:55:21 +00:00
int wl = strlen ( context - > workgroup ) ;
2001-01-06 12:15:46 +00:00
2007-02-08 14:55:21 +00:00
if ( wl > 16 ) {
wl = 16 ;
}
2007-11-30 13:09:04 -08:00
* pp_server = talloc_strdup ( ctx , context - > workgroup ) ;
if ( ! * pp_server ) {
return - 1 ;
}
* pp_server [ wl ] = ' \0 ' ;
2001-11-21 03:55:59 +00:00
return 0 ;
}
2001-01-06 12:15:46 +00:00
2001-11-21 03:55:59 +00:00
/*
2007-11-30 13:09:04 -08:00
* ok , its for us . Now parse out the server , share etc .
2001-11-21 03:55:59 +00:00
*
* However , we want to parse out [ [ domain ; ] user [ : password ] @ ] if it
* exists . . .
*/
2001-01-29 09:34:24 +00:00
2001-11-21 03:55:59 +00:00
/* check that '@' occurs before '/', if '/' exists at all */
q = strchr_m ( p , ' @ ' ) ;
r = strchr_m ( p , ' / ' ) ;
if ( q & & ( ! r | | q < r ) ) {
2007-11-30 13:09:04 -08:00
char * userinfo = NULL ;
const char * u ;
2001-01-29 09:34:24 +00:00
2007-11-30 13:09:04 -08:00
next_token_no_ltrim_talloc ( ctx , & p , & userinfo , " @ " ) ;
if ( ! userinfo ) {
return - 1 ;
}
u = userinfo ;
2001-01-29 09:34:24 +00:00
2001-11-21 03:55:59 +00:00
if ( strchr_m ( u , ' ; ' ) ) {
2007-11-30 13:09:04 -08:00
char * workgroup ;
next_token_no_ltrim_talloc ( ctx , & u , & workgroup , " ; " ) ;
if ( ! workgroup ) {
return - 1 ;
}
if ( pp_workgroup ) {
* pp_workgroup = workgroup ;
}
2001-11-21 03:55:59 +00:00
}
2001-01-29 09:34:24 +00:00
2001-11-21 03:55:59 +00:00
if ( strchr_m ( u , ' : ' ) ) {
2007-11-30 13:09:04 -08:00
next_token_no_ltrim_talloc ( ctx , & u , pp_user , " : " ) ;
if ( ! * pp_user ) {
return - 1 ;
}
* pp_password = talloc_strdup ( ctx , u ) ;
if ( ! * pp_password ) {
return - 1 ;
}
} else {
* pp_user = talloc_strdup ( ctx , u ) ;
if ( ! * pp_user ) {
return - 1 ;
}
2001-11-21 03:55:59 +00:00
}
}
2000-12-26 05:57:10 +00:00
2007-11-30 13:09:04 -08:00
if ( ! next_token_talloc ( ctx , & p , pp_server , " / " ) ) {
2001-11-21 03:55:59 +00:00
return - 1 ;
}
2001-01-05 13:43:19 +00:00
2007-11-30 13:09:04 -08:00
if ( * p = = ( char ) 0 ) {
goto decoding ; /* That's it ... */
}
2000-12-26 05:57:10 +00:00
2007-11-30 13:09:04 -08:00
if ( ! next_token_talloc ( ctx , & p , pp_share , " / " ) ) {
2001-11-21 03:55:59 +00:00
return - 1 ;
}
2001-01-05 13:43:19 +00:00
2006-09-03 01:37:26 +00:00
/*
* Prepend a leading slash if there ' s a file path , as required by
* NetApp filers .
*/
if ( * p ! = ' \0 ' ) {
2007-11-30 13:09:04 -08:00
* pp_path = talloc_asprintf ( ctx ,
" \\ %s " ,
p ) ;
} else {
* pp_path = talloc_strdup ( ctx , " " ) ;
}
if ( ! * pp_path ) {
return - 1 ;
}
string_replace ( * pp_path , ' / ' , ' \\ ' ) ;
2000-12-26 05:57:10 +00:00
2003-04-16 14:45:11 +00:00
decoding :
2007-11-30 13:09:04 -08:00
( void ) smbc_urldecode_talloc ( ctx , pp_path , * pp_path ) ;
( void ) smbc_urldecode_talloc ( ctx , pp_server , * pp_server ) ;
( void ) smbc_urldecode_talloc ( ctx , pp_share , * pp_share ) ;
( void ) smbc_urldecode_talloc ( ctx , pp_user , * pp_user ) ;
( void ) smbc_urldecode_talloc ( ctx , pp_password , * pp_password ) ;
2003-04-16 14:45:11 +00:00
2001-11-21 03:55:59 +00:00
return 0 ;
2000-12-26 05:57:10 +00:00
}
/*
2004-03-19 16:22:47 +00:00
* Verify that the options specified in a URL are valid
2000-12-26 05:57:10 +00:00
*/
2005-12-29 15:06:53 +00:00
static int
smbc_check_options ( char * server ,
char * share ,
char * path ,
char * options )
2004-03-19 16:22:47 +00:00
{
2005-12-29 15:06:53 +00:00
DEBUG ( 4 , ( " smbc_check_options(): server='%s' share='%s' "
" path='%s' options='%s' \n " ,
server , share , path , options ) ) ;
2004-03-19 16:22:47 +00:00
/* No options at all is always ok */
if ( ! * options ) return 0 ;
2000-12-26 05:57:10 +00:00
2005-03-10 23:41:19 +00:00
/* Currently, we don't support any options. */
return - 1 ;
2004-03-19 16:22:47 +00:00
}
/*
* Convert an SMB error into a UNIX error . . .
*/
2005-12-29 15:06:53 +00:00
static int
smbc_errno ( SMBCCTX * context ,
struct cli_state * c )
2000-12-26 05:57:10 +00:00
{
2002-09-25 15:19:00 +00:00
int ret = cli_errno ( c ) ;
2001-08-10 06:00:33 +00:00
if ( cli_is_dos_error ( c ) ) {
uint8 eclass ;
uint32 ecode ;
cli_dos_error ( c , & eclass , & ecode ) ;
DEBUG ( 3 , ( " smbc_error %d %d (0x%x) -> %d \n " ,
( int ) eclass , ( int ) ecode , ( int ) ecode , ret ) ) ;
} else {
2001-08-27 19:46:22 +00:00
NTSTATUS status ;
2001-08-10 06:00:33 +00:00
2001-08-10 06:16:05 +00:00
status = cli_nt_error ( c ) ;
2001-08-10 06:00:33 +00:00
2001-09-04 10:57:29 +00:00
DEBUG ( 3 , ( " smbc errno %s -> %d \n " ,
2002-09-25 15:19:00 +00:00
nt_errstr ( status ) , ret ) ) ;
2001-08-10 06:00:33 +00:00
}
2000-12-26 05:57:10 +00:00
return ret ;
}
2002-07-15 10:35:28 +00:00
/*
2005-06-01 20:17:16 +00:00
* Check a server for being alive and well .
2002-07-15 10:35:28 +00:00
* returns 0 if the server is in shape . Returns 1 on error
*
* Also useable outside libsmbclient to enable external cache
* to do some checks too .
*/
2005-12-29 15:06:53 +00:00
static int
smbc_check_server ( SMBCCTX * context ,
SMBCSRV * server )
2002-07-15 10:35:28 +00:00
{
2007-05-18 13:42:48 +00:00
socklen_t size ;
2007-02-03 17:13:58 +00:00
struct sockaddr addr ;
2007-09-01 18:34:50 +00:00
size = sizeof ( addr ) ;
return ( getpeername ( server - > cli - > fd , & addr , & size ) = = - 1 ) ;
2002-07-15 10:35:28 +00:00
}
/*
2003-01-13 20:04:40 +00:00
* Remove a server from the cached server list it ' s unused .
2002-07-15 10:35:28 +00:00
* On success , 0 is returned . 1 is returned if the server could not be removed .
*
* Also useable outside libsmbclient
*/
2005-12-29 15:06:53 +00:00
int
smbc_remove_unused_server ( SMBCCTX * context ,
SMBCSRV * srv )
2002-07-15 10:35:28 +00:00
{
SMBCFILE * file ;
/* are we being fooled ? */
2003-01-13 20:04:40 +00:00
if ( ! context | | ! context - > internal | |
! context - > internal - > _initialized | | ! srv ) return 1 ;
2002-07-15 10:35:28 +00:00
/* Check all open files/directories for a relation with this server */
2003-01-13 20:04:40 +00:00
for ( file = context - > internal - > _files ; file ; file = file - > next ) {
2002-07-15 10:35:28 +00:00
if ( file - > srv = = srv ) {
/* Still used */
2005-12-29 15:06:53 +00:00
DEBUG ( 3 , ( " smbc_remove_usused_server: "
2007-11-30 14:19:55 -08:00
" %p still used by %p. \n " ,
2002-07-15 10:35:28 +00:00
srv , file ) ) ;
return 1 ;
}
}
2003-01-13 20:04:40 +00:00
DLIST_REMOVE ( context - > internal - > _servers , srv ) ;
2002-07-15 10:35:28 +00:00
2006-07-11 18:01:26 +00:00
cli_shutdown ( srv - > cli ) ;
srv - > cli = NULL ;
2002-07-15 10:35:28 +00:00
DEBUG ( 3 , ( " smbc_remove_usused_server: %p removed. \n " , srv ) ) ;
2007-09-06 13:21:31 +00:00
( context - > callbacks . remove_cached_srv_fn ) ( context , srv ) ;
2005-12-06 17:09:44 +00:00
SAFE_FREE ( srv ) ;
2002-07-15 10:35:28 +00:00
return 0 ;
}
2005-12-29 15:06:53 +00:00
static SMBCSRV *
find_server ( SMBCCTX * context ,
2007-11-30 14:19:55 -08:00
const char * server ,
const char * share ,
char * workgroup ,
char * username ,
char * password )
2003-10-24 17:01:19 +00:00
{
SMBCSRV * srv ;
int auth_called = 0 ;
2007-11-30 13:09:04 -08:00
2003-10-24 17:01:19 +00:00
check_server_cache :
2007-11-30 14:19:55 -08:00
srv = ( context - > callbacks . get_cached_srv_fn ) ( context , server , share ,
2007-09-06 13:21:31 +00:00
workgroup , username ) ;
2005-03-10 23:41:19 +00:00
2003-10-24 17:01:19 +00:00
if ( ! auth_called & & ! srv & & ( ! username [ 0 ] | | ! password [ 0 ] ) ) {
2006-03-22 22:05:19 +00:00
if ( context - > internal - > _auth_fn_with_context ! = NULL ) {
2007-09-06 13:21:31 +00:00
( context - > internal - > _auth_fn_with_context ) (
2006-03-22 22:05:19 +00:00
context ,
server , share ,
2007-11-30 14:19:55 -08:00
workgroup , strlen ( workgroup ) + 1 ,
username , strlen ( username ) + 1 ,
password , strlen ( password ) + 1 ) ;
2006-03-22 22:05:19 +00:00
} else {
2007-09-06 13:21:31 +00:00
( context - > callbacks . auth_fn ) (
2006-03-22 22:05:19 +00:00
server , share ,
2007-11-30 14:19:55 -08:00
workgroup , strlen ( workgroup ) + 1 ,
username , strlen ( username ) + 1 ,
password , strlen ( password ) + 1 ) ;
}
2006-03-22 22:05:19 +00:00
2003-10-24 17:01:19 +00:00
/*
* However , smbc_auth_fn may have picked up info relating to
* an existing connection , so try for an existing connection
* again . . .
*/
auth_called = 1 ;
goto check_server_cache ;
2007-11-30 14:19:55 -08:00
2003-10-24 17:01:19 +00:00
}
2007-11-30 14:19:55 -08:00
2003-10-24 17:01:19 +00:00
if ( srv ) {
2007-09-06 13:21:31 +00:00
if ( ( context - > callbacks . check_server_fn ) ( context , srv ) ) {
2003-10-24 17:01:19 +00:00
/*
2007-11-30 14:19:55 -08:00
* This server is no good anymore
2003-10-24 17:01:19 +00:00
* Try to remove it and check for more possible
* servers in the cache
*/
2007-09-06 13:21:31 +00:00
if ( ( context - > callbacks . remove_unused_server_fn ) ( context ,
srv ) ) {
2003-10-24 17:01:19 +00:00
/*
* We could not remove the server completely ,
* remove it from the cache so we will not get
* it again . It will be removed when the last
* file / dir is closed .
*/
2007-09-06 13:21:31 +00:00
( context - > callbacks . remove_cached_srv_fn ) ( context ,
srv ) ;
2003-10-24 17:01:19 +00:00
}
/*
* Maybe there are more cached connections to this
* server
*/
goto check_server_cache ;
}
2005-03-10 23:41:19 +00:00
2003-10-24 17:01:19 +00:00
return srv ;
}
return NULL ;
}
2000-12-26 05:57:10 +00:00
/*
* Connect to a server , possibly on an existing connection
2001-01-12 05:10:45 +00:00
*
* Here , what we want to do is : If the server and username
2007-10-24 14:16:54 -07:00
* match an existing connection , reuse that , otherwise , establish a
2001-01-12 05:10:45 +00:00
* new connection .
*
* If we have to create a new connection , call the auth_fn to get the
* info we need , unless the username and password were passed in .
2000-12-26 05:57:10 +00:00
*/
2005-12-29 15:06:53 +00:00
static SMBCSRV *
smbc_server ( SMBCCTX * context ,
2007-11-30 14:19:55 -08:00
bool connect_if_not_found ,
const char * server ,
const char * share ,
char * workgroup ,
char * username ,
char * password )
2000-12-26 05:57:10 +00:00
{
2002-07-15 10:35:28 +00:00
SMBCSRV * srv = NULL ;
2006-07-11 18:01:26 +00:00
struct cli_state * c ;
2001-11-21 03:55:59 +00:00
struct nmb_name called , calling ;
2003-04-16 14:45:11 +00:00
const char * server_n = server ;
2007-10-24 14:16:54 -07:00
struct sockaddr_storage ss ;
2002-07-15 10:35:28 +00:00
int tried_reverse = 0 ;
2005-03-10 23:41:19 +00:00
int port_try_first ;
int port_try_next ;
2005-03-31 21:16:20 +00:00
const char * username_used ;
2007-06-20 17:38:42 +00:00
NTSTATUS status ;
2007-10-27 20:29:36 -07:00
zero_addr ( & ss ) ;
2001-11-21 03:55:59 +00:00
ZERO_STRUCT ( c ) ;
if ( server [ 0 ] = = 0 ) {
errno = EPERM ;
return NULL ;
}
2005-12-05 23:30:40 +00:00
/* Look for a cached connection */
srv = find_server ( context , server , share ,
workgroup , username , password ) ;
2007-10-24 14:16:54 -07:00
2005-03-10 23:41:19 +00:00
/*
* If we found a connection and we ' re only allowed one share per
* server . . .
*/
2005-03-11 17:01:30 +00:00
if ( srv & & * share ! = ' \0 ' & & context - > options . one_share_per_server ) {
2005-03-10 23:41:19 +00:00
/*
* . . . then if there ' s no current connection to the share ,
* connect to it . find_server ( ) , or rather the function
* pointed to by context - > callbacks . get_cached_srv_fn which
* was called by find_server ( ) , will have issued a tree
* disconnect if the requested share is not the same as the
* one that was already connected .
*/
2006-07-11 18:01:26 +00:00
if ( srv - > cli - > cnum = = ( uint16 ) - 1 ) {
2005-03-10 23:41:19 +00:00
/* Ensure we have accurate auth info */
2006-03-22 22:05:19 +00:00
if ( context - > internal - > _auth_fn_with_context ! = NULL ) {
2007-09-06 13:21:31 +00:00
( context - > internal - > _auth_fn_with_context ) (
2006-03-22 22:05:19 +00:00
context ,
server , share ,
2007-11-30 14:19:55 -08:00
workgroup , strlen ( workgroup ) + 1 ,
username , strlen ( username ) + 1 ,
password , strlen ( password ) + 1 ) ;
2006-03-22 22:05:19 +00:00
} else {
2007-09-06 13:21:31 +00:00
( context - > callbacks . auth_fn ) (
2006-03-22 22:05:19 +00:00
server , share ,
2007-11-30 14:19:55 -08:00
workgroup , strlen ( workgroup ) + 1 ,
username , strlen ( username ) + 1 ,
password , strlen ( password ) + 1 ) ;
2006-03-22 22:05:19 +00:00
}
2005-03-10 23:41:19 +00:00
2006-07-11 18:01:26 +00:00
if ( ! cli_send_tconX ( srv - > cli , share , " ????? " ,
2005-03-10 23:41:19 +00:00
password , strlen ( password ) + 1 ) ) {
2007-10-24 14:16:54 -07:00
2006-07-11 18:01:26 +00:00
errno = smbc_errno ( context , srv - > cli ) ;
cli_shutdown ( srv - > cli ) ;
srv - > cli = NULL ;
2007-09-06 13:21:31 +00:00
( context - > callbacks . remove_cached_srv_fn ) ( context ,
srv ) ;
2005-03-10 23:41:19 +00:00
srv = NULL ;
}
2005-12-29 15:06:59 +00:00
/*
* Regenerate the dev value since it ' s based on both
* server and share
*/
2005-03-10 23:41:19 +00:00
if ( srv ) {
2005-12-29 15:06:59 +00:00
srv - > dev = ( dev_t ) ( str_checksum ( server ) ^
str_checksum ( share ) ) ;
2005-03-10 23:41:19 +00:00
}
}
}
2007-10-24 14:16:54 -07:00
2005-03-10 23:41:19 +00:00
/* If we have a connection... */
if ( srv ) {
/* ... then we're done here. Give 'em what they came for. */
2003-10-24 17:01:19 +00:00
return srv ;
2005-03-10 23:41:19 +00:00
}
2001-11-21 03:55:59 +00:00
2005-12-29 15:06:59 +00:00
/* If we're not asked to connect when a connection doesn't exist... */
if ( ! connect_if_not_found ) {
/* ... then we're done here. */
return NULL ;
}
2002-07-15 10:35:28 +00:00
make_nmb_name ( & calling , context - > netbios_name , 0x0 ) ;
2001-11-21 03:55:59 +00:00
make_nmb_name ( & called , server , 0x20 ) ;
DEBUG ( 4 , ( " smbc_server: server_n=[%s] server=[%s] \n " , server_n , server ) ) ;
2007-10-24 14:16:54 -07:00
2001-11-21 03:55:59 +00:00
DEBUG ( 4 , ( " -> server_n=[%s] server=[%s] \n " , server_n , server ) ) ;
2000-12-26 05:57:10 +00:00
again :
2001-11-21 03:55:59 +00:00
2007-10-27 20:29:36 -07:00
zero_addr ( & ss ) ;
2001-11-21 03:55:59 +00:00
/* have to open a new connection */
2006-07-11 18:01:26 +00:00
if ( ( c = cli_initialise ( ) ) = = NULL ) {
2003-10-24 17:01:19 +00:00
errno = ENOMEM ;
2001-11-21 03:55:59 +00:00
return NULL ;
}
2005-01-24 20:21:15 +00:00
if ( context - > flags & SMB_CTX_FLAG_USE_KERBEROS ) {
2006-07-11 18:01:26 +00:00
c - > use_kerberos = True ;
2005-01-24 20:21:15 +00:00
}
if ( context - > flags & SMB_CTX_FLAG_FALLBACK_AFTER_KERBEROS ) {
2006-07-11 18:01:26 +00:00
c - > fallback_after_kerberos = True ;
2005-01-24 20:21:15 +00:00
}
2006-07-11 18:01:26 +00:00
c - > timeout = context - > timeout ;
2002-07-15 10:35:28 +00:00
2005-03-10 23:41:19 +00:00
/*
* Force use of port 139 for first try if share is $ IPC , empty , or
* null , so browse lists can work
*/
2005-04-19 19:23:49 +00:00
if ( share = = NULL | | * share = = ' \0 ' | | strcmp ( share , " IPC$ " ) = = 0 ) {
2005-03-10 23:41:19 +00:00
port_try_first = 139 ;
port_try_next = 445 ;
2005-04-19 19:23:49 +00:00
} else {
2005-03-10 23:41:19 +00:00
port_try_first = 445 ;
port_try_next = 139 ;
}
2006-07-11 18:01:26 +00:00
c - > port = port_try_first ;
2003-10-24 17:01:19 +00:00
2007-10-24 14:16:54 -07:00
status = cli_connect ( c , server_n , & ss ) ;
2007-06-20 17:38:42 +00:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
2005-03-10 23:41:19 +00:00
/* First connection attempt failed. Try alternate port. */
2006-07-11 18:01:26 +00:00
c - > port = port_try_next ;
2005-03-10 23:41:19 +00:00
2007-10-24 14:16:54 -07:00
status = cli_connect ( c , server_n , & ss ) ;
2007-06-20 17:38:42 +00:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
cli_shutdown ( c ) ;
errno = ETIMEDOUT ;
return NULL ;
}
}
2002-07-15 10:35:28 +00:00
2006-07-11 18:01:26 +00:00
if ( ! cli_session_request ( c , & calling , & called ) ) {
cli_shutdown ( c ) ;
2001-11-21 03:55:59 +00:00
if ( strcmp ( called . name , " *SMBSERVER " ) ) {
make_nmb_name ( & called , " *SMBSERVER " , 0x20 ) ;
goto again ;
2006-07-11 18:01:26 +00:00
} else { /* Try one more time, but ensure we don't loop */
2002-07-15 10:35:28 +00:00
2006-07-11 18:01:26 +00:00
/* Only try this if server is an IP address ... */
2002-07-15 10:35:28 +00:00
2007-10-24 14:16:54 -07:00
if ( is_ipaddress ( server ) & & ! tried_reverse ) {
2006-07-11 18:01:26 +00:00
fstring remote_name ;
2007-10-24 14:16:54 -07:00
struct sockaddr_storage rem_ss ;
2002-07-15 10:35:28 +00:00
2007-10-24 14:16:54 -07:00
if ( ! interpret_string_addr ( & rem_ss , server ,
NI_NUMERICHOST ) ) {
2006-07-11 18:01:26 +00:00
DEBUG ( 4 , ( " Could not convert IP address "
2007-10-24 14:16:54 -07:00
" %s to struct sockaddr_storage \n " ,
server ) ) ;
2006-07-11 18:01:26 +00:00
errno = ETIMEDOUT ;
return NULL ;
}
2002-07-15 10:35:28 +00:00
2006-07-11 18:01:26 +00:00
tried_reverse + + ; /* Yuck */
2002-07-15 10:35:28 +00:00
2007-10-24 14:16:54 -07:00
if ( name_status_find ( " * " , 0 , 0 , & rem_ss , remote_name ) ) {
2006-07-11 18:01:26 +00:00
make_nmb_name ( & called , remote_name , 0x20 ) ;
goto again ;
}
}
2002-07-15 10:35:28 +00:00
}
2005-03-10 23:41:19 +00:00
errno = ETIMEDOUT ;
2001-11-21 03:55:59 +00:00
return NULL ;
}
2007-10-24 14:16:54 -07:00
2001-11-21 03:55:59 +00:00
DEBUG ( 4 , ( " session request ok \n " ) ) ;
2007-10-24 14:16:54 -07:00
2006-07-11 18:01:26 +00:00
if ( ! cli_negprot ( c ) ) {
cli_shutdown ( c ) ;
2005-03-10 23:41:19 +00:00
errno = ETIMEDOUT ;
2001-11-21 03:55:59 +00:00
return NULL ;
}
2005-03-31 21:16:20 +00:00
username_used = username ;
2007-10-24 14:16:54 -07:00
if ( ! NT_STATUS_IS_OK ( cli_session_setup ( c , username_used ,
2006-08-16 17:14:16 +00:00
password , strlen ( password ) ,
password , strlen ( password ) ,
workgroup ) ) ) {
2007-10-24 14:16:54 -07:00
2005-03-31 21:16:20 +00:00
/* Failed. Try an anonymous login, if allowed by flags. */
username_used = " " ;
if ( ( context - > flags & SMBCCTX_FLAG_NO_AUTO_ANONYMOUS_LOGON ) | |
2006-08-16 17:14:16 +00:00
! NT_STATUS_IS_OK ( cli_session_setup ( c , username_used ,
password , 1 ,
password , 0 ,
workgroup ) ) ) {
2005-03-31 21:16:20 +00:00
2006-07-11 18:01:26 +00:00
cli_shutdown ( c ) ;
2005-03-31 21:16:20 +00:00
errno = EPERM ;
return NULL ;
}
2001-11-21 03:55:59 +00:00
}
DEBUG ( 4 , ( " session setup ok \n " ) ) ;
2006-07-11 18:01:26 +00:00
if ( ! cli_send_tconX ( c , share , " ????? " ,
2001-11-21 03:55:59 +00:00
password , strlen ( password ) + 1 ) ) {
2006-07-11 18:01:26 +00:00
errno = smbc_errno ( context , c ) ;
cli_shutdown ( c ) ;
2001-11-21 03:55:59 +00:00
return NULL ;
}
2007-10-24 14:16:54 -07:00
2001-11-21 03:55:59 +00:00
DEBUG ( 4 , ( " tconx ok \n " ) ) ;
2007-10-24 14:16:54 -07:00
2002-07-15 10:35:28 +00:00
/*
* Ok , we have got a nice connection
2005-06-01 20:17:16 +00:00
* Let ' s allocate a server structure .
2002-07-15 10:35:28 +00:00
*/
2004-12-07 18:25:53 +00:00
srv = SMB_MALLOC_P ( SMBCSRV ) ;
2001-11-21 03:55:59 +00:00
if ( ! srv ) {
errno = ENOMEM ;
goto failed ;
}
2000-12-26 05:57:10 +00:00
2001-11-21 03:55:59 +00:00
ZERO_STRUCTP ( srv ) ;
srv - > cli = c ;
srv - > dev = ( dev_t ) ( str_checksum ( server ) ^ str_checksum ( share ) ) ;
2005-06-01 20:17:16 +00:00
srv - > no_pathinfo = False ;
srv - > no_pathinfo2 = False ;
srv - > no_nt_session = False ;
2000-12-26 05:57:10 +00:00
2004-05-09 17:29:09 +00:00
/* now add it to the cache (internal or external) */
/* Let the cache function set errno if it wants to */
errno = 0 ;
2007-09-06 13:21:31 +00:00
if ( ( context - > callbacks . add_cached_srv_fn ) ( context , srv ,
server , share ,
workgroup , username ) ) {
2004-05-09 17:29:09 +00:00
int saved_errno = errno ;
2002-07-15 10:35:28 +00:00
DEBUG ( 3 , ( " Failed to add server to cache \n " ) ) ;
2004-05-09 22:39:39 +00:00
errno = saved_errno ;
2004-05-09 17:29:09 +00:00
if ( errno = = 0 ) {
errno = ENOMEM ;
}
2001-11-21 03:55:59 +00:00
goto failed ;
}
2007-10-24 14:16:54 -07:00
DEBUG ( 2 , ( " Server connect ok: //%s/%s: %p \n " ,
2002-07-15 10:35:28 +00:00
server , share , srv ) ) ;
2000-12-26 05:57:10 +00:00
2004-03-19 16:22:47 +00:00
DLIST_ADD ( context - > internal - > _servers , srv ) ;
2001-11-21 03:55:59 +00:00
return srv ;
2000-12-26 05:57:10 +00:00
failed :
2006-07-11 18:01:26 +00:00
cli_shutdown ( c ) ;
if ( ! srv ) {
return NULL ;
}
2007-10-24 14:16:54 -07:00
2001-11-21 03:55:59 +00:00
SAFE_FREE ( srv ) ;
return NULL ;
}
2003-10-24 17:01:19 +00:00
/*
* Connect to a server for getting / setting attributes , possibly on an existing
* connection . This works similarly to smbc_server ( ) .
*/
2005-12-29 15:06:53 +00:00
static SMBCSRV *
smbc_attr_server ( SMBCCTX * context ,
const char * server ,
2007-10-24 14:16:54 -07:00
const char * share ,
2007-11-30 14:19:55 -08:00
char * workgroup ,
char * username ,
char * password ,
2005-12-29 15:06:53 +00:00
POLICY_HND * pol )
2003-10-24 17:01:19 +00:00
{
2007-02-03 17:13:58 +00:00
int flags ;
2007-10-24 14:16:54 -07:00
struct sockaddr_storage ss ;
2003-10-24 17:01:19 +00:00
struct cli_state * ipc_cli ;
2005-09-30 17:13:37 +00:00
struct rpc_pipe_client * pipe_hnd ;
2003-10-24 17:01:19 +00:00
NTSTATUS nt_status ;
SMBCSRV * ipc_srv = NULL ;
/*
2005-12-06 17:09:44 +00:00
* See if we ' ve already created this special connection . Reference
* our " special " share name ' * IPC $ ' , which is an impossible real share
* name due to the leading asterisk .
2003-10-24 17:01:19 +00:00
*/
2005-03-10 23:41:19 +00:00
ipc_srv = find_server ( context , server , " *IPC$ " ,
2003-10-24 17:01:19 +00:00
workgroup , username , password ) ;
if ( ! ipc_srv ) {
/* We didn't find a cached connection. Get the password */
if ( * password = = ' \0 ' ) {
/* ... then retrieve it now. */
2006-03-22 22:05:19 +00:00
if ( context - > internal - > _auth_fn_with_context ! = NULL ) {
2007-09-06 13:21:31 +00:00
( context - > internal - > _auth_fn_with_context ) (
2006-03-22 22:05:19 +00:00
context ,
server , share ,
2007-11-30 14:19:55 -08:00
workgroup , strlen ( workgroup ) + 1 ,
username , strlen ( username ) + 1 ,
password , strlen ( password ) + 1 ) ;
2006-03-22 22:05:19 +00:00
} else {
2007-09-06 13:21:31 +00:00
( context - > callbacks . auth_fn ) (
2006-03-22 22:05:19 +00:00
server , share ,
2007-11-30 14:19:55 -08:00
workgroup , strlen ( workgroup ) + 1 ,
username , strlen ( username ) + 1 ,
password , strlen ( password ) + 1 ) ;
2006-03-22 22:05:19 +00:00
}
2003-10-24 17:01:19 +00:00
}
2007-10-24 14:16:54 -07:00
2007-02-03 17:13:58 +00:00
flags = 0 ;
if ( context - > flags & SMB_CTX_FLAG_USE_KERBEROS ) {
flags | = CLI_FULL_CONNECTION_USE_KERBEROS ;
}
2007-10-27 20:29:36 -07:00
zero_addr ( & ss ) ;
2003-10-24 17:01:19 +00:00
nt_status = cli_full_connection ( & ipc_cli ,
2007-10-24 14:16:54 -07:00
global_myname ( ) , server ,
& ss , 0 , " IPC$ " , " ????? " ,
2003-10-24 17:01:19 +00:00
username , workgroup ,
2007-02-03 17:13:58 +00:00
password , flags ,
2003-10-24 17:01:19 +00:00
Undefined , NULL ) ;
if ( ! NT_STATUS_IS_OK ( nt_status ) ) {
2004-03-19 16:22:47 +00:00
DEBUG ( 1 , ( " cli_full_connection failed! (%s) \n " ,
2003-10-24 17:01:19 +00:00
nt_errstr ( nt_status ) ) ) ;
errno = ENOTSUP ;
return NULL ;
}
2005-12-14 04:00:58 +00:00
ipc_srv = SMB_MALLOC_P ( SMBCSRV ) ;
if ( ! ipc_srv ) {
errno = ENOMEM ;
cli_shutdown ( ipc_cli ) ;
return NULL ;
}
ZERO_STRUCTP ( ipc_srv ) ;
2006-07-11 18:01:26 +00:00
ipc_srv - > cli = ipc_cli ;
2005-12-14 04:00:58 +00:00
2005-12-08 03:41:19 +00:00
if ( pol ) {
2006-07-11 18:01:26 +00:00
pipe_hnd = cli_rpc_pipe_open_noauth ( ipc_srv - > cli ,
2005-12-08 03:41:19 +00:00
PI_LSARPC ,
& nt_status ) ;
2005-10-17 16:44:26 +00:00
if ( ! pipe_hnd ) {
DEBUG ( 1 , ( " cli_nt_session_open fail! \n " ) ) ;
errno = ENOTSUP ;
2006-07-11 18:01:26 +00:00
cli_shutdown ( ipc_srv - > cli ) ;
2005-12-14 04:00:58 +00:00
free ( ipc_srv ) ;
2005-10-17 16:44:26 +00:00
return NULL ;
}
2005-09-03 16:40:05 +00:00
2005-12-08 03:41:19 +00:00
/*
* Some systems don ' t support
* SEC_RIGHTS_MAXIMUM_ALLOWED , but NT sends 0x2000000
* so we might as well do it too .
*/
2005-09-30 17:13:37 +00:00
2005-12-08 03:41:19 +00:00
nt_status = rpccli_lsa_open_policy (
pipe_hnd ,
2007-11-29 13:24:54 -08:00
talloc_tos ( ) ,
2005-12-08 03:41:19 +00:00
True ,
GENERIC_EXECUTE_ACCESS ,
pol ) ;
2005-09-30 17:13:37 +00:00
2005-10-17 16:44:26 +00:00
if ( ! NT_STATUS_IS_OK ( nt_status ) ) {
2006-07-11 18:01:26 +00:00
errno = smbc_errno ( context , ipc_srv - > cli ) ;
cli_shutdown ( ipc_srv - > cli ) ;
2005-10-17 16:44:26 +00:00
return NULL ;
}
2003-10-24 17:01:19 +00:00
}
/* now add it to the cache (internal or external) */
2004-03-19 16:22:47 +00:00
errno = 0 ; /* let cache function set errno if it likes */
2007-09-06 13:21:31 +00:00
if ( ( context - > callbacks . add_cached_srv_fn ) ( context , ipc_srv ,
server ,
" *IPC$ " ,
workgroup ,
username ) ) {
2003-10-24 17:01:19 +00:00
DEBUG ( 3 , ( " Failed to add server to cache \n " ) ) ;
2004-03-19 16:22:47 +00:00
if ( errno = = 0 ) {
errno = ENOMEM ;
}
2006-07-11 18:01:26 +00:00
cli_shutdown ( ipc_srv - > cli ) ;
2004-03-19 16:22:47 +00:00
free ( ipc_srv ) ;
2003-10-24 17:01:19 +00:00
return NULL ;
}
2004-03-19 16:22:47 +00:00
DLIST_ADD ( context - > internal - > _servers , ipc_srv ) ;
2003-10-24 17:01:19 +00:00
}
return ipc_srv ;
}
2000-12-26 05:57:10 +00:00
/*
* Routine to open ( ) a file . . .
*/
2005-12-29 15:06:53 +00:00
static SMBCFILE *
smbc_open_ctx ( SMBCCTX * context ,
const char * fname ,
int flags ,
mode_t mode )
2000-12-26 05:57:10 +00:00
{
2007-11-30 13:09:04 -08:00
char * server , * share , * user , * password , * workgroup ;
char * path ;
2007-11-29 17:25:41 -08:00
char * targetpath = NULL ;
2005-09-12 18:12:53 +00:00
struct cli_state * targetcli ;
2002-07-15 10:35:28 +00:00
SMBCSRV * srv = NULL ;
SMBCFILE * file = NULL ;
2001-11-21 03:55:59 +00:00
int fd ;
2007-11-19 12:36:16 +01:00
TALLOC_CTX * frame = talloc_stackframe ( ) ;
2000-12-26 05:57:10 +00:00
2003-01-13 20:04:40 +00:00
if ( ! context | | ! context - > internal | |
! context - > internal - > _initialized ) {
2000-12-26 05:57:10 +00:00
2001-11-21 03:55:59 +00:00
errno = EINVAL ; /* Best I can think of ... */
2007-11-19 12:36:16 +01:00
TALLOC_FREE ( frame ) ;
2002-07-15 10:35:28 +00:00
return NULL ;
2000-12-26 05:57:10 +00:00
2001-11-21 03:55:59 +00:00
}
2000-12-26 05:57:10 +00:00
2001-11-21 03:55:59 +00:00
if ( ! fname ) {
2000-12-26 05:57:10 +00:00
2001-11-21 03:55:59 +00:00
errno = EINVAL ;
2007-11-19 12:36:16 +01:00
TALLOC_FREE ( frame ) ;
2002-07-15 10:35:28 +00:00
return NULL ;
2000-12-26 05:57:10 +00:00
2001-11-21 03:55:59 +00:00
}
2000-12-26 05:57:10 +00:00
2007-11-30 13:09:04 -08:00
if ( smbc_parse_path ( frame ,
context ,
fname ,
& workgroup ,
& server ,
& share ,
& path ,
& user ,
& password ,
NULL ) ) {
errno = EINVAL ;
2007-11-19 12:36:16 +01:00
TALLOC_FREE ( frame ) ;
2007-11-30 13:09:04 -08:00
return NULL ;
2004-03-19 16:22:47 +00:00
}
2001-01-12 05:10:45 +00:00
2007-11-30 13:09:04 -08:00
if ( ! user | | user [ 0 ] = = ( char ) 0 ) {
user = talloc_strdup ( frame , context - > user ) ;
if ( ! user ) {
errno = ENOMEM ;
TALLOC_FREE ( frame ) ;
return NULL ;
}
}
2000-12-26 05:57:10 +00:00
2005-12-29 15:06:59 +00:00
srv = smbc_server ( context , True ,
server , share , workgroup , user , password ) ;
2000-12-26 05:57:10 +00:00
2001-11-21 03:55:59 +00:00
if ( ! srv ) {
if ( errno = = EPERM ) errno = EACCES ;
2007-11-19 12:36:16 +01:00
TALLOC_FREE ( frame ) ;
2002-07-15 10:35:28 +00:00
return NULL ; /* smbc_server sets errno */
2001-11-21 03:55:59 +00:00
}
2000-12-26 05:57:10 +00:00
2001-11-21 03:55:59 +00:00
/* Hmmm, the test for a directory is suspect here ... FIXME */
2001-03-27 12:13:59 +00:00
2001-11-21 03:55:59 +00:00
if ( strlen ( path ) > 0 & & path [ strlen ( path ) - 1 ] = = ' \\ ' ) {
fd = - 1 ;
2007-11-29 17:25:41 -08:00
} else {
2004-12-07 18:25:53 +00:00
file = SMB_MALLOC_P ( SMBCFILE ) ;
2000-12-26 05:57:10 +00:00
2002-07-15 10:35:28 +00:00
if ( ! file ) {
2001-11-21 03:55:59 +00:00
errno = ENOMEM ;
2007-11-19 12:36:16 +01:00
TALLOC_FREE ( frame ) ;
2002-07-15 10:35:28 +00:00
return NULL ;
2001-11-21 03:55:59 +00:00
}
2000-12-26 05:57:10 +00:00
2002-07-15 10:35:28 +00:00
ZERO_STRUCTP ( file ) ;
2005-09-12 18:12:53 +00:00
/*d_printf(">>>open: resolving %s\n", path);*/
2007-11-30 13:09:04 -08:00
if ( ! cli_resolve_path ( frame , " " , srv - > cli , path , & targetcli , & targetpath ) ) {
2005-09-12 18:12:53 +00:00
d_printf ( " Could not resolve %s \n " , path ) ;
2006-03-12 11:00:06 +00:00
SAFE_FREE ( file ) ;
2007-11-19 12:36:16 +01:00
TALLOC_FREE ( frame ) ;
2005-09-12 18:12:53 +00:00
return NULL ;
}
/*d_printf(">>>open: resolved %s as %s\n", path, targetpath);*/
2007-11-29 17:25:41 -08:00
2006-09-03 02:10:24 +00:00
if ( ( fd = cli_open ( targetcli , targetpath , flags ,
context - > internal - > _share_mode ) ) < 0 ) {
2001-01-24 12:32:20 +00:00
2001-11-21 03:55:59 +00:00
/* Handle the error ... */
2001-01-24 12:32:20 +00:00
2002-07-15 10:35:28 +00:00
SAFE_FREE ( file ) ;
2005-09-12 18:12:53 +00:00
errno = smbc_errno ( context , targetcli ) ;
2007-11-19 12:36:16 +01:00
TALLOC_FREE ( frame ) ;
2002-07-15 10:35:28 +00:00
return NULL ;
2001-01-24 12:32:20 +00:00
2001-11-21 03:55:59 +00:00
}
2000-12-26 05:57:10 +00:00
2001-11-21 03:55:59 +00:00
/* Fill in file struct */
2000-12-26 05:57:10 +00:00
2002-07-15 10:35:28 +00:00
file - > cli_fd = fd ;
2004-12-07 18:25:53 +00:00
file - > fname = SMB_STRDUP ( fname ) ;
2002-07-15 10:35:28 +00:00
file - > srv = srv ;
file - > offset = 0 ;
file - > file = True ;
2000-12-26 05:57:10 +00:00
2003-01-13 20:04:40 +00:00
DLIST_ADD ( context - > internal - > _files , file ) ;
2005-03-28 19:52:23 +00:00
/*
* If the file was opened in O_APPEND mode , all write
* operations should be appended to the file . To do that ,
* though , using this protocol , would require a getattrE ( )
* call for each and every write , to determine where the end
* of the file is . ( There does not appear to be an append flag
* in the protocol . ) Rather than add all of that overhead of
* retrieving the current end - of - file offset prior to each
* write operation , we ' ll assume that most append operations
* will continuously write , so we ' ll just set the offset to
* the end of the file now and hope that ' s adequate .
*
* Note to self : If this proves inadequate , and O_APPEND
* should , in some cases , be forced for each write , add a
* field in the context options structure , for
* " strict_append_mode " which would select between the current
* behavior ( if FALSE ) or issuing a getattrE ( ) prior to each
* write and forcing the write to the end of the file ( if
* TRUE ) . Adding that capability will likely require adding
* an " append " flag into the _SMBCFILE structure to track
* whether a file was opened in O_APPEND mode . - - djl
*/
if ( flags & O_APPEND ) {
if ( smbc_lseek_ctx ( context , file , 0 , SEEK_END ) < 0 ) {
( void ) smbc_close_ctx ( context , file ) ;
errno = ENXIO ;
2007-11-19 12:36:16 +01:00
TALLOC_FREE ( frame ) ;
2005-03-28 19:52:23 +00:00
return NULL ;
}
}
2007-11-19 12:36:16 +01:00
TALLOC_FREE ( frame ) ;
2002-07-15 10:35:28 +00:00
return file ;
2000-12-26 05:57:10 +00:00
2001-11-21 03:55:59 +00:00
}
2000-12-26 05:57:10 +00:00
2001-11-21 03:55:59 +00:00
/* Check if opendir needed ... */
2000-12-26 05:57:10 +00:00
2001-11-21 03:55:59 +00:00
if ( fd = = - 1 ) {
int eno = 0 ;
2000-12-26 05:57:10 +00:00
2006-07-11 18:01:26 +00:00
eno = smbc_errno ( context , srv - > cli ) ;
2007-09-06 13:21:31 +00:00
file = ( context - > opendir ) ( context , fname ) ;
2002-07-15 10:35:28 +00:00
if ( ! file ) errno = eno ;
2007-11-19 12:36:16 +01:00
TALLOC_FREE ( frame ) ;
2002-07-15 10:35:28 +00:00
return file ;
2000-12-26 05:57:10 +00:00
2001-11-21 03:55:59 +00:00
}
2000-12-26 05:57:10 +00:00
2002-07-15 10:35:28 +00:00
errno = EINVAL ; /* FIXME, correct errno ? */
2007-11-19 12:36:16 +01:00
TALLOC_FREE ( frame ) ;
2002-07-15 10:35:28 +00:00
return NULL ;
2000-12-26 05:57:10 +00:00
}
/*
* Routine to create a file
*/
static int creat_bits = O_WRONLY | O_CREAT | O_TRUNC ; /* FIXME: Do we need this */
2005-12-29 15:06:53 +00:00
static SMBCFILE *
smbc_creat_ctx ( SMBCCTX * context ,
const char * path ,
mode_t mode )
2000-12-26 05:57:10 +00:00
{
2001-01-07 07:10:50 +00:00
2003-01-13 20:04:40 +00:00
if ( ! context | | ! context - > internal | |
! context - > internal - > _initialized ) {
2001-01-07 07:10:50 +00:00
2001-11-21 03:55:59 +00:00
errno = EINVAL ;
2002-07-15 10:35:28 +00:00
return NULL ;
2001-01-07 07:10:50 +00:00
2001-11-21 03:55:59 +00:00
}
2001-01-07 07:10:50 +00:00
2002-07-15 10:35:28 +00:00
return smbc_open_ctx ( context , path , creat_bits , mode ) ;
2000-12-26 05:57:10 +00:00
}
/*
* Routine to read ( ) a file . . .
*/
2005-12-29 15:06:53 +00:00
static ssize_t
smbc_read_ctx ( SMBCCTX * context ,
SMBCFILE * file ,
void * buf ,
size_t count )
2000-12-26 05:57:10 +00:00
{
2001-11-21 03:55:59 +00:00
int ret ;
2007-11-30 13:09:04 -08:00
char * server , * share , * user , * password ;
char * path ;
2007-11-29 17:25:41 -08:00
char * targetpath = NULL ;
2005-09-12 18:12:53 +00:00
struct cli_state * targetcli ;
2007-11-19 12:36:16 +01:00
TALLOC_CTX * frame = talloc_stackframe ( ) ;
2000-12-26 05:57:10 +00:00
2005-03-22 21:17:01 +00:00
/*
* offset :
*
* Compiler bug ( possibly ) - - gcc ( GCC ) 3.3 .5 ( Debian 1 : 3.3 .5 - 2 ) - -
* appears to pass file - > offset ( which is type off_t ) differently than
* a local variable of type off_t . Using local variable " offset " in
* the call to cli_read ( ) instead of file - > offset fixes a problem
* retrieving data at an offset greater than 4 GB .
*/
2006-03-12 17:18:26 +00:00
off_t offset ;
2005-03-22 21:17:01 +00:00
2003-01-13 20:04:40 +00:00
if ( ! context | | ! context - > internal | |
! context - > internal - > _initialized ) {
2001-11-21 03:55:59 +00:00
errno = EINVAL ;
2007-11-19 12:36:16 +01:00
TALLOC_FREE ( frame ) ;
2001-11-21 03:55:59 +00:00
return - 1 ;
2001-01-07 07:10:50 +00:00
2001-11-21 03:55:59 +00:00
}
2001-01-07 07:10:50 +00:00
2002-07-15 10:35:28 +00:00
DEBUG ( 4 , ( " smbc_read(%p, %d) \n " , file , ( int ) count ) ) ;
2000-12-26 05:57:10 +00:00
2003-01-13 20:04:40 +00:00
if ( ! file | | ! DLIST_CONTAINS ( context - > internal - > _files , file ) ) {
2001-11-21 03:55:59 +00:00
errno = EBADF ;
2007-11-19 12:36:16 +01:00
TALLOC_FREE ( frame ) ;
2001-11-21 03:55:59 +00:00
return - 1 ;
2000-12-26 05:57:10 +00:00
2001-11-21 03:55:59 +00:00
}
2000-12-26 05:57:10 +00:00
2006-03-12 17:18:26 +00:00
offset = file - > offset ;
2001-11-21 03:55:59 +00:00
/* Check that the buffer exists ... */
2001-03-01 19:21:57 +00:00
2001-11-21 03:55:59 +00:00
if ( buf = = NULL ) {
errno = EINVAL ;
2007-11-19 12:36:16 +01:00
TALLOC_FREE ( frame ) ;
2001-11-21 03:55:59 +00:00
return - 1 ;
2001-03-01 19:21:57 +00:00
2001-11-21 03:55:59 +00:00
}
2001-03-01 19:21:57 +00:00
2005-09-12 18:12:53 +00:00
/*d_printf(">>>read: parsing %s\n", file->fname);*/
2007-11-30 13:09:04 -08:00
if ( smbc_parse_path ( frame ,
context ,
file - > fname ,
NULL ,
& server ,
& share ,
& path ,
& user ,
& password ,
NULL ) ) {
2005-09-12 18:12:53 +00:00
errno = EINVAL ;
2007-11-19 12:36:16 +01:00
TALLOC_FREE ( frame ) ;
2005-09-12 18:12:53 +00:00
return - 1 ;
}
2007-11-29 17:25:41 -08:00
2005-09-12 18:12:53 +00:00
/*d_printf(">>>read: resolving %s\n", path);*/
2007-11-29 17:25:41 -08:00
if ( ! cli_resolve_path ( frame , " " , file - > srv - > cli , path ,
2007-11-30 13:09:04 -08:00
& targetcli , & targetpath ) ) {
2005-09-12 18:12:53 +00:00
d_printf ( " Could not resolve %s \n " , path ) ;
2007-11-19 12:36:16 +01:00
TALLOC_FREE ( frame ) ;
2005-09-12 18:12:53 +00:00
return - 1 ;
}
/*d_printf(">>>fstat: resolved path as %s\n", targetpath);*/
2007-11-29 17:25:41 -08:00
2006-07-31 03:53:39 +00:00
ret = cli_read ( targetcli , file - > cli_fd , ( char * ) buf , offset , count ) ;
2000-12-26 05:57:10 +00:00
2001-11-21 03:55:59 +00:00
if ( ret < 0 ) {
2000-12-26 05:57:10 +00:00
2005-09-12 18:12:53 +00:00
errno = smbc_errno ( context , targetcli ) ;
2007-11-19 12:36:16 +01:00
TALLOC_FREE ( frame ) ;
2001-11-21 03:55:59 +00:00
return - 1 ;
2000-12-26 05:57:10 +00:00
2001-11-21 03:55:59 +00:00
}
2000-12-26 05:57:10 +00:00
2002-07-15 10:35:28 +00:00
file - > offset + = ret ;
2000-12-26 05:57:10 +00:00
2001-11-21 03:55:59 +00:00
DEBUG ( 4 , ( " --> %d \n " , ret ) ) ;
2000-12-26 05:57:10 +00:00
2007-11-19 12:36:16 +01:00
TALLOC_FREE ( frame ) ;
2001-11-21 03:55:59 +00:00
return ret ; /* Success, ret bytes of data ... */
2000-12-26 05:57:10 +00:00
}
/*
* Routine to write ( ) a file . . .
*/
2005-12-29 15:06:53 +00:00
static ssize_t
smbc_write_ctx ( SMBCCTX * context ,
SMBCFILE * file ,
void * buf ,
size_t count )
2000-12-26 05:57:10 +00:00
{
2001-11-21 03:55:59 +00:00
int ret ;
2005-12-29 15:06:53 +00:00
off_t offset ;
2007-11-30 13:09:04 -08:00
char * server , * share , * user , * password ;
char * path ;
2007-11-29 17:25:41 -08:00
char * targetpath = NULL ;
2005-09-12 18:12:53 +00:00
struct cli_state * targetcli ;
2007-11-19 12:36:16 +01:00
TALLOC_CTX * frame = talloc_stackframe ( ) ;
2000-12-26 05:57:10 +00:00
2006-03-10 14:39:29 +00:00
/* First check all pointers before dereferencing them */
2007-11-29 17:25:41 -08:00
2003-01-13 20:04:40 +00:00
if ( ! context | | ! context - > internal | |
! context - > internal - > _initialized ) {
2001-11-21 03:55:59 +00:00
errno = EINVAL ;
2007-11-19 12:36:16 +01:00
TALLOC_FREE ( frame ) ;
2001-11-21 03:55:59 +00:00
return - 1 ;
2001-01-07 07:10:50 +00:00
2001-11-21 03:55:59 +00:00
}
2001-01-07 07:10:50 +00:00
2003-01-13 20:04:40 +00:00
if ( ! file | | ! DLIST_CONTAINS ( context - > internal - > _files , file ) ) {
2001-11-21 03:55:59 +00:00
errno = EBADF ;
2007-11-19 12:36:16 +01:00
TALLOC_FREE ( frame ) ;
2001-11-21 03:55:59 +00:00
return - 1 ;
}
2000-12-26 05:57:10 +00:00
2001-11-21 03:55:59 +00:00
/* Check that the buffer exists ... */
2001-02-26 11:53:22 +00:00
2001-11-21 03:55:59 +00:00
if ( buf = = NULL ) {
errno = EINVAL ;
2007-11-19 12:36:16 +01:00
TALLOC_FREE ( frame ) ;
2001-11-21 03:55:59 +00:00
return - 1 ;
2001-02-26 11:53:22 +00:00
2001-11-21 03:55:59 +00:00
}
2001-02-26 11:53:22 +00:00
2006-03-10 14:39:29 +00:00
offset = file - > offset ; /* See "offset" comment in smbc_read_ctx() */
2005-09-12 18:12:53 +00:00
/*d_printf(">>>write: parsing %s\n", file->fname);*/
2007-11-30 13:09:04 -08:00
if ( smbc_parse_path ( frame ,
context ,
file - > fname ,
NULL ,
& server ,
& share ,
& path ,
& user ,
& password ,
NULL ) ) {
2005-09-12 18:12:53 +00:00
errno = EINVAL ;
2007-11-19 12:36:16 +01:00
TALLOC_FREE ( frame ) ;
2005-09-12 18:12:53 +00:00
return - 1 ;
}
2007-11-29 17:25:41 -08:00
2005-09-12 18:12:53 +00:00
/*d_printf(">>>write: resolving %s\n", path);*/
2007-11-29 17:25:41 -08:00
if ( ! cli_resolve_path ( frame , " " , file - > srv - > cli , path ,
& targetcli , & targetpath ) ) {
2005-09-12 18:12:53 +00:00
d_printf ( " Could not resolve %s \n " , path ) ;
2007-11-19 12:36:16 +01:00
TALLOC_FREE ( frame ) ;
2005-09-12 18:12:53 +00:00
return - 1 ;
}
/*d_printf(">>>write: resolved path as %s\n", targetpath);*/
2006-07-31 03:53:39 +00:00
ret = cli_write ( targetcli , file - > cli_fd , 0 , ( char * ) buf , offset , count ) ;
2000-12-26 05:57:10 +00:00
2001-11-21 03:55:59 +00:00
if ( ret < = 0 ) {
2005-09-12 18:12:53 +00:00
errno = smbc_errno ( context , targetcli ) ;
2007-11-19 12:36:16 +01:00
TALLOC_FREE ( frame ) ;
2001-11-21 03:55:59 +00:00
return - 1 ;
2000-12-26 05:57:10 +00:00
2001-11-21 03:55:59 +00:00
}
2000-12-26 05:57:10 +00:00
2002-07-15 10:35:28 +00:00
file - > offset + = ret ;
2000-12-26 05:57:10 +00:00
2007-11-19 12:36:16 +01:00
TALLOC_FREE ( frame ) ;
2001-11-21 03:55:59 +00:00
return ret ; /* Success, 0 bytes of data ... */
2000-12-26 05:57:10 +00:00
}
2007-11-29 17:25:41 -08:00
2000-12-26 05:57:10 +00:00
/*
* Routine to close ( ) a file . . .
*/
2005-12-29 15:06:53 +00:00
static int
smbc_close_ctx ( SMBCCTX * context ,
SMBCFILE * file )
2000-12-26 05:57:10 +00:00
{
2007-11-29 17:25:41 -08:00
SMBCSRV * srv ;
2007-11-30 13:09:04 -08:00
char * server , * share , * user , * password ;
char * path ;
2007-11-29 17:25:41 -08:00
char * targetpath = NULL ;
2005-09-12 18:12:53 +00:00
struct cli_state * targetcli ;
2007-11-19 12:36:16 +01:00
TALLOC_CTX * frame = talloc_stackframe ( ) ;
2000-12-26 05:57:10 +00:00
2003-01-13 20:04:40 +00:00
if ( ! context | | ! context - > internal | |
! context - > internal - > _initialized ) {
2001-01-07 07:10:50 +00:00
2001-11-21 03:55:59 +00:00
errno = EINVAL ;
2007-11-19 12:36:16 +01:00
TALLOC_FREE ( frame ) ;
2001-11-21 03:55:59 +00:00
return - 1 ;
}
2001-01-07 07:10:50 +00:00
2003-01-13 20:04:40 +00:00
if ( ! file | | ! DLIST_CONTAINS ( context - > internal - > _files , file ) ) {
2001-11-21 03:55:59 +00:00
errno = EBADF ;
2007-11-19 12:36:16 +01:00
TALLOC_FREE ( frame ) ;
2001-11-21 03:55:59 +00:00
return - 1 ;
}
2000-12-26 05:57:10 +00:00
2002-07-15 10:35:28 +00:00
/* IS a dir ... */
if ( ! file - > file ) {
2007-11-19 12:36:16 +01:00
TALLOC_FREE ( frame ) ;
2007-09-06 13:21:31 +00:00
return ( context - > closedir ) ( context , file ) ;
2002-07-15 10:35:28 +00:00
}
2005-09-12 18:12:53 +00:00
/*d_printf(">>>close: parsing %s\n", file->fname);*/
2007-11-30 13:09:04 -08:00
if ( smbc_parse_path ( frame ,
context ,
file - > fname ,
NULL ,
& server ,
& share ,
& path ,
& user ,
& password ,
NULL ) ) {
2005-09-12 18:12:53 +00:00
errno = EINVAL ;
2007-11-19 12:36:16 +01:00
TALLOC_FREE ( frame ) ;
2005-09-12 18:12:53 +00:00
return - 1 ;
}
2007-11-29 17:25:41 -08:00
2005-09-12 18:12:53 +00:00
/*d_printf(">>>close: resolving %s\n", path);*/
2007-11-29 17:25:41 -08:00
if ( ! cli_resolve_path ( frame , " " , file - > srv - > cli , path ,
& targetcli , & targetpath ) ) {
2005-09-12 18:12:53 +00:00
d_printf ( " Could not resolve %s \n " , path ) ;
2007-11-19 12:36:16 +01:00
TALLOC_FREE ( frame ) ;
2005-09-12 18:12:53 +00:00
return - 1 ;
}
/*d_printf(">>>close: resolved path as %s\n", targetpath);*/
if ( ! cli_close ( targetcli , file - > cli_fd ) ) {
2002-07-15 10:35:28 +00:00
DEBUG ( 3 , ( " cli_close failed on %s. purging server. \n " ,
file - > fname ) ) ;
/* Deallocate slot and remove the server
* from the server cache if unused */
2005-09-12 18:12:53 +00:00
errno = smbc_errno ( context , targetcli ) ;
2002-07-15 10:35:28 +00:00
srv = file - > srv ;
2003-01-13 20:04:40 +00:00
DLIST_REMOVE ( context - > internal - > _files , file ) ;
2002-07-15 10:35:28 +00:00
SAFE_FREE ( file - > fname ) ;
SAFE_FREE ( file ) ;
2007-09-06 13:21:31 +00:00
( context - > callbacks . remove_unused_server_fn ) ( context , srv ) ;
2007-11-19 12:36:16 +01:00
TALLOC_FREE ( frame ) ;
2001-11-21 03:55:59 +00:00
return - 1 ;
2001-03-01 19:21:57 +00:00
2001-11-21 03:55:59 +00:00
}
2001-03-01 19:21:57 +00:00
2003-01-13 20:04:40 +00:00
DLIST_REMOVE ( context - > internal - > _files , file ) ;
2002-07-15 10:35:28 +00:00
SAFE_FREE ( file - > fname ) ;
SAFE_FREE ( file ) ;
2007-11-19 12:36:16 +01:00
TALLOC_FREE ( frame ) ;
2000-12-26 05:57:10 +00:00
2001-11-21 03:55:59 +00:00
return 0 ;
2000-12-26 05:57:10 +00:00
}
2002-07-15 10:35:28 +00:00
/*
* Get info from an SMB server on a file . Use a qpathinfo call first
* and if that fails , use getatr , as Win95 sometimes refuses qpathinfo
*/
2007-10-18 17:40:25 -07:00
static bool
2005-12-29 15:06:53 +00:00
smbc_getatr ( SMBCCTX * context ,
SMBCSRV * srv ,
2007-11-30 13:09:04 -08:00
char * path ,
2005-12-29 15:06:53 +00:00
uint16 * mode ,
2007-11-30 13:09:04 -08:00
SMB_OFF_T * size ,
r18009: Fixes bug 4026.
This completes the work Jeremy began last week, disambiguating the meaning of
c_time. (In POSIX terminology, c_time means "status Change time", not "create
time".) All uses of c_time, a_time and m_time have now been replaced with
change_time, access_time, and write_time, and when creation time is intended,
create_time is used.
Additionally, the capability of setting and retrieving the create time have
been added to the smbc_setxattr() and smbc_getxattr() functions. An example
of setting all four times can be seen with the program
examples/libsmbclient/testacl
with the following command line similar to:
testacl -f -S "system.*:CREATE_TIME:1000000000,ACCESS_TIME:1000000060,WRITE_TIME:1000000120,CHANGE_TIME:1000000180" 'smb://server/share/testfile.txt'
The -f option turns on the new mode which uses full time names in the
attribute specification (e.g. ACCESS_TIME vs A_TIME).
(This used to be commit 8e119b64f1d92026dda855d904be09912a40601c)
2006-09-02 21:47:56 +00:00
struct timespec * create_time_ts ,
struct timespec * access_time_ts ,
struct timespec * write_time_ts ,
struct timespec * change_time_ts ,
2005-12-29 15:06:53 +00:00
SMB_INO_T * ino )
2002-07-15 10:35:28 +00:00
{
2007-11-30 13:09:04 -08:00
char * fixedpath ;
2007-11-29 17:25:41 -08:00
char * targetpath = NULL ;
2005-09-12 18:12:53 +00:00
struct cli_state * targetcli ;
r18009: Fixes bug 4026.
This completes the work Jeremy began last week, disambiguating the meaning of
c_time. (In POSIX terminology, c_time means "status Change time", not "create
time".) All uses of c_time, a_time and m_time have now been replaced with
change_time, access_time, and write_time, and when creation time is intended,
create_time is used.
Additionally, the capability of setting and retrieving the create time have
been added to the smbc_setxattr() and smbc_getxattr() functions. An example
of setting all four times can be seen with the program
examples/libsmbclient/testacl
with the following command line similar to:
testacl -f -S "system.*:CREATE_TIME:1000000000,ACCESS_TIME:1000000060,WRITE_TIME:1000000120,CHANGE_TIME:1000000180" 'smb://server/share/testfile.txt'
The -f option turns on the new mode which uses full time names in the
attribute specification (e.g. ACCESS_TIME vs A_TIME).
(This used to be commit 8e119b64f1d92026dda855d904be09912a40601c)
2006-09-02 21:47:56 +00:00
time_t write_time ;
2007-11-19 12:36:16 +01:00
TALLOC_CTX * frame = talloc_stackframe ( ) ;
2005-12-29 15:06:53 +00:00
2003-01-13 20:04:40 +00:00
if ( ! context | | ! context - > internal | |
! context - > internal - > _initialized ) {
2002-07-15 10:35:28 +00:00
errno = EINVAL ;
2007-11-19 12:36:16 +01:00
TALLOC_FREE ( frame ) ;
2002-07-15 10:35:28 +00:00
return - 1 ;
}
2005-09-12 18:12:53 +00:00
/* path fixup for . and .. */
2007-11-30 13:09:04 -08:00
if ( strequal ( path , " . " ) | | strequal ( path , " .. " ) ) {
fixedpath = talloc_strdup ( frame , " \\ " ) ;
if ( ! fixedpath ) {
errno = ENOMEM ;
TALLOC_FREE ( frame ) ;
return - 1 ;
}
} else {
fixedpath = talloc_strdup ( frame , path ) ;
if ( ! fixedpath ) {
errno = ENOMEM ;
TALLOC_FREE ( frame ) ;
return - 1 ;
}
2005-09-12 18:12:53 +00:00
trim_string ( fixedpath , NULL , " \\ .. " ) ;
trim_string ( fixedpath , NULL , " \\ . " ) ;
}
2002-07-15 10:35:28 +00:00
DEBUG ( 4 , ( " smbc_getatr: sending qpathinfo \n " ) ) ;
2007-11-29 17:25:41 -08:00
if ( ! cli_resolve_path ( frame , " " , srv - > cli , fixedpath ,
& targetcli , & targetpath ) ) {
2005-09-12 18:12:53 +00:00
d_printf ( " Couldn't resolve %s \n " , path ) ;
2007-11-19 12:36:16 +01:00
TALLOC_FREE ( frame ) ;
2005-09-12 18:12:53 +00:00
return False ;
}
2007-11-29 17:25:41 -08:00
2002-07-15 10:35:28 +00:00
if ( ! srv - > no_pathinfo2 & &
2005-12-25 02:00:21 +00:00
cli_qpathinfo2 ( targetcli , targetpath ,
r18009: Fixes bug 4026.
This completes the work Jeremy began last week, disambiguating the meaning of
c_time. (In POSIX terminology, c_time means "status Change time", not "create
time".) All uses of c_time, a_time and m_time have now been replaced with
change_time, access_time, and write_time, and when creation time is intended,
create_time is used.
Additionally, the capability of setting and retrieving the create time have
been added to the smbc_setxattr() and smbc_getxattr() functions. An example
of setting all four times can be seen with the program
examples/libsmbclient/testacl
with the following command line similar to:
testacl -f -S "system.*:CREATE_TIME:1000000000,ACCESS_TIME:1000000060,WRITE_TIME:1000000120,CHANGE_TIME:1000000180" 'smb://server/share/testfile.txt'
The -f option turns on the new mode which uses full time names in the
attribute specification (e.g. ACCESS_TIME vs A_TIME).
(This used to be commit 8e119b64f1d92026dda855d904be09912a40601c)
2006-09-02 21:47:56 +00:00
create_time_ts ,
access_time_ts ,
write_time_ts ,
change_time_ts ,
size , mode , ino ) ) {
2007-11-19 12:36:16 +01:00
TALLOC_FREE ( frame ) ;
return True ;
2005-12-25 02:00:21 +00:00
}
2002-07-15 10:35:28 +00:00
/* if this is NT then don't bother with the getatr */
2005-09-12 18:12:53 +00:00
if ( targetcli - > capabilities & CAP_NT_SMBS ) {
2003-10-24 17:01:19 +00:00
errno = EPERM ;
2007-11-19 12:36:16 +01:00
TALLOC_FREE ( frame ) ;
2003-10-24 17:01:19 +00:00
return False ;
}
2002-07-15 10:35:28 +00:00
r18009: Fixes bug 4026.
This completes the work Jeremy began last week, disambiguating the meaning of
c_time. (In POSIX terminology, c_time means "status Change time", not "create
time".) All uses of c_time, a_time and m_time have now been replaced with
change_time, access_time, and write_time, and when creation time is intended,
create_time is used.
Additionally, the capability of setting and retrieving the create time have
been added to the smbc_setxattr() and smbc_getxattr() functions. An example
of setting all four times can be seen with the program
examples/libsmbclient/testacl
with the following command line similar to:
testacl -f -S "system.*:CREATE_TIME:1000000000,ACCESS_TIME:1000000060,WRITE_TIME:1000000120,CHANGE_TIME:1000000180" 'smb://server/share/testfile.txt'
The -f option turns on the new mode which uses full time names in the
attribute specification (e.g. ACCESS_TIME vs A_TIME).
(This used to be commit 8e119b64f1d92026dda855d904be09912a40601c)
2006-09-02 21:47:56 +00:00
if ( cli_getatr ( targetcli , targetpath , mode , size , & write_time ) ) {
struct timespec w_time_ts ;
w_time_ts = convert_time_t_to_timespec ( write_time ) ;
if ( write_time_ts ! = NULL ) {
* write_time_ts = w_time_ts ;
}
if ( create_time_ts ! = NULL ) {
* create_time_ts = w_time_ts ;
}
if ( access_time_ts ! = NULL ) {
* access_time_ts = w_time_ts ;
2005-06-01 17:40:40 +00:00
}
r18009: Fixes bug 4026.
This completes the work Jeremy began last week, disambiguating the meaning of
c_time. (In POSIX terminology, c_time means "status Change time", not "create
time".) All uses of c_time, a_time and m_time have now been replaced with
change_time, access_time, and write_time, and when creation time is intended,
create_time is used.
Additionally, the capability of setting and retrieving the create time have
been added to the smbc_setxattr() and smbc_getxattr() functions. An example
of setting all four times can be seen with the program
examples/libsmbclient/testacl
with the following command line similar to:
testacl -f -S "system.*:CREATE_TIME:1000000000,ACCESS_TIME:1000000060,WRITE_TIME:1000000120,CHANGE_TIME:1000000180" 'smb://server/share/testfile.txt'
The -f option turns on the new mode which uses full time names in the
attribute specification (e.g. ACCESS_TIME vs A_TIME).
(This used to be commit 8e119b64f1d92026dda855d904be09912a40601c)
2006-09-02 21:47:56 +00:00
if ( change_time_ts ! = NULL ) {
* change_time_ts = w_time_ts ;
}
2002-07-15 10:35:28 +00:00
srv - > no_pathinfo2 = True ;
2007-11-19 12:36:16 +01:00
TALLOC_FREE ( frame ) ;
2002-07-15 10:35:28 +00:00
return True ;
}
2003-10-24 17:01:19 +00:00
errno = EPERM ;
2007-11-19 12:36:16 +01:00
TALLOC_FREE ( frame ) ;
2002-07-15 10:35:28 +00:00
return False ;
}
2000-12-26 05:57:10 +00:00
/*
2005-06-01 20:17:16 +00:00
* Set file info on an SMB server . Use setpathinfo call first . If that
* fails , use setattrE . .
*
2005-06-01 20:25:33 +00:00
* Access and modification time parameters are always used and must be
* provided . Create time , if zero , will be determined from the actual create
* time of the file . If non - zero , the create time will be set as well .
*
2005-06-01 20:17:16 +00:00
* " mode " ( attributes ) parameter may be set to - 1 if it is not to be set .
2000-12-26 05:57:10 +00:00
*/
2007-10-18 17:40:25 -07:00
static bool
2005-12-29 15:06:53 +00:00
smbc_setatr ( SMBCCTX * context , SMBCSRV * srv , char * path ,
r18009: Fixes bug 4026.
This completes the work Jeremy began last week, disambiguating the meaning of
c_time. (In POSIX terminology, c_time means "status Change time", not "create
time".) All uses of c_time, a_time and m_time have now been replaced with
change_time, access_time, and write_time, and when creation time is intended,
create_time is used.
Additionally, the capability of setting and retrieving the create time have
been added to the smbc_setxattr() and smbc_getxattr() functions. An example
of setting all four times can be seen with the program
examples/libsmbclient/testacl
with the following command line similar to:
testacl -f -S "system.*:CREATE_TIME:1000000000,ACCESS_TIME:1000000060,WRITE_TIME:1000000120,CHANGE_TIME:1000000180" 'smb://server/share/testfile.txt'
The -f option turns on the new mode which uses full time names in the
attribute specification (e.g. ACCESS_TIME vs A_TIME).
(This used to be commit 8e119b64f1d92026dda855d904be09912a40601c)
2006-09-02 21:47:56 +00:00
time_t create_time ,
time_t access_time ,
time_t write_time ,
time_t change_time ,
2005-12-29 15:06:53 +00:00
uint16 mode )
2005-06-01 20:17:16 +00:00
{
int fd ;
int ret ;
2007-11-19 12:36:16 +01:00
TALLOC_CTX * frame = talloc_stackframe ( ) ;
2005-06-01 20:17:16 +00:00
/*
* First , try setpathinfo ( if qpathinfo succeeded ) , for it is the
* modern function for " new code " to be using , and it works given a
* filename rather than requiring that the file be opened to have its
* attributes manipulated .
*/
if ( srv - > no_pathinfo | |
r18009: Fixes bug 4026.
This completes the work Jeremy began last week, disambiguating the meaning of
c_time. (In POSIX terminology, c_time means "status Change time", not "create
time".) All uses of c_time, a_time and m_time have now been replaced with
change_time, access_time, and write_time, and when creation time is intended,
create_time is used.
Additionally, the capability of setting and retrieving the create time have
been added to the smbc_setxattr() and smbc_getxattr() functions. An example
of setting all four times can be seen with the program
examples/libsmbclient/testacl
with the following command line similar to:
testacl -f -S "system.*:CREATE_TIME:1000000000,ACCESS_TIME:1000000060,WRITE_TIME:1000000120,CHANGE_TIME:1000000180" 'smb://server/share/testfile.txt'
The -f option turns on the new mode which uses full time names in the
attribute specification (e.g. ACCESS_TIME vs A_TIME).
(This used to be commit 8e119b64f1d92026dda855d904be09912a40601c)
2006-09-02 21:47:56 +00:00
! cli_setpathinfo ( srv - > cli , path ,
create_time ,
access_time ,
write_time ,
change_time ,
mode ) ) {
2005-06-01 20:17:16 +00:00
/*
* setpathinfo is not supported ; go to plan B .
*
* cli_setatr ( ) does not work on win98 , and it also doesn ' t
* support setting the access time ( only the modification
* time ) , so in all cases , we open the specified file and use
* cli_setattrE ( ) which should work on all OS versions , and
* supports both times .
*/
2000-12-26 05:57:10 +00:00
2005-06-01 20:17:16 +00:00
/* Don't try {q,set}pathinfo() again, with this server */
srv - > no_pathinfo = True ;
/* Open the file */
2006-07-11 18:01:26 +00:00
if ( ( fd = cli_open ( srv - > cli , path , O_RDWR , DENY_NONE ) ) < 0 ) {
2005-06-01 20:17:16 +00:00
2006-07-11 18:01:26 +00:00
errno = smbc_errno ( context , srv - > cli ) ;
2007-11-19 12:36:16 +01:00
TALLOC_FREE ( frame ) ;
2005-06-01 20:17:16 +00:00
return - 1 ;
}
r18009: Fixes bug 4026.
This completes the work Jeremy began last week, disambiguating the meaning of
c_time. (In POSIX terminology, c_time means "status Change time", not "create
time".) All uses of c_time, a_time and m_time have now been replaced with
change_time, access_time, and write_time, and when creation time is intended,
create_time is used.
Additionally, the capability of setting and retrieving the create time have
been added to the smbc_setxattr() and smbc_getxattr() functions. An example
of setting all four times can be seen with the program
examples/libsmbclient/testacl
with the following command line similar to:
testacl -f -S "system.*:CREATE_TIME:1000000000,ACCESS_TIME:1000000060,WRITE_TIME:1000000120,CHANGE_TIME:1000000180" 'smb://server/share/testfile.txt'
The -f option turns on the new mode which uses full time names in the
attribute specification (e.g. ACCESS_TIME vs A_TIME).
(This used to be commit 8e119b64f1d92026dda855d904be09912a40601c)
2006-09-02 21:47:56 +00:00
/* Set the new attributes */
ret = cli_setattrE ( srv - > cli , fd ,
change_time ,
access_time ,
write_time ) ;
2005-06-01 20:17:16 +00:00
r18009: Fixes bug 4026.
This completes the work Jeremy began last week, disambiguating the meaning of
c_time. (In POSIX terminology, c_time means "status Change time", not "create
time".) All uses of c_time, a_time and m_time have now been replaced with
change_time, access_time, and write_time, and when creation time is intended,
create_time is used.
Additionally, the capability of setting and retrieving the create time have
been added to the smbc_setxattr() and smbc_getxattr() functions. An example
of setting all four times can be seen with the program
examples/libsmbclient/testacl
with the following command line similar to:
testacl -f -S "system.*:CREATE_TIME:1000000000,ACCESS_TIME:1000000060,WRITE_TIME:1000000120,CHANGE_TIME:1000000180" 'smb://server/share/testfile.txt'
The -f option turns on the new mode which uses full time names in the
attribute specification (e.g. ACCESS_TIME vs A_TIME).
(This used to be commit 8e119b64f1d92026dda855d904be09912a40601c)
2006-09-02 21:47:56 +00:00
/* Close the file */
cli_close ( srv - > cli , fd ) ;
2005-06-01 20:17:16 +00:00
/*
* Unfortunately , setattrE ( ) doesn ' t have a provision for
* setting the access mode ( attributes ) . We ' ll have to try
* cli_setatr ( ) for that , and with only this parameter , it
* seems to work on win98 .
*/
if ( ret & & mode ! = ( uint16 ) - 1 ) {
2006-07-11 18:01:26 +00:00
ret = cli_setatr ( srv - > cli , path , mode , 0 ) ;
2005-06-01 20:17:16 +00:00
}
if ( ! ret ) {
2006-07-11 18:01:26 +00:00
errno = smbc_errno ( context , srv - > cli ) ;
2007-11-19 12:36:16 +01:00
TALLOC_FREE ( frame ) ;
2005-06-01 20:17:16 +00:00
return False ;
}
}
2007-11-19 12:36:16 +01:00
TALLOC_FREE ( frame ) ;
2005-06-01 20:17:16 +00:00
return True ;
}
/*
* Routine to unlink ( ) a file
*/
2005-12-29 15:06:53 +00:00
static int
smbc_unlink_ctx ( SMBCCTX * context ,
const char * fname )
2000-12-26 05:57:10 +00:00
{
2007-11-30 13:09:04 -08:00
char * server , * share , * user , * password , * workgroup ;
char * path ;
2007-11-29 17:25:41 -08:00
char * targetpath ;
2005-09-12 18:12:53 +00:00
struct cli_state * targetcli ;
2002-07-15 10:35:28 +00:00
SMBCSRV * srv = NULL ;
2007-11-19 12:36:16 +01:00
TALLOC_CTX * frame = talloc_stackframe ( ) ;
2000-12-26 05:57:10 +00:00
2003-01-13 20:04:40 +00:00
if ( ! context | | ! context - > internal | |
! context - > internal - > _initialized ) {
2001-11-21 03:55:59 +00:00
errno = EINVAL ; /* Best I can think of ... */
2007-11-19 12:36:16 +01:00
TALLOC_FREE ( frame ) ;
2001-11-21 03:55:59 +00:00
return - 1 ;
2000-12-26 05:57:10 +00:00
2001-11-21 03:55:59 +00:00
}
2000-12-26 05:57:10 +00:00
2001-11-21 03:55:59 +00:00
if ( ! fname ) {
errno = EINVAL ;
2007-11-19 12:36:16 +01:00
TALLOC_FREE ( frame ) ;
2001-11-21 03:55:59 +00:00
return - 1 ;
2000-12-26 05:57:10 +00:00
2001-11-21 03:55:59 +00:00
}
2000-12-26 05:57:10 +00:00
2007-11-30 13:09:04 -08:00
if ( smbc_parse_path ( frame ,
context ,
fname ,
& workgroup ,
& server ,
& share ,
& path ,
& user ,
& password ,
NULL ) ) {
2004-03-19 16:22:47 +00:00
errno = EINVAL ;
2007-11-19 12:36:16 +01:00
TALLOC_FREE ( frame ) ;
2004-03-19 16:22:47 +00:00
return - 1 ;
}
2000-12-26 05:57:10 +00:00
2007-11-30 13:09:04 -08:00
if ( ! user | | user [ 0 ] = = ( char ) 0 ) {
user = talloc_strdup ( frame , context - > user ) ;
if ( ! user ) {
errno = ENOMEM ;
TALLOC_FREE ( frame ) ;
return - 1 ;
}
}
2001-01-12 05:10:45 +00:00
2005-12-29 15:06:59 +00:00
srv = smbc_server ( context , True ,
server , share , workgroup , user , password ) ;
2000-12-26 05:57:10 +00:00
2001-11-21 03:55:59 +00:00
if ( ! srv ) {
2007-11-19 12:36:16 +01:00
TALLOC_FREE ( frame ) ;
2001-11-21 03:55:59 +00:00
return - 1 ; /* smbc_server sets errno */
2000-12-26 05:57:10 +00:00
2001-11-21 03:55:59 +00:00
}
2000-12-26 05:57:10 +00:00
2005-09-12 18:12:53 +00:00
/*d_printf(">>>unlink: resolving %s\n", path);*/
2007-11-29 17:25:41 -08:00
if ( ! cli_resolve_path ( frame , " " , srv - > cli , path ,
& targetcli , & targetpath ) ) {
2005-09-12 18:12:53 +00:00
d_printf ( " Could not resolve %s \n " , path ) ;
2007-11-19 12:36:16 +01:00
TALLOC_FREE ( frame ) ;
2005-09-12 18:12:53 +00:00
return - 1 ;
}
/*d_printf(">>>unlink: resolved path as %s\n", targetpath);*/
2000-12-26 05:57:10 +00:00
2005-09-12 18:12:53 +00:00
if ( ! cli_unlink ( targetcli , targetpath ) ) {
errno = smbc_errno ( context , targetcli ) ;
2001-01-24 12:32:20 +00:00
2001-11-21 03:55:59 +00:00
if ( errno = = EACCES ) { /* Check if the file is a directory */
2001-01-24 12:32:20 +00:00
2001-11-21 03:55:59 +00:00
int saverr = errno ;
2005-03-22 21:17:01 +00:00
SMB_OFF_T size = 0 ;
2001-11-21 03:55:59 +00:00
uint16 mode = 0 ;
r18009: Fixes bug 4026.
This completes the work Jeremy began last week, disambiguating the meaning of
c_time. (In POSIX terminology, c_time means "status Change time", not "create
time".) All uses of c_time, a_time and m_time have now been replaced with
change_time, access_time, and write_time, and when creation time is intended,
create_time is used.
Additionally, the capability of setting and retrieving the create time have
been added to the smbc_setxattr() and smbc_getxattr() functions. An example
of setting all four times can be seen with the program
examples/libsmbclient/testacl
with the following command line similar to:
testacl -f -S "system.*:CREATE_TIME:1000000000,ACCESS_TIME:1000000060,WRITE_TIME:1000000120,CHANGE_TIME:1000000180" 'smb://server/share/testfile.txt'
The -f option turns on the new mode which uses full time names in the
attribute specification (e.g. ACCESS_TIME vs A_TIME).
(This used to be commit 8e119b64f1d92026dda855d904be09912a40601c)
2006-09-02 21:47:56 +00:00
struct timespec write_time_ts ;
struct timespec access_time_ts ;
struct timespec change_time_ts ;
2001-11-21 03:55:59 +00:00
SMB_INO_T ino = 0 ;
2001-01-24 12:32:20 +00:00
2002-07-15 10:35:28 +00:00
if ( ! smbc_getatr ( context , srv , path , & mode , & size ,
r18009: Fixes bug 4026.
This completes the work Jeremy began last week, disambiguating the meaning of
c_time. (In POSIX terminology, c_time means "status Change time", not "create
time".) All uses of c_time, a_time and m_time have now been replaced with
change_time, access_time, and write_time, and when creation time is intended,
create_time is used.
Additionally, the capability of setting and retrieving the create time have
been added to the smbc_setxattr() and smbc_getxattr() functions. An example
of setting all four times can be seen with the program
examples/libsmbclient/testacl
with the following command line similar to:
testacl -f -S "system.*:CREATE_TIME:1000000000,ACCESS_TIME:1000000060,WRITE_TIME:1000000120,CHANGE_TIME:1000000180" 'smb://server/share/testfile.txt'
The -f option turns on the new mode which uses full time names in the
attribute specification (e.g. ACCESS_TIME vs A_TIME).
(This used to be commit 8e119b64f1d92026dda855d904be09912a40601c)
2006-09-02 21:47:56 +00:00
NULL ,
& access_time_ts ,
& write_time_ts ,
& change_time_ts ,
& ino ) ) {
2001-01-24 12:32:20 +00:00
2001-11-21 03:55:59 +00:00
/* Hmmm, bad error ... What? */
2001-01-24 12:32:20 +00:00
2005-09-12 18:12:53 +00:00
errno = smbc_errno ( context , targetcli ) ;
2007-11-19 12:36:16 +01:00
TALLOC_FREE ( frame ) ;
2001-11-21 03:55:59 +00:00
return - 1 ;
2001-01-24 12:32:20 +00:00
2001-11-21 03:55:59 +00:00
}
else {
2001-01-24 12:32:20 +00:00
2001-11-21 03:55:59 +00:00
if ( IS_DOS_DIR ( mode ) )
errno = EISDIR ;
else
errno = saverr ; /* Restore this */
2001-01-24 12:32:20 +00:00
2001-11-21 03:55:59 +00:00
}
}
2001-01-24 12:32:20 +00:00
2007-11-19 12:36:16 +01:00
TALLOC_FREE ( frame ) ;
2001-11-21 03:55:59 +00:00
return - 1 ;
2000-12-26 05:57:10 +00:00
2001-11-21 03:55:59 +00:00
}
2000-12-26 05:57:10 +00:00
2007-11-19 12:36:16 +01:00
TALLOC_FREE ( frame ) ;
2001-11-21 03:55:59 +00:00
return 0 ; /* Success ... */
2000-12-26 05:57:10 +00:00
}
/*
* Routine to rename ( ) a file
*/
2005-12-29 15:06:53 +00:00
static int
smbc_rename_ctx ( SMBCCTX * ocontext ,
const char * oname ,
SMBCCTX * ncontext ,
const char * nname )
2000-12-26 05:57:10 +00:00
{
2007-11-30 13:09:04 -08:00
char * server1 ;
char * share1 ;
char * server2 ;
char * share2 ;
char * user1 ;
char * user2 ;
char * password1 ;
char * password2 ;
char * workgroup ;
char * path1 ;
char * path2 ;
2007-11-29 17:25:41 -08:00
char * targetpath1 ;
char * targetpath2 ;
2005-12-29 15:06:53 +00:00
struct cli_state * targetcli1 ;
struct cli_state * targetcli2 ;
2002-07-15 10:35:28 +00:00
SMBCSRV * srv = NULL ;
2007-11-19 12:36:16 +01:00
TALLOC_CTX * frame = talloc_stackframe ( ) ;
2000-12-26 05:57:10 +00:00
2007-11-29 17:25:41 -08:00
if ( ! ocontext | | ! ncontext | |
2003-01-13 20:04:40 +00:00
! ocontext - > internal | | ! ncontext - > internal | |
2007-11-29 17:25:41 -08:00
! ocontext - > internal - > _initialized | |
2003-01-13 20:04:40 +00:00
! ncontext - > internal - > _initialized ) {
2001-11-21 03:55:59 +00:00
errno = EINVAL ; /* Best I can think of ... */
2007-11-19 12:36:16 +01:00
TALLOC_FREE ( frame ) ;
2001-11-21 03:55:59 +00:00
return - 1 ;
}
2000-12-26 05:57:10 +00:00
2007-11-29 17:25:41 -08:00
if ( ! oname | | ! nname ) {
2001-11-21 03:55:59 +00:00
errno = EINVAL ;
2007-11-19 12:36:16 +01:00
TALLOC_FREE ( frame ) ;
2001-11-21 03:55:59 +00:00
return - 1 ;
}
2007-11-29 17:25:41 -08:00
2001-11-21 03:55:59 +00:00
DEBUG ( 4 , ( " smbc_rename(%s,%s) \n " , oname , nname ) ) ;
2000-12-26 05:57:10 +00:00
2007-11-30 13:09:04 -08:00
if ( smbc_parse_path ( frame ,
ocontext ,
oname ,
& workgroup ,
& server1 ,
& share1 ,
& path1 ,
& user1 ,
& password1 ,
NULL ) ) {
errno = EINVAL ;
TALLOC_FREE ( frame ) ;
return - 1 ;
}
2001-01-12 05:10:45 +00:00
2007-11-30 13:09:04 -08:00
if ( ! user1 | | user1 [ 0 ] = = ( char ) 0 ) {
user1 = talloc_strdup ( frame , ocontext - > user ) ;
if ( ! user1 ) {
errno = ENOMEM ;
TALLOC_FREE ( frame ) ;
return - 1 ;
}
}
2001-01-12 05:10:45 +00:00
2007-11-30 13:09:04 -08:00
if ( smbc_parse_path ( frame ,
ncontext ,
nname ,
NULL ,
& server2 ,
& share2 ,
& path2 ,
& user2 ,
& password2 ,
NULL ) ) {
errno = EINVAL ;
TALLOC_FREE ( frame ) ;
return - 1 ;
}
2000-12-26 05:57:10 +00:00
2007-11-30 13:09:04 -08:00
if ( ! user2 | | user2 [ 0 ] = = ( char ) 0 ) {
user2 = talloc_strdup ( frame , ncontext - > user ) ;
if ( ! user2 ) {
errno = ENOMEM ;
TALLOC_FREE ( frame ) ;
return - 1 ;
}
}
2000-12-26 05:57:10 +00:00
2001-11-21 03:55:59 +00:00
if ( strcmp ( server1 , server2 ) | | strcmp ( share1 , share2 ) | |
strcmp ( user1 , user2 ) ) {
/* Can't rename across file systems, or users?? */
errno = EXDEV ;
2007-11-19 12:36:16 +01:00
TALLOC_FREE ( frame ) ;
2001-11-21 03:55:59 +00:00
return - 1 ;
}
2000-12-26 05:57:10 +00:00
2005-12-29 15:06:59 +00:00
srv = smbc_server ( ocontext , True ,
server1 , share1 , workgroup , user1 , password1 ) ;
2001-11-21 03:55:59 +00:00
if ( ! srv ) {
2007-11-19 12:36:16 +01:00
TALLOC_FREE ( frame ) ;
2001-11-21 03:55:59 +00:00
return - 1 ;
2000-12-26 05:57:10 +00:00
2001-11-21 03:55:59 +00:00
}
2000-12-26 05:57:10 +00:00
2005-09-12 18:12:53 +00:00
/*d_printf(">>>rename: resolving %s\n", path1);*/
2007-11-29 17:25:41 -08:00
if ( ! cli_resolve_path ( frame , " " , srv - > cli , path1 ,
& targetcli1 , & targetpath1 ) ) {
2005-09-12 18:12:53 +00:00
d_printf ( " Could not resolve %s \n " , path1 ) ;
2007-11-19 12:36:16 +01:00
TALLOC_FREE ( frame ) ;
2005-09-12 18:12:53 +00:00
return - 1 ;
}
/*d_printf(">>>rename: resolved path as %s\n", targetpath1);*/
/*d_printf(">>>rename: resolving %s\n", path2);*/
2007-11-29 17:25:41 -08:00
if ( ! cli_resolve_path ( frame , " " , srv - > cli , path2 ,
& targetcli2 , & targetpath2 ) ) {
2005-09-12 18:12:53 +00:00
d_printf ( " Could not resolve %s \n " , path2 ) ;
2007-11-19 12:36:16 +01:00
TALLOC_FREE ( frame ) ;
2005-09-12 18:12:53 +00:00
return - 1 ;
}
/*d_printf(">>>rename: resolved path as %s\n", targetpath2);*/
2007-11-29 17:25:41 -08:00
2005-12-29 15:06:53 +00:00
if ( strcmp ( targetcli1 - > desthost , targetcli2 - > desthost ) | |
strcmp ( targetcli1 - > share , targetcli2 - > share ) )
2005-09-12 18:12:53 +00:00
{
/* can't rename across file systems */
errno = EXDEV ;
2007-11-19 12:36:16 +01:00
TALLOC_FREE ( frame ) ;
2005-09-12 18:12:53 +00:00
return - 1 ;
}
if ( ! cli_rename ( targetcli1 , targetpath1 , targetpath2 ) ) {
int eno = smbc_errno ( ocontext , targetcli1 ) ;
2000-12-26 05:57:10 +00:00
2001-11-21 03:55:59 +00:00
if ( eno ! = EEXIST | |
2005-09-12 18:12:53 +00:00
! cli_unlink ( targetcli1 , targetpath2 ) | |
! cli_rename ( targetcli1 , targetpath1 , targetpath2 ) ) {
2000-12-26 05:57:10 +00:00
2001-11-21 03:55:59 +00:00
errno = eno ;
2007-11-19 12:36:16 +01:00
TALLOC_FREE ( frame ) ;
2001-11-21 03:55:59 +00:00
return - 1 ;
2000-12-26 05:57:10 +00:00
2001-11-21 03:55:59 +00:00
}
}
2000-12-26 05:57:10 +00:00
2007-11-19 12:36:16 +01:00
TALLOC_FREE ( frame ) ;
2001-11-21 03:55:59 +00:00
return 0 ; /* Success */
2000-12-26 05:57:10 +00:00
}
/*
* A routine to lseek ( ) a file
*/
2005-12-29 15:06:53 +00:00
static off_t
smbc_lseek_ctx ( SMBCCTX * context ,
SMBCFILE * file ,
off_t offset ,
int whence )
2000-12-26 05:57:10 +00:00
{
2005-03-22 21:17:01 +00:00
SMB_OFF_T size ;
2007-11-30 13:09:04 -08:00
char * server , * share , * user , * password ;
char * path ;
2007-11-29 17:25:41 -08:00
char * targetpath ;
2005-09-12 18:12:53 +00:00
struct cli_state * targetcli ;
2007-11-29 13:24:54 -08:00
TALLOC_CTX * frame = talloc_stackframe ( ) ;
2000-12-26 05:57:10 +00:00
2003-01-13 20:04:40 +00:00
if ( ! context | | ! context - > internal | |
! context - > internal - > _initialized ) {
2001-11-21 03:55:59 +00:00
errno = EINVAL ;
2007-11-19 12:36:16 +01:00
TALLOC_FREE ( frame ) ;
2001-11-21 03:55:59 +00:00
return - 1 ;
}
2000-12-26 05:57:10 +00:00
2003-01-13 20:04:40 +00:00
if ( ! file | | ! DLIST_CONTAINS ( context - > internal - > _files , file ) ) {
2001-03-01 19:21:57 +00:00
2001-11-21 03:55:59 +00:00
errno = EBADF ;
2007-11-19 12:36:16 +01:00
TALLOC_FREE ( frame ) ;
2001-11-21 03:55:59 +00:00
return - 1 ;
2001-03-01 19:21:57 +00:00
2001-11-21 03:55:59 +00:00
}
2001-03-01 19:21:57 +00:00
2002-07-15 10:35:28 +00:00
if ( ! file - > file ) {
2000-12-26 05:57:10 +00:00
2001-11-21 03:55:59 +00:00
errno = EINVAL ;
2007-11-19 12:36:16 +01:00
TALLOC_FREE ( frame ) ;
2001-11-21 03:55:59 +00:00
return - 1 ; /* Can't lseek a dir ... */
2000-12-26 05:57:10 +00:00
2001-11-21 03:55:59 +00:00
}
2000-12-26 05:57:10 +00:00
2001-11-21 03:55:59 +00:00
switch ( whence ) {
case SEEK_SET :
2002-07-15 10:35:28 +00:00
file - > offset = offset ;
2001-11-21 03:55:59 +00:00
break ;
2000-12-26 05:57:10 +00:00
2001-11-21 03:55:59 +00:00
case SEEK_CUR :
2002-07-15 10:35:28 +00:00
file - > offset + = offset ;
2001-11-21 03:55:59 +00:00
break ;
2000-12-26 05:57:10 +00:00
2001-11-21 03:55:59 +00:00
case SEEK_END :
2005-09-12 18:12:53 +00:00
/*d_printf(">>>lseek: parsing %s\n", file->fname);*/
2007-11-30 13:09:04 -08:00
if ( smbc_parse_path ( frame ,
context ,
file - > fname ,
NULL ,
& server ,
& share ,
& path ,
& user ,
& password ,
NULL ) ) {
errno = EINVAL ;
TALLOC_FREE ( frame ) ;
return - 1 ;
}
2007-11-29 17:25:41 -08:00
2005-09-12 18:12:53 +00:00
/*d_printf(">>>lseek: resolving %s\n", path);*/
2007-11-29 17:25:41 -08:00
if ( ! cli_resolve_path ( frame , " " , file - > srv - > cli , path ,
& targetcli , & targetpath ) ) {
2005-09-12 18:12:53 +00:00
d_printf ( " Could not resolve %s \n " , path ) ;
2007-11-19 12:36:16 +01:00
TALLOC_FREE ( frame ) ;
2005-09-12 18:12:53 +00:00
return - 1 ;
}
/*d_printf(">>>lseek: resolved path as %s\n", targetpath);*/
2007-11-29 17:25:41 -08:00
2005-12-29 15:06:53 +00:00
if ( ! cli_qfileinfo ( targetcli , file - > cli_fd , NULL ,
2007-11-29 17:25:41 -08:00
& size , NULL , NULL , NULL , NULL , NULL ) )
2003-04-16 14:45:11 +00:00
{
2005-09-30 17:13:37 +00:00
SMB_OFF_T b_size = size ;
2005-12-29 15:06:53 +00:00
if ( ! cli_getattrE ( targetcli , file - > cli_fd ,
2007-11-29 17:25:41 -08:00
NULL , & b_size , NULL , NULL , NULL ) )
2003-04-16 14:45:11 +00:00
{
2001-11-21 03:55:59 +00:00
errno = EINVAL ;
2007-11-19 12:36:16 +01:00
TALLOC_FREE ( frame ) ;
2001-11-21 03:55:59 +00:00
return - 1 ;
2003-04-16 14:45:11 +00:00
} else
size = b_size ;
2001-11-21 03:55:59 +00:00
}
2002-07-15 10:35:28 +00:00
file - > offset = size + offset ;
2001-11-21 03:55:59 +00:00
break ;
2000-12-26 05:57:10 +00:00
2001-11-21 03:55:59 +00:00
default :
errno = EINVAL ;
break ;
2000-12-26 05:57:10 +00:00
2001-11-21 03:55:59 +00:00
}
2000-12-26 05:57:10 +00:00
2007-11-19 12:36:16 +01:00
TALLOC_FREE ( frame ) ;
2002-07-15 10:35:28 +00:00
return file - > offset ;
2000-12-26 05:57:10 +00:00
}
/*
* Generate an inode number from file name for those things that need it
*/
2005-12-29 15:06:53 +00:00
static ino_t
smbc_inode ( SMBCCTX * context ,
const char * name )
2000-12-26 05:57:10 +00:00
{
2003-01-13 20:04:40 +00:00
if ( ! context | | ! context - > internal | |
! context - > internal - > _initialized ) {
2002-07-15 10:35:28 +00:00
errno = EINVAL ;
return - 1 ;
}
2001-11-21 03:55:59 +00:00
if ( ! * name ) return 2 ; /* FIXME, why 2 ??? */
return ( ino_t ) str_checksum ( name ) ;
2000-12-26 05:57:10 +00:00
}
/*
* Routine to put basic stat info into a stat structure . . . Used by stat and
* fstat below .
*/
2005-12-29 15:06:53 +00:00
static int
smbc_setup_stat ( SMBCCTX * context ,
struct stat * st ,
char * fname ,
SMB_OFF_T size ,
int mode )
2000-12-26 05:57:10 +00:00
{
2007-11-19 12:36:16 +01:00
TALLOC_CTX * frame = talloc_stackframe ( ) ;
2002-07-15 10:35:28 +00:00
2001-11-21 03:55:59 +00:00
st - > st_mode = 0 ;
2000-12-26 05:57:10 +00:00
2001-11-21 03:55:59 +00:00
if ( IS_DOS_DIR ( mode ) ) {
st - > st_mode = SMBC_DIR_MODE ;
} else {
st - > st_mode = SMBC_FILE_MODE ;
}
2000-12-26 05:57:10 +00:00
2001-11-21 03:55:59 +00:00
if ( IS_DOS_ARCHIVE ( mode ) ) st - > st_mode | = S_IXUSR ;
if ( IS_DOS_SYSTEM ( mode ) ) st - > st_mode | = S_IXGRP ;
if ( IS_DOS_HIDDEN ( mode ) ) st - > st_mode | = S_IXOTH ;
if ( ! IS_DOS_READONLY ( mode ) ) st - > st_mode | = S_IWUSR ;
st - > st_size = size ;
2003-10-14 03:56:42 +00:00
# ifdef HAVE_STAT_ST_BLKSIZE
2001-11-21 03:55:59 +00:00
st - > st_blksize = 512 ;
2003-10-14 03:56:42 +00:00
# endif
# ifdef HAVE_STAT_ST_BLOCKS
2001-11-21 03:55:59 +00:00
st - > st_blocks = ( size + 511 ) / 512 ;
2003-10-14 03:56:42 +00:00
# endif
2001-11-21 03:55:59 +00:00
st - > st_uid = getuid ( ) ;
st - > st_gid = getgid ( ) ;
if ( IS_DOS_DIR ( mode ) ) {
st - > st_nlink = 2 ;
} else {
st - > st_nlink = 1 ;
}
2000-12-26 05:57:10 +00:00
2001-11-21 03:55:59 +00:00
if ( st - > st_ino = = 0 ) {
2002-07-15 10:35:28 +00:00
st - > st_ino = smbc_inode ( context , fname ) ;
2001-11-21 03:55:59 +00:00
}
2002-07-15 10:35:28 +00:00
2007-11-19 12:36:16 +01:00
TALLOC_FREE ( frame ) ;
2001-11-21 03:55:59 +00:00
return True ; /* FIXME: Is this needed ? */
2001-02-26 11:53:22 +00:00
2000-12-26 05:57:10 +00:00
}
/*
* Routine to stat a file given a name
*/
2005-12-29 15:06:53 +00:00
static int
smbc_stat_ctx ( SMBCCTX * context ,
const char * fname ,
struct stat * st )
2000-12-26 05:57:10 +00:00
{
2002-07-15 10:35:28 +00:00
SMBCSRV * srv ;
2007-11-30 13:09:04 -08:00
char * server ;
char * share ;
char * user ;
char * password ;
char * workgroup ;
char * path ;
r18009: Fixes bug 4026.
This completes the work Jeremy began last week, disambiguating the meaning of
c_time. (In POSIX terminology, c_time means "status Change time", not "create
time".) All uses of c_time, a_time and m_time have now been replaced with
change_time, access_time, and write_time, and when creation time is intended,
create_time is used.
Additionally, the capability of setting and retrieving the create time have
been added to the smbc_setxattr() and smbc_getxattr() functions. An example
of setting all four times can be seen with the program
examples/libsmbclient/testacl
with the following command line similar to:
testacl -f -S "system.*:CREATE_TIME:1000000000,ACCESS_TIME:1000000060,WRITE_TIME:1000000120,CHANGE_TIME:1000000180" 'smb://server/share/testfile.txt'
The -f option turns on the new mode which uses full time names in the
attribute specification (e.g. ACCESS_TIME vs A_TIME).
(This used to be commit 8e119b64f1d92026dda855d904be09912a40601c)
2006-09-02 21:47:56 +00:00
struct timespec write_time_ts ;
struct timespec access_time_ts ;
struct timespec change_time_ts ;
2005-03-22 21:17:01 +00:00
SMB_OFF_T size = 0 ;
2001-11-21 03:55:59 +00:00
uint16 mode = 0 ;
SMB_INO_T ino = 0 ;
2007-11-19 12:36:16 +01:00
TALLOC_CTX * frame = talloc_stackframe ( ) ;
2000-12-26 05:57:10 +00:00
2003-01-13 20:04:40 +00:00
if ( ! context | | ! context - > internal | |
! context - > internal - > _initialized ) {
2000-12-26 05:57:10 +00:00
2001-11-21 03:55:59 +00:00
errno = EINVAL ; /* Best I can think of ... */
2007-11-19 12:36:16 +01:00
TALLOC_FREE ( frame ) ;
2001-11-21 03:55:59 +00:00
return - 1 ;
}
2000-12-26 05:57:10 +00:00
2001-11-21 03:55:59 +00:00
if ( ! fname ) {
errno = EINVAL ;
2007-11-19 12:36:16 +01:00
TALLOC_FREE ( frame ) ;
2001-11-21 03:55:59 +00:00
return - 1 ;
}
2007-11-30 13:09:04 -08:00
2001-11-21 03:55:59 +00:00
DEBUG ( 4 , ( " smbc_stat(%s) \n " , fname ) ) ;
2000-12-26 05:57:10 +00:00
2007-11-30 13:09:04 -08:00
if ( smbc_parse_path ( frame ,
context ,
fname ,
& workgroup ,
& server ,
& share ,
& path ,
& user ,
& password ,
NULL ) ) {
errno = EINVAL ;
2007-11-19 12:36:16 +01:00
TALLOC_FREE ( frame ) ;
2004-03-19 16:22:47 +00:00
return - 1 ;
}
2001-01-12 05:10:45 +00:00
2007-11-30 13:09:04 -08:00
if ( ! user | | user [ 0 ] = = ( char ) 0 ) {
user = talloc_strdup ( frame , context - > user ) ;
if ( ! user ) {
errno = ENOMEM ;
TALLOC_FREE ( frame ) ;
return - 1 ;
}
}
2000-12-26 05:57:10 +00:00
2005-12-29 15:06:59 +00:00
srv = smbc_server ( context , True ,
server , share , workgroup , user , password ) ;
2000-12-26 05:57:10 +00:00
2001-11-21 03:55:59 +00:00
if ( ! srv ) {
2007-11-19 12:36:16 +01:00
TALLOC_FREE ( frame ) ;
2001-11-21 03:55:59 +00:00
return - 1 ; /* errno set by smbc_server */
}
2000-12-26 05:57:10 +00:00
2007-11-30 13:09:04 -08:00
if ( ! smbc_getatr ( context , srv , path , & mode , & size ,
r18009: Fixes bug 4026.
This completes the work Jeremy began last week, disambiguating the meaning of
c_time. (In POSIX terminology, c_time means "status Change time", not "create
time".) All uses of c_time, a_time and m_time have now been replaced with
change_time, access_time, and write_time, and when creation time is intended,
create_time is used.
Additionally, the capability of setting and retrieving the create time have
been added to the smbc_setxattr() and smbc_getxattr() functions. An example
of setting all four times can be seen with the program
examples/libsmbclient/testacl
with the following command line similar to:
testacl -f -S "system.*:CREATE_TIME:1000000000,ACCESS_TIME:1000000060,WRITE_TIME:1000000120,CHANGE_TIME:1000000180" 'smb://server/share/testfile.txt'
The -f option turns on the new mode which uses full time names in the
attribute specification (e.g. ACCESS_TIME vs A_TIME).
(This used to be commit 8e119b64f1d92026dda855d904be09912a40601c)
2006-09-02 21:47:56 +00:00
NULL ,
& access_time_ts ,
& write_time_ts ,
& change_time_ts ,
& ino ) ) {
2006-07-11 18:01:26 +00:00
errno = smbc_errno ( context , srv - > cli ) ;
2007-11-19 12:36:16 +01:00
TALLOC_FREE ( frame ) ;
2001-11-21 03:55:59 +00:00
return - 1 ;
}
2000-12-26 05:57:10 +00:00
2001-11-21 03:55:59 +00:00
st - > st_ino = ino ;
2000-12-26 05:57:10 +00:00
2002-07-15 10:35:28 +00:00
smbc_setup_stat ( context , st , path , size , mode ) ;
2000-12-26 05:57:10 +00:00
r18009: Fixes bug 4026.
This completes the work Jeremy began last week, disambiguating the meaning of
c_time. (In POSIX terminology, c_time means "status Change time", not "create
time".) All uses of c_time, a_time and m_time have now been replaced with
change_time, access_time, and write_time, and when creation time is intended,
create_time is used.
Additionally, the capability of setting and retrieving the create time have
been added to the smbc_setxattr() and smbc_getxattr() functions. An example
of setting all four times can be seen with the program
examples/libsmbclient/testacl
with the following command line similar to:
testacl -f -S "system.*:CREATE_TIME:1000000000,ACCESS_TIME:1000000060,WRITE_TIME:1000000120,CHANGE_TIME:1000000180" 'smb://server/share/testfile.txt'
The -f option turns on the new mode which uses full time names in the
attribute specification (e.g. ACCESS_TIME vs A_TIME).
(This used to be commit 8e119b64f1d92026dda855d904be09912a40601c)
2006-09-02 21:47:56 +00:00
set_atimespec ( st , access_time_ts ) ;
set_ctimespec ( st , change_time_ts ) ;
set_mtimespec ( st , write_time_ts ) ;
2001-11-21 03:55:59 +00:00
st - > st_dev = srv - > dev ;
2000-12-26 05:57:10 +00:00
2007-11-19 12:36:16 +01:00
TALLOC_FREE ( frame ) ;
2001-11-21 03:55:59 +00:00
return 0 ;
2000-12-26 05:57:10 +00:00
}
/*
* Routine to stat a file given an fd
*/
2005-12-29 15:06:53 +00:00
static int
smbc_fstat_ctx ( SMBCCTX * context ,
SMBCFILE * file ,
struct stat * st )
2000-12-26 05:57:10 +00:00
{
r18009: Fixes bug 4026.
This completes the work Jeremy began last week, disambiguating the meaning of
c_time. (In POSIX terminology, c_time means "status Change time", not "create
time".) All uses of c_time, a_time and m_time have now been replaced with
change_time, access_time, and write_time, and when creation time is intended,
create_time is used.
Additionally, the capability of setting and retrieving the create time have
been added to the smbc_setxattr() and smbc_getxattr() functions. An example
of setting all four times can be seen with the program
examples/libsmbclient/testacl
with the following command line similar to:
testacl -f -S "system.*:CREATE_TIME:1000000000,ACCESS_TIME:1000000060,WRITE_TIME:1000000120,CHANGE_TIME:1000000180" 'smb://server/share/testfile.txt'
The -f option turns on the new mode which uses full time names in the
attribute specification (e.g. ACCESS_TIME vs A_TIME).
(This used to be commit 8e119b64f1d92026dda855d904be09912a40601c)
2006-09-02 21:47:56 +00:00
struct timespec change_time_ts ;
struct timespec access_time_ts ;
struct timespec write_time_ts ;
2005-03-22 21:17:01 +00:00
SMB_OFF_T size ;
2001-11-21 03:55:59 +00:00
uint16 mode ;
2007-11-30 13:09:04 -08:00
char * server ;
char * share ;
char * user ;
char * password ;
char * path ;
2007-11-29 17:25:41 -08:00
char * targetpath ;
2005-09-12 18:12:53 +00:00
struct cli_state * targetcli ;
2001-11-21 03:55:59 +00:00
SMB_INO_T ino = 0 ;
2007-11-19 12:36:16 +01:00
TALLOC_CTX * frame = talloc_stackframe ( ) ;
2000-12-26 05:57:10 +00:00
2003-01-13 20:04:40 +00:00
if ( ! context | | ! context - > internal | |
! context - > internal - > _initialized ) {
2001-11-21 03:55:59 +00:00
errno = EINVAL ;
2007-11-19 12:36:16 +01:00
TALLOC_FREE ( frame ) ;
2001-11-21 03:55:59 +00:00
return - 1 ;
}
2001-01-07 07:10:50 +00:00
2003-01-13 20:04:40 +00:00
if ( ! file | | ! DLIST_CONTAINS ( context - > internal - > _files , file ) ) {
2001-11-21 03:55:59 +00:00
errno = EBADF ;
2007-11-19 12:36:16 +01:00
TALLOC_FREE ( frame ) ;
2001-11-21 03:55:59 +00:00
return - 1 ;
}
2000-12-26 05:57:10 +00:00
2002-07-15 10:35:28 +00:00
if ( ! file - > file ) {
2007-11-19 12:36:16 +01:00
TALLOC_FREE ( frame ) ;
2007-09-06 13:21:31 +00:00
return ( context - > fstatdir ) ( context , file , st ) ;
2001-11-21 03:55:59 +00:00
}
2000-12-26 05:57:10 +00:00
2005-09-12 18:12:53 +00:00
/*d_printf(">>>fstat: parsing %s\n", file->fname);*/
2007-11-30 13:09:04 -08:00
if ( smbc_parse_path ( frame ,
context ,
file - > fname ,
NULL ,
& server ,
& share ,
& path ,
& user ,
& password ,
NULL ) ) {
2005-09-12 18:12:53 +00:00
errno = EINVAL ;
2007-11-19 12:36:16 +01:00
TALLOC_FREE ( frame ) ;
2005-09-12 18:12:53 +00:00
return - 1 ;
}
2007-11-29 17:25:41 -08:00
2005-09-12 18:12:53 +00:00
/*d_printf(">>>fstat: resolving %s\n", path);*/
2007-11-29 17:25:41 -08:00
if ( ! cli_resolve_path ( frame , " " , file - > srv - > cli , path ,
& targetcli , & targetpath ) ) {
2005-09-12 18:12:53 +00:00
d_printf ( " Could not resolve %s \n " , path ) ;
2007-11-19 12:36:16 +01:00
TALLOC_FREE ( frame ) ;
2005-09-12 18:12:53 +00:00
return - 1 ;
}
/*d_printf(">>>fstat: resolved path as %s\n", targetpath);*/
2005-12-29 15:06:53 +00:00
if ( ! cli_qfileinfo ( targetcli , file - > cli_fd , & mode , & size ,
r18009: Fixes bug 4026.
This completes the work Jeremy began last week, disambiguating the meaning of
c_time. (In POSIX terminology, c_time means "status Change time", not "create
time".) All uses of c_time, a_time and m_time have now been replaced with
change_time, access_time, and write_time, and when creation time is intended,
create_time is used.
Additionally, the capability of setting and retrieving the create time have
been added to the smbc_setxattr() and smbc_getxattr() functions. An example
of setting all four times can be seen with the program
examples/libsmbclient/testacl
with the following command line similar to:
testacl -f -S "system.*:CREATE_TIME:1000000000,ACCESS_TIME:1000000060,WRITE_TIME:1000000120,CHANGE_TIME:1000000180" 'smb://server/share/testfile.txt'
The -f option turns on the new mode which uses full time names in the
attribute specification (e.g. ACCESS_TIME vs A_TIME).
(This used to be commit 8e119b64f1d92026dda855d904be09912a40601c)
2006-09-02 21:47:56 +00:00
NULL ,
& access_time_ts ,
& write_time_ts ,
& change_time_ts ,
& ino ) ) {
time_t change_time , access_time , write_time ;
2006-08-24 16:44:00 +00:00
if ( ! cli_getattrE ( targetcli , file - > cli_fd , & mode , & size ,
r18009: Fixes bug 4026.
This completes the work Jeremy began last week, disambiguating the meaning of
c_time. (In POSIX terminology, c_time means "status Change time", not "create
time".) All uses of c_time, a_time and m_time have now been replaced with
change_time, access_time, and write_time, and when creation time is intended,
create_time is used.
Additionally, the capability of setting and retrieving the create time have
been added to the smbc_setxattr() and smbc_getxattr() functions. An example
of setting all four times can be seen with the program
examples/libsmbclient/testacl
with the following command line similar to:
testacl -f -S "system.*:CREATE_TIME:1000000000,ACCESS_TIME:1000000060,WRITE_TIME:1000000120,CHANGE_TIME:1000000180" 'smb://server/share/testfile.txt'
The -f option turns on the new mode which uses full time names in the
attribute specification (e.g. ACCESS_TIME vs A_TIME).
(This used to be commit 8e119b64f1d92026dda855d904be09912a40601c)
2006-09-02 21:47:56 +00:00
& change_time , & access_time , & write_time ) ) {
2000-12-26 05:57:10 +00:00
2006-08-24 16:44:00 +00:00
errno = EINVAL ;
2007-11-19 12:36:16 +01:00
TALLOC_FREE ( frame ) ;
2006-08-24 16:44:00 +00:00
return - 1 ;
}
r18009: Fixes bug 4026.
This completes the work Jeremy began last week, disambiguating the meaning of
c_time. (In POSIX terminology, c_time means "status Change time", not "create
time".) All uses of c_time, a_time and m_time have now been replaced with
change_time, access_time, and write_time, and when creation time is intended,
create_time is used.
Additionally, the capability of setting and retrieving the create time have
been added to the smbc_setxattr() and smbc_getxattr() functions. An example
of setting all four times can be seen with the program
examples/libsmbclient/testacl
with the following command line similar to:
testacl -f -S "system.*:CREATE_TIME:1000000000,ACCESS_TIME:1000000060,WRITE_TIME:1000000120,CHANGE_TIME:1000000180" 'smb://server/share/testfile.txt'
The -f option turns on the new mode which uses full time names in the
attribute specification (e.g. ACCESS_TIME vs A_TIME).
(This used to be commit 8e119b64f1d92026dda855d904be09912a40601c)
2006-09-02 21:47:56 +00:00
change_time_ts = convert_time_t_to_timespec ( change_time ) ;
access_time_ts = convert_time_t_to_timespec ( access_time ) ;
write_time_ts = convert_time_t_to_timespec ( write_time ) ;
2001-11-21 03:55:59 +00:00
}
2000-12-26 05:57:10 +00:00
2001-11-21 03:55:59 +00:00
st - > st_ino = ino ;
2000-12-26 05:57:10 +00:00
2002-07-15 10:35:28 +00:00
smbc_setup_stat ( context , st , file - > fname , size , mode ) ;
2000-12-26 05:57:10 +00:00
r18009: Fixes bug 4026.
This completes the work Jeremy began last week, disambiguating the meaning of
c_time. (In POSIX terminology, c_time means "status Change time", not "create
time".) All uses of c_time, a_time and m_time have now been replaced with
change_time, access_time, and write_time, and when creation time is intended,
create_time is used.
Additionally, the capability of setting and retrieving the create time have
been added to the smbc_setxattr() and smbc_getxattr() functions. An example
of setting all four times can be seen with the program
examples/libsmbclient/testacl
with the following command line similar to:
testacl -f -S "system.*:CREATE_TIME:1000000000,ACCESS_TIME:1000000060,WRITE_TIME:1000000120,CHANGE_TIME:1000000180" 'smb://server/share/testfile.txt'
The -f option turns on the new mode which uses full time names in the
attribute specification (e.g. ACCESS_TIME vs A_TIME).
(This used to be commit 8e119b64f1d92026dda855d904be09912a40601c)
2006-09-02 21:47:56 +00:00
set_atimespec ( st , access_time_ts ) ;
set_ctimespec ( st , change_time_ts ) ;
set_mtimespec ( st , write_time_ts ) ;
2002-07-15 10:35:28 +00:00
st - > st_dev = file - > srv - > dev ;
2000-12-26 05:57:10 +00:00
2007-11-19 12:36:16 +01:00
TALLOC_FREE ( frame ) ;
2001-11-21 03:55:59 +00:00
return 0 ;
2000-12-26 05:57:10 +00:00
}
/*
* Routine to open a directory
2004-03-19 16:22:47 +00:00
* We accept the URL syntax explained in smbc_parse_path ( ) , above .
2000-12-26 05:57:10 +00:00
*/
2005-12-29 15:06:53 +00:00
static void
smbc_remove_dir ( SMBCFILE * dir )
2001-01-05 13:43:19 +00:00
{
2001-11-21 03:55:59 +00:00
struct smbc_dir_list * d , * f ;
2001-01-07 07:10:50 +00:00
2001-11-21 03:55:59 +00:00
d = dir - > dir_list ;
while ( d ) {
2001-01-05 13:43:19 +00:00
2001-11-21 03:55:59 +00:00
f = d ; d = d - > next ;
2001-01-07 07:10:50 +00:00
2001-11-21 03:55:59 +00:00
SAFE_FREE ( f - > dirent ) ;
SAFE_FREE ( f ) ;
2001-01-05 13:43:19 +00:00
2001-11-21 03:55:59 +00:00
}
2001-01-05 13:43:19 +00:00
2001-11-21 03:55:59 +00:00
dir - > dir_list = dir - > dir_end = dir - > dir_next = NULL ;
2001-01-05 13:43:19 +00:00
}
2005-12-29 15:06:53 +00:00
static int
add_dirent ( SMBCFILE * dir ,
const char * name ,
const char * comment ,
uint32 type )
2000-12-26 05:57:10 +00:00
{
2001-11-21 03:55:59 +00:00
struct smbc_dirent * dirent ;
int size ;
2005-03-10 23:41:19 +00:00
int name_length = ( name = = NULL ? 0 : strlen ( name ) ) ;
int comment_len = ( comment = = NULL ? 0 : strlen ( comment ) ) ;
2001-01-05 13:43:19 +00:00
2001-11-21 03:55:59 +00:00
/*
* Allocate space for the dirent , which must be increased by the
2005-03-10 23:41:19 +00:00
* size of the name and the comment and 1 each for the null terminator .
2001-11-21 03:55:59 +00:00
*/
2001-01-05 13:43:19 +00:00
2005-03-10 23:41:19 +00:00
size = sizeof ( struct smbc_dirent ) + name_length + comment_len + 2 ;
2001-01-05 13:43:19 +00:00
2006-07-31 03:53:39 +00:00
dirent = ( struct smbc_dirent * ) SMB_MALLOC ( size ) ;
2001-01-07 07:10:50 +00:00
2001-11-21 03:55:59 +00:00
if ( ! dirent ) {
2001-01-05 13:43:19 +00:00
2001-11-21 03:55:59 +00:00
dir - > dir_error = ENOMEM ;
return - 1 ;
2001-01-05 13:43:19 +00:00
2001-11-21 03:55:59 +00:00
}
2001-01-05 13:43:19 +00:00
2002-07-15 10:35:28 +00:00
ZERO_STRUCTP ( dirent ) ;
2001-11-21 03:55:59 +00:00
if ( dir - > dir_list = = NULL ) {
2001-01-05 13:43:19 +00:00
2004-12-07 18:25:53 +00:00
dir - > dir_list = SMB_MALLOC_P ( struct smbc_dir_list ) ;
2001-11-21 03:55:59 +00:00
if ( ! dir - > dir_list ) {
2001-01-05 13:43:19 +00:00
2001-11-21 03:55:59 +00:00
SAFE_FREE ( dirent ) ;
dir - > dir_error = ENOMEM ;
return - 1 ;
2001-01-05 13:43:19 +00:00
2001-11-21 03:55:59 +00:00
}
2002-07-15 10:35:28 +00:00
ZERO_STRUCTP ( dir - > dir_list ) ;
2001-01-05 13:43:19 +00:00
2001-11-21 03:55:59 +00:00
dir - > dir_end = dir - > dir_next = dir - > dir_list ;
}
else {
2001-01-05 13:43:19 +00:00
2004-12-07 18:25:53 +00:00
dir - > dir_end - > next = SMB_MALLOC_P ( struct smbc_dir_list ) ;
2002-07-15 10:35:28 +00:00
if ( ! dir - > dir_end - > next ) {
2001-11-21 03:55:59 +00:00
SAFE_FREE ( dirent ) ;
dir - > dir_error = ENOMEM ;
return - 1 ;
2001-01-05 13:43:19 +00:00
2001-11-21 03:55:59 +00:00
}
2002-07-15 10:35:28 +00:00
ZERO_STRUCTP ( dir - > dir_end - > next ) ;
2001-01-05 13:43:19 +00:00
2001-11-21 03:55:59 +00:00
dir - > dir_end = dir - > dir_end - > next ;
}
2001-01-05 13:43:19 +00:00
2001-11-21 03:55:59 +00:00
dir - > dir_end - > next = NULL ;
dir - > dir_end - > dirent = dirent ;
2002-07-15 10:35:28 +00:00
2001-11-21 03:55:59 +00:00
dirent - > smbc_type = type ;
2005-03-10 23:41:19 +00:00
dirent - > namelen = name_length ;
dirent - > commentlen = comment_len ;
2001-11-21 03:55:59 +00:00
dirent - > dirlen = size ;
2001-01-07 07:10:50 +00:00
2006-01-29 00:11:34 +00:00
/*
* dirent - > namelen + 1 includes the null ( no null termination needed )
* Ditto for dirent - > commentlen .
* The space for the two null bytes was allocated .
*/
2005-03-10 23:41:19 +00:00
strncpy ( dirent - > name , ( name ? name : " " ) , dirent - > namelen + 1 ) ;
2001-11-21 03:55:59 +00:00
dirent - > comment = ( char * ) ( & dirent - > name + dirent - > namelen + 1 ) ;
2005-03-10 23:41:19 +00:00
strncpy ( dirent - > comment , ( comment ? comment : " " ) , dirent - > commentlen + 1 ) ;
2003-04-16 14:45:11 +00:00
2001-11-21 03:55:59 +00:00
return 0 ;
2000-12-26 05:57:10 +00:00
}
2004-03-19 16:22:47 +00:00
static void
2005-12-29 15:06:53 +00:00
list_unique_wg_fn ( const char * name ,
uint32 type ,
const char * comment ,
void * state )
2004-03-19 16:22:47 +00:00
{
SMBCFILE * dir = ( SMBCFILE * ) state ;
struct smbc_dir_list * dir_list ;
struct smbc_dirent * dirent ;
int dirent_type ;
2004-11-24 01:03:23 +00:00
int do_remove = 0 ;
2004-03-19 16:22:47 +00:00
dirent_type = dir - > dir_type ;
if ( add_dirent ( dir , name , comment , dirent_type ) < 0 ) {
/* An error occurred, what do we do? */
/* FIXME: Add some code here */
}
/* Point to the one just added */
dirent = dir - > dir_end - > dirent ;
/* See if this was a duplicate */
for ( dir_list = dir - > dir_list ;
dir_list ! = dir - > dir_end ;
dir_list = dir_list - > next ) {
2004-11-24 01:03:23 +00:00
if ( ! do_remove & &
2004-03-19 16:22:47 +00:00
strcmp ( dir_list - > dirent - > name , dirent - > name ) = = 0 ) {
/* Duplicate. End end of list need to be removed. */
2004-11-24 01:03:23 +00:00
do_remove = 1 ;
2004-03-19 16:22:47 +00:00
}
2004-11-24 01:03:23 +00:00
if ( do_remove & & dir_list - > next = = dir - > dir_end ) {
2004-03-19 16:22:47 +00:00
/* Found the end of the list. Remove it. */
dir - > dir_end = dir_list ;
free ( dir_list - > next ) ;
2005-12-05 23:30:40 +00:00
free ( dirent ) ;
2004-03-19 16:22:47 +00:00
dir_list - > next = NULL ;
break ;
}
}
}
2001-01-05 13:43:19 +00:00
static void
2005-12-29 15:06:53 +00:00
list_fn ( const char * name ,
uint32 type ,
const char * comment ,
void * state )
2001-01-05 13:43:19 +00:00
{
2002-07-15 10:35:28 +00:00
SMBCFILE * dir = ( SMBCFILE * ) state ;
2001-11-21 03:55:59 +00:00
int dirent_type ;
2001-01-07 07:10:50 +00:00
2005-12-14 04:00:58 +00:00
/*
* We need to process the type a little . . .
*
* Disk share = 0x00000000
* Print share = 0x00000001
* Comms share = 0x00000002 ( obsolete ? )
2007-11-30 13:09:04 -08:00
* IPC $ share = 0x00000003
2005-12-14 04:00:58 +00:00
*
* administrative shares :
* ADMIN $ , IPC $ , C $ , D $ , E $ . . . are type | = 0x80000000
*/
2007-11-30 13:09:04 -08:00
2001-11-21 03:55:59 +00:00
if ( dir - > dir_type = = SMBC_FILE_SHARE ) {
switch ( type ) {
2005-12-14 04:00:58 +00:00
case 0 | 0x80000000 :
case 0 :
2001-11-21 03:55:59 +00:00
dirent_type = SMBC_FILE_SHARE ;
break ;
2001-01-07 07:10:50 +00:00
2001-11-21 03:55:59 +00:00
case 1 :
dirent_type = SMBC_PRINTER_SHARE ;
break ;
2001-01-07 07:10:50 +00:00
2001-11-21 03:55:59 +00:00
case 2 :
dirent_type = SMBC_COMMS_SHARE ;
break ;
2001-01-05 13:43:19 +00:00
2005-12-14 04:00:58 +00:00
case 3 | 0x80000000 :
2001-11-21 03:55:59 +00:00
case 3 :
dirent_type = SMBC_IPC_SHARE ;
break ;
2001-01-07 07:10:50 +00:00
2001-11-21 03:55:59 +00:00
default :
dirent_type = SMBC_FILE_SHARE ; /* FIXME, error? */
break ;
}
}
2005-12-14 04:00:58 +00:00
else {
dirent_type = dir - > dir_type ;
}
2001-01-07 07:10:50 +00:00
2001-11-21 03:55:59 +00:00
if ( add_dirent ( dir , name , comment , dirent_type ) < 0 ) {
2001-01-05 13:43:19 +00:00
2001-11-21 03:55:59 +00:00
/* An error occurred, what do we do? */
/* FIXME: Add some code here */
2001-01-05 13:43:19 +00:00
2001-11-21 03:55:59 +00:00
}
2001-01-05 13:43:19 +00:00
}
2001-01-06 14:48:55 +00:00
static void
2005-12-29 15:06:53 +00:00
dir_list_fn ( const char * mnt ,
file_info * finfo ,
const char * mask ,
void * state )
2001-01-06 14:48:55 +00:00
{
2002-07-15 10:35:28 +00:00
if ( add_dirent ( ( SMBCFILE * ) state , finfo - > name , " " ,
2001-11-21 03:55:59 +00:00
( finfo - > mode & aDIR ? SMBC_DIR : SMBC_FILE ) ) < 0 ) {
2001-01-06 14:48:55 +00:00
2001-11-21 03:55:59 +00:00
/* Handle an error ... */
2002-07-15 10:35:28 +00:00
2001-11-21 03:55:59 +00:00
/* FIXME: Add some code ... */
2001-01-06 14:48:55 +00:00
2001-11-21 03:55:59 +00:00
}
2001-01-06 14:48:55 +00:00
}
2005-12-08 03:41:19 +00:00
static int
net_share_enum_rpc ( struct cli_state * cli ,
void ( * fn ) ( const char * name ,
uint32 type ,
const char * comment ,
void * state ) ,
void * state )
{
int i ;
2007-10-10 15:34:30 -05:00
WERROR result ;
ENUM_HND enum_hnd ;
2005-12-08 03:41:19 +00:00
uint32 info_level = 1 ;
uint32 preferred_len = 0xffffffff ;
2007-10-10 15:34:30 -05:00
uint32 type ;
SRV_SHARE_INFO_CTR ctr ;
fstring name = " " ;
fstring comment = " " ;
2005-12-08 03:41:19 +00:00
struct rpc_pipe_client * pipe_hnd ;
2005-12-14 04:00:58 +00:00
NTSTATUS nt_status ;
2005-12-08 03:41:19 +00:00
/* Open the server service pipe */
pipe_hnd = cli_rpc_pipe_open_noauth ( cli , PI_SRVSVC , & nt_status ) ;
if ( ! pipe_hnd ) {
DEBUG ( 1 , ( " net_share_enum_rpc pipe open fail! \n " ) ) ;
return - 1 ;
}
/* Issue the NetShareEnum RPC call and retrieve the response */
2007-10-10 15:34:30 -05:00
init_enum_hnd ( & enum_hnd , 0 ) ;
result = rpccli_srvsvc_net_share_enum ( pipe_hnd ,
2007-11-19 12:36:16 +01:00
talloc_tos ( ) ,
2007-10-10 15:34:30 -05:00
info_level ,
& ctr ,
preferred_len ,
& enum_hnd ) ;
2005-12-08 03:41:19 +00:00
/* Was it successful? */
2007-10-10 15:34:30 -05:00
if ( ! W_ERROR_IS_OK ( result ) | | ctr . num_entries = = 0 ) {
2005-12-08 03:41:19 +00:00
/* Nope. Go clean up. */
goto done ;
}
/* For each returned entry... */
2007-10-10 15:34:30 -05:00
for ( i = 0 ; i < ctr . num_entries ; i + + ) {
/* pull out the share name */
rpcstr_pull_unistr2_fstring (
name , & ctr . share . info1 [ i ] . info_1_str . uni_netname ) ;
/* pull out the share's comment */
rpcstr_pull_unistr2_fstring (
comment , & ctr . share . info1 [ i ] . info_1_str . uni_remark ) ;
/* Get the type value */
type = ctr . share . info1 [ i ] . info_1 . type ;
2005-12-14 04:00:58 +00:00
2005-12-08 03:41:19 +00:00
/* Add this share to the list */
2007-10-10 15:34:30 -05:00
( * fn ) ( name , type , comment , state ) ;
2005-12-08 03:41:19 +00:00
}
done :
2005-12-14 04:00:58 +00:00
/* Close the server service pipe */
cli_rpc_pipe_close ( pipe_hnd ) ;
2005-12-08 03:41:19 +00:00
/* Tell 'em if it worked */
2007-10-10 15:34:30 -05:00
return W_ERROR_IS_OK ( result ) ? 0 : - 1 ;
2005-12-08 03:41:19 +00:00
}
2005-12-29 15:06:53 +00:00
static SMBCFILE *
smbc_opendir_ctx ( SMBCCTX * context ,
const char * fname )
2001-01-05 13:43:19 +00:00
{
2006-09-03 00:50:34 +00:00
int saved_errno ;
2007-11-30 13:09:04 -08:00
char * server , * share , * user , * password , * options ;
char * workgroup ;
char * path ;
2005-04-19 19:23:49 +00:00
uint16 mode ;
char * p ;
2002-07-15 10:35:28 +00:00
SMBCSRV * srv = NULL ;
SMBCFILE * dir = NULL ;
2006-09-03 00:50:34 +00:00
struct _smbc_callbacks * cb ;
2007-10-24 14:16:54 -07:00
struct sockaddr_storage rem_ss ;
2007-11-19 12:36:16 +01:00
TALLOC_CTX * frame = talloc_stackframe ( ) ;
2001-01-05 13:43:19 +00:00
2003-01-13 20:04:40 +00:00
if ( ! context | | ! context - > internal | |
! context - > internal - > _initialized ) {
2003-04-16 14:45:11 +00:00
DEBUG ( 4 , ( " no valid context \n " ) ) ;
2005-03-10 23:41:19 +00:00
errno = EINVAL + 8192 ;
2007-11-19 12:36:16 +01:00
TALLOC_FREE ( frame ) ;
2002-07-15 10:35:28 +00:00
return NULL ;
2001-01-05 13:43:19 +00:00
2001-11-21 03:55:59 +00:00
}
2001-01-05 13:43:19 +00:00
2001-11-21 03:55:59 +00:00
if ( ! fname ) {
2003-04-16 14:45:11 +00:00
DEBUG ( 4 , ( " no valid fname \n " ) ) ;
2005-03-10 23:41:19 +00:00
errno = EINVAL + 8193 ;
2007-11-19 12:36:16 +01:00
TALLOC_FREE ( frame ) ;
2002-07-15 10:35:28 +00:00
return NULL ;
2001-11-21 03:55:59 +00:00
}
2001-01-05 13:43:19 +00:00
2007-11-30 13:09:04 -08:00
if ( smbc_parse_path ( frame ,
context ,
fname ,
& workgroup ,
& server ,
& share ,
& path ,
& user ,
& password ,
& options ) ) {
2003-04-16 14:45:11 +00:00
DEBUG ( 4 , ( " no valid path \n " ) ) ;
2005-03-10 23:41:19 +00:00
errno = EINVAL + 8194 ;
2007-11-19 12:36:16 +01:00
TALLOC_FREE ( frame ) ;
2002-07-15 10:35:28 +00:00
return NULL ;
2001-11-21 03:55:59 +00:00
}
2001-01-05 13:43:19 +00:00
2005-12-29 15:06:53 +00:00
DEBUG ( 4 , ( " parsed path: fname='%s' server='%s' share='%s' "
" path='%s' options='%s' \n " ,
fname , server , share , path , options ) ) ;
2004-03-19 16:22:47 +00:00
/* Ensure the options are valid */
if ( smbc_check_options ( server , share , path , options ) ) {
DEBUG ( 4 , ( " unacceptable options (%s) \n " , options ) ) ;
2005-03-10 23:41:19 +00:00
errno = EINVAL + 8195 ;
2007-11-19 12:36:16 +01:00
TALLOC_FREE ( frame ) ;
2004-03-19 16:22:47 +00:00
return NULL ;
}
2003-04-16 14:45:11 +00:00
2007-11-30 14:19:55 -08:00
if ( ! user | | user [ 0 ] = = ( char ) 0 ) {
user = talloc_strdup ( frame , context - > user ) ;
if ( ! user ) {
errno = ENOMEM ;
TALLOC_FREE ( frame ) ;
return NULL ;
}
}
2001-01-05 13:43:19 +00:00
2004-12-07 18:25:53 +00:00
dir = SMB_MALLOC_P ( SMBCFILE ) ;
2001-01-05 13:43:19 +00:00
2002-07-15 10:35:28 +00:00
if ( ! dir ) {
2001-11-21 03:55:59 +00:00
errno = ENOMEM ;
2007-11-19 12:36:16 +01:00
TALLOC_FREE ( frame ) ;
2002-07-15 10:35:28 +00:00
return NULL ;
2001-11-21 03:55:59 +00:00
}
2001-01-05 13:43:19 +00:00
2002-07-15 10:35:28 +00:00
ZERO_STRUCTP ( dir ) ;
dir - > cli_fd = 0 ;
2004-12-07 18:25:53 +00:00
dir - > fname = SMB_STRDUP ( fname ) ;
2002-07-15 10:35:28 +00:00
dir - > srv = NULL ;
dir - > offset = 0 ;
dir - > file = False ;
dir - > dir_list = dir - > dir_next = dir - > dir_end = NULL ;
2001-01-05 13:43:19 +00:00
2005-03-10 23:41:19 +00:00
if ( server [ 0 ] = = ( char ) 0 ) {
2004-03-19 16:22:47 +00:00
int i ;
int count ;
2005-03-10 23:41:19 +00:00
int max_lmb_count ;
2004-03-19 16:22:47 +00:00
struct ip_service * ip_list ;
struct ip_service server_addr ;
struct user_auth_info u_info ;
2001-01-05 13:43:19 +00:00
2004-03-19 16:22:47 +00:00
if ( share [ 0 ] ! = ( char ) 0 | | path [ 0 ] ! = ( char ) 0 ) {
2005-03-10 23:41:19 +00:00
errno = EINVAL + 8196 ;
2004-03-19 16:22:47 +00:00
if ( dir ) {
SAFE_FREE ( dir - > fname ) ;
SAFE_FREE ( dir ) ;
}
2007-11-19 12:36:16 +01:00
TALLOC_FREE ( frame ) ;
2004-03-19 16:22:47 +00:00
return NULL ;
}
2005-03-10 23:41:19 +00:00
/* Determine how many local master browsers to query */
2005-03-11 17:01:30 +00:00
max_lmb_count = ( context - > options . browse_max_lmb_count = = 0
2005-03-10 23:41:19 +00:00
? INT_MAX
2005-03-11 17:01:30 +00:00
: context - > options . browse_max_lmb_count ) ;
2005-03-10 23:41:19 +00:00
2007-12-07 12:26:32 -08:00
memset ( & u_info , ' \0 ' , sizeof ( u_info ) ) ;
u_info . username = talloc_strdup ( frame , user ) ;
u_info . password = talloc_strdup ( frame , password ) ;
if ( ! u_info . username | | ! u_info . password ) {
if ( dir ) {
SAFE_FREE ( dir - > fname ) ;
SAFE_FREE ( dir ) ;
}
TALLOC_FREE ( frame ) ;
return NULL ;
}
2004-03-19 16:22:47 +00:00
/*
* We have server and share and path empty but options
* requesting that we scan all master browsers for their list
* of workgroups / domains . This implies that we must first try
* broadcast queries to find all master browsers , and if that
* doesn ' t work , then try our other methods which return only
* a single master browser .
*/
2005-12-05 23:30:40 +00:00
ip_list = NULL ;
2007-08-28 15:38:03 +00:00
if ( ! NT_STATUS_IS_OK ( name_resolve_bcast ( MSBROWSE , 1 , & ip_list ,
& count ) ) )
{
2005-12-05 23:30:40 +00:00
SAFE_FREE ( ip_list ) ;
2007-10-24 14:16:54 -07:00
if ( ! find_master_ip ( workgroup , & server_addr . ss ) ) {
2004-03-19 16:22:47 +00:00
2006-03-12 10:57:42 +00:00
if ( dir ) {
SAFE_FREE ( dir - > fname ) ;
SAFE_FREE ( dir ) ;
}
2004-03-19 16:22:47 +00:00
errno = ENOENT ;
2007-11-19 12:36:16 +01:00
TALLOC_FREE ( frame ) ;
2004-03-19 16:22:47 +00:00
return NULL ;
}
2007-11-09 14:23:16 +01:00
ip_list = ( struct ip_service * ) memdup (
& server_addr , sizeof ( server_addr ) ) ;
2007-10-20 11:12:11 +02:00
if ( ip_list = = NULL ) {
errno = ENOMEM ;
2007-11-19 12:36:16 +01:00
TALLOC_FREE ( frame ) ;
2007-10-20 11:12:11 +02:00
return NULL ;
}
2004-03-19 16:22:47 +00:00
count = 1 ;
}
2005-03-10 23:41:19 +00:00
for ( i = 0 ; i < count & & i < max_lmb_count ; i + + ) {
2007-10-24 14:16:54 -07:00
char addr [ INET6_ADDRSTRLEN ] ;
2007-11-29 13:24:54 -08:00
char * wg_ptr = NULL ;
2007-11-30 21:57:43 -08:00
struct cli_state * cli = NULL ;
2007-11-29 13:24:54 -08:00
2007-10-24 14:16:54 -07:00
print_sockaddr ( addr , sizeof ( addr ) , & ip_list [ i ] . ss ) ;
2005-12-29 15:06:53 +00:00
DEBUG ( 99 , ( " Found master browser %d of %d: %s \n " ,
i + 1 , MAX ( count , max_lmb_count ) ,
2007-10-24 14:16:54 -07:00
addr ) ) ;
2007-11-29 13:24:54 -08:00
cli = get_ipc_connect_master_ip ( talloc_tos ( ) ,
& ip_list [ i ] ,
& u_info ,
& wg_ptr ) ;
2007-10-24 14:16:54 -07:00
/* cli == NULL is the master browser refused to talk or
2004-05-07 15:59:13 +00:00
could not be found */
2007-11-30 21:57:43 -08:00
if ( ! cli ) {
2004-05-07 15:59:13 +00:00
continue ;
2007-11-30 21:57:43 -08:00
}
2004-05-07 15:59:13 +00:00
2007-11-30 14:19:55 -08:00
workgroup = talloc_strdup ( frame , wg_ptr ) ;
server = talloc_strdup ( frame , cli - > desthost ) ;
2007-11-30 21:57:43 -08:00
cli_shutdown ( cli ) ;
2007-11-30 14:19:55 -08:00
if ( ! workgroup | | ! server ) {
errno = ENOMEM ;
TALLOC_FREE ( frame ) ;
return NULL ;
}
2004-03-19 16:22:47 +00:00
2005-12-29 15:06:53 +00:00
DEBUG ( 4 , ( " using workgroup %s %s \n " ,
workgroup , server ) ) ;
2004-03-19 16:22:47 +00:00
/*
* For each returned master browser IP address , get a
* connection to IPC $ on the server if we do not
* already have one , and determine the
* workgroups / domains that it knows about .
*/
2007-10-24 14:16:54 -07:00
2005-12-29 15:06:59 +00:00
srv = smbc_server ( context , True , server , " IPC$ " ,
workgroup , user , password ) ;
2004-03-19 16:22:47 +00:00
if ( ! srv ) {
2005-03-22 21:17:01 +00:00
continue ;
2004-03-19 16:22:47 +00:00
}
2007-10-24 14:16:54 -07:00
2004-03-19 16:22:47 +00:00
dir - > srv = srv ;
dir - > dir_type = SMBC_WORKGROUP ;
/* Now, list the stuff ... */
2007-10-24 14:16:54 -07:00
2006-07-11 18:01:26 +00:00
if ( ! cli_NetServerEnum ( srv - > cli ,
2005-12-06 17:09:44 +00:00
workgroup ,
SV_TYPE_DOMAIN_ENUM ,
list_unique_wg_fn ,
2004-03-19 16:22:47 +00:00
( void * ) dir ) ) {
2005-03-22 21:17:01 +00:00
continue ;
2004-03-19 16:22:47 +00:00
}
}
2005-12-05 23:30:40 +00:00
SAFE_FREE ( ip_list ) ;
2007-10-24 14:16:54 -07:00
} else {
2004-03-19 16:22:47 +00:00
/*
* Server not an empty string . . . Check the rest and see what
* gives
*/
2005-12-25 21:46:58 +00:00
if ( * share = = ' \0 ' ) {
if ( * path ! = ' \0 ' ) {
2001-01-05 13:43:19 +00:00
2005-12-25 21:46:58 +00:00
/* Should not have empty share with path */
2005-03-10 23:41:19 +00:00
errno = EINVAL + 8197 ;
2002-07-15 10:35:28 +00:00
if ( dir ) {
SAFE_FREE ( dir - > fname ) ;
SAFE_FREE ( dir ) ;
2001-11-21 03:55:59 +00:00
}
2007-11-19 12:36:16 +01:00
TALLOC_FREE ( frame ) ;
2002-07-15 10:35:28 +00:00
return NULL ;
2007-12-07 12:26:32 -08:00
2001-11-21 03:55:59 +00:00
}
2001-01-05 13:43:19 +00:00
2005-12-25 21:46:58 +00:00
/*
* We don ' t know if < server > is really a server name
* or is a workgroup / domain name . If we already have
* a server structure for it , we ' ll use it .
* Otherwise , check to see if < server > < 1 D > ,
* < server > < 1 B > , or < server > < 20 > translates . We check
* to see if < server > is an IP address first .
*/
2005-12-29 15:06:59 +00:00
/*
* See if we have an existing server . Do not
* establish a connection if one does not already
* exist .
*/
srv = smbc_server ( context , False , server , " IPC$ " ,
2005-12-25 21:46:58 +00:00
workgroup , user , password ) ;
/*
* If no existing server and not an IP addr , look for
* LMB or DMB
*/
if ( ! srv & &
2007-10-24 14:16:54 -07:00
! is_ipaddress ( server ) & &
( resolve_name ( server , & rem_ss , 0x1d ) | | /* LMB */
resolve_name ( server , & rem_ss , 0x1b ) ) ) { /* DMB */
2001-01-05 13:43:19 +00:00
2004-03-13 02:16:21 +00:00
fstring buserver ;
2001-01-05 13:43:19 +00:00
2002-07-15 10:35:28 +00:00
dir - > dir_type = SMBC_SERVER ;
2001-01-05 13:43:19 +00:00
2001-11-21 03:55:59 +00:00
/*
* Get the backup list . . .
*/
2005-12-25 21:46:58 +00:00
if ( ! name_status_find ( server , 0 , 0 ,
2007-10-24 14:16:54 -07:00
& rem_ss , buserver ) ) {
2001-01-05 13:43:19 +00:00
2005-12-25 21:46:58 +00:00
DEBUG ( 0 , ( " Could not get name of "
" local/domain master browser "
" for server %s \n " , server ) ) ;
2006-03-12 10:57:42 +00:00
if ( dir ) {
SAFE_FREE ( dir - > fname ) ;
SAFE_FREE ( dir ) ;
}
2005-12-25 21:46:58 +00:00
errno = EPERM ;
2007-11-19 12:36:16 +01:00
TALLOC_FREE ( frame ) ;
2002-07-15 10:35:28 +00:00
return NULL ;
2001-02-26 11:53:22 +00:00
2001-11-21 03:55:59 +00:00
}
2001-01-05 13:43:19 +00:00
2001-11-21 03:55:59 +00:00
/*
2005-12-25 21:46:58 +00:00
* Get a connection to IPC $ on the server if
* we do not already have one
*/
2005-12-29 15:06:59 +00:00
srv = smbc_server ( context , True ,
buserver , " IPC$ " ,
2005-12-25 21:46:58 +00:00
workgroup , user , password ) ;
2001-11-21 03:55:59 +00:00
if ( ! srv ) {
2003-04-16 14:45:11 +00:00
DEBUG ( 0 , ( " got no contact to IPC$ \n " ) ) ;
2002-07-15 10:35:28 +00:00
if ( dir ) {
SAFE_FREE ( dir - > fname ) ;
SAFE_FREE ( dir ) ;
2001-11-21 03:55:59 +00:00
}
2007-11-19 12:36:16 +01:00
TALLOC_FREE ( frame ) ;
2002-07-15 10:35:28 +00:00
return NULL ;
2001-01-05 13:43:19 +00:00
2001-11-21 03:55:59 +00:00
}
2001-01-05 13:43:19 +00:00
2002-07-15 10:35:28 +00:00
dir - > srv = srv ;
2001-01-05 13:43:19 +00:00
2001-11-21 03:55:59 +00:00
/* Now, list the servers ... */
2006-07-11 18:01:26 +00:00
if ( ! cli_NetServerEnum ( srv - > cli , server ,
2005-12-25 21:46:58 +00:00
0x0000FFFE , list_fn ,
2002-07-15 10:35:28 +00:00
( void * ) dir ) ) {
2001-01-05 13:43:19 +00:00
2002-07-15 10:35:28 +00:00
if ( dir ) {
SAFE_FREE ( dir - > fname ) ;
SAFE_FREE ( dir ) ;
2001-11-21 03:55:59 +00:00
}
2007-11-19 12:36:16 +01:00
TALLOC_FREE ( frame ) ;
2002-07-15 10:35:28 +00:00
return NULL ;
2001-11-21 03:55:59 +00:00
}
2005-12-25 21:46:58 +00:00
} else if ( srv | |
2007-10-24 14:16:54 -07:00
( resolve_name ( server , & rem_ss , 0x20 ) ) ) {
2005-12-25 21:46:58 +00:00
/* If we hadn't found the server, get one now */
if ( ! srv ) {
2005-12-29 15:06:59 +00:00
srv = smbc_server ( context , True ,
server , " IPC$ " ,
workgroup ,
2005-12-25 21:46:58 +00:00
user , password ) ;
}
2001-01-05 13:43:19 +00:00
2005-12-25 21:46:58 +00:00
if ( ! srv ) {
if ( dir ) {
SAFE_FREE ( dir - > fname ) ;
SAFE_FREE ( dir ) ;
}
2007-11-19 12:36:16 +01:00
TALLOC_FREE ( frame ) ;
2005-12-25 21:46:58 +00:00
return NULL ;
2001-01-05 13:43:19 +00:00
2005-12-25 21:46:58 +00:00
}
2001-01-05 13:43:19 +00:00
2005-12-25 21:46:58 +00:00
dir - > dir_type = SMBC_FILE_SHARE ;
dir - > srv = srv ;
2001-01-05 13:43:19 +00:00
2005-12-25 21:46:58 +00:00
/* List the shares ... */
2001-01-05 13:43:19 +00:00
2005-12-25 21:46:58 +00:00
if ( net_share_enum_rpc (
2006-07-11 18:01:26 +00:00
srv - > cli ,
2005-12-25 21:46:58 +00:00
list_fn ,
( void * ) dir ) < 0 & &
cli_RNetShareEnum (
2006-07-11 18:01:26 +00:00
srv - > cli ,
2007-10-24 14:16:54 -07:00
list_fn ,
2005-12-25 21:46:58 +00:00
( void * ) dir ) < 0 ) {
2007-10-24 14:16:54 -07:00
2006-07-11 18:01:26 +00:00
errno = cli_errno ( srv - > cli ) ;
2005-12-25 21:46:58 +00:00
if ( dir ) {
SAFE_FREE ( dir - > fname ) ;
SAFE_FREE ( dir ) ;
}
2007-11-19 12:36:16 +01:00
TALLOC_FREE ( frame ) ;
2005-12-25 21:46:58 +00:00
return NULL ;
2001-01-05 13:43:19 +00:00
2005-12-25 21:46:58 +00:00
}
} else {
/* Neither the workgroup nor server exists */
2007-10-24 14:16:54 -07:00
errno = ECONNREFUSED ;
2005-12-25 21:46:58 +00:00
if ( dir ) {
SAFE_FREE ( dir - > fname ) ;
SAFE_FREE ( dir ) ;
}
2007-11-19 12:36:16 +01:00
TALLOC_FREE ( frame ) ;
2005-12-25 21:46:58 +00:00
return NULL ;
2001-11-21 03:55:59 +00:00
}
2001-01-05 13:43:19 +00:00
2001-11-21 03:55:59 +00:00
}
2005-12-25 21:46:58 +00:00
else {
/*
* The server and share are specified . . . work from
* there . . .
*/
2007-11-29 17:25:41 -08:00
char * targetpath ;
2005-09-12 18:12:53 +00:00
struct cli_state * targetcli ;
2001-01-05 13:43:19 +00:00
2005-12-25 21:46:58 +00:00
/* We connect to the server and list the directory */
2002-07-15 10:35:28 +00:00
dir - > dir_type = SMBC_FILE_SHARE ;
2001-01-06 14:48:55 +00:00
2005-12-29 15:06:59 +00:00
srv = smbc_server ( context , True , server , share ,
2005-12-25 21:46:58 +00:00
workgroup , user , password ) ;
2001-01-05 13:43:19 +00:00
2001-11-21 03:55:59 +00:00
if ( ! srv ) {
2002-07-15 10:35:28 +00:00
if ( dir ) {
SAFE_FREE ( dir - > fname ) ;
SAFE_FREE ( dir ) ;
2001-11-21 03:55:59 +00:00
}
2007-11-19 12:36:16 +01:00
TALLOC_FREE ( frame ) ;
2002-07-15 10:35:28 +00:00
return NULL ;
2001-11-21 03:55:59 +00:00
}
2001-01-06 14:48:55 +00:00
2002-07-15 10:35:28 +00:00
dir - > srv = srv ;
2001-01-06 14:48:55 +00:00
2001-11-21 03:55:59 +00:00
/* Now, list the files ... */
2001-01-06 14:48:55 +00:00
2005-04-19 19:23:49 +00:00
p = path + strlen ( path ) ;
2007-11-30 14:19:55 -08:00
path = talloc_asprintf_append ( path , " \\ * " ) ;
if ( ! path ) {
if ( dir ) {
SAFE_FREE ( dir - > fname ) ;
SAFE_FREE ( dir ) ;
}
TALLOC_FREE ( frame ) ;
return NULL ;
}
2001-01-06 14:48:55 +00:00
2007-11-29 17:25:41 -08:00
if ( ! cli_resolve_path ( frame , " " , srv - > cli , path ,
& targetcli , & targetpath ) ) {
2005-09-12 18:12:53 +00:00
d_printf ( " Could not resolve %s \n " , path ) ;
2006-03-12 10:57:42 +00:00
if ( dir ) {
SAFE_FREE ( dir - > fname ) ;
SAFE_FREE ( dir ) ;
}
2007-11-19 12:36:16 +01:00
TALLOC_FREE ( frame ) ;
2005-09-12 18:12:53 +00:00
return NULL ;
}
2007-11-29 17:25:41 -08:00
2005-12-29 15:06:53 +00:00
if ( cli_list ( targetcli , targetpath ,
aDIR | aSYSTEM | aHIDDEN ,
dir_list_fn , ( void * ) dir ) < 0 ) {
2001-01-06 14:48:55 +00:00
2002-07-15 10:35:28 +00:00
if ( dir ) {
SAFE_FREE ( dir - > fname ) ;
SAFE_FREE ( dir ) ;
2001-11-21 03:55:59 +00:00
}
2006-09-03 00:50:34 +00:00
saved_errno = smbc_errno ( context , targetcli ) ;
2005-04-19 19:23:49 +00:00
2006-09-03 00:50:34 +00:00
if ( saved_errno = = EINVAL ) {
2005-04-19 19:23:49 +00:00
/*
* See if they asked to opendir something
* other than a directory . If so , the
* converted error value we got would have
* been EINVAL rather than ENOTDIR .
*/
* p = ' \0 ' ; /* restore original path */
if ( smbc_getatr ( context , srv , path ,
& mode , NULL ,
r18009: Fixes bug 4026.
This completes the work Jeremy began last week, disambiguating the meaning of
c_time. (In POSIX terminology, c_time means "status Change time", not "create
time".) All uses of c_time, a_time and m_time have now been replaced with
change_time, access_time, and write_time, and when creation time is intended,
create_time is used.
Additionally, the capability of setting and retrieving the create time have
been added to the smbc_setxattr() and smbc_getxattr() functions. An example
of setting all four times can be seen with the program
examples/libsmbclient/testacl
with the following command line similar to:
testacl -f -S "system.*:CREATE_TIME:1000000000,ACCESS_TIME:1000000060,WRITE_TIME:1000000120,CHANGE_TIME:1000000180" 'smb://server/share/testfile.txt'
The -f option turns on the new mode which uses full time names in the
attribute specification (e.g. ACCESS_TIME vs A_TIME).
(This used to be commit 8e119b64f1d92026dda855d904be09912a40601c)
2006-09-02 21:47:56 +00:00
NULL , NULL , NULL , NULL ,
2005-04-19 19:23:49 +00:00
NULL ) & &
! IS_DOS_DIR ( mode ) ) {
/* It is. Correct the error value */
2006-09-03 00:50:34 +00:00
saved_errno = ENOTDIR ;
2005-04-19 19:23:49 +00:00
}
}
2006-09-03 00:50:34 +00:00
/*
* If there was an error and the server is no
* good any more . . .
*/
cb = & context - > callbacks ;
if ( cli_is_error ( targetcli ) & &
2007-09-06 13:21:31 +00:00
( cb - > check_server_fn ) ( context , srv ) ) {
/* ... then remove it. */
if ( ( cb - > remove_unused_server_fn ) ( context ,
srv ) ) {
/*
* We could not remove the
* server completely , remove
* it from the cache so we
* will not get it again . It
* will be removed when the
* last file / dir is closed .
*/
( cb - > remove_cached_srv_fn ) ( context ,
srv ) ;
}
2006-09-03 00:50:34 +00:00
}
2001-01-06 14:48:55 +00:00
2006-09-03 00:50:34 +00:00
errno = saved_errno ;
2007-11-19 12:36:16 +01:00
TALLOC_FREE ( frame ) ;
2006-09-03 00:50:34 +00:00
return NULL ;
2001-11-21 03:55:59 +00:00
}
}
2001-01-05 13:43:19 +00:00
2001-11-21 03:55:59 +00:00
}
2001-01-05 13:43:19 +00:00
2003-01-13 20:04:40 +00:00
DLIST_ADD ( context - > internal - > _files , dir ) ;
2007-11-19 12:36:16 +01:00
TALLOC_FREE ( frame ) ;
2002-07-15 10:35:28 +00:00
return dir ;
2001-01-05 13:43:19 +00:00
}
2000-12-26 05:57:10 +00:00
/*
* Routine to close a directory
*/
2005-12-29 15:06:53 +00:00
static int
smbc_closedir_ctx ( SMBCCTX * context ,
SMBCFILE * dir )
2000-12-26 05:57:10 +00:00
{
2007-11-29 13:24:54 -08:00
TALLOC_CTX * frame = talloc_stackframe ( ) ;
2001-01-07 07:10:50 +00:00
2003-01-13 20:04:40 +00:00
if ( ! context | | ! context - > internal | |
! context - > internal - > _initialized ) {
2001-11-21 03:55:59 +00:00
errno = EINVAL ;
2007-11-19 12:36:16 +01:00
TALLOC_FREE ( frame ) ;
2001-11-21 03:55:59 +00:00
return - 1 ;
}
2001-01-07 07:10:50 +00:00
2003-01-13 20:04:40 +00:00
if ( ! dir | | ! DLIST_CONTAINS ( context - > internal - > _files , dir ) ) {
2001-11-21 03:55:59 +00:00
errno = EBADF ;
2007-11-19 12:36:16 +01:00
TALLOC_FREE ( frame ) ;
2001-11-21 03:55:59 +00:00
return - 1 ;
}
2001-01-07 07:10:50 +00:00
2002-07-15 10:35:28 +00:00
smbc_remove_dir ( dir ) ; /* Clean it up */
2001-01-07 07:10:50 +00:00
2003-01-13 20:04:40 +00:00
DLIST_REMOVE ( context - > internal - > _files , dir ) ;
2001-01-07 07:10:50 +00:00
2002-07-15 10:35:28 +00:00
if ( dir ) {
2001-03-27 12:13:59 +00:00
2002-07-15 10:35:28 +00:00
SAFE_FREE ( dir - > fname ) ;
SAFE_FREE ( dir ) ; /* Free the space too */
2001-11-21 03:55:59 +00:00
}
2001-01-07 07:10:50 +00:00
2007-11-19 12:36:16 +01:00
TALLOC_FREE ( frame ) ;
2001-11-21 03:55:59 +00:00
return 0 ;
2000-12-26 05:57:10 +00:00
}
2005-12-29 15:06:53 +00:00
static void
smbc_readdir_internal ( SMBCCTX * context ,
struct smbc_dirent * dest ,
struct smbc_dirent * src ,
int max_namebuf_len )
2005-03-10 23:41:19 +00:00
{
2005-03-11 17:01:30 +00:00
if ( context - > options . urlencode_readdir_entries ) {
2005-03-10 23:41:19 +00:00
/* url-encode the name. get back remaining buffer space */
max_namebuf_len =
smbc_urlencode ( dest - > name , src - > name , max_namebuf_len ) ;
/* We now know the name length */
dest - > namelen = strlen ( dest - > name ) ;
/* Save the pointer to the beginning of the comment */
dest - > comment = dest - > name + dest - > namelen + 1 ;
/* Copy the comment */
2006-01-29 00:11:34 +00:00
strncpy ( dest - > comment , src - > comment , max_namebuf_len - 1 ) ;
dest - > comment [ max_namebuf_len - 1 ] = ' \0 ' ;
2005-03-10 23:41:19 +00:00
/* Save other fields */
dest - > smbc_type = src - > smbc_type ;
dest - > commentlen = strlen ( dest - > comment ) ;
dest - > dirlen = ( ( dest - > comment + dest - > commentlen + 1 ) -
( char * ) dest ) ;
} else {
/* No encoding. Just copy the entry as is. */
memcpy ( dest , src , src - > dirlen ) ;
dest - > comment = ( char * ) ( & dest - > name + src - > namelen + 1 ) ;
}
}
2000-12-26 05:57:10 +00:00
/*
* Routine to get a directory entry
*/
2005-12-29 15:06:53 +00:00
struct smbc_dirent *
smbc_readdir_ctx ( SMBCCTX * context ,
SMBCFILE * dir )
2001-01-12 05:10:45 +00:00
{
2005-03-10 23:41:19 +00:00
int maxlen ;
2001-11-21 03:55:59 +00:00
struct smbc_dirent * dirp , * dirent ;
2007-11-19 12:36:16 +01:00
TALLOC_CTX * frame = talloc_stackframe ( ) ;
2001-01-12 05:10:45 +00:00
2001-11-21 03:55:59 +00:00
/* Check that all is ok first ... */
2001-01-12 05:10:45 +00:00
2003-01-13 20:04:40 +00:00
if ( ! context | | ! context - > internal | |
! context - > internal - > _initialized ) {
2001-01-12 05:10:45 +00:00
2001-11-21 03:55:59 +00:00
errno = EINVAL ;
2004-03-19 16:22:47 +00:00
DEBUG ( 0 , ( " Invalid context in smbc_readdir_ctx() \n " ) ) ;
2007-11-19 12:36:16 +01:00
TALLOC_FREE ( frame ) ;
2001-11-21 03:55:59 +00:00
return NULL ;
2001-01-12 05:10:45 +00:00
2001-11-21 03:55:59 +00:00
}
2001-01-12 05:10:45 +00:00
2003-01-13 20:04:40 +00:00
if ( ! dir | | ! DLIST_CONTAINS ( context - > internal - > _files , dir ) ) {
2001-03-01 19:21:57 +00:00
2001-11-21 03:55:59 +00:00
errno = EBADF ;
2004-03-19 16:22:47 +00:00
DEBUG ( 0 , ( " Invalid dir in smbc_readdir_ctx() \n " ) ) ;
2007-11-19 12:36:16 +01:00
TALLOC_FREE ( frame ) ;
2001-11-21 03:55:59 +00:00
return NULL ;
2001-03-01 19:21:57 +00:00
2001-11-21 03:55:59 +00:00
}
2001-03-01 19:21:57 +00:00
2002-07-15 10:35:28 +00:00
if ( dir - > file ! = False ) { /* FIXME, should be dir, perhaps */
2001-01-12 05:10:45 +00:00
2001-11-21 03:55:59 +00:00
errno = ENOTDIR ;
2004-03-19 16:22:47 +00:00
DEBUG ( 0 , ( " Found file vs directory in smbc_readdir_ctx() \n " ) ) ;
2007-11-19 12:36:16 +01:00
TALLOC_FREE ( frame ) ;
2001-11-21 03:55:59 +00:00
return NULL ;
2001-01-12 05:10:45 +00:00
2001-11-21 03:55:59 +00:00
}
2001-01-12 05:10:45 +00:00
2004-03-19 16:22:47 +00:00
if ( ! dir - > dir_next ) {
2007-11-19 12:36:16 +01:00
TALLOC_FREE ( frame ) ;
2001-11-21 03:55:59 +00:00
return NULL ;
2004-03-19 16:22:47 +00:00
}
2001-01-12 05:10:45 +00:00
2005-03-10 23:41:19 +00:00
dirent = dir - > dir_next - > dirent ;
if ( ! dirent ) {
2001-01-12 05:10:45 +00:00
2005-03-10 23:41:19 +00:00
errno = ENOENT ;
2007-11-19 12:36:16 +01:00
TALLOC_FREE ( frame ) ;
2005-03-10 23:41:19 +00:00
return NULL ;
2001-01-12 05:10:45 +00:00
2005-03-10 23:41:19 +00:00
}
2001-01-12 05:10:45 +00:00
2005-03-10 23:41:19 +00:00
dirp = ( struct smbc_dirent * ) context - > internal - > _dirent ;
maxlen = ( sizeof ( context - > internal - > _dirent ) -
sizeof ( struct smbc_dirent ) ) ;
2001-01-12 05:10:45 +00:00
2005-03-10 23:41:19 +00:00
smbc_readdir_internal ( context , dirp , dirent , maxlen ) ;
2001-01-12 05:10:45 +00:00
2005-03-10 23:41:19 +00:00
dir - > dir_next = dir - > dir_next - > next ;
2001-01-12 05:10:45 +00:00
2007-11-19 12:36:16 +01:00
TALLOC_FREE ( frame ) ;
2005-03-10 23:41:19 +00:00
return dirp ;
2001-01-12 05:10:45 +00:00
}
/*
* Routine to get directory entries
*/
2005-12-29 15:06:53 +00:00
static int
smbc_getdents_ctx ( SMBCCTX * context ,
SMBCFILE * dir ,
struct smbc_dirent * dirp ,
int count )
2000-12-26 05:57:10 +00:00
{
2005-03-10 23:41:19 +00:00
int rem = count ;
int reqd ;
int maxlen ;
2001-11-21 03:55:59 +00:00
char * ndir = ( char * ) dirp ;
2005-03-10 23:41:19 +00:00
struct smbc_dir_list * dirlist ;
2007-11-19 12:36:16 +01:00
TALLOC_CTX * frame = talloc_stackframe ( ) ;
2000-12-26 05:57:10 +00:00
2001-11-21 03:55:59 +00:00
/* Check that all is ok first ... */
2001-01-05 13:43:19 +00:00
2003-01-13 20:04:40 +00:00
if ( ! context | | ! context - > internal | |
! context - > internal - > _initialized ) {
2001-01-07 07:10:50 +00:00
2001-11-21 03:55:59 +00:00
errno = EINVAL ;
2007-11-19 12:36:16 +01:00
TALLOC_FREE ( frame ) ;
2001-11-21 03:55:59 +00:00
return - 1 ;
2001-01-07 07:10:50 +00:00
2001-11-21 03:55:59 +00:00
}
2001-01-07 07:10:50 +00:00
2003-01-13 20:04:40 +00:00
if ( ! dir | | ! DLIST_CONTAINS ( context - > internal - > _files , dir ) ) {
2001-03-01 19:21:57 +00:00
2001-11-21 03:55:59 +00:00
errno = EBADF ;
2007-11-19 12:36:16 +01:00
TALLOC_FREE ( frame ) ;
2001-11-21 03:55:59 +00:00
return - 1 ;
2002-07-15 10:35:28 +00:00
2001-11-21 03:55:59 +00:00
}
2001-03-01 19:21:57 +00:00
2002-07-15 10:35:28 +00:00
if ( dir - > file ! = False ) { /* FIXME, should be dir, perhaps */
2001-01-05 13:43:19 +00:00
2001-11-21 03:55:59 +00:00
errno = ENOTDIR ;
2007-11-19 12:36:16 +01:00
TALLOC_FREE ( frame ) ;
2001-11-21 03:55:59 +00:00
return - 1 ;
2001-01-05 13:43:19 +00:00
2001-11-21 03:55:59 +00:00
}
2001-01-05 13:43:19 +00:00
2001-11-21 03:55:59 +00:00
/*
* Now , retrieve the number of entries that will fit in what was passed
* We have to figure out if the info is in the list , or we need to
* send a request to the server to get the info .
*/
2001-01-05 13:43:19 +00:00
2002-07-15 10:35:28 +00:00
while ( ( dirlist = dir - > dir_next ) ) {
2001-11-21 03:55:59 +00:00
struct smbc_dirent * dirent ;
2001-01-05 13:43:19 +00:00
2002-07-15 10:35:28 +00:00
if ( ! dirlist - > dirent ) {
2001-01-05 13:43:19 +00:00
2001-11-21 03:55:59 +00:00
errno = ENOENT ; /* Bad error */
2007-11-19 12:36:16 +01:00
TALLOC_FREE ( frame ) ;
2001-11-21 03:55:59 +00:00
return - 1 ;
2001-01-05 13:43:19 +00:00
2001-11-21 03:55:59 +00:00
}
2001-01-05 13:43:19 +00:00
2005-03-10 23:41:19 +00:00
/* Do urlencoding of next entry, if so selected */
dirent = ( struct smbc_dirent * ) context - > internal - > _dirent ;
maxlen = ( sizeof ( context - > internal - > _dirent ) -
sizeof ( struct smbc_dirent ) ) ;
smbc_readdir_internal ( context , dirent , dirlist - > dirent , maxlen ) ;
reqd = dirent - > dirlen ;
if ( rem < reqd ) {
2001-01-05 13:43:19 +00:00
2001-11-21 03:55:59 +00:00
if ( rem < count ) { /* We managed to copy something */
2001-01-05 13:43:19 +00:00
2001-11-21 03:55:59 +00:00
errno = 0 ;
2007-11-19 12:36:16 +01:00
TALLOC_FREE ( frame ) ;
2001-11-21 03:55:59 +00:00
return count - rem ;
2001-01-05 13:43:19 +00:00
2001-11-21 03:55:59 +00:00
}
else { /* Nothing copied ... */
2001-01-05 13:43:19 +00:00
2001-11-21 03:55:59 +00:00
errno = EINVAL ; /* Not enough space ... */
2007-11-19 12:36:16 +01:00
TALLOC_FREE ( frame ) ;
2001-11-21 03:55:59 +00:00
return - 1 ;
2001-01-05 13:43:19 +00:00
2001-11-21 03:55:59 +00:00
}
2001-01-05 13:43:19 +00:00
2001-11-21 03:55:59 +00:00
}
2001-01-05 13:43:19 +00:00
2002-02-26 17:40:43 +00:00
memcpy ( ndir , dirent , reqd ) ; /* Copy the data in ... */
2001-01-05 13:43:19 +00:00
2001-11-21 03:55:59 +00:00
( ( struct smbc_dirent * ) ndir ) - > comment =
2005-03-10 23:41:19 +00:00
( char * ) ( & ( ( struct smbc_dirent * ) ndir ) - > name +
dirent - > namelen +
1 ) ;
2001-01-05 13:43:19 +00:00
2001-11-21 03:55:59 +00:00
ndir + = reqd ;
2001-01-05 13:43:19 +00:00
2001-11-21 03:55:59 +00:00
rem - = reqd ;
2001-01-05 13:43:19 +00:00
2002-07-15 10:35:28 +00:00
dir - > dir_next = dirlist = dirlist - > next ;
2001-11-21 03:55:59 +00:00
}
2001-01-05 13:43:19 +00:00
2007-11-19 12:36:16 +01:00
TALLOC_FREE ( frame ) ;
2001-11-21 03:55:59 +00:00
if ( rem = = count )
return 0 ;
2007-11-30 13:09:04 -08:00
else
2001-11-21 03:55:59 +00:00
return count - rem ;
2000-12-26 05:57:10 +00:00
}
/*
* Routine to create a directory . . .
*/
2005-12-29 15:06:53 +00:00
static int
smbc_mkdir_ctx ( SMBCCTX * context ,
const char * fname ,
mode_t mode )
2000-12-26 05:57:10 +00:00
{
2002-07-15 10:35:28 +00:00
SMBCSRV * srv ;
2007-11-30 13:09:04 -08:00
char * server ;
char * share ;
char * user ;
char * password ;
char * workgroup ;
char * path ;
2007-11-29 17:25:41 -08:00
char * targetpath ;
2005-09-12 18:12:53 +00:00
struct cli_state * targetcli ;
2007-11-19 12:36:16 +01:00
TALLOC_CTX * frame = talloc_stackframe ( ) ;
2000-12-26 05:57:10 +00:00
2007-11-29 17:25:41 -08:00
if ( ! context | | ! context - > internal | |
2003-01-13 20:04:40 +00:00
! context - > internal - > _initialized ) {
2001-11-21 03:55:59 +00:00
errno = EINVAL ;
2007-11-19 12:36:16 +01:00
TALLOC_FREE ( frame ) ;
2001-11-21 03:55:59 +00:00
return - 1 ;
}
2001-01-07 07:10:50 +00:00
2001-11-21 03:55:59 +00:00
if ( ! fname ) {
errno = EINVAL ;
2007-11-19 12:36:16 +01:00
TALLOC_FREE ( frame ) ;
2001-11-21 03:55:59 +00:00
return - 1 ;
}
2007-11-29 17:25:41 -08:00
2001-11-21 03:55:59 +00:00
DEBUG ( 4 , ( " smbc_mkdir(%s) \n " , fname ) ) ;
2001-01-12 12:48:55 +00:00
2007-11-30 13:09:04 -08:00
if ( smbc_parse_path ( frame ,
context ,
fname ,
& workgroup ,
& server ,
& share ,
& path ,
& user ,
& password ,
NULL ) ) {
2004-03-19 16:22:47 +00:00
errno = EINVAL ;
2007-11-19 12:36:16 +01:00
TALLOC_FREE ( frame ) ;
2007-11-30 13:09:04 -08:00
return - 1 ;
2004-03-19 16:22:47 +00:00
}
2001-01-12 12:48:55 +00:00
2007-11-30 13:09:04 -08:00
if ( ! user | | user [ 0 ] = = ( char ) 0 ) {
user = talloc_strdup ( frame , context - > user ) ;
if ( ! user ) {
errno = ENOMEM ;
TALLOC_FREE ( frame ) ;
return - 1 ;
}
}
2001-01-12 12:48:55 +00:00
2005-12-29 15:06:59 +00:00
srv = smbc_server ( context , True ,
server , share , workgroup , user , password ) ;
2001-01-12 12:48:55 +00:00
2001-11-21 03:55:59 +00:00
if ( ! srv ) {
2001-01-12 12:48:55 +00:00
2007-11-19 12:36:16 +01:00
TALLOC_FREE ( frame ) ;
2001-11-21 03:55:59 +00:00
return - 1 ; /* errno set by smbc_server */
2001-01-12 12:48:55 +00:00
2001-11-21 03:55:59 +00:00
}
2001-01-12 12:48:55 +00:00
2005-09-12 18:12:53 +00:00
/*d_printf(">>>mkdir: resolving %s\n", path);*/
2007-11-29 17:25:41 -08:00
if ( ! cli_resolve_path ( frame , " " , srv - > cli , path ,
& targetcli , & targetpath ) ) {
2005-09-12 18:12:53 +00:00
d_printf ( " Could not resolve %s \n " , path ) ;
2007-11-19 12:36:16 +01:00
TALLOC_FREE ( frame ) ;
2005-09-12 18:12:53 +00:00
return - 1 ;
}
/*d_printf(">>>mkdir: resolved path as %s\n", targetpath);*/
if ( ! cli_mkdir ( targetcli , targetpath ) ) {
2001-01-12 12:48:55 +00:00
2005-09-12 18:12:53 +00:00
errno = smbc_errno ( context , targetcli ) ;
2007-11-19 12:36:16 +01:00
TALLOC_FREE ( frame ) ;
2001-11-21 03:55:59 +00:00
return - 1 ;
2001-01-12 12:48:55 +00:00
2001-11-21 03:55:59 +00:00
}
2001-01-12 12:48:55 +00:00
2007-11-19 12:36:16 +01:00
TALLOC_FREE ( frame ) ;
2001-11-21 03:55:59 +00:00
return 0 ;
2001-01-12 12:48:55 +00:00
}
2001-03-27 12:13:59 +00:00
/*
* Our list function simply checks to see if a directory is not empty
*/
static int smbc_rmdir_dirempty = True ;
2005-12-29 15:06:53 +00:00
static void
rmdir_list_fn ( const char * mnt ,
file_info * finfo ,
const char * mask ,
void * state )
2001-03-27 12:13:59 +00:00
{
2005-12-29 15:06:53 +00:00
if ( strncmp ( finfo - > name , " . " , 1 ) ! = 0 & &
strncmp ( finfo - > name , " .. " , 2 ) ! = 0 ) {
2001-11-21 03:55:59 +00:00
smbc_rmdir_dirempty = False ;
2005-12-29 15:06:53 +00:00
}
2001-03-27 12:13:59 +00:00
}
2001-01-12 12:48:55 +00:00
/*
* Routine to remove a directory
*/
2005-12-29 15:06:53 +00:00
static int
smbc_rmdir_ctx ( SMBCCTX * context ,
const char * fname )
2001-01-12 12:48:55 +00:00
{
2002-07-15 10:35:28 +00:00
SMBCSRV * srv ;
2007-11-30 13:09:04 -08:00
char * server ;
char * share ;
char * user ;
char * password ;
char * workgroup ;
char * path ;
2007-11-29 17:25:41 -08:00
char * targetpath ;
2005-09-12 18:12:53 +00:00
struct cli_state * targetcli ;
2007-11-19 12:36:16 +01:00
TALLOC_CTX * frame = talloc_stackframe ( ) ;
2001-01-12 12:48:55 +00:00
2007-11-29 17:25:41 -08:00
if ( ! context | | ! context - > internal | |
2003-01-13 20:04:40 +00:00
! context - > internal - > _initialized ) {
2001-11-21 03:55:59 +00:00
errno = EINVAL ;
2007-11-19 12:36:16 +01:00
TALLOC_FREE ( frame ) ;
2001-11-21 03:55:59 +00:00
return - 1 ;
}
2001-01-12 12:48:55 +00:00
2001-11-21 03:55:59 +00:00
if ( ! fname ) {
errno = EINVAL ;
2007-11-19 12:36:16 +01:00
TALLOC_FREE ( frame ) ;
2001-11-21 03:55:59 +00:00
return - 1 ;
}
2007-11-29 17:25:41 -08:00
2001-11-21 03:55:59 +00:00
DEBUG ( 4 , ( " smbc_rmdir(%s) \n " , fname ) ) ;
2001-01-12 12:48:55 +00:00
2007-11-30 13:09:04 -08:00
if ( smbc_parse_path ( frame ,
context ,
fname ,
& workgroup ,
& server ,
& share ,
& path ,
& user ,
& password ,
NULL ) ) {
2004-03-19 16:22:47 +00:00
errno = EINVAL ;
2007-11-19 12:36:16 +01:00
TALLOC_FREE ( frame ) ;
2007-11-30 13:09:04 -08:00
return - 1 ;
2004-03-19 16:22:47 +00:00
}
2001-01-12 12:48:55 +00:00
2007-11-30 13:09:04 -08:00
if ( ! user | | user [ 0 ] = = ( char ) 0 ) {
user = talloc_strdup ( frame , context - > user ) ;
if ( ! user ) {
errno = ENOMEM ;
TALLOC_FREE ( frame ) ;
return - 1 ;
}
}
2001-01-12 12:48:55 +00:00
2005-12-29 15:06:59 +00:00
srv = smbc_server ( context , True ,
server , share , workgroup , user , password ) ;
2001-01-12 12:48:55 +00:00
2001-11-21 03:55:59 +00:00
if ( ! srv ) {
2001-01-12 12:48:55 +00:00
2007-11-19 12:36:16 +01:00
TALLOC_FREE ( frame ) ;
2001-11-21 03:55:59 +00:00
return - 1 ; /* errno set by smbc_server */
2001-01-12 12:48:55 +00:00
2001-11-21 03:55:59 +00:00
}
2001-01-12 12:48:55 +00:00
2005-09-12 18:12:53 +00:00
/*d_printf(">>>rmdir: resolving %s\n", path);*/
2007-11-29 17:25:41 -08:00
if ( ! cli_resolve_path ( frame , " " , srv - > cli , path ,
& targetcli , & targetpath ) ) {
2005-09-12 18:12:53 +00:00
d_printf ( " Could not resolve %s \n " , path ) ;
2007-11-19 12:36:16 +01:00
TALLOC_FREE ( frame ) ;
2005-09-12 18:12:53 +00:00
return - 1 ;
}
/*d_printf(">>>rmdir: resolved path as %s\n", targetpath);*/
2001-01-12 12:48:55 +00:00
2005-09-12 18:12:53 +00:00
if ( ! cli_rmdir ( targetcli , targetpath ) ) {
errno = smbc_errno ( context , targetcli ) ;
2001-03-27 12:13:59 +00:00
2001-11-21 03:55:59 +00:00
if ( errno = = EACCES ) { /* Check if the dir empty or not */
2001-03-27 12:13:59 +00:00
2005-12-29 15:06:53 +00:00
/* Local storage to avoid buffer overflows */
2007-11-30 13:09:04 -08:00
char * lpath ;
2001-03-27 12:13:59 +00:00
2001-11-21 03:55:59 +00:00
smbc_rmdir_dirempty = True ; /* Make this so ... */
2001-03-27 12:13:59 +00:00
2007-11-30 13:09:04 -08:00
lpath = talloc_asprintf ( frame , " %s \\ * " ,
targetpath ) ;
if ( ! lpath ) {
errno = ENOMEM ;
TALLOC_FREE ( frame ) ;
return - 1 ;
}
2001-03-27 12:13:59 +00:00
2005-12-29 15:06:53 +00:00
if ( cli_list ( targetcli , lpath ,
aDIR | aSYSTEM | aHIDDEN ,
rmdir_list_fn , NULL ) < 0 ) {
2001-03-27 12:13:59 +00:00
2001-11-21 03:55:59 +00:00
/* Fix errno to ignore latest error ... */
2005-12-29 15:06:53 +00:00
DEBUG ( 5 , ( " smbc_rmdir: "
2007-11-30 13:09:04 -08:00
" cli_list returned an error: %d \n " ,
2005-09-12 18:12:53 +00:00
smbc_errno ( context , targetcli ) ) ) ;
2001-11-21 03:55:59 +00:00
errno = EACCES ;
2001-03-27 12:13:59 +00:00
2001-11-21 03:55:59 +00:00
}
2001-03-27 12:13:59 +00:00
2001-11-21 03:55:59 +00:00
if ( smbc_rmdir_dirempty )
errno = EACCES ;
else
errno = ENOTEMPTY ;
2001-03-27 12:13:59 +00:00
2001-11-21 03:55:59 +00:00
}
2001-03-27 12:13:59 +00:00
2007-11-19 12:36:16 +01:00
TALLOC_FREE ( frame ) ;
2001-11-21 03:55:59 +00:00
return - 1 ;
2001-01-12 12:48:55 +00:00
2001-11-21 03:55:59 +00:00
}
2001-01-12 12:48:55 +00:00
2007-11-19 12:36:16 +01:00
TALLOC_FREE ( frame ) ;
2001-11-21 03:55:59 +00:00
return 0 ;
2001-01-07 07:10:50 +00:00
2000-12-26 05:57:10 +00:00
}
2001-01-12 12:48:55 +00:00
/*
* Routine to return the current directory position
*/
2005-12-29 15:06:53 +00:00
static off_t
smbc_telldir_ctx ( SMBCCTX * context ,
SMBCFILE * dir )
2001-01-12 12:48:55 +00:00
{
2007-11-19 12:36:16 +01:00
TALLOC_CTX * frame = talloc_stackframe ( ) ;
2003-01-13 20:04:40 +00:00
if ( ! context | | ! context - > internal | |
! context - > internal - > _initialized ) {
2001-01-12 12:48:55 +00:00
2001-11-21 03:55:59 +00:00
errno = EINVAL ;
2007-11-19 12:36:16 +01:00
TALLOC_FREE ( frame ) ;
2001-11-21 03:55:59 +00:00
return - 1 ;
2001-01-12 12:48:55 +00:00
2001-11-21 03:55:59 +00:00
}
2001-01-12 12:48:55 +00:00
2003-01-13 20:04:40 +00:00
if ( ! dir | | ! DLIST_CONTAINS ( context - > internal - > _files , dir ) ) {
2001-03-01 19:21:57 +00:00
2001-11-21 03:55:59 +00:00
errno = EBADF ;
2007-11-19 12:36:16 +01:00
TALLOC_FREE ( frame ) ;
2001-11-21 03:55:59 +00:00
return - 1 ;
2001-03-01 19:21:57 +00:00
2001-11-21 03:55:59 +00:00
}
2001-03-01 19:21:57 +00:00
2002-07-15 10:35:28 +00:00
if ( dir - > file ! = False ) { /* FIXME, should be dir, perhaps */
2001-01-12 12:48:55 +00:00
2001-11-21 03:55:59 +00:00
errno = ENOTDIR ;
2007-11-19 12:36:16 +01:00
TALLOC_FREE ( frame ) ;
2001-11-21 03:55:59 +00:00
return - 1 ;
2001-01-12 12:48:55 +00:00
2001-11-21 03:55:59 +00:00
}
2001-01-12 12:48:55 +00:00
2007-08-14 03:02:34 +00:00
/* See if we're already at the end. */
if ( dir - > dir_next = = NULL ) {
/* We are. */
2007-11-19 12:36:16 +01:00
TALLOC_FREE ( frame ) ;
2007-08-14 03:02:34 +00:00
return - 1 ;
}
2003-04-16 14:45:11 +00:00
/*
* We return the pointer here as the offset
*/
2007-11-19 12:36:16 +01:00
TALLOC_FREE ( frame ) ;
2007-08-14 03:02:34 +00:00
return ( off_t ) ( long ) dir - > dir_next - > dirent ;
2001-01-12 12:48:55 +00:00
}
2001-03-06 14:00:48 +00:00
/*
* A routine to run down the list and see if the entry is OK
*/
2005-12-29 15:06:53 +00:00
struct smbc_dir_list *
smbc_check_dir_ent ( struct smbc_dir_list * list ,
struct smbc_dirent * dirent )
2001-03-06 14:00:48 +00:00
{
2001-11-21 03:55:59 +00:00
/* Run down the list looking for what we want */
2001-03-06 14:00:48 +00:00
2001-11-21 03:55:59 +00:00
if ( dirent ) {
2001-03-06 14:00:48 +00:00
2001-11-21 03:55:59 +00:00
struct smbc_dir_list * tmp = list ;
2001-03-06 14:00:48 +00:00
2001-11-21 03:55:59 +00:00
while ( tmp ) {
2001-03-06 14:00:48 +00:00
2001-11-21 03:55:59 +00:00
if ( tmp - > dirent = = dirent )
return tmp ;
2001-03-06 14:00:48 +00:00
2001-11-21 03:55:59 +00:00
tmp = tmp - > next ;
2001-03-06 14:00:48 +00:00
2001-11-21 03:55:59 +00:00
}
2001-03-06 14:00:48 +00:00
2001-11-21 03:55:59 +00:00
}
2001-03-06 14:00:48 +00:00
2001-11-21 03:55:59 +00:00
return NULL ; /* Not found, or an error */
2001-03-06 14:00:48 +00:00
}
2000-12-26 05:57:10 +00:00
/*
* Routine to seek on a directory
*/
2005-12-29 15:06:53 +00:00
static int
smbc_lseekdir_ctx ( SMBCCTX * context ,
SMBCFILE * dir ,
off_t offset )
2000-12-26 05:57:10 +00:00
{
2003-04-16 14:45:11 +00:00
long int l_offset = offset ; /* Handle problems of size */
struct smbc_dirent * dirent = ( struct smbc_dirent * ) l_offset ;
struct smbc_dir_list * list_ent = ( struct smbc_dir_list * ) NULL ;
2007-11-19 12:36:16 +01:00
TALLOC_CTX * frame = talloc_stackframe ( ) ;
2000-12-26 05:57:10 +00:00
2003-01-13 20:04:40 +00:00
if ( ! context | | ! context - > internal | |
! context - > internal - > _initialized ) {
2001-01-07 07:10:50 +00:00
2001-11-21 03:55:59 +00:00
errno = EINVAL ;
2007-11-19 12:36:16 +01:00
TALLOC_FREE ( frame ) ;
2001-11-21 03:55:59 +00:00
return - 1 ;
2001-01-07 07:10:50 +00:00
2001-11-21 03:55:59 +00:00
}
2001-01-07 07:10:50 +00:00
2002-07-15 10:35:28 +00:00
if ( dir - > file ! = False ) { /* FIXME, should be dir, perhaps */
2001-03-05 13:34:48 +00:00
2001-11-21 03:55:59 +00:00
errno = ENOTDIR ;
2007-11-19 12:36:16 +01:00
TALLOC_FREE ( frame ) ;
2001-11-21 03:55:59 +00:00
return - 1 ;
2001-03-05 13:34:48 +00:00
2001-11-21 03:55:59 +00:00
}
2001-03-05 13:34:48 +00:00
2001-11-21 03:55:59 +00:00
/* Now, check what we were passed and see if it is OK ... */
2001-03-05 13:34:48 +00:00
2001-11-21 03:55:59 +00:00
if ( dirent = = NULL ) { /* Seek to the begining of the list */
2001-03-06 14:00:48 +00:00
2002-07-15 10:35:28 +00:00
dir - > dir_next = dir - > dir_list ;
2007-11-19 12:36:16 +01:00
TALLOC_FREE ( frame ) ;
2001-11-21 03:55:59 +00:00
return 0 ;
2001-03-06 14:00:48 +00:00
2001-11-21 03:55:59 +00:00
}
2001-03-06 14:00:48 +00:00
2007-08-18 17:29:39 +00:00
if ( offset = = - 1 ) { /* Seek to the end of the list */
dir - > dir_next = NULL ;
2007-11-19 12:36:16 +01:00
TALLOC_FREE ( frame ) ;
2007-08-18 17:29:39 +00:00
return 0 ;
}
2001-11-21 03:55:59 +00:00
/* Now, run down the list and make sure that the entry is OK */
/* This may need to be changed if we change the format of the list */
2001-03-06 14:00:48 +00:00
2002-07-15 10:35:28 +00:00
if ( ( list_ent = smbc_check_dir_ent ( dir - > dir_list , dirent ) ) = = NULL ) {
2001-11-21 03:55:59 +00:00
errno = EINVAL ; /* Bad entry */
2007-11-19 12:36:16 +01:00
TALLOC_FREE ( frame ) ;
2001-11-21 03:55:59 +00:00
return - 1 ;
}
2001-03-06 14:00:48 +00:00
2002-07-15 10:35:28 +00:00
dir - > dir_next = list_ent ;
2001-03-06 14:00:48 +00:00
2007-11-19 12:36:16 +01:00
TALLOC_FREE ( frame ) ;
2007-11-30 13:09:04 -08:00
return 0 ;
2000-12-26 05:57:10 +00:00
}
/*
* Routine to fstat a dir
*/
2005-12-29 15:06:53 +00:00
static int
smbc_fstatdir_ctx ( SMBCCTX * context ,
SMBCFILE * dir ,
struct stat * st )
2000-12-26 05:57:10 +00:00
{
2007-11-30 13:09:04 -08:00
if ( ! context | | ! context - > internal | |
2003-01-13 20:04:40 +00:00
! context - > internal - > _initialized ) {
2001-11-21 03:55:59 +00:00
errno = EINVAL ;
return - 1 ;
}
2001-01-07 07:10:50 +00:00
2001-11-21 03:55:59 +00:00
/* No code yet ... */
return 0 ;
2001-02-05 13:02:20 +00:00
}
2005-12-29 15:06:53 +00:00
static int
smbc_chmod_ctx ( SMBCCTX * context ,
const char * fname ,
mode_t newmode )
2002-07-15 10:35:28 +00:00
{
2003-10-24 17:01:19 +00:00
SMBCSRV * srv ;
2007-11-30 13:09:04 -08:00
char * server ;
char * share ;
char * user ;
char * password ;
char * workgroup ;
char * path ;
2003-10-24 17:01:19 +00:00
uint16 mode ;
2007-11-19 12:36:16 +01:00
TALLOC_CTX * frame = talloc_stackframe ( ) ;
2003-10-24 17:01:19 +00:00
2003-01-13 20:04:40 +00:00
if ( ! context | | ! context - > internal | |
! context - > internal - > _initialized ) {
2003-10-24 17:01:19 +00:00
errno = EINVAL ; /* Best I can think of ... */
2007-11-19 12:36:16 +01:00
TALLOC_FREE ( frame ) ;
2003-10-24 17:01:19 +00:00
return - 1 ;
2002-07-15 10:35:28 +00:00
}
if ( ! fname ) {
errno = EINVAL ;
2007-11-19 12:36:16 +01:00
TALLOC_FREE ( frame ) ;
2003-10-24 17:01:19 +00:00
return - 1 ;
2002-07-15 10:35:28 +00:00
}
2007-11-30 13:09:04 -08:00
2003-10-24 17:01:19 +00:00
DEBUG ( 4 , ( " smbc_chmod(%s, 0%3o) \n " , fname , newmode ) ) ;
2002-07-15 10:35:28 +00:00
2007-11-30 13:09:04 -08:00
if ( smbc_parse_path ( frame ,
context ,
fname ,
& workgroup ,
& server ,
& share ,
& path ,
& user ,
& password ,
NULL ) ) {
2004-03-19 16:22:47 +00:00
errno = EINVAL ;
2007-11-19 12:36:16 +01:00
TALLOC_FREE ( frame ) ;
2007-11-30 13:09:04 -08:00
return - 1 ;
2004-03-19 16:22:47 +00:00
}
2002-07-15 10:35:28 +00:00
2007-11-30 13:09:04 -08:00
if ( ! user | | user [ 0 ] = = ( char ) 0 ) {
user = talloc_strdup ( frame , context - > user ) ;
if ( ! user ) {
errno = ENOMEM ;
TALLOC_FREE ( frame ) ;
return - 1 ;
}
}
2001-02-06 19:25:12 +00:00
2005-12-29 15:06:59 +00:00
srv = smbc_server ( context , True ,
server , share , workgroup , user , password ) ;
2001-02-06 19:25:12 +00:00
2003-10-24 17:01:19 +00:00
if ( ! srv ) {
2007-11-19 12:36:16 +01:00
TALLOC_FREE ( frame ) ;
2003-10-24 17:01:19 +00:00
return - 1 ; /* errno set by smbc_server */
2001-11-21 03:55:59 +00:00
}
2001-02-06 19:25:12 +00:00
2003-10-24 17:01:19 +00:00
mode = 0 ;
2001-02-06 19:25:12 +00:00
2003-10-24 17:01:19 +00:00
if ( ! ( newmode & ( S_IWUSR | S_IWGRP | S_IWOTH ) ) ) mode | = aRONLY ;
if ( ( newmode & S_IXUSR ) & & lp_map_archive ( - 1 ) ) mode | = aARCH ;
if ( ( newmode & S_IXGRP ) & & lp_map_system ( - 1 ) ) mode | = aSYSTEM ;
if ( ( newmode & S_IXOTH ) & & lp_map_hidden ( - 1 ) ) mode | = aHIDDEN ;
2001-02-06 19:25:12 +00:00
2006-07-11 18:01:26 +00:00
if ( ! cli_setatr ( srv - > cli , path , mode , 0 ) ) {
errno = smbc_errno ( context , srv - > cli ) ;
2007-11-19 12:36:16 +01:00
TALLOC_FREE ( frame ) ;
2001-11-21 03:55:59 +00:00
return - 1 ;
}
2007-11-30 13:09:04 -08:00
2007-11-19 12:36:16 +01:00
TALLOC_FREE ( frame ) ;
2003-10-24 17:01:19 +00:00
return 0 ;
2001-02-06 19:25:12 +00:00
}
2005-12-29 15:06:53 +00:00
static int
smbc_utimes_ctx ( SMBCCTX * context ,
const char * fname ,
struct timeval * tbuf )
2001-02-06 19:25:12 +00:00
{
2003-10-24 17:01:19 +00:00
SMBCSRV * srv ;
2007-11-30 13:09:04 -08:00
char * server ;
char * share ;
char * user ;
char * password ;
char * workgroup ;
char * path ;
r18009: Fixes bug 4026.
This completes the work Jeremy began last week, disambiguating the meaning of
c_time. (In POSIX terminology, c_time means "status Change time", not "create
time".) All uses of c_time, a_time and m_time have now been replaced with
change_time, access_time, and write_time, and when creation time is intended,
create_time is used.
Additionally, the capability of setting and retrieving the create time have
been added to the smbc_setxattr() and smbc_getxattr() functions. An example
of setting all four times can be seen with the program
examples/libsmbclient/testacl
with the following command line similar to:
testacl -f -S "system.*:CREATE_TIME:1000000000,ACCESS_TIME:1000000060,WRITE_TIME:1000000120,CHANGE_TIME:1000000180" 'smb://server/share/testfile.txt'
The -f option turns on the new mode which uses full time names in the
attribute specification (e.g. ACCESS_TIME vs A_TIME).
(This used to be commit 8e119b64f1d92026dda855d904be09912a40601c)
2006-09-02 21:47:56 +00:00
time_t access_time ;
time_t write_time ;
2007-11-19 12:36:16 +01:00
TALLOC_CTX * frame = talloc_stackframe ( ) ;
2001-02-06 19:25:12 +00:00
2003-01-13 20:04:40 +00:00
if ( ! context | | ! context - > internal | |
! context - > internal - > _initialized ) {
2003-10-24 17:01:19 +00:00
errno = EINVAL ; /* Best I can think of ... */
2007-11-19 12:36:16 +01:00
TALLOC_FREE ( frame ) ;
2001-11-21 03:55:59 +00:00
return - 1 ;
}
2001-02-06 19:25:12 +00:00
2001-11-21 03:55:59 +00:00
if ( ! fname ) {
errno = EINVAL ;
2007-11-19 12:36:16 +01:00
TALLOC_FREE ( frame ) ;
2001-11-21 03:55:59 +00:00
return - 1 ;
}
2007-11-30 13:09:04 -08:00
2005-06-01 17:40:40 +00:00
if ( tbuf = = NULL ) {
r18009: Fixes bug 4026.
This completes the work Jeremy began last week, disambiguating the meaning of
c_time. (In POSIX terminology, c_time means "status Change time", not "create
time".) All uses of c_time, a_time and m_time have now been replaced with
change_time, access_time, and write_time, and when creation time is intended,
create_time is used.
Additionally, the capability of setting and retrieving the create time have
been added to the smbc_setxattr() and smbc_getxattr() functions. An example
of setting all four times can be seen with the program
examples/libsmbclient/testacl
with the following command line similar to:
testacl -f -S "system.*:CREATE_TIME:1000000000,ACCESS_TIME:1000000060,WRITE_TIME:1000000120,CHANGE_TIME:1000000180" 'smb://server/share/testfile.txt'
The -f option turns on the new mode which uses full time names in the
attribute specification (e.g. ACCESS_TIME vs A_TIME).
(This used to be commit 8e119b64f1d92026dda855d904be09912a40601c)
2006-09-02 21:47:56 +00:00
access_time = write_time = time ( NULL ) ;
2005-06-01 17:40:40 +00:00
} else {
r18009: Fixes bug 4026.
This completes the work Jeremy began last week, disambiguating the meaning of
c_time. (In POSIX terminology, c_time means "status Change time", not "create
time".) All uses of c_time, a_time and m_time have now been replaced with
change_time, access_time, and write_time, and when creation time is intended,
create_time is used.
Additionally, the capability of setting and retrieving the create time have
been added to the smbc_setxattr() and smbc_getxattr() functions. An example
of setting all four times can be seen with the program
examples/libsmbclient/testacl
with the following command line similar to:
testacl -f -S "system.*:CREATE_TIME:1000000000,ACCESS_TIME:1000000060,WRITE_TIME:1000000120,CHANGE_TIME:1000000180" 'smb://server/share/testfile.txt'
The -f option turns on the new mode which uses full time names in the
attribute specification (e.g. ACCESS_TIME vs A_TIME).
(This used to be commit 8e119b64f1d92026dda855d904be09912a40601c)
2006-09-02 21:47:56 +00:00
access_time = tbuf [ 0 ] . tv_sec ;
write_time = tbuf [ 1 ] . tv_sec ;
2005-06-01 17:40:40 +00:00
}
2007-11-30 13:09:04 -08:00
if ( DEBUGLVL ( 4 ) ) {
2005-06-21 20:34:24 +00:00
char * p ;
2005-06-01 17:40:40 +00:00
char atimebuf [ 32 ] ;
char mtimebuf [ 32 ] ;
r18009: Fixes bug 4026.
This completes the work Jeremy began last week, disambiguating the meaning of
c_time. (In POSIX terminology, c_time means "status Change time", not "create
time".) All uses of c_time, a_time and m_time have now been replaced with
change_time, access_time, and write_time, and when creation time is intended,
create_time is used.
Additionally, the capability of setting and retrieving the create time have
been added to the smbc_setxattr() and smbc_getxattr() functions. An example
of setting all four times can be seen with the program
examples/libsmbclient/testacl
with the following command line similar to:
testacl -f -S "system.*:CREATE_TIME:1000000000,ACCESS_TIME:1000000060,WRITE_TIME:1000000120,CHANGE_TIME:1000000180" 'smb://server/share/testfile.txt'
The -f option turns on the new mode which uses full time names in the
attribute specification (e.g. ACCESS_TIME vs A_TIME).
(This used to be commit 8e119b64f1d92026dda855d904be09912a40601c)
2006-09-02 21:47:56 +00:00
strncpy ( atimebuf , ctime ( & access_time ) , sizeof ( atimebuf ) - 1 ) ;
2005-06-21 20:34:24 +00:00
atimebuf [ sizeof ( atimebuf ) - 1 ] = ' \0 ' ;
if ( ( p = strchr ( atimebuf , ' \n ' ) ) ! = NULL ) {
* p = ' \0 ' ;
}
r18009: Fixes bug 4026.
This completes the work Jeremy began last week, disambiguating the meaning of
c_time. (In POSIX terminology, c_time means "status Change time", not "create
time".) All uses of c_time, a_time and m_time have now been replaced with
change_time, access_time, and write_time, and when creation time is intended,
create_time is used.
Additionally, the capability of setting and retrieving the create time have
been added to the smbc_setxattr() and smbc_getxattr() functions. An example
of setting all four times can be seen with the program
examples/libsmbclient/testacl
with the following command line similar to:
testacl -f -S "system.*:CREATE_TIME:1000000000,ACCESS_TIME:1000000060,WRITE_TIME:1000000120,CHANGE_TIME:1000000180" 'smb://server/share/testfile.txt'
The -f option turns on the new mode which uses full time names in the
attribute specification (e.g. ACCESS_TIME vs A_TIME).
(This used to be commit 8e119b64f1d92026dda855d904be09912a40601c)
2006-09-02 21:47:56 +00:00
strncpy ( mtimebuf , ctime ( & write_time ) , sizeof ( mtimebuf ) - 1 ) ;
2005-06-21 20:34:24 +00:00
mtimebuf [ sizeof ( mtimebuf ) - 1 ] = ' \0 ' ;
if ( ( p = strchr ( mtimebuf , ' \n ' ) ) ! = NULL ) {
* p = ' \0 ' ;
}
dbgtext ( " smbc_utimes(%s, atime = %s mtime = %s) \n " ,
fname , atimebuf , mtimebuf ) ;
2005-06-01 17:40:40 +00:00
}
2001-02-06 19:25:12 +00:00
2007-11-30 13:09:04 -08:00
if ( smbc_parse_path ( frame ,
context ,
fname ,
& workgroup ,
& server ,
& share ,
& path ,
& user ,
& password ,
NULL ) ) {
errno = EINVAL ;
2007-11-19 12:36:16 +01:00
TALLOC_FREE ( frame ) ;
2007-11-30 13:09:04 -08:00
return - 1 ;
2004-03-19 16:22:47 +00:00
}
2001-02-06 19:25:12 +00:00
2007-11-30 13:09:04 -08:00
if ( ! user | | user [ 0 ] = = ( char ) 0 ) {
user = talloc_strdup ( frame , context - > user ) ;
if ( ! user ) {
errno = ENOMEM ;
TALLOC_FREE ( frame ) ;
return - 1 ;
}
}
2003-10-24 17:01:19 +00:00
2005-12-29 15:06:59 +00:00
srv = smbc_server ( context , True ,
server , share , workgroup , user , password ) ;
2002-07-15 10:35:28 +00:00
if ( ! srv ) {
2007-11-19 12:36:16 +01:00
TALLOC_FREE ( frame ) ;
2005-06-01 20:17:16 +00:00
return - 1 ; /* errno set by smbc_server */
2002-07-15 10:35:28 +00:00
}
r18009: Fixes bug 4026.
This completes the work Jeremy began last week, disambiguating the meaning of
c_time. (In POSIX terminology, c_time means "status Change time", not "create
time".) All uses of c_time, a_time and m_time have now been replaced with
change_time, access_time, and write_time, and when creation time is intended,
create_time is used.
Additionally, the capability of setting and retrieving the create time have
been added to the smbc_setxattr() and smbc_getxattr() functions. An example
of setting all four times can be seen with the program
examples/libsmbclient/testacl
with the following command line similar to:
testacl -f -S "system.*:CREATE_TIME:1000000000,ACCESS_TIME:1000000060,WRITE_TIME:1000000120,CHANGE_TIME:1000000180" 'smb://server/share/testfile.txt'
The -f option turns on the new mode which uses full time names in the
attribute specification (e.g. ACCESS_TIME vs A_TIME).
(This used to be commit 8e119b64f1d92026dda855d904be09912a40601c)
2006-09-02 21:47:56 +00:00
if ( ! smbc_setatr ( context , srv , path ,
0 , access_time , write_time , 0 , 0 ) ) {
2007-11-19 12:36:16 +01:00
TALLOC_FREE ( frame ) ;
2005-06-01 20:17:16 +00:00
return - 1 ; /* errno set by smbc_setatr */
2005-06-01 17:40:40 +00:00
}
2002-07-15 10:35:28 +00:00
2007-11-19 12:36:16 +01:00
TALLOC_FREE ( frame ) ;
2005-06-01 20:17:16 +00:00
return 0 ;
2000-12-26 05:57:10 +00:00
}
2001-02-04 19:48:26 +00:00
2007-08-15 17:40:26 +00:00
/*
* Sort ACEs according to the documentation at
* http : //support.microsoft.com/kb/269175, at least as far as it defines the
* order .
*/
2001-02-04 19:48:26 +00:00
2005-12-29 15:06:53 +00:00
static int
ace_compare ( SEC_ACE * ace1 ,
SEC_ACE * ace2 )
2003-10-24 17:01:19 +00:00
{
2007-10-18 17:40:25 -07:00
bool b1 ;
bool b2 ;
2007-08-15 17:40:26 +00:00
/* If the ACEs are equal, we have nothing more to do. */
if ( sec_ace_equal ( ace1 , ace2 ) ) {
2003-10-24 17:01:19 +00:00
return 0 ;
2007-08-15 17:40:26 +00:00
}
/* Inherited follow non-inherited */
b1 = ( ( ace1 - > flags & SEC_ACE_FLAG_INHERITED_ACE ) ! = 0 ) ;
b2 = ( ( ace2 - > flags & SEC_ACE_FLAG_INHERITED_ACE ) ! = 0 ) ;
if ( b1 ! = b2 ) {
return ( b1 ? 1 : - 1 ) ;
}
/*
* What shall we do with AUDITs and ALARMs ? It ' s undefined . We ' ll
* sort them after DENY and ALLOW .
*/
b1 = ( ace1 - > type ! = SEC_ACE_TYPE_ACCESS_ALLOWED & &
ace1 - > type ! = SEC_ACE_TYPE_ACCESS_ALLOWED_OBJECT & &
ace1 - > type ! = SEC_ACE_TYPE_ACCESS_DENIED & &
ace1 - > type ! = SEC_ACE_TYPE_ACCESS_DENIED_OBJECT ) ;
b2 = ( ace2 - > type ! = SEC_ACE_TYPE_ACCESS_ALLOWED & &
ace2 - > type ! = SEC_ACE_TYPE_ACCESS_ALLOWED_OBJECT & &
ace2 - > type ! = SEC_ACE_TYPE_ACCESS_DENIED & &
ace2 - > type ! = SEC_ACE_TYPE_ACCESS_DENIED_OBJECT ) ;
if ( b1 ! = b2 ) {
return ( b1 ? 1 : - 1 ) ;
}
/* Allowed ACEs follow denied ACEs */
b1 = ( ace1 - > type = = SEC_ACE_TYPE_ACCESS_ALLOWED | |
ace1 - > type = = SEC_ACE_TYPE_ACCESS_ALLOWED_OBJECT ) ;
b2 = ( ace2 - > type = = SEC_ACE_TYPE_ACCESS_ALLOWED | |
ace2 - > type = = SEC_ACE_TYPE_ACCESS_ALLOWED_OBJECT ) ;
if ( b1 ! = b2 ) {
return ( b1 ? 1 : - 1 ) ;
}
2001-02-04 19:48:26 +00:00
2007-08-15 17:40:26 +00:00
/*
* ACEs applying to an entity ' s object follow those applying to the
* entity itself
*/
b1 = ( ace1 - > type = = SEC_ACE_TYPE_ACCESS_ALLOWED_OBJECT | |
ace1 - > type = = SEC_ACE_TYPE_ACCESS_DENIED_OBJECT ) ;
b2 = ( ace2 - > type = = SEC_ACE_TYPE_ACCESS_ALLOWED_OBJECT | |
ace2 - > type = = SEC_ACE_TYPE_ACCESS_DENIED_OBJECT ) ;
if ( b1 ! = b2 ) {
return ( b1 ? 1 : - 1 ) ;
}
/*
* If we get this far , the ACEs are similar as far as the
* characteristics we typically care about ( those defined by the
* referenced MS document ) . We ' ll now sort by characteristics that
* just seems reasonable .
*/
2007-11-30 13:09:04 -08:00
2007-08-15 17:40:26 +00:00
if ( ace1 - > type ! = ace2 - > type ) {
2003-10-24 17:01:19 +00:00
return ace2 - > type - ace1 - > type ;
2007-08-15 17:40:26 +00:00
}
2001-02-04 19:48:26 +00:00
2007-08-15 17:40:26 +00:00
if ( sid_compare ( & ace1 - > trustee , & ace2 - > trustee ) ) {
2003-10-24 17:01:19 +00:00
return sid_compare ( & ace1 - > trustee , & ace2 - > trustee ) ;
2007-08-15 17:40:26 +00:00
}
2001-02-04 19:48:26 +00:00
2007-08-15 17:40:26 +00:00
if ( ace1 - > flags ! = ace2 - > flags ) {
2003-10-24 17:01:19 +00:00
return ace1 - > flags - ace2 - > flags ;
2007-08-15 17:40:26 +00:00
}
2001-02-04 19:48:26 +00:00
2007-08-15 17:40:26 +00:00
if ( ace1 - > access_mask ! = ace2 - > access_mask ) {
2006-09-20 22:23:12 +00:00
return ace1 - > access_mask - ace2 - > access_mask ;
2007-08-15 17:40:26 +00:00
}
2001-02-04 19:48:26 +00:00
2007-08-15 17:40:26 +00:00
if ( ace1 - > size ! = ace2 - > size ) {
2003-10-24 17:01:19 +00:00
return ace1 - > size - ace2 - > size ;
2007-08-15 17:40:26 +00:00
}
2001-02-04 19:48:26 +00:00
2003-10-24 17:01:19 +00:00
return memcmp ( ace1 , ace2 , sizeof ( SEC_ACE ) ) ;
}
2001-11-17 07:30:19 +00:00
2001-02-04 19:48:26 +00:00
2005-12-29 15:06:53 +00:00
static void
sort_acl ( SEC_ACL * the_acl )
2003-10-24 17:01:19 +00:00
{
uint32 i ;
if ( ! the_acl ) return ;
2001-02-04 19:48:26 +00:00
2006-09-20 22:23:12 +00:00
qsort ( the_acl - > aces , the_acl - > num_aces , sizeof ( the_acl - > aces [ 0 ] ) ,
2005-12-29 15:06:53 +00:00
QSORT_CAST ace_compare ) ;
2001-02-04 19:48:26 +00:00
2003-10-24 17:01:19 +00:00
for ( i = 1 ; i < the_acl - > num_aces ; ) {
2006-09-20 22:23:12 +00:00
if ( sec_ace_equal ( & the_acl - > aces [ i - 1 ] , & the_acl - > aces [ i ] ) ) {
2003-10-24 17:01:19 +00:00
int j ;
for ( j = i ; j < the_acl - > num_aces - 1 ; j + + ) {
2006-09-20 22:23:12 +00:00
the_acl - > aces [ j ] = the_acl - > aces [ j + 1 ] ;
2003-10-24 17:01:19 +00:00
}
the_acl - > num_aces - - ;
} else {
i + + ;
}
2001-11-21 03:55:59 +00:00
}
2003-10-24 17:01:19 +00:00
}
2001-02-04 19:48:26 +00:00
2003-10-24 17:01:19 +00:00
/* convert a SID to a string, either numeric or username/group */
2005-12-29 15:06:53 +00:00
static void
convert_sid_to_string ( struct cli_state * ipc_cli ,
POLICY_HND * pol ,
fstring str ,
2007-10-18 17:40:25 -07:00
bool numeric ,
2005-12-29 15:06:53 +00:00
DOM_SID * sid )
2003-10-24 17:01:19 +00:00
{
char * * domains = NULL ;
char * * names = NULL ;
2006-09-08 14:28:06 +00:00
enum lsa_SidType * types = NULL ;
2005-09-30 17:13:37 +00:00
struct rpc_pipe_client * pipe_hnd = find_lsa_pipe_hnd ( ipc_cli ) ;
2007-11-29 13:24:54 -08:00
TALLOC_CTX * ctx ;
2003-10-24 17:01:19 +00:00
sid_to_string ( str , sid ) ;
2001-02-04 19:48:26 +00:00
2005-09-30 17:13:37 +00:00
if ( numeric ) {
return ; /* no lookup desired */
}
2007-11-30 13:09:04 -08:00
2005-09-30 17:13:37 +00:00
if ( ! pipe_hnd ) {
return ;
}
2007-11-30 13:09:04 -08:00
2003-10-24 17:01:19 +00:00
/* Ask LSA to convert the sid to a name */
2007-11-29 13:24:54 -08:00
ctx = talloc_stackframe ( ) ;
if ( ! NT_STATUS_IS_OK ( rpccli_lsa_lookup_sids ( pipe_hnd , ctx ,
2007-11-30 13:09:04 -08:00
pol , 1 , sid , & domains ,
2003-10-24 17:01:19 +00:00
& names , & types ) ) | |
! domains | | ! domains [ 0 ] | | ! names | | ! names [ 0 ] ) {
2007-11-29 13:24:54 -08:00
TALLOC_FREE ( ctx ) ;
2003-10-24 17:01:19 +00:00
return ;
2001-11-21 03:55:59 +00:00
}
2001-02-04 19:48:26 +00:00
2007-11-29 13:24:54 -08:00
TALLOC_FREE ( ctx ) ;
2003-10-24 17:01:19 +00:00
/* Converted OK */
2001-02-04 19:48:26 +00:00
2003-10-24 17:01:19 +00:00
slprintf ( str , sizeof ( fstring ) - 1 , " %s%s%s " ,
domains [ 0 ] , lp_winbind_separator ( ) ,
names [ 0 ] ) ;
2001-02-04 19:48:26 +00:00
}
2003-10-24 17:01:19 +00:00
/* convert a string to a SID, either numeric or username/group */
2007-10-18 17:40:25 -07:00
static bool
2005-12-29 15:06:53 +00:00
convert_string_to_sid ( struct cli_state * ipc_cli ,
POLICY_HND * pol ,
2007-10-18 17:40:25 -07:00
bool numeric ,
2005-12-29 15:06:53 +00:00
DOM_SID * sid ,
const char * str )
2002-07-15 10:35:28 +00:00
{
2006-09-08 14:28:06 +00:00
enum lsa_SidType * types = NULL ;
2003-10-24 17:01:19 +00:00
DOM_SID * sids = NULL ;
2007-10-18 17:40:25 -07:00
bool result = True ;
2007-12-01 11:43:00 +01:00
TALLOC_CTX * ctx = NULL ;
2005-09-30 17:13:37 +00:00
struct rpc_pipe_client * pipe_hnd = find_lsa_pipe_hnd ( ipc_cli ) ;
if ( ! pipe_hnd ) {
return False ;
}
2001-02-05 13:02:20 +00:00
2003-10-24 17:01:19 +00:00
if ( numeric ) {
if ( strncmp ( str , " S- " , 2 ) = = 0 ) {
return string_to_sid ( sid , str ) ;
}
2003-01-13 20:04:40 +00:00
2003-10-24 17:01:19 +00:00
result = False ;
goto done ;
}
2002-07-15 10:35:28 +00:00
2007-11-29 13:24:54 -08:00
ctx = talloc_stackframe ( ) ;
if ( ! NT_STATUS_IS_OK ( rpccli_lsa_lookup_names ( pipe_hnd , ctx ,
2007-11-30 13:09:04 -08:00
pol , 1 , & str , NULL , 1 , & sids ,
& types ) ) ) {
2003-10-24 17:01:19 +00:00
result = False ;
goto done ;
2003-01-13 20:04:40 +00:00
}
2003-10-24 17:01:19 +00:00
sid_copy ( sid , & sids [ 0 ] ) ;
done :
2003-01-13 20:04:40 +00:00
2007-11-29 13:24:54 -08:00
TALLOC_FREE ( ctx ) ;
2003-10-24 17:01:19 +00:00
return result ;
2002-07-15 10:35:28 +00:00
}
2003-10-24 17:01:19 +00:00
/* parse an ACE in the same format as print_ace() */
2007-10-18 17:40:25 -07:00
static bool
2005-12-29 15:06:53 +00:00
parse_ace ( struct cli_state * ipc_cli ,
POLICY_HND * pol ,
SEC_ACE * ace ,
2007-10-18 17:40:25 -07:00
bool numeric ,
2005-12-29 15:06:53 +00:00
char * str )
2001-02-05 13:02:20 +00:00
{
2003-10-24 17:01:19 +00:00
char * p ;
const char * cp ;
2007-12-07 17:32:32 -08:00
char * tok ;
2005-12-29 15:06:53 +00:00
unsigned int atype ;
unsigned int aflags ;
unsigned int amask ;
2003-10-24 17:01:19 +00:00
DOM_SID sid ;
SEC_ACCESS mask ;
const struct perm_value * v ;
struct perm_value {
const char * perm ;
uint32 mask ;
} ;
2007-12-07 17:32:32 -08:00
TALLOC_CTX * frame = talloc_stackframe ( ) ;
2003-10-24 17:01:19 +00:00
/* These values discovered by inspection */
static const struct perm_value special_values [ ] = {
{ " R " , 0x00120089 } ,
{ " W " , 0x00120116 } ,
{ " X " , 0x001200a0 } ,
{ " D " , 0x00010000 } ,
{ " P " , 0x00040000 } ,
{ " O " , 0x00080000 } ,
{ NULL , 0 } ,
} ;
static const struct perm_value standard_values [ ] = {
{ " READ " , 0x001200a9 } ,
{ " CHANGE " , 0x001301bf } ,
{ " FULL " , 0x001f01ff } ,
{ NULL , 0 } ,
} ;
ZERO_STRUCTP ( ace ) ;
p = strchr_m ( str , ' : ' ) ;
2007-12-07 17:32:32 -08:00
if ( ! p ) {
TALLOC_FREE ( frame ) ;
return False ;
}
2003-10-24 17:01:19 +00:00
* p = ' \0 ' ;
p + + ;
/* Try to parse numeric form */
if ( sscanf ( p , " %i/%i/%i " , & atype , & aflags , & amask ) = = 3 & &
convert_string_to_sid ( ipc_cli , pol , numeric , & sid , str ) ) {
goto done ;
}
/* Try to parse text form */
if ( ! convert_string_to_sid ( ipc_cli , pol , numeric , & sid , str ) ) {
2007-12-07 17:32:32 -08:00
TALLOC_FREE ( frame ) ;
return false ;
2003-10-24 17:01:19 +00:00
}
cp = p ;
2007-12-07 17:32:32 -08:00
if ( ! next_token_talloc ( frame , & cp , & tok , " / " ) ) {
TALLOC_FREE ( frame ) ;
return false ;
2003-10-24 17:01:19 +00:00
}
if ( StrnCaseCmp ( tok , " ALLOWED " , strlen ( " ALLOWED " ) ) = = 0 ) {
atype = SEC_ACE_TYPE_ACCESS_ALLOWED ;
} else if ( StrnCaseCmp ( tok , " DENIED " , strlen ( " DENIED " ) ) = = 0 ) {
atype = SEC_ACE_TYPE_ACCESS_DENIED ;
} else {
2007-12-07 17:32:32 -08:00
TALLOC_FREE ( frame ) ;
return false ;
2002-07-15 10:35:28 +00:00
}
2003-10-24 17:01:19 +00:00
/* Only numeric form accepted for flags at present */
2007-12-07 17:32:32 -08:00
if ( ! ( next_token_talloc ( frame , & cp , & tok , " / " ) & &
2003-10-24 17:01:19 +00:00
sscanf ( tok , " %i " , & aflags ) ) ) {
2007-12-07 17:32:32 -08:00
TALLOC_FREE ( frame ) ;
return false ;
2003-10-24 17:01:19 +00:00
}
2007-12-07 17:32:32 -08:00
if ( ! next_token_talloc ( frame , & cp , & tok , " / " ) ) {
TALLOC_FREE ( frame ) ;
return false ;
2003-10-24 17:01:19 +00:00
}
if ( strncmp ( tok , " 0x " , 2 ) = = 0 ) {
if ( sscanf ( tok , " %i " , & amask ) ! = 1 ) {
2007-12-07 17:32:32 -08:00
TALLOC_FREE ( frame ) ;
return false ;
2002-07-15 10:35:28 +00:00
}
2003-10-24 17:01:19 +00:00
goto done ;
2002-07-15 10:35:28 +00:00
}
2003-10-24 17:01:19 +00:00
for ( v = standard_values ; v - > perm ; v + + ) {
if ( strcmp ( tok , v - > perm ) = = 0 ) {
amask = v - > mask ;
goto done ;
2002-07-15 10:35:28 +00:00
}
2003-10-24 17:01:19 +00:00
}
p = tok ;
while ( * p ) {
2007-10-18 17:40:25 -07:00
bool found = False ;
2003-10-24 17:01:19 +00:00
for ( v = special_values ; v - > perm ; v + + ) {
if ( v - > perm [ 0 ] = = * p ) {
amask | = v - > mask ;
found = True ;
}
2002-07-15 10:35:28 +00:00
}
2003-10-24 17:01:19 +00:00
2007-12-07 17:32:32 -08:00
if ( ! found ) {
TALLOC_FREE ( frame ) ;
return false ;
}
2003-10-24 17:01:19 +00:00
p + + ;
2002-07-15 10:35:28 +00:00
}
2001-02-05 13:02:20 +00:00
2003-10-24 17:01:19 +00:00
if ( * p ) {
2007-12-07 17:32:32 -08:00
TALLOC_FREE ( frame ) ;
return false ;
2003-10-24 17:01:19 +00:00
}
2001-02-05 13:02:20 +00:00
2003-10-24 17:01:19 +00:00
done :
2006-09-20 22:23:12 +00:00
mask = amask ;
2003-10-24 17:01:19 +00:00
init_sec_ace ( ace , & sid , atype , mask , aflags ) ;
2007-12-07 17:32:32 -08:00
TALLOC_FREE ( frame ) ;
return true ;
2003-10-24 17:01:19 +00:00
}
2001-02-05 13:02:20 +00:00
2003-10-24 17:01:19 +00:00
/* add an ACE to a list of ACEs in a SEC_ACL */
2007-10-18 17:40:25 -07:00
static bool
2005-12-29 15:06:53 +00:00
add_ace ( SEC_ACL * * the_acl ,
SEC_ACE * ace ,
TALLOC_CTX * ctx )
2002-07-15 10:35:28 +00:00
{
2005-06-24 20:25:18 +00:00
SEC_ACL * newacl ;
2003-10-24 17:01:19 +00:00
SEC_ACE * aces ;
2005-12-29 15:06:53 +00:00
2003-10-24 17:01:19 +00:00
if ( ! * the_acl ) {
( * the_acl ) = make_sec_acl ( ctx , 3 , 1 , ace ) ;
return True ;
}
2002-07-15 10:35:28 +00:00
2006-06-19 19:07:39 +00:00
if ( ( aces = SMB_CALLOC_ARRAY ( SEC_ACE , 1 + ( * the_acl ) - > num_aces ) ) = = NULL ) {
return False ;
}
2006-09-20 22:23:12 +00:00
memcpy ( aces , ( * the_acl ) - > aces , ( * the_acl ) - > num_aces * sizeof ( SEC_ACE ) ) ;
2003-10-24 17:01:19 +00:00
memcpy ( aces + ( * the_acl ) - > num_aces , ace , sizeof ( SEC_ACE ) ) ;
2005-12-29 15:06:53 +00:00
newacl = make_sec_acl ( ctx , ( * the_acl ) - > revision ,
1 + ( * the_acl ) - > num_aces , aces ) ;
2003-10-24 17:01:19 +00:00
SAFE_FREE ( aces ) ;
2005-06-24 20:25:18 +00:00
( * the_acl ) = newacl ;
2003-10-24 17:01:19 +00:00
return True ;
}
/* parse a ascii version of a security descriptor */
2005-12-29 15:06:53 +00:00
static SEC_DESC *
sec_desc_parse ( TALLOC_CTX * ctx ,
struct cli_state * ipc_cli ,
POLICY_HND * pol ,
2007-10-18 17:40:25 -07:00
bool numeric ,
2005-12-29 15:06:53 +00:00
char * str )
2003-10-24 17:01:19 +00:00
{
const char * p = str ;
2007-12-07 17:32:32 -08:00
char * tok ;
2006-03-13 01:42:40 +00:00
SEC_DESC * ret = NULL ;
2003-10-24 17:01:19 +00:00
size_t sd_size ;
2007-10-10 15:34:30 -05:00
DOM_SID * group_sid = NULL ;
2005-12-29 15:06:53 +00:00
DOM_SID * owner_sid = NULL ;
2003-10-24 17:01:19 +00:00
SEC_ACL * dacl = NULL ;
int revision = 1 ;
2007-12-07 17:32:32 -08:00
while ( next_token_talloc ( ctx , & p , & tok , " \t , \r \n " ) ) {
2003-10-24 17:01:19 +00:00
if ( StrnCaseCmp ( tok , " REVISION: " , 9 ) = = 0 ) {
revision = strtol ( tok + 9 , NULL , 16 ) ;
continue ;
}
if ( StrnCaseCmp ( tok , " OWNER: " , 6 ) = = 0 ) {
2006-03-13 01:42:40 +00:00
if ( owner_sid ) {
DEBUG ( 5 , ( " OWNER specified more than once! \n " ) ) ;
goto done ;
}
2004-12-07 18:25:53 +00:00
owner_sid = SMB_CALLOC_ARRAY ( DOM_SID , 1 ) ;
2003-10-24 17:01:19 +00:00
if ( ! owner_sid | |
! convert_string_to_sid ( ipc_cli , pol ,
numeric ,
owner_sid , tok + 6 ) ) {
DEBUG ( 5 , ( " Failed to parse owner sid \n " ) ) ;
2006-03-13 01:42:40 +00:00
goto done ;
2003-10-24 17:01:19 +00:00
}
continue ;
}
if ( StrnCaseCmp ( tok , " OWNER+: " , 7 ) = = 0 ) {
2006-03-13 01:42:40 +00:00
if ( owner_sid ) {
DEBUG ( 5 , ( " OWNER specified more than once! \n " ) ) ;
goto done ;
}
2004-12-07 18:25:53 +00:00
owner_sid = SMB_CALLOC_ARRAY ( DOM_SID , 1 ) ;
2003-10-24 17:01:19 +00:00
if ( ! owner_sid | |
! convert_string_to_sid ( ipc_cli , pol ,
False ,
owner_sid , tok + 7 ) ) {
DEBUG ( 5 , ( " Failed to parse owner sid \n " ) ) ;
2006-03-13 01:42:40 +00:00
goto done ;
2003-10-24 17:01:19 +00:00
}
continue ;
}
if ( StrnCaseCmp ( tok , " GROUP: " , 6 ) = = 0 ) {
2007-10-10 15:34:30 -05:00
if ( group_sid ) {
2006-03-13 01:42:40 +00:00
DEBUG ( 5 , ( " GROUP specified more than once! \n " ) ) ;
goto done ;
}
2007-10-10 15:34:30 -05:00
group_sid = SMB_CALLOC_ARRAY ( DOM_SID , 1 ) ;
if ( ! group_sid | |
2003-10-24 17:01:19 +00:00
! convert_string_to_sid ( ipc_cli , pol ,
numeric ,
2007-10-10 15:34:30 -05:00
group_sid , tok + 6 ) ) {
2003-10-24 17:01:19 +00:00
DEBUG ( 5 , ( " Failed to parse group sid \n " ) ) ;
2006-03-13 01:42:40 +00:00
goto done ;
2003-10-24 17:01:19 +00:00
}
continue ;
}
if ( StrnCaseCmp ( tok , " GROUP+: " , 7 ) = = 0 ) {
2007-10-10 15:34:30 -05:00
if ( group_sid ) {
2006-03-13 01:42:40 +00:00
DEBUG ( 5 , ( " GROUP specified more than once! \n " ) ) ;
goto done ;
}
2007-10-10 15:34:30 -05:00
group_sid = SMB_CALLOC_ARRAY ( DOM_SID , 1 ) ;
if ( ! group_sid | |
2003-10-24 17:01:19 +00:00
! convert_string_to_sid ( ipc_cli , pol ,
False ,
2007-10-10 15:34:30 -05:00
group_sid , tok + 6 ) ) {
2003-10-24 17:01:19 +00:00
DEBUG ( 5 , ( " Failed to parse group sid \n " ) ) ;
2006-03-13 01:42:40 +00:00
goto done ;
2003-10-24 17:01:19 +00:00
}
continue ;
}
if ( StrnCaseCmp ( tok , " ACL: " , 4 ) = = 0 ) {
SEC_ACE ace ;
if ( ! parse_ace ( ipc_cli , pol , & ace , numeric , tok + 4 ) ) {
DEBUG ( 5 , ( " Failed to parse ACL %s \n " , tok ) ) ;
2006-03-13 01:42:40 +00:00
goto done ;
2003-10-24 17:01:19 +00:00
}
if ( ! add_ace ( & dacl , & ace , ctx ) ) {
DEBUG ( 5 , ( " Failed to add ACL %s \n " , tok ) ) ;
2006-03-13 01:42:40 +00:00
goto done ;
2003-10-24 17:01:19 +00:00
}
continue ;
}
if ( StrnCaseCmp ( tok , " ACL+: " , 5 ) = = 0 ) {
SEC_ACE ace ;
if ( ! parse_ace ( ipc_cli , pol , & ace , False , tok + 5 ) ) {
DEBUG ( 5 , ( " Failed to parse ACL %s \n " , tok ) ) ;
2006-03-13 01:42:40 +00:00
goto done ;
2003-10-24 17:01:19 +00:00
}
if ( ! add_ace ( & dacl , & ace , ctx ) ) {
DEBUG ( 5 , ( " Failed to add ACL %s \n " , tok ) ) ;
2006-03-13 01:42:40 +00:00
goto done ;
2003-10-24 17:01:19 +00:00
}
continue ;
}
DEBUG ( 5 , ( " Failed to parse security descriptor \n " ) ) ;
2006-03-13 01:42:40 +00:00
goto done ;
2001-11-21 03:55:59 +00:00
}
2001-02-05 13:02:20 +00:00
2003-10-24 17:01:19 +00:00
ret = make_sec_desc ( ctx , revision , SEC_DESC_SELF_RELATIVE ,
2007-10-10 15:34:30 -05:00
owner_sid , group_sid , NULL , dacl , & sd_size ) ;
2002-07-15 10:35:28 +00:00
2006-03-13 01:42:40 +00:00
done :
2007-10-10 15:34:30 -05:00
SAFE_FREE ( group_sid ) ;
2003-10-24 17:01:19 +00:00
SAFE_FREE ( owner_sid ) ;
2001-02-05 13:02:20 +00:00
2003-10-24 17:01:19 +00:00
return ret ;
}
2001-02-05 13:02:20 +00:00
2003-10-24 17:01:19 +00:00
2005-03-10 23:41:19 +00:00
/* Obtain the current dos attributes */
2005-12-29 15:06:53 +00:00
static DOS_ATTR_DESC *
dos_attr_query ( SMBCCTX * context ,
TALLOC_CTX * ctx ,
const char * filename ,
SMBCSRV * srv )
2005-03-10 23:41:19 +00:00
{
r18009: Fixes bug 4026.
This completes the work Jeremy began last week, disambiguating the meaning of
c_time. (In POSIX terminology, c_time means "status Change time", not "create
time".) All uses of c_time, a_time and m_time have now been replaced with
change_time, access_time, and write_time, and when creation time is intended,
create_time is used.
Additionally, the capability of setting and retrieving the create time have
been added to the smbc_setxattr() and smbc_getxattr() functions. An example
of setting all four times can be seen with the program
examples/libsmbclient/testacl
with the following command line similar to:
testacl -f -S "system.*:CREATE_TIME:1000000000,ACCESS_TIME:1000000060,WRITE_TIME:1000000120,CHANGE_TIME:1000000180" 'smb://server/share/testfile.txt'
The -f option turns on the new mode which uses full time names in the
attribute specification (e.g. ACCESS_TIME vs A_TIME).
(This used to be commit 8e119b64f1d92026dda855d904be09912a40601c)
2006-09-02 21:47:56 +00:00
struct timespec create_time_ts ;
struct timespec write_time_ts ;
struct timespec access_time_ts ;
struct timespec change_time_ts ;
2005-03-22 21:17:01 +00:00
SMB_OFF_T size = 0 ;
2005-03-10 23:41:19 +00:00
uint16 mode = 0 ;
SMB_INO_T inode = 0 ;
DOS_ATTR_DESC * ret ;
2007-11-30 13:09:04 -08:00
2005-05-03 07:33:49 +00:00
ret = TALLOC_P ( ctx , DOS_ATTR_DESC ) ;
2005-03-10 23:41:19 +00:00
if ( ! ret ) {
errno = ENOMEM ;
return NULL ;
}
/* Obtain the DOS attributes */
2005-03-31 05:06:04 +00:00
if ( ! smbc_getatr ( context , srv , CONST_DISCARD ( char * , filename ) ,
2007-11-30 13:09:04 -08:00
& mode , & size ,
r18009: Fixes bug 4026.
This completes the work Jeremy began last week, disambiguating the meaning of
c_time. (In POSIX terminology, c_time means "status Change time", not "create
time".) All uses of c_time, a_time and m_time have now been replaced with
change_time, access_time, and write_time, and when creation time is intended,
create_time is used.
Additionally, the capability of setting and retrieving the create time have
been added to the smbc_setxattr() and smbc_getxattr() functions. An example
of setting all four times can be seen with the program
examples/libsmbclient/testacl
with the following command line similar to:
testacl -f -S "system.*:CREATE_TIME:1000000000,ACCESS_TIME:1000000060,WRITE_TIME:1000000120,CHANGE_TIME:1000000180" 'smb://server/share/testfile.txt'
The -f option turns on the new mode which uses full time names in the
attribute specification (e.g. ACCESS_TIME vs A_TIME).
(This used to be commit 8e119b64f1d92026dda855d904be09912a40601c)
2006-09-02 21:47:56 +00:00
& create_time_ts ,
& access_time_ts ,
& write_time_ts ,
2007-11-30 13:09:04 -08:00
& change_time_ts ,
r18009: Fixes bug 4026.
This completes the work Jeremy began last week, disambiguating the meaning of
c_time. (In POSIX terminology, c_time means "status Change time", not "create
time".) All uses of c_time, a_time and m_time have now been replaced with
change_time, access_time, and write_time, and when creation time is intended,
create_time is used.
Additionally, the capability of setting and retrieving the create time have
been added to the smbc_setxattr() and smbc_getxattr() functions. An example
of setting all four times can be seen with the program
examples/libsmbclient/testacl
with the following command line similar to:
testacl -f -S "system.*:CREATE_TIME:1000000000,ACCESS_TIME:1000000060,WRITE_TIME:1000000120,CHANGE_TIME:1000000180" 'smb://server/share/testfile.txt'
The -f option turns on the new mode which uses full time names in the
attribute specification (e.g. ACCESS_TIME vs A_TIME).
(This used to be commit 8e119b64f1d92026dda855d904be09912a40601c)
2006-09-02 21:47:56 +00:00
& inode ) ) {
2006-07-11 18:01:26 +00:00
errno = smbc_errno ( context , srv - > cli ) ;
2005-03-10 23:41:19 +00:00
DEBUG ( 5 , ( " dos_attr_query Failed to query old attributes \n " ) ) ;
return NULL ;
}
2007-11-30 13:09:04 -08:00
2005-03-10 23:41:19 +00:00
ret - > mode = mode ;
ret - > size = size ;
r18009: Fixes bug 4026.
This completes the work Jeremy began last week, disambiguating the meaning of
c_time. (In POSIX terminology, c_time means "status Change time", not "create
time".) All uses of c_time, a_time and m_time have now been replaced with
change_time, access_time, and write_time, and when creation time is intended,
create_time is used.
Additionally, the capability of setting and retrieving the create time have
been added to the smbc_setxattr() and smbc_getxattr() functions. An example
of setting all four times can be seen with the program
examples/libsmbclient/testacl
with the following command line similar to:
testacl -f -S "system.*:CREATE_TIME:1000000000,ACCESS_TIME:1000000060,WRITE_TIME:1000000120,CHANGE_TIME:1000000180" 'smb://server/share/testfile.txt'
The -f option turns on the new mode which uses full time names in the
attribute specification (e.g. ACCESS_TIME vs A_TIME).
(This used to be commit 8e119b64f1d92026dda855d904be09912a40601c)
2006-09-02 21:47:56 +00:00
ret - > create_time = convert_timespec_to_time_t ( create_time_ts ) ;
ret - > access_time = convert_timespec_to_time_t ( access_time_ts ) ;
ret - > write_time = convert_timespec_to_time_t ( write_time_ts ) ;
ret - > change_time = convert_timespec_to_time_t ( change_time_ts ) ;
2005-03-10 23:41:19 +00:00
ret - > inode = inode ;
return ret ;
}
/* parse a ascii version of a security descriptor */
2005-12-29 15:06:53 +00:00
static void
dos_attr_parse ( SMBCCTX * context ,
DOS_ATTR_DESC * dad ,
SMBCSRV * srv ,
char * str )
2005-03-10 23:41:19 +00:00
{
r18009: Fixes bug 4026.
This completes the work Jeremy began last week, disambiguating the meaning of
c_time. (In POSIX terminology, c_time means "status Change time", not "create
time".) All uses of c_time, a_time and m_time have now been replaced with
change_time, access_time, and write_time, and when creation time is intended,
create_time is used.
Additionally, the capability of setting and retrieving the create time have
been added to the smbc_setxattr() and smbc_getxattr() functions. An example
of setting all four times can be seen with the program
examples/libsmbclient/testacl
with the following command line similar to:
testacl -f -S "system.*:CREATE_TIME:1000000000,ACCESS_TIME:1000000060,WRITE_TIME:1000000120,CHANGE_TIME:1000000180" 'smb://server/share/testfile.txt'
The -f option turns on the new mode which uses full time names in the
attribute specification (e.g. ACCESS_TIME vs A_TIME).
(This used to be commit 8e119b64f1d92026dda855d904be09912a40601c)
2006-09-02 21:47:56 +00:00
int n ;
const char * p = str ;
2007-12-07 17:32:32 -08:00
char * tok = NULL ;
TALLOC_CTX * frame = NULL ;
r18009: Fixes bug 4026.
This completes the work Jeremy began last week, disambiguating the meaning of
c_time. (In POSIX terminology, c_time means "status Change time", not "create
time".) All uses of c_time, a_time and m_time have now been replaced with
change_time, access_time, and write_time, and when creation time is intended,
create_time is used.
Additionally, the capability of setting and retrieving the create time have
been added to the smbc_setxattr() and smbc_getxattr() functions. An example
of setting all four times can be seen with the program
examples/libsmbclient/testacl
with the following command line similar to:
testacl -f -S "system.*:CREATE_TIME:1000000000,ACCESS_TIME:1000000060,WRITE_TIME:1000000120,CHANGE_TIME:1000000180" 'smb://server/share/testfile.txt'
The -f option turns on the new mode which uses full time names in the
attribute specification (e.g. ACCESS_TIME vs A_TIME).
(This used to be commit 8e119b64f1d92026dda855d904be09912a40601c)
2006-09-02 21:47:56 +00:00
struct {
const char * create_time_attr ;
const char * access_time_attr ;
const char * write_time_attr ;
const char * change_time_attr ;
} attr_strings ;
/* Determine whether to use old-style or new-style attribute names */
if ( context - > internal - > _full_time_names ) {
/* new-style names */
attr_strings . create_time_attr = " CREATE_TIME " ;
attr_strings . access_time_attr = " ACCESS_TIME " ;
attr_strings . write_time_attr = " WRITE_TIME " ;
attr_strings . change_time_attr = " CHANGE_TIME " ;
} else {
/* old-style names */
attr_strings . create_time_attr = NULL ;
attr_strings . access_time_attr = " A_TIME " ;
attr_strings . write_time_attr = " M_TIME " ;
attr_strings . change_time_attr = " C_TIME " ;
}
/* if this is to set the entire ACL... */
if ( * str = = ' * ' ) {
/* ... then increment past the first colon if there is one */
if ( ( p = strchr ( str , ' : ' ) ) ! = NULL ) {
+ + p ;
} else {
p = str ;
}
}
2005-03-10 23:41:19 +00:00
2007-12-07 17:32:32 -08:00
frame = talloc_stackframe ( ) ;
while ( next_token_talloc ( frame , & p , & tok , " \t , \r \n " ) ) {
2005-03-10 23:41:19 +00:00
if ( StrnCaseCmp ( tok , " MODE: " , 5 ) = = 0 ) {
dad - > mode = strtol ( tok + 5 , NULL , 16 ) ;
continue ;
}
if ( StrnCaseCmp ( tok , " SIZE: " , 5 ) = = 0 ) {
2005-10-21 22:48:27 +00:00
dad - > size = ( SMB_OFF_T ) atof ( tok + 5 ) ;
2005-03-10 23:41:19 +00:00
continue ;
}
r18009: Fixes bug 4026.
This completes the work Jeremy began last week, disambiguating the meaning of
c_time. (In POSIX terminology, c_time means "status Change time", not "create
time".) All uses of c_time, a_time and m_time have now been replaced with
change_time, access_time, and write_time, and when creation time is intended,
create_time is used.
Additionally, the capability of setting and retrieving the create time have
been added to the smbc_setxattr() and smbc_getxattr() functions. An example
of setting all four times can be seen with the program
examples/libsmbclient/testacl
with the following command line similar to:
testacl -f -S "system.*:CREATE_TIME:1000000000,ACCESS_TIME:1000000060,WRITE_TIME:1000000120,CHANGE_TIME:1000000180" 'smb://server/share/testfile.txt'
The -f option turns on the new mode which uses full time names in the
attribute specification (e.g. ACCESS_TIME vs A_TIME).
(This used to be commit 8e119b64f1d92026dda855d904be09912a40601c)
2006-09-02 21:47:56 +00:00
n = strlen ( attr_strings . access_time_attr ) ;
if ( StrnCaseCmp ( tok , attr_strings . access_time_attr , n ) = = 0 ) {
dad - > access_time = ( time_t ) strtol ( tok + n + 1 , NULL , 10 ) ;
2005-03-10 23:41:19 +00:00
continue ;
}
r18009: Fixes bug 4026.
This completes the work Jeremy began last week, disambiguating the meaning of
c_time. (In POSIX terminology, c_time means "status Change time", not "create
time".) All uses of c_time, a_time and m_time have now been replaced with
change_time, access_time, and write_time, and when creation time is intended,
create_time is used.
Additionally, the capability of setting and retrieving the create time have
been added to the smbc_setxattr() and smbc_getxattr() functions. An example
of setting all four times can be seen with the program
examples/libsmbclient/testacl
with the following command line similar to:
testacl -f -S "system.*:CREATE_TIME:1000000000,ACCESS_TIME:1000000060,WRITE_TIME:1000000120,CHANGE_TIME:1000000180" 'smb://server/share/testfile.txt'
The -f option turns on the new mode which uses full time names in the
attribute specification (e.g. ACCESS_TIME vs A_TIME).
(This used to be commit 8e119b64f1d92026dda855d904be09912a40601c)
2006-09-02 21:47:56 +00:00
n = strlen ( attr_strings . change_time_attr ) ;
if ( StrnCaseCmp ( tok , attr_strings . change_time_attr , n ) = = 0 ) {
dad - > change_time = ( time_t ) strtol ( tok + n + 1 , NULL , 10 ) ;
2005-03-10 23:41:19 +00:00
continue ;
}
r18009: Fixes bug 4026.
This completes the work Jeremy began last week, disambiguating the meaning of
c_time. (In POSIX terminology, c_time means "status Change time", not "create
time".) All uses of c_time, a_time and m_time have now been replaced with
change_time, access_time, and write_time, and when creation time is intended,
create_time is used.
Additionally, the capability of setting and retrieving the create time have
been added to the smbc_setxattr() and smbc_getxattr() functions. An example
of setting all four times can be seen with the program
examples/libsmbclient/testacl
with the following command line similar to:
testacl -f -S "system.*:CREATE_TIME:1000000000,ACCESS_TIME:1000000060,WRITE_TIME:1000000120,CHANGE_TIME:1000000180" 'smb://server/share/testfile.txt'
The -f option turns on the new mode which uses full time names in the
attribute specification (e.g. ACCESS_TIME vs A_TIME).
(This used to be commit 8e119b64f1d92026dda855d904be09912a40601c)
2006-09-02 21:47:56 +00:00
n = strlen ( attr_strings . write_time_attr ) ;
if ( StrnCaseCmp ( tok , attr_strings . write_time_attr , n ) = = 0 ) {
dad - > write_time = ( time_t ) strtol ( tok + n + 1 , NULL , 10 ) ;
continue ;
}
2006-12-23 16:47:50 +00:00
if ( attr_strings . create_time_attr ! = NULL ) {
n = strlen ( attr_strings . create_time_attr ) ;
if ( StrnCaseCmp ( tok , attr_strings . create_time_attr ,
n ) = = 0 ) {
dad - > create_time = ( time_t ) strtol ( tok + n + 1 ,
NULL , 10 ) ;
continue ;
}
2005-03-10 23:41:19 +00:00
}
if ( StrnCaseCmp ( tok , " INODE: " , 6 ) = = 0 ) {
2005-10-21 22:48:27 +00:00
dad - > inode = ( SMB_INO_T ) atof ( tok + 6 ) ;
2005-03-10 23:41:19 +00:00
continue ;
}
}
2007-12-07 17:32:32 -08:00
TALLOC_FREE ( frame ) ;
2005-03-10 23:41:19 +00:00
}
2007-11-30 13:09:04 -08:00
/*****************************************************
2005-10-21 22:48:27 +00:00
Retrieve the acls for a file .
2003-10-24 17:01:19 +00:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2005-10-21 22:48:27 +00:00
2005-12-29 15:06:53 +00:00
static int
cacl_get ( SMBCCTX * context ,
TALLOC_CTX * ctx ,
SMBCSRV * srv ,
struct cli_state * ipc_cli ,
POLICY_HND * pol ,
char * filename ,
char * attr_name ,
char * buf ,
int bufsize )
2003-10-24 17:01:19 +00:00
{
uint32 i ;
int n = 0 ;
int n_used ;
2007-10-18 17:40:25 -07:00
bool all ;
bool all_nt ;
bool all_nt_acls ;
bool all_dos ;
bool some_nt ;
bool some_dos ;
bool exclude_nt_revision = False ;
bool exclude_nt_owner = False ;
bool exclude_nt_group = False ;
bool exclude_nt_acl = False ;
bool exclude_dos_mode = False ;
bool exclude_dos_size = False ;
bool exclude_dos_create_time = False ;
bool exclude_dos_access_time = False ;
bool exclude_dos_write_time = False ;
bool exclude_dos_change_time = False ;
bool exclude_dos_inode = False ;
bool numeric = True ;
bool determine_size = ( bufsize = = 0 ) ;
2003-10-24 17:01:19 +00:00
int fnum = - 1 ;
SEC_DESC * sd ;
fstring sidstr ;
2005-03-31 05:06:04 +00:00
fstring name_sandbox ;
char * name ;
char * pExclude ;
2003-10-24 17:01:19 +00:00
char * p ;
r18009: Fixes bug 4026.
This completes the work Jeremy began last week, disambiguating the meaning of
c_time. (In POSIX terminology, c_time means "status Change time", not "create
time".) All uses of c_time, a_time and m_time have now been replaced with
change_time, access_time, and write_time, and when creation time is intended,
create_time is used.
Additionally, the capability of setting and retrieving the create time have
been added to the smbc_setxattr() and smbc_getxattr() functions. An example
of setting all four times can be seen with the program
examples/libsmbclient/testacl
with the following command line similar to:
testacl -f -S "system.*:CREATE_TIME:1000000000,ACCESS_TIME:1000000060,WRITE_TIME:1000000120,CHANGE_TIME:1000000180" 'smb://server/share/testfile.txt'
The -f option turns on the new mode which uses full time names in the
attribute specification (e.g. ACCESS_TIME vs A_TIME).
(This used to be commit 8e119b64f1d92026dda855d904be09912a40601c)
2006-09-02 21:47:56 +00:00
struct timespec create_time_ts ;
struct timespec write_time_ts ;
struct timespec access_time_ts ;
struct timespec change_time_ts ;
time_t create_time = ( time_t ) 0 ;
time_t write_time = ( time_t ) 0 ;
time_t access_time = ( time_t ) 0 ;
time_t change_time = ( time_t ) 0 ;
2005-03-22 21:17:01 +00:00
SMB_OFF_T size = 0 ;
2005-03-10 23:41:19 +00:00
uint16 mode = 0 ;
SMB_INO_T ino = 0 ;
2006-07-11 18:01:26 +00:00
struct cli_state * cli = srv - > cli ;
r18009: Fixes bug 4026.
This completes the work Jeremy began last week, disambiguating the meaning of
c_time. (In POSIX terminology, c_time means "status Change time", not "create
time".) All uses of c_time, a_time and m_time have now been replaced with
change_time, access_time, and write_time, and when creation time is intended,
create_time is used.
Additionally, the capability of setting and retrieving the create time have
been added to the smbc_setxattr() and smbc_getxattr() functions. An example
of setting all four times can be seen with the program
examples/libsmbclient/testacl
with the following command line similar to:
testacl -f -S "system.*:CREATE_TIME:1000000000,ACCESS_TIME:1000000060,WRITE_TIME:1000000120,CHANGE_TIME:1000000180" 'smb://server/share/testfile.txt'
The -f option turns on the new mode which uses full time names in the
attribute specification (e.g. ACCESS_TIME vs A_TIME).
(This used to be commit 8e119b64f1d92026dda855d904be09912a40601c)
2006-09-02 21:47:56 +00:00
struct {
const char * create_time_attr ;
const char * access_time_attr ;
const char * write_time_attr ;
const char * change_time_attr ;
} attr_strings ;
struct {
const char * create_time_attr ;
const char * access_time_attr ;
const char * write_time_attr ;
const char * change_time_attr ;
} excl_attr_strings ;
/* Determine whether to use old-style or new-style attribute names */
if ( context - > internal - > _full_time_names ) {
/* new-style names */
attr_strings . create_time_attr = " CREATE_TIME " ;
attr_strings . access_time_attr = " ACCESS_TIME " ;
attr_strings . write_time_attr = " WRITE_TIME " ;
attr_strings . change_time_attr = " CHANGE_TIME " ;
excl_attr_strings . create_time_attr = " CREATE_TIME " ;
excl_attr_strings . access_time_attr = " ACCESS_TIME " ;
excl_attr_strings . write_time_attr = " WRITE_TIME " ;
excl_attr_strings . change_time_attr = " CHANGE_TIME " ;
} else {
/* old-style names */
attr_strings . create_time_attr = NULL ;
attr_strings . access_time_attr = " A_TIME " ;
attr_strings . write_time_attr = " M_TIME " ;
attr_strings . change_time_attr = " C_TIME " ;
excl_attr_strings . create_time_attr = NULL ;
excl_attr_strings . access_time_attr = " dos_attr.A_TIME " ;
excl_attr_strings . write_time_attr = " dos_attr.M_TIME " ;
excl_attr_strings . change_time_attr = " dos_attr.C_TIME " ;
}
2003-10-24 17:01:19 +00:00
2005-03-31 05:06:04 +00:00
/* Copy name so we can strip off exclusions (if any are specified) */
strncpy ( name_sandbox , attr_name , sizeof ( name_sandbox ) - 1 ) ;
/* Ensure name is null terminated */
name_sandbox [ sizeof ( name_sandbox ) - 1 ] = ' \0 ' ;
/* Play in the sandbox */
name = name_sandbox ;
/* If there are any exclusions, point to them and mask them from name */
if ( ( pExclude = strchr ( name , ' ! ' ) ) ! = NULL )
{
* pExclude + + = ' \0 ' ;
}
2005-03-10 23:41:19 +00:00
all = ( StrnCaseCmp ( name , " system.* " , 8 ) = = 0 ) ;
all_nt = ( StrnCaseCmp ( name , " system.nt_sec_desc.* " , 20 ) = = 0 ) ;
2005-03-31 05:06:04 +00:00
all_nt_acls = ( StrnCaseCmp ( name , " system.nt_sec_desc.acl.* " , 24 ) = = 0 ) ;
2005-03-10 23:41:19 +00:00
all_dos = ( StrnCaseCmp ( name , " system.dos_attr.* " , 17 ) = = 0 ) ;
some_nt = ( StrnCaseCmp ( name , " system.nt_sec_desc. " , 19 ) = = 0 ) ;
some_dos = ( StrnCaseCmp ( name , " system.dos_attr. " , 16 ) = = 0 ) ;
numeric = ( * ( name + strlen ( name ) - 1 ) ! = ' + ' ) ;
2001-02-05 13:02:20 +00:00
2005-03-31 05:06:04 +00:00
/* Look for exclusions from "all" requests */
if ( all | | all_nt | | all_dos ) {
/* Exclusions are delimited by '!' */
2005-12-29 15:06:53 +00:00
for ( ;
pExclude ! = NULL ;
pExclude = ( p = = NULL ? NULL : p + 1 ) ) {
2005-03-31 05:06:04 +00:00
/* Find end of this exclusion name */
if ( ( p = strchr ( pExclude , ' ! ' ) ) ! = NULL )
{
* p = ' \0 ' ;
}
/* Which exclusion name is this? */
if ( StrCaseCmp ( pExclude , " nt_sec_desc.revision " ) = = 0 ) {
exclude_nt_revision = True ;
}
else if ( StrCaseCmp ( pExclude , " nt_sec_desc.owner " ) = = 0 ) {
exclude_nt_owner = True ;
}
else if ( StrCaseCmp ( pExclude , " nt_sec_desc.group " ) = = 0 ) {
exclude_nt_group = True ;
}
else if ( StrCaseCmp ( pExclude , " nt_sec_desc.acl " ) = = 0 ) {
exclude_nt_acl = True ;
}
else if ( StrCaseCmp ( pExclude , " dos_attr.mode " ) = = 0 ) {
exclude_dos_mode = True ;
}
else if ( StrCaseCmp ( pExclude , " dos_attr.size " ) = = 0 ) {
exclude_dos_size = True ;
}
r18009: Fixes bug 4026.
This completes the work Jeremy began last week, disambiguating the meaning of
c_time. (In POSIX terminology, c_time means "status Change time", not "create
time".) All uses of c_time, a_time and m_time have now been replaced with
change_time, access_time, and write_time, and when creation time is intended,
create_time is used.
Additionally, the capability of setting and retrieving the create time have
been added to the smbc_setxattr() and smbc_getxattr() functions. An example
of setting all four times can be seen with the program
examples/libsmbclient/testacl
with the following command line similar to:
testacl -f -S "system.*:CREATE_TIME:1000000000,ACCESS_TIME:1000000060,WRITE_TIME:1000000120,CHANGE_TIME:1000000180" 'smb://server/share/testfile.txt'
The -f option turns on the new mode which uses full time names in the
attribute specification (e.g. ACCESS_TIME vs A_TIME).
(This used to be commit 8e119b64f1d92026dda855d904be09912a40601c)
2006-09-02 21:47:56 +00:00
else if ( excl_attr_strings . create_time_attr ! = NULL & &
StrCaseCmp ( pExclude ,
excl_attr_strings . change_time_attr ) = = 0 ) {
exclude_dos_create_time = True ;
}
else if ( StrCaseCmp ( pExclude ,
excl_attr_strings . access_time_attr ) = = 0 ) {
exclude_dos_access_time = True ;
2005-03-31 05:06:04 +00:00
}
r18009: Fixes bug 4026.
This completes the work Jeremy began last week, disambiguating the meaning of
c_time. (In POSIX terminology, c_time means "status Change time", not "create
time".) All uses of c_time, a_time and m_time have now been replaced with
change_time, access_time, and write_time, and when creation time is intended,
create_time is used.
Additionally, the capability of setting and retrieving the create time have
been added to the smbc_setxattr() and smbc_getxattr() functions. An example
of setting all four times can be seen with the program
examples/libsmbclient/testacl
with the following command line similar to:
testacl -f -S "system.*:CREATE_TIME:1000000000,ACCESS_TIME:1000000060,WRITE_TIME:1000000120,CHANGE_TIME:1000000180" 'smb://server/share/testfile.txt'
The -f option turns on the new mode which uses full time names in the
attribute specification (e.g. ACCESS_TIME vs A_TIME).
(This used to be commit 8e119b64f1d92026dda855d904be09912a40601c)
2006-09-02 21:47:56 +00:00
else if ( StrCaseCmp ( pExclude ,
excl_attr_strings . write_time_attr ) = = 0 ) {
exclude_dos_write_time = True ;
2005-03-31 05:06:04 +00:00
}
r18009: Fixes bug 4026.
This completes the work Jeremy began last week, disambiguating the meaning of
c_time. (In POSIX terminology, c_time means "status Change time", not "create
time".) All uses of c_time, a_time and m_time have now been replaced with
change_time, access_time, and write_time, and when creation time is intended,
create_time is used.
Additionally, the capability of setting and retrieving the create time have
been added to the smbc_setxattr() and smbc_getxattr() functions. An example
of setting all four times can be seen with the program
examples/libsmbclient/testacl
with the following command line similar to:
testacl -f -S "system.*:CREATE_TIME:1000000000,ACCESS_TIME:1000000060,WRITE_TIME:1000000120,CHANGE_TIME:1000000180" 'smb://server/share/testfile.txt'
The -f option turns on the new mode which uses full time names in the
attribute specification (e.g. ACCESS_TIME vs A_TIME).
(This used to be commit 8e119b64f1d92026dda855d904be09912a40601c)
2006-09-02 21:47:56 +00:00
else if ( StrCaseCmp ( pExclude ,
excl_attr_strings . change_time_attr ) = = 0 ) {
exclude_dos_change_time = True ;
2005-03-31 05:06:04 +00:00
}
else if ( StrCaseCmp ( pExclude , " dos_attr.inode " ) = = 0 ) {
exclude_dos_inode = True ;
}
else {
DEBUG ( 5 , ( " cacl_get received unknown exclusion: %s \n " ,
pExclude ) ) ;
errno = ENOATTR ;
return - 1 ;
}
}
}
2005-03-10 23:41:19 +00:00
n_used = 0 ;
2001-02-05 13:02:20 +00:00
2005-03-10 23:41:19 +00:00
/*
* If we are ( possibly ) talking to an NT or new system and some NT
* attributes have been requested . . .
*/
2005-03-31 05:06:04 +00:00
if ( ipc_cli & & ( all | | some_nt | | all_nt_acls ) ) {
2005-03-10 23:41:19 +00:00
/* Point to the portion after "system.nt_sec_desc." */
name + = 19 ; /* if (all) this will be invalid but unused */
2001-11-17 07:30:19 +00:00
2005-03-10 23:41:19 +00:00
/* ... then obtain any NT attributes which were requested */
fnum = cli_nt_create ( cli , filename , CREATE_ACCESS_READ ) ;
2003-10-24 17:01:19 +00:00
2005-03-10 23:41:19 +00:00
if ( fnum = = - 1 ) {
DEBUG ( 5 , ( " cacl_get failed to open %s: %s \n " ,
filename , cli_errstr ( cli ) ) ) ;
errno = 0 ;
return - 1 ;
}
2003-10-24 17:01:19 +00:00
2005-03-10 23:41:19 +00:00
sd = cli_query_secdesc ( cli , fnum , ctx ) ;
2003-10-24 17:01:19 +00:00
2005-03-10 23:41:19 +00:00
if ( ! sd ) {
DEBUG ( 5 ,
( " cacl_get Failed to query old descriptor \n " ) ) ;
errno = 0 ;
return - 1 ;
2003-10-24 17:01:19 +00:00
}
2005-03-10 23:41:19 +00:00
cli_close ( cli , fnum ) ;
2005-03-31 05:06:04 +00:00
if ( ! exclude_nt_revision ) {
if ( all | | all_nt ) {
if ( determine_size ) {
p = talloc_asprintf ( ctx ,
" REVISION:%d " ,
sd - > revision ) ;
if ( ! p ) {
errno = ENOMEM ;
return - 1 ;
}
n = strlen ( p ) ;
} else {
n = snprintf ( buf , bufsize ,
2005-12-29 15:06:53 +00:00
" REVISION:%d " ,
sd - > revision ) ;
2005-03-10 23:41:19 +00:00
}
2005-03-31 05:06:04 +00:00
} else if ( StrCaseCmp ( name , " revision " ) = = 0 ) {
if ( determine_size ) {
p = talloc_asprintf ( ctx , " %d " ,
sd - > revision ) ;
if ( ! p ) {
errno = ENOMEM ;
return - 1 ;
}
n = strlen ( p ) ;
} else {
n = snprintf ( buf , bufsize , " %d " ,
sd - > revision ) ;
2005-03-10 23:41:19 +00:00
}
2003-10-24 17:01:19 +00:00
}
2007-11-30 13:09:04 -08:00
2005-03-31 05:06:04 +00:00
if ( ! determine_size & & n > bufsize ) {
errno = ERANGE ;
return - 1 ;
}
buf + = n ;
n_used + = n ;
bufsize - = n ;
2007-08-14 03:02:34 +00:00
n = 0 ;
2005-03-10 23:41:19 +00:00
}
2003-10-24 17:01:19 +00:00
2005-03-31 05:06:04 +00:00
if ( ! exclude_nt_owner ) {
/* Get owner and group sid */
if ( sd - > owner_sid ) {
convert_sid_to_string ( ipc_cli , pol ,
sidstr ,
numeric ,
sd - > owner_sid ) ;
2005-03-10 23:41:19 +00:00
} else {
2005-03-31 05:06:04 +00:00
fstrcpy ( sidstr , " " ) ;
2005-03-10 23:41:19 +00:00
}
2005-03-31 05:06:04 +00:00
if ( all | | all_nt ) {
if ( determine_size ) {
p = talloc_asprintf ( ctx , " ,OWNER:%s " ,
sidstr ) ;
if ( ! p ) {
errno = ENOMEM ;
return - 1 ;
}
n = strlen ( p ) ;
2007-05-15 19:10:29 +00:00
} else if ( sidstr [ 0 ] ! = ' \0 ' ) {
2005-03-31 05:06:04 +00:00
n = snprintf ( buf , bufsize ,
" ,OWNER:%s " , sidstr ) ;
2005-03-10 23:41:19 +00:00
}
2005-03-31 05:06:04 +00:00
} else if ( StrnCaseCmp ( name , " owner " , 5 ) = = 0 ) {
if ( determine_size ) {
p = talloc_asprintf ( ctx , " %s " , sidstr ) ;
if ( ! p ) {
errno = ENOMEM ;
return - 1 ;
}
n = strlen ( p ) ;
} else {
n = snprintf ( buf , bufsize , " %s " ,
sidstr ) ;
2005-03-10 23:41:19 +00:00
}
}
2005-03-31 05:06:04 +00:00
if ( ! determine_size & & n > bufsize ) {
errno = ERANGE ;
return - 1 ;
}
buf + = n ;
n_used + = n ;
bufsize - = n ;
2007-08-14 03:02:34 +00:00
n = 0 ;
2005-03-10 23:41:19 +00:00
}
2005-03-31 05:06:04 +00:00
if ( ! exclude_nt_group ) {
2006-09-20 22:23:12 +00:00
if ( sd - > group_sid ) {
2005-03-31 05:06:04 +00:00
convert_sid_to_string ( ipc_cli , pol ,
sidstr , numeric ,
2006-09-20 22:23:12 +00:00
sd - > group_sid ) ;
2005-03-31 05:06:04 +00:00
} else {
fstrcpy ( sidstr , " " ) ;
}
2005-03-10 23:41:19 +00:00
if ( all | | all_nt ) {
if ( determine_size ) {
2005-03-31 05:06:04 +00:00
p = talloc_asprintf ( ctx , " ,GROUP:%s " ,
sidstr ) ;
2005-03-10 23:41:19 +00:00
if ( ! p ) {
errno = ENOMEM ;
return - 1 ;
}
n = strlen ( p ) ;
2007-05-15 19:10:29 +00:00
} else if ( sidstr [ 0 ] ! = ' \0 ' ) {
2005-03-10 23:41:19 +00:00
n = snprintf ( buf , bufsize ,
2005-03-31 05:06:04 +00:00
" ,GROUP:%s " , sidstr ) ;
2005-03-10 23:41:19 +00:00
}
2005-03-31 05:06:04 +00:00
} else if ( StrnCaseCmp ( name , " group " , 5 ) = = 0 ) {
2005-03-10 23:41:19 +00:00
if ( determine_size ) {
2005-03-31 05:06:04 +00:00
p = talloc_asprintf ( ctx , " %s " , sidstr ) ;
2005-03-10 23:41:19 +00:00
if ( ! p ) {
errno = ENOMEM ;
return - 1 ;
}
n = strlen ( p ) ;
} else {
2005-12-29 15:06:53 +00:00
n = snprintf ( buf , bufsize ,
" %s " , sidstr ) ;
2005-03-10 23:41:19 +00:00
}
}
2005-03-31 05:06:04 +00:00
if ( ! determine_size & & n > bufsize ) {
2005-03-10 23:41:19 +00:00
errno = ERANGE ;
2003-10-24 17:01:19 +00:00
return - 1 ;
}
2005-03-10 23:41:19 +00:00
buf + = n ;
n_used + = n ;
bufsize - = n ;
2007-08-14 03:02:34 +00:00
n = 0 ;
2003-10-24 17:01:19 +00:00
}
2001-02-05 13:02:20 +00:00
2005-03-31 05:06:04 +00:00
if ( ! exclude_nt_acl ) {
/* Add aces to value buffer */
for ( i = 0 ; sd - > dacl & & i < sd - > dacl - > num_aces ; i + + ) {
2006-09-20 22:23:12 +00:00
SEC_ACE * ace = & sd - > dacl - > aces [ i ] ;
2005-03-31 05:06:04 +00:00
convert_sid_to_string ( ipc_cli , pol ,
sidstr , numeric ,
& ace - > trustee ) ;
if ( all | | all_nt ) {
if ( determine_size ) {
p = talloc_asprintf (
ctx ,
" ,ACL: "
" %s:%d/%d/0x%08x " ,
sidstr ,
ace - > type ,
ace - > flags ,
2006-09-20 22:23:12 +00:00
ace - > access_mask ) ;
2005-03-31 05:06:04 +00:00
if ( ! p ) {
errno = ENOMEM ;
return - 1 ;
}
n = strlen ( p ) ;
} else {
n = snprintf (
buf , bufsize ,
" ,ACL:%s:%d/%d/0x%08x " ,
sidstr ,
ace - > type ,
ace - > flags ,
2006-09-20 22:23:12 +00:00
ace - > access_mask ) ;
2005-03-31 05:06:04 +00:00
}
} else if ( ( StrnCaseCmp ( name , " acl " , 3 ) = = 0 & &
2005-12-29 15:06:53 +00:00
StrCaseCmp ( name + 3 , sidstr ) = = 0 ) | |
2005-03-31 05:06:04 +00:00
( StrnCaseCmp ( name , " acl+ " , 4 ) = = 0 & &
2005-12-29 15:06:53 +00:00
StrCaseCmp ( name + 4 , sidstr ) = = 0 ) ) {
2005-03-31 05:06:04 +00:00
if ( determine_size ) {
p = talloc_asprintf (
ctx ,
" %d/%d/0x%08x " ,
ace - > type ,
ace - > flags ,
2006-09-20 22:23:12 +00:00
ace - > access_mask ) ;
2005-03-31 05:06:04 +00:00
if ( ! p ) {
errno = ENOMEM ;
return - 1 ;
}
n = strlen ( p ) ;
} else {
n = snprintf ( buf , bufsize ,
" %d/%d/0x%08x " ,
ace - > type ,
ace - > flags ,
2006-09-20 22:23:12 +00:00
ace - > access_mask ) ;
2005-03-31 05:06:04 +00:00
}
} else if ( all_nt_acls ) {
if ( determine_size ) {
p = talloc_asprintf (
ctx ,
" %s%s:%d/%d/0x%08x " ,
i ? " , " : " " ,
sidstr ,
ace - > type ,
ace - > flags ,
2006-09-20 22:23:12 +00:00
ace - > access_mask ) ;
2005-03-31 05:06:04 +00:00
if ( ! p ) {
errno = ENOMEM ;
return - 1 ;
}
n = strlen ( p ) ;
} else {
n = snprintf ( buf , bufsize ,
" %s%s:%d/%d/0x%08x " ,
i ? " , " : " " ,
sidstr ,
ace - > type ,
ace - > flags ,
2006-09-20 22:23:12 +00:00
ace - > access_mask ) ;
2005-03-31 05:06:04 +00:00
}
}
2007-05-14 14:19:30 +00:00
if ( ! determine_size & & n > bufsize ) {
2005-03-31 05:06:04 +00:00
errno = ERANGE ;
return - 1 ;
}
buf + = n ;
n_used + = n ;
bufsize - = n ;
2007-08-14 03:02:34 +00:00
n = 0 ;
2005-03-31 05:06:04 +00:00
}
}
2005-03-10 23:41:19 +00:00
/* Restore name pointer to its original value */
name - = 19 ;
2003-10-24 17:01:19 +00:00
}
2001-02-05 13:02:20 +00:00
2005-03-10 23:41:19 +00:00
if ( all | | some_dos ) {
/* Point to the portion after "system.dos_attr." */
name + = 16 ; /* if (all) this will be invalid but unused */
2003-10-24 17:01:19 +00:00
2005-03-10 23:41:19 +00:00
/* Obtain the DOS attributes */
if ( ! smbc_getatr ( context , srv , filename , & mode , & size ,
r18009: Fixes bug 4026.
This completes the work Jeremy began last week, disambiguating the meaning of
c_time. (In POSIX terminology, c_time means "status Change time", not "create
time".) All uses of c_time, a_time and m_time have now been replaced with
change_time, access_time, and write_time, and when creation time is intended,
create_time is used.
Additionally, the capability of setting and retrieving the create time have
been added to the smbc_setxattr() and smbc_getxattr() functions. An example
of setting all four times can be seen with the program
examples/libsmbclient/testacl
with the following command line similar to:
testacl -f -S "system.*:CREATE_TIME:1000000000,ACCESS_TIME:1000000060,WRITE_TIME:1000000120,CHANGE_TIME:1000000180" 'smb://server/share/testfile.txt'
The -f option turns on the new mode which uses full time names in the
attribute specification (e.g. ACCESS_TIME vs A_TIME).
(This used to be commit 8e119b64f1d92026dda855d904be09912a40601c)
2006-09-02 21:47:56 +00:00
& create_time_ts ,
& access_time_ts ,
& write_time_ts ,
& change_time_ts ,
& ino ) ) {
2007-11-30 13:09:04 -08:00
2006-07-11 18:01:26 +00:00
errno = smbc_errno ( context , srv - > cli ) ;
2005-03-10 23:41:19 +00:00
return - 1 ;
2007-11-30 13:09:04 -08:00
2005-03-10 23:41:19 +00:00
}
r18009: Fixes bug 4026.
This completes the work Jeremy began last week, disambiguating the meaning of
c_time. (In POSIX terminology, c_time means "status Change time", not "create
time".) All uses of c_time, a_time and m_time have now been replaced with
change_time, access_time, and write_time, and when creation time is intended,
create_time is used.
Additionally, the capability of setting and retrieving the create time have
been added to the smbc_setxattr() and smbc_getxattr() functions. An example
of setting all four times can be seen with the program
examples/libsmbclient/testacl
with the following command line similar to:
testacl -f -S "system.*:CREATE_TIME:1000000000,ACCESS_TIME:1000000060,WRITE_TIME:1000000120,CHANGE_TIME:1000000180" 'smb://server/share/testfile.txt'
The -f option turns on the new mode which uses full time names in the
attribute specification (e.g. ACCESS_TIME vs A_TIME).
(This used to be commit 8e119b64f1d92026dda855d904be09912a40601c)
2006-09-02 21:47:56 +00:00
create_time = convert_timespec_to_time_t ( create_time_ts ) ;
access_time = convert_timespec_to_time_t ( access_time_ts ) ;
write_time = convert_timespec_to_time_t ( write_time_ts ) ;
change_time = convert_timespec_to_time_t ( change_time_ts ) ;
2006-08-24 16:44:00 +00:00
2005-03-31 05:06:04 +00:00
if ( ! exclude_dos_mode ) {
if ( all | | all_dos ) {
if ( determine_size ) {
p = talloc_asprintf ( ctx ,
" %sMODE:0x%x " ,
( ipc_cli & &
( all | | some_nt )
? " , "
: " " ) ,
mode ) ;
if ( ! p ) {
errno = ENOMEM ;
return - 1 ;
}
n = strlen ( p ) ;
} else {
n = snprintf ( buf , bufsize ,
" %sMODE:0x%x " ,
( ipc_cli & &
( all | | some_nt )
? " , "
: " " ) ,
mode ) ;
2005-03-10 23:41:19 +00:00
}
2005-03-31 05:06:04 +00:00
} else if ( StrCaseCmp ( name , " mode " ) = = 0 ) {
if ( determine_size ) {
p = talloc_asprintf ( ctx , " 0x%x " , mode ) ;
if ( ! p ) {
errno = ENOMEM ;
return - 1 ;
}
n = strlen ( p ) ;
} else {
2005-12-29 15:06:53 +00:00
n = snprintf ( buf , bufsize ,
" 0x%x " , mode ) ;
2005-03-10 23:41:19 +00:00
}
2003-10-24 17:01:19 +00:00
}
2007-11-30 13:09:04 -08:00
2005-03-31 05:06:04 +00:00
if ( ! determine_size & & n > bufsize ) {
errno = ERANGE ;
return - 1 ;
}
buf + = n ;
n_used + = n ;
bufsize - = n ;
2007-08-14 03:02:34 +00:00
n = 0 ;
2005-03-10 23:41:19 +00:00
}
2005-03-31 05:06:04 +00:00
if ( ! exclude_dos_size ) {
if ( all | | all_dos ) {
if ( determine_size ) {
p = talloc_asprintf (
ctx ,
2005-10-21 22:48:27 +00:00
" ,SIZE:%.0f " ,
( double ) size ) ;
2005-03-31 05:06:04 +00:00
if ( ! p ) {
errno = ENOMEM ;
return - 1 ;
}
n = strlen ( p ) ;
} else {
n = snprintf ( buf , bufsize ,
2005-10-21 22:48:27 +00:00
" ,SIZE:%.0f " ,
( double ) size ) ;
2005-03-10 23:41:19 +00:00
}
2005-03-31 05:06:04 +00:00
} else if ( StrCaseCmp ( name , " size " ) = = 0 ) {
if ( determine_size ) {
p = talloc_asprintf (
ctx ,
2005-10-21 22:48:27 +00:00
" %.0f " ,
( double ) size ) ;
2005-03-31 05:06:04 +00:00
if ( ! p ) {
errno = ENOMEM ;
return - 1 ;
}
n = strlen ( p ) ;
} else {
n = snprintf ( buf , bufsize ,
2005-10-21 22:48:27 +00:00
" %.0f " ,
( double ) size ) ;
2005-03-10 23:41:19 +00:00
}
2003-10-24 17:01:19 +00:00
}
2007-11-30 13:09:04 -08:00
2005-03-31 05:06:04 +00:00
if ( ! determine_size & & n > bufsize ) {
errno = ERANGE ;
return - 1 ;
}
buf + = n ;
n_used + = n ;
bufsize - = n ;
2007-08-14 03:02:34 +00:00
n = 0 ;
2005-03-10 23:41:19 +00:00
}
2005-03-31 05:06:04 +00:00
r18009: Fixes bug 4026.
This completes the work Jeremy began last week, disambiguating the meaning of
c_time. (In POSIX terminology, c_time means "status Change time", not "create
time".) All uses of c_time, a_time and m_time have now been replaced with
change_time, access_time, and write_time, and when creation time is intended,
create_time is used.
Additionally, the capability of setting and retrieving the create time have
been added to the smbc_setxattr() and smbc_getxattr() functions. An example
of setting all four times can be seen with the program
examples/libsmbclient/testacl
with the following command line similar to:
testacl -f -S "system.*:CREATE_TIME:1000000000,ACCESS_TIME:1000000060,WRITE_TIME:1000000120,CHANGE_TIME:1000000180" 'smb://server/share/testfile.txt'
The -f option turns on the new mode which uses full time names in the
attribute specification (e.g. ACCESS_TIME vs A_TIME).
(This used to be commit 8e119b64f1d92026dda855d904be09912a40601c)
2006-09-02 21:47:56 +00:00
if ( ! exclude_dos_create_time & &
attr_strings . create_time_attr ! = NULL ) {
if ( all | | all_dos ) {
if ( determine_size ) {
p = talloc_asprintf ( ctx ,
" ,%s:%lu " ,
attr_strings . create_time_attr ,
create_time ) ;
if ( ! p ) {
errno = ENOMEM ;
return - 1 ;
}
n = strlen ( p ) ;
} else {
n = snprintf ( buf , bufsize ,
" ,%s:%lu " ,
attr_strings . create_time_attr ,
create_time ) ;
}
} else if ( StrCaseCmp ( name , attr_strings . create_time_attr ) = = 0 ) {
if ( determine_size ) {
p = talloc_asprintf ( ctx , " %lu " , create_time ) ;
if ( ! p ) {
errno = ENOMEM ;
return - 1 ;
}
n = strlen ( p ) ;
} else {
n = snprintf ( buf , bufsize ,
" %lu " , create_time ) ;
}
}
2007-11-30 13:09:04 -08:00
r18009: Fixes bug 4026.
This completes the work Jeremy began last week, disambiguating the meaning of
c_time. (In POSIX terminology, c_time means "status Change time", not "create
time".) All uses of c_time, a_time and m_time have now been replaced with
change_time, access_time, and write_time, and when creation time is intended,
create_time is used.
Additionally, the capability of setting and retrieving the create time have
been added to the smbc_setxattr() and smbc_getxattr() functions. An example
of setting all four times can be seen with the program
examples/libsmbclient/testacl
with the following command line similar to:
testacl -f -S "system.*:CREATE_TIME:1000000000,ACCESS_TIME:1000000060,WRITE_TIME:1000000120,CHANGE_TIME:1000000180" 'smb://server/share/testfile.txt'
The -f option turns on the new mode which uses full time names in the
attribute specification (e.g. ACCESS_TIME vs A_TIME).
(This used to be commit 8e119b64f1d92026dda855d904be09912a40601c)
2006-09-02 21:47:56 +00:00
if ( ! determine_size & & n > bufsize ) {
errno = ERANGE ;
return - 1 ;
}
buf + = n ;
n_used + = n ;
bufsize - = n ;
2007-08-14 03:02:34 +00:00
n = 0 ;
r18009: Fixes bug 4026.
This completes the work Jeremy began last week, disambiguating the meaning of
c_time. (In POSIX terminology, c_time means "status Change time", not "create
time".) All uses of c_time, a_time and m_time have now been replaced with
change_time, access_time, and write_time, and when creation time is intended,
create_time is used.
Additionally, the capability of setting and retrieving the create time have
been added to the smbc_setxattr() and smbc_getxattr() functions. An example
of setting all four times can be seen with the program
examples/libsmbclient/testacl
with the following command line similar to:
testacl -f -S "system.*:CREATE_TIME:1000000000,ACCESS_TIME:1000000060,WRITE_TIME:1000000120,CHANGE_TIME:1000000180" 'smb://server/share/testfile.txt'
The -f option turns on the new mode which uses full time names in the
attribute specification (e.g. ACCESS_TIME vs A_TIME).
(This used to be commit 8e119b64f1d92026dda855d904be09912a40601c)
2006-09-02 21:47:56 +00:00
}
if ( ! exclude_dos_access_time ) {
2005-03-31 05:06:04 +00:00
if ( all | | all_dos ) {
if ( determine_size ) {
p = talloc_asprintf ( ctx ,
r18009: Fixes bug 4026.
This completes the work Jeremy began last week, disambiguating the meaning of
c_time. (In POSIX terminology, c_time means "status Change time", not "create
time".) All uses of c_time, a_time and m_time have now been replaced with
change_time, access_time, and write_time, and when creation time is intended,
create_time is used.
Additionally, the capability of setting and retrieving the create time have
been added to the smbc_setxattr() and smbc_getxattr() functions. An example
of setting all four times can be seen with the program
examples/libsmbclient/testacl
with the following command line similar to:
testacl -f -S "system.*:CREATE_TIME:1000000000,ACCESS_TIME:1000000060,WRITE_TIME:1000000120,CHANGE_TIME:1000000180" 'smb://server/share/testfile.txt'
The -f option turns on the new mode which uses full time names in the
attribute specification (e.g. ACCESS_TIME vs A_TIME).
(This used to be commit 8e119b64f1d92026dda855d904be09912a40601c)
2006-09-02 21:47:56 +00:00
" ,%s:%lu " ,
attr_strings . access_time_attr ,
access_time ) ;
2005-03-31 05:06:04 +00:00
if ( ! p ) {
errno = ENOMEM ;
return - 1 ;
}
n = strlen ( p ) ;
} else {
n = snprintf ( buf , bufsize ,
r18009: Fixes bug 4026.
This completes the work Jeremy began last week, disambiguating the meaning of
c_time. (In POSIX terminology, c_time means "status Change time", not "create
time".) All uses of c_time, a_time and m_time have now been replaced with
change_time, access_time, and write_time, and when creation time is intended,
create_time is used.
Additionally, the capability of setting and retrieving the create time have
been added to the smbc_setxattr() and smbc_getxattr() functions. An example
of setting all four times can be seen with the program
examples/libsmbclient/testacl
with the following command line similar to:
testacl -f -S "system.*:CREATE_TIME:1000000000,ACCESS_TIME:1000000060,WRITE_TIME:1000000120,CHANGE_TIME:1000000180" 'smb://server/share/testfile.txt'
The -f option turns on the new mode which uses full time names in the
attribute specification (e.g. ACCESS_TIME vs A_TIME).
(This used to be commit 8e119b64f1d92026dda855d904be09912a40601c)
2006-09-02 21:47:56 +00:00
" ,%s:%lu " ,
attr_strings . access_time_attr ,
access_time ) ;
2005-03-10 23:41:19 +00:00
}
r18009: Fixes bug 4026.
This completes the work Jeremy began last week, disambiguating the meaning of
c_time. (In POSIX terminology, c_time means "status Change time", not "create
time".) All uses of c_time, a_time and m_time have now been replaced with
change_time, access_time, and write_time, and when creation time is intended,
create_time is used.
Additionally, the capability of setting and retrieving the create time have
been added to the smbc_setxattr() and smbc_getxattr() functions. An example
of setting all four times can be seen with the program
examples/libsmbclient/testacl
with the following command line similar to:
testacl -f -S "system.*:CREATE_TIME:1000000000,ACCESS_TIME:1000000060,WRITE_TIME:1000000120,CHANGE_TIME:1000000180" 'smb://server/share/testfile.txt'
The -f option turns on the new mode which uses full time names in the
attribute specification (e.g. ACCESS_TIME vs A_TIME).
(This used to be commit 8e119b64f1d92026dda855d904be09912a40601c)
2006-09-02 21:47:56 +00:00
} else if ( StrCaseCmp ( name , attr_strings . access_time_attr ) = = 0 ) {
2005-03-31 05:06:04 +00:00
if ( determine_size ) {
r18009: Fixes bug 4026.
This completes the work Jeremy began last week, disambiguating the meaning of
c_time. (In POSIX terminology, c_time means "status Change time", not "create
time".) All uses of c_time, a_time and m_time have now been replaced with
change_time, access_time, and write_time, and when creation time is intended,
create_time is used.
Additionally, the capability of setting and retrieving the create time have
been added to the smbc_setxattr() and smbc_getxattr() functions. An example
of setting all four times can be seen with the program
examples/libsmbclient/testacl
with the following command line similar to:
testacl -f -S "system.*:CREATE_TIME:1000000000,ACCESS_TIME:1000000060,WRITE_TIME:1000000120,CHANGE_TIME:1000000180" 'smb://server/share/testfile.txt'
The -f option turns on the new mode which uses full time names in the
attribute specification (e.g. ACCESS_TIME vs A_TIME).
(This used to be commit 8e119b64f1d92026dda855d904be09912a40601c)
2006-09-02 21:47:56 +00:00
p = talloc_asprintf ( ctx , " %lu " , access_time ) ;
2005-03-31 05:06:04 +00:00
if ( ! p ) {
errno = ENOMEM ;
return - 1 ;
}
n = strlen ( p ) ;
} else {
2005-12-29 15:06:53 +00:00
n = snprintf ( buf , bufsize ,
r18009: Fixes bug 4026.
This completes the work Jeremy began last week, disambiguating the meaning of
c_time. (In POSIX terminology, c_time means "status Change time", not "create
time".) All uses of c_time, a_time and m_time have now been replaced with
change_time, access_time, and write_time, and when creation time is intended,
create_time is used.
Additionally, the capability of setting and retrieving the create time have
been added to the smbc_setxattr() and smbc_getxattr() functions. An example
of setting all four times can be seen with the program
examples/libsmbclient/testacl
with the following command line similar to:
testacl -f -S "system.*:CREATE_TIME:1000000000,ACCESS_TIME:1000000060,WRITE_TIME:1000000120,CHANGE_TIME:1000000180" 'smb://server/share/testfile.txt'
The -f option turns on the new mode which uses full time names in the
attribute specification (e.g. ACCESS_TIME vs A_TIME).
(This used to be commit 8e119b64f1d92026dda855d904be09912a40601c)
2006-09-02 21:47:56 +00:00
" %lu " , access_time ) ;
2005-03-10 23:41:19 +00:00
}
}
2007-11-30 13:09:04 -08:00
2005-03-31 05:06:04 +00:00
if ( ! determine_size & & n > bufsize ) {
errno = ERANGE ;
return - 1 ;
}
buf + = n ;
n_used + = n ;
bufsize - = n ;
2007-08-14 03:02:34 +00:00
n = 0 ;
2005-03-10 23:41:19 +00:00
}
2005-03-31 05:06:04 +00:00
r18009: Fixes bug 4026.
This completes the work Jeremy began last week, disambiguating the meaning of
c_time. (In POSIX terminology, c_time means "status Change time", not "create
time".) All uses of c_time, a_time and m_time have now been replaced with
change_time, access_time, and write_time, and when creation time is intended,
create_time is used.
Additionally, the capability of setting and retrieving the create time have
been added to the smbc_setxattr() and smbc_getxattr() functions. An example
of setting all four times can be seen with the program
examples/libsmbclient/testacl
with the following command line similar to:
testacl -f -S "system.*:CREATE_TIME:1000000000,ACCESS_TIME:1000000060,WRITE_TIME:1000000120,CHANGE_TIME:1000000180" 'smb://server/share/testfile.txt'
The -f option turns on the new mode which uses full time names in the
attribute specification (e.g. ACCESS_TIME vs A_TIME).
(This used to be commit 8e119b64f1d92026dda855d904be09912a40601c)
2006-09-02 21:47:56 +00:00
if ( ! exclude_dos_write_time ) {
2005-03-31 05:06:04 +00:00
if ( all | | all_dos ) {
if ( determine_size ) {
p = talloc_asprintf ( ctx ,
r18009: Fixes bug 4026.
This completes the work Jeremy began last week, disambiguating the meaning of
c_time. (In POSIX terminology, c_time means "status Change time", not "create
time".) All uses of c_time, a_time and m_time have now been replaced with
change_time, access_time, and write_time, and when creation time is intended,
create_time is used.
Additionally, the capability of setting and retrieving the create time have
been added to the smbc_setxattr() and smbc_getxattr() functions. An example
of setting all four times can be seen with the program
examples/libsmbclient/testacl
with the following command line similar to:
testacl -f -S "system.*:CREATE_TIME:1000000000,ACCESS_TIME:1000000060,WRITE_TIME:1000000120,CHANGE_TIME:1000000180" 'smb://server/share/testfile.txt'
The -f option turns on the new mode which uses full time names in the
attribute specification (e.g. ACCESS_TIME vs A_TIME).
(This used to be commit 8e119b64f1d92026dda855d904be09912a40601c)
2006-09-02 21:47:56 +00:00
" ,%s:%lu " ,
attr_strings . write_time_attr ,
write_time ) ;
2005-03-31 05:06:04 +00:00
if ( ! p ) {
errno = ENOMEM ;
return - 1 ;
}
n = strlen ( p ) ;
} else {
n = snprintf ( buf , bufsize ,
r18009: Fixes bug 4026.
This completes the work Jeremy began last week, disambiguating the meaning of
c_time. (In POSIX terminology, c_time means "status Change time", not "create
time".) All uses of c_time, a_time and m_time have now been replaced with
change_time, access_time, and write_time, and when creation time is intended,
create_time is used.
Additionally, the capability of setting and retrieving the create time have
been added to the smbc_setxattr() and smbc_getxattr() functions. An example
of setting all four times can be seen with the program
examples/libsmbclient/testacl
with the following command line similar to:
testacl -f -S "system.*:CREATE_TIME:1000000000,ACCESS_TIME:1000000060,WRITE_TIME:1000000120,CHANGE_TIME:1000000180" 'smb://server/share/testfile.txt'
The -f option turns on the new mode which uses full time names in the
attribute specification (e.g. ACCESS_TIME vs A_TIME).
(This used to be commit 8e119b64f1d92026dda855d904be09912a40601c)
2006-09-02 21:47:56 +00:00
" ,%s:%lu " ,
attr_strings . write_time_attr ,
write_time ) ;
2005-03-10 23:41:19 +00:00
}
r18009: Fixes bug 4026.
This completes the work Jeremy began last week, disambiguating the meaning of
c_time. (In POSIX terminology, c_time means "status Change time", not "create
time".) All uses of c_time, a_time and m_time have now been replaced with
change_time, access_time, and write_time, and when creation time is intended,
create_time is used.
Additionally, the capability of setting and retrieving the create time have
been added to the smbc_setxattr() and smbc_getxattr() functions. An example
of setting all four times can be seen with the program
examples/libsmbclient/testacl
with the following command line similar to:
testacl -f -S "system.*:CREATE_TIME:1000000000,ACCESS_TIME:1000000060,WRITE_TIME:1000000120,CHANGE_TIME:1000000180" 'smb://server/share/testfile.txt'
The -f option turns on the new mode which uses full time names in the
attribute specification (e.g. ACCESS_TIME vs A_TIME).
(This used to be commit 8e119b64f1d92026dda855d904be09912a40601c)
2006-09-02 21:47:56 +00:00
} else if ( StrCaseCmp ( name , attr_strings . write_time_attr ) = = 0 ) {
2005-03-31 05:06:04 +00:00
if ( determine_size ) {
r18009: Fixes bug 4026.
This completes the work Jeremy began last week, disambiguating the meaning of
c_time. (In POSIX terminology, c_time means "status Change time", not "create
time".) All uses of c_time, a_time and m_time have now been replaced with
change_time, access_time, and write_time, and when creation time is intended,
create_time is used.
Additionally, the capability of setting and retrieving the create time have
been added to the smbc_setxattr() and smbc_getxattr() functions. An example
of setting all four times can be seen with the program
examples/libsmbclient/testacl
with the following command line similar to:
testacl -f -S "system.*:CREATE_TIME:1000000000,ACCESS_TIME:1000000060,WRITE_TIME:1000000120,CHANGE_TIME:1000000180" 'smb://server/share/testfile.txt'
The -f option turns on the new mode which uses full time names in the
attribute specification (e.g. ACCESS_TIME vs A_TIME).
(This used to be commit 8e119b64f1d92026dda855d904be09912a40601c)
2006-09-02 21:47:56 +00:00
p = talloc_asprintf ( ctx , " %lu " , write_time ) ;
2005-03-31 05:06:04 +00:00
if ( ! p ) {
errno = ENOMEM ;
return - 1 ;
}
n = strlen ( p ) ;
} else {
2005-12-29 15:06:53 +00:00
n = snprintf ( buf , bufsize ,
r18009: Fixes bug 4026.
This completes the work Jeremy began last week, disambiguating the meaning of
c_time. (In POSIX terminology, c_time means "status Change time", not "create
time".) All uses of c_time, a_time and m_time have now been replaced with
change_time, access_time, and write_time, and when creation time is intended,
create_time is used.
Additionally, the capability of setting and retrieving the create time have
been added to the smbc_setxattr() and smbc_getxattr() functions. An example
of setting all four times can be seen with the program
examples/libsmbclient/testacl
with the following command line similar to:
testacl -f -S "system.*:CREATE_TIME:1000000000,ACCESS_TIME:1000000060,WRITE_TIME:1000000120,CHANGE_TIME:1000000180" 'smb://server/share/testfile.txt'
The -f option turns on the new mode which uses full time names in the
attribute specification (e.g. ACCESS_TIME vs A_TIME).
(This used to be commit 8e119b64f1d92026dda855d904be09912a40601c)
2006-09-02 21:47:56 +00:00
" %lu " , write_time ) ;
2005-03-10 23:41:19 +00:00
}
}
2007-11-30 13:09:04 -08:00
2005-03-31 05:06:04 +00:00
if ( ! determine_size & & n > bufsize ) {
errno = ERANGE ;
return - 1 ;
}
buf + = n ;
n_used + = n ;
bufsize - = n ;
2007-08-14 03:02:34 +00:00
n = 0 ;
2005-03-10 23:41:19 +00:00
}
2005-03-31 05:06:04 +00:00
r18009: Fixes bug 4026.
This completes the work Jeremy began last week, disambiguating the meaning of
c_time. (In POSIX terminology, c_time means "status Change time", not "create
time".) All uses of c_time, a_time and m_time have now been replaced with
change_time, access_time, and write_time, and when creation time is intended,
create_time is used.
Additionally, the capability of setting and retrieving the create time have
been added to the smbc_setxattr() and smbc_getxattr() functions. An example
of setting all four times can be seen with the program
examples/libsmbclient/testacl
with the following command line similar to:
testacl -f -S "system.*:CREATE_TIME:1000000000,ACCESS_TIME:1000000060,WRITE_TIME:1000000120,CHANGE_TIME:1000000180" 'smb://server/share/testfile.txt'
The -f option turns on the new mode which uses full time names in the
attribute specification (e.g. ACCESS_TIME vs A_TIME).
(This used to be commit 8e119b64f1d92026dda855d904be09912a40601c)
2006-09-02 21:47:56 +00:00
if ( ! exclude_dos_change_time ) {
2005-03-31 05:06:04 +00:00
if ( all | | all_dos ) {
if ( determine_size ) {
p = talloc_asprintf ( ctx ,
r18009: Fixes bug 4026.
This completes the work Jeremy began last week, disambiguating the meaning of
c_time. (In POSIX terminology, c_time means "status Change time", not "create
time".) All uses of c_time, a_time and m_time have now been replaced with
change_time, access_time, and write_time, and when creation time is intended,
create_time is used.
Additionally, the capability of setting and retrieving the create time have
been added to the smbc_setxattr() and smbc_getxattr() functions. An example
of setting all four times can be seen with the program
examples/libsmbclient/testacl
with the following command line similar to:
testacl -f -S "system.*:CREATE_TIME:1000000000,ACCESS_TIME:1000000060,WRITE_TIME:1000000120,CHANGE_TIME:1000000180" 'smb://server/share/testfile.txt'
The -f option turns on the new mode which uses full time names in the
attribute specification (e.g. ACCESS_TIME vs A_TIME).
(This used to be commit 8e119b64f1d92026dda855d904be09912a40601c)
2006-09-02 21:47:56 +00:00
" ,%s:%lu " ,
attr_strings . change_time_attr ,
change_time ) ;
2005-03-31 05:06:04 +00:00
if ( ! p ) {
errno = ENOMEM ;
return - 1 ;
}
n = strlen ( p ) ;
} else {
n = snprintf ( buf , bufsize ,
r18009: Fixes bug 4026.
This completes the work Jeremy began last week, disambiguating the meaning of
c_time. (In POSIX terminology, c_time means "status Change time", not "create
time".) All uses of c_time, a_time and m_time have now been replaced with
change_time, access_time, and write_time, and when creation time is intended,
create_time is used.
Additionally, the capability of setting and retrieving the create time have
been added to the smbc_setxattr() and smbc_getxattr() functions. An example
of setting all four times can be seen with the program
examples/libsmbclient/testacl
with the following command line similar to:
testacl -f -S "system.*:CREATE_TIME:1000000000,ACCESS_TIME:1000000060,WRITE_TIME:1000000120,CHANGE_TIME:1000000180" 'smb://server/share/testfile.txt'
The -f option turns on the new mode which uses full time names in the
attribute specification (e.g. ACCESS_TIME vs A_TIME).
(This used to be commit 8e119b64f1d92026dda855d904be09912a40601c)
2006-09-02 21:47:56 +00:00
" ,%s:%lu " ,
attr_strings . change_time_attr ,
change_time ) ;
2005-03-10 23:41:19 +00:00
}
r18009: Fixes bug 4026.
This completes the work Jeremy began last week, disambiguating the meaning of
c_time. (In POSIX terminology, c_time means "status Change time", not "create
time".) All uses of c_time, a_time and m_time have now been replaced with
change_time, access_time, and write_time, and when creation time is intended,
create_time is used.
Additionally, the capability of setting and retrieving the create time have
been added to the smbc_setxattr() and smbc_getxattr() functions. An example
of setting all four times can be seen with the program
examples/libsmbclient/testacl
with the following command line similar to:
testacl -f -S "system.*:CREATE_TIME:1000000000,ACCESS_TIME:1000000060,WRITE_TIME:1000000120,CHANGE_TIME:1000000180" 'smb://server/share/testfile.txt'
The -f option turns on the new mode which uses full time names in the
attribute specification (e.g. ACCESS_TIME vs A_TIME).
(This used to be commit 8e119b64f1d92026dda855d904be09912a40601c)
2006-09-02 21:47:56 +00:00
} else if ( StrCaseCmp ( name , attr_strings . change_time_attr ) = = 0 ) {
2005-03-31 05:06:04 +00:00
if ( determine_size ) {
r18009: Fixes bug 4026.
This completes the work Jeremy began last week, disambiguating the meaning of
c_time. (In POSIX terminology, c_time means "status Change time", not "create
time".) All uses of c_time, a_time and m_time have now been replaced with
change_time, access_time, and write_time, and when creation time is intended,
create_time is used.
Additionally, the capability of setting and retrieving the create time have
been added to the smbc_setxattr() and smbc_getxattr() functions. An example
of setting all four times can be seen with the program
examples/libsmbclient/testacl
with the following command line similar to:
testacl -f -S "system.*:CREATE_TIME:1000000000,ACCESS_TIME:1000000060,WRITE_TIME:1000000120,CHANGE_TIME:1000000180" 'smb://server/share/testfile.txt'
The -f option turns on the new mode which uses full time names in the
attribute specification (e.g. ACCESS_TIME vs A_TIME).
(This used to be commit 8e119b64f1d92026dda855d904be09912a40601c)
2006-09-02 21:47:56 +00:00
p = talloc_asprintf ( ctx , " %lu " , change_time ) ;
2005-03-31 05:06:04 +00:00
if ( ! p ) {
errno = ENOMEM ;
return - 1 ;
}
n = strlen ( p ) ;
} else {
2005-12-29 15:06:53 +00:00
n = snprintf ( buf , bufsize ,
r18009: Fixes bug 4026.
This completes the work Jeremy began last week, disambiguating the meaning of
c_time. (In POSIX terminology, c_time means "status Change time", not "create
time".) All uses of c_time, a_time and m_time have now been replaced with
change_time, access_time, and write_time, and when creation time is intended,
create_time is used.
Additionally, the capability of setting and retrieving the create time have
been added to the smbc_setxattr() and smbc_getxattr() functions. An example
of setting all four times can be seen with the program
examples/libsmbclient/testacl
with the following command line similar to:
testacl -f -S "system.*:CREATE_TIME:1000000000,ACCESS_TIME:1000000060,WRITE_TIME:1000000120,CHANGE_TIME:1000000180" 'smb://server/share/testfile.txt'
The -f option turns on the new mode which uses full time names in the
attribute specification (e.g. ACCESS_TIME vs A_TIME).
(This used to be commit 8e119b64f1d92026dda855d904be09912a40601c)
2006-09-02 21:47:56 +00:00
" %lu " , change_time ) ;
2005-03-10 23:41:19 +00:00
}
}
2007-11-30 13:09:04 -08:00
2005-03-31 05:06:04 +00:00
if ( ! determine_size & & n > bufsize ) {
errno = ERANGE ;
return - 1 ;
}
buf + = n ;
n_used + = n ;
bufsize - = n ;
2007-08-14 03:02:34 +00:00
n = 0 ;
2005-03-10 23:41:19 +00:00
}
2005-03-31 05:06:04 +00:00
if ( ! exclude_dos_inode ) {
if ( all | | all_dos ) {
if ( determine_size ) {
p = talloc_asprintf (
ctx ,
2005-10-21 22:48:27 +00:00
" ,INODE:%.0f " ,
( double ) ino ) ;
2005-03-31 05:06:04 +00:00
if ( ! p ) {
errno = ENOMEM ;
return - 1 ;
}
n = strlen ( p ) ;
} else {
n = snprintf ( buf , bufsize ,
2005-10-21 22:48:27 +00:00
" ,INODE:%.0f " ,
( double ) ino ) ;
2003-10-24 17:01:19 +00:00
}
2005-03-31 05:06:04 +00:00
} else if ( StrCaseCmp ( name , " inode " ) = = 0 ) {
if ( determine_size ) {
p = talloc_asprintf (
ctx ,
2005-10-21 22:48:27 +00:00
" %.0f " ,
( double ) ino ) ;
2005-03-31 05:06:04 +00:00
if ( ! p ) {
errno = ENOMEM ;
return - 1 ;
}
n = strlen ( p ) ;
} else {
n = snprintf ( buf , bufsize ,
2005-10-21 22:48:27 +00:00
" %.0f " ,
( double ) ino ) ;
2003-10-24 17:01:19 +00:00
}
}
2007-11-30 13:09:04 -08:00
2005-03-31 05:06:04 +00:00
if ( ! determine_size & & n > bufsize ) {
errno = ERANGE ;
return - 1 ;
}
buf + = n ;
n_used + = n ;
bufsize - = n ;
2007-08-14 03:02:34 +00:00
n = 0 ;
2003-10-24 17:01:19 +00:00
}
2005-03-10 23:41:19 +00:00
/* Restore name pointer to its original value */
name - = 16 ;
}
2003-10-24 17:01:19 +00:00
if ( n_used = = 0 ) {
errno = ENOATTR ;
return - 1 ;
}
2005-03-10 23:41:19 +00:00
2003-10-24 17:01:19 +00:00
return n_used ;
}
2007-11-30 13:09:04 -08:00
/*****************************************************
2003-10-24 17:01:19 +00:00
set the ACLs on a file given an ascii description
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2005-12-29 15:06:53 +00:00
static int
cacl_set ( TALLOC_CTX * ctx ,
struct cli_state * cli ,
struct cli_state * ipc_cli ,
POLICY_HND * pol ,
const char * filename ,
const char * the_acl ,
int mode ,
int flags )
2003-10-24 17:01:19 +00:00
{
int fnum ;
int err = 0 ;
SEC_DESC * sd = NULL , * old ;
SEC_ACL * dacl = NULL ;
2007-11-30 13:09:04 -08:00
DOM_SID * owner_sid = NULL ;
2007-10-10 15:34:30 -05:00
DOM_SID * group_sid = NULL ;
2003-10-24 17:01:19 +00:00
uint32 i , j ;
size_t sd_size ;
int ret = 0 ;
char * p ;
2007-10-18 17:40:25 -07:00
bool numeric = True ;
2003-10-24 17:01:19 +00:00
/* the_acl will be null for REMOVE_ALL operations */
if ( the_acl ) {
numeric = ( ( p = strchr ( the_acl , ' : ' ) ) ! = NULL & &
p > the_acl & &
p [ - 1 ] ! = ' + ' ) ;
/* if this is to set the entire ACL... */
if ( * the_acl = = ' * ' ) {
/* ... then increment past the first colon */
the_acl = p + 1 ;
}
2005-03-31 05:06:04 +00:00
sd = sec_desc_parse ( ctx , ipc_cli , pol , numeric ,
CONST_DISCARD ( char * , the_acl ) ) ;
2003-10-24 17:01:19 +00:00
if ( ! sd ) {
2006-03-15 03:27:03 +00:00
errno = EINVAL ;
return - 1 ;
2003-10-24 17:01:19 +00:00
}
}
2006-03-15 03:27:03 +00:00
/* SMBC_XATTR_MODE_REMOVE_ALL is the only caller
that doesn ' t deref sd */
if ( ! sd & & ( mode ! = SMBC_XATTR_MODE_REMOVE_ALL ) ) {
errno = EINVAL ;
return - 1 ;
}
2003-10-24 17:01:19 +00:00
/* The desired access below is the only one I could find that works
with NT4 , W2KP and Samba */
fnum = cli_nt_create ( cli , filename , CREATE_ACCESS_READ ) ;
2001-02-05 13:02:20 +00:00
2003-10-24 17:01:19 +00:00
if ( fnum = = - 1 ) {
DEBUG ( 5 , ( " cacl_set failed to open %s: %s \n " ,
filename , cli_errstr ( cli ) ) ) ;
errno = 0 ;
return - 1 ;
2002-07-15 10:35:28 +00:00
}
2003-10-24 17:01:19 +00:00
old = cli_query_secdesc ( cli , fnum , ctx ) ;
if ( ! old ) {
DEBUG ( 5 , ( " cacl_set Failed to query old descriptor \n " ) ) ;
errno = 0 ;
return - 1 ;
2002-07-15 10:35:28 +00:00
}
2001-02-05 13:02:20 +00:00
2003-10-24 17:01:19 +00:00
cli_close ( cli , fnum ) ;
switch ( mode ) {
case SMBC_XATTR_MODE_REMOVE_ALL :
old - > dacl - > num_aces = 0 ;
dacl = old - > dacl ;
break ;
case SMBC_XATTR_MODE_REMOVE :
for ( i = 0 ; sd - > dacl & & i < sd - > dacl - > num_aces ; i + + ) {
2007-10-18 17:40:25 -07:00
bool found = False ;
2003-10-24 17:01:19 +00:00
for ( j = 0 ; old - > dacl & & j < old - > dacl - > num_aces ; j + + ) {
2006-09-20 22:23:12 +00:00
if ( sec_ace_equal ( & sd - > dacl - > aces [ i ] ,
& old - > dacl - > aces [ j ] ) ) {
2003-10-24 17:01:19 +00:00
uint32 k ;
for ( k = j ; k < old - > dacl - > num_aces - 1 ; k + + ) {
2006-09-20 22:23:12 +00:00
old - > dacl - > aces [ k ] =
old - > dacl - > aces [ k + 1 ] ;
2003-10-24 17:01:19 +00:00
}
old - > dacl - > num_aces - - ;
found = True ;
dacl = old - > dacl ;
break ;
}
}
if ( ! found ) {
err = ENOATTR ;
ret = - 1 ;
goto failed ;
}
2002-07-15 10:35:28 +00:00
}
2003-10-24 17:01:19 +00:00
break ;
case SMBC_XATTR_MODE_ADD :
for ( i = 0 ; sd - > dacl & & i < sd - > dacl - > num_aces ; i + + ) {
2007-10-18 17:40:25 -07:00
bool found = False ;
2003-10-24 17:01:19 +00:00
for ( j = 0 ; old - > dacl & & j < old - > dacl - > num_aces ; j + + ) {
2006-09-20 22:23:12 +00:00
if ( sid_equal ( & sd - > dacl - > aces [ i ] . trustee ,
& old - > dacl - > aces [ j ] . trustee ) ) {
2003-10-24 17:01:19 +00:00
if ( ! ( flags & SMBC_XATTR_FLAG_CREATE ) ) {
err = EEXIST ;
ret = - 1 ;
goto failed ;
}
2006-09-20 22:23:12 +00:00
old - > dacl - > aces [ j ] = sd - > dacl - > aces [ i ] ;
2003-10-24 17:01:19 +00:00
ret = - 1 ;
found = True ;
}
}
if ( ! found & & ( flags & SMBC_XATTR_FLAG_REPLACE ) ) {
err = ENOATTR ;
ret = - 1 ;
goto failed ;
2002-07-15 10:35:28 +00:00
}
2007-11-30 13:09:04 -08:00
2003-10-24 17:01:19 +00:00
for ( i = 0 ; sd - > dacl & & i < sd - > dacl - > num_aces ; i + + ) {
2006-09-20 22:23:12 +00:00
add_ace ( & old - > dacl , & sd - > dacl - > aces [ i ] , ctx ) ;
2003-10-24 17:01:19 +00:00
}
2002-07-15 10:35:28 +00:00
}
2003-10-24 17:01:19 +00:00
dacl = old - > dacl ;
break ;
case SMBC_XATTR_MODE_SET :
old = sd ;
owner_sid = old - > owner_sid ;
2007-10-10 15:34:30 -05:00
group_sid = old - > group_sid ;
2003-10-24 17:01:19 +00:00
dacl = old - > dacl ;
break ;
case SMBC_XATTR_MODE_CHOWN :
owner_sid = sd - > owner_sid ;
break ;
case SMBC_XATTR_MODE_CHGRP :
2007-10-10 15:34:30 -05:00
group_sid = sd - > group_sid ;
2003-10-24 17:01:19 +00:00
break ;
2002-07-15 10:35:28 +00:00
}
2003-04-16 14:45:11 +00:00
2003-10-24 17:01:19 +00:00
/* Denied ACE entries must come before allowed ones */
sort_acl ( old - > dacl ) ;
2001-03-05 13:34:48 +00:00
2003-10-24 17:01:19 +00:00
/* Create new security descriptor and set it */
2007-11-30 13:09:04 -08:00
sd = make_sec_desc ( ctx , old - > revision , SEC_DESC_SELF_RELATIVE ,
2007-10-10 15:34:30 -05:00
owner_sid , group_sid , NULL , dacl , & sd_size ) ;
2003-10-24 17:01:19 +00:00
fnum = cli_nt_create ( cli , filename ,
WRITE_DAC_ACCESS | WRITE_OWNER_ACCESS ) ;
if ( fnum = = - 1 ) {
DEBUG ( 5 , ( " cacl_set failed to open %s: %s \n " ,
filename , cli_errstr ( cli ) ) ) ;
errno = 0 ;
return - 1 ;
2001-11-21 03:55:59 +00:00
}
2003-04-16 14:45:11 +00:00
2003-10-24 17:01:19 +00:00
if ( ! cli_set_secdesc ( cli , fnum , sd ) ) {
DEBUG ( 5 , ( " ERROR: secdesc set failed: %s \n " , cli_errstr ( cli ) ) ) ;
ret = - 1 ;
}
2001-02-05 13:02:20 +00:00
2003-10-24 17:01:19 +00:00
/* Clean up */
2001-02-05 13:02:20 +00:00
2003-10-24 17:01:19 +00:00
failed :
cli_close ( cli , fnum ) ;
if ( err ! = 0 ) {
errno = err ;
}
2007-11-30 13:09:04 -08:00
2003-10-24 17:01:19 +00:00
return ret ;
}
2005-12-29 15:06:53 +00:00
static int
smbc_setxattr_ctx ( SMBCCTX * context ,
const char * fname ,
const char * name ,
const void * value ,
size_t size ,
int flags )
2003-10-24 17:01:19 +00:00
{
int ret ;
2005-03-10 23:41:19 +00:00
int ret2 ;
2003-10-24 17:01:19 +00:00
SMBCSRV * srv ;
SMBCSRV * ipc_srv ;
2007-11-30 13:09:04 -08:00
char * server ;
char * share ;
char * user ;
char * password ;
char * workgroup ;
char * path ;
2003-10-24 17:01:19 +00:00
POLICY_HND pol ;
2005-03-10 23:41:19 +00:00
DOS_ATTR_DESC * dad ;
r18009: Fixes bug 4026.
This completes the work Jeremy began last week, disambiguating the meaning of
c_time. (In POSIX terminology, c_time means "status Change time", not "create
time".) All uses of c_time, a_time and m_time have now been replaced with
change_time, access_time, and write_time, and when creation time is intended,
create_time is used.
Additionally, the capability of setting and retrieving the create time have
been added to the smbc_setxattr() and smbc_getxattr() functions. An example
of setting all four times can be seen with the program
examples/libsmbclient/testacl
with the following command line similar to:
testacl -f -S "system.*:CREATE_TIME:1000000000,ACCESS_TIME:1000000060,WRITE_TIME:1000000120,CHANGE_TIME:1000000180" 'smb://server/share/testfile.txt'
The -f option turns on the new mode which uses full time names in the
attribute specification (e.g. ACCESS_TIME vs A_TIME).
(This used to be commit 8e119b64f1d92026dda855d904be09912a40601c)
2006-09-02 21:47:56 +00:00
struct {
const char * create_time_attr ;
const char * access_time_attr ;
const char * write_time_attr ;
const char * change_time_attr ;
} attr_strings ;
2007-11-19 12:36:16 +01:00
TALLOC_CTX * frame = talloc_stackframe ( ) ;
2003-10-24 17:01:19 +00:00
if ( ! context | | ! context - > internal | |
! context - > internal - > _initialized ) {
errno = EINVAL ; /* Best I can think of ... */
2007-11-19 12:36:16 +01:00
TALLOC_FREE ( frame ) ;
2003-10-24 17:01:19 +00:00
return - 1 ;
}
if ( ! fname ) {
errno = EINVAL ;
2007-11-19 12:36:16 +01:00
TALLOC_FREE ( frame ) ;
2003-10-24 17:01:19 +00:00
return - 1 ;
}
2007-11-30 13:09:04 -08:00
2005-12-29 15:06:53 +00:00
DEBUG ( 4 , ( " smbc_setxattr(%s, %s, %.*s) \n " ,
fname , name , ( int ) size , ( const char * ) value ) ) ;
2003-10-24 17:01:19 +00:00
2007-11-30 13:09:04 -08:00
if ( smbc_parse_path ( frame ,
context ,
fname ,
& workgroup ,
& server ,
& share ,
& path ,
& user ,
& password ,
NULL ) ) {
errno = EINVAL ;
2007-11-19 12:36:16 +01:00
TALLOC_FREE ( frame ) ;
2007-11-30 13:09:04 -08:00
return - 1 ;
2004-03-19 16:22:47 +00:00
}
2003-10-24 17:01:19 +00:00
2007-11-30 13:09:04 -08:00
if ( ! user | | user [ 0 ] = = ( char ) 0 ) {
user = talloc_strdup ( frame , context - > user ) ;
if ( ! user ) {
errno = ENOMEM ;
TALLOC_FREE ( frame ) ;
return - 1 ;
}
}
2003-10-24 17:01:19 +00:00
2005-12-29 15:06:59 +00:00
srv = smbc_server ( context , True ,
server , share , workgroup , user , password ) ;
2003-10-24 17:01:19 +00:00
if ( ! srv ) {
2007-11-19 12:36:16 +01:00
TALLOC_FREE ( frame ) ;
2003-10-24 17:01:19 +00:00
return - 1 ; /* errno set by smbc_server */
}
2005-03-10 23:41:19 +00:00
if ( ! srv - > no_nt_session ) {
ipc_srv = smbc_attr_server ( context , server , share ,
workgroup , user , password ,
& pol ) ;
2007-05-15 19:10:29 +00:00
if ( ! ipc_srv ) {
srv - > no_nt_session = True ;
}
2005-03-10 23:41:19 +00:00
} else {
ipc_srv = NULL ;
2003-10-24 17:01:19 +00:00
}
2007-11-30 13:09:04 -08:00
2005-03-10 23:41:19 +00:00
/*
* Are they asking to set the entire set of known attributes ?
*/
if ( StrCaseCmp ( name , " system.* " ) = = 0 | |
StrCaseCmp ( name , " system.*+ " ) = = 0 ) {
/* Yup. */
char * namevalue =
2007-11-19 12:36:16 +01:00
talloc_asprintf ( talloc_tos ( ) , " %s:%s " ,
2005-12-29 15:06:53 +00:00
name + 7 , ( const char * ) value ) ;
2005-03-10 23:41:19 +00:00
if ( ! namevalue ) {
errno = ENOMEM ;
ret = - 1 ;
2007-11-19 12:36:16 +01:00
TALLOC_FREE ( frame ) ;
2005-03-10 23:41:19 +00:00
return - 1 ;
}
if ( ipc_srv ) {
2007-11-19 12:36:16 +01:00
ret = cacl_set ( talloc_tos ( ) , srv - > cli ,
2006-07-11 18:01:26 +00:00
ipc_srv - > cli , & pol , path ,
2005-03-10 23:41:19 +00:00
namevalue ,
( * namevalue = = ' * '
? SMBC_XATTR_MODE_SET
: SMBC_XATTR_MODE_ADD ) ,
flags ) ;
} else {
ret = 0 ;
}
/* get a DOS Attribute Descriptor with current attributes */
2007-11-19 12:36:16 +01:00
dad = dos_attr_query ( context , talloc_tos ( ) , path , srv ) ;
2005-03-10 23:41:19 +00:00
if ( dad ) {
/* Overwrite old with new, using what was provided */
dos_attr_parse ( context , dad , srv , namevalue ) ;
/* Set the new DOS attributes */
2005-06-01 20:17:16 +00:00
if ( ! smbc_setatr ( context , srv , path ,
r18009: Fixes bug 4026.
This completes the work Jeremy began last week, disambiguating the meaning of
c_time. (In POSIX terminology, c_time means "status Change time", not "create
time".) All uses of c_time, a_time and m_time have now been replaced with
change_time, access_time, and write_time, and when creation time is intended,
create_time is used.
Additionally, the capability of setting and retrieving the create time have
been added to the smbc_setxattr() and smbc_getxattr() functions. An example
of setting all four times can be seen with the program
examples/libsmbclient/testacl
with the following command line similar to:
testacl -f -S "system.*:CREATE_TIME:1000000000,ACCESS_TIME:1000000060,WRITE_TIME:1000000120,CHANGE_TIME:1000000180" 'smb://server/share/testfile.txt'
The -f option turns on the new mode which uses full time names in the
attribute specification (e.g. ACCESS_TIME vs A_TIME).
(This used to be commit 8e119b64f1d92026dda855d904be09912a40601c)
2006-09-02 21:47:56 +00:00
dad - > create_time ,
dad - > access_time ,
dad - > write_time ,
dad - > change_time ,
2005-06-01 20:17:16 +00:00
dad - > mode ) ) {
/* cause failure if NT failed too */
dad = NULL ;
2005-03-10 23:41:19 +00:00
}
}
/* we only fail if both NT and DOS sets failed */
if ( ret < 0 & & ! dad ) {
ret = - 1 ; /* in case dad was null */
}
else {
ret = 0 ;
}
2007-11-19 12:36:16 +01:00
TALLOC_FREE ( frame ) ;
2005-03-10 23:41:19 +00:00
return ret ;
}
2003-10-24 17:01:19 +00:00
/*
* Are they asking to set an access control element or to set
* the entire access control list ?
*/
if ( StrCaseCmp ( name , " system.nt_sec_desc.* " ) = = 0 | |
StrCaseCmp ( name , " system.nt_sec_desc.*+ " ) = = 0 | |
StrCaseCmp ( name , " system.nt_sec_desc.revision " ) = = 0 | |
StrnCaseCmp ( name , " system.nt_sec_desc.acl " , 22 ) = = 0 | |
StrnCaseCmp ( name , " system.nt_sec_desc.acl+ " , 23 ) = = 0 ) {
/* Yup. */
char * namevalue =
2007-11-19 12:36:16 +01:00
talloc_asprintf ( talloc_tos ( ) , " %s:%s " ,
2005-12-29 15:06:53 +00:00
name + 19 , ( const char * ) value ) ;
2005-03-10 23:41:19 +00:00
if ( ! ipc_srv ) {
ret = - 1 ; /* errno set by smbc_server() */
}
else if ( ! namevalue ) {
2003-10-24 17:01:19 +00:00
errno = ENOMEM ;
ret = - 1 ;
} else {
2007-11-19 12:36:16 +01:00
ret = cacl_set ( talloc_tos ( ) , srv - > cli ,
2006-07-11 18:01:26 +00:00
ipc_srv - > cli , & pol , path ,
2003-10-24 17:01:19 +00:00
namevalue ,
( * namevalue = = ' * '
? SMBC_XATTR_MODE_SET
: SMBC_XATTR_MODE_ADD ) ,
flags ) ;
}
2007-11-19 12:36:16 +01:00
TALLOC_FREE ( frame ) ;
2003-10-24 17:01:19 +00:00
return ret ;
}
/*
* Are they asking to set the owner ?
*/
if ( StrCaseCmp ( name , " system.nt_sec_desc.owner " ) = = 0 | |
StrCaseCmp ( name , " system.nt_sec_desc.owner+ " ) = = 0 ) {
/* Yup. */
char * namevalue =
2007-11-19 12:36:16 +01:00
talloc_asprintf ( talloc_tos ( ) , " %s:%s " ,
2005-12-29 15:06:53 +00:00
name + 19 , ( const char * ) value ) ;
2005-03-10 23:41:19 +00:00
if ( ! ipc_srv ) {
ret = - 1 ; /* errno set by smbc_server() */
}
else if ( ! namevalue ) {
2003-10-24 17:01:19 +00:00
errno = ENOMEM ;
ret = - 1 ;
} else {
2007-11-19 12:36:16 +01:00
ret = cacl_set ( talloc_tos ( ) , srv - > cli ,
2006-07-11 18:01:26 +00:00
ipc_srv - > cli , & pol , path ,
2003-10-24 17:01:19 +00:00
namevalue , SMBC_XATTR_MODE_CHOWN , 0 ) ;
}
2007-11-19 12:36:16 +01:00
TALLOC_FREE ( frame ) ;
2003-10-24 17:01:19 +00:00
return ret ;
}
/*
* Are they asking to set the group ?
*/
if ( StrCaseCmp ( name , " system.nt_sec_desc.group " ) = = 0 | |
StrCaseCmp ( name , " system.nt_sec_desc.group+ " ) = = 0 ) {
/* Yup. */
char * namevalue =
2007-11-19 12:36:16 +01:00
talloc_asprintf ( talloc_tos ( ) , " %s:%s " ,
2005-12-29 15:06:53 +00:00
name + 19 , ( const char * ) value ) ;
2005-03-10 23:41:19 +00:00
if ( ! ipc_srv ) {
/* errno set by smbc_server() */
ret = - 1 ;
}
else if ( ! namevalue ) {
2003-10-24 17:01:19 +00:00
errno = ENOMEM ;
ret = - 1 ;
} else {
2007-11-19 12:36:16 +01:00
ret = cacl_set ( talloc_tos ( ) , srv - > cli ,
2006-07-11 18:01:26 +00:00
ipc_srv - > cli , & pol , path ,
2003-10-24 17:01:19 +00:00
namevalue , SMBC_XATTR_MODE_CHOWN , 0 ) ;
}
2007-11-19 12:36:16 +01:00
TALLOC_FREE ( frame ) ;
2003-10-24 17:01:19 +00:00
return ret ;
}
r18009: Fixes bug 4026.
This completes the work Jeremy began last week, disambiguating the meaning of
c_time. (In POSIX terminology, c_time means "status Change time", not "create
time".) All uses of c_time, a_time and m_time have now been replaced with
change_time, access_time, and write_time, and when creation time is intended,
create_time is used.
Additionally, the capability of setting and retrieving the create time have
been added to the smbc_setxattr() and smbc_getxattr() functions. An example
of setting all four times can be seen with the program
examples/libsmbclient/testacl
with the following command line similar to:
testacl -f -S "system.*:CREATE_TIME:1000000000,ACCESS_TIME:1000000060,WRITE_TIME:1000000120,CHANGE_TIME:1000000180" 'smb://server/share/testfile.txt'
The -f option turns on the new mode which uses full time names in the
attribute specification (e.g. ACCESS_TIME vs A_TIME).
(This used to be commit 8e119b64f1d92026dda855d904be09912a40601c)
2006-09-02 21:47:56 +00:00
/* Determine whether to use old-style or new-style attribute names */
if ( context - > internal - > _full_time_names ) {
/* new-style names */
attr_strings . create_time_attr = " system.dos_attr.CREATE_TIME " ;
attr_strings . access_time_attr = " system.dos_attr.ACCESS_TIME " ;
attr_strings . write_time_attr = " system.dos_attr.WRITE_TIME " ;
attr_strings . change_time_attr = " system.dos_attr.CHANGE_TIME " ;
} else {
/* old-style names */
attr_strings . create_time_attr = NULL ;
attr_strings . access_time_attr = " system.dos_attr.A_TIME " ;
attr_strings . write_time_attr = " system.dos_attr.M_TIME " ;
attr_strings . change_time_attr = " system.dos_attr.C_TIME " ;
}
2005-03-10 23:41:19 +00:00
/*
* Are they asking to set a DOS attribute ?
*/
if ( StrCaseCmp ( name , " system.dos_attr.* " ) = = 0 | |
StrCaseCmp ( name , " system.dos_attr.mode " ) = = 0 | |
r18009: Fixes bug 4026.
This completes the work Jeremy began last week, disambiguating the meaning of
c_time. (In POSIX terminology, c_time means "status Change time", not "create
time".) All uses of c_time, a_time and m_time have now been replaced with
change_time, access_time, and write_time, and when creation time is intended,
create_time is used.
Additionally, the capability of setting and retrieving the create time have
been added to the smbc_setxattr() and smbc_getxattr() functions. An example
of setting all four times can be seen with the program
examples/libsmbclient/testacl
with the following command line similar to:
testacl -f -S "system.*:CREATE_TIME:1000000000,ACCESS_TIME:1000000060,WRITE_TIME:1000000120,CHANGE_TIME:1000000180" 'smb://server/share/testfile.txt'
The -f option turns on the new mode which uses full time names in the
attribute specification (e.g. ACCESS_TIME vs A_TIME).
(This used to be commit 8e119b64f1d92026dda855d904be09912a40601c)
2006-09-02 21:47:56 +00:00
( attr_strings . create_time_attr ! = NULL & &
StrCaseCmp ( name , attr_strings . create_time_attr ) = = 0 ) | |
StrCaseCmp ( name , attr_strings . access_time_attr ) = = 0 | |
StrCaseCmp ( name , attr_strings . write_time_attr ) = = 0 | |
StrCaseCmp ( name , attr_strings . change_time_attr ) = = 0 ) {
2005-03-10 23:41:19 +00:00
/* get a DOS Attribute Descriptor with current attributes */
2007-11-19 12:36:16 +01:00
dad = dos_attr_query ( context , talloc_tos ( ) , path , srv ) ;
2005-03-10 23:41:19 +00:00
if ( dad ) {
char * namevalue =
2007-11-19 12:36:16 +01:00
talloc_asprintf ( talloc_tos ( ) , " %s:%s " ,
2005-12-29 15:06:53 +00:00
name + 16 , ( const char * ) value ) ;
2005-03-10 23:41:19 +00:00
if ( ! namevalue ) {
errno = ENOMEM ;
ret = - 1 ;
} else {
/* Overwrite old with provided new params */
dos_attr_parse ( context , dad , srv , namevalue ) ;
/* Set the new DOS attributes */
2005-06-01 20:17:16 +00:00
ret2 = smbc_setatr ( context , srv , path ,
r18009: Fixes bug 4026.
This completes the work Jeremy began last week, disambiguating the meaning of
c_time. (In POSIX terminology, c_time means "status Change time", not "create
time".) All uses of c_time, a_time and m_time have now been replaced with
change_time, access_time, and write_time, and when creation time is intended,
create_time is used.
Additionally, the capability of setting and retrieving the create time have
been added to the smbc_setxattr() and smbc_getxattr() functions. An example
of setting all four times can be seen with the program
examples/libsmbclient/testacl
with the following command line similar to:
testacl -f -S "system.*:CREATE_TIME:1000000000,ACCESS_TIME:1000000060,WRITE_TIME:1000000120,CHANGE_TIME:1000000180" 'smb://server/share/testfile.txt'
The -f option turns on the new mode which uses full time names in the
attribute specification (e.g. ACCESS_TIME vs A_TIME).
(This used to be commit 8e119b64f1d92026dda855d904be09912a40601c)
2006-09-02 21:47:56 +00:00
dad - > create_time ,
dad - > access_time ,
dad - > write_time ,
dad - > change_time ,
2005-06-01 20:17:16 +00:00
dad - > mode ) ;
2005-03-10 23:41:19 +00:00
/* ret2 has True (success) / False (failure) */
if ( ret2 ) {
ret = 0 ;
} else {
ret = - 1 ;
}
}
} else {
ret = - 1 ;
}
2007-11-19 12:36:16 +01:00
TALLOC_FREE ( frame ) ;
2005-03-10 23:41:19 +00:00
return ret ;
}
2003-10-24 17:01:19 +00:00
/* Unsupported attribute name */
errno = EINVAL ;
2007-11-19 12:36:16 +01:00
TALLOC_FREE ( frame ) ;
2003-10-24 17:01:19 +00:00
return - 1 ;
}
2005-12-29 15:06:53 +00:00
static int
smbc_getxattr_ctx ( SMBCCTX * context ,
const char * fname ,
const char * name ,
const void * value ,
size_t size )
2003-10-24 17:01:19 +00:00
{
int ret ;
SMBCSRV * srv ;
SMBCSRV * ipc_srv ;
2007-11-30 13:09:04 -08:00
char * server ;
char * share ;
char * user ;
char * password ;
char * workgroup ;
char * path ;
2003-10-24 17:01:19 +00:00
POLICY_HND pol ;
r18009: Fixes bug 4026.
This completes the work Jeremy began last week, disambiguating the meaning of
c_time. (In POSIX terminology, c_time means "status Change time", not "create
time".) All uses of c_time, a_time and m_time have now been replaced with
change_time, access_time, and write_time, and when creation time is intended,
create_time is used.
Additionally, the capability of setting and retrieving the create time have
been added to the smbc_setxattr() and smbc_getxattr() functions. An example
of setting all four times can be seen with the program
examples/libsmbclient/testacl
with the following command line similar to:
testacl -f -S "system.*:CREATE_TIME:1000000000,ACCESS_TIME:1000000060,WRITE_TIME:1000000120,CHANGE_TIME:1000000180" 'smb://server/share/testfile.txt'
The -f option turns on the new mode which uses full time names in the
attribute specification (e.g. ACCESS_TIME vs A_TIME).
(This used to be commit 8e119b64f1d92026dda855d904be09912a40601c)
2006-09-02 21:47:56 +00:00
struct {
const char * create_time_attr ;
const char * access_time_attr ;
const char * write_time_attr ;
const char * change_time_attr ;
} attr_strings ;
2007-11-19 12:36:16 +01:00
TALLOC_CTX * frame = talloc_stackframe ( ) ;
2005-03-10 23:41:19 +00:00
2003-10-24 17:01:19 +00:00
if ( ! context | | ! context - > internal | |
! context - > internal - > _initialized ) {
errno = EINVAL ; /* Best I can think of ... */
2007-11-19 12:36:16 +01:00
TALLOC_FREE ( frame ) ;
2003-10-24 17:01:19 +00:00
return - 1 ;
}
if ( ! fname ) {
errno = EINVAL ;
2007-11-19 12:36:16 +01:00
TALLOC_FREE ( frame ) ;
2003-10-24 17:01:19 +00:00
return - 1 ;
}
2007-11-30 13:09:04 -08:00
2003-10-24 17:01:19 +00:00
DEBUG ( 4 , ( " smbc_getxattr(%s, %s) \n " , fname , name ) ) ;
2007-11-30 13:09:04 -08:00
if ( smbc_parse_path ( frame ,
context ,
fname ,
& workgroup ,
& server ,
& share ,
& path ,
& user ,
& password ,
NULL ) ) {
errno = EINVAL ;
2007-11-19 12:36:16 +01:00
TALLOC_FREE ( frame ) ;
2007-11-30 13:09:04 -08:00
return - 1 ;
2004-03-19 16:22:47 +00:00
}
2003-10-24 17:01:19 +00:00
2007-11-30 13:09:04 -08:00
if ( ! user | | user [ 0 ] = = ( char ) 0 ) {
user = talloc_strdup ( frame , context - > user ) ;
if ( ! user ) {
errno = ENOMEM ;
TALLOC_FREE ( frame ) ;
return - 1 ;
}
}
2003-10-24 17:01:19 +00:00
2005-12-29 15:06:59 +00:00
srv = smbc_server ( context , True ,
server , share , workgroup , user , password ) ;
2003-10-24 17:01:19 +00:00
if ( ! srv ) {
2007-11-19 12:36:16 +01:00
TALLOC_FREE ( frame ) ;
2003-10-24 17:01:19 +00:00
return - 1 ; /* errno set by smbc_server */
}
2005-03-10 23:41:19 +00:00
if ( ! srv - > no_nt_session ) {
ipc_srv = smbc_attr_server ( context , server , share ,
workgroup , user , password ,
& pol ) ;
if ( ! ipc_srv ) {
srv - > no_nt_session = True ;
}
} else {
ipc_srv = NULL ;
2003-10-24 17:01:19 +00:00
}
2007-11-30 13:09:04 -08:00
r18009: Fixes bug 4026.
This completes the work Jeremy began last week, disambiguating the meaning of
c_time. (In POSIX terminology, c_time means "status Change time", not "create
time".) All uses of c_time, a_time and m_time have now been replaced with
change_time, access_time, and write_time, and when creation time is intended,
create_time is used.
Additionally, the capability of setting and retrieving the create time have
been added to the smbc_setxattr() and smbc_getxattr() functions. An example
of setting all four times can be seen with the program
examples/libsmbclient/testacl
with the following command line similar to:
testacl -f -S "system.*:CREATE_TIME:1000000000,ACCESS_TIME:1000000060,WRITE_TIME:1000000120,CHANGE_TIME:1000000180" 'smb://server/share/testfile.txt'
The -f option turns on the new mode which uses full time names in the
attribute specification (e.g. ACCESS_TIME vs A_TIME).
(This used to be commit 8e119b64f1d92026dda855d904be09912a40601c)
2006-09-02 21:47:56 +00:00
/* Determine whether to use old-style or new-style attribute names */
if ( context - > internal - > _full_time_names ) {
/* new-style names */
attr_strings . create_time_attr = " system.dos_attr.CREATE_TIME " ;
attr_strings . access_time_attr = " system.dos_attr.ACCESS_TIME " ;
attr_strings . write_time_attr = " system.dos_attr.WRITE_TIME " ;
attr_strings . change_time_attr = " system.dos_attr.CHANGE_TIME " ;
} else {
/* old-style names */
attr_strings . create_time_attr = NULL ;
attr_strings . access_time_attr = " system.dos_attr.A_TIME " ;
attr_strings . write_time_attr = " system.dos_attr.M_TIME " ;
attr_strings . change_time_attr = " system.dos_attr.C_TIME " ;
}
2003-10-24 17:01:19 +00:00
/* Are they requesting a supported attribute? */
2005-03-10 23:41:19 +00:00
if ( StrCaseCmp ( name , " system.* " ) = = 0 | |
2005-03-31 05:06:04 +00:00
StrnCaseCmp ( name , " system.*! " , 9 ) = = 0 | |
2005-03-10 23:41:19 +00:00
StrCaseCmp ( name , " system.*+ " ) = = 0 | |
2005-03-31 05:06:04 +00:00
StrnCaseCmp ( name , " system.*+! " , 10 ) = = 0 | |
2005-03-10 23:41:19 +00:00
StrCaseCmp ( name , " system.nt_sec_desc.* " ) = = 0 | |
2005-03-31 05:06:04 +00:00
StrnCaseCmp ( name , " system.nt_sec_desc.*! " , 21 ) = = 0 | |
2003-10-24 17:01:19 +00:00
StrCaseCmp ( name , " system.nt_sec_desc.*+ " ) = = 0 | |
2005-03-31 05:06:04 +00:00
StrnCaseCmp ( name , " system.nt_sec_desc.*+! " , 22 ) = = 0 | |
2003-10-24 17:01:19 +00:00
StrCaseCmp ( name , " system.nt_sec_desc.revision " ) = = 0 | |
StrCaseCmp ( name , " system.nt_sec_desc.owner " ) = = 0 | |
StrCaseCmp ( name , " system.nt_sec_desc.owner+ " ) = = 0 | |
StrCaseCmp ( name , " system.nt_sec_desc.group " ) = = 0 | |
StrCaseCmp ( name , " system.nt_sec_desc.group+ " ) = = 0 | |
StrnCaseCmp ( name , " system.nt_sec_desc.acl " , 22 ) = = 0 | |
2005-03-10 23:41:19 +00:00
StrnCaseCmp ( name , " system.nt_sec_desc.acl+ " , 23 ) = = 0 | |
StrCaseCmp ( name , " system.dos_attr.* " ) = = 0 | |
2005-03-31 05:06:04 +00:00
StrnCaseCmp ( name , " system.dos_attr.*! " , 18 ) = = 0 | |
2005-03-10 23:41:19 +00:00
StrCaseCmp ( name , " system.dos_attr.mode " ) = = 0 | |
StrCaseCmp ( name , " system.dos_attr.size " ) = = 0 | |
r18009: Fixes bug 4026.
This completes the work Jeremy began last week, disambiguating the meaning of
c_time. (In POSIX terminology, c_time means "status Change time", not "create
time".) All uses of c_time, a_time and m_time have now been replaced with
change_time, access_time, and write_time, and when creation time is intended,
create_time is used.
Additionally, the capability of setting and retrieving the create time have
been added to the smbc_setxattr() and smbc_getxattr() functions. An example
of setting all four times can be seen with the program
examples/libsmbclient/testacl
with the following command line similar to:
testacl -f -S "system.*:CREATE_TIME:1000000000,ACCESS_TIME:1000000060,WRITE_TIME:1000000120,CHANGE_TIME:1000000180" 'smb://server/share/testfile.txt'
The -f option turns on the new mode which uses full time names in the
attribute specification (e.g. ACCESS_TIME vs A_TIME).
(This used to be commit 8e119b64f1d92026dda855d904be09912a40601c)
2006-09-02 21:47:56 +00:00
( attr_strings . create_time_attr ! = NULL & &
StrCaseCmp ( name , attr_strings . create_time_attr ) = = 0 ) | |
StrCaseCmp ( name , attr_strings . access_time_attr ) = = 0 | |
StrCaseCmp ( name , attr_strings . write_time_attr ) = = 0 | |
StrCaseCmp ( name , attr_strings . change_time_attr ) = = 0 | |
2005-03-10 23:41:19 +00:00
StrCaseCmp ( name , " system.dos_attr.inode " ) = = 0 ) {
2003-10-24 17:01:19 +00:00
/* Yup. */
2007-11-19 12:36:16 +01:00
ret = cacl_get ( context , talloc_tos ( ) , srv ,
2006-07-11 18:01:26 +00:00
ipc_srv = = NULL ? NULL : ipc_srv - > cli ,
2005-03-31 05:06:04 +00:00
& pol , path ,
CONST_DISCARD ( char * , name ) ,
CONST_DISCARD ( char * , value ) , size ) ;
2003-10-24 17:01:19 +00:00
if ( ret < 0 & & errno = = 0 ) {
2006-07-11 18:01:26 +00:00
errno = smbc_errno ( context , srv - > cli ) ;
2003-10-24 17:01:19 +00:00
}
2007-11-19 12:36:16 +01:00
TALLOC_FREE ( frame ) ;
2003-10-24 17:01:19 +00:00
return ret ;
}
/* Unsupported attribute name */
errno = EINVAL ;
2007-11-19 12:36:16 +01:00
TALLOC_FREE ( frame ) ;
2003-10-24 17:01:19 +00:00
return - 1 ;
}
2005-12-29 15:06:53 +00:00
static int
smbc_removexattr_ctx ( SMBCCTX * context ,
const char * fname ,
const char * name )
2003-10-24 17:01:19 +00:00
{
int ret ;
SMBCSRV * srv ;
SMBCSRV * ipc_srv ;
2007-11-30 13:09:04 -08:00
char * server ;
char * share ;
char * user ;
char * password ;
char * workgroup ;
char * path ;
2003-10-24 17:01:19 +00:00
POLICY_HND pol ;
2007-11-19 12:36:16 +01:00
TALLOC_CTX * frame = talloc_stackframe ( ) ;
2003-10-24 17:01:19 +00:00
if ( ! context | | ! context - > internal | |
! context - > internal - > _initialized ) {
errno = EINVAL ; /* Best I can think of ... */
2007-11-19 12:36:16 +01:00
TALLOC_FREE ( frame ) ;
2003-10-24 17:01:19 +00:00
return - 1 ;
}
if ( ! fname ) {
errno = EINVAL ;
2007-11-19 12:36:16 +01:00
TALLOC_FREE ( frame ) ;
2003-10-24 17:01:19 +00:00
return - 1 ;
}
2007-11-30 13:09:04 -08:00
2003-10-24 17:01:19 +00:00
DEBUG ( 4 , ( " smbc_removexattr(%s, %s) \n " , fname , name ) ) ;
2007-11-30 13:09:04 -08:00
if ( smbc_parse_path ( frame ,
context ,
fname ,
& workgroup ,
& server ,
& share ,
& path ,
& user ,
& password ,
NULL ) ) {
errno = EINVAL ;
2007-11-19 12:36:16 +01:00
TALLOC_FREE ( frame ) ;
2007-11-30 13:09:04 -08:00
return - 1 ;
2004-03-19 16:22:47 +00:00
}
2003-10-24 17:01:19 +00:00
2007-11-30 13:09:04 -08:00
if ( ! user | | user [ 0 ] = = ( char ) 0 ) {
user = talloc_strdup ( frame , context - > user ) ;
if ( ! user ) {
errno = ENOMEM ;
TALLOC_FREE ( frame ) ;
return - 1 ;
}
}
2003-10-24 17:01:19 +00:00
2005-12-29 15:06:59 +00:00
srv = smbc_server ( context , True ,
server , share , workgroup , user , password ) ;
2003-10-24 17:01:19 +00:00
if ( ! srv ) {
2007-11-19 12:36:16 +01:00
TALLOC_FREE ( frame ) ;
2003-10-24 17:01:19 +00:00
return - 1 ; /* errno set by smbc_server */
}
2005-03-10 23:41:19 +00:00
if ( ! srv - > no_nt_session ) {
ipc_srv = smbc_attr_server ( context , server , share ,
workgroup , user , password ,
& pol ) ;
2007-05-15 19:10:29 +00:00
if ( ! ipc_srv ) {
srv - > no_nt_session = True ;
}
2005-03-10 23:41:19 +00:00
} else {
ipc_srv = NULL ;
2003-10-24 17:01:19 +00:00
}
2007-11-30 13:09:04 -08:00
2005-03-10 23:41:19 +00:00
if ( ! ipc_srv ) {
2007-11-19 12:36:16 +01:00
TALLOC_FREE ( frame ) ;
2005-03-10 23:41:19 +00:00
return - 1 ; /* errno set by smbc_attr_server */
2003-10-24 17:01:19 +00:00
}
2005-03-10 23:41:19 +00:00
2003-10-24 17:01:19 +00:00
/* Are they asking to set the entire ACL? */
if ( StrCaseCmp ( name , " system.nt_sec_desc.* " ) = = 0 | |
StrCaseCmp ( name , " system.nt_sec_desc.*+ " ) = = 0 ) {
/* Yup. */
2007-11-19 12:36:16 +01:00
ret = cacl_set ( talloc_tos ( ) , srv - > cli ,
2006-07-11 18:01:26 +00:00
ipc_srv - > cli , & pol , path ,
2003-10-24 17:01:19 +00:00
NULL , SMBC_XATTR_MODE_REMOVE_ALL , 0 ) ;
2007-11-19 12:36:16 +01:00
TALLOC_FREE ( frame ) ;
2003-10-24 17:01:19 +00:00
return ret ;
}
/*
* Are they asking to remove one or more spceific security descriptor
* attributes ?
*/
if ( StrCaseCmp ( name , " system.nt_sec_desc.revision " ) = = 0 | |
StrCaseCmp ( name , " system.nt_sec_desc.owner " ) = = 0 | |
StrCaseCmp ( name , " system.nt_sec_desc.owner+ " ) = = 0 | |
StrCaseCmp ( name , " system.nt_sec_desc.group " ) = = 0 | |
StrCaseCmp ( name , " system.nt_sec_desc.group+ " ) = = 0 | |
StrnCaseCmp ( name , " system.nt_sec_desc.acl " , 22 ) = = 0 | |
StrnCaseCmp ( name , " system.nt_sec_desc.acl+ " , 23 ) = = 0 ) {
/* Yup. */
2007-11-19 12:36:16 +01:00
ret = cacl_set ( talloc_tos ( ) , srv - > cli ,
2006-07-11 18:01:26 +00:00
ipc_srv - > cli , & pol , path ,
2003-10-24 17:01:19 +00:00
name + 19 , SMBC_XATTR_MODE_REMOVE , 0 ) ;
2007-11-19 12:36:16 +01:00
TALLOC_FREE ( frame ) ;
2003-10-24 17:01:19 +00:00
return ret ;
}
/* Unsupported attribute name */
errno = EINVAL ;
2007-11-19 12:36:16 +01:00
TALLOC_FREE ( frame ) ;
2003-10-24 17:01:19 +00:00
return - 1 ;
}
2005-12-29 15:06:53 +00:00
static int
smbc_listxattr_ctx ( SMBCCTX * context ,
const char * fname ,
char * list ,
size_t size )
2003-10-24 17:01:19 +00:00
{
/*
* This isn ' t quite what listxattr ( ) is supposed to do . This returns
2005-03-10 23:41:19 +00:00
* the complete set of attribute names , always , rather than only those
2003-10-24 17:01:19 +00:00
* attribute names which actually exist for a file . Hmmm . . .
*/
r18009: Fixes bug 4026.
This completes the work Jeremy began last week, disambiguating the meaning of
c_time. (In POSIX terminology, c_time means "status Change time", not "create
time".) All uses of c_time, a_time and m_time have now been replaced with
change_time, access_time, and write_time, and when creation time is intended,
create_time is used.
Additionally, the capability of setting and retrieving the create time have
been added to the smbc_setxattr() and smbc_getxattr() functions. An example
of setting all four times can be seen with the program
examples/libsmbclient/testacl
with the following command line similar to:
testacl -f -S "system.*:CREATE_TIME:1000000000,ACCESS_TIME:1000000060,WRITE_TIME:1000000120,CHANGE_TIME:1000000180" 'smb://server/share/testfile.txt'
The -f option turns on the new mode which uses full time names in the
attribute specification (e.g. ACCESS_TIME vs A_TIME).
(This used to be commit 8e119b64f1d92026dda855d904be09912a40601c)
2006-09-02 21:47:56 +00:00
const char supported_old [ ] =
2005-03-10 23:41:19 +00:00
" system.* \0 "
" system.*+ \0 "
2003-10-24 17:01:19 +00:00
" system.nt_sec_desc.revision \0 "
" system.nt_sec_desc.owner \0 "
" system.nt_sec_desc.owner+ \0 "
" system.nt_sec_desc.group \0 "
" system.nt_sec_desc.group+ \0 "
2005-03-31 05:06:04 +00:00
" system.nt_sec_desc.acl.* \0 "
2003-10-24 17:01:19 +00:00
" system.nt_sec_desc.acl \0 "
" system.nt_sec_desc.acl+ \0 "
" system.nt_sec_desc.* \0 "
" system.nt_sec_desc.*+ \0 "
2005-03-10 23:41:19 +00:00
" system.dos_attr.* \0 "
" system.dos_attr.mode \0 "
" system.dos_attr.c_time \0 "
" system.dos_attr.a_time \0 "
" system.dos_attr.m_time \0 "
2003-10-24 17:01:19 +00:00
;
r18009: Fixes bug 4026.
This completes the work Jeremy began last week, disambiguating the meaning of
c_time. (In POSIX terminology, c_time means "status Change time", not "create
time".) All uses of c_time, a_time and m_time have now been replaced with
change_time, access_time, and write_time, and when creation time is intended,
create_time is used.
Additionally, the capability of setting and retrieving the create time have
been added to the smbc_setxattr() and smbc_getxattr() functions. An example
of setting all four times can be seen with the program
examples/libsmbclient/testacl
with the following command line similar to:
testacl -f -S "system.*:CREATE_TIME:1000000000,ACCESS_TIME:1000000060,WRITE_TIME:1000000120,CHANGE_TIME:1000000180" 'smb://server/share/testfile.txt'
The -f option turns on the new mode which uses full time names in the
attribute specification (e.g. ACCESS_TIME vs A_TIME).
(This used to be commit 8e119b64f1d92026dda855d904be09912a40601c)
2006-09-02 21:47:56 +00:00
const char supported_new [ ] =
" system.* \0 "
" system.*+ \0 "
" system.nt_sec_desc.revision \0 "
" system.nt_sec_desc.owner \0 "
" system.nt_sec_desc.owner+ \0 "
" system.nt_sec_desc.group \0 "
" system.nt_sec_desc.group+ \0 "
" system.nt_sec_desc.acl.* \0 "
" system.nt_sec_desc.acl \0 "
" system.nt_sec_desc.acl+ \0 "
" system.nt_sec_desc.* \0 "
" system.nt_sec_desc.*+ \0 "
" system.dos_attr.* \0 "
" system.dos_attr.mode \0 "
" system.dos_attr.create_time \0 "
" system.dos_attr.access_time \0 "
" system.dos_attr.write_time \0 "
" system.dos_attr.change_time \0 "
;
const char * supported ;
if ( context - > internal - > _full_time_names ) {
supported = supported_new ;
} else {
supported = supported_old ;
}
2003-10-24 17:01:19 +00:00
if ( size = = 0 ) {
return sizeof ( supported ) ;
}
if ( sizeof ( supported ) > size ) {
errno = ERANGE ;
return - 1 ;
}
/* this can't be strcpy() because there are embedded null characters */
memcpy ( list , supported , sizeof ( supported ) ) ;
return sizeof ( supported ) ;
}
/*
* Open a print file to be written to by other calls
*/
2005-12-29 15:06:53 +00:00
static SMBCFILE *
smbc_open_print_job_ctx ( SMBCCTX * context ,
const char * fname )
2003-10-24 17:01:19 +00:00
{
2007-11-30 13:09:04 -08:00
char * server ;
char * share ;
char * user ;
char * password ;
char * path ;
2007-11-19 12:36:16 +01:00
TALLOC_CTX * frame = talloc_stackframe ( ) ;
2007-11-30 13:09:04 -08:00
2003-10-24 17:01:19 +00:00
if ( ! context | | ! context - > internal | |
! context - > internal - > _initialized ) {
errno = EINVAL ;
2007-11-19 12:36:16 +01:00
TALLOC_FREE ( frame ) ;
2003-10-24 17:01:19 +00:00
return NULL ;
}
if ( ! fname ) {
errno = EINVAL ;
2007-11-19 12:36:16 +01:00
TALLOC_FREE ( frame ) ;
2003-10-24 17:01:19 +00:00
return NULL ;
}
2007-11-30 13:09:04 -08:00
2003-10-24 17:01:19 +00:00
DEBUG ( 4 , ( " smbc_open_print_job_ctx(%s) \n " , fname ) ) ;
2007-11-30 13:09:04 -08:00
if ( smbc_parse_path ( frame ,
context ,
fname ,
NULL ,
& server ,
& share ,
& path ,
& user ,
& password ,
NULL ) ) {
2004-03-19 16:22:47 +00:00
errno = EINVAL ;
2007-11-19 12:36:16 +01:00
TALLOC_FREE ( frame ) ;
2004-03-19 16:22:47 +00:00
return NULL ;
}
2003-10-24 17:01:19 +00:00
/* What if the path is empty, or the file exists? */
2007-11-19 12:36:16 +01:00
TALLOC_FREE ( frame ) ;
2007-09-05 12:53:56 +00:00
return ( context - > open ) ( context , fname , O_WRONLY , 666 ) ;
2003-10-24 17:01:19 +00:00
}
/*
* Routine to print a file on a remote server . . .
*
* We open the file , which we assume to be on a remote server , and then
* copy it to a print file on the share specified by printq .
*/
2005-12-29 15:06:53 +00:00
static int
smbc_print_file_ctx ( SMBCCTX * c_file ,
const char * fname ,
SMBCCTX * c_print ,
const char * printq )
2003-10-24 17:01:19 +00:00
{
2005-12-29 15:06:53 +00:00
SMBCFILE * fid1 ;
SMBCFILE * fid2 ;
int bytes ;
int saverr ;
int tot_bytes = 0 ;
2003-10-24 17:01:19 +00:00
char buf [ 4096 ] ;
2007-11-19 12:36:16 +01:00
TALLOC_CTX * frame = talloc_stackframe ( ) ;
2003-10-24 17:01:19 +00:00
if ( ! c_file | | ! c_file - > internal - > _initialized | | ! c_print | |
! c_print - > internal - > _initialized ) {
errno = EINVAL ;
2007-11-19 12:36:16 +01:00
TALLOC_FREE ( frame ) ;
2003-10-24 17:01:19 +00:00
return - 1 ;
}
if ( ! fname & & ! printq ) {
errno = EINVAL ;
2007-11-19 12:36:16 +01:00
TALLOC_FREE ( frame ) ;
2003-10-24 17:01:19 +00:00
return - 1 ;
}
/* Try to open the file for reading ... */
2007-09-05 12:53:56 +00:00
if ( ( long ) ( fid1 = ( c_file - > open ) ( c_file , fname , O_RDONLY , 0666 ) ) < 0 ) {
2003-10-24 17:01:19 +00:00
DEBUG ( 3 , ( " Error, fname=%s, errno=%i \n " , fname , errno ) ) ;
2007-11-19 12:36:16 +01:00
TALLOC_FREE ( frame ) ;
2003-10-24 17:01:19 +00:00
return - 1 ; /* smbc_open sets errno */
}
/* Now, try to open the printer file for writing */
2007-09-06 13:21:31 +00:00
if ( ( long ) ( fid2 = ( c_print - > open_print_job ) ( c_print , printq ) ) < 0 ) {
2003-10-24 17:01:19 +00:00
saverr = errno ; /* Save errno */
2007-09-06 13:21:31 +00:00
( c_file - > close_fn ) ( c_file , fid1 ) ;
2003-10-24 17:01:19 +00:00
errno = saverr ;
2007-11-19 12:36:16 +01:00
TALLOC_FREE ( frame ) ;
2003-10-24 17:01:19 +00:00
return - 1 ;
}
2007-09-06 13:21:31 +00:00
while ( ( bytes = ( c_file - > read ) ( c_file , fid1 , buf , sizeof ( buf ) ) ) > 0 ) {
2003-10-24 17:01:19 +00:00
tot_bytes + = bytes ;
2007-09-06 13:21:31 +00:00
if ( ( ( c_print - > write ) ( c_print , fid2 , buf , bytes ) ) < 0 ) {
2003-10-24 17:01:19 +00:00
saverr = errno ;
2007-09-06 13:21:31 +00:00
( c_file - > close_fn ) ( c_file , fid1 ) ;
( c_print - > close_fn ) ( c_print , fid2 ) ;
2003-10-24 17:01:19 +00:00
errno = saverr ;
}
}
saverr = errno ;
2007-09-06 13:21:31 +00:00
( c_file - > close_fn ) ( c_file , fid1 ) ; /* We have to close these anyway */
( c_print - > close_fn ) ( c_print , fid2 ) ;
2003-10-24 17:01:19 +00:00
if ( bytes < 0 ) {
errno = saverr ;
2007-11-19 12:36:16 +01:00
TALLOC_FREE ( frame ) ;
2003-10-24 17:01:19 +00:00
return - 1 ;
}
2007-11-19 12:36:16 +01:00
TALLOC_FREE ( frame ) ;
2003-10-24 17:01:19 +00:00
return tot_bytes ;
}
/*
* Routine to list print jobs on a printer share . . .
*/
2005-12-29 15:06:53 +00:00
static int
smbc_list_print_jobs_ctx ( SMBCCTX * context ,
const char * fname ,
smbc_list_print_job_fn fn )
2003-10-24 17:01:19 +00:00
{
2007-11-30 13:09:04 -08:00
SMBCSRV * srv ;
char * server ;
char * share ;
char * user ;
char * password ;
char * workgroup ;
char * path ;
2007-11-19 12:36:16 +01:00
TALLOC_CTX * frame = talloc_stackframe ( ) ;
2003-10-24 17:01:19 +00:00
if ( ! context | | ! context - > internal | |
! context - > internal - > _initialized ) {
errno = EINVAL ;
2007-11-19 12:36:16 +01:00
TALLOC_FREE ( frame ) ;
2003-10-24 17:01:19 +00:00
return - 1 ;
}
if ( ! fname ) {
errno = EINVAL ;
2007-11-19 12:36:16 +01:00
TALLOC_FREE ( frame ) ;
2003-10-24 17:01:19 +00:00
return - 1 ;
}
2007-11-30 13:09:04 -08:00
2003-10-24 17:01:19 +00:00
DEBUG ( 4 , ( " smbc_list_print_jobs(%s) \n " , fname ) ) ;
2007-11-30 13:09:04 -08:00
if ( smbc_parse_path ( frame ,
context ,
fname ,
& workgroup ,
& server ,
& share ,
& path ,
& user ,
& password ,
NULL ) ) {
errno = EINVAL ;
2007-11-19 12:36:16 +01:00
TALLOC_FREE ( frame ) ;
2007-11-30 13:09:04 -08:00
return - 1 ;
2004-03-19 16:22:47 +00:00
}
2003-10-24 17:01:19 +00:00
2007-11-30 13:09:04 -08:00
if ( ! user | | user [ 0 ] = = ( char ) 0 ) {
user = talloc_strdup ( frame , context - > user ) ;
if ( ! user ) {
errno = ENOMEM ;
TALLOC_FREE ( frame ) ;
return - 1 ;
}
}
2005-12-29 15:06:59 +00:00
srv = smbc_server ( context , True ,
server , share , workgroup , user , password ) ;
2003-10-24 17:01:19 +00:00
if ( ! srv ) {
2007-11-19 12:36:16 +01:00
TALLOC_FREE ( frame ) ;
2003-10-24 17:01:19 +00:00
return - 1 ; /* errno set by smbc_server */
}
2006-07-11 18:01:26 +00:00
if ( cli_print_queue ( srv - > cli ,
2005-12-29 15:06:53 +00:00
( void ( * ) ( struct print_job_info * ) ) fn ) < 0 ) {
2006-07-11 18:01:26 +00:00
errno = smbc_errno ( context , srv - > cli ) ;
2007-11-19 12:36:16 +01:00
TALLOC_FREE ( frame ) ;
2003-10-24 17:01:19 +00:00
return - 1 ;
}
2007-11-30 13:09:04 -08:00
2007-11-19 12:36:16 +01:00
TALLOC_FREE ( frame ) ;
2003-10-24 17:01:19 +00:00
return 0 ;
}
/*
* Delete a print job from a remote printer share
*/
2005-12-29 15:06:53 +00:00
static int
smbc_unlink_print_job_ctx ( SMBCCTX * context ,
const char * fname ,
int id )
2003-10-24 17:01:19 +00:00
{
2007-11-30 13:09:04 -08:00
SMBCSRV * srv ;
char * server ;
char * share ;
char * user ;
char * password ;
char * workgroup ;
char * path ;
2003-10-24 17:01:19 +00:00
int err ;
2007-11-19 12:36:16 +01:00
TALLOC_CTX * frame = talloc_stackframe ( ) ;
2003-10-24 17:01:19 +00:00
if ( ! context | | ! context - > internal | |
! context - > internal - > _initialized ) {
errno = EINVAL ;
2007-11-19 12:36:16 +01:00
TALLOC_FREE ( frame ) ;
2003-10-24 17:01:19 +00:00
return - 1 ;
}
if ( ! fname ) {
errno = EINVAL ;
2007-11-19 12:36:16 +01:00
TALLOC_FREE ( frame ) ;
2003-10-24 17:01:19 +00:00
return - 1 ;
}
2007-11-30 13:09:04 -08:00
2003-10-24 17:01:19 +00:00
DEBUG ( 4 , ( " smbc_unlink_print_job(%s) \n " , fname ) ) ;
2007-11-30 13:09:04 -08:00
if ( smbc_parse_path ( frame ,
context ,
fname ,
& workgroup ,
& server ,
& share ,
& path ,
& user ,
& password ,
NULL ) ) {
errno = EINVAL ;
2007-11-19 12:36:16 +01:00
TALLOC_FREE ( frame ) ;
2007-11-30 13:09:04 -08:00
return - 1 ;
2004-03-19 16:22:47 +00:00
}
2003-10-24 17:01:19 +00:00
2007-11-30 13:09:04 -08:00
if ( ! user | | user [ 0 ] = = ( char ) 0 ) {
user = talloc_strdup ( frame , context - > user ) ;
if ( ! user ) {
errno = ENOMEM ;
TALLOC_FREE ( frame ) ;
return - 1 ;
}
}
2003-10-24 17:01:19 +00:00
2005-12-29 15:06:59 +00:00
srv = smbc_server ( context , True ,
server , share , workgroup , user , password ) ;
2003-10-24 17:01:19 +00:00
if ( ! srv ) {
2007-11-19 12:36:16 +01:00
TALLOC_FREE ( frame ) ;
2003-10-24 17:01:19 +00:00
return - 1 ; /* errno set by smbc_server */
}
2006-07-11 18:01:26 +00:00
if ( ( err = cli_printjob_del ( srv - > cli , id ) ) ! = 0 ) {
2003-10-24 17:01:19 +00:00
if ( err < 0 )
2006-07-11 18:01:26 +00:00
errno = smbc_errno ( context , srv - > cli ) ;
2003-10-24 17:01:19 +00:00
else if ( err = = ERRnosuchprintjob )
errno = EINVAL ;
2007-11-19 12:36:16 +01:00
TALLOC_FREE ( frame ) ;
2003-10-24 17:01:19 +00:00
return - 1 ;
}
2007-11-19 12:36:16 +01:00
TALLOC_FREE ( frame ) ;
2003-10-24 17:01:19 +00:00
return 0 ;
}
/*
2007-11-30 13:09:04 -08:00
* Get a new empty handle to fill in with your own info
2003-10-24 17:01:19 +00:00
*/
2005-12-29 15:06:53 +00:00
SMBCCTX *
smbc_new_context ( void )
2003-10-24 17:01:19 +00:00
{
2005-12-29 15:06:53 +00:00
SMBCCTX * context ;
2003-10-24 17:01:19 +00:00
2004-12-07 18:25:53 +00:00
context = SMB_MALLOC_P ( SMBCCTX ) ;
2003-10-24 17:01:19 +00:00
if ( ! context ) {
errno = ENOMEM ;
return NULL ;
}
ZERO_STRUCTP ( context ) ;
2004-12-07 18:25:53 +00:00
context - > internal = SMB_MALLOC_P ( struct smbc_internal_data ) ;
2003-10-24 17:01:19 +00:00
if ( ! context - > internal ) {
2006-03-12 10:52:56 +00:00
SAFE_FREE ( context ) ;
2003-10-24 17:01:19 +00:00
errno = ENOMEM ;
return NULL ;
}
ZERO_STRUCTP ( context - > internal ) ;
/* ADD REASONABLE DEFAULTS */
context - > debug = 0 ;
context - > timeout = 20000 ; /* 20 seconds */
2005-03-11 17:01:30 +00:00
context - > options . browse_max_lmb_count = 3 ; /* # LMBs to query */
context - > options . urlencode_readdir_entries = False ; /* backward compat */
context - > options . one_share_per_server = False ; /* backward compat */
2006-09-03 02:10:24 +00:00
context - > internal - > _share_mode = SMBC_SHAREMODE_DENY_NONE ;
/* backward compat */
2005-03-10 23:41:19 +00:00
context - > open = smbc_open_ctx ;
context - > creat = smbc_creat_ctx ;
context - > read = smbc_read_ctx ;
context - > write = smbc_write_ctx ;
2005-07-03 12:05:07 +00:00
context - > close_fn = smbc_close_ctx ;
2005-03-10 23:41:19 +00:00
context - > unlink = smbc_unlink_ctx ;
context - > rename = smbc_rename_ctx ;
context - > lseek = smbc_lseek_ctx ;
context - > stat = smbc_stat_ctx ;
context - > fstat = smbc_fstat_ctx ;
context - > opendir = smbc_opendir_ctx ;
context - > closedir = smbc_closedir_ctx ;
context - > readdir = smbc_readdir_ctx ;
context - > getdents = smbc_getdents_ctx ;
context - > mkdir = smbc_mkdir_ctx ;
context - > rmdir = smbc_rmdir_ctx ;
context - > telldir = smbc_telldir_ctx ;
context - > lseekdir = smbc_lseekdir_ctx ;
context - > fstatdir = smbc_fstatdir_ctx ;
context - > chmod = smbc_chmod_ctx ;
context - > utimes = smbc_utimes_ctx ;
context - > setxattr = smbc_setxattr_ctx ;
context - > getxattr = smbc_getxattr_ctx ;
context - > removexattr = smbc_removexattr_ctx ;
context - > listxattr = smbc_listxattr_ctx ;
context - > open_print_job = smbc_open_print_job_ctx ;
context - > print_file = smbc_print_file_ctx ;
context - > list_print_jobs = smbc_list_print_jobs_ctx ;
context - > unlink_print_job = smbc_unlink_print_job_ctx ;
context - > callbacks . check_server_fn = smbc_check_server ;
2003-10-24 17:01:19 +00:00
context - > callbacks . remove_unused_server_fn = smbc_remove_unused_server ;
smbc_default_cache_functions ( context ) ;
return context ;
}
2007-11-30 13:09:04 -08:00
/*
2003-10-24 17:01:19 +00:00
* Free a context
*
2007-11-30 13:09:04 -08:00
* Returns 0 on success . Otherwise returns 1 , the SMBCCTX is _not_ freed
2003-10-24 17:01:19 +00:00
* and thus you ' ll be leaking memory if not handled properly .
*
*/
2005-12-29 15:06:53 +00:00
int
smbc_free_context ( SMBCCTX * context ,
int shutdown_ctx )
2003-10-24 17:01:19 +00:00
{
if ( ! context ) {
errno = EBADF ;
return 1 ;
}
2007-11-30 13:09:04 -08:00
2003-10-24 17:01:19 +00:00
if ( shutdown_ctx ) {
SMBCFILE * f ;
DEBUG ( 1 , ( " Performing aggressive shutdown. \n " ) ) ;
2007-11-30 13:09:04 -08:00
2003-10-24 17:01:19 +00:00
f = context - > internal - > _files ;
while ( f ) {
2007-09-06 13:21:31 +00:00
( context - > close_fn ) ( context , f ) ;
2003-10-24 17:01:19 +00:00
f = f - > next ;
}
context - > internal - > _files = NULL ;
/* First try to remove the servers the nice way. */
if ( context - > callbacks . purge_cached_fn ( context ) ) {
SMBCSRV * s ;
2004-03-19 16:22:47 +00:00
SMBCSRV * next ;
2005-12-29 15:06:53 +00:00
DEBUG ( 1 , ( " Could not purge all servers, "
" Nice way shutdown failed. \n " ) ) ;
2003-10-24 17:01:19 +00:00
s = context - > internal - > _servers ;
while ( s ) {
2005-12-29 15:06:53 +00:00
DEBUG ( 1 , ( " Forced shutdown: %p (fd=%d) \n " ,
2006-07-11 18:01:26 +00:00
s , s - > cli - > fd ) ) ;
cli_shutdown ( s - > cli ) ;
2007-09-06 13:21:31 +00:00
( context - > callbacks . remove_cached_srv_fn ) ( context ,
s ) ;
2004-03-19 16:22:47 +00:00
next = s - > next ;
DLIST_REMOVE ( context - > internal - > _servers , s ) ;
2003-10-24 17:01:19 +00:00
SAFE_FREE ( s ) ;
2004-03-19 16:22:47 +00:00
s = next ;
2003-10-24 17:01:19 +00:00
}
context - > internal - > _servers = NULL ;
}
}
else {
2007-11-30 13:09:04 -08:00
/* This is the polite way */
2007-09-06 13:21:31 +00:00
if ( ( context - > callbacks . purge_cached_fn ) ( context ) ) {
2005-12-29 15:06:53 +00:00
DEBUG ( 1 , ( " Could not purge all servers, "
" free_context failed. \n " ) ) ;
2003-10-24 17:01:19 +00:00
errno = EBUSY ;
return 1 ;
}
if ( context - > internal - > _servers ) {
2005-12-29 15:06:53 +00:00
DEBUG ( 1 , ( " Active servers in context, "
" free_context failed. \n " ) ) ;
2003-10-24 17:01:19 +00:00
errno = EBUSY ;
return 1 ;
}
if ( context - > internal - > _files ) {
2005-12-29 15:06:53 +00:00
DEBUG ( 1 , ( " Active files in context, "
" free_context failed. \n " ) ) ;
2003-10-24 17:01:19 +00:00
errno = EBUSY ;
return 1 ;
2007-11-30 13:09:04 -08:00
}
2003-10-24 17:01:19 +00:00
}
/* Things we have to clean up */
SAFE_FREE ( context - > workgroup ) ;
SAFE_FREE ( context - > netbios_name ) ;
SAFE_FREE ( context - > user ) ;
2007-11-30 13:09:04 -08:00
2003-10-24 17:01:19 +00:00
DEBUG ( 3 , ( " Context %p succesfully freed \n " , context ) ) ;
SAFE_FREE ( context - > internal ) ;
SAFE_FREE ( context ) ;
return 0 ;
}
2005-12-29 16:26:06 +00:00
/*
* Each time the context structure is changed , we have binary backward
* compatibility issues . Instead of modifying the public portions of the
* context structure to add new options , instead , we put them in the internal
* portion of the context structure and provide a set function for these new
* options .
*/
void
smbc_option_set ( SMBCCTX * context ,
char * option_name ,
2006-06-27 02:30:58 +00:00
. . . /* option_value */ )
2005-12-29 16:26:06 +00:00
{
2006-06-27 02:30:58 +00:00
va_list ap ;
union {
2006-09-03 02:10:24 +00:00
int i ;
2007-10-18 17:40:25 -07:00
bool b ;
2006-06-27 02:30:58 +00:00
smbc_get_auth_data_with_context_fn auth_fn ;
void * v ;
} option_value ;
va_start ( ap , option_name ) ;
if ( strcmp ( option_name , " debug_to_stderr " ) = = 0 ) {
2005-12-29 16:26:06 +00:00
/*
* Log to standard error instead of standard output .
*/
2007-10-18 17:40:25 -07:00
option_value . b = ( bool ) va_arg ( ap , int ) ;
2006-06-27 02:30:58 +00:00
context - > internal - > _debug_stderr = option_value . b ;
r18009: Fixes bug 4026.
This completes the work Jeremy began last week, disambiguating the meaning of
c_time. (In POSIX terminology, c_time means "status Change time", not "create
time".) All uses of c_time, a_time and m_time have now been replaced with
change_time, access_time, and write_time, and when creation time is intended,
create_time is used.
Additionally, the capability of setting and retrieving the create time have
been added to the smbc_setxattr() and smbc_getxattr() functions. An example
of setting all four times can be seen with the program
examples/libsmbclient/testacl
with the following command line similar to:
testacl -f -S "system.*:CREATE_TIME:1000000000,ACCESS_TIME:1000000060,WRITE_TIME:1000000120,CHANGE_TIME:1000000180" 'smb://server/share/testfile.txt'
The -f option turns on the new mode which uses full time names in the
attribute specification (e.g. ACCESS_TIME vs A_TIME).
(This used to be commit 8e119b64f1d92026dda855d904be09912a40601c)
2006-09-02 21:47:56 +00:00
} else if ( strcmp ( option_name , " full_time_names " ) = = 0 ) {
2006-06-27 02:30:58 +00:00
/*
r18009: Fixes bug 4026.
This completes the work Jeremy began last week, disambiguating the meaning of
c_time. (In POSIX terminology, c_time means "status Change time", not "create
time".) All uses of c_time, a_time and m_time have now been replaced with
change_time, access_time, and write_time, and when creation time is intended,
create_time is used.
Additionally, the capability of setting and retrieving the create time have
been added to the smbc_setxattr() and smbc_getxattr() functions. An example
of setting all four times can be seen with the program
examples/libsmbclient/testacl
with the following command line similar to:
testacl -f -S "system.*:CREATE_TIME:1000000000,ACCESS_TIME:1000000060,WRITE_TIME:1000000120,CHANGE_TIME:1000000180" 'smb://server/share/testfile.txt'
The -f option turns on the new mode which uses full time names in the
attribute specification (e.g. ACCESS_TIME vs A_TIME).
(This used to be commit 8e119b64f1d92026dda855d904be09912a40601c)
2006-09-02 21:47:56 +00:00
* Use new - style time attribute names , e . g . WRITE_TIME rather
* than the old - style names such as M_TIME . This allows also
* setting / getting CREATE_TIME which was previously
* unimplemented . ( Note that the old C_TIME was supposed to
* be CHANGE_TIME but was confused and sometimes referred to
* CREATE_TIME . )
2006-06-27 02:30:58 +00:00
*/
2007-10-18 17:40:25 -07:00
option_value . b = ( bool ) va_arg ( ap , int ) ;
r18009: Fixes bug 4026.
This completes the work Jeremy began last week, disambiguating the meaning of
c_time. (In POSIX terminology, c_time means "status Change time", not "create
time".) All uses of c_time, a_time and m_time have now been replaced with
change_time, access_time, and write_time, and when creation time is intended,
create_time is used.
Additionally, the capability of setting and retrieving the create time have
been added to the smbc_setxattr() and smbc_getxattr() functions. An example
of setting all four times can be seen with the program
examples/libsmbclient/testacl
with the following command line similar to:
testacl -f -S "system.*:CREATE_TIME:1000000000,ACCESS_TIME:1000000060,WRITE_TIME:1000000120,CHANGE_TIME:1000000180" 'smb://server/share/testfile.txt'
The -f option turns on the new mode which uses full time names in the
attribute specification (e.g. ACCESS_TIME vs A_TIME).
(This used to be commit 8e119b64f1d92026dda855d904be09912a40601c)
2006-09-02 21:47:56 +00:00
context - > internal - > _full_time_names = option_value . b ;
2006-06-27 02:30:58 +00:00
2006-09-03 02:10:24 +00:00
} else if ( strcmp ( option_name , " open_share_mode " ) = = 0 ) {
/*
* The share mode to use for files opened with
* smbc_open_ctx ( ) . The default is SMBC_SHAREMODE_DENY_NONE .
*/
option_value . i = va_arg ( ap , int ) ;
context - > internal - > _share_mode =
( smbc_share_mode ) option_value . i ;
2006-03-22 22:05:19 +00:00
} else if ( strcmp ( option_name , " auth_function " ) = = 0 ) {
/*
* Use the new - style authentication function which includes
* the context .
*/
2006-06-27 02:30:58 +00:00
option_value . auth_fn =
va_arg ( ap , smbc_get_auth_data_with_context_fn ) ;
context - > internal - > _auth_fn_with_context =
option_value . auth_fn ;
2006-03-22 22:05:19 +00:00
} else if ( strcmp ( option_name , " user_data " ) = = 0 ) {
/*
* Save a user data handle which may be retrieved by the user
* with smbc_option_get ( )
*/
2006-06-27 02:30:58 +00:00
option_value . v = va_arg ( ap , void * ) ;
context - > internal - > _user_data = option_value . v ;
2006-03-22 22:05:19 +00:00
}
2006-06-27 02:30:58 +00:00
va_end ( ap ) ;
2006-03-22 22:05:19 +00:00
}
/*
* Retrieve the current value of an option
*/
void *
smbc_option_get ( SMBCCTX * context ,
char * option_name )
{
if ( strcmp ( option_name , " debug_stderr " ) = = 0 ) {
/*
* Log to standard error instead of standard output .
*/
2006-06-16 02:23:02 +00:00
# if defined(__intptr_t_defined) || defined(HAVE_INTPTR_T)
2006-07-11 18:01:26 +00:00
return ( void * ) ( intptr_t ) context - > internal - > _debug_stderr ;
2006-06-16 02:23:02 +00:00
# else
2006-07-11 18:01:26 +00:00
return ( void * ) context - > internal - > _debug_stderr ;
2006-06-16 02:23:02 +00:00
# endif
r18009: Fixes bug 4026.
This completes the work Jeremy began last week, disambiguating the meaning of
c_time. (In POSIX terminology, c_time means "status Change time", not "create
time".) All uses of c_time, a_time and m_time have now been replaced with
change_time, access_time, and write_time, and when creation time is intended,
create_time is used.
Additionally, the capability of setting and retrieving the create time have
been added to the smbc_setxattr() and smbc_getxattr() functions. An example
of setting all four times can be seen with the program
examples/libsmbclient/testacl
with the following command line similar to:
testacl -f -S "system.*:CREATE_TIME:1000000000,ACCESS_TIME:1000000060,WRITE_TIME:1000000120,CHANGE_TIME:1000000180" 'smb://server/share/testfile.txt'
The -f option turns on the new mode which uses full time names in the
attribute specification (e.g. ACCESS_TIME vs A_TIME).
(This used to be commit 8e119b64f1d92026dda855d904be09912a40601c)
2006-09-02 21:47:56 +00:00
} else if ( strcmp ( option_name , " full_time_names " ) = = 0 ) {
/*
* Use new - style time attribute names , e . g . WRITE_TIME rather
* than the old - style names such as M_TIME . This allows also
* setting / getting CREATE_TIME which was previously
* unimplemented . ( Note that the old C_TIME was supposed to
* be CHANGE_TIME but was confused and sometimes referred to
* CREATE_TIME . )
*/
# if defined(__intptr_t_defined) || defined(HAVE_INTPTR_T)
return ( void * ) ( intptr_t ) context - > internal - > _full_time_names ;
# else
return ( void * ) context - > internal - > _full_time_names ;
# endif
2006-03-22 22:05:19 +00:00
} else if ( strcmp ( option_name , " auth_function " ) = = 0 ) {
/*
* Use the new - style authentication function which includes
* the context .
*/
return ( void * ) context - > internal - > _auth_fn_with_context ;
} else if ( strcmp ( option_name , " user_data " ) = = 0 ) {
/*
* Save a user data handle which may be retrieved by the user
* with smbc_option_get ( )
*/
return context - > internal - > _user_data ;
2005-12-29 16:26:06 +00:00
}
2006-03-22 22:05:19 +00:00
return NULL ;
2005-12-29 16:26:06 +00:00
}
2003-10-24 17:01:19 +00:00
/*
2007-11-30 13:09:04 -08:00
* Initialise the library etc
2003-10-24 17:01:19 +00:00
*
* We accept a struct containing handle information .
* valid values for info - > debug from 0 to 100 ,
* and insist that info - > fn must be non - null .
*/
2005-12-29 15:06:53 +00:00
SMBCCTX *
smbc_init_context ( SMBCCTX * context )
2003-10-24 17:01:19 +00:00
{
int pid ;
2005-12-29 15:06:53 +00:00
char * user = NULL ;
char * home = NULL ;
2003-10-24 17:01:19 +00:00
if ( ! context | | ! context - > internal ) {
errno = EBADF ;
return NULL ;
}
/* Do not initialise the same client twice */
2007-11-30 13:09:04 -08:00
if ( context - > internal - > _initialized ) {
2003-10-24 17:01:19 +00:00
return 0 ;
}
2006-03-22 22:05:19 +00:00
if ( ( ! context - > callbacks . auth_fn & &
! context - > internal - > _auth_fn_with_context ) | |
2005-12-29 15:06:53 +00:00
context - > debug < 0 | |
context - > debug > 100 ) {
2003-10-24 17:01:19 +00:00
errno = EINVAL ;
return NULL ;
}
if ( ! smbc_initialized ) {
2005-12-29 15:06:53 +00:00
/*
* Do some library - wide intializations the first time we get
* called
*/
2007-10-18 17:40:25 -07:00
bool conf_loaded = False ;
2007-11-30 14:19:55 -08:00
TALLOC_CTX * frame = talloc_stackframe ( ) ;
2003-10-24 17:01:19 +00:00
/* Set this to what the user wants */
DEBUGLEVEL = context - > debug ;
2007-11-30 13:09:04 -08:00
2005-12-29 15:06:59 +00:00
load_case_tables ( ) ;
2005-12-29 16:26:06 +00:00
setup_logging ( " libsmbclient " , True ) ;
if ( context - > internal - > _debug_stderr ) {
dbf = x_stderr ;
x_setbuf ( x_stderr , NULL ) ;
}
2003-10-24 17:01:19 +00:00
/* Here we would open the smb.conf file if needed ... */
2007-11-30 13:09:04 -08:00
2003-10-24 17:01:19 +00:00
in_client = True ; /* FIXME, make a param */
2005-10-13 18:08:25 +00:00
home = getenv ( " HOME " ) ;
if ( home ) {
2007-11-30 13:09:04 -08:00
char * conf = NULL ;
if ( asprintf ( & conf , " %s/.smb/smb.conf " , home ) > 0 ) {
if ( lp_load ( conf , True , False , False , True ) ) {
conf_loaded = True ;
} else {
DEBUG ( 5 , ( " Could not load config file: %s \n " ,
conf ) ) ;
}
SAFE_FREE ( conf ) ;
2005-10-13 18:08:25 +00:00
}
}
2007-11-30 13:09:04 -08:00
2005-10-13 18:08:25 +00:00
if ( ! conf_loaded ) {
2003-10-24 17:01:19 +00:00
/*
2007-12-10 11:30:37 -08:00
* Well , if that failed , try the get_dyn_CONFIGFILE
2003-10-24 17:01:19 +00:00
* Which points to the standard locn , and if that
* fails , silently ignore it and use the internal
* defaults . . .
*/
2007-12-10 11:30:37 -08:00
if ( ! lp_load ( get_dyn_CONFIGFILE ( ) , True , False , False , False ) ) {
2005-10-13 18:08:25 +00:00
DEBUG ( 5 , ( " Could not load config file: %s \n " ,
2007-12-10 11:30:37 -08:00
get_dyn_CONFIGFILE ( ) ) ) ;
2005-10-13 18:08:25 +00:00
} else if ( home ) {
2007-11-30 13:09:04 -08:00
char * conf ;
2005-03-31 20:28:47 +00:00
/*
* We loaded the global config file . Now lets
* load user - specific modifications to the
* global config .
*/
2007-11-30 13:09:04 -08:00
if ( asprintf ( & conf ,
" %s/.smb/smb.conf.append " ,
home ) > 0 ) {
if ( ! lp_load ( conf , True , False , False , False ) ) {
DEBUG ( 10 ,
( " Could not append config file: "
" %s \n " ,
conf ) ) ;
}
SAFE_FREE ( conf ) ;
}
2005-03-31 20:28:47 +00:00
}
2003-10-24 17:01:19 +00:00
}
2005-12-25 04:26:59 +00:00
load_interfaces ( ) ; /* Load the list of interfaces ... */
2007-11-30 13:09:04 -08:00
2003-10-24 17:01:19 +00:00
reopen_logs ( ) ; /* Get logging working ... */
2007-11-30 13:09:04 -08:00
/*
* Block SIGPIPE ( from lib / util_sock . c : write ( ) )
* It is not needed and should not stop execution
2003-10-24 17:01:19 +00:00
*/
BlockSignals ( True , SIGPIPE ) ;
2007-11-30 13:09:04 -08:00
2003-10-24 17:01:19 +00:00
/* Done with one-time initialisation */
2007-11-30 13:09:04 -08:00
smbc_initialized = 1 ;
2003-10-24 17:01:19 +00:00
2007-11-30 14:19:55 -08:00
TALLOC_FREE ( frame ) ;
2003-10-24 17:01:19 +00:00
}
2007-11-30 13:09:04 -08:00
2003-10-24 17:01:19 +00:00
if ( ! context - > user ) {
/*
2007-11-30 13:09:04 -08:00
* FIXME : Is this the best way to get the user info ?
2003-10-24 17:01:19 +00:00
*/
user = getenv ( " USER " ) ;
/* walk around as "guest" if no username can be found */
2004-12-07 18:25:53 +00:00
if ( ! user ) context - > user = SMB_STRDUP ( " guest " ) ;
else context - > user = SMB_STRDUP ( user ) ;
2003-10-24 17:01:19 +00:00
}
if ( ! context - > netbios_name ) {
/*
2005-12-29 15:06:53 +00:00
* We try to get our netbios name from the config . If that
* fails we fall back on constructing our netbios name from
* our hostname etc
2003-10-24 17:01:19 +00:00
*/
if ( global_myname ( ) ) {
2004-12-07 18:25:53 +00:00
context - > netbios_name = SMB_STRDUP ( global_myname ( ) ) ;
2003-10-24 17:01:19 +00:00
}
else {
/*
2005-12-29 15:06:53 +00:00
* Hmmm , I want to get hostname as well , but I am too
* lazy for the moment
2003-10-24 17:01:19 +00:00
*/
pid = sys_getpid ( ) ;
2006-07-31 03:53:39 +00:00
context - > netbios_name = ( char * ) SMB_MALLOC ( 17 ) ;
2003-10-24 17:01:19 +00:00
if ( ! context - > netbios_name ) {
errno = ENOMEM ;
return NULL ;
}
2005-12-29 15:06:53 +00:00
slprintf ( context - > netbios_name , 16 ,
" smbc%s%d " , context - > user , pid ) ;
2003-10-24 17:01:19 +00:00
}
}
DEBUG ( 1 , ( " Using netbios name %s. \n " , context - > netbios_name ) ) ;
if ( ! context - > workgroup ) {
if ( lp_workgroup ( ) ) {
2004-12-07 18:25:53 +00:00
context - > workgroup = SMB_STRDUP ( lp_workgroup ( ) ) ;
2003-10-24 17:01:19 +00:00
}
else {
/* TODO: Think about a decent default workgroup */
2004-12-07 18:25:53 +00:00
context - > workgroup = SMB_STRDUP ( " samba " ) ;
2003-10-24 17:01:19 +00:00
}
}
DEBUG ( 1 , ( " Using workgroup %s. \n " , context - > workgroup ) ) ;
2007-11-30 13:09:04 -08:00
2003-10-24 17:01:19 +00:00
/* shortest timeout is 1 second */
2007-11-30 13:09:04 -08:00
if ( context - > timeout > 0 & & context - > timeout < 1000 )
2003-10-24 17:01:19 +00:00
context - > timeout = 1000 ;
/*
2007-11-30 13:09:04 -08:00
* FIXME : Should we check the function pointers here ?
2003-10-24 17:01:19 +00:00
*/
2005-12-29 16:26:06 +00:00
context - > internal - > _initialized = True ;
2007-11-30 13:09:04 -08:00
2003-10-24 17:01:19 +00:00
return context ;
2001-02-05 13:02:20 +00:00
}
2005-03-10 23:41:19 +00:00
/* Return the verion of samba, and thus libsmbclient */
const char *
smbc_version ( void )
{
return samba_version_string ( ) ;
}