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
;
40 * Do not set any disallow rules for forwardable, proxiable,
41 * renewable, postdate and server.
43 * The KDC will take care setting the flags based on the incoming
65 *k
|= KRB5_KDB_DISALLOW_ALL_TIX
;
67 if (s
->require_preauth
) {
68 *k
|= KRB5_KDB_REQUIRES_PRE_AUTH
;
71 *k
|= KRB5_KDB_PWCHANGE_SERVICE
;
73 if (s
->require_hwauth
) {
74 *k
|= KRB5_KDB_REQUIRES_HW_AUTH
;
76 if (s
->ok_as_delegate
) {
77 *k
|= KRB5_KDB_OK_AS_DELEGATE
;
79 if (s
->user_to_user
) {
85 if (s
->trusted_for_delegation
) {
86 *k
|= KRB5_KDB_OK_TO_AUTH_AS_DELEGATE
;
88 if (s
->allow_kerberos4
) {
91 if (s
->allow_digest
) {
98 static int sdb_event_to_kmod(krb5_context context
,
99 const struct sdb_event
*s
,
103 krb5_principal principal
= NULL
;
105 if (s
->principal
!= NULL
) {
106 ret
= krb5_copy_principal(context
,
114 ret
= krb5_dbe_update_mod_princ_data(context
,
118 krb5_free_principal(context
, principal
);
123 /* sets up salt on the 2nd array position */
125 static int sdb_salt_to_krb5_key_data(const struct sdb_salt
*s
,
130 /* for now use the special mechanism where the MIT KDC creates the salt
132 case 3: /* FIXME KRB5_PW_SALT */
133 k
->key_data_type
[1] = KRB5_KDB_SALTTYPE_NORMAL
;
137 k->key_data_type[1] = KRB5_KDB_SALTTYPE_AFS3;
142 k
->key_data_type
[1] = KRB5_KDB_SALTTYPE_SPECIAL
;
146 k
->key_data_contents
[1] = malloc(s
->salt
.length
);
147 if (k
->key_data_contents
[1] == NULL
) {
150 memcpy(k
->key_data_contents
[1],
153 k
->key_data_length
[1] = s
->salt
.length
;
158 static int sdb_key_to_krb5_key_data(const struct sdb_key
*s
,
166 k
->key_data_ver
= KRB5_KDB_V1_KEY_DATA_ARRAY
;
167 k
->key_data_kvno
= kvno
;
169 k
->key_data_type
[0] = KRB5_KEY_TYPE(&s
->key
);
170 k
->key_data_length
[0] = KRB5_KEY_LENGTH(&s
->key
);
171 k
->key_data_contents
[0] = malloc(k
->key_data_length
[0]);
172 if (k
->key_data_contents
[0] == NULL
) {
176 memcpy(k
->key_data_contents
[0],
177 KRB5_KEY_DATA(&s
->key
),
178 k
->key_data_length
[0]);
180 if (s
->salt
!= NULL
) {
181 ret
= sdb_salt_to_krb5_key_data(s
->salt
, k
);
183 memset(k
->key_data_contents
[0], 0, k
->key_data_length
[0]);
184 free(k
->key_data_contents
[0]);
191 static void free_krb5_db_entry(krb5_context context
,
194 krb5_tl_data
*tl_data_next
= NULL
;
195 krb5_tl_data
*tl_data
= NULL
;
202 krb5_free_principal(context
, k
->princ
);
204 for (tl_data
= k
->tl_data
; tl_data
; tl_data
= tl_data_next
) {
205 tl_data_next
= tl_data
->tl_data_next
;
206 if (tl_data
->tl_data_contents
!= NULL
) {
207 free(tl_data
->tl_data_contents
);
212 if (k
->key_data
!= NULL
) {
213 for (i
= 0; i
< k
->n_key_data
; i
++) {
214 for (j
= 0; j
< k
->key_data
[i
].key_data_ver
; j
++) {
215 if (k
->key_data
[i
].key_data_length
[j
] != 0) {
216 if (k
->key_data
[i
].key_data_contents
[j
] != NULL
) {
217 memset(k
->key_data
[i
].key_data_contents
[j
], 0, k
->key_data
[i
].key_data_length
[j
]);
218 free(k
->key_data
[i
].key_data_contents
[j
]);
221 k
->key_data
[i
].key_data_contents
[j
] = NULL
;
222 k
->key_data
[i
].key_data_length
[j
] = 0;
223 k
->key_data
[i
].key_data_type
[j
] = 0;
232 static int sdb_entry_ex_to_krb5_db_entry(krb5_context context
,
233 const struct sdb_entry
*s
,
239 k
->magic
= KRB5_KDB_MAGIC_NUMBER
;
240 k
->len
= KRB5_KDB_V1_BASE_LENGTH
;
242 ret
= krb5_copy_principal(context
,
246 free_krb5_db_entry(context
, k
);
250 ret
= SDBFlags_to_kflags(&s
->flags
,
253 free_krb5_db_entry(context
, k
);
257 if (s
->max_life
!= NULL
) {
258 k
->max_life
= *s
->max_life
;
260 if (s
->max_renew
!= NULL
) {
261 k
->max_renewable_life
= *s
->max_renew
;
263 if (s
->valid_end
!= NULL
) {
264 k
->expiration
= *s
->valid_end
;
266 if (s
->pw_end
!= NULL
) {
267 k
->pw_expiration
= *s
->pw_end
;
272 /* fail_auth_count */
276 * If we leave early when looking up the realm, we do not have all
277 * information about a principal. We need to construct a db entry
278 * with minimal information, so skip this part.
280 if (s
->created_by
.time
!= 0) {
281 ret
= sdb_event_to_kmod(context
,
282 s
->modified_by
? s
->modified_by
: &s
->created_by
,
285 free_krb5_db_entry(context
, k
);
290 /* FIXME: TODO HDB Extensions */
292 if (s
->keys
.len
> 0) {
293 k
->key_data
= malloc(s
->keys
.len
* sizeof(krb5_key_data
));
294 if (k
->key_data
== NULL
) {
295 free_krb5_db_entry(context
, k
);
299 for (i
=0; i
< s
->keys
.len
; i
++) {
300 ret
= sdb_key_to_krb5_key_data(&s
->keys
.val
[i
],
304 free_krb5_db_entry(context
, k
);
315 static int samba_kdc_kdb_entry_destructor(struct samba_kdc_entry
*p
)
317 krb5_db_entry
*entry_ex
= p
->entry_ex
;
319 krb5_context context
;
321 if (entry_ex
->e_data
!= NULL
) {
322 struct samba_kdc_entry
*skdc_entry
;
324 skdc_entry
= talloc_get_type(entry_ex
->e_data
,
325 struct samba_kdc_entry
);
326 talloc_set_destructor(skdc_entry
, NULL
);
327 entry_ex
->e_data
= NULL
;
330 ret
= krb5_init_context(&context
);
335 krb5_db_free_principal(context
, entry_ex
);
336 krb5_free_context(context
);
341 int sdb_entry_ex_to_kdb_entry_ex(krb5_context context
,
342 const struct sdb_entry_ex
*s
,
347 if (s
->ctx
!= NULL
) {
348 struct samba_kdc_entry
*skdc_entry
;
350 skdc_entry
= talloc_get_type(s
->ctx
, struct samba_kdc_entry
);
352 k
->e_data
= (void *)skdc_entry
;
354 talloc_set_destructor(skdc_entry
,
355 samba_kdc_kdb_entry_destructor
);
358 return sdb_entry_ex_to_krb5_db_entry(context
, &s
->entry
, k
);