Beispiel #1
0
static void
test_get_init_creds(krb5_context context,
		    krb5_principal client)
{
    krb5_error_code ret;
    krb5_get_init_creds_opt *opt;
    krb5_creds cred;

    ret = krb5_get_init_creds_opt_alloc(context, &opt);
    if (ret)
	krb5_err(context, 1, ret, "krb5_get_init_creds_opt_alloc");


    ret = krb5_get_init_creds_opt_set_process_last_req(context,
						       opt,
						       lr_proc,
						       NULL);
    if (ret)
	krb5_err(context, 1, ret,
		 "krb5_get_init_creds_opt_set_process_last_req");

    ret = krb5_get_init_creds_password(context,
				       &cred,
				       client,
				       password_str,
				       krb5_prompter_posix,
				       NULL,
				       0,
				       NULL,
				       opt);
    if (ret)
	krb5_err(context, 1, ret, "krb5_get_init_creds_password");

    krb5_get_init_creds_opt_free(context, opt);
}
/* Inspired by krb5_verify_user from Heimdal */
static krb5_error_code verify_krb5_user(krb5_context context, krb5_principal principal, const char *password, krb5_principal server)
{
    krb5_creds creds;
    krb5_get_init_creds_opt gic_options;
    krb5_error_code ret;
    char *name = NULL;

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

    ret = krb5_unparse_name(context, principal, &name);
    if (ret == 0)
    {
#ifdef PRINTFS
        printf("Trying to get TGT for user %s\n", name);
#endif
        free(name);
    }

    krb5_get_init_creds_opt_init(&gic_options);
    ret = krb5_get_init_creds_password(context, &creds, principal, (char *)password, NULL, NULL, 0, NULL, &gic_options);
    if (ret)
    {
        set_basicauth_error(context, ret);
        goto end;
    }

end:
    krb5_free_cred_contents(context, &creds);

    return ret;
}
Beispiel #3
0
static E2kKerberosResult
get_init_cred (krb5_context ctx, const char *usr_name, const char *passwd,
	       const char *in_tkt_service, krb5_creds *cred)
{
	krb5_principal principal;
	krb5_get_init_creds_opt opt;
	krb5_error_code result;

	result = krb5_parse_name (ctx, usr_name, &principal);
	if (result)
		return E2K_KERBEROS_USER_UNKNOWN;

	krb5_get_init_creds_opt_init (&opt);
	krb5_get_init_creds_opt_set_tkt_life (&opt, 5*60);
	krb5_get_init_creds_opt_set_renew_life (&opt, 0);
	krb5_get_init_creds_opt_set_forwardable (&opt, 0);
	krb5_get_init_creds_opt_set_proxiable (&opt, 0);

	result = krb5_get_init_creds_password (ctx, cred, principal,
					       (char *) passwd,
					       NULL, NULL, 0,
					       (char *) in_tkt_service, &opt);
	krb5_free_principal (ctx, principal);

	return krb5_result_to_e2k_kerberos_result (result);
}
Beispiel #4
0
static krb5_error_code
verify_user_opt_int(krb5_context context,
		    krb5_principal principal,
		    const char *password,
		    krb5_verify_opt *vopt)

{
    krb5_error_code ret;
    krb5_get_init_creds_opt *opt;
    krb5_creds cred;

    ret = krb5_get_init_creds_opt_alloc (context, &opt);
    if (ret)
	return ret;
    krb5_get_init_creds_opt_set_default_flags(context, NULL,
					      krb5_principal_get_realm(context, principal),
					      opt);
    ret = krb5_get_init_creds_password (context,
					&cred,
					principal,
					password,
					krb5_prompter_posix,
					NULL,
					0,
					NULL,
					opt);
    krb5_get_init_creds_opt_free(context, opt);
    if(ret)
	return ret;
#define OPT(V, D) ((vopt && (vopt->V)) ? (vopt->V) : (D))
    return verify_common (context, principal, OPT(ccache, NULL),
			  OPT(keytab, NULL), vopt ? vopt->secure : TRUE,
			  OPT(service, "host"), cred);
#undef OPT
}
Beispiel #5
0
int init_krb5_cc(){
	krb5_ccache cc = NULL;
	krb5_context ctx;
	krb5_error_code err;
	krb5_principal princ;
	krb5_creds creds;
	char name[64];
	char *pass;

	err = krb5_init_context(&ctx);
	if (err) {
		printf("krb5_init_context: %d: %s\n", err,
				krb5_get_error_message(ctx, err));
		return -1;
	}
	printf("Username: "******"%s", name);

	err = krb5_parse_name(ctx, name, &princ);
	if (err) {
		printf("krb5_parse_name: %d: %s\n", err,
				krb5_get_error_message(ctx, err));
		return -1;
	}

	err = krb5_cc_default(ctx, &cc);
	if (err) {
		printf("krb5_cc_default: %d: %s\n", err,
				krb5_get_error_message(ctx, err));
		return -1;
	}

	err = krb5_cc_initialize(ctx, cc, princ);
	if (err) {
		printf("krb5_cc_initialize: %d: %s\n", err,
				krb5_get_error_message(ctx, err));
		return -1;
	}

	pass = getpass("Password: "******"krb5_get_init_creds_password: %d: %s\n", err,
				krb5_get_error_message(ctx, err));
		return -1;
	}

	err = krb5_cc_store_cred(ctx, cc, &creds);
	if (err) {
		printf("krb5_cc_store_cred: %d: %s\n", err,
				krb5_get_error_message(ctx, err));
		return -1;
	}

	return 0;
}
Beispiel #6
0
KRB5Creds::KRB5Creds(KRB5Principal &principal, const std::string &password, const char *tkt_service) : m_creds()
{
    krb5_error_code ret =
        krb5_get_init_creds_password(g_context.get(), &m_creds, principal.get(),
                                     const_cast<char*>(password.c_str()), NULL, NULL,
                                     0, const_cast<char*>(tkt_service), NULL);
    if (ret) {
        throw KRB5Exception("krb5_get_init_creds_keytab", ret);
    }
}
Beispiel #7
0
/*
  simulate a kinit, putting the tgt in the default cache location
  [email protected]
*/
int kerberos_kinit_password(const char *principal, const char *password, int time_offset)
{
	krb5_context ctx;
	krb5_error_code code = 0;
	krb5_ccache cc;
	krb5_principal me;
	krb5_creds my_creds;

	if ((code = krb5_init_context(&ctx)))
		return code;

	if (time_offset != 0) {
		krb5_set_real_time(ctx, time(NULL) + time_offset, 0);
	}
	
	if ((code = krb5_cc_default(ctx, &cc))) {
		krb5_free_context(ctx);
		return code;
	}
	
	if ((code = krb5_parse_name(ctx, principal, &me))) {
		krb5_free_context(ctx);	
		return code;
	}
	
	if ((code = krb5_get_init_creds_password(ctx, &my_creds, me, NULL, 
						 kerb_prompter, 
						 password, 0, NULL, NULL))) {
		krb5_free_principal(ctx, me);
		krb5_free_context(ctx);		
		return code;
	}
	
	if ((code = krb5_cc_initialize(ctx, cc, me))) {
		krb5_free_cred_contents(ctx, &my_creds);
		krb5_free_principal(ctx, me);
		krb5_free_context(ctx);		
		return code;
	}
	
	if ((code = krb5_cc_store_cred(ctx, cc, &my_creds))) {
		krb5_cc_close(ctx, cc);
		krb5_free_cred_contents(ctx, &my_creds);
		krb5_free_principal(ctx, me);
		krb5_free_context(ctx);		
		return code;
	}
	
	krb5_cc_close(ctx, cc);
	krb5_free_cred_contents(ctx, &my_creds);
	krb5_free_principal(ctx, me);
	krb5_free_context(ctx);		
	
	return 0;
}
Beispiel #8
0
/* call-seq:
 *   krb5.change_password(old, new)
 *
 * Changes the password for the principal from +old+ to +new+. The principal
 * is defined as whoever the last principal was authenticated via the
 * Krb5#get_init_creds_password method.
 *
 * Attempting to change a password before a principal has been established
 * will raise an error.
 *
 * Example:
 *
 * krb5.get_init_creds_password('foo', 'XXXXXX') # Authenticate 'foo' user
 * krb5.change_password('XXXXXX', 'YYYYYY')      # Change password for 'foo'
 */
