return KRB5_KDB_DBTYPE_NOSUP;
}
-static krb5_error_code
-ks_db_set_option(krb5_context context,
- int option,
- void *value)
-{
- /* NOTE: looks like nothing uses this */
- return KRB5_KDB_DBTYPE_NOSUP;
-}
-
static krb5_error_code
ks_db_lock(krb5_context context, int kmode)
{
ks_get_principal(krb5_context context,
krb5_const_principal principal,
unsigned int flags,
- krb5_db_entry *kentry)
+ krb5_db_entry **kentry)
{
struct ks_context *ks = GET_KS_CONTEXT(context);
char *principal_string = NULL;
static krb5_error_code
ks_get_master_key_principal(krb5_context context,
krb5_const_principal princ,
- krb5_db_entry *kentry,
- int *nentries)
+ krb5_db_entry **kentry_ptr)
{
krb5_error_code code;
krb5_key_data *key_data;
krb5_timestamp now;
+ krb5_db_entry *kentry;
- memset(kentry, 0, sizeof(*kentry));
- *nentries = 0;
+ *kentry_ptr = NULL;
+
+ kentry = k5alloc(sizeof(*kentry), &code);
+ if (kentry == NULL) {
+ return code;
+ }
kentry->magic = KRB5_KDB_MAGIC_NUMBER;
kentry->len = KRB5_KDB_V1_BASE_LENGTH;
kentry->attributes = KRB5_KDB_DISALLOW_ALL_TIX;
- if (princ == NULL)
+ if (princ == NULL) {
code = krb5_parse_name(context, KRB5_KDB_M_NAME, &kentry->princ);
- else
+ } else {
code = krb5_copy_principal(context, princ, &kentry->princ);
- if (code != 0)
+ }
+ if (code != 0) {
+ ks_free_krb5_db_entry(context, kentry);
return code;
+ }
now = time(NULL);
key_data->key_data_kvno = 1;
key_data->key_data_type[0] = ENCTYPE_UNKNOWN;
if (code != 0) {
+ ks_free_krb5_db_entry(context, kentry);
return code;
}
- *nentries = 1;
+ *kentry_ptr = kentry;
return 0;
}
static krb5_error_code
ks_get_dummy_principal(krb5_context context,
krb5_const_principal princ,
- krb5_db_entry *kentry,
- int *nentries)
+ krb5_db_entry **kentry_ptr)
{
krb5_error_code code;
krb5_key_data *key_data;
krb5_timestamp now;
+ krb5_db_entry *kentry;
krb5_keyblock key;
krb5_data salt;
krb5_data pwd;
return KRB5_KDB_NOENTRY;
}
- memset(kentry, 0, sizeof(*kentry));
- *nentries = 0;
+ *kentry_ptr = NULL;
+
+ kentry = k5alloc(sizeof(*kentry), &code);
+ if (kentry == NULL) {
+ return code;
+ }
kentry->magic = KRB5_KDB_MAGIC_NUMBER;
kentry->len = KRB5_KDB_V1_BASE_LENGTH;
code = krb5_copy_principal(context, princ, &kentry->princ);
if (code != 0) {
+ ks_free_krb5_db_entry(context, kentry);
return code;
}
key_data->key_data_length[1] = salt.length;
key_data->key_data_contents[1] = (krb5_octet *)strdup("salt");
- *nentries = 1;
+ *kentry_ptr = kentry;
return 0;
}
ks_db_get_principal(krb5_context context,
krb5_const_principal princ,
unsigned int kflags,
- krb5_db_entry *kentry,
- int *nentries,
- krb5_boolean *more)
+ krb5_db_entry **kentry)
{
struct ks_context *ks = GET_KS_CONTEXT(context);
krb5_error_code code;
unsigned int hflags;
- *nentries = 0;
- *more = FALSE;
- memset(kentry, 0, sizeof(*kentry));
-
if (ks == NULL) {
return KRB5_KDB_DBNOTINITED;
}
if (ks_is_master_key_principal(context, princ)) {
- return ks_get_master_key_principal(context, princ, kentry, nentries);
+ return ks_get_master_key_principal(context, princ, kentry);
}
/* FIXME: temporarily fake up kadmin history to let kadmin.local work */
if (ks_is_kadmin_history(context, princ)) {
- return ks_get_dummy_principal(context, princ, kentry, nentries);
+ return ks_get_dummy_principal(context, princ, kentry);
}
code = k5_mutex_lock(ks->lock);
- if (code != 0)
+ if (code != 0) {
return code;
+ }
hflags = 0;
if (kflags & KRB5_KDB_FLAG_CANONICALIZE)
hflags |= HDB_F_GET_ANY;
code = ks_get_principal(context, princ, hflags, kentry);
- switch (code) {
- case 0:
- *nentries = 1;
- break;
- case KRB5_KDB_NOENTRY:
- code = 0;
- break;
- default:
- break;
- }
k5_mutex_unlock(ks->lock);
return code;
}
-static krb5_error_code
+static void
ks_db_free_principal(krb5_context context,
- krb5_db_entry *entry,
- int count)
+ krb5_db_entry *entry)
{
struct ks_context *ks = GET_KS_CONTEXT(context);
krb5_error_code code;
- int i;
if (!ks) {
- return KRB5_KDB_DBNOTINITED;
+ return;
}
code = k5_mutex_lock(ks->lock);
if (code != 0) {
- return code;
+ return;
}
- for (i = 0; i < count; i++) {
- ks_free_krb5_db_entry(context, &entry[i]);
- }
+ ks_free_krb5_db_entry(context, entry);
k5_mutex_unlock(ks->lock);
-
- return 0;
}
static krb5_error_code
ks_db_put_principal(krb5_context context,
- krb5_db_entry *entries,
- int *nentries,
+ krb5_db_entry *entry,
char **db_args)
{
static krb5_error_code
ks_db_delete_principal(krb5_context context,
- krb5_const_principal princ,
- int *nentries)
+ krb5_const_principal princ)
{
/* NOTE: deferred, samba does not allow the KDC to delete
code = ks_map_error(error);
while (code == 0) {
- krb5_db_entry kentry;
+ krb5_db_entry *kentry;
code = ks_unmarshal_hdb_entry(context, hentry, &kentry);
if (code == 0) {
- code = (*func)(func_arg, &kentry);
- ks_free_krb5_db_entry(context, &kentry);
+ code = (*func)(func_arg, kentry);
+ ks_free_krb5_db_entry(context, kentry);
}
if (code != 0) {
free(ptr);
}
-static krb5_error_code
-ks_set_master_key(krb5_context context,
- char *pwd,
- krb5_keyblock *kkey)
-{
-
- /* NOTE: samba does not support master keys
- * so just ignore the request */
- return 0;
-}
-
-static krb5_error_code
-ks_get_master_key(krb5_context context,
- krb5_keyblock **pkey)
-{
- /* NOTE: looks like nothing uses this */
- return KRB5_KDB_DBTYPE_NOSUP;
-}
-
static krb5_error_code
ks_fetch_master_key(krb5_context context,
krb5_principal name,
return 0;
}
-/*
- * db_invoke() related methods
- */
-
-static struct ks_invoke_table {
- unsigned int method;
- krb5_error_code (*function)(krb5_context, unsigned int,
- const krb5_data *, krb5_data *);
-} ks_invoke_vtable[] = {
- { KRB5_KDB_METHOD_CHECK_POLICY_AS, ks_db_check_policy_as },
- { KRB5_KDB_METHOD_SIGN_AUTH_DATA, ks_db_sign_auth_data },
- { KRB5_KDB_METHOD_CHECK_ALLOWED_TO_DELEGATE, ks_db_check_allowed_to_delegate },
- { 0, NULL }
-};
-
-static krb5_error_code
-ks_db_invoke(krb5_context context,
- unsigned int method,
- const krb5_data *req,
- krb5_data *rep)
-{
- struct ks_context *ks = GET_KS_CONTEXT(context);
- krb5_error_code code;
- int i;
-
- if (!ks) {
- return KRB5_KDB_DBNOTINITED;
- }
-
- code = k5_mutex_lock(ks->lock);
- if (code != 0) {
- return code;
- }
-
- code = KRB5_KDB_DBTYPE_NOSUP;
-
- for (i = 0; ks_invoke_vtable[i].method; i++) {
-
- if (ks_invoke_vtable[i].method == method) {
- code = (ks_invoke_vtable[i].function)(context, method, req, rep);
- break;
- }
- }
-
- k5_mutex_unlock(ks->lock);
-
- return code;
-}
-
kdb_vftabl kdb_function_table = {
- 1,
+ KRB5_KDB_DAL_MAJOR_VERSION,
0,
ks_init,
ks_fini,
ks_db_create,
ks_db_destroy,
ks_db_get_age,
- ks_db_set_option,
ks_db_lock,
ks_db_unlock,
ks_db_get_principal,
ks_db_put_principal,
ks_db_delete_principal,
ks_db_iterate,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
- NULL,
+ NULL, /* create_policy */
+ NULL, /* get_policy */
+ NULL, /* put_policy */
+ NULL, /* iter_policy */
+ NULL, /* delete_policy */
+ NULL, /* free_policy */
ks_db_alloc,
ks_db_free,
- ks_set_master_key,
- ks_get_master_key,
- NULL,
- NULL,
- NULL,
- NULL,
ks_fetch_master_key,
- NULL,
ks_fetch_master_key_list,
- NULL,
- NULL,
- NULL,
+ NULL, /* store_master_key_list */
+ NULL, /* dbe_search_enctype */
+ NULL, /* change_pwd */
ks_promote_db,
ks_dbekd_decrypt_key_data,
ks_dbekd_encrypt_key_data,
- ks_db_invoke,
+ ks_db_sign_auth_data,
+ NULL, /* check_transited_realms */
+ ks_db_check_policy_as,
+ NULL, /* check_policy_tgs */
+ NULL, /* audit_as_req */
+ NULL, /* refresh_config */
+ ks_db_check_allowed_to_delegate
};
krb5_error_code
ks_unmarshal_hdb_entry(krb5_context context,
struct hdb_entry_ex *hentry,
- krb5_db_entry *kentry);
+ krb5_db_entry **kentry_ptr);
/* from kdb_samba_policies.c */
krb5_error_code
ks_db_check_allowed_to_delegate(krb5_context context,
- unsigned int method,
- const krb5_data *req_data,
- krb5_data *rep_data);
+ krb5_const_principal client,
+ const krb5_db_entry *server,
+ krb5_const_principal proxy);
krb5_error_code
ks_db_check_policy_as(krb5_context context,
- unsigned int method,
- const krb5_data *req_data,
- krb5_data *rep_data);
+ krb5_kdc_req *kdcreq,
+ krb5_db_entry *client_dbe,
+ krb5_db_entry *server_dbe,
+ krb5_timestamp kdc_time,
+ const char **status,
+ krb5_data *e_data);
krb5_error_code
ks_db_sign_auth_data(krb5_context context,
- unsigned int method,
- const krb5_data *req_data,
- krb5_data *rep_data);
+ unsigned int flags,
+ krb5_const_principal client_princ,
+ krb5_db_entry *client,
+ krb5_db_entry *server,
+ krb5_db_entry *krbtgt,
+ krb5_keyblock *client_key,
+ krb5_keyblock *server_key,
+ krb5_keyblock *krbtgt_key,
+ krb5_keyblock *session_key,
+ krb5_timestamp authtime,
+ krb5_authdata **tgt_auth_data,
+ krb5_authdata ***signed_auth_data);
#endif /* _KDB_SAMBA_H_ */
krb5_error_code
ks_db_check_allowed_to_delegate(krb5_context context,
- unsigned int method,
- const krb5_data *req_data,
- krb5_data *rep_data)
+ krb5_const_principal client,
+ const krb5_db_entry *server,
+ krb5_const_principal proxy)
{
struct ks_context *ks = GET_KS_CONTEXT(context);
- kdb_check_allowed_to_delegate_req *req;
hdb_entry_ex *delegating_service;
char *target_name = NULL;
bool is_enterprise;
krb5_error_code code;
int error;
- req = (kdb_check_allowed_to_delegate_req *)req_data->data;
-
/*
* Names are quite odd and confusing in the current implementation.
* The following mappings should help understanding what is what.
- * req->client -> client to impersonate
- * req->server; -> delegating service
- * req->proxy; -> target principal
+ * client -> client to impersonate
+ * server; -> delegating service
+ * proxy; -> target principal
*/
- delegating_service = (hdb_entry_ex *)req->server->e_data;
+ delegating_service = (hdb_entry_ex *)server->e_data;
- code = krb5_unparse_name(context, req->proxy, &target_name);
+ code = krb5_unparse_name(context, proxy, &target_name);
if (code) {
goto done;
}
- is_enterprise = (req->proxy->type == KRB5_NT_ENTERPRISE_PRINCIPAL);
+ is_enterprise = (proxy->type == KRB5_NT_ENTERPRISE_PRINCIPAL);
error = KS_CHECK_S4U2PROXY(ks, delegating_service,
target_name, is_enterprise);
krb5_error_code
ks_db_check_policy_as(krb5_context context,
- unsigned int method,
- const krb5_data *req_data,
- krb5_data *rep_data)
+ krb5_kdc_req *kdcreq,
+ krb5_db_entry *client_dbe,
+ krb5_db_entry *server_dbe,
+ krb5_timestamp kdc_time,
+ const char **status,
+ krb5_data *e_data)
{
struct ks_context *ks = GET_KS_CONTEXT(context);
- kdb_check_policy_as_req *req;
- kdb_check_policy_as_rep *rep;
- krb5_kdc_req *kdcreq;
krb5_error_code code;
hdb_entry_ex *client;
hdb_entry_ex *server;
char *netbios_name = NULL;
char *realm = NULL;
bool password_change = false;
- DATA_BLOB e_data;
+ DATA_BLOB int_data = { NULL, 0 };
int error;
- req = (kdb_check_policy_as_req *)req_data->data;
- rep = (kdb_check_policy_as_rep *)rep_data->data;
- kdcreq = req->request;
-
- server = (hdb_entry_ex *)req->server->e_data;
- client = (hdb_entry_ex *)req->client->e_data;
+ server = (hdb_entry_ex *)server_dbe->e_data;
+ client = (hdb_entry_ex *)client_dbe->e_data;
if (krb5_princ_size(context, kdcreq->server) == 2 &&
data_eq_string(kdcreq->server->data[0], "kadmin") &&
server, server_name,
netbios_name,
password_change,
- &e_data);
+ &int_data);
code = ks_map_error(error);
if (code) {
goto done;
}
- rep->e_data = make_data(e_data.data, e_data.length);
+ *e_data = make_data(int_data.data, int_data.length);
done:
free(realm);
static krb5_error_code
ks_verify_pac(krb5_context context,
+ unsigned int flags,
krb5_const_principal client_princ,
- kdb_sign_auth_data_req *req,
+ krb5_db_entry *client,
+ krb5_keyblock *server_key,
+ krb5_keyblock *krbtgt_key,
+ krb5_timestamp authtime,
+ krb5_authdata **tgt_auth_data,
krb5_pac *pac)
{
struct ks_context *ks = GET_KS_CONTEXT(context);
/* find the existing PAC, if present */
code = krb5int_find_authdata(context,
- req->auth_data, NULL,
+ tgt_auth_data, NULL,
KRB5_AUTHDATA_WIN2K_PAC,
&authdata);
if (code != 0) {
* ticket rather than a TGT; we must verify the server and KDC
* signatures to assert that the server did not forge the PAC.
*/
- if (req->flags & KRB5_KDB_FLAG_CONSTRAINED_DELEGATION) {
- code = krb5_pac_verify(context, ipac, req->authtime,
+ if (flags & KRB5_KDB_FLAG_CONSTRAINED_DELEGATION) {
+ code = krb5_pac_verify(context, ipac, authtime,
client_princ,
- req->server_key, req->krbtgt_key);
+ server_key, krbtgt_key);
} else {
- code = krb5_pac_verify(context, ipac, req->authtime,
+ code = krb5_pac_verify(context, ipac, authtime,
client_princ,
- req->krbtgt_key, NULL);
+ krbtgt_key, NULL);
}
if (code != 0) {
goto done;
}
/* check and update PAC */
- if (req->client) {
- hentry = (hdb_entry_ex *)req->client->e_data;
+ if (client) {
+ hentry = (hdb_entry_ex *)client->e_data;
}
pac_data.data = authdata[0]->contents;
krb5_error_code
ks_db_sign_auth_data(krb5_context context,
- unsigned int method,
- const krb5_data *req_data,
- krb5_data *rep_data)
+ unsigned int flags,
+ krb5_const_principal client_princ,
+ krb5_db_entry *client,
+ krb5_db_entry *server,
+ krb5_db_entry *krbtgt,
+ krb5_keyblock *client_key,
+ krb5_keyblock *server_key,
+ krb5_keyblock *krbtgt_key,
+ krb5_keyblock *session_key,
+ krb5_timestamp authtime,
+ krb5_authdata **tgt_auth_data,
+ krb5_authdata ***signed_auth_data)
{
- kdb_sign_auth_data_req *req = (kdb_sign_auth_data_req *)req_data->data;
- kdb_sign_auth_data_rep *rep = (kdb_sign_auth_data_rep *)rep_data->data;
- krb5_const_principal client_princ;
+ krb5_const_principal ks_client_princ;
krb5_authdata **authdata = NULL;
krb5_boolean is_as_req;
krb5_error_code code;
krb5_pac pac = NULL;
krb5_data pac_data;
- memset(rep, 0, sizeof(*rep));
-
/* Prefer canonicalised name from client entry */
- if (req->client != NULL) {
- client_princ = req->client->princ;
+ if (client != NULL) {
+ ks_client_princ = client->princ;
} else {
- client_princ = req->client_princ;
+ ks_client_princ = client_princ;
}
- is_as_req = ((req->flags & KRB5_KDB_FLAG_CLIENT_REFERRALS_ONLY) != 0);
+ is_as_req = ((flags & KRB5_KDB_FLAG_CLIENT_REFERRALS_ONLY) != 0);
- if (is_as_req && (req->flags & KRB5_KDB_FLAG_INCLUDE_PAC)) {
+ if (is_as_req && (flags & KRB5_KDB_FLAG_INCLUDE_PAC)) {
- code = ks_get_pac(context, req->client, &pac);
+ code = ks_get_pac(context, client, &pac);
if (code != 0) {
goto done;
}
}
if (!is_as_req) {
- code = ks_verify_pac(context, client_princ, req, &pac);
+ code = ks_verify_pac(context, flags, ks_client_princ, client,
+ server_key, krbtgt_key, authtime,
+ tgt_auth_data, &pac);
if (code != 0) {
goto done;
}
}
- if (pac == NULL && req->client != NULL) {
+ if (pac == NULL && client != NULL) {
- code = ks_get_pac(context, req->client, &pac);
+ code = ks_get_pac(context, client, &pac);
if (code != 0) {
goto done;
}
goto done;
}
- code = krb5int_pac_sign(context, pac, req->authtime, client_princ,
- req->server_key, req->krbtgt_key, &pac_data);
+ code = krb5int_pac_sign(context, pac, authtime, ks_client_princ,
+ server_key, krbtgt_key, &pac_data);
if (code != 0) {
goto done;
}
code = krb5_encode_authdata_container(context,
KRB5_AUTHDATA_IF_RELEVANT,
authdata,
- &rep->auth_data);
+ signed_auth_data);
if (code != 0) {
goto done;
}
krb5_tl_data *tl_data = NULL;
int i, j;
+ if (entry == NULL) {
+ return;
+ }
+
if (entry->e_data) {
KS_FREE_DB_ENTRY(ks, (struct hdb_entry_ex *)(entry->e_data));
}
free(entry->key_data);
}
- memset(entry, 0, sizeof(*entry));
+ free(entry);
}
#if 0
krb5_error_code
ks_unmarshal_hdb_entry(krb5_context context,
struct hdb_entry_ex *hentry_ex,
- krb5_db_entry *kentry)
+ krb5_db_entry **kentry_ptr)
{
const hdb_entry *hentry = &hentry_ex->entry;
+ krb5_db_entry *kentry;
krb5_error_code code;
unsigned int i;
- memset(kentry, 0, sizeof(*kentry));
+ *kentry_ptr = NULL;
+
+ kentry = k5alloc(sizeof(*kentry), &code);
+ if (kentry == NULL) {
+ return code;
+ }
kentry->magic = KRB5_KDB_MAGIC_NUMBER;
kentry->len = KRB5_KDB_V1_BASE_LENGTH;
kentry->e_data = (void *)hentry_ex;
+ *kentry_ptr = kentry;
+
cleanup:
if (code != 0) {
ks_free_krb5_db_entry(context, kentry);