2005-06-03 18:32:10 +04:00
/*
* Copyright ( c ) 1999 - 2001 , 2003 , PADL Software Pty Ltd .
2009-05-26 06:31:39 +04:00
* Copyright ( c ) 2004 - 2009 , Andrew Bartlett < abartlet @ samba . org > .
2005-06-03 18:32:10 +04:00
* Copyright ( c ) 2004 , Stefan Metzmacher < metze @ samba . org >
* All rights reserved .
*
* Redistribution and use in source and binary forms , with or without
* modification , are permitted provided that the following conditions
* are met :
*
* 1. Redistributions of source code must retain the above copyright
* notice , this list of conditions and the following disclaimer .
*
* 2. Redistributions in binary form must reproduce the above copyright
* notice , this list of conditions and the following disclaimer in the
* documentation and / or other materials provided with the distribution .
*
* 3. Neither the name of PADL Software nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission .
*
* THIS SOFTWARE IS PROVIDED BY PADL SOFTWARE AND CONTRIBUTORS ` ` AS IS ' ' AND
* ANY EXPRESS OR IMPLIED WARRANTIES , INCLUDING , BUT NOT LIMITED TO , THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED . IN NO EVENT SHALL PADL SOFTWARE OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT , INDIRECT , INCIDENTAL , SPECIAL , EXEMPLARY , OR CONSEQUENTIAL
* DAMAGES ( INCLUDING , BUT NOT LIMITED TO , PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES ; LOSS OF USE , DATA , OR PROFITS ; OR BUSINESS INTERRUPTION )
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY , WHETHER IN CONTRACT , STRICT
* LIABILITY , OR TORT ( INCLUDING NEGLIGENCE OR OTHERWISE ) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE , EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE .
*/
# include "includes.h"
2010-11-11 06:09:41 +03:00
# include "kdc/kdc-glue.h"
2010-01-28 09:27:11 +03:00
# include "kdc/db-glue.h"
2013-11-06 01:39:42 +04:00
# include "auth/auth_sam.h"
# include <ldb.h>
2014-05-08 19:13:04 +04:00
# include "sdb.h"
# include "sdb_hdb.h"
2008-08-08 04:35:57 +04:00
2009-07-16 06:47:57 +04:00
static krb5_error_code hdb_samba4_open ( krb5_context context , HDB * db , int flags , mode_t mode )
2005-06-03 18:32:10 +04:00
{
if ( db - > hdb_master_key_set ) {
2009-06-08 13:06:16 +04:00
krb5_error_code ret = HDB_ERR_NOENTRY ;
2009-07-16 06:47:57 +04:00
krb5_warnx ( context , " hdb_samba4_open: use of a master key incompatible with LDB \n " ) ;
krb5_set_error_message ( context , ret , " hdb_samba4_open: use of a master key incompatible with LDB \n " ) ;
2009-06-08 13:06:16 +04:00
return ret ;
2009-12-23 23:08:02 +03:00
}
2005-06-03 18:32:10 +04:00
return 0 ;
}
2009-07-16 06:47:57 +04:00
static krb5_error_code hdb_samba4_close ( krb5_context context , HDB * db )
2005-06-03 18:32:10 +04:00
{
return 0 ;
}
2009-07-16 06:47:57 +04:00
static krb5_error_code hdb_samba4_lock ( krb5_context context , HDB * db , int operation )
2005-06-03 18:32:10 +04:00
{
return 0 ;
}
2009-07-16 06:47:57 +04:00
static krb5_error_code hdb_samba4_unlock ( krb5_context context , HDB * db )
2005-06-03 18:32:10 +04:00
{
return 0 ;
}
2009-07-16 06:47:57 +04:00
static krb5_error_code hdb_samba4_rename ( krb5_context context , HDB * db , const char * new_name )
2005-06-03 18:32:10 +04:00
{
return HDB_ERR_DB_INUSE ;
}
2009-07-16 06:47:57 +04:00
static krb5_error_code hdb_samba4_store ( krb5_context context , HDB * db , unsigned flags , hdb_entry_ex * entry )
2005-06-03 18:32:10 +04:00
{
return HDB_ERR_DB_INUSE ;
}
2009-07-16 06:47:57 +04:00
static krb5_error_code hdb_samba4_remove ( krb5_context context , HDB * db , krb5_const_principal principal )
2005-06-03 18:32:10 +04:00
{
return HDB_ERR_DB_INUSE ;
}
2010-10-02 10:55:06 +04:00
static krb5_error_code hdb_samba4_fetch_kvno ( krb5_context context , HDB * db ,
krb5_const_principal principal ,
unsigned flags ,
2010-12-04 01:06:53 +03:00
krb5_kvno kvno ,
2010-10-02 10:55:06 +04:00
hdb_entry_ex * entry_ex )
{
struct samba_kdc_db_context * kdc_db_ctx ;
2014-05-08 19:13:04 +04:00
struct sdb_entry_ex sdb_entry_ex = { } ;
krb5_error_code code , ret ;
2010-10-02 10:55:06 +04:00
kdc_db_ctx = talloc_get_type_abort ( db - > hdb_db ,
struct samba_kdc_db_context ) ;
2014-05-08 19:13:04 +04:00
code = samba_kdc_fetch ( context ,
kdc_db_ctx ,
principal ,
flags ,
kvno ,
& sdb_entry_ex ) ;
/*
* If SDB_ERR_WRONG_REALM is returned we need to process the sdb_entry
* to fill the principal in the HDB entry .
*/
if ( code ! = 0 & & code ! = SDB_ERR_WRONG_REALM ) {
return code ;
}
ret = sdb_entry_ex_to_hdb_entry_ex ( context , & sdb_entry_ex , entry_ex ) ;
sdb_free_entry ( & sdb_entry_ex ) ;
if ( code = = 0 & & ret ! = 0 ) {
code = ret ;
}
return code ;
2010-10-02 10:55:06 +04:00
}
2009-07-16 06:47:57 +04:00
static krb5_error_code hdb_samba4_firstkey ( krb5_context context , HDB * db , unsigned flags ,
2005-12-15 23:38:24 +03:00
hdb_entry_ex * entry )
2005-06-03 18:32:10 +04:00
{
2010-01-28 09:27:11 +03:00
struct samba_kdc_db_context * kdc_db_ctx ;
2014-05-08 19:13:04 +04:00
struct sdb_entry_ex sdb_entry_ex = { } ;
krb5_error_code ret ;
2005-06-03 18:32:10 +04:00
2010-01-28 09:27:11 +03:00
kdc_db_ctx = talloc_get_type_abort ( db - > hdb_db ,
struct samba_kdc_db_context ) ;
2007-06-14 16:19:53 +04:00
2014-05-08 19:13:04 +04:00
ret = samba_kdc_firstkey ( context , kdc_db_ctx , & sdb_entry_ex ) ;
if ( ret ) {
return ret ;
}
ret = sdb_entry_ex_to_hdb_entry_ex ( context , & sdb_entry_ex , entry ) ;
sdb_free_entry ( & sdb_entry_ex ) ;
return ret ;
2005-06-03 18:32:10 +04:00
}
2009-07-16 06:47:57 +04:00
static krb5_error_code hdb_samba4_nextkey ( krb5_context context , HDB * db , unsigned flags ,
2005-12-15 23:38:24 +03:00
hdb_entry_ex * entry )
2005-06-03 18:32:10 +04:00
{
2010-01-28 09:27:11 +03:00
struct samba_kdc_db_context * kdc_db_ctx ;
2014-05-08 19:13:04 +04:00
struct sdb_entry_ex sdb_entry_ex = { } ;
krb5_error_code ret ;
2010-01-28 09:27:11 +03:00
kdc_db_ctx = talloc_get_type_abort ( db - > hdb_db ,
struct samba_kdc_db_context ) ;
2014-05-08 19:13:04 +04:00
ret = samba_kdc_nextkey ( context , kdc_db_ctx , & sdb_entry_ex ) ;
if ( ret ) {
return ret ;
}
ret = sdb_entry_ex_to_hdb_entry_ex ( context , & sdb_entry_ex , entry ) ;
sdb_free_entry ( & sdb_entry_ex ) ;
return ret ;
2005-06-03 18:32:10 +04:00
}
2009-07-16 06:47:57 +04:00
static krb5_error_code hdb_samba4_destroy ( krb5_context context , HDB * db )
2005-06-03 18:32:10 +04:00
{
talloc_free ( db ) ;
return 0 ;
}
2010-01-21 17:57:41 +03:00
static krb5_error_code
2011-04-07 13:16:55 +04:00
hdb_samba4_check_constrained_delegation ( krb5_context context , HDB * db ,
2010-01-21 17:57:41 +03:00
hdb_entry_ex * entry ,
krb5_const_principal target_principal )
2009-07-18 04:15:55 +04:00
{
2010-01-28 09:27:11 +03:00
struct samba_kdc_db_context * kdc_db_ctx ;
2014-05-09 16:58:08 +04:00
struct samba_kdc_entry * skdc_entry ;
2009-07-18 04:15:55 +04:00
2010-01-28 09:27:11 +03:00
kdc_db_ctx = talloc_get_type_abort ( db - > hdb_db ,
struct samba_kdc_db_context ) ;
2014-05-09 16:58:08 +04:00
skdc_entry = talloc_get_type_abort ( entry - > ctx ,
struct samba_kdc_entry ) ;
2009-07-18 04:15:55 +04:00
2011-04-07 13:16:55 +04:00
return samba_kdc_check_s4u2proxy ( context , kdc_db_ctx ,
2014-05-09 16:58:08 +04:00
skdc_entry ,
2011-04-07 13:16:55 +04:00
target_principal ) ;
2009-07-18 04:15:55 +04:00
}
2010-01-21 17:57:41 +03:00
static krb5_error_code
hdb_samba4_check_pkinit_ms_upn_match ( krb5_context context , HDB * db ,
hdb_entry_ex * entry ,
krb5_const_principal certificate_principal )
2009-07-28 08:05:19 +04:00
{
2010-01-28 09:27:11 +03:00
struct samba_kdc_db_context * kdc_db_ctx ;
2014-05-09 16:56:22 +04:00
struct samba_kdc_entry * skdc_entry ;
2009-07-28 08:05:19 +04:00
2010-01-28 09:27:11 +03:00
kdc_db_ctx = talloc_get_type_abort ( db - > hdb_db ,
struct samba_kdc_db_context ) ;
2014-05-09 16:56:22 +04:00
skdc_entry = talloc_get_type_abort ( entry - > ctx ,
struct samba_kdc_entry ) ;
2009-07-28 08:05:19 +04:00
2010-01-28 09:27:11 +03:00
return samba_kdc_check_pkinit_ms_upn_match ( context , kdc_db_ctx ,
2014-05-09 16:56:22 +04:00
skdc_entry ,
2010-01-28 09:27:11 +03:00
certificate_principal ) ;
2009-07-28 08:05:19 +04:00
}
2011-04-07 13:16:55 +04:00
static krb5_error_code
hdb_samba4_check_s4u2self ( krb5_context context , HDB * db ,
hdb_entry_ex * entry ,
krb5_const_principal target_principal )
{
struct samba_kdc_db_context * kdc_db_ctx ;
2014-05-09 16:54:23 +04:00
struct samba_kdc_entry * skdc_entry ;
2011-04-07 13:16:55 +04:00
kdc_db_ctx = talloc_get_type_abort ( db - > hdb_db ,
struct samba_kdc_db_context ) ;
2014-05-09 16:54:23 +04:00
skdc_entry = talloc_get_type_abort ( entry - > ctx ,
struct samba_kdc_entry ) ;
2011-04-07 13:16:55 +04:00
return samba_kdc_check_s4u2self ( context , kdc_db_ctx ,
2014-05-09 16:54:23 +04:00
skdc_entry ,
target_principal ) ;
2011-04-07 13:16:55 +04:00
}
2013-11-06 01:39:42 +04:00
static krb5_error_code hdb_samba4_auth_status ( krb5_context context , HDB * db ,
hdb_entry_ex * entry ,
int hdb_auth_status )
{
struct samba_kdc_db_context * kdc_db_ctx = talloc_get_type_abort ( db - > hdb_db ,
struct samba_kdc_db_context ) ;
struct samba_kdc_entry * p = talloc_get_type ( entry - > ctx , struct samba_kdc_entry ) ;
if ( hdb_auth_status = = HDB_AUTH_WRONG_PASSWORD ) {
authsam_update_bad_pwd_count ( kdc_db_ctx - > samdb , p - > msg , ldb_get_default_basedn ( kdc_db_ctx - > samdb ) ) ;
2013-11-26 06:32:18 +04:00
} else if ( hdb_auth_status = = HDB_AUTH_SUCCESS ) {
authsam_zero_bad_pwd_count ( kdc_db_ctx - > samdb , p - > msg ) ;
2013-11-06 01:39:42 +04:00
}
return 0 ;
}
2010-01-28 09:27:11 +03:00
/* This interface is to be called by the KDC and libnet_keytab_dump,
* which is expecting Samba calling conventions .
* It is also called by a wrapper ( hdb_samba4_create ) from the
* kpasswdd - > krb5 - > keytab_hdb - > hdb code */
2006-01-24 08:31:08 +03:00
2010-01-28 08:08:36 +03:00
NTSTATUS hdb_samba4_create_kdc ( struct samba_kdc_base_context * base_ctx ,
krb5_context context , struct HDB * * db )
2005-06-03 18:32:10 +04:00
{
2010-01-28 08:08:36 +03:00
struct samba_kdc_db_context * kdc_db_ctx ;
2009-11-09 13:38:49 +03:00
NTSTATUS nt_status ;
2014-01-14 02:23:04 +04:00
if ( hdb_interface_version ! = HDB_INTERFACE_VERSION ) {
krb5_set_error_message ( context , EINVAL , " Heimdal HDB interface version mismatch between build-time and run-time libraries! " ) ;
return NT_STATUS_ERROR_DS_INCOMPATIBLE_VERSION ;
}
2010-01-28 08:08:36 +03:00
* db = talloc ( base_ctx , HDB ) ;
2005-06-03 18:32:10 +04:00
if ( ! * db ) {
2009-06-08 13:06:16 +04:00
krb5_set_error_message ( context , ENOMEM , " malloc: out of memory " ) ;
2005-12-11 11:31:46 +03:00
return NT_STATUS_NO_MEMORY ;
2005-06-03 18:32:10 +04:00
}
( * db ) - > hdb_master_key_set = 0 ;
( * db ) - > hdb_db = NULL ;
2014-12-17 07:02:53 +03:00
( * db ) - > hdb_capability_flags = HDB_CAP_F_HANDLE_ENTERPRISE_PRINCIPAL ;
2005-06-05 17:11:42 +04:00
2010-09-28 07:05:37 +04:00
nt_status = samba_kdc_setup_db_ctx ( * db , base_ctx , & kdc_db_ctx ) ;
2009-11-09 13:38:49 +03:00
if ( ! NT_STATUS_IS_OK ( nt_status ) ) {
2010-09-28 07:05:37 +04:00
talloc_free ( * db ) ;
return nt_status ;
2009-11-09 13:38:49 +03:00
}
2010-01-28 08:08:36 +03:00
( * db ) - > hdb_db = kdc_db_ctx ;
2007-06-15 04:14:11 +04:00
( * db ) - > hdb_dbc = NULL ;
2009-07-16 06:47:57 +04:00
( * db ) - > hdb_open = hdb_samba4_open ;
( * db ) - > hdb_close = hdb_samba4_close ;
2010-10-02 10:55:06 +04:00
( * db ) - > hdb_fetch_kvno = hdb_samba4_fetch_kvno ;
2009-07-16 06:47:57 +04:00
( * db ) - > hdb_store = hdb_samba4_store ;
( * db ) - > hdb_remove = hdb_samba4_remove ;
( * db ) - > hdb_firstkey = hdb_samba4_firstkey ;
( * db ) - > hdb_nextkey = hdb_samba4_nextkey ;
( * db ) - > hdb_lock = hdb_samba4_lock ;
( * db ) - > hdb_unlock = hdb_samba4_unlock ;
( * db ) - > hdb_rename = hdb_samba4_rename ;
2005-06-03 18:32:10 +04:00
/* we don't implement these, as we are not a lockable database */
( * db ) - > hdb__get = NULL ;
( * db ) - > hdb__put = NULL ;
/* kadmin should not be used for deletes - use other tools instead */
( * db ) - > hdb__del = NULL ;
2009-07-16 06:47:57 +04:00
( * db ) - > hdb_destroy = hdb_samba4_destroy ;
2005-06-03 18:32:10 +04:00
2013-11-06 01:39:42 +04:00
( * db ) - > hdb_auth_status = hdb_samba4_auth_status ;
2011-04-07 13:16:55 +04:00
( * db ) - > hdb_check_constrained_delegation = hdb_samba4_check_constrained_delegation ;
2009-07-28 08:05:19 +04:00
( * db ) - > hdb_check_pkinit_ms_upn_match = hdb_samba4_check_pkinit_ms_upn_match ;
2011-04-07 13:16:55 +04:00
( * db ) - > hdb_check_s4u2self = hdb_samba4_check_s4u2self ;
2009-07-07 06:34:55 +04:00
2005-12-11 11:31:46 +03:00
return NT_STATUS_OK ;
2005-06-03 18:32:10 +04:00
}