mirror of
https://github.com/samba-team/samba.git
synced 2025-03-30 06:50:24 +03:00
s4-kdc: Use sdb in db-glue and hdb-samba4
Guenther Pair-Programmed-With: Andreas Schneider <asn@samba.org> Signed-off-by: Guenther Deschner <gd@samba.org> Signed-off-by: Andreas Schneider <asn@samba.org> Reviewed-by: Alexander Bokovoy <ab@samba.org> Autobuild-User(master): Andreas Schneider <asn@cryptomilk.org> Autobuild-Date(master): Thu Jul 30 13:29:27 CEST 2015 on sn-devel-104
This commit is contained in:
parent
99d3719e7d
commit
d49b4aafa8
@ -32,7 +32,7 @@
|
||||
#include "../lib/crypto/md4.h"
|
||||
#include "system/kerberos.h"
|
||||
#include "auth/kerberos/kerberos.h"
|
||||
#include <hdb.h>
|
||||
#include "kdc/sdb.h"
|
||||
#include "kdc/samba_kdc.h"
|
||||
#include "kdc/db-glue.h"
|
||||
|
||||
@ -84,9 +84,9 @@ static time_t ldb_msg_find_krb5time_ldap_time(struct ldb_message *msg, const cha
|
||||
return timegm(&tm);
|
||||
}
|
||||
|
||||
static HDBFlags uf2HDBFlags(krb5_context context, uint32_t userAccountControl, enum samba_kdc_ent_type ent_type)
|
||||
static struct SDBFlags uf2SDBFlags(krb5_context context, uint32_t userAccountControl, enum samba_kdc_ent_type ent_type)
|
||||
{
|
||||
HDBFlags flags = int2HDBFlags(0);
|
||||
struct SDBFlags flags = int2SDBFlags(0);
|
||||
|
||||
/* we don't allow kadmin deletes */
|
||||
flags.immutable = 1;
|
||||
@ -189,25 +189,13 @@ static HDBFlags uf2HDBFlags(krb5_context context, uint32_t userAccountControl, e
|
||||
static int samba_kdc_entry_destructor(struct samba_kdc_entry *p)
|
||||
{
|
||||
if (p->entry_ex != NULL) {
|
||||
hdb_entry_ex *entry_ex = p->entry_ex;
|
||||
free_hdb_entry(&entry_ex->entry);
|
||||
struct sdb_entry_ex *entry_ex = p->entry_ex;
|
||||
free_sdb_entry(&entry_ex->entry);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void samba_kdc_free_entry(krb5_context context, hdb_entry_ex *entry_ex)
|
||||
{
|
||||
/* this function is called only from hdb_free_entry().
|
||||
* Make sure we neutralize the destructor or we will
|
||||
* get a double free later when hdb_free_entry() will
|
||||
* try to call free_hdb_entry() */
|
||||
talloc_set_destructor(entry_ex->ctx, NULL);
|
||||
|
||||
/* now proceed to free the talloc part */
|
||||
talloc_free(entry_ex->ctx);
|
||||
}
|
||||
|
||||
static krb5_error_code samba_kdc_message2entry_keys(krb5_context context,
|
||||
struct samba_kdc_db_context *kdc_db_ctx,
|
||||
TALLOC_CTX *mem_ctx,
|
||||
@ -216,7 +204,7 @@ static krb5_error_code samba_kdc_message2entry_keys(krb5_context context,
|
||||
bool is_rodc,
|
||||
uint32_t userAccountControl,
|
||||
enum samba_kdc_ent_type ent_type,
|
||||
hdb_entry_ex *entry_ex)
|
||||
struct sdb_entry_ex *entry_ex)
|
||||
{
|
||||
krb5_error_code ret = 0;
|
||||
enum ndr_err_code ndr_err;
|
||||
@ -377,7 +365,7 @@ static krb5_error_code samba_kdc_message2entry_keys(krb5_context context,
|
||||
if (kdc_db_ctx->rodc) {
|
||||
/* We are on an RODC, but don't have keys for this account. Signal this to the caller */
|
||||
/* TODO: We need to call a generalised version of auth_sam_trigger_repl_secret from here */
|
||||
return HDB_ERR_NOT_FOUND_HERE;
|
||||
return SDB_ERR_NOT_FOUND_HERE;
|
||||
}
|
||||
|
||||
/* oh, no password. Apparently (comment in
|
||||
@ -388,17 +376,14 @@ static krb5_error_code samba_kdc_message2entry_keys(krb5_context context,
|
||||
|
||||
/* allocate space to decode into */
|
||||
entry_ex->entry.keys.len = 0;
|
||||
entry_ex->entry.keys.val = calloc(allocated_keys, sizeof(Key));
|
||||
entry_ex->entry.keys.val = calloc(allocated_keys, sizeof(struct sdb_key));
|
||||
if (entry_ex->entry.keys.val == NULL) {
|
||||
ret = ENOMEM;
|
||||
goto out;
|
||||
}
|
||||
|
||||
if (hash && (supported_enctypes & ENC_RC4_HMAC_MD5)) {
|
||||
Key key;
|
||||
|
||||
key.mkvno = 0;
|
||||
key.salt = NULL; /* No salt for this enc type */
|
||||
struct sdb_key key = {};
|
||||
|
||||
ret = smb_krb5_keyblock_init_contents(context,
|
||||
ENCTYPE_ARCFOUR_HMAC,
|
||||
@ -415,7 +400,7 @@ static krb5_error_code samba_kdc_message2entry_keys(krb5_context context,
|
||||
|
||||
if (pkb4) {
|
||||
for (i=0; i < pkb4->num_keys; i++) {
|
||||
Key key;
|
||||
struct sdb_key key = {};
|
||||
|
||||
if (!pkb4->keys[i].value) continue;
|
||||
|
||||
@ -423,9 +408,6 @@ static krb5_error_code samba_kdc_message2entry_keys(krb5_context context,
|
||||
continue;
|
||||
}
|
||||
|
||||
key.mkvno = 0;
|
||||
key.salt = NULL;
|
||||
|
||||
if (pkb4->salt.string) {
|
||||
DATA_BLOB salt;
|
||||
|
||||
@ -464,7 +446,7 @@ static krb5_error_code samba_kdc_message2entry_keys(krb5_context context,
|
||||
}
|
||||
if (ret) {
|
||||
if (key.salt) {
|
||||
free_Salt(key.salt);
|
||||
kerberos_free_data_contents(context, &key.salt->salt);
|
||||
free(key.salt);
|
||||
key.salt = NULL;
|
||||
}
|
||||
@ -476,7 +458,7 @@ static krb5_error_code samba_kdc_message2entry_keys(krb5_context context,
|
||||
}
|
||||
} else if (pkb3) {
|
||||
for (i=0; i < pkb3->num_keys; i++) {
|
||||
Key key;
|
||||
struct sdb_key key = {};
|
||||
|
||||
if (!pkb3->keys[i].value) continue;
|
||||
|
||||
@ -484,9 +466,6 @@ static krb5_error_code samba_kdc_message2entry_keys(krb5_context context,
|
||||
continue;
|
||||
}
|
||||
|
||||
key.mkvno = 0;
|
||||
key.salt = NULL;
|
||||
|
||||
if (pkb3->salt.string) {
|
||||
DATA_BLOB salt;
|
||||
|
||||
@ -517,7 +496,7 @@ static krb5_error_code samba_kdc_message2entry_keys(krb5_context context,
|
||||
&key.key);
|
||||
if (ret) {
|
||||
if (key.salt) {
|
||||
free_Salt(key.salt);
|
||||
kerberos_free_data_contents(context, &key.salt->salt);
|
||||
free(key.salt);
|
||||
key.salt = NULL;
|
||||
}
|
||||
@ -605,7 +584,7 @@ static krb5_error_code samba_kdc_message2entry(krb5_context context,
|
||||
unsigned flags,
|
||||
struct ldb_dn *realm_dn,
|
||||
struct ldb_message *msg,
|
||||
hdb_entry_ex *entry_ex)
|
||||
struct sdb_entry_ex *entry_ex)
|
||||
{
|
||||
struct loadparm_context *lp_ctx = kdc_db_ctx->lp_ctx;
|
||||
uint32_t userAccountControl;
|
||||
@ -651,7 +630,6 @@ static krb5_error_code samba_kdc_message2entry(krb5_context context,
|
||||
}
|
||||
|
||||
p->kdc_db_ctx = kdc_db_ctx;
|
||||
p->entry_ex = entry_ex;
|
||||
p->realm_dn = talloc_reference(p, realm_dn);
|
||||
if (!p->realm_dn) {
|
||||
ret = ENOMEM;
|
||||
@ -660,11 +638,7 @@ static krb5_error_code samba_kdc_message2entry(krb5_context context,
|
||||
|
||||
talloc_set_destructor(p, samba_kdc_entry_destructor);
|
||||
|
||||
/* make sure we do not have bogus data in there */
|
||||
memset(&entry_ex->entry, 0, sizeof(hdb_entry));
|
||||
|
||||
entry_ex->ctx = p;
|
||||
entry_ex->free_entry = samba_kdc_free_entry;
|
||||
|
||||
userAccountControl = ldb_msg_find_attr_as_uint(msg, "userAccountControl", 0);
|
||||
|
||||
@ -701,7 +675,7 @@ static krb5_error_code samba_kdc_message2entry(krb5_context context,
|
||||
*/
|
||||
|
||||
if (ent_type == SAMBA_KDC_ENT_TYPE_KRBTGT) {
|
||||
if (flags & (HDB_F_CANON)) {
|
||||
if (flags & (SDB_F_CANON)) {
|
||||
/*
|
||||
* When requested to do so, ensure that the
|
||||
* both realm values in the principal are set
|
||||
@ -738,9 +712,9 @@ static krb5_error_code samba_kdc_message2entry(krb5_context context,
|
||||
krb5_clear_error_message(context);
|
||||
goto out;
|
||||
}
|
||||
} else if (flags & HDB_F_CANON && flags & HDB_F_FOR_AS_REQ) {
|
||||
} else if (flags & SDB_F_CANON && flags & SDB_F_FOR_AS_REQ) {
|
||||
/*
|
||||
* HDB_F_CANON maps from the canonicalize flag in the
|
||||
* SDB_F_CANON maps from the canonicalize flag in the
|
||||
* packet, and has a different meaning between AS-REQ
|
||||
* and TGS-REQ. We only change the principal in the AS-REQ case
|
||||
*/
|
||||
@ -773,7 +747,7 @@ static krb5_error_code samba_kdc_message2entry(krb5_context context,
|
||||
}
|
||||
|
||||
/* First try and figure out the flags based on the userAccountControl */
|
||||
entry_ex->entry.flags = uf2HDBFlags(context, userAccountControl, ent_type);
|
||||
entry_ex->entry.flags = uf2SDBFlags(context, userAccountControl, ent_type);
|
||||
|
||||
/* Windows 2008 seems to enforce this (very sensible) rule by
|
||||
* default - don't allow offline attacks on a user's password
|
||||
@ -794,11 +768,11 @@ static krb5_error_code samba_kdc_message2entry(krb5_context context,
|
||||
* KRB5KDC_ERR_S_PRINCIPAL_UNKNOWN
|
||||
*/
|
||||
if (ent_type == SAMBA_KDC_ENT_TYPE_SERVER && entry_ex->entry.flags.server == 0) {
|
||||
ret = HDB_ERR_NOENTRY;
|
||||
ret = SDB_ERR_NOENTRY;
|
||||
krb5_set_error_message(context, ret, "samba_kdc_message2entry: no servicePrincipalName present for this server, refusing with no-such-entry");
|
||||
goto out;
|
||||
}
|
||||
if (flags & HDB_F_ADMIN_DATA) {
|
||||
if (flags & SDB_F_ADMIN_DATA) {
|
||||
/* These (created_by, modified_by) parts of the entry are not relevant for Samba4's use
|
||||
* of the Heimdal KDC. They are stored in a the traditional
|
||||
* DB for audit purposes, and still form part of the structure
|
||||
@ -816,7 +790,7 @@ static krb5_error_code samba_kdc_message2entry(krb5_context context,
|
||||
goto out;
|
||||
}
|
||||
|
||||
entry_ex->entry.modified_by = (Event *) malloc(sizeof(Event));
|
||||
entry_ex->entry.modified_by = (struct sdb_event *) malloc(sizeof(struct sdb_event));
|
||||
if (entry_ex->entry.modified_by == NULL) {
|
||||
ret = ENOMEM;
|
||||
krb5_set_error_message(context, ret, "malloc: out of memory");
|
||||
@ -989,7 +963,7 @@ static krb5_error_code samba_kdc_message2entry(krb5_context context,
|
||||
out:
|
||||
if (ret != 0) {
|
||||
/* This doesn't free ent itself, that is for the eventual caller to do */
|
||||
hdb_free_entry(context, entry_ex);
|
||||
sdb_free_entry(entry_ex);
|
||||
ZERO_STRUCTP(entry_ex);
|
||||
} else {
|
||||
talloc_steal(kdc_db_ctx, entry_ex->ctx);
|
||||
@ -1010,7 +984,7 @@ static krb5_error_code samba_kdc_trust_message2entry(krb5_context context,
|
||||
unsigned flags,
|
||||
uint32_t kvno,
|
||||
struct ldb_message *msg,
|
||||
hdb_entry_ex *entry_ex)
|
||||
struct sdb_entry_ex *entry_ex)
|
||||
{
|
||||
struct loadparm_context *lp_ctx = kdc_db_ctx->lp_ctx;
|
||||
const char *our_realm = lpcfg_realm(lp_ctx);
|
||||
@ -1048,14 +1022,14 @@ static krb5_error_code samba_kdc_trust_message2entry(krb5_context context,
|
||||
trust_direction_flags = ldb_msg_find_attr_as_int(msg, "trustDirection", 0);
|
||||
if (!(trust_direction_flags & direction)) {
|
||||
krb5_clear_error_message(context);
|
||||
ret = HDB_ERR_NOENTRY;
|
||||
ret = SDB_ERR_NOENTRY;
|
||||
goto out;
|
||||
}
|
||||
|
||||
dnsdomain = ldb_msg_find_attr_as_string(msg, "trustPartner", NULL);
|
||||
if (dnsdomain == NULL) {
|
||||
krb5_clear_error_message(context);
|
||||
ret = HDB_ERR_NOENTRY;
|
||||
ret = SDB_ERR_NOENTRY;
|
||||
goto out;
|
||||
}
|
||||
partner_realm = strupper_talloc(mem_ctx, dnsdomain);
|
||||
@ -1079,7 +1053,7 @@ static krb5_error_code samba_kdc_trust_message2entry(krb5_context context,
|
||||
|
||||
if (password_val == NULL) {
|
||||
krb5_clear_error_message(context);
|
||||
ret = HDB_ERR_NOENTRY;
|
||||
ret = SDB_ERR_NOENTRY;
|
||||
goto out;
|
||||
}
|
||||
|
||||
@ -1098,16 +1072,14 @@ static krb5_error_code samba_kdc_trust_message2entry(krb5_context context,
|
||||
}
|
||||
|
||||
p->kdc_db_ctx = kdc_db_ctx;
|
||||
p->entry_ex = entry_ex;
|
||||
p->realm_dn = realm_dn;
|
||||
|
||||
talloc_set_destructor(p, samba_kdc_entry_destructor);
|
||||
|
||||
/* make sure we do not have bogus data in there */
|
||||
memset(&entry_ex->entry, 0, sizeof(hdb_entry));
|
||||
memset(&entry_ex->entry, 0, sizeof(struct sdb_entry));
|
||||
|
||||
entry_ex->ctx = p;
|
||||
entry_ex->free_entry = samba_kdc_free_entry;
|
||||
|
||||
/* use 'whenCreated' */
|
||||
entry_ex->entry.created_by.time = ldb_msg_find_krb5time_ldap_time(msg, "whenCreated", 0);
|
||||
@ -1185,7 +1157,7 @@ static krb5_error_code samba_kdc_trust_message2entry(krb5_context context,
|
||||
if (password_blob.previous.count == 0) {
|
||||
/* there is no previous password */
|
||||
use_previous = false;
|
||||
} else if (!(flags & HDB_F_KVNO_SPECIFIED)) {
|
||||
} else if (!(flags & SDB_F_KVNO_SPECIFIED)) {
|
||||
/*
|
||||
* If not specified we use the lowest kvno
|
||||
* for the first hour after an update.
|
||||
@ -1223,7 +1195,7 @@ static krb5_error_code samba_kdc_trust_message2entry(krb5_context context,
|
||||
}
|
||||
|
||||
/* use the kvno the client specified, if available */
|
||||
if (flags & HDB_F_KVNO_SPECIFIED) {
|
||||
if (flags & SDB_F_KVNO_SPECIFIED) {
|
||||
entry_ex->entry.kvno = kvno;
|
||||
} else {
|
||||
entry_ex->entry.kvno = *auth_kvno;
|
||||
@ -1282,11 +1254,11 @@ static krb5_error_code samba_kdc_trust_message2entry(krb5_context context,
|
||||
if (num_keys == 0) {
|
||||
DEBUG(1,(__location__ ": no usable key found\n"));
|
||||
krb5_clear_error_message(context);
|
||||
ret = HDB_ERR_NOENTRY;
|
||||
ret = SDB_ERR_NOENTRY;
|
||||
goto out;
|
||||
}
|
||||
|
||||
entry_ex->entry.keys.val = calloc(num_keys, sizeof(Key));
|
||||
entry_ex->entry.keys.val = calloc(num_keys, sizeof(struct sdb_key));
|
||||
if (entry_ex->entry.keys.val == NULL) {
|
||||
krb5_clear_error_message(context);
|
||||
ret = ENOMEM;
|
||||
@ -1294,7 +1266,7 @@ static krb5_error_code samba_kdc_trust_message2entry(krb5_context context,
|
||||
}
|
||||
|
||||
if (password_utf8.length != 0) {
|
||||
Key key = {};
|
||||
struct sdb_key key = {};
|
||||
krb5_const_principal salt_principal = entry_ex->entry.principal;
|
||||
krb5_data salt;
|
||||
krb5_data cleartext_data;
|
||||
@ -1345,7 +1317,7 @@ static krb5_error_code samba_kdc_trust_message2entry(krb5_context context,
|
||||
}
|
||||
|
||||
if (password_hash != NULL) {
|
||||
Key key = {};
|
||||
struct sdb_key key = {};
|
||||
|
||||
ret = smb_krb5_keyblock_init_contents(context,
|
||||
ENCTYPE_ARCFOUR_HMAC,
|
||||
@ -1360,7 +1332,7 @@ static krb5_error_code samba_kdc_trust_message2entry(krb5_context context,
|
||||
entry_ex->entry.keys.len++;
|
||||
}
|
||||
|
||||
entry_ex->entry.flags = int2HDBFlags(0);
|
||||
entry_ex->entry.flags = int2SDBFlags(0);
|
||||
entry_ex->entry.flags.immutable = 1;
|
||||
entry_ex->entry.flags.invalid = 0;
|
||||
entry_ex->entry.flags.server = 1;
|
||||
@ -1396,7 +1368,7 @@ out:
|
||||
|
||||
if (ret != 0) {
|
||||
/* This doesn't free ent itself, that is for the eventual caller to do */
|
||||
hdb_free_entry(context, entry_ex);
|
||||
sdb_free_entry(entry_ex);
|
||||
} else {
|
||||
talloc_steal(kdc_db_ctx, entry_ex->ctx);
|
||||
}
|
||||
@ -1419,7 +1391,7 @@ static krb5_error_code samba_kdc_lookup_trust(krb5_context context, struct ldb_c
|
||||
if (NT_STATUS_IS_OK(status)) {
|
||||
return 0;
|
||||
} else if (NT_STATUS_EQUAL(status, NT_STATUS_OBJECT_NAME_NOT_FOUND)) {
|
||||
return HDB_ERR_NOENTRY;
|
||||
return SDB_ERR_NOENTRY;
|
||||
} else if (NT_STATUS_EQUAL(status, NT_STATUS_NO_MEMORY)) {
|
||||
int ret = ENOMEM;
|
||||
krb5_set_error_message(context, ret, "get_sam_result_trust: out of memory");
|
||||
@ -1555,7 +1527,7 @@ static krb5_error_code samba_kdc_lookup_client(krb5_context context,
|
||||
TALLOC_FREE(principal_string);
|
||||
|
||||
if (NT_STATUS_EQUAL(nt_status, NT_STATUS_NO_SUCH_USER)) {
|
||||
return HDB_ERR_NOENTRY;
|
||||
return SDB_ERR_NOENTRY;
|
||||
} else if (NT_STATUS_EQUAL(nt_status, NT_STATUS_NO_MEMORY)) {
|
||||
return ENOMEM;
|
||||
} else if (!NT_STATUS_IS_OK(nt_status)) {
|
||||
@ -1570,7 +1542,7 @@ static krb5_error_code samba_kdc_fetch_client(krb5_context context,
|
||||
TALLOC_CTX *mem_ctx,
|
||||
krb5_const_principal principal,
|
||||
unsigned flags,
|
||||
hdb_entry_ex *entry_ex) {
|
||||
struct sdb_entry_ex *entry_ex) {
|
||||
struct ldb_dn *realm_dn;
|
||||
krb5_error_code ret;
|
||||
struct ldb_message *msg = NULL;
|
||||
@ -1595,7 +1567,7 @@ static krb5_error_code samba_kdc_fetch_krbtgt(krb5_context context,
|
||||
krb5_const_principal principal,
|
||||
unsigned flags,
|
||||
uint32_t kvno,
|
||||
hdb_entry_ex *entry_ex)
|
||||
struct sdb_entry_ex *entry_ex)
|
||||
{
|
||||
struct loadparm_context *lp_ctx = kdc_db_ctx->lp_ctx;
|
||||
krb5_error_code ret;
|
||||
@ -1607,18 +1579,18 @@ static krb5_error_code samba_kdc_fetch_krbtgt(krb5_context context,
|
||||
realm_from_princ_malloc = smb_krb5_principal_get_realm(context, principal);
|
||||
if (realm_from_princ_malloc == NULL) {
|
||||
/* can't happen */
|
||||
return HDB_ERR_NOENTRY;
|
||||
return SDB_ERR_NOENTRY;
|
||||
}
|
||||
realm_from_princ = talloc_strdup(mem_ctx, realm_from_princ_malloc);
|
||||
free(realm_from_princ_malloc);
|
||||
if (realm_from_princ == NULL) {
|
||||
return HDB_ERR_NOENTRY;
|
||||
return SDB_ERR_NOENTRY;
|
||||
}
|
||||
|
||||
if (krb5_princ_size(context, principal) != 2
|
||||
|| (principal_comp_strcmp(context, principal, 0, KRB5_TGS_NAME) != 0)) {
|
||||
/* Not a krbtgt */
|
||||
return HDB_ERR_NOENTRY;
|
||||
return SDB_ERR_NOENTRY;
|
||||
}
|
||||
|
||||
/* krbtgt case. Either us or a trusted realm */
|
||||
@ -1635,11 +1607,11 @@ static krb5_error_code samba_kdc_fetch_krbtgt(krb5_context context,
|
||||
/* w2k8r2 sometimes gives us a kvno of 255 for inter-domain
|
||||
trust tickets. We don't yet know what this means, but we do
|
||||
seem to need to treat it as unspecified */
|
||||
if (flags & HDB_F_KVNO_SPECIFIED) {
|
||||
if (flags & SDB_F_KVNO_SPECIFIED) {
|
||||
krbtgt_number = SAMBA_KVNO_GET_KRBTGT(kvno);
|
||||
if (kdc_db_ctx->rodc) {
|
||||
if (krbtgt_number != kdc_db_ctx->my_krbtgt_number) {
|
||||
return HDB_ERR_NOT_FOUND_HERE;
|
||||
return SDB_ERR_NOT_FOUND_HERE;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
@ -1665,17 +1637,17 @@ static krb5_error_code samba_kdc_fetch_krbtgt(krb5_context context,
|
||||
if (lret == LDB_ERR_NO_SUCH_OBJECT) {
|
||||
krb5_warnx(context, "samba_kdc_fetch: could not find KRBTGT number %u in DB!",
|
||||
(unsigned)(krbtgt_number));
|
||||
krb5_set_error_message(context, HDB_ERR_NOENTRY,
|
||||
krb5_set_error_message(context, SDB_ERR_NOENTRY,
|
||||
"samba_kdc_fetch: could not find KRBTGT number %u in DB!",
|
||||
(unsigned)(krbtgt_number));
|
||||
return HDB_ERR_NOENTRY;
|
||||
return SDB_ERR_NOENTRY;
|
||||
} else if (lret != LDB_SUCCESS) {
|
||||
krb5_warnx(context, "samba_kdc_fetch: could not find KRBTGT number %u in DB!",
|
||||
(unsigned)(krbtgt_number));
|
||||
krb5_set_error_message(context, HDB_ERR_NOENTRY,
|
||||
krb5_set_error_message(context, SDB_ERR_NOENTRY,
|
||||
"samba_kdc_fetch: could not find KRBTGT number %u in DB!",
|
||||
(unsigned)(krbtgt_number));
|
||||
return HDB_ERR_NOENTRY;
|
||||
return SDB_ERR_NOENTRY;
|
||||
}
|
||||
|
||||
ret = samba_kdc_message2entry(context, kdc_db_ctx, mem_ctx,
|
||||
@ -1704,10 +1676,10 @@ static krb5_error_code samba_kdc_fetch_krbtgt(krb5_context context,
|
||||
krb5_warnx(context, "samba_kdc_fetch: not our realm for trusts ('%s', '%s')",
|
||||
realm_from_princ,
|
||||
realm_princ_comp);
|
||||
krb5_set_error_message(context, HDB_ERR_NOENTRY, "samba_kdc_fetch: not our realm for trusts ('%s', '%s')",
|
||||
krb5_set_error_message(context, SDB_ERR_NOENTRY, "samba_kdc_fetch: not our realm for trusts ('%s', '%s')",
|
||||
realm_from_princ,
|
||||
realm_princ_comp);
|
||||
return HDB_ERR_NOENTRY;
|
||||
return SDB_ERR_NOENTRY;
|
||||
}
|
||||
|
||||
/* Trusted domains are under CN=system */
|
||||
@ -1771,7 +1743,7 @@ static krb5_error_code samba_kdc_lookup_server(krb5_context context,
|
||||
free(principal_string);
|
||||
|
||||
if (!NT_STATUS_IS_OK(nt_status)) {
|
||||
return HDB_ERR_NOENTRY;
|
||||
return SDB_ERR_NOENTRY;
|
||||
}
|
||||
|
||||
ldb_ret = dsdb_search_one(kdc_db_ctx->samdb,
|
||||
@ -1781,10 +1753,10 @@ static krb5_error_code samba_kdc_lookup_server(krb5_context context,
|
||||
DSDB_SEARCH_SHOW_EXTENDED_DN | DSDB_SEARCH_NO_GLOBAL_CATALOG,
|
||||
"(objectClass=*)");
|
||||
if (ldb_ret != LDB_SUCCESS) {
|
||||
return HDB_ERR_NOENTRY;
|
||||
return SDB_ERR_NOENTRY;
|
||||
}
|
||||
return 0;
|
||||
} else if (!(flags & HDB_F_FOR_AS_REQ)
|
||||
} else if (!(flags & SDB_F_FOR_AS_REQ)
|
||||
&& smb_krb5_principal_get_type(context, principal) == KRB5_NT_ENTERPRISE_PRINCIPAL) {
|
||||
/*
|
||||
* The behaviour of accepting an
|
||||
@ -1888,21 +1860,21 @@ static krb5_error_code samba_kdc_lookup_server(krb5_context context,
|
||||
if (lret == LDB_ERR_NO_SUCH_OBJECT) {
|
||||
DEBUG(10, ("Failed to find an entry for %s filter:%s\n",
|
||||
name1, filter));
|
||||
return HDB_ERR_NOENTRY;
|
||||
return SDB_ERR_NOENTRY;
|
||||
}
|
||||
if (lret == LDB_ERR_CONSTRAINT_VIOLATION) {
|
||||
DEBUG(10, ("Failed to find unique entry for %s filter:%s\n",
|
||||
name1, filter));
|
||||
return HDB_ERR_NOENTRY;
|
||||
return SDB_ERR_NOENTRY;
|
||||
}
|
||||
if (lret != LDB_SUCCESS) {
|
||||
DEBUG(0, ("Failed single search for %s - %s\n",
|
||||
name1, ldb_errstring(kdc_db_ctx->samdb)));
|
||||
return HDB_ERR_NOENTRY;
|
||||
return SDB_ERR_NOENTRY;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
return HDB_ERR_NOENTRY;
|
||||
return SDB_ERR_NOENTRY;
|
||||
}
|
||||
|
||||
|
||||
@ -1912,7 +1884,7 @@ static krb5_error_code samba_kdc_fetch_server(krb5_context context,
|
||||
TALLOC_CTX *mem_ctx,
|
||||
krb5_const_principal principal,
|
||||
unsigned flags,
|
||||
hdb_entry_ex *entry_ex)
|
||||
struct sdb_entry_ex *entry_ex)
|
||||
{
|
||||
krb5_error_code ret;
|
||||
struct ldb_dn *realm_dn;
|
||||
@ -1940,7 +1912,7 @@ static krb5_error_code samba_kdc_lookup_realm(krb5_context context,
|
||||
TALLOC_CTX *mem_ctx,
|
||||
krb5_const_principal principal,
|
||||
unsigned flags,
|
||||
hdb_entry_ex *entry_ex)
|
||||
struct sdb_entry_ex *entry_ex)
|
||||
{
|
||||
TALLOC_CTX *frame = talloc_stackframe();
|
||||
NTSTATUS status;
|
||||
@ -1956,13 +1928,13 @@ static krb5_error_code samba_kdc_lookup_realm(krb5_context context,
|
||||
|
||||
num_comp = krb5_princ_size(context, principal);
|
||||
|
||||
if (flags & HDB_F_GET_CLIENT) {
|
||||
if (flags & HDB_F_FOR_AS_REQ) {
|
||||
if (flags & SDB_F_GET_CLIENT) {
|
||||
if (flags & SDB_F_FOR_AS_REQ) {
|
||||
check_realm = true;
|
||||
}
|
||||
}
|
||||
if (flags & HDB_F_GET_SERVER) {
|
||||
if (flags & HDB_F_FOR_TGS_REQ) {
|
||||
if (flags & SDB_F_GET_SERVER) {
|
||||
if (flags & SDB_F_FOR_TGS_REQ) {
|
||||
check_realm = true;
|
||||
}
|
||||
}
|
||||
@ -1988,7 +1960,7 @@ static krb5_error_code samba_kdc_lookup_realm(krb5_context context,
|
||||
*/
|
||||
SAFE_FREE(_realm);
|
||||
TALLOC_FREE(frame);
|
||||
return HDB_ERR_NOENTRY;
|
||||
return SDB_ERR_NOENTRY;
|
||||
}
|
||||
|
||||
realm = talloc_strdup(frame, _realm);
|
||||
@ -2005,7 +1977,7 @@ static krb5_error_code samba_kdc_lookup_realm(krb5_context context,
|
||||
|
||||
if (num_comp != 1) {
|
||||
TALLOC_FREE(frame);
|
||||
return HDB_ERR_NOENTRY;
|
||||
return SDB_ERR_NOENTRY;
|
||||
}
|
||||
|
||||
principal_string = smb_krb5_principal_get_comp_string(frame, context,
|
||||
@ -2036,7 +2008,7 @@ static krb5_error_code samba_kdc_lookup_realm(krb5_context context,
|
||||
}
|
||||
}
|
||||
|
||||
if (flags & HDB_F_GET_SERVER) {
|
||||
if (flags & SDB_F_GET_SERVER) {
|
||||
char *service_realm = NULL;
|
||||
|
||||
ret = principal_comp_strcmp(context, principal, 0, KRB5_TGS_NAME);
|
||||
@ -2141,7 +2113,7 @@ static krb5_error_code samba_kdc_lookup_realm(krb5_context context,
|
||||
}
|
||||
|
||||
TALLOC_FREE(frame);
|
||||
return HDB_ERR_WRONG_REALM;
|
||||
return SDB_ERR_WRONG_REALM;
|
||||
}
|
||||
|
||||
krb5_error_code samba_kdc_fetch(krb5_context context,
|
||||
@ -2149,9 +2121,9 @@ krb5_error_code samba_kdc_fetch(krb5_context context,
|
||||
krb5_const_principal principal,
|
||||
unsigned flags,
|
||||
krb5_kvno kvno,
|
||||
hdb_entry_ex *entry_ex)
|
||||
struct sdb_entry_ex *entry_ex)
|
||||
{
|
||||
krb5_error_code ret = HDB_ERR_NOENTRY;
|
||||
krb5_error_code ret = SDB_ERR_NOENTRY;
|
||||
TALLOC_CTX *mem_ctx;
|
||||
|
||||
mem_ctx = talloc_named(kdc_db_ctx, 0, "samba_kdc_fetch context");
|
||||
@ -2167,24 +2139,24 @@ krb5_error_code samba_kdc_fetch(krb5_context context,
|
||||
goto done;
|
||||
}
|
||||
|
||||
ret = HDB_ERR_NOENTRY;
|
||||
ret = SDB_ERR_NOENTRY;
|
||||
|
||||
if (flags & HDB_F_GET_CLIENT) {
|
||||
if (flags & SDB_F_GET_CLIENT) {
|
||||
ret = samba_kdc_fetch_client(context, kdc_db_ctx, mem_ctx, principal, flags, entry_ex);
|
||||
if (ret != HDB_ERR_NOENTRY) goto done;
|
||||
if (ret != SDB_ERR_NOENTRY) goto done;
|
||||
}
|
||||
if (flags & HDB_F_GET_SERVER) {
|
||||
if (flags & SDB_F_GET_SERVER) {
|
||||
/* krbtgt fits into this situation for trusted realms, and for resolving different versions of our own realm name */
|
||||
ret = samba_kdc_fetch_krbtgt(context, kdc_db_ctx, mem_ctx, principal, flags, kvno, entry_ex);
|
||||
if (ret != HDB_ERR_NOENTRY) goto done;
|
||||
if (ret != SDB_ERR_NOENTRY) goto done;
|
||||
|
||||
/* We return 'no entry' if it does not start with krbtgt/, so move to the common case quickly */
|
||||
ret = samba_kdc_fetch_server(context, kdc_db_ctx, mem_ctx, principal, flags, entry_ex);
|
||||
if (ret != HDB_ERR_NOENTRY) goto done;
|
||||
if (ret != SDB_ERR_NOENTRY) goto done;
|
||||
}
|
||||
if (flags & HDB_F_GET_KRBTGT) {
|
||||
if (flags & SDB_F_GET_KRBTGT) {
|
||||
ret = samba_kdc_fetch_krbtgt(context, kdc_db_ctx, mem_ctx, principal, flags, kvno, entry_ex);
|
||||
if (ret != HDB_ERR_NOENTRY) goto done;
|
||||
if (ret != SDB_ERR_NOENTRY) goto done;
|
||||
}
|
||||
|
||||
done:
|
||||
@ -2201,7 +2173,7 @@ struct samba_kdc_seq {
|
||||
|
||||
static krb5_error_code samba_kdc_seq(krb5_context context,
|
||||
struct samba_kdc_db_context *kdc_db_ctx,
|
||||
hdb_entry_ex *entry)
|
||||
struct sdb_entry_ex *entry)
|
||||
{
|
||||
krb5_error_code ret;
|
||||
struct samba_kdc_seq *priv = kdc_db_ctx->seq_ctx;
|
||||
@ -2212,7 +2184,7 @@ static krb5_error_code samba_kdc_seq(krb5_context context,
|
||||
TALLOC_CTX *mem_ctx;
|
||||
|
||||
if (!priv) {
|
||||
return HDB_ERR_NOENTRY;
|
||||
return SDB_ERR_NOENTRY;
|
||||
}
|
||||
|
||||
mem_ctx = talloc_named(priv, 0, "samba_kdc_seq context");
|
||||
@ -2233,7 +2205,7 @@ static krb5_error_code samba_kdc_seq(krb5_context context,
|
||||
}
|
||||
|
||||
if (sAMAccountName == NULL) {
|
||||
ret = HDB_ERR_NOENTRY;
|
||||
ret = SDB_ERR_NOENTRY;
|
||||
goto out;
|
||||
}
|
||||
|
||||
@ -2245,7 +2217,7 @@ static krb5_error_code samba_kdc_seq(krb5_context context,
|
||||
|
||||
ret = samba_kdc_message2entry(context, kdc_db_ctx, mem_ctx,
|
||||
principal, SAMBA_KDC_ENT_TYPE_ANY,
|
||||
HDB_F_ADMIN_DATA|HDB_F_GET_ANY,
|
||||
SDB_F_ADMIN_DATA|SDB_F_GET_ANY,
|
||||
priv->realm_dn, msg, entry);
|
||||
|
||||
out:
|
||||
@ -2265,7 +2237,7 @@ out:
|
||||
|
||||
krb5_error_code samba_kdc_firstkey(krb5_context context,
|
||||
struct samba_kdc_db_context *kdc_db_ctx,
|
||||
hdb_entry_ex *entry)
|
||||
struct sdb_entry_ex *entry)
|
||||
{
|
||||
struct ldb_context *ldb_ctx = kdc_db_ctx->samdb;
|
||||
struct samba_kdc_seq *priv = kdc_db_ctx->seq_ctx;
|
||||
@ -2314,7 +2286,7 @@ krb5_error_code samba_kdc_firstkey(krb5_context context,
|
||||
|
||||
if (lret != LDB_SUCCESS) {
|
||||
TALLOC_FREE(priv);
|
||||
return HDB_ERR_NOENTRY;
|
||||
return SDB_ERR_NOENTRY;
|
||||
}
|
||||
|
||||
priv->count = res->count;
|
||||
@ -2336,7 +2308,7 @@ krb5_error_code samba_kdc_firstkey(krb5_context context,
|
||||
|
||||
krb5_error_code samba_kdc_nextkey(krb5_context context,
|
||||
struct samba_kdc_db_context *kdc_db_ctx,
|
||||
hdb_entry_ex *entry)
|
||||
struct sdb_entry_ex *entry)
|
||||
{
|
||||
return samba_kdc_seq(context, kdc_db_ctx, entry);
|
||||
}
|
||||
@ -2369,7 +2341,7 @@ samba_kdc_check_s4u2self(krb5_context context,
|
||||
}
|
||||
|
||||
ret = samba_kdc_lookup_server(context, kdc_db_ctx, mem_ctx, target_principal,
|
||||
HDB_F_GET_CLIENT|HDB_F_GET_SERVER,
|
||||
SDB_F_GET_CLIENT|SDB_F_GET_SERVER,
|
||||
delegation_check_attrs, &realm_dn, &msg);
|
||||
|
||||
if (ret != 0) {
|
||||
|
@ -21,20 +21,22 @@
|
||||
along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
struct sdb_entry_ex;
|
||||
|
||||
krb5_error_code samba_kdc_fetch(krb5_context context,
|
||||
struct samba_kdc_db_context *kdc_db_ctx,
|
||||
krb5_const_principal principal,
|
||||
unsigned flags,
|
||||
krb5_kvno kvno,
|
||||
hdb_entry_ex *entry_ex);
|
||||
struct sdb_entry_ex *entry_ex);
|
||||
|
||||
krb5_error_code samba_kdc_firstkey(krb5_context context,
|
||||
struct samba_kdc_db_context *kdc_db_ctx,
|
||||
hdb_entry_ex *entry);
|
||||
struct sdb_entry_ex *entry);
|
||||
|
||||
krb5_error_code samba_kdc_nextkey(krb5_context context,
|
||||
struct samba_kdc_db_context *kdc_db_ctx,
|
||||
hdb_entry_ex *entry);
|
||||
struct sdb_entry_ex *entry);
|
||||
|
||||
krb5_error_code
|
||||
samba_kdc_check_s4u2self(krb5_context context,
|
||||
|
@ -37,6 +37,8 @@
|
||||
#include "kdc/db-glue.h"
|
||||
#include "auth/auth_sam.h"
|
||||
#include <ldb.h>
|
||||
#include "sdb.h"
|
||||
#include "sdb_hdb.h"
|
||||
|
||||
static krb5_error_code hdb_samba4_open(krb5_context context, HDB *db, int flags, mode_t mode)
|
||||
{
|
||||
@ -87,33 +89,74 @@ static krb5_error_code hdb_samba4_fetch_kvno(krb5_context context, HDB *db,
|
||||
hdb_entry_ex *entry_ex)
|
||||
{
|
||||
struct samba_kdc_db_context *kdc_db_ctx;
|
||||
struct sdb_entry_ex sdb_entry_ex = {};
|
||||
krb5_error_code code, ret;
|
||||
|
||||
kdc_db_ctx = talloc_get_type_abort(db->hdb_db,
|
||||
struct samba_kdc_db_context);
|
||||
|
||||
return samba_kdc_fetch(context, kdc_db_ctx, principal, flags, kvno, entry_ex);
|
||||
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;
|
||||
}
|
||||
|
||||
static krb5_error_code hdb_samba4_firstkey(krb5_context context, HDB *db, unsigned flags,
|
||||
hdb_entry_ex *entry)
|
||||
{
|
||||
struct samba_kdc_db_context *kdc_db_ctx;
|
||||
struct sdb_entry_ex sdb_entry_ex = {};
|
||||
krb5_error_code ret;
|
||||
|
||||
kdc_db_ctx = talloc_get_type_abort(db->hdb_db,
|
||||
struct samba_kdc_db_context);
|
||||
|
||||
return samba_kdc_firstkey(context, kdc_db_ctx, entry);
|
||||
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;
|
||||
}
|
||||
|
||||
static krb5_error_code hdb_samba4_nextkey(krb5_context context, HDB *db, unsigned flags,
|
||||
hdb_entry_ex *entry)
|
||||
{
|
||||
struct samba_kdc_db_context *kdc_db_ctx;
|
||||
struct sdb_entry_ex sdb_entry_ex = {};
|
||||
krb5_error_code ret;
|
||||
|
||||
kdc_db_ctx = talloc_get_type_abort(db->hdb_db,
|
||||
struct samba_kdc_db_context);
|
||||
|
||||
return samba_kdc_nextkey(context, kdc_db_ctx, entry);
|
||||
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;
|
||||
}
|
||||
|
||||
static krb5_error_code hdb_samba4_destroy(krb5_context context, HDB *db)
|
||||
|
@ -27,7 +27,7 @@ bld.SAMBA_MODULE('service_kdc',
|
||||
|
||||
bld.SAMBA_LIBRARY('HDB_SAMBA4',
|
||||
source='hdb-samba4.c hdb-samba4-plugin.c',
|
||||
deps='ldb auth4_sam auth_sam_reply samba-credentials hdb db-glue samba-hostconfig com_err',
|
||||
deps='ldb auth4_sam auth_sam_reply samba-credentials hdb db-glue samba-hostconfig com_err sdb_hdb',
|
||||
includes=kdc_include,
|
||||
private_library=True,
|
||||
enabled=bld.CONFIG_SET('SAMBA4_USES_HEIMDAL')
|
||||
@ -87,7 +87,7 @@ bld.SAMBA_LIBRARY('pac',
|
||||
|
||||
bld.SAMBA_LIBRARY('db-glue',
|
||||
source='db-glue.c',
|
||||
deps='ldb auth4_sam auth_sam_reply samba-credentials hdb samba-hostconfig com_err',
|
||||
deps='ldb auth4_sam auth_sam_reply samba-credentials sdb samba-hostconfig com_err',
|
||||
private_library=True,
|
||||
includes=kdc_include,
|
||||
)
|
||||
|
Loading…
x
Reference in New Issue
Block a user