2009-07-11 02:35:08 +04:00
/*
Unix SMB / CIFS implementation .
Filename utility functions .
Copyright ( C ) Tim Prouty 2009
This program is free software ; you can redistribute it and / or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation ; either version 3 of the License , or
( at your option ) any later version .
This program is distributed in the hope that it will be useful ,
but WITHOUT ANY WARRANTY ; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
GNU General Public License for more details .
You should have received a copy of the GNU General Public License
along with this program . If not , see < http : //www.gnu.org/licenses/>.
*/
# include "includes.h"
/**
* XXX : This is temporary and there should be no callers of this outside of
* this file once smb_filename is plumbed through all path based operations .
* The one legitimate caller currently is smb_fname_str_dbg ( ) , which this
* could be made static for .
*/
NTSTATUS get_full_smb_filename ( TALLOC_CTX * ctx ,
const struct smb_filename * smb_fname ,
char * * full_name )
{
if ( smb_fname - > stream_name ) {
2009-07-21 01:32:32 +04:00
/* stream_name must always be NULL if there is no stream. */
SMB_ASSERT ( smb_fname - > stream_name [ 0 ] ! = ' \0 ' ) ;
2009-07-11 02:35:08 +04:00
* full_name = talloc_asprintf ( ctx , " %s%s " , smb_fname - > base_name ,
smb_fname - > stream_name ) ;
} else {
* full_name = talloc_strdup ( ctx , smb_fname - > base_name ) ;
}
if ( ! * full_name ) {
return NT_STATUS_NO_MEMORY ;
}
return NT_STATUS_OK ;
}
/**
* There are actually legitimate callers of this such as functions that
* enumerate streams using the SMB_VFS_STREAMINFO interface and then want to
* operate on each stream .
*/
NTSTATUS create_synthetic_smb_fname ( TALLOC_CTX * ctx , const char * base_name ,
const char * stream_name ,
const SMB_STRUCT_STAT * psbuf ,
struct smb_filename * * smb_fname_out )
{
struct smb_filename smb_fname_loc ;
ZERO_STRUCT ( smb_fname_loc ) ;
/* Setup the base_name/stream_name. */
2011-05-06 01:22:11 +04:00
smb_fname_loc . base_name = discard_const_p ( char , base_name ) ;
smb_fname_loc . stream_name = discard_const_p ( char , stream_name ) ;
2009-07-11 02:35:08 +04:00
/* Copy the psbuf if one was given. */
if ( psbuf )
smb_fname_loc . st = * psbuf ;
/* Let copy_smb_filename() do the heavy lifting. */
return copy_smb_filename ( ctx , & smb_fname_loc , smb_fname_out ) ;
}
/**
* XXX : This is temporary and there should be no callers of this once
* smb_filename is plumbed through all path based operations .
*/
NTSTATUS create_synthetic_smb_fname_split ( TALLOC_CTX * ctx ,
const char * fname ,
const SMB_STRUCT_STAT * psbuf ,
struct smb_filename * * smb_fname_out )
{
NTSTATUS status ;
const char * stream_name = NULL ;
char * base_name = NULL ;
if ( ! lp_posix_pathnames ( ) ) {
stream_name = strchr_m ( fname , ' : ' ) ;
}
/* Setup the base_name/stream_name. */
if ( stream_name ) {
base_name = talloc_strndup ( ctx , fname ,
PTR_DIFF ( stream_name , fname ) ) ;
} else {
base_name = talloc_strdup ( ctx , fname ) ;
}
if ( ! base_name ) {
return NT_STATUS_NO_MEMORY ;
}
status = create_synthetic_smb_fname ( ctx , base_name , stream_name , psbuf ,
smb_fname_out ) ;
TALLOC_FREE ( base_name ) ;
return status ;
}
/**
2009-11-03 12:59:18 +03:00
* Return a string using the talloc_tos ( )
2009-07-11 02:35:08 +04:00
*/
const char * smb_fname_str_dbg ( const struct smb_filename * smb_fname )
{
char * fname = NULL ;
NTSTATUS status ;
if ( smb_fname = = NULL ) {
return " " ;
}
2009-11-03 12:59:18 +03:00
status = get_full_smb_filename ( talloc_tos ( ) , smb_fname , & fname ) ;
2009-07-11 02:35:08 +04:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
return " " ;
}
return fname ;
}
/**
2009-11-03 12:59:18 +03:00
* Return a debug string using the talloc_tos ( ) . This can only be called from
2009-07-11 02:35:08 +04:00
* DEBUG ( ) macros due to the debut_ctx ( ) .
*/
const char * fsp_str_dbg ( const struct files_struct * fsp )
{
return smb_fname_str_dbg ( fsp - > fsp_name ) ;
}
NTSTATUS copy_smb_filename ( TALLOC_CTX * ctx ,
const struct smb_filename * smb_fname_in ,
struct smb_filename * * smb_fname_out )
{
2009-07-21 01:32:32 +04:00
/* stream_name must always be NULL if there is no stream. */
if ( smb_fname_in - > stream_name ) {
SMB_ASSERT ( smb_fname_in - > stream_name [ 0 ] ! = ' \0 ' ) ;
}
2009-07-11 02:35:08 +04:00
* smb_fname_out = talloc_zero ( ctx , struct smb_filename ) ;
if ( * smb_fname_out = = NULL ) {
return NT_STATUS_NO_MEMORY ;
}
if ( smb_fname_in - > base_name ) {
( * smb_fname_out ) - > base_name =
talloc_strdup ( * smb_fname_out , smb_fname_in - > base_name ) ;
if ( ! ( * smb_fname_out ) - > base_name )
goto no_mem_err ;
}
if ( smb_fname_in - > stream_name ) {
( * smb_fname_out ) - > stream_name =
talloc_strdup ( * smb_fname_out , smb_fname_in - > stream_name ) ;
if ( ! ( * smb_fname_out ) - > stream_name )
goto no_mem_err ;
}
if ( smb_fname_in - > original_lcomp ) {
( * smb_fname_out ) - > original_lcomp =
talloc_strdup ( * smb_fname_out , smb_fname_in - > original_lcomp ) ;
if ( ! ( * smb_fname_out ) - > original_lcomp )
goto no_mem_err ;
}
( * smb_fname_out ) - > st = smb_fname_in - > st ;
return NT_STATUS_OK ;
no_mem_err :
TALLOC_FREE ( * smb_fname_out ) ;
return NT_STATUS_NO_MEMORY ;
}
/****************************************************************************
Simple check to determine if the filename is a stream .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
bool is_ntfs_stream_smb_fname ( const struct smb_filename * smb_fname )
{
2009-07-21 01:32:32 +04:00
/* stream_name must always be NULL if there is no stream. */
if ( smb_fname - > stream_name ) {
SMB_ASSERT ( smb_fname - > stream_name [ 0 ] ! = ' \0 ' ) ;
}
2009-07-11 02:35:08 +04:00
if ( lp_posix_pathnames ( ) ) {
return false ;
}
2009-09-18 05:34:55 +04:00
return smb_fname - > stream_name ! = NULL ;
2009-07-11 02:35:08 +04:00
}
/****************************************************************************
Returns true if the filename ' s stream = = " ::$DATA "
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
bool is_ntfs_default_stream_smb_fname ( const struct smb_filename * smb_fname )
{
if ( ! is_ntfs_stream_smb_fname ( smb_fname ) ) {
return false ;
}
2011-05-13 22:21:30 +04:00
return strcasecmp_m ( smb_fname - > stream_name , " ::$DATA " ) = = 0 ;
2009-07-11 02:35:08 +04:00
}