Exemple #1
0
/*
 * Serialize krb5_keytab.
 */
static krb5_error_code
ser_keytab_test(krb5_context kcontext, int verbose)
{
    krb5_error_code	kret;
    char		ccname[128];
    krb5_keytab		keytab;

    snprintf(ccname, sizeof(ccname), "temp_kt_%d", (int) getpid());
    if (!(kret = krb5_kt_resolve(kcontext, ccname, &keytab)) &&
	!(kret = ser_data(verbose, "> Resolved default keytab",
			  (krb5_pointer) keytab, KV5M_KEYTAB)) &&
	!(kret = krb5_kt_close(kcontext, keytab))) {
	sprintf(ccname, "FILE:temp_kt_%d", (int) getpid());
	if (!(kret = krb5_kt_resolve(kcontext, ccname, &keytab)) &&
	    !(kret = ser_data(verbose, "> Resolved FILE keytab",
			      (krb5_pointer) keytab, KV5M_KEYTAB)) &&
	    !(kret = krb5_kt_close(kcontext, keytab))) {
	    snprintf(ccname, sizeof(ccname),
		     "WRFILE:temp_kt_%d", (int) getpid());
	    if (!(kret = krb5_kt_resolve(kcontext, ccname, &keytab)) &&
		!(kret = ser_data(verbose, "> Resolved WRFILE keytab",
				  (krb5_pointer) keytab, KV5M_KEYTAB)) &&
		!(kret = krb5_kt_close(kcontext, keytab))) {
		if (verbose)
		    printf("* keytab test succeeded\n");
	    }
	}
    }
    if (kret)
	printf("* krb5_keytab test failed\n");
    return(kret);
}
Exemple #2
0
int
kerberos5_init(Authenticator *ap, int server)
{
    krb5_error_code ret;

    ret = krb5_init_context(&context);
    if (ret)
	return 0;
    if (server) {
	krb5_keytab kt;
	krb5_kt_cursor cursor;

	ret = krb5_kt_default(context, &kt);
	if (ret)
	    return 0;

	ret = krb5_kt_start_seq_get (context, kt, &cursor);
	if (ret) {
	    krb5_kt_close (context, kt);
	    return 0;
	}
	krb5_kt_end_seq_get (context, kt, &cursor);
	krb5_kt_close (context, kt);

	str_data[3] = TELQUAL_REPLY;
    } else
	str_data[3] = TELQUAL_IS;
    return(1);
}
Exemple #3
0
/*
 * Given two files containing keytab data, second keytab, merge the keys into
 * the new file.  Currently, this doesn't do any cleanup of old kvnos and
 * doesn't handle duplicate kvnos correctly.  Dies on any error.
 */
