summaryrefslogtreecommitdiff
path: root/source3/libsmb
diff options
context:
space:
mode:
Diffstat (limited to 'source3/libsmb')
-rw-r--r--source3/libsmb/clientgen.c1892
-rw-r--r--source3/libsmb/namequery.c827
-rw-r--r--source3/libsmb/nmblib.c288
-rw-r--r--source3/libsmb/nterr.c20
-rw-r--r--source3/libsmb/passchange.c4
-rw-r--r--source3/libsmb/pwd_cache.c217
-rw-r--r--source3/libsmb/smbdes.c23
-rw-r--r--source3/libsmb/smbencrypt.c481
-rw-r--r--source3/libsmb/smberr.c85
9 files changed, 1411 insertions, 2426 deletions
diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c
index 62c7429b59..4f620bc5f4 100644
--- a/source3/libsmb/clientgen.c
+++ b/source3/libsmb/clientgen.c
@@ -2,8 +2,7 @@
Unix SMB/Netbios implementation.
Version 1.9.
SMB client generic functions
- Copyright (C) Andrew Tridgell 1994-1999
- Copyright (C) Luke Kenneth Casson Leighton 1996-1999
+ Copyright (C) Andrew Tridgell 1994-1998
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
@@ -25,84 +24,52 @@
#include "includes.h"
#include "trans2.h"
+
extern int DEBUGLEVEL;
+extern pstring user_socket_options;
+extern pstring scope;
-/*
- * set the port that will be used for connections by the client
- */
+static void cli_process_oplock(struct cli_state *cli);
+/*
+ * Change the port number used to call on
+ */
int cli_set_port(struct cli_state *cli, int port)
{
-
- if (port != 0)
+ if (port > 0)
cli->port = port;
- return cli->port; /* return it incase caller wants it */
-
+ return cli->port;
}
/****************************************************************************
-copy a string (unicode or otherwise) into an SMB buffer. skips a string
-plus points to next
+recv an smb
****************************************************************************/
-static char *cli_put_string(struct cli_state *cli, char *p, const char *str,
- BOOL skip_end)
+static BOOL cli_receive_smb(struct cli_state *cli)
{
- uint16 flgs2 = SVAL(cli->outbuf, smb_flg2);
- if (IS_BITS_SET_ALL(flgs2, FLAGS2_UNICODE_STRINGS))
- {
- p = align2(p, cli->outbuf);
- p = ascii_to_unibuf(p, str, 1024);
- if (skip_end)
- {
- CVAL(p, 0) = 0; p++;
- CVAL(p, 0) = 0; p++;
- }
- return p;
- }
- else
- {
- pstrcpy(p, str);
- p = skip_string(p, 1);
- if (skip_end)
- {
- CVAL(p, 0) = 0; p++;
+ BOOL ret;
+ again:
+ ret = client_receive_smb(cli->fd,cli->inbuf,cli->timeout);
+
+ if (ret) {
+ /* it might be an oplock break request */
+ if (CVAL(cli->inbuf,smb_com) == SMBlockingX &&
+ SVAL(cli->inbuf,smb_vwv6) == 0 &&
+ SVAL(cli->inbuf,smb_vwv7) == 0) {
+ if (cli->use_oplocks) cli_process_oplock(cli);
+ /* try to prevent loops */
+ CVAL(cli->inbuf,smb_com) = 0xFF;
+ goto again;
}
- return p;
}
-}
-/****************************************************************************
-copy a string (unicode or otherwise) into an SMB buffer. skips a string
-plus points to next
-****************************************************************************/
-static const char *cli_get_string(struct cli_state *cli, char *p,
- char *str, size_t str_len)
-{
- uint16 flgs2 = SVAL(cli->inbuf,smb_flg2);
- if (IS_BITS_SET_ALL(flgs2, FLAGS2_UNICODE_STRINGS))
- {
- return unibuf_to_ascii(str, p, str_len);
- }
- else
- {
- safe_strcpy(str, p, str_len-1);
- return skip_string(p, 1);
- }
-}
-
-/****************************************************************************
-recv an smb
-****************************************************************************/
-static BOOL cli_receive_smb(struct cli_state *cli)
-{
- return client_receive_smb(cli->fd,cli->inbuf,cli->timeout);
+ return ret;
}
/****************************************************************************
send an smb to a fd and re-establish if necessary
****************************************************************************/
-static BOOL cli_send_smb(struct cli_state *cli, BOOL show)
+static BOOL cli_send_smb(struct cli_state *cli)
{
size_t len;
size_t nwritten=0;
@@ -111,26 +78,9 @@ static BOOL cli_send_smb(struct cli_state *cli, BOOL show)
len = smb_len(cli->outbuf) + 4;
- if (show)
- {
- uint8 msg_type = CVAL(cli->outbuf, 0);
- if (msg_type == 0)
- {
- show_msg(cli->outbuf);
- }
- else
- {
- dump_data(10, cli->outbuf, len);
- }
- }
-
while (nwritten < len) {
ret = write_socket(cli->fd,cli->outbuf+nwritten,len - nwritten);
- if (ret <= 0 && errno == EPIPE && !reestablished)
- {
- DEBUG(5,("cli_send_smb: write error (%s) - reconnecting\n",
- strerror(errno)));
-
+ if (ret <= 0 && errno == EPIPE && !reestablished) {
if (cli_reestablish_connection(cli)) {
reestablished = True;
nwritten=0;
@@ -139,8 +89,9 @@ static BOOL cli_send_smb(struct cli_state *cli, BOOL show)
}
if (ret <= 0) {
DEBUG(0,("Error writing %d bytes to client. %d. Exiting\n",
- len,ret));
- return False;
+ (int)len,(int)ret));
+ close_sockets();
+ exit(1);
}
nwritten += ret;
}
@@ -148,26 +99,62 @@ static BOOL cli_send_smb(struct cli_state *cli, BOOL show)
return True;
}
-/******************************************************
- Return an error message - either an SMB error or a RAP
- error.
-*******************************************************/
-
-char *cli_errstr(struct cli_state *cli)
-{
- static fstring error_message;
- cli_safe_errstr(cli, error_message, sizeof(error_message));
- return error_message;
+/****************************************************************************
+setup basics in a outgoing packet
+****************************************************************************/
+static void cli_setup_packet(struct cli_state *cli)
+{
+ cli->rap_error = 0;
+ cli->nt_error = 0;
+ SSVAL(cli->outbuf,smb_pid,cli->pid);
+ SSVAL(cli->outbuf,smb_uid,cli->vuid);
+ SSVAL(cli->outbuf,smb_mid,cli->mid);
+ if (cli->protocol > PROTOCOL_CORE) {
+ SCVAL(cli->outbuf,smb_flg,0x8);
+ SSVAL(cli->outbuf,smb_flg2,0x1);
+ }
}
+
+
/****************************************************************************
- return a description of an SMB error
+process an oplock break request from the server
****************************************************************************/
-void cli_safe_smb_errstr(struct cli_state *cli, char *msg, size_t len)
+static void cli_process_oplock(struct cli_state *cli)
{
- smb_safe_errstr(cli->inbuf, msg, len);
+ char *oldbuf = cli->outbuf;
+ pstring buf;
+ int fnum;
+
+ fnum = SVAL(cli->inbuf,smb_vwv2);
+
+ /* damn, we really need to keep a record of open files so we
+ can detect a oplock break and a close crossing on the
+ wire. for now this swallows the errors */
+ if (fnum == 0) return;
+
+ cli->outbuf = buf;
+
+ memset(buf,'\0',smb_size);
+ set_message(buf,8,0,True);
+
+ CVAL(buf,smb_com) = SMBlockingX;
+ SSVAL(buf,smb_tid, cli->cnum);
+ cli_setup_packet(cli);
+ SSVAL(buf,smb_vwv0,0xFF);
+ SSVAL(buf,smb_vwv1,0);
+ SSVAL(buf,smb_vwv2,fnum);
+ SSVAL(buf,smb_vwv3,2); /* oplock break ack */
+ SIVAL(buf,smb_vwv4,0); /* timoeut */
+ SSVAL(buf,smb_vwv6,0); /* unlockcount */
+ SSVAL(buf,smb_vwv7,0); /* lockcount */
+
+ cli_send_smb(cli);
+
+ cli->outbuf = oldbuf;
}
+
/*****************************************************
RAP error codes - a small start but will be extended.
*******************************************************/
@@ -186,36 +173,36 @@ struct
{2244, "This password cannot be used now (password history conflict)." },
{2245, "The password is shorter than required." },
{2246, "The password of this user is too recent to change."},
+
+ /* these really shouldn't be here ... */
+ {0x80, "Not listening on called name"},
+ {0x81, "Not listening for calling name"},
+ {0x82, "Called name not present"},
+ {0x83, "Called name present, but insufficient resources"},
+
{0, NULL}
};
/****************************************************************************
- return a description of a RAP error
+ return a description of an SMB error
****************************************************************************/
-BOOL get_safe_rap_errstr(int rap_error, char *err_msg, size_t msglen)
+static char *cli_smb_errstr(struct cli_state *cli)
{
- int i;
-
- slprintf(err_msg, msglen - 1, "RAP code %d", rap_error);
-
- for (i = 0; rap_errmap[i].message != NULL; i++)
- {
- if (rap_errmap[i].err == rap_error)
- {
- safe_strcpy( err_msg, rap_errmap[i].message, msglen);
- return True;
- }
- }
- return False;
+ return smb_errstr(cli->inbuf);
}
-/****************************************************************************
- return a description of an SMB error
-****************************************************************************/
-void cli_safe_errstr(struct cli_state *cli, char *err_msg, size_t msglen)
+/******************************************************
+ Return an error message - either an SMB error or a RAP
+ error.
+*******************************************************/
+
+char *cli_errstr(struct cli_state *cli)
{
+ static fstring error_message;
uint8 errclass;
uint32 errnum;
+ uint32 nt_rpc_error;
+ int i;
/*
* Errors are of three kinds - smb errors,
@@ -224,54 +211,50 @@ void cli_safe_errstr(struct cli_state *cli, char *err_msg, size_t msglen)
* errors, whose error code is in cli.rap_error.
*/
- cli_error(cli, &errclass, &errnum);
+ cli_error(cli, &errclass, &errnum, &nt_rpc_error);
if (errclass != 0)
{
- cli_safe_smb_errstr(cli, err_msg, msglen);
+ return cli_smb_errstr(cli);
}
- else if (cli->nt_error)
- {
- /*
- * Was it an NT error ?
- */
- (void)get_safe_nt_error_msg(cli->nt_error, err_msg, msglen);
- }
- else
+ /*
+ * Was it an NT error ?
+ */
+
+ if (nt_rpc_error)
{
- /*
- * Must have been a rap error.
- */
- (void)get_safe_rap_errstr(cli->rap_error, err_msg, msglen);
+ char *nt_msg = get_nt_error_msg(nt_rpc_error);
+
+ if (nt_msg == NULL)
+ {
+ slprintf(error_message, sizeof(fstring) - 1, "NT code %d", nt_rpc_error);
+ }
+ else
+ {
+ fstrcpy(error_message, nt_msg);
+ }
+
+ return error_message;
}
-}
-/****************************************************************************
-setup basics in a outgoing packet
-****************************************************************************/
-static void cli_setup_packet(struct cli_state *cli)
-{
- uint16 flgs2 = 0;
- flgs2 |= FLAGS2_LONG_PATH_COMPONENTS;
- flgs2 |= FLAGS2_32_BIT_ERROR_CODES;
- flgs2 |= FLAGS2_EXT_SEC;
-#if 0
- flgs2 |= FLAGS2_UNICODE_STRINGS;
-#endif
- cli->rap_error = 0;
- cli->nt_error = 0;
- SSVAL(cli->outbuf,smb_pid,cli->pid);
- SSVAL(cli->outbuf,smb_uid,cli->vuid);
- SSVAL(cli->outbuf,smb_mid,cli->mid);
+ /*
+ * Must have been a rap error.
+ */
+
+ slprintf(error_message, sizeof(error_message) - 1, "code %d", cli->rap_error);
- if (cli->protocol > PROTOCOL_CORE)
+ for (i = 0; rap_errmap[i].message != NULL; i++)
{
- SCVAL(cli->outbuf,smb_flg,0x8);
- SSVAL(cli->outbuf,smb_flg2,flgs2);
- }
-}
+ if (rap_errmap[i].err == cli->rap_error)
+ {
+ fstrcpy( error_message, rap_errmap[i].message);
+ break;
+ }
+ }
+ return error_message;
+}
/*****************************************************************************
Convert a character pointer in a cli_call_api() response to a form we can use.
@@ -299,7 +282,7 @@ static char *fix_char_ptr(unsigned int datap, unsigned int converter,
/****************************************************************************
send a SMB trans or trans2 request
****************************************************************************/
-BOOL cli_send_trans(struct cli_state *cli, int trans,
+static BOOL cli_send_trans(struct cli_state *cli, int trans,
char *name, int pipe_name_len,
int fid, int flags,
uint16 *setup, int lsetup, int msetup,
@@ -315,7 +298,7 @@ BOOL cli_send_trans(struct cli_state *cli, int trans,
this_lparam = MIN(lparam,cli->max_xmit - (500+lsetup*2)); /* hack */
this_ldata = MIN(ldata,cli->max_xmit - (500+lsetup*2+this_lparam));
- bzero(cli->outbuf,smb_size);
+ memset(cli->outbuf,'\0',smb_size);
set_message(cli->outbuf,14+lsetup,0,True);
CVAL(cli->outbuf,smb_com) = trans;
SSVAL(cli->outbuf,smb_tid, cli->cnum);
@@ -353,7 +336,8 @@ BOOL cli_send_trans(struct cli_state *cli, int trans,
set_message(cli->outbuf,14+lsetup, /* wcnt, bcc */
PTR_DIFF(outdata+this_ldata,smb_buf(cli->outbuf)),False);
- cli_send_smb(cli, True);
+ show_msg(cli->outbuf);
+ cli_send_smb(cli);
if (this_ldata < ldata || this_lparam < lparam) {
/* receive interim response */
@@ -387,13 +371,14 @@ BOOL cli_send_trans(struct cli_state *cli, int trans,
if (trans==SMBtrans2)
SSVALS(cli->outbuf,smb_sfid,fid); /* fid */
if (this_lparam) /* param[] */
- memcpy(outparam,param,this_lparam);
+ memcpy(outparam,param+tot_param,this_lparam);
if (this_ldata) /* data[] */
- memcpy(outdata,data,this_ldata);
+ memcpy(outdata,data+tot_data,this_ldata);
set_message(cli->outbuf,trans==SMBtrans?8:9, /* wcnt, bcc */
PTR_DIFF(outdata+this_ldata,smb_buf(cli->outbuf)),False);
- cli_send_smb(cli, True);
+ show_msg(cli->outbuf);
+ cli_send_smb(cli);
tot_data += this_ldata;
tot_param += this_lparam;
@@ -414,12 +399,16 @@ static BOOL cli_receive_trans(struct cli_state *cli,int trans,
int total_data=0;
int total_param=0;
int this_data,this_param;
-
+ uint8 eclass;
+ uint32 ecode;
+
*data_len = *param_len = 0;
if (!cli_receive_smb(cli))
return False;
+ show_msg(cli->inbuf);
+
/* sanity check */
if (CVAL(cli->inbuf,smb_com) != trans) {
DEBUG(0,("Expected %s response, got command 0x%02x\n",
@@ -428,9 +417,16 @@ static BOOL cli_receive_trans(struct cli_state *cli,int trans,
return(False);
}
- if (cli_error(cli, NULL, NULL))
+ /*
+ * An NT RPC pipe call can return ERRDOS, ERRmoredata
+ * to a trans call. This is not an error and should not
+ * be treated as such.
+ */
+
+ if (cli_error(cli, &eclass, &ecode, NULL))
{
- return(False);
+ if(cli->nt_pipe_fnum == 0 || !(eclass == ERRDOS && ecode == ERRmoredata))
+ return(False);
}
/* parse out the lengths */
@@ -472,6 +468,8 @@ static BOOL cli_receive_trans(struct cli_state *cli,int trans,
if (!cli_receive_smb(cli))
return False;
+ show_msg(cli->inbuf);
+
/* sanity check */
if (CVAL(cli->inbuf,smb_com) != trans) {
DEBUG(0,("Expected %s response, got command 0x%02x\n",
@@ -479,10 +477,10 @@ static BOOL cli_receive_trans(struct cli_state *cli,int trans,
CVAL(cli->inbuf,smb_com)));
return(False);
}
-
- if (cli_error(cli, NULL, NULL))
+ if (cli_error(cli, &eclass, &ecode, NULL))
{
- return(False);
+ if(cli->nt_pipe_fnum == 0 || !(eclass == ERRDOS && ecode == ERRmoredata))
+ return(False);
}
}
@@ -642,6 +640,8 @@ BOOL cli_RNetShareEnum(struct cli_state *cli, void (*fn)(const char *, uint32, c
int type = SVAL(p,14);
int comment_offset = IVAL(p,16) & 0xFFFF;
char *cmnt = comment_offset?(rdata+comment_offset-converter):"";
+ dos_to_unix(sname,True);
+ dos_to_unix(cmnt,True);
fn(sname, type, cmnt);
}
} else {
@@ -719,6 +719,8 @@ BOOL cli_NetServerEnum(struct cli_state *cli, char *workgroup, uint32 stype,
stype = IVAL(p,18) & ~SV_TYPE_LOCAL_LIST_ONLY;
+ dos_to_unix(sname, True);
+ dos_to_unix(cmnt, True);
fn(sname, stype, cmnt);
}
}
@@ -754,41 +756,76 @@ prots[] =
/****************************************************************************
-send a session setup
+ Send a session setup. The username is in UNIX character format and must be
+ converted to DOS codepage format before sending. If the password is in
+ plaintext, the same should be done.
****************************************************************************/
-BOOL cli_session_setup_x(struct cli_state *cli,
- char *user,
- char *pass, int passlen,
- char *ntpass, int ntpasslen,
- char *user_domain)
+
+BOOL cli_session_setup(struct cli_state *cli,
+ char *user,
+ char *pass, int passlen,
+ char *ntpass, int ntpasslen,
+ char *workgroup)
{
- uint8 eclass;
- uint32 ecode;
char *p;
- BOOL esec = cli->capabilities & CAP_EXTENDED_SECURITY;
+ fstring pword, ntpword;
- if (cli->reuse)
- {
- DEBUG(3,("cli_session_setup_x: reuse enabled, skipping SMBsesssetupX\n"));
+ if (cli->protocol < PROTOCOL_LANMAN1)
return True;
- }
- DEBUG(100,("cli_session_setup. extended security: %s\n",
- BOOLSTR(esec)));
-
-#ifdef DEBUG_PASSWORD
- DEBUG(100,("cli_session_setup. pass, ntpass\n"));
- dump_data(100, pass, passlen);
- dump_data(100, ntpass, ntpasslen);
-#endif
+ if (passlen > sizeof(pword)-1 || ntpasslen > sizeof(ntpword)-1) {
+ return False;
+ }
- if (cli->protocol < PROTOCOL_LANMAN1)
- {
- return True;
+ if (((passlen == 0) || (passlen == 1)) && (pass[0] == '\0')) {
+ /* Null session connect. */
+ pword[0] = '\0';
+ ntpword[0] = '\0';
+ } else {
+ if ((cli->sec_mode & 2) && passlen != 24) {
+ /*
+ * Encrypted mode needed, and non encrypted password supplied.
+ */
+ passlen = 24;
+ ntpasslen = 24;
+ fstrcpy(pword, pass);
+ unix_to_dos(pword,True);
+ fstrcpy(ntpword, ntpass);;
+ unix_to_dos(ntpword,True);
+ SMBencrypt((uchar *)pword,(uchar *)cli->cryptkey,(uchar *)pword);
+ SMBNTencrypt((uchar *)ntpword,(uchar *)cli->cryptkey,(uchar *)ntpword);
+ } else if ((cli->sec_mode & 2) && passlen == 24) {
+ /*
+ * Encrypted mode needed, and encrypted password supplied.
+ */
+ memcpy(pword, pass, passlen);
+ if(ntpasslen == 24) {
+ memcpy(ntpword, ntpass, ntpasslen);
+ } else {
+ fstrcpy(ntpword, "");
+ ntpasslen = 0;
+ }
+ } else {
+ /*
+ * Plaintext mode needed, assume plaintext supplied.
+ */
+ fstrcpy(pword, pass);
+ unix_to_dos(pword,True);
+ fstrcpy(ntpword, "");
+ ntpasslen = 0;
+ }
}
+ /* if in share level security then don't send a password now */
+ if (!(cli->sec_mode & 1)) {
+ fstrcpy(pword, "");
+ passlen=1;
+ fstrcpy(ntpword, "");
+ ntpasslen=1;
+ }
+
/* send a session setup command */
- bzero(cli->outbuf,smb_size);
+ memset(cli->outbuf,'\0',smb_size);
if (cli->protocol < PROTOCOL_NT1)
{
@@ -803,36 +840,13 @@ BOOL cli_session_setup_x(struct cli_state *cli,
SIVAL(cli->outbuf,smb_vwv5,cli->sesskey);
SSVAL(cli->outbuf,smb_vwv7,passlen);
p = smb_buf(cli->outbuf);
- memcpy(p,pass,passlen);
+ memcpy(p,pword,passlen);
p += passlen;
pstrcpy(p,user);
+ unix_to_dos(p,True);
strupper(p);
}
- else if (esec)
- {
- set_message(cli->outbuf,12,0,True);
- CVAL(cli->outbuf,smb_com) = SMBsesssetupX;
- cli_setup_packet(cli);
-
- CVAL(cli->outbuf,smb_vwv0) = 0xFF;
- SSVAL(cli->outbuf,smb_vwv2,CLI_BUFFER_SIZE);
- SSVAL(cli->outbuf,smb_vwv3,2);
- SSVAL(cli->outbuf,smb_vwv4,cli->pid);
- SIVAL(cli->outbuf,smb_vwv5,cli->sesskey);
- SSVAL(cli->outbuf,smb_vwv7,passlen);
- SIVAL(cli->outbuf,smb_vwv10, CAP_EXTENDED_SECURITY|CAP_STATUS32|CAP_UNICODE);
- p = smb_buf(cli->outbuf);
- memcpy(p,pass,passlen);
- p += passlen;
-
- p = cli_put_string(cli, p, "Unix", False);
- p = cli_put_string(cli, p, "Samba", False);
- p = cli_put_string(cli, p, "", False);
- p++;
-
- set_message(cli->outbuf,12,PTR_DIFF(p,smb_buf(cli->outbuf)),False);
- }
- else
+ else
{
set_message(cli->outbuf,13,0,True);
CVAL(cli->outbuf,smb_com) = SMBsesssetupX;
@@ -845,204 +859,58 @@ BOOL cli_session_setup_x(struct cli_state *cli,
SIVAL(cli->outbuf,smb_vwv5,cli->sesskey);
SSVAL(cli->outbuf,smb_vwv7,passlen);
SSVAL(cli->outbuf,smb_vwv8,ntpasslen);
- SIVAL(cli->outbuf,smb_vwv11, 0);
+ SSVAL(cli->outbuf,smb_vwv11,0);
p = smb_buf(cli->outbuf);
- memcpy(p,pass,passlen);
+ memcpy(p,pword,passlen);
p += SVAL(cli->outbuf,smb_vwv7);
- memcpy(p,ntpass,ntpasslen);
+ memcpy(p,ntpword,ntpasslen);
p += SVAL(cli->outbuf,smb_vwv8);
- strupper(user);
- p = cli_put_string(cli, p, user, False);
- strupper(user_domain);
- p = cli_put_string(cli, p, user_domain, False);
- p = cli_put_string(cli, p, "Unix", True);
- p = cli_put_string(cli, p, "Samba", False);
-
+ pstrcpy(p,user);
+ unix_to_dos(p,True);
+ strupper(p);
+ p = skip_string(p,1);
+ pstrcpy(p,workgroup);
+ strupper(p);
+ p = skip_string(p,1);
+ pstrcpy(p,"Unix");p = skip_string(p,1);
+ pstrcpy(p,"Samba");p = skip_string(p,1);
set_message(cli->outbuf,13,PTR_DIFF(p,smb_buf(cli->outbuf)),False);
}
- cli_send_smb(cli, True);
- if (!cli_receive_smb(cli))
- {
- DEBUG(10,("cli_session_setup_x: receive smb failed\n"));
+ cli_send_smb(cli);
+ if (!cli_receive_smb(cli))
return False;
- }
-
- if (cli_error(cli, &eclass, &ecode))
- {
- uint16 flgs2 = SVAL(cli->inbuf,smb_flg2);
- if (IS_BITS_CLR_ALL(flgs2, FLAGS2_32_BIT_ERROR_CODES))
- {
- if (ecode != ERRmoredata || !esec)
- {
- return False;
- }
- }
- else if (ecode != 0xC0000016) /* STATUS_MORE_PROCESSING_REQD */
- {
- return False;
- }
- }
- /* use the returned vuid from now on */
- cli->vuid = SVAL(cli->inbuf,smb_uid);
+ show_msg(cli->inbuf);
- if (cli->protocol >= PROTOCOL_NT1)
- {
- if (esec)
- {
- }
- else
- {
- /*
- * Save off some of the connected server
- * info.
- */
- char *server_domain;
- char *server_os;
- char *server_type;
-
- server_os = smb_buf(cli->inbuf);
- server_type = skip_string(server_os,1);
- server_domain = skip_string(server_type,1);
-
- fstrcpy(cli->server_os, server_os);
- fstrcpy(cli->server_type, server_type);
- fstrcpy(cli->server_domain, server_domain);
- }
+ if (CVAL(cli->inbuf,smb_rcls) != 0) {
+ return False;
}
- return True;
-}
-
-static BOOL cli_calc_session_pwds(struct cli_state *cli,
- char *myhostname,
- char *pword, char *ntpword,
- char *pass, int *passlen,
- char *ntpass, int *ntpasslen,
- char *sess_key,
- BOOL ntlmv2)
-{
- BOOL ntpass_ok = ntpass != NULL && ntpasslen != NULL;
-
- if (pass == NULL || passlen == NULL)
- {
- DEBUG(0,("cli_calc_session_pwds: pass and passlen are NULL\n"));
- return False;
- }
- if ((ntpass != NULL || ntpasslen != NULL) &&
- (ntpass == NULL || ntpasslen == NULL))
- {
- DEBUG(0,("cli_calc_session_pwds: ntpasswd pointers invalid\n"));
- return False;
- }
-
-#ifdef DEBUG_PASSWORD
- DEBUG(100,("cli_calc_session_pwds. pass, ntpass\n"));
- dump_data(100, pass, *passlen);
- if (ntpass_ok)
- {
- dump_data(100, ntpass, *ntpasslen);
- }
-#endif
- if (!IS_BITS_SET_ALL(cli->sec_mode, 1))
- {
- /* if in share level security then don't send a password now */
- pword[0] = '\0';
- *passlen=1;
- if (ntpass_ok)
- {
- ntpword[0] = '\0';
- *ntpasslen=1;
- }
- return True;
- }
- else if ((*passlen == 0 || *passlen == 1) && (pass[0] == '\0'))
- {
- /* Null session connect. */
- pword [0] = '\0';
- if (ntpass_ok)
- {
- ntpword[0] = '\0';
- *ntpasslen=0;
- }
-
- return True;
- }
-
- if (!ntpass_ok)
- {
- return False;
- }
-
- if (*passlen == 24 && *ntpasslen >= 24)
- {
- if (IS_BITS_SET_ALL(cli->sec_mode, 2))
- {
- /* encrypted password, implicit from 24-byte lengths */
- memcpy(pword , pass , *passlen);
- memcpy(ntpword, ntpass, *ntpasslen);
- }
- else
- {
- DEBUG(0,("cli_calc_session_pwds: encrypted passwords not supported by server\n"));
- return False;
- }
- }
- else if (*ntpasslen == 0 || !IS_BITS_SET_ALL(cli->sec_mode, 2))
- {
- /* plain-text password: server doesn't support encrypted. */
- fstrcpy(pword, pass);
- fstrcpy(ntpword, "");
- *ntpasslen = 0;
- }
- else if (ntpasslen != NULL)
- {
- if (cli->use_ntlmv2 != False)
- {
- DEBUG(10,("cli_establish_connection: NTLMv2\n"));
- pwd_make_lm_nt_owf2(&(cli->usr.pwd), cli->cryptkey,
- cli->usr.user_name, myhostname,
- cli->usr.domain);
- }
- else
- {
- DEBUG(10,("cli_establish_connection: NTLMv1\n"));
- pwd_make_lm_nt_owf(&(cli->usr.pwd), cli->cryptkey);
- }
-
- pwd_get_lm_nt_owf(&(cli->usr.pwd), pass, ntpass,
- ntpasslen, sess_key);
-
- *passlen = 24;
- }
- return True;
-}
-
-/****************************************************************************
-send a session setup
-****************************************************************************/
-BOOL cli_session_setup(struct cli_state *cli,
- char *myhostname, char *user,
- char *pass, int passlen,
- char *ntpass, int ntpasslen,
- char *user_domain)
-{
- fstring pword, ntpword;
-
- if (passlen > sizeof(pword)-1 || ntpasslen > sizeof(ntpword)-1)
- {
- return False;
- }
+ /* use the returned vuid from now on */
+ cli->vuid = SVAL(cli->inbuf,smb_uid);
+
+ if (cli->protocol >= PROTOCOL_NT1) {
+ /*
+ * Save off some of the connected server
+ * info.
+ */
+ char *server_domain,*server_os,*server_type;
+ server_os = smb_buf(cli->inbuf);
+ server_type = skip_string(server_os,1);
+ server_domain = skip_string(server_type,1);
+ fstrcpy(cli->server_os, server_os);
+ dos_to_unix(cli->server_os, True);
+ fstrcpy(cli->server_type, server_type);
+ dos_to_unix(cli->server_type, True);
+ fstrcpy(cli->server_domain, server_domain);
+ dos_to_unix(cli->server_domain, True);
+ }
- fstrcpy(cli->usr.user_name, user);
+ fstrcpy(cli->user_name, user);
+ dos_to_unix(cli->user_name, True);
- return cli_calc_session_pwds(cli, myhostname, pword, ntpword,
- pass, &passlen,
- ntpass, &ntpasslen, cli->sess_key,
- cli->use_ntlmv2) &&
- cli_session_setup_x(cli, user, pass, passlen, ntpass, ntpasslen,
- user_domain);
+ return True;
}
/****************************************************************************
@@ -1051,20 +919,14 @@ BOOL cli_session_setup(struct cli_state *cli,
BOOL cli_ulogoff(struct cli_state *cli)
{
- if (cli->reuse)
- {
- DEBUG(3,("cli_ulogoff: reuse enabled, skipping SMBulogoff\n"));
- return True;
- }
-
- bzero(cli->outbuf,smb_size);
+ memset(cli->outbuf,'\0',smb_size);
set_message(cli->outbuf,2,0,True);
CVAL(cli->outbuf,smb_com) = SMBulogoffX;
cli_setup_packet(cli);
SSVAL(cli->outbuf,smb_vwv0,0xFF);
SSVAL(cli->outbuf,smb_vwv2,0); /* no additional info */
- cli_send_smb(cli, True);
+ cli_send_smb(cli);
if (!cli_receive_smb(cli))
return False;
@@ -1077,10 +939,10 @@ send a tconX
BOOL cli_send_tconX(struct cli_state *cli,
char *share, char *dev, char *pass, int passlen)
{
- fstring fullshare, pword;
+ fstring fullshare, pword, dos_pword;
char *p;
- bzero(cli->outbuf,smb_size);
- bzero(cli->inbuf,smb_size);
+ memset(cli->outbuf,'\0',smb_size);
+ memset(cli->inbuf,'\0',smb_size);
fstrcpy(cli->share, share);
@@ -1091,17 +953,32 @@ BOOL cli_send_tconX(struct cli_state *cli,
}
if ((cli->sec_mode & 2) && *pass && passlen != 24) {
+ /*
+ * Non-encrypted passwords - convert to DOS codepage before encryption.
+ */
passlen = 24;
- SMBencrypt((uchar *)pass,(uchar *)cli->cryptkey,(uchar *)pword);
+ fstrcpy(dos_pword,pass);
+ unix_to_dos(dos_pword,True);
+ SMBencrypt((uchar *)dos_pword,(uchar *)cli->cryptkey,(uchar *)pword);
} else {
- memcpy(pword, pass, passlen);
+ if(!(cli->sec_mode & 2)) {
+ /*
+ * Non-encrypted passwords - convert to DOS codepage before using.
+ */
+ fstrcpy(pword,pass);
+ unix_to_dos(pword,True);
+ } else {
+ memcpy(pword, pass, passlen);
+ }
}
slprintf(fullshare, sizeof(fullshare)-1,
"\\\\%s\\%s", cli->desthost, share);
+ unix_to_dos(fullshare, True);
strupper(fullshare);
- set_message(cli->outbuf,4, 0, True);
+ set_message(cli->outbuf,4,
+ 2 + strlen(fullshare) + passlen + strlen(dev),True);
CVAL(cli->outbuf,smb_com) = SMBtconX;
cli_setup_packet(cli);
@@ -1111,15 +988,14 @@ BOOL cli_send_tconX(struct cli_state *cli,
p = smb_buf(cli->outbuf);
memcpy(p,pword,passlen);
p += passlen;
- p = cli_put_string(cli, p, fullshare, False);
- fstrcpy(p, dev);
- p = skip_string(p, 1);
-
- set_message(cli->outbuf,4,PTR_DIFF(p, smb_buf(cli->outbuf)),False);
+ fstrcpy(p,fullshare);
+ p = skip_string(p,1);
+ pstrcpy(p,dev);
+ unix_to_dos(p,True);
SCVAL(cli->inbuf,smb_rcls, 1);
- cli_send_smb(cli, True);
+ cli_send_smb(cli);
if (!cli_receive_smb(cli))
return False;
@@ -1129,10 +1005,8 @@ BOOL cli_send_tconX(struct cli_state *cli,
fstrcpy(cli->dev, "A:");
- if (cli->protocol >= PROTOCOL_NT1)
- {
- cli_get_string(cli, smb_buf(cli->inbuf),
- cli->dev, sizeof(cli->dev));
+ if (cli->protocol >= PROTOCOL_NT1) {
+ fstrcpy(cli->dev, smb_buf(cli->inbuf));
}
if (strcasecmp(share,"IPC$")==0) {
@@ -1140,8 +1014,8 @@ BOOL cli_send_tconX(struct cli_state *cli,
}
/* only grab the device if we have a recent protocol level */
- if (cli->protocol >= PROTOCOL_NT1 && smb_buflen(cli->inbuf) == 3)
- {
+ if (cli->protocol >= PROTOCOL_NT1 &&
+ smb_buflen(cli->inbuf) == 3) {
/* almost certainly win95 - enable bug fixes */
cli->win95 = True;
}
@@ -1156,13 +1030,13 @@ send a tree disconnect
****************************************************************************/
BOOL cli_tdis(struct cli_state *cli)
{
- bzero(cli->outbuf,smb_size);
+ memset(cli->outbuf,'\0',smb_size);
set_message(cli->outbuf,0,0,True);
CVAL(cli->outbuf,smb_com) = SMBtdis;
SSVAL(cli->outbuf,smb_tid,cli->cnum);
cli_setup_packet(cli);
- cli_send_smb(cli, True);
+ cli_send_smb(cli);
if (!cli_receive_smb(cli))
return False;
@@ -1176,8 +1050,8 @@ BOOL cli_rename(struct cli_state *cli, char *fname_src, char *fname_dst)
{
char *p;
- bzero(cli->outbuf,smb_size);
- bzero(cli->inbuf,smb_size);
+ memset(cli->outbuf,'\0',smb_size);
+ memset(cli->inbuf,'\0',smb_size);
set_message(cli->outbuf,1, 4 + strlen(fname_src) + strlen(fname_dst), True);
@@ -1190,11 +1064,13 @@ BOOL cli_rename(struct cli_state *cli, char *fname_src, char *fname_dst)
p = smb_buf(cli->outbuf);
*p++ = 4;
pstrcpy(p,fname_src);
+ unix_to_dos(p,True);
p = skip_string(p,1);
*p++ = 4;
pstrcpy(p,fname_dst);
+ unix_to_dos(p,True);
- cli_send_smb(cli, True);
+ cli_send_smb(cli);
if (!cli_receive_smb(cli)) {
return False;
}
@@ -1213,8 +1089,8 @@ BOOL cli_unlink(struct cli_state *cli, char *fname)
{
char *p;
- bzero(cli->outbuf,smb_size);
- bzero(cli->inbuf,smb_size);
+ memset(cli->outbuf,'\0',smb_size);
+ memset(cli->inbuf,'\0',smb_size);
set_message(cli->outbuf,1, 2 + strlen(fname),True);
@@ -1227,8 +1103,9 @@ BOOL cli_unlink(struct cli_state *cli, char *fname)
p = smb_buf(cli->outbuf);
*p++ = 4;
pstrcpy(p,fname);
+ unix_to_dos(p,True);
- cli_send_smb(cli, True);
+ cli_send_smb(cli);
if (!cli_receive_smb(cli)) {
return False;
}
@@ -1247,8 +1124,8 @@ BOOL cli_mkdir(struct cli_state *cli, char *dname)
{
char *p;
- bzero(cli->outbuf,smb_size);
- bzero(cli->inbuf,smb_size);
+ memset(cli->outbuf,'\0',smb_size);
+ memset(cli->inbuf,'\0',smb_size);
set_message(cli->outbuf,0, 2 + strlen(dname),True);
@@ -1259,8 +1136,9 @@ BOOL cli_mkdir(struct cli_state *cli, char *dname)
p = smb_buf(cli->outbuf);
*p++ = 4;
pstrcpy(p,dname);
+ unix_to_dos(p,True);
- cli_send_smb(cli, True);
+ cli_send_smb(cli);
if (!cli_receive_smb(cli)) {
return False;
}
@@ -1279,8 +1157,8 @@ BOOL cli_rmdir(struct cli_state *cli, char *dname)
{
char *p;
- bzero(cli->outbuf,smb_size);
- bzero(cli->inbuf,smb_size);
+ memset(cli->outbuf,'\0',smb_size);
+ memset(cli->inbuf,'\0',smb_size);
set_message(cli->outbuf,0, 2 + strlen(dname),True);
@@ -1291,8 +1169,9 @@ BOOL cli_rmdir(struct cli_state *cli, char *dname)
p = smb_buf(cli->outbuf);
*p++ = 4;
pstrcpy(p,dname);
+ unix_to_dos(p,True);
- cli_send_smb(cli, True);
+ cli_send_smb(cli);
if (!cli_receive_smb(cli)) {
return False;
}
@@ -1309,12 +1188,12 @@ BOOL cli_rmdir(struct cli_state *cli, char *dname)
/****************************************************************************
open a file
****************************************************************************/
-int cli_nt_create(struct cli_state *cli, const char *fname)
+int cli_nt_create(struct cli_state *cli, char *fname)
{
char *p;
- bzero(cli->outbuf,smb_size);
- bzero(cli->inbuf,smb_size);
+ memset(cli->outbuf,'\0',smb_size);
+ memset(cli->inbuf,'\0',smb_size);
set_message(cli->outbuf,24,1 + strlen(fname),True);
@@ -1335,9 +1214,10 @@ int cli_nt_create(struct cli_state *cli, const char *fname)
p = smb_buf(cli->outbuf);
pstrcpy(p,fname);
+ unix_to_dos(p,True);
p = skip_string(p,1);
- cli_send_smb(cli, True);
+ cli_send_smb(cli);
if (!cli_receive_smb(cli)) {
return -1;
}
@@ -1353,8 +1233,7 @@ int cli_nt_create(struct cli_state *cli, const char *fname)
/****************************************************************************
open a file
****************************************************************************/
-int cli_open(struct cli_state *cli, const char *fname,
- int flags, int share_mode)
+int cli_open(struct cli_state *cli, char *fname, int flags, int share_mode)
{
char *p;
unsigned openfn=0;
@@ -1389,8 +1268,8 @@ int cli_open(struct cli_state *cli, const char *fname,
}
#endif /* O_SYNC */
- bzero(cli->outbuf,smb_size);
- bzero(cli->inbuf,smb_size);
+ memset(cli->outbuf,'\0',smb_size);
+ memset(cli->inbuf,'\0',smb_size);
set_message(cli->outbuf,15,1 + strlen(fname),True);
@@ -1404,13 +1283,21 @@ int cli_open(struct cli_state *cli, const char *fname,
SSVAL(cli->outbuf,smb_vwv4,aSYSTEM | aHIDDEN);
SSVAL(cli->outbuf,smb_vwv5,0);
SSVAL(cli->outbuf,smb_vwv8,openfn);
+
+ if (cli->use_oplocks) {
+ /* if using oplocks then ask for a batch oplock via
+ core and extended methods */
+ CVAL(cli->outbuf,smb_flg) |=
+ FLAG_REQUEST_OPLOCK|FLAG_REQUEST_BATCH_OPLOCK;
+ SSVAL(cli->outbuf,smb_vwv2,SVAL(cli->outbuf,smb_vwv2) | 6);
+ }
p = smb_buf(cli->outbuf);
- p = cli_put_string(cli, p, fname, False);
-
- set_message(cli->outbuf,15,PTR_DIFF(p, smb_buf(cli->outbuf)),False);
+ pstrcpy(p,fname);
+ unix_to_dos(p,True);
+ p = skip_string(p,1);
- cli_send_smb(cli, True);
+ cli_send_smb(cli);
if (!cli_receive_smb(cli)) {
return -1;
}
@@ -1430,8 +1317,8 @@ int cli_open(struct cli_state *cli, const char *fname,
****************************************************************************/
BOOL cli_close(struct cli_state *cli, int fnum)
{
- bzero(cli->outbuf,smb_size);
- bzero(cli->inbuf,smb_size);
+ memset(cli->outbuf,'\0',smb_size);
+ memset(cli->inbuf,'\0',smb_size);
set_message(cli->outbuf,3,0,True);
@@ -1442,7 +1329,7 @@ BOOL cli_close(struct cli_state *cli, int fnum)
SSVAL(cli->outbuf,smb_vwv0,fnum);
SIVALS(cli->outbuf,smb_vwv1,-1);
- cli_send_smb(cli, True);
+ cli_send_smb(cli);
if (!cli_receive_smb(cli)) {
return False;
}
@@ -1463,8 +1350,8 @@ BOOL cli_lock(struct cli_state *cli, int fnum, uint32 offset, uint32 len, int ti
char *p;
int saved_timeout = cli->timeout;
- bzero(cli->outbuf,smb_size);
- bzero(cli->inbuf,smb_size);
+ memset(cli->outbuf,'\0',smb_size);
+ memset(cli->inbuf,'\0', smb_size);
set_message(cli->outbuf,8,10,True);
@@ -1483,7 +1370,7 @@ BOOL cli_lock(struct cli_state *cli, int fnum, uint32 offset, uint32 len, int ti
SSVAL(p, 0, cli->pid);
SIVAL(p, 2, offset);
SIVAL(p, 6, len);
- cli_send_smb(cli, True);
+ cli_send_smb(cli);
cli->timeout = (timeout == -1) ? 0x7FFFFFFF : timeout;
@@ -1508,8 +1395,8 @@ BOOL cli_unlock(struct cli_state *cli, int fnum, uint32 offset, uint32 len, int
{
char *p;
- bzero(cli->outbuf,smb_size);
- bzero(cli->inbuf,smb_size);
+ memset(cli->outbuf,'\0',smb_size);
+ memset(cli->inbuf,'\0',smb_size);
set_message(cli->outbuf,8,10,True);
@@ -1529,7 +1416,7 @@ BOOL cli_unlock(struct cli_state *cli, int fnum, uint32 offset, uint32 len, int
SIVAL(p, 2, offset);
SIVAL(p, 6, len);
- cli_send_smb(cli, True);
+ cli_send_smb(cli);
if (!cli_receive_smb(cli)) {
return False;
}
@@ -1549,8 +1436,8 @@ issue a single SMBread and don't wait for a reply
static void cli_issue_read(struct cli_state *cli, int fnum, off_t offset,
size_t size, int i)
{
- bzero(cli->outbuf,smb_size);
- bzero(cli->inbuf,smb_size);
+ memset(cli->outbuf,'\0',smb_size);
+ memset(cli->inbuf,'\0',smb_size);
set_message(cli->outbuf,10,0,True);
@@ -1565,7 +1452,7 @@ static void cli_issue_read(struct cli_state *cli, int fnum, off_t offset,
SSVAL(cli->outbuf,smb_vwv6,size);
SSVAL(cli->outbuf,smb_mid,cli->mid + i);
- cli_send_smb(cli, True);
+ cli_send_smb(cli);
}
/****************************************************************************
@@ -1577,15 +1464,24 @@ size_t cli_read(struct cli_state *cli, int fnum, char *buf, off_t offset, size_t
int total = -1;
int issued=0;
int received=0;
- int mpx = MIN(MAX(cli->max_mux-1, 1), MAX_MAX_MUX_LIMIT);
+/*
+ * There is a problem in this code when mpx is more than one.
+ * for some reason files can get corrupted when being read.
+ * Until we understand this fully I am serializing reads (one
+ * read/one reply) for now. JRA.
+ */
+#if 0
+ int mpx = MAX(cli->max_mux-1, 1);
+#else
+ int mpx = 1;
+#endif
int block = (cli->max_xmit - (smb_size+32)) & ~1023;
int mid;
int blocks = (size + (block-1)) / block;
if (size == 0) return 0;
- while (received < blocks)
- {
+ while (received < blocks) {
int size2;
while (issued - received < mpx && issued < blocks) {
@@ -1602,8 +1498,7 @@ size_t cli_read(struct cli_state *cli, int fnum, char *buf, off_t offset, size_t
mid = SVAL(cli->inbuf, smb_mid) - cli->mid;
size2 = SVAL(cli->inbuf, smb_vwv5);
- if (cli_error(cli, NULL, NULL))
- {
+ if (CVAL(cli->inbuf,smb_rcls) != 0) {
blocks = MIN(blocks, mid-1);
continue;
}
@@ -1647,8 +1542,8 @@ static void cli_issue_write(struct cli_state *cli, int fnum, off_t offset, uint1
{
char *p;
- bzero(cli->outbuf,smb_size);
- bzero(cli->inbuf,smb_size);
+ memset(cli->outbuf,'\0',smb_size);
+ memset(cli->inbuf,'\0',smb_size);
set_message(cli->outbuf,12,size,True);
@@ -1673,7 +1568,8 @@ static void cli_issue_write(struct cli_state *cli, int fnum, off_t offset, uint1
SSVAL(cli->outbuf,smb_mid,cli->mid + i);
- cli_send_smb(cli, True);
+ show_msg(cli->outbuf);
+ cli_send_smb(cli);
}
/****************************************************************************
@@ -1687,58 +1583,98 @@ ssize_t cli_write(struct cli_state *cli,
int fnum, uint16 write_mode,
char *buf, off_t offset, size_t size)
{
- int total = -1;
- int issued=0;
- int received=0;
+ int bwritten = 0;
+ int issued = 0;
+ int received = 0;
int mpx = MAX(cli->max_mux-1, 1);
int block = (cli->max_xmit - (smb_size+32)) & ~1023;
- int mid;
int blocks = (size + (block-1)) / block;
- if (size == 0) return 0;
-
while (received < blocks) {
- int size2;
- while (issued - received < mpx && issued < blocks) {
- int size1 = MIN(block, size-issued*block);
- cli_issue_write(cli, fnum, offset+issued*block,
+ while ((issued - received < mpx) && (issued < blocks))
+ {
+ int bsent = issued * block;
+ int size1 = MIN(block, size - bsent);
+
+ cli_issue_write(cli, fnum, offset + bsent,
write_mode,
- buf + issued*block,
+ buf + bsent,
size1, issued);
issued++;
}
- if (!cli_receive_smb(cli)) {
- return total;
+ if (!cli_receive_smb(cli))
+ {
+ return bwritten;
}
received++;
- mid = SVAL(cli->inbuf, smb_mid) - cli->mid;
- size2 = SVAL(cli->inbuf, smb_vwv2);
-
- if (CVAL(cli->inbuf,smb_rcls) != 0) {
- blocks = MIN(blocks, mid-1);
- continue;
- }
- if (size2 <= 0) {
- blocks = MIN(blocks, mid-1);
- /* this distinguishes EOF from an error */
- total = MAX(total, 0);
- continue;
+ if (CVAL(cli->inbuf,smb_rcls) != 0)
+ {
+ break;
}
- total += size2;
-
- total = MAX(total, mid*block + size2);
+ bwritten += SVAL(cli->inbuf, smb_vwv2);
}
- while (received < issued) {
- cli_receive_smb(cli);
+ while (received < issued && cli_receive_smb(cli))
+ {
received++;
}
+ return bwritten;
+}
+
+
+/****************************************************************************
+ write to a file using a SMBwrite and not bypassing 0 byte writes
+****************************************************************************/
+ssize_t cli_smbwrite(struct cli_state *cli,
+ int fnum, char *buf, off_t offset, size_t size1)
+{
+ char *p;
+ ssize_t total = 0;
+
+ do {
+ size_t size = MIN(size1, cli->max_xmit - 48);
+
+ memset(cli->outbuf,'\0',smb_size);
+ memset(cli->inbuf,'\0',smb_size);
+
+ set_message(cli->outbuf,5, 3 + size,True);
+
+ CVAL(cli->outbuf,smb_com) = SMBwrite;
+ SSVAL(cli->outbuf,smb_tid,cli->cnum);
+ cli_setup_packet(cli);
+
+ SSVAL(cli->outbuf,smb_vwv0,fnum);
+ SSVAL(cli->outbuf,smb_vwv1,size);
+ SIVAL(cli->outbuf,smb_vwv2,offset);
+ SSVAL(cli->outbuf,smb_vwv4,0);
+
+ p = smb_buf(cli->outbuf);
+ *p++ = 1;
+ SSVAL(p, 0, size);
+ memcpy(p+2, buf, size);
+
+ cli_send_smb(cli);
+ if (!cli_receive_smb(cli)) {
+ return -1;
+ }
+
+ if (CVAL(cli->inbuf,smb_rcls) != 0) {
+ return -1;
+ }
+
+ size = SVAL(cli->inbuf,smb_vwv0);
+ if (size == 0) break;
+
+ size1 -= size;
+ total += size;
+ } while (size1);
+
return total;
}
@@ -1750,10 +1686,10 @@ BOOL cli_getattrE(struct cli_state *cli, int fd,
uint16 *attr, size_t *size,
time_t *c_time, time_t *a_time, time_t *m_time)
{
- bzero(cli->outbuf,smb_size);
- bzero(cli->inbuf,smb_size);
+ memset(cli->outbuf,'\0',smb_size);
+ memset(cli->inbuf,'\0',smb_size);
- set_message(cli->outbuf,2,0,True);
+ set_message(cli->outbuf,1,0,True);
CVAL(cli->outbuf,smb_com) = SMBgetattrE;
SSVAL(cli->outbuf,smb_tid,cli->cnum);
@@ -1761,7 +1697,7 @@ BOOL cli_getattrE(struct cli_state *cli, int fd,
SSVAL(cli->outbuf,smb_vwv0,fd);
- cli_send_smb(cli, True);
+ cli_send_smb(cli);
if (!cli_receive_smb(cli)) {
return False;
}
@@ -1802,8 +1738,8 @@ BOOL cli_getatr(struct cli_state *cli, char *fname,
{
char *p;
- bzero(cli->outbuf,smb_size);
- bzero(cli->inbuf,smb_size);
+ memset(cli->outbuf,'\0',smb_size);
+ memset(cli->inbuf,'\0',smb_size);
set_message(cli->outbuf,0,strlen(fname)+2,True);
@@ -1814,8 +1750,9 @@ BOOL cli_getatr(struct cli_state *cli, char *fname,
p = smb_buf(cli->outbuf);
*p = 4;
pstrcpy(p+1, fname);
+ unix_to_dos(p+1,True);
- cli_send_smb(cli, True);
+ cli_send_smb(cli);
if (!cli_receive_smb(cli)) {
return False;
}
@@ -1848,8 +1785,8 @@ BOOL cli_setatr(struct cli_state *cli, char *fname, uint16 attr, time_t t)
{
char *p;
- bzero(cli->outbuf,smb_size);
- bzero(cli->inbuf,smb_size);
+ memset(cli->outbuf,'\0',smb_size);
+ memset(cli->inbuf,'\0',smb_size);
set_message(cli->outbuf,8,strlen(fname)+4,True);
@@ -1863,10 +1800,11 @@ BOOL cli_setatr(struct cli_state *cli, char *fname, uint16 attr, time_t t)
p = smb_buf(cli->outbuf);
*p = 4;
pstrcpy(p+1, fname);
+ unix_to_dos(p+1,True);
p = skip_string(p,1);
*p = 4;
- cli_send_smb(cli, True);
+ cli_send_smb(cli);
if (!cli_receive_smb(cli)) {
return False;
}
@@ -1899,6 +1837,7 @@ BOOL cli_qpathinfo(struct cli_state *cli, const char *fname,
memset(param, 0, param_len);
SSVAL(param, 0, SMB_INFO_STANDARD);
pstrcpy(&param[6], fname);
+ unix_to_dos(&param[6],True);
do {
ret = (cli_send_trans(cli, SMBtrans2,
@@ -1916,7 +1855,7 @@ BOOL cli_qpathinfo(struct cli_state *cli, const char *fname,
it gives ERRSRV/ERRerror temprarily */
uint8 eclass;
uint32 ecode;
- cli_error(cli, &eclass, &ecode);
+ cli_error(cli, &eclass, &ecode, NULL);
if (eclass != ERRSRV || ecode != ERRerror) break;
msleep(100);
}
@@ -1972,6 +1911,7 @@ BOOL cli_qpathinfo2(struct cli_state *cli, const char *fname,
memset(param, 0, param_len);
SSVAL(param, 0, SMB_QUERY_FILE_ALL_INFO);
pstrcpy(&param[6], fname);
+ unix_to_dos(&param[6],True);
if (!cli_send_trans(cli, SMBtrans2,
NULL, 0, /* name, length */
@@ -2009,7 +1949,7 @@ BOOL cli_qpathinfo2(struct cli_state *cli, const char *fname,
*mode = SVAL(rdata, 32);
}
if (size) {
- *size = IVAL(rdata, 40);
+ *size = IVAL(rdata, 48);
}
if (ino) {
*ino = IVAL(rdata, 64);
@@ -2081,7 +2021,7 @@ BOOL cli_qfileinfo(struct cli_state *cli, int fnum,
*mode = SVAL(rdata, 32);
}
if (size) {
- *size = IVAL(rdata, 40);
+ *size = IVAL(rdata, 48);
}
if (ino) {
*ino = IVAL(rdata, 64);
@@ -2117,6 +2057,7 @@ static int interpret_long_filename(int level,char *p,file_info *finfo)
finfo->size = IVAL(p,16);
finfo->mode = CVAL(p,24);
pstrcpy(finfo->name,p+27);
+ dos_to_unix(finfo->name,True);
}
return(28 + CVAL(p,26));
@@ -2129,6 +2070,7 @@ static int interpret_long_filename(int level,char *p,file_info *finfo)
finfo->size = IVAL(p,16);
finfo->mode = CVAL(p,24);
pstrcpy(finfo->name,p+31);
+ dos_to_unix(finfo->name,True);
}
return(32 + CVAL(p,30));
@@ -2142,6 +2084,7 @@ static int interpret_long_filename(int level,char *p,file_info *finfo)
finfo->size = IVAL(p,20);
finfo->mode = CVAL(p,28);
pstrcpy(finfo->name,p+33);
+ dos_to_unix(finfo->name,True);
}
return(SVAL(p,4)+4);
@@ -2154,6 +2097,7 @@ static int interpret_long_filename(int level,char *p,file_info *finfo)
finfo->size = IVAL(p,20);
finfo->mode = CVAL(p,28);
pstrcpy(finfo->name,p+37);
+ dos_to_unix(finfo->name,True);
}
return(SVAL(p,4)+4);
@@ -2189,7 +2133,8 @@ static int interpret_long_filename(int level,char *p,file_info *finfo)
p += 4; /* EA size */
p += 2; /* short name len? */
p += 24; /* short name? */
- StrnCpy(finfo->name,p,namelen);
+ StrnCpy(finfo->name,p,MIN(sizeof(finfo->name)-1,namelen));
+ dos_to_unix(finfo->name,True);
return(ret);
}
return(SVAL(p,0));
@@ -2217,7 +2162,6 @@ int cli_list(struct cli_state *cli,const char *Mask,uint16 attribute,
int dirlist_len = 0;
int total_received = -1;
BOOL First = True;
- int ff_resume_key = 0;
int ff_searchcount=0;
int ff_eos=0;
int ff_lastname=0;
@@ -2230,6 +2174,7 @@ int cli_list(struct cli_state *cli,const char *Mask,uint16 attribute,
pstring param;
pstrcpy(mask,Mask);
+ unix_to_dos(mask,True);
while (ff_eos == 0) {
loop_count++;
@@ -2253,12 +2198,12 @@ int cli_list(struct cli_state *cli,const char *Mask,uint16 attribute,
SSVAL(param,0,ff_dir_handle);
SSVAL(param,2,max_matches); /* max count */
SSVAL(param,4,info_level);
- SIVAL(param,6,ff_resume_key); /* ff_resume_key */
+ SIVAL(param,6,0); /* ff_resume_key */
SSVAL(param,10,8+4+2); /* resume required + close on end + continue */
pstrcpy(param+12,mask);
- DEBUG(5,("hand=0x%X resume=%d ff_lastname=%d mask=%s\n",
- ff_dir_handle,ff_resume_key,ff_lastname,mask));
+ DEBUG(5,("hand=0x%X ff_lastname=%d mask=%s\n",
+ ff_dir_handle,ff_lastname,mask));
}
if (!cli_send_trans(cli, SMBtrans2,
@@ -2279,7 +2224,7 @@ int cli_list(struct cli_state *cli,const char *Mask,uint16 attribute,
it gives ERRSRV/ERRerror temprarily */
uint8 eclass;
uint32 ecode;
- cli_error(cli, &eclass, &ecode);
+ cli_error(cli, &eclass, &ecode, NULL);
if (eclass != ERRSRV || ecode != ERRerror) break;
msleep(100);
continue;
@@ -2311,19 +2256,19 @@ int cli_list(struct cli_state *cli,const char *Mask,uint16 attribute,
switch(info_level)
{
case 260:
- ff_resume_key =0;
StrnCpy(mask,p+ff_lastname,
- data_len-ff_lastname);
+ MIN(sizeof(mask)-1,data_len-ff_lastname));
break;
case 1:
pstrcpy(mask,p + ff_lastname + 1);
- ff_resume_key = 0;
break;
}
} else {
pstrcpy(mask,"");
}
-
+
+ dos_to_unix(mask, True);
+
/* and add them to the dirlist pool */
dirlist = Realloc(dirlist,dirlist_len + data_len);
@@ -2347,8 +2292,10 @@ int cli_list(struct cli_state *cli,const char *Mask,uint16 attribute,
if (rdata) free(rdata); rdata = NULL;
if (rparam) free(rparam); rparam = NULL;
- DEBUG(3,("received %d entries (eos=%d resume=%d)\n",
- ff_searchcount,ff_eos,ff_resume_key));
+ DEBUG(3,("received %d entries (eos=%d)\n",
+ ff_searchcount,ff_eos));
+
+ if (ff_searchcount > 0) loop_count = 0;
First = False;
}
@@ -2383,6 +2330,7 @@ BOOL cli_oem_change_password(struct cli_state *cli, const char *user, const char
char *rparam = NULL;
char *rdata = NULL;
int rprcnt, rdrcnt;
+ pstring dos_new_password;
if (strlen(user) >= sizeof(fstring)-1) {
DEBUG(0,("cli_oem_change_password: user name %s is too long.\n", user));
@@ -2408,19 +2356,22 @@ BOOL cli_oem_change_password(struct cli_state *cli, const char *user, const char
*/
memset(upper_case_old_pw, '\0', sizeof(upper_case_old_pw));
fstrcpy(upper_case_old_pw, old_password);
+ unix_to_dos(upper_case_old_pw,True);
strupper(upper_case_old_pw);
E_P16((uchar *)upper_case_old_pw, old_pw_hash);
- if (!make_oem_passwd_hash( data, new_password, old_pw_hash, False))
- {
- return False;
- }
+ pstrcpy(dos_new_password, new_password);
+ unix_to_dos(dos_new_password, True);
+
+ if (!make_oem_passwd_hash( data, dos_new_password, old_pw_hash, False))
+ return False;
/*
* Now place the old password hash in the data.
*/
memset(upper_case_new_pw, '\0', sizeof(upper_case_new_pw));
fstrcpy(upper_case_new_pw, new_password);
+ unix_to_dos(upper_case_new_pw,True);
strupper(upper_case_new_pw);
E_P16((uchar *)upper_case_new_pw, new_pw_hash);
@@ -2429,14 +2380,13 @@ BOOL cli_oem_change_password(struct cli_state *cli, const char *user, const char
data_len = 532;
- if (!cli_send_trans(cli,SMBtrans,
+ if (cli_send_trans(cli,SMBtrans,
PIPE_LANMAN,strlen(PIPE_LANMAN), /* name, length */
0,0, /* fid, flags */
NULL,0,0, /* setup, length, max */
param,param_len,2, /* param, length, max */
data,data_len,0 /* data, length, max */
- ))
- {
+ ) == False) {
DEBUG(0,("cli_oem_change_password: Failed to send password change for user %s\n",
user ));
return False;
@@ -2466,7 +2416,7 @@ BOOL cli_negprot(struct cli_state *cli)
int numprots;
int plength;
- bzero(cli->outbuf,smb_size);
+ memset(cli->outbuf,'\0',smb_size);
/* setup the protocol strings */
for (plength=0,numprots=0;
@@ -2482,6 +2432,7 @@ BOOL cli_negprot(struct cli_state *cli)
numprots++) {
*p++ = 2;
pstrcpy(p,prots[numprots].name);
+ unix_to_dos(p,True);
p += strlen(p) + 1;
}
@@ -2490,11 +2441,11 @@ BOOL cli_negprot(struct cli_state *cli)
CVAL(smb_buf(cli->outbuf),0) = 2;
- cli_send_smb(cli, True);
+ cli_send_smb(cli);
if (!cli_receive_smb(cli))
- {
return False;
- }
+
+ show_msg(cli->inbuf);
if (CVAL(cli->inbuf,smb_rcls) != 0 ||
((int)SVAL(cli->inbuf,smb_vwv0) >= numprots)) {
@@ -2504,56 +2455,28 @@ BOOL cli_negprot(struct cli_state *cli)
cli->protocol = prots[SVAL(cli->inbuf,smb_vwv0)].prot;
- if (cli->protocol >= PROTOCOL_NT1)
- {
- char *buf = smb_buf(cli->inbuf);
- int bcc = SVAL(cli->inbuf,smb_vwv+2*(CVAL(cli->inbuf,smb_wct)));
+ if (cli->protocol >= PROTOCOL_NT1) {
/* NT protocol */
cli->sec_mode = CVAL(cli->inbuf,smb_vwv1);
cli->max_mux = SVAL(cli->inbuf, smb_vwv1+1);
cli->max_xmit = IVAL(cli->inbuf,smb_vwv3+1);
cli->sesskey = IVAL(cli->inbuf,smb_vwv7+1);
- cli->serverzone = SVALS(cli->inbuf,smb_vwv15+1)*60;
+ cli->serverzone = SVALS(cli->inbuf,smb_vwv15+1);
+ cli->serverzone *= 60;
/* this time arrives in real GMT */
cli->servertime = interpret_long_date(cli->inbuf+smb_vwv11+1);
-
+ memcpy(cli->cryptkey,smb_buf(cli->inbuf),8);
cli->capabilities = IVAL(cli->inbuf,smb_vwv9+1);
- if (IS_BITS_SET_ALL(cli->capabilities, CAP_RAW_MODE))
- {
+ if (cli->capabilities & 1) {
cli->readbraw_supported = True;
cli->writebraw_supported = True;
}
-
- if (IS_BITS_SET_ALL(cli->capabilities, CAP_EXTENDED_SECURITY))
- {
- /* oops, some kerberos-related nonsense. */
- /* expect to have to use NTLMSSP-over-SMB */
- DEBUG(10,("unknown kerberos-related (?) blob\n"));
- memset(cli->cryptkey, 0, 8);
- cli->server_domain[0] = 0;
- }
- else
- {
- memcpy(cli->cryptkey, buf,8);
- if (bcc > 8)
- {
- unibuf_to_ascii(cli->server_domain, buf+8,
- sizeof(cli->server_domain));
- }
- else
- {
- cli->server_domain[0] = 0;
- }
- DEBUG(5,("server's domain: %s bcc: %d\n",
- cli->server_domain, bcc));
- }
- }
- else if (cli->protocol >= PROTOCOL_LANMAN1)
- {
+ } else if (cli->protocol >= PROTOCOL_LANMAN1) {
cli->sec_mode = SVAL(cli->inbuf,smb_vwv1);
cli->max_xmit = SVAL(cli->inbuf,smb_vwv2);
cli->sesskey = IVAL(cli->inbuf,smb_vwv6);
- cli->serverzone = SVALS(cli->inbuf,smb_vwv10)*60;
+ cli->serverzone = SVALS(cli->inbuf,smb_vwv10);
+ cli->serverzone *= 60;
/* this time is converted to GMT by make_unix_date */
cli->servertime = make_unix_date(cli->inbuf+smb_vwv8);
cli->readbraw_supported = ((SVAL(cli->inbuf,smb_vwv5) & 0x1) != 0);
@@ -2584,11 +2507,6 @@ BOOL cli_session_request(struct cli_state *cli,
memcpy(&(cli->calling), calling, sizeof(*calling));
memcpy(&(cli->called ), called , sizeof(*called ));
- if (cli->port == 445)
- {
- return True;
- }
-
/* put in the destination name */
p = cli->outbuf+len;
name_mangle(cli->called .name, p, cli->called .name_type);
@@ -2607,12 +2525,41 @@ BOOL cli_session_request(struct cli_state *cli,
retry:
#endif /* WITH_SSL */
- cli_send_smb(cli, True);
+ cli_send_smb(cli);
DEBUG(5,("Sent session request\n"));
if (!cli_receive_smb(cli))
return False;
+ if (CVAL(cli->inbuf,0) == 0x84) {
+ /* C. Hoch 9/14/95 Start */
+ /* For information, here is the response structure.
+ * We do the byte-twiddling to for portability.
+ struct RetargetResponse{
+ unsigned char type;
+ unsigned char flags;
+ int16 length;
+ int32 ip_addr;
+ int16 port;
+ };
+ */
+ int port = (CVAL(cli->inbuf,8)<<8)+CVAL(cli->inbuf,9);
+ /* SESSION RETARGET */
+ putip((char *)&cli->dest_ip,cli->inbuf+4);
+
+ close_sockets();
+ cli->fd = open_socket_out(SOCK_STREAM, &cli->dest_ip, port, LONG_CONNECT_TIMEOUT);
+ if (cli->fd == -1)
+ return False;
+
+ DEBUG(3,("Retargeted\n"));
+
+ set_socket_options(cli->fd,user_socket_options);
+
+ /* Try again */
+ return cli_session_request(cli, calling, called);
+ } /* C. Hoch 9/14/95 End */
+
#ifdef WITH_SSL
if (CVAL(cli->inbuf,0) == 0x83 && CVAL(cli->inbuf,4) == 0x8e){ /* use ssl */
if (!sslutil_fd_is_ssl(cli->fd)){
@@ -2624,7 +2571,7 @@ retry:
if (CVAL(cli->inbuf,0) != 0x82) {
/* This is the wrong place to put the error... JRA. */
- cli->rap_error = CVAL(cli->inbuf,0);
+ cli->rap_error = CVAL(cli->inbuf,4);
return False;
}
return(True);
@@ -2637,7 +2584,6 @@ open the client sockets
BOOL cli_connect(struct cli_state *cli, const char *host, struct in_addr *ip)
{
extern struct in_addr ipzero;
- int port = cli->port;
fstrcpy(cli->desthost, host);
@@ -2650,25 +2596,14 @@ BOOL cli_connect(struct cli_state *cli, const char *host, struct in_addr *ip)
cli->dest_ip = *ip;
}
-
- if (port == 0) port = SMB_PORT2;
+ if (cli->port == 0) cli->port = 139; /* Set to default */
cli->fd = open_socket_out(SOCK_STREAM, &cli->dest_ip,
- port, cli->timeout);
+ cli->port, cli->timeout);
if (cli->fd == -1)
- {
- if (cli->port != 0)
- {
- return False;
- }
- port = SMB_PORT;
-
- cli->fd = open_socket_out(SOCK_STREAM, &cli->dest_ip,
- port, cli->timeout);
- if (cli->fd == -1) return False;
- }
+ return False;
- cli->port = port;
+ set_socket_options(cli->fd,user_socket_options);
return True;
}
@@ -2677,14 +2612,6 @@ BOOL cli_connect(struct cli_state *cli, const char *host, struct in_addr *ip)
/****************************************************************************
initialise a client structure
****************************************************************************/
-void cli_init_creds(struct cli_state *cli, const struct ntuser_creds *usr)
-{
- copy_nt_creds(&cli->usr, usr);
-}
-
-/****************************************************************************
-initialise a client structure
-****************************************************************************/
struct cli_state *cli_initialise(struct cli_state *cli)
{
if (!cli) {
@@ -2707,7 +2634,7 @@ struct cli_state *cli_initialise(struct cli_state *cli)
cli->mid = 1;
cli->vuid = UID_FIELD_INVALID;
cli->protocol = PROTOCOL_NT1;
- cli->timeout = 20000;
+ cli->timeout = 20000; /* Timeout is in milliseconds. */
cli->bufsize = CLI_BUFFER_SIZE+4;
cli->max_xmit = cli->bufsize;
cli->outbuf = (char *)malloc(cli->bufsize);
@@ -2717,39 +2644,19 @@ struct cli_state *cli_initialise(struct cli_state *cli)
return False;
}
- cli->initialised = 1;
- cli->capabilities = CAP_DFS | CAP_NT_SMBS | CAP_STATUS32;
- cli->use_ntlmv2 = Auto;
+ memset(cli->outbuf, '\0', cli->bufsize);
+ memset(cli->inbuf, '\0', cli->bufsize);
- cli_init_creds(cli, NULL);
+ cli->initialised = 1;
return cli;
}
/****************************************************************************
-close the socket descriptor
-****************************************************************************/
-void cli_close_socket(struct cli_state *cli)
-{
-#ifdef WITH_SSL
- if (cli->fd != -1)
- {
- sslutil_disconnect(cli->fd);
- }
-#endif /* WITH_SSL */
- if (cli->fd != -1)
- {
- close(cli->fd);
- }
- cli->fd = -1;
-}
-
-/****************************************************************************
shutdown a client structure
****************************************************************************/
void cli_shutdown(struct cli_state *cli)
{
- DEBUG(10,("cli_shutdown\n"));
if (cli->outbuf)
{
free(cli->outbuf);
@@ -2758,7 +2665,12 @@ void cli_shutdown(struct cli_state *cli)
{
free(cli->inbuf);
}
- cli_close_socket(cli);
+#ifdef WITH_SSL
+ if (cli->fd != -1)
+ sslutil_disconnect(cli->fd);
+#endif /* WITH_SSL */
+ if (cli->fd != -1)
+ close(cli->fd);
memset(cli, 0, sizeof(*cli));
}
@@ -2771,43 +2683,34 @@ void cli_shutdown(struct cli_state *cli)
for 32 bit "warnings", a return code of 0 is expected.
****************************************************************************/
-int cli_error(struct cli_state *cli, uint8 *eclass, uint32 *num)
+int cli_error(struct cli_state *cli, uint8 *eclass, uint32 *num, uint32 *nt_rpc_error)
{
- int flgs2;
+ int flgs2 = SVAL(cli->inbuf,smb_flg2);
char rcls;
int code;
- if (!cli->initialised)
- {
- DEBUG(0,("cli_error: client state uninitialised!\n"));
- return EINVAL;
- }
-
- flgs2 = SVAL(cli->inbuf,smb_flg2);
-
if (eclass) *eclass = 0;
if (num ) *num = 0;
+ if (nt_rpc_error) *nt_rpc_error = cli->nt_error;
- if (flgs2 & FLAGS2_32_BIT_ERROR_CODES)
- {
+ if (flgs2 & FLAGS2_32_BIT_ERROR_CODES) {
/* 32 bit error codes detected */
uint32 nt_err = IVAL(cli->inbuf,smb_rcls);
if (num) *num = nt_err;
DEBUG(10,("cli_error: 32 bit codes: code=%08x\n", nt_err));
if (!IS_BITS_SET_ALL(nt_err, 0xc0000000)) return 0;
- switch (nt_err & 0xFFFFFF)
- {
- case NT_STATUS_ACCESS_VIOLATION : return EACCES;
- case NT_STATUS_NO_SUCH_FILE : return ENOENT;
- case NT_STATUS_NO_SUCH_DEVICE : return ENODEV;
- case NT_STATUS_INVALID_HANDLE : return EBADF;
- case NT_STATUS_NO_MEMORY : return ENOMEM;
- case NT_STATUS_ACCESS_DENIED : return EACCES;
- case NT_STATUS_OBJECT_NAME_NOT_FOUND: return ENOENT;
- case NT_STATUS_SHARING_VIOLATION : return EBUSY;
- case NT_STATUS_OBJECT_PATH_INVALID : return ENOTDIR;
- case NT_STATUS_OBJECT_NAME_COLLISION: return EEXIST;
+ switch (nt_err & 0xFFFFFF) {
+ case NT_STATUS_ACCESS_VIOLATION: return EACCES;
+ case NT_STATUS_NO_SUCH_FILE: return ENOENT;
+ case NT_STATUS_NO_SUCH_DEVICE: return ENODEV;
+ case NT_STATUS_INVALID_HANDLE: return EBADF;
+ case NT_STATUS_NO_MEMORY: return ENOMEM;
+ case NT_STATUS_ACCESS_DENIED: return EACCES;
+ case NT_STATUS_OBJECT_NAME_NOT_FOUND: return ENOENT;
+ case NT_STATUS_SHARING_VIOLATION: return EBUSY;
+ case NT_STATUS_OBJECT_PATH_INVALID: return ENOTDIR;
+ case NT_STATUS_OBJECT_NAME_COLLISION: return EEXIST;
}
/* for all other cases - a default code */
@@ -2830,7 +2733,6 @@ int cli_error(struct cli_state *cli, uint8 *eclass, uint32 *num)
case ERRrename: return EEXIST;
case ERRbadshare: return EBUSY;
case ERRlock: return EBUSY;
- case ERRmoredata: return 0; /* Informational only */
}
}
if (rcls == ERRSRV) {
@@ -2887,36 +2789,29 @@ BOOL cli_reestablish_connection(struct cli_state *cli)
if (cli->cnum != 0)
{
- do_tcon = True;
- }
-
- if (do_tcon)
- {
fstrcpy(share, cli->share);
fstrcpy(dev , cli->dev);
+ do_tcon = True;
}
memcpy(&called , &(cli->called ), sizeof(called ));
memcpy(&calling, &(cli->calling), sizeof(calling));
- fstrcpy(dest_host, cli->desthost);
+ fstrcpy(dest_host, cli->full_dest_host_name);
DEBUG(5,("cli_reestablish_connection: %s connecting to %s (ip %s) - %s [%s]\n",
nmb_namestr(&calling), nmb_namestr(&called),
inet_ntoa(cli->dest_ip),
- cli->usr.user_name, cli->usr.domain));
+ cli->user_name, cli->domain));
cli->fd = -1;
if (cli_establish_connection(cli,
dest_host, &cli->dest_ip,
&calling, &called,
- share, dev, False, do_tcon))
- {
- if (cli->fd != oldfd)
- {
- if (dup2(cli->fd, oldfd) == oldfd)
- {
- cli_close_socket(cli);
+ share, dev, False, do_tcon)) {
+ if (cli->fd != oldfd) {
+ if (dup2(cli->fd, oldfd) == oldfd) {
+ close(cli->fd);
}
}
return True;
@@ -2924,101 +2819,18 @@ BOOL cli_reestablish_connection(struct cli_state *cli)
return False;
}
-static BOOL cli_init_redirect(struct cli_state *cli,
- const char* srv_name, struct in_addr *destip,
- const struct ntuser_creds *usr)
-{
- int sock;
- fstring ip_name;
- struct cli_state cli_redir;
- fstring path;
-
- uint32 len;
- char *data;
- char *in = cli->inbuf;
- char *out = cli->outbuf;
- prs_struct ps;
- uint16 command;
-
- slprintf(path, sizeof(path)-1, "/tmp/.smb.%d/agent", getuid());
-
- if (strequal(srv_name, "*SMBSERVER"))
- {
- fstrcpy(ip_name, "\\\\");
- inet_aton(&ip_name[2], destip);
- srv_name = ip_name;
- }
-
- sock = open_pipe_sock(path);
-
- if (sock < 0)
- {
- return False;
- }
-
- command = usr != NULL ? AGENT_CMD_CON : AGENT_CMD_CON_ANON;
-
- if (!create_ntuser_creds(&ps, srv_name, 0x0, command, usr, cli->reuse))
- {
- DEBUG(0,("could not parse credentials\n"));
- close(sock);
- return False;
- }
-
- len = ps.offset;
- data = mem_data(&ps.data, 0);
-
-#ifdef DEBUG_PASSWORD
- DEBUG(100,("data len: %d\n", len));
- dump_data(100, data, len);
-#endif
-
- SIVAL(data, 0, len);
-
- if (write(sock, data, len) <= 0)
- {
- DEBUG(0,("write failed\n"));
- close(sock);
- return False;
- }
-
- len = read(sock, &cli_redir, sizeof(cli_redir));
-
- if (len != sizeof(cli_redir))
- {
- DEBUG(0,("read failed\n"));
- close(sock);
- return False;
- }
-
- memcpy(cli, &cli_redir, sizeof(cli_redir));
- cli->inbuf = in;
- cli->outbuf = out;
- cli->fd = sock;
- cli->reuse = False;
-
- return sock;
-}
-
/****************************************************************************
establishes a connection right up to doing tconX, reading in a password.
****************************************************************************/
BOOL cli_establish_connection(struct cli_state *cli,
- const char *dest_host, struct in_addr *dest_ip,
+ char *dest_host, struct in_addr *dest_ip,
struct nmb_name *calling, struct nmb_name *called,
char *service, char *service_type,
BOOL do_shutdown, BOOL do_tcon)
{
- fstring callingstr;
- fstring calledstr;
-
- nmb_safe_namestr(calling, callingstr, sizeof(callingstr));
- nmb_safe_namestr(called , calledstr , sizeof(calledstr ));
-
- DEBUG(5,("cli_establish_connection: %s connecting to %s (%s) - %s [%s] with NTLM%s\n",
- callingstr, calledstr, inet_ntoa(*dest_ip),
- cli->usr.user_name, cli->usr.domain,
- cli->use_ntlmv2 ? "v2" : "v1"));
+ DEBUG(5,("cli_establish_connection: %s connecting to %s (%s) - %s [%s]\n",
+ nmb_namestr(calling), nmb_namestr(called), inet_ntoa(*dest_ip),
+ cli->user_name, cli->domain));
/* establish connection */
@@ -3027,24 +2839,12 @@ BOOL cli_establish_connection(struct cli_state *cli,
return False;
}
- if (cli->fd == -1 && cli->redirect)
- {
- if (cli_init_redirect(cli, dest_host, dest_ip, &cli->usr))
- {
- DEBUG(10,("cli_establish_connection: redirected OK\n"));
- return True;
- }
- else
- {
- DEBUG(10,("redirect FAILED, make direct connection\n"));
- }
- }
if (cli->fd == -1)
{
if (!cli_connect(cli, dest_host, dest_ip))
{
DEBUG(1,("cli_establish_connection: failed to connect to %s (%s)\n",
- callingstr, inet_ntoa(*dest_ip)));
+ nmb_namestr(calling), inet_ntoa(*dest_ip)));
return False;
}
}
@@ -3053,9 +2853,7 @@ BOOL cli_establish_connection(struct cli_state *cli,
{
DEBUG(1,("failed session request\n"));
if (do_shutdown)
- {
- cli_shutdown(cli);
- }
+ cli_shutdown(cli);
return False;
}
@@ -3063,242 +2861,33 @@ BOOL cli_establish_connection(struct cli_state *cli,
{
DEBUG(1,("failed negprot\n"));
if (do_shutdown)
- {
- cli_shutdown(cli);
- }
+ cli_shutdown(cli);
return False;
}
- if (cli->usr.domain[0] == 0)
- {
- safe_strcpy(cli->usr.domain, cli->server_domain,
- sizeof(cli->usr.domain));
- }
-
- if (IS_BITS_SET_ALL(cli->capabilities, CAP_EXTENDED_SECURITY))
+ if (cli->pwd.cleartext || cli->pwd.null_pwd)
{
- /* common to both session setups */
- uint32 ntlmssp_flgs;
- char pwd_buf[128];
- int buf_len;
- char *p;
- char *e = pwd_buf + sizeof(pwd_buf);
-
- /* 1st session setup */
- char pwd_data[34] =
- {
- 0x60, 0x40, 0x06, 0x06, 0x2b, 0x06, 0x01, 0x05,
- 0x05, 0x02, 0xa0, 0x36, 0x30, 0x34, 0xa0, 0x0e,
- 0x30, 0x0c, 0x06, 0x0a, 0x2b, 0x06, 0x01, 0x04,
- 0x01, 0x82, 0x37, 0x02, 0x02, 0x0a, 0xa2, 0x22,
- 0x04, 0x20
- };
- /* 2nd session setup */
-#if 0
- char pwd_data_2[8] =
- {
- 0xa1, 0x51, 0x30, 0x4f, 0xa2, 0x4d, 0x04, 0x4b
- };
-#endif
- char pwd_data_2[8] =
- {
- 0xa1, 0x51, 0x30, 0x4f, 0xa2, 0x4d, 0x04, 0x4b
- };
- prs_struct auth_resp;
- int resp_len;
- char *p_gssapi;
- char *p_oem;
- char *p_gssapi_end;
- uint16 gssapi_len;
-
- memset(pwd_buf, 0, sizeof(pwd_buf));
- memcpy(pwd_buf, pwd_data, sizeof(pwd_data));
- p = pwd_buf + sizeof(pwd_data);
-
- safe_strcpy(p, "NTLMSSP", PTR_DIFF(e, p) - 1);
- p = skip_string(p, 1);
- CVAL(p, 0) = 0x1;
- p += 4;
- ntlmssp_flgs =
- NTLMSSP_NEGOTIATE_UNICODE |
- NTLMSSP_NEGOTIATE_OEM |
- NTLMSSP_NEGOTIATE_SIGN |
- NTLMSSP_NEGOTIATE_SEAL |
- NTLMSSP_NEGOTIATE_LM_KEY |
- NTLMSSP_NEGOTIATE_NTLM |
- NTLMSSP_NEGOTIATE_ALWAYS_SIGN |
- NTLMSSP_NEGOTIATE_00001000 |
- NTLMSSP_NEGOTIATE_00002000;
- SIVAL(p, 0, ntlmssp_flgs);
- p += 4;
- p += 16; /* skip some NULL space */
- CVAL(p, 0) = 0; p++; /* alignment */
-
- buf_len = PTR_DIFF(p, pwd_buf);
-
- /* first session negotiation stage */
- if (!cli_session_setup_x(cli, cli->usr.user_name,
- pwd_buf, buf_len,
- NULL, 0,
- cli->usr.domain))
- {
- DEBUG(1,("failed session setup\n"));
- if (do_shutdown)
- {
- cli_shutdown(cli);
- }
- return False;
- }
-
- DEBUG(1,("1st session setup ok\n"));
+ fstring passwd;
+ int pass_len;
- if (*cli->server_domain || *cli->server_os || *cli->server_type)
- {
- DEBUG(1,("Domain=[%s] OS=[%s] Server=[%s]\n",
- cli->server_domain,
- cli->server_os,
- cli->server_type));
- }
-
- p = smb_buf(cli->inbuf) + 0x2f;
- ntlmssp_flgs = IVAL(p, 0); /* 0x80808a05; */
- p += 4;
- memcpy(cli->cryptkey, p, 8);
-#ifdef DEBUG_PASSWORD
- DEBUG(100,("cli_session_setup_x: ntlmssp %8x\n",
- ntlmssp_flgs));
-
- DEBUG(100,("cli_session_setup_x: crypt key\n"));
- dump_data(100, cli->cryptkey, 8);
-#endif
- prs_init(&auth_resp, 1024, 4, SAFETY_MARGIN, False);
-
- if (cli->use_ntlmv2 != False)
- {
- DEBUG(10,("cli_establish_connection: NTLMv2\n"));
- pwd_make_lm_nt_owf2(&(cli->usr.pwd), cli->cryptkey,
- cli->usr.user_name, calling->name, cli->usr.domain);
- }
- else
- {
- DEBUG(10,("cli_establish_connection: NTLMv1\n"));
- pwd_make_lm_nt_owf(&(cli->usr.pwd), cli->cryptkey);
- }
-
- create_ntlmssp_resp(&cli->usr.pwd, cli->usr.domain,
- cli->usr.user_name, cli->calling.name,
- ntlmssp_flgs,
- &auth_resp);
- prs_link(NULL, &auth_resp, NULL);
-
- memset(pwd_buf, 0, sizeof(pwd_buf));
- p = pwd_buf;
-
- CVAL(p, 0) = 0xa1; p++;
- CVAL(p, 0) = 0x82; p++;
- p_gssapi = p; p+= 2;
- CVAL(p, 0) = 0x30; p++;
- CVAL(p, 0) = 0x82; p++;
- p += 2;
-
- CVAL(p, 0) = 0xa2; p++;
- CVAL(p, 0) = 0x82; p++;
- p_oem = p; p+= 2;
- CVAL(p, 0) = 0x04; p++;
- CVAL(p, 0) = 0x82; p++;
- p += 2;
-
- p_gssapi_end = p;
-
- safe_strcpy(p, "NTLMSSP", PTR_DIFF(e, p) - 1);
- p = skip_string(p, 1);
- CVAL(p, 0) = 0x3;
- p += 4;
-
- resp_len = mem_buf_len(auth_resp.data);
- mem_buf_copy(p, auth_resp.data, 0, resp_len);
- prs_mem_free(&auth_resp);
-
- p += resp_len;
-
- buf_len = PTR_DIFF(p, pwd_buf);
- gssapi_len = PTR_DIFF(p, p_gssapi_end) + 12;
-
- *p_gssapi++ = (gssapi_len >> 8) & 0xff;
- *p_gssapi++ = gssapi_len & 0xff;
-
- p_gssapi += 2;
- gssapi_len -= 4;
-
- *p_gssapi++ = (gssapi_len >> 8) & 0xff;
- *p_gssapi++ = gssapi_len & 0xff;
-
- gssapi_len -= 4;
-
- *p_oem++ = (gssapi_len >> 8) & 0xff;
- *p_oem++ = gssapi_len & 0xff;
-
- p_oem += 2;
- gssapi_len -= 4;
-
- *p_oem++ = (gssapi_len >> 8) & 0xff;
- *p_oem++ = gssapi_len & 0xff;
-
- /* second session negotiation stage */
- if (!cli_session_setup_x(cli, cli->usr.user_name,
- pwd_buf, buf_len,
- NULL, 0,
- cli->usr.domain))
- {
- DEBUG(1,("failed session setup\n"));
- if (do_shutdown)
- {
- cli_shutdown(cli);
- }
- return False;
- }
-
- DEBUG(1,("2nd session setup ok\n"));
-
- if (do_tcon)
- {
- if (!cli_send_tconX(cli, service, service_type,
- NULL, 0))
-
- {
- DEBUG(1,("failed tcon_X\n"));
- if (do_shutdown)
- {
- cli_shutdown(cli);
- }
- return False;
- }
- }
- }
- else if (cli->usr.pwd.cleartext || cli->usr.pwd.null_pwd)
- {
- fstring passwd, ntpasswd;
- int pass_len = 0, ntpass_len = 0;
-
- if (cli->usr.pwd.null_pwd)
+ if (cli->pwd.null_pwd)
{
/* attempt null session */
- passwd[0] = ntpasswd[0] = 0;
- pass_len = ntpass_len = 1;
+ passwd[0] = 0;
+ pass_len = 1;
}
else
{
/* attempt clear-text session */
- pwd_get_cleartext(&(cli->usr.pwd), passwd);
+ pwd_get_cleartext(&(cli->pwd), passwd);
pass_len = strlen(passwd);
}
/* attempt clear-text session */
- if (!cli_session_setup(cli, calling->name,
- cli->usr.user_name,
+ if (!cli_session_setup(cli, cli->user_name,
passwd, pass_len,
- ntpasswd, ntpass_len,
- cli->usr.domain))
+ NULL, 0,
+ cli->domain))
{
DEBUG(1,("failed session setup\n"));
if (do_shutdown)
@@ -3324,68 +2913,25 @@ BOOL cli_establish_connection(struct cli_state *cli,
else
{
/* attempt encrypted session */
+ unsigned char nt_sess_pwd[24];
unsigned char lm_sess_pwd[24];
- unsigned char nt_sess_pwd[128];
- size_t nt_sess_pwd_len;
-
- if (cli->use_ntlmv2 != False)
- {
- DEBUG(10,("cli_establish_connection: NTLMv2\n"));
- pwd_make_lm_nt_owf2(&(cli->usr.pwd), cli->cryptkey,
- cli->usr.user_name, calling->name, cli->usr.domain);
- }
- else
- {
- DEBUG(10,("cli_establish_connection: NTLMv1\n"));
- pwd_make_lm_nt_owf(&(cli->usr.pwd), cli->cryptkey);
- }
- pwd_get_lm_nt_owf(&(cli->usr.pwd), lm_sess_pwd, nt_sess_pwd,
- &nt_sess_pwd_len, cli->sess_key);
+ /* creates (storing a copy of) and then obtains a 24 byte password OWF */
+ pwd_make_lm_nt_owf(&(cli->pwd), cli->cryptkey);
+ pwd_get_lm_nt_owf(&(cli->pwd), lm_sess_pwd, nt_sess_pwd);
/* attempt encrypted session */
- if (!cli_session_setup_x(cli, cli->usr.user_name,
- (char*)lm_sess_pwd, sizeof(lm_sess_pwd),
- (char*)nt_sess_pwd, nt_sess_pwd_len,
- cli->usr.domain))
+ if (!cli_session_setup(cli, cli->user_name,
+ (char*)lm_sess_pwd, sizeof(lm_sess_pwd),
+ (char*)nt_sess_pwd, sizeof(nt_sess_pwd),
+ cli->domain))
{
DEBUG(1,("failed session setup\n"));
-
- if (cli->use_ntlmv2 == Auto)
- {
- DEBUG(10,("NTLMv2 failed. Using NTLMv1\n"));
- cli->use_ntlmv2 = False;
- if (do_tcon)
- {
- fstrcpy(cli->share, service);
- fstrcpy(cli->dev, service_type);
- }
- fstrcpy(cli->desthost, dest_host);
- cli_close_socket(cli);
- return cli_establish_connection(cli,
- dest_host, dest_ip,
- calling, called,
- service, service_type,
- do_shutdown, do_tcon);
- }
-
if (do_shutdown)
- {
- cli_shutdown(cli);
- }
+ cli_shutdown(cli);
return False;
}
- DEBUG(1,("session setup ok\n"));
-
- if (*cli->server_domain || *cli->server_os || *cli->server_type)
- {
- DEBUG(1,("Domain=[%s] OS=[%s] Server=[%s]\n",
- cli->server_domain,
- cli->server_os,
- cli->server_type));
- }
-
if (do_tcon)
{
if (!cli_send_tconX(cli, service, service_type,
@@ -3393,184 +2939,18 @@ BOOL cli_establish_connection(struct cli_state *cli,
{
DEBUG(1,("failed tcon_X\n"));
if (do_shutdown)
- {
- cli_shutdown(cli);
- }
+ cli_shutdown(cli);
return False;
}
}
}
if (do_shutdown)
- {
- cli_shutdown(cli);
- }
-
- return True;
-}
-
-BOOL cli_connect_auth(struct cli_state *cli,
- const char* desthost,
- struct in_addr *dest_ip,
- const struct ntuser_creds *usr)
-{
- extern pstring global_myname;
- extern pstring scope;
- struct nmb_name calling, called;
-
- ZERO_STRUCTP(cli);
- if (!cli_initialise(cli))
- {
- DEBUG(0,("unable to initialise client connection.\n"));
- return False;
- }
-
- make_nmb_name(&calling, global_myname, 0x0 , scope);
- make_nmb_name(&called , desthost , 0x20, scope);
-
- cli_init_creds(cli, usr);
-
- if (!cli_establish_connection(cli, desthost, dest_ip,
- &calling, &called,
- "IPC$", "IPC",
- False, True))
- {
- cli_shutdown(cli);
- return False;
- }
+ cli_shutdown(cli);
return True;
}
-/****************************************************************************
- connect to one of multiple servers: don't care which
-****************************************************************************/
-BOOL cli_connect_servers_auth(struct cli_state *cli,
- char *p,
- const struct ntuser_creds *usr)
-{
- fstring remote_host;
- BOOL connected_ok = False;
-
- /*
- * Treat each name in the 'password server =' line as a potential
- * PDC/BDC. Contact each in turn and try and authenticate.
- */
-
- while(p && next_token(&p,remote_host,LIST_SEP,sizeof(remote_host)))
- {
- fstring desthost;
- struct in_addr dest_ip;
- strupper(remote_host);
-
- if (!resolve_srv_name( remote_host, desthost, &dest_ip))
- {
- DEBUG(1,("Can't resolve address for %s\n", remote_host));
- continue;
- }
-
- if (!cli_connect_auth(cli, desthost, &dest_ip, usr) &&
- !cli_connect_auth(cli, "*SMBSERVER", &dest_ip, usr))
- {
- continue;
- }
-
- if (cli->protocol < PROTOCOL_LANMAN2 ||
- !IS_BITS_SET_ALL(cli->sec_mode, 1))
- {
- DEBUG(1,("machine %s not in user level security mode\n",
- remote_host));
- cli_shutdown(cli);
- continue;
- }
-
- /*
- * We have an anonymous connection to IPC$.
- */
-
- connected_ok = True;
- break;
- }
-
- if (!connected_ok)
- {
- DEBUG(0,("Domain password server not available.\n"));
- }
-
- return connected_ok;
-}
-
-/****************************************************************************
- connect to one of multiple servers: don't care which
-****************************************************************************/
-BOOL cli_connect_serverlist(struct cli_state *cli, char *p)
-{
- fstring remote_host;
- fstring desthost;
- struct in_addr dest_ip;
- BOOL connected_ok = False;
-
- /*
- * Treat each name in the 'password server =' line as a potential
- * PDC/BDC. Contact each in turn and try and authenticate.
- */
-
- while(p && next_token(&p,remote_host,LIST_SEP,sizeof(remote_host)))
- {
- ZERO_STRUCTP(cli);
-
- if (!cli_initialise(cli))
- {
- DEBUG(0,("cli_connect_serverlist: unable to initialise client connection.\n"));
- return False;
- }
-
- standard_sub_basic(remote_host);
- strupper(remote_host);
-
- if (!resolve_srv_name( remote_host, desthost, &dest_ip))
- {
- DEBUG(1,("cli_connect_serverlist: Can't resolve address for %s\n", remote_host));
- continue;
- }
-
- if ((lp_security() != SEC_USER) && (ismyip(dest_ip)))
- {
- DEBUG(1,("cli_connect_serverlist: Password server loop - not using password server %s\n", remote_host));
- continue;
- }
-
- if (!cli_connect_auth(cli, remote_host , &dest_ip, NULL) &&
- !cli_connect_auth(cli, "*SMBSERVER", &dest_ip, NULL))
- {
- continue;
- }
-
-
- if (cli->protocol < PROTOCOL_LANMAN2 ||
- !IS_BITS_SET_ALL(cli->sec_mode, 1))
- {
- DEBUG(1,("cli_connect_serverlist: machine %s isn't in user level security mode\n",
- remote_host));
- cli_shutdown(cli);
- continue;
- }
-
- /*
- * We have an anonymous connection to IPC$.
- */
-
- connected_ok = True;
- break;
- }
-
- if (!connected_ok)
- {
- DEBUG(0,("cli_connect_serverlist: Domain password server not available.\n"));
- }
-
- return connected_ok;
-}
/****************************************************************************
cancel a print job
@@ -3583,7 +2963,7 @@ int cli_printjob_del(struct cli_state *cli, int job)
int rdrcnt,rprcnt, ret = -1;
pstring param;
- bzero(param,sizeof(param));
+ memset(param,'\0',sizeof(param));
p = param;
SSVAL(p,0,81); /* DosPrintJobDel() */
@@ -3624,7 +3004,7 @@ int cli_print_queue(struct cli_state *cli,
int result_code=0;
int i = -1;
- bzero(param,sizeof(param));
+ memset(param,'\0',sizeof(param));
p = param;
SSVAL(p,0,76); /* API function number 76 (DosPrintJobEnum) */
@@ -3686,29 +3066,29 @@ check for existance of a dir
****************************************************************************/
BOOL cli_chkpath(struct cli_state *cli, char *path)
{
- fstring path2;
+ pstring path2;
char *p;
- fstrcpy(path2,path);
+ safe_strcpy(path2,path,sizeof(pstring));
trim_string(path2,NULL,"\\");
if (!*path2) *path2 = '\\';
- bzero(cli->outbuf,smb_size);
+ memset(cli->outbuf,'\0',smb_size);
set_message(cli->outbuf,0,4 + strlen(path2),True);
SCVAL(cli->outbuf,smb_com,SMBchkpth);
SSVAL(cli->outbuf,smb_tid,cli->cnum);
cli_setup_packet(cli);
-
p = smb_buf(cli->outbuf);
*p++ = 4;
- fstrcpy(p,path2);
+ safe_strcpy(p,path2,strlen(path2));
+ unix_to_dos(p,True);
- cli_send_smb(cli, True);
+ cli_send_smb(cli);
if (!cli_receive_smb(cli)) {
return False;
}
- if (cli_error(cli, NULL, NULL)) return False;
+ if (cli_error(cli, NULL, NULL, NULL)) return False;
return True;
}
@@ -3723,7 +3103,7 @@ BOOL cli_message_start(struct cli_state *cli, char *host, char *username,
char *p;
/* send a SMBsendstrt command */
- bzero(cli->outbuf,smb_size);
+ memset(cli->outbuf,'\0',smb_size);
set_message(cli->outbuf,0,0,True);
CVAL(cli->outbuf,smb_com) = SMBsendstrt;
SSVAL(cli->outbuf,smb_tid,cli->cnum);
@@ -3732,20 +3112,22 @@ BOOL cli_message_start(struct cli_state *cli, char *host, char *username,
p = smb_buf(cli->outbuf);
*p++ = 4;
pstrcpy(p,username);
+ unix_to_dos(p,True);
p = skip_string(p,1);
*p++ = 4;
pstrcpy(p,host);
+ unix_to_dos(p,True);
p = skip_string(p,1);
set_message(cli->outbuf,0,PTR_DIFF(p,smb_buf(cli->outbuf)),False);
- cli_send_smb(cli, True);
+ cli_send_smb(cli);
if (!cli_receive_smb(cli)) {
return False;
}
- if (cli_error(cli, NULL, NULL)) return False;
+ if (cli_error(cli, NULL, NULL, NULL)) return False;
*grp = SVAL(cli->inbuf,smb_vwv0);
@@ -3760,7 +3142,7 @@ BOOL cli_message_text(struct cli_state *cli, char *msg, int len, int grp)
{
char *p;
- bzero(cli->outbuf,smb_size);
+ memset(cli->outbuf,'\0',smb_size);
set_message(cli->outbuf,1,len+3,True);
CVAL(cli->outbuf,smb_com) = SMBsendtxt;
SSVAL(cli->outbuf,smb_tid,cli->cnum);
@@ -3772,13 +3154,13 @@ BOOL cli_message_text(struct cli_state *cli, char *msg, int len, int grp)
*p = 1;
SSVAL(p,1,len);
memcpy(p+3,msg,len);
- cli_send_smb(cli, True);
+ cli_send_smb(cli);
if (!cli_receive_smb(cli)) {
return False;
}
- if (cli_error(cli, NULL, NULL)) return False;
+ if (cli_error(cli, NULL, NULL, NULL)) return False;
return True;
}
@@ -3788,7 +3170,7 @@ end a message
****************************************************************************/
BOOL cli_message_end(struct cli_state *cli, int grp)
{
- bzero(cli->outbuf,smb_size);
+ memset(cli->outbuf,'\0',smb_size);
set_message(cli->outbuf,1,0,True);
CVAL(cli->outbuf,smb_com) = SMBsendend;
SSVAL(cli->outbuf,smb_tid,cli->cnum);
@@ -3797,13 +3179,13 @@ BOOL cli_message_end(struct cli_state *cli, int grp)
cli_setup_packet(cli);
- cli_send_smb(cli, True);
+ cli_send_smb(cli);
if (!cli_receive_smb(cli)) {
return False;
}
- if (cli_error(cli, NULL, NULL)) return False;
+ if (cli_error(cli, NULL, NULL, NULL)) return False;
return True;
}
@@ -3814,13 +3196,13 @@ query disk space
****************************************************************************/
BOOL cli_dskattr(struct cli_state *cli, int *bsize, int *total, int *avail)
{
- bzero(cli->outbuf,smb_size);
+ memset(cli->outbuf,'\0',smb_size);
set_message(cli->outbuf,0,0,True);
CVAL(cli->outbuf,smb_com) = SMBdskattr;
SSVAL(cli->outbuf,smb_tid,cli->cnum);
cli_setup_packet(cli);
- cli_send_smb(cli, True);
+ cli_send_smb(cli);
if (!cli_receive_smb(cli)) {
return False;
}
@@ -3832,21 +3214,49 @@ BOOL cli_dskattr(struct cli_state *cli, int *bsize, int *total, int *avail)
return True;
}
-BOOL get_any_dc_name(const char *domain, char *srv_name)
+/****************************************************************************
+ Attempt a NetBIOS session request, falling back to *SMBSERVER if needed.
+****************************************************************************/
+
+BOOL attempt_netbios_session_request(struct cli_state *cli, char *srchost, char *desthost,
+ struct in_addr *pdest_ip)
{
- struct cli_state cli;
+ struct nmb_name calling, called;
- if (!cli_connect_servers_auth(&cli,
- get_trusted_serverlist(domain), NULL))
- {
- return False;
- }
+ make_nmb_name(&calling, srchost, 0x0, scope);
+
+ /*
+ * If the called name is an IP address
+ * then use *SMBSERVER immediately.
+ */
- fstrcpy(srv_name, "\\\\");
- fstrcat(srv_name, cli.desthost);
- strupper(srv_name);
+ if(is_ipaddress(desthost))
+ make_nmb_name(&called, "*SMBSERVER", 0x20, scope);
+ else
+ make_nmb_name(&called, desthost, 0x20, scope);
- cli_shutdown(&cli);
+ if (!cli_session_request(cli, &calling, &called)) {
+ struct nmb_name smbservername;
- return True;
+ /*
+ * If the name wasn't *SMBSERVER then
+ * try with *SMBSERVER if the first name fails.
+ */
+
+ cli_shutdown(cli);
+
+ make_nmb_name(&smbservername , "*SMBSERVER", 0x20, scope);
+
+ if (!nmb_name_equal(&called, &smbservername) ||
+ !cli_initialise(cli) ||
+ !cli_connect(cli, desthost, pdest_ip) ||
+ !cli_session_request(cli, &calling, &smbservername)) {
+ DEBUG(0,("attempt_netbios_session_request: %s rejected the session for name *SMBSERVER.\n",
+ desthost));
+ cli_shutdown(cli);
+ return False;
+ }
+ }
+
+ return True;
}
diff --git a/source3/libsmb/namequery.c b/source3/libsmb/namequery.c
index 299145ceff..abb9b7d42f 100644
--- a/source3/libsmb/namequery.c
+++ b/source3/libsmb/namequery.c
@@ -23,17 +23,15 @@
#include "includes.h"
extern pstring scope;
-extern pstring global_myname;
extern int DEBUGLEVEL;
/* nmbd.c sets this to True. */
BOOL global_in_nmbd = False;
- static int name_trn_id = 0;
-
/****************************************************************************
-interpret a node status response
+ Interpret a node status response.
****************************************************************************/
+
static void _interpret_node_status(char *p, char *master,char *rname)
{
int numnames = CVAL(p,0);
@@ -43,55 +41,54 @@ static void _interpret_node_status(char *p, char *master,char *rname)
if (master) *master = 0;
p += 1;
- while (numnames--)
- {
- char qname[17];
- int type;
- fstring flags;
- int i;
- *flags = 0;
- StrnCpy(qname,p,15);
- type = CVAL(p,15);
- p += 16;
-
- fstrcat(flags, (p[0] & 0x80) ? "<GROUP> " : " ");
- if ((p[0] & 0x60) == 0x00) fstrcat(flags,"B ");
- if ((p[0] & 0x60) == 0x20) fstrcat(flags,"P ");
- if ((p[0] & 0x60) == 0x40) fstrcat(flags,"M ");
- if ((p[0] & 0x60) == 0x60) fstrcat(flags,"H ");
- if (p[0] & 0x10) fstrcat(flags,"<DEREGISTERING> ");
- if (p[0] & 0x08) fstrcat(flags,"<CONFLICT> ");
- if (p[0] & 0x04) fstrcat(flags,"<ACTIVE> ");
- if (p[0] & 0x02) fstrcat(flags,"<PERMANENT> ");
-
- if (master && !*master && type == 0x1d) {
- StrnCpy(master,qname,15);
- trim_string(master,NULL," ");
- }
+ while (numnames--) {
+ char qname[17];
+ int type;
+ fstring flags;
+ int i;
+ *flags = 0;
+ StrnCpy(qname,p,15);
+ type = CVAL(p,15);
+ p += 16;
+
+ fstrcat(flags, (p[0] & 0x80) ? "<GROUP> " : " ");
+ if ((p[0] & 0x60) == 0x00) fstrcat(flags,"B ");
+ if ((p[0] & 0x60) == 0x20) fstrcat(flags,"P ");
+ if ((p[0] & 0x60) == 0x40) fstrcat(flags,"M ");
+ if ((p[0] & 0x60) == 0x60) fstrcat(flags,"H ");
+ if (p[0] & 0x10) fstrcat(flags,"<DEREGISTERING> ");
+ if (p[0] & 0x08) fstrcat(flags,"<CONFLICT> ");
+ if (p[0] & 0x04) fstrcat(flags,"<ACTIVE> ");
+ if (p[0] & 0x02) fstrcat(flags,"<PERMANENT> ");
+
+ if (master && !*master && type == 0x1d) {
+ StrnCpy(master,qname,15);
+ trim_string(master,NULL," ");
+ }
- if (rname && !*rname && type == 0x20 && !(p[0]&0x80)) {
- StrnCpy(rname,qname,15);
- trim_string(rname,NULL," ");
- }
+ if (rname && !*rname && type == 0x20 && !(p[0]&0x80)) {
+ StrnCpy(rname,qname,15);
+ trim_string(rname,NULL," ");
+ }
- for (i = strlen( qname) ; --i >= 0 ; ) {
- if (!isprint((int)qname[i])) qname[i] = '.';
- }
- DEBUG(1,("\t%-15s <%02x> - %s\n",qname,type,flags));
- p+=2;
+ for (i = strlen( qname) ; --i >= 0 ; ) {
+ if (!isprint((int)qname[i])) qname[i] = '.';
}
+ DEBUG(1,("\t%-15s <%02x> - %s\n",qname,type,flags));
+ p+=2;
+ }
+
DEBUG(1,("num_good_sends=%d num_good_receives=%d\n",
IVAL(p,20),IVAL(p,24)));
}
-
/****************************************************************************
- do a netbios name status query on a host
+ Internal function handling a netbios name status query on a host.
+**************************************************************************/
- the "master" parameter is a hack used for finding workgroups.
- **************************************************************************/
-BOOL name_status(int fd,char *name,int name_type,BOOL recurse,
- struct in_addr to_ip,char *master,char *rname,
+static BOOL internal_name_status(int fd,char *name,int name_type,BOOL recurse,
+ struct in_addr to_ip,char *master,char *rname, BOOL verbose,
+ void (*fn_interpret_node_status)(char *, char *,char *),
void (*fn)(struct packet_struct *))
{
BOOL found=False;
@@ -101,21 +98,9 @@ BOOL name_status(int fd,char *name,int name_type,BOOL recurse,
struct packet_struct p;
struct packet_struct *p2;
struct nmb_packet *nmb = &p.packet.nmb;
- int packet_type = NMB_PACKET;
- BOOL first_time = True;
+ static int name_trn_id = 0;
- if (fd == -1)
- {
- retries = 1;
- packet_type = NMB_SOCK_PACKET;
- fd = get_nmb_sock();
-
- if (fd < 0)
- {
- return False;
- }
- }
- bzero((char *)&p,sizeof(p));
+ memset((char *)&p,'\0',sizeof(p));
if (!name_trn_id) name_trn_id = ((unsigned)time(NULL)%(unsigned)0x7FFF) +
((unsigned)getpid()%(unsigned)100);
@@ -144,39 +129,40 @@ BOOL name_status(int fd,char *name,int name_type,BOOL recurse,
p.port = NMB_PORT;
p.fd = fd;
p.timestamp = time(NULL);
- p.packet_type = packet_type;
+ p.packet_type = NMB_PACKET;
GetTimeOfDay(&tval);
- while (1)
- {
- struct timeval tval2;
- GetTimeOfDay(&tval2);
- if (first_time || TvalDiff(&tval,&tval2) > retry_time)
- {
- first_time = False;
- if (!found && !send_packet(&p))
- {
- if (packet_type == NMB_SOCK_PACKET) close(fd);
- return False;
- }
- GetTimeOfDay(&tval);
- }
+ if (!send_packet(&p))
+ return(False);
+
+ retries--;
+
+ while (1) {
+ struct timeval tval2;
+ GetTimeOfDay(&tval2);
+ if (TvalDiff(&tval,&tval2) > retry_time) {
+ if (!retries)
+ break;
+ if (!found && !send_packet(&p))
+ return False;
+ GetTimeOfDay(&tval);
+ retries--;
+ }
- if ((p2=receive_packet(fd,packet_type,90)))
- {
- struct nmb_packet *nmb2 = &p2->packet.nmb;
+ if ((p2=receive_packet(fd,NMB_PACKET,90))) {
+ struct nmb_packet *nmb2 = &p2->packet.nmb;
debug_nmb_packet(p2);
- if (nmb->header.name_trn_id != nmb2->header.name_trn_id ||
- !nmb2->header.response) {
- /* its not for us - maybe deal with it later */
- if (fn)
- fn(p2);
- else
- free_packet(p2);
- continue;
- }
+ if (nmb->header.name_trn_id != nmb2->header.name_trn_id ||
+ !nmb2->header.response) {
+ /* its not for us - maybe deal with it later */
+ if (fn)
+ fn(p2);
+ else
+ free_packet(p2);
+ continue;
+ }
if (nmb2->header.opcode != 0 ||
nmb2->header.nm_flags.bcast ||
@@ -189,55 +175,53 @@ BOOL name_status(int fd,char *name,int name_type,BOOL recurse,
continue;
}
- retries--;
-
- _interpret_node_status(&nmb2->answers->rdata[0], master,rname);
+ if(fn_interpret_node_status)
+ (*fn_interpret_node_status)(&nmb2->answers->rdata[0],master,rname);
free_packet(p2);
- if (packet_type == NMB_SOCK_PACKET) close(fd);
return(True);
}
- }
-
+ }
- DEBUG(0,("No status response (this is not unusual)\n"));
+ if(verbose)
+ DEBUG(0,("No status response (this is not unusual)\n"));
-if (packet_type == NMB_SOCK_PACKET) close(fd);
return(False);
}
+/****************************************************************************
+ Do a netbios name status query on a host.
+ The "master" parameter is a hack used for finding workgroups.
+**************************************************************************/
+
+BOOL name_status(int fd,char *name,int name_type,BOOL recurse,
+ struct in_addr to_ip,char *master,char *rname,
+ void (*fn)(struct packet_struct *))
+{
+ return internal_name_status(fd,name,name_type,recurse,
+ to_ip,master,rname,True,
+ _interpret_node_status, fn);
+}
/****************************************************************************
- do a netbios name query to find someones IP
- returns an array of IP addresses or NULL if none
- *count will be set to the number of addresses returned
- ****************************************************************************/
+ Do a netbios name query to find someones IP.
+ Returns an array of IP addresses or NULL if none.
+ *count will be set to the number of addresses returned.
+****************************************************************************/
+
struct in_addr *name_query(int fd,const char *name,int name_type, BOOL bcast,BOOL recurse,
struct in_addr to_ip, int *count, void (*fn)(struct packet_struct *))
{
BOOL found=False;
int i, retries = 3;
- int retry_time = bcast?2000:2000;
+ int retry_time = bcast?250:2000;
struct timeval tval;
struct packet_struct p;
struct packet_struct *p2;
struct nmb_packet *nmb = &p.packet.nmb;
+ static int name_trn_id = 0;
struct in_addr *ip_list = NULL;
- BOOL packet_type = NMB_PACKET;
- BOOL first_send = True;
-
- if (fd == -1)
- {
- retries = 1;
- packet_type = NMB_SOCK_PACKET;
- fd = get_nmb_sock();
-
- if (fd < 0)
- {
- return NULL;
- }
- }
- bzero((char *)&p,sizeof(p));
+ memset((char *)&p,'\0',sizeof(p));
(*count) = 0;
if (!name_trn_id) name_trn_id = ((unsigned)time(NULL)%(unsigned)0x7FFF) +
@@ -267,27 +251,30 @@ struct in_addr *name_query(int fd,const char *name,int name_type, BOOL bcast,BOO
p.port = NMB_PORT;
p.fd = fd;
p.timestamp = time(NULL);
- p.packet_type = packet_type;
+ p.packet_type = NMB_PACKET;
+
+ GetTimeOfDay(&tval);
- GetTimeOfDay(&tval);
+ if (!send_packet(&p))
+ return NULL;
- while (retries >= 0)
+ retries--;
+
+ while (1)
{
struct timeval tval2;
-
GetTimeOfDay(&tval2);
- if (first_send || TvalDiff(&tval,&tval2) > retry_time)
+ if (TvalDiff(&tval,&tval2) > retry_time)
{
- first_send = False;
+ if (!retries)
+ break;
if (!found && !send_packet(&p))
- {
- if (packet_type == NMB_SOCK_PACKET) close(fd);
return NULL;
- }
GetTimeOfDay(&tval);
+ retries--;
}
- if ((p2=receive_packet(fd,packet_type,90)))
+ if ((p2=receive_packet(fd,NMB_PACKET,90)))
{
struct nmb_packet *nmb2 = &p2->packet.nmb;
debug_nmb_packet(p2);
@@ -295,8 +282,6 @@ struct in_addr *name_query(int fd,const char *name,int name_type, BOOL bcast,BOO
if (nmb->header.name_trn_id != nmb2->header.name_trn_id ||
!nmb2->header.response)
{
- DEBUG(10,("packet not for us (received %d, expected %d\n",
- nmb2->header.name_trn_id, nmb->header.name_trn_id));
/*
* Its not for us - maybe deal with it later
* (put it on the queue?).
@@ -305,12 +290,9 @@ struct in_addr *name_query(int fd,const char *name,int name_type, BOOL bcast,BOO
fn(p2);
else
free_packet(p2);
-
continue;
}
- retries--;
-
if (nmb2->header.opcode != 0 ||
nmb2->header.nm_flags.bcast ||
nmb2->header.rcode ||
@@ -345,15 +327,16 @@ struct in_addr *name_query(int fd,const char *name,int name_type, BOOL bcast,BOO
if (fn)
break;
- if(found)
- {
- DEBUG(10,("returning OK\n"));
+ /*
+ * If we're doing a unicast lookup we only
+ * expect one reply. Don't wait the full 2
+ * seconds if we got one. JRA.
+ */
+ if(!bcast && found)
break;
- }
}
}
- if (packet_type == NMB_SOCK_PACKET) close(fd);
return ip_list;
}
@@ -375,6 +358,7 @@ FILE *startlmhosts(char *fname)
/********************************************************
Parse the next line in the lmhosts file.
*********************************************************/
+
BOOL getlmhostsent( FILE *fp, pstring name, int *name_type, struct in_addr *ipaddr)
{
pstring line;
@@ -439,7 +423,7 @@ BOOL getlmhostsent( FILE *fp, pstring name, int *name_type, struct in_addr *ipad
char *endptr;
ptr++;
- *name_type = (int)strtol(ptr, &endptr,0);
+ *name_type = (int)strtol(ptr, &endptr, 16);
if(!*ptr || (endptr == ptr))
{
@@ -465,108 +449,107 @@ void endlmhosts(FILE *fp)
fclose(fp);
}
-
-
/********************************************************
-resolve via "bcast" method
+ Resolve via "bcast" method.
*********************************************************/
-static BOOL resolve_bcast(const char *name, struct in_addr *return_ip, int name_type)
+
+static BOOL resolve_bcast(const char *name, int name_type,
+ struct in_addr **return_ip_list, int *return_count)
{
int sock, i;
+ int num_interfaces = iface_count();
+
+ *return_ip_list = NULL;
+ *return_count = 0;
/*
* "bcast" means do a broadcast lookup on all the local interfaces.
*/
- DEBUG(3,("resolve_name: Attempting broadcast lookup for name %s<0x20>\n", name));
+ DEBUG(3,("resolve_bcast: Attempting broadcast lookup for name %s<0x%x>\n", name, name_type));
sock = open_socket_in( SOCK_DGRAM, 0, 3,
- interpret_addr(lp_socket_address()) );
-
- if (sock != -1) {
- struct in_addr *iplist = NULL;
- int count;
- int num_interfaces = iface_count();
- set_socket_options(sock,"SO_BROADCAST");
- /*
- * Lookup the name on all the interfaces, return on
- * the first successful match.
- */
- for( i = 0; i < num_interfaces; i++) {
- struct in_addr sendto_ip;
- /* Done this way to fix compiler error on IRIX 5.x */
- sendto_ip = *iface_bcast(*iface_n_ip(i));
- iplist = name_query(sock, name, name_type, True,
- True, sendto_ip, &count, NULL);
- if(iplist != NULL) {
- *return_ip = iplist[0];
- free((char *)iplist);
- close(sock);
- return True;
- }
+ interpret_addr(lp_socket_address()), True );
+
+ if (sock == -1) return False;
+
+ set_socket_options(sock,"SO_BROADCAST");
+ /*
+ * Lookup the name on all the interfaces, return on
+ * the first successful match.
+ */
+ for( i = num_interfaces-1; i >= 0; i--) {
+ struct in_addr sendto_ip;
+ /* Done this way to fix compiler error on IRIX 5.x */
+ sendto_ip = *iface_bcast(*iface_n_ip(i));
+ *return_ip_list = name_query(sock, name, name_type, True,
+ True, sendto_ip, return_count, NULL);
+ if(*return_ip_list != NULL) {
+ close(sock);
+ return True;
}
- close(sock);
}
+ close(sock);
return False;
}
-
-
/********************************************************
-resolve via "wins" method
+ Resolve via "wins" method.
*********************************************************/
-static BOOL resolve_wins(const char *name, struct in_addr *return_ip, int name_type)
+
+static BOOL resolve_wins(const char *name, int name_type,
+ struct in_addr **return_iplist, int *return_count)
{
- int sock;
- struct in_addr wins_ip;
- BOOL wins_ismyip;
+ int sock;
+ struct in_addr wins_ip;
+ BOOL wins_ismyip;
- /*
- * "wins" means do a unicast lookup to the WINS server.
- * Ignore if there is no WINS server specified or if the
- * WINS server is one of our interfaces (if we're being
- * called from within nmbd - we can't do this call as we
- * would then block).
- */
+ *return_iplist = NULL;
+ *return_count = 0;
+
+ /*
+ * "wins" means do a unicast lookup to the WINS server.
+ * Ignore if there is no WINS server specified or if the
+ * WINS server is one of our interfaces (if we're being
+ * called from within nmbd - we can't do this call as we
+ * would then block).
+ */
- DEBUG(3,("resolve_name: Attempting wins lookup for name %s<0x20>\n", name));
+ DEBUG(3,("resolve_wins: Attempting wins lookup for name %s<0x%x>\n", name, name_type));
- if(!*lp_wins_server()) {
- DEBUG(3,("resolve_name: WINS server resolution selected and no WINS server present.\n"));
- return False;
- }
+ if(!*lp_wins_server()) {
+ DEBUG(3,("resolve_wins: WINS server resolution selected and no WINS server present.\n"));
+ return False;
+ }
- wins_ip = *interpret_addr2(lp_wins_server());
- wins_ismyip = ismyip(wins_ip);
+ wins_ip = *interpret_addr2(lp_wins_server());
+ wins_ismyip = ismyip(wins_ip);
- if((wins_ismyip && !global_in_nmbd) || !wins_ismyip) {
- sock = open_socket_in( SOCK_DGRAM, 0, 3,
- interpret_addr(lp_socket_address()) );
+ if((wins_ismyip && !global_in_nmbd) || !wins_ismyip) {
+ sock = open_socket_in( SOCK_DGRAM, 0, 3,
+ interpret_addr(lp_socket_address()), True );
- if (sock != -1) {
- struct in_addr *iplist = NULL;
- int count;
- iplist = name_query(sock, name, name_type, False,
- True, wins_ip, &count, NULL);
- if(iplist != NULL) {
- *return_ip = iplist[0];
- free((char *)iplist);
- close(sock);
- return True;
- }
- close(sock);
- }
- }
+ if (sock != -1) {
+ *return_iplist = name_query(sock, name, name_type, False,
+ True, wins_ip, return_count, NULL);
+ if(*return_iplist != NULL) {
+ close(sock);
+ return True;
+ }
+ close(sock);
+ }
+ }
- return False;
+ return False;
}
-
/********************************************************
-resolve via "lmhosts" method
+ Resolve via "lmhosts" method.
*********************************************************/
-static BOOL resolve_lmhosts(const char *name, struct in_addr *return_ip, int name_type)
+
+static BOOL resolve_lmhosts(const char *name, int name_type,
+ struct in_addr **return_iplist, int *return_count)
{
/*
* "lmhosts" means parse the local lmhosts file.
@@ -575,15 +558,27 @@ static BOOL resolve_lmhosts(const char *name, struct in_addr *return_ip, int nam
FILE *fp;
pstring lmhost_name;
int name_type2;
+ struct in_addr return_ip;
+
+ *return_iplist = NULL;
+ *return_count = 0;
- DEBUG(3,("resolve_name: Attempting lmhosts lookup for name %s\n", name));
+ DEBUG(3,("resolve_lmhosts: Attempting lmhosts lookup for name %s<0x%x>\n", name, name_type));
fp = startlmhosts( LMHOSTSFILE );
if(fp) {
- while (getlmhostsent(fp, lmhost_name, &name_type2, return_ip)) {
+ while (getlmhostsent(fp, lmhost_name, &name_type2, &return_ip)) {
if (strequal(name, lmhost_name) &&
- name_type == name_type2) {
+ ((name_type2 == -1) || (name_type == name_type2))
+ ) {
endlmhosts(fp);
+ *return_iplist = (struct in_addr *)malloc(sizeof(struct in_addr));
+ if(*return_iplist == NULL) {
+ DEBUG(3,("resolve_lmhosts: malloc fail !\n"));
+ return False;
+ }
+ **return_iplist = return_ip;
+ *return_count = 1;
return True;
}
}
@@ -594,89 +589,94 @@ static BOOL resolve_lmhosts(const char *name, struct in_addr *return_ip, int nam
/********************************************************
-resolve via "hosts" method
+ Resolve via "hosts" method.
*********************************************************/
-static BOOL resolve_hosts(const char *name, struct in_addr *return_ip)
+
+static BOOL resolve_hosts(const char *name,
+ struct in_addr **return_iplist, int *return_count)
{
/*
* "host" means do a localhost, or dns lookup.
*/
struct hostent *hp;
- DEBUG(3,("resolve_name: Attempting host lookup for name %s\n", name));
+ *return_iplist = NULL;
+ *return_count = 0;
+
+ DEBUG(3,("resolve_hosts: Attempting host lookup for name %s<0x20>\n", name));
if (((hp = Get_Hostbyname(name)) != NULL) && (hp->h_addr != NULL)) {
- putip((char *)return_ip,(char *)hp->h_addr);
+ struct in_addr return_ip;
+ putip((char *)&return_ip,(char *)hp->h_addr);
+ *return_iplist = (struct in_addr *)malloc(sizeof(struct in_addr));
+ if(*return_iplist == NULL) {
+ DEBUG(3,("resolve_hosts: malloc fail !\n"));
+ return False;
+ }
+ **return_iplist = return_ip;
+ *return_count = 1;
return True;
}
return False;
}
-
/********************************************************
- Resolve a name into an IP address. Use this function if
- the string is either an IP address, DNS or host name
- or NetBIOS name. This uses the name switch in the
+ Internal interface to resolve a name into an IP address.
+ Use this function if the string is either an IP address, DNS
+ or host name or NetBIOS name. This uses the name switch in the
smb.conf to determine the order of name resolution.
*********************************************************/
-BOOL is_ip_address(const char *name)
-{
- int i;
- for (i=0; name[i]; i++)
- if (!(isdigit((int)name[i]) || name[i] == '.'))
- return False;
-
- return True;
-}
-/********************************************************
- Resolve a name into an IP address. Use this function if
- the string is either an IP address, DNS or host name
- or NetBIOS name. This uses the name switch in the
- smb.conf to determine the order of name resolution.
-*********************************************************/
-BOOL resolve_name(const char *name, struct in_addr *return_ip, int name_type)
+static BOOL internal_resolve_name(const char *name, int name_type,
+ struct in_addr **return_iplist, int *return_count)
{
pstring name_resolve_list;
fstring tok;
char *ptr;
-
- if (strcmp(name,"0.0.0.0") == 0) {
- return_ip->s_addr = 0;
- return True;
- }
- if (strcmp(name,"255.255.255.255") == 0) {
- return_ip->s_addr = 0xFFFFFFFF;
- return True;
- }
-
- /* if it's in the form of an IP address then get the lib to interpret it */
- if (is_ip_address(name)) {
- return_ip->s_addr = inet_addr(name);
+ BOOL allones = (strcmp(name,"255.255.255.255") == 0);
+ BOOL allzeros = (strcmp(name,"0.0.0.0") == 0);
+ BOOL is_address = is_ipaddress(name);
+ *return_iplist = NULL;
+ *return_count = 0;
+
+ if (allzeros || allones || is_address) {
+ *return_iplist = (struct in_addr *)malloc(sizeof(struct in_addr));
+ if(*return_iplist == NULL) {
+ DEBUG(3,("internal_resolve_name: malloc fail !\n"));
+ return False;
+ }
+ if(is_address) {
+ /* if it's in the form of an IP address then get the lib to interpret it */
+ (*return_iplist)->s_addr = inet_addr(name);
+ } else {
+ (*return_iplist)->s_addr = allones ? 0xFFFFFFFF : 0;
+ *return_count = 1;
+ }
return True;
}
-
+
pstrcpy(name_resolve_list, lp_name_resolve_order());
ptr = name_resolve_list;
- if (!ptr || !*ptr) ptr = "host";
+ if (!ptr || !*ptr)
+ ptr = "host";
while (next_token(&ptr, tok, LIST_SEP, sizeof(tok))) {
if((strequal(tok, "host") || strequal(tok, "hosts"))) {
- if (name_type == 0x20 && resolve_hosts(name, return_ip)) {
+ if (name_type == 0x20 && resolve_hosts(name, return_iplist, return_count)) {
return True;
}
} else if(strequal( tok, "lmhosts")) {
- if (resolve_lmhosts(name, return_ip, name_type)) {
+ if (resolve_lmhosts(name, name_type, return_iplist, return_count)) {
return True;
}
} else if(strequal( tok, "wins")) {
/* don't resolve 1D via WINS */
if (name_type != 0x1D &&
- resolve_wins(name, return_ip, name_type)) {
+ resolve_wins(name, name_type, return_iplist, return_count)) {
return True;
}
} else if(strequal( tok, "bcast")) {
- if (resolve_bcast(name, return_ip, name_type)) {
+ if (resolve_bcast(name, name_type, return_iplist, return_count)) {
return True;
}
} else {
@@ -684,50 +684,319 @@ BOOL resolve_name(const char *name, struct in_addr *return_ip, int name_type)
}
}
+ if((*return_iplist) != NULL) {
+ free((char *)(*return_iplist));
+ *return_iplist = NULL;
+ }
return False;
}
/********************************************************
- resolve a name of format \\server_name or \\ipaddress
- into a name. also, cut the \\ from the front for us.
+ Internal interface to resolve a name into one IP address.
+ Use this function if the string is either an IP address, DNS
+ or host name or NetBIOS name. This uses the name switch in the
+ smb.conf to determine the order of name resolution.
*********************************************************/
-BOOL resolve_srv_name(const char* srv_name, fstring dest_host,
- struct in_addr *ip)
-{
- BOOL ret;
- const char *sv_name = srv_name;
- DEBUG(10,("resolve_srv_name: %s\n", srv_name));
+BOOL resolve_name(const char *name, struct in_addr *return_ip, int name_type)
+{
+ struct in_addr *ip_list = NULL;
+ int count = 0;
- if (srv_name == NULL || strequal("\\\\.", srv_name))
- {
- fstrcpy(dest_host, global_myname);
- ip = interpret_addr2("127.0.0.1");
+ if(internal_resolve_name(name, name_type, &ip_list, &count)) {
+ *return_ip = ip_list[0];
+ free((char *)ip_list);
return True;
}
+ if(ip_list != NULL)
+ free((char *)ip_list);
+ return False;
+}
- if (strnequal("\\\\", srv_name, 2))
- {
- sv_name = &srv_name[2];
- }
+/********************************************************
+ Find the IP address of the master browser or DMB for a workgroup.
+*********************************************************/
- fstrcpy(dest_host, sv_name);
- ret = resolve_name(dest_host, ip, 0x20);
-
- if (is_ip_address(dest_host))
- {
- fstrcpy(dest_host, "*SMBSERVER");
+BOOL find_master_ip(char *group, struct in_addr *master_ip)
+{
+ struct in_addr *ip_list = NULL;
+ int count = 0;
+
+ if (internal_resolve_name(group, 0x1D, &ip_list, &count)) {
+ *master_ip = ip_list[0];
+ free((char *)ip_list);
+ return True;
}
-
- return ret;
+ if(internal_resolve_name(group, 0x1B, &ip_list, &count)) {
+ *master_ip = ip_list[0];
+ free((char *)ip_list);
+ return True;
+ }
+
+ if(ip_list != NULL)
+ free((char *)ip_list);
+ return False;
}
/********************************************************
-find the IP address of the master browser or DMB for a workgroup
+ Internal function to extract the MACHINE<0x20> name.
*********************************************************/
-BOOL find_master_ip(char *group, struct in_addr *master_ip)
+
+static void _lookup_pdc_name(char *p, char *master,char *rname)
+{
+ int numnames = CVAL(p,0);
+
+ *rname = '\0';
+
+ p += 1;
+ while (numnames--) {
+ int type = CVAL(p,15);
+ if(type == 0x20) {
+ StrnCpy(rname,p,15);
+ trim_string(rname,NULL," ");
+ return;
+ }
+ p += 18;
+ }
+}
+
+/********************************************************
+ Lookup a PDC name given a Domain name and IP address.
+*********************************************************/
+
+BOOL lookup_pdc_name(const char *srcname, const char *domain, struct in_addr *pdc_ip, char *ret_name)
{
- if (resolve_name(group, master_ip, 0x1D)) return True;
+#if !defined(I_HATE_WINDOWS_REPLY_CODE)
+
+ fstring pdc_name;
+ BOOL ret;
+
+ /*
+ * Due to the fact win WinNT *sucks* we must do a node status
+ * query here... JRA.
+ */
- return resolve_name(group, master_ip, 0x1B);
+ int sock = open_socket_in(SOCK_DGRAM, 0, 3, interpret_addr(lp_socket_address()), True );
+
+ if(sock == -1)
+ return False;
+
+ *pdc_name = '\0';
+
+ ret = internal_name_status(sock,"*SMBSERVER",0x20,True,
+ *pdc_ip,NULL,pdc_name,False,
+ _lookup_pdc_name,NULL);
+
+ close(sock);
+
+ if(ret && *pdc_name) {
+ fstrcpy(ret_name, pdc_name);
+ return True;
+ }
+
+ return False;
+
+#else /* defined(I_HATE_WINDOWS_REPLY_CODE) */
+ /*
+ * Sigh. I *love* this code, it took me ages to get right and it's
+ * completely *USELESS* because NT 4.x refuses to send the mailslot
+ * reply back to the correct port (it always uses 138).
+ * I hate NT when it does these things... JRA.
+ */
+
+ int retries = 3;
+ int retry_time = 2000;
+ struct timeval tval;
+ struct packet_struct p;
+ struct dgram_packet *dgram = &p.packet.dgram;
+ char *ptr,*p2;
+ char tmp[4];
+ int len;
+ struct sockaddr_in sock_name;
+ int sock_len = sizeof(sock_name);
+ const char *mailslot = "\\MAILSLOT\\NET\\NETLOGON";
+ static int name_trn_id = 0;
+ char buffer[1024];
+ char *bufp;
+ int sock = open_socket_in(SOCK_DGRAM, 0, 3, interpret_addr(lp_socket_address()), True );
+
+ if(sock == -1)
+ return False;
+
+ /* Find out the transient UDP port we have been allocated. */
+ if(getsockname(sock, (struct sockaddr *)&sock_name, &sock_len)<0) {
+ DEBUG(0,("lookup_pdc_name: Failed to get local UDP port. Error was %s\n",
+ strerror(errno)));
+ close(sock);
+ return False;
+ }
+
+ /*
+ * Create the request data.
+ */
+
+ memset(buffer,'\0',sizeof(buffer));
+ bufp = buffer;
+ SSVAL(bufp,0,QUERYFORPDC);
+ bufp += 2;
+ fstrcpy(bufp,srcname);
+ bufp += (strlen(bufp) + 1);
+ fstrcpy(bufp,"\\MAILSLOT\\NET\\GETDC411");
+ bufp += (strlen(bufp) + 1);
+ bufp = align2(bufp, buffer);
+ dos_PutUniCode(bufp, srcname, sizeof(buffer) - (bufp - buffer) - 1);
+ bufp = skip_unicode_string(bufp, 1);
+ SIVAL(bufp,0,1);
+ SSVAL(bufp,4,0xFFFF);
+ SSVAL(bufp,6,0xFFFF);
+ bufp += 8;
+ len = PTR_DIFF(bufp,buffer);
+
+ if (!name_trn_id)
+ name_trn_id = ((unsigned)time(NULL)%(unsigned)0x7FFF) + ((unsigned)getpid()%(unsigned)100);
+ name_trn_id = (name_trn_id+1) % (unsigned)0x7FFF;
+
+ memset((char *)&p,'\0',sizeof(p));
+
+ /* DIRECT GROUP or UNIQUE datagram. */
+ dgram->header.msg_type = 0x10;
+ dgram->header.flags.node_type = M_NODE;
+ dgram->header.flags.first = True;
+ dgram->header.flags.more = False;
+ dgram->header.dgm_id = name_trn_id;
+ dgram->header.source_ip = sock_name.sin_addr;
+ dgram->header.source_port = ntohs(sock_name.sin_port);
+ dgram->header.dgm_length = 0; /* Let build_dgram() handle this. */
+ dgram->header.packet_offset = 0;
+
+ make_nmb_name(&dgram->source_name,srcname,0,scope);
+ make_nmb_name(&dgram->dest_name,domain,0x1B,scope);
+
+ ptr = &dgram->data[0];
+
+ /* Setup the smb part. */
+ ptr -= 4; /* XXX Ugliness because of handling of tcp SMB length. */
+ memcpy(tmp,ptr,4);
+ set_message(ptr,17,17 + len,True);
+ memcpy(ptr,tmp,4);
+
+ CVAL(ptr,smb_com) = SMBtrans;
+ SSVAL(ptr,smb_vwv1,len);
+ SSVAL(ptr,smb_vwv11,len);
+ SSVAL(ptr,smb_vwv12,70 + strlen(mailslot));
+ SSVAL(ptr,smb_vwv13,3);
+ SSVAL(ptr,smb_vwv14,1);
+ SSVAL(ptr,smb_vwv15,1);
+ SSVAL(ptr,smb_vwv16,2);
+ p2 = smb_buf(ptr);
+ pstrcpy(p2,mailslot);
+ p2 = skip_string(p2,1);
+
+ memcpy(p2,buffer,len);
+ p2 += len;
+
+ dgram->datasize = PTR_DIFF(p2,ptr+4); /* +4 for tcp length. */
+
+ p.ip = *pdc_ip;
+ p.port = DGRAM_PORT;
+ p.fd = sock;
+ p.timestamp = time(NULL);
+ p.packet_type = DGRAM_PACKET;
+
+ GetTimeOfDay(&tval);
+
+ if (!send_packet(&p)) {
+ DEBUG(0,("lookup_pdc_name: send_packet failed.\n"));
+ close(sock);
+ return False;
+ }
+
+ retries--;
+
+ while (1) {
+ struct timeval tval2;
+ struct packet_struct *p_ret;
+
+ GetTimeOfDay(&tval2);
+ if (TvalDiff(&tval,&tval2) > retry_time) {
+ if (!retries)
+ break;
+ if (!send_packet(&p)) {
+ DEBUG(0,("lookup_pdc_name: send_packet failed.\n"));
+ close(sock);
+ return False;
+ }
+ GetTimeOfDay(&tval);
+ retries--;
+ }
+
+ if ((p_ret = receive_packet(sock,NMB_PACKET,90))) {
+ struct nmb_packet *nmb2 = &p_ret->packet.nmb;
+ struct dgram_packet *dgram2 = &p_ret->packet.dgram;
+ char *buf;
+ char *buf2;
+
+ debug_nmb_packet(p_ret);
+
+ if (memcmp(&p.ip, &p_ret->ip, sizeof(p.ip))) {
+ /*
+ * Not for us.
+ */
+ DEBUG(0,("lookup_pdc_name: datagram return IP %s doesn't match\n", inet_ntoa(p_ret->ip) ));
+ free_packet(p_ret);
+ continue;
+ }
+
+ buf = &dgram2->data[0];
+ buf -= 4;
+
+ if (CVAL(buf,smb_com) != SMBtrans) {
+ DEBUG(0,("lookup_pdc_name: datagram type %u != SMBtrans(%u)\n", (unsigned int)CVAL(buf,smb_com),
+ (unsigned int)SMBtrans ));
+ free_packet(p_ret);
+ continue;
+ }
+
+ len = SVAL(buf,smb_vwv11);
+ buf2 = smb_base(buf) + SVAL(buf,smb_vwv12);
+
+ if (len <= 0) {
+ DEBUG(0,("lookup_pdc_name: datagram len < 0 (%d)\n", len ));
+ free_packet(p_ret);
+ continue;
+ }
+
+ DEBUG(4,("lookup_pdc_name: datagram reply from %s to %s IP %s for %s of type %d len=%d\n",
+ nmb_namestr(&dgram2->source_name),nmb_namestr(&dgram2->dest_name),
+ inet_ntoa(p_ret->ip), smb_buf(buf),CVAL(buf2,0),len));
+
+ if(SVAL(buf,0) != QUERYFORPDC_R) {
+ DEBUG(0,("lookup_pdc_name: datagram type (%u) != QUERYFORPDC_R(%u)\n",
+ (unsigned int)SVAL(buf,0), (unsigned int)QUERYFORPDC_R ));
+ free_packet(p_ret);
+ continue;
+ }
+
+ buf += 2;
+ /* Note this is safe as it is a bounded strcpy. */
+ fstrcpy(ret_name, buf);
+ ret_name[sizeof(fstring)-1] = '\0';
+ close(sock);
+ free_packet(p_ret);
+ return True;
+ }
+ }
+
+ close(sock);
+ return False;
+#endif /* I_HATE_WINDOWS_REPLY_CODE */
+}
+
+/********************************************************
+ Get the IP address list of the PDC/BDC's of a Domain.
+*********************************************************/
+
+BOOL get_dc_list(char *group, struct in_addr **ip_list, int *count)
+{
+ return internal_resolve_name(group, 0x1C, ip_list, count);
}
diff --git a/source3/libsmb/nmblib.c b/source3/libsmb/nmblib.c
index 006cb5f5ee..3b14fd2c6b 100644
--- a/source3/libsmb/nmblib.c
+++ b/source3/libsmb/nmblib.c
@@ -179,27 +179,34 @@ static int parse_nmb_name(char *inbuf,int offset,int length, struct nmb_name *na
unsigned char *ubuf = (unsigned char *)inbuf;
int ret = 0;
BOOL got_pointer=False;
+ int loop_count=0;
- if (length - offset < 2) return(0);
+ if (length - offset < 2)
+ return(0);
/* handle initial name pointers */
- if (!handle_name_ptrs(ubuf,&offset,length,&got_pointer,&ret)) return(0);
+ if (!handle_name_ptrs(ubuf,&offset,length,&got_pointer,&ret))
+ return(0);
m = ubuf[offset];
- if (!m) return(0);
- if ((m & 0xC0) || offset+m+2 > length) return(0);
+ if (!m)
+ return(0);
+ if ((m & 0xC0) || offset+m+2 > length)
+ return(0);
- bzero((char *)name,sizeof(*name));
+ memset((char *)name,'\0',sizeof(*name));
/* the "compressed" part */
- if (!got_pointer) ret += m + 2;
+ if (!got_pointer)
+ ret += m + 2;
offset++;
- while (m) {
+ while (m > 0) {
unsigned char c1,c2;
c1 = ubuf[offset++]-'A';
c2 = ubuf[offset++]-'A';
- if ((c1 & 0xF0) || (c2 & 0xF0) || (n > sizeof(name->name)-1)) return(0);
+ if ((c1 & 0xF0) || (c2 & 0xF0) || (n > sizeof(name->name)-1))
+ return(0);
name->name[n++] = (c1<<4) | c2;
m -= 2;
}
@@ -213,21 +220,38 @@ static int parse_nmb_name(char *inbuf,int offset,int length, struct nmb_name *na
/* remove trailing spaces */
name->name[15] = 0;
n = 14;
- while (n && name->name[n]==' ') name->name[n--] = 0;
+ while (n && name->name[n]==' ')
+ name->name[n--] = 0;
}
/* now the domain parts (if any) */
n = 0;
while (ubuf[offset]) {
/* we can have pointers within the domain part as well */
- if (!handle_name_ptrs(ubuf,&offset,length,&got_pointer,&ret)) return(0);
+ if (!handle_name_ptrs(ubuf,&offset,length,&got_pointer,&ret))
+ return(0);
m = ubuf[offset];
- if (!got_pointer) ret += m+1;
- if (n) name->scope[n++] = '.';
- if (m+2+offset>length || n+m+1>sizeof(name->scope)) return(0);
+ /*
+ * Don't allow null domain parts.
+ */
+ if (!m)
+ return(0);
+ if (!got_pointer)
+ ret += m+1;
+ if (n)
+ name->scope[n++] = '.';
+ if (m+2+offset>length || n+m+1>sizeof(name->scope))
+ return(0);
offset++;
- while (m--) name->scope[n++] = (char)ubuf[offset++];
+ while (m--)
+ name->scope[n++] = (char)ubuf[offset++];
+
+ /*
+ * Watch for malicious loops.
+ */
+ if (loop_count++ == 10)
+ return 0;
}
name->scope[n++] = 0;
@@ -251,7 +275,7 @@ static int put_nmb_name(char *buf,int offset,struct nmb_name *name)
if (strcmp(name->name,"*") == 0) {
/* special case for wildcard name */
- bzero(buf1,20);
+ memset(buf1,'\0',20);
buf1[0] = '*';
buf1[15] = name->name_type;
} else {
@@ -287,7 +311,6 @@ static int put_nmb_name(char *buf,int offset,struct nmb_name *name)
return(ret);
}
-
/*******************************************************************
useful for debugging messages
******************************************************************/
@@ -297,24 +320,16 @@ char *nmb_namestr(struct nmb_name *n)
static fstring ret[4];
char *p = ret[i];
- nmb_safe_namestr(n, p, sizeof(fstring));
+ if (!n->scope[0])
+ slprintf(p,sizeof(fstring)-1, "%s<%02x>",n->name,n->name_type);
+ else
+ slprintf(p,sizeof(fstring)-1, "%s<%02x>.%s",n->name,n->name_type,n->scope);
i = (i+1)%4;
return(p);
}
/*******************************************************************
- useful for debugging messages
- ******************************************************************/
-void nmb_safe_namestr(struct nmb_name *n, char *str, size_t len)
-{
- if (!n->scope[0])
- slprintf(str, len-1, "%s<%02x>",n->name,n->name_type);
- else
- slprintf(str, len-1, "%s<%02x>.%s",n->name,n->name_type,n->scope);
-}
-
-/*******************************************************************
allocate and parse some resource records
******************************************************************/
static BOOL parse_alloc_res_rec(char *inbuf,int *offset,int length,
@@ -324,13 +339,14 @@ static BOOL parse_alloc_res_rec(char *inbuf,int *offset,int length,
*recs = (struct res_rec *)malloc(sizeof(**recs)*count);
if (!*recs) return(False);
- bzero(*recs,sizeof(**recs)*count);
+ memset((char *)*recs,'\0',sizeof(**recs)*count);
for (i=0;i<count;i++) {
int l = parse_nmb_name(inbuf,*offset,length,&(*recs)[i].rr_name);
(*offset) += l;
if (!l || (*offset)+10 > length) {
free(*recs);
+ *recs = NULL;
return(False);
}
(*recs)[i].rr_type = RSVAL(inbuf,(*offset));
@@ -341,6 +357,7 @@ static BOOL parse_alloc_res_rec(char *inbuf,int *offset,int length,
if ((*recs)[i].rdlength>sizeof((*recs)[i].rdata) ||
(*offset)+(*recs)[i].rdlength > length) {
free(*recs);
+ *recs = NULL;
return(False);
}
memcpy((*recs)[i].rdata,inbuf+(*offset),(*recs)[i].rdlength);
@@ -405,7 +422,7 @@ static BOOL parse_dgram(char *inbuf,int length,struct dgram_packet *dgram)
int offset;
int flags;
- bzero((char *)dgram,sizeof(*dgram));
+ memset((char *)dgram,'\0',sizeof(*dgram));
if (length < 14) return(False);
@@ -447,7 +464,7 @@ static BOOL parse_nmb(char *inbuf,int length,struct nmb_packet *nmb)
{
int nm_flags,offset;
- bzero((char *)nmb,sizeof(*nmb));
+ memset((char *)nmb,'\0',sizeof(*nmb));
if (length < 12) return(False);
@@ -563,12 +580,18 @@ static struct packet_struct *copy_nmb_packet(struct packet_struct *packet)
free_and_exit:
- if(copy_nmb->answers)
+ if(copy_nmb->answers) {
free((char *)copy_nmb->answers);
- if(copy_nmb->nsrecs)
+ copy_nmb->answers = NULL;
+ }
+ if(copy_nmb->nsrecs) {
free((char *)copy_nmb->nsrecs);
- if(copy_nmb->additional)
+ copy_nmb->nsrecs = NULL;
+ }
+ if(copy_nmb->additional) {
free((char *)copy_nmb->additional);
+ copy_nmb->additional = NULL;
+ }
free((char *)pkt_copy);
DEBUG(0,("copy_nmb_packet: malloc fail in resource records.\n"));
@@ -617,9 +640,18 @@ struct packet_struct *copy_packet(struct packet_struct *packet)
******************************************************************/
static void free_nmb_packet(struct nmb_packet *nmb)
{
- if (nmb->answers) free(nmb->answers);
- if (nmb->nsrecs) free(nmb->nsrecs);
- if (nmb->additional) free(nmb->additional);
+ if (nmb->answers) {
+ free(nmb->answers);
+ nmb->answers = NULL;
+ }
+ if (nmb->nsrecs) {
+ free(nmb->nsrecs);
+ nmb->nsrecs = NULL;
+ }
+ if (nmb->additional) {
+ free(nmb->additional);
+ nmb->additional = NULL;
+ }
}
/*******************************************************************
@@ -641,6 +673,7 @@ void free_packet(struct packet_struct *packet)
free_nmb_packet(&packet->packet.nmb);
else if (packet->packet_type == DGRAM_PACKET)
free_dgram_packet(&packet->packet.dgram);
+ ZERO_STRUCTPN(packet);
free(packet);
}
@@ -651,47 +684,15 @@ void free_packet(struct packet_struct *packet)
struct packet_struct *read_packet(int fd,enum packet_type packet_type)
{
extern struct in_addr lastip;
- struct nmb_state con;
extern int lastport;
struct packet_struct *packet;
char buf[MAX_DGRAM_SIZE];
int length;
BOOL ok=False;
- if (packet_type == NMB_SOCK_PACKET || packet_type == DGRAM_SOCK_PACKET)
- {
- uint16 trn_id = 0;
- if (!read_nmb_sock(fd, &con))
- {
- return False;
- }
- if (write(fd, &trn_id, sizeof(trn_id)) != sizeof(trn_id))
- {
- return False;
- }
- }
-
- length = read_udp_socket(fd,buf,sizeof(buf));
-
- dump_data(100, buf, length);
-
- if (packet_type == NMB_SOCK_PACKET || packet_type == DGRAM_SOCK_PACKET)
- {
- uint16 trn_id = 0;
- if (write(fd, &trn_id, sizeof(trn_id)) != sizeof(trn_id))
- {
- return False;
- }
- }
-
+ length = read_udp_socket(fd,buf,sizeof(buf));
if (length < MIN_DGRAM_SIZE) return(NULL);
- if (packet_type == NMB_SOCK_PACKET || packet_type == DGRAM_SOCK_PACKET)
- {
- lastip = con.ip;
- lastport = con.port;
- }
-
packet = (struct packet_struct *)malloc(sizeof(*packet));
if (!packet) return(NULL);
@@ -706,19 +707,17 @@ struct packet_struct *read_packet(int fd,enum packet_type packet_type)
switch (packet_type)
{
case NMB_PACKET:
- case NMB_SOCK_PACKET:
ok = parse_nmb(buf,length,&packet->packet.nmb);
break;
case DGRAM_PACKET:
- case DGRAM_SOCK_PACKET:
ok = parse_dgram(buf,length,&packet->packet.dgram);
break;
}
if (!ok) {
DEBUG(10,("read_packet: discarding packet id = %d\n",
packet->packet.nmb.header.name_trn_id));
- free(packet);
+ free_packet(packet);
return(NULL);
}
@@ -740,7 +739,7 @@ static BOOL send_udp(int fd,char *buf,int len,struct in_addr ip,int port)
struct sockaddr_in sock_out;
/* set the address and port */
- bzero((char *)&sock_out,sizeof(sock_out));
+ memset((char *)&sock_out,'\0',sizeof(sock_out));
putip((char *)&sock_out.sin_addr,(char *)&ip);
sock_out.sin_port = htons( port );
sock_out.sin_family = AF_INET;
@@ -776,7 +775,7 @@ static int build_dgram(char *buf,struct packet_struct *p)
/* put in the header */
ubuf[0] = dgram->header.msg_type;
- ubuf[1] = (((unsigned int)dgram->header.flags.node_type)<<2);
+ ubuf[1] = (((int)dgram->header.flags.node_type)<<2);
if (dgram->header.flags.more) ubuf[1] |= 1;
if (dgram->header.flags.first) ubuf[1] |= 2;
RSSVAL(ubuf,2,dgram->header.dgm_id);
@@ -909,82 +908,23 @@ BOOL send_packet(struct packet_struct *p)
char buf[1024];
int len=0;
- DEBUG(100,("send_packet: %d %d\n", p->fd, p->packet_type));
-
- bzero(buf,sizeof(buf));
+ memset(buf,'\0',sizeof(buf));
switch (p->packet_type)
{
case NMB_PACKET:
- case NMB_SOCK_PACKET:
len = build_nmb(buf,p);
debug_nmb_packet(p);
break;
case DGRAM_PACKET:
- case DGRAM_SOCK_PACKET:
len = build_dgram(buf,p);
break;
}
if (!len) return(False);
- switch (p->packet_type)
- {
- case DGRAM_PACKET:
- case NMB_PACKET:
- return(send_udp(p->fd,buf,len,p->ip,p->port));
- break;
-
- case NMB_SOCK_PACKET:
- case DGRAM_SOCK_PACKET:
- {
- fstring qbuf;
- struct nmb_state nmb;
- int qlen;
- uint16 trn_id;
- char *q = qbuf + 4;
-
- nmb.ip = p->ip;
- nmb.port = p->port;
-
- SSVAL(q, 0, 0);
- q += 2;
- SSVAL(q, 0, 0);
- q += 2;
- memcpy(q, &nmb, sizeof(nmb));
- q += sizeof(nmb);
-
- qlen = PTR_DIFF(q, qbuf);
- SIVAL(qbuf, 0, qlen);
-
- dump_data(100, qbuf, qlen);
-
- if (write(p->fd,qbuf,qlen) != qlen)
- {
- DEBUG(0,("send_packet: write hdr failed\n"));
- return False;
- }
- if (read(p->fd, &trn_id, sizeof(trn_id)) != sizeof(trn_id))
- {
- DEBUG(0,("send_packet: 1st ack failed\n"));
- return False;
- }
- if (write(p->fd,buf,len) != len)
- {
- DEBUG(0,("send_packet: write packet failed\n"));
- return False;
- }
- if (read(p->fd, &trn_id, sizeof(trn_id)) != sizeof(trn_id))
- {
- DEBUG(0,("send_packet: 2nd ack failed\n"));
- return False;
- }
- return True;
- }
- }
-
- return False;
+ return(send_udp(p->fd,buf,len,p->ip,p->port));
}
/****************************************************************************
@@ -1001,8 +941,7 @@ struct packet_struct *receive_packet(int fd,enum packet_type type,int t)
timeout.tv_sec = t/1000;
timeout.tv_usec = 1000*(t%1000);
- DEBUG(100,("receive_packet: %d %d\n", fd, type));
- sys_select(fd+1,&fds,NULL, &timeout);
+ sys_select(fd+1,&fds,&timeout);
if (FD_ISSET(fd,&fds))
return(read_packet(fd,type));
@@ -1055,76 +994,3 @@ void sort_query_replies(char *data, int n, struct in_addr ip)
qsort(data, n, 6, QSORT_CAST name_query_comp);
}
-
-BOOL read_nmb_sock(int c, struct nmb_state *con)
-{
- fstring buf;
- char *p = buf;
- int rl;
- uint32 len;
- uint16 version;
- uint16 command;
-
- ZERO_STRUCTP(con);
-
- rl = read(c, &buf, sizeof(len));
-
- if (rl < 0)
- {
- DEBUG(0,("read_nmb_sock: error\n"));
- return False;
- }
- if (rl != sizeof(len))
- {
- DEBUG(0,("Unable to read length\n"));
- dump_data(0, buf, sizeof(len));
- return False;
- }
-
- len = IVAL(buf, 0);
-
- if (len > sizeof(buf))
- {
- DEBUG(0,("length %d too long\n", len));
- return False;
- }
-
- rl = read(c, buf, len);
-
- if (rl < 0)
- {
- DEBUG(0,("Unable to read from connection\n"));
- return False;
- }
-
-#ifdef DEBUG_PASSWORD
- dump_data(100, buf, rl);
-#endif
- version = SVAL(p, 0);
- p += 2;
- command = SVAL(p, 0);
- p += 2;
-
- memcpy(con, p, sizeof(*con));
- p += sizeof(*con);
-
- DEBUG(10,("read_nmb_sock: ip %s port: %d\n",
- inet_ntoa(con->ip), con->port));
-
- if (PTR_DIFF(p, buf) != rl)
- {
- DEBUG(0,("Buffer size %d %d!\n",
- PTR_DIFF(p, buf), rl));
- return False;
- }
-
- return True;
-}
-
-int get_nmb_sock(void)
-{
- fstring path;
- slprintf(path, sizeof(path)-1, "/tmp/.nmb/agent");
-
- return open_pipe_sock(path);
-}
diff --git a/source3/libsmb/nterr.c b/source3/libsmb/nterr.c
index 9cf1fb8214..d2f9335000 100644
--- a/source3/libsmb/nterr.c
+++ b/source3/libsmb/nterr.c
@@ -514,18 +514,18 @@ nt_err_code_struct nt_errs[] =
{ "NT_STATUS_TOO_MANY_LINKS", NT_STATUS_TOO_MANY_LINKS },
{ "NT_STATUS_QUOTA_LIST_INCONSISTENT", NT_STATUS_QUOTA_LIST_INCONSISTENT },
{ "NT_STATUS_FILE_IS_OFFLINE", NT_STATUS_FILE_IS_OFFLINE },
- { "NT_STATUS_NO_SUCH_JOB", NT_STATUS_NO_SUCH_JOB },
{ NULL, 0 }
};
/*****************************************************************************
returns an NT error message. not amazingly helpful, but better than a number.
*****************************************************************************/
-void get_safe_nt_error_msg(uint32 nt_code, char *msg, size_t len)
+char *get_nt_error_msg(uint32 nt_code)
{
+ static pstring msg;
int idx = 0;
- snprintf(msg, len, "NT code %08x", nt_code);
+ pstrcpy(msg, "Unknown NT error");
nt_code &= 0xFFFF;
@@ -533,19 +533,11 @@ void get_safe_nt_error_msg(uint32 nt_code, char *msg, size_t len)
{
if (nt_errs[idx].nt_errcode == nt_code)
{
- safe_strcpy(msg, nt_errs[idx].nt_errstr, len);
- return;
+ pstrcpy(msg, nt_errs[idx].nt_errstr);
+ return msg;
}
idx++;
}
-}
-
-/*****************************************************************************
- returns an NT error message. not amazingly helpful, but better than a number.
- *****************************************************************************/
-char *get_nt_error_msg(uint32 nt_code)
-{
- static pstring msg;
- get_safe_nt_error_msg(nt_code, msg, sizeof(msg));
return msg;
}
+
diff --git a/source3/libsmb/passchange.c b/source3/libsmb/passchange.c
index b5552d4cea..b0b1188f32 100644
--- a/source3/libsmb/passchange.c
+++ b/source3/libsmb/passchange.c
@@ -36,6 +36,8 @@ BOOL remote_password_change(const char *remote_machine, const char *user_name,
struct cli_state cli;
struct in_addr ip;
+ *err_str = '\0';
+
if(!resolve_name( remote_machine, &ip, 0x20)) {
slprintf(err_str, err_str_len-1, "unable to find an IP address for machine %s.\n",
remote_machine );
@@ -75,7 +77,7 @@ BOOL remote_password_change(const char *remote_machine, const char *user_name,
* Thanks to <Nicholas.S.Jenkins@cdc.com> for this fix.
*/
- if (!cli_session_setup(&cli, global_myname, "", "", 0, "", 0, "")) {
+ if (!cli_session_setup(&cli, "", "", 0, "", 0, "")) {
slprintf(err_str, err_str_len-1, "machine %s rejected the session setup. Error was : %s.\n",
remote_machine, cli_errstr(&cli) );
cli_shutdown(&cli);
diff --git a/source3/libsmb/pwd_cache.c b/source3/libsmb/pwd_cache.c
index 29cf77dd55..94b60d3ff0 100644
--- a/source3/libsmb/pwd_cache.c
+++ b/source3/libsmb/pwd_cache.c
@@ -29,13 +29,11 @@ initialises a password structure
****************************************************************************/
void pwd_init(struct pwd_info *pwd)
{
- ZERO_STRUCT(pwd->password );
- ZERO_STRUCT(pwd->smb_lm_pwd);
- ZERO_STRUCT(pwd->smb_nt_pwd);
- ZERO_STRUCT(pwd->smb_lm_owf);
- ZERO_STRUCT(pwd->smb_nt_owf);
- ZERO_STRUCT(pwd->sess_key );
- pwd->nt_owf_len = 0;
+ memset((char *)pwd->password , '\0', sizeof(pwd->password ));
+ memset((char *)pwd->smb_lm_pwd, '\0', sizeof(pwd->smb_lm_pwd));
+ memset((char *)pwd->smb_nt_pwd, '\0', sizeof(pwd->smb_nt_pwd));
+ memset((char *)pwd->smb_lm_owf, '\0', sizeof(pwd->smb_lm_owf));
+ memset((char *)pwd->smb_nt_owf, '\0', sizeof(pwd->smb_nt_owf));
pwd->null_pwd = True; /* safest option... */
pwd->cleartext = False;
@@ -43,24 +41,16 @@ void pwd_init(struct pwd_info *pwd)
}
/****************************************************************************
-returns NULL password flag
-****************************************************************************/
-BOOL pwd_is_nullpwd(const struct pwd_info *pwd)
-{
- return pwd->null_pwd;
-}
-
-/****************************************************************************
de-obfuscates a password
****************************************************************************/
-static void pwd_deobfuscate(const struct pwd_info *pwd)
+static void pwd_deobfuscate(struct pwd_info *pwd)
{
}
/****************************************************************************
obfuscates a password
****************************************************************************/
-static void pwd_obfuscate(const struct pwd_info *pwd)
+static void pwd_obfuscate(struct pwd_info *pwd)
{
}
@@ -72,59 +62,6 @@ void pwd_obfuscate_key(struct pwd_info *pwd, uint32 int_key, char *str_key)
}
/****************************************************************************
-compares two passwords. hmm, not as trivial as expected. hmm.
-****************************************************************************/
-BOOL pwd_compare(struct pwd_info *pwd1, struct pwd_info *pwd2)
-{
- pwd_deobfuscate(pwd1);
- pwd_deobfuscate(pwd2);
- if (pwd1->cleartext && pwd2->cleartext)
- {
- if (strequal(pwd1->password, pwd2->password))
- {
- pwd_obfuscate(pwd1);
- pwd_obfuscate(pwd2);
- return True;
- }
- }
- if (pwd1->null_pwd && pwd2->null_pwd)
- {
- pwd_obfuscate(pwd1);
- pwd_obfuscate(pwd2);
- return True;
- }
-
- if (!pwd1->null_pwd && !pwd2->null_pwd &&
- !pwd1->cleartext && !pwd2->cleartext)
- {
-#ifdef DEBUG_PASSWORD
- DEBUG(100,("pwd compare: nt#\n"));
- dump_data(100, pwd1->smb_nt_pwd, 16);
- dump_data(100, pwd2->smb_nt_pwd, 16);
-#endif
- if (memcmp(pwd1->smb_nt_pwd, pwd2->smb_nt_pwd, 16) == 0)
- {
- pwd_obfuscate(pwd1);
- pwd_obfuscate(pwd2);
- return True;
- }
-#ifdef DEBUG_PASSWORD
- DEBUG(100,("pwd compare: lm#\n"));
- dump_data(100, pwd1->smb_lm_pwd, 16);
- dump_data(100, pwd2->smb_lm_pwd, 16);
-#endif
- if (memcmp(pwd1->smb_lm_pwd, pwd2->smb_lm_pwd, 16) == 0)
- {
- pwd_obfuscate(pwd1);
- pwd_obfuscate(pwd2);
- return True;
- }
- }
- pwd_obfuscate(pwd1);
- pwd_obfuscate(pwd2);
- return False;
-}
-/****************************************************************************
reads a password
****************************************************************************/
void pwd_read(struct pwd_info *pwd, char *passwd_report, BOOL do_encrypt)
@@ -169,6 +106,7 @@ void pwd_set_cleartext(struct pwd_info *pwd, char *clr)
{
pwd_init(pwd);
fstrcpy(pwd->password, clr);
+ unix_to_dos(pwd->password,True);
pwd->cleartext = True;
pwd->null_pwd = False;
pwd->crypted = False;
@@ -185,6 +123,7 @@ void pwd_get_cleartext(struct pwd_info *pwd, char *clr)
if (pwd->cleartext)
{
fstrcpy(clr, pwd->password);
+ dos_to_unix(clr, True);
}
else
{
@@ -206,7 +145,7 @@ void pwd_set_lm_nt_16(struct pwd_info *pwd, uchar lm_pwd[16], uchar nt_pwd[16])
}
else
{
- bzero(pwd->smb_lm_pwd, 16);
+ memset((char *)pwd->smb_lm_pwd, '\0', 16);
}
if (nt_pwd)
@@ -215,7 +154,7 @@ void pwd_set_lm_nt_16(struct pwd_info *pwd, uchar lm_pwd[16], uchar nt_pwd[16])
}
else
{
- bzero(pwd->smb_nt_pwd, 16);
+ memset((char *)pwd->smb_nt_pwd, '\0', 16);
}
pwd->null_pwd = False;
@@ -228,7 +167,7 @@ void pwd_set_lm_nt_16(struct pwd_info *pwd, uchar lm_pwd[16], uchar nt_pwd[16])
/****************************************************************************
gets lm and nt hashed passwords
****************************************************************************/
-void pwd_get_lm_nt_16(const struct pwd_info *pwd, uchar lm_pwd[16], uchar nt_pwd[16])
+void pwd_get_lm_nt_16(struct pwd_info *pwd, uchar lm_pwd[16], uchar nt_pwd[16])
{
pwd_deobfuscate(pwd);
if (lm_pwd != NULL)
@@ -247,9 +186,14 @@ void pwd_get_lm_nt_16(const struct pwd_info *pwd, uchar lm_pwd[16], uchar nt_pwd
****************************************************************************/
void pwd_make_lm_nt_16(struct pwd_info *pwd, char *clr)
{
+ pstring dos_passwd;
+
pwd_init(pwd);
- nt_lm_owf_gen(clr, pwd->smb_nt_pwd, pwd->smb_lm_pwd);
+ pstrcpy(dos_passwd, clr);
+ unix_to_dos(dos_passwd, True);
+
+ nt_lm_owf_gen(dos_passwd, pwd->smb_nt_pwd, pwd->smb_lm_pwd);
pwd->null_pwd = False;
pwd->cleartext = False;
pwd->crypted = False;
@@ -260,109 +204,31 @@ void pwd_make_lm_nt_16(struct pwd_info *pwd, char *clr)
/****************************************************************************
makes lm and nt OWF crypts
****************************************************************************/
-void pwd_make_lm_nt_owf2(struct pwd_info *pwd, const uchar srv_key[8],
- const char *user, const char *server, const char *domain)
+void pwd_make_lm_nt_owf(struct pwd_info *pwd, uchar cryptkey[8])
{
- uchar kr[16];
-
- DEBUG(10,("pwd_make_lm_nt_owf2: user %s, srv %s, dom %s\n",
- user, server, domain));
-
pwd_deobfuscate(pwd);
- SMBgenclientchals(pwd->lm_cli_chal,
- pwd->nt_cli_chal,
- &pwd->nt_cli_chal_len,
- server, domain);
-
- ntv2_owf_gen(pwd->smb_nt_pwd, user, domain, kr);
-
- /* lm # */
- SMBOWFencrypt_ntv2(kr,
- srv_key, 8,
- pwd->lm_cli_chal, 8,
- pwd->smb_lm_owf);
- memcpy(&pwd->smb_lm_owf[16], pwd->lm_cli_chal, 8);
-
- /* nt # */
- SMBOWFencrypt_ntv2(kr,
- srv_key, 8,
- pwd->nt_cli_chal, pwd->nt_cli_chal_len,
- pwd->smb_nt_owf);
- memcpy(&pwd->smb_nt_owf[16], pwd->nt_cli_chal, pwd->nt_cli_chal_len);
- pwd->nt_owf_len = pwd->nt_cli_chal_len + 16;
-
- SMBsesskeygen_ntv2(kr, pwd->smb_nt_owf, pwd->sess_key);
-
-#if DEBUG_PASSWORD
-#endif
-
#ifdef DEBUG_PASSWORD
- DEBUG(100,("server cryptkey: "));
- dump_data(100, srv_key, 8);
-
- DEBUG(100,("client lmv2 cryptkey: "));
- dump_data(100, pwd->lm_cli_chal, 8);
-
- DEBUG(100,("client ntv2 cryptkey: "));
- dump_data(100, pwd->nt_cli_chal, pwd->nt_cli_chal_len);
-
- DEBUG(100,("ntv2_owf_passwd: "));
- dump_data(100, pwd->smb_nt_owf, pwd->nt_owf_len);
- DEBUG(100,("nt_sess_pwd: "));
- dump_data(100, pwd->smb_nt_pwd, sizeof(pwd->smb_nt_pwd));
-
- DEBUG(100,("lmv2_owf_passwd: "));
- dump_data(100, pwd->smb_lm_owf, sizeof(pwd->smb_lm_owf));
- DEBUG(100,("lm_sess_pwd: "));
- dump_data(100, pwd->smb_lm_pwd, sizeof(pwd->smb_lm_pwd));
-
- DEBUG(100,("session key:\n"));
- dump_data(100, pwd->sess_key, sizeof(pwd->sess_key));
+ DEBUG(100,("client cryptkey: "));
+ dump_data(100, (char *)cryptkey, 8);
#endif
- pwd->crypted = True;
- pwd_obfuscate(pwd);
-}
+ SMBOWFencrypt(pwd->smb_nt_pwd, cryptkey, pwd->smb_nt_owf);
-/****************************************************************************
- makes lm and nt OWF crypts
- ****************************************************************************/
-void pwd_make_lm_nt_owf(struct pwd_info *pwd, uchar cryptkey[8])
-{
- if (pwd->null_pwd)
- {
#ifdef DEBUG_PASSWORD
- DEBUG(100,("pwd_make_lm_nt_owf: NULL password\n"));
+ DEBUG(100,("nt_owf_passwd: "));
+ dump_data(100, (char *)pwd->smb_nt_owf, sizeof(pwd->smb_nt_owf));
+ DEBUG(100,("nt_sess_pwd: "));
+ dump_data(100, (char *)pwd->smb_nt_pwd, sizeof(pwd->smb_nt_pwd));
#endif
- pwd->nt_owf_len = 0;
- return;
- }
- pwd_deobfuscate(pwd);
- /* generate 24-byte hashes */
SMBOWFencrypt(pwd->smb_lm_pwd, cryptkey, pwd->smb_lm_owf);
- SMBOWFencrypt(pwd->smb_nt_pwd, cryptkey, pwd->smb_nt_owf);
- pwd->nt_owf_len = 24;
-
- SMBsesskeygen_ntv1(pwd->smb_nt_pwd, pwd->smb_nt_owf, pwd->sess_key);
#ifdef DEBUG_PASSWORD
- DEBUG(100,("client cryptkey: "));
- dump_data(100, cryptkey, 8);
-
- DEBUG(100,("nt_owf_passwd: "));
- dump_data(100, pwd->smb_nt_owf, pwd->nt_owf_len);
- DEBUG(100,("nt_sess_pwd: "));
- dump_data(100, pwd->smb_nt_pwd, sizeof(pwd->smb_nt_pwd));
-
DEBUG(100,("lm_owf_passwd: "));
- dump_data(100, pwd->smb_lm_owf, sizeof(pwd->smb_lm_owf));
+ dump_data(100, (char *)pwd->smb_lm_owf, sizeof(pwd->smb_lm_owf));
DEBUG(100,("lm_sess_pwd: "));
- dump_data(100, pwd->smb_lm_pwd, sizeof(pwd->smb_lm_pwd));
-
- DEBUG(100,("session key:\n"));
- dump_data(100, pwd->sess_key, sizeof(pwd->sess_key));
+ dump_data(100, (char *)pwd->smb_lm_pwd, sizeof(pwd->smb_lm_pwd));
#endif
pwd->crypted = True;
@@ -373,22 +239,8 @@ void pwd_make_lm_nt_owf(struct pwd_info *pwd, uchar cryptkey[8])
/****************************************************************************
gets lm and nt crypts
****************************************************************************/
-void pwd_get_lm_nt_owf(struct pwd_info *pwd, uchar lm_owf[24],
- uchar *nt_owf, size_t *nt_owf_len,
- uchar *sess_key)
+void pwd_get_lm_nt_owf(struct pwd_info *pwd, uchar lm_owf[24], uchar nt_owf[24])
{
- if (pwd->null_pwd)
- {
-#ifdef DEBUG_PASSWORD
- DEBUG(100,("pwd_get_lm_nt_owf: NULL password\n"));
-#endif
- if (nt_owf_len != NULL)
- {
- *nt_owf_len = 0;
- }
- return;
- }
-
pwd_deobfuscate(pwd);
if (lm_owf != NULL)
{
@@ -396,16 +248,7 @@ void pwd_get_lm_nt_owf(struct pwd_info *pwd, uchar lm_owf[24],
}
if (nt_owf != NULL)
{
- memcpy(nt_owf, pwd->smb_nt_owf, pwd->nt_owf_len);
- }
- if (sess_key != NULL)
- {
- memcpy(sess_key, pwd->sess_key, 16);
- }
- if (nt_owf_len != NULL)
- {
- *nt_owf_len = pwd->nt_owf_len;
+ memcpy(nt_owf, pwd->smb_nt_owf, 24);
}
pwd_obfuscate(pwd);
}
-
diff --git a/source3/libsmb/smbdes.c b/source3/libsmb/smbdes.c
index e60b93d6a2..d0e1c6e85f 100644
--- a/source3/libsmb/smbdes.c
+++ b/source3/libsmb/smbdes.c
@@ -259,7 +259,7 @@ static void dohash(char *out, char *in, char *key, int forw)
permute(out, rl, perm6, 64);
}
-static void str_to_key(const uchar *str, uchar *key)
+static void str_to_key(unsigned char *str,unsigned char *key)
{
int i;
@@ -277,7 +277,7 @@ static void str_to_key(const uchar *str, uchar *key)
}
-void smbhash(unsigned char *out, const uchar *in, const uchar *key, int forw)
+static void smbhash(unsigned char *out, unsigned char *in, unsigned char *key, int forw)
{
int i;
char outb[64];
@@ -365,10 +365,6 @@ void SamOEMhash( unsigned char *data, unsigned char *key, int val)
unsigned char index_j = 0;
unsigned char j = 0;
int ind;
- int len = 0;
- if (val == 1) len = 516;
- if (val == 0) len = 16;
- if (val == 2) len = 68;
for (ind = 0; ind < 256; ind++)
{
@@ -385,7 +381,7 @@ void SamOEMhash( unsigned char *data, unsigned char *key, int val)
s_box[ind] = s_box[j];
s_box[j] = tc;
}
- for( ind = 0; ind < len; ind++)
+ for( ind = 0; ind < (val ? 516 : 16); ind++)
{
unsigned char tc;
unsigned char t;
@@ -401,16 +397,3 @@ void SamOEMhash( unsigned char *data, unsigned char *key, int val)
data[ind] = data[ind] ^ s_box[t];
}
}
-
-void sam_pwd_hash(uint32 rid, const uchar *in, uchar *out, int forw)
-{
- unsigned char s[14];
-
- s[0] = s[4] = s[8] = s[12] = (unsigned char)(rid & 0xFF);
- s[1] = s[5] = s[9] = s[13] = (unsigned char)((rid >> 8) & 0xFF);
- s[2] = s[6] = s[10] = (unsigned char)((rid >> 16) & 0xFF);
- s[3] = s[7] = s[11] = (unsigned char)((rid >> 24) & 0xFF);
-
- smbhash(out, in, s, forw);
- smbhash(out+8, in+8, s+7, forw);
-}
diff --git a/source3/libsmb/smbencrypt.c b/source3/libsmb/smbencrypt.c
index 34e6f43975..b927e193dd 100644
--- a/source3/libsmb/smbencrypt.c
+++ b/source3/libsmb/smbencrypt.c
@@ -24,39 +24,30 @@
extern int DEBUGLEVEL;
+#include "byteorder.h"
+
/*
This implements the X/Open SMB password encryption
It takes a password, a 8 byte "crypt key" and puts 24 bytes of
encrypted password into p24 */
-void SMBencrypt(uchar *pwrd, uchar *c8, uchar *p24)
+void SMBencrypt(uchar *passwd, uchar *c8, uchar *p24)
{
- uchar p21[21];
+ uchar p14[15], p21[21];
- lm_owf_gen(pwrd, p21);
- SMBOWFencrypt(p21, c8, p24);
+ memset(p21,'\0',21);
+ memset(p14,'\0',14);
+ StrnCpy((char *)p14,(char *)passwd,14);
-#ifdef DEBUG_PASSWORD
- DEBUG(100,("SMBencrypt: lm#, challenge, response\n"));
- dump_data(100, p21, 16);
- dump_data(100, c8, 8);
- dump_data(100, p24, 24);
-#endif
-}
+ strupper((char *)p14);
+ E_P16(p14, p21);
-void SMBNTencrypt(uchar *pwrd, uchar *c8, uchar *p24)
-{
- uchar p21[21];
-
- memset(p21,'\0',21);
-
- nt_owf_gen(pwrd, p21);
SMBOWFencrypt(p21, c8, p24);
#ifdef DEBUG_PASSWORD
- DEBUG(100,("SMBNTencrypt: nt#, challenge, response\n"));
- dump_data(100, p21, 16);
- dump_data(100, c8, 8);
- dump_data(100, p24, 24);
+ DEBUG(100,("SMBencrypt: lm#, challenge, response\n"));
+ dump_data(100, (char *)p21, 16);
+ dump_data(100, (char *)c8, 8);
+ dump_data(100, (char *)p24, 24);
#endif
}
@@ -76,23 +67,7 @@ static int _my_wcslen(int16 *str)
* format.
*/
-static int _my_mbstowcsupper(int16 *dst, const uchar *src, int len)
-{
- int i;
- int16 val;
-
- for(i = 0; i < len; i++) {
- val = toupper(*src);
- SSVAL(dst,0,val);
- dst++;
- src++;
- if(val == 0)
- break;
- }
- return i;
-}
-
-static int _my_mbstowcs(int16 *dst, const uchar *src, int len)
+static int _my_mbstowcs(int16 *dst, uchar *src, int len)
{
int i;
int16 val;
@@ -112,17 +87,17 @@ static int _my_mbstowcs(int16 *dst, const uchar *src, int len)
* Creates the MD4 Hash of the users password in NT UNICODE.
*/
-void E_md4hash(uchar *pwrd, uchar *p16)
+void E_md4hash(uchar *passwd, uchar *p16)
{
int len;
int16 wpwd[129];
/* Password cannot be longer than 128 characters */
- len = strlen((char *)pwrd);
+ len = strlen((char *)passwd);
if(len > 128)
len = 128;
/* Password must be converted to NT unicode */
- _my_mbstowcs(wpwd, pwrd, len);
+ _my_mbstowcs(wpwd, passwd, len);
wpwd[len] = 0; /* Ensure string is null terminated */
/* Calculate length in bytes */
len = _my_wcslen(wpwd) * sizeof(int16);
@@ -130,289 +105,98 @@ void E_md4hash(uchar *pwrd, uchar *p16)
mdfour(p16, (unsigned char *)wpwd, len);
}
-/* Does the LM owf of a user's password */
-void lm_owf_genW(const UNISTR2 *pwd, uchar p16[16])
+/* Does both the NT and LM owfs of a user's password */
+void nt_lm_owf_gen(char *pwd, uchar nt_p16[16], uchar p16[16])
{
- char pwrd[15];
-
- memset(pwrd,'\0',15);
- if (pwd != NULL)
- {
- unistr2_to_ascii( pwrd, pwd, sizeof(pwrd)-1);
- }
+ char passwd[130];
- /* Mangle the passwords into Lanman format */
- pwrd[14] = '\0';
- strupper(pwrd);
-
- /* Calculate the SMB (lanman) hash functions of the password */
+ memset(passwd,'\0',130);
+ safe_strcpy( passwd, pwd, sizeof(passwd)-1);
- memset(p16, '\0', 16);
- E_P16((uchar *) pwrd, (uchar *)p16);
+ /* Calculate the MD4 hash (NT compatible) of the password */
+ memset(nt_p16, '\0', 16);
+ E_md4hash((uchar *)passwd, nt_p16);
#ifdef DEBUG_PASSWORD
- DEBUG(100,("nt_lm_owf_gen: pwd, lm#\n"));
- dump_data(120, pwrd, strlen(pwrd));
- dump_data(100, p16, 16);
+ DEBUG(100,("nt_lm_owf_gen: pwd, nt#\n"));
+ dump_data(120, passwd, strlen(passwd));
+ dump_data(100, (char *)nt_p16, 16);
#endif
- /* clear out local copy of user's password (just being paranoid). */
- bzero(pwrd, sizeof(pwrd));
-}
-
-/* Does the LM owf of a user's password */
-void lm_owf_gen(const char *pwd, uchar p16[16])
-{
- char pwrd[15];
-
- memset(pwrd,'\0',15);
- if (pwd != NULL)
- {
- safe_strcpy( pwrd, pwd, sizeof(pwrd)-1);
- }
/* Mangle the passwords into Lanman format */
- pwrd[14] = '\0';
- strupper(pwrd);
+ passwd[14] = '\0';
+ strupper(passwd);
/* Calculate the SMB (lanman) hash functions of the password */
memset(p16, '\0', 16);
- E_P16((uchar *) pwrd, (uchar *)p16);
+ E_P16((uchar *) passwd, (uchar *)p16);
#ifdef DEBUG_PASSWORD
DEBUG(100,("nt_lm_owf_gen: pwd, lm#\n"));
- dump_data(120, pwrd, strlen(pwrd));
- dump_data(100, p16, 16);
-#endif
- /* clear out local copy of user's password (just being paranoid). */
- bzero(pwrd, sizeof(pwrd));
-}
-
-/* Does both the NT and LM owfs of a user's password */
-void nt_owf_genW(const UNISTR2 *pwd, uchar nt_p16[16])
-{
- UNISTR2 pwrd;
-
- memset(&pwrd,'\0',sizeof(pwrd));
- if (pwd != NULL)
- {
- copy_unistr2(&pwrd, pwd);
- }
-
- /* Calculate the MD4 hash (NT compatible) of the password */
- memset(nt_p16, '\0', 16);
- mdfour(nt_p16, (unsigned char *)pwrd.buffer, pwrd.uni_str_len * 2);
-
-#ifdef DEBUG_PASSWORD
- DEBUG(100,("nt_owf_gen: pwd, nt#\n"));
- dump_data(120, (const char*)pwrd.buffer, pwrd.uni_str_len * 2);
- dump_data(100, nt_p16, 16);
-#endif
- /* clear out local copy of user's password (just being paranoid). */
- memset(&pwrd, 0, sizeof(pwrd));
-}
-
-/* Does both the NT and LM owfs of a user's password */
-void nt_owf_gen(const char *pwd, uchar nt_p16[16])
-{
- char pwrd[130];
-
- memset(pwrd,'\0',130);
- if (pwd != NULL)
- {
- safe_strcpy( pwrd, pwd, sizeof(pwrd)-1);
- }
-
- /* Calculate the MD4 hash (NT compatible) of the password */
- memset(nt_p16, '\0', 16);
- E_md4hash((uchar *)pwrd, nt_p16);
-
-#ifdef DEBUG_PASSWORD
- DEBUG(100,("nt_owf_gen: pwd, nt#\n"));
- dump_data(120, pwrd, strlen(pwrd));
- dump_data(100, nt_p16, 16);
+ dump_data(120, passwd, strlen(passwd));
+ dump_data(100, (char *)p16, 16);
#endif
/* clear out local copy of user's password (just being paranoid). */
- bzero(pwrd, sizeof(pwrd));
-}
-
-/* Does both the NT and LM owfs of a user's UNICODE password */
-void nt_lm_owf_genW(const UNISTR2 *pwd, uchar nt_p16[16], uchar lm_p16[16])
-{
- nt_owf_genW(pwd, nt_p16);
- lm_owf_genW(pwd, lm_p16);
-}
-
-/* Does both the NT and LM owfs of a user's password */
-void nt_lm_owf_gen(const char *pwd, uchar nt_p16[16], uchar lm_p16[16])
-{
- nt_owf_gen(pwd, nt_p16);
- lm_owf_gen(pwd, lm_p16);
+ memset(passwd, '\0', sizeof(passwd));
}
/* Does the des encryption from the NT or LM MD4 hash. */
-void SMBOWFencrypt(uchar pwrd[16], uchar *c8, uchar p24[24])
+void SMBOWFencrypt(uchar passwd[16], uchar *c8, uchar p24[24])
{
uchar p21[21];
memset(p21,'\0',21);
- memcpy(p21, pwrd, 16);
+ memcpy(p21, passwd, 16);
E_P24(p21, c8, p24);
}
-void SMBOWFencrypt_ntv2(const uchar kr[16],
- const uchar *srv_chal, int srv_chal_len,
- const uchar *cli_chal, int cli_chal_len,
- char resp_buf[16])
-{
- HMACMD5Context ctx;
-
- hmac_md5_init_limK_to_64(kr, 16, &ctx);
- hmac_md5_update(srv_chal, srv_chal_len, &ctx);
- hmac_md5_update(cli_chal, cli_chal_len, &ctx);
- hmac_md5_final(resp_buf, &ctx);
-
-#ifdef DEBUG_PASSWORD
- DEBUG(100,("SMBOWFencrypt_ntv2: srv_chal, cli_chal, resp_buf\n"));
- dump_data(100, srv_chal, srv_chal_len);
- dump_data(100, cli_chal, cli_chal_len);
- dump_data(100, resp_buf, 16);
-#endif
-}
-
-void SMBsesskeygen_ntv2(const uchar kr[16],
- const uchar *nt_resp,
- char sess_key[16])
-{
- HMACMD5Context ctx;
-
- hmac_md5_init_limK_to_64(kr, 16, &ctx);
- hmac_md5_update(nt_resp, 16, &ctx);
- hmac_md5_final(sess_key, &ctx);
-
-#ifdef DEBUG_PASSWORD
- DEBUG(100,("SMBsesskeygen_ntv2:\n"));
- dump_data(100, sess_key, 16);
-#endif
-}
-
-void SMBsesskeygen_ntv1(const uchar kr[16],
- const uchar *nt_resp,
- char sess_key[16])
+/* Does the des encryption from the FIRST 8 BYTES of the NT or LM MD4 hash. */
+void NTLMSSPOWFencrypt(uchar passwd[8], uchar *ntlmchalresp, uchar p24[24])
{
- mdfour(sess_key, kr, 16);
+ uchar p21[21];
+
+ memset(p21,'\0',21);
+ memcpy(p21, passwd, 8);
+ memset(p21 + 8, 0xbd, 8);
+ E_P24(p21, ntlmchalresp, p24);
#ifdef DEBUG_PASSWORD
- DEBUG(100,("SMBsesskeygen_ntv2:\n"));
- dump_data(100, sess_key, 16);
+ DEBUG(100,("NTLMSSPOWFencrypt: p21, c8, p24\n"));
+ dump_data(100, (char *)p21, 21);
+ dump_data(100, (char *)ntlmchalresp, 8);
+ dump_data(100, (char *)p24, 24);
#endif
}
-void SMBgenclientchals(char *lm_cli_chal,
- char *nt_cli_chal, int *nt_cli_chal_len,
- const char *srv, const char *dom)
-{
- NTTIME nt_time;
- int srv_len = strlen(srv);
- int dom_len = strlen(dom);
- fstring server;
- fstring domain;
- fstrcpy(server, srv);
- fstrcpy(domain, dom);
- strupper(server);
- strupper(domain);
-
- generate_random_buffer(lm_cli_chal, 8, False);
- unix_to_nt_time(&nt_time, time(NULL));
-
- CVAL(nt_cli_chal,0) = 0x1;
- CVAL(nt_cli_chal,1) = 0x1;
- SSVAL(nt_cli_chal, 2, 0x0);
- SIVAL(nt_cli_chal, 4, 0x0);
- SIVAL(nt_cli_chal, 8, nt_time.low);
- SIVAL(nt_cli_chal, 12, nt_time.high);
- memcpy(nt_cli_chal+16, lm_cli_chal, 8);
- /* fill in offset 24, size of structure, later */
-
- *nt_cli_chal_len = 28;
-
- SSVAL(nt_cli_chal, *nt_cli_chal_len, 2);
- *nt_cli_chal_len += 2;
- SSVAL(nt_cli_chal, *nt_cli_chal_len, dom_len*2);
- *nt_cli_chal_len += 2;
- ascii_to_unibuf(nt_cli_chal+(*nt_cli_chal_len), domain, dom_len*2);
- *nt_cli_chal_len += dom_len*2;
- *nt_cli_chal_len += 4 - ((*nt_cli_chal_len) % 4);
-
- SSVAL(nt_cli_chal, *nt_cli_chal_len, 2);
- *nt_cli_chal_len += 2;
- SSVAL(nt_cli_chal, 30, srv_len*2);
- *nt_cli_chal_len += 2;
- ascii_to_unibuf(nt_cli_chal+(*nt_cli_chal_len), server, srv_len*2);
- *nt_cli_chal_len += srv_len*2;
-
- SSVAL(nt_cli_chal, 24, (*nt_cli_chal_len)+16);
- SSVAL(nt_cli_chal, 26, (*nt_cli_chal_len)+15);
-
- DEBUG(100,("SMBgenclientchals: srv %s, dom %s\n", server, domain));
- dump_data(100, nt_cli_chal, *nt_cli_chal_len);
-}
-
-void ntv2_owf_gen(const uchar owf[16],
- const char *user_n,
- const char *domain_n,
- uchar kr_buf[16])
-{
- pstring user_u;
- pstring dom_u;
- HMACMD5Context ctx;
-
- int user_l = strlen(user_n );
- int domain_l = strlen(domain_n);
-
- _my_mbstowcsupper((int16*)user_u, user_n , user_l*2 );
- _my_mbstowcsupper((int16*)dom_u , domain_n, domain_l*2);
-
- hmac_md5_init_limK_to_64(owf, 16, &ctx);
- hmac_md5_update(user_u, user_l*2, &ctx);
- hmac_md5_update(dom_u, domain_l*2, &ctx);
- hmac_md5_final(kr_buf, &ctx);
-#ifdef DEBUG_PASSWORD
- DEBUG(100,("ntv2_owf_gen: user, domain, owfkey, kr\n"));
- dump_data(100, user_u, user_l*2);
- dump_data(100, dom_u, domain_l*2);
- dump_data(100, owf, 16);
- dump_data(100, kr_buf, 16);
-#endif
-}
-
-/* Does the des encryption from the FIRST 8 BYTES of the NT or LM MD4 hash. */
-void NTLMSSPOWFencrypt(uchar pwrd[8], uchar *ntlmchalresp, uchar p24[24])
+/* Does the NT MD4 hash then des encryption. */
+
+void SMBNTencrypt(uchar *passwd, uchar *c8, uchar *p24)
{
uchar p21[21];
memset(p21,'\0',21);
- memcpy(p21, pwrd, 8);
- memset(p21 + 8, 0xbd, 8);
+
+ E_md4hash(passwd, p21);
+ SMBOWFencrypt(p21, c8, p24);
- E_P24(p21, ntlmchalresp, p24);
#ifdef DEBUG_PASSWORD
- DEBUG(100,("NTLMSSPOWFencrypt: p21, c8, p24\n"));
- dump_data(100, p21, 21);
- dump_data(100, ntlmchalresp, 8);
- dump_data(100, p24, 24);
+ DEBUG(100,("SMBNTencrypt: nt#, challenge, response\n"));
+ dump_data(100, (char *)p21, 16);
+ dump_data(100, (char *)c8, 8);
+ dump_data(100, (char *)p24, 24);
#endif
}
-BOOL make_oem_passwd_hash(char data[516], const char *pwrd, uchar old_pw_hash[16], BOOL unicode)
+BOOL make_oem_passwd_hash(char data[516], const char *passwd, uchar old_pw_hash[16], BOOL unicode)
{
- int new_pw_len = strlen(pwrd) * (unicode ? 2 : 1);
+ int new_pw_len = strlen(passwd) * (unicode ? 2 : 1);
if (new_pw_len > 512)
{
- DEBUG(0,("make_oem_pwrd_hash: new password is too long.\n"));
+ DEBUG(0,("make_oem_passwd_hash: new password is too long.\n"));
return False;
}
@@ -425,16 +209,18 @@ BOOL make_oem_passwd_hash(char data[516], const char *pwrd, uchar old_pw_hash[16
generate_random_buffer((unsigned char *)data, 516, False);
if (unicode)
{
- ascii_to_unibuf(&data[512 - new_pw_len], pwrd, new_pw_len);
+ /* Note that passwd should be in DOS oem character set. */
+ dos_struni2( &data[512 - new_pw_len], passwd, 512);
}
else
{
- fstrcpy( &data[512 - new_pw_len], pwrd);
+ /* Note that passwd should be in DOS oem character set. */
+ fstrcpy( &data[512 - new_pw_len], passwd);
}
SIVAL(data, 512, new_pw_len);
#ifdef DEBUG_PASSWORD
- DEBUG(100,("make_oem_pwrd_hash\n"));
+ DEBUG(100,("make_oem_passwd_hash\n"));
dump_data(100, data, 516);
#endif
SamOEMhash( (unsigned char *)data, (unsigned char *)old_pw_hash, True);
@@ -442,138 +228,3 @@ BOOL make_oem_passwd_hash(char data[516], const char *pwrd, uchar old_pw_hash[16
return True;
}
-BOOL nt_decrypt_string2(STRING2 *out, const STRING2 *in, const uchar *key)
-{
- uchar bufhdr[8];
- int datalen;
-
- const uchar *keyptr = key;
- const uchar *keyend = key + 16;
-
- uchar *outbuf = (uchar *)out->buffer;
- const uchar *inbuf = (const uchar *)in->buffer;
- const uchar *inbufend;
-
- smbhash(bufhdr, inbuf, keyptr, 0);
- datalen = IVAL(bufhdr, 0);
-
- if ((datalen > in->str_str_len) || (datalen > MAX_STRINGLEN))
- {
- DEBUG(0, ("nt_decrypt_string2: failed\n"));
- return False;
- }
-
- out->str_max_len = out->str_str_len = datalen;
- inbuf += 8;
- inbufend = inbuf + datalen;
-
- while (inbuf < inbufend)
- {
- keyptr += 7;
- if (keyptr + 7 > keyend)
- {
- keyptr = (keyend - keyptr) + key;
- }
-
- smbhash(outbuf, inbuf, keyptr, 0);
-
- inbuf += 8;
- outbuf += 8;
- }
-
- return True;
-}
-
-/*******************************************************************
- creates a DCE/RPC bind authentication response
-
- - initialises the parse structure.
- - dynamically allocates the header data structure
- - caller is expected to free the header data structure once used.
-
- ********************************************************************/
-void create_ntlmssp_resp(struct pwd_info *pwd,
- char *domain, char *user_name, char *my_name,
- uint32 ntlmssp_cli_flgs,
- prs_struct *auth_resp)
-{
- RPC_AUTH_NTLMSSP_RESP ntlmssp_resp;
- unsigned char lm_owf[24];
- unsigned char nt_owf[128];
- size_t nt_owf_len;
-
- pwd_get_lm_nt_owf(pwd, lm_owf, nt_owf, &nt_owf_len, NULL);
-
- make_rpc_auth_ntlmssp_resp(&ntlmssp_resp,
- lm_owf, nt_owf, nt_owf_len,
- domain, user_name, my_name,
- ntlmssp_cli_flgs);
-
- smb_io_rpc_auth_ntlmssp_resp("ntlmssp_resp", &ntlmssp_resp, auth_resp, 0);
- mem_realloc_data(auth_resp->data, auth_resp->offset);
-}
-
-/***********************************************************
- decode a password buffer
-************************************************************/
-BOOL decode_pw_buffer(const char buffer[516], char *new_pwrd,
- int new_pwrd_size, uint32 *new_pw_len)
-{
- /*
- * The length of the new password is in the last 4 bytes of
- * the data buffer.
- */
-
- (*new_pw_len) = IVAL(buffer, 512);
-
-#ifdef DEBUG_PASSWORD
- dump_data(100, buffer, 516);
-#endif
-
- if ((*new_pw_len) < 0 || (*new_pw_len) > new_pwrd_size - 1)
- {
- DEBUG(0,("check_oem_password: incorrect password length (%d).\n", (*new_pw_len)));
- return False;
- }
-
- memcpy(new_pwrd, &buffer[512-(*new_pw_len)], (*new_pw_len));
- new_pwrd[(*new_pw_len)] = '\0';
-
- return True;
-}
-
-/***********************************************************
- encode a password buffer
-************************************************************/
-BOOL encode_pw_buffer(char buffer[516], const char *new_pass,
- int new_pw_len, BOOL nt_pass_set)
-{
- generate_random_buffer(buffer, 516, True);
-
- if (nt_pass_set)
- {
- /*
- * nt passwords are in unicode. last char overwrites NULL
- * in ascii_to_unibuf, so use SIVAL *afterwards*.
- */
- new_pw_len *= 2;
- ascii_to_unibuf(&buffer[512-new_pw_len], new_pass, new_pw_len);
- }
- else
- {
- memcpy(&buffer[512-new_pw_len], new_pass, new_pw_len);
- }
-
- /*
- * The length of the new password is in the last 4 bytes of
- * the data buffer.
- */
-
- SIVAL(buffer, 512, new_pw_len);
-
-#ifdef DEBUG_PASSWORD
- dump_data(100, buffer, 516);
-#endif
-
- return True;
-}
diff --git a/source3/libsmb/smberr.c b/source3/libsmb/smberr.c
index 228eee5892..c2d8884d73 100644
--- a/source3/libsmb/smberr.c
+++ b/source3/libsmb/smberr.c
@@ -143,70 +143,39 @@ struct
{0xFF,"ERRCMD",NULL},
{-1,NULL,NULL}};
-char *smb_err_msg(uint8 class, uint32 num)
-{
- static pstring ret;
- smb_safe_err_msg(class, num, ret, sizeof(ret));
- return ret;
-}
-
/****************************************************************************
return a SMB error string from a SMB buffer
****************************************************************************/
-BOOL smb_safe_err_msg(uint8 class, uint32 num, char *ret, size_t len)
+char *smb_errstr(char *inbuf)
{
- int i,j;
-
- for (i=0;err_classes[i].class;i++)
- {
- if (err_classes[i].code == class)
+ static pstring ret;
+ int class = CVAL(inbuf,smb_rcls);
+ int num = SVAL(inbuf,smb_err);
+ int i,j;
+
+ for (i=0;err_classes[i].class;i++)
+ if (err_classes[i].code == class)
+ {
+ if (err_classes[i].err_msgs)
+ {
+ err_code_struct *err = err_classes[i].err_msgs;
+ for (j=0;err[j].name;j++)
+ if (num == err[j].code)
{
- err_code_struct *err = err_classes[i].err_msgs;
- if (err != NULL)
- {
- for (j=0;err[j].name;j++)
- {
- if (num == err[j].code)
- {
- if (DEBUGLEVEL > 0)
- {
- slprintf(ret, len - 1, "%s - %s (%s)",err_classes[i].class,
- err[j].name,err[j].message);
- }
- else
- {
- slprintf(ret, len - 1, "%s - %s",err_classes[i].class,err[j].name);
- }
- return True;
- }
- }
- }
- slprintf(ret, len - 1, "%s - %d",err_classes[i].class, num);
- return True;
+ if (DEBUGLEVEL > 0)
+ slprintf(ret, sizeof(ret) - 1, "%s - %s (%s)",err_classes[i].class,
+ err[j].name,err[j].message);
+ else
+ slprintf(ret, sizeof(ret) - 1, "%s - %s",err_classes[i].class,err[j].name);
+ return ret;
}
+ }
- }
-
- slprintf(ret, len - 1, "Error: Unknown error (%d,%d)",class,num);
- return False;
-}
-
-/****************************************************************************
-return a SMB error string from a SMB buffer
-****************************************************************************/
-BOOL smb_safe_errstr(char *inbuf, char *msg, size_t len)
-{
- return smb_safe_err_msg(CVAL(inbuf,smb_rcls), SVAL(inbuf,smb_err),
- msg, len);
-}
-
-/****************************************************************************
-return a SMB error string from a SMB buffer
-****************************************************************************/
-char *smb_errstr(char *inbuf)
-{
- static fstring errmsg;
- (void)smb_safe_errstr(inbuf, errmsg, sizeof(errmsg));
- return errmsg;
+ slprintf(ret, sizeof(ret) - 1, "%s - %d",err_classes[i].class,num);
+ return ret;
+ }
+
+ slprintf(ret, sizeof(ret) - 1, "Error: Unknown error (%d,%d)",class,num);
+ return(ret);
}