/*
* Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
#pragma ident "%Z%%M% %I% %E% SMI"
/*
* Copyright 2006 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.
*/
/*
* This code was based on code donated to MIT by Novell for
* distribution under the MIT license.
*/
/*
* Include files
*/
#include <stdio.h>
#include <string.h>
#include <k5-int.h>
#include <osconf.h>
#include "kdb5.h"
#include <assert.h>
#include "k5-platform.h"
#include <libintl.h>
/* Currently DB2 policy related errors are exported from DAL. But
other databases should set_err function to return string. */
#include "adb_err.h"
/*
* Type definitions
*/
/*
* internal static variable
*/
#ifdef _KDB5_STATIC_LINK
#else
/* to avoid redefinition problem */
#define _KDB5_DYNAMIC_LINK
#endif
/*
* Helper Functions
*/
int
kdb_init_lock_list(void)
{
return k5_mutex_finish_init(&db_lock);
}
static int
{
int err;
if (err)
return err;
return k5_mutex_lock(&db_lock);
}
void
kdb_fini_lock_list(void)
{
}
static int
{
return k5_mutex_unlock(&db_lock);
}
#define kdb_init_lib_lock(a) 0
#define kdb_destroy_lib_lock(a) (void)0
#define kdb_lock_lib_lock(a, b) 0
#define kdb_unlock_lib_lock(a, b) (void)0
/* Caller must free result*/
static char *
{
return NULL;
/* The profile has to have been initialized. If the profile was
not initialized, expect nothing less than a crash. */
/* realms */
/* under the realm name, database_module */
/* default value is the realm name itself */
&value);
if (status) {
/* some problem */
/* let NULL be handled by the caller */
} else {
/* free profile string */
}
return result;
}
static char *
{
/* realms */
/* under the realm name, database_module */
/* default value is the realm name itself */
&value);
if (status) {
goto clean_n_exit;
}
/* we got the module section. Get the library name from the module */
/* default to db2 */
&lib);
if (status) {
goto clean_n_exit;
}
if (value) {
/* free profile string */
}
if (lib) {
/* free profile string */
}
return result;
}
static void
{
}
}
}
}
}
}
}
}
}
static int kdb_db2_pol_err_loaded = 0;
#ifdef _KDB5_STATIC_LINK
static krb5_error_code
{
}
goto clean_n_exit;
}
if (status) {
goto clean_n_exit;
}
#if !defined(KDB5_USE_LIB_KDB_DB2) && !defined(KDB5_USE_LIB_TEST)
#endif
#ifdef KDB5_USE_LIB_KDB_DB2
} else
#endif
#ifdef KDB5_USE_LIB_TEST
} else
#endif
{
lib_name);
goto clean_n_exit;
}
/* ERROR. library not initialized cleanly */
goto clean_n_exit;
}
if (status) {
}
return status;
}
#else /* KDB5_STATIC_LINK*/
static krb5_error_code
{
int ndx;
/* N.B.: If this is "const" but not "static", the Solaris 10
native compiler has trouble building the library because of
absolute relocations needed in read-only section ".rodata".
When it's static, it goes into ".picdata", which is
read-write. */
static const char *const dbpath_names[] = {
};
}
goto clean_n_exit;
}
if (status) {
goto clean_n_exit;
}
/* Fetch the list of directories specified in the config
file(s) first. */
goto clean_n_exit;
ndx = 0;
if (profpath)
ndx++;
goto clean_n_exit;
}
if (ndx)
status = 0;
goto clean_n_exit;
}
goto clean_n_exit;
}
if (vftabl_addrs[0] == NULL) {
/* No plugins! */
gettext("Unable to load requested database module '%s': plugin symbol 'kdb_function_table' not found"),
lib_name);
goto clean_n_exit;
}
/* ERROR. library not initialized cleanly */
goto clean_n_exit;
}
/* Both of these DTRT with NULL. */
if (status) {
if (*lib) {
}
}
}
return status;
}
#endif /* end of _KDB5_STATIC_LINK */
static krb5_error_code
{
/* lock here so that no two threads try to do the same at the same time */
int locked = 0;
if ((status = kdb_lock_list()) != 0) {
goto clean_n_exit;
}
locked = 1;
goto clean_n_exit;
}
}
/* module not found. create and add to list */
if (status) {
goto clean_n_exit;
}
if (prev_elt) {
/* prev_elt points to the last element in the list */
} else {
}
if (*lib) {
(*lib)->reference_cnt++;
}
if (locked) {
(void)kdb_unlock_list();
}
return status;
}
static krb5_error_code
{
int locked = 0;
if ((status = kdb_lock_list()) != 0) {
goto clean_n_exit;
}
locked = 1;
lib->reference_cnt--;
if (lib->reference_cnt == 0) {
if (status) {
goto clean_n_exit;
}
/* close the library */
}
/* first element in the list */
} else {
}
}
}
if (locked) {
(void)kdb_unlock_list();
}
return status;
}
static krb5_error_code
{
if (dal_handle == NULL) {
goto clean_n_exit;
}
goto clean_n_exit;
}
if (status) {
goto clean_n_exit;
}
if (status) {
if (lib) {
(void)kdb_free_library(lib);
}
}
return status;
}
static krb5_error_code
{
status =
if (status) {
goto clean_n_exit;
}
return status;
}
static void
{
const char *e;
if (err_code == 0)
return;
/* Must be called with dal_handle->lib_handle locked! */
return;
}
/*
* External functions... DAL API
*/
{
gettext("unable to determine configuration section for realm %s\n"),
goto clean_n_exit;
}
if (status) {
goto clean_n_exit;
}
}
if (status) {
/* Solaris Kerberos */
goto clean_n_exit;
}
status =
mode);
/* Solaris Kerberos */
if (status)
if (section)
return status;
}
{
}
{
gettext("unable to determine configuration section for realm %s\n"),
goto clean_n_exit;
}
if (status) {
goto clean_n_exit;
}
}
if (status) {
goto clean_n_exit;
}
status =
if (section)
return status;
}
{
/* module not loaded. So nothing to be done */
goto clean_n_exit;
}
if (status) {
goto clean_n_exit;
}
if (status) {
goto clean_n_exit;
}
return status;
}
{
gettext("unable to determine configuration section for realm %s\n"),
goto clean_n_exit;
}
if (status) {
goto clean_n_exit;
}
}
if (status) {
goto clean_n_exit;
}
status =
if (section)
return status;
}
{
if (status) {
goto clean_n_exit;
}
}
if (status) {
goto clean_n_exit;
}
return status;
}
{
if (status) {
goto clean_n_exit;
}
}
if (status) {
goto clean_n_exit;
}
status =
return status;
}
{
if (status) {
goto clean_n_exit;
}
}
/* acquire an exclusive lock, ensures no other thread uses this context */
if (status) {
goto clean_n_exit;
}
/* exclusive lock is still held, so no other thread could use this context */
return status;
}
{
if (status) {
goto clean_n_exit;
}
}
/* normal lock acquired and exclusive lock released */
if (status) {
goto clean_n_exit;
}
return status;
}
{
if (status) {
goto clean_n_exit;
}
}
if (status) {
goto clean_n_exit;
}
status =
more);
return status;
}
{
if (status) {
goto clean_n_exit;
}
}
if (status) {
goto clean_n_exit;
}
status =
more);
return status;
}
{
if (status) {
goto clean_n_exit;
}
}
if (status) {
goto clean_n_exit;
}
status =
count);
return status;
}
{
int db_args_size = 0;
if (status) {
goto clean_n_exit;
}
}
/* Giving db_args as part of tl data causes, db2 to store the
tl_data as such. To prevent this, tl_data is collated and
passed as a sepearte argument. Currently supports only one
principal. but passing it as a seperate argument makes it
difficult for kadmin remote to pass arguments to server. */
while (curr) {
char **t;
/* Since this is expected to be NULL terminated string and
this could come from any client, do a check before
passing it to db. */
'\0') {
/* not null terminated. Dangerous input */
goto clean_n_exit;
}
db_args_size++;
if (t == NULL) {
goto clean_n_exit;
}
db_args = t;
/* current node is the first in the linked list. remove it */
} else {
}
/* previous does not change */
} else {
}
}
if (status) {
goto clean_n_exit;
}
db_args);
while (db_args_size) {
db_args_size--;
}
if (db_args)
return status;
}
{
if (status) {
goto clean_n_exit;
}
}
if (status) {
goto clean_n_exit;
}
status =
nentries);
return status;
}
char *match_entry,
/* Solaris Kerberos: adding support for db_args */
char **db_args)
{
if (status) {
goto clean_n_exit;
}
}
if (status) {
goto clean_n_exit;
}
/* Solaris Kerberos: adding support for db_args */
db_args);
return status;
}
{
if (status) {
goto clean_n_exit;
}
}
if (status) {
goto clean_n_exit;
}
status =
return status;
}
{
if (status) {
goto clean_n_exit;
}
}
if (status) {
goto clean_n_exit;
}
status =
realms);
return status;
}
{
if (status) {
goto clean_n_exit;
}
}
if (status) {
goto clean_n_exit;
}
return status;
}
{
}
{
if (status) {
goto clean_n_exit;
}
}
if (status) {
goto clean_n_exit;
}
/* Lets use temp key and copy it later to avoid memory problems
when freed by the caller. */
return status;
}
char *db_arg,
{
if (status) {
goto clean_n_exit;
}
}
if (status) {
goto clean_n_exit;
}
key, master_pwd);
return status;
}
{
int kvno;
if (fromkeyboard) {
twice ? krb5_mkey_pwd_prompt2 : 0,
goto clean_n_exit;
}
if (!salt) {
if (retval)
goto clean_n_exit;
}
retval =
key);
if (!salt)
} else {
if (retval) {
goto clean_n_exit;
}
}
if (retval) {
goto clean_n_exit;
}
#if 0 /************** Begin IFDEF'ed OUT *******************************/
/* Orig MIT */
#else
/* Solaris Kerberos: need to use etype */
#endif /**************** END IFDEF'ed OUT *******************************/
&tmp_key,
&kvno,
db_args);
if (retval) {
goto clean_n_exit;
}
goto clean_n_exit;
}
}
}
return retval;
}
{
if (status) {
goto clean_n_exit;
}
}
if (status) {
goto clean_n_exit;
}
return status;
}
void *
{
if (status) {
goto clean_n_exit;
}
}
return new_ptr;
}
void
{
if (status) {
goto clean_n_exit;
}
}
return;
}
/* has to be modified */
{
}
krb5_int32 * start,
{
if (status) {
goto clean_n_exit;
}
}
if (status) {
goto clean_n_exit;
}
return status;
}
const char *keyname,
const char *realm,
{
char *fname;
if (!keyname)
if (!fname)
return ENOMEM;
return retval;
if (fullname)
else
return 0;
}
{
return (code);
*stamp = 0;
return (0);
}
return (0);
}
/*ARGSUSED*/
{
*ret_tl_data = *tl_data;
return (0);
}
}
/* if the requested record isn't found, return zero bytes.
* if it ever means something to have a zero-length tl_data,
* this code and its callers will have to be changed */
ret_tl_data->tl_data_length = 0;
return (0);
}
{
(sizeof(krb5_key_data) *
return (ENOMEM);
entry->n_key_data++;
return 0;
}
{
char *unparse_mod_princ = 0;
unsigned int unparse_mod_princ_size;
return (retval);
== NULL) {
return (ENOMEM);
}
/* Mod Date */
/* Mod Princ */
return (retval);
}
{
return (code);
return (KRB5_KDB_TRUNCATED_RECORD);
/* Mod Date */
/* Mod Princ */
mod_princ)))
return (code);
return (0);
}
{
}
{
/* copy the new data first, so we can fail cleanly if malloc()
* fails */
if ((tmp =
return (ENOMEM);
/* Find an existing entry of the specified type and point at
* it, or NULL if not found */
break;
}
/* if necessary, chain a new record in the beginning and point at it */
if (!tl_data) {
if ((tl_data =
sizeof(krb5_tl_data)))
== NULL) {
return (ENOMEM);
}
}
/* fill in the record */
if (tl_data->tl_data_contents)
return (0);
}
/* change password functions */
int ks_tuple_count,
char *passwd,
{
if (status) {
goto clean_n_exit;
}
}
if (status) {
goto clean_n_exit;
}
return status;
}
/* policy management functions */
{
if (status) {
goto clean_n_exit;
}
}
if (status) {
goto clean_n_exit;
}
return status;
}
{
if (status) {
goto clean_n_exit;
}
}
if (status) {
goto clean_n_exit;
}
status =
cnt);
return status;
}
{
if (status) {
goto clean_n_exit;
}
}
if (status) {
goto clean_n_exit;
}
return status;
}
{
if (status) {
goto clean_n_exit;
}
}
if (status) {
goto clean_n_exit;
}
status =
return status;
}
{
if (status) {
goto clean_n_exit;
}
}
if (status) {
goto clean_n_exit;
}
return status;
}
void
{
if (status) {
goto clean_n_exit;
}
}
if (status) {
goto clean_n_exit;
}
return;
}
{
gettext("unable to determine configuration section for realm %s\n"),
goto clean_n_exit;
}
if (status) {
goto clean_n_exit;
}
}
if (status) {
goto clean_n_exit;
}
status =
if (section)
return status;
}
/*
* Solaris Kerberos: support for iprop
*
* Not all KDB plugins support iprop.
*
* sets iprop_supported to 1 if iprop supportd, 0 otherwise.
*/
{
if (status) {
goto clean_n_exit;
}
}
if (status) {
goto clean_n_exit;
}
return status;
}