static void
merge_keytab(krb5_context ctx, const char *newfile, const char *file)
{
    char *oldfile;
    krb5_keytab old = NULL, temp = NULL;
    krb5_kt_cursor cursor;
    krb5_keytab_entry entry;
    krb5_error_code status;

    memset(&entry, 0, sizeof(entry));
    xasprintf(&oldfile, "WRFILE:%s", file);
    status = krb5_kt_resolve(ctx, oldfile, &old);
    if (status != 0)
        die_krb5(ctx, status, "cannot open keytab %s", file);
    free(oldfile);
    status = krb5_kt_resolve(ctx, newfile, &temp);
    if (status != 0)
        die_krb5(ctx, status, "cannot open temporary keytab %s", newfile);
    status = krb5_kt_start_seq_get(ctx, temp, &cursor);
    if (status != 0)
        die_krb5(ctx, status, "cannot read temporary keytab %s", newfile);
    while ((status = krb5_kt_next_entry(ctx, temp, &entry, &cursor)) == 0) {
        status = krb5_kt_add_entry(ctx, old, &entry);
        if (status != 0)
            die_krb5(ctx, status, "cannot write to keytab %s", file);
        krb5_kt_free_entry(ctx, &entry);
    }
    if (status != KRB5_KT_END)
        die_krb5(ctx, status, "error reading temporary keytab %s", newfile);
    krb5_kt_end_seq_get(ctx, temp, &cursor);
    if (old != NULL)
        krb5_kt_close(ctx, old);
    if (temp != NULL)
        krb5_kt_close(ctx, temp);
}
Exemple #4
0
static void
finish_realm(kdc_realm_t *rdp)
{
    if (rdp->realm_dbname)
	free(rdp->realm_dbname);
    if (rdp->realm_mpname)
	free(rdp->realm_mpname);
    if (rdp->realm_stash)
	free(rdp->realm_stash);
    if (rdp->realm_ports)
	free(rdp->realm_ports);
    if (rdp->realm_tcp_ports)
	free(rdp->realm_tcp_ports);
    if (rdp->realm_keytab)
	krb5_kt_close(rdp->realm_context, rdp->realm_keytab);
    if (rdp->realm_context) {
	if (rdp->realm_mprinc)
	    krb5_free_principal(rdp->realm_context, rdp->realm_mprinc);
	if (rdp->realm_mkey.length && rdp->realm_mkey.contents) {
	    memset(rdp->realm_mkey.contents, 0, rdp->realm_mkey.length);
	    free(rdp->realm_mkey.contents);
	}
	krb5_db_fini(rdp->realm_context);
	if (rdp->realm_tgsprinc)
	    krb5_free_principal(rdp->realm_context, rdp->realm_tgsprinc);
	krb5_free_context(rdp->realm_context);
    }
    memset((char *) rdp, 0, sizeof(*rdp));
    free(rdp);
}
static int
pg_krb5_init(void)
{
	krb5_error_code retval;
	char	   *khostname;

	if (pg_krb5_initialised)
		return STATUS_OK;

	retval = krb5_init_context(&pg_krb5_context);
	if (retval)
	{
		ereport(LOG,
				(errmsg("Kerberos initialization returned error %d",
						retval)));
		com_err("postgres", retval, "while initializing krb5");
		return STATUS_ERROR;
	}

	retval = krb5_kt_resolve(pg_krb5_context, pg_krb_server_keyfile, &pg_krb5_keytab);
	if (retval)
	{
		ereport(LOG,
				(errmsg("Kerberos keytab resolving returned error %d",
						retval)));
		com_err("postgres", retval, "while resolving keytab file \"%s\"",
				pg_krb_server_keyfile);
		krb5_free_context(pg_krb5_context);
		return STATUS_ERROR;
	}

	/*
	 * If no hostname was specified, pg_krb_server_hostname is already NULL.
	 * If it's set to blank, force it to NULL.
	 */
	khostname = pg_krb_server_hostname;
	if (khostname && khostname[0] == '\0')
		khostname = NULL;

	retval = krb5_sname_to_principal(pg_krb5_context,
									 khostname,
									 pg_krb_srvnam,
									 KRB5_NT_SRV_HST,
									 &pg_krb5_server);
	if (retval)
	{
		ereport(LOG,
				(errmsg("Kerberos sname_to_principal(\"%s\", \"%s\") returned error %d",
		 khostname ? khostname : "server hostname", pg_krb_srvnam, retval)));
		com_err("postgres", retval,
		"while getting server principal for server \"%s\" for service \"%s\"",
				khostname ? khostname : "server hostname", pg_krb_srvnam);
		krb5_kt_close(pg_krb5_context, pg_krb5_keytab);
		krb5_free_context(pg_krb5_context);
		return STATUS_ERROR;
	}

	pg_krb5_initialised = 1;
	return STATUS_OK;
}
krb5_error_code
_adcli_krb5_keytab_discover_salt (krb5_context k5,
                                  krb5_principal principal,
                                  krb5_kvno kvno,
                                  krb5_data *password,
                                  krb5_enctype *enctypes,
                                  krb5_data *salts,
                                  int *discovered)
{
	krb5_keytab scratch;
	krb5_error_code code;
	int i;

	/* TODO: This should be a unique name */

	code = krb5_kt_resolve (k5, "MEMORY:adcli-discover-salt", &scratch);
	return_val_if_fail (code == 0, code);

	for (i = 0; salts[i].data != NULL; i++) {
		code = _adcli_krb5_keytab_test_salt (k5, scratch, principal, kvno,
		                                     password, enctypes, &salts[i]);
		if (code == 0) {
			*discovered = i;
			break;
		} else if (code != KRB5_PREAUTH_FAILED && code != KRB5KDC_ERR_PREAUTH_FAILED) {
			break;
		}
	}

	krb5_kt_close (k5, scratch);
	return code;
}
Exemple #7
0
KRB5_DEPRECATED
KRB5_LIB_FUNCTION krb5_error_code KRB5_CALLCONV
krb5_keytab_key_proc (krb5_context context,
		      krb5_enctype enctype,
		      krb5_salt salt,
		      krb5_const_pointer keyseed,
		      krb5_keyblock **key)
{
    krb5_keytab_key_proc_args *args  = rk_UNCONST(keyseed);
    krb5_keytab keytab = args->keytab;
    krb5_principal principal  = args->principal;
    krb5_error_code ret;
    krb5_keytab real_keytab;
    krb5_keytab_entry entry;

    if(keytab == NULL)
	krb5_kt_default(context, &real_keytab);
    else
	real_keytab = keytab;

    ret = krb5_kt_get_entry (context, real_keytab, principal,
			     0, enctype, &entry);

    if (keytab == NULL)
	krb5_kt_close (context, real_keytab);

    if (ret)
	return ret;

    ret = krb5_copy_keyblock (context, &entry.keyblock, key);
    krb5_kt_free_entry(context, &entry);
    return ret;
}
Exemple #8
0
int
term_module() {
	if (principal)
		ch_free(principal);
	if (kt_name)
		ch_free(kt_name);
	if (kid) {
		struct re_s *task;

		task=ldap_pvt_runqueue_find( &slapd_rq, kinit_qtask, (void*)kid);
		if (task) {
			if ( ldap_pvt_runqueue_isrunning(&slapd_rq, task) ) {
				ldap_pvt_runqueue_stoptask(&slapd_rq, task);
			}
			ldap_pvt_runqueue_remove(&slapd_rq, task);
		}
		if ( kid->ctx ) {
			if ( kid->princ )
				krb5_free_principal(kid->ctx, kid->princ);
			if ( kid->ccache )
				krb5_cc_close(kid->ctx, kid->ccache);
			if ( kid->keytab )
				krb5_kt_close(kid->ctx, kid->keytab);
			if ( kid->opts )
				krb5_get_init_creds_opt_free(kid->ctx, kid->opts);
			krb5_free_context(kid->ctx);
		}
		ch_free(kid);
	}
	return 0;
}
Exemple #9
0
OM_uint32 gss_release_cred
           (OM_uint32 * minor_status,
            gss_cred_id_t * cred_handle
           )
{
    *minor_status = 0;

    if (*cred_handle == GSS_C_NO_CREDENTIAL) {
        return GSS_S_COMPLETE;
    }

    GSSAPI_KRB5_INIT ();

    HEIMDAL_MUTEX_lock(&(*cred_handle)->cred_id_mutex);

    if ((*cred_handle)->principal != NULL)
        krb5_free_principal(gssapi_krb5_context, (*cred_handle)->principal);
    if ((*cred_handle)->keytab != NULL)
	krb5_kt_close(gssapi_krb5_context, (*cred_handle)->keytab);
    if ((*cred_handle)->ccache != NULL) {
	const krb5_cc_ops *ops;
	ops = krb5_cc_get_ops(gssapi_krb5_context, (*cred_handle)->ccache);
	if (ops == &krb5_mcc_ops)
	    krb5_cc_destroy(gssapi_krb5_context, (*cred_handle)->ccache);
	else 
	    krb5_cc_close(gssapi_krb5_context, (*cred_handle)->ccache);
    }
    gss_release_oid_set(NULL, &(*cred_handle)->mechanisms);
    HEIMDAL_MUTEX_unlock(&(*cred_handle)->cred_id_mutex);
    HEIMDAL_MUTEX_destroy(&(*cred_handle)->cred_id_mutex);
    memset(*cred_handle, 0, sizeof(**cred_handle));
    free(*cred_handle);
    *cred_handle = GSS_C_NO_CREDENTIAL;
    return GSS_S_COMPLETE;
}
Exemple #10
0
/*
 * Find the principal of the first entry of a keytab and return it.  The
 * caller is responsible for freeing the result with krb5_free_principal.
 * Exit on error.
 */
