mirror of
https://github.com/samba-team/samba.git
synced 2025-02-23 09:57:40 +03:00
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)
This commit is contained in:
parent
a39f08eec2
commit
540911001d
@ -271,19 +271,17 @@ static int do_cd(char *newdir)
|
||||
|
||||
pstrcpy(saved_dir, cur_dir);
|
||||
|
||||
if (*p == CLI_DIRSEP_CHAR)
|
||||
if (*p == CLI_DIRSEP_CHAR) {
|
||||
pstrcpy(cur_dir,p);
|
||||
else
|
||||
} else {
|
||||
pstrcat(cur_dir,p);
|
||||
|
||||
if ((cur_dir[0] != '\0') && (*(cur_dir+strlen(cur_dir)-1) != CLI_DIRSEP_CHAR)) {
|
||||
pstrcat(cur_dir, CLI_DIRSEP_STR);
|
||||
if ((cur_dir[0] != '\0') && (*(cur_dir+strlen(cur_dir)-1) != CLI_DIRSEP_CHAR)) {
|
||||
pstrcat(cur_dir, CLI_DIRSEP_STR);
|
||||
}
|
||||
}
|
||||
|
||||
dos_clean_name(cur_dir);
|
||||
clean_name(cur_dir);
|
||||
pstrcpy( dname, cur_dir );
|
||||
pstrcat(cur_dir,CLI_DIRSEP_STR);
|
||||
dos_clean_name(cur_dir);
|
||||
|
||||
if ( !cli_resolve_path( "", cli, dname, &targetcli, targetpath ) ) {
|
||||
d_printf("cd %s: %s\n", dname, cli_errstr(cli));
|
||||
@ -291,9 +289,9 @@ static int do_cd(char *newdir)
|
||||
goto out;
|
||||
}
|
||||
|
||||
|
||||
if ( strequal(targetpath,CLI_DIRSEP_STR ) )
|
||||
return 0;
|
||||
if (strequal(targetpath,CLI_DIRSEP_STR )) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Use a trans2_qpathinfo to test directories for modern servers.
|
||||
Except Win9x doesn't support the qpathinfo_basic() call..... */
|
||||
@ -312,7 +310,7 @@ static int do_cd(char *newdir)
|
||||
}
|
||||
} else {
|
||||
pstrcat( targetpath, CLI_DIRSEP_STR );
|
||||
dos_clean_name( targetpath );
|
||||
clean_name( targetpath );
|
||||
|
||||
if ( !cli_chkpath(targetcli, targetpath) ) {
|
||||
d_printf("cd %s: %s\n", dname, cli_errstr(targetcli));
|
||||
@ -398,25 +396,25 @@ static void display_finfo(file_info *finfo)
|
||||
return;
|
||||
/* create absolute filename for cli_nt_create() FIXME */
|
||||
pstrcpy( afname, cwd);
|
||||
pstrcat( afname, "\\");
|
||||
pstrcat( afname, CLI_DIRSEP_STR);
|
||||
pstrcat( afname, finfo->name);
|
||||
/* print file meta date header */
|
||||
d_printf( "FILENAME:%s\n", afname);
|
||||
d_printf( "MODE:%s\n", attrib_string(finfo->mode));
|
||||
d_printf( "SIZE:%.0f\n", (double)finfo->size);
|
||||
d_printf( "MTIME:%s", time_to_asc(t));
|
||||
fnum = cli_nt_create(cli, afname, CREATE_ACCESS_READ);
|
||||
fnum = cli_nt_create(finfo->cli, afname, CREATE_ACCESS_READ);
|
||||
if (fnum == -1) {
|
||||
DEBUG( 0, ("display_finfo() Failed to open %s: %s\n",
|
||||
afname,
|
||||
cli_errstr( cli)));
|
||||
cli_errstr( finfo->cli)));
|
||||
} else {
|
||||
SEC_DESC *sd = NULL;
|
||||
sd = cli_query_secdesc(cli, fnum, ctx);
|
||||
sd = cli_query_secdesc(finfo->cli, fnum, ctx);
|
||||
if (!sd) {
|
||||
DEBUG( 0, ("display_finfo() failed to "
|
||||
"get security descriptor: %s",
|
||||
cli_errstr( cli)));
|
||||
cli_errstr( finfo->cli)));
|
||||
} else {
|
||||
display_sec_desc(sd);
|
||||
}
|
||||
@ -591,7 +589,8 @@ static void do_list_helper(const char *mntpoint, file_info *f, const char *mask,
|
||||
return;
|
||||
p[1] = 0;
|
||||
pstrcat(mask2, f->name);
|
||||
pstrcat(mask2,"\\*");
|
||||
pstrcat(mask2,CLI_DIRSEP_STR);
|
||||
pstrcat(mask2,"*");
|
||||
add_to_do_list_queue(mask2);
|
||||
}
|
||||
return;
|
||||
@ -795,17 +794,6 @@ static int do_get(char *rname, char *lname, BOOL reget)
|
||||
|
||||
GetTimeOfDay(&tp_start);
|
||||
|
||||
if ( targetcli->dfsroot ) {
|
||||
pstring path;
|
||||
|
||||
/* we need to refer to the full \server\share\path format
|
||||
for dfs shares */
|
||||
|
||||
pstrcpy( path, targetname );
|
||||
cli_dfs_make_full_path( targetname, targetcli->desthost,
|
||||
targetcli->share, path);
|
||||
}
|
||||
|
||||
fnum = cli_open(targetcli, targetname, O_RDONLY, DENY_NONE);
|
||||
|
||||
if (fnum == -1) {
|
||||
@ -929,7 +917,7 @@ static int cmd_get(void)
|
||||
return 1;
|
||||
}
|
||||
pstrcpy(lname,p);
|
||||
dos_clean_name(rname);
|
||||
clean_name(rname);
|
||||
|
||||
next_token_nr(NULL,lname,NULL,sizeof(lname));
|
||||
|
||||
@ -1030,7 +1018,7 @@ static int cmd_more(void)
|
||||
unlink(lname);
|
||||
return 1;
|
||||
}
|
||||
dos_clean_name(rname);
|
||||
clean_name(rname);
|
||||
|
||||
rc = do_get(rname, lname, False);
|
||||
|
||||
@ -1160,14 +1148,20 @@ static int cmd_mkdir(void)
|
||||
if (recurse) {
|
||||
pstring ddir;
|
||||
pstring ddir2;
|
||||
struct cli_state *targetcli;
|
||||
pstring targetname;
|
||||
*ddir2 = 0;
|
||||
|
||||
pstrcpy(ddir,mask);
|
||||
if ( !cli_resolve_path( "", cli, mask, &targetcli, targetname ) ) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
pstrcpy(ddir,targetname);
|
||||
trim_char(ddir,'.','\0');
|
||||
p = strtok(ddir,"/\\");
|
||||
while (p) {
|
||||
pstrcat(ddir2,p);
|
||||
if (!cli_chkpath(cli, ddir2)) {
|
||||
if (!cli_chkpath(targetcli, ddir2)) {
|
||||
do_mkdir(ddir2);
|
||||
}
|
||||
pstrcat(ddir2,CLI_DIRSEP_STR);
|
||||
@ -1363,7 +1357,7 @@ static int cmd_put(void)
|
||||
else
|
||||
pstrcat(rname,lname);
|
||||
|
||||
dos_clean_name(rname);
|
||||
clean_name(rname);
|
||||
|
||||
{
|
||||
SMB_STRUCT_STAT st;
|
||||
@ -1677,13 +1671,13 @@ static void do_del(file_info *finfo)
|
||||
{
|
||||
pstring mask;
|
||||
|
||||
pstr_sprintf( mask, "%s\\%s", finfo->dir, finfo->name );
|
||||
pstr_sprintf( mask, "%s%c%s", finfo->dir, CLI_DIRSEP_CHAR, finfo->name );
|
||||
|
||||
if (finfo->mode & aDIR)
|
||||
return;
|
||||
|
||||
if (!cli_unlink(cli, mask)) {
|
||||
d_printf("%s deleting remote file %s\n",cli_errstr(cli),mask);
|
||||
if (!cli_unlink(finfo->cli, mask)) {
|
||||
d_printf("%s deleting remote file %s\n",cli_errstr(finfo->cli),mask);
|
||||
}
|
||||
}
|
||||
|
||||
@ -1722,6 +1716,8 @@ static int cmd_wdel(void)
|
||||
pstring mask;
|
||||
pstring buf;
|
||||
uint16 attribute;
|
||||
struct cli_state *targetcli;
|
||||
pstring targetname;
|
||||
|
||||
if (!next_token_nr(NULL,buf,NULL,sizeof(buf))) {
|
||||
d_printf("wdel 0x<attrib> <wcard>\n");
|
||||
@ -1738,8 +1734,13 @@ static int cmd_wdel(void)
|
||||
pstrcpy(mask,cur_dir);
|
||||
pstrcat(mask,buf);
|
||||
|
||||
if (!cli_unlink_full(cli, mask, attribute)) {
|
||||
d_printf("%s deleting remote files %s\n",cli_errstr(cli),mask);
|
||||
if ( !cli_resolve_path( "", cli, mask, &targetcli, targetname ) ) {
|
||||
d_printf("cmd_wdel %s: %s\n", mask, cli_errstr(cli));
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (!cli_unlink_full(targetcli, targetname, attribute)) {
|
||||
d_printf("%s deleting remote files %s\n",cli_errstr(targetcli),targetname);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@ -1854,7 +1855,7 @@ static int cmd_posix_mkdir(void)
|
||||
d_printf("posix_mkdir %s: %s\n", mask, cli_errstr(cli));
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
fnum = cli_posix_mkdir(targetcli, targetname, mode);
|
||||
if (fnum == -1) {
|
||||
d_printf("Failed to open file %s. %s\n", targetname, cli_errstr(cli));
|
||||
@ -2160,6 +2161,8 @@ static int cmd_symlink(void)
|
||||
{
|
||||
pstring oldname,newname;
|
||||
pstring buf,buf2;
|
||||
struct cli_state *targetcli;
|
||||
pstring targetname;
|
||||
|
||||
if (!SERVER_HAS_UNIX_CIFS(cli)) {
|
||||
d_printf("Server doesn't support UNIX CIFS calls.\n");
|
||||
@ -2177,9 +2180,14 @@ static int cmd_symlink(void)
|
||||
pstrcpy(oldname,buf);
|
||||
pstrcat(newname,buf2);
|
||||
|
||||
if (!cli_unix_symlink(cli, oldname, newname)) {
|
||||
if ( !cli_resolve_path( "", cli, oldname, &targetcli, targetname ) ) {
|
||||
d_printf("link %s: %s\n", oldname, cli_errstr(cli));
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (!cli_unix_symlink(targetcli, targetname, newname)) {
|
||||
d_printf("%s symlinking files (%s -> %s)\n",
|
||||
cli_errstr(cli), newname, oldname);
|
||||
cli_errstr(targetcli), newname, targetname);
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -2377,7 +2385,6 @@ static int cmd_getfacl(void)
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
if (!cli_unix_stat(targetcli, targetname, &sbuf)) {
|
||||
d_printf("%s getfacl doing a stat on file %s\n",
|
||||
cli_errstr(targetcli), src);
|
||||
@ -2619,7 +2626,6 @@ static int cmd_chown(void)
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
if (!SERVER_HAS_UNIX_CIFS(targetcli)) {
|
||||
d_printf("Server doesn't support UNIX CIFS calls.\n");
|
||||
return 1;
|
||||
@ -2642,6 +2648,8 @@ static int cmd_rename(void)
|
||||
{
|
||||
pstring src,dest;
|
||||
pstring buf,buf2;
|
||||
struct cli_state *targetcli;
|
||||
pstring targetname;
|
||||
|
||||
pstrcpy(src,cur_dir);
|
||||
pstrcpy(dest,cur_dir);
|
||||
@ -2655,8 +2663,13 @@ static int cmd_rename(void)
|
||||
pstrcat(src,buf);
|
||||
pstrcat(dest,buf2);
|
||||
|
||||
if (!cli_rename(cli, src, dest)) {
|
||||
d_printf("%s renaming files\n",cli_errstr(cli));
|
||||
if ( !cli_resolve_path( "", cli, src, &targetcli, targetname ) ) {
|
||||
d_printf("chown %s: %s\n", src, cli_errstr(cli));
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (!cli_rename(targetcli, targetname, dest)) {
|
||||
d_printf("%s renaming files\n",cli_errstr(targetcli));
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -2885,7 +2898,7 @@ static int cmd_reget(void)
|
||||
return 1;
|
||||
}
|
||||
pstrcpy(local_name, p);
|
||||
dos_clean_name(remote_name);
|
||||
clean_name(remote_name);
|
||||
|
||||
next_token_nr(NULL, local_name, NULL, sizeof(local_name));
|
||||
|
||||
@ -2923,7 +2936,7 @@ static int cmd_reput(void)
|
||||
else
|
||||
pstrcat(remote_name, local_name);
|
||||
|
||||
dos_clean_name(remote_name);
|
||||
clean_name(remote_name);
|
||||
|
||||
return do_put(remote_name, local_name, True);
|
||||
}
|
||||
|
@ -652,7 +652,7 @@ static void do_atar(char *rname,char *lname,file_info *finfo1)
|
||||
|
||||
fnum = cli_open(cli, rname, O_RDONLY, DENY_NONE);
|
||||
|
||||
dos_clean_name(rname);
|
||||
clean_name(rname);
|
||||
|
||||
if (fnum == -1) {
|
||||
DEBUG(0,("%s opening remote file %s (%s)\n",
|
||||
|
@ -368,7 +368,7 @@ static int do_cd(char *newdir)
|
||||
all_string_sub(cur_dir, "/./", "/", 0);
|
||||
|
||||
/* Format the directory in a libmsmbclient friendly way */
|
||||
unix_clean_name(cur_dir);
|
||||
clean_name(cur_dir);
|
||||
all_string_sub(cur_dir, "/./", "/", 0);
|
||||
pstrcpy(targetpath, "smb:");
|
||||
pstrcat(targetpath, service);
|
||||
@ -1130,7 +1130,7 @@ static int cmd_more(void)
|
||||
unlink(lname);
|
||||
return 1;
|
||||
}
|
||||
dos_clean_name(rname);
|
||||
clean_name(rname);
|
||||
|
||||
rc = do_get(rname, lname, False);
|
||||
|
||||
@ -2678,7 +2678,7 @@ static int cmd_reget(void)
|
||||
return 1;
|
||||
}
|
||||
pstrcpy(local_name, p);
|
||||
dos_clean_name(remote_name);
|
||||
clean_name(remote_name);
|
||||
|
||||
next_token_nr(NULL, local_name, NULL, sizeof(local_name));
|
||||
|
||||
@ -2716,7 +2716,7 @@ static int cmd_reput(void)
|
||||
else
|
||||
pstrcat(remote_name, local_name);
|
||||
|
||||
dos_clean_name(remote_name);
|
||||
clean_name(remote_name);
|
||||
|
||||
return do_put(remote_name, local_name, True);
|
||||
}
|
||||
|
@ -34,21 +34,6 @@
|
||||
* These definitions depend on smb.h
|
||||
*/
|
||||
|
||||
typedef struct file_info
|
||||
{
|
||||
SMB_BIG_UINT size;
|
||||
uint16 mode;
|
||||
uid_t uid;
|
||||
gid_t gid;
|
||||
/* these times are normally kept in GMT */
|
||||
struct timespec mtime_ts;
|
||||
struct timespec atime_ts;
|
||||
struct timespec ctime_ts;
|
||||
pstring name;
|
||||
pstring dir;
|
||||
char short_name[13*3]; /* the *3 is to cope with multi-byte */
|
||||
} file_info;
|
||||
|
||||
struct print_job_info
|
||||
{
|
||||
uint16 id;
|
||||
@ -173,6 +158,21 @@ struct cli_state {
|
||||
BOOL case_sensitive; /* False by default. */
|
||||
};
|
||||
|
||||
typedef struct file_info {
|
||||
struct cli_state *cli;
|
||||
SMB_BIG_UINT size;
|
||||
uint16 mode;
|
||||
uid_t uid;
|
||||
gid_t gid;
|
||||
/* these times are normally kept in GMT */
|
||||
struct timespec mtime_ts;
|
||||
struct timespec atime_ts;
|
||||
struct timespec ctime_ts;
|
||||
pstring name;
|
||||
pstring dir;
|
||||
char short_name[13*3]; /* the *3 is to cope with multi-byte */
|
||||
} file_info;
|
||||
|
||||
#define CLI_FULL_CONNECTION_DONT_SPNEGO 0x0001
|
||||
#define CLI_FULL_CONNECTION_USE_KERBEROS 0x0002
|
||||
#define CLI_FULL_CONNECTION_ANONYMOUS_FALLBACK 0x0004
|
||||
|
@ -579,6 +579,13 @@ void dos_clean_name(char *s)
|
||||
/* remove any double slashes */
|
||||
all_string_sub(s, "\\\\", "\\", 0);
|
||||
|
||||
/* Remove leading .\\ characters */
|
||||
if(strncmp(s, ".\\", 2) == 0) {
|
||||
trim_string(s, ".\\", NULL);
|
||||
if(*s == 0)
|
||||
pstrcpy(s,".\\");
|
||||
}
|
||||
|
||||
while ((p = strstr_m(s,"\\..\\")) != NULL) {
|
||||
pstring s1;
|
||||
|
||||
@ -593,7 +600,6 @@ void dos_clean_name(char *s)
|
||||
}
|
||||
|
||||
trim_string(s,NULL,"\\..");
|
||||
|
||||
all_string_sub(s, "\\.\\", "\\", 0);
|
||||
}
|
||||
|
||||
@ -631,6 +637,13 @@ void unix_clean_name(char *s)
|
||||
}
|
||||
|
||||
trim_string(s,NULL,"/..");
|
||||
all_string_sub(s, "/./", "/", 0);
|
||||
}
|
||||
|
||||
void clean_name(char *s)
|
||||
{
|
||||
dos_clean_name(s);
|
||||
unix_clean_name(s);
|
||||
}
|
||||
|
||||
/*******************************************************************
|
||||
|
@ -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)
|
||||
clean_name( fullpath );
|
||||
if ((ppath = strchr_m( fullpath, '\\' )) == NULL) {
|
||||
return False;
|
||||
if ((ppath = strchr_m( ppath+1, '\\' )) == 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;
|
||||
|
@ -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 */
|
||||
|
@ -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);
|
||||
|
@ -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,
|
||||
|
@ -3507,15 +3507,23 @@ static void copy_fn(const char *mnt, file_info *f, const char *mask, void *state
|
||||
**/
|
||||
BOOL sync_files(struct copy_clistate *cp_clistate, pstring mask)
|
||||
{
|
||||
struct cli_state *targetcli;
|
||||
pstring targetpath;
|
||||
|
||||
DEBUG(3,("calling cli_list with mask: %s\n", mask));
|
||||
|
||||
if (cli_list(cp_clistate->cli_share_src, mask, cp_clistate->attribute, copy_fn, cp_clistate) == -1) {
|
||||
d_fprintf(stderr, "listing %s failed with error: %s\n",
|
||||
if ( !cli_resolve_path( "", cp_clistate->cli_share_src, mask, &targetcli, targetpath ) ) {
|
||||
d_fprintf(stderr, "cli_resolve_path %s failed with error: %s\n",
|
||||
mask, cli_errstr(cp_clistate->cli_share_src));
|
||||
return False;
|
||||
}
|
||||
|
||||
if (cli_list(targetcli, targetpath, cp_clistate->attribute, copy_fn, cp_clistate) == -1) {
|
||||
d_fprintf(stderr, "listing %s failed with error: %s\n",
|
||||
mask, cli_errstr(targetcli));
|
||||
return False;
|
||||
}
|
||||
|
||||
return True;
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user