static VALUE rkrb5_change_password(VALUE self, VALUE v_old, VALUE v_new){

  RUBY_KRB5* ptr;
  krb5_data result_string;
  krb5_data pw_result_string;
  krb5_error_code kerror;
  char *old_passwd;
  char *new_passwd;

  int pw_result;

  Check_Type(v_old, T_STRING);
  Check_Type(v_new, T_STRING);

  old_passwd = StringValueCStr(v_old);
  new_passwd = StringValueCStr(v_new);

  Data_Get_Struct(self, RUBY_KRB5, ptr); 

  if(!ptr->ctx)
    rb_raise(cKrb5Exception, "no context has been established"); 

  if(!ptr->princ)
    rb_raise(cKrb5Exception, "no principal has been established"); 

  kerror = krb5_get_init_creds_password(
    ptr->ctx,
    &ptr->creds,
    ptr->princ,
    old_passwd,
    NULL,
    NULL,
    0,
    "kadmin/changepw",
    NULL
  );

  if(kerror)
    rb_raise(cKrb5Exception, "krb5_get_init_creds_password: %s", error_message(kerror));

  kerror = krb5_change_password(
    ptr->ctx,
    &ptr->creds,
    new_passwd,
    &pw_result,
    &pw_result_string,
    &result_string
  );

  if(kerror)
    rb_raise(cKrb5Exception, "krb5_change_password: %s", error_message(kerror));

  return Qtrue;
}
Beispiel #9
0
static PyObject *
k5_change_password(PyObject *self, PyObject *args)
{
    int result_code;
    char *name, *oldpass, *newpass;
    krb5_context ctx;
    krb5_error_code code;
    krb5_principal principal;
    krb5_get_init_creds_opt options;
    krb5_creds creds;
    krb5_data result_code_string, result_string;

    if (!PyArg_ParseTuple(args, "sss", &name, &oldpass, &newpass))
        return NULL;

    /* Initialize parameters. */
    code = krb5_init_context(&ctx);
    RETURN_ON_ERROR("krb5_init_context()", code);
    code = krb5_parse_name(ctx, name, &principal);
    RETURN_ON_ERROR("krb5_parse_name()", code);

    /* Get credentials using the password. */
    krb5_get_init_creds_opt_init(&options);
    krb5_get_init_creds_opt_set_tkt_life(&options, 5*60);
    krb5_get_init_creds_opt_set_renew_life(&options, 0);
    krb5_get_init_creds_opt_set_forwardable(&options, 0);
    krb5_get_init_creds_opt_set_proxiable(&options, 0);
    memset(&creds, 0, sizeof (creds));
    code = krb5_get_init_creds_password(ctx, &creds, principal, oldpass,
					NULL, NULL, 0, "kadmin/changepw",
					&options);
    RETURN_ON_ERROR("krb5_get_init_creds_password()", code);

    code = krb5_change_password(ctx, &creds, newpass, &result_code,
				&result_code_string, &result_string);
    RETURN_ON_ERROR("krb5_change_password()", code);

    /* Any other error? */
    if (result_code != 0)
    {
	_k5_set_password_error(&result_code_string, &result_string);
	return NULL;
    }

    /* Free up results. */
    if (result_code_string.data != NULL)
	free(result_code_string.data);
    if (result_string.data != NULL)
	free(result_string.data);

    Py_INCREF(Py_None);
    return Py_None;
}
Beispiel #10
0
/*
 * call-seq:
 *   krb5.get_init_creds_password(user, password, service = nil)
 *
 * Authenticates the credentials of +user+ using +password+ against +service+,
 * and has the effect of setting the principal and context internally. This method
 * must typically be called before using other methods.
 */
