コード例 #1
0
static NTSTATUS ntlmssp_server_negotiate(struct ntlmssp_state *ntlmssp_state,
					 const DATA_BLOB request, DATA_BLOB *reply) 
{
	DATA_BLOB struct_blob;
	const char *dnsname;
	char *dnsdomname = NULL;
	uint32 neg_flags = 0;
	uint32 ntlmssp_command, chal_flags;
	const uint8 *cryptkey;
	const char *target_name;

	/* parse the NTLMSSP packet */
#if 0
	file_save("ntlmssp_negotiate.dat", request.data, request.length);
#endif

	if (request.length) {
		if ((request.length < 16) || !msrpc_parse(&request, "Cdd",
							"NTLMSSP",
							&ntlmssp_command,
							&neg_flags)) {
			DEBUG(1, ("ntlmssp_server_negotiate: failed to parse NTLMSSP Negotiate of length %u\n",
				(unsigned int)request.length));
			dump_data(2, request.data, request.length);
			return NT_STATUS_INVALID_PARAMETER;
		}
		debug_ntlmssp_flags(neg_flags);
	}

	ntlmssp_handle_neg_flags(ntlmssp_state, neg_flags, lp_lanman_auth());

	/* Ask our caller what challenge they would like in the packet */
	cryptkey = ntlmssp_state->get_challenge(ntlmssp_state);

	/* Check if we may set the challenge */
	if (!ntlmssp_state->may_set_challenge(ntlmssp_state)) {
		ntlmssp_state->neg_flags &= ~NTLMSSP_NEGOTIATE_NTLM2;
	}

	/* The flags we send back are not just the negotiated flags,
	 * they are also 'what is in this packet'.  Therfore, we
	 * operate on 'chal_flags' from here on
	 */

	chal_flags = ntlmssp_state->neg_flags;

	/* get the right name to fill in as 'target' */
	target_name = ntlmssp_target_name(ntlmssp_state,
					  neg_flags, &chal_flags);
	if (target_name == NULL) {
		return NT_STATUS_INVALID_PARAMETER;
	}

	ntlmssp_state->chal = data_blob_talloc(ntlmssp_state->mem_ctx, cryptkey, 8);
	ntlmssp_state->internal_chal = data_blob_talloc(ntlmssp_state->mem_ctx, cryptkey, 8);

	/* This should be a 'netbios domain -> DNS domain' mapping */
	dnsdomname = get_mydnsdomname(ntlmssp_state->mem_ctx);
	if (!dnsdomname) {
		dnsdomname = talloc_strdup(ntlmssp_state->mem_ctx, "");
	}
	if (!dnsdomname) {
		return NT_STATUS_NO_MEMORY;
	}
	strlower_m(dnsdomname);

	dnsname = get_mydnsfullname();
	if (!dnsname) {
		dnsname = "";
	}

	/* This creates the 'blob' of names that appears at the end of the packet */
	if (chal_flags & NTLMSSP_CHAL_TARGET_INFO)
	{
		msrpc_gen(&struct_blob, "aaaaa",
			  NTLMSSP_NAME_TYPE_DOMAIN, target_name,
			  NTLMSSP_NAME_TYPE_SERVER, ntlmssp_state->get_global_myname(),
			  NTLMSSP_NAME_TYPE_DOMAIN_DNS, dnsdomname,
			  NTLMSSP_NAME_TYPE_SERVER_DNS, dnsname,
			  0, "");
	} else {
		struct_blob = data_blob_null;
	}

	{
		/* Marshel the packet in the right format, be it unicode or ASCII */
		const char *gen_string;
		if (ntlmssp_state->unicode) {
			gen_string = "CdUdbddB";
		} else {
			gen_string = "CdAdbddB";
		}

		msrpc_gen(reply, gen_string,
			  "NTLMSSP",
			  NTLMSSP_CHALLENGE,
			  target_name,
			  chal_flags,
			  cryptkey, 8,
			  0, 0,
			  struct_blob.data, struct_blob.length);
	}

	data_blob_free(&struct_blob);

	ntlmssp_state->expected_state = NTLMSSP_AUTH;

	return NT_STATUS_MORE_PROCESSING_REQUIRED;
}
コード例 #2
0
ファイル: negprot.c プロジェクト: aosm/samba
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;
}
コード例 #3
0
ファイル: auth_generic.c プロジェクト: Gazzonyx/samba
NTSTATUS auth_generic_prepare(TALLOC_CTX *mem_ctx,
			      const struct tsocket_address *remote_address,
			      struct gensec_security **gensec_security_out)
{
	struct gensec_security *gensec_security;
	struct auth_context *auth_context;
	NTSTATUS nt_status;

	TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
	NT_STATUS_HAVE_NO_MEMORY(tmp_ctx);

	nt_status = make_auth_context_subsystem(tmp_ctx, &auth_context);
	if (!NT_STATUS_IS_OK(nt_status)) {
		TALLOC_FREE(tmp_ctx);
		return nt_status;
	}

	if (auth_context->prepare_gensec) {
		nt_status = auth_context->prepare_gensec(auth_context, tmp_ctx,
							 &gensec_security);
		if (!NT_STATUS_IS_OK(nt_status)) {
			TALLOC_FREE(tmp_ctx);
			return nt_status;
		}
	} else {
		const struct gensec_security_ops **backends = NULL;
		struct gensec_settings *gensec_settings;
		struct loadparm_context *lp_ctx;
		size_t idx = 0;
		struct cli_credentials *server_credentials;
		const char *dns_name;
		const char *dns_domain;
		struct auth4_context *auth4_context = make_auth4_context_s3(tmp_ctx, auth_context);
		if (auth4_context == NULL) {
			TALLOC_FREE(tmp_ctx);
			return NT_STATUS_NO_MEMORY;
		}

		lp_ctx = loadparm_init_s3(tmp_ctx, loadparm_s3_helpers());
		if (lp_ctx == NULL) {
			DEBUG(10, ("loadparm_init_s3 failed\n"));
			TALLOC_FREE(tmp_ctx);
			return NT_STATUS_INVALID_SERVER_STATE;
		}

		gensec_settings = lpcfg_gensec_settings(tmp_ctx, lp_ctx);
		if (lp_ctx == NULL) {
			DEBUG(10, ("lpcfg_gensec_settings failed\n"));
			TALLOC_FREE(tmp_ctx);
			return NT_STATUS_NO_MEMORY;
		}

		/*
		 * This should be a 'netbios domain -> DNS domain'
		 * mapping, and can currently validly return NULL on
		 * poorly configured systems.
		 *
		 * This is used for the NTLMSSP server
		 *
		 */
		dns_name = get_mydnsfullname();
		if (dns_name == NULL) {
			dns_name = "";
		}

		dns_domain = get_mydnsdomname(tmp_ctx);
		if (dns_domain == NULL) {
			dns_domain = "";
		}

		gensec_settings->server_dns_name = strlower_talloc(gensec_settings, dns_name);
		if (gensec_settings->server_dns_name == NULL) {
			TALLOC_FREE(tmp_ctx);
			return NT_STATUS_NO_MEMORY;
		}

		gensec_settings->server_dns_domain = strlower_talloc(gensec_settings, dns_domain);
		if (gensec_settings->server_dns_domain == NULL) {
			TALLOC_FREE(tmp_ctx);
			return NT_STATUS_NO_MEMORY;
		}

		backends = talloc_zero_array(gensec_settings,
					     const struct gensec_security_ops *, 6);
		if (backends == NULL) {
			TALLOC_FREE(tmp_ctx);
			return NT_STATUS_NO_MEMORY;
		}
		gensec_settings->backends = backends;

		gensec_init();

		/* These need to be in priority order, krb5 before NTLMSSP */
#if defined(HAVE_KRB5)
		backends[idx++] = &gensec_gse_krb5_security_ops;
#endif

		backends[idx++] = gensec_security_by_oid(NULL, GENSEC_OID_NTLMSSP);

		backends[idx++] = gensec_security_by_oid(NULL, GENSEC_OID_SPNEGO);

		backends[idx++] = gensec_security_by_auth_type(NULL, DCERPC_AUTH_TYPE_SCHANNEL);

		backends[idx++] = gensec_security_by_auth_type(NULL, DCERPC_AUTH_TYPE_NCALRPC_AS_SYSTEM);

		/*
		 * This is anonymous for now, because we just use it
		 * to set the kerberos state at the moment
		 */
		server_credentials = cli_credentials_init_anon(tmp_ctx);
		if (!server_credentials) {
			DEBUG(0, ("auth_generic_prepare: Failed to init server credentials\n"));
			return NT_STATUS_NO_MEMORY;
		}

		cli_credentials_set_conf(server_credentials, lp_ctx);

		if (lp_security() == SEC_ADS || USE_KERBEROS_KEYTAB) {
			cli_credentials_set_kerberos_state(server_credentials, CRED_AUTO_USE_KERBEROS);
		} else {
			cli_credentials_set_kerberos_state(server_credentials, CRED_DONT_USE_KERBEROS);
		}

		nt_status = gensec_server_start(tmp_ctx, gensec_settings,
						auth4_context, &gensec_security);

		if (!NT_STATUS_IS_OK(nt_status)) {
			TALLOC_FREE(tmp_ctx);
			return nt_status;
		}

		gensec_set_credentials(gensec_security, server_credentials);

		talloc_unlink(tmp_ctx, lp_ctx);
		talloc_unlink(tmp_ctx, server_credentials);
		talloc_unlink(tmp_ctx, gensec_settings);
		talloc_unlink(tmp_ctx, auth4_context);
	}