krb5_principal
kerberos_keytab_principal(krb5_context ctx, const char *path)
{
    krb5_keytab keytab;
    krb5_kt_cursor cursor;
    krb5_keytab_entry entry;
    krb5_principal princ;
    krb5_error_code status;

    status = krb5_kt_resolve(ctx, path, &keytab);
    if (status != 0)
        bail_krb5(ctx, status, "error opening %s", path);
    status = krb5_kt_start_seq_get(ctx, keytab, &cursor);
    if (status != 0)
        bail_krb5(ctx, status, "error reading %s", path);
    status = krb5_kt_next_entry(ctx, keytab, &entry, &cursor);
    if (status == 0) {
        status = krb5_copy_principal(ctx, entry.principal, &princ);
        if (status != 0)
            bail_krb5(ctx, status, "error copying principal from %s", path);
        krb5_kt_free_entry(ctx, &entry);
    }
    if (status != 0)
        bail("no principal found in keytab file %s", path);
    krb5_kt_end_seq_get(ctx, keytab, &cursor);
    krb5_kt_close(ctx, keytab);
    return princ;
}
static OM_uint32 acquire_acceptor_cred
		  (OM_uint32 * minor_status,
		   krb5_context context,
		   const gss_name_t desired_name,
		   OM_uint32 time_req,
		   gss_cred_usage_t cred_usage,
		   gsskrb5_cred handle
		  )
{
    krb5_error_code kret;

    kret = get_keytab(context, handle, 0);

    if (kret) {
	if (handle->keytab != NULL) {
	    krb5_kt_close(context, handle->keytab);
	    handle->keytab = NULL;
	}
	*minor_status = kret;
	return GSS_S_FAILURE;
    }

    handle->endtime = INT_MAX;

    return GSS_S_COMPLETE;
}
Exemple #12
0
static void
finish_realm(kdc_realm_t *rdp)
{
    if (rdp->realm_name)
        free(rdp->realm_name);
    if (rdp->realm_mpname)
        free(rdp->realm_mpname);
    if (rdp->realm_stash)
        free(rdp->realm_stash);
    if (rdp->realm_listen)
        free(rdp->realm_listen);
    if (rdp->realm_tcp_listen)
        free(rdp->realm_tcp_listen);
    if (rdp->realm_keytab)
        krb5_kt_close(rdp->realm_context, rdp->realm_keytab);
    if (rdp->realm_hostbased)
        free(rdp->realm_hostbased);
    if (rdp->realm_no_referral)
        free(rdp->realm_no_referral);
    if (rdp->realm_context) {
        if (rdp->realm_mprinc)
            krb5_free_principal(rdp->realm_context, rdp->realm_mprinc);
        if (rdp->realm_mkey.length && rdp->realm_mkey.contents) {
            /* XXX shouldn't memset be zap for safety? */
            memset(rdp->realm_mkey.contents, 0, rdp->realm_mkey.length);
            free(rdp->realm_mkey.contents);
        }
        krb5_db_fini(rdp->realm_context);
        if (rdp->realm_tgsprinc)
            krb5_free_principal(rdp->realm_context, rdp->realm_tgsprinc);
        krb5_free_context(rdp->realm_context);
    }
    memset(rdp, 0, sizeof(*rdp));
    free(rdp);
}
Exemple #13
0
int
ext_keytab(struct ext_keytab_options *opt, int argc, char **argv)
{
    krb5_error_code ret;
    int i;
    struct ext_keytab_data data;

    if (opt->keytab_string == NULL)
	ret = krb5_kt_default(context, &data.keytab);
    else
	ret = krb5_kt_resolve(context, opt->keytab_string, &data.keytab);

    if(ret){
	krb5_warn(context, ret, "krb5_kt_resolve");
	return 1;
    }

    for(i = 0; i < argc; i++) {
	ret = foreach_principal(argv[i], do_ext_keytab, "ext", &data);
	if (ret)
	    break;
    }

    krb5_kt_close(context, data.keytab);

    return ret != 0;
}
Exemple #14
0
krb5_error_code KRB5_LIB_FUNCTION
krb5_kt_read_service_key(krb5_context context,
			 krb5_pointer keyprocarg,
			 krb5_principal principal,
			 krb5_kvno vno,
			 krb5_enctype enctype,
			 krb5_keyblock **key)
{
    krb5_keytab keytab;
    krb5_keytab_entry entry;
    krb5_error_code ret;

    if (keyprocarg)
	ret = krb5_kt_resolve (context, keyprocarg, &keytab);
    else
	ret = krb5_kt_default (context, &keytab);

    if (ret)
	return ret;

    ret = krb5_kt_get_entry (context, keytab, principal, vno, enctype, &entry);
    krb5_kt_close (context, keytab);
    if (ret)
	return ret;
    ret = krb5_copy_keyblock (context, &entry.keyblock, key);
    krb5_kt_free_entry(context, &entry);
    return ret;
}
mit_krb5_error_code KRB5_CALLCONV
krb5_kt_read_service_key(mit_krb5_context context,
			 mit_krb5_pointer keyprocarg,
			 mit_krb5_principal principal,
			 mit_krb5_kvno vno,
			 mit_krb5_enctype enctype,
			 mit_krb5_keyblock **key)
{
    mit_krb5_keytab keytab;
    mit_krb5_keytab_entry entry;
    mit_krb5_error_code ret;

    LOG_ENTRY();

    if (keyprocarg)
	ret = krb5_kt_resolve (context, keyprocarg, &keytab);
    else
	ret = krb5_kt_default (context, &keytab);

    if (ret)
	return ret;

    ret = krb5_kt_get_entry (context, keytab, principal, vno, enctype, &entry);
    krb5_kt_close (context, keytab);
    if (ret)
	return ret;
    ret = krb5_copy_keyblock (context, &entry.key, key);
    krb5_kt_free_entry(context, &entry);
    return ret;
}
Exemple #16
0
/*
 * Given a context, a keytab file, and a realm, return a list of all
 * principals in that file.
 */
