summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source3/Makefile.in4
-rw-r--r--source3/client/client.c300
-rw-r--r--source3/libsmb/clidfs.c278
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
********************************************************************/