summaryrefslogtreecommitdiff
path: root/source3/libsmb
diff options
context:
space:
mode:
authorJelmer Vernooij <jelmer@samba.org>2002-08-17 17:00:51 +0000
committerJelmer Vernooij <jelmer@samba.org>2002-08-17 17:00:51 +0000
commitb2edf254eda92f775e7d3d9b6793b4d77f9000b6 (patch)
tree18eb2564a769678c774a19bb07c00fc4aa7b2758 /source3/libsmb
parent669a39fae36f8bc60753c9b352556ef8ffaeb568 (diff)
downloadsamba-b2edf254eda92f775e7d3d9b6793b4d77f9000b6.tar.gz
samba-b2edf254eda92f775e7d3d9b6793b4d77f9000b6.tar.bz2
samba-b2edf254eda92f775e7d3d9b6793b4d77f9000b6.zip
sync 3.0 branch with head
(This used to be commit 3928578b52cfc949be5e0ef444fce1558d75f290)
Diffstat (limited to 'source3/libsmb')
-rw-r--r--source3/libsmb/cliconnect.c47
-rw-r--r--source3/libsmb/clispnego.c61
-rw-r--r--source3/libsmb/namequery.c67
-rw-r--r--source3/libsmb/smbencrypt.c16
-rw-r--r--source3/libsmb/trust_passwd.c2
5 files changed, 155 insertions, 38 deletions
diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c
index 472db69fd0..93cf3d95db 100644
--- a/source3/libsmb/cliconnect.c
+++ b/source3/libsmb/cliconnect.c
@@ -54,9 +54,6 @@ static BOOL cli_session_setup_lanman2(struct cli_state *cli, char *user,
return False;
}
- /* Lanman2 cannot use SMB signing. */
- cli->sign_info.use_smb_signing = False;
-
/* if in share level security then don't send a password now */
if (!(cli->sec_mode & NEGOTIATE_SECURITY_USER_LEVEL)) {
passlen = 0;
@@ -209,12 +206,11 @@ static BOOL cli_session_setup_plaintext(struct cli_state *cli, char *user,
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);
SSVAL(cli->outbuf,smb_vwv8,0);
SIVAL(cli->outbuf,smb_vwv11,capabilities);
p = smb_buf(cli->outbuf);
- memcpy(p, pword, passlen);
- p += passlen;
+ p += clistr_push(cli, p, pword, -1, STR_TERMINATE); /* password */
+ SSVAL(cli->outbuf,smb_vwv7,PTR_DIFF(p, smb_buf(cli->outbuf)));
p += clistr_push(cli, p, user, -1, STR_TERMINATE); /* username */
p += clistr_push(cli, p, workgroup, -1, STR_TERMINATE); /* workgroup */
p += clistr_push(cli, p, "Unix", -1, STR_TERMINATE);
@@ -257,11 +253,12 @@ static BOOL cli_session_setup_nt1(struct cli_state *cli, char *user,
char *workgroup)
{
uint32 capabilities = cli_session_setup_capabilities(cli);
- fstring pword, ntpword;
+ uchar pword[24];
+ uchar ntpword[24];
char *p;
BOOL tried_signing = False;
- if (passlen > sizeof(pword)-1 || ntpasslen > sizeof(ntpword)-1) {
+ if (passlen > sizeof(pword) || ntpasslen > sizeof(ntpword)) {
return False;
}
@@ -269,15 +266,21 @@ static BOOL cli_session_setup_nt1(struct cli_state *cli, char *user,
/* non encrypted password supplied. Ignore ntpass. */
passlen = 24;
ntpasslen = 24;
- SMBencrypt((uchar *)pass,cli->secblob.data,(uchar *)pword);
- SMBNTencrypt((uchar *)pass,cli->secblob.data,(uchar *)ntpword);
+ SMBencrypt(pass,cli->secblob.data,pword);
+ SMBNTencrypt(pass,cli->secblob.data,ntpword);
if (!cli->sign_info.use_smb_signing && cli->sign_info.negotiated_smb_signing) {
- cli_calculate_mac_key(cli, (uchar *)pass, (uchar *)ntpword);
+ cli_calculate_mac_key(cli, pass, ntpword);
tried_signing = True;
}
} else {
- memcpy(pword, pass, passlen);
- memcpy(ntpword, ntpass, ntpasslen);
+ /* pre-encrypted password supplied. Only used for security=server, can't do
+ signing becouse we don't have oringial key */
+ memcpy(pword, pass, 24);
+ if (ntpasslen == 24) {
+ memcpy(ntpword, ntpass, 24);
+ } else {
+ ZERO_STRUCT(ntpword);
+ }
}
/* send a session setup command */
@@ -305,8 +308,13 @@ static BOOL cli_session_setup_nt1(struct cli_state *cli, char *user,
cli_setup_bcc(cli, p);
cli_send_smb(cli);
- if (!cli_receive_smb(cli))
+ if (!cli_receive_smb(cli)) {
+ if (tried_signing) {
+ /* We only use it if we have a successful non-guest connect */
+ cli->sign_info.use_smb_signing = False;
+ }
return False;
+ }
show_msg(cli->inbuf);
@@ -482,8 +490,8 @@ static BOOL cli_session_setup_ntlmssp(struct cli_state *cli, char *user,
/* encrypt the password with the challenge */
memcpy(challenge, chal1.data + 24, 8);
- SMBencrypt((unsigned char *)pass, challenge,lmhash);
- SMBNTencrypt((unsigned char *)pass, challenge,nthash);
+ SMBencrypt(pass, challenge,lmhash);
+ SMBNTencrypt(pass, challenge,nthash);
#if 0
file_save("nthash.dat", nthash, 24);
@@ -1062,7 +1070,7 @@ BOOL cli_connect(struct cli_state *cli, const char *host, struct in_addr *ip)
}
if (cli->fd == -1) {
DEBUG(1,("Error connecting to %s (%s)\n",
- inet_ntoa(*ip),strerror(errno)));
+ ip?inet_ntoa(*ip):host,strerror(errno)));
return False;
}
@@ -1182,9 +1190,8 @@ again:
if (!cli_session_setup(cli, user, password, strlen(password)+1,
password, strlen(password)+1,
domain)) {
- if (!(flags & CLI_FULL_CONNECTION_ANNONYMOUS_FALLBACK)
- || cli_session_setup(cli, "", "", 0,
- "", 0, domain)) {
+ if ((flags & CLI_FULL_CONNECTION_ANNONYMOUS_FALLBACK)
+ && cli_session_setup(cli, "", "", 0, "", 0, domain)) {
} else {
nt_status = cli_nt_error(cli);
DEBUG(1,("failed session setup with %s\n", nt_errstr(nt_status)));
diff --git a/source3/libsmb/clispnego.c b/source3/libsmb/clispnego.c
index 469b946088..16702c375b 100644
--- a/source3/libsmb/clispnego.c
+++ b/source3/libsmb/clispnego.c
@@ -2,6 +2,7 @@
Unix SMB/CIFS implementation.
simple kerberos5/SPNEGO routines
Copyright (C) Andrew Tridgell 2001
+ Copyright (C) Jim McDonough 2002
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
@@ -439,6 +440,28 @@ BOOL spnego_parse_auth(DATA_BLOB blob, DATA_BLOB *auth)
return True;
}
+/*
+ generate a minimal SPNEGO NTLMSSP response packet. Doesn't contain much.
+*/
+DATA_BLOB spnego_gen_auth_response(void)
+{
+ ASN1_DATA data;
+ DATA_BLOB ret;
+
+ memset(&data, 0, sizeof(data));
+
+ asn1_push_tag(&data, ASN1_CONTEXT(1));
+ asn1_push_tag(&data, ASN1_SEQUENCE(0));
+ asn1_push_tag(&data, ASN1_CONTEXT(0));
+ asn1_write_enumerated(&data, 0);
+ asn1_pop_tag(&data);
+ asn1_pop_tag(&data);
+ asn1_pop_tag(&data);
+
+ ret = data_blob(data.data, data.length);
+ asn1_free(&data);
+ return ret;
+}
/*
this is a tiny msrpc packet generator. I am only using this to
@@ -449,6 +472,7 @@ BOOL spnego_parse_auth(DATA_BLOB blob, DATA_BLOB *auth)
format specifiers are:
U = unicode string (input is unix string)
+ a = address (1 byte type, 1 byte length, unicode string, all inline)
B = data blob (pointer + length)
b = data blob in header (pointer + length)
d = word (4 bytes)
@@ -473,6 +497,11 @@ BOOL msrpc_gen(DATA_BLOB *blob,
head_size += 8;
data_size += str_charnum(s) * 2;
break;
+ case 'a':
+ n = va_arg(ap, int);
+ s = va_arg(ap, char *);
+ data_size += (str_charnum(s) * 2) + 4;
+ break;
case 'B':
b = va_arg(ap, uint8 *);
head_size += 8;
@@ -512,6 +541,19 @@ BOOL msrpc_gen(DATA_BLOB *blob,
push_string(NULL, blob->data+data_ofs, s, n*2, STR_UNICODE|STR_NOALIGN);
data_ofs += n*2;
break;
+ case 'a':
+ n = va_arg(ap, int);
+ SSVAL(blob->data, data_ofs, n); data_ofs += 2;
+ s = va_arg(ap, char *);
+ n = str_charnum(s);
+ SSVAL(blob->data, data_ofs, n*2); data_ofs += 2;
+ if (0 < n) {
+ push_string(NULL, blob->data+data_ofs, s, n*2,
+ STR_UNICODE|STR_NOALIGN);
+ }
+ data_ofs += n*2;
+ break;
+
case 'B':
b = va_arg(ap, uint8 *);
n = va_arg(ap, int);
@@ -550,6 +592,7 @@ BOOL msrpc_gen(DATA_BLOB *blob,
format specifiers are:
U = unicode string (output is unix string)
+ A = ascii string
B = data blob
b = data blob in header
d = word (4 bytes)
@@ -584,6 +627,24 @@ BOOL msrpc_parse(DATA_BLOB *blob,
STR_UNICODE|STR_NOALIGN);
(*ps) = strdup(p);
break;
+ case 'A':
+ len1 = SVAL(blob->data, head_ofs); head_ofs += 2;
+ len2 = SVAL(blob->data, head_ofs); head_ofs += 2;
+ ptr = IVAL(blob->data, head_ofs); head_ofs += 4;
+
+ /* make sure its in the right format - be strict */
+ if (len1 != len2 || ptr + len1 > blob->length) {
+ return False;
+ }
+ ps = va_arg(ap, char **);
+ if (0 < len1) {
+ pull_string(NULL, p, blob->data + ptr, -1,
+ len1, STR_ASCII|STR_NOALIGN);
+ (*ps) = strdup(p);
+ } else {
+ (*ps) = NULL;
+ }
+ break;
case 'B':
len1 = SVAL(blob->data, head_ofs); head_ofs += 2;
len2 = SVAL(blob->data, head_ofs); head_ofs += 2;
diff --git a/source3/libsmb/namequery.c b/source3/libsmb/namequery.c
index 18564bccf4..40a353fa8b 100644
--- a/source3/libsmb/namequery.c
+++ b/source3/libsmb/namequery.c
@@ -170,6 +170,11 @@ BOOL name_status_find(const char *q_name, int q_type, int type, struct in_addr t
int sock;
BOOL result = False;
+ if (lp_disable_netbios()) {
+ DEBUG(5,("name_status_find(%s#%02x): netbios is disabled\n", q_name, q_type));
+ return False;
+ }
+
DEBUG(10, ("name_status_find: looking up %s#%02x at %s\n", q_name,
q_type, inet_ntoa(to_ip)));
@@ -191,7 +196,7 @@ BOOL name_status_find(const char *q_name, int q_type, int type, struct in_addr t
if (i == count)
goto done;
- pull_ascii(name, status[i].name, 15, -1, STR_TERMINATE);
+ pull_ascii(name, status[i].name, 16, 15, STR_TERMINATE);
result = True;
done:
@@ -211,7 +216,7 @@ BOOL name_status_find(const char *q_name, int q_type, int type, struct in_addr t
/*
comparison function used by sort_ip_list
*/
-static int ip_compare(struct in_addr *ip1, struct in_addr *ip2)
+int ip_compare(struct in_addr *ip1, struct in_addr *ip2)
{
int max_bits1=0, max_bits2=0;
int num_interfaces = iface_count();
@@ -273,6 +278,11 @@ struct in_addr *name_query(int fd,const char *name,int name_type,
struct nmb_packet *nmb = &p.packet.nmb;
struct in_addr *ip_list = NULL;
+ if (lp_disable_netbios()) {
+ DEBUG(5,("name_query(%s#%02x): netbios is disabled\n", name, name_type));
+ return NULL;
+ }
+
if (timed_out) {
*timed_out = False;
}
@@ -556,6 +566,11 @@ BOOL name_resolve_bcast(const char *name, int name_type,
int sock, i;
int num_interfaces = iface_count();
+ if (lp_disable_netbios()) {
+ DEBUG(5,("name_resolve_bcast(%s#%02x): netbios is disabled\n", name, name_type));
+ return False;
+ }
+
*return_ip_list = NULL;
*return_count = 0;
@@ -602,6 +617,11 @@ BOOL resolve_wins(const char *name, int name_type,
char **wins_tags;
struct in_addr src_ip;
+ if (lp_disable_netbios()) {
+ DEBUG(5,("resolve_wins(%s#%02x): netbios is disabled\n", name, name_type));
+ return False;
+ }
+
*return_iplist = NULL;
*return_count = 0;
@@ -763,7 +783,7 @@ static BOOL resolve_hosts(const char *name,
*********************************************************/
static BOOL internal_resolve_name(const char *name, int name_type,
- struct in_addr **return_iplist, int *return_count)
+ struct in_addr **return_iplist, int *return_count)
{
pstring name_resolve_list;
fstring tok;
@@ -796,6 +816,15 @@ static BOOL internal_resolve_name(const char *name, int name_type,
return True;
}
+ /* Check netbios name cache */
+
+ if (namecache_fetch(name, name_type, return_iplist, return_count)) {
+
+ /* This could be a negative response */
+
+ return (*return_count > 0);
+ }
+
pstrcpy(name_resolve_list, lp_name_resolve_order());
ptr = name_resolve_list;
if (!ptr || !*ptr)
@@ -803,9 +832,16 @@ static BOOL internal_resolve_name(const char *name, int name_type,
while (next_token(&ptr, tok, LIST_SEP, sizeof(tok))) {
if((strequal(tok, "host") || strequal(tok, "hosts"))) {
- if (name_type == 0x20 && resolve_hosts(name, return_iplist, return_count)) {
- result = True;
- goto done;
+ if (name_type == 0x20) {
+ if (resolve_hosts(name, return_iplist, return_count)) {
+ result = True;
+ goto done;
+ } else {
+
+ /* Store negative lookup result */
+
+ namecache_store(name, name_type, 0, NULL);
+ }
}
} else if(strequal( tok, "lmhosts")) {
if (resolve_lmhosts(name, name_type, return_iplist, return_count)) {
@@ -877,6 +913,10 @@ static BOOL internal_resolve_name(const char *name, int name_type,
*return_iplist = nodupes_iplist;
*return_count = nodupes_count;
}
+
+ /* Save in name cache */
+
+ namecache_store(name, name_type, *return_count, *return_iplist);
/* Display some debugging info */
@@ -930,11 +970,16 @@ BOOL resolve_name(const char *name, struct in_addr *return_ip, int name_type)
Find the IP address of the master browser or DMB for a workgroup.
*********************************************************/
-BOOL find_master_ip(char *group, struct in_addr *master_ip)
+BOOL find_master_ip(const char *group, struct in_addr *master_ip)
{
struct in_addr *ip_list = NULL;
int count = 0;
+ if (lp_disable_netbios()) {
+ DEBUG(5,("find_master_ip(%s): netbios is disabled\n", group));
+ return False;
+ }
+
if (internal_resolve_name(group, 0x1D, &ip_list, &count)) {
*master_ip = ip_list[0];
SAFE_FREE(ip_list);
@@ -957,10 +1002,14 @@ BOOL find_master_ip(char *group, struct in_addr *master_ip)
BOOL lookup_dc_name(const char *srcname, const char *domain,
struct in_addr *dc_ip, char *ret_name)
{
-#if !defined(I_HATE_WINDOWS_REPLY_CODE)
-
+#if !defined(I_HATE_WINDOWS_REPLY_CODE)
fstring dc_name;
BOOL ret;
+
+ if (lp_disable_netbios()) {
+ DEBUG(5,("lookup_dc_name(%s): netbios is disabled\n", domain));
+ return False;
+ }
/*
* Due to the fact win WinNT *sucks* we must do a node status
diff --git a/source3/libsmb/smbencrypt.c b/source3/libsmb/smbencrypt.c
index 95434d0ae4..dfa355a7ec 100644
--- a/source3/libsmb/smbencrypt.c
+++ b/source3/libsmb/smbencrypt.c
@@ -28,7 +28,7 @@
This implements the X/Open SMB password encryption
It takes a password ('unix' string), a 8 byte "crypt key"
and puts 24 bytes of encrypted password into p24 */
-void SMBencrypt(const char *passwd, const uchar *c8, uchar *p24)
+void SMBencrypt(const char *passwd, const uchar *c8, uchar p24[24])
{
uchar p21[21];
@@ -66,9 +66,9 @@ void E_md4hash(const char *passwd, uchar p16[16])
}
/**
- * Creates the MD4 Hash of the users password in NT UNICODE.
+ * Creates the DES forward-only Hash of the users password in DOS ASCII charset
* @param passwd password in 'unix' charset.
- * @param p16 return password hashed with md4, caller allocated 16 byte buffer
+ * @param p16 return password hashed with DES, caller allocated 16 byte buffer
*/
void E_deshash(const char *passwd, uchar p16[16])
@@ -77,7 +77,7 @@ void E_deshash(const char *passwd, uchar p16[16])
ZERO_STRUCT(dospwd);
ZERO_STRUCTP(p16);
- /* Password must be converted to DOS charset - null terminated. */
+ /* Password must be converted to DOS charset - null terminated, uppercase. */
push_ascii(dospwd, (const char *)passwd, sizeof(dospwd), STR_UPPER|STR_TERMINATE);
E_P16(dospwd, p16);
@@ -175,7 +175,7 @@ void NTLMSSPOWFencrypt(const uchar passwd[8], const uchar *ntlmchalresp, uchar p
/* Does the NT MD4 hash then des encryption. */
-void SMBNTencrypt(const uchar *passwd, uchar *c8, uchar *p24)
+void SMBNTencrypt(const char *passwd, uchar *c8, uchar *p24)
{
uchar p21[21];
@@ -226,14 +226,14 @@ BOOL make_oem_passwd_hash(char data[516], const char *passwd, uchar old_pw_hash[
void SMBOWFencrypt_ntv2(const uchar kr[16],
const DATA_BLOB srv_chal,
const DATA_BLOB cli_chal,
- char resp_buf[16])
+ uchar resp_buf[16])
{
HMACMD5Context ctx;
hmac_md5_init_limK_to_64(kr, 16, &ctx);
hmac_md5_update(srv_chal.data, srv_chal.length, &ctx);
hmac_md5_update(cli_chal.data, cli_chal.length, &ctx);
- hmac_md5_final((unsigned char *)resp_buf, &ctx);
+ hmac_md5_final(resp_buf, &ctx);
#ifdef DEBUG_PASSWORD
DEBUG(100, ("SMBOWFencrypt_ntv2: srv_chal, cli_chal, resp_buf\n"));
@@ -337,7 +337,7 @@ BOOL decode_pw_buffer(char in_buffer[516], char *new_pwrd,
SMB signing - setup the MAC key.
************************************************************/
-void cli_calculate_mac_key(struct cli_state *cli, const unsigned char *ntpasswd, const uchar resp[24])
+void cli_calculate_mac_key(struct cli_state *cli, const char *ntpasswd, const uchar resp[24])
{
/* Get first 16 bytes. */
E_md4hash(ntpasswd,&cli->sign_info.mac_key[0]);
diff --git a/source3/libsmb/trust_passwd.c b/source3/libsmb/trust_passwd.c
index 3b77f7330e..fe6b673e39 100644
--- a/source3/libsmb/trust_passwd.c
+++ b/source3/libsmb/trust_passwd.c
@@ -35,7 +35,7 @@ static NTSTATUS just_change_the_password(struct cli_state *cli, TALLOC_CTX *mem_
unsigned char new_trust_passwd_hash[16])
{
NTSTATUS result;
- result = new_cli_nt_setup_creds(cli, (lp_server_role() == ROLE_DOMAIN_MEMBER) ?
+ result = cli_nt_setup_creds(cli, (lp_server_role() == ROLE_DOMAIN_MEMBER) ?
SEC_CHAN_WKSTA : SEC_CHAN_BDC, orig_trust_passwd_hash);
if (!NT_STATUS_IS_OK(result)) {