Ejemplo n.º 1
0
Archivo: open.c Proyecto: riton/remctl
static bool
internal_set_cred(struct remctl *r, gss_cred_id_t *gss_cred)
{
    krb5_error_code code;
    OM_uint32 major, minor;

    if (r->krb_ctx == NULL) {
        code = krb5_init_context(&r->krb_ctx);
        if (code != 0) {
            internal_krb5_error(r, "opening ticket cache", code);
            return false;
        }
    }
    if (r->krb_ccache != NULL)
        krb5_cc_close(r->krb_ctx, r->krb_ccache);
    code = krb5_cc_resolve(r->krb_ctx, r->ccache, &r->krb_ccache);
    if (code != 0) {
        internal_krb5_error(r, "opening ticket cache", code);
        return false;
    }
    major = gss_krb5_import_cred(&minor, r->krb_ccache, NULL, NULL, gss_cred);
    if (major != GSS_S_COMPLETE) {
        internal_gssapi_error(r, "importing ticket cache", major, minor);
        return false;
    }
    return true;
}
Ejemplo n.º 2
0
int cli_credentials_get_client_gss_creds(struct cli_credentials *cred, 
					 struct gssapi_creds_container **_gcc) 
{
	int ret = 0;
	OM_uint32 maj_stat, min_stat;
	struct gssapi_creds_container *gcc;
	struct ccache_container *ccache;
	if (cred->client_gss_creds_obtained >= (MAX(cred->ccache_obtained, 
					     MAX(cred->principal_obtained, 
						 cred->username_obtained)))) {
		*_gcc = cred->client_gss_creds;
		return 0;
	}
	ret = cli_credentials_get_ccache(cred, 
					 &ccache);
	if (ret) {
		DEBUG(1, ("Failed to get CCACHE for GSSAPI client: %s\n", error_message(ret)));
		return ret;
	}

	gcc = talloc(cred, struct gssapi_creds_container);
	if (!gcc) {
		return ENOMEM;
	}

