Cleanup references to module objects returned from PyImport_ImportModule
[gd/samba-autobuild/.git] / source4 / kdc / sdb_to_hdb.c
1 /*
2    Unix SMB/CIFS implementation.
3
4    Database Glue between Samba and the KDC
5
6    Copyright (C) Guenther Deschner <gd@samba.org> 2014
7    Copyright (C) Andreas Schneider <asn@samba.org> 2014
8
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.
13
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.
18
19
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/>.
22 */
23
24 #include "includes.h"
25 #include <hdb.h>
26 #include "sdb.h"
27 #include "sdb_hdb.h"
28 #include "lib/krb5_wrap/krb5_samba.h"
29 #include "kdc/samba_kdc.h"
30
31 static void sdb_flags_to_hdb_flags(const struct SDBFlags *s,
32                                    HDBFlags *h)
33 {
34         SMB_ASSERT(sizeof(struct SDBFlags) == sizeof(HDBFlags));
35
36         h->initial = s->initial;
37         h->forwardable = s->forwardable;
38         h->proxiable = s->proxiable;
39         h->renewable = s->renewable;
40         h->postdate = s->postdate;
41         h->server = s->server;
42         h->client = s->client;
43         h->invalid = s->invalid;
44         h->require_preauth = s->require_preauth;
45         h->change_pw = s->change_pw;
46         h->require_hwauth = s->require_hwauth;
47         h->ok_as_delegate = s->ok_as_delegate;
48         h->user_to_user = s->user_to_user;
49         h->immutable = s->immutable;
50         h->trusted_for_delegation = s->trusted_for_delegation;
51         h->allow_kerberos4 = s->allow_kerberos4;
52         h->allow_digest = s->allow_digest;
53         h->locked_out = s->locked_out;
54         h->_unused18 = s->_unused18;
55         h->_unused19 = s->_unused19;
56         h->_unused20 = s->_unused20;
57         h->_unused21 = s->_unused21;
58         h->_unused22 = s->_unused22;
59         h->_unused23 = s->_unused23;
60         h->_unused24 = s->_unused24;
61         h->_unused25 = s->_unused25;
62         h->_unused26 = s->_unused26;
63         h->_unused27 = s->_unused27;
64         h->_unused28 = s->_unused28;
65         h->_unused29 = s->_unused29;
66         h->_unused30 = s->_unused30;
67         h->do_not_store = s->do_not_store;
68 }
69
70 static int sdb_salt_to_Salt(const struct sdb_salt *s, Salt *h)
71 {
72         int ret;
73
74         h->type = s->type;
75         ret = smb_krb5_copy_data_contents(&h->salt, s->salt.data, s->salt.length);
76         if (ret != 0) {
77                 free_Salt(h);
78                 return ENOMEM;
79         }
80         h->opaque = NULL;
81
82         return 0;
83 }
84
85 static int sdb_key_to_Key(const struct sdb_key *s, Key *h)
86 {
87         int rc;
88
89         if (s->mkvno != NULL) {
90                 h->mkvno = malloc(sizeof(unsigned int));
91                 if (h->mkvno == NULL) {
92                         goto error_nomem;
93                 }
94                 *h->mkvno = *s->mkvno;
95         } else {
96                 h->mkvno = NULL;
97         }
98
99         h->key.keytype = s->key.keytype;
100         rc = smb_krb5_copy_data_contents(&h->key.keyvalue,
101                                          s->key.keyvalue.data,
102                                          s->key.keyvalue.length);
103         if (rc != 0) {
104                 goto error_nomem;
105         }
106
107         if (s->salt != NULL) {
108                 h->salt = malloc(sizeof(Salt));
109                 if (h->salt == NULL) {
110                         goto error_nomem;
111                 }
112
113                 rc = sdb_salt_to_Salt(s->salt,
114                                       h->salt);
115                 if (rc != 0) {
116                         goto error_nomem;
117                 }
118         } else {
119                 h->salt = NULL;
120         }
121
122         return 0;
123
124 error_nomem:
125         free_Key(h);
126         return ENOMEM;
127 }
128
129 static int sdb_keys_to_Keys(const struct sdb_keys *s, Keys *h)
130 {
131         int ret, i;
132
133         h->len = s->len;
134         if (s->val != NULL) {
135                 h->val = malloc(h->len * sizeof(Key));
136                 if (h->val == NULL) {
137                         return ENOMEM;
138                 }
139                 for (i = 0; i < h->len; i++) {
140                         ret = sdb_key_to_Key(&s->val[i],
141                                              &h->val[i]);
142                         if (ret != 0) {
143                                 free_Keys(h);
144                                 return ENOMEM;
145                         }
146                 }
147         } else {
148                 h->val = NULL;
149         }
150
151         return 0;
152 }
153
154 static int sdb_event_to_Event(krb5_context context,
155                               const struct sdb_event *s, Event *h)
156 {
157         int ret;
158
159         if (s->principal != NULL) {
160                 ret = krb5_copy_principal(context,
161                                           s->principal,
162                                           &h->principal);
163                 if (ret != 0) {
164                         free_Event(h);
165                         return ret;
166                 }
167         } else {
168                 h->principal = NULL;
169         }
170         h->time = s->time;
171
172         return 0;
173 }
174
175
176 static int sdb_entry_to_hdb_entry(krb5_context context,
177                                   const struct sdb_entry *s,
178                                   struct hdb_entry *h)
179 {
180         unsigned int i;
181         int rc;
182
183         ZERO_STRUCTP(h);
184
185         rc = krb5_copy_principal(context,
186                                  s->principal,
187                                  &h->principal);
188         if (rc != 0) {
189                 return rc;
190         }
191
192         h->kvno = s->kvno;
193
194         rc = sdb_keys_to_Keys(&s->keys, &h->keys);
195         if (rc != 0) {
196                 goto error;
197         }
198
199         rc = sdb_event_to_Event(context,
200                                  &s->created_by,
201                                  &h->created_by);
202         if (rc != 0) {
203                 goto error;
204         }
205
206         if (s->modified_by) {
207                 h->modified_by = malloc(sizeof(Event));
208                 if (h->modified_by == NULL) {
209                         rc = ENOMEM;
210                         goto error;
211                 }
212
213                 rc = sdb_event_to_Event(context,
214                                          s->modified_by,
215                                          h->modified_by);
216                 if (rc != 0) {
217                         goto error;
218                 }
219         } else {
220                 h->modified_by = NULL;
221         }
222
223         if (s->valid_start != NULL) {
224                 h->valid_start = malloc(sizeof(KerberosTime));
225                 if (h->valid_start == NULL) {
226                         rc = ENOMEM;
227                         goto error;
228                 }
229                 *h->valid_start = *s->valid_start;
230         } else {
231                 h->valid_start = NULL;
232         }
233
234         if (s->valid_end != NULL) {
235                 h->valid_end = malloc(sizeof(KerberosTime));
236                 if (h->valid_end == NULL) {
237                         rc = ENOMEM;
238                         goto error;
239                 }
240                 *h->valid_end = *s->valid_end;
241         } else {
242                 h->valid_end = NULL;
243         }
244
245         if (s->pw_end != NULL) {
246                 h->pw_end = malloc(sizeof(KerberosTime));
247                 if (h->pw_end == NULL) {
248                         rc = ENOMEM;
249                         goto error;
250                 }
251                 *h->pw_end = *s->pw_end;
252         } else {
253                 h->pw_end = NULL;
254         }
255
256         if (s->max_life != NULL) {
257                 h->max_life = malloc(sizeof(unsigned int));
258                 if (h->max_life == NULL) {
259                         rc = ENOMEM;
260                         goto error;
261                 }
262                 *h->max_life = *s->max_life;
263         } else {
264                 h->max_life = NULL;
265         }
266
267         if (s->max_renew != NULL) {
268                 h->max_renew = malloc(sizeof(unsigned int));
269                 if (h->max_renew == NULL) {
270                         rc = ENOMEM;
271                         goto error;
272                 }
273                 *h->max_renew = *s->max_renew;
274         } else {
275                 h->max_renew = NULL;
276         }
277
278         sdb_flags_to_hdb_flags(&s->flags, &h->flags);
279
280         h->etypes = NULL;
281         if (h->keys.val != NULL) {
282                 h->etypes = malloc(sizeof(*h->etypes));
283                 if (h->etypes == NULL) {
284                         rc = ENOMEM;
285                         goto error;
286                 }
287
288                 h->etypes->len = s->keys.len;
289
290                 h->etypes->val = calloc(h->etypes->len, sizeof(int));
291                 if (h->etypes->val == NULL) {
292                         rc = ENOMEM;
293                         goto error;
294                 }
295
296                 for (i = 0; i < h->etypes->len; i++) {
297                         Key k = h->keys.val[i];
298
299                         h->etypes->val[i] = KRB5_KEY_TYPE(&(k.key));
300                 }
301         }
302
303         h->generation = NULL;
304         h->extensions = NULL; /* really sure ? FIXME */
305
306         return 0;
307 error:
308         free_hdb_entry(h);
309         return rc;
310 }
311
312 static int samba_kdc_hdb_entry_destructor(struct samba_kdc_entry *p)
313 {
314         struct hdb_entry_ex *entry_ex = p->entry_ex;
315         free_hdb_entry(&entry_ex->entry);
316
317         return 0;
318 }
319
320 static void samba_kdc_free_hdb_entry(krb5_context context,
321                                      struct hdb_entry_ex *entry_ex)
322 {
323         /* this function is called only from hdb_free_entry().
324          * Make sure we neutralize the destructor or we will
325          * get a double free later when hdb_free_entry() will
326          * try to call free_hdb_entry() */
327         talloc_set_destructor(entry_ex->ctx, NULL);
328
329         /* now proceed to free the talloc part */
330         talloc_free(entry_ex->ctx);
331 }
332
333 int sdb_entry_ex_to_hdb_entry_ex(krb5_context context,
334                                  const struct sdb_entry_ex *s,
335                                  struct hdb_entry_ex *h)
336 {
337         struct samba_kdc_entry *skdc_entry;
338
339         ZERO_STRUCTP(h);
340
341         if (s->ctx != NULL) {
342                 skdc_entry = talloc_get_type(s->ctx, struct samba_kdc_entry);
343
344                 h->ctx          = skdc_entry;
345                 h->free_entry   = samba_kdc_free_hdb_entry;
346
347                 talloc_set_destructor(skdc_entry,
348                                       samba_kdc_hdb_entry_destructor);
349         }
350
351         return sdb_entry_to_hdb_entry(context, &s->entry, &h->entry);
352 }