summaryrefslogtreecommitdiff
path: root/source3/libsmb
diff options
context:
space:
mode:
authorJeremy Allison <jra@samba.org>2007-03-08 23:54:57 +0000
committerGerald (Jerry) Carter <jerry@samba.org>2007-10-10 12:18:30 -0500
commit540911001d1bf25d9534b72b90a32fc7e5efc4b0 (patch)
treee9ed5f9507e4d8b4980aadcc12a71796a1a93192 /source3/libsmb
parenta39f08eec29235d9b09c169e3a95eba0484c7847 (diff)
downloadsamba-540911001d1bf25d9534b72b90a32fc7e5efc4b0.tar.gz
samba-540911001d1bf25d9534b72b90a32fc7e5efc4b0.tar.bz2
samba-540911001d1bf25d9534b72b90a32fc7e5efc4b0.zip
r21768: Fix the client dfs code such that smbclient can
process deep dfs links (ie. links that go to non root parts of a share). Make the directory handling conanonical in POSIX and Windows pathname processing. dfs should not be fully working in client tools. Please bug me if not. Jeremy. (This used to be commit 1c9e10569cd97ee41de39f9f012bea4e4c932b5d)
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,