diff options
author | Gerald Carter <jerry@samba.org> | 2005-05-09 22:39:20 +0000 |
---|---|---|
committer | Gerald (Jerry) Carter <jerry@samba.org> | 2007-10-10 10:56:51 -0500 |
commit | 6a3a0766d5772a33d888c51ac4d68d2fa3e504ae (patch) | |
tree | 0a489cbabf5156bb2db6cc645e6c90d4770d50d6 | |
parent | 5df279f1444273fb8ba588d32f27f3239fa95e20 (diff) | |
download | samba-6a3a0766d5772a33d888c51ac4d68d2fa3e504ae.tar.gz samba-6a3a0766d5772a33d888c51ac4d68d2fa3e504ae.tar.bz2 samba-6a3a0766d5772a33d888c51ac4d68d2fa3e504ae.zip |
r6685: smbclient fixes
* BUG 2680: copy files from an MSDFS win2k root share
* BUG 2688: re-implement support for the -P (--port) option
* support connecting to an 'msdfs proxy' share on a Samba server
(This used to be commit 9e3e473632fee669eda477d8cbe309b7109552ea)
-rw-r--r-- | source3/client/client.c | 19 | ||||
-rw-r--r-- | source3/libsmb/clidfs.c | 69 |
2 files changed, 80 insertions, 8 deletions
diff --git a/source3/client/client.c b/source3/client/client.c index 9cb0d15a68..0ada2e3a9a 100644 --- a/source3/client/client.c +++ b/source3/client/client.c @@ -734,9 +734,19 @@ static int do_get(char *rname, char *lname, BOOL reget) return 1; } - 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) { @@ -3440,8 +3450,11 @@ static int do_message_op(void) poptGetArg(pc); - if ( have_ip ) - + /* check for the -P option */ + + if ( port != 0 ) + cli_cm_set_port( port ); + /* * Don't load debug level from smb.conf. It should be * set by cmdline arg or remain default (0) diff --git a/source3/libsmb/clidfs.c b/source3/libsmb/clidfs.c index 21046cd380..6d1e597410 100644 --- a/source3/libsmb/clidfs.c +++ b/source3/libsmb/clidfs.c @@ -59,6 +59,7 @@ static struct cli_state *do_connect( const char *server, const char *share, struct in_addr ip; pstring servicename; char *sharename; + fstring newserver, newshare; /* make a copy so we don't modify the global string 'service' */ pstrcpy(servicename, share); @@ -155,8 +156,19 @@ static struct cli_state *do_connect( const char *server, const char *share, } DEBUG(4,(" session setup ok\n")); - if (!cli_send_tconX(c, sharename, "?????", - password, strlen(password)+1)) { + /* here's the fun part....to support 'msdfs proxy' shares + (on Samba or windows) we have to issues a TRANS_GET_DFS_REFERRAL + here before trying to connect to the original share. + check_dfs_proxy() will fail if it is a normal share. */ + + if ( cli_check_msdfs_proxy( c, sharename, newserver, newshare ) ) { + cli_shutdown(c); + return do_connect( newserver, newshare, False ); + } + + /* must be a normal share */ + + if (!cli_send_tconX(c, sharename, "?????", password, strlen(password)+1)) { d_printf("tree connect failed: %s\n", cli_errstr(c)); cli_shutdown(c); return NULL; @@ -414,7 +426,7 @@ static void clean_path( pstring clean, const char *path ) /**************************************************************************** ****************************************************************************/ -static BOOL make_full_path( pstring path, const char *server, const char *share, +BOOL cli_dfs_make_full_path( pstring path, const char *server, const char *share, const char *dir ) { pstring servicename; @@ -583,7 +595,7 @@ BOOL cli_resolve_path( const char *mountpt, struct cli_state *rootcli, const cha /* send a trans2_query_path_info to check for a referral */ clean_path( cleanpath, path ); - make_full_path( fullpath, rootcli->desthost, rootcli->share, cleanpath ); + cli_dfs_make_full_path( fullpath, rootcli->desthost, rootcli->share, cleanpath ); /* don't bother continuing if this is not a dfs root */ @@ -612,7 +624,7 @@ BOOL cli_resolve_path( const char *mountpt, struct cli_state *rootcli, const cha /* just store the first referral for now Make sure to recreate the original string including any wildcards */ - make_full_path( fullpath, rootcli->desthost, rootcli->share, path ); + cli_dfs_make_full_path( fullpath, rootcli->desthost, rootcli->share, path ); pathlen = strlen( fullpath )*2; consumed = MIN(pathlen, consumed ); pstrcpy( targetpath, &fullpath[consumed/2] ); @@ -654,3 +666,50 @@ BOOL cli_resolve_path( const char *mountpt, struct cli_state *rootcli, const cha return True; } + +/******************************************************************** +********************************************************************/ + +BOOL cli_check_msdfs_proxy( struct cli_state *cli, const char *sharename, + fstring newserver, fstring newshare ) +{ + CLIENT_DFS_REFERRAL *refs = NULL; + size_t num_refs; + uint16 consumed; + struct cli_state *cli_ipc; + pstring fullpath; + + if ( !cli || !sharename ) + return False; + + /* special case. never check for a referral on the IPC$ share */ + + if ( strequal( sharename, "IPC$" ) ) + return False; + + /* send a trans2_query_path_info to check for a referral */ + + pstr_sprintf( fullpath, "\\%s\\%s", cli->desthost, sharename ); + + /* check for the referral */ + + if ( !(cli_ipc = cli_cm_open( cli->desthost, "IPC$", False )) ) + return False; + + if ( !cli_dfs_get_referral(cli_ipc, fullpath, &refs, &num_refs, &consumed) + || !num_refs ) + { + return False; + } + + split_dfs_path( refs[0].dfspath, newserver, newshare ); + + /* check that this is not a self-referral */ + + if ( strequal( cli->desthost, newserver ) && strequal( sharename, newshare ) ) + return False; + + SAFE_FREE( refs ); + + return True; +} |