/* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */
/*
*
* Copyright 1995, 2009 by the Massachusetts Institute of Technology.
* All Rights Reserved.
*
* Export of this software from the United States of America may
* require a specific license from the United States Government.
* It is the responsibility of any person or organization contemplating
* export to obtain such a license before exporting.
*
* WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
* distribute this software and its documentation for any purpose and
* without fee is hereby granted, provided that the above copyright
* notice appear in all copies and that both that copyright notice and
* this permission notice appear in supporting documentation, and that
* the name of M.I.T. not be used in advertising or publicity pertaining
* to distribution of the software without specific, written prior
* permission. Furthermore if you modify this software you must label
* your software as modified software and not distribute it in such a
* fashion that it might be confused with the original M.I.T. software.
* M.I.T. makes no representations about the suitability of
* this software for any purpose. It is provided "as is" without express
* or implied warranty.
*
*/
/*
*/
#include "k5-int.h"
#include "kdb.h"
#include <string.h>
#include <stdio.h>
#include <errno.h>
#include <libintl.h> /* Solaris Kerberos */
/*
* Given a particular enctype and optional salttype and kvno, find the
* most appropriate krb5_key_data entry of the database entry.
*
* If stype or kvno is negative, it is ignored.
* If kvno is 0 get the key which is maxkvno for the princ and matches
* the other attributes.
*/
{
int i, idx;
int maxkvno;
ret = 0;
kvno = 0;
if (kvno == 0) {
/* Get the max key version */
for (i = 0; i < dbentp->n_key_data; i++) {
}
}
}
maxkvno = -1;
ret = 0;
} else {
}
/* Match this entry against the arguments. */
if (ktype != -1) {
&similar)))
return(ret);
if (!similar)
continue;
}
continue;
continue;
/* Filter out non-permitted enctypes. */
continue;
}
idx = i;
}
}
/* If we scanned the whole set of keys and matched only non-permitted
* enctypes, indicate that. */
if (maxkvno < 0)
return 0;
}
/*
* kdb default functions. Ideally, some other file should have this functions. For now, TBD.
*/
#ifndef min
#define min(a,b) (((a) < (b)) ? (a) : (b))
#endif
char *keyfile,
char *master_pwd)
{
int statrc;
if (!keyfile) {
}
/*
* XXX making the assumption that the keyfile is in a dir that requires root
* privilege to write to thus making timing attacks unlikely.
*/
/* if keyfile exists it better be a regular file */
gettext("keyfile (%s) is not a regular file: %s"),
goto out;
}
}
/* Use temp keytab file name in case creation of keytab fails */
/* create temp file template for use by mktemp() */
"Could not create temp keytab file name.");
goto out;
}
/*
* Set tmp_ktpath to point to the keyfile path (skip WRFILE:). Subtracting
* 1 to account for NULL terminator in sizeof calculation of a string
* constant. Used further down.
*/
"Could not create temp stash file: %s",
goto out;
}
/* create new stash keytab using temp file name */
if (retval != 0)
goto out;
}
if (retval != 0) {
/* delete tmp keyfile if it exists and an error occurrs */
(void) unlink(tmp_ktpath);
} else {
/* rename original keyfile to original filename */
"rename of temporary keyfile (%s) to (%s) failed: %s",
}
}
out:
if (tmp_ktname != NULL)
return retval;
}
char *keyfile,
char *master_pwd)
{
}
static krb5_error_code
const char *keyfile,
{
#ifdef ANSI_STDIO
#else
#endif
return KRB5_KDB_CANTREAD_STORED;
goto errout;
}
#endif
goto errout;
}
goto errout;
}
#else
#endif
goto errout;
}
goto errout;
}
} else
retval = 0;
/*
* Note, the old stash format did not store the kvno and at this point it
* can be assumed to be 1 as is the case for the mkey princ. If the kvno is
* passed in and isn't ignore_vno just leave it alone as this could cause
* verifcation trouble if the mkey princ is using a kvno other than 1.
*/
*kvno = 1;
return retval;
}
static krb5_error_code
const char *keyfile,
{
goto errout;
/* override default */
&kt_ent)) == 0) {
goto errout;
}
/*
* If a kvno pointer was passed in and it dereferences the
* IGNORE_VNO value then it should be assigned the value of the kvno
* found in the keytab otherwise the KNVO specified should be the
* same as the one returned from the keytab.
*/
/*
* kt_ent will be free'd so need to allocate and copy key contents for
* output to caller.
*/
goto errout;
}
}
if (kt)
return retval;
}
char *db_args)
{
} else {
}
/* null terminate no matter what */
/* Try the keytab and old stash file formats. */
if (retval == KRB5_KEYTAB_BADVNO)
/*
* Use a generic error code for failure to retrieve the master
* key, but set a message indicating the actual error.
*/
if (retval != 0) {
"Can not fetch master key (error: %s).",
return KRB5_KDB_CANTREAD_STORED;
} else
return 0;
}
/*
* Note, this verifies that the input mkey is currently protecting all the mkeys
*/
{
int nprinc;
nprinc = 1;
return(retval);
if (nprinc != 1) {
if (nprinc)
return(KRB5_KDB_NOMASTERKEY);
} else if (more) {
return(KRB5KDC_ERR_PRINCIPAL_NOT_UNIQUE);
}
&master_entry.key_data[0],
return retval;
}
}
if (kvno != IGNORE_VNO &&
"User specified mkeyVNO (%u) does not match master key princ's KVNO (%u)",
}
return retval;
}
/* Solaris Kerberos: removed unused mkvno arg */
const krb5_keyblock *mkey,
{
int nprinc;
int i;
if (mkeys_list == NULL)
return (EINVAL);
nprinc = 1;
return (retval);
if (nprinc != 1) {
if (nprinc)
return(KRB5_KDB_NOMASTERKEY);
} else if (more) {
return (KRB5KDC_ERR_PRINCIPAL_NOT_UNIQUE);
}
/*
* Check if the input mkey is the latest key and if it isn't then find the
* latest mkey.
*/
&master_entry.key_data[0],
}
}
if (!found_key) {
goto clean_n_exit;
break;
}
}
"Unable to decrypt latest master key with the provided master key\n");
goto clean_n_exit;
}
}
/*
* Extract all the mkeys from master_entry using the most current mkey and
* create a mkey list for the mkeys field in kdc_realm_t.
*/
if (mkey_list_head == NULL) {
goto clean_n_exit;
}
/* loop through any other master keys creating a list of krb5_keylist_nodes */
if (*mkey_list_node == NULL) {
/* *mkey_list_node points to next field of previous node */
if (*mkey_list_node == NULL) {
goto clean_n_exit;
}
}
&((*mkey_list_node)->keyblock),
NULL);
if (retval)
goto clean_n_exit;
}
/*
* Solaris Kerberos: moved this part down because we cache derived keys in
* the cur_mkey block during the krb5_dbekd_decrypt_key_data() above so the
* latest version of cur_mkey should be copied to mkey_list_head->keyblock
* so it has those derived keys.
*/
/* Set mkey_list_head to the current mkey as an optimization. */
/* mkvno may not be latest so ... */
/* this is the latest clear mkey (avoids a redundant decrypt) */
if (retval != 0) {
/*
* Solaris Kerberos: derived key caching changes. If retval != 0 then
* mkey_list_head->keyblock hasn't been set so just free mkey_list_head
* and maybe free cur_mkey separately.
*/
if (mkey_list_head != NULL) {
}
}
return retval;
}
char *pwd,
krb5_keyblock *key )
{
/* printf("default set master key\n"); */
return 0;
}
krb5_keyblock **key )
{
/* printf("default get master key\n"); */
return 0;
}
{
/* printf("default set master key\n"); */
return 0;
}
{
/* printf("default get master key\n"); */
return 0;
}
char *s, char **args)
{
/* printf("default promote_db\n"); */
return KRB5_PLUGIN_OP_NOTSUPP;
}