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 /* The forwardable and proxiable flags are set according to client and
40 * server attributes. */
41 if (!s
->forwardable
) {
42 *k
|= KRB5_KDB_DISALLOW_FORWARDABLE
;
45 *k
|= KRB5_KDB_DISALLOW_PROXIABLE
;
60 *k
|= KRB5_KDB_DISALLOW_ALL_TIX
;
62 if (s
->require_preauth
) {
63 *k
|= KRB5_KDB_REQUIRES_PRE_AUTH
;
66 *k
|= KRB5_KDB_PWCHANGE_SERVICE
;
68 if (s
->require_hwauth
) {
69 *k
|= KRB5_KDB_REQUIRES_HW_AUTH
;
71 if (s
->ok_as_delegate
) {
72 *k
|= KRB5_KDB_OK_AS_DELEGATE
;
74 if (s
->user_to_user
) {
80 if (s
->trusted_for_delegation
) {
81 *k
|= KRB5_KDB_OK_TO_AUTH_AS_DELEGATE
;
83 if (s
->allow_kerberos4
) {
86 if (s
->allow_digest
) {
93 static int sdb_event_to_kmod(krb5_context context
,
94 const struct sdb_event
*s
,
98 krb5_principal principal
= NULL
;
100 if (s
->principal
!= NULL
) {
101 ret
= krb5_copy_principal(context
,
109 ret
= krb5_dbe_update_mod_princ_data(context
,
113 krb5_free_principal(context
, principal
);
118 /* sets up salt on the 2nd array position */
120 static int sdb_salt_to_krb5_key_data(const struct sdb_salt
*s
,
125 /* for now use the special mechanism where the MIT KDC creates the salt
127 case 3: /* FIXME KRB5_PW_SALT */
128 k
->key_data_type
[1] = KRB5_KDB_SALTTYPE_NORMAL
;
132 k->key_data_type[1] = KRB5_KDB_SALTTYPE_AFS3;
137 k
->key_data_type
[1] = KRB5_KDB_SALTTYPE_SPECIAL
;
141 k
->key_data_contents
[1] = malloc(s
->salt
.length
);
142 if (k
->key_data_contents
[1] == NULL
) {
145 memcpy(k
->key_data_contents
[1],
148 k
->key_data_length
[1] = s
->salt
.length
;
153 static int sdb_key_to_krb5_key_data(const struct sdb_key
*s
,
161 k
->key_data_ver
= KRB5_KDB_V1_KEY_DATA_ARRAY
;
162 k
->key_data_kvno
= kvno
;
164 k
->key_data_type
[0] = KRB5_KEY_TYPE(&s
->key
);
165 k
->key_data_length
[0] = KRB5_KEY_LENGTH(&s
->key
);
166 k
->key_data_contents
[0] = malloc(k
->key_data_length
[0]);
167 if (k
->key_data_contents
[0] == NULL
) {
171 memcpy(k
->key_data_contents
[0],
172 KRB5_KEY_DATA(&s
->key
),
173 k
->key_data_length
[0]);
175 if (s
->salt
!= NULL
) {
176 ret
= sdb_salt_to_krb5_key_data(s
->salt
, k
);
178 memset(k
->key_data_contents
[0], 0, k
->key_data_length
[0]);
179 free(k
->key_data_contents
[0]);
186 static void free_krb5_db_entry(krb5_context context
,
189 krb5_tl_data
*tl_data_next
= NULL
;
190 krb5_tl_data
*tl_data
= NULL
;
197 krb5_free_principal(context
, k
->princ
);
199 for (tl_data
= k
->tl_data
; tl_data
; tl_data
= tl_data_next
) {
200 tl_data_next
= tl_data
->tl_data_next
;
201 if (tl_data
->tl_data_contents
!= NULL
) {
202 free(tl_data
->tl_data_contents
);
207 if (k
->key_data
!= NULL
) {
208 for (i
= 0; i
< k
->n_key_data
; i
++) {
209 for (j
= 0; j
< k
->key_data
[i
].key_data_ver
; j
++) {
210 if (k
->key_data
[i
].key_data_length
[j
] != 0) {
211 if (k
->key_data
[i
].key_data_contents
[j
] != NULL
) {
212 memset(k
->key_data
[i
].key_data_contents
[j
], 0, k
->key_data
[i
].key_data_length
[j
]);
213 free(k
->key_data
[i
].key_data_contents
[j
]);
216 k
->key_data
[i
].key_data_contents
[j
] = NULL
;
217 k
->key_data
[i
].key_data_length
[j
] = 0;
218 k
->key_data
[i
].key_data_type
[j
] = 0;
227 static int sdb_entry_ex_to_krb5_db_entry(krb5_context context
,
228 const struct sdb_entry
*s
,
234 k
->magic
= KRB5_KDB_MAGIC_NUMBER
;
235 k
->len
= KRB5_KDB_V1_BASE_LENGTH
;
237 ret
= krb5_copy_principal(context
,
241 free_krb5_db_entry(context
, k
);
245 ret
= SDBFlags_to_kflags(&s
->flags
,
248 free_krb5_db_entry(context
, k
);
252 if (s
->max_life
!= NULL
) {
253 k
->max_life
= *s
->max_life
;
255 if (s
->max_renew
!= NULL
) {
256 k
->max_renewable_life
= *s
->max_renew
;
258 if (s
->valid_end
!= NULL
) {
259 k
->expiration
= *s
->valid_end
;
261 if (s
->pw_end
!= NULL
) {
262 k
->pw_expiration
= *s
->pw_end
;
267 /* fail_auth_count */
271 * If we leave early when looking up the realm, we do not have all
272 * information about a principal. We need to construct a db entry
273 * with minimal information, so skip this part.
275 if (s
->created_by
.time
!= 0) {
276 ret
= sdb_event_to_kmod(context
,
277 s
->modified_by
? s
->modified_by
: &s
->created_by
,
280 free_krb5_db_entry(context
, k
);
285 /* FIXME: TODO HDB Extensions */
287 if (s
->keys
.len
> 0) {
288 k
->key_data
= malloc(s
->keys
.len
* sizeof(krb5_key_data
));
289 if (k
->key_data
== NULL
) {
290 free_krb5_db_entry(context
, k
);
294 for (i
=0; i
< s
->keys
.len
; i
++) {
295 ret
= sdb_key_to_krb5_key_data(&s
->keys
.val
[i
],
299 free_krb5_db_entry(context
, k
);
310 static int samba_kdc_kdb_entry_destructor(struct samba_kdc_entry
*p
)
312 krb5_db_entry
*entry_ex
= p
->entry_ex
;
314 krb5_context context
;
316 if (entry_ex
->e_data
!= NULL
) {
317 struct samba_kdc_entry
*skdc_entry
;
319 skdc_entry
= talloc_get_type(entry_ex
->e_data
,
320 struct samba_kdc_entry
);
321 talloc_set_destructor(skdc_entry
, NULL
);
322 entry_ex
->e_data
= NULL
;
325 ret
= smb_krb5_init_context_common(&context
);
327 DBG_ERR("kerberos init context failed (%s)\n",
332 krb5_db_free_principal(context
, entry_ex
);
333 krb5_free_context(context
);
338 int sdb_entry_ex_to_kdb_entry_ex(krb5_context context
,
339 const struct sdb_entry_ex
*s
,
344 if (s
->ctx
!= NULL
) {
345 struct samba_kdc_entry
*skdc_entry
;
347 skdc_entry
= talloc_get_type(s
->ctx
, struct samba_kdc_entry
);
349 k
->e_data
= (void *)skdc_entry
;
351 talloc_set_destructor(skdc_entry
,
352 samba_kdc_kdb_entry_destructor
);
355 return sdb_entry_ex_to_krb5_db_entry(context
, &s
->entry
, k
);