	maj_stat = gss_krb5_import_cred(&min_stat, ccache->ccache, NULL, NULL, 
					&gcc->creds);
	if (maj_stat) {
		if (min_stat) {
			ret = min_stat;
		} else {
			ret = EINVAL;
		}
	}
	if (ret == 0) {
		cred->client_gss_creds_obtained = cred->ccache_obtained;
		talloc_set_destructor(gcc, free_gssapi_creds);
		cred->client_gss_creds = gcc;
		*_gcc = gcc;
	}
	return ret;
}
Ejemplo n.º 3
0
static gss_client_response *init_gss_creds(const char *credential_cache, gss_cred_id_t *cred) {
  OM_uint32 maj_stat;
  OM_uint32 min_stat;
  krb5_context context;
  krb5_error_code problem;
  gss_client_response *response = NULL;
  krb5_ccache ccache = NULL;

  *cred = GSS_C_NO_CREDENTIAL;

  if (credential_cache == NULL || strlen(credential_cache) == 0) {
      return NULL;
  }

  problem = krb5_init_context(&context);
  if (problem) {
      return other_error("unable to initialize krb5 context (%d)", (int)problem);
  }

  problem = krb5_cc_resolve(context, credential_cache, &ccache);
  if (problem) {
      response = krb5_ctx_error(context, problem);
      goto done;
  }

  maj_stat = gss_krb5_import_cred(&min_stat, ccache, NULL, NULL, cred);
  if (GSS_ERROR(maj_stat)) {
    response = gss_error(__func__, "gss_krb5_import_cred", maj_stat, min_stat);
    response->return_code = AUTH_GSS_ERROR;
  }

 done:
  if (response && ccache) {
      krb5_cc_close(context, ccache);
  }

  krb5_free_context(context);

  return response;
}
Ejemplo n.º 4
0
static ADS_STATUS ads_init_gssapi_cred(ADS_STRUCT *ads, gss_cred_id_t *cred)
{
	ADS_STATUS status;
	krb5_context kctx;
	krb5_error_code kerr;
	krb5_ccache kccache = NULL;
	uint32_t maj, min;

	*cred = GSS_C_NO_CREDENTIAL;

	if (!ads->auth.ccache_name) {
		return ADS_SUCCESS;
	}

	kerr = krb5_init_context(&kctx);
	if (kerr) {
		return ADS_ERROR_KRB5(kerr);
	}

#ifdef HAVE_GSS_KRB5_IMPORT_CRED
	kerr = krb5_cc_resolve(kctx, ads->auth.ccache_name, &kccache);
	if (kerr) {
		status = ADS_ERROR_KRB5(kerr);
		goto done;
	}

	maj = gss_krb5_import_cred(&min, kccache, NULL, NULL, cred);
	if (maj != GSS_S_COMPLETE) {
		status = ADS_ERROR_GSS(maj, min);
		goto done;
	}
#else
	/* We need to fallback to overriding the default creds.
	 * This operation is not thread safe as it changes the process
	 * environment variable, but we do not have any better option
	 * with older kerberos libraries */
	{
		const char *oldccname = NULL;

		oldccname = getenv("KRB5CCNAME");
		setenv("KRB5CCNAME", ads->auth.ccache_name, 1);

		maj = gss_acquire_cred(&min, GSS_C_NO_NAME, GSS_C_INDEFINITE,
				       NULL, GSS_C_INITIATE, cred, NULL, NULL);

		if (oldccname) {
			setenv("KRB5CCNAME", oldccname, 1);
		} else {
			unsetenv("KRB5CCNAME");
		}

		if (maj != GSS_S_COMPLETE) {
			status = ADS_ERROR_GSS(maj, min);
			goto done;
		}
	}
#endif

	status = ADS_SUCCESS;

done:
	if (!ADS_ERR_OK(status) && kccache != NULL) {
		krb5_cc_close(kctx, kccache);
	}
	krb5_free_context(kctx);
	return status;
}
Ejemplo n.º 5
0
static int32_t
acquire_cred(struct client *c,
	     krb5_principal principal,
	     krb5_get_init_creds_opt *opt,
	     int32_t *handle)
{
    krb5_error_code ret;
    krb5_creds cred;
    krb5_ccache id;
    gss_cred_id_t gcred;
    OM_uint32 maj_stat, min_stat;

    *handle = 0;

    krb5_get_init_creds_opt_set_forwardable (opt, 1);
    krb5_get_init_creds_opt_set_renew_life (opt, 3600 * 24 * 30);

    memset(&cred, 0, sizeof(cred));

    ret = krb5_get_init_creds_password (context,
					&cred,
					principal,
					NULL,
					NULL,
					NULL,
					0,
					NULL,
					opt);
    if (ret) {
	logmessage(c, __FILE__, __LINE__, 0,
		   "krb5_get_init_creds failed: %d", ret);
	return convert_krb5_to_gsm(ret);
    }

    ret = krb5_cc_new_unique(context, "MEMORY", NULL, &id);
    if (ret)
	krb5_err (context, 1, ret, "krb5_cc_initialize");

    ret = krb5_cc_initialize (context, id, cred.client);
    if (ret)
	krb5_err (context, 1, ret, "krb5_cc_initialize");

    ret = krb5_cc_store_cred (context, id, &cred);
    if (ret)
	krb5_err (context, 1, ret, "krb5_cc_store_cred");

    krb5_free_cred_contents (context, &cred);

    maj_stat = gss_krb5_import_cred(&min_stat,
				    id,
				    NULL,
				    NULL,
				    &gcred);
    krb5_cc_close(context, id);
    if (maj_stat) {
	logmessage(c, __FILE__, __LINE__, 0,
		   "krb5 import creds failed with: %d", maj_stat);
	return convert_gss_to_gsm(maj_stat);
    }

    *handle = add_handle(c, handle_cred, gcred);

    return 0;
}
Ejemplo n.º 6
0
_PUBLIC_ int cli_credentials_get_server_gss_creds(struct cli_credentials *cred, 
						  struct loadparm_context *lp_ctx,
						  struct gssapi_creds_container **_gcc)
{
	int ret = 0;
	OM_uint32 maj_stat, min_stat;
	struct gssapi_creds_container *gcc;
	struct keytab_container *ktc;
	struct smb_krb5_context *smb_krb5_context;
	TALLOC_CTX *mem_ctx;
	krb5_principal princ;
	const char *error_string;
	enum credentials_obtained obtained;

