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"
2005-12-11 11:31:46 +03:00
# include "auth/auth.h"
2006-11-07 03:48:36 +03:00
# include "auth/credentials/credentials.h"
2005-12-28 18:38:36 +03:00
# include "dsdb/samdb/samdb.h"
2007-09-08 16:42:09 +04:00
# include "param/param.h"
2008-06-04 17:39:17 +04:00
# include "kdc/kdc.h"
2010-01-28 09:27:11 +03:00
# include "kdc/db-glue.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-01-28 09:27:11 +03:00
static krb5_error_code hdb_samba4_fetch ( krb5_context context , HDB * db ,
krb5_const_principal principal ,
unsigned flags ,
hdb_entry_ex * entry_ex )
2005-06-03 18:32:10 +04:00
{
2010-01-28 09:27:11 +03:00
struct samba_kdc_db_context * kdc_db_ctx ;
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 ) ;
2005-06-03 18:32:10 +04:00
2010-01-28 09:27:11 +03:00
return samba_kdc_fetch ( context , kdc_db_ctx , principal , flags , entry_ex ) ;
2005-06-03 18:32:10 +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 ;
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
2010-01-28 09:27:11 +03:00
return samba_kdc_firstkey ( context , kdc_db_ctx , entry ) ;
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 ;
kdc_db_ctx = talloc_get_type_abort ( db - > hdb_db ,
struct samba_kdc_db_context ) ;
return samba_kdc_nextkey ( context , kdc_db_ctx , entry ) ;
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
{
2010-01-28 09:27:11 +03:00
struct samba_kdc_db_context * kdc_db_ctx ;
kdc_db_ctx = talloc_get_type_abort ( db - > hdb_db ,
struct samba_kdc_db_context ) ;
if ( kdc_db_ctx ) {
talloc_free ( kdc_db_ctx - > samdb ) ;
kdc_db_ctx - > samdb = NULL ;
}
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
hdb_samba4_check_constrained_delegation ( krb5_context context , HDB * db ,
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 ;
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 ) ;
2009-07-18 04:15:55 +04:00
2010-01-28 09:27:11 +03:00
return samba_kdc_check_constrained_delegation ( context , kdc_db_ctx ,
entry ,
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 ;
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 ) ;
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 ,
entry ,
certificate_principal ) ;
2009-07-28 08:05:19 +04:00
}
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 ;
2005-12-11 11:31:46 +03:00
struct auth_session_info * session_info ;
2009-11-09 13:38:49 +03:00
NTSTATUS nt_status ;
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 ;
2009-06-30 06:11:14 +04:00
( * db ) - > hdb_capability_flags = 0 ;
2005-06-05 17:11:42 +04:00
2009-11-09 13:38:49 +03:00
# if 1
/* we would prefer to use system_session(), as that would
* allow us to share the samdb backend context with other parts of the
* system . For now we can ' t as we need to override the
* credentials to set CRED_DONT_USE_KERBEROS , which would
2009-12-23 23:08:02 +03:00
* break other users of the system_session */
2009-11-09 13:38:49 +03:00
DEBUG ( 0 , ( " FIXME: Using new system session for hdb \n " ) ) ;
2010-01-28 08:08:36 +03:00
nt_status = auth_system_session_info ( * db , base_ctx - > lp_ctx , & session_info ) ;
2009-11-09 13:38:49 +03:00
if ( ! NT_STATUS_IS_OK ( nt_status ) ) {
2010-01-28 08:08:36 +03:00
return nt_status ;
2009-11-09 13:38:49 +03:00
}
# else
2010-01-28 08:08:36 +03:00
session_info = system_session ( kdc_db_ctx - > lp_ctx ) ;
2009-10-25 09:19:03 +03:00
if ( session_info = = NULL ) {
return NT_STATUS_INTERNAL_ERROR ;
2005-12-11 11:31:46 +03:00
}
2009-11-09 13:38:49 +03:00
# endif
2009-12-23 23:08:02 +03:00
2005-12-11 11:31:46 +03:00
/* The idea here is very simple. Using Kerberos to
* authenticate the KDC to the LDAP server is higly likely to
* be circular .
*
* In future we may set this up to use EXERNAL and SSL
2009-11-09 13:38:49 +03:00
* certificates , for now it will almost certainly be NTLMSSP_SET_USERNAME
2005-12-11 11:31:46 +03:00
*/
2009-12-23 23:08:02 +03:00
cli_credentials_set_kerberos_state ( session_info - > credentials ,
2006-01-28 15:19:20 +03:00
CRED_DONT_USE_KERBEROS ) ;
2005-12-11 11:31:46 +03:00
2010-01-28 08:08:36 +03:00
kdc_db_ctx = talloc_zero ( * db , struct samba_kdc_db_context ) ;
if ( kdc_db_ctx = = NULL ) {
return NT_STATUS_NO_MEMORY ;
}
kdc_db_ctx - > ev_ctx = base_ctx - > ev_ctx ;
kdc_db_ctx - > lp_ctx = base_ctx - > lp_ctx ;
2010-01-28 08:19:59 +03:00
kdc_db_ctx - > ic_ctx = lp_iconv_convenience ( base_ctx - > lp_ctx ) ;
2010-01-28 08:08:36 +03:00
2005-06-29 17:55:09 +04:00
/* Setup the link to LDB */
2010-01-28 08:08:36 +03:00
kdc_db_ctx - > samdb = samdb_connect ( kdc_db_ctx , base_ctx - > ev_ctx ,
base_ctx - > lp_ctx , session_info ) ;
if ( kdc_db_ctx - > samdb = = NULL ) {
2009-07-27 07:48:45 +04:00
DEBUG ( 1 , ( " hdb_samba4_create: Cannot open samdb for KDC backend! " ) ) ;
2005-12-11 11:31:46 +03:00
return NT_STATUS_CANT_ACCESS_DOMAIN_INFO ;
2005-06-03 18:32:10 +04: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 ;
( * db ) - > hdb_fetch = hdb_samba4_fetch ;
( * 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
2009-07-07 06:34:55 +04:00
( * db ) - > hdb_auth_status = NULL ;
2009-07-18 04:15: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 ;
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
}
2006-01-24 08:31:08 +03:00
2009-07-27 07:48:45 +04:00
static krb5_error_code hdb_samba4_create ( krb5_context context , struct HDB * * db , const char * arg )
2006-01-24 08:31:08 +03:00
{
NTSTATUS nt_status ;
2009-07-27 10:09:25 +04:00
void * ptr ;
2010-01-28 08:08:36 +03:00
struct samba_kdc_base_context * base_ctx ;
2009-12-23 23:08:02 +03:00
2009-07-27 10:09:25 +04:00
if ( sscanf ( arg , " &%p " , & ptr ) ! = 1 ) {
return EINVAL ;
}
2010-01-28 08:08:36 +03:00
base_ctx = talloc_get_type_abort ( ptr , struct samba_kdc_base_context ) ;
2008-02-21 19:17:37 +03:00
/* The global kdc_mem_ctx and kdc_lp_ctx, Disgusting, ugly hack, but it means one less private hook */
2010-01-28 08:08:36 +03:00
nt_status = hdb_samba4_create_kdc ( base_ctx , context , db ) ;
2006-01-24 08:31:08 +03:00
if ( NT_STATUS_IS_OK ( nt_status ) ) {
return 0 ;
}
return EINVAL ;
}
2009-07-27 07:48:45 +04:00
/* Only used in the hdb-backed keytab code
2009-07-27 10:09:25 +04:00
* for a keytab of ' samba4 & < address > ' , to find
2009-07-27 07:48:45 +04:00
* kpasswd ' s key in the main DB , and to
2009-07-27 10:09:25 +04:00
* copy all the keys into a file ( libnet_keytab_export )
*
* The < address > is the string form of a pointer to a talloced struct hdb_samba_context
*/
2009-07-27 07:48:45 +04:00
struct hdb_method hdb_samba4 = {
. interface_version = HDB_INTERFACE_VERSION ,
2009-12-23 23:08:02 +03:00
. prefix = " samba4 " ,
2009-07-27 07:48:45 +04:00
. create = hdb_samba4_create
} ;