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"
32 #define DBGC_CLASS DBGC_KERBEROS
34 static int SDBFlags_to_kflags(const struct SDBFlags
*s
,
40 *k
|= KRB5_KDB_DISALLOW_TGT_BASED
;
42 /* The forwardable and proxiable flags are set according to client and
43 * server attributes. */
44 if (!s
->forwardable
) {
45 *k
|= KRB5_KDB_DISALLOW_FORWARDABLE
;
48 *k
|= KRB5_KDB_DISALLOW_PROXIABLE
;
63 *k
|= KRB5_KDB_DISALLOW_ALL_TIX
;
65 if (s
->require_preauth
) {
66 *k
|= KRB5_KDB_REQUIRES_PRE_AUTH
;
69 *k
|= KRB5_KDB_PWCHANGE_SERVICE
;
73 * Do not set KRB5_KDB_REQUIRES_HW_AUTH as this would tell the client
74 * to enforce hardware authentication. It prevents the use of files
75 * based public key authentication which we use for testing.
77 if (s
->require_hwauth
) {
78 *k
|= KRB5_KDB_REQUIRES_HW_AUTH
;
81 if (s
->ok_as_delegate
) {
82 *k
|= KRB5_KDB_OK_AS_DELEGATE
;
84 if (s
->user_to_user
) {
90 if (s
->trusted_for_delegation
) {
91 *k
|= KRB5_KDB_OK_TO_AUTH_AS_DELEGATE
;
93 if (s
->allow_kerberos4
) {
96 if (s
->allow_digest
) {
99 if (s
->no_auth_data_reqd
) {
100 *k
|= KRB5_KDB_NO_AUTH_DATA_REQUIRED
;
106 static int sdb_event_to_kmod(krb5_context context
,
107 const struct sdb_event
*s
,
111 krb5_principal principal
= NULL
;
113 if (s
->principal
!= NULL
) {
114 ret
= krb5_copy_principal(context
,
122 ret
= krb5_dbe_update_mod_princ_data(context
,
126 krb5_free_principal(context
, principal
);
131 /* sets up salt on the 2nd array position */
133 static int sdb_salt_to_krb5_key_data(const struct sdb_salt
*s
,
138 /* for now use the special mechanism where the MIT KDC creates the salt
140 case 3: /* FIXME KRB5_PW_SALT */
141 k
->key_data_type
[1] = KRB5_KDB_SALTTYPE_NORMAL
;
145 k->key_data_type[1] = KRB5_KDB_SALTTYPE_AFS3;
150 k
->key_data_type
[1] = KRB5_KDB_SALTTYPE_SPECIAL
;
154 k
->key_data_contents
[1] = malloc(s
->salt
.length
);
155 if (k
->key_data_contents
[1] == NULL
) {
158 memcpy(k
->key_data_contents
[1],
161 k
->key_data_length
[1] = s
->salt
.length
;
166 static int sdb_key_to_krb5_key_data(const struct sdb_key
*s
,
174 k
->key_data_ver
= KRB5_KDB_V1_KEY_DATA_ARRAY
;
175 k
->key_data_kvno
= kvno
;
177 k
->key_data_type
[0] = KRB5_KEY_TYPE(&s
->key
);
178 k
->key_data_length
[0] = KRB5_KEY_LENGTH(&s
->key
);
179 k
->key_data_contents
[0] = malloc(k
->key_data_length
[0]);
180 if (k
->key_data_contents
[0] == NULL
) {
184 memcpy(k
->key_data_contents
[0],
185 KRB5_KEY_DATA(&s
->key
),
186 k
->key_data_length
[0]);
188 if (s
->salt
!= NULL
) {
189 ret
= sdb_salt_to_krb5_key_data(s
->salt
, k
);
191 memset(k
->key_data_contents
[0], 0, k
->key_data_length
[0]);
192 free(k
->key_data_contents
[0]);
199 static void free_krb5_db_entry(krb5_context context
,
202 krb5_tl_data
*tl_data_next
= NULL
;
203 krb5_tl_data
*tl_data
= NULL
;
210 krb5_free_principal(context
, k
->princ
);
212 for (tl_data
= k
->tl_data
; tl_data
; tl_data
= tl_data_next
) {
213 tl_data_next
= tl_data
->tl_data_next
;
214 if (tl_data
->tl_data_contents
!= NULL
) {
215 free(tl_data
->tl_data_contents
);
220 if (k
->key_data
!= NULL
) {
221 for (i
= 0; i
< k
->n_key_data
; i
++) {
222 for (j
= 0; j
< k
->key_data
[i
].key_data_ver
; j
++) {
223 if (k
->key_data
[i
].key_data_length
[j
] != 0) {
224 if (k
->key_data
[i
].key_data_contents
[j
] != NULL
) {
225 BURN_PTR_SIZE(k
->key_data
[i
].key_data_contents
[j
], k
->key_data
[i
].key_data_length
[j
]);
226 free(k
->key_data
[i
].key_data_contents
[j
]);
229 k
->key_data
[i
].key_data_contents
[j
] = NULL
;
230 k
->key_data
[i
].key_data_length
[j
] = 0;
231 k
->key_data
[i
].key_data_type
[j
] = 0;
240 int sdb_entry_to_krb5_db_entry(krb5_context context
,
241 const struct sdb_entry
*s
,
244 struct samba_kdc_entry
*ske
= s
->skdc_entry
;
250 k
->magic
= KRB5_KDB_MAGIC_NUMBER
;
251 k
->len
= KRB5_KDB_V1_BASE_LENGTH
;
253 ret
= krb5_copy_principal(context
,
257 free_krb5_db_entry(context
, k
);
261 ret
= SDBFlags_to_kflags(&s
->flags
,
264 free_krb5_db_entry(context
, k
);
268 if (s
->max_life
!= NULL
) {
269 k
->max_life
= *s
->max_life
;
271 if (s
->max_renew
!= NULL
) {
272 k
->max_renewable_life
= *s
->max_renew
;
274 if (s
->valid_end
!= NULL
) {
275 k
->expiration
= *s
->valid_end
;
277 if (s
->pw_end
!= NULL
) {
278 k
->pw_expiration
= *s
->pw_end
;
283 /* fail_auth_count */
287 * If we leave early when looking up the realm, we do not have all
288 * information about a principal. We need to construct a db entry
289 * with minimal information, so skip this part.
291 if (s
->created_by
.time
!= 0) {
292 ret
= sdb_event_to_kmod(context
,
293 s
->modified_by
? s
->modified_by
: &s
->created_by
,
296 free_krb5_db_entry(context
, k
);
301 /* FIXME: TODO HDB Extensions */
304 * Don't copy keys (allow password auth) if s->flags.require_hwauth is
305 * set which translates to UF_SMARTCARD_REQUIRED.
307 if (s
->keys
.len
> 0 && s
->flags
.require_hwauth
== 0) {
308 k
->key_data
= malloc(s
->keys
.len
* sizeof(krb5_key_data
));
309 if (k
->key_data
== NULL
) {
310 free_krb5_db_entry(context
, k
);
314 for (i
=0; i
< s
->keys
.len
; i
++) {
315 ret
= sdb_key_to_krb5_key_data(&s
->keys
.val
[i
],
319 free_krb5_db_entry(context
, k
);
327 k
->e_data
= (void *)ske
;