2 Unix SMB/CIFS implementation.
4 Database Glue between Samba and the KDC
6 Copyright (C) Guenther Deschner <gd@samba.org> 2014
7 Copyright (C) Andreas Schneider <asn@samba.org> 2014
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; either version 3 of the License, or
12 (at your option) any later version.
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
20 You should have received a copy of the GNU General Public License
21 along with this program. If not, see <http://www.gnu.org/licenses/>.
28 #include "kdc/samba_kdc.h"
29 #include "lib/krb5_wrap/krb5_samba.h"
31 static int SDBFlags_to_kflags(const struct SDBFlags *s,
37 *k |= KRB5_KDB_DISALLOW_TGT_BASED;
39 if (!s->forwardable) {
40 *k |= KRB5_KDB_DISALLOW_FORWARDABLE;
43 *k |= KRB5_KDB_DISALLOW_PROXIABLE;
46 *k |= KRB5_KDB_DISALLOW_RENEWABLE;
49 *k |= KRB5_KDB_DISALLOW_POSTDATED;
52 *k |= KRB5_KDB_DISALLOW_SVR;
58 *k |= KRB5_KDB_DISALLOW_ALL_TIX;
60 if (s->require_preauth) {
61 *k |= KRB5_KDB_REQUIRES_PRE_AUTH;
64 *k |= KRB5_KDB_PWCHANGE_SERVICE;
66 if (s->require_hwauth) {
67 *k |= KRB5_KDB_REQUIRES_HW_AUTH;
69 if (s->ok_as_delegate) {
70 *k |= KRB5_KDB_OK_AS_DELEGATE;
72 if (s->user_to_user) {
78 if (s->trusted_for_delegation) {
79 *k |= KRB5_KDB_OK_TO_AUTH_AS_DELEGATE;
81 if (s->allow_kerberos4) {
84 if (s->allow_digest) {
91 static int sdb_event_to_kmod(krb5_context context,
92 const struct sdb_event *s,
96 krb5_principal principal = NULL;
98 if (s->principal != NULL) {
99 ret = krb5_copy_principal(context,
107 ret = krb5_dbe_update_mod_princ_data(context,
111 krb5_free_principal(context, principal);
116 /* sets up salt on the 2nd array position */
118 static int sdb_salt_to_krb5_key_data(const struct sdb_salt *s,
123 /* for now use the special mechanism where the MIT KDC creates the salt
125 case 3: /* FIXME KRB5_PW_SALT */
126 k->key_data_type[1] = KRB5_KDB_SALTTYPE_NORMAL;
130 k->key_data_type[1] = KRB5_KDB_SALTTYPE_AFS3;
135 k->key_data_type[1] = KRB5_KDB_SALTTYPE_SPECIAL;
139 k->key_data_contents[1] = malloc(s->salt.length);
140 if (k->key_data_contents[1] == NULL) {
143 memcpy(k->key_data_contents[1],
146 k->key_data_length[1] = s->salt.length;
151 static int sdb_key_to_krb5_key_data(const struct sdb_key *s,
159 k->key_data_ver = KRB5_KDB_V1_KEY_DATA_ARRAY;
160 k->key_data_kvno = kvno;
162 k->key_data_type[0] = KRB5_KEY_TYPE(&s->key);
163 k->key_data_length[0] = KRB5_KEY_LENGTH(&s->key);
164 k->key_data_contents[0] = malloc(k->key_data_length[0]);
165 if (k->key_data_contents[0] == NULL) {
169 memcpy(k->key_data_contents[0],
170 KRB5_KEY_DATA(&s->key),
171 k->key_data_length[0]);
173 if (s->salt != NULL) {
174 ret = sdb_salt_to_krb5_key_data(s->salt, k);
176 memset(k->key_data_contents[0], 0, k->key_data_length[0]);
177 free(k->key_data_contents[0]);
184 static void free_krb5_db_entry(krb5_context context,
187 krb5_tl_data *tl_data_next = NULL;
188 krb5_tl_data *tl_data = NULL;
195 krb5_free_principal(context, k->princ);
197 for (tl_data = k->tl_data; tl_data; tl_data = tl_data_next) {
198 tl_data_next = tl_data->tl_data_next;
199 if (tl_data->tl_data_contents != NULL) {
200 free(tl_data->tl_data_contents);
205 if (k->key_data != NULL) {
206 for (i = 0; i < k->n_key_data; i++) {
207 for (j = 0; j < k->key_data[i].key_data_ver; j++) {
208 if (k->key_data[i].key_data_length[j] != 0) {
209 if (k->key_data[i].key_data_contents[j] != NULL) {
210 memset(k->key_data[i].key_data_contents[j], 0, k->key_data[i].key_data_length[j]);
211 free(k->key_data[i].key_data_contents[j]);
214 k->key_data[i].key_data_contents[j] = NULL;
215 k->key_data[i].key_data_length[j] = 0;
216 k->key_data[i].key_data_type[j] = 0;
225 static int sdb_entry_ex_to_krb5_db_entry(krb5_context context,
226 const struct sdb_entry *s,
232 k->magic = KRB5_KDB_MAGIC_NUMBER;
233 k->len = KRB5_KDB_V1_BASE_LENGTH;
235 ret = krb5_copy_principal(context,
239 free_krb5_db_entry(context, k);
243 ret = SDBFlags_to_kflags(&s->flags,
246 free_krb5_db_entry(context, k);
250 if (s->max_life != NULL) {
251 k->max_life = *s->max_life;
253 if (s->max_renew != NULL) {
254 k->max_renewable_life = *s->max_renew;
256 if (s->valid_end != NULL) {
257 k->expiration = *s->valid_end;
259 if (s->pw_end != NULL) {
260 k->pw_expiration = *s->pw_end;
265 /* fail_auth_count */
268 ret = sdb_event_to_kmod(context,
269 s->modified_by ? s->modified_by : &s->created_by,
272 free_krb5_db_entry(context, k);
276 /* FIXME: TODO HDB Extensions */
279 k->key_data = malloc(s->keys.len * sizeof(krb5_key_data));
280 if (k->key_data == NULL) {
281 free_krb5_db_entry(context, k);
285 for (i=0; i < s->keys.len; i++) {
287 ret = sdb_key_to_krb5_key_data(&s->keys.val[i],
291 free_krb5_db_entry(context, k);
301 static int samba_kdc_kdb_entry_destructor(struct samba_kdc_entry *p)
303 krb5_db_entry *entry_ex = p->entry_ex;
305 krb5_context context;
307 ret = krb5_init_context(&context);
312 free_krb5_db_entry(context, entry_ex);
313 krb5_free_context(context);
319 int sdb_entry_ex_to_kdb_entry_ex(krb5_context context,
320 const struct sdb_entry_ex *s,
323 struct samba_kdc_entry *skdc_entry;
327 skdc_entry = talloc_get_type(s->ctx, struct samba_kdc_entry);
329 k->e_data = (void *)skdc_entry;
331 talloc_set_destructor(skdc_entry, samba_kdc_kdb_entry_destructor);
333 return sdb_entry_ex_to_krb5_db_entry(context, &s->entry, k);