2007-08-31 01:46:42 +04:00
/*
2002-01-30 09:08:46 +03:00
Unix SMB / CIFS implementation .
1998-08-17 11:40:06 +04:00
filename handling routines
Copyright ( C ) Andrew Tridgell 1992 - 1998
2007-09-08 00:57:01 +04:00
Copyright ( C ) Jeremy Allison 1999 - 2007
2000-01-27 00:25:35 +03:00
Copyright ( C ) Ying Chen 2000
2007-07-12 02:39:11 +04:00
Copyright ( C ) Volker Lendecke 2007
2007-08-31 01:46:42 +04:00
1998-08-17 11:40:06 +04: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 23:25:36 +04:00
the Free Software Foundation ; either version 3 of the License , or
1998-08-17 11:40:06 +04:00
( at your option ) any later version .
2007-08-31 01:46:42 +04:00
1998-08-17 11:40:06 +04:00
This program is distributed in the hope that it will be useful ,
but WITHOUT ANY WARRANTY ; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
GNU General Public License for more details .
2007-08-31 01:46:42 +04:00
1998-08-17 11:40:06 +04:00
You should have received a copy of the GNU General Public License
2007-07-10 04:52:41 +04:00
along with this program . If not , see < http : //www.gnu.org/licenses/>.
1998-08-17 11:40:06 +04:00
*/
2000-01-27 00:25:35 +03:00
/*
* New hash table stat cache code added by Ying Chen .
*/
1998-08-17 11:40:06 +04:00
# include "includes.h"
2008-01-20 01:25:36 +03:00
static NTSTATUS build_stream_path ( TALLOC_CTX * mem_ctx ,
connection_struct * conn ,
const char * orig_path ,
s3: Change unix_convert (and its callers) to use struct smb_filename
This is the first of a series of patches that change path based
operations to operate on a struct smb_filename instead of a char *.
This same concept already exists in source4.
My goals for this series of patches are to eventually:
1) Solve the stream vs. posix filename that contains a colon ambiguity
that currently exists.
2) Make unix_convert the only function that parses the stream name.
3) Clean up the unix_convert API.
4) Change all path based vfs operation to take a struct smb_filename.
5) Make is_ntfs_stream_name() a constant operation that can simply
check the state of struct smb_filename rather than re-parse the
filename.
6) Eliminate the need for split_ntfs_stream_name() to exist.
My strategy is to start from the inside at unix_convert() and work my
way out through the vfs layer, call by call. This first patch does
just that, by changing unix_convert and all of its callers to operate
on struct smb_filename. Since this is such a large change, I plan on
pushing the patches in phases, where each phase keeps full
compatibility and passes make test.
The API of unix_convert has been simplified from:
NTSTATUS unix_convert(TALLOC_CTX *ctx,
connection_struct *conn,
const char *orig_path,
bool allow_wcard_last_component,
char **pp_conv_path,
char **pp_saved_last_component,
SMB_STRUCT_STAT *pst)
to:
NTSTATUS unix_convert(TALLOC_CTX *ctx,
connection_struct *conn,
const char *orig_path,
struct smb_filename *smb_fname,
uint32_t ucf_flags)
Currently the smb_filename struct looks like:
struct smb_filename {
char *base_name;
char *stream_name;
char *original_lcomp;
SMB_STRUCT_STAT st;
};
One key point here is the decision to break up the base_name and
stream_name. I have introduced a helper function called
get_full_smb_filename() that takes an smb_filename struct and
allocates the full_name. I changed the callers of unix_convert() to
subsequently call get_full_smb_filename() for the time being, but I
plan to eventually eliminate get_full_smb_filename().
2009-04-08 00:39:57 +04:00
struct smb_filename * smb_fname ) ;
1998-08-17 11:40:06 +04:00
/****************************************************************************
1998-08-28 00:38:53 +04:00
Mangle the 2 nd name and check if it is then equal to the first name .
1998-08-17 11:40:06 +04:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2002-07-15 14:35:28 +04:00
2007-10-19 04:40:25 +04:00
static bool mangled_equal ( const char * name1 ,
2007-08-31 01:46:42 +04:00
const char * name2 ,
const struct share_params * p )
1998-08-17 11:40:06 +04:00
{
2007-09-08 00:57:01 +04:00
char mname [ 13 ] ;
2007-08-31 01:46:42 +04:00
2007-09-08 00:57:01 +04:00
if ( ! name_to_8_3 ( name2 , mname , False , p ) ) {
return False ;
}
return strequal ( name1 , mname ) ;
1998-08-17 11:40:06 +04:00
}
2007-01-13 04:29:10 +03:00
/****************************************************************************
Cope with the differing wildcard and non - wildcard error cases .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2007-08-31 01:46:42 +04:00
static NTSTATUS determine_path_error ( const char * name ,
2007-10-19 04:40:25 +04:00
bool allow_wcard_last_component )
2007-01-13 04:29:10 +03:00
{
const char * p ;
if ( ! allow_wcard_last_component ) {
/* Error code within a pathname. */
return NT_STATUS_OBJECT_PATH_NOT_FOUND ;
}
/* We're terminating here so we
* can be a little slower and get
* the error code right . Windows
* treats the last part of the pathname
* separately I think , so if the last
* component is a wildcard then we treat
* this . / as " end of component " */
p = strchr ( name , ' / ' ) ;
if ( ! p & & ( ms_has_wild ( name ) | | ISDOT ( name ) ) ) {
/* Error code at the end of a pathname. */
return NT_STATUS_OBJECT_NAME_INVALID ;
} else {
/* Error code within a pathname. */
return NT_STATUS_OBJECT_PATH_NOT_FOUND ;
}
}
2007-08-31 01:46:42 +04:00
1998-08-17 11:40:06 +04:00
/****************************************************************************
This routine is called to convert names from the dos namespace to unix
s3: Change unix_convert (and its callers) to use struct smb_filename
This is the first of a series of patches that change path based
operations to operate on a struct smb_filename instead of a char *.
This same concept already exists in source4.
My goals for this series of patches are to eventually:
1) Solve the stream vs. posix filename that contains a colon ambiguity
that currently exists.
2) Make unix_convert the only function that parses the stream name.
3) Clean up the unix_convert API.
4) Change all path based vfs operation to take a struct smb_filename.
5) Make is_ntfs_stream_name() a constant operation that can simply
check the state of struct smb_filename rather than re-parse the
filename.
6) Eliminate the need for split_ntfs_stream_name() to exist.
My strategy is to start from the inside at unix_convert() and work my
way out through the vfs layer, call by call. This first patch does
just that, by changing unix_convert and all of its callers to operate
on struct smb_filename. Since this is such a large change, I plan on
pushing the patches in phases, where each phase keeps full
compatibility and passes make test.
The API of unix_convert has been simplified from:
NTSTATUS unix_convert(TALLOC_CTX *ctx,
connection_struct *conn,
const char *orig_path,
bool allow_wcard_last_component,
char **pp_conv_path,
char **pp_saved_last_component,
SMB_STRUCT_STAT *pst)
to:
NTSTATUS unix_convert(TALLOC_CTX *ctx,
connection_struct *conn,
const char *orig_path,
struct smb_filename *smb_fname,
uint32_t ucf_flags)
Currently the smb_filename struct looks like:
struct smb_filename {
char *base_name;
char *stream_name;
char *original_lcomp;
SMB_STRUCT_STAT st;
};
One key point here is the decision to break up the base_name and
stream_name. I have introduced a helper function called
get_full_smb_filename() that takes an smb_filename struct and
allocates the full_name. I changed the callers of unix_convert() to
subsequently call get_full_smb_filename() for the time being, but I
plan to eventually eliminate get_full_smb_filename().
2009-04-08 00:39:57 +04:00
namespace . It needs to handle any case conversions , mangling , format changes ,
streams etc .
1998-08-17 11:40:06 +04:00
We assume that we have already done a chdir ( ) to the right " root " directory
for this service .
2007-08-31 01:46:42 +04:00
The function will return an NTSTATUS error if some part of the name except for
the last part cannot be resolved , else NT_STATUS_OK .
2007-01-13 02:47:16 +03:00
s3: Change unix_convert (and its callers) to use struct smb_filename
This is the first of a series of patches that change path based
operations to operate on a struct smb_filename instead of a char *.
This same concept already exists in source4.
My goals for this series of patches are to eventually:
1) Solve the stream vs. posix filename that contains a colon ambiguity
that currently exists.
2) Make unix_convert the only function that parses the stream name.
3) Clean up the unix_convert API.
4) Change all path based vfs operation to take a struct smb_filename.
5) Make is_ntfs_stream_name() a constant operation that can simply
check the state of struct smb_filename rather than re-parse the
filename.
6) Eliminate the need for split_ntfs_stream_name() to exist.
My strategy is to start from the inside at unix_convert() and work my
way out through the vfs layer, call by call. This first patch does
just that, by changing unix_convert and all of its callers to operate
on struct smb_filename. Since this is such a large change, I plan on
pushing the patches in phases, where each phase keeps full
compatibility and passes make test.
The API of unix_convert has been simplified from:
NTSTATUS unix_convert(TALLOC_CTX *ctx,
connection_struct *conn,
const char *orig_path,
bool allow_wcard_last_component,
char **pp_conv_path,
char **pp_saved_last_component,
SMB_STRUCT_STAT *pst)
to:
NTSTATUS unix_convert(TALLOC_CTX *ctx,
connection_struct *conn,
const char *orig_path,
struct smb_filename *smb_fname,
uint32_t ucf_flags)
Currently the smb_filename struct looks like:
struct smb_filename {
char *base_name;
char *stream_name;
char *original_lcomp;
SMB_STRUCT_STAT st;
};
One key point here is the decision to break up the base_name and
stream_name. I have introduced a helper function called
get_full_smb_filename() that takes an smb_filename struct and
allocates the full_name. I changed the callers of unix_convert() to
subsequently call get_full_smb_filename() for the time being, but I
plan to eventually eliminate get_full_smb_filename().
2009-04-08 00:39:57 +04:00
Note NT_STATUS_OK doesn ' t mean the name exists or is valid , just that we
didn ' t get any fatal errors that should immediately terminate the calling SMB
processing whilst resolving .
1998-08-17 11:40:06 +04:00
s3: Change unix_convert (and its callers) to use struct smb_filename
This is the first of a series of patches that change path based
operations to operate on a struct smb_filename instead of a char *.
This same concept already exists in source4.
My goals for this series of patches are to eventually:
1) Solve the stream vs. posix filename that contains a colon ambiguity
that currently exists.
2) Make unix_convert the only function that parses the stream name.
3) Clean up the unix_convert API.
4) Change all path based vfs operation to take a struct smb_filename.
5) Make is_ntfs_stream_name() a constant operation that can simply
check the state of struct smb_filename rather than re-parse the
filename.
6) Eliminate the need for split_ntfs_stream_name() to exist.
My strategy is to start from the inside at unix_convert() and work my
way out through the vfs layer, call by call. This first patch does
just that, by changing unix_convert and all of its callers to operate
on struct smb_filename. Since this is such a large change, I plan on
pushing the patches in phases, where each phase keeps full
compatibility and passes make test.
The API of unix_convert has been simplified from:
NTSTATUS unix_convert(TALLOC_CTX *ctx,
connection_struct *conn,
const char *orig_path,
bool allow_wcard_last_component,
char **pp_conv_path,
char **pp_saved_last_component,
SMB_STRUCT_STAT *pst)
to:
NTSTATUS unix_convert(TALLOC_CTX *ctx,
connection_struct *conn,
const char *orig_path,
struct smb_filename *smb_fname,
uint32_t ucf_flags)
Currently the smb_filename struct looks like:
struct smb_filename {
char *base_name;
char *stream_name;
char *original_lcomp;
SMB_STRUCT_STAT st;
};
One key point here is the decision to break up the base_name and
stream_name. I have introduced a helper function called
get_full_smb_filename() that takes an smb_filename struct and
allocates the full_name. I changed the callers of unix_convert() to
subsequently call get_full_smb_filename() for the time being, but I
plan to eventually eliminate get_full_smb_filename().
2009-04-08 00:39:57 +04:00
If the UCF_SAVE_LCOMP flag is passed in , then the unmodified last component
of the pathname is set in smb_filename - > original_lcomp .
1998-08-17 11:40:06 +04:00
2009-07-25 05:38:40 +04:00
If UCF_ALWAYS_ALLOW_WCARD_LCOMP is passed in , then a MS wildcard was detected
and should be allowed in the last component of the path only .
2000-10-19 06:58:24 +04:00
s3: Change unix_convert (and its callers) to use struct smb_filename
This is the first of a series of patches that change path based
operations to operate on a struct smb_filename instead of a char *.
This same concept already exists in source4.
My goals for this series of patches are to eventually:
1) Solve the stream vs. posix filename that contains a colon ambiguity
that currently exists.
2) Make unix_convert the only function that parses the stream name.
3) Clean up the unix_convert API.
4) Change all path based vfs operation to take a struct smb_filename.
5) Make is_ntfs_stream_name() a constant operation that can simply
check the state of struct smb_filename rather than re-parse the
filename.
6) Eliminate the need for split_ntfs_stream_name() to exist.
My strategy is to start from the inside at unix_convert() and work my
way out through the vfs layer, call by call. This first patch does
just that, by changing unix_convert and all of its callers to operate
on struct smb_filename. Since this is such a large change, I plan on
pushing the patches in phases, where each phase keeps full
compatibility and passes make test.
The API of unix_convert has been simplified from:
NTSTATUS unix_convert(TALLOC_CTX *ctx,
connection_struct *conn,
const char *orig_path,
bool allow_wcard_last_component,
char **pp_conv_path,
char **pp_saved_last_component,
SMB_STRUCT_STAT *pst)
to:
NTSTATUS unix_convert(TALLOC_CTX *ctx,
connection_struct *conn,
const char *orig_path,
struct smb_filename *smb_fname,
uint32_t ucf_flags)
Currently the smb_filename struct looks like:
struct smb_filename {
char *base_name;
char *stream_name;
char *original_lcomp;
SMB_STRUCT_STAT st;
};
One key point here is the decision to break up the base_name and
stream_name. I have introduced a helper function called
get_full_smb_filename() that takes an smb_filename struct and
allocates the full_name. I changed the callers of unix_convert() to
subsequently call get_full_smb_filename() for the time being, but I
plan to eventually eliminate get_full_smb_filename().
2009-04-08 00:39:57 +04:00
If the orig_path was a stream , smb_filename - > base_name will point to the base
filename , and smb_filename - > stream_name will point to the stream name . If
orig_path was not a stream , then smb_filename - > stream_name will be NULL .
On exit from unix_convert , the smb_filename - > st stat struct will be populated
if the file exists and was found , if not this stat struct will be filled with
zeros ( and this can be detected by checking for nlinks = 0 , which can never be
true for any file ) .
1998-08-17 11:40:06 +04:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
1999-12-13 16:27:58 +03:00
2007-09-14 02:08:59 +04:00
NTSTATUS unix_convert ( TALLOC_CTX * ctx ,
s3: Change unix_convert (and its callers) to use struct smb_filename
This is the first of a series of patches that change path based
operations to operate on a struct smb_filename instead of a char *.
This same concept already exists in source4.
My goals for this series of patches are to eventually:
1) Solve the stream vs. posix filename that contains a colon ambiguity
that currently exists.
2) Make unix_convert the only function that parses the stream name.
3) Clean up the unix_convert API.
4) Change all path based vfs operation to take a struct smb_filename.
5) Make is_ntfs_stream_name() a constant operation that can simply
check the state of struct smb_filename rather than re-parse the
filename.
6) Eliminate the need for split_ntfs_stream_name() to exist.
My strategy is to start from the inside at unix_convert() and work my
way out through the vfs layer, call by call. This first patch does
just that, by changing unix_convert and all of its callers to operate
on struct smb_filename. Since this is such a large change, I plan on
pushing the patches in phases, where each phase keeps full
compatibility and passes make test.
The API of unix_convert has been simplified from:
NTSTATUS unix_convert(TALLOC_CTX *ctx,
connection_struct *conn,
const char *orig_path,
bool allow_wcard_last_component,
char **pp_conv_path,
char **pp_saved_last_component,
SMB_STRUCT_STAT *pst)
to:
NTSTATUS unix_convert(TALLOC_CTX *ctx,
connection_struct *conn,
const char *orig_path,
struct smb_filename *smb_fname,
uint32_t ucf_flags)
Currently the smb_filename struct looks like:
struct smb_filename {
char *base_name;
char *stream_name;
char *original_lcomp;
SMB_STRUCT_STAT st;
};
One key point here is the decision to break up the base_name and
stream_name. I have introduced a helper function called
get_full_smb_filename() that takes an smb_filename struct and
allocates the full_name. I changed the callers of unix_convert() to
subsequently call get_full_smb_filename() for the time being, but I
plan to eventually eliminate get_full_smb_filename().
2009-04-08 00:39:57 +04:00
connection_struct * conn ,
const char * orig_path ,
struct smb_filename * * smb_fname_out ,
uint32_t ucf_flags )
1998-08-17 11:40:06 +04:00
{
s3: Change unix_convert (and its callers) to use struct smb_filename
This is the first of a series of patches that change path based
operations to operate on a struct smb_filename instead of a char *.
This same concept already exists in source4.
My goals for this series of patches are to eventually:
1) Solve the stream vs. posix filename that contains a colon ambiguity
that currently exists.
2) Make unix_convert the only function that parses the stream name.
3) Clean up the unix_convert API.
4) Change all path based vfs operation to take a struct smb_filename.
5) Make is_ntfs_stream_name() a constant operation that can simply
check the state of struct smb_filename rather than re-parse the
filename.
6) Eliminate the need for split_ntfs_stream_name() to exist.
My strategy is to start from the inside at unix_convert() and work my
way out through the vfs layer, call by call. This first patch does
just that, by changing unix_convert and all of its callers to operate
on struct smb_filename. Since this is such a large change, I plan on
pushing the patches in phases, where each phase keeps full
compatibility and passes make test.
The API of unix_convert has been simplified from:
NTSTATUS unix_convert(TALLOC_CTX *ctx,
connection_struct *conn,
const char *orig_path,
bool allow_wcard_last_component,
char **pp_conv_path,
char **pp_saved_last_component,
SMB_STRUCT_STAT *pst)
to:
NTSTATUS unix_convert(TALLOC_CTX *ctx,
connection_struct *conn,
const char *orig_path,
struct smb_filename *smb_fname,
uint32_t ucf_flags)
Currently the smb_filename struct looks like:
struct smb_filename {
char *base_name;
char *stream_name;
char *original_lcomp;
SMB_STRUCT_STAT st;
};
One key point here is the decision to break up the base_name and
stream_name. I have introduced a helper function called
get_full_smb_filename() that takes an smb_filename struct and
allocates the full_name. I changed the callers of unix_convert() to
subsequently call get_full_smb_filename() for the time being, but I
plan to eventually eliminate get_full_smb_filename().
2009-04-08 00:39:57 +04:00
struct smb_filename * smb_fname = NULL ;
2002-07-15 14:35:28 +04:00
char * start , * end ;
2007-07-12 02:39:11 +04:00
char * dirpath = NULL ;
2008-01-20 01:25:36 +03:00
char * stream = NULL ;
2007-10-19 04:40:25 +04:00
bool component_was_mangled = False ;
bool name_has_wildcard = False ;
2009-02-05 03:33:52 +03:00
bool posix_pathnames = false ;
2009-07-25 05:38:40 +04:00
bool allow_wcard_last_component =
( ucf_flags & UCF_ALWAYS_ALLOW_WCARD_LCOMP ) ;
s3: Change unix_convert (and its callers) to use struct smb_filename
This is the first of a series of patches that change path based
operations to operate on a struct smb_filename instead of a char *.
This same concept already exists in source4.
My goals for this series of patches are to eventually:
1) Solve the stream vs. posix filename that contains a colon ambiguity
that currently exists.
2) Make unix_convert the only function that parses the stream name.
3) Clean up the unix_convert API.
4) Change all path based vfs operation to take a struct smb_filename.
5) Make is_ntfs_stream_name() a constant operation that can simply
check the state of struct smb_filename rather than re-parse the
filename.
6) Eliminate the need for split_ntfs_stream_name() to exist.
My strategy is to start from the inside at unix_convert() and work my
way out through the vfs layer, call by call. This first patch does
just that, by changing unix_convert and all of its callers to operate
on struct smb_filename. Since this is such a large change, I plan on
pushing the patches in phases, where each phase keeps full
compatibility and passes make test.
The API of unix_convert has been simplified from:
NTSTATUS unix_convert(TALLOC_CTX *ctx,
connection_struct *conn,
const char *orig_path,
bool allow_wcard_last_component,
char **pp_conv_path,
char **pp_saved_last_component,
SMB_STRUCT_STAT *pst)
to:
NTSTATUS unix_convert(TALLOC_CTX *ctx,
connection_struct *conn,
const char *orig_path,
struct smb_filename *smb_fname,
uint32_t ucf_flags)
Currently the smb_filename struct looks like:
struct smb_filename {
char *base_name;
char *stream_name;
char *original_lcomp;
SMB_STRUCT_STAT st;
};
One key point here is the decision to break up the base_name and
stream_name. I have introduced a helper function called
get_full_smb_filename() that takes an smb_filename struct and
allocates the full_name. I changed the callers of unix_convert() to
subsequently call get_full_smb_filename() for the time being, but I
plan to eventually eliminate get_full_smb_filename().
2009-04-08 00:39:57 +04:00
bool save_last_component = ucf_flags & UCF_SAVE_LCOMP ;
2009-07-22 20:52:09 +04:00
NTSTATUS status ;
2009-02-05 03:33:52 +03:00
int ret = - 1 ;
2002-07-15 14:35:28 +04:00
s3: Change unix_convert (and its callers) to use struct smb_filename
This is the first of a series of patches that change path based
operations to operate on a struct smb_filename instead of a char *.
This same concept already exists in source4.
My goals for this series of patches are to eventually:
1) Solve the stream vs. posix filename that contains a colon ambiguity
that currently exists.
2) Make unix_convert the only function that parses the stream name.
3) Clean up the unix_convert API.
4) Change all path based vfs operation to take a struct smb_filename.
5) Make is_ntfs_stream_name() a constant operation that can simply
check the state of struct smb_filename rather than re-parse the
filename.
6) Eliminate the need for split_ntfs_stream_name() to exist.
My strategy is to start from the inside at unix_convert() and work my
way out through the vfs layer, call by call. This first patch does
just that, by changing unix_convert and all of its callers to operate
on struct smb_filename. Since this is such a large change, I plan on
pushing the patches in phases, where each phase keeps full
compatibility and passes make test.
The API of unix_convert has been simplified from:
NTSTATUS unix_convert(TALLOC_CTX *ctx,
connection_struct *conn,
const char *orig_path,
bool allow_wcard_last_component,
char **pp_conv_path,
char **pp_saved_last_component,
SMB_STRUCT_STAT *pst)
to:
NTSTATUS unix_convert(TALLOC_CTX *ctx,
connection_struct *conn,
const char *orig_path,
struct smb_filename *smb_fname,
uint32_t ucf_flags)
Currently the smb_filename struct looks like:
struct smb_filename {
char *base_name;
char *stream_name;
char *original_lcomp;
SMB_STRUCT_STAT st;
};
One key point here is the decision to break up the base_name and
stream_name. I have introduced a helper function called
get_full_smb_filename() that takes an smb_filename struct and
allocates the full_name. I changed the callers of unix_convert() to
subsequently call get_full_smb_filename() for the time being, but I
plan to eventually eliminate get_full_smb_filename().
2009-04-08 00:39:57 +04:00
* smb_fname_out = NULL ;
2009-07-22 20:52:09 +04:00
smb_fname = talloc_zero ( ctx , struct smb_filename ) ;
s3: Change unix_convert (and its callers) to use struct smb_filename
This is the first of a series of patches that change path based
operations to operate on a struct smb_filename instead of a char *.
This same concept already exists in source4.
My goals for this series of patches are to eventually:
1) Solve the stream vs. posix filename that contains a colon ambiguity
that currently exists.
2) Make unix_convert the only function that parses the stream name.
3) Clean up the unix_convert API.
4) Change all path based vfs operation to take a struct smb_filename.
5) Make is_ntfs_stream_name() a constant operation that can simply
check the state of struct smb_filename rather than re-parse the
filename.
6) Eliminate the need for split_ntfs_stream_name() to exist.
My strategy is to start from the inside at unix_convert() and work my
way out through the vfs layer, call by call. This first patch does
just that, by changing unix_convert and all of its callers to operate
on struct smb_filename. Since this is such a large change, I plan on
pushing the patches in phases, where each phase keeps full
compatibility and passes make test.
The API of unix_convert has been simplified from:
NTSTATUS unix_convert(TALLOC_CTX *ctx,
connection_struct *conn,
const char *orig_path,
bool allow_wcard_last_component,
char **pp_conv_path,
char **pp_saved_last_component,
SMB_STRUCT_STAT *pst)
to:
NTSTATUS unix_convert(TALLOC_CTX *ctx,
connection_struct *conn,
const char *orig_path,
struct smb_filename *smb_fname,
uint32_t ucf_flags)
Currently the smb_filename struct looks like:
struct smb_filename {
char *base_name;
char *stream_name;
char *original_lcomp;
SMB_STRUCT_STAT st;
};
One key point here is the decision to break up the base_name and
stream_name. I have introduced a helper function called
get_full_smb_filename() that takes an smb_filename struct and
allocates the full_name. I changed the callers of unix_convert() to
subsequently call get_full_smb_filename() for the time being, but I
plan to eventually eliminate get_full_smb_filename().
2009-04-08 00:39:57 +04:00
if ( smb_fname = = NULL ) {
return NT_STATUS_NO_MEMORY ;
2007-01-13 02:47:16 +03:00
}
2002-07-15 14:35:28 +04:00
if ( conn - > printer ) {
/* we don't ever use the filenames on a printer share as a
filename - so don ' t convert them */
s3: Change unix_convert (and its callers) to use struct smb_filename
This is the first of a series of patches that change path based
operations to operate on a struct smb_filename instead of a char *.
This same concept already exists in source4.
My goals for this series of patches are to eventually:
1) Solve the stream vs. posix filename that contains a colon ambiguity
that currently exists.
2) Make unix_convert the only function that parses the stream name.
3) Clean up the unix_convert API.
4) Change all path based vfs operation to take a struct smb_filename.
5) Make is_ntfs_stream_name() a constant operation that can simply
check the state of struct smb_filename rather than re-parse the
filename.
6) Eliminate the need for split_ntfs_stream_name() to exist.
My strategy is to start from the inside at unix_convert() and work my
way out through the vfs layer, call by call. This first patch does
just that, by changing unix_convert and all of its callers to operate
on struct smb_filename. Since this is such a large change, I plan on
pushing the patches in phases, where each phase keeps full
compatibility and passes make test.
The API of unix_convert has been simplified from:
NTSTATUS unix_convert(TALLOC_CTX *ctx,
connection_struct *conn,
const char *orig_path,
bool allow_wcard_last_component,
char **pp_conv_path,
char **pp_saved_last_component,
SMB_STRUCT_STAT *pst)
to:
NTSTATUS unix_convert(TALLOC_CTX *ctx,
connection_struct *conn,
const char *orig_path,
struct smb_filename *smb_fname,
uint32_t ucf_flags)
Currently the smb_filename struct looks like:
struct smb_filename {
char *base_name;
char *stream_name;
char *original_lcomp;
SMB_STRUCT_STAT st;
};
One key point here is the decision to break up the base_name and
stream_name. I have introduced a helper function called
get_full_smb_filename() that takes an smb_filename struct and
allocates the full_name. I changed the callers of unix_convert() to
subsequently call get_full_smb_filename() for the time being, but I
plan to eventually eliminate get_full_smb_filename().
2009-04-08 00:39:57 +04:00
if ( ! ( smb_fname - > base_name = talloc_strdup ( smb_fname ,
orig_path ) ) ) {
2009-07-22 20:52:09 +04:00
status = NT_STATUS_NO_MEMORY ;
goto err ;
2007-09-08 00:57:01 +04:00
}
2009-07-22 20:52:09 +04:00
goto done ;
2002-07-15 14:35:28 +04:00
}
2007-07-12 02:39:11 +04:00
DEBUG ( 5 , ( " unix_convert called on file \" %s \" \n " , orig_path ) ) ;
2002-07-15 14:35:28 +04:00
2007-07-12 02:39:11 +04:00
/*
2007-08-31 01:46:42 +04:00
* Conversion to basic unix format is already done in
* check_path_syntax ( ) .
2002-07-15 14:35:28 +04:00
*/
2007-07-12 02:39:11 +04:00
/*
2004-03-03 23:55:59 +03:00
* Names must be relative to the root of the service - any leading / .
* and trailing / ' s should have been trimmed by check_path_syntax ( ) .
2002-07-15 14:35:28 +04:00
*/
2004-03-03 23:55:59 +03:00
# ifdef DEVELOPER
2007-07-12 02:39:11 +04:00
SMB_ASSERT ( * orig_path ! = ' / ' ) ;
2004-03-03 23:55:59 +03:00
# endif
2002-07-15 14:35:28 +04:00
/*
* If we trimmed down to a single ' \0 ' character
* then we should use the " . " directory to avoid
* searching the cache , but not if we are in a
* printing share .
2004-03-03 23:55:59 +03:00
* As we know this is valid we can return true here .
2002-07-15 14:35:28 +04:00
*/
2007-07-12 02:39:11 +04:00
if ( ! * orig_path ) {
2009-07-22 20:52:09 +04:00
if ( ! ( smb_fname - > base_name = talloc_strdup ( smb_fname , " . " ) ) ) {
status = NT_STATUS_NO_MEMORY ;
goto err ;
2007-07-12 02:39:11 +04:00
}
2009-07-22 20:52:09 +04:00
if ( SMB_VFS_STAT ( conn , smb_fname ) ! = 0 ) {
status = map_nt_error_from_unix ( errno ) ;
goto err ;
2004-05-14 05:22:17 +04:00
}
2009-07-22 20:52:09 +04:00
DEBUG ( 5 , ( " conversion finished \" \" -> %s \n " ,
smb_fname - > base_name ) ) ;
2007-07-12 02:39:11 +04:00
goto done ;
2007-01-13 02:47:16 +03:00
}
2007-08-31 01:46:42 +04:00
if ( orig_path [ 0 ] = = ' . ' & & ( orig_path [ 1 ] = = ' / ' | |
orig_path [ 1 ] = = ' \0 ' ) ) {
2007-01-13 02:47:16 +03:00
/* Start of pathname can't be "." only. */
2007-07-12 02:39:11 +04:00
if ( orig_path [ 1 ] = = ' \0 ' | | orig_path [ 2 ] = = ' \0 ' ) {
2009-07-22 20:52:09 +04:00
status = NT_STATUS_OBJECT_NAME_INVALID ;
2007-01-13 04:07:39 +03:00
} else {
2009-07-22 20:52:09 +04:00
status = determine_path_error ( & orig_path [ 2 ] ,
allow_wcard_last_component ) ;
2007-01-13 04:07:39 +03:00
}
2009-07-22 20:52:09 +04:00
goto err ;
2002-07-15 14:35:28 +04:00
}
2009-07-22 20:52:09 +04:00
/* Start with the full orig_path as given by the caller. */
if ( ! ( smb_fname - > base_name = talloc_strdup ( smb_fname , orig_path ) ) ) {
2008-11-18 21:57:54 +03:00
DEBUG ( 0 , ( " talloc_strdup failed \n " ) ) ;
2009-07-22 20:52:09 +04:00
status = NT_STATUS_NO_MEMORY ;
goto err ;
2008-11-18 21:57:54 +03:00
}
/*
* Large directory fix normalization . If we ' re case sensitive , and
* the case preserving parameters are set to " no " , normalize the case of
* the incoming filename from the client WHETHER IT EXISTS OR NOT !
* This is in conflict with the current ( 3.0 .20 ) man page , but is
* what people expect from the " large directory howto " . I ' ll update
* the man page . Thanks to jht @ samba . org for finding this . JRA .
*/
if ( conn - > case_sensitive & & ! conn - > case_preserve & &
! conn - > short_case_preserve ) {
2009-07-22 20:52:09 +04:00
strnorm ( smb_fname - > base_name , lp_defaultcase ( SNUM ( conn ) ) ) ;
2008-11-18 21:57:54 +03:00
}
2002-07-15 14:35:28 +04:00
/*
* Ensure saved_last_component is valid even if file exists .
*/
s3: Change unix_convert (and its callers) to use struct smb_filename
This is the first of a series of patches that change path based
operations to operate on a struct smb_filename instead of a char *.
This same concept already exists in source4.
My goals for this series of patches are to eventually:
1) Solve the stream vs. posix filename that contains a colon ambiguity
that currently exists.
2) Make unix_convert the only function that parses the stream name.
3) Clean up the unix_convert API.
4) Change all path based vfs operation to take a struct smb_filename.
5) Make is_ntfs_stream_name() a constant operation that can simply
check the state of struct smb_filename rather than re-parse the
filename.
6) Eliminate the need for split_ntfs_stream_name() to exist.
My strategy is to start from the inside at unix_convert() and work my
way out through the vfs layer, call by call. This first patch does
just that, by changing unix_convert and all of its callers to operate
on struct smb_filename. Since this is such a large change, I plan on
pushing the patches in phases, where each phase keeps full
compatibility and passes make test.
The API of unix_convert has been simplified from:
NTSTATUS unix_convert(TALLOC_CTX *ctx,
connection_struct *conn,
const char *orig_path,
bool allow_wcard_last_component,
char **pp_conv_path,
char **pp_saved_last_component,
SMB_STRUCT_STAT *pst)
to:
NTSTATUS unix_convert(TALLOC_CTX *ctx,
connection_struct *conn,
const char *orig_path,
struct smb_filename *smb_fname,
uint32_t ucf_flags)
Currently the smb_filename struct looks like:
struct smb_filename {
char *base_name;
char *stream_name;
char *original_lcomp;
SMB_STRUCT_STAT st;
};
One key point here is the decision to break up the base_name and
stream_name. I have introduced a helper function called
get_full_smb_filename() that takes an smb_filename struct and
allocates the full_name. I changed the callers of unix_convert() to
subsequently call get_full_smb_filename() for the time being, but I
plan to eventually eliminate get_full_smb_filename().
2009-04-08 00:39:57 +04:00
if ( save_last_component ) {
2009-07-22 20:52:09 +04:00
end = strrchr_m ( smb_fname - > base_name , ' / ' ) ;
2007-01-13 02:47:16 +03:00
if ( end ) {
2009-07-22 20:52:09 +04:00
smb_fname - > original_lcomp = talloc_strdup ( smb_fname ,
s3: Change unix_convert (and its callers) to use struct smb_filename
This is the first of a series of patches that change path based
operations to operate on a struct smb_filename instead of a char *.
This same concept already exists in source4.
My goals for this series of patches are to eventually:
1) Solve the stream vs. posix filename that contains a colon ambiguity
that currently exists.
2) Make unix_convert the only function that parses the stream name.
3) Clean up the unix_convert API.
4) Change all path based vfs operation to take a struct smb_filename.
5) Make is_ntfs_stream_name() a constant operation that can simply
check the state of struct smb_filename rather than re-parse the
filename.
6) Eliminate the need for split_ntfs_stream_name() to exist.
My strategy is to start from the inside at unix_convert() and work my
way out through the vfs layer, call by call. This first patch does
just that, by changing unix_convert and all of its callers to operate
on struct smb_filename. Since this is such a large change, I plan on
pushing the patches in phases, where each phase keeps full
compatibility and passes make test.
The API of unix_convert has been simplified from:
NTSTATUS unix_convert(TALLOC_CTX *ctx,
connection_struct *conn,
const char *orig_path,
bool allow_wcard_last_component,
char **pp_conv_path,
char **pp_saved_last_component,
SMB_STRUCT_STAT *pst)
to:
NTSTATUS unix_convert(TALLOC_CTX *ctx,
connection_struct *conn,
const char *orig_path,
struct smb_filename *smb_fname,
uint32_t ucf_flags)
Currently the smb_filename struct looks like:
struct smb_filename {
char *base_name;
char *stream_name;
char *original_lcomp;
SMB_STRUCT_STAT st;
};
One key point here is the decision to break up the base_name and
stream_name. I have introduced a helper function called
get_full_smb_filename() that takes an smb_filename struct and
allocates the full_name. I changed the callers of unix_convert() to
subsequently call get_full_smb_filename() for the time being, but I
plan to eventually eliminate get_full_smb_filename().
2009-04-08 00:39:57 +04:00
end + 1 ) ;
2007-01-13 02:47:16 +03:00
} else {
2009-07-22 20:52:09 +04:00
smb_fname - > original_lcomp =
talloc_strdup ( smb_fname , smb_fname - > base_name ) ;
}
if ( smb_fname - > original_lcomp = = NULL ) {
status = NT_STATUS_NO_MEMORY ;
goto err ;
2008-11-18 19:03:38 +03:00
}
2002-07-15 14:35:28 +04:00
}
2009-02-05 03:33:52 +03:00
posix_pathnames = lp_posix_pathnames ( ) ;
2009-07-22 20:52:09 +04:00
/*
* Strip off the stream , and add it back when we ' re done with the
* base_name .
*/
2009-02-05 03:33:52 +03:00
if ( ! posix_pathnames ) {
2009-07-22 20:52:09 +04:00
stream = strchr_m ( smb_fname - > base_name , ' : ' ) ;
2008-01-20 08:53:49 +03:00
if ( stream ! = NULL ) {
2009-07-22 20:52:09 +04:00
char * tmp = talloc_strdup ( smb_fname , stream ) ;
2008-01-20 08:53:49 +03:00
if ( tmp = = NULL ) {
2009-07-22 20:52:09 +04:00
status = NT_STATUS_NO_MEMORY ;
goto err ;
2008-01-20 08:53:49 +03:00
}
2009-07-22 20:52:09 +04:00
/*
* Since this is actually pointing into
* smb_fname - > base_name this truncates base_name .
*/
2008-01-20 08:53:49 +03:00
* stream = ' \0 ' ;
stream = tmp ;
2008-01-20 01:25:36 +03:00
}
}
2009-07-22 20:52:09 +04:00
start = smb_fname - > base_name ;
2002-07-15 14:35:28 +04:00
2009-07-22 20:52:09 +04:00
/*
* If we ' re providing case insentive semantics or
2007-12-23 04:38:18 +03:00
* the underlying filesystem is case insensitive ,
* then a case - normalized hit in the stat - cache is
* authoratitive . JRA .
2009-07-22 20:52:09 +04:00
*
* Note : We ' re only checking base_name . The stream_name will be
* added and verified in build_stream_path ( ) .
2007-12-23 04:38:18 +03:00
*/
2009-07-22 20:52:09 +04:00
if ( ( ! conn - > case_sensitive | | ! ( conn - > fs_capabilities &
FILE_CASE_SENSITIVE_SEARCH ) ) & &
stat_cache_lookup ( conn , & smb_fname - > base_name , & dirpath , & start ,
& smb_fname - > st ) ) {
2007-07-12 02:39:11 +04:00
goto done ;
}
/*
* Make sure " dirpath " is an allocated string , we use this for
* building the directories with asprintf and free it .
*/
2007-09-08 00:57:01 +04:00
if ( ( dirpath = = NULL ) & & ( ! ( dirpath = talloc_strdup ( ctx , " " ) ) ) ) {
DEBUG ( 0 , ( " talloc_strdup failed \n " ) ) ;
2009-07-22 20:52:09 +04:00
status = NT_STATUS_NO_MEMORY ;
goto err ;
2002-07-15 14:35:28 +04:00
}
2007-07-12 02:39:11 +04:00
/*
2009-07-22 20:52:09 +04:00
* stat the name - if it exists then we can add the stream back ( if
* there was one ) and be done !
2002-07-15 14:35:28 +04:00
*/
2009-02-05 03:33:52 +03:00
if ( posix_pathnames ) {
2009-07-22 20:52:09 +04:00
ret = SMB_VFS_LSTAT ( conn , smb_fname ) ;
2009-02-05 03:33:52 +03:00
} else {
2009-07-22 20:52:09 +04:00
ret = SMB_VFS_STAT ( conn , smb_fname ) ;
2009-02-05 03:33:52 +03:00
}
if ( ret = = 0 ) {
2007-01-13 02:47:16 +03:00
/* Ensure we catch all names with in "/."
this is disallowed under Windows . */
2009-07-22 20:52:09 +04:00
const char * p = strstr ( smb_fname - > base_name , " /. " ) ; /*mb safe*/
2007-01-13 02:47:16 +03:00
if ( p ) {
if ( p [ 2 ] = = ' / ' ) {
/* Error code within a pathname. */
2009-07-22 20:52:09 +04:00
status = NT_STATUS_OBJECT_PATH_NOT_FOUND ;
2007-07-15 13:42:43 +04:00
goto fail ;
2007-01-13 02:47:16 +03:00
} else if ( p [ 2 ] = = ' \0 ' ) {
/* Error code at the end of a pathname. */
2009-07-22 20:52:09 +04:00
status = NT_STATUS_OBJECT_NAME_INVALID ;
2007-07-15 13:42:43 +04:00
goto fail ;
2007-01-13 02:47:16 +03:00
}
}
2009-07-22 20:52:09 +04:00
/* Add the path (not including the stream) to the cache. */
stat_cache_add ( orig_path , smb_fname - > base_name ,
conn - > case_sensitive ) ;
DEBUG ( 5 , ( " conversion of base_name finished %s -> %s \n " ,
orig_path , smb_fname - > base_name ) ) ;
2007-07-12 02:39:11 +04:00
goto done ;
2002-07-15 14:35:28 +04:00
}
2007-08-31 01:46:42 +04:00
DEBUG ( 5 , ( " unix_convert begin: name = %s, dirpath = %s, start = %s \n " ,
2009-07-22 20:52:09 +04:00
smb_fname - > base_name , dirpath , start ) ) ;
2002-07-15 14:35:28 +04:00
2007-07-12 02:39:11 +04:00
/*
2002-07-15 14:35:28 +04:00
* A special case - if we don ' t have any mangling chars and are case
2007-12-23 04:38:18 +03:00
* sensitive or the underlying filesystem is case insentive then searching
* won ' t help .
2002-07-15 14:35:28 +04:00
*/
2009-07-22 20:52:09 +04:00
if ( ( conn - > case_sensitive | | ! ( conn - > fs_capabilities &
FILE_CASE_SENSITIVE_SEARCH ) ) & &
! mangle_is_mangled ( smb_fname - > base_name , conn - > params ) ) {
2007-07-12 02:39:11 +04:00
goto done ;
2007-01-13 02:47:16 +03:00
}
2002-07-15 14:35:28 +04:00
2007-07-12 02:39:11 +04:00
/*
* is_mangled ( ) was changed to look at an entire pathname , not
2002-07-15 14:35:28 +04:00
* just a component . JRA .
*/
2007-01-13 02:47:16 +03:00
if ( mangle_is_mangled ( start , conn - > params ) ) {
2002-07-15 14:35:28 +04:00
component_was_mangled = True ;
2007-01-13 02:47:16 +03:00
}
2002-07-15 14:35:28 +04:00
2007-07-12 02:39:11 +04:00
/*
* Now we need to recursively match the name against the real
2002-07-15 14:35:28 +04:00
* directory structure .
*/
2007-07-12 02:39:11 +04:00
/*
2002-07-15 14:35:28 +04:00
* Match each part of the path name separately , trying the names
* as is first , then trying to scan the directory for matching names .
*/
for ( ; start ; start = ( end ? end + 1 : ( char * ) NULL ) ) {
2007-07-12 02:39:11 +04:00
/*
2002-07-15 14:35:28 +04:00
* Pinpoint the end of this section of the filename .
*/
2007-08-31 01:46:42 +04:00
/* mb safe. '/' can't be in any encoded char. */
end = strchr ( start , ' / ' ) ;
2002-07-15 14:35:28 +04:00
2007-07-12 02:39:11 +04:00
/*
2002-07-15 14:35:28 +04:00
* Chop the name at this point .
*/
2007-01-13 02:47:16 +03:00
if ( end ) {
2002-07-15 14:35:28 +04:00
* end = 0 ;
2007-01-13 02:47:16 +03:00
}
2002-07-15 14:35:28 +04:00
s3: Change unix_convert (and its callers) to use struct smb_filename
This is the first of a series of patches that change path based
operations to operate on a struct smb_filename instead of a char *.
This same concept already exists in source4.
My goals for this series of patches are to eventually:
1) Solve the stream vs. posix filename that contains a colon ambiguity
that currently exists.
2) Make unix_convert the only function that parses the stream name.
3) Clean up the unix_convert API.
4) Change all path based vfs operation to take a struct smb_filename.
5) Make is_ntfs_stream_name() a constant operation that can simply
check the state of struct smb_filename rather than re-parse the
filename.
6) Eliminate the need for split_ntfs_stream_name() to exist.
My strategy is to start from the inside at unix_convert() and work my
way out through the vfs layer, call by call. This first patch does
just that, by changing unix_convert and all of its callers to operate
on struct smb_filename. Since this is such a large change, I plan on
pushing the patches in phases, where each phase keeps full
compatibility and passes make test.
The API of unix_convert has been simplified from:
NTSTATUS unix_convert(TALLOC_CTX *ctx,
connection_struct *conn,
const char *orig_path,
bool allow_wcard_last_component,
char **pp_conv_path,
char **pp_saved_last_component,
SMB_STRUCT_STAT *pst)
to:
NTSTATUS unix_convert(TALLOC_CTX *ctx,
connection_struct *conn,
const char *orig_path,
struct smb_filename *smb_fname,
uint32_t ucf_flags)
Currently the smb_filename struct looks like:
struct smb_filename {
char *base_name;
char *stream_name;
char *original_lcomp;
SMB_STRUCT_STAT st;
};
One key point here is the decision to break up the base_name and
stream_name. I have introduced a helper function called
get_full_smb_filename() that takes an smb_filename struct and
allocates the full_name. I changed the callers of unix_convert() to
subsequently call get_full_smb_filename() for the time being, but I
plan to eventually eliminate get_full_smb_filename().
2009-04-08 00:39:57 +04:00
if ( save_last_component ) {
TALLOC_FREE ( smb_fname - > original_lcomp ) ;
2009-07-22 20:52:09 +04:00
smb_fname - > original_lcomp = talloc_strdup ( smb_fname ,
2007-09-08 00:57:01 +04:00
end ? end + 1 : start ) ;
s3: Change unix_convert (and its callers) to use struct smb_filename
This is the first of a series of patches that change path based
operations to operate on a struct smb_filename instead of a char *.
This same concept already exists in source4.
My goals for this series of patches are to eventually:
1) Solve the stream vs. posix filename that contains a colon ambiguity
that currently exists.
2) Make unix_convert the only function that parses the stream name.
3) Clean up the unix_convert API.
4) Change all path based vfs operation to take a struct smb_filename.
5) Make is_ntfs_stream_name() a constant operation that can simply
check the state of struct smb_filename rather than re-parse the
filename.
6) Eliminate the need for split_ntfs_stream_name() to exist.
My strategy is to start from the inside at unix_convert() and work my
way out through the vfs layer, call by call. This first patch does
just that, by changing unix_convert and all of its callers to operate
on struct smb_filename. Since this is such a large change, I plan on
pushing the patches in phases, where each phase keeps full
compatibility and passes make test.
The API of unix_convert has been simplified from:
NTSTATUS unix_convert(TALLOC_CTX *ctx,
connection_struct *conn,
const char *orig_path,
bool allow_wcard_last_component,
char **pp_conv_path,
char **pp_saved_last_component,
SMB_STRUCT_STAT *pst)
to:
NTSTATUS unix_convert(TALLOC_CTX *ctx,
connection_struct *conn,
const char *orig_path,
struct smb_filename *smb_fname,
uint32_t ucf_flags)
Currently the smb_filename struct looks like:
struct smb_filename {
char *base_name;
char *stream_name;
char *original_lcomp;
SMB_STRUCT_STAT st;
};
One key point here is the decision to break up the base_name and
stream_name. I have introduced a helper function called
get_full_smb_filename() that takes an smb_filename struct and
allocates the full_name. I changed the callers of unix_convert() to
subsequently call get_full_smb_filename() for the time being, but I
plan to eventually eliminate get_full_smb_filename().
2009-04-08 00:39:57 +04:00
if ( ! smb_fname - > original_lcomp ) {
2007-09-08 00:57:01 +04:00
DEBUG ( 0 , ( " talloc failed \n " ) ) ;
2009-07-22 20:52:09 +04:00
status = NT_STATUS_NO_MEMORY ;
goto err ;
2007-09-08 00:57:01 +04:00
}
2007-01-13 02:47:16 +03:00
}
/* The name cannot have a component of "." */
if ( ISDOT ( start ) ) {
2007-01-13 04:29:10 +03:00
if ( ! end ) {
2007-01-13 02:47:16 +03:00
/* Error code at the end of a pathname. */
2009-07-22 20:52:09 +04:00
status = NT_STATUS_OBJECT_NAME_INVALID ;
2007-07-12 02:39:11 +04:00
} else {
2009-07-22 20:52:09 +04:00
status = determine_path_error ( end + 1 ,
2007-07-12 02:39:11 +04:00
allow_wcard_last_component ) ;
2007-01-13 02:47:16 +03:00
}
2007-07-12 02:39:11 +04:00
goto fail ;
2007-01-13 02:47:16 +03:00
}
/* The name cannot have a wildcard if it's not
the last component . */
name_has_wildcard = ms_has_wild ( start ) ;
/* Wildcard not valid anywhere. */
if ( name_has_wildcard & & ! allow_wcard_last_component ) {
2009-07-22 20:52:09 +04:00
status = NT_STATUS_OBJECT_NAME_INVALID ;
2007-07-12 02:39:11 +04:00
goto fail ;
2007-01-13 02:47:16 +03:00
}
/* Wildcards never valid within a pathname. */
if ( name_has_wildcard & & end ) {
2009-07-22 20:52:09 +04:00
status = NT_STATUS_OBJECT_NAME_INVALID ;
2007-07-12 02:39:11 +04:00
goto fail ;
2007-01-13 02:47:16 +03:00
}
2002-07-15 14:35:28 +04:00
2007-07-12 02:39:11 +04:00
/*
2002-07-15 14:35:28 +04:00
* Check if the name exists up to this point .
*/
2009-02-05 03:33:52 +03:00
if ( posix_pathnames ) {
2009-07-22 20:52:09 +04:00
ret = SMB_VFS_LSTAT ( conn , smb_fname ) ;
2009-02-05 03:33:52 +03:00
} else {
2009-07-22 20:52:09 +04:00
ret = SMB_VFS_STAT ( conn , smb_fname ) ;
2009-02-05 03:33:52 +03:00
}
if ( ret = = 0 ) {
2002-07-15 14:35:28 +04:00
/*
2007-08-31 01:46:42 +04:00
* It exists . it must either be a directory or this must
* be the last part of the path for it to be OK .
2002-07-15 14:35:28 +04:00
*/
2009-07-22 20:52:09 +04:00
if ( end & & ! S_ISDIR ( smb_fname - > st . st_ex_mode ) ) {
2002-07-15 14:35:28 +04:00
/*
2007-08-31 01:46:42 +04:00
* An intermediate part of the name isn ' t
* a directory .
2002-07-15 14:35:28 +04:00
*/
DEBUG ( 5 , ( " Not a dir %s \n " , start ) ) ;
* end = ' / ' ;
2007-07-12 02:39:11 +04:00
/*
2007-08-31 01:46:42 +04:00
* We need to return the fact that the
* intermediate name resolution failed . This
* is used to return an error of ERRbadpath
* rather than ERRbadfile . Some Windows
* applications depend on the difference between
2004-06-11 21:54:23 +04:00
* these two errors .
*/
2009-07-22 20:52:09 +04:00
status = NT_STATUS_OBJECT_PATH_NOT_FOUND ;
2007-07-12 02:39:11 +04:00
goto fail ;
2002-07-15 14:35:28 +04:00
}
} else {
2007-07-12 02:39:11 +04:00
char * found_name = NULL ;
2002-07-15 14:35:28 +04:00
/* Stat failed - ensure we don't use it. */
2009-07-22 20:52:09 +04:00
SET_STAT_INVALID ( smb_fname - > st ) ;
2002-07-15 14:35:28 +04:00
2007-08-31 01:46:42 +04:00
/*
* Reset errno so we can detect
* directory open errors .
*/
2004-06-11 21:54:23 +04:00
errno = 0 ;
2002-07-15 14:35:28 +04:00
/*
* Try to find this part of the path in the directory .
*/
2007-08-31 01:46:42 +04:00
if ( name_has_wildcard | |
2009-05-02 04:28:38 +04:00
( get_real_filename ( conn , dirpath , start ,
talloc_tos ( ) ,
& found_name ) = = - 1 ) ) {
2007-07-12 02:39:11 +04:00
char * unmangled ;
2002-07-15 14:35:28 +04:00
if ( end ) {
/*
2007-08-31 01:46:42 +04:00
* An intermediate part of the name
* can ' t be found .
2002-07-15 14:35:28 +04:00
*/
2007-08-31 01:46:42 +04:00
DEBUG ( 5 , ( " Intermediate not found %s \n " ,
start ) ) ;
2002-07-15 14:35:28 +04:00
* end = ' / ' ;
2007-07-12 02:39:11 +04:00
/*
2007-08-31 01:46:42 +04:00
* We need to return the fact that the
* intermediate name resolution failed .
* This is used to return an error of
* ERRbadpath rather than ERRbadfile .
* Some Windows applications depend on
* the difference between these two
* errors .
2002-07-15 14:35:28 +04:00
*/
2007-01-13 05:13:45 +03:00
2007-07-12 03:54:01 +04:00
/*
* ENOENT , ENOTDIR and ELOOP all map
* to NT_STATUS_OBJECT_PATH_NOT_FOUND
* in the filename walk .
*/
2007-01-13 05:13:45 +03:00
2007-07-12 03:54:01 +04:00
if ( errno = = ENOENT | |
errno = = ENOTDIR | |
errno = = ELOOP ) {
2009-07-22 20:52:09 +04:00
status =
2007-08-31 01:46:42 +04:00
NT_STATUS_OBJECT_PATH_NOT_FOUND ;
2007-07-12 02:39:11 +04:00
}
else {
2009-07-22 20:52:09 +04:00
status =
2007-08-31 01:46:42 +04:00
map_nt_error_from_unix ( errno ) ;
2007-01-13 02:47:16 +03:00
}
2007-07-12 02:39:11 +04:00
goto fail ;
2002-07-15 14:35:28 +04:00
}
2007-07-12 02:39:11 +04:00
2009-05-30 13:30:16 +04:00
/*
* ENOENT / EACCESS are the only valid errors
* here . EACCESS needs handling here for
* " dropboxes " , i . e . directories where users
* can only put stuff with permission - wx .
*/
if ( ( errno ! = 0 ) & & ( errno ! = ENOENT )
& & ( errno ! = EACCES ) ) {
2007-07-12 03:54:01 +04:00
/*
* ENOTDIR and ELOOP both map to
* NT_STATUS_OBJECT_PATH_NOT_FOUND
* in the filename walk .
*/
if ( errno = = ENOTDIR | |
errno = = ELOOP ) {
2009-07-22 20:52:09 +04:00
status =
2007-08-31 01:46:42 +04:00
NT_STATUS_OBJECT_PATH_NOT_FOUND ;
2009-05-30 13:30:16 +04:00
} else {
2009-07-22 20:52:09 +04:00
status =
2007-08-31 01:46:42 +04:00
map_nt_error_from_unix ( errno ) ;
2007-01-13 05:13:45 +03:00
}
2009-05-30 13:30:16 +04:00
goto fail ;
2004-06-11 21:54:23 +04:00
}
2005-11-22 19:21:52 +03:00
/*
2002-07-15 14:35:28 +04:00
* Just the last part of the name doesn ' t exist .
2005-11-22 19:21:52 +03:00
* We need to strupper ( ) or strlower ( ) it as
2007-08-31 01:46:42 +04:00
* this conversion may be used for file creation
* purposes . Fix inspired by
* Thomas Neumann < t . neumann @ iku - ag . de > .
2002-07-15 14:35:28 +04:00
*/
2005-11-22 19:21:52 +03:00
if ( ! conn - > case_preserve | |
2007-08-31 01:46:42 +04:00
( mangle_is_8_3 ( start , False ,
conn - > params ) & &
2005-11-22 19:21:52 +03:00
! conn - > short_case_preserve ) ) {
2007-08-31 01:46:42 +04:00
strnorm ( start ,
lp_defaultcase ( SNUM ( conn ) ) ) ;
2005-11-22 19:21:52 +03:00
}
2002-07-15 14:35:28 +04:00
/*
2007-08-31 01:46:42 +04:00
* check on the mangled stack to see if we can
* recover the base of the filename .
2002-07-15 14:35:28 +04:00
*/
2007-07-12 02:39:11 +04:00
if ( mangle_is_mangled ( start , conn - > params )
2007-09-08 00:57:01 +04:00
& & mangle_lookup_name_from_8_3 ( ctx ,
start ,
& unmangled ,
conn - > params ) ) {
2007-07-12 02:39:11 +04:00
char * tmp ;
2009-07-22 20:52:09 +04:00
size_t start_ofs =
start - smb_fname - > base_name ;
2007-07-12 02:39:11 +04:00
if ( * dirpath ! = ' \0 ' ) {
2009-07-22 20:52:09 +04:00
tmp = talloc_asprintf (
smb_fname , " %s/%s " ,
dirpath , unmangled ) ;
2007-09-08 00:57:01 +04:00
TALLOC_FREE ( unmangled ) ;
2007-07-12 02:39:11 +04:00
}
else {
tmp = unmangled ;
}
if ( tmp = = NULL ) {
2007-09-08 00:57:01 +04:00
DEBUG ( 0 , ( " talloc failed \n " ) ) ;
2009-07-22 20:52:09 +04:00
status = NT_STATUS_NO_MEMORY ;
goto err ;
2007-07-12 02:39:11 +04:00
}
2009-07-22 20:52:09 +04:00
TALLOC_FREE ( smb_fname - > base_name ) ;
smb_fname - > base_name = tmp ;
start =
smb_fname - > base_name + start_ofs ;
2007-07-12 02:39:11 +04:00
end = start + strlen ( start ) ;
2002-07-15 14:35:28 +04:00
}
DEBUG ( 5 , ( " New file %s \n " , start ) ) ;
2007-07-12 02:39:11 +04:00
goto done ;
2002-07-15 14:35:28 +04:00
}
2007-07-12 02:39:11 +04:00
/*
2007-08-31 01:46:42 +04:00
* Restore the rest of the string . If the string was
* mangled the size may have changed .
2002-07-15 14:35:28 +04:00
*/
if ( end ) {
2007-07-12 02:39:11 +04:00
char * tmp ;
2009-07-22 20:52:09 +04:00
size_t start_ofs =
start - smb_fname - > base_name ;
2007-07-12 02:39:11 +04:00
if ( * dirpath ! = ' \0 ' ) {
2009-07-22 20:52:09 +04:00
tmp = talloc_asprintf ( smb_fname ,
2007-09-08 00:57:01 +04:00
" %s/%s/%s " , dirpath ,
found_name , end + 1 ) ;
2003-02-07 07:11:36 +03:00
}
2007-07-12 02:39:11 +04:00
else {
2009-07-22 20:52:09 +04:00
tmp = talloc_asprintf ( smb_fname ,
2007-09-08 00:57:01 +04:00
" %s/%s " , found_name ,
end + 1 ) ;
2007-07-12 02:39:11 +04:00
}
if ( tmp = = NULL ) {
2007-09-08 00:57:01 +04:00
DEBUG ( 0 , ( " talloc_asprintf failed \n " ) ) ;
2009-07-22 20:52:09 +04:00
status = NT_STATUS_NO_MEMORY ;
goto err ;
2007-07-12 02:39:11 +04:00
}
2009-07-22 20:52:09 +04:00
TALLOC_FREE ( smb_fname - > base_name ) ;
smb_fname - > base_name = tmp ;
start = smb_fname - > base_name + start_ofs ;
2007-07-12 02:39:11 +04:00
end = start + strlen ( found_name ) ;
2002-07-15 14:35:28 +04:00
* end = ' \0 ' ;
2002-10-11 05:19:00 +04:00
} else {
2007-07-12 02:39:11 +04:00
char * tmp ;
2009-07-22 20:52:09 +04:00
size_t start_ofs =
start - smb_fname - > base_name ;
2007-07-12 02:39:11 +04:00
if ( * dirpath ! = ' \0 ' ) {
2009-07-22 20:52:09 +04:00
tmp = talloc_asprintf ( smb_fname ,
2007-09-08 00:57:01 +04:00
" %s/%s " , dirpath ,
found_name ) ;
2007-09-12 03:57:59 +04:00
} else {
2009-07-22 20:52:09 +04:00
tmp = talloc_strdup ( smb_fname ,
2007-09-08 00:57:01 +04:00
found_name ) ;
2007-07-12 02:39:11 +04:00
}
if ( tmp = = NULL ) {
2007-09-08 00:57:01 +04:00
DEBUG ( 0 , ( " talloc failed \n " ) ) ;
2009-07-22 20:52:09 +04:00
status = NT_STATUS_NO_MEMORY ;
goto err ;
2007-07-12 02:39:11 +04:00
}
2009-07-22 20:52:09 +04:00
TALLOC_FREE ( smb_fname - > base_name ) ;
smb_fname - > base_name = tmp ;
start = smb_fname - > base_name + start_ofs ;
2007-07-12 02:39:11 +04:00
2002-10-11 05:19:00 +04:00
/*
2007-08-31 01:46:42 +04:00
* We just scanned for , and found the end of
* the path . We must return a valid stat struct
* if it exists . JRA .
2002-10-11 05:19:00 +04:00
*/
2009-02-05 03:33:52 +03:00
if ( posix_pathnames ) {
2009-07-22 20:52:09 +04:00
ret = SMB_VFS_LSTAT ( conn , smb_fname ) ;
2009-02-05 03:33:52 +03:00
} else {
2009-07-22 20:52:09 +04:00
ret = SMB_VFS_STAT ( conn , smb_fname ) ;
2009-02-05 03:33:52 +03:00
}
2009-07-22 20:52:09 +04:00
if ( ret ! = 0 ) {
SET_STAT_INVALID ( smb_fname - > st ) ;
2002-10-11 05:19:00 +04:00
}
2002-07-15 14:35:28 +04:00
}
2007-07-12 02:39:11 +04:00
2007-09-08 00:57:01 +04:00
TALLOC_FREE ( found_name ) ;
2002-07-15 14:35:28 +04:00
} /* end else */
2007-01-20 00:46:12 +03:00
# ifdef DEVELOPER
2008-04-01 13:40:23 +04:00
/*
* This sucks !
* We should never provide different behaviors
* depending on DEVELOPER ! ! !
*/
2009-07-22 20:52:09 +04:00
if ( VALID_STAT ( smb_fname - > st ) ) {
2008-04-01 13:40:23 +04:00
bool delete_pending ;
2009-07-22 20:52:09 +04:00
get_file_infos ( vfs_file_id_from_sbuf ( conn ,
& smb_fname - > st ) ,
2008-04-01 13:40:23 +04:00
& delete_pending , NULL ) ;
if ( delete_pending ) {
2009-07-22 20:52:09 +04:00
status = NT_STATUS_DELETE_PENDING ;
2008-04-01 13:40:23 +04:00
goto fail ;
}
2007-01-20 00:46:12 +03:00
}
# endif
2007-08-31 01:46:42 +04:00
/*
2002-07-15 14:35:28 +04:00
* Add to the dirpath that we have resolved so far .
*/
2007-07-12 02:39:11 +04:00
if ( * dirpath ! = ' \0 ' ) {
2007-09-08 00:57:01 +04:00
char * tmp = talloc_asprintf ( ctx ,
" %s/%s " , dirpath , start ) ;
if ( ! tmp ) {
DEBUG ( 0 , ( " talloc_asprintf failed \n " ) ) ;
2009-07-22 20:52:09 +04:00
status = NT_STATUS_NO_MEMORY ;
goto err ;
2007-07-12 02:39:11 +04:00
}
2007-09-08 00:57:01 +04:00
TALLOC_FREE ( dirpath ) ;
2007-07-12 02:39:11 +04:00
dirpath = tmp ;
}
else {
2007-09-08 00:57:01 +04:00
TALLOC_FREE ( dirpath ) ;
if ( ! ( dirpath = talloc_strdup ( ctx , start ) ) ) {
DEBUG ( 0 , ( " talloc_strdup failed \n " ) ) ;
2009-07-22 20:52:09 +04:00
status = NT_STATUS_NO_MEMORY ;
goto err ;
2007-07-12 02:39:11 +04:00
}
}
2002-07-15 14:35:28 +04:00
/*
2009-07-22 20:52:09 +04:00
* Cache the dirpath thus far . Don ' t cache a name with mangled
* or wildcard components as this can change the size .
2002-07-15 14:35:28 +04:00
*/
2007-01-13 02:47:16 +03:00
if ( ! component_was_mangled & & ! name_has_wildcard ) {
2007-08-31 01:46:42 +04:00
stat_cache_add ( orig_path , dirpath ,
conn - > case_sensitive ) ;
2007-01-13 02:47:16 +03:00
}
2007-07-12 02:39:11 +04:00
/*
2002-07-15 14:35:28 +04:00
* Restore the / that we wiped out earlier .
*/
2007-01-13 02:47:16 +03:00
if ( end ) {
2002-07-15 14:35:28 +04:00
* end = ' / ' ;
2007-01-13 02:47:16 +03:00
}
2002-07-15 14:35:28 +04:00
}
2007-07-12 02:39:11 +04:00
2002-07-15 14:35:28 +04:00
/*
2009-07-22 20:52:09 +04:00
* Cache the full path . Don ' t cache a name with mangled or wildcard
* components as this can change the size .
2002-07-15 14:35:28 +04:00
*/
2000-12-12 03:11:34 +03:00
2007-01-13 02:47:16 +03:00
if ( ! component_was_mangled & & ! name_has_wildcard ) {
2009-07-22 20:52:09 +04:00
stat_cache_add ( orig_path , smb_fname - > base_name ,
conn - > case_sensitive ) ;
2007-01-13 02:47:16 +03:00
}
2000-12-12 03:11:34 +03:00
2007-07-12 02:39:11 +04:00
/*
2002-07-15 14:35:28 +04:00
* The name has been resolved .
*/
1998-08-28 00:38:53 +04:00
2009-07-22 20:52:09 +04:00
DEBUG ( 5 , ( " conversion finished %s -> %s \n " , orig_path ,
smb_fname - > base_name ) ) ;
2007-07-12 02:39:11 +04:00
done :
2009-07-22 20:52:09 +04:00
/* Add back the stream if one was stripped off originally. */
2008-01-20 01:25:36 +03:00
if ( stream ! = NULL ) {
s3: Change unix_convert (and its callers) to use struct smb_filename
This is the first of a series of patches that change path based
operations to operate on a struct smb_filename instead of a char *.
This same concept already exists in source4.
My goals for this series of patches are to eventually:
1) Solve the stream vs. posix filename that contains a colon ambiguity
that currently exists.
2) Make unix_convert the only function that parses the stream name.
3) Clean up the unix_convert API.
4) Change all path based vfs operation to take a struct smb_filename.
5) Make is_ntfs_stream_name() a constant operation that can simply
check the state of struct smb_filename rather than re-parse the
filename.
6) Eliminate the need for split_ntfs_stream_name() to exist.
My strategy is to start from the inside at unix_convert() and work my
way out through the vfs layer, call by call. This first patch does
just that, by changing unix_convert and all of its callers to operate
on struct smb_filename. Since this is such a large change, I plan on
pushing the patches in phases, where each phase keeps full
compatibility and passes make test.
The API of unix_convert has been simplified from:
NTSTATUS unix_convert(TALLOC_CTX *ctx,
connection_struct *conn,
const char *orig_path,
bool allow_wcard_last_component,
char **pp_conv_path,
char **pp_saved_last_component,
SMB_STRUCT_STAT *pst)
to:
NTSTATUS unix_convert(TALLOC_CTX *ctx,
connection_struct *conn,
const char *orig_path,
struct smb_filename *smb_fname,
uint32_t ucf_flags)
Currently the smb_filename struct looks like:
struct smb_filename {
char *base_name;
char *stream_name;
char *original_lcomp;
SMB_STRUCT_STAT st;
};
One key point here is the decision to break up the base_name and
stream_name. I have introduced a helper function called
get_full_smb_filename() that takes an smb_filename struct and
allocates the full_name. I changed the callers of unix_convert() to
subsequently call get_full_smb_filename() for the time being, but I
plan to eventually eliminate get_full_smb_filename().
2009-04-08 00:39:57 +04:00
smb_fname - > stream_name = stream ;
2008-01-20 01:25:36 +03:00
s3: Change unix_convert (and its callers) to use struct smb_filename
This is the first of a series of patches that change path based
operations to operate on a struct smb_filename instead of a char *.
This same concept already exists in source4.
My goals for this series of patches are to eventually:
1) Solve the stream vs. posix filename that contains a colon ambiguity
that currently exists.
2) Make unix_convert the only function that parses the stream name.
3) Clean up the unix_convert API.
4) Change all path based vfs operation to take a struct smb_filename.
5) Make is_ntfs_stream_name() a constant operation that can simply
check the state of struct smb_filename rather than re-parse the
filename.
6) Eliminate the need for split_ntfs_stream_name() to exist.
My strategy is to start from the inside at unix_convert() and work my
way out through the vfs layer, call by call. This first patch does
just that, by changing unix_convert and all of its callers to operate
on struct smb_filename. Since this is such a large change, I plan on
pushing the patches in phases, where each phase keeps full
compatibility and passes make test.
The API of unix_convert has been simplified from:
NTSTATUS unix_convert(TALLOC_CTX *ctx,
connection_struct *conn,
const char *orig_path,
bool allow_wcard_last_component,
char **pp_conv_path,
char **pp_saved_last_component,
SMB_STRUCT_STAT *pst)
to:
NTSTATUS unix_convert(TALLOC_CTX *ctx,
connection_struct *conn,
const char *orig_path,
struct smb_filename *smb_fname,
uint32_t ucf_flags)
Currently the smb_filename struct looks like:
struct smb_filename {
char *base_name;
char *stream_name;
char *original_lcomp;
SMB_STRUCT_STAT st;
};
One key point here is the decision to break up the base_name and
stream_name. I have introduced a helper function called
get_full_smb_filename() that takes an smb_filename struct and
allocates the full_name. I changed the callers of unix_convert() to
subsequently call get_full_smb_filename() for the time being, but I
plan to eventually eliminate get_full_smb_filename().
2009-04-08 00:39:57 +04:00
/* Check path now that the base_name has been converted. */
2009-07-22 20:52:09 +04:00
status = build_stream_path ( ctx , conn , orig_path , smb_fname ) ;
if ( ! NT_STATUS_IS_OK ( status ) ) {
2008-01-20 01:25:36 +03:00
goto fail ;
}
}
2007-09-08 00:57:01 +04:00
TALLOC_FREE ( dirpath ) ;
s3: Change unix_convert (and its callers) to use struct smb_filename
This is the first of a series of patches that change path based
operations to operate on a struct smb_filename instead of a char *.
This same concept already exists in source4.
My goals for this series of patches are to eventually:
1) Solve the stream vs. posix filename that contains a colon ambiguity
that currently exists.
2) Make unix_convert the only function that parses the stream name.
3) Clean up the unix_convert API.
4) Change all path based vfs operation to take a struct smb_filename.
5) Make is_ntfs_stream_name() a constant operation that can simply
check the state of struct smb_filename rather than re-parse the
filename.
6) Eliminate the need for split_ntfs_stream_name() to exist.
My strategy is to start from the inside at unix_convert() and work my
way out through the vfs layer, call by call. This first patch does
just that, by changing unix_convert and all of its callers to operate
on struct smb_filename. Since this is such a large change, I plan on
pushing the patches in phases, where each phase keeps full
compatibility and passes make test.
The API of unix_convert has been simplified from:
NTSTATUS unix_convert(TALLOC_CTX *ctx,
connection_struct *conn,
const char *orig_path,
bool allow_wcard_last_component,
char **pp_conv_path,
char **pp_saved_last_component,
SMB_STRUCT_STAT *pst)
to:
NTSTATUS unix_convert(TALLOC_CTX *ctx,
connection_struct *conn,
const char *orig_path,
struct smb_filename *smb_fname,
uint32_t ucf_flags)
Currently the smb_filename struct looks like:
struct smb_filename {
char *base_name;
char *stream_name;
char *original_lcomp;
SMB_STRUCT_STAT st;
};
One key point here is the decision to break up the base_name and
stream_name. I have introduced a helper function called
get_full_smb_filename() that takes an smb_filename struct and
allocates the full_name. I changed the callers of unix_convert() to
subsequently call get_full_smb_filename() for the time being, but I
plan to eventually eliminate get_full_smb_filename().
2009-04-08 00:39:57 +04:00
* smb_fname_out = smb_fname ;
2007-08-20 00:00:43 +04:00
return NT_STATUS_OK ;
2007-08-16 19:44:13 +04:00
fail :
2007-08-20 00:00:43 +04:00
DEBUG ( 10 , ( " dirpath = [%s] start = [%s] \n " , dirpath , start ) ) ;
2007-09-08 00:57:01 +04:00
if ( * dirpath ! = ' \0 ' ) {
2009-07-22 20:52:09 +04:00
smb_fname - > base_name = talloc_asprintf ( smb_fname , " %s/%s " ,
dirpath , start ) ;
2007-09-08 00:57:01 +04:00
} else {
2009-07-22 20:52:09 +04:00
smb_fname - > base_name = talloc_strdup ( smb_fname , start ) ;
2007-09-08 00:57:01 +04:00
}
s3: Change unix_convert (and its callers) to use struct smb_filename
This is the first of a series of patches that change path based
operations to operate on a struct smb_filename instead of a char *.
This same concept already exists in source4.
My goals for this series of patches are to eventually:
1) Solve the stream vs. posix filename that contains a colon ambiguity
that currently exists.
2) Make unix_convert the only function that parses the stream name.
3) Clean up the unix_convert API.
4) Change all path based vfs operation to take a struct smb_filename.
5) Make is_ntfs_stream_name() a constant operation that can simply
check the state of struct smb_filename rather than re-parse the
filename.
6) Eliminate the need for split_ntfs_stream_name() to exist.
My strategy is to start from the inside at unix_convert() and work my
way out through the vfs layer, call by call. This first patch does
just that, by changing unix_convert and all of its callers to operate
on struct smb_filename. Since this is such a large change, I plan on
pushing the patches in phases, where each phase keeps full
compatibility and passes make test.
The API of unix_convert has been simplified from:
NTSTATUS unix_convert(TALLOC_CTX *ctx,
connection_struct *conn,
const char *orig_path,
bool allow_wcard_last_component,
char **pp_conv_path,
char **pp_saved_last_component,
SMB_STRUCT_STAT *pst)
to:
NTSTATUS unix_convert(TALLOC_CTX *ctx,
connection_struct *conn,
const char *orig_path,
struct smb_filename *smb_fname,
uint32_t ucf_flags)
Currently the smb_filename struct looks like:
struct smb_filename {
char *base_name;
char *stream_name;
char *original_lcomp;
SMB_STRUCT_STAT st;
};
One key point here is the decision to break up the base_name and
stream_name. I have introduced a helper function called
get_full_smb_filename() that takes an smb_filename struct and
allocates the full_name. I changed the callers of unix_convert() to
subsequently call get_full_smb_filename() for the time being, but I
plan to eventually eliminate get_full_smb_filename().
2009-04-08 00:39:57 +04:00
if ( ! smb_fname - > base_name ) {
2007-09-08 00:57:01 +04:00
DEBUG ( 0 , ( " talloc_asprintf failed \n " ) ) ;
2009-07-22 20:52:09 +04:00
status = NT_STATUS_NO_MEMORY ;
goto err ;
2007-09-08 00:57:01 +04:00
}
s3: Change unix_convert (and its callers) to use struct smb_filename
This is the first of a series of patches that change path based
operations to operate on a struct smb_filename instead of a char *.
This same concept already exists in source4.
My goals for this series of patches are to eventually:
1) Solve the stream vs. posix filename that contains a colon ambiguity
that currently exists.
2) Make unix_convert the only function that parses the stream name.
3) Clean up the unix_convert API.
4) Change all path based vfs operation to take a struct smb_filename.
5) Make is_ntfs_stream_name() a constant operation that can simply
check the state of struct smb_filename rather than re-parse the
filename.
6) Eliminate the need for split_ntfs_stream_name() to exist.
My strategy is to start from the inside at unix_convert() and work my
way out through the vfs layer, call by call. This first patch does
just that, by changing unix_convert and all of its callers to operate
on struct smb_filename. Since this is such a large change, I plan on
pushing the patches in phases, where each phase keeps full
compatibility and passes make test.
The API of unix_convert has been simplified from:
NTSTATUS unix_convert(TALLOC_CTX *ctx,
connection_struct *conn,
const char *orig_path,
bool allow_wcard_last_component,
char **pp_conv_path,
char **pp_saved_last_component,
SMB_STRUCT_STAT *pst)
to:
NTSTATUS unix_convert(TALLOC_CTX *ctx,
connection_struct *conn,
const char *orig_path,
struct smb_filename *smb_fname,
uint32_t ucf_flags)
Currently the smb_filename struct looks like:
struct smb_filename {
char *base_name;
char *stream_name;
char *original_lcomp;
SMB_STRUCT_STAT st;
};
One key point here is the decision to break up the base_name and
stream_name. I have introduced a helper function called
get_full_smb_filename() that takes an smb_filename struct and
allocates the full_name. I changed the callers of unix_convert() to
subsequently call get_full_smb_filename() for the time being, but I
plan to eventually eliminate get_full_smb_filename().
2009-04-08 00:39:57 +04:00
* smb_fname_out = smb_fname ;
2007-09-08 00:57:01 +04:00
TALLOC_FREE ( dirpath ) ;
2009-07-22 20:52:09 +04:00
return status ;
err :
TALLOC_FREE ( smb_fname ) ;
return status ;
1998-08-17 11:40:06 +04:00
}
/****************************************************************************
2007-07-09 13:43:41 +04:00
Check a filename - possibly calling check_reduced_name .
2002-07-15 14:35:28 +04:00
This is called by every routine before it allows an operation on a filename .
It does any final confirmation necessary to ensure that the filename is
a valid one for the user to access .
1998-08-17 11:40:06 +04:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2002-07-15 14:35:28 +04:00
2007-09-08 00:57:01 +04:00
NTSTATUS check_name ( connection_struct * conn , const char * name )
1998-08-17 11:40:06 +04:00
{
2009-11-23 18:33:53 +03:00
if ( IS_VETO_PATH ( conn , name ) ) {
2004-03-06 01:32:45 +03:00
/* Is it not dot or dot dot. */
2007-08-31 01:46:42 +04:00
if ( ! ( ( name [ 0 ] = = ' . ' ) & & ( ! name [ 1 ] | |
( name [ 1 ] = = ' . ' & & ! name [ 2 ] ) ) ) ) {
DEBUG ( 5 , ( " check_name: file path name %s vetoed \n " ,
name ) ) ;
2007-01-17 05:09:37 +03:00
return map_nt_error_from_unix ( ENOENT ) ;
2002-07-15 14:35:28 +04:00
}
}
1998-08-17 11:40:06 +04:00
2004-09-01 02:52:05 +04:00
if ( ! lp_widelinks ( SNUM ( conn ) ) | | ! lp_symlinks ( SNUM ( conn ) ) ) {
2007-07-09 13:43:41 +04:00
NTSTATUS status = check_reduced_name ( conn , name ) ;
2007-01-17 05:09:37 +03:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
2007-08-31 01:46:42 +04:00
DEBUG ( 5 , ( " check_name: name %s failed with %s \n " , name ,
nt_errstr ( status ) ) ) ;
2007-01-17 05:09:37 +03:00
return status ;
}
2004-06-11 21:54:23 +04:00
}
1998-08-17 11:40:06 +04:00
2007-01-17 05:09:37 +03:00
return NT_STATUS_OK ;
1998-08-17 11:40:06 +04:00
}
2007-07-12 02:39:11 +04:00
/****************************************************************************
Check if two filenames are equal .
This needs to be careful about whether we are case sensitive .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2007-10-19 04:40:25 +04:00
static bool fname_equal ( const char * name1 , const char * name2 ,
bool case_sensitive )
2007-07-12 02:39:11 +04:00
{
/* Normal filename handling */
2007-09-08 00:57:01 +04:00
if ( case_sensitive ) {
2007-07-12 02:39:11 +04:00
return ( strcmp ( name1 , name2 ) = = 0 ) ;
2007-09-08 00:57:01 +04:00
}
2007-07-12 02:39:11 +04:00
return ( strequal ( name1 , name2 ) ) ;
}
1998-08-17 11:40:06 +04:00
/****************************************************************************
2002-07-15 14:35:28 +04:00
Scan a directory to find a filename , matching without case sensitivity .
If the name looks like a mangled name then try via the mangling functions
1998-08-17 11:40:06 +04:00
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
2002-07-15 14:35:28 +04:00
2009-05-02 04:28:38 +04:00
static int get_real_filename_full_scan ( connection_struct * conn ,
const char * path , const char * name ,
2009-05-09 13:12:52 +04:00
bool mangled ,
2009-05-02 04:28:38 +04:00
TALLOC_CTX * mem_ctx , char * * found_name )
1998-08-17 11:40:06 +04:00
{
2009-04-23 16:54:52 +04:00
struct smb_Dir * cur_dir ;
2009-11-16 11:49:23 +03:00
const char * dname = NULL ;
char * talloced = NULL ;
2007-07-12 02:39:11 +04:00
char * unmangled_name = NULL ;
2009-04-23 16:54:52 +04:00
long curpos ;
2002-07-15 14:35:28 +04:00
/* handle null paths */
2007-09-08 00:57:01 +04:00
if ( ( path = = NULL ) | | ( * path = = 0 ) ) {
2002-07-15 14:35:28 +04:00
path = " . " ;
2007-09-08 00:57:01 +04:00
}
2002-07-15 14:35:28 +04:00
2007-12-23 01:55:37 +03:00
/* If we have a case-sensitive filesystem, it doesn't do us any
* good to search for a name . If a case variation of the name was
* there , then the original stat ( 2 ) would have found it .
*/
if ( ! mangled & & ! ( conn - > fs_capabilities & FILE_CASE_SENSITIVE_SEARCH ) ) {
errno = ENOENT ;
2008-12-10 05:03:51 +03:00
return - 1 ;
2007-12-23 01:55:37 +03:00
}
2002-07-15 14:35:28 +04:00
/*
* The incoming name can be mangled , and if we de - mangle it
* here it will not compare correctly against the filename ( name2 )
2007-09-08 00:57:01 +04:00
* read from the directory and then mangled by the name_to_8_3 ( )
2002-07-15 14:35:28 +04:00
* call . We need to mangle both names or neither .
* ( JRA ) .
2005-10-28 05:42:03 +04:00
*
* Fix for bug found by Dina Fine . If in case sensitive mode then
* the mangle cache is no good ( 3 letter extension could be wrong
* case - so don ' t demangle in this case - leave as mangled and
* allow the mangling of the directory entry read ( which is done
* case insensitively ) to match instead . This will lead to more
* false positive matches but we fail completely without it . JRA .
2002-07-15 14:35:28 +04:00
*/
2005-10-28 05:42:03 +04:00
if ( mangled & & ! conn - > case_sensitive ) {
2008-12-09 15:40:41 +03:00
mangled = ! mangle_lookup_name_from_8_3 ( talloc_tos ( ) , name ,
& unmangled_name ,
conn - > params ) ;
2007-09-14 22:24:31 +04:00
if ( ! mangled ) {
/* Name is now unmangled. */
2007-09-08 00:57:01 +04:00
name = unmangled_name ;
}
2005-10-28 05:42:03 +04:00
}
2002-07-15 14:35:28 +04:00
/* open the directory */
2008-01-12 19:08:04 +03:00
if ( ! ( cur_dir = OpenDir ( talloc_tos ( ) , conn , path , NULL , 0 ) ) ) {
2002-07-15 14:35:28 +04:00
DEBUG ( 3 , ( " scan dir didn't open dir [%s] \n " , path ) ) ;
2007-09-08 00:57:01 +04:00
TALLOC_FREE ( unmangled_name ) ;
2008-12-10 05:03:51 +03:00
return - 1 ;
2002-07-15 14:35:28 +04:00
}
/* now scan for matching names */
2005-01-29 00:01:58 +03:00
curpos = 0 ;
2009-11-16 11:49:23 +03:00
while ( ( dname = ReadDirName ( cur_dir , & curpos , NULL , & talloced ) ) ) {
2004-03-06 01:32:45 +03:00
/* Is it dot or dot dot. */
2007-09-08 00:57:01 +04:00
if ( ISDOT ( dname ) | | ISDOTDOT ( dname ) ) {
2009-11-16 11:49:23 +03:00
TALLOC_FREE ( talloced ) ;
2002-07-15 14:35:28 +04:00
continue ;
2004-03-06 01:32:45 +03:00
}
2002-07-15 14:35:28 +04:00
/*
* At this point dname is the unmangled name .
2007-08-31 01:46:42 +04:00
* name is either mangled or not , depending on the state
* of the " mangled " variable . JRA .
2002-07-15 14:35:28 +04:00
*/
/*
* Check mangled name against mangled name , or unmangled name
* against unmangled name .
*/
2007-08-31 01:46:42 +04:00
if ( ( mangled & & mangled_equal ( name , dname , conn - > params ) ) | |
fname_equal ( name , dname , conn - > case_sensitive ) ) {
2002-07-15 14:35:28 +04:00
/* we've found the file, change it's name and return */
2008-12-09 15:40:41 +03:00
* found_name = talloc_strdup ( mem_ctx , dname ) ;
2007-09-08 00:57:01 +04:00
TALLOC_FREE ( unmangled_name ) ;
2008-01-12 19:08:04 +03:00
TALLOC_FREE ( cur_dir ) ;
2007-09-08 00:57:01 +04:00
if ( ! * found_name ) {
errno = ENOMEM ;
2009-11-16 11:49:23 +03:00
TALLOC_FREE ( talloced ) ;
2008-12-10 05:03:51 +03:00
return - 1 ;
2007-09-08 00:57:01 +04:00
}
2009-11-16 11:49:23 +03:00
TALLOC_FREE ( talloced ) ;
2008-12-10 05:03:51 +03:00
return 0 ;
2002-07-15 14:35:28 +04:00
}
2009-11-16 11:49:23 +03:00
TALLOC_FREE ( talloced ) ;
2002-07-15 14:35:28 +04:00
}
2007-09-08 00:57:01 +04:00
TALLOC_FREE ( unmangled_name ) ;
2008-01-12 19:08:04 +03:00
TALLOC_FREE ( cur_dir ) ;
2004-06-11 21:54:23 +04:00
errno = ENOENT ;
2008-12-10 05:03:51 +03:00
return - 1 ;
1998-08-17 11:40:06 +04:00
}
2008-01-20 01:25:36 +03:00
2009-05-02 04:28:38 +04:00
/****************************************************************************
Wrapper around the vfs get_real_filename and the full directory scan
fallback .
* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */
int get_real_filename ( connection_struct * conn , const char * path ,
const char * name , TALLOC_CTX * mem_ctx ,
char * * found_name )
{
int ret ;
2009-05-09 13:12:52 +04:00
bool mangled ;
mangled = mangle_is_mangled ( name , conn - > params ) ;
if ( mangled ) {
return get_real_filename_full_scan ( conn , path , name , mangled ,
mem_ctx , found_name ) ;
}
2009-05-02 04:28:38 +04:00
/* Try the vfs first to take advantage of case-insensitive stat. */
ret = SMB_VFS_GET_REAL_FILENAME ( conn , path , name , mem_ctx , found_name ) ;
/*
* If the case - insensitive stat was successful , or returned an error
* other than EOPNOTSUPP then there is no need to fall back on the
* full directory scan .
*/
if ( ret = = 0 | | ( ret = = - 1 & & errno ! = EOPNOTSUPP ) ) {
return ret ;
}
2009-05-09 13:12:52 +04:00
return get_real_filename_full_scan ( conn , path , name , mangled , mem_ctx ,
found_name ) ;
2009-05-02 04:28:38 +04:00
}
2008-01-20 01:25:36 +03:00
static NTSTATUS build_stream_path ( TALLOC_CTX * mem_ctx ,
connection_struct * conn ,
const char * orig_path ,
s3: Change unix_convert (and its callers) to use struct smb_filename
This is the first of a series of patches that change path based
operations to operate on a struct smb_filename instead of a char *.
This same concept already exists in source4.
My goals for this series of patches are to eventually:
1) Solve the stream vs. posix filename that contains a colon ambiguity
that currently exists.
2) Make unix_convert the only function that parses the stream name.
3) Clean up the unix_convert API.
4) Change all path based vfs operation to take a struct smb_filename.
5) Make is_ntfs_stream_name() a constant operation that can simply
check the state of struct smb_filename rather than re-parse the
filename.
6) Eliminate the need for split_ntfs_stream_name() to exist.
My strategy is to start from the inside at unix_convert() and work my
way out through the vfs layer, call by call. This first patch does
just that, by changing unix_convert and all of its callers to operate
on struct smb_filename. Since this is such a large change, I plan on
pushing the patches in phases, where each phase keeps full
compatibility and passes make test.
The API of unix_convert has been simplified from:
NTSTATUS unix_convert(TALLOC_CTX *ctx,
connection_struct *conn,
const char *orig_path,
bool allow_wcard_last_component,
char **pp_conv_path,
char **pp_saved_last_component,
SMB_STRUCT_STAT *pst)
to:
NTSTATUS unix_convert(TALLOC_CTX *ctx,
connection_struct *conn,
const char *orig_path,
struct smb_filename *smb_fname,
uint32_t ucf_flags)
Currently the smb_filename struct looks like:
struct smb_filename {
char *base_name;
char *stream_name;
char *original_lcomp;
SMB_STRUCT_STAT st;
};
One key point here is the decision to break up the base_name and
stream_name. I have introduced a helper function called
get_full_smb_filename() that takes an smb_filename struct and
allocates the full_name. I changed the callers of unix_convert() to
subsequently call get_full_smb_filename() for the time being, but I
plan to eventually eliminate get_full_smb_filename().
2009-04-08 00:39:57 +04:00
struct smb_filename * smb_fname )
2008-01-20 01:25:36 +03:00
{
NTSTATUS status ;
unsigned int i , num_streams ;
struct stream_struct * streams = NULL ;
2009-06-23 02:26:56 +04:00
if ( SMB_VFS_STAT ( conn , smb_fname ) = = 0 ) {
2009-07-22 20:52:09 +04:00
DEBUG ( 10 , ( " '%s' exists \n " , smb_fname_str_dbg ( smb_fname ) ) ) ;
2008-01-20 01:25:36 +03:00
return NT_STATUS_OK ;
}
if ( errno ! = ENOENT ) {
2009-08-29 02:53:05 +04:00
DEBUG ( 10 , ( " vfs_stat failed: %s \n " , strerror ( errno ) ) ) ;
2008-01-20 01:25:36 +03:00
status = map_nt_error_from_unix ( errno ) ;
goto fail ;
}
s3: Change unix_convert (and its callers) to use struct smb_filename
This is the first of a series of patches that change path based
operations to operate on a struct smb_filename instead of a char *.
This same concept already exists in source4.
My goals for this series of patches are to eventually:
1) Solve the stream vs. posix filename that contains a colon ambiguity
that currently exists.
2) Make unix_convert the only function that parses the stream name.
3) Clean up the unix_convert API.
4) Change all path based vfs operation to take a struct smb_filename.
5) Make is_ntfs_stream_name() a constant operation that can simply
check the state of struct smb_filename rather than re-parse the
filename.
6) Eliminate the need for split_ntfs_stream_name() to exist.
My strategy is to start from the inside at unix_convert() and work my
way out through the vfs layer, call by call. This first patch does
just that, by changing unix_convert and all of its callers to operate
on struct smb_filename. Since this is such a large change, I plan on
pushing the patches in phases, where each phase keeps full
compatibility and passes make test.
The API of unix_convert has been simplified from:
NTSTATUS unix_convert(TALLOC_CTX *ctx,
connection_struct *conn,
const char *orig_path,
bool allow_wcard_last_component,
char **pp_conv_path,
char **pp_saved_last_component,
SMB_STRUCT_STAT *pst)
to:
NTSTATUS unix_convert(TALLOC_CTX *ctx,
connection_struct *conn,
const char *orig_path,
struct smb_filename *smb_fname,
uint32_t ucf_flags)
Currently the smb_filename struct looks like:
struct smb_filename {
char *base_name;
char *stream_name;
char *original_lcomp;
SMB_STRUCT_STAT st;
};
One key point here is the decision to break up the base_name and
stream_name. I have introduced a helper function called
get_full_smb_filename() that takes an smb_filename struct and
allocates the full_name. I changed the callers of unix_convert() to
subsequently call get_full_smb_filename() for the time being, but I
plan to eventually eliminate get_full_smb_filename().
2009-04-08 00:39:57 +04:00
/* Fall back to a case-insensitive scan of all streams on the file. */
status = SMB_VFS_STREAMINFO ( conn , NULL , smb_fname - > base_name , mem_ctx ,
2008-01-20 01:25:36 +03:00
& num_streams , & streams ) ;
if ( NT_STATUS_EQUAL ( status , NT_STATUS_OBJECT_NAME_NOT_FOUND ) ) {
s3: Change unix_convert (and its callers) to use struct smb_filename
This is the first of a series of patches that change path based
operations to operate on a struct smb_filename instead of a char *.
This same concept already exists in source4.
My goals for this series of patches are to eventually:
1) Solve the stream vs. posix filename that contains a colon ambiguity
that currently exists.
2) Make unix_convert the only function that parses the stream name.
3) Clean up the unix_convert API.
4) Change all path based vfs operation to take a struct smb_filename.
5) Make is_ntfs_stream_name() a constant operation that can simply
check the state of struct smb_filename rather than re-parse the
filename.
6) Eliminate the need for split_ntfs_stream_name() to exist.
My strategy is to start from the inside at unix_convert() and work my
way out through the vfs layer, call by call. This first patch does
just that, by changing unix_convert and all of its callers to operate
on struct smb_filename. Since this is such a large change, I plan on
pushing the patches in phases, where each phase keeps full
compatibility and passes make test.
The API of unix_convert has been simplified from:
NTSTATUS unix_convert(TALLOC_CTX *ctx,
connection_struct *conn,
const char *orig_path,
bool allow_wcard_last_component,
char **pp_conv_path,
char **pp_saved_last_component,
SMB_STRUCT_STAT *pst)
to:
NTSTATUS unix_convert(TALLOC_CTX *ctx,
connection_struct *conn,
const char *orig_path,
struct smb_filename *smb_fname,
uint32_t ucf_flags)
Currently the smb_filename struct looks like:
struct smb_filename {
char *base_name;
char *stream_name;
char *original_lcomp;
SMB_STRUCT_STAT st;
};
One key point here is the decision to break up the base_name and
stream_name. I have introduced a helper function called
get_full_smb_filename() that takes an smb_filename struct and
allocates the full_name. I changed the callers of unix_convert() to
subsequently call get_full_smb_filename() for the time being, but I
plan to eventually eliminate get_full_smb_filename().
2009-04-08 00:39:57 +04:00
SET_STAT_INVALID ( smb_fname - > st ) ;
2008-01-20 01:25:36 +03:00
return NT_STATUS_OK ;
}
if ( ! NT_STATUS_IS_OK ( status ) ) {
DEBUG ( 10 , ( " vfs_streaminfo failed: %s \n " , nt_errstr ( status ) ) ) ;
goto fail ;
}
for ( i = 0 ; i < num_streams ; i + + ) {
DEBUG ( 10 , ( " comparing [%s] and [%s]: " ,
s3: Change unix_convert (and its callers) to use struct smb_filename
This is the first of a series of patches that change path based
operations to operate on a struct smb_filename instead of a char *.
This same concept already exists in source4.
My goals for this series of patches are to eventually:
1) Solve the stream vs. posix filename that contains a colon ambiguity
that currently exists.
2) Make unix_convert the only function that parses the stream name.
3) Clean up the unix_convert API.
4) Change all path based vfs operation to take a struct smb_filename.
5) Make is_ntfs_stream_name() a constant operation that can simply
check the state of struct smb_filename rather than re-parse the
filename.
6) Eliminate the need for split_ntfs_stream_name() to exist.
My strategy is to start from the inside at unix_convert() and work my
way out through the vfs layer, call by call. This first patch does
just that, by changing unix_convert and all of its callers to operate
on struct smb_filename. Since this is such a large change, I plan on
pushing the patches in phases, where each phase keeps full
compatibility and passes make test.
The API of unix_convert has been simplified from:
NTSTATUS unix_convert(TALLOC_CTX *ctx,
connection_struct *conn,
const char *orig_path,
bool allow_wcard_last_component,
char **pp_conv_path,
char **pp_saved_last_component,
SMB_STRUCT_STAT *pst)
to:
NTSTATUS unix_convert(TALLOC_CTX *ctx,
connection_struct *conn,
const char *orig_path,
struct smb_filename *smb_fname,
uint32_t ucf_flags)
Currently the smb_filename struct looks like:
struct smb_filename {
char *base_name;
char *stream_name;
char *original_lcomp;
SMB_STRUCT_STAT st;
};
One key point here is the decision to break up the base_name and
stream_name. I have introduced a helper function called
get_full_smb_filename() that takes an smb_filename struct and
allocates the full_name. I changed the callers of unix_convert() to
subsequently call get_full_smb_filename() for the time being, but I
plan to eventually eliminate get_full_smb_filename().
2009-04-08 00:39:57 +04:00
smb_fname - > stream_name , streams [ i ] . name ) ) ;
if ( fname_equal ( smb_fname - > stream_name , streams [ i ] . name ,
2008-01-20 01:25:36 +03:00
conn - > case_sensitive ) ) {
DEBUGADD ( 10 , ( " equal \n " ) ) ;
break ;
}
DEBUGADD ( 10 , ( " not equal \n " ) ) ;
}
s3: Change unix_convert (and its callers) to use struct smb_filename
This is the first of a series of patches that change path based
operations to operate on a struct smb_filename instead of a char *.
This same concept already exists in source4.
My goals for this series of patches are to eventually:
1) Solve the stream vs. posix filename that contains a colon ambiguity
that currently exists.
2) Make unix_convert the only function that parses the stream name.
3) Clean up the unix_convert API.
4) Change all path based vfs operation to take a struct smb_filename.
5) Make is_ntfs_stream_name() a constant operation that can simply
check the state of struct smb_filename rather than re-parse the
filename.
6) Eliminate the need for split_ntfs_stream_name() to exist.
My strategy is to start from the inside at unix_convert() and work my
way out through the vfs layer, call by call. This first patch does
just that, by changing unix_convert and all of its callers to operate
on struct smb_filename. Since this is such a large change, I plan on
pushing the patches in phases, where each phase keeps full
compatibility and passes make test.
The API of unix_convert has been simplified from:
NTSTATUS unix_convert(TALLOC_CTX *ctx,
connection_struct *conn,
const char *orig_path,
bool allow_wcard_last_component,
char **pp_conv_path,
char **pp_saved_last_component,
SMB_STRUCT_STAT *pst)
to:
NTSTATUS unix_convert(TALLOC_CTX *ctx,
connection_struct *conn,
const char *orig_path,
struct smb_filename *smb_fname,
uint32_t ucf_flags)
Currently the smb_filename struct looks like:
struct smb_filename {
char *base_name;
char *stream_name;
char *original_lcomp;
SMB_STRUCT_STAT st;
};
One key point here is the decision to break up the base_name and
stream_name. I have introduced a helper function called
get_full_smb_filename() that takes an smb_filename struct and
allocates the full_name. I changed the callers of unix_convert() to
subsequently call get_full_smb_filename() for the time being, but I
plan to eventually eliminate get_full_smb_filename().
2009-04-08 00:39:57 +04:00
/* Couldn't find the stream. */
2008-01-20 01:25:36 +03:00
if ( i = = num_streams ) {
s3: Change unix_convert (and its callers) to use struct smb_filename
This is the first of a series of patches that change path based
operations to operate on a struct smb_filename instead of a char *.
This same concept already exists in source4.
My goals for this series of patches are to eventually:
1) Solve the stream vs. posix filename that contains a colon ambiguity
that currently exists.
2) Make unix_convert the only function that parses the stream name.
3) Clean up the unix_convert API.
4) Change all path based vfs operation to take a struct smb_filename.
5) Make is_ntfs_stream_name() a constant operation that can simply
check the state of struct smb_filename rather than re-parse the
filename.
6) Eliminate the need for split_ntfs_stream_name() to exist.
My strategy is to start from the inside at unix_convert() and work my
way out through the vfs layer, call by call. This first patch does
just that, by changing unix_convert and all of its callers to operate
on struct smb_filename. Since this is such a large change, I plan on
pushing the patches in phases, where each phase keeps full
compatibility and passes make test.
The API of unix_convert has been simplified from:
NTSTATUS unix_convert(TALLOC_CTX *ctx,
connection_struct *conn,
const char *orig_path,
bool allow_wcard_last_component,
char **pp_conv_path,
char **pp_saved_last_component,
SMB_STRUCT_STAT *pst)
to:
NTSTATUS unix_convert(TALLOC_CTX *ctx,
connection_struct *conn,
const char *orig_path,
struct smb_filename *smb_fname,
uint32_t ucf_flags)
Currently the smb_filename struct looks like:
struct smb_filename {
char *base_name;
char *stream_name;
char *original_lcomp;
SMB_STRUCT_STAT st;
};
One key point here is the decision to break up the base_name and
stream_name. I have introduced a helper function called
get_full_smb_filename() that takes an smb_filename struct and
allocates the full_name. I changed the callers of unix_convert() to
subsequently call get_full_smb_filename() for the time being, but I
plan to eventually eliminate get_full_smb_filename().
2009-04-08 00:39:57 +04:00
SET_STAT_INVALID ( smb_fname - > st ) ;
2008-01-20 01:25:36 +03:00
TALLOC_FREE ( streams ) ;
return NT_STATUS_OK ;
}
s3: Change unix_convert (and its callers) to use struct smb_filename
This is the first of a series of patches that change path based
operations to operate on a struct smb_filename instead of a char *.
This same concept already exists in source4.
My goals for this series of patches are to eventually:
1) Solve the stream vs. posix filename that contains a colon ambiguity
that currently exists.
2) Make unix_convert the only function that parses the stream name.
3) Clean up the unix_convert API.
4) Change all path based vfs operation to take a struct smb_filename.
5) Make is_ntfs_stream_name() a constant operation that can simply
check the state of struct smb_filename rather than re-parse the
filename.
6) Eliminate the need for split_ntfs_stream_name() to exist.
My strategy is to start from the inside at unix_convert() and work my
way out through the vfs layer, call by call. This first patch does
just that, by changing unix_convert and all of its callers to operate
on struct smb_filename. Since this is such a large change, I plan on
pushing the patches in phases, where each phase keeps full
compatibility and passes make test.
The API of unix_convert has been simplified from:
NTSTATUS unix_convert(TALLOC_CTX *ctx,
connection_struct *conn,
const char *orig_path,
bool allow_wcard_last_component,
char **pp_conv_path,
char **pp_saved_last_component,
SMB_STRUCT_STAT *pst)
to:
NTSTATUS unix_convert(TALLOC_CTX *ctx,
connection_struct *conn,
const char *orig_path,
struct smb_filename *smb_fname,
uint32_t ucf_flags)
Currently the smb_filename struct looks like:
struct smb_filename {
char *base_name;
char *stream_name;
char *original_lcomp;
SMB_STRUCT_STAT st;
};
One key point here is the decision to break up the base_name and
stream_name. I have introduced a helper function called
get_full_smb_filename() that takes an smb_filename struct and
allocates the full_name. I changed the callers of unix_convert() to
subsequently call get_full_smb_filename() for the time being, but I
plan to eventually eliminate get_full_smb_filename().
2009-04-08 00:39:57 +04:00
DEBUG ( 10 , ( " case insensitive stream. requested: %s, actual: %s \n " ,
smb_fname - > stream_name , streams [ i ] . name ) ) ;
2008-01-20 01:25:36 +03:00
s3: Change unix_convert (and its callers) to use struct smb_filename
This is the first of a series of patches that change path based
operations to operate on a struct smb_filename instead of a char *.
This same concept already exists in source4.
My goals for this series of patches are to eventually:
1) Solve the stream vs. posix filename that contains a colon ambiguity
that currently exists.
2) Make unix_convert the only function that parses the stream name.
3) Clean up the unix_convert API.
4) Change all path based vfs operation to take a struct smb_filename.
5) Make is_ntfs_stream_name() a constant operation that can simply
check the state of struct smb_filename rather than re-parse the
filename.
6) Eliminate the need for split_ntfs_stream_name() to exist.
My strategy is to start from the inside at unix_convert() and work my
way out through the vfs layer, call by call. This first patch does
just that, by changing unix_convert and all of its callers to operate
on struct smb_filename. Since this is such a large change, I plan on
pushing the patches in phases, where each phase keeps full
compatibility and passes make test.
The API of unix_convert has been simplified from:
NTSTATUS unix_convert(TALLOC_CTX *ctx,
connection_struct *conn,
const char *orig_path,
bool allow_wcard_last_component,
char **pp_conv_path,
char **pp_saved_last_component,
SMB_STRUCT_STAT *pst)
to:
NTSTATUS unix_convert(TALLOC_CTX *ctx,
connection_struct *conn,
const char *orig_path,
struct smb_filename *smb_fname,
uint32_t ucf_flags)
Currently the smb_filename struct looks like:
struct smb_filename {
char *base_name;
char *stream_name;
char *original_lcomp;
SMB_STRUCT_STAT st;
};
One key point here is the decision to break up the base_name and
stream_name. I have introduced a helper function called
get_full_smb_filename() that takes an smb_filename struct and
allocates the full_name. I changed the callers of unix_convert() to
subsequently call get_full_smb_filename() for the time being, but I
plan to eventually eliminate get_full_smb_filename().
2009-04-08 00:39:57 +04:00
TALLOC_FREE ( smb_fname - > stream_name ) ;
2009-07-22 20:52:09 +04:00
smb_fname - > stream_name = talloc_strdup ( smb_fname , streams [ i ] . name ) ;
if ( smb_fname - > stream_name = = NULL ) {
status = NT_STATUS_NO_MEMORY ;
goto fail ;
}
s3: Change unix_convert (and its callers) to use struct smb_filename
This is the first of a series of patches that change path based
operations to operate on a struct smb_filename instead of a char *.
This same concept already exists in source4.
My goals for this series of patches are to eventually:
1) Solve the stream vs. posix filename that contains a colon ambiguity
that currently exists.
2) Make unix_convert the only function that parses the stream name.
3) Clean up the unix_convert API.
4) Change all path based vfs operation to take a struct smb_filename.
5) Make is_ntfs_stream_name() a constant operation that can simply
check the state of struct smb_filename rather than re-parse the
filename.
6) Eliminate the need for split_ntfs_stream_name() to exist.
My strategy is to start from the inside at unix_convert() and work my
way out through the vfs layer, call by call. This first patch does
just that, by changing unix_convert and all of its callers to operate
on struct smb_filename. Since this is such a large change, I plan on
pushing the patches in phases, where each phase keeps full
compatibility and passes make test.
The API of unix_convert has been simplified from:
NTSTATUS unix_convert(TALLOC_CTX *ctx,
connection_struct *conn,
const char *orig_path,
bool allow_wcard_last_component,
char **pp_conv_path,
char **pp_saved_last_component,
SMB_STRUCT_STAT *pst)
to:
NTSTATUS unix_convert(TALLOC_CTX *ctx,
connection_struct *conn,
const char *orig_path,
struct smb_filename *smb_fname,
uint32_t ucf_flags)
Currently the smb_filename struct looks like:
struct smb_filename {
char *base_name;
char *stream_name;
char *original_lcomp;
SMB_STRUCT_STAT st;
};
One key point here is the decision to break up the base_name and
stream_name. I have introduced a helper function called
get_full_smb_filename() that takes an smb_filename struct and
allocates the full_name. I changed the callers of unix_convert() to
subsequently call get_full_smb_filename() for the time being, but I
plan to eventually eliminate get_full_smb_filename().
2009-04-08 00:39:57 +04:00
SET_STAT_INVALID ( smb_fname - > st ) ;
2008-01-20 01:25:36 +03:00
2009-06-23 02:26:56 +04:00
if ( SMB_VFS_STAT ( conn , smb_fname ) = = 0 ) {
2009-07-22 20:52:09 +04:00
DEBUG ( 10 , ( " '%s' exists \n " , smb_fname_str_dbg ( smb_fname ) ) ) ;
2009-06-23 02:26:56 +04:00
}
status = NT_STATUS_OK ;
2008-01-20 01:25:36 +03:00
fail :
TALLOC_FREE ( streams ) ;
return status ;
}
2009-06-19 00:13:38 +04:00
2009-07-24 23:13:07 +04:00
/**
* Go through all the steps to validate a filename .
*
* @ param ctx talloc_ctx to allocate memory with .
* @ param conn connection struct for vfs calls .
* @ param dfs_path Whether this path requires dfs resolution .
* @ param name_in The unconverted name .
* @ param ucf_flags flags to pass through to unix_convert ( ) .
2009-07-25 05:38:40 +04:00
* UCF_ALWAYS_ALLOW_WCARD_LCOMP will be OR ' d in if
* p_cont_wcard ! = NULL and is true and
* UCF_COND_ALLOW_WCARD_LCOMP .
2009-07-24 23:13:07 +04:00
* @ param p_cont_wcard If not NULL , will be set to true if the dfs path
* resolution detects a wildcard .
* @ param pp_smb_fname The final converted name will be allocated if the
* return is NT_STATUS_OK .
*
* @ return NT_STATUS_OK if all operations completed succesfully , appropriate
* error otherwise .
*/
2009-06-19 00:13:38 +04:00
NTSTATUS filename_convert ( TALLOC_CTX * ctx ,
connection_struct * conn ,
bool dfs_path ,
const char * name_in ,
2009-07-24 23:13:07 +04:00
uint32_t ucf_flags ,
bool * ppath_contains_wcard ,
2009-07-21 21:28:28 +04:00
struct smb_filename * * pp_smb_fname )
2009-06-19 00:13:38 +04:00
{
NTSTATUS status ;
2009-07-02 03:14:40 +04:00
char * fname = NULL ;
2009-06-19 00:13:38 +04:00
* pp_smb_fname = NULL ;
2009-07-24 23:13:07 +04:00
status = resolve_dfspath_wcard ( ctx , conn ,
2009-06-19 00:13:38 +04:00
dfs_path ,
name_in ,
2009-07-24 23:13:07 +04:00
& fname ,
ppath_contains_wcard ) ;
2009-06-19 00:13:38 +04:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
DEBUG ( 10 , ( " filename_convert: resolve_dfspath failed "
" for name %s with %s \n " ,
name_in ,
nt_errstr ( status ) ) ) ;
return status ;
}
2009-07-24 23:13:07 +04:00
2009-08-19 11:58:38 +04:00
if ( is_fake_file_path ( name_in ) ) {
SMB_STRUCT_STAT st ;
ZERO_STRUCT ( st ) ;
st . st_ex_nlink = 1 ;
status = create_synthetic_smb_fname_split ( ctx ,
name_in ,
& st ,
pp_smb_fname ) ;
return status ;
}
2009-07-24 23:13:07 +04:00
/*
2009-07-25 05:38:40 +04:00
* If the caller conditionally allows wildcard lookups , only add the
* always allow if the path actually does contain a wildcard .
2009-07-24 23:13:07 +04:00
*/
2009-07-25 05:38:40 +04:00
if ( ucf_flags & UCF_COND_ALLOW_WCARD_LCOMP & &
ppath_contains_wcard ! = NULL & & * ppath_contains_wcard ) {
ucf_flags | = UCF_ALWAYS_ALLOW_WCARD_LCOMP ;
2009-07-24 23:13:07 +04:00
}
status = unix_convert ( ctx , conn , fname , pp_smb_fname , ucf_flags ) ;
2009-06-19 00:13:38 +04:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
DEBUG ( 10 , ( " filename_convert: unix_convert failed "
" for name %s with %s \n " ,
2009-07-02 03:14:40 +04:00
fname ,
2009-06-19 00:13:38 +04:00
nt_errstr ( status ) ) ) ;
return status ;
}
2009-07-21 21:28:28 +04:00
status = check_name ( conn , ( * pp_smb_fname ) - > base_name ) ;
2009-06-19 00:13:38 +04:00
if ( ! NT_STATUS_IS_OK ( status ) ) {
DEBUG ( 3 , ( " filename_convert: check_name failed "
" for name %s with %s \n " ,
2009-07-21 21:28:28 +04:00
smb_fname_str_dbg ( * pp_smb_fname ) ,
2009-06-19 00:13:38 +04:00
nt_errstr ( status ) ) ) ;
2009-07-21 21:28:28 +04:00
TALLOC_FREE ( * pp_smb_fname ) ;
2009-06-19 00:13:38 +04:00
return status ;
}
2009-07-02 03:14:40 +04:00
2009-06-19 00:13:38 +04:00
return status ;
}