	nt_status = gensec_set_remote_address(gensec_security,
					      remote_address);
	if (!NT_STATUS_IS_OK(nt_status)) {
		TALLOC_FREE(tmp_ctx);
		return nt_status;
	}

	*gensec_security_out = talloc_steal(mem_ctx, gensec_security);
	TALLOC_FREE(tmp_ctx);
	return NT_STATUS_OK;
}
コード例 #4
0
static WERROR nt_printer_info_to_mods(TALLOC_CTX *ctx,
				      struct spoolss_PrinterInfo2 *info2,
				      ADS_MODLIST *mods)
{
	char *info_str;

	ads_mod_str(ctx, mods, SPOOL_REG_PRINTERNAME, info2->sharename);
	ads_mod_str(ctx, mods, SPOOL_REG_SHORTSERVERNAME, global_myname());
	ads_mod_str(ctx, mods, SPOOL_REG_SERVERNAME, get_mydnsfullname());

	info_str = talloc_asprintf(ctx, "\\\\%s\\%s",
				   get_mydnsfullname(), info2->sharename);
	if (info_str == NULL) {
		return WERR_NOMEM;
	}
	ads_mod_str(ctx, mods, SPOOL_REG_UNCNAME, info_str);

	info_str = talloc_asprintf(ctx, "%d", 4);
	if (info_str == NULL) {
		return WERR_NOMEM;
	}
	ads_mod_str(ctx, mods, SPOOL_REG_VERSIONNUMBER, info_str);

	/* empty strings in the mods list result in an attrubute error */
	if (strlen(info2->drivername) != 0)
		ads_mod_str(ctx, mods, SPOOL_REG_DRIVERNAME, info2->drivername);
	if (strlen(info2->location) != 0)
		ads_mod_str(ctx, mods, SPOOL_REG_LOCATION, info2->location);
	if (strlen(info2->comment) != 0)
		ads_mod_str(ctx, mods, SPOOL_REG_DESCRIPTION, info2->comment);
	if (strlen(info2->portname) != 0)
		ads_mod_str(ctx, mods, SPOOL_REG_PORTNAME, info2->portname);
	if (strlen(info2->sepfile) != 0)
		ads_mod_str(ctx, mods, SPOOL_REG_PRINTSEPARATORFILE, info2->sepfile);

	info_str = talloc_asprintf(ctx, "%u", info2->starttime);
	if (info_str == NULL) {
		return WERR_NOMEM;
	}
	ads_mod_str(ctx, mods, SPOOL_REG_PRINTSTARTTIME, info_str);

	info_str = talloc_asprintf(ctx, "%u", info2->untiltime);
	if (info_str == NULL) {
		return WERR_NOMEM;
	}
	ads_mod_str(ctx, mods, SPOOL_REG_PRINTENDTIME, info_str);

	info_str = talloc_asprintf(ctx, "%u", info2->priority);
	if (info_str == NULL) {
		return WERR_NOMEM;
	}
	ads_mod_str(ctx, mods, SPOOL_REG_PRIORITY, info_str);

	if (info2->attributes & PRINTER_ATTRIBUTE_KEEPPRINTEDJOBS) {
		ads_mod_str(ctx, mods, SPOOL_REG_PRINTKEEPPRINTEDJOBS, "TRUE");
	} else {
		ads_mod_str(ctx, mods, SPOOL_REG_PRINTKEEPPRINTEDJOBS, "FALSE");
	}

	switch (info2->attributes & 0x3) {
	case 0:
		ads_mod_str(ctx, mods, SPOOL_REG_PRINTSPOOLING,
			    SPOOL_REGVAL_PRINTWHILESPOOLING);
		break;
	case 1:
		ads_mod_str(ctx, mods, SPOOL_REG_PRINTSPOOLING,
			    SPOOL_REGVAL_PRINTAFTERSPOOLED);
		break;
	case 2:
		ads_mod_str(ctx, mods, SPOOL_REG_PRINTSPOOLING,
			    SPOOL_REGVAL_PRINTDIRECT);
		break;
	default:
		DEBUG(3, ("unsupported printer attributes %x\n",
			  info2->attributes));
	}

	return WERR_OK;
}
コード例 #5
0
ファイル: kerberos_verify.c プロジェクト: aosm/samba
static BOOL ads_keytab_verify_ticket(krb5_context context,
					krb5_auth_context auth_context,
					const DATA_BLOB *ticket,
					krb5_ticket **pp_tkt,
					krb5_keyblock **keyblock,
					krb5_error_code *perr)
{
	krb5_error_code ret = 0;
	BOOL auth_ok = False;
	krb5_keytab keytab = NULL;
	krb5_kt_cursor kt_cursor;
	krb5_keytab_entry kt_entry;
	char *valid_princ_formats[9];
	fstring my_name, my_fqdn;
	int i;

	const char * lkdc_realm = lp_parm_talloc_string(GLOBAL_SECTION_SNUM,
					"com.apple", "lkdc realm", NULL);

	ZERO_ARRAY(valid_princ_formats);

	*pp_tkt = NULL;
	*keyblock = NULL;
	*perr = 0;

	/* Generate the list of principal names which we expect
	 * clients might want to use for authenticating to the file
	 * service.  We allow name$,{host,cifs}/{name,fqdn,name.REALM}. */

	fstrcpy(my_name, global_myname());

	my_fqdn[0] = '\0';
	get_mydnsfullname(my_fqdn);

	asprintf(&valid_princ_formats[0], "%s$@%s", my_name, lp_realm());
	asprintf(&valid_princ_formats[1], "host/%s@%s", my_name, lp_realm());
	asprintf(&valid_princ_formats[2], "host/%s@%s", my_fqdn, lp_realm());
	asprintf(&valid_princ_formats[3], "host/%s.%s@%s", my_name, lp_realm(), lp_realm());
	asprintf(&valid_princ_formats[4], "cifs/%s@%s", my_name, lp_realm());
	asprintf(&valid_princ_formats[5], "cifs/%s@%s", my_fqdn, lp_realm());
	asprintf(&valid_princ_formats[6], "cifs/%s.%s@%s", my_name, lp_realm(), lp_realm());

	if (lkdc_realm) {
		asprintf(&valid_princ_formats[7],
			"host/%s@%s", lkdc_realm, lkdc_realm);
		asprintf(&valid_princ_formats[8],
			"cifs/%s@%s", lkdc_realm, lkdc_realm);
	}

	for (i = 0; i < ARRAY_SIZE(valid_princ_formats); i++) {

		ZERO_STRUCT(kt_entry);
		ZERO_STRUCT(kt_cursor);

		ret = krb5_kt_default(context, &keytab);
		if (ret) {
			DEBUG(1, ("ads_keytab_verify_ticket: krb5_kt_default failed (%s)\n", error_message(ret)));
			goto out;
		}

		/* Iterate through the keytab.  For each key, if the principal
		 * name case-insensitively matches one of the allowed formats,
		 * try verifying the ticket using that principal.
		 */

		ret = krb5_kt_start_seq_get(context, keytab, &kt_cursor);
		if (ret) {
			DEBUG(1, ("ads_keytab_verify_ticket: krb5_kt_start_seq_get failed (%s)\n", error_message(ret)));
			goto out;
		}

		while (!auth_ok && (krb5_kt_next_entry(context, keytab, &kt_entry, &kt_cursor) == 0)) {

			/* In MIT Kerberos, it is not legal to interleave krb5_rd_req()
			 * with krb5_kt_start_seq_get() and krb5_kt_end_seq_get() on the
			 * same krb5_keytab object. We have to keep a separate
			 * krb5_keytab object around for the krb5_rd_req().
			 */
			ret = ads_keytab_verify_for_principal(context,
				auth_context, &kt_entry, ticket,
				valid_princ_formats[i], pp_tkt, keyblock);

			if (ret == 0) {
				auth_ok = True;
			}

			/* Free the entry we just read. */
			smb_krb5_kt_free_entry(context, &kt_entry);
			ZERO_STRUCT(kt_entry);

			if (auth_ok) {
				/* success, let's go. */
				break;
			}

			/* workaround for MIT:
			* as krb5_ktfile_get_entry will explicitly
			* close the krb5_keytab as soon as krb5_rd_req
			* has sucessfully decrypted the ticket but the
			* ticket is not valid yet (due to clockskew)
			* there is no point in querying more keytab
			* entries - Guenther */
			if (ret == KRB5KRB_AP_ERR_TKT_NYV ||
			    ret == KRB5KRB_AP_ERR_TKT_EXPIRED ||
			    ret == KRB5KRB_AP_ERR_SKEW ||
			    ret == KRB5KRB_AP_ERR_REPEAT) {
			    break;
			}

		}

		krb5_kt_end_seq_get(context, keytab, &kt_cursor);
		krb5_kt_close(context, keytab);
		keytab = NULL;
	}

	ZERO_STRUCT(kt_cursor);

out:

	TALLOC_FREE(lkdc_realm);

	for (i = 0; i < ARRAY_SIZE(valid_princ_formats); i++) {
		SAFE_FREE(valid_princ_formats[i]);
	}

	{
		krb5_keytab_entry zero_kt_entry;
		ZERO_STRUCT(zero_kt_entry);
		if (memcmp(&zero_kt_entry, &kt_entry, sizeof(krb5_keytab_entry))) {
			smb_krb5_kt_free_entry(context, &kt_entry);
		}
	}

	{
		krb5_kt_cursor zero_csr;
		ZERO_STRUCT(zero_csr);
		if ((memcmp(&kt_cursor, &zero_csr, sizeof(krb5_kt_cursor)) != 0) && keytab) {
			krb5_kt_end_seq_get(context, keytab, &kt_cursor);
		}
	}

	if (keytab) {
		krb5_kt_close(context, keytab);
	}
	*perr = ret;
	return auth_ok;
}
コード例 #6
0
ファイル: auth_ntlmssp.c プロジェクト: srimalik/samba
static NTSTATUS gensec_ntlmssp3_server_start(struct gensec_security *gensec_security)
{
	NTSTATUS nt_status;
	bool is_standalone;
	const char *netbios_name;
	const char *netbios_domain;
	const char *dns_name;
	char *dns_domain;
	struct gensec_ntlmssp_context *gensec_ntlmssp;

	if ((enum server_role)lp_server_role() == ROLE_STANDALONE) {
		is_standalone = true;
	} else {
		is_standalone = false;
	}

	netbios_name = lp_netbios_name();
	netbios_domain = lp_workgroup();
	/* This should be a 'netbios domain -> DNS domain' mapping */
	dns_domain = get_mydnsdomname(talloc_tos());
	if (dns_domain) {
		strlower_m(dns_domain);
	}
	dns_name = get_mydnsfullname();

	nt_status = gensec_ntlmssp_start(gensec_security);
	NT_STATUS_NOT_OK_RETURN(nt_status);

	gensec_ntlmssp =
		talloc_get_type_abort(gensec_security->private_data,
				      struct gensec_ntlmssp_context);

	nt_status = make_auth_context_subsystem(gensec_ntlmssp, &gensec_ntlmssp->auth_context);
	if (!NT_STATUS_IS_OK(nt_status)) {
		return nt_status;
	}

	nt_status = ntlmssp_server_start(gensec_ntlmssp,
					 is_standalone,
					 netbios_name,
					 netbios_domain,
					 dns_name,
					 dns_domain,
					 &gensec_ntlmssp->ntlmssp_state);
	if (!NT_STATUS_IS_OK(nt_status)) {
		return nt_status;
	}

	gensec_ntlmssp->ntlmssp_state->callback_private = gensec_ntlmssp;

	gensec_ntlmssp->ntlmssp_state->get_challenge = auth_ntlmssp_get_challenge;
	gensec_ntlmssp->ntlmssp_state->may_set_challenge = auth_ntlmssp_may_set_challenge;
	gensec_ntlmssp->ntlmssp_state->set_challenge = auth_ntlmssp_set_challenge;
	gensec_ntlmssp->ntlmssp_state->check_password = auth_ntlmssp_check_password;

	if (gensec_ntlmssp->gensec_security->want_features & GENSEC_FEATURE_SESSION_KEY) {
		gensec_ntlmssp->ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SIGN;
	}
	if (gensec_ntlmssp->gensec_security->want_features & GENSEC_FEATURE_SIGN) {
		gensec_ntlmssp->ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SIGN;
	}
	if (gensec_ntlmssp->gensec_security->want_features & GENSEC_FEATURE_SEAL) {
		gensec_ntlmssp->ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SIGN;
		gensec_ntlmssp->ntlmssp_state->neg_flags |= NTLMSSP_NEGOTIATE_SEAL;
	}

	return NT_STATUS_OK;
}
コード例 #7
0
ファイル: auth_ntlmssp.c プロジェクト: Arkhont/samba
NTSTATUS auth_ntlmssp_start(const struct tsocket_address *remote_address,
			    struct auth_ntlmssp_state **auth_ntlmssp_state)
{
	NTSTATUS nt_status;
	bool is_standalone;
	const char *netbios_name;
	const char *netbios_domain;
	const char *dns_name;
	char *dns_domain;
	struct auth_ntlmssp_state *ans;
	struct auth_context *auth_context;