static struct principal_name *
keytab_principals(krb5_context ctx, const char *file, char *realm)
{
    char *princname = NULL, *princrealm = NULL;
    bool found;
    krb5_keytab keytab = NULL;
    krb5_kt_cursor cursor;
    krb5_keytab_entry entry;
    krb5_error_code status;
    struct principal_name *names = NULL, *current = NULL, *last = NULL;

    memset(&entry, 0, sizeof(entry));
    status = krb5_kt_resolve(ctx, file, &keytab);
    if (status != 0)
        die_krb5(ctx, status, "cannot open keytab %s", file);
    status = krb5_kt_start_seq_get(ctx, keytab, &cursor);
    if (status != 0)
        die_krb5(ctx, status, "cannot read keytab %s", file);
    while ((status = krb5_kt_next_entry(ctx, keytab, &entry, &cursor)) == 0) {
        status = krb5_unparse_name(ctx, entry.principal, &princname);
        if (status != 0)
            die_krb5(ctx, status, "cannot unparse name for a principal");

        /* Separate into principal and realm. */
        princrealm = strchr(princname, '@');
        if (princrealm != NULL) {
            *princrealm = '\0';
            princrealm++;
        }
        if (princrealm == NULL || strcmp(princrealm, realm) != 0)
            continue;

        /* Check to see if the principal has already been listed. */
        found = false;
        for (current = names; current != NULL; current = current->next) {
            if (strcmp(current->princ, princname) == 0) {
                found = true;
                break;
            }
            last = current;
        }
        if (found == false) {
            current = xmalloc(sizeof(struct principal_name));
            current->princ = xstrdup(princname);
            current->next = NULL;
            if (last == NULL)
                names = current;
            else
                last->next = current;
        }
        krb5_kt_free_entry(ctx, &entry);
        free(princname);
    }
    if (status != KRB5_KT_END)
        die_krb5(ctx, status, "error reading keytab %s", file);
    krb5_kt_end_seq_get(ctx, keytab, &cursor);
    krb5_kt_close(ctx, keytab);
    return names;
}
Exemple #17
0
krb5_error_code KRB5_CALLCONV
krb5_get_in_tkt_with_keytab(krb5_context context, krb5_flags options,
			      krb5_address *const *addrs, krb5_enctype *ktypes,
			      krb5_preauthtype *pre_auth_types,
			      krb5_keytab arg_keytab, krb5_ccache ccache,
			      krb5_creds *creds, krb5_kdc_rep **ret_as_reply)
{
    krb5_error_code retval;
    krb5_gic_opt_ext *opte;
    char * server = NULL;
    krb5_keytab keytab;
    krb5_principal client_princ, server_princ;
    int use_master = 0;
    
    retval = krb5int_populate_gic_opt(context, &opte,
				      options, addrs, ktypes,
				      pre_auth_types, creds);
    if (retval)
	return retval;

    if (arg_keytab == NULL) {
	retval = krb5_kt_default(context, &keytab);
	if (retval)
	    return retval;
    }
    else keytab = arg_keytab;
    
    retval = krb5_unparse_name( context, creds->server, &server);
    if (retval)
	goto cleanup;
    server_princ = creds->server;
    client_princ = creds->client;
    retval = krb5_get_init_creds (context,
				  creds, creds->client,  
				  krb5_prompter_posix,  NULL,
				  0, server, opte,
				  krb5_get_as_key_keytab, (void *)keytab,
				  &use_master, ret_as_reply);
    krb5_free_unparsed_name( context, server);
    krb5_get_init_creds_opt_free(context, (krb5_get_init_creds_opt *)opte);
    if (retval) {
	goto cleanup;
    }
	if (creds->server)
	    krb5_free_principal( context, creds->server);
	if (creds->client)
	    krb5_free_principal( context, creds->client);
	creds->client = client_princ;
	creds->server = server_princ;
	
    /* store it in the ccache! */
    if (ccache)
	if ((retval = krb5_cc_store_cred(context, ccache, creds)))
	    goto cleanup;
 cleanup:    if (arg_keytab == NULL)
     krb5_kt_close(context, keytab);
    return retval;
}
Exemple #18
0
krb5_error_code kt_copy (krb5_context context, const char *from, const char *to)
{
    krb5_error_code ret;
    krb5_keytab src_keytab, dst_keytab;
    krb5_kt_cursor cursor;
    krb5_keytab_entry entry;

    ret = krb5_kt_resolve (context, from, &src_keytab);
    if (ret) {
	krb5_set_error_message (context, ret, "resolving src keytab `%s'", from);
	return ret;
    }

    ret = krb5_kt_resolve (context, to, &dst_keytab);
    if (ret) {
	krb5_kt_close (context, src_keytab);
	krb5_set_error_message (context, ret, "resolving dst keytab `%s'", to);
	return ret;
    }

    ret = krb5_kt_start_seq_get (context, src_keytab, &cursor);
    if (ret) {
	krb5_set_error_message (context, ret, "krb5_kt_start_seq_get %s", from);
	goto out;
    }

    while((ret = krb5_kt_next_entry(context, src_keytab,
				    &entry, &cursor)) == 0) {
	ret = copy_one_entry(context, src_keytab, dst_keytab, entry);
	if (ret) {
	    break;
	}
    }
    krb5_kt_end_seq_get (context, src_keytab, &cursor);

  out:
    krb5_kt_close (context, src_keytab);
    krb5_kt_close (context, dst_keytab);
    if (ret == KRB5_KT_END) {
	return 0;
    } else if (ret == 0) {
	return EINVAL;
    }
    return ret;
}
Exemple #19
0
static OM_uint32 acquire_acceptor_cred
		  (OM_uint32 * minor_status,
		   krb5_context context,
		   const gss_name_t desired_name,
		   OM_uint32 time_req,
		   const gss_OID_set desired_mechs,
		   gss_cred_usage_t cred_usage,
		   gsskrb5_cred handle,
		   gss_OID_set * actual_mechs,
		   OM_uint32 * time_rec
		  )
{
    OM_uint32 ret;
    krb5_error_code kret;

    ret = GSS_S_FAILURE;
    kret = get_keytab(context, &handle->keytab);
    if (kret)
	goto end;

    /* check that the requested principal exists in the keytab */
    if (handle->principal) {
	krb5_keytab_entry entry;

	kret = krb5_kt_get_entry(context, handle->keytab,
				 handle->principal, 0, 0, &entry);
	if (kret)
	    goto end;
	krb5_kt_free_entry(context, &entry);
	ret = GSS_S_COMPLETE;
    } else {
	/*
	 * Check if there is at least one entry in the keytab before
	 * declaring it as an useful keytab.
	 */
	krb5_keytab_entry tmp;
	krb5_kt_cursor c;

	kret = krb5_kt_start_seq_get (context, handle->keytab, &c);
	if (kret)
	    goto end;
	if (krb5_kt_next_entry(context, handle->keytab, &tmp, &c) == 0) {
	    krb5_kt_free_entry(context, &tmp);
	    ret = GSS_S_COMPLETE; /* ok found one entry */
	}
	krb5_kt_end_seq_get (context, handle->keytab, &c);
    }
end:
    if (ret != GSS_S_COMPLETE) {
	if (handle->keytab != NULL)
	    krb5_kt_close(context, handle->keytab);
	if (kret != 0) {
	    *minor_status = kret;
	}
    }
    return (ret);
}
Exemple #20
0
static void
get_creds(krb5_context context, const char *keytab_str,
	  krb5_ccache *cache, const char *serverhost)
{
    krb5_keytab keytab;
    krb5_principal client;
    krb5_error_code ret;
    krb5_get_init_creds_opt *init_opts;
    krb5_creds creds;
    char *server;
    char keytab_buf[256];
    int aret;

    if (keytab_str == NULL) {
	ret = krb5_kt_default_name (context, keytab_buf, sizeof(keytab_buf));
	if (ret)
	    krb5_err (context, 1, ret, "krb5_kt_default_name");
	keytab_str = keytab_buf;
    }

    ret = krb5_kt_resolve(context, keytab_str, &keytab);
    if(ret)
	krb5_err(context, 1, ret, "%s", keytab_str);


    ret = krb5_sname_to_principal (context, slave_str, IPROP_NAME,
				   KRB5_NT_SRV_HST, &client);
    if (ret) krb5_err(context, 1, ret, "krb5_sname_to_principal");

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

    aret = asprintf (&server, "%s/%s", IPROP_NAME, serverhost);
    if (aret == -1 || server == NULL)
	krb5_errx (context, 1, "malloc: no memory");

    ret = krb5_get_init_creds_keytab(context, &creds, client, keytab,
				     0, server, init_opts);
    free (server);
    krb5_get_init_creds_opt_free(context, init_opts);
    if(ret) krb5_err(context, 1, ret, "krb5_get_init_creds");

    ret = krb5_kt_close(context, keytab);
    if(ret) krb5_err(context, 1, ret, "krb5_kt_close");

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

    ret = krb5_cc_initialize(context, *cache, client);
    if(ret) krb5_err(context, 1, ret, "krb5_cc_initialize");

    ret = krb5_cc_store_cred(context, *cache, &creds);
    if(ret) krb5_err(context, 1, ret, "krb5_cc_store_cred");

    krb5_free_cred_contents(context, &creds);
    krb5_free_principal(context, client);
}
Exemple #21
0
int
kssl_keytab_is_available(KSSL_CTX *kssl_ctx)
{
	krb5_context		krb5context = NULL;
	krb5_keytab 		krb5keytab = NULL;
	krb5_keytab_entry           entry;
	krb5_principal              princ = NULL;
	krb5_error_code  		krb5rc = KRB5KRB_ERR_GENERIC;
	int rc = 0;

	if ((krb5rc = krb5_init_context(&krb5context)))
		return (0);

    /*	kssl_ctx->keytab_file == NULL ==> use Kerberos default
    */
	if (kssl_ctx->keytab_file) {
		krb5rc = krb5_kt_resolve(krb5context, kssl_ctx->keytab_file,
		    &krb5keytab);
		if (krb5rc)
			goto exit;
	} else {
		krb5rc = krb5_kt_default(krb5context, &krb5keytab);
		if (krb5rc)
			goto exit;
	}

	/* the host key we are looking for */
	krb5rc = krb5_sname_to_principal(krb5context, NULL,
	    kssl_ctx->service_name ? kssl_ctx->service_name : KRB5SVC,
	    KRB5_NT_SRV_HST, &princ);

	if (krb5rc)
		goto exit;

	krb5rc = krb5_kt_get_entry(krb5context, krb5keytab, princ,
	    0 /* IGNORE_VNO */,
	    0 /* IGNORE_ENCTYPE */,
	    &entry);
	if (krb5rc == KRB5_KT_NOTFOUND) {
		rc = 1;
		goto exit;
	} else if (krb5rc)
		goto exit;

	krb5_kt_free_entry(krb5context, &entry);
	rc = 1;

	exit:
	if (krb5keytab)
		krb5_kt_close(krb5context, krb5keytab);
	if (princ)
		krb5_free_principal(krb5context, princ);
	if (krb5context)
		krb5_free_context(krb5context);
	return (rc);
}
Exemple #22
0
KRB5_LIB_FUNCTION krb5_error_code KRB5_LIB_CALL
krb5_kt_destroy(krb5_context context,
		krb5_keytab id)
{
    krb5_error_code ret;

    ret = (*id->destroy)(context, id);
    krb5_kt_close(context, id);
    return ret;
}
Exemple #23
0
int
kt_remove(struct remove_options *opt, int argc, char **argv)
{
    krb5_error_code ret = 0;
    krb5_keytab_entry entry;
    krb5_keytab keytab;
    krb5_principal principal = NULL;
    krb5_enctype enctype = 0;

    if(opt->principal_string) {
	ret = krb5_parse_name(context, opt->principal_string, &principal);
	if(ret) {
	    krb5_warn(context, ret, "%s", opt->principal_string);
	    return 1;
	}
    }
    if(opt->enctype_string) {
	ret = krb5_string_to_enctype(context, opt->enctype_string, &enctype);
	if(ret) {
	    int t;
	    if(sscanf(opt->enctype_string, "%d", &t) == 1)
		enctype = t;
	    else {
		krb5_warn(context, ret, "%s", opt->enctype_string);
		if(principal)
		    krb5_free_principal(context, principal);
		return 1;
	    }
	}
    }
    if (!principal && !enctype && !opt->kvno_integer) {
	krb5_warnx(context,
		   "You must give at least one of "
		   "principal, enctype or kvno.");
	ret = EINVAL;
	goto out;
    }

    if((keytab = ktutil_open_keytab()) == NULL) {
	ret = 1;
	goto out;
    }

    entry.principal = principal;
    entry.keyblock.keytype = enctype;
    entry.vno = opt->kvno_integer;
    ret = krb5_kt_remove_entry(context, keytab, &entry);
    krb5_kt_close(context, keytab);
    if(ret)
	krb5_warn(context, ret, "remove");
 out:
    if(principal)
	krb5_free_principal(context, principal);
    return ret != 0;
}
Exemple #24
0
/** Frees libkrb5 resources associated with the handle
 *
 * Must not be called directly.
 *
 * @param conn to free.
 * @return 0 (always indicates success).
 */
