diff options
author | Gerald Carter <jerry@samba.org> | 2005-02-24 21:54:52 +0000 |
---|---|---|
committer | Gerald (Jerry) Carter <jerry@samba.org> | 2007-10-10 10:55:46 -0500 |
commit | 038d939c2aeafcf6e0cd174d5509588e6f953f32 (patch) | |
tree | 1523c3f58340f293918d8beecb053750477903e3 | |
parent | 413eb87493d5f4c2ed8e1f674b223e270fcb3667 (diff) | |
download | samba-038d939c2aeafcf6e0cd174d5509588e6f953f32.tar.gz samba-038d939c2aeafcf6e0cd174d5509588e6f953f32.tar.bz2 samba-038d939c2aeafcf6e0cd174d5509588e6f953f32.zip |
r5545: move cli_cm_XXX() connection handling code to clidfs and out of client.c; client.c still maintains a pointer to the first connection so the change is fairly reansparent to other smbclient functions such as -L and -M
(This used to be commit d6a05ffd664e2e304f6e481af34a4c5d640fc3f9)
-rw-r--r-- | source3/Makefile.in | 4 | ||||
-rw-r--r-- | source3/client/client.c | 300 | ||||
-rw-r--r-- | source3/libsmb/clidfs.c | 278 |
3 files changed, 307 insertions, 275 deletions
diff --git a/source3/Makefile.in b/source3/Makefile.in index 81ed0a3779..eb39dbf88b 100644 --- a/source3/Makefile.in +++ b/source3/Makefile.in @@ -245,7 +245,7 @@ LIBSMB_OBJ = libsmb/clientgen.o libsmb/cliconnect.o libsmb/clifile.o \ libsmb/clireadwrite.o libsmb/clilist.o libsmb/cliprint.o \ libsmb/clitrans.o libsmb/clisecdesc.o libsmb/clidgram.o \ libsmb/clistr.o lib/util_seaccess.o \ - libsmb/cliquota.o libsmb/clifsinfo.o \ + libsmb/cliquota.o libsmb/clifsinfo.o libsmb/clidfs.o \ libsmb/smberr.o libsmb/credentials.o libsmb/pwd_cache.o \ libsmb/clioplock.o $(ERRORMAP_OBJ) libsmb/clirap2.o \ $(DOSERR_OBJ) \ @@ -522,7 +522,7 @@ LIBBIGBALLOFMUD_OBJ = $(PARAM_OBJ) $(LIB_NONSMBD_OBJ) $(UBIQX_OBJ) $(SECRETS_OBJ LIBBIGBALLOFMUD_PICOBJS = $(LIBBIGBALLOFMUD_OBJ:.o=.@PICSUFFIX@) -CLIENT_OBJ1 = client/client.o client/clitar.o libsmb/clidfs.o +CLIENT_OBJ1 = client/client.o client/clitar.o CLIENT_OBJ = $(CLIENT_OBJ1) $(PARAM_OBJ) $(LIBSMB_OBJ) \ $(LIB_NONSMBD_OBJ) $(KRBCLIENT_OBJ) \ diff --git a/source3/client/client.c b/source3/client/client.c index 6a9e57f86f..55e9f1a71d 100644 --- a/source3/client/client.c +++ b/source3/client/client.c @@ -36,10 +36,7 @@ static pstring cd_path = ""; static pstring service; static pstring desthost; static pstring username; -static pstring password; static pstring calling_name; -static BOOL use_kerberos; -static BOOL got_pass; static BOOL grepable=False; static char *cmdstr = NULL; @@ -62,7 +59,6 @@ time_t newer_than = 0; static int archive_level = 0; static BOOL translation = False; - static BOOL have_ip; /* clitar bits insert */ @@ -98,251 +94,11 @@ static unsigned int put_total_time_ms = 0; /* totals globals */ static double dir_total; - -struct client_connection { - struct client_connection *prev, *next; - struct client_connection *parent; - struct cli_state *cli; - pstring mntpath; -}; +/* root cli_state connection */ struct cli_state *cli; -static struct client_connection *connections; -/******************************************************************** - Return a connection to a server. -********************************************************************/ -static struct cli_state *do_connect( const char *server, const char *share, - BOOL show_sessetup ) -{ - struct cli_state *c; - struct nmb_name called, calling; - const char *server_n; - struct in_addr ip; - pstring servicename; - char *sharename; - - /* make a copy so we don't modify the global string 'service' */ - pstrcpy(servicename, share); - sharename = servicename; - if (*sharename == '\\') { - server = sharename+2; - sharename = strchr_m(server,'\\'); - if (!sharename) return NULL; - *sharename = 0; - sharename++; - } - - server_n = server; - - zero_ip(&ip); - - make_nmb_name(&calling, calling_name, 0x0); - make_nmb_name(&called , server, name_type); - - again: - zero_ip(&ip); - if (have_ip) ip = dest_ip; - - /* have to open a new connection */ - if (!(c=cli_initialise(NULL)) || (cli_set_port(c, port) != port) || - !cli_connect(c, server_n, &ip)) { - d_printf("Connection to %s failed\n", server_n); - return NULL; - } - - c->protocol = max_protocol; - c->use_kerberos = use_kerberos; - cli_setup_signing_state(c, cmdline_auth_info.signing_state); - - - if (!cli_session_request(c, &calling, &called)) { - char *p; - d_printf("session request to %s failed (%s)\n", - called.name, cli_errstr(c)); - cli_shutdown(c); - if ((p=strchr_m(called.name, '.'))) { - *p = 0; - goto again; - } - if (strcmp(called.name, "*SMBSERVER")) { - make_nmb_name(&called , "*SMBSERVER", 0x20); - goto again; - } - return NULL; - } - - DEBUG(4,(" session request ok\n")); - - if (!cli_negprot(c)) { - d_printf("protocol negotiation failed\n"); - cli_shutdown(c); - return NULL; - } - - if (!got_pass) { - char *pass = getpass("Password: "); - if (pass) { - pstrcpy(password, pass); - got_pass = 1; - } - } - - if (!cli_session_setup(c, username, - password, strlen(password), - password, strlen(password), - lp_workgroup())) { - /* if a password was not supplied then try again with a null username */ - if (password[0] || !username[0] || use_kerberos || - !cli_session_setup(c, "", "", 0, "", 0, lp_workgroup())) { - d_printf("session setup failed: %s\n", cli_errstr(c)); - if (NT_STATUS_V(cli_nt_error(c)) == - NT_STATUS_V(NT_STATUS_MORE_PROCESSING_REQUIRED)) - d_printf("did you forget to run kinit?\n"); - cli_shutdown(c); - return NULL; - } - d_printf("Anonymous login successful\n"); - } - - if ( show_sessetup ) { - if (*c->server_domain) { - DEBUG(1,("Domain=[%s] OS=[%s] Server=[%s]\n", - c->server_domain,c->server_os,c->server_type)); - } else if (*c->server_os || *c->server_type){ - DEBUG(1,("OS=[%s] Server=[%s]\n", - c->server_os,c->server_type)); - } - } - DEBUG(4,(" session setup ok\n")); - - 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; - } - - DEBUG(4,(" tconx ok\n")); - - return c; -} - -/******************************************************************** - Add a new connection to the list -********************************************************************/ - -static struct cli_state* cli_cm_connect( const char *server, const char *share, - BOOL show_hdr ) -{ - struct client_connection *node, *pparent, *p; - - node = SMB_XMALLOC_P( struct client_connection ); - - node->cli = do_connect( server, share, show_hdr ); - - if ( !node->cli ) { - SAFE_FREE( node ); - return NULL; - } - - pparent = NULL; - for ( p=connections; p; p=p->next ) { - if ( strequal(cli->desthost, p->cli->desthost) && strequal(cli->share, p->cli->share) ) - pparent = p; - } - - node->parent = pparent; - pstrcpy( node->mntpath, cur_dir ); - - DLIST_ADD( connections, node ); - - return node->cli; - -} - -/******************************************************************** - Return a connection to a server. -********************************************************************/ - -static struct cli_state* cli_cm_find( const char *server, const char *share ) -{ - struct client_connection *p; - - for ( p=connections; p; p=p->next ) { - if ( strequal(server, p->cli->desthost) && strequal(share,p->cli->share) ) - return p->cli; - } - - return NULL; -} - -/**************************************************************************** - open a client connection to a \\server\share. Set's the current *cli - global variable as a side-effect (but only if the connection is successful). -****************************************************************************/ - -struct cli_state* cli_cm_open( const char *server, const char *share, BOOL show_hdr ) -{ - struct cli_state *c; - - /* try to reuse an existing connection */ - - c = cli_cm_find( server, share ); - - if ( !c ) - c = cli_cm_connect( server, share, show_hdr ); - - return c; -} - -/**************************************************************************** -****************************************************************************/ - -struct cli_state* cli_cm_current( void ) -{ - return cli; -} - -/**************************************************************************** -****************************************************************************/ - -static void cli_cm_shutdown( void ) -{ - - struct client_connection *p, *x; - - for ( p=connections; p; ) { - cli_shutdown( p->cli ); - x = p; - p = p->next; - - SAFE_FREE( x ); - } - - connections = NULL; - - return; -} - -/**************************************************************************** -****************************************************************************/ - -const char* cli_cm_get_mntpath( struct cli_state *pcli ) -{ - struct client_connection *p; - - for ( p=connections; p; p=p->next ) { - if ( strequal(pcli->desthost, p->cli->desthost) && strequal(pcli->share, p->cli->share) ) - break; - } - - if ( !p ) - return NULL; - - return p->mntpath; -} /**************************************************************************** Write to a local file with CR/LF->LF translation if appropriate. Return the @@ -500,7 +256,6 @@ static int do_cd(char *newdir) struct cli_state *targetcli; SMB_STRUCT_STAT sbuf; uint32 attributes; - pstring fullpath; dos_format(newdir); @@ -2870,15 +2625,14 @@ static int cmd_logon(void) pstrcpy(l_username, buf); - if (!next_token_nr(NULL,buf2,NULL,sizeof(buf))) { + if (!next_token_nr(NULL,buf2,NULL,sizeof(buf))) + { char *pass = getpass("Password: "); - if (pass) { + if (pass) pstrcpy(l_password, pass); - got_pass = 1; - } - } else { + } + else pstrcpy(l_password, buf2); - } if (!cli_session_setup(cli, l_username, l_password, strlen(l_password), @@ -2899,13 +2653,7 @@ static int cmd_logon(void) static int cmd_list_connect(void) { - struct client_connection *p; - int i; - - for ( p=connections,i=0; p; p=p->next,i++ ) { - d_printf("%d:\tserver=%s, share=%s\n", - i, p->cli->desthost, p->cli->share ); - } + cli_cm_display(); return 0; } @@ -3075,7 +2823,7 @@ static int process_command_string(char *cmd) /* establish the connection if not already */ if (!cli) { - cli = cli_cm_connect(desthost, service, True); + cli = cli_cm_open(desthost, service, True); if (!cli) return 0; } @@ -3391,7 +3139,7 @@ static int process(char *base_directory) { int rc = 0; - cli = cli_cm_connect(desthost, service, True); + cli = cli_cm_open(desthost, service, True); if (!cli) { return 1; } @@ -3414,7 +3162,7 @@ static int process(char *base_directory) static int do_host_query(char *query_host) { - cli = cli_cm_connect(query_host, "IPC$", True); + cli = cli_cm_open(query_host, "IPC$", True); if (!cli) return 1; @@ -3426,8 +3174,8 @@ static int do_host_query(char *query_host) else but port 139... */ cli_cm_shutdown(); - port = 139; - cli = cli_cm_connect(query_host, "IPC$", True); + cli_cm_set_port( 139 ); + cli = cli_cm_open(query_host, "IPC$", True); } if (cli == NULL) { @@ -3452,7 +3200,7 @@ static int do_tar_op(char *base_directory) /* do we already have a connection? */ if (!cli) { - cli = cli_cm_connect(desthost, service, True); + cli = cli_cm_open(desthost, service, True); if (!cli) return 1; } @@ -3487,7 +3235,8 @@ static int do_message_op(void) fstrcat(server_name, name_type_hex); zero_ip(&ip); - if (have_ip) ip = dest_ip; + if (have_ip) + ip = dest_ip; if (!(cli=cli_initialise(NULL)) || (cli_set_port(cli, port) != port) || !cli_connect(cli, server_name, &ip)) { @@ -3585,9 +3334,10 @@ static int do_message_op(void) * to port 139 instead of port 445. srl,crh */ name_type = 0x03; + cli_cm_set_dest_name_type( name_type ); pstrcpy(desthost,poptGetOptArg(pc)); - if( 0 == port ) - port = 139; + if( !port ) + cli_cm_set_port( 139 ); message = True; break; case 'I': @@ -3596,6 +3346,8 @@ static int do_message_op(void) if (is_zero_ip(dest_ip)) exit(1); have_ip = True; + + cli_cm_set_dest_ip( dest_ip ); } break; case 'E': @@ -3644,6 +3396,8 @@ static int do_message_op(void) } poptGetArg(pc); + + if ( have_ip ) /* * Don't load debug level from smb.conf. It should be @@ -3705,11 +3459,10 @@ static int do_message_op(void) poptFreeContext(pc); - pstrcpy(username, cmdline_auth_info.username); - pstrcpy(password, cmdline_auth_info.password); + /* store the username an password for dfs support */ - use_kerberos = cmdline_auth_info.use_kerberos; - got_pass = cmdline_auth_info.got_pass; + cli_cm_set_credentials( &cmdline_auth_info ); + pstrcpy(username, cmdline_auth_info.username); DEBUG(3,("Client started (version %s).\n", SAMBA_VERSION_STRING)); @@ -3735,8 +3488,9 @@ static int do_message_op(void) *p = 0; p++; sscanf(p, "%x", &name_type); + cli_cm_set_dest_name_type( name_type ); } - + return do_host_query(qhost); } diff --git a/source3/libsmb/clidfs.c b/source3/libsmb/clidfs.c index 6d0d4a8edf..1b0860b675 100644 --- a/source3/libsmb/clidfs.c +++ b/source3/libsmb/clidfs.c @@ -1,6 +1,7 @@ /* Unix SMB/CIFS implementation. client connect/disconnect routines + Copyright (C) Andrew Tridgell 1994-1998 Copyright (C) Gerald (Jerry) Carter 2004 This program is free software; you can redistribute it and/or modify @@ -23,6 +24,283 @@ #include "includes.h" +struct client_connection { + struct client_connection *prev, *next; + struct cli_state *cli; +}; + +/* global state....globals reek! */ + +static pstring username; +static pstring password; +static BOOL use_kerberos; +static BOOL got_pass; +static int signing_state; + +static int port; +static int name_type = 0x20; +static int max_protocol = PROTOCOL_NT1; +static BOOL have_ip; +static struct in_addr dest_ip; + +static struct client_connection *connections; + +/******************************************************************** + Return a connection to a server. +********************************************************************/ + +static struct cli_state *do_connect( const char *server, const char *share, + BOOL show_sessetup ) +{ + struct cli_state *c; + struct nmb_name called, calling; + const char *server_n; + struct in_addr ip; + pstring servicename; + char *sharename; + + /* make a copy so we don't modify the global string 'service' */ + pstrcpy(servicename, share); + sharename = servicename; + if (*sharename == '\\') { + server = sharename+2; + sharename = strchr_m(server,'\\'); + if (!sharename) return NULL; + *sharename = 0; + sharename++; + } + + server_n = server; + + zero_ip(&ip); + + make_nmb_name(&calling, global_myname(), 0x0); + make_nmb_name(&called , server, name_type); + + again: + zero_ip(&ip); + if (have_ip) + ip = dest_ip; + + /* have to open a new connection */ + if (!(c=cli_initialise(NULL)) || (cli_set_port(c, port) != port) || + !cli_connect(c, server_n, &ip)) { + d_printf("Connection to %s failed\n", server_n); + return NULL; + } + + c->protocol = max_protocol; + c->use_kerberos = use_kerberos; + cli_setup_signing_state(c, signing_state); + + + if (!cli_session_request(c, &calling, &called)) { + char *p; + d_printf("session request to %s failed (%s)\n", + called.name, cli_errstr(c)); + cli_shutdown(c); + if ((p=strchr_m(called.name, '.'))) { + *p = 0; + goto again; + } + if (strcmp(called.name, "*SMBSERVER")) { + make_nmb_name(&called , "*SMBSERVER", 0x20); + goto again; + } + return NULL; + } + + DEBUG(4,(" session request ok\n")); + + if (!cli_negprot(c)) { + d_printf("protocol negotiation failed\n"); + cli_shutdown(c); + return NULL; + } + + if (!got_pass) { + char *pass = getpass("Password: "); + if (pass) { + pstrcpy(password, pass); + got_pass = 1; + } + } + + if (!cli_session_setup(c, username, + password, strlen(password), + password, strlen(password), + lp_workgroup())) { + /* if a password was not supplied then try again with a null username */ + if (password[0] || !username[0] || use_kerberos || + !cli_session_setup(c, "", "", 0, "", 0, lp_workgroup())) { + d_printf("session setup failed: %s\n", cli_errstr(c)); + if (NT_STATUS_V(cli_nt_error(c)) == + NT_STATUS_V(NT_STATUS_MORE_PROCESSING_REQUIRED)) + d_printf("did you forget to run kinit?\n"); + cli_shutdown(c); + return NULL; + } + d_printf("Anonymous login successful\n"); + } + + if ( show_sessetup ) { + if (*c->server_domain) { + DEBUG(1,("Domain=[%s] OS=[%s] Server=[%s]\n", + c->server_domain,c->server_os,c->server_type)); + } else if (*c->server_os || *c->server_type){ + DEBUG(1,("OS=[%s] Server=[%s]\n", + c->server_os,c->server_type)); + } + } + DEBUG(4,(" session setup ok\n")); + + 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; + } + + DEBUG(4,(" tconx ok\n")); + + return c; +} + +/******************************************************************** + Add a new connection to the list +********************************************************************/ + +static struct cli_state* cli_cm_connect( const char *server, const char *share, + BOOL show_hdr ) +{ + struct client_connection *node; + + node = SMB_XMALLOC_P( struct client_connection ); + + node->cli = do_connect( server, share, show_hdr ); + + if ( !node->cli ) { + SAFE_FREE( node ); + return NULL; + } + + DLIST_ADD( connections, node ); + + return node->cli; + +} + +/******************************************************************** + Return a connection to a server. +********************************************************************/ + +static struct cli_state* cli_cm_find( const char *server, const char *share ) +{ + struct client_connection *p; + + for ( p=connections; p; p=p->next ) { + if ( strequal(server, p->cli->desthost) && strequal(share,p->cli->share) ) + return p->cli; + } + + return NULL; +} + +/**************************************************************************** + open a client connection to a \\server\share. Set's the current *cli + global variable as a side-effect (but only if the connection is successful). +****************************************************************************/ + +struct cli_state* cli_cm_open( const char *server, const char *share, BOOL show_hdr ) +{ + struct cli_state *c; + + /* try to reuse an existing connection */ + + c = cli_cm_find( server, share ); + + if ( !c ) + c = cli_cm_connect( server, share, show_hdr ); + + return c; +} + +/**************************************************************************** +****************************************************************************/ + +void cli_cm_shutdown( void ) +{ + + struct client_connection *p, *x; + + for ( p=connections; p; ) { + cli_shutdown( p->cli ); + x = p; + p = p->next; + + SAFE_FREE( x ); + } + + connections = NULL; + + return; +} + +/**************************************************************************** +****************************************************************************/ + +void cli_cm_display(void) +{ + struct client_connection *p; + int i; + + for ( p=connections,i=0; p; p=p->next,i++ ) { + d_printf("%d:\tserver=%s, share=%s\n", + i, p->cli->desthost, p->cli->share ); + } +} + +/**************************************************************************** +****************************************************************************/ + +void cli_cm_set_credentials( struct user_auth_info *user ) +{ + pstrcpy( username, user->username ); + + if ( user->got_pass ) { + pstrcpy( password, user->password ); + got_pass = True; + } + + use_kerberos = user->use_kerberos; + signing_state = user->signing_state; +} + +/**************************************************************************** +****************************************************************************/ + +void cli_cm_set_port( int port_number ) +{ + port = port_number; +} + +/**************************************************************************** +****************************************************************************/ + +void cli_cm_set_dest_name_type( int type ) +{ + name_type = type; +} + +/**************************************************************************** +****************************************************************************/ + +void cli_cm_set_dest_ip(struct in_addr ip ) +{ + dest_ip = ip; + have_ip = True; +} + /******************************************************************** split a dfs path into the server and share name components ********************************************************************/ |