	if ((enum server_role)lp_server_role() == ROLE_STANDALONE) {
		is_standalone = true;
	} else {
		is_standalone = false;
	}

	netbios_name = lp_netbios_name();
	netbios_domain = lp_workgroup();
	/* This should be a 'netbios domain -> DNS domain' mapping */
	dns_domain = get_mydnsdomname(talloc_tos());
	if (dns_domain) {
		strlower_m(dns_domain);
	}
	dns_name = get_mydnsfullname();

	ans = talloc_zero(NULL, struct auth_ntlmssp_state);
	if (!ans) {
		DEBUG(0,("auth_ntlmssp_start: talloc failed!\n"));
		return NT_STATUS_NO_MEMORY;
	}

	ans->remote_address = tsocket_address_copy(remote_address, ans);
	if (ans->remote_address == NULL) {
		DEBUG(0,("auth_ntlmssp_start: talloc failed!\n"));
		return NT_STATUS_NO_MEMORY;
	}

	nt_status = ntlmssp_server_start(ans,
					 is_standalone,
					 netbios_name,
					 netbios_domain,
					 dns_name,
					 dns_domain,
					 &ans->ntlmssp_state);
	if (!NT_STATUS_IS_OK(nt_status)) {
		return nt_status;
	}

	nt_status = make_auth_context_subsystem(talloc_tos(), &auth_context);
	if (!NT_STATUS_IS_OK(nt_status)) {
		return nt_status;
	}
	ans->auth_context = talloc_steal(ans, auth_context);

	ans->ntlmssp_state->callback_private = ans;
	ans->ntlmssp_state->get_challenge = auth_ntlmssp_get_challenge;
	ans->ntlmssp_state->may_set_challenge = auth_ntlmssp_may_set_challenge;
	ans->ntlmssp_state->set_challenge = auth_ntlmssp_set_challenge;
	ans->ntlmssp_state->check_password = auth_ntlmssp_check_password;

	talloc_set_destructor((TALLOC_CTX *)ans, auth_ntlmssp_state_destructor);

	*auth_ntlmssp_state = ans;
	return NT_STATUS_OK;
}