diff options
Diffstat (limited to 'source3/libsmb')
-rw-r--r-- | source3/libsmb/clidfs.c | 71 | ||||
-rw-r--r-- | source3/libsmb/clilist.c | 10 | ||||
-rw-r--r-- | source3/libsmb/clirap.c | 16 | ||||
-rw-r--r-- | source3/libsmb/libsmbclient.c | 15 |
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, |