static int _mod_conn_free(rlm_krb5_handle_t *conn) {
	krb5_free_context(conn->context);

	if (conn->keytab) krb5_kt_close(conn->context, conn->keytab);

#ifdef HEIMDAL_KRB5
	if (conn->ccache) krb5_cc_destroy(conn->context, conn->ccache);
#endif

	return 0;
}
Exemple #25
0
static krb5_error_code
hkt_close(krb5_context context, HDB *db)
{
    hdb_keytab k = (hdb_keytab)db->hdb_db;
    krb5_error_code ret;

    assert(k->keytab);

    ret = krb5_kt_close(context, k->keytab);
    k->keytab = NULL;

    return ret;
}
static void
free_list (krb5_context context, struct any_data *a)
{
    struct any_data *next;

    for (; a != NULL; a = next) {
	next = a->next;
	free (a->name);
	if(a->kt)
	    krb5_kt_close(context, a->kt);
	free (a);
    }
}
Exemple #27
0
static void
get_tickets(krb5_context context)
{
    char *server;
    krb5_error_code retval;
    krb5_keytab keytab = NULL;
    krb5_principal server_princ = NULL;

    /* Figure out what tickets we'll be using to send. */
    retval = sn2princ_realm(context, NULL, KPROP_SERVICE_NAME, realm,
                            &my_principal);
    if (retval) {
        com_err(progname, errno, _("while setting client principal name"));
        exit(1);
    }

    /* Construct the principal name for the slave host. */
    memset(&creds, 0, sizeof(creds));
    retval = sn2princ_realm(context, slave_host, KPROP_SERVICE_NAME, realm,
                            &server_princ);
    if (retval) {
        com_err(progname, errno, _("while setting server principal name"));
        exit(1);
    }
    retval = krb5_unparse_name_flags(context, server_princ,
                                     KRB5_PRINCIPAL_UNPARSE_NO_REALM, &server);
    if (retval) {
        com_err(progname, retval, _("while unparsing server name"));
        exit(1);
    }

    if (srvtab != NULL) {
        retval = krb5_kt_resolve(context, srvtab, &keytab);
        if (retval) {
            com_err(progname, retval, _("while resolving keytab"));
            exit(1);
        }
    }

    retval = krb5_get_init_creds_keytab(context, &creds, my_principal, keytab,
                                        0, server, NULL);
    if (retval) {
        com_err(progname, retval, _("while getting initial credentials\n"));
        exit(1);
    }

    if (keytab != NULL)
        krb5_kt_close(context, keytab);
    krb5_free_unparsed_name(context, server);
    krb5_free_principal(context, server_princ);
}
Exemple #28
0
/* Dispatch routine for set/change password */
void
dispatch(void *handle, struct sockaddr *local_saddr,
         const krb5_fulladdr *remote_faddr, krb5_data *request, int is_tcp,
         verto_ctx *vctx, loop_respond_fn respond, void *arg)
{
    krb5_error_code ret;
    krb5_keytab kt = NULL;
    kadm5_server_handle_t server_handle = (kadm5_server_handle_t)handle;
    krb5_fulladdr local_faddr;
    krb5_address **local_kaddrs = NULL, local_kaddr_buf;
    krb5_data *response = NULL;

    if (local_saddr == NULL) {
        ret = krb5_os_localaddr(server_handle->context, &local_kaddrs);
        if (ret != 0)
            goto egress;

        local_faddr.address = local_kaddrs[0];
        local_faddr.port = 0;
    } else {
        local_faddr.address = &local_kaddr_buf;
        init_addr(&local_faddr, local_saddr);
    }

    ret = krb5_kt_resolve(server_handle->context, "KDB:", &kt);
    if (ret != 0) {
        krb5_klog_syslog(LOG_ERR, _("chpw: Couldn't open admin keytab %s"),
                         krb5_get_error_message(server_handle->context, ret));
        goto egress;
    }

    response = k5alloc(sizeof(krb5_data), &ret);
    if (response == NULL)
        goto egress;

    ret = process_chpw_request(server_handle->context,
                               handle,
                               server_handle->params.realm,
                               kt,
                               &local_faddr,
                               remote_faddr,
                               request,
                               response);
egress:
    if (ret)
        krb5_free_data(server_handle->context, response);
    krb5_free_addresses(server_handle->context, local_kaddrs);
    krb5_kt_close(server_handle->context, kt);
    (*respond)(arg, ret, ret == 0 ? response : NULL);
}
Exemple #29
0
krb5_error_code libnet_keytab_init(TALLOC_CTX *mem_ctx,
				   const char *keytab_name,
				   struct libnet_keytab_context **ctx)
{
	krb5_error_code ret = 0;
	krb5_context context = NULL;
	krb5_keytab keytab = NULL;
	const char *keytab_string = NULL;