static VALUE rkrb5_get_init_creds_passwd(int argc, VALUE* argv, VALUE self){
  RUBY_KRB5* ptr;
  VALUE v_user, v_pass, v_service;
  char* user;
  char* pass;
  char* service;
  krb5_error_code kerror;

  Data_Get_Struct(self, RUBY_KRB5, ptr); 

  if(!ptr->ctx)
    rb_raise(cKrb5Exception, "no context has been established");

  rb_scan_args(argc, argv, "21", &v_user, &v_pass, &v_service);

  Check_Type(v_user, T_STRING);
  Check_Type(v_pass, T_STRING);
  user = StringValueCStr(v_user);
  pass = StringValueCStr(v_pass);

  if(NIL_P(v_service)){
    service = NULL;
  }
  else{
    Check_Type(v_service, T_STRING);
    service = StringValueCStr(v_service);
  }

  kerror = krb5_parse_name(ptr->ctx, user, &ptr->princ); 

  if(kerror)
    rb_raise(cKrb5Exception, "krb5_parse_name: %s", error_message(kerror));

  kerror = krb5_get_init_creds_password(
    ptr->ctx,
    &ptr->creds,
    ptr->princ,
    pass,
    0,
    NULL,
    0,
    service,
    NULL
  );

  if(kerror)
    rb_raise(cKrb5Exception, "krb5_get_init_creds_password: %s", error_message(kerror));

  return Qtrue;
}
Beispiel #11
0
static int
k5ping(krb5_context ctx, const char *host, int socktype, krb5_principal princ,
    int use_kt, const char *passwd, krb5_principal sprinc)
{
	K5BAIL_DECLS;
	krb5_error_code		 kerr;
	krb5_ccache		 ccache = NULL;
	krb5_keytab		 kt;
	krb5_creds		 creds;
	krb5_get_init_creds_opt	*opt = NULL;

	VERBOSE(1, (stderr, "initiating kerberos5/%s ping to %s\n",
	    socktype == SOCK_DGRAM ? "udp" : "tcp", host));

	parse_kdc(host);
	current_socktype = socktype;

	K5BAIL(krb5_cc_resolve(ctx, "MEMORY:k5ping", &ccache));

        K5BAIL(krb5_get_init_creds_opt_alloc(ctx, &opt));
        krb5_get_init_creds_opt_set_tkt_life(opt, 15 * 60);

	if (use_kt) {
		K5BAIL(krb5_kt_default(ctx, &kt));
		K5BAIL(krb5_get_init_creds_keytab(ctx, &creds, princ, kt, 0,
		    NULL, opt));
	} else {
		K5BAIL(krb5_get_init_creds_password(ctx, &creds, princ, passwd,
		    krb5_prompter_posix, NULL, 0, NULL, opt));
	}

	K5BAIL(krb5_cc_store_cred(ctx, ccache, &creds));

	kret = kvno5(ctx, host, socktype, princ, sprinc, ccache);
done:
	if (ccache)
		krb5_cc_destroy(ctx, ccache);

	/* XXXrcd: free a few more things here... */
	/*	   opt.  creds.                   */

	if (croakstr[0])
		fail_msg("kerberos5", socktype, host, croakstr);

	return kret;
}
Beispiel #12
0
/*
 * call-seq:
 *   get_init_creds_password(username, password)
 *
 * Call krb5_get_init_creds_password() to get credentials based on a username 
 * and password.  Returns true on success, raises Krb5Auth::Krb5::Exception 
 * on failure.
 */
int Krb5_get_init_creds_password(char* user, char* pass)
{

  struct krb5_object *kerb = Krb5_new();
  krb5_error_code krbret;

  krbret = krb5_parse_name(kerb->ctx, user, &kerb->princ);
  if (krbret) {
    //fail
  }

  krbret = krb5_get_init_creds_password(kerb->ctx, &kerb->creds, kerb->princ,
					pass, 0, NULL, 0,NULL, NULL);
  if (krbret) 
     return 0;
  else
     return 1;
}
Beispiel #13
0
/*
 * Test whether anonymous authentication works.  If this doesn't, we need to
 * skip the tests of anonymous FAST.
 */
static bool
anon_fast_works(void)
{
    krb5_context ctx;
    krb5_error_code retval;
    krb5_principal princ = NULL;
    char *realm;
    krb5_creds creds;
    krb5_get_init_creds_opt *opts = NULL;

    /* Construct the anonymous principal name. */
    retval = krb5_init_context(&ctx);
    if (retval != 0)
        bail("cannot initialize Kerberos");
    retval = krb5_get_default_realm(ctx, &realm);
    if (retval != 0)
        bail("cannot get default realm");
    retval = krb5_build_principal_ext(ctx, &princ, strlen(realm), realm,
                 strlen(KRB5_WELLKNOWN_NAME), KRB5_WELLKNOWN_NAME,
                 strlen(KRB5_ANON_NAME), KRB5_ANON_NAME, NULL);
    if (retval != 0)
        bail("cannot construct anonymous principal");
    krb5_free_default_realm(ctx, realm);

    /* Obtain the credentials. */
    memset(&creds, 0, sizeof(creds));
    retval = krb5_get_init_creds_opt_alloc(ctx, &opts);
    if (retval != 0)
        bail("cannot create credential options");
    krb5_get_init_creds_opt_set_anonymous(opts, 1);
    krb5_get_init_creds_opt_set_tkt_life(opts, 60);
    retval = krb5_get_init_creds_password(ctx, &creds, princ, NULL, NULL,
                                          NULL, 0, NULL, opts);

    /* Clean up. */
    if (princ != NULL)
        krb5_free_principal(ctx, princ);
    if (opts != NULL)
        krb5_get_init_creds_opt_free(ctx, opts);
    krb5_free_cred_contents(ctx, &creds);
    return (retval == 0);
}
Beispiel #14
0
int
v5::initCredential(krb5_context kcontext, krb5_principal kprincipal,
                    krb5_get_init_creds_opt *opts, const QString& password,
                    krb5_timestamp *tgtEndtime)
{
	krb5_error_code retval;
	krb5_creds      my_creds;
	krb5_ccache     ccache;
	
	qDebug("call initCredential");

	retval = krb5_get_init_creds_password(kcontext, &my_creds, kprincipal,
	                                      password.toUtf8().data(), NULL, NULL,
	                                      0, NULL, opts);
	if (retval)
	{
		return retval;
	}
	
	retval = krb5_cc_default(kcontext, &ccache);
	if (retval)
	{
		goto out;
	}
	
	retval = krb5_cc_initialize(kcontext, ccache, kprincipal);
	if (retval)
		goto out;
	
	retval = krb5_cc_store_cred(kcontext, ccache, &my_creds);
	if (retval)
		goto out;
	
	*tgtEndtime = my_creds.times.endtime;
	
out:
	krb5_free_cred_contents (kcontext, &my_creds);
	krb5_cc_close (kcontext, ccache);
	
	return retval;
}
Beispiel #15
0
/*
  simulate a kinit, putting the tgt in the given credentials cache.
  Orignally by [email protected]
*/
int kerberos_kinit_password_cc(krb5_context ctx, krb5_ccache cc,
                               krb5_principal principal, const char *password,
                               time_t *expire_time, time_t *kdc_time)
{
    krb5_error_code code = 0;
    krb5_creds my_creds;
    krb5_get_init_creds_opt options;

    krb5_get_init_creds_opt_init(&options);

    krb5_get_init_creds_opt_set_default_flags(ctx, NULL, NULL, &options);

    if ((code = krb5_get_init_creds_password(ctx, &my_creds, principal, password,
                NULL,
                NULL, 0, NULL, &options))) {
        return code;
    }

    if ((code = krb5_cc_initialize(ctx, cc, principal))) {
        krb5_free_cred_contents(ctx, &my_creds);
        return code;
    }

    if ((code = krb5_cc_store_cred(ctx, cc, &my_creds))) {
        krb5_free_cred_contents(ctx, &my_creds);
        return code;
    }

    if (expire_time) {
        *expire_time = (time_t) my_creds.times.endtime;
    }

    if (kdc_time) {
        *kdc_time = (time_t) my_creds.times.starttime;
    }

    krb5_free_cred_contents(ctx, &my_creds);

    return 0;
}
Beispiel #16
0
static PyObject *
k5_get_init_creds_password(PyObject *self, PyObject *args)
{
    char *name, *password;
    krb5_context ctx;
    krb5_error_code code;
    krb5_ccache ccache;
    krb5_principal principal;
    krb5_get_init_creds_opt options;
    krb5_creds creds;

    if (!PyArg_ParseTuple(args, "ss", &name, &password))
        return NULL;

    /* Initialize parameters. */
    code = krb5_init_context(&ctx);
    RETURN_ON_ERROR("krb5_init_context()", code);
    code = krb5_parse_name(ctx, name, &principal);
    RETURN_ON_ERROR("krb5_parse_name()", code);
    krb5_get_init_creds_opt_init(&options);
    memset(&creds, 0, sizeof (creds));

    /* Get the credentials. */
    code = krb5_get_init_creds_password(ctx, &creds, principal, password,
                                        NULL, NULL, 0, NULL, &options);
    RETURN_ON_ERROR("krb5_get_init_creds_password()", code);

    /* Store the credential in the credential cache. */
    code = krb5_cc_default(ctx, &ccache);
    RETURN_ON_ERROR("krb5_cc_default()", code);
    code = krb5_cc_initialize(ctx, ccache, principal);
    RETURN_ON_ERROR("krb5_cc_initialize()", code);
    code = krb5_cc_store_cred(ctx, ccache, &creds);
    RETURN_ON_ERROR("krb5_cc_store_creds()", code);
    krb5_cc_close(ctx, ccache);

    Py_INCREF(Py_None);
    return Py_None;
}
Beispiel #17
0
krb5CredsObject *creds_new(PyObject *unused, PyObject *args)
{
	krb5_error_code ret;
	krb5ContextObject *context;
	krb5PrincipalObject *principal;
	char *password_string;
	char *in_tkt_service;
	krb5CredsObject *self = (krb5CredsObject *) PyObject_NEW(krb5CredsObject, &krb5CredsType);
	int error = 0;

	if (!PyArg_ParseTuple(args, "OOss", &context, &principal, &password_string,
				&in_tkt_service))
		return NULL;

	/* FIXME */
	if (in_tkt_service[0] == '\0')
		in_tkt_service = NULL;

	if (self == NULL)
		return NULL;
	self->context = context->context;

	ret = krb5_get_init_creds_password(self->context, &self->creds,
			principal->principal, NULL, kerb_prompter, password_string,
			0, in_tkt_service, NULL);
	if (ret) {
		error = 1;
		krb5_exception(NULL, ret);
		goto out;
	}

 out:
	if (error)
		return NULL;
	else
		return self;
}
Beispiel #18
0
/*
 * call-seq:
 *   get_init_creds_password(username, password)
 *
 * Call krb5_get_init_creds_password() to get credentials based on a username
 * and password.  Returns true on success, raises Krb5Auth::Krb5::Exception on
 * failure.
 */
