Example #1
0
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;
}
Example #2
0
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;
}