	mem_ctx = talloc_new(cred);
	if (!mem_ctx) {
		return ENOMEM;
	}

	ret = cli_credentials_get_krb5_context(cred, lp_ctx, &smb_krb5_context);
	if (ret) {
		return ret;
	}

	ret = principal_from_credentials(mem_ctx, cred, smb_krb5_context, &princ, &obtained, &error_string);
	if (ret) {
		DEBUG(1,("cli_credentials_get_server_gss_creds: making krb5 principal failed (%s)\n",
			 error_string));
		talloc_free(mem_ctx);
		return ret;
	}

	if (cred->server_gss_creds_obtained >= (MAX(cred->keytab_obtained, obtained))) {
		talloc_free(mem_ctx);
		*_gcc = cred->server_gss_creds;
		return 0;
	}

	ret = cli_credentials_get_keytab(cred, lp_ctx, &ktc);
	if (ret) {
		DEBUG(1, ("Failed to get keytab for GSSAPI server: %s\n", error_message(ret)));
		return ret;
	}

	gcc = talloc(cred, struct gssapi_creds_container);
	if (!gcc) {
		talloc_free(mem_ctx);
		return ENOMEM;
	}

	if (ktc->password_based || obtained < CRED_SPECIFIED) {
		/* This creates a GSSAPI cred_id_t for match-by-key with only the keytab set */
		maj_stat = gss_krb5_import_cred(&min_stat, NULL, NULL, ktc->keytab,
						&gcc->creds);
	} else {
		/* This creates a GSSAPI cred_id_t with the principal and keytab set, matching by name */
		maj_stat = gss_krb5_import_cred(&min_stat, NULL, princ, ktc->keytab,
						&gcc->creds);
	}
	if (maj_stat) {
		if (min_stat) {
			ret = min_stat;
		} else {
			ret = EINVAL;
		}
	}
	if (ret == 0) {
		cred->server_gss_creds_obtained = cred->keytab_obtained;
		talloc_set_destructor(gcc, free_gssapi_creds);
		cred->server_gss_creds = gcc;
		*_gcc = gcc;
	}
	talloc_free(mem_ctx);
	return ret;
}
Ejemplo n.º 7
0
_PUBLIC_ int cli_credentials_get_client_gss_creds(struct cli_credentials *cred, 
						  struct tevent_context *event_ctx,
						  struct loadparm_context *lp_ctx,
						  struct gssapi_creds_container **_gcc,
						  const char **error_string)
{
	int ret = 0;
	OM_uint32 maj_stat, min_stat;
	struct gssapi_creds_container *gcc;
	struct ccache_container *ccache;
#ifdef SAMBA4_USES_HEIMDAL
	gss_buffer_desc empty_buffer = GSS_C_EMPTY_BUFFER;
#endif
	krb5_enctype *etypes = NULL;

	if (cred->client_gss_creds_obtained >= cred->client_gss_creds_threshold && 
	    cred->client_gss_creds_obtained > CRED_UNINITIALISED) {
		bool expired = false;
		OM_uint32 lifetime = 0;
		gss_cred_usage_t usage = 0;
		maj_stat = gss_inquire_cred(&min_stat, cred->client_gss_creds->creds, 
					    NULL, &lifetime, &usage, NULL);
		if (maj_stat == GSS_S_CREDENTIALS_EXPIRED) {
			DEBUG(3, ("Credentials for %s expired, must refresh credentials cache\n", cli_credentials_get_principal(cred, cred)));
			expired = true;
		} else if (maj_stat == GSS_S_COMPLETE && lifetime < 300) {
			DEBUG(3, ("Credentials for %s will expire shortly (%u sec), must refresh credentials cache\n", cli_credentials_get_principal(cred, cred), lifetime));
			expired = true;
		} else if (maj_stat != GSS_S_COMPLETE) {
			*error_string = talloc_asprintf(cred, "inquiry of credential lifefime via GSSAPI gss_inquire_cred failed: %s\n",
							gssapi_error_string(cred, maj_stat, min_stat, NULL));
			return EINVAL;
		}
		if (expired) {
			cli_credentials_unconditionally_invalidate_client_gss_creds(cred);
		} else {
			DEBUG(5, ("GSSAPI credentials for %s will expire in %u secs\n", 
				  cli_credentials_get_principal(cred, cred), (unsigned int)lifetime));
		
			*_gcc = cred->client_gss_creds;
			return 0;
		}
	}

	ret = cli_credentials_get_ccache(cred, event_ctx, lp_ctx,
					 &ccache, error_string);
	if (ret) {
		if (cli_credentials_get_kerberos_state(cred) == CRED_MUST_USE_KERBEROS) {
			DEBUG(1, ("Failed to get kerberos credentials (kerberos required): %s\n", *error_string));
		} else {
			DEBUG(4, ("Failed to get kerberos credentials: %s\n", *error_string));
		}
		return ret;
	}

	gcc = talloc(cred, struct gssapi_creds_container);
	if (!gcc) {
		(*error_string) = error_message(ENOMEM);
		return ENOMEM;
	}

	maj_stat = gss_krb5_import_cred(&min_stat, ccache->ccache, NULL, NULL, 
					&gcc->creds);
	if ((maj_stat == GSS_S_FAILURE) && (min_stat == (OM_uint32)KRB5_CC_END || min_stat == (OM_uint32) KRB5_CC_NOTFOUND)) {
		/* This CCACHE is no good.  Ensure we don't use it again */
		cli_credentials_unconditionally_invalidate_ccache(cred);

		/* Now try again to get a ccache */
		ret = cli_credentials_get_ccache(cred, event_ctx, lp_ctx,
						 &ccache, error_string);
		if (ret) {
			DEBUG(1, ("Failed to re-get CCACHE for GSSAPI client: %s\n", error_message(ret)));
			return ret;
		}

		maj_stat = gss_krb5_import_cred(&min_stat, ccache->ccache, NULL, NULL,
						&gcc->creds);

	}

	if (maj_stat) {
		talloc_free(gcc);
		if (min_stat) {
			ret = min_stat;
		} else {
			ret = EINVAL;
		}
		(*error_string) = talloc_asprintf(cred, "gss_krb5_import_cred failed: %s", error_message(ret));
		return ret;
	}


	/*
	 * transfer the enctypes from the smb_krb5_context to the gssapi layer
	 *
	 * We use 'our' smb_krb5_context to do the AS-REQ and it is possible
	 * to configure the enctypes via the krb5.conf.
	 *
	 * And the gss_init_sec_context() creates it's own krb5_context and
	 * the TGS-REQ had all enctypes in it and only the ones configured
	 * and used for the AS-REQ, so it wasn't possible to disable the usage
	 * of AES keys.
	 */
	min_stat = get_kerberos_allowed_etypes(ccache->smb_krb5_context->krb5_context,
					       &etypes);
	if (min_stat == 0) {
		OM_uint32 num_ktypes;

		for (num_ktypes = 0; etypes[num_ktypes]; num_ktypes++);

		maj_stat = gss_krb5_set_allowable_enctypes(&min_stat, gcc->creds,
							   num_ktypes,
							   (int32_t *) etypes);
		SAFE_FREE(etypes);
		if (maj_stat) {
			talloc_free(gcc);
			if (min_stat) {
				ret = min_stat;
			} else {
				ret = EINVAL;
			}
			(*error_string) = talloc_asprintf(cred, "gss_krb5_set_allowable_enctypes failed: %s", error_message(ret));
			return ret;
		}
	}

#ifdef SAMBA4_USES_HEIMDAL /* MIT lacks GSS_KRB5_CRED_NO_CI_FLAGS_X */

	/* don't force GSS_C_CONF_FLAG and GSS_C_INTEG_FLAG */
	maj_stat = gss_set_cred_option(&min_stat, &gcc->creds,
				       GSS_KRB5_CRED_NO_CI_FLAGS_X,
				       &empty_buffer);
	if (maj_stat) {
		talloc_free(gcc);
		if (min_stat) {
			ret = min_stat;
		} else {
			ret = EINVAL;
		}
		(*error_string) = talloc_asprintf(cred, "gss_set_cred_option failed: %s", error_message(ret));
		return ret;
	}
#endif
	cred->client_gss_creds_obtained = cred->ccache_obtained;
	talloc_set_destructor(gcc, free_gssapi_creds);
	cred->client_gss_creds = gcc;
	*_gcc = gcc;
	return 0;
}
Ejemplo n.º 8
0
int cli_credentials_get_server_gss_creds(struct cli_credentials *cred, 
					 struct gssapi_creds_container **_gcc) 
{
	int ret = 0;
	OM_uint32 maj_stat, min_stat;
	struct gssapi_creds_container *gcc;
	struct keytab_container *ktc;
	struct smb_krb5_context *smb_krb5_context;
	TALLOC_CTX *mem_ctx;
	krb5_principal princ;

