static int negprot_spnego(char *p) { DATA_BLOB blob; nstring dos_name; fstring unix_name; uint8 guid[17]; const char *OIDs_krb5[] = {OID_KERBEROS5, OID_KERBEROS5_OLD, OID_NTLMSSP, NULL }; const char *OIDs_plain[] = {OID_NTLMSSP, NULL}; char *principal; int len; global_spnego_negotiated = True; ZERO_STRUCT(guid); safe_strcpy(unix_name, global_myname(), sizeof(unix_name)-1); strlower_m(unix_name); push_ascii_nstring(dos_name, unix_name); safe_strcpy((char *)guid, dos_name, sizeof(guid)-1); #ifdef DEVELOPER /* valgrind fixer... */ { size_t sl = strlen(guid); if (sizeof(guid)-sl) memset(&guid[sl], '\0', sizeof(guid)-sl); } #endif #if 0 /* strangely enough, NT does not sent the single OID NTLMSSP when not a ADS member, it sends no OIDs at all we can't do this until we teach our sesssion setup parser to know about raw NTLMSSP (clients send no ASN.1 wrapping if we do this) */ if (lp_security() != SEC_ADS) { memcpy(p, guid, 16); return 16; } #endif if (lp_security() != SEC_ADS) { blob = spnego_gen_negTokenInit(guid, OIDs_plain, "NONE"); } else { asprintf(&principal, "%s$@%s", guid, lp_realm()); blob = spnego_gen_negTokenInit(guid, OIDs_krb5, principal); free(principal); } memcpy(p, blob.data, blob.length); len = blob.length; data_blob_free(&blob); return len; }
void register_name(struct subnet_record *subrec, const char *name, int type, uint16 nb_flags, register_name_success_function success_fn, register_name_fail_function fail_fn, struct userdata_struct *userdata) { struct nmb_name nmbname; nstring nname; errno = 0; push_ascii_nstring(nname, name); if (errno == E2BIG) { unstring tname; pull_ascii_nstring(tname, sizeof(tname), nname); DEBUG(0,("register_name: NetBIOS name %s is too long. Truncating to %s\n", name, tname)); make_nmb_name(&nmbname, tname, type); } else { make_nmb_name(&nmbname, name, type); } /* Always set the NB_ACTIVE flag on the name we are registering. Doesn't make sense without it. */ nb_flags |= NB_ACTIVE; if (subrec == unicast_subnet) { /* we now always do multi-homed registration if we are registering to a WINS server. This copes much better with complex WINS setups */ multihomed_register_name(&nmbname, nb_flags, success_fn, fail_fn); return; } if (queue_register_name(subrec, register_name_response, register_name_timeout_response, success_fn, fail_fn, userdata, &nmbname, nb_flags) == NULL) { DEBUG(0,("register_name: Failed to send packet trying to register name %s\n", nmb_namestr(&nmbname))); } }
static void name_to_unstring(unstring unname, const char *name) { nstring nname; errno = 0; push_ascii_nstring(nname, name); if (errno == E2BIG) { unstring tname; pull_ascii_nstring(tname, sizeof(tname), nname); strlcpy(unname, tname, sizeof(nname)); DEBUG(0,("name_to_nstring: workgroup name %s is too long. Truncating to %s\n", name, tname)); } else { unstrcpy(unname, name); } }
static DATA_BLOB negprot_spnego(void) { DATA_BLOB blob; nstring dos_name; fstring unix_name; #ifdef DEVELOPER size_t slen; #endif char guid[17]; const char *OIDs_krb5[] = {OID_KERBEROS5, OID_KERBEROS5_OLD, OID_NTLMSSP, NULL}; const char *OIDs_plain[] = {OID_NTLMSSP, NULL}; global_spnego_negotiated = True; memset(guid, '\0', sizeof(guid)); safe_strcpy(unix_name, global_myname(), sizeof(unix_name)-1); strlower_m(unix_name); push_ascii_nstring(dos_name, unix_name); safe_strcpy(guid, dos_name, sizeof(guid)-1); #ifdef DEVELOPER /* Fix valgrind 'uninitialized bytes' issue. */ slen = strlen(dos_name); if (slen < sizeof(guid)) { memset(guid+slen, '\0', sizeof(guid) - slen); } #endif /* strangely enough, NT does not sent the single OID NTLMSSP when not a ADS member, it sends no OIDs at all OLD COMMENT : "we can't do this until we teach our sesssion setup parser to know about raw NTLMSSP (clients send no ASN.1 wrapping if we do this)" Our sessionsetup code now handles raw NTLMSSP connects, so we can go back to doing what W2K3 does here. This is needed to make PocketPC 2003 CIFS connections work with SPNEGO. See bugzilla bugs #1828 and #3133 for details. JRA. */ if (lp_security() != SEC_ADS && !lp_use_kerberos_keytab()) { #if 0 /* Code for PocketPC client */ blob = data_blob(guid, 16); #else /* Code for standalone WXP client */ blob = spnego_gen_negTokenInit(guid, OIDs_plain, "NONE"); #endif } else { fstring myname; char *host_princ_s = NULL; const char * lkdc_realm = lp_parm_talloc_string(GLOBAL_SECTION_SNUM, "com.apple", "lkdc realm", NULL); myname[0] = '\0'; get_mydnsfullname(myname); strlower_m(myname); /* If we have a LKDC, use it unless there is a managed realm * also configured. The managed realm should have precedence. */ if (lkdc_realm && (*lp_realm() == '\0' || strcmp(lkdc_realm, lp_realm()) == 0)) { asprintf(&host_princ_s, "cifs/%s@%s", lkdc_realm, lkdc_realm); } else { asprintf(&host_princ_s, "cifs/%s@%s", myname, lp_realm()); } blob = spnego_gen_negTokenInit(guid, OIDs_krb5, host_princ_s); SAFE_FREE(host_princ_s); TALLOC_FREE(lkdc_realm); } return blob; }
DATA_BLOB negprot_spnego(TALLOC_CTX *ctx, struct smbd_server_connection *sconn) { DATA_BLOB blob = data_blob_null; DATA_BLOB blob_out = data_blob_null; nstring dos_name; fstring unix_name; NTSTATUS status; #ifdef DEVELOPER size_t slen; #endif struct gensec_security *gensec_security; /* See if we can get an SPNEGO blob */ status = auth_generic_prepare(talloc_tos(), sconn->remote_address, &gensec_security); if (NT_STATUS_IS_OK(status)) { status = gensec_start_mech_by_oid(gensec_security, GENSEC_OID_SPNEGO); if (NT_STATUS_IS_OK(status)) { status = gensec_update(gensec_security, ctx, NULL, data_blob_null, &blob); /* If we get the list of OIDs, the 'OK' answer * is NT_STATUS_MORE_PROCESSING_REQUIRED */ if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) { DEBUG(0, ("Failed to start SPNEGO handler for negprot OID list!\n")); blob = data_blob_null; } } TALLOC_FREE(gensec_security); } sconn->smb1.negprot.spnego = true; /* strangely enough, NT does not sent the single OID NTLMSSP when not a ADS member, it sends no OIDs at all OLD COMMENT : "we can't do this until we teach our sesssion setup parser to know about raw NTLMSSP (clients send no ASN.1 wrapping if we do this)" Our sessionsetup code now handles raw NTLMSSP connects, so we can go back to doing what W2K3 does here. This is needed to make PocketPC 2003 CIFS connections work with SPNEGO. See bugzilla bugs #1828 and #3133 for details. JRA. */ if (blob.length == 0 || blob.data == NULL) { return data_blob_null; } blob_out = data_blob_talloc(ctx, NULL, 16 + blob.length); if (blob_out.data == NULL) { data_blob_free(&blob); return data_blob_null; } memset(blob_out.data, '\0', 16); checked_strlcpy(unix_name, lp_netbios_name(), sizeof(unix_name)); (void)strlower_m(unix_name); push_ascii_nstring(dos_name, unix_name); strlcpy((char *)blob_out.data, dos_name, 17); #ifdef DEVELOPER /* Fix valgrind 'uninitialized bytes' issue. */ slen = strlen(dos_name); if (slen < 16) { memset(blob_out.data+slen, '\0', 16 - slen); } #endif memcpy(&blob_out.data[16], blob.data, blob.length); data_blob_free(&blob); return blob_out; }
void register_name(struct subnet_record *subrec, const char *name, int type, uint16_t nb_flags, register_name_success_function success_fn, register_name_fail_function fail_fn, struct userdata_struct *userdata) { struct nmb_name nmbname; nstring nname; size_t converted_size; errno = 0; converted_size = push_ascii_nstring(nname, name); if (converted_size != (size_t)-1) { /* Success. */ make_nmb_name(&nmbname, name, type); } else if (errno == E2BIG) { /* * Name converted to CH_DOS is too large. * try to truncate. */ char *converted_str_dos = NULL; char *converted_str_unix = NULL; bool ok; converted_size = 0; ok = convert_string_talloc(talloc_tos(), CH_UNIX, CH_DOS, name, strlen(name)+1, &converted_str_dos, &converted_size); if (!ok) { DEBUG(0,("register_name: NetBIOS name %s cannot be " "converted. Failing to register name.\n", name)); return; } /* * As it's now CH_DOS codepage * we truncate by writing '\0' at * MAX_NETBIOSNAME_LEN-1 and then * convert back to CH_UNIX which we * need for the make_nmb_name() call. */ if (converted_size >= MAX_NETBIOSNAME_LEN) { converted_str_dos[MAX_NETBIOSNAME_LEN-1] = '\0'; } ok = convert_string_talloc(talloc_tos(), CH_DOS, CH_UNIX, converted_str_dos, strlen(converted_str_dos)+1, &converted_str_unix, &converted_size); if (!ok) { DEBUG(0,("register_name: NetBIOS name %s cannot be " "converted back to CH_UNIX. " "Failing to register name.\n", converted_str_dos)); TALLOC_FREE(converted_str_dos); return; } make_nmb_name(&nmbname, converted_str_unix, type); TALLOC_FREE(converted_str_dos); TALLOC_FREE(converted_str_unix); } else { /* * Generic conversion error. Fail to register. */ DEBUG(0,("register_name: NetBIOS name %s cannot be " "converted (%s). Failing to register name.\n", name, strerror(errno))); return; } /* Always set the NB_ACTIVE flag on the name we are registering. Doesn't make sense without it. */ nb_flags |= NB_ACTIVE; if (subrec == unicast_subnet) { /* we now always do multi-homed registration if we are registering to a WINS server. This copes much better with complex WINS setups */ multihomed_register_name(&nmbname, nb_flags, success_fn, fail_fn); return; } if (queue_register_name(subrec, register_name_response, register_name_timeout_response, success_fn, fail_fn, userdata, &nmbname, nb_flags) == NULL) { DEBUG(0,("register_name: Failed to send packet trying to register name %s\n", nmb_namestr(&nmbname))); } }
DATA_BLOB negprot_spnego(TALLOC_CTX *ctx, struct smbd_server_connection *sconn) { DATA_BLOB blob = data_blob_null; DATA_BLOB blob_out = data_blob_null; nstring dos_name; fstring unix_name; #ifdef DEVELOPER size_t slen; #endif const char *OIDs_krb5[] = {OID_KERBEROS5, OID_KERBEROS5_OLD, OID_NTLMSSP, NULL}; const char *OIDs_ntlm[] = {OID_NTLMSSP, NULL}; sconn->smb1.negprot.spnego = true; /* strangely enough, NT does not sent the single OID NTLMSSP when not a ADS member, it sends no OIDs at all OLD COMMENT : "we can't do this until we teach our sesssion setup parser to know about raw NTLMSSP (clients send no ASN.1 wrapping if we do this)" Our sessionsetup code now handles raw NTLMSSP connects, so we can go back to doing what W2K3 does here. This is needed to make PocketPC 2003 CIFS connections work with SPNEGO. See bugzilla bugs #1828 and #3133 for details. JRA. */ if (lp_security() != SEC_ADS && !USE_KERBEROS_KEYTAB) { #if 0 /* Code for PocketPC client */ blob = data_blob(guid, 16); #else /* Code for standalone WXP client */ blob = spnego_gen_negTokenInit(ctx, OIDs_ntlm, NULL, "NONE"); #endif } else if (!lp_send_spnego_principal()) { /* By default, Windows 2008 and later sends not_defined_in_RFC4178@please_ignore */ blob = spnego_gen_negTokenInit(ctx, OIDs_krb5, NULL, ADS_IGNORE_PRINCIPAL); } else { fstring myname; char *host_princ_s = NULL; name_to_fqdn(myname, global_myname()); strlower_m(myname); if (asprintf(&host_princ_s, "cifs/%s@%s", myname, lp_realm()) == -1) { return data_blob_null; } blob = spnego_gen_negTokenInit(ctx, OIDs_krb5, NULL, host_princ_s); SAFE_FREE(host_princ_s); } if (blob.length == 0 || blob.data == NULL) { return data_blob_null; } blob_out = data_blob_talloc(ctx, NULL, 16 + blob.length); if (blob_out.data == NULL) { data_blob_free(&blob); return data_blob_null; } memset(blob_out.data, '\0', 16); safe_strcpy(unix_name, global_myname(), sizeof(unix_name)-1); strlower_m(unix_name); push_ascii_nstring(dos_name, unix_name); strlcpy((char *)blob_out.data, dos_name, 17); #ifdef DEVELOPER /* Fix valgrind 'uninitialized bytes' issue. */ slen = strlen(dos_name); if (slen < 16) { memset(blob_out.data+slen, '\0', 16 - slen); } #endif memcpy(&blob_out.data[16], blob.data, blob.length); data_blob_free(&blob); return blob_out; }
static int negprot_spnego(char *p, uint8 *pkeylen) { DATA_BLOB blob; nstring dos_name; fstring unix_name; char guid[17]; const char *OIDs_krb5[] = {OID_KERBEROS5, OID_KERBEROS5_OLD, OID_NTLMSSP, NULL}; const char *OIDs_plain[] = {OID_NTLMSSP, NULL}; int len; global_spnego_negotiated = True; ZERO_STRUCT(guid); safe_strcpy(unix_name, global_myname(), sizeof(unix_name)-1); strlower_m(unix_name); push_ascii_nstring(dos_name, unix_name); safe_strcpy(guid, dos_name, sizeof(guid)-1); #ifdef DEVELOPER /* valgrind fixer... */ { size_t sl = strlen(guid); if (sizeof(guid)-sl) memset(&guid[sl], '\0', sizeof(guid)-sl); } #endif /* strangely enough, NT does not sent the single OID NTLMSSP when not a ADS member, it sends no OIDs at all OLD COMMENT : "we can't do this until we teach our sesssion setup parser to know about raw NTLMSSP (clients send no ASN.1 wrapping if we do this)" Our sessionsetup code now handles raw NTLMSSP connects, so we can go back to doing what W2K3 does here. This is needed to make PocketPC 2003 CIFS connections work with SPNEGO. See bugzilla bugs #1828 and #3133 for details. JRA. */ if (lp_security() != SEC_ADS && !lp_use_kerberos_keytab()) { #if 0 /* Code for PocketPC client */ blob = data_blob(guid, 16); #else /* Code for standalone WXP client */ blob = spnego_gen_negTokenInit(guid, OIDs_plain, "NONE"); #endif } else { fstring myname; char *host_princ_s = NULL; name_to_fqdn(myname, global_myname()); strlower_m(myname); asprintf(&host_princ_s, "cifs/%s@%s", myname, lp_realm()); blob = spnego_gen_negTokenInit(guid, OIDs_krb5, host_princ_s); SAFE_FREE(host_princ_s); } memcpy(p, blob.data, blob.length); len = blob.length; if (len > 256) { DEBUG(0,("negprot_spnego: blob length too long (%d)\n", len)); len = 255; } data_blob_free(&blob); if (lp_security() != SEC_ADS && !lp_use_kerberos_keytab()) { *pkeylen = 0; } else { *pkeylen = len; } return len; }
DATA_BLOB negprot_spnego(TALLOC_CTX *ctx, struct smbd_server_connection *sconn) { DATA_BLOB blob = data_blob_null; DATA_BLOB blob_out = data_blob_null; nstring dos_name; fstring unix_name; NTSTATUS status; #ifdef DEVELOPER size_t slen; #endif const char *OIDs_krb5[] = {OID_KERBEROS5, OID_KERBEROS5_OLD, OID_NTLMSSP, NULL}; const char *OIDs_ntlm[] = {OID_NTLMSSP, NULL}; struct auth_ntlmssp_state *auth_ntlmssp_state; sconn->use_gensec_hook = false; /* See if we can get an SPNEGO blob out of the gensec hook (if auth_samba4 is loaded) */ status = auth_ntlmssp_prepare(sconn->remote_address, &auth_ntlmssp_state); if (NT_STATUS_IS_OK(status)) { status = auth_generic_start(auth_ntlmssp_state, GENSEC_OID_SPNEGO); if (NT_STATUS_IS_OK(status)) { status = auth_ntlmssp_update(auth_ntlmssp_state, ctx, data_blob_null, &blob); /* If we get the list of OIDs, the 'OK' answer * is NT_STATUS_MORE_PROCESSING_REQUIRED */ if (NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED)) { sconn->use_gensec_hook = true; } } TALLOC_FREE(auth_ntlmssp_state); } sconn->smb1.negprot.spnego = true; /* strangely enough, NT does not sent the single OID NTLMSSP when not a ADS member, it sends no OIDs at all OLD COMMENT : "we can't do this until we teach our sesssion setup parser to know about raw NTLMSSP (clients send no ASN.1 wrapping if we do this)" Our sessionsetup code now handles raw NTLMSSP connects, so we can go back to doing what W2K3 does here. This is needed to make PocketPC 2003 CIFS connections work with SPNEGO. See bugzilla bugs #1828 and #3133 for details. JRA. */ if (sconn->use_gensec_hook) { /* blob initialised above */ } else if (lp_security() != SEC_ADS && !USE_KERBEROS_KEYTAB) { #if 0 /* Code for PocketPC client */ blob = data_blob(guid, 16); #else /* Code for standalone WXP client */ blob = spnego_gen_negTokenInit(ctx, OIDs_ntlm, NULL, "NONE"); #endif } else if (!lp_send_spnego_principal()) { /* By default, Windows 2008 and later sends not_defined_in_RFC4178@please_ignore */ blob = spnego_gen_negTokenInit(ctx, OIDs_krb5, NULL, ADS_IGNORE_PRINCIPAL); } else { fstring myname; char *host_princ_s = NULL; name_to_fqdn(myname, lp_netbios_name()); strlower_m(myname); if (asprintf(&host_princ_s, "cifs/%s@%s", myname, lp_realm()) == -1) { return data_blob_null; } blob = spnego_gen_negTokenInit(ctx, OIDs_krb5, NULL, host_princ_s); SAFE_FREE(host_princ_s); } if (blob.length == 0 || blob.data == NULL) { return data_blob_null; } blob_out = data_blob_talloc(ctx, NULL, 16 + blob.length); if (blob_out.data == NULL) { data_blob_free(&blob); return data_blob_null; } memset(blob_out.data, '\0', 16); checked_strlcpy(unix_name, lp_netbios_name(), sizeof(unix_name)); strlower_m(unix_name); push_ascii_nstring(dos_name, unix_name); strlcpy((char *)blob_out.data, dos_name, 17); #ifdef DEVELOPER /* Fix valgrind 'uninitialized bytes' issue. */ slen = strlen(dos_name); if (slen < 16) { memset(blob_out.data+slen, '\0', 16 - slen); } #endif memcpy(&blob_out.data[16], blob.data, blob.length); data_blob_free(&blob); return blob_out; }