	struct libnet_keytab_context *r;

	r = talloc_zero(mem_ctx, struct libnet_keytab_context);
	if (!r) {
		return ENOMEM;
	}

	talloc_set_destructor(r, keytab_close);

	initialize_krb5_error_table();
	ret = krb5_init_context(&context);
	if (ret) {
		DEBUG(1,("keytab_init: could not krb5_init_context: %s\n",
			error_message(ret)));
		return ret;
	}

	ret = smb_krb5_open_keytab(context, keytab_name, true, &keytab);
	if (ret) {
		DEBUG(1,("keytab_init: smb_krb5_open_keytab failed (%s)\n",
			error_message(ret)));
		krb5_free_context(context);
		return ret;
	}

	ret = smb_krb5_keytab_name(mem_ctx, context, keytab, &keytab_string);
	if (ret) {
		krb5_kt_close(context, keytab);
		krb5_free_context(context);
		return ret;
	}

	r->context = context;
	r->keytab = keytab;
	r->keytab_name = keytab_string;
	r->clean_old_entries = false;

	*ctx = r;

	return 0;
}
Exemple #30
0
static int
pg_krb5_init(void)
{
	krb5_error_code retval;

	if (pg_krb5_initialised)
		return STATUS_OK;

	retval = krb5_init_context(&pg_krb5_context);
	if (retval)
	{
		ereport(LOG,
				(errmsg("Kerberos initialization returned error %d",
						retval)));
		com_err("postgres", retval, "while initializing krb5");
		return STATUS_ERROR;
	}

	retval = krb5_kt_resolve(pg_krb5_context, pg_krb_server_keyfile, &pg_krb5_keytab);
	if (retval)
	{
		ereport(LOG,
				(errmsg("Kerberos keytab resolving returned error %d",
						retval)));
		com_err("postgres", retval, "while resolving keytab file \"%s\"",
				pg_krb_server_keyfile);
		krb5_free_context(pg_krb5_context);
		return STATUS_ERROR;
	}

	retval = krb5_sname_to_principal(pg_krb5_context, NULL, PG_KRB_SRVNAM,
									 KRB5_NT_SRV_HST, &pg_krb5_server);
	if (retval)
	{
		ereport(LOG,
		 (errmsg("Kerberos sname_to_principal(\"%s\") returned error %d",
				 PG_KRB_SRVNAM, retval)));
		com_err("postgres", retval,
				"while getting server principal for service \"%s\"",
				PG_KRB_SRVNAM);
		krb5_kt_close(pg_krb5_context, pg_krb5_keytab);
		krb5_free_context(pg_krb5_context);
		return STATUS_ERROR;
	}

	pg_krb5_initialised = 1;
	return STATUS_OK;
}