static VALUE Krb5_get_init_creds_password(VALUE self, VALUE _user, VALUE _pass)
{
  Check_Type(_user,T_STRING);
  Check_Type(_pass,T_STRING);
  char *user = StringValueCStr(_user);
  char *pass = StringValueCStr(_pass);

  struct ruby_krb5 *kerb;
  krb5_error_code krbret;

  Data_Get_Struct(self, struct ruby_krb5, kerb);
  if (!kerb) {
    NOSTRUCT_EXCEPT();
    return Qfalse;
  }

  krbret = krb5_parse_name(kerb->ctx, user, &kerb->princ);
  if (krbret) {
    goto failed_pass;
  }

  krbret = krb5_get_init_creds_password(kerb->ctx, &kerb->creds, kerb->princ,
					pass, 0, NULL, 0,NULL, NULL);
  if (krbret) {
    goto failed_pass;
  }

  return Qtrue;

 failed_pass:
  Krb5_register_error(krbret);

  // we will never reach here, since Krb5_register_error will rb_raise().  just
  // leave it to shut the compiler up
  return Qfalse;
}
Beispiel #19
0
int
main(int argc, char **argv)
{
    krb5_context ctx;
    krb5_get_init_creds_opt *opt;
    char *user, *password, *service = NULL;
    krb5_boolean use_cb;
    krb5_principal client;
    krb5_creds creds;

    if (argc < 4) {
	fprintf(stderr, "Usage: %s username password {1|0} [service]\n",
		argv[0]);
	return 1;
    }
    user = argv[1];
    password = argv[2];
    use_cb = atoi(argv[3]);
    if (argc >= 5)
	service = argv[4];

    assert(krb5_init_context(&ctx) == 0);
    assert(krb5_get_init_creds_opt_alloc(ctx, &opt) == 0);
    if (use_cb) {
	assert(krb5_get_init_creds_opt_set_expire_callback(ctx, opt, expire_cb,
							   &exp_dummy) == 0);
    }
    assert(krb5_parse_name(ctx, user, &client) == 0);
    assert(krb5_get_init_creds_password(ctx, &creds, client, password,
					prompter_cb, &prompt_dummy, 0, service,
					opt) == 0);
    krb5_get_init_creds_opt_free(ctx, opt);
    krb5_free_principal(ctx, client);
    krb5_free_cred_contents(ctx, &creds);
    return 0;
}
Beispiel #20
0
static krb5_error_code
get_new_cache(krb5_context context,
	      krb5_principal client,
	      const char *password,
	      krb5_prompter_fct prompter,
	      const char *keytab,
	      const char *server_name,
	      krb5_ccache *ret_cache)
{
    krb5_error_code ret;
    krb5_creds cred;
    krb5_get_init_creds_opt *opt;
    krb5_ccache id;

    ret = krb5_get_init_creds_opt_alloc (context, &opt);
    if (ret)
	return ret;

    krb5_get_init_creds_opt_set_default_flags(context, "kadmin",
					      krb5_principal_get_realm(context,
								       client),
					      opt);


    krb5_get_init_creds_opt_set_forwardable (opt, FALSE);
    krb5_get_init_creds_opt_set_proxiable (opt, FALSE);

    if(password == NULL && prompter == NULL) {
	krb5_keytab kt;
	if(keytab == NULL)
	    ret = krb5_kt_default(context, &kt);
	else
	    ret = krb5_kt_resolve(context, keytab, &kt);
	if(ret) {
	    krb5_get_init_creds_opt_free(context, opt);
	    return ret;
	}
	ret = krb5_get_init_creds_keytab (context,
					  &cred,
					  client,
					  kt,
					  0,
					  server_name,
					  opt);
	krb5_kt_close(context, kt);
    } else {
	ret = krb5_get_init_creds_password (context,
					    &cred,
					    client,
					    password,
					    prompter,
					    NULL,
					    0,
					    server_name,
					    opt);
    }
    krb5_get_init_creds_opt_free(context, opt);
    switch(ret){
    case 0:
	break;
    case KRB5_LIBOS_PWDINTR:	/* don't print anything if it was just C-c:ed */
    case KRB5KRB_AP_ERR_BAD_INTEGRITY:
    case KRB5KRB_AP_ERR_MODIFIED:
	return KADM5_BAD_PASSWORD;
    default:
	return ret;
    }
    ret = krb5_cc_new_unique(context, krb5_cc_type_memory, NULL, &id);
    if(ret)
	return ret;
    ret = krb5_cc_initialize (context, id, cred.client);
    if (ret)
	return ret;
    ret = krb5_cc_store_cred (context, id, &cred);
    if (ret)
	return ret;
    krb5_free_cred_contents (context, &cred);
    *ret_cache = id;
    return 0;
}
Beispiel #21
0
krb5_error_code
kcm_ccache_acquire(krb5_context context,
		   kcm_ccache ccache,
		   time_t *expire)
{
    krb5_error_code ret = 0;
    krb5_creds cred;
    krb5_const_realm realm;
    krb5_get_init_creds_opt *opt = NULL;
    krb5_ccache_data ccdata;
    char *in_tkt_service = NULL;

    *expire = 0;
    memset(&cred, 0, sizeof(cred));

    KCM_ASSERT_VALID(ccache);

    /* We need a cached key or keytab to acquire credentials */
    if (ccache->flags & KCM_FLAGS_USE_PASSWORD) {
	if (ccache->password == NULL)
	    krb5_abortx(context,
			"kcm_ccache_acquire: KCM_FLAGS_USE_PASSWORD without password");
    } else if (ccache->flags & KCM_FLAGS_USE_KEYTAB) {
	if (ccache->keytab == NULL)
	    krb5_abortx(context,
			"kcm_ccache_acquire: KCM_FLAGS_USE_KEYTAB without keytab");
    } else {
	kcm_log(0, "Cannot acquire initial credentials for cache %s without key",
		ccache->name);
	return KRB5_FCC_INTERNAL;
    }

    /* Fake up an internal ccache */
    kcm_internal_ccache(context, ccache, &ccdata);

    /* Now, actually acquire the creds */
    if (ccache->server != NULL) {
	ret = krb5_unparse_name(context, ccache->server, &in_tkt_service);
	if (ret) {
	    kcm_log(0, "Failed to unparse service name for cache %s",
		    ccache->name);
	    return ret;
	}
    }

    realm = krb5_principal_get_realm(context, ccache->client);

    ret = krb5_get_init_creds_opt_alloc(context, &opt);
    if (ret)
	goto out;
    krb5_get_init_creds_opt_set_default_flags(context, "kcm", realm, opt);
    if (ccache->tkt_life != 0)
	krb5_get_init_creds_opt_set_tkt_life(opt, ccache->tkt_life);
    if (ccache->renew_life != 0)
	krb5_get_init_creds_opt_set_renew_life(opt, ccache->renew_life);

    krb5_get_init_creds_opt_set_forwardable(opt, 1);

    if (ccache->flags & KCM_FLAGS_USE_PASSWORD) {
	ret = krb5_get_init_creds_password(context,
					   &cred,
					   ccache->client,
					   ccache->password,
					   NULL,
					   NULL,
					   0,
					   in_tkt_service,
					   opt);
    } else {
	ret = krb5_get_init_creds_keytab(context,
					 &cred,
					 ccache->client,
					 ccache->keytab,
					 0,
					 in_tkt_service,
					 opt);
    }

    if (ret) {
	const char *msg = krb5_get_error_message(context, ret);
	kcm_log(0, "Failed to acquire credentials for cache %s: %s",
		ccache->name, msg);
	krb5_free_error_message(context, msg);
	if (in_tkt_service != NULL)
	    free(in_tkt_service);
	goto out;
    }

    if (in_tkt_service != NULL)
	free(in_tkt_service);

    /* Swap them in */
    kcm_ccache_remove_creds_internal(context, ccache);

    ret = kcm_ccache_store_cred_internal(context, ccache, &cred, NULL, 0);
    if (ret) {
	const char *msg = krb5_get_error_message(context, ret);
	kcm_log(0, "Failed to store credentials for cache %s: %s",
		ccache->name, msg);
	krb5_free_error_message(context, msg);
	krb5_free_cred_contents(context, &cred);
	goto out;
    }

    *expire = cred.times.endtime;

out:
    if (opt)
	krb5_get_init_creds_opt_free(context, opt);

    return ret;
}
Beispiel #22
0
static void do_renew(GtkWidget *widget, GtkWidget *entry)
{
  char *pass;
  krb5_error_code code;
  krb5_context kcontext;
  krb5_principal me = NULL;
  char *service_name = NULL;
  krb5_ccache ccache = NULL;
  krb5_creds my_creds;
  char *msg = NULL;
  krb5_deltat start_time = 0;
  krb5_deltat lifetime = 10 * 60 * 60;
  krb5_get_init_creds_opt opts;
  int non_fatal = 0;

  pass = g_strdup(gtk_entry_get_text(GTK_ENTRY(entry)));
  gtk_entry_set_text(GTK_ENTRY(entry), "");

  krb5_get_init_creds_opt_init(&opts);

  if (!pass || !strlen(pass))
    {
      non_fatal = 1;
      msg = g_strdup("Incorrect password: please try again.");
    }
  else if ((code = krb5_init_context(&kcontext)))
    msg = g_strdup_printf("%s when initializing kerberos library",
			  error_message(code));
  else if ((code = krb5_cc_default(kcontext, &ccache)))
    msg = g_strdup_printf("%s while getting default cache.",
			  error_message(code));
  else if ((code = krb5_parse_name(kcontext, name, &me)))
    msg = g_strdup_printf("%s while parsing name %s.", error_message(code),
			  name);
  else if ((code = krb5_get_init_creds_password(kcontext,
						&my_creds, me, pass,
						krb5_prompter_posix, NULL,
						start_time, service_name,
						&opts)))
    {
      if (code == KRB5KRB_AP_ERR_BAD_INTEGRITY)
	{
	  non_fatal = 1;
	  msg = g_strdup("Incorrect password: please try again.");
	}
      else
	{
	  msg = g_strdup_printf("%s while getting initial"
				" credentials", error_message(code));
	}
    }
  else
    {
      if ((code = krb5_cc_initialize(kcontext, ccache, me)))
	{
	  msg = g_strdup_printf("%s while initializing cache",
				error_message(code));
	}
      else if ((code = krb5_cc_store_cred(kcontext, ccache,
					  &my_creds)))
	{
	  msg = g_strdup_printf("%s while storing credentials",
				error_message(code));
	}
      else
	{
	  if (me)
	    krb5_free_principal(kcontext, me);
	  if (ccache)
	    krb5_cc_close(kcontext, ccache);

	  krb5_free_context(kcontext);
	}
    }

  g_free(pass);

  if (msg)
    {
      /* encountered an error. don't quit */
      if (non_fatal)
	do_error_dialog(msg);
      else
	do_fatal_dialog(msg);
      g_free(msg);
    }
  else
    /* no errors, we're done */
    {
      system("fsid -a > /dev/null");
      system("zctl load /dev/null > /dev/null");
      exit(0);
    }
}
Beispiel #23
0
DWORD
VMCALoginUserPrivate(
    PCSTR pszUserName,
    const char* pszPassword
    )
