summaryrefslogtreecommitdiff
path: root/source3/libsmb
diff options
context:
space:
mode:
Diffstat (limited to 'source3/libsmb')
-rw-r--r--source3/libsmb/clidfs.c71
-rw-r--r--source3/libsmb/clilist.c10
-rw-r--r--source3/libsmb/clirap.c16
-rw-r--r--source3/libsmb/libsmbclient.c15
4 files changed, 62 insertions, 50 deletions
diff --git a/source3/libsmb/clidfs.c b/source3/libsmb/clidfs.c
index 93ac2ae58b..e2cfd12114 100644
--- a/source3/libsmb/clidfs.c
+++ b/source3/libsmb/clidfs.c
@@ -3,6 +3,7 @@
client connect/disconnect routines
Copyright (C) Andrew Tridgell 1994-1998
Copyright (C) Gerald (Jerry) Carter 2004
+ Copyright (C) Jeremy Allison 2007
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
@@ -21,6 +22,16 @@
#include "includes.h"
+/********************************************************************
+ Important point.
+
+ DFS paths are of the form \server\share\<pathname> (the \ characters
+ are not C escaped here).
+
+ - but if we're using POSIX paths then <pathname> may contain
+ '/' separators, not '\\' separators. So cope with '\\' or '/'
+ as a separator when looking at the pathname part.... JRA.
+********************************************************************/
struct client_connection {
struct client_connection *prev, *next;
@@ -194,7 +205,7 @@ static void cli_cm_set_mntpoint( struct cli_state *c, const char *mnt )
if ( p ) {
pstrcpy( p->mount, mnt );
- dos_clean_name( p->mount );
+ clean_name( p->mount );
}
}
@@ -427,7 +438,7 @@ static void clean_path( pstring clean, const char *path )
/* strip a trailing backslash */
len = strlen( newpath );
- if ( (len > 0) && (newpath[len-1] == '\\') )
+ if ( (len > 0) && (newpath[len-1] == '\\' || newpath[len-1] == '/') )
newpath[len-1] = '\0';
pstrcpy( clean, newpath );
@@ -462,7 +473,7 @@ BOOL cli_dfs_make_full_path( pstring path, const char *server, const char *share
}
directory = dir;
- if ( *directory == '\\' )
+ if ( *directory == '\\' || *directory == '/' )
directory++;
pstr_sprintf( path, "\\%s\\%s\\%s", server, sharename, directory );
@@ -597,8 +608,9 @@ BOOL cli_resolve_path( const char *mountpt, struct cli_state *rootcli, const cha
SMB_STRUCT_STAT sbuf;
uint32 attributes;
- if ( !rootcli || !path || !targetcli )
+ if ( !rootcli || !path || !targetcli ) {
return False;
+ }
*targetcli = NULL;
@@ -609,7 +621,7 @@ BOOL cli_resolve_path( const char *mountpt, struct cli_state *rootcli, const cha
/* don't bother continuing if this is not a dfs root */
- if ( !rootcli->dfsroot || cli_qpathinfo_basic( rootcli, cleanpath, &sbuf, &attributes ) ) {
+ if ( !rootcli->dfsroot || cli_qpathinfo_basic( rootcli, fullpath, &sbuf, &attributes ) ) {
*targetcli = rootcli;
pstrcpy( targetpath, path );
return True;
@@ -620,22 +632,23 @@ BOOL cli_resolve_path( const char *mountpt, struct cli_state *rootcli, const cha
if ( cli_dfs_check_error(rootcli, NT_STATUS_OBJECT_NAME_NOT_FOUND) ) {
*targetcli = rootcli;
pstrcpy( targetpath, path );
- return True;
+ goto done;
}
/* we got an error, check for DFS referral */
- if ( !cli_dfs_check_error(rootcli, NT_STATUS_PATH_NOT_COVERED) )
+ if ( !cli_dfs_check_error(rootcli, NT_STATUS_PATH_NOT_COVERED)) {
return False;
+ }
/* check for the referral */
- if ( !(cli_ipc = cli_cm_open( rootcli->desthost, "IPC$", False )) )
+ if ( !(cli_ipc = cli_cm_open( rootcli->desthost, "IPC$", False )) ) {
return False;
+ }
if ( !cli_dfs_get_referral(cli_ipc, fullpath, &refs, &num_refs, &consumed)
- || !num_refs )
- {
+ || !num_refs ) {
return False;
}
@@ -669,13 +682,28 @@ BOOL cli_resolve_path( const char *mountpt, struct cli_state *rootcli, const cha
/* trim off the \server\share\ */
fullpath[consumed/2] = '\0';
- dos_clean_name( fullpath );
- if ((ppath = strchr_m( fullpath, '\\' )) == NULL)
- return False;
- if ((ppath = strchr_m( ppath+1, '\\' )) == NULL)
+ clean_name( fullpath );
+ if ((ppath = strchr_m( fullpath, '\\' )) == NULL) {
return False;
- if ((ppath = strchr_m( ppath+1, '\\' )) == NULL)
+ }
+ if ((ppath = strchr_m( ppath+1, '\\' )) == NULL) {
return False;
+ }
+ {
+ char *p1, *p2;
+
+ /* Last component can be '\\' or '/' posix path. */
+
+ p1 = strchr_m( ppath+1, '\\' );
+ p2 = strchr_m( ppath+1, '/' );
+
+ ppath = MAX(p1,p2);
+
+ if (ppath == NULL) {
+ return False;
+ }
+ }
+
ppath++;
pstr_sprintf( newmount, "%s\\%s", mountpt, ppath );
@@ -684,13 +712,22 @@ BOOL cli_resolve_path( const char *mountpt, struct cli_state *rootcli, const cha
/* check for another dfs referral, note that we are not
checking for loops here */
- if ( !strequal( targetpath, "\\" ) ) {
+ if ( !strequal( targetpath, "\\" ) && !strequal( targetpath, "/")) {
if ( cli_resolve_path( newmount, *targetcli, targetpath, &newcli, newpath ) ) {
*targetcli = newcli;
pstrcpy( targetpath, newpath );
}
}
+ done:
+
+ /* If returning True ensure we return a dfs root full path. */
+ if ( (*targetcli)->dfsroot ) {
+ pstrcpy( fullpath, targetpath );
+ cli_dfs_make_full_path( targetpath, (*targetcli)->desthost,
+ (*targetcli)->share, fullpath);
+ }
+
return True;
}
@@ -736,7 +773,7 @@ BOOL cli_check_msdfs_proxy( struct cli_state *cli, const char *sharename,
}
cli->cnum = cnum;
-
+
if (!res || !num_refs ) {
SAFE_FREE( refs );
return False;
diff --git a/source3/libsmb/clilist.c b/source3/libsmb/clilist.c
index 22cb5930c2..3e76cd4775 100644
--- a/source3/libsmb/clilist.c
+++ b/source3/libsmb/clilist.c
@@ -44,6 +44,7 @@ static size_t interpret_long_filename(struct cli_state *cli, int level,char *p,f
*p_resume_key = 0;
}
memcpy(finfo,&def_finfo,sizeof(*finfo));
+ finfo->cli = cli;
switch (level) {
case 1: /* OS/2 understands this */
@@ -185,13 +186,7 @@ int cli_list_new(struct cli_state *cli,const char *Mask,uint16 attribute,
/* NT uses 260, OS/2 uses 2. Both accept 1. */
info_level = (cli->capabilities&CAP_NT_SMBS)?260:1;
- /* when getting a directory listing from a 2k dfs root share,
- we have to include the full path (\server\share\mask) here */
-
- if ( cli->dfsroot )
- pstr_sprintf( mask, "\\%s\\%s\\%s", cli->desthost, cli->share, Mask );
- else
- pstrcpy(mask,Mask);
+ pstrcpy(mask,Mask);
while (ff_eos == 0) {
loop_count++;
@@ -377,6 +372,7 @@ static int interpret_short_filename(struct cli_state *cli, char *p,file_info *fi
*finfo = def_finfo;
+ finfo->cli = cli;
finfo->mode = CVAL(p,21);
/* this date is converted to GMT by make_unix_date */
diff --git a/source3/libsmb/clirap.c b/source3/libsmb/clirap.c
index 61cdd79f36..ba4305dd0a 100644
--- a/source3/libsmb/clirap.c
+++ b/source3/libsmb/clirap.c
@@ -749,10 +749,10 @@ BOOL cli_qfileinfo(struct cli_state *cli, int fnum,
return True;
}
-
/****************************************************************************
-send a qpathinfo BASIC_INFO call
+ Send a qpathinfo BASIC_INFO call.
****************************************************************************/
+
BOOL cli_qpathinfo_basic( struct cli_state *cli, const char *name,
SMB_STRUCT_STAT *sbuf, uint32 *attributes )
{
@@ -765,18 +765,12 @@ BOOL cli_qpathinfo_basic( struct cli_state *cli, const char *name,
pstring path;
int len;
- /* send full paths to dfs root shares */
-
- if ( cli->dfsroot )
- pstr_sprintf(path, "\\%s\\%s\\%s", cli->desthost, cli->share, name );
- else
- pstrcpy( path, name );
-
+ pstrcpy( path, name );
/* cleanup */
len = strlen( path );
- if ( path[len] == '\\' )
- path[len] = '\0';
+ if ( path[len-1] == '\\' || path[len-1] == '/')
+ path[len-1] = '\0';
p = param;
memset(p, 0, 6);
diff --git a/source3/libsmb/libsmbclient.c b/source3/libsmb/libsmbclient.c
index b3c873145f..e8929c1589 100644
--- a/source3/libsmb/libsmbclient.c
+++ b/source3/libsmb/libsmbclient.c
@@ -1145,13 +1145,6 @@ smbc_open_ctx(SMBCCTX *context,
}
/*d_printf(">>>open: resolved %s as %s\n", path, targetpath);*/
- if ( targetcli->dfsroot )
- {
- pstring temppath;
- pstrcpy(temppath, targetpath);
- cli_dfs_make_full_path( targetpath, targetcli->desthost, targetcli->share, temppath);
- }
-
if ((fd = cli_open(targetcli, targetpath, flags,
context->internal->_share_mode)) < 0) {
@@ -1548,14 +1541,6 @@ smbc_getatr(SMBCCTX * context,
return False;
}
- if ( targetcli->dfsroot )
- {
- pstring temppath;
- pstrcpy(temppath, targetpath);
- cli_dfs_make_full_path(targetpath, targetcli->desthost,
- targetcli->share, temppath);
- }
-
if (!srv->no_pathinfo2 &&
cli_qpathinfo2(targetcli, targetpath,
create_time_ts,