Ejemplo n.º 1
0
static NTSTATUS gensec_gssapi_start(struct gensec_security *gensec_security)
{
	struct gensec_gssapi_state *gensec_gssapi_state;
	krb5_error_code ret;
#ifdef SAMBA4_USES_HEIMDAL
	const char *realm;
#endif

	gensec_gssapi_state = talloc_zero(gensec_security, struct gensec_gssapi_state);
	if (!gensec_gssapi_state) {
		return NT_STATUS_NO_MEMORY;
	}

	gensec_security->private_data = gensec_gssapi_state;

	gensec_gssapi_state->gssapi_context = GSS_C_NO_CONTEXT;

	/* TODO: Fill in channel bindings */
	gensec_gssapi_state->input_chan_bindings = GSS_C_NO_CHANNEL_BINDINGS;

	gensec_gssapi_state->server_name = GSS_C_NO_NAME;
	gensec_gssapi_state->client_name = GSS_C_NO_NAME;
	
	gensec_gssapi_state->gss_want_flags = 0;
	gensec_gssapi_state->expire_time = GENSEC_EXPIRE_TIME_INFINITY;

	if (gensec_setting_bool(gensec_security->settings, "gensec_gssapi", "delegation_by_kdc_policy", true)) {
		gensec_gssapi_state->gss_want_flags |= GSS_C_DELEG_POLICY_FLAG;
	}
	if (gensec_setting_bool(gensec_security->settings, "gensec_gssapi", "mutual", true)) {
		gensec_gssapi_state->gss_want_flags |= GSS_C_MUTUAL_FLAG;
	}
	if (gensec_setting_bool(gensec_security->settings, "gensec_gssapi", "delegation", true)) {
		gensec_gssapi_state->gss_want_flags |= GSS_C_DELEG_FLAG;
	}
	if (gensec_setting_bool(gensec_security->settings, "gensec_gssapi", "replay", true)) {
		gensec_gssapi_state->gss_want_flags |= GSS_C_REPLAY_FLAG;
	}
	if (gensec_setting_bool(gensec_security->settings, "gensec_gssapi", "sequence", true)) {
		gensec_gssapi_state->gss_want_flags |= GSS_C_SEQUENCE_FLAG;
	}

	if (gensec_security->want_features & GENSEC_FEATURE_SIGN) {
		gensec_gssapi_state->gss_want_flags |= GSS_C_INTEG_FLAG;
	}
	if (gensec_security->want_features & GENSEC_FEATURE_SEAL) {
		gensec_gssapi_state->gss_want_flags |= GSS_C_INTEG_FLAG;
		gensec_gssapi_state->gss_want_flags |= GSS_C_CONF_FLAG;
	}
	if (gensec_security->want_features & GENSEC_FEATURE_DCE_STYLE) {
		gensec_gssapi_state->gss_want_flags |= GSS_C_DCE_STYLE;
	}

	gensec_gssapi_state->gss_got_flags = 0;

	switch (gensec_security->ops->auth_type) {
	case DCERPC_AUTH_TYPE_SPNEGO:
		gensec_gssapi_state->gss_oid = gss_mech_spnego;
		break;
	case DCERPC_AUTH_TYPE_KRB5:
	default:
		gensec_gssapi_state->gss_oid =
			discard_const_p(void, gss_mech_krb5);
		break;
	}

	ret = smb_krb5_init_context(gensec_gssapi_state,
				    gensec_security->settings->lp_ctx,
				    &gensec_gssapi_state->smb_krb5_context);
	if (ret) {
		DEBUG(1,("gensec_gssapi_start: smb_krb5_init_context failed (%s)\n",
			 error_message(ret)));
		talloc_free(gensec_gssapi_state);
		return NT_STATUS_INTERNAL_ERROR;
	}

	gensec_gssapi_state->client_cred = NULL;
	gensec_gssapi_state->server_cred = NULL;

	gensec_gssapi_state->delegated_cred_handle = GSS_C_NO_CREDENTIAL;

	gensec_gssapi_state->sasl = false;
	gensec_gssapi_state->sasl_state = STAGE_GSS_NEG;
	gensec_gssapi_state->sasl_protection = 0;

	gensec_gssapi_state->max_wrap_buf_size
		= gensec_setting_int(gensec_security->settings, "gensec_gssapi", "max wrap buf size", 65536);
	gensec_gssapi_state->gss_exchange_count = 0;
	gensec_gssapi_state->sig_size = 0;

	talloc_set_destructor(gensec_gssapi_state, gensec_gssapi_destructor);

#ifdef SAMBA4_USES_HEIMDAL
	realm = lpcfg_realm(gensec_security->settings->lp_ctx);
	if (realm != NULL) {
		ret = gsskrb5_set_default_realm(realm);
		if (ret) {
			DEBUG(1,("gensec_gssapi_start: gsskrb5_set_default_realm failed\n"));
			talloc_free(gensec_gssapi_state);
			return NT_STATUS_INTERNAL_ERROR;
		}
	}

	/* don't do DNS lookups of any kind, it might/will fail for a netbios name */
	ret = gsskrb5_set_dns_canonicalize(gensec_setting_bool(gensec_security->settings, "krb5", "set_dns_canonicalize", false));
	if (ret) {
		DEBUG(1,("gensec_gssapi_start: gsskrb5_set_dns_canonicalize failed\n"));
		talloc_free(gensec_gssapi_state);
		return NT_STATUS_INTERNAL_ERROR;
	}
#endif
	return NT_STATUS_OK;
}
Ejemplo n.º 2
0
int
main(int argc, char **argv)
{
    gss_buffer_desc name_buffer;
    OM_uint32 maj_stat, min_stat;
    gss_name_t name, MNname, MNname2;
    int optidx = 0;
    char *str;
    int len, equal;

    setprogname(argv[0]);
    if(getarg(args, sizeof(args) / sizeof(args[0]), argc, argv, &optidx))
	usage(1);

    if (help_flag)
	usage (0);

    if(version_flag){
	print_version(NULL);
	exit(0);
    }

    argc -= optidx;
    argv += optidx;

    gsskrb5_set_default_realm("MIT.EDU");

    /*
     * test import/export
     */

    str = NULL;
    len = asprintf(&str, "*****@*****.**");
    if (len < 0 || str == NULL)
	errx(1, "asprintf");

    name_buffer.value = str;
    name_buffer.length = len;

    maj_stat = gss_import_name(&min_stat, &name_buffer,
			       GSS_C_NT_HOSTBASED_SERVICE,
			       &name);
    if (maj_stat != GSS_S_COMPLETE)
	gss_err(1, min_stat, "import name error");
    free(str);

    maj_stat = gss_canonicalize_name (&min_stat,
				      name,
				      GSS_KRB5_MECHANISM,
				      &MNname);
    if (maj_stat != GSS_S_COMPLETE)
	gss_err(1, min_stat, "canonicalize name error");

    maj_stat = gss_export_name(&min_stat,
			       MNname,
			       &name_buffer);
    if (maj_stat != GSS_S_COMPLETE)
	gss_err(1, min_stat, "export name error (KRB5)");

    /*
     * Import the exported name and compare
     */

    maj_stat = gss_import_name(&min_stat, &name_buffer,
			       GSS_C_NT_EXPORT_NAME,
			       &MNname2);
    if (maj_stat != GSS_S_COMPLETE)
	gss_err(1, min_stat, "import name error (exported KRB5 name)");


    maj_stat = gss_compare_name(&min_stat, MNname, MNname2, &equal);
    if (maj_stat != GSS_S_COMPLETE)
	errx(1, "gss_compare_name");
    if (!equal)
	errx(1, "names not equal");

    gss_release_name(&min_stat, &MNname2);
    gss_release_buffer(&min_stat, &name_buffer);
    gss_release_name(&min_stat, &MNname);
    gss_release_name(&min_stat, &name);

    /*
     * Import oid less name and compare to mech name.
     * Dovecot SASL lib does this.
     */

    str = NULL;
    len = asprintf(&str, "lha");
    if (len < 0 || str == NULL)
	errx(1, "asprintf");

    name_buffer.value = str;
    name_buffer.length = len;

    maj_stat = gss_import_name(&min_stat, &name_buffer,
			       GSS_C_NO_OID,
			       &name);
    if (maj_stat != GSS_S_COMPLETE)
	gss_err(1, min_stat, "import (no oid) name error");

    maj_stat = gss_import_name(&min_stat, &name_buffer,
			       GSS_KRB5_NT_USER_NAME,
			       &MNname);
    if (maj_stat != GSS_S_COMPLETE)
	gss_err(1, min_stat, "import (krb5 mn) name error");

    free(str);

    maj_stat = gss_compare_name(&min_stat, name, MNname, &equal);
    if (maj_stat != GSS_S_COMPLETE)
	errx(1, "gss_compare_name");
    if (!equal)
	errx(1, "names not equal");

    gss_release_name(&min_stat, &MNname);
    gss_release_name(&min_stat, &name);

#if 0
    maj_stat = gss_canonicalize_name (&min_stat,
				      name,
				      GSS_SPNEGO_MECHANISM,
				      &MNname);
    if (maj_stat != GSS_S_COMPLETE)
	gss_err(1, min_stat, "canonicalize name error");


    maj_stat = gss_export_name(&maj_stat,
			       MNname,
			       &name_buffer);
    if (maj_stat != GSS_S_COMPLETE)
	gss_err(1, min_stat, "export name error (SPNEGO)");

    gss_release_name(&min_stat, &MNname);
    gss_release_buffer(&min_stat, &name_buffer);
#endif

    return 0;
}