/*
VMCALoginUser Creates a TGT cache for the Process to
communicate with the VMCA
*/
{
    DWORD dwError = 0;
    krb5_context context = NULL;
    krb5_get_init_creds_opt *opt = NULL;
    krb5_principal principal = NULL;
    krb5_ccache ccache = NULL;
    krb5_creds creds = { 0 };
    krb5_error_code err_code = 0;
#ifdef DEBUG_KRB
    PSTR pszErrstr = NULL;
#endif

    err_code = krb5_init_context(&context);
    BAIL_ON_ERROR(err_code);

    // it is assumed that pszUserName is in user@REALM format.
    err_code = krb5_parse_name_flags(
                                    context,
                                    pszUserName,
                                    KRB5_PRINCIPAL_PARSE_REQUIRE_REALM,
                                    &principal);
    BAIL_ON_ERROR(err_code);

    // Find the default cred cache
    err_code = krb5_cc_default(context, &ccache);
    BAIL_ON_ERROR(err_code);

#ifdef DEBUG_KRB
    printf("Default Cache Name is : %s\n", krb5_cc_default_name(context));
#endif

    err_code = krb5_get_init_creds_opt_alloc(context, &opt);
    BAIL_ON_ERROR(err_code);

    krb5_get_init_creds_opt_set_tkt_life(opt, 2 * 60 * 60); //2 hours ticket
    krb5_get_init_creds_opt_set_forwardable(opt, 1);

    // Let us get the Creds from the Kerberos Server

    err_code =  krb5_get_init_creds_password(
                        context,
                        &creds,
                        principal,
                        (PSTR) pszPassword,
                        NULL,
                        NULL,
                        0,
                        NULL,
                        opt);
    BAIL_ON_ERROR(err_code);

    err_code = krb5_cc_store_cred(context, ccache, &creds);
    if ( err_code == KRB5_FCC_NOFILE){
        krb5_cc_initialize(context, ccache, principal);
        err_code = krb5_cc_store_cred(context, ccache, &creds);
        BAIL_ON_ERROR(err_code);
    }
    BAIL_ON_ERROR(err_code);
cleanup:

    if(principal != NULL) {
        krb5_free_principal(context, principal);
    }

    if(opt != NULL){
        krb5_get_init_creds_opt_free(context,opt);
    }

    if ( ccache != NULL) {
        krb5_cc_close(context, ccache);
    }

    krb5_free_cred_contents(context, &creds);

    if(context != NULL){
        krb5_free_context(context);
    }

    return dwError;
error :
#ifdef DEBUG_KRB
        pszErrstr   = (PSTR) krb5_get_error_message(context, err_code);
        printf("Error code : %d\n", err_code);
        printf("Error Message : %s\n", pszErrstr);
        krb5_free_error_message(context, (const char *)pszErrstr);
#endif
    dwError = err_code;
    goto cleanup;

}
Beispiel #24
0
/*
 * This function produces a cred with a MEMORY ccache containing a TGT
 * acquired with a password.
 */