	if (cred->server_gss_creds_obtained >= (MAX(cred->keytab_obtained, 
						    MAX(cred->principal_obtained, 
							cred->username_obtained)))) {
		*_gcc = cred->server_gss_creds;
		return 0;
	}

	ret = cli_credentials_get_krb5_context(cred, &smb_krb5_context);
	if (ret) {
		return ret;
	}

	ret = cli_credentials_get_keytab(cred, 
					 &ktc);
	if (ret) {
		DEBUG(1, ("Failed to get keytab for GSSAPI server: %s\n", error_message(ret)));
		return ret;
	}

	mem_ctx = talloc_new(cred);
	if (!mem_ctx) {
		return ENOMEM;
	}

	ret = principal_from_credentials(mem_ctx, cred, smb_krb5_context, &princ);
	if (ret) {
		DEBUG(1,("cli_credentials_get_server_gss_creds: makeing krb5 principal failed (%s)\n",
			 smb_get_krb5_error_message(smb_krb5_context->krb5_context, 
						    ret, mem_ctx)));
		talloc_free(mem_ctx);
		return ret;
	}

	gcc = talloc(cred, struct gssapi_creds_container);
	if (!gcc) {
		talloc_free(mem_ctx);
		return ENOMEM;
	}

	/* This creates a GSSAPI cred_id_t with the principal and keytab set */
	maj_stat = gss_krb5_import_cred(&min_stat, NULL, princ, ktc->keytab, 
					&gcc->creds);
	if (maj_stat) {
		if (min_stat) {
			ret = min_stat;
		} else {
			ret = EINVAL;
		}
	}
	if (ret == 0) {
		cred->server_gss_creds_obtained = cred->keytab_obtained;
		talloc_set_destructor(gcc, free_gssapi_creds);
		cred->server_gss_creds = gcc;
		*_gcc = gcc;
	}
	talloc_free(mem_ctx);
	return ret;
}
static void
copy_import(void)
{
    gss_cred_id_t cred1, cred2;
    OM_uint32 maj_stat, min_stat;
    gss_name_t name1, name2;
    OM_uint32 lifetime1, lifetime2;
    gss_cred_usage_t usage1, usage2;
    gss_OID_set mechs1, mechs2;
    krb5_ccache id;
    krb5_error_code ret;
    krb5_context context;
    int equal;

    maj_stat = gss_acquire_cred(&min_stat, GSS_C_NO_NAME, GSS_C_INDEFINITE,
				GSS_C_NO_OID_SET, GSS_C_INITIATE,
				&cred1, NULL, NULL);
    if (maj_stat != GSS_S_COMPLETE)
	errx(1, "gss_acquire_cred");

    maj_stat = gss_inquire_cred(&min_stat, cred1, &name1, &lifetime1,
				&usage1, &mechs1);
    if (maj_stat != GSS_S_COMPLETE)
	errx(1, "gss_inquire_cred");

    ret = krb5_init_context(&context);
    if (ret)
	errx(1, "krb5_init_context");

    ret = krb5_cc_new_unique(context, krb5_cc_type_memory, NULL, &id);
    if (ret)
	krb5_err(context, 1, ret, "krb5_cc_new_unique");

    maj_stat = gss_krb5_copy_ccache(&min_stat, cred1, id);
    if (maj_stat != GSS_S_COMPLETE)
	errx(1, "gss_krb5_copy_ccache");

    maj_stat = gss_krb5_import_cred(&min_stat, id, NULL, NULL, &cred2);
    if (maj_stat != GSS_S_COMPLETE)
	errx(1, "gss_krb5_import_cred");

    maj_stat = gss_inquire_cred(&min_stat, cred2, &name2, &lifetime2,
				&usage2, &mechs2);
    if (maj_stat != GSS_S_COMPLETE)
	errx(1, "gss_inquire_cred 2");

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

    if (lifetime1 != lifetime2)
	errx(1, "lifetime not equal %lu != %lu",
	     (unsigned long)lifetime1, (unsigned long)lifetime2);

    if (usage1 != usage2) {
	/* as long any of them is both are everything it ok */
	if (usage1 != GSS_C_BOTH && usage2 != GSS_C_BOTH)
	    errx(1, "usages disjoined");
    }

    gss_release_name(&min_stat, &name2);
    gss_release_oid_set(&min_stat, &mechs2);

    maj_stat = gss_inquire_cred(&min_stat, cred2, &name2, &lifetime2,
				&usage2, &mechs2);
    if (maj_stat != GSS_S_COMPLETE)
	errx(1, "gss_inquire_cred");

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

    if (lifetime1 != lifetime2)
	errx(1, "lifetime not equal %lu != %lu",
	     (unsigned long)lifetime1, (unsigned long)lifetime2);

    gss_release_cred(&min_stat, &cred1);
    gss_release_cred(&min_stat, &cred2);

    gss_release_name(&min_stat, &name1);
    gss_release_name(&min_stat, &name2);

#if 0
    compare(mechs1, mechs2);
#endif

    gss_release_oid_set(&min_stat, &mechs1);
    gss_release_oid_set(&min_stat, &mechs2);

    krb5_cc_destroy(context, id);
    krb5_free_context(context);
}
Ejemplo n.º 10
0
OM_uint32 Curl_gss_init_sec_context(
    struct connectdata *conn,
    OM_uint32 * minor_status,
    gss_ctx_id_t * context,
    gss_name_t target_name,
    gss_channel_bindings_t input_chan_bindings,
    gss_buffer_t input_token,
    gss_buffer_t output_token,
    OM_uint32 * ret_flags)
{ 
	krb5_context krb_context = NULL;							/* Kerberos context object */
	krb5_ccache ccache = NULL;									
    krb5_creds creds;
    krb5_get_init_creds_opt *opts = NULL;
    krb5_principal principal = NULL;
    krb5_keytab ktab = NULL;
	OM_uint32 min_stat, maj_stat;
	char *cachename = NULL;
    char *keytabfile = "";
	OM_uint32 major_status;

	struct SessionHandle *data = conn->data;
	int ret;
	OM_uint32 req_flags = GSS_C_MUTUAL_FLAG | GSS_C_REPLAY_FLAG;
	conn->data->curl_gss_creds = GSS_C_NO_CREDENTIAL;
	
	memset(&creds, 0, sizeof(creds));

	if(data->set.gssapi_delegation & CURLGSSAPI_DELEGATION_POLICY_FLAG) {
		#ifdef GSS_C_DELEG_POLICY_FLAG
			req_flags |= GSS_C_DELEG_POLICY_FLAG;
		#else
		    infof(data, "warning: support for CURLGSSAPI_DELEGATION_POLICY_FLAG not "
		        "compiled in\n");
		#endif
	}

	if(data->set.gssapi_delegation & CURLGSSAPI_DELEGATION_FLAG)
		req_flags |= GSS_C_DELEG_FLAG;

	if((ret = krb5_init_context(&krb_context)) != 0) {
		 curl_krb5_print_error_message(krb_context, ret, data);
		 curl_krb5_free_local_data(krb_context, ccache, &creds, principal, opts, ktab);
		 return CURLE_KERBEROS_AUTH_FAILED;
	}
  
	if ((ret = krb5_parse_name(krb_context, conn->user, &principal)) != 0) {
		 curl_krb5_print_error_message(krb_context, ret, data);
		 curl_krb5_free_local_data(krb_context, ccache, &creds, principal, opts, ktab);
		 return CURLE_KERBEROS_AUTH_FAILED;
	}
	
	if ((ret = krb5_get_init_creds_opt_alloc (krb_context , &opts)) != 0) {
         curl_krb5_print_error_message(krb_context, ret, data);
		 curl_krb5_free_local_data(krb_context, ccache, &creds, principal, opts, ktab);
	     return CURLE_KERBEROS_AUTH_FAILED;
	}  

	if (conn->bits.user_keytab) {
		 infof(data, "KRB5_DATA: Keytab location is %s \n", conn->keytab_location);
		 if ((ret = krb5_kt_resolve(krb_context, conn->keytab_location, &ktab)) != 0) {
			curl_krb5_print_error_message(krb_context, ret, data);
			curl_krb5_free_local_data(krb_context, ccache, &creds, principal, opts, ktab);
		    return CURLE_KERBEROS_AUTH_FAILED;
		 }
		 if ((ret = krb5_get_init_creds_keytab(krb_context, &creds, principal, ktab, 0, NULL, opts)) != 0) {
			 curl_krb5_print_error_message(krb_context, ret, data);
			 curl_krb5_free_local_data(krb_context, ccache, &creds, principal, opts, ktab);
		     return CURLE_KERBEROS_AUTH_FAILED;
		 }
    } else if(conn->bits.user_passwd) {
		  infof(data,"KRB5_DATA: Using the user password method \n");
		  if ((ret = krb5_get_init_creds_password(krb_context,&creds,principal,conn->passwd,NULL,NULL,0,NULL,opts)) != 0 ) {
				curl_krb5_print_error_message(krb_context, ret, data);
				curl_krb5_free_local_data(krb_context, ccache, &creds, principal, opts, ktab);
				return CURLE_KERBEROS_AUTH_FAILED;
		  }
	} else if(conn->bits.credential_cache) {
		infof(data, "Resolving given credential cache \n");
		infof(data, "KRB5_DATA: Credential cache location is %s \n", conn->credential_cache);
		if ((ret = krb5_cc_resolve(krb_context, conn->credential_cache, &ccache))!=0) {
			   curl_krb5_print_error_message(krb_context, ret, data);
			   curl_krb5_free_local_data(krb_context, ccache, &creds, principal, opts, ktab);
			   return CURLE_KERBEROS_AUTH_FAILED;
		}
	} else if(conn->data->isIntermediateServer) {
		infof(data, "KRB5_DATA: Curl is carrying a gss credential \n");
		major_status = gss_init_sec_context(minor_status,
                              conn->data->deleg_gss_creds, /* cred_handle */
                              context,
                              target_name,
                              GSS_C_NO_OID, /* mech_type */
                              req_flags,
                              0, /* time_req */
                              input_chan_bindings,
                              input_token,
                              NULL, /* actual_mech_type */
                              output_token,
                              ret_flags,
                              NULL /* time_rec */);
		curl_krb5_free_local_data(krb_context, ccache, &creds, principal, opts, ktab);
		return major_status;
	} else {		
	      infof(data, "KRB5_DATA: Passed no password/keytab location, using default credentials\n ");
		  conn->data->curl_gss_creds = GSS_C_NO_CREDENTIAL;
		  major_status = gss_init_sec_context(minor_status,
                              conn->data->curl_gss_creds, /* cred_handle */
                              context,
                              target_name,
                              GSS_C_NO_OID, /* mech_type */
                              req_flags,
                              0, /* time_req */
                              input_chan_bindings,
                              input_token,
                              NULL, /* actual_mech_type */
                              output_token,
                              ret_flags,
                              NULL /* time_rec */);
		  curl_krb5_free_local_data(krb_context, ccache, &creds, principal, opts, ktab);
		  return major_status;
    }
	if(!conn->bits.credential_cache) {
		infof(data, "Creating new credential cache, since none specified \n");
		if((ret = krb5_cc_new_unique( krb_context, "MEMORY", NULL, &ccache)) != 0) {
			 curl_krb5_print_error_message(krb_context, ret, data);
			 curl_krb5_free_local_data_memory(krb_context, ccache, &creds, principal, opts, ktab);
			 return CURLE_KERBEROS_AUTH_FAILED;
		}
		infof(data, "Initializing credential cache \n");
		if ((ret = krb5_cc_initialize(krb_context, ccache, principal))!=0) {
		     curl_krb5_print_error_message(krb_context, ret, data);
			 curl_krb5_free_local_data_memory(krb_context, ccache, &creds, principal, opts, ktab);
			 return CURLE_KERBEROS_AUTH_FAILED;
		}
		infof(data, "Storing credential within credential cache \n");
		if ((ret = krb5_cc_store_cred(krb_context,ccache,&creds)) != 0) {
			 curl_krb5_print_error_message(krb_context, ret, data);
			 curl_krb5_free_local_data_memory(krb_context, ccache, &creds, principal, opts, ktab);
			 return CURLE_KERBEROS_AUTH_FAILED ;
		}
	}
	infof(data, "Attempting to import the credential \n");
	if ((maj_stat = gss_krb5_import_cred(&min_stat,
	    ccache,
		principal,
		NULL,
		&conn->data->curl_gss_creds))!=0) {
			  infof(data, "Importing krb5 credential into gss credentials failed\n");
			  curl_krb5_print_error_message(krb_context, min_stat, data);
			  if(conn->bits.credential_cache)
				  curl_krb5_free_local_data(krb_context, ccache, &creds, principal, opts, ktab);
			  else
				  curl_krb5_free_local_data_memory(krb_context, ccache, &creds, principal, opts, ktab);
			  return CURLE_KERBEROS_AUTH_FAILED;
		}

	infof(data, "Able to convert the credential \n");
	infof(data, "Attempting init sec context \n");

	major_status = gss_init_sec_context(minor_status,
                              conn->data->curl_gss_creds, /* cred_handle */
                              context,
                              target_name,
                              GSS_C_NO_OID, /* mech_type */
                              req_flags,
                              0, /* time_req */
                              input_chan_bindings,
                              input_token,
                              NULL, /* actual_mech_type */
                              output_token,
                              ret_flags,
                              NULL /* time_rec */);

	if(conn->bits.credential_cache)
        curl_krb5_free_local_data(krb_context, ccache, &creds, principal, opts, ktab);
    else
        curl_krb5_free_local_data_memory(krb_context, ccache, &creds, principal, opts, ktab);

	return major_status;
}
Ejemplo n.º 11
0
static OM_uint32
getDefaultCred(OM_uint32 *minor, const char *keytab_name, gss_OID_set mechs,
               gss_cred_id_t *impersonator_cred_handle)
{
    OM_uint32 major = GSS_S_FAILURE, tmp_minor;

    if (keytab_name) {
        krb5_error_code code;
        krb5_context context = NULL;
        krb5_keytab keytab = NULL;
        krb5_principal keytab_principal = NULL;
        krb5_ccache ccache = NULL;

        code = krb5_init_context(&context);
        if (code) {
            displayStatus("krb5_init_context", major, code);
            return major;
        }

        code = krb5_kt_resolve(context, keytab_name, &keytab);
        if (code) {
            displayStatus("krb5_kt_resolve", major, code);
            goto out;
        }

        code = krb5_cc_default(context, &ccache);
        if (code) {
            displayStatus("krb5_cc_default", major, code);
            goto out;
        }

        code = krb5_cc_get_principal(context, ccache, &keytab_principal);
        if (code) {
            displayStatus("krb5_cc_get_principal", major, code);
            goto out;
        }

        major = gss_krb5_import_cred(minor,
                                     ccache,
                                     keytab_principal,
                                     keytab,
                                     impersonator_cred_handle);
        if (GSS_ERROR(major)) {
            displayStatus("gss_krb5_import_cred", major, *minor);
            goto out;
        }

    out:
        if (code)
            *minor = code;
        krb5_free_principal(context, keytab_principal);
        krb5_cc_close(context, ccache);
        krb5_kt_close(context, keytab);
        krb5_free_context(context);
     } else {
        gss_OID_set actual_mechs = GSS_C_NO_OID_SET;

        major = gss_acquire_cred(minor,
                                 GSS_C_NO_NAME,
                                 GSS_C_INDEFINITE,
                                 mechs,
                                 GSS_C_BOTH,
                                 impersonator_cred_handle,
                                 &actual_mechs,
                                 NULL);
        if (GSS_ERROR(major)) {
            displayStatus("gss_acquire_cred", major, *minor);
        }
        (void) gss_release_oid_set(&tmp_minor, &actual_mechs);
    }

    return major;
}