From 9f7cb41f11c0d2fc09104f6998f75c59bc363b26 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 12 Oct 2001 04:49:42 +0000 Subject: added NTLMSSP authentication to libsmb. It seems to work well so I have enabled it by default if the server supports it. Let me know if this breaks anything. Choose kerberos with the -k flag to smbclient, otherwise it will use SPNEGO/NTLMSSP/NTLM (This used to be commit 076aa97bee54d182288d9e93ae160ae22a5f7757) --- source3/libsmb/clispnego.c | 395 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 395 insertions(+) create mode 100644 source3/libsmb/clispnego.c (limited to 'source3/libsmb/clispnego.c') diff --git a/source3/libsmb/clispnego.c b/source3/libsmb/clispnego.c new file mode 100644 index 0000000000..6c6b18a923 --- /dev/null +++ b/source3/libsmb/clispnego.c @@ -0,0 +1,395 @@ +/* + Unix SMB/Netbios implementation. + Version 3.0 + simple kerberos5/SPNEGO routines + Copyright (C) Andrew Tridgell 2001 + + 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 + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +*/ + +#include "includes.h" + +#define OID_SPNEGO "1 3 6 1 5 5 2" +#define OID_KERBEROS5 "1 2 840 113554 1 2 2" + +/* + generate a negTokenInit packet given a GUID, a list of supported + OIDs (the mechanisms) and a principle name string +*/ +ASN1_DATA spnego_gen_negTokenInit(uint8 guid[16], + const char *OIDs[], + const char *principle) +{ + int i; + ASN1_DATA data; + + memset(&data, 0, sizeof(data)); + + asn1_write(&data, guid, 16); + asn1_push_tag(&data,ASN1_APPLICATION(0)); + asn1_write_OID(&data,OID_SPNEGO); + asn1_push_tag(&data,ASN1_CONTEXT(0)); + asn1_push_tag(&data,ASN1_SEQUENCE(0)); + + asn1_push_tag(&data,ASN1_CONTEXT(0)); + asn1_push_tag(&data,ASN1_SEQUENCE(0)); + for (i=0; OIDs[i]; i++) { + asn1_write_OID(&data,OIDs[i]); + } + asn1_pop_tag(&data); + asn1_pop_tag(&data); + + asn1_push_tag(&data, ASN1_CONTEXT(3)); + asn1_push_tag(&data, ASN1_SEQUENCE(0)); + asn1_push_tag(&data, ASN1_CONTEXT(0)); + asn1_write_GeneralString(&data,principle); + asn1_pop_tag(&data); + asn1_pop_tag(&data); + asn1_pop_tag(&data); + + asn1_pop_tag(&data); + asn1_pop_tag(&data); + + asn1_pop_tag(&data); + + if (data.has_error) { + DEBUG(1,("Failed to build negTokenInit at offset %d\n", (int)data.ofs)); + asn1_free(&data); + } + + return data; +} + + +/* + parse a negTokenInit packet giving a GUID, a list of supported + OIDs (the mechanisms) and a principle name string +*/ +BOOL spnego_parse_negTokenInit(DATA_BLOB blob, + uint8 guid[16], + char *OIDs[ASN1_MAX_OIDS], + char **principle) +{ + int i; + BOOL ret; + ASN1_DATA data; + + asn1_load(&data, blob); + + asn1_read(&data, guid, 16); + asn1_start_tag(&data,ASN1_APPLICATION(0)); + asn1_check_OID(&data,OID_SPNEGO); + asn1_start_tag(&data,ASN1_CONTEXT(0)); + asn1_start_tag(&data,ASN1_SEQUENCE(0)); + + asn1_start_tag(&data,ASN1_CONTEXT(0)); + asn1_start_tag(&data,ASN1_SEQUENCE(0)); + for (i=0; asn1_tag_remaining(&data) > 0 && i < ASN1_MAX_OIDS; i++) { + char *oid = NULL; + asn1_read_OID(&data,&oid); + OIDs[i] = oid; + } + OIDs[i] = NULL; + asn1_end_tag(&data); + asn1_end_tag(&data); + + asn1_start_tag(&data, ASN1_CONTEXT(3)); + asn1_start_tag(&data, ASN1_SEQUENCE(0)); + asn1_start_tag(&data, ASN1_CONTEXT(0)); + asn1_read_GeneralString(&data,principle); + asn1_end_tag(&data); + asn1_end_tag(&data); + asn1_end_tag(&data); + + asn1_end_tag(&data); + asn1_end_tag(&data); + + asn1_end_tag(&data); + + ret = !data.has_error; + asn1_free(&data); + return ret; +} + + +/* + generate a negTokenTarg packet given a list of OIDs and a security blob +*/ +DATA_BLOB gen_negTokenTarg(const char *OIDs[], DATA_BLOB blob) +{ + int i; + ASN1_DATA data; + DATA_BLOB ret; + + memset(&data, 0, sizeof(data)); + + asn1_push_tag(&data, ASN1_APPLICATION(0)); + asn1_write_OID(&data,OID_SPNEGO); + asn1_push_tag(&data, ASN1_CONTEXT(0)); + asn1_push_tag(&data, ASN1_SEQUENCE(0)); + + asn1_push_tag(&data, ASN1_CONTEXT(0)); + asn1_push_tag(&data, ASN1_SEQUENCE(0)); + for (i=0; OIDs[i]; i++) { + asn1_write_OID(&data,OIDs[i]); + } + asn1_pop_tag(&data); + asn1_pop_tag(&data); + + asn1_push_tag(&data, ASN1_CONTEXT(2)); + asn1_write_OctetString(&data,blob.data,blob.length); + asn1_pop_tag(&data); + + asn1_pop_tag(&data); + asn1_pop_tag(&data); + + asn1_pop_tag(&data); + + if (data.has_error) { + DEBUG(1,("Failed to build negTokenTarg at offset %d\n", (int)data.ofs)); + asn1_free(&data); + } + + ret = data_blob(data.data, data.length); + asn1_free(&data); + + return ret; +} + + +/* + generate a krb5 GSS-API wrapper packet given a ticket +*/ +static DATA_BLOB spnego_gen_krb5_wrap(DATA_BLOB ticket) +{ + ASN1_DATA data; + DATA_BLOB ret; + + memset(&data, 0, sizeof(data)); + + asn1_push_tag(&data, ASN1_APPLICATION(0)); + asn1_write_OID(&data, OID_KERBEROS5); + asn1_write_BOOLEAN(&data, 0); + asn1_write(&data, ticket.data, ticket.length); + asn1_pop_tag(&data); + + if (data.has_error) { + DEBUG(1,("Failed to build krb5 wrapper at offset %d\n", (int)data.ofs)); + asn1_free(&data); + } + + ret = data_blob(data.data, data.length); + asn1_free(&data); + + return ret; +} + + +/* + generate a SPNEGO negTokenTarg packet, ready for a EXTENDED_SECURITY + kerberos session setup +*/ +DATA_BLOB spnego_gen_negTokenTarg(struct cli_state *cli, char *principle) +{ + char *p; + fstring service; + char *realm; + DATA_BLOB tkt, tkt_wrapped, targ; + const char *krb_mechs[] = + {"1 2 840 48018 1 2 2", "1 3 6 1 4 1 311 2 2 10", NULL}; + + fstrcpy(service, principle); + p = strchr_m(service, '@'); + if (!p) { + DEBUG(1,("Malformed principle [%s] in spnego_gen_negTokenTarg\n", + principle)); + return data_blob(NULL, 0); + } + *p = 0; + realm = p+1; + + /* get a kerberos ticket for the service */ + tkt = krb5_get_ticket(service, realm); + + /* wrap that up in a nice GSS-API wrapping */ + tkt_wrapped = spnego_gen_krb5_wrap(tkt); + + /* and wrap that in a shiny SPNEGO wrapper */ + targ = gen_negTokenTarg(krb_mechs, tkt_wrapped); + + data_blob_free(tkt_wrapped); + data_blob_free(tkt); + + return targ; +} + + +/* + parse a spnego NTLMSSP challenge packet giving two security blobs +*/ +BOOL spnego_parse_challenge(DATA_BLOB blob, + DATA_BLOB *chal1, DATA_BLOB *chal2) +{ + BOOL ret; + ASN1_DATA data; + + asn1_load(&data, blob); + asn1_start_tag(&data,ASN1_CONTEXT(1)); + asn1_start_tag(&data,ASN1_SEQUENCE(0)); + + asn1_start_tag(&data,ASN1_CONTEXT(0)); + asn1_check_enumerated(&data,1); + asn1_end_tag(&data); + + asn1_start_tag(&data,ASN1_CONTEXT(1)); + asn1_check_OID(&data, "1 3 6 1 4 1 311 2 2 10"); + asn1_end_tag(&data); + + asn1_start_tag(&data,ASN1_CONTEXT(2)); + asn1_read_octet_string(&data, chal1); + asn1_end_tag(&data); + + asn1_start_tag(&data,ASN1_CONTEXT(3)); + asn1_read_octet_string(&data, chal2); + asn1_end_tag(&data); + + asn1_end_tag(&data); + asn1_end_tag(&data); + + ret = !data.has_error; + asn1_free(&data); + return ret; +} + +/* + generate a SPNEGO NTLMSSP auth packet. This will contain the encrypted passwords +*/ +DATA_BLOB spnego_gen_auth(DATA_BLOB blob) +{ + 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(2)); + asn1_write_OctetString(&data,blob.data,blob.length); + 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 + avoid tying this code to a particular varient of our rpc code. This + generator is not general enough for all our rpc needs, its just + enough for the spnego/ntlmssp code + + format specifiers are: + + U = unicode string (input is unix string) + B = data blob (pointer + length) + d = word (4 bytes) + C = constant ascii string + */ +BOOL msrpc_gen(DATA_BLOB *blob, + const char *format, ...) +{ + int i, n; + va_list ap; + char *s; + uint8 *b; + int head_size=0, data_size=0; + int head_ofs, data_ofs; + + /* first scan the format to work out the header and body size */ + va_start(ap, format); + for (i=0; format[i]; i++) { + switch (format[i]) { + case 'U': + s = va_arg(ap, char *); + head_size += 8; + data_size += str_charnum(s) * 2; + break; + case 'B': + b = va_arg(ap, uint8 *); + head_size += 8; + data_size += va_arg(ap, int); + break; + case 'd': + n = va_arg(ap, int); + head_size += 4; + break; + case 'C': + s = va_arg(ap, char *); + head_size += str_charnum(s) + 1; + break; + } + } + va_end(ap); + + /* allocate the space, then scan the format again to fill in the values */ + blob->data = malloc(head_size + data_size); + blob->length = head_size + data_size; + if (!blob->data) return False; + + head_ofs = 0; + data_ofs = head_size; + + va_start(ap, format); + for (i=0; format[i]; i++) { + switch (format[i]) { + case 'U': + s = va_arg(ap, char *); + n = str_charnum(s); + SSVAL(blob->data, head_ofs, n*2); head_ofs += 2; + SSVAL(blob->data, head_ofs, n*2); head_ofs += 2; + SIVAL(blob->data, head_ofs, data_ofs); head_ofs += 4; + 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); + SSVAL(blob->data, head_ofs, n); head_ofs += 2; + SSVAL(blob->data, head_ofs, n); head_ofs += 2; + SIVAL(blob->data, head_ofs, data_ofs); head_ofs += 4; + memcpy(blob->data+data_ofs, b, n); + data_ofs += n; + break; + case 'd': + n = va_arg(ap, int); + SIVAL(blob->data, head_ofs, n); head_ofs += 4; + break; + case 'C': + s = va_arg(ap, char *); + head_ofs += push_string(NULL, blob->data+head_ofs, s, -1, + STR_ASCII|STR_TERMINATE); + break; + } + } + va_end(ap); + + return True; +} -- cgit From d726eb216ad431d2bbd4ee07f4098b72446cdca2 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Fri, 12 Oct 2001 04:54:53 +0000 Subject: moved some OIDs to the ASN.1 header (This used to be commit 7092beef9d7a68018ede569883b22c822300c7ff) --- source3/libsmb/clispnego.c | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) (limited to 'source3/libsmb/clispnego.c') diff --git a/source3/libsmb/clispnego.c b/source3/libsmb/clispnego.c index 6c6b18a923..6b705658c3 100644 --- a/source3/libsmb/clispnego.c +++ b/source3/libsmb/clispnego.c @@ -21,9 +21,6 @@ #include "includes.h" -#define OID_SPNEGO "1 3 6 1 5 5 2" -#define OID_KERBEROS5 "1 2 840 113554 1 2 2" - /* generate a negTokenInit packet given a GUID, a list of supported OIDs (the mechanisms) and a principle name string @@ -207,8 +204,7 @@ DATA_BLOB spnego_gen_negTokenTarg(struct cli_state *cli, char *principle) fstring service; char *realm; DATA_BLOB tkt, tkt_wrapped, targ; - const char *krb_mechs[] = - {"1 2 840 48018 1 2 2", "1 3 6 1 4 1 311 2 2 10", NULL}; + const char *krb_mechs[] = {OID_KERBEROS5_OLD, OID_NTLMSSP, NULL}; fstrcpy(service, principle); p = strchr_m(service, '@'); @@ -254,7 +250,7 @@ BOOL spnego_parse_challenge(DATA_BLOB blob, asn1_end_tag(&data); asn1_start_tag(&data,ASN1_CONTEXT(1)); - asn1_check_OID(&data, "1 3 6 1 4 1 311 2 2 10"); + asn1_check_OID(&data, OID_NTLMSSP); asn1_end_tag(&data); asn1_start_tag(&data,ASN1_CONTEXT(2)); -- cgit From b46f6d865efa6dd50ed8b83d498f9e04919c9bc9 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sun, 14 Oct 2001 06:14:11 +0000 Subject: fixed NTLMSSP with XP servers (who don't send the duplicate challenge in the asn1 spnego structures) (This used to be commit 131010e9fb842b4d5a8660c538a3313c95fadae7) --- source3/libsmb/clispnego.c | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) (limited to 'source3/libsmb/clispnego.c') diff --git a/source3/libsmb/clispnego.c b/source3/libsmb/clispnego.c index 6b705658c3..da8c6450ae 100644 --- a/source3/libsmb/clispnego.c +++ b/source3/libsmb/clispnego.c @@ -241,6 +241,9 @@ BOOL spnego_parse_challenge(DATA_BLOB blob, BOOL ret; ASN1_DATA data; + ZERO_STRUCTP(chal1); + ZERO_STRUCTP(chal2); + asn1_load(&data, blob); asn1_start_tag(&data,ASN1_CONTEXT(1)); asn1_start_tag(&data,ASN1_SEQUENCE(0)); @@ -257,9 +260,12 @@ BOOL spnego_parse_challenge(DATA_BLOB blob, asn1_read_octet_string(&data, chal1); asn1_end_tag(&data); - asn1_start_tag(&data,ASN1_CONTEXT(3)); - asn1_read_octet_string(&data, chal2); - asn1_end_tag(&data); + /* the second challenge is optional (XP doesn't send it) */ + if (asn1_tag_remaining(&data)) { + asn1_start_tag(&data,ASN1_CONTEXT(3)); + asn1_read_octet_string(&data, chal2); + asn1_end_tag(&data); + } asn1_end_tag(&data); asn1_end_tag(&data); -- cgit From b728042334f67738fd1a6fdd03e619bdb78fe06a Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Wed, 17 Oct 2001 08:54:19 +0000 Subject: added basic NTLMSSP support in smbd. This is still quite rough, and loses things like username mapping. I wanted to get this in then discuss it a bit to see how we want to split up the existing session setup code (This used to be commit b74fda69bf23207c26d8b2af23910d8f2eb89875) --- source3/libsmb/clispnego.c | 222 +++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 215 insertions(+), 7 deletions(-) (limited to 'source3/libsmb/clispnego.c') diff --git a/source3/libsmb/clispnego.c b/source3/libsmb/clispnego.c index da8c6450ae..78cae3315a 100644 --- a/source3/libsmb/clispnego.c +++ b/source3/libsmb/clispnego.c @@ -25,12 +25,13 @@ generate a negTokenInit packet given a GUID, a list of supported OIDs (the mechanisms) and a principle name string */ -ASN1_DATA spnego_gen_negTokenInit(uint8 guid[16], +DATA_BLOB spnego_gen_negTokenInit(uint8 guid[16], const char *OIDs[], const char *principle) { int i; ASN1_DATA data; + DATA_BLOB ret; memset(&data, 0, sizeof(data)); @@ -66,7 +67,10 @@ ASN1_DATA spnego_gen_negTokenInit(uint8 guid[16], asn1_free(&data); } - return data; + ret = data_blob(data.data, data.length); + asn1_free(&data); + + return ret; } @@ -166,6 +170,50 @@ DATA_BLOB gen_negTokenTarg(const char *OIDs[], DATA_BLOB blob) } +/* + parse a negTokenTarg packet giving a list of OIDs and a security blob +*/ +BOOL parse_negTokenTarg(DATA_BLOB blob, char *OIDs[ASN1_MAX_OIDS], DATA_BLOB *secblob) +{ + int i; + ASN1_DATA data; + + asn1_load(&data, blob); + asn1_start_tag(&data, ASN1_APPLICATION(0)); + asn1_check_OID(&data,OID_SPNEGO); + asn1_start_tag(&data, ASN1_CONTEXT(0)); + asn1_start_tag(&data, ASN1_SEQUENCE(0)); + + asn1_start_tag(&data, ASN1_CONTEXT(0)); + asn1_start_tag(&data, ASN1_SEQUENCE(0)); + for (i=0; asn1_tag_remaining(&data) > 0 && i < ASN1_MAX_OIDS; i++) { + char *oid = NULL; + asn1_read_OID(&data,&oid); + OIDs[i] = oid; + } + OIDs[i] = NULL; + asn1_end_tag(&data); + asn1_end_tag(&data); + + asn1_start_tag(&data, ASN1_CONTEXT(2)); + asn1_read_OctetString(&data,secblob); + asn1_end_tag(&data); + + asn1_end_tag(&data); + asn1_end_tag(&data); + + asn1_end_tag(&data); + + if (data.has_error) { + DEBUG(1,("Failed to parse negTokenTarg at offset %d\n", (int)data.ofs)); + asn1_free(&data); + return False; + } + + asn1_free(&data); + return True; +} + /* generate a krb5 GSS-API wrapper packet given a ticket */ @@ -225,8 +273,8 @@ DATA_BLOB spnego_gen_negTokenTarg(struct cli_state *cli, char *principle) /* and wrap that in a shiny SPNEGO wrapper */ targ = gen_negTokenTarg(krb_mechs, tkt_wrapped); - data_blob_free(tkt_wrapped); - data_blob_free(tkt); + data_blob_free(&tkt_wrapped); + data_blob_free(&tkt); return targ; } @@ -257,13 +305,13 @@ BOOL spnego_parse_challenge(DATA_BLOB blob, asn1_end_tag(&data); asn1_start_tag(&data,ASN1_CONTEXT(2)); - asn1_read_octet_string(&data, chal1); + asn1_read_OctetString(&data, chal1); asn1_end_tag(&data); /* the second challenge is optional (XP doesn't send it) */ if (asn1_tag_remaining(&data)) { asn1_start_tag(&data,ASN1_CONTEXT(3)); - asn1_read_octet_string(&data, chal2); + asn1_read_OctetString(&data, chal2); asn1_end_tag(&data); } @@ -275,6 +323,52 @@ BOOL spnego_parse_challenge(DATA_BLOB blob, return ret; } + +/* + generate a spnego NTLMSSP challenge packet given two security blobs + The second challenge is optional +*/ +BOOL spnego_gen_challenge(DATA_BLOB *blob, + DATA_BLOB *chal1, DATA_BLOB *chal2) +{ + ASN1_DATA data; + + ZERO_STRUCT(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,1); + asn1_pop_tag(&data); + + asn1_push_tag(&data,ASN1_CONTEXT(1)); + asn1_write_OID(&data, OID_NTLMSSP); + asn1_pop_tag(&data); + + asn1_push_tag(&data,ASN1_CONTEXT(2)); + asn1_write_OctetString(&data, chal1->data, chal1->length); + asn1_pop_tag(&data); + + /* the second challenge is optional (XP doesn't send it) */ + if (chal2) { + asn1_push_tag(&data,ASN1_CONTEXT(3)); + asn1_write_OctetString(&data, chal2->data, chal2->length); + asn1_pop_tag(&data); + } + + asn1_pop_tag(&data); + asn1_pop_tag(&data); + + if (data.has_error) { + return False; + } + + *blob = data_blob(data.data, data.length); + asn1_free(&data); + return True; +} + /* generate a SPNEGO NTLMSSP auth packet. This will contain the encrypted passwords */ @@ -298,7 +392,32 @@ DATA_BLOB spnego_gen_auth(DATA_BLOB blob) asn1_free(&data); return ret; - +} + +/* + parse a SPNEGO NTLMSSP auth packet. This contains the encrypted passwords +*/ +BOOL spnego_parse_auth(DATA_BLOB blob, DATA_BLOB *auth) +{ + ASN1_DATA data; + + asn1_load(&data, blob); + asn1_start_tag(&data, ASN1_CONTEXT(1)); + asn1_start_tag(&data, ASN1_SEQUENCE(0)); + asn1_start_tag(&data, ASN1_CONTEXT(2)); + asn1_read_OctetString(&data,auth); + asn1_end_tag(&data); + asn1_end_tag(&data); + asn1_end_tag(&data); + + if (data.has_error) { + DEBUG(3,("spnego_parse_auth failed at %d\n", (int)data.ofs)); + asn1_free(&data); + return False; + } + + asn1_free(&data); + return True; } @@ -312,6 +431,7 @@ DATA_BLOB spnego_gen_auth(DATA_BLOB blob) U = unicode string (input is unix string) B = data blob (pointer + length) + b = data blob in header (pointer + length) d = word (4 bytes) C = constant ascii string */ @@ -339,6 +459,10 @@ BOOL msrpc_gen(DATA_BLOB *blob, head_size += 8; data_size += va_arg(ap, int); break; + case 'b': + b = va_arg(ap, uint8 *); + head_size += va_arg(ap, int); + break; case 'd': n = va_arg(ap, int); head_size += 4; @@ -384,6 +508,12 @@ BOOL msrpc_gen(DATA_BLOB *blob, n = va_arg(ap, int); SIVAL(blob->data, head_ofs, n); head_ofs += 4; break; + case 'b': + b = va_arg(ap, uint8 *); + n = va_arg(ap, int); + memcpy(blob->data + head_ofs, b, n); + head_ofs += n; + break; case 'C': s = va_arg(ap, char *); head_ofs += push_string(NULL, blob->data+head_ofs, s, -1, @@ -395,3 +525,81 @@ BOOL msrpc_gen(DATA_BLOB *blob, return True; } + + +/* + this is a tiny msrpc packet parser. This the the partner of msrpc_gen + + format specifiers are: + + U = unicode string (input is unix string) + B = data blob + b = data blob in header + d = word (4 bytes) + C = constant ascii string + */ +BOOL msrpc_parse(DATA_BLOB *blob, + const char *format, ...) +{ + int i; + va_list ap; + char **ps, *s; + DATA_BLOB *b; + int head_ofs = 0; + uint16 len1, len2; + uint32 ptr; + uint32 *v; + pstring p; + + va_start(ap, format); + for (i=0; format[i]; i++) { + switch (format[i]) { + case 'U': + 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 || (len1&1) || ptr + len1 > blob->length) { + return False; + } + ps = va_arg(ap, char **); + pull_string(NULL, p, blob->data + ptr, -1, len1, + STR_UNICODE|STR_NOALIGN); + (*ps) = strdup(p); + break; + case 'B': + 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; + } + b = (DATA_BLOB *)va_arg(ap, void *); + *b = data_blob(blob->data + ptr, len1); + break; + case 'b': + b = (DATA_BLOB *)va_arg(ap, void *); + len1 = va_arg(ap, unsigned); + *b = data_blob(blob->data + head_ofs, len1); + head_ofs += len1; + break; + case 'd': + v = va_arg(ap, uint32 *); + *v = IVAL(blob->data, head_ofs); head_ofs += 4; + break; + case 'C': + s = va_arg(ap, char *); + head_ofs += pull_string(NULL, p, blob->data+head_ofs, -1, + blob->length - head_ofs, + STR_ASCII|STR_TERMINATE); + if (strcmp(s, p) != 0) { + return False; + } + break; + } + } + va_end(ap); + + return True; +} -- cgit From 5ad7448359c7bc1d3b1579f105b7324290bf21ec Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Thu, 18 Oct 2001 10:26:06 +0000 Subject: the beginnings of kerberos support in smbd. It doesn't work yet, but it should give something for others to hack on and possibly find what I'm doing wrong. (This used to be commit 353c290f059347265b9be2aa1010c2956da06485) --- source3/libsmb/clispnego.c | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) (limited to 'source3/libsmb/clispnego.c') diff --git a/source3/libsmb/clispnego.c b/source3/libsmb/clispnego.c index 78cae3315a..c421d75913 100644 --- a/source3/libsmb/clispnego.c +++ b/source3/libsmb/clispnego.c @@ -241,6 +241,29 @@ static DATA_BLOB spnego_gen_krb5_wrap(DATA_BLOB ticket) return ret; } +/* + parse a krb5 GSS-API wrapper packet giving a ticket +*/ +BOOL spnego_parse_krb5_wrap(DATA_BLOB blob, DATA_BLOB *ticket) +{ + BOOL ret; + ASN1_DATA data; + + asn1_load(&data, blob); + asn1_start_tag(&data, ASN1_APPLICATION(0)); + asn1_check_OID(&data, OID_KERBEROS5); + asn1_check_BOOLEAN(&data, 0); + *ticket = data_blob(data.data, asn1_tag_remaining(&data)); + asn1_read(&data, ticket->data, ticket->length); + asn1_end_tag(&data); + + ret = !data.has_error; + + asn1_free(&data); + + return ret; +} + /* generate a SPNEGO negTokenTarg packet, ready for a EXTENDED_SECURITY -- cgit From bbcd9deb07fe0cfcb2911093e1c99d30b210e7d2 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sun, 21 Oct 2001 03:25:34 +0000 Subject: made smbclient cope better with arbitrary principle forms (This used to be commit d1341d74b7aa5f6b3f72e5409b245f87f1ad670b) --- source3/libsmb/clispnego.c | 15 +-------------- 1 file changed, 1 insertion(+), 14 deletions(-) (limited to 'source3/libsmb/clispnego.c') diff --git a/source3/libsmb/clispnego.c b/source3/libsmb/clispnego.c index c421d75913..bcce0f6173 100644 --- a/source3/libsmb/clispnego.c +++ b/source3/libsmb/clispnego.c @@ -271,24 +271,11 @@ BOOL spnego_parse_krb5_wrap(DATA_BLOB blob, DATA_BLOB *ticket) */ DATA_BLOB spnego_gen_negTokenTarg(struct cli_state *cli, char *principle) { - char *p; - fstring service; - char *realm; DATA_BLOB tkt, tkt_wrapped, targ; const char *krb_mechs[] = {OID_KERBEROS5_OLD, OID_NTLMSSP, NULL}; - fstrcpy(service, principle); - p = strchr_m(service, '@'); - if (!p) { - DEBUG(1,("Malformed principle [%s] in spnego_gen_negTokenTarg\n", - principle)); - return data_blob(NULL, 0); - } - *p = 0; - realm = p+1; - /* get a kerberos ticket for the service */ - tkt = krb5_get_ticket(service, realm); + tkt = krb5_get_ticket(principle); /* wrap that up in a nice GSS-API wrapping */ tkt_wrapped = spnego_gen_krb5_wrap(tkt); -- cgit From cfd68eaac48a29dec245dc6de03aae0d58698862 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Sun, 21 Oct 2001 20:51:27 +0000 Subject: Ok, I know it's a language thing and it shouldn't matter.... but a kerberos name is a "principal", not a principle. English majors will complain :-). Jeremy. (This used to be commit b668d7d656cdd066820fb8044f24bcd4fda29524) --- source3/libsmb/clispnego.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) (limited to 'source3/libsmb/clispnego.c') diff --git a/source3/libsmb/clispnego.c b/source3/libsmb/clispnego.c index bcce0f6173..784463566f 100644 --- a/source3/libsmb/clispnego.c +++ b/source3/libsmb/clispnego.c @@ -23,11 +23,11 @@ /* generate a negTokenInit packet given a GUID, a list of supported - OIDs (the mechanisms) and a principle name string + OIDs (the mechanisms) and a principal name string */ DATA_BLOB spnego_gen_negTokenInit(uint8 guid[16], const char *OIDs[], - const char *principle) + const char *principal) { int i; ASN1_DATA data; @@ -52,7 +52,7 @@ DATA_BLOB spnego_gen_negTokenInit(uint8 guid[16], asn1_push_tag(&data, ASN1_CONTEXT(3)); asn1_push_tag(&data, ASN1_SEQUENCE(0)); asn1_push_tag(&data, ASN1_CONTEXT(0)); - asn1_write_GeneralString(&data,principle); + asn1_write_GeneralString(&data,principal); asn1_pop_tag(&data); asn1_pop_tag(&data); asn1_pop_tag(&data); @@ -76,12 +76,12 @@ DATA_BLOB spnego_gen_negTokenInit(uint8 guid[16], /* parse a negTokenInit packet giving a GUID, a list of supported - OIDs (the mechanisms) and a principle name string + OIDs (the mechanisms) and a principal name string */ BOOL spnego_parse_negTokenInit(DATA_BLOB blob, uint8 guid[16], char *OIDs[ASN1_MAX_OIDS], - char **principle) + char **principal) { int i; BOOL ret; @@ -109,7 +109,7 @@ BOOL spnego_parse_negTokenInit(DATA_BLOB blob, asn1_start_tag(&data, ASN1_CONTEXT(3)); asn1_start_tag(&data, ASN1_SEQUENCE(0)); asn1_start_tag(&data, ASN1_CONTEXT(0)); - asn1_read_GeneralString(&data,principle); + asn1_read_GeneralString(&data,principal); asn1_end_tag(&data); asn1_end_tag(&data); asn1_end_tag(&data); @@ -269,13 +269,13 @@ BOOL spnego_parse_krb5_wrap(DATA_BLOB blob, DATA_BLOB *ticket) generate a SPNEGO negTokenTarg packet, ready for a EXTENDED_SECURITY kerberos session setup */ -DATA_BLOB spnego_gen_negTokenTarg(struct cli_state *cli, char *principle) +DATA_BLOB spnego_gen_negTokenTarg(struct cli_state *cli, char *principal) { DATA_BLOB tkt, tkt_wrapped, targ; const char *krb_mechs[] = {OID_KERBEROS5_OLD, OID_NTLMSSP, NULL}; /* get a kerberos ticket for the service */ - tkt = krb5_get_ticket(principle); + tkt = krb5_get_ticket(principal); /* wrap that up in a nice GSS-API wrapping */ tkt_wrapped = spnego_gen_krb5_wrap(tkt); -- cgit From 5d378a280f74405fccbadbfb28e1066613c76fd8 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sat, 8 Dec 2001 11:18:56 +0000 Subject: added internal sasl/gssapi code. This means we are no longer dependent on cyrus-sasl which makes the code much less fragile. Also added code to auto-determine the server name or realm (This used to be commit 435fdf276a79c2a517adcd7726933aeef3fa924b) --- source3/libsmb/clispnego.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb/clispnego.c') diff --git a/source3/libsmb/clispnego.c b/source3/libsmb/clispnego.c index 784463566f..bc3873bf18 100644 --- a/source3/libsmb/clispnego.c +++ b/source3/libsmb/clispnego.c @@ -217,7 +217,7 @@ BOOL parse_negTokenTarg(DATA_BLOB blob, char *OIDs[ASN1_MAX_OIDS], DATA_BLOB *se /* generate a krb5 GSS-API wrapper packet given a ticket */ -static DATA_BLOB spnego_gen_krb5_wrap(DATA_BLOB ticket) +DATA_BLOB spnego_gen_krb5_wrap(DATA_BLOB ticket) { ASN1_DATA data; DATA_BLOB ret; -- cgit From b0e4827b9750edd358230890fdc671f378da9626 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Sat, 5 Jan 2002 23:30:59 +0000 Subject: simple fix for creating blank data blobs (This used to be commit 08bb2dfec2ca0282e9268d09da2b966d3bdf493a) --- source3/libsmb/clispnego.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) (limited to 'source3/libsmb/clispnego.c') diff --git a/source3/libsmb/clispnego.c b/source3/libsmb/clispnego.c index bc3873bf18..035b47b417 100644 --- a/source3/libsmb/clispnego.c +++ b/source3/libsmb/clispnego.c @@ -486,9 +486,7 @@ BOOL msrpc_gen(DATA_BLOB *blob, va_end(ap); /* allocate the space, then scan the format again to fill in the values */ - blob->data = malloc(head_size + data_size); - blob->length = head_size + data_size; - if (!blob->data) return False; + *blob = data_blob(NULL, head_size + data_size); head_ofs = 0; data_ofs = head_size; -- cgit From cd68afe31256ad60748b34f7318a180cfc2127cc Mon Sep 17 00:00:00 2001 From: Tim Potter Date: Wed, 30 Jan 2002 06:08:46 +0000 Subject: Removed version number from file header. Changed "SMB/Netbios" to "SMB/CIFS" in file header. (This used to be commit 6a58c9bd06d0d7502a24bf5ce5a2faf0a146edfa) --- source3/libsmb/clispnego.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'source3/libsmb/clispnego.c') diff --git a/source3/libsmb/clispnego.c b/source3/libsmb/clispnego.c index 035b47b417..a962953b90 100644 --- a/source3/libsmb/clispnego.c +++ b/source3/libsmb/clispnego.c @@ -1,6 +1,5 @@ /* - Unix SMB/Netbios implementation. - Version 3.0 + Unix SMB/CIFS implementation. simple kerberos5/SPNEGO routines Copyright (C) Andrew Tridgell 2001 -- cgit From ba9341c7de216acea5fc194fb42944714553a1a5 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Fri, 15 Feb 2002 23:11:13 +0000 Subject: Try not to malloc -1 bytes (apx 4GB) when the data is already in error. Andrew Bartlett (This used to be commit ad1faf8fa4019cb57fbb7f311f6d4943359bcd45) --- source3/libsmb/clispnego.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) (limited to 'source3/libsmb/clispnego.c') diff --git a/source3/libsmb/clispnego.c b/source3/libsmb/clispnego.c index a962953b90..a4fcfa5d9a 100644 --- a/source3/libsmb/clispnego.c +++ b/source3/libsmb/clispnego.c @@ -247,13 +247,23 @@ BOOL spnego_parse_krb5_wrap(DATA_BLOB blob, DATA_BLOB *ticket) { BOOL ret; ASN1_DATA data; + int data_remaining; asn1_load(&data, blob); asn1_start_tag(&data, ASN1_APPLICATION(0)); asn1_check_OID(&data, OID_KERBEROS5); asn1_check_BOOLEAN(&data, 0); - *ticket = data_blob(data.data, asn1_tag_remaining(&data)); - asn1_read(&data, ticket->data, ticket->length); + + data_remaining = asn1_tag_remaining(&data); + + if (data_remaining < 1) { + data.has_error = True; + } else { + + *ticket = data_blob(data.data, data_remaining); + asn1_read(&data, ticket->data, ticket->length); + } + asn1_end_tag(&data); ret = !data.has_error; -- cgit From e90b65284812aaa5ff9e9935ce9bbad7791cbbcd Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Mon, 15 Jul 2002 10:35:28 +0000 Subject: updated the 3.0 branch from the head branch - ready for alpha18 (This used to be commit 03ac082dcb375b6f3ca3d810a6a6367542bc23ce) --- source3/libsmb/clispnego.c | 43 ++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 42 insertions(+), 1 deletion(-) (limited to 'source3/libsmb/clispnego.c') diff --git a/source3/libsmb/clispnego.c b/source3/libsmb/clispnego.c index a4fcfa5d9a..469b946088 100644 --- a/source3/libsmb/clispnego.c +++ b/source3/libsmb/clispnego.c @@ -549,7 +549,7 @@ BOOL msrpc_gen(DATA_BLOB *blob, format specifiers are: - U = unicode string (input is unix string) + U = unicode string (output is unix string) B = data blob b = data blob in header d = word (4 bytes) @@ -620,3 +620,44 @@ BOOL msrpc_parse(DATA_BLOB *blob, return True; } + +/** + * Print out the NTLMSSP flags for debugging + */ + +void debug_ntlmssp_flags(uint32 neg_flags) +{ + if (neg_flags & NTLMSSP_NEGOTIATE_UNICODE) + DEBUG(4, (" NTLMSSP_NEGOTIATE_UNICODE\n")); + if (neg_flags & NTLMSSP_NEGOTIATE_OEM) + DEBUG(4, (" NTLMSSP_NEGOTIATE_OEM\n")); + if (neg_flags & NTLMSSP_REQUEST_TARGET) + DEBUG(4, (" NTLMSSP_REQUEST_TARGET\n")); + if (neg_flags & NTLMSSP_NEGOTIATE_SIGN) + DEBUG(4, (" NTLMSSP_NEGOTIATE_SIGN\n")); + if (neg_flags & NTLMSSP_NEGOTIATE_SIGN) + DEBUG(4, (" NTLMSSP_NEGOTIATE_SEAL\n")); + if (neg_flags & NTLMSSP_NEGOTIATE_LM_KEY) + DEBUG(4, (" NTLMSSP_NEGOTIATE_LM_KEY\n")); + if (neg_flags & NTLMSSP_NEGOTIATE_NETWARE) + DEBUG(4, (" NTLMSSP_NEGOTIATE_NETWARE\n")); + if (neg_flags & NTLMSSP_NEGOTIATE_NTLM) + DEBUG(4, (" NTLMSSP_NEGOTIATE_NTLM\n")); + if (neg_flags & NTLMSSP_NEGOTIATE_DOMAIN_SUPPLIED) + DEBUG(4, (" NTLMSSP_NEGOTIATE_DOMAIN_SUPPLIED\n")); + if (neg_flags & NTLMSSP_NEGOTIATE_WORKSTATION_SUPPLIED) + DEBUG(4, (" NTLMSSP_NEGOTIATE_WORKSTATION_SUPPLIED\n")); + if (neg_flags & NTLMSSP_NEGOTIATE_THIS_IS_LOCAL_CALL) + DEBUG(4, (" NTLMSSP_NEGOTIATE_THIS_IS_LOCAL_CALL\n")); + if (neg_flags & NTLMSSP_NEGOTIATE_ALWAYS_SIGN) + DEBUG(4, (" NTLMSSP_NEGOTIATE_ALWAYS_SIGN\n")); + if (neg_flags & NTLMSSP_NEGOTIATE_NTLM2) + DEBUG(4, (" NTLMSSP_NEGOTIATE_NTLM2\n")); + if (neg_flags & NTLMSSP_CHAL_TARGET_INFO) + DEBUG(4, (" NTLMSSP_CHAL_TARGET_INFO\n")); + if (neg_flags & NTLMSSP_NEGOTIATE_128) + DEBUG(4, (" NTLMSSP_NEGOTIATE_128\n")); + if (neg_flags & NTLMSSP_NEGOTIATE_KEY_EXCH) + DEBUG(4, (" NTLMSSP_NEGOTIATE_KEY_EXCH\n")); +} + -- cgit From b2edf254eda92f775e7d3d9b6793b4d77f9000b6 Mon Sep 17 00:00:00 2001 From: Jelmer Vernooij Date: Sat, 17 Aug 2002 17:00:51 +0000 Subject: sync 3.0 branch with head (This used to be commit 3928578b52cfc949be5e0ef444fce1558d75f290) --- source3/libsmb/clispnego.c | 61 ++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 61 insertions(+) (limited to 'source3/libsmb/clispnego.c') 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; -- cgit From a834a73e341059be154426390304a42e4a011f72 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Wed, 25 Sep 2002 15:19:00 +0000 Subject: sync'ing up for 3.0alpha20 release (This used to be commit 65e7b5273bb58802bf0c389b77f7fcae0a1f6139) --- source3/libsmb/clispnego.c | 92 +++++++++++++++++++++++++++++++++++----------- 1 file changed, 70 insertions(+), 22 deletions(-) (limited to 'source3/libsmb/clispnego.c') diff --git a/source3/libsmb/clispnego.c b/source3/libsmb/clispnego.c index 16702c375b..55f49c5987 100644 --- a/source3/libsmb/clispnego.c +++ b/source3/libsmb/clispnego.c @@ -73,13 +73,56 @@ DATA_BLOB spnego_gen_negTokenInit(uint8 guid[16], return ret; } +/* + Generate a negTokenInit as used by the client side ... It has a mechType + (OID), and a mechToken (a security blob) ... + + Really, we need to break out the NTLMSSP stuff as well, because it could be + raw in the packets! +*/ +DATA_BLOB gen_negTokenInit(const char *OID, DATA_BLOB blob) +{ + ASN1_DATA data; + DATA_BLOB ret; + + memset(&data, 0, sizeof(data)); + + asn1_push_tag(&data, ASN1_APPLICATION(0)); + asn1_write_OID(&data,OID_SPNEGO); + asn1_push_tag(&data, ASN1_CONTEXT(0)); + asn1_push_tag(&data, ASN1_SEQUENCE(0)); + + asn1_push_tag(&data, ASN1_CONTEXT(0)); + asn1_push_tag(&data, ASN1_SEQUENCE(0)); + asn1_write_OID(&data, OID); + asn1_pop_tag(&data); + asn1_pop_tag(&data); + + asn1_push_tag(&data, ASN1_CONTEXT(2)); + asn1_write_OctetString(&data,blob.data,blob.length); + asn1_pop_tag(&data); + + asn1_pop_tag(&data); + asn1_pop_tag(&data); + + asn1_pop_tag(&data); + + if (data.has_error) { + DEBUG(1,("Failed to build negTokenInit at offset %d\n", (int)data.ofs)); + asn1_free(&data); + } + + ret = data_blob(data.data, data.length); + asn1_free(&data); + + return ret; +} /* parse a negTokenInit packet giving a GUID, a list of supported OIDs (the mechanisms) and a principal name string */ BOOL spnego_parse_negTokenInit(DATA_BLOB blob, - uint8 guid[16], char *OIDs[ASN1_MAX_OIDS], char **principal) { @@ -89,7 +132,6 @@ BOOL spnego_parse_negTokenInit(DATA_BLOB blob, asn1_load(&data, blob); - asn1_read(&data, guid, 16); asn1_start_tag(&data,ASN1_APPLICATION(0)); asn1_check_OID(&data,OID_SPNEGO); asn1_start_tag(&data,ASN1_CONTEXT(0)); @@ -279,13 +321,13 @@ BOOL spnego_parse_krb5_wrap(DATA_BLOB blob, DATA_BLOB *ticket) generate a SPNEGO negTokenTarg packet, ready for a EXTENDED_SECURITY kerberos session setup */ -DATA_BLOB spnego_gen_negTokenTarg(struct cli_state *cli, char *principal) +DATA_BLOB spnego_gen_negTokenTarg(const char *principal, int time_offset) { DATA_BLOB tkt, tkt_wrapped, targ; const char *krb_mechs[] = {OID_KERBEROS5_OLD, OID_NTLMSSP, NULL}; /* get a kerberos ticket for the service */ - tkt = krb5_get_ticket(principal); + tkt = krb5_get_ticket(principal, time_offset); /* wrap that up in a nice GSS-API wrapping */ tkt_wrapped = spnego_gen_krb5_wrap(tkt); @@ -473,8 +515,10 @@ DATA_BLOB spnego_gen_auth_response(void) U = unicode string (input is unix string) a = address (1 byte type, 1 byte length, unicode string, all inline) + A = ASCII string (pointer + length) Actually same as B B = data blob (pointer + length) b = data blob in header (pointer + length) + D d = word (4 bytes) C = constant ascii string */ @@ -502,6 +546,7 @@ BOOL msrpc_gen(DATA_BLOB *blob, s = va_arg(ap, char *); data_size += (str_charnum(s) * 2) + 4; break; + case 'A': case 'B': b = va_arg(ap, uint8 *); head_size += 8; @@ -553,7 +598,8 @@ BOOL msrpc_gen(DATA_BLOB *blob, } data_ofs += n*2; break; - + + case 'A': case 'B': b = va_arg(ap, uint8 *); n = va_arg(ap, int); @@ -688,37 +734,39 @@ BOOL msrpc_parse(DATA_BLOB *blob, void debug_ntlmssp_flags(uint32 neg_flags) { + DEBUG(3,("Got NTLMSSP neg_flags=0x%08x\n", neg_flags)); + if (neg_flags & NTLMSSP_NEGOTIATE_UNICODE) - DEBUG(4, (" NTLMSSP_NEGOTIATE_UNICODE\n")); + DEBUGADD(4, (" NTLMSSP_NEGOTIATE_UNICODE\n")); if (neg_flags & NTLMSSP_NEGOTIATE_OEM) - DEBUG(4, (" NTLMSSP_NEGOTIATE_OEM\n")); + DEBUGADD(4, (" NTLMSSP_NEGOTIATE_OEM\n")); if (neg_flags & NTLMSSP_REQUEST_TARGET) - DEBUG(4, (" NTLMSSP_REQUEST_TARGET\n")); - if (neg_flags & NTLMSSP_NEGOTIATE_SIGN) - DEBUG(4, (" NTLMSSP_NEGOTIATE_SIGN\n")); + DEBUGADD(4, (" NTLMSSP_REQUEST_TARGET\n")); if (neg_flags & NTLMSSP_NEGOTIATE_SIGN) - DEBUG(4, (" NTLMSSP_NEGOTIATE_SEAL\n")); + DEBUGADD(4, (" NTLMSSP_NEGOTIATE_SIGN\n")); + if (neg_flags & NTLMSSP_NEGOTIATE_SEAL) + DEBUGADD(4, (" NTLMSSP_NEGOTIATE_SEAL\n")); if (neg_flags & NTLMSSP_NEGOTIATE_LM_KEY) - DEBUG(4, (" NTLMSSP_NEGOTIATE_LM_KEY\n")); + DEBUGADD(4, (" NTLMSSP_NEGOTIATE_LM_KEY\n")); if (neg_flags & NTLMSSP_NEGOTIATE_NETWARE) - DEBUG(4, (" NTLMSSP_NEGOTIATE_NETWARE\n")); + DEBUGADD(4, (" NTLMSSP_NEGOTIATE_NETWARE\n")); if (neg_flags & NTLMSSP_NEGOTIATE_NTLM) - DEBUG(4, (" NTLMSSP_NEGOTIATE_NTLM\n")); + DEBUGADD(4, (" NTLMSSP_NEGOTIATE_NTLM\n")); if (neg_flags & NTLMSSP_NEGOTIATE_DOMAIN_SUPPLIED) - DEBUG(4, (" NTLMSSP_NEGOTIATE_DOMAIN_SUPPLIED\n")); + DEBUGADD(4, (" NTLMSSP_NEGOTIATE_DOMAIN_SUPPLIED\n")); if (neg_flags & NTLMSSP_NEGOTIATE_WORKSTATION_SUPPLIED) - DEBUG(4, (" NTLMSSP_NEGOTIATE_WORKSTATION_SUPPLIED\n")); + DEBUGADD(4, (" NTLMSSP_NEGOTIATE_WORKSTATION_SUPPLIED\n")); if (neg_flags & NTLMSSP_NEGOTIATE_THIS_IS_LOCAL_CALL) - DEBUG(4, (" NTLMSSP_NEGOTIATE_THIS_IS_LOCAL_CALL\n")); + DEBUGADD(4, (" NTLMSSP_NEGOTIATE_THIS_IS_LOCAL_CALL\n")); if (neg_flags & NTLMSSP_NEGOTIATE_ALWAYS_SIGN) - DEBUG(4, (" NTLMSSP_NEGOTIATE_ALWAYS_SIGN\n")); + DEBUGADD(4, (" NTLMSSP_NEGOTIATE_ALWAYS_SIGN\n")); if (neg_flags & NTLMSSP_NEGOTIATE_NTLM2) - DEBUG(4, (" NTLMSSP_NEGOTIATE_NTLM2\n")); + DEBUGADD(4, (" NTLMSSP_NEGOTIATE_NTLM2\n")); if (neg_flags & NTLMSSP_CHAL_TARGET_INFO) - DEBUG(4, (" NTLMSSP_CHAL_TARGET_INFO\n")); + DEBUGADD(4, (" NTLMSSP_CHAL_TARGET_INFO\n")); if (neg_flags & NTLMSSP_NEGOTIATE_128) - DEBUG(4, (" NTLMSSP_NEGOTIATE_128\n")); + DEBUGADD(4, (" NTLMSSP_NEGOTIATE_128\n")); if (neg_flags & NTLMSSP_NEGOTIATE_KEY_EXCH) - DEBUG(4, (" NTLMSSP_NEGOTIATE_KEY_EXCH\n")); + DEBUGADD(4, (" NTLMSSP_NEGOTIATE_KEY_EXCH\n")); } -- cgit From 1cba0a757970ffd8b81d61c88965010968ab3eff Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Tue, 28 Jan 2003 12:07:02 +0000 Subject: Merge from HEAD: - NTLMSSP over SPENGO (sesssion-setup-and-x) cleanup and code refactor. - also consequential changes to the NTLMSSP and SPNEGO parsing functions - and the client code that uses the same functions - Add ntlm_auth, a NTLMSSP authentication interface for use by applications like Squid and Apache. - also consquential changes to use common code for base64 encode/decode. - Winbind changes to support ntlm_auth (I don't want this program to need to read smb.conf, instead getting all it's details over the pipe). - nmbd changes for fstrcat() instead of fstrcpy(). Andrew Bartlett (This used to be commit fbb46da79cf322570a7e3318100c304bbf33409e) --- source3/libsmb/clispnego.c | 124 +++++++++++++++++++++++---------------------- 1 file changed, 64 insertions(+), 60 deletions(-) (limited to 'source3/libsmb/clispnego.c') diff --git a/source3/libsmb/clispnego.c b/source3/libsmb/clispnego.c index 55f49c5987..3e28baa417 100644 --- a/source3/libsmb/clispnego.c +++ b/source3/libsmb/clispnego.c @@ -386,51 +386,6 @@ BOOL spnego_parse_challenge(DATA_BLOB blob, } -/* - generate a spnego NTLMSSP challenge packet given two security blobs - The second challenge is optional -*/ -BOOL spnego_gen_challenge(DATA_BLOB *blob, - DATA_BLOB *chal1, DATA_BLOB *chal2) -{ - ASN1_DATA data; - - ZERO_STRUCT(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,1); - asn1_pop_tag(&data); - - asn1_push_tag(&data,ASN1_CONTEXT(1)); - asn1_write_OID(&data, OID_NTLMSSP); - asn1_pop_tag(&data); - - asn1_push_tag(&data,ASN1_CONTEXT(2)); - asn1_write_OctetString(&data, chal1->data, chal1->length); - asn1_pop_tag(&data); - - /* the second challenge is optional (XP doesn't send it) */ - if (chal2) { - asn1_push_tag(&data,ASN1_CONTEXT(3)); - asn1_write_OctetString(&data, chal2->data, chal2->length); - asn1_pop_tag(&data); - } - - asn1_pop_tag(&data); - asn1_pop_tag(&data); - - if (data.has_error) { - return False; - } - - *blob = data_blob(data.data, data.length); - asn1_free(&data); - return True; -} - /* generate a SPNEGO NTLMSSP auth packet. This will contain the encrypted passwords */ @@ -485,18 +440,37 @@ BOOL spnego_parse_auth(DATA_BLOB blob, DATA_BLOB *auth) /* generate a minimal SPNEGO NTLMSSP response packet. Doesn't contain much. */ -DATA_BLOB spnego_gen_auth_response(void) +DATA_BLOB spnego_gen_auth_response(DATA_BLOB *ntlmssp_reply, NTSTATUS nt_status) { ASN1_DATA data; DATA_BLOB ret; + uint8 negResult; - memset(&data, 0, sizeof(data)); + if (NT_STATUS_IS_OK(nt_status)) { + negResult = SPNGEO_NEG_RESULT_ACCEPT; + } else if (NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) { + negResult = SPNGEO_NEG_RESULT_INCOMPLETE; + } else { + negResult = SPNGEO_NEG_RESULT_REJECT; + } + + ZERO_STRUCT(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_write_enumerated(&data, negResult); asn1_pop_tag(&data); + if (negResult == SPNGEO_NEG_RESULT_INCOMPLETE) { + asn1_push_tag(&data,ASN1_CONTEXT(1)); + asn1_write_OID(&data, OID_NTLMSSP); + asn1_pop_tag(&data); + + asn1_push_tag(&data,ASN1_CONTEXT(2)); + asn1_write_OctetString(&data, ntlmssp_reply->data, ntlmssp_reply->length); + asn1_pop_tag(&data); + } + asn1_pop_tag(&data); asn1_pop_tag(&data); @@ -514,8 +488,9 @@ DATA_BLOB spnego_gen_auth_response(void) format specifiers are: U = unicode string (input is unix string) - a = address (1 byte type, 1 byte length, unicode string, all inline) - A = ASCII string (pointer + length) Actually same as B + a = address (input is BOOL unicode, char *unix_string) + (1 byte type, 1 byte length, unicode/ASCII string, all inline) + A = ASCII string (input is unix string) B = data blob (pointer + length) b = data blob in header (pointer + length) D @@ -531,6 +506,7 @@ BOOL msrpc_gen(DATA_BLOB *blob, uint8 *b; int head_size=0, data_size=0; int head_ofs, data_ofs; + BOOL unicode; /* first scan the format to work out the header and body size */ va_start(ap, format); @@ -541,12 +517,21 @@ BOOL msrpc_gen(DATA_BLOB *blob, head_size += 8; data_size += str_charnum(s) * 2; break; + case 'A': + s = va_arg(ap, char *); + head_size += 8; + data_size += str_ascii_charnum(s); + break; case 'a': + unicode = va_arg(ap, BOOL); n = va_arg(ap, int); s = va_arg(ap, char *); - data_size += (str_charnum(s) * 2) + 4; + if (unicode) { + data_size += (str_charnum(s) * 2) + 4; + } else { + data_size += (str_ascii_charnum(s)) + 4; + } break; - case 'A': case 'B': b = va_arg(ap, uint8 *); head_size += 8; @@ -586,20 +571,39 @@ 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': + s = va_arg(ap, char *); + n = str_ascii_charnum(s); + SSVAL(blob->data, head_ofs, n); head_ofs += 2; + SSVAL(blob->data, head_ofs, n); head_ofs += 2; + SIVAL(blob->data, head_ofs, data_ofs); head_ofs += 4; + push_string(NULL, blob->data+data_ofs, s, n, STR_ASCII|STR_NOALIGN); + data_ofs += n; + break; case 'a': + unicode = va_arg(ap, BOOL); 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); + if (unicode) { + 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; + } else { + n = str_ascii_charnum(s); + SSVAL(blob->data, data_ofs, n); data_ofs += 2; + if (0 < n) { + push_string(NULL, blob->data+data_ofs, s, n, + STR_ASCII|STR_NOALIGN); + } + data_ofs += n; } - data_ofs += n*2; break; - case 'A': case 'B': b = va_arg(ap, uint8 *); n = va_arg(ap, int); @@ -714,7 +718,7 @@ BOOL msrpc_parse(DATA_BLOB *blob, break; case 'C': s = va_arg(ap, char *); - head_ofs += pull_string(NULL, p, blob->data+head_ofs, -1, + head_ofs += pull_string(NULL, p, blob->data+head_ofs, sizeof(p), blob->length - head_ofs, STR_ASCII|STR_TERMINATE); if (strcmp(s, p) != 0) { -- cgit From 251ea1e6776401005e302addd56a689c01924426 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Wed, 19 Feb 2003 12:31:16 +0000 Subject: Merge minor library fixes from HEAD to 3.0. - setenv() replacement - mimir's ASN1/SPNEGO typo fixes - (size_t)-1 fixes for push_* returns - function argument signed/unsigned correction - ASN1 error handling (ensure we don't use initiailsed data) - extra net ads join error checking - allow 'set security discriptor' to fail - escape ldap strings in libads. - getgrouplist() correctness fixes (include primary gid) Andrew Bartlett (This used to be commit e9d6e2ea9a3dc01d3849b925c50702cda6ddf225) --- source3/libsmb/clispnego.c | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) (limited to 'source3/libsmb/clispnego.c') diff --git a/source3/libsmb/clispnego.c b/source3/libsmb/clispnego.c index 3e28baa417..41b5c3f990 100644 --- a/source3/libsmb/clispnego.c +++ b/source3/libsmb/clispnego.c @@ -345,7 +345,7 @@ DATA_BLOB spnego_gen_negTokenTarg(const char *principal, int time_offset) /* parse a spnego NTLMSSP challenge packet giving two security blobs */ -BOOL spnego_parse_challenge(DATA_BLOB blob, +BOOL spnego_parse_challenge(const DATA_BLOB blob, DATA_BLOB *chal1, DATA_BLOB *chal2) { BOOL ret; @@ -387,7 +387,7 @@ BOOL spnego_parse_challenge(DATA_BLOB blob, /* - generate a SPNEGO NTLMSSP auth packet. This will contain the encrypted passwords + generate a SPNEGO auth packet. This will contain the encrypted passwords */ DATA_BLOB spnego_gen_auth(DATA_BLOB blob) { @@ -412,7 +412,7 @@ DATA_BLOB spnego_gen_auth(DATA_BLOB blob) } /* - parse a SPNEGO NTLMSSP auth packet. This contains the encrypted passwords + parse a SPNEGO auth packet. This contains the encrypted passwords */ BOOL spnego_parse_auth(DATA_BLOB blob, DATA_BLOB *auth) { @@ -447,11 +447,11 @@ DATA_BLOB spnego_gen_auth_response(DATA_BLOB *ntlmssp_reply, NTSTATUS nt_status) uint8 negResult; if (NT_STATUS_IS_OK(nt_status)) { - negResult = SPNGEO_NEG_RESULT_ACCEPT; + negResult = SPNEGO_NEG_RESULT_ACCEPT; } else if (NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) { - negResult = SPNGEO_NEG_RESULT_INCOMPLETE; + negResult = SPNEGO_NEG_RESULT_INCOMPLETE; } else { - negResult = SPNGEO_NEG_RESULT_REJECT; + negResult = SPNEGO_NEG_RESULT_REJECT; } ZERO_STRUCT(data); @@ -461,7 +461,8 @@ DATA_BLOB spnego_gen_auth_response(DATA_BLOB *ntlmssp_reply, NTSTATUS nt_status) asn1_push_tag(&data, ASN1_CONTEXT(0)); asn1_write_enumerated(&data, negResult); asn1_pop_tag(&data); - if (negResult == SPNGEO_NEG_RESULT_INCOMPLETE) { + + if (negResult == SPNEGO_NEG_RESULT_INCOMPLETE) { asn1_push_tag(&data,ASN1_CONTEXT(1)); asn1_write_OID(&data, OID_NTLMSSP); asn1_pop_tag(&data); -- cgit From d1221c9b6c369113a531063737890b58d89bf6fe Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Mon, 24 Feb 2003 02:55:00 +0000 Subject: Merge from HEAD client-side authentication changes: - new kerberos code, allowing the account to change it's own password without special SD settings required - NTLMSSP client code, now seperated from cliconnect.c - NTLMv2 client code - SMB signing fixes Andrew Bartlett (This used to be commit 837680ca517982f2e5944730581a83012d4181ae) --- source3/libsmb/clispnego.c | 321 ++++++--------------------------------------- 1 file changed, 37 insertions(+), 284 deletions(-) (limited to 'source3/libsmb/clispnego.c') diff --git a/source3/libsmb/clispnego.c b/source3/libsmb/clispnego.c index 41b5c3f990..e93f1855dd 100644 --- a/source3/libsmb/clispnego.c +++ b/source3/libsmb/clispnego.c @@ -481,297 +481,50 @@ DATA_BLOB spnego_gen_auth_response(DATA_BLOB *ntlmssp_reply, NTSTATUS nt_status) } /* - this is a tiny msrpc packet generator. I am only using this to - avoid tying this code to a particular varient of our rpc code. This - generator is not general enough for all our rpc needs, its just - enough for the spnego/ntlmssp code - - format specifiers are: - - U = unicode string (input is unix string) - a = address (input is BOOL unicode, char *unix_string) - (1 byte type, 1 byte length, unicode/ASCII string, all inline) - A = ASCII string (input is unix string) - B = data blob (pointer + length) - b = data blob in header (pointer + length) - D - d = word (4 bytes) - C = constant ascii string - */ -BOOL msrpc_gen(DATA_BLOB *blob, - const char *format, ...) + parse a SPNEGO NTLMSSP auth packet. This contains the encrypted passwords +*/ +BOOL spnego_parse_auth_response(DATA_BLOB blob, NTSTATUS nt_status, + DATA_BLOB *auth) { - int i, n; - va_list ap; - char *s; - uint8 *b; - int head_size=0, data_size=0; - int head_ofs, data_ofs; - BOOL unicode; - - /* first scan the format to work out the header and body size */ - va_start(ap, format); - for (i=0; format[i]; i++) { - switch (format[i]) { - case 'U': - s = va_arg(ap, char *); - head_size += 8; - data_size += str_charnum(s) * 2; - break; - case 'A': - s = va_arg(ap, char *); - head_size += 8; - data_size += str_ascii_charnum(s); - break; - case 'a': - unicode = va_arg(ap, BOOL); - n = va_arg(ap, int); - s = va_arg(ap, char *); - if (unicode) { - data_size += (str_charnum(s) * 2) + 4; - } else { - data_size += (str_ascii_charnum(s)) + 4; - } - break; - case 'B': - b = va_arg(ap, uint8 *); - head_size += 8; - data_size += va_arg(ap, int); - break; - case 'b': - b = va_arg(ap, uint8 *); - head_size += va_arg(ap, int); - break; - case 'd': - n = va_arg(ap, int); - head_size += 4; - break; - case 'C': - s = va_arg(ap, char *); - head_size += str_charnum(s) + 1; - break; - } - } - va_end(ap); - - /* allocate the space, then scan the format again to fill in the values */ - *blob = data_blob(NULL, head_size + data_size); - - head_ofs = 0; - data_ofs = head_size; - - va_start(ap, format); - for (i=0; format[i]; i++) { - switch (format[i]) { - case 'U': - s = va_arg(ap, char *); - n = str_charnum(s); - SSVAL(blob->data, head_ofs, n*2); head_ofs += 2; - SSVAL(blob->data, head_ofs, n*2); head_ofs += 2; - SIVAL(blob->data, head_ofs, data_ofs); head_ofs += 4; - push_string(NULL, blob->data+data_ofs, s, n*2, STR_UNICODE|STR_NOALIGN); - data_ofs += n*2; - break; - case 'A': - s = va_arg(ap, char *); - n = str_ascii_charnum(s); - SSVAL(blob->data, head_ofs, n); head_ofs += 2; - SSVAL(blob->data, head_ofs, n); head_ofs += 2; - SIVAL(blob->data, head_ofs, data_ofs); head_ofs += 4; - push_string(NULL, blob->data+data_ofs, s, n, STR_ASCII|STR_NOALIGN); - data_ofs += n; - break; - case 'a': - unicode = va_arg(ap, BOOL); - n = va_arg(ap, int); - SSVAL(blob->data, data_ofs, n); data_ofs += 2; - s = va_arg(ap, char *); - if (unicode) { - 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; - } else { - n = str_ascii_charnum(s); - SSVAL(blob->data, data_ofs, n); data_ofs += 2; - if (0 < n) { - push_string(NULL, blob->data+data_ofs, s, n, - STR_ASCII|STR_NOALIGN); - } - data_ofs += n; - } - break; - - case 'B': - b = va_arg(ap, uint8 *); - n = va_arg(ap, int); - SSVAL(blob->data, head_ofs, n); head_ofs += 2; - SSVAL(blob->data, head_ofs, n); head_ofs += 2; - SIVAL(blob->data, head_ofs, data_ofs); head_ofs += 4; - memcpy(blob->data+data_ofs, b, n); - data_ofs += n; - break; - case 'd': - n = va_arg(ap, int); - SIVAL(blob->data, head_ofs, n); head_ofs += 4; - break; - case 'b': - b = va_arg(ap, uint8 *); - n = va_arg(ap, int); - memcpy(blob->data + head_ofs, b, n); - head_ofs += n; - break; - case 'C': - s = va_arg(ap, char *); - head_ofs += push_string(NULL, blob->data+head_ofs, s, -1, - STR_ASCII|STR_TERMINATE); - break; - } - } - va_end(ap); + ASN1_DATA data; + uint8 negResult; - return True; -} + if (NT_STATUS_IS_OK(nt_status)) { + negResult = SPNEGO_NEG_RESULT_ACCEPT; + } else if (NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) { + negResult = SPNEGO_NEG_RESULT_INCOMPLETE; + } else { + negResult = SPNEGO_NEG_RESULT_REJECT; + } + asn1_load(&data, blob); + asn1_start_tag(&data, ASN1_CONTEXT(1)); + asn1_start_tag(&data, ASN1_SEQUENCE(0)); + asn1_start_tag(&data, ASN1_CONTEXT(0)); + asn1_check_enumerated(&data, negResult); + asn1_end_tag(&data); -/* - this is a tiny msrpc packet parser. This the the partner of msrpc_gen - - 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) - C = constant ascii string - */ -BOOL msrpc_parse(DATA_BLOB *blob, - const char *format, ...) -{ - int i; - va_list ap; - char **ps, *s; - DATA_BLOB *b; - int head_ofs = 0; - uint16 len1, len2; - uint32 ptr; - uint32 *v; - pstring p; - - va_start(ap, format); - for (i=0; format[i]; i++) { - switch (format[i]) { - case 'U': - 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 || (len1&1) || ptr + len1 > blob->length) { - return False; - } - ps = va_arg(ap, char **); - pull_string(NULL, p, blob->data + ptr, -1, len1, - 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; - 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; - } - b = (DATA_BLOB *)va_arg(ap, void *); - *b = data_blob(blob->data + ptr, len1); - break; - case 'b': - b = (DATA_BLOB *)va_arg(ap, void *); - len1 = va_arg(ap, unsigned); - *b = data_blob(blob->data + head_ofs, len1); - head_ofs += len1; - break; - case 'd': - v = va_arg(ap, uint32 *); - *v = IVAL(blob->data, head_ofs); head_ofs += 4; - break; - case 'C': - s = va_arg(ap, char *); - head_ofs += pull_string(NULL, p, blob->data+head_ofs, sizeof(p), - blob->length - head_ofs, - STR_ASCII|STR_TERMINATE); - if (strcmp(s, p) != 0) { - return False; - } - break; - } + if (negResult == SPNEGO_NEG_RESULT_INCOMPLETE) { + asn1_start_tag(&data,ASN1_CONTEXT(1)); + asn1_check_OID(&data, OID_NTLMSSP); + asn1_end_tag(&data); + + asn1_start_tag(&data,ASN1_CONTEXT(2)); + asn1_read_OctetString(&data, auth); + asn1_end_tag(&data); } - va_end(ap); - return True; -} + asn1_end_tag(&data); + asn1_end_tag(&data); -/** - * Print out the NTLMSSP flags for debugging - */ + if (data.has_error) { + DEBUG(3,("spnego_parse_auth_response failed at %d\n", (int)data.ofs)); + asn1_free(&data); + data_blob_free(auth); + return False; + } -void debug_ntlmssp_flags(uint32 neg_flags) -{ - DEBUG(3,("Got NTLMSSP neg_flags=0x%08x\n", neg_flags)); - - if (neg_flags & NTLMSSP_NEGOTIATE_UNICODE) - DEBUGADD(4, (" NTLMSSP_NEGOTIATE_UNICODE\n")); - if (neg_flags & NTLMSSP_NEGOTIATE_OEM) - DEBUGADD(4, (" NTLMSSP_NEGOTIATE_OEM\n")); - if (neg_flags & NTLMSSP_REQUEST_TARGET) - DEBUGADD(4, (" NTLMSSP_REQUEST_TARGET\n")); - if (neg_flags & NTLMSSP_NEGOTIATE_SIGN) - DEBUGADD(4, (" NTLMSSP_NEGOTIATE_SIGN\n")); - if (neg_flags & NTLMSSP_NEGOTIATE_SEAL) - DEBUGADD(4, (" NTLMSSP_NEGOTIATE_SEAL\n")); - if (neg_flags & NTLMSSP_NEGOTIATE_LM_KEY) - DEBUGADD(4, (" NTLMSSP_NEGOTIATE_LM_KEY\n")); - if (neg_flags & NTLMSSP_NEGOTIATE_NETWARE) - DEBUGADD(4, (" NTLMSSP_NEGOTIATE_NETWARE\n")); - if (neg_flags & NTLMSSP_NEGOTIATE_NTLM) - DEBUGADD(4, (" NTLMSSP_NEGOTIATE_NTLM\n")); - if (neg_flags & NTLMSSP_NEGOTIATE_DOMAIN_SUPPLIED) - DEBUGADD(4, (" NTLMSSP_NEGOTIATE_DOMAIN_SUPPLIED\n")); - if (neg_flags & NTLMSSP_NEGOTIATE_WORKSTATION_SUPPLIED) - DEBUGADD(4, (" NTLMSSP_NEGOTIATE_WORKSTATION_SUPPLIED\n")); - if (neg_flags & NTLMSSP_NEGOTIATE_THIS_IS_LOCAL_CALL) - DEBUGADD(4, (" NTLMSSP_NEGOTIATE_THIS_IS_LOCAL_CALL\n")); - if (neg_flags & NTLMSSP_NEGOTIATE_ALWAYS_SIGN) - DEBUGADD(4, (" NTLMSSP_NEGOTIATE_ALWAYS_SIGN\n")); - if (neg_flags & NTLMSSP_NEGOTIATE_NTLM2) - DEBUGADD(4, (" NTLMSSP_NEGOTIATE_NTLM2\n")); - if (neg_flags & NTLMSSP_CHAL_TARGET_INFO) - DEBUGADD(4, (" NTLMSSP_CHAL_TARGET_INFO\n")); - if (neg_flags & NTLMSSP_NEGOTIATE_128) - DEBUGADD(4, (" NTLMSSP_NEGOTIATE_128\n")); - if (neg_flags & NTLMSSP_NEGOTIATE_KEY_EXCH) - DEBUGADD(4, (" NTLMSSP_NEGOTIATE_KEY_EXCH\n")); + asn1_free(&data); + return True; } -- cgit From ec458fa87e3ee858be39671f575e21a9350674b6 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Mon, 17 Mar 2003 22:45:16 +0000 Subject: Merge from HEAD - sync up SessionSetup code to HEAD, including Luke Howard's session key and auth verifier patches. Andrew Bartlett (This used to be commit 3f9616a68a855acbae3f405c27ee2358fbe7ba2c) --- source3/libsmb/clispnego.c | 29 ++++++++++++++++------------- 1 file changed, 16 insertions(+), 13 deletions(-) (limited to 'source3/libsmb/clispnego.c') diff --git a/source3/libsmb/clispnego.c b/source3/libsmb/clispnego.c index e93f1855dd..53f7eb6e7d 100644 --- a/source3/libsmb/clispnego.c +++ b/source3/libsmb/clispnego.c @@ -3,6 +3,7 @@ simple kerberos5/SPNEGO routines Copyright (C) Andrew Tridgell 2001 Copyright (C) Jim McDonough 2002 + Copyright (C) Luke Howard 2003 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 @@ -259,7 +260,7 @@ BOOL parse_negTokenTarg(DATA_BLOB blob, char *OIDs[ASN1_MAX_OIDS], DATA_BLOB *se /* generate a krb5 GSS-API wrapper packet given a ticket */ -DATA_BLOB spnego_gen_krb5_wrap(DATA_BLOB ticket) +DATA_BLOB spnego_gen_krb5_wrap(DATA_BLOB ticket, const uint8 tok_id[2]) { ASN1_DATA data; DATA_BLOB ret; @@ -268,7 +269,8 @@ DATA_BLOB spnego_gen_krb5_wrap(DATA_BLOB ticket) asn1_push_tag(&data, ASN1_APPLICATION(0)); asn1_write_OID(&data, OID_KERBEROS5); - asn1_write_BOOLEAN(&data, 0); + + asn1_write(&data, tok_id, 2); asn1_write(&data, ticket.data, ticket.length); asn1_pop_tag(&data); @@ -286,7 +288,7 @@ DATA_BLOB spnego_gen_krb5_wrap(DATA_BLOB ticket) /* parse a krb5 GSS-API wrapper packet giving a ticket */ -BOOL spnego_parse_krb5_wrap(DATA_BLOB blob, DATA_BLOB *ticket) +BOOL spnego_parse_krb5_wrap(DATA_BLOB blob, DATA_BLOB *ticket, uint8 tok_id[2]) { BOOL ret; ASN1_DATA data; @@ -295,15 +297,15 @@ BOOL spnego_parse_krb5_wrap(DATA_BLOB blob, DATA_BLOB *ticket) asn1_load(&data, blob); asn1_start_tag(&data, ASN1_APPLICATION(0)); asn1_check_OID(&data, OID_KERBEROS5); - asn1_check_BOOLEAN(&data, 0); data_remaining = asn1_tag_remaining(&data); - if (data_remaining < 1) { + if (data_remaining < 3) { data.has_error = True; } else { - - *ticket = data_blob(data.data, data_remaining); + asn1_read(&data, tok_id, 2); + data_remaining -= 2; + *ticket = data_blob(NULL, data_remaining); asn1_read(&data, ticket->data, ticket->length); } @@ -330,7 +332,7 @@ DATA_BLOB spnego_gen_negTokenTarg(const char *principal, int time_offset) tkt = krb5_get_ticket(principal, time_offset); /* wrap that up in a nice GSS-API wrapping */ - tkt_wrapped = spnego_gen_krb5_wrap(tkt); + tkt_wrapped = spnego_gen_krb5_wrap(tkt, TOK_ID_KRB_AP_REQ); /* and wrap that in a shiny SPNEGO wrapper */ targ = gen_negTokenTarg(krb_mechs, tkt_wrapped); @@ -438,9 +440,10 @@ BOOL spnego_parse_auth(DATA_BLOB blob, DATA_BLOB *auth) } /* - generate a minimal SPNEGO NTLMSSP response packet. Doesn't contain much. + generate a minimal SPNEGO response packet. Doesn't contain much. */ -DATA_BLOB spnego_gen_auth_response(DATA_BLOB *ntlmssp_reply, NTSTATUS nt_status) +DATA_BLOB spnego_gen_auth_response(DATA_BLOB *reply, NTSTATUS nt_status, + const char *mechOID) { ASN1_DATA data; DATA_BLOB ret; @@ -462,13 +465,13 @@ DATA_BLOB spnego_gen_auth_response(DATA_BLOB *ntlmssp_reply, NTSTATUS nt_status) asn1_write_enumerated(&data, negResult); asn1_pop_tag(&data); - if (negResult == SPNEGO_NEG_RESULT_INCOMPLETE) { + if (reply->data != NULL) { asn1_push_tag(&data,ASN1_CONTEXT(1)); - asn1_write_OID(&data, OID_NTLMSSP); + asn1_write_OID(&data, mechOID); asn1_pop_tag(&data); asn1_push_tag(&data,ASN1_CONTEXT(2)); - asn1_write_OctetString(&data, ntlmssp_reply->data, ntlmssp_reply->length); + asn1_write_OctetString(&data, reply->data, reply->length); asn1_pop_tag(&data); } -- cgit From 4f276f969633f3c39e3ffc609b167930ff7fd42c Mon Sep 17 00:00:00 2001 From: Jim McDonough Date: Fri, 30 May 2003 20:11:34 +0000 Subject: More on bug 137: rename more of krb5_xxx functions to not start with krb5_ (This used to be commit 10f1da3f4a9680a039a2aa26301b97e31c06c38d) --- source3/libsmb/clispnego.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb/clispnego.c') diff --git a/source3/libsmb/clispnego.c b/source3/libsmb/clispnego.c index 53f7eb6e7d..bb48f57915 100644 --- a/source3/libsmb/clispnego.c +++ b/source3/libsmb/clispnego.c @@ -329,7 +329,7 @@ DATA_BLOB spnego_gen_negTokenTarg(const char *principal, int time_offset) const char *krb_mechs[] = {OID_KERBEROS5_OLD, OID_NTLMSSP, NULL}; /* get a kerberos ticket for the service */ - tkt = krb5_get_ticket(principal, time_offset); + tkt = cli_krb5_get_ticket(principal, time_offset); /* wrap that up in a nice GSS-API wrapping */ tkt_wrapped = spnego_gen_krb5_wrap(tkt, TOK_ID_KRB_AP_REQ); -- cgit From 4632786cfb193dd80ce04206912297186e871814 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 25 Jul 2003 23:15:30 +0000 Subject: W00t! Client smb signing is now working correctly with krb5 and w2k server. Server code *should* also work (I'll check shortly). May be the odd memory leak. Problem was we (a) weren't setting signing on in the client krb5 sessionsetup code (b) we need to ask for a subkey... (c). The client and server need to ask for local and remote subkeys respectively. Thanks to Paul Nelson @ Thursby for some sage advice on this :-). Jeremy. (This used to be commit 3f9e3b60709df5ab755045a093e642510d4cde00) --- source3/libsmb/clispnego.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'source3/libsmb/clispnego.c') diff --git a/source3/libsmb/clispnego.c b/source3/libsmb/clispnego.c index bb48f57915..fbf8323679 100644 --- a/source3/libsmb/clispnego.c +++ b/source3/libsmb/clispnego.c @@ -323,13 +323,13 @@ BOOL spnego_parse_krb5_wrap(DATA_BLOB blob, DATA_BLOB *ticket, uint8 tok_id[2]) generate a SPNEGO negTokenTarg packet, ready for a EXTENDED_SECURITY kerberos session setup */ -DATA_BLOB spnego_gen_negTokenTarg(const char *principal, int time_offset) +DATA_BLOB spnego_gen_negTokenTarg(const char *principal, int time_offset, unsigned char session_key_krb5[16]) { DATA_BLOB tkt, tkt_wrapped, targ; const char *krb_mechs[] = {OID_KERBEROS5_OLD, OID_NTLMSSP, NULL}; - /* get a kerberos ticket for the service */ - tkt = cli_krb5_get_ticket(principal, time_offset); + /* get a kerberos ticket for the service and extract the session key */ + tkt = cli_krb5_get_ticket(principal, time_offset, session_key_krb5); /* wrap that up in a nice GSS-API wrapping */ tkt_wrapped = spnego_gen_krb5_wrap(tkt, TOK_ID_KRB_AP_REQ); -- cgit From 9f2e6167d22cc06fa94495574fc29d6bcbb1dd8a Mon Sep 17 00:00:00 2001 From: Jim McDonough Date: Fri, 1 Aug 2003 15:21:20 +0000 Subject: Update my copyrights according to my agreement with IBM (This used to be commit c9b209be2b17c2e4677cc30b46b1074f48878f43) --- source3/libsmb/clispnego.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb/clispnego.c') diff --git a/source3/libsmb/clispnego.c b/source3/libsmb/clispnego.c index fbf8323679..b0570b09b6 100644 --- a/source3/libsmb/clispnego.c +++ b/source3/libsmb/clispnego.c @@ -2,7 +2,7 @@ Unix SMB/CIFS implementation. simple kerberos5/SPNEGO routines Copyright (C) Andrew Tridgell 2001 - Copyright (C) Jim McDonough 2002 + Copyright (C) Jim McDonough 2002 Copyright (C) Luke Howard 2003 This program is free software; you can redistribute it and/or modify -- cgit From d7ec3205e9f8202c47931d7362a18ab2a36c60ea Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Wed, 13 Aug 2003 20:27:18 +0000 Subject: Don't wrap up anything that is not there. Otherwise upper layers can not figure that we got no ticket. Volker (This used to be commit 2a724a7a873c08f14644427766bfd48908ddb501) --- source3/libsmb/clispnego.c | 3 +++ 1 file changed, 3 insertions(+) (limited to 'source3/libsmb/clispnego.c') diff --git a/source3/libsmb/clispnego.c b/source3/libsmb/clispnego.c index b0570b09b6..63076a1a1c 100644 --- a/source3/libsmb/clispnego.c +++ b/source3/libsmb/clispnego.c @@ -331,6 +331,9 @@ DATA_BLOB spnego_gen_negTokenTarg(const char *principal, int time_offset, unsign /* get a kerberos ticket for the service and extract the session key */ tkt = cli_krb5_get_ticket(principal, time_offset, session_key_krb5); + if (tkt.data == NULL) + return tkt; + /* wrap that up in a nice GSS-API wrapping */ tkt_wrapped = spnego_gen_krb5_wrap(tkt, TOK_ID_KRB_AP_REQ); -- cgit From fcbfc7ad0669009957c65fa61bb20df75a9701b4 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Sat, 22 Nov 2003 13:19:38 +0000 Subject: Changes all over the shop, but all towards: - NTLM2 support in the server - KEY_EXCH support in the server - variable length session keys. In detail: - NTLM2 is an extension of NTLMv1, that is compatible with existing domain controllers (unlike NTLMv2, which requires a DC upgrade). * This is known as 'NTLMv2 session security' * (This is not yet implemented on the RPC pipes however, so there may well still be issues for PDC setups, particuarly around password changes. We do not fully understand the sign/seal implications of NTLM2 on RPC pipes.) This requires modifications to our authentication subsystem, as we must handle the 'challege' input into the challenge-response algorithm being changed. This also needs to be turned off for 'security=server', which does not support this. - KEY_EXCH is another 'security' mechanism, whereby the session key actually used by the server is sent by the client, rather than being the shared-secret directly or indirectly. - As both these methods change the session key, the auth subsystem needed to be changed, to 'override' session keys provided by the backend. - There has also been a major overhaul of the NTLMSSP subsystem, to merge the 'client' and 'server' functions, so they both operate on a single structure. This should help the SPNEGO implementation. - The 'names blob' in NTLMSSP is always in unicode - never in ascii. Don't make an ascii version ever. - The other big change is to allow variable length session keys. We have always assumed that session keys are 16 bytes long - and padded to this length if shorter. However, Kerberos session keys are 8 bytes long, when the krb5 login uses DES. * This fix allows SMB signging on machines not yet running MIT KRB5 1.3.1. * - Add better DEBUG() messages to ntlm_auth, warning administrators of misconfigurations that prevent access to the privileged pipe. This should help reduce some of the 'it just doesn't work' issues. - Fix data_blob_talloc() to behave the same way data_blob() does when passed a NULL data pointer. (just allocate) REMEMBER to make clean after this commit - I have changed plenty of data structures... (This used to be commit f3bbc87b0dac63426cda6fac7a295d3aad810ecc) --- source3/libsmb/clispnego.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb/clispnego.c') diff --git a/source3/libsmb/clispnego.c b/source3/libsmb/clispnego.c index 63076a1a1c..92543736ff 100644 --- a/source3/libsmb/clispnego.c +++ b/source3/libsmb/clispnego.c @@ -323,7 +323,7 @@ BOOL spnego_parse_krb5_wrap(DATA_BLOB blob, DATA_BLOB *ticket, uint8 tok_id[2]) generate a SPNEGO negTokenTarg packet, ready for a EXTENDED_SECURITY kerberos session setup */ -DATA_BLOB spnego_gen_negTokenTarg(const char *principal, int time_offset, unsigned char session_key_krb5[16]) +DATA_BLOB spnego_gen_negTokenTarg(const char *principal, int time_offset, DATA_BLOB *session_key_krb5) { DATA_BLOB tkt, tkt_wrapped, targ; const char *krb_mechs[] = {OID_KERBEROS5_OLD, OID_NTLMSSP, NULL}; -- cgit From 7d068355aae99060acac03c6633509545aa782a4 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Thu, 8 Jan 2004 08:19:18 +0000 Subject: This merges in my 'always use ADS' patch. Tested on a mix of NT and ADS domains, this patch ensures that we always use the ADS backend when security=ADS, and the remote server is capable. The routines used for this behaviour have been upgraded to modern Samba codeing standards. This is a change in behaviour for mixed mode domains, and if the trusted domain cannot be reached with our current krb5.conf file, we will show that domain as disconnected. This is in line with existing behaviour for native mode domains, and for our primary domain. As a consequence of testing this patch, I found that our kerberos error handling was well below par - we would often throw away useful error values. These changes move more routines to ADS_STATUS to return kerberos errors. Also found when valgrinding the setup, fix a few memory leaks. While sniffing the resultant connections, I noticed we would query our list of trusted domains twice - so I have reworked some of the code to avoid that. Andrew Bartlett (This used to be commit 7c34de8096b86d2869e7177420fe129bd0c7541d) --- source3/libsmb/clispnego.c | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) (limited to 'source3/libsmb/clispnego.c') diff --git a/source3/libsmb/clispnego.c b/source3/libsmb/clispnego.c index 92543736ff..e6cadc466c 100644 --- a/source3/libsmb/clispnego.c +++ b/source3/libsmb/clispnego.c @@ -323,27 +323,30 @@ BOOL spnego_parse_krb5_wrap(DATA_BLOB blob, DATA_BLOB *ticket, uint8 tok_id[2]) generate a SPNEGO negTokenTarg packet, ready for a EXTENDED_SECURITY kerberos session setup */ -DATA_BLOB spnego_gen_negTokenTarg(const char *principal, int time_offset, DATA_BLOB *session_key_krb5) +int spnego_gen_negTokenTarg(const char *principal, int time_offset, + DATA_BLOB *targ, + DATA_BLOB *session_key_krb5) { - DATA_BLOB tkt, tkt_wrapped, targ; + int retval; + DATA_BLOB tkt, tkt_wrapped; const char *krb_mechs[] = {OID_KERBEROS5_OLD, OID_NTLMSSP, NULL}; /* get a kerberos ticket for the service and extract the session key */ - tkt = cli_krb5_get_ticket(principal, time_offset, session_key_krb5); + retval = cli_krb5_get_ticket(principal, time_offset, &tkt, session_key_krb5); - if (tkt.data == NULL) - return tkt; + if (retval) + return retval; /* wrap that up in a nice GSS-API wrapping */ tkt_wrapped = spnego_gen_krb5_wrap(tkt, TOK_ID_KRB_AP_REQ); /* and wrap that in a shiny SPNEGO wrapper */ - targ = gen_negTokenTarg(krb_mechs, tkt_wrapped); + *targ = gen_negTokenTarg(krb_mechs, tkt_wrapped); data_blob_free(&tkt_wrapped); data_blob_free(&tkt); - return targ; + return retval; } -- cgit From 792776782e18417b8e6e63954db153f4d3d0d558 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 24 Jun 2004 19:25:20 +0000 Subject: r1240: Ensure we don't shadow Heimdal globals. Jeremy. (This used to be commit 464d2e90480c676688a851a141aabddf992e0b0e) --- source3/libsmb/clispnego.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'source3/libsmb/clispnego.c') diff --git a/source3/libsmb/clispnego.c b/source3/libsmb/clispnego.c index e6cadc466c..85b7bd9e1e 100644 --- a/source3/libsmb/clispnego.c +++ b/source3/libsmb/clispnego.c @@ -141,9 +141,9 @@ BOOL spnego_parse_negTokenInit(DATA_BLOB blob, asn1_start_tag(&data,ASN1_CONTEXT(0)); asn1_start_tag(&data,ASN1_SEQUENCE(0)); for (i=0; asn1_tag_remaining(&data) > 0 && i < ASN1_MAX_OIDS; i++) { - char *oid = NULL; - asn1_read_OID(&data,&oid); - OIDs[i] = oid; + char *oid_str = NULL; + asn1_read_OID(&data,&oid_str); + OIDs[i] = oid_str; } OIDs[i] = NULL; asn1_end_tag(&data); @@ -230,9 +230,9 @@ BOOL parse_negTokenTarg(DATA_BLOB blob, char *OIDs[ASN1_MAX_OIDS], DATA_BLOB *se asn1_start_tag(&data, ASN1_CONTEXT(0)); asn1_start_tag(&data, ASN1_SEQUENCE(0)); for (i=0; asn1_tag_remaining(&data) > 0 && i < ASN1_MAX_OIDS; i++) { - char *oid = NULL; - asn1_read_OID(&data,&oid); - OIDs[i] = oid; + char *oid_str = NULL; + asn1_read_OID(&data,&oid_str); + OIDs[i] = oid_str; } OIDs[i] = NULL; asn1_end_tag(&data); -- cgit From 9840db418bad5a39edc4a32a1786f5e2d2c9dff8 Mon Sep 17 00:00:00 2001 From: Derrell Lipman Date: Thu, 31 Mar 2005 05:06:04 +0000 Subject: r6149: Fixes bugs #2498 and 2484. 1. using smbc_getxattr() et al, one may now request all access control entities in the ACL without getting all other NT attributes. 2. added the ability to exclude specified attributes from the result set provided by smbc_getxattr() et al, when requesting all attributes, all NT attributes, or all DOS attributes. 3. eliminated all compiler warnings, including when --enable-developer compiler flags are in use. removed -Wcast-qual flag from list, as that is specifically to force warnings in the case of casting away qualifiers. Note: In the process of eliminating compiler warnings, a few nasties were discovered. In the file libads/sasl.c, PRIVATE kerberos interfaces are being used; and in libsmb/clikrb5.c, both PRIAVE and DEPRECATED kerberos interfaces are being used. Someone who knows kerberos should look at these and determine if there is an alternate method of accomplishing the task. (This used to be commit 994694f7f26da5099f071e1381271a70407f33bb) --- source3/libsmb/clispnego.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'source3/libsmb/clispnego.c') diff --git a/source3/libsmb/clispnego.c b/source3/libsmb/clispnego.c index 85b7bd9e1e..5d07999bc3 100644 --- a/source3/libsmb/clispnego.c +++ b/source3/libsmb/clispnego.c @@ -338,7 +338,8 @@ int spnego_gen_negTokenTarg(const char *principal, int time_offset, return retval; /* wrap that up in a nice GSS-API wrapping */ - tkt_wrapped = spnego_gen_krb5_wrap(tkt, TOK_ID_KRB_AP_REQ); + tkt_wrapped = spnego_gen_krb5_wrap( + tkt, CONST_ADD(const uint8 *, TOK_ID_KRB_AP_REQ)); /* and wrap that in a shiny SPNEGO wrapper */ *targ = gen_negTokenTarg(krb_mechs, tkt_wrapped); -- cgit From f24d88cf9da46680d52b42b92bd484e7b09ce99b Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Tue, 31 May 2005 13:46:45 +0000 Subject: r7139: trying to reduce the number of diffs between trunk and 3.0; changing version to 3.0.20pre1 (This used to be commit 9727d05241574042dd3aa8844ae5c701d22e2da1) --- source3/libsmb/clispnego.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'source3/libsmb/clispnego.c') diff --git a/source3/libsmb/clispnego.c b/source3/libsmb/clispnego.c index 5d07999bc3..85b7bd9e1e 100644 --- a/source3/libsmb/clispnego.c +++ b/source3/libsmb/clispnego.c @@ -338,8 +338,7 @@ int spnego_gen_negTokenTarg(const char *principal, int time_offset, return retval; /* wrap that up in a nice GSS-API wrapping */ - tkt_wrapped = spnego_gen_krb5_wrap( - tkt, CONST_ADD(const uint8 *, TOK_ID_KRB_AP_REQ)); + tkt_wrapped = spnego_gen_krb5_wrap(tkt, TOK_ID_KRB_AP_REQ); /* and wrap that in a shiny SPNEGO wrapper */ *targ = gen_negTokenTarg(krb_mechs, tkt_wrapped); -- cgit From 54abd2aa66069e6baf7769c496f46d9dba18db39 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Fri, 30 Sep 2005 17:13:37 +0000 Subject: r10656: BIG merge from trunk. Features not copied over * \PIPE\unixinfo * winbindd's {group,alias}membership new functions * winbindd's lookupsids() functionality * swat (trunk changes to be reverted as per discussion with Deryck) (This used to be commit 939c3cb5d78e3a2236209b296aa8aba8bdce32d3) --- source3/libsmb/clispnego.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'source3/libsmb/clispnego.c') diff --git a/source3/libsmb/clispnego.c b/source3/libsmb/clispnego.c index 85b7bd9e1e..33fc265f79 100644 --- a/source3/libsmb/clispnego.c +++ b/source3/libsmb/clispnego.c @@ -325,14 +325,15 @@ BOOL spnego_parse_krb5_wrap(DATA_BLOB blob, DATA_BLOB *ticket, uint8 tok_id[2]) */ int spnego_gen_negTokenTarg(const char *principal, int time_offset, DATA_BLOB *targ, - DATA_BLOB *session_key_krb5) + DATA_BLOB *session_key_krb5, uint32 extra_ap_opts) { int retval; DATA_BLOB tkt, tkt_wrapped; const char *krb_mechs[] = {OID_KERBEROS5_OLD, OID_NTLMSSP, NULL}; /* get a kerberos ticket for the service and extract the session key */ - retval = cli_krb5_get_ticket(principal, time_offset, &tkt, session_key_krb5); + retval = cli_krb5_get_ticket(principal, time_offset, + &tkt, session_key_krb5, extra_ap_opts); if (retval) return retval; -- cgit From 8d7c88667190fe286971ac4fffb64ee5bd9eeeb0 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Tue, 18 Oct 2005 03:24:00 +0000 Subject: r11137: Compile with only 2 warnings (I'm still working on that code) on a gcc4 x86_64 box. Jeremy. (This used to be commit d720867a788c735e56d53d63265255830ec21208) --- source3/libsmb/clispnego.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb/clispnego.c') diff --git a/source3/libsmb/clispnego.c b/source3/libsmb/clispnego.c index 33fc265f79..6340a9bdcd 100644 --- a/source3/libsmb/clispnego.c +++ b/source3/libsmb/clispnego.c @@ -26,7 +26,7 @@ generate a negTokenInit packet given a GUID, a list of supported OIDs (the mechanisms) and a principal name string */ -DATA_BLOB spnego_gen_negTokenInit(uint8 guid[16], +DATA_BLOB spnego_gen_negTokenInit(char guid[16], const char *OIDs[], const char *principal) { -- cgit From a0d20293393f30c99d6593bd1976f11810681f9b Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Sun, 25 Dec 2005 10:27:45 +0000 Subject: r12476: Apply some const (This used to be commit a3f102f6c3ada10e74d72944e767b9b263fe83dd) --- source3/libsmb/clispnego.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb/clispnego.c') diff --git a/source3/libsmb/clispnego.c b/source3/libsmb/clispnego.c index 6340a9bdcd..cc481a066a 100644 --- a/source3/libsmb/clispnego.c +++ b/source3/libsmb/clispnego.c @@ -260,7 +260,7 @@ BOOL parse_negTokenTarg(DATA_BLOB blob, char *OIDs[ASN1_MAX_OIDS], DATA_BLOB *se /* generate a krb5 GSS-API wrapper packet given a ticket */ -DATA_BLOB spnego_gen_krb5_wrap(DATA_BLOB ticket, const uint8 tok_id[2]) +DATA_BLOB spnego_gen_krb5_wrap(const DATA_BLOB ticket, const uint8 tok_id[2]) { ASN1_DATA data; DATA_BLOB ret; -- cgit From 0af1500fc0bafe61019f1b2ab1d9e1d369221240 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Fri, 3 Feb 2006 22:19:41 +0000 Subject: r13316: Let the carnage begin.... Sync with trunk as off r13315 (This used to be commit 17e63ac4ed8325c0d44fe62b2442449f3298559f) --- source3/libsmb/clispnego.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb/clispnego.c') diff --git a/source3/libsmb/clispnego.c b/source3/libsmb/clispnego.c index cc481a066a..13bf1a866c 100644 --- a/source3/libsmb/clispnego.c +++ b/source3/libsmb/clispnego.c @@ -333,7 +333,7 @@ int spnego_gen_negTokenTarg(const char *principal, int time_offset, /* get a kerberos ticket for the service and extract the session key */ retval = cli_krb5_get_ticket(principal, time_offset, - &tkt, session_key_krb5, extra_ap_opts); + &tkt, session_key_krb5, extra_ap_opts, NULL); if (retval) return retval; -- cgit From 3ea740f5e5265103eacec2979c6c535eed30e346 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Mon, 12 Jun 2006 18:32:25 +0000 Subject: r16156: Fix storing NULL in the wrong place. Klocwork id's 127 and 128. Volker (This used to be commit 7674a4f8361d3f3b649245118b82d8a074a2760e) --- source3/libsmb/clispnego.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'source3/libsmb/clispnego.c') diff --git a/source3/libsmb/clispnego.c b/source3/libsmb/clispnego.c index 13bf1a866c..e87e9f0c7c 100644 --- a/source3/libsmb/clispnego.c +++ b/source3/libsmb/clispnego.c @@ -140,7 +140,7 @@ BOOL spnego_parse_negTokenInit(DATA_BLOB blob, asn1_start_tag(&data,ASN1_CONTEXT(0)); asn1_start_tag(&data,ASN1_SEQUENCE(0)); - for (i=0; asn1_tag_remaining(&data) > 0 && i < ASN1_MAX_OIDS; i++) { + for (i=0; asn1_tag_remaining(&data) > 0 && i < ASN1_MAX_OIDS-1; i++) { char *oid_str = NULL; asn1_read_OID(&data,&oid_str); OIDs[i] = oid_str; @@ -229,7 +229,7 @@ BOOL parse_negTokenTarg(DATA_BLOB blob, char *OIDs[ASN1_MAX_OIDS], DATA_BLOB *se asn1_start_tag(&data, ASN1_CONTEXT(0)); asn1_start_tag(&data, ASN1_SEQUENCE(0)); - for (i=0; asn1_tag_remaining(&data) > 0 && i < ASN1_MAX_OIDS; i++) { + for (i=0; asn1_tag_remaining(&data) > 0 && i < ASN1_MAX_OIDS-1; i++) { char *oid_str = NULL; asn1_read_OID(&data,&oid_str); OIDs[i] = oid_str; -- cgit From 3a8bf11ae341c34db61ef35cbdba6ff835940c79 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Fri, 16 Jun 2006 22:25:17 +0000 Subject: r16306: Error handling in this asn1 code *sucks*. Fix a generic class of memory leak bugs on error found by Klocwork (#123). Many of these functions didn't free allocated memory on error exit. Jeremy. (This used to be commit 8ef11a7c6de74024b7d535d959db2d462662a86f) --- source3/libsmb/clispnego.c | 27 ++++++++++++++++++++++++--- 1 file changed, 24 insertions(+), 3 deletions(-) (limited to 'source3/libsmb/clispnego.c') diff --git a/source3/libsmb/clispnego.c b/source3/libsmb/clispnego.c index e87e9f0c7c..3dad37d9e1 100644 --- a/source3/libsmb/clispnego.c +++ b/source3/libsmb/clispnego.c @@ -163,11 +163,18 @@ BOOL spnego_parse_negTokenInit(DATA_BLOB blob, asn1_end_tag(&data); ret = !data.has_error; + if (data.has_error) { + int j; + SAFE_FREE(principal); + for(j = 0; j < i && j < ASN1_MAX_OIDS-1; j++) { + SAFE_FREE(OIDs[j]); + } + } + asn1_free(&data); return ret; } - /* generate a negTokenTarg packet given a list of OIDs and a security blob */ @@ -212,7 +219,6 @@ DATA_BLOB gen_negTokenTarg(const char *OIDs[], DATA_BLOB blob) return ret; } - /* parse a negTokenTarg packet giving a list of OIDs and a security blob */ @@ -248,6 +254,11 @@ BOOL parse_negTokenTarg(DATA_BLOB blob, char *OIDs[ASN1_MAX_OIDS], DATA_BLOB *se asn1_end_tag(&data); if (data.has_error) { + int j; + data_blob_free(secblob); + for(j = 0; j < i && j < ASN1_MAX_OIDS-1; j++) { + SAFE_FREE(OIDs[j]); + } DEBUG(1,("Failed to parse negTokenTarg at offset %d\n", (int)data.ofs)); asn1_free(&data); return False; @@ -313,6 +324,10 @@ BOOL spnego_parse_krb5_wrap(DATA_BLOB blob, DATA_BLOB *ticket, uint8 tok_id[2]) ret = !data.has_error; + if (data.has_error) { + data_blob_free(ticket); + } + asn1_free(&data); return ret; @@ -390,6 +405,12 @@ BOOL spnego_parse_challenge(const DATA_BLOB blob, asn1_end_tag(&data); ret = !data.has_error; + + if (data.has_error) { + data_blob_free(chal1); + data_blob_free(chal2); + } + asn1_free(&data); return ret; } @@ -438,6 +459,7 @@ BOOL spnego_parse_auth(DATA_BLOB blob, DATA_BLOB *auth) if (data.has_error) { DEBUG(3,("spnego_parse_auth failed at %d\n", (int)data.ofs)); + data_blob_free(auth); asn1_free(&data); return False; } @@ -537,4 +559,3 @@ BOOL spnego_parse_auth_response(DATA_BLOB blob, NTSTATUS nt_status, asn1_free(&data); return True; } - -- cgit From a3a082b24836e50755e2086eeb35a4fee8dac17c Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Mon, 2 Oct 2006 11:03:53 +0000 Subject: r19037: Fix a segfault (This used to be commit 1c18ebe67500a59d4bf08c7e2e2c2af416bfa084) --- source3/libsmb/clispnego.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb/clispnego.c') diff --git a/source3/libsmb/clispnego.c b/source3/libsmb/clispnego.c index 3dad37d9e1..fedf7e5c6e 100644 --- a/source3/libsmb/clispnego.c +++ b/source3/libsmb/clispnego.c @@ -165,7 +165,7 @@ BOOL spnego_parse_negTokenInit(DATA_BLOB blob, ret = !data.has_error; if (data.has_error) { int j; - SAFE_FREE(principal); + SAFE_FREE(*principal); for(j = 0; j < i && j < ASN1_MAX_OIDS-1; j++) { SAFE_FREE(OIDs[j]); } -- cgit From eb00981fc363a104d43dba75a8d18cc02421bbf8 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Mon, 2 Oct 2006 12:54:49 +0000 Subject: r19041: Make us connect to Vista RC1. Apparently metze had done the same patch some weeks ago. We have some work before us, when in AD mode Vista sends "not_defined_in_RFC4178@please_ignore" as the principal..... Volker (This used to be commit af85d8ec02b36b765ceadf0a342c7eda2410034b) --- source3/libsmb/clispnego.c | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) (limited to 'source3/libsmb/clispnego.c') diff --git a/source3/libsmb/clispnego.c b/source3/libsmb/clispnego.c index fedf7e5c6e..a01c009b6e 100644 --- a/source3/libsmb/clispnego.c +++ b/source3/libsmb/clispnego.c @@ -149,13 +149,16 @@ BOOL spnego_parse_negTokenInit(DATA_BLOB blob, asn1_end_tag(&data); asn1_end_tag(&data); - asn1_start_tag(&data, ASN1_CONTEXT(3)); - asn1_start_tag(&data, ASN1_SEQUENCE(0)); - asn1_start_tag(&data, ASN1_CONTEXT(0)); - asn1_read_GeneralString(&data,principal); - asn1_end_tag(&data); - asn1_end_tag(&data); - asn1_end_tag(&data); + *principal = NULL; + if (asn1_tag_remaining(&data) > 0) { + asn1_start_tag(&data, ASN1_CONTEXT(3)); + asn1_start_tag(&data, ASN1_SEQUENCE(0)); + asn1_start_tag(&data, ASN1_CONTEXT(0)); + asn1_read_GeneralString(&data,principal); + asn1_end_tag(&data); + asn1_end_tag(&data); + asn1_end_tag(&data); + } asn1_end_tag(&data); asn1_end_tag(&data); -- cgit From 69cee2a3ec4f39aab83a8cbf55307df182bf3065 Mon Sep 17 00:00:00 2001 From: Günther Deschner Date: Thu, 8 Feb 2007 17:02:39 +0000 Subject: r21240: Fix longstanding Bug #4009. For the winbind cached ADS LDAP connection handling (ads_cached_connection()) we were (incorrectly) assuming that the service ticket lifetime equaled the tgt lifetime. For setups where the service ticket just lives 10 minutes, we were leaving hundreds of LDAP connections in CLOSE_WAIT state, until we fail to service entirely with "Too many open files". Also sequence_number() in winbindd_ads.c needs to delete the cached LDAP connection after the ads_do_search_retry() has failed to submit the search request (although the bind succeeded (returning an expired service ticket that we cannot delete from the memory cred cache - this will get fixed later)). Guenther (This used to be commit 7e1a84b7226fb8dcd5d34c64a3478a6d886a9a91) --- source3/libsmb/clispnego.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'source3/libsmb/clispnego.c') diff --git a/source3/libsmb/clispnego.c b/source3/libsmb/clispnego.c index a01c009b6e..6aca217e25 100644 --- a/source3/libsmb/clispnego.c +++ b/source3/libsmb/clispnego.c @@ -343,7 +343,8 @@ BOOL spnego_parse_krb5_wrap(DATA_BLOB blob, DATA_BLOB *ticket, uint8 tok_id[2]) */ int spnego_gen_negTokenTarg(const char *principal, int time_offset, DATA_BLOB *targ, - DATA_BLOB *session_key_krb5, uint32 extra_ap_opts) + DATA_BLOB *session_key_krb5, uint32 extra_ap_opts, + time_t *expire_time) { int retval; DATA_BLOB tkt, tkt_wrapped; @@ -351,7 +352,8 @@ int spnego_gen_negTokenTarg(const char *principal, int time_offset, /* get a kerberos ticket for the service and extract the session key */ retval = cli_krb5_get_ticket(principal, time_offset, - &tkt, session_key_krb5, extra_ap_opts, NULL); + &tkt, session_key_krb5, extra_ap_opts, NULL, + expire_time); if (retval) return retval; -- cgit From eceb926df94063e91c5abc96f52a1bc7b45ce290 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 5 Apr 2007 12:30:23 +0000 Subject: r22092: - make spnego_parse_auth_response() more generic and not specific for NTLMSSP - it's possible that the server sends a mechOID and authdata if negResult != SPNEGO_NEG_RESULT_INCOMPLETE, but we still force the mechOID to be present if negResult == SPNEGO_NEG_RESULT_INCOMPLETE metze (This used to be commit e9f2aa22f90208a5e530ef3b68664151960a0a22) --- source3/libsmb/clispnego.c | 23 +++++++++++++++-------- 1 file changed, 15 insertions(+), 8 deletions(-) (limited to 'source3/libsmb/clispnego.c') diff --git a/source3/libsmb/clispnego.c b/source3/libsmb/clispnego.c index 6aca217e25..0c4217c417 100644 --- a/source3/libsmb/clispnego.c +++ b/source3/libsmb/clispnego.c @@ -518,9 +518,10 @@ DATA_BLOB spnego_gen_auth_response(DATA_BLOB *reply, NTSTATUS nt_status, } /* - parse a SPNEGO NTLMSSP auth packet. This contains the encrypted passwords + parse a SPNEGO auth packet. This contains the encrypted passwords */ -BOOL spnego_parse_auth_response(DATA_BLOB blob, NTSTATUS nt_status, +BOOL spnego_parse_auth_response(DATA_BLOB blob, NTSTATUS nt_status, + const char *mechOID, DATA_BLOB *auth) { ASN1_DATA data; @@ -541,14 +542,20 @@ BOOL spnego_parse_auth_response(DATA_BLOB blob, NTSTATUS nt_status, asn1_check_enumerated(&data, negResult); asn1_end_tag(&data); - if (negResult == SPNEGO_NEG_RESULT_INCOMPLETE) { + *auth = data_blob(NULL,0); + + if (asn1_tag_remaining(&data)) { asn1_start_tag(&data,ASN1_CONTEXT(1)); - asn1_check_OID(&data, OID_NTLMSSP); - asn1_end_tag(&data); - - asn1_start_tag(&data,ASN1_CONTEXT(2)); - asn1_read_OctetString(&data, auth); + asn1_check_OID(&data, mechOID); asn1_end_tag(&data); + + if (asn1_tag_remaining(&data)) { + asn1_start_tag(&data,ASN1_CONTEXT(2)); + asn1_read_OctetString(&data, auth); + asn1_end_tag(&data); + } + } else if (negResult == SPNEGO_NEG_RESULT_INCOMPLETE) { + data.has_error = 1; } asn1_end_tag(&data); -- cgit From 14ac7712f3fd78ecb5f84b8b8e5e7fd6cb469671 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Thu, 5 Apr 2007 12:36:10 +0000 Subject: r22093: send also the correct OID_KERBEROS5 not only the broken OID_KERBEROS_OLD one. metze (This used to be commit 294c69334fce1cbb74ae9eb5a06e17b397f994df) --- source3/libsmb/clispnego.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb/clispnego.c') diff --git a/source3/libsmb/clispnego.c b/source3/libsmb/clispnego.c index 0c4217c417..d2494cac86 100644 --- a/source3/libsmb/clispnego.c +++ b/source3/libsmb/clispnego.c @@ -348,7 +348,7 @@ int spnego_gen_negTokenTarg(const char *principal, int time_offset, { int retval; DATA_BLOB tkt, tkt_wrapped; - const char *krb_mechs[] = {OID_KERBEROS5_OLD, OID_NTLMSSP, NULL}; + const char *krb_mechs[] = {OID_KERBEROS5_OLD, OID_KERBEROS5, OID_NTLMSSP, NULL}; /* get a kerberos ticket for the service and extract the session key */ retval = cli_krb5_get_ticket(principal, time_offset, -- cgit From b4a7b7a8889737e2891fc1176feabd4ce47f2737 Mon Sep 17 00:00:00 2001 From: Volker Lendecke Date: Mon, 14 May 2007 12:16:20 +0000 Subject: r22844: Introduce const DATA_BLOB data_blob_null = { NULL, 0, NULL }; and replace all data_blob(NULL, 0) calls. (This used to be commit 3d3d61687ef00181f4f04e001d42181d93ac931e) --- source3/libsmb/clispnego.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb/clispnego.c') diff --git a/source3/libsmb/clispnego.c b/source3/libsmb/clispnego.c index d2494cac86..5ea5cf3011 100644 --- a/source3/libsmb/clispnego.c +++ b/source3/libsmb/clispnego.c @@ -542,7 +542,7 @@ BOOL spnego_parse_auth_response(DATA_BLOB blob, NTSTATUS nt_status, asn1_check_enumerated(&data, negResult); asn1_end_tag(&data); - *auth = data_blob(NULL,0); + *auth = data_blob_null; if (asn1_tag_remaining(&data)) { asn1_start_tag(&data,ASN1_CONTEXT(1)); -- cgit From d824b98f80ba186030cbb70b3a1e5daf80469ecd Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Mon, 9 Jul 2007 19:25:36 +0000 Subject: r23779: Change from v2 or later to v3 or later. Jeremy. (This used to be commit 407e6e695b8366369b7c76af1ff76869b45347b3) --- source3/libsmb/clispnego.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'source3/libsmb/clispnego.c') diff --git a/source3/libsmb/clispnego.c b/source3/libsmb/clispnego.c index 5ea5cf3011..aaa18a94bd 100644 --- a/source3/libsmb/clispnego.c +++ b/source3/libsmb/clispnego.c @@ -7,7 +7,7 @@ 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 - the Free Software Foundation; either version 2 of the License, or + the Free Software Foundation; either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, -- cgit From 5e54558c6dea67b56bbfaba5698f3a434d3dffb6 Mon Sep 17 00:00:00 2001 From: Andrew Tridgell Date: Tue, 10 Jul 2007 00:52:41 +0000 Subject: r23784: use the GPLv3 boilerplate as recommended by the FSF and the license text (This used to be commit b0132e94fc5fef936aa766fb99a306b3628e9f07) --- source3/libsmb/clispnego.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'source3/libsmb/clispnego.c') diff --git a/source3/libsmb/clispnego.c b/source3/libsmb/clispnego.c index aaa18a94bd..f93cbcf39b 100644 --- a/source3/libsmb/clispnego.c +++ b/source3/libsmb/clispnego.c @@ -16,8 +16,7 @@ GNU General Public License for more details. You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + along with this program. If not, see . */ #include "includes.h" -- cgit From 42349190b7c9b69009549770fe6ec7cd2df5d8ee Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 19 Sep 2007 14:33:32 +0000 Subject: r25227: Patch from "Steven Danneman" : - We ran across a bug joining our Samba server to a Win2K domain with LDAP signing turned on. Upon investigation I discovered that there is a bug in Win2K server which returns a duplicated responseToken in the LDAP bindResponse packet. This blob is placed in the optional mechListMIC field which is unsupported in both Win2K and Win2K3. You can see RFC 2478 for the proper packet construction. I've worked with metze on this to confirm all these finding. This patch properly parses then discards the mechListMIC field if it exists in the packet, so we don't produce a malformed packet error, causing LDAP signed joins to fail. Also attached is a sniff of the domain join, exposing Win2Ks bad behavior (packet 21). - (I've just changed the scope of the DATA_BLOB mechList) metze (This used to be commit 200b5bfb8180af09446762e915eac63d14c6c7b0) --- source3/libsmb/clispnego.c | 14 ++++++++++++++ 1 file changed, 14 insertions(+) (limited to 'source3/libsmb/clispnego.c') diff --git a/source3/libsmb/clispnego.c b/source3/libsmb/clispnego.c index f93cbcf39b..9432ce81d3 100644 --- a/source3/libsmb/clispnego.c +++ b/source3/libsmb/clispnego.c @@ -557,6 +557,20 @@ BOOL spnego_parse_auth_response(DATA_BLOB blob, NTSTATUS nt_status, data.has_error = 1; } + /* Binding against Win2K DC returns a duplicate of the responseToken in + * the optional mechListMIC field. This is a bug in Win2K. We ignore + * this field if it exists. Win2K8 may return a proper mechListMIC at + * which point we need to implement the integrity checking. */ + if (asn1_tag_remaining(&data)) { + DATA_BLOB mechList = data_blob_null; + asn1_start_tag(&data, ASN1_CONTEXT(3)); + asn1_read_OctetString(&data, &mechList); + asn1_end_tag(&data); + data_blob_free(&mechList); + DEBUG(5,("spnego_parse_auth_response received mechListMIC, " + "ignoring.\n")); + } + asn1_end_tag(&data); asn1_end_tag(&data); -- cgit From 3529156971e17c7ec13f6a6243f7b613e4666cdd Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Fri, 28 Sep 2007 03:54:42 +0000 Subject: r25400: Windows 2008 (Longhorn) Interop fixes for AD specific auth2 flags, and client fixes. Patch from Todd Stetcher . (This used to be commit 8304ccba7346597425307e260e88647e49081f68) --- source3/libsmb/clispnego.c | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) (limited to 'source3/libsmb/clispnego.c') diff --git a/source3/libsmb/clispnego.c b/source3/libsmb/clispnego.c index 9432ce81d3..c45883d890 100644 --- a/source3/libsmb/clispnego.c +++ b/source3/libsmb/clispnego.c @@ -52,7 +52,18 @@ DATA_BLOB spnego_gen_negTokenInit(char guid[16], asn1_push_tag(&data, ASN1_CONTEXT(3)); asn1_push_tag(&data, ASN1_SEQUENCE(0)); asn1_push_tag(&data, ASN1_CONTEXT(0)); + + /* + * @todo + * Windows 2008 sends a bogus principal, since this + * is not truly supported in the SPNEGO protocol. + * + * We should do the same, but I'm worried this will break things, + * such as DFS. + * todd.stecher@isilon.com + */ asn1_write_GeneralString(&data,principal); + asn1_pop_tag(&data); asn1_pop_tag(&data); asn1_pop_tag(&data); @@ -154,6 +165,14 @@ BOOL spnego_parse_negTokenInit(DATA_BLOB blob, asn1_start_tag(&data, ASN1_SEQUENCE(0)); asn1_start_tag(&data, ASN1_CONTEXT(0)); asn1_read_GeneralString(&data,principal); + /* + * Windows 2008 sends a bogus principal, since this + * is not truly supported in the SPNEGO protocol. + * todd.stecher@isilon.com + */ + if (strcmp(ADS_IGNORE_PRINCIPAL, *principal) == 0) + SAFE_FREE(*principal); + asn1_end_tag(&data); asn1_end_tag(&data); asn1_end_tag(&data); -- cgit From 5221ebb299081da6a806362212c6a8ceb9cc70a8 Mon Sep 17 00:00:00 2001 From: Gerald Carter Date: Fri, 28 Sep 2007 18:15:34 +0000 Subject: r25407: Revert Longhorn join patch as it is not correct for the 3.2 tree. The translate_name() used by cli_session_setup_spnego() cann rely Winbindd since it is needed by the join process (and hence before Winbind can be run). (This used to be commit 00a93ed336c5f36643e6e33bd277608eaf05677c) --- source3/libsmb/clispnego.c | 19 ------------------- 1 file changed, 19 deletions(-) (limited to 'source3/libsmb/clispnego.c') diff --git a/source3/libsmb/clispnego.c b/source3/libsmb/clispnego.c index c45883d890..9432ce81d3 100644 --- a/source3/libsmb/clispnego.c +++ b/source3/libsmb/clispnego.c @@ -52,18 +52,7 @@ DATA_BLOB spnego_gen_negTokenInit(char guid[16], asn1_push_tag(&data, ASN1_CONTEXT(3)); asn1_push_tag(&data, ASN1_SEQUENCE(0)); asn1_push_tag(&data, ASN1_CONTEXT(0)); - - /* - * @todo - * Windows 2008 sends a bogus principal, since this - * is not truly supported in the SPNEGO protocol. - * - * We should do the same, but I'm worried this will break things, - * such as DFS. - * todd.stecher@isilon.com - */ asn1_write_GeneralString(&data,principal); - asn1_pop_tag(&data); asn1_pop_tag(&data); asn1_pop_tag(&data); @@ -165,14 +154,6 @@ BOOL spnego_parse_negTokenInit(DATA_BLOB blob, asn1_start_tag(&data, ASN1_SEQUENCE(0)); asn1_start_tag(&data, ASN1_CONTEXT(0)); asn1_read_GeneralString(&data,principal); - /* - * Windows 2008 sends a bogus principal, since this - * is not truly supported in the SPNEGO protocol. - * todd.stecher@isilon.com - */ - if (strcmp(ADS_IGNORE_PRINCIPAL, *principal) == 0) - SAFE_FREE(*principal); - asn1_end_tag(&data); asn1_end_tag(&data); asn1_end_tag(&data); -- cgit From 30191d1a5704ad2b158386b511558972d539ce47 Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 18 Oct 2007 17:40:25 -0700 Subject: RIP BOOL. Convert BOOL -> bool. I found a few interesting bugs in various places whilst doing this (places that assumed BOOL == int). I also need to fix the Samba4 pidl generation (next checkin). Jeremy. (This used to be commit f35a266b3cbb3e5fa6a86be60f34fe340a3ca71f) --- source3/libsmb/clispnego.c | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) (limited to 'source3/libsmb/clispnego.c') diff --git a/source3/libsmb/clispnego.c b/source3/libsmb/clispnego.c index 9432ce81d3..f95b11e4cd 100644 --- a/source3/libsmb/clispnego.c +++ b/source3/libsmb/clispnego.c @@ -122,12 +122,12 @@ DATA_BLOB gen_negTokenInit(const char *OID, DATA_BLOB blob) parse a negTokenInit packet giving a GUID, a list of supported OIDs (the mechanisms) and a principal name string */ -BOOL spnego_parse_negTokenInit(DATA_BLOB blob, +bool spnego_parse_negTokenInit(DATA_BLOB blob, char *OIDs[ASN1_MAX_OIDS], char **principal) { int i; - BOOL ret; + bool ret; ASN1_DATA data; asn1_load(&data, blob); @@ -224,7 +224,7 @@ DATA_BLOB gen_negTokenTarg(const char *OIDs[], DATA_BLOB blob) /* parse a negTokenTarg packet giving a list of OIDs and a security blob */ -BOOL parse_negTokenTarg(DATA_BLOB blob, char *OIDs[ASN1_MAX_OIDS], DATA_BLOB *secblob) +bool parse_negTokenTarg(DATA_BLOB blob, char *OIDs[ASN1_MAX_OIDS], DATA_BLOB *secblob) { int i; ASN1_DATA data; @@ -301,9 +301,9 @@ DATA_BLOB spnego_gen_krb5_wrap(const DATA_BLOB ticket, const uint8 tok_id[2]) /* parse a krb5 GSS-API wrapper packet giving a ticket */ -BOOL spnego_parse_krb5_wrap(DATA_BLOB blob, DATA_BLOB *ticket, uint8 tok_id[2]) +bool spnego_parse_krb5_wrap(DATA_BLOB blob, DATA_BLOB *ticket, uint8 tok_id[2]) { - BOOL ret; + bool ret; ASN1_DATA data; int data_remaining; @@ -373,10 +373,10 @@ int spnego_gen_negTokenTarg(const char *principal, int time_offset, /* parse a spnego NTLMSSP challenge packet giving two security blobs */ -BOOL spnego_parse_challenge(const DATA_BLOB blob, +bool spnego_parse_challenge(const DATA_BLOB blob, DATA_BLOB *chal1, DATA_BLOB *chal2) { - BOOL ret; + bool ret; ASN1_DATA data; ZERO_STRUCTP(chal1); @@ -448,7 +448,7 @@ DATA_BLOB spnego_gen_auth(DATA_BLOB blob) /* parse a SPNEGO auth packet. This contains the encrypted passwords */ -BOOL spnego_parse_auth(DATA_BLOB blob, DATA_BLOB *auth) +bool spnego_parse_auth(DATA_BLOB blob, DATA_BLOB *auth) { ASN1_DATA data; @@ -519,7 +519,7 @@ DATA_BLOB spnego_gen_auth_response(DATA_BLOB *reply, NTSTATUS nt_status, /* parse a SPNEGO auth packet. This contains the encrypted passwords */ -BOOL spnego_parse_auth_response(DATA_BLOB blob, NTSTATUS nt_status, +bool spnego_parse_auth_response(DATA_BLOB blob, NTSTATUS nt_status, const char *mechOID, DATA_BLOB *auth) { -- cgit From 39e0dbcf07251670b5475e9d0533c08a2712fffa Mon Sep 17 00:00:00 2001 From: Jeremy Allison Date: Thu, 14 Feb 2008 11:29:54 -0800 Subject: Allow the mechOID to be written separately. Jeremy. (This used to be commit e3e08c6e7d270e1be7a9d3042b1f36f5a291f90a) --- source3/libsmb/clispnego.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'source3/libsmb/clispnego.c') diff --git a/source3/libsmb/clispnego.c b/source3/libsmb/clispnego.c index f95b11e4cd..a75032a47d 100644 --- a/source3/libsmb/clispnego.c +++ b/source3/libsmb/clispnego.c @@ -498,11 +498,13 @@ DATA_BLOB spnego_gen_auth_response(DATA_BLOB *reply, NTSTATUS nt_status, asn1_write_enumerated(&data, negResult); asn1_pop_tag(&data); - if (reply->data != NULL) { + if (mechOID) { asn1_push_tag(&data,ASN1_CONTEXT(1)); asn1_write_OID(&data, mechOID); asn1_pop_tag(&data); - + } + + if (reply && reply->data != NULL) { asn1_push_tag(&data,ASN1_CONTEXT(2)); asn1_write_OctetString(&data, reply->data, reply->length); asn1_pop_tag(&data); -- cgit From f700ee6418c7b861efdb0f8eaa61b99ad598b7c3 Mon Sep 17 00:00:00 2001 From: Bill Ricker Date: Mon, 7 Apr 2008 15:02:56 -0700 Subject: Fix Kerberos interop with Mac OS X 10.5 clients. Ignore optional req_flags. Use the Kerberos mechanism OID negotiated with the client rather than hardcoding OID_KERBEROS5_OLD. (This used to be commit 59a2bcf30fef14ecc826271862b645dd3a61cb48) --- source3/libsmb/clispnego.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'source3/libsmb/clispnego.c') diff --git a/source3/libsmb/clispnego.c b/source3/libsmb/clispnego.c index a75032a47d..fa9dba098f 100644 --- a/source3/libsmb/clispnego.c +++ b/source3/libsmb/clispnego.c @@ -246,6 +246,18 @@ bool parse_negTokenTarg(DATA_BLOB blob, char *OIDs[ASN1_MAX_OIDS], DATA_BLOB *se asn1_end_tag(&data); asn1_end_tag(&data); + /* Skip any optional req_flags that are sent per RFC 4178 */ + if (asn1_check_tag(&data, ASN1_CONTEXT(1))) { + uint8 flags; + + asn1_start_tag(&data, ASN1_CONTEXT(1)); + asn1_start_tag(&data, ASN1_BITFIELD); + while (asn1_tag_remaining(&data) > 0) + asn1_read_uint8(&data, &flags); + asn1_end_tag(&data); + asn1_end_tag(&data); + } + asn1_start_tag(&data, ASN1_CONTEXT(2)); asn1_read_OctetString(&data,secblob); asn1_end_tag(&data); -- cgit