static OM_uint32
acquire_cred_with_password(OM_uint32 *minor_status,
                           krb5_context context,
                           const char *password,
                           OM_uint32 time_req,
                           gss_const_OID desired_mech,
                           gss_cred_usage_t cred_usage,
                           gsskrb5_cred handle)
{
    OM_uint32 ret = GSS_S_FAILURE;
    krb5_creds cred;
    krb5_get_init_creds_opt *opt;
    krb5_ccache ccache = NULL;
    krb5_error_code kret;
    time_t now;
    OM_uint32 left;

    if (cred_usage == GSS_C_ACCEPT) {
        /*
         * TODO: Here we should eventually support user2user (when we get
         *       support for that via an extension to the mechanism
         *       allowing for more than two security context tokens),
         *       and/or new unique MEMORY keytabs (we have MEMORY keytab
         *       support, but we don't have a keytab equivalent of
         *       krb5_cc_new_unique()).  Either way, for now we can't
         *       support this.
         */
        *minor_status = ENOTSUP; /* XXX Better error? */
        return GSS_S_FAILURE;
    }

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

    if (handle->principal == NULL) {
        kret = krb5_get_default_principal(context, &handle->principal);
        if (kret)
            goto end;
    }
    kret = krb5_get_init_creds_opt_alloc(context, &opt);
    if (kret)
        goto end;

    /*
     * Get the current time before the AS exchange so we don't
     * accidentally end up returning a value that puts advertised
     * expiration past the real expiration.
     *
     * We need to do this because krb5_cc_get_lifetime() returns a
     * relative time that we need to add to the current time.  We ought
     * to have a version of krb5_cc_get_lifetime() that returns absolute
     * time...
     */
    krb5_timeofday(context, &now);

    kret = krb5_get_init_creds_password(context, &cred, handle->principal,
                                        password, NULL, NULL, 0, NULL, opt);
    krb5_get_init_creds_opt_free(context, opt);
    if (kret)
        goto end;

    kret = krb5_cc_new_unique(context, krb5_cc_type_memory, NULL, &ccache);
    if (kret)
        goto end;

    kret = krb5_cc_initialize(context, ccache, cred.client);
    if (kret)
        goto end;

    kret = krb5_cc_store_cred(context, ccache, &cred);
    if (kret)
        goto end;

    handle->cred_flags |= GSS_CF_DESTROY_CRED_ON_RELEASE;

    ret = __gsskrb5_ccache_lifetime(minor_status, context, ccache,
                                    handle->principal, &left);
    if (ret != GSS_S_COMPLETE)
        goto end;
    handle->endtime = now + left;
    handle->ccache = ccache;
    ccache = NULL;
    ret = GSS_S_COMPLETE;
    kret = 0;

end:
    if (ccache != NULL)
        krb5_cc_destroy(context, ccache);
    if (cred.client != NULL)
	krb5_free_cred_contents(context, &cred);
    if (ret != GSS_S_COMPLETE && kret != 0)
	*minor_status = kret;
    return (ret);
}
Beispiel #25
0
int
main(int argc, char **argv)
{
    krb5_context context;
    krb5_error_code ret;
    krb5_creds cred;
    krb5_preauthtype pre_auth_types[] = {KRB5_PADATA_ENC_TIMESTAMP};
    krb5_get_init_creds_opt *get_options;
    krb5_verify_init_creds_opt verify_options;
    krb5_principal principal = NULL;
    int optidx = 0;

    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;

    ret = krb5_init_context(&context);
    if (ret)
	errx (1, "krb5_init_context failed: %d", ret);

    ret = krb5_get_init_creds_opt_alloc (context, &get_options);
    if (ret)
	krb5_err(context, 1, ret, "krb5_get_init_creds_opt_alloc");

    krb5_get_init_creds_opt_set_preauth_list (get_options,
					      pre_auth_types,
					      1);

    krb5_verify_init_creds_opt_init (&verify_options);

    if (argc) {
	ret = krb5_parse_name(context, argv[0], &principal);
	if (ret)
	    krb5_err(context, 1, ret, "krb5_parse_name: %s", argv[0]);
    } else {
	ret = krb5_get_default_principal(context, &principal);
	if (ret)
	    krb5_err(context, 1, ret, "krb5_get_default_principal");

    }

    ret = krb5_get_init_creds_password (context,
					&cred,
					principal,
					NULL,
					krb5_prompter_posix,
					NULL,
					0,
					NULL,
					get_options);
    if (ret)
	krb5_err(context, 1, ret,  "krb5_get_init_creds");

    ret = krb5_verify_init_creds (context,
				  &cred,
				  NULL,
				  NULL,
				  NULL,
				  &verify_options);
    if (ret)
	krb5_err(context, 1, ret, "krb5_verify_init_creds");
    krb5_free_cred_contents (context, &cred);
    krb5_free_context (context);
    return 0;
}
Beispiel #26
0
/* Perform one iteration of attempting to get credentials.  This includes
 * searching existing ccache for requested service if INIT_CREDS. */
