mirror of
https://github.com/samba-team/samba.git
synced 2024-12-23 17:34:34 +03:00
This change reworkes the connection code for both rpcclient and net new
'net' untility.
This should make it easier to port rpcclient code across to net.
It also allows SPNEGO (the NTLMSSP subsystem in particular) to work, becouse
it kills off the early destruction of the clear-text password.
Andrew Bartlett
(This used to be commit eee925861a
)
This commit is contained in:
parent
8e16021383
commit
3ea7519b06
@ -1013,7 +1013,7 @@ BOOL cli_connect(struct cli_state *cli, const char *host, struct in_addr *ip)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
establishes a connection right up to doing tconX, reading in a password.
|
establishes a connection right up to doing tconX, password in cache.
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
BOOL cli_establish_connection(struct cli_state *cli,
|
BOOL cli_establish_connection(struct cli_state *cli,
|
||||||
char *dest_host, struct in_addr *dest_ip,
|
char *dest_host, struct in_addr *dest_ip,
|
||||||
@ -1158,6 +1158,118 @@ BOOL cli_establish_connection(struct cli_state *cli,
|
|||||||
return True;
|
return True;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Initialise client credentials for authenticated pipe access */
|
||||||
|
|
||||||
|
static void init_creds(struct ntuser_creds *creds, char* username,
|
||||||
|
char* domain, char* password, int pass_len)
|
||||||
|
{
|
||||||
|
ZERO_STRUCTP(creds);
|
||||||
|
|
||||||
|
pwd_set_cleartext(&creds->pwd, password);
|
||||||
|
|
||||||
|
fstrcpy(creds->user_name, username);
|
||||||
|
fstrcpy(creds->domain, domain);
|
||||||
|
|
||||||
|
if (!*username) {
|
||||||
|
creds->pwd.null_pwd = True;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
establishes a connection right up to doing tconX, password specified.
|
||||||
|
****************************************************************************/
|
||||||
|
NTSTATUS cli_full_connection(struct cli_state **output_cli,
|
||||||
|
const char *my_name, const char *dest_host,
|
||||||
|
struct in_addr *dest_ip, int port,
|
||||||
|
char *service, char *service_type,
|
||||||
|
char *user, char *domain,
|
||||||
|
char *password, int pass_len)
|
||||||
|
{
|
||||||
|
struct ntuser_creds creds;
|
||||||
|
NTSTATUS nt_status;
|
||||||
|
struct nmb_name calling;
|
||||||
|
struct nmb_name called;
|
||||||
|
struct cli_state *cli;
|
||||||
|
struct in_addr ip;
|
||||||
|
|
||||||
|
make_nmb_name(&calling, my_name, 0x0);
|
||||||
|
make_nmb_name(&called , dest_host, 0x20);
|
||||||
|
|
||||||
|
again:
|
||||||
|
|
||||||
|
if (!(cli = cli_initialise(NULL))) {
|
||||||
|
return NT_STATUS_NO_MEMORY;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cli_set_port(cli, port) != port) {
|
||||||
|
return NT_STATUS_UNSUCCESSFUL;
|
||||||
|
}
|
||||||
|
|
||||||
|
ip = *dest_ip;
|
||||||
|
|
||||||
|
DEBUG(3,("Connecting to host=%s share=%s\n\n",
|
||||||
|
dest_host, service));
|
||||||
|
|
||||||
|
if (!cli_connect(cli, dest_host, &ip))
|
||||||
|
{
|
||||||
|
DEBUG(1,("cli_establish_connection: failed to connect to %s (%s)\n",
|
||||||
|
nmb_namestr(&called), inet_ntoa(*dest_ip)));
|
||||||
|
return NT_STATUS_UNSUCCESSFUL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!cli_session_request(cli, &calling, &called)) {
|
||||||
|
char *p;
|
||||||
|
DEBUG(1,("session request to %s failed (%s)\n",
|
||||||
|
called.name, cli_errstr(cli)));
|
||||||
|
cli_shutdown(cli);
|
||||||
|
if ((p=strchr(called.name, '.'))) {
|
||||||
|
*p = 0;
|
||||||
|
goto again;
|
||||||
|
}
|
||||||
|
if (strcmp(called.name, "*SMBSERVER")) {
|
||||||
|
make_nmb_name(&called , "*SMBSERVER", 0x20);
|
||||||
|
goto again;
|
||||||
|
}
|
||||||
|
return NT_STATUS_UNSUCCESSFUL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!cli_negprot(cli))
|
||||||
|
{
|
||||||
|
DEBUG(1,("failed negprot\n"));
|
||||||
|
nt_status = cli_nt_error(cli);
|
||||||
|
cli_shutdown(cli);
|
||||||
|
return nt_status;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!cli_session_setup(cli, user,
|
||||||
|
password, pass_len,
|
||||||
|
NULL, 0,
|
||||||
|
domain))
|
||||||
|
{
|
||||||
|
DEBUG(1,("failed session setup\n"));
|
||||||
|
nt_status = cli_nt_error(cli);
|
||||||
|
cli_shutdown(cli);
|
||||||
|
return nt_status;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (service)
|
||||||
|
{
|
||||||
|
if (!cli_send_tconX(cli, service, service_type,
|
||||||
|
(char*)password, pass_len))
|
||||||
|
{
|
||||||
|
DEBUG(1,("failed tcon_X\n"));
|
||||||
|
nt_status = cli_nt_error(cli);
|
||||||
|
cli_shutdown(cli);
|
||||||
|
return nt_status;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
init_creds(&creds, user, domain, password, pass_len);
|
||||||
|
cli_init_creds(cli, &creds);
|
||||||
|
|
||||||
|
*output_cli = cli;
|
||||||
|
return NT_STATUS_OK;
|
||||||
|
}
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
Attempt a NetBIOS session request, falling back to *SMBSERVER if needed.
|
Attempt a NetBIOS session request, falling back to *SMBSERVER if needed.
|
||||||
|
@ -243,27 +243,6 @@ void fetch_machine_sid(struct cli_state *cli)
|
|||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Initialise client credentials for authenticated pipe access */
|
|
||||||
|
|
||||||
void init_rpcclient_creds(struct ntuser_creds *creds, char* username,
|
|
||||||
char* domain, char* password)
|
|
||||||
{
|
|
||||||
ZERO_STRUCTP(creds);
|
|
||||||
|
|
||||||
if (lp_encrypted_passwords()) {
|
|
||||||
pwd_make_lm_nt_16(&creds->pwd, password);
|
|
||||||
} else {
|
|
||||||
pwd_set_cleartext(&creds->pwd, password);
|
|
||||||
}
|
|
||||||
|
|
||||||
fstrcpy(creds->user_name, username);
|
|
||||||
fstrcpy(creds->domain, domain);
|
|
||||||
|
|
||||||
if (! *username) {
|
|
||||||
creds->pwd.null_pwd = True;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* Display help on commands */
|
/* Display help on commands */
|
||||||
|
|
||||||
@ -550,47 +529,6 @@ static NTSTATUS process_cmd(struct cli_state *cli, char *cmd)
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
/************************************************************************/
|
|
||||||
struct cli_state *setup_connection(struct cli_state *cli, char *system_name,
|
|
||||||
struct ntuser_creds *creds)
|
|
||||||
{
|
|
||||||
struct in_addr dest_ip;
|
|
||||||
struct nmb_name calling, called;
|
|
||||||
fstring dest_host;
|
|
||||||
extern pstring global_myname;
|
|
||||||
struct ntuser_creds anon;
|
|
||||||
|
|
||||||
/* Initialise cli_state information */
|
|
||||||
if (!cli_initialise(cli)) {
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!creds) {
|
|
||||||
ZERO_STRUCT(anon);
|
|
||||||
anon.pwd.null_pwd = 1;
|
|
||||||
creds = &anon;
|
|
||||||
}
|
|
||||||
|
|
||||||
cli_init_creds(cli, creds);
|
|
||||||
|
|
||||||
/* Establish a SMB connection */
|
|
||||||
if (!resolve_srv_name(system_name, dest_host, &dest_ip)) {
|
|
||||||
fprintf(stderr, "Could not resolve %s\n", dest_host);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
make_nmb_name(&called, dns_to_netbios_name(dest_host), 0x20);
|
|
||||||
make_nmb_name(&calling, dns_to_netbios_name(global_myname), 0);
|
|
||||||
|
|
||||||
if (!cli_establish_connection(cli, dest_host, &dest_ip, &calling,
|
|
||||||
&called, "IPC$", "IPC", False, True)) {
|
|
||||||
fprintf(stderr, "Error establishing IPC$ connection\n");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
return cli;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* Print usage information */
|
/* Print usage information */
|
||||||
static void usage(void)
|
static void usage(void)
|
||||||
@ -621,13 +559,14 @@ static void usage(void)
|
|||||||
int opt;
|
int opt;
|
||||||
int olddebug;
|
int olddebug;
|
||||||
pstring cmdstr = "";
|
pstring cmdstr = "";
|
||||||
struct ntuser_creds creds;
|
struct cli_state *cli;
|
||||||
struct cli_state cli;
|
|
||||||
fstring password,
|
fstring password,
|
||||||
username,
|
username,
|
||||||
domain,
|
domain,
|
||||||
server;
|
server;
|
||||||
struct cmd_set **cmd_set;
|
struct cmd_set **cmd_set;
|
||||||
|
struct in_addr server_ip;
|
||||||
|
NTSTATUS nt_status;
|
||||||
|
|
||||||
setlinebuf(stdout);
|
setlinebuf(stdout);
|
||||||
|
|
||||||
@ -718,33 +657,42 @@ static void usage(void)
|
|||||||
|
|
||||||
get_myname((*global_myname)?NULL:global_myname);
|
get_myname((*global_myname)?NULL:global_myname);
|
||||||
strupper(global_myname);
|
strupper(global_myname);
|
||||||
|
|
||||||
/*
|
|
||||||
* initialize the credentials struct. Get password
|
|
||||||
* from stdin if necessary
|
|
||||||
*/
|
|
||||||
if (!strlen(username) && !got_pass)
|
|
||||||
get_username(username);
|
|
||||||
|
|
||||||
if (!got_pass) {
|
|
||||||
init_rpcclient_creds (&creds, username, domain, "");
|
|
||||||
pwd_read(&creds.pwd, "Enter Password: ", lp_encrypted_passwords());
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
init_rpcclient_creds (&creds, username, domain, password);
|
|
||||||
}
|
|
||||||
memset(password,'X',sizeof(password));
|
|
||||||
|
|
||||||
/* open a connection to the specified server */
|
|
||||||
ZERO_STRUCTP (&cli);
|
/* resolve the IP address */
|
||||||
if (!setup_connection (&cli, server, &creds)) {
|
if (!resolve_name(server, &server_ip, 0x20)) {
|
||||||
|
DEBUG(1,("Unable to resolve server name\n"));
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* There are no pointers in ntuser_creds struct so zero it out */
|
/*
|
||||||
|
* Get password
|
||||||
|
* from stdin if necessary
|
||||||
|
*/
|
||||||
|
|
||||||
ZERO_STRUCTP (&creds);
|
if (!got_pass) {
|
||||||
|
char *pass = getpass("Password:");
|
||||||
|
if (pass) {
|
||||||
|
fstrcpy(password, pass);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!strlen(username) && !got_pass)
|
||||||
|
get_username(username);
|
||||||
|
|
||||||
|
nt_status = cli_full_connection(&cli, global_myname, server,
|
||||||
|
&server_ip, 0,
|
||||||
|
"IPC$", "IPC",
|
||||||
|
username, domain,
|
||||||
|
password, strlen(password));
|
||||||
|
|
||||||
|
if (!NT_STATUS_IS_OK(nt_status)) {
|
||||||
|
DEBUG(1,("Cannot connect to server. Error was %s\n", get_nt_error_msg(nt_status)));
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
memset(password,'X',sizeof(password));
|
||||||
|
|
||||||
/* Load command lists */
|
/* Load command lists */
|
||||||
|
|
||||||
cmd_set = rpcclient_command_list;
|
cmd_set = rpcclient_command_list;
|
||||||
@ -755,7 +703,7 @@ static void usage(void)
|
|||||||
cmd_set++;
|
cmd_set++;
|
||||||
}
|
}
|
||||||
|
|
||||||
fetch_machine_sid(&cli);
|
fetch_machine_sid(cli);
|
||||||
|
|
||||||
/* Do anything specified with -c */
|
/* Do anything specified with -c */
|
||||||
if (cmdstr[0]) {
|
if (cmdstr[0]) {
|
||||||
@ -763,9 +711,10 @@ static void usage(void)
|
|||||||
char *p = cmdstr;
|
char *p = cmdstr;
|
||||||
|
|
||||||
while((cmd=next_command(&p)) != NULL) {
|
while((cmd=next_command(&p)) != NULL) {
|
||||||
process_cmd(&cli, cmd);
|
process_cmd(cli, cmd);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cli_shutdown(cli);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -783,8 +732,9 @@ static void usage(void)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
if (line[0] != '\n')
|
if (line[0] != '\n')
|
||||||
process_cmd(&cli, line);
|
process_cmd(cli, line);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cli_shutdown(cli);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -49,7 +49,6 @@
|
|||||||
/* be used (if possible). */
|
/* be used (if possible). */
|
||||||
/***********************************************************************/
|
/***********************************************************************/
|
||||||
|
|
||||||
#define PASSWORD_PROMPT "Password: "
|
|
||||||
#define YES_STRING "Yes"
|
#define YES_STRING "Yes"
|
||||||
#define NO_STRING "No"
|
#define NO_STRING "No"
|
||||||
|
|
||||||
@ -105,85 +104,27 @@ connect to \\server\ipc$
|
|||||||
static struct cli_state *connect_to_ipc(struct in_addr *server_ip, const char *server_name)
|
static struct cli_state *connect_to_ipc(struct in_addr *server_ip, const char *server_name)
|
||||||
{
|
{
|
||||||
struct cli_state *c;
|
struct cli_state *c;
|
||||||
struct nmb_name called, calling;
|
NTSTATUS nt_status;
|
||||||
struct in_addr ip;
|
|
||||||
fstring sharename;
|
|
||||||
|
|
||||||
make_nmb_name(&calling, opt_requester_name, 0x0);
|
|
||||||
make_nmb_name(&called , server_name, 0x20);
|
|
||||||
|
|
||||||
again:
|
|
||||||
ip = *server_ip;
|
|
||||||
|
|
||||||
DEBUG(3,("Connecting to host=%s share=%s\n\n",
|
|
||||||
server_name, "IPC$"));
|
|
||||||
|
|
||||||
/* have to open a new connection */
|
|
||||||
if (!(c=cli_initialise(NULL)) || cli_set_port(c, opt_port) != opt_port ||
|
|
||||||
!cli_connect(c, server_name, &ip)) {
|
|
||||||
DEBUG(1,("Connection to %s failed\n", server_name));
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
c->protocol = PROTOCOL_NT1;
|
|
||||||
|
|
||||||
if (!cli_session_request(c, &calling, &called)) {
|
|
||||||
char *p;
|
|
||||||
DEBUG(1,("session request to %s failed (%s)\n",
|
|
||||||
called.name, cli_errstr(c)));
|
|
||||||
cli_shutdown(c);
|
|
||||||
if ((p=strchr(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)) {
|
|
||||||
DEBUG(1,("protocol negotiation failed\n"));
|
|
||||||
cli_shutdown(c);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!got_pass) {
|
if (!got_pass) {
|
||||||
char *pass = getpass(PASSWORD_PROMPT);
|
char *pass = getpass("Password:");
|
||||||
if (pass) {
|
if (pass) {
|
||||||
opt_password = strdup(pass);
|
opt_password = strdup(pass);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!cli_session_setup(c, opt_user_name,
|
nt_status = cli_full_connection(&c, opt_requester_name, server_name,
|
||||||
opt_password, strlen(opt_password),
|
server_ip, opt_port,
|
||||||
opt_password, strlen(opt_password),
|
"IPC$", "IPC",
|
||||||
opt_workgroup)) {
|
opt_user_name, opt_workgroup,
|
||||||
/* try again with a null username */
|
opt_password, strlen(opt_password));
|
||||||
if (!cli_session_setup(c, "", "", 0, "", 0, opt_workgroup)) {
|
|
||||||
DEBUG(1,("session setup failed: %s\n", cli_errstr(c)));
|
|
||||||
cli_shutdown(c);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
DEBUG(3,("Anonymous login successful\n"));
|
|
||||||
}
|
|
||||||
|
|
||||||
snprintf(sharename, sizeof(sharename), "\\\\%s\\IPC$", server_name);
|
if (NT_STATUS_IS_OK(nt_status)) {
|
||||||
|
return c;
|
||||||
DEBUG(4,(" session setup ok\n"));
|
} else {
|
||||||
if (!cli_send_tconX(c, sharename, "?????",
|
DEBUG(1,("Cannot connect to server. Error was %s\n", get_nt_error_msg(nt_status)));
|
||||||
opt_password, strlen(opt_password)+1)) {
|
|
||||||
DEBUG(1,("tree connect failed: %s\n", cli_errstr(c)));
|
|
||||||
cli_shutdown(c);
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
DEBUG(4,(" tconx ok\n"));
|
|
||||||
|
|
||||||
return c;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
struct cli_state *net_make_ipc_connection(unsigned flags)
|
struct cli_state *net_make_ipc_connection(unsigned flags)
|
||||||
@ -199,7 +140,7 @@ struct cli_state *net_make_ipc_connection(unsigned flags)
|
|||||||
} else if (server_name) {
|
} else if (server_name) {
|
||||||
/* resolve the IP address */
|
/* resolve the IP address */
|
||||||
if (!resolve_name(server_name, &server_ip, 0x20)) {
|
if (!resolve_name(server_name, &server_ip, 0x20)) {
|
||||||
DEBUG(1,("Unable to resolve domain browser via name lookup\n"));
|
DEBUG(1,("Unable to resolve server name\n"));
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
} else if (flags & NET_FLAGS_DMB) {
|
} else if (flags & NET_FLAGS_DMB) {
|
||||||
@ -251,7 +192,7 @@ struct cli_state *net_make_ipc_connection(unsigned flags)
|
|||||||
cli = connect_to_ipc(&server_ip, server_name);
|
cli = connect_to_ipc(&server_ip, server_name);
|
||||||
if(!cli) {
|
if(!cli) {
|
||||||
d_printf("\nUnable to connect to target server\n");
|
d_printf("\nUnable to connect to target server\n");
|
||||||
return False;
|
return NULL;
|
||||||
}
|
}
|
||||||
return cli;
|
return cli;
|
||||||
}
|
}
|
||||||
|
@ -212,7 +212,8 @@ static const char *share_type[] = {
|
|||||||
"IPC"
|
"IPC"
|
||||||
};
|
};
|
||||||
|
|
||||||
/* End of weild 'strings at top of file' section */
|
/* End of weird 'strings at top of file' section */
|
||||||
|
|
||||||
static int general_rap_usage(int argc, const char **argv)
|
static int general_rap_usage(int argc, const char **argv)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user