static kadm5_ret_t
gic_iter(kadm5_server_handle_t handle, enum init_type init_type,
         krb5_ccache ccache, krb5_principal client, char *pass, char *svcname,
         char *realm, krb5_principal *server_out)
{
    kadm5_ret_t code;
    krb5_context ctx;
    krb5_keytab kt;
    krb5_get_init_creds_opt *opt = NULL;
    krb5_creds mcreds, outcreds;

    *server_out = NULL;
    ctx = handle->context;
    kt = NULL;
    memset(&opt, 0, sizeof(opt));
    memset(&mcreds, 0, sizeof(mcreds));
    memset(&outcreds, 0, sizeof(outcreds));

    /* Credentials for kadmin don't need to be forwardable or proxiable. */
    if (init_type != INIT_CREDS) {
        code = krb5_get_init_creds_opt_alloc(ctx, &opt);
        krb5_get_init_creds_opt_set_forwardable(opt, 0);
        krb5_get_init_creds_opt_set_proxiable(opt, 0);
        krb5_get_init_creds_opt_set_out_ccache(ctx, opt, ccache);
        if (init_type == INIT_ANONYMOUS)
            krb5_get_init_creds_opt_set_anonymous(opt, 1);
    }

    if (init_type == INIT_PASS || init_type == INIT_ANONYMOUS) {
        code = krb5_get_init_creds_password(ctx, &outcreds, client, pass,
                                            krb5_prompter_posix,
                                            NULL, 0, svcname, opt);
        if (code)
            goto error;
    } else if (init_type == INIT_SKEY) {
        if (pass) {
            code = krb5_kt_resolve(ctx, pass, &kt);
            if (code)
                goto error;
        }
        code = krb5_get_init_creds_keytab(ctx, &outcreds, client, kt,
                                          0, svcname, opt);
        if (pass)
            krb5_kt_close(ctx, kt);
        if (code)
            goto error;
    } else if (init_type == INIT_CREDS) {
        mcreds.client = client;
        code = krb5_parse_name_flags(ctx, svcname,
                                     KRB5_PRINCIPAL_PARSE_IGNORE_REALM,
                                     &mcreds.server);
        if (code)
            goto error;
        code = krb5_set_principal_realm(ctx, mcreds.server, realm);
        if (code)
            goto error;
        code = krb5_cc_retrieve_cred(ctx, ccache, 0,
                                     &mcreds, &outcreds);
        krb5_free_principal(ctx, mcreds.server);
        if (code)
            goto error;
    } else {
        code = EINVAL;
        goto error;
    }

    /* Steal the server principal of the creds we acquired and return it to the
     * caller, which needs to knows what service to authenticate to. */
    *server_out = outcreds.server;
    outcreds.server = NULL;

error:
    krb5_free_cred_contents(ctx, &outcreds);
    if (opt)
        krb5_get_init_creds_opt_free(ctx, opt);
    return code;
}
Beispiel #27
0
static void
generate_requests (const char *filename, unsigned nreq)
{
    krb5_context context;
    krb5_error_code ret;
    int i;
    char **words;
    unsigned nwords;

    ret = krb5_init_context (&context);
    if (ret)
	errx (1, "krb5_init_context failed: %d", ret);

    nwords = read_words (filename, &words);

    for (i = 0; i < nreq; ++i) {
	char *name = words[rand() % nwords];
	krb5_get_init_creds_opt *opt;
	krb5_creds cred;
	krb5_principal principal;
	int result_code;
	krb5_data result_code_string, result_string;
	char *old_pwd, *new_pwd;
	int aret;

	krb5_get_init_creds_opt_alloc (context, &opt);
	krb5_get_init_creds_opt_set_tkt_life (opt, 300);
	krb5_get_init_creds_opt_set_forwardable (opt, FALSE);
	krb5_get_init_creds_opt_set_proxiable (opt, FALSE);

	ret = krb5_parse_name (context, name, &principal);
	if (ret)
	    krb5_err (context, 1, ret, "krb5_parse_name %s", name);

	aret = asprintf (&old_pwd, "%s", name);
	if (aret == -1)
	    krb5_errx(context, 1, "out of memory");
	aret = asprintf (&new_pwd, "%s2", name);
	if (aret == -1)
	    krb5_errx(context, 1, "out of memory");

	ret = krb5_get_init_creds_password (context,
					    &cred,
					    principal,
					    old_pwd,
					    nop_prompter,
					    NULL,
					    0,
					    "kadmin/changepw",
					    opt);
	if( ret == KRB5KRB_AP_ERR_BAD_INTEGRITY
	    || ret == KRB5KRB_AP_ERR_MODIFIED) {
	    char *tmp;

	    tmp = new_pwd;
	    new_pwd = old_pwd;
	    old_pwd = tmp;

	    ret = krb5_get_init_creds_password (context,
						&cred,
						principal,
						old_pwd,
						nop_prompter,
						NULL,
						0,
						"kadmin/changepw",
						opt);
	}
	if (ret)
	    krb5_err (context, 1, ret, "krb5_get_init_creds_password");

	krb5_free_principal (context, principal);


	ret = krb5_set_password (context,
				 &cred,
				 new_pwd,
				 NULL,
				 &result_code,
				 &result_code_string,
				 &result_string);
	if (ret)
	    krb5_err (context, 1, ret, "krb5_change_password");

	free (old_pwd);
	free (new_pwd);
	krb5_free_cred_contents (context, &cred);
	krb5_get_init_creds_opt_free(context, opt);
    }
}
Beispiel #28
0
/*
 * call-seq:
 *   change_password(old_password, new_password)
 *
 * Allow user to change their Kerberos password, providing the +old_password+ 
 * and the +new_password+.
 * 
 * Returns true on success, raises a Krb5Auth::Krb5::Exception on failure.
 */
static VALUE Krb5_change_password(VALUE self, VALUE v_old, VALUE v_new)
{
  char *oldpass;
  char *newpass;
  int pw_result;
  struct ruby_krb5 *kerb;
  krb5_error_code krbret;
  krb5_data pw_res_string, res_string;

  Check_Type(v_old, T_STRING);
  Check_Type(v_new, T_STRING);

  oldpass = StringValueCStr(v_old);
  newpass = StringValueCStr(v_new);

  Data_Get_Struct(self, struct ruby_krb5, kerb);

  if(!kerb){
    NOSTRUCT_EXCEPT();
    return Qfalse;
  }

  krbret = krb5_get_init_creds_password(
    kerb->ctx,
    &kerb->creds,
    kerb->princ,
    oldpass,
    NULL,
    NULL,
    0,
    "kadmin/changepw",
    NULL
  );

  if(krbret){
    Krb5_register_error(krbret);
    return Qfalse; 
  }

  krbret = krb5_change_password(
    kerb->ctx,
    &kerb->creds,
    newpass,
    &pw_result,
    &pw_res_string,
    &res_string    
  );

  // 0 is success. Anything else is failure.

  if(krbret){
    Krb5_register_error(krbret);
    return Qfalse; 
  }

  if(pw_result){
    Krb5_register_error(pw_result);
    return Qfalse; 
  }

  return Qtrue;
}
Beispiel #29
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;
}
Beispiel #30
0
static OM_uint32 acquire_initiator_cred
		  (OM_uint32 * minor_status,
		   krb5_context context,
		   gss_const_OID credential_type,
		   const void *credential_data,
		   gss_const_name_t desired_name,
		   OM_uint32 time_req,
		   gss_const_OID desired_mech,
		   gss_cred_usage_t cred_usage,
		   gsskrb5_cred handle
		  )
{
    OM_uint32 ret;
    krb5_creds cred;
    krb5_principal def_princ;
    krb5_get_init_creds_opt *opt;
    krb5_ccache ccache;
    krb5_keytab keytab;
    krb5_error_code kret;

    keytab = NULL;
    ccache = NULL;
    def_princ = NULL;
    ret = GSS_S_FAILURE;
    memset(&cred, 0, sizeof(cred));

    /*
     * If we have a preferred principal, lets try to find it in all
     * caches, otherwise, fall back to default cache, ignore all
     * errors while searching.
     */

    if (credential_type != GSS_C_NO_OID &&
	!gss_oid_equal(credential_type, GSS_C_CRED_PASSWORD)) {
	kret = KRB5_NOCREDS_SUPPLIED; /* XXX */
	goto end;
    }

    if (handle->principal) {
	kret = krb5_cc_cache_match (context,
				    handle->principal,
				    &ccache);
	if (kret == 0) {
	    ret = GSS_S_COMPLETE;
	    goto found;
	}
    }

    if (ccache == NULL) {
	kret = krb5_cc_default(context, &ccache);
	if (kret)
	    goto end;
    }
    kret = krb5_cc_get_principal(context, ccache, &def_princ);
    if (kret != 0) {
	/* we'll try to use a keytab below */
	krb5_cc_close(context, ccache);
	def_princ = NULL;
	kret = 0;
    } else if (handle->principal == NULL)  {
	kret = krb5_copy_principal(context, def_princ, &handle->principal);
	if (kret)
	    goto end;
    } else if (handle->principal != NULL &&
	       krb5_principal_compare(context, handle->principal,
				      def_princ) == FALSE) {
	krb5_free_principal(context, def_princ);
	def_princ = NULL;
	krb5_cc_close(context, ccache);
	ccache = NULL;
    }
    if (def_princ == NULL) {
	/* We have no existing credentials cache,
	 * so attempt to get a TGT using a keytab.
	 */
	if (handle->principal == NULL) {
	    kret = krb5_get_default_principal(context, &handle->principal);
	    if (kret)
		goto end;
	}
	kret = krb5_get_init_creds_opt_alloc(context, &opt);
	if (kret)
	    goto end;
	if (credential_type != GSS_C_NO_OID &&
	    gss_oid_equal(credential_type, GSS_C_CRED_PASSWORD)) {
	    gss_buffer_t password = (gss_buffer_t)credential_data;

	    /* XXX are we requiring password to be NUL terminated? */

	    kret = krb5_get_init_creds_password(context, &cred,
						handle->principal,
						password->value,
						NULL, NULL, 0, NULL, opt);
	} else {
	    kret = get_keytab(context, &keytab);
	    if (kret) {
		krb5_get_init_creds_opt_free(context, opt);
		goto end;
	    }
	    kret = krb5_get_init_creds_keytab(context, &cred,
					      handle->principal, keytab,
					      0, NULL, opt);
	}
	krb5_get_init_creds_opt_free(context, opt);
	if (kret)
	    goto end;
	kret = krb5_cc_new_unique(context, krb5_cc_type_memory,
				  NULL, &ccache);
	if (kret)
	    goto end;
	kret = krb5_cc_initialize(context, ccache, cred.client);
	if (kret) {
	    krb5_cc_destroy(context, ccache);
	    goto end;
	}
	kret = krb5_cc_store_cred(context, ccache, &cred);
	if (kret) {
	    krb5_cc_destroy(context, ccache);
	    goto end;
	}
	handle->lifetime = cred.times.endtime;
	handle->cred_flags |= GSS_CF_DESTROY_CRED_ON_RELEASE;
    } else {

	ret = __gsskrb5_ccache_lifetime(minor_status,
					context,
					ccache,
					handle->principal,
					&handle->lifetime);
	if (ret != GSS_S_COMPLETE) {
	    krb5_cc_close(context, ccache);
	    goto end;
	}
	kret = 0;
    }
 found:
    handle->ccache = ccache;
    ret = GSS_S_COMPLETE;

end:
    if (cred.client != NULL)
	krb5_free_cred_contents(context, &cred);
    if (def_princ != NULL)
	krb5_free_principal(context, def_princ);
    if (keytab != NULL)
	krb5_kt_close(context, keytab);
    if (ret != GSS_S_COMPLETE && kret != 0)
	*minor_status = kret;
    return (ret);
}