Line data Source code
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 "librpc/gen_ndr/security.h"
30 : #include "kdc/samba_kdc.h"
31 :
32 209651 : static void sdb_flags_to_hdb_flags(const struct SDBFlags *s,
33 : HDBFlags *h)
34 : {
35 : SMB_ASSERT(sizeof(struct SDBFlags) == sizeof(HDBFlags));
36 :
37 209651 : h->initial = s->initial;
38 209651 : h->forwardable = s->forwardable;
39 209651 : h->proxiable = s->proxiable;
40 209651 : h->renewable = s->renewable;
41 209651 : h->postdate = s->postdate;
42 209651 : h->server = s->server;
43 209651 : h->client = s->client;
44 209651 : h->invalid = s->invalid;
45 209651 : h->require_preauth = s->require_preauth;
46 209651 : h->change_pw = s->change_pw;
47 209651 : h->require_hwauth = s->require_hwauth;
48 209651 : h->ok_as_delegate = s->ok_as_delegate;
49 209651 : h->user_to_user = s->user_to_user;
50 209651 : h->immutable = s->immutable;
51 209651 : h->trusted_for_delegation = s->trusted_for_delegation;
52 209651 : h->allow_kerberos4 = s->allow_kerberos4;
53 209651 : h->allow_digest = s->allow_digest;
54 209651 : h->locked_out = s->locked_out;
55 209651 : h->require_pwchange = s->require_pwchange;
56 209651 : h->materialize = s->materialize;
57 209651 : h->virtual_keys = s->virtual_keys;
58 209651 : h->virtual = s->virtual;
59 209651 : h->synthetic = s->synthetic;
60 209651 : h->no_auth_data_reqd = s->no_auth_data_reqd;
61 209651 : h->_unused24 = s->_unused24;
62 209651 : h->_unused25 = s->_unused25;
63 209651 : h->_unused26 = s->_unused26;
64 209651 : h->_unused27 = s->_unused27;
65 209651 : h->_unused28 = s->_unused28;
66 209651 : h->_unused29 = s->_unused29;
67 209651 : h->force_canonicalize = s->force_canonicalize;
68 209651 : h->do_not_store = s->do_not_store;
69 209651 : }
70 :
71 256552 : static int sdb_salt_to_Salt(const struct sdb_salt *s, Salt *h)
72 : {
73 : int ret;
74 :
75 256552 : h->type = s->type;
76 256552 : ret = smb_krb5_copy_data_contents(&h->salt, s->salt.data, s->salt.length);
77 256552 : if (ret != 0) {
78 0 : free_Salt(h);
79 0 : return ENOMEM;
80 : }
81 256552 : h->opaque = NULL;
82 :
83 256552 : return 0;
84 : }
85 :
86 356455 : static int sdb_key_to_Key(const struct sdb_key *s, Key *h)
87 : {
88 : int rc;
89 :
90 356455 : ZERO_STRUCTP(h);
91 :
92 356455 : h->key.keytype = s->key.keytype;
93 712910 : rc = smb_krb5_copy_data_contents(&h->key.keyvalue,
94 356455 : s->key.keyvalue.data,
95 : s->key.keyvalue.length);
96 356455 : if (rc != 0) {
97 0 : goto error_nomem;
98 : }
99 :
100 356455 : if (s->salt != NULL) {
101 256552 : h->salt = malloc(sizeof(Salt));
102 256552 : if (h->salt == NULL) {
103 0 : goto error_nomem;
104 : }
105 :
106 256552 : rc = sdb_salt_to_Salt(s->salt,
107 : h->salt);
108 256552 : if (rc != 0) {
109 0 : goto error_nomem;
110 : }
111 : } else {
112 99903 : h->salt = NULL;
113 : }
114 :
115 356455 : return 0;
116 :
117 0 : error_nomem:
118 0 : free_Key(h);
119 0 : return ENOMEM;
120 : }
121 :
122 209651 : static int sdb_keys_to_Keys(const struct sdb_keys *s, Keys *h)
123 : {
124 : int ret, i;
125 :
126 209651 : h->len = s->len;
127 209651 : if (s->val != NULL) {
128 208792 : h->val = malloc(h->len * sizeof(Key));
129 208792 : if (h->val == NULL) {
130 0 : return ENOMEM;
131 : }
132 565247 : for (i = 0; i < h->len; i++) {
133 356455 : ret = sdb_key_to_Key(&s->val[i],
134 356455 : &h->val[i]);
135 356455 : if (ret != 0) {
136 0 : free_Keys(h);
137 0 : return ENOMEM;
138 : }
139 : }
140 : } else {
141 859 : h->val = NULL;
142 : }
143 :
144 209651 : return 0;
145 : }
146 :
147 209651 : static int sdb_event_to_Event(krb5_context context,
148 : const struct sdb_event *s, Event *h)
149 : {
150 : int ret;
151 :
152 209651 : if (s->principal != NULL) {
153 1147 : ret = krb5_copy_principal(context,
154 1147 : s->principal,
155 1147 : &h->principal);
156 1147 : if (ret != 0) {
157 0 : free_Event(h);
158 0 : return ret;
159 : }
160 : } else {
161 208504 : h->principal = NULL;
162 : }
163 209651 : h->time = s->time;
164 :
165 209651 : return 0;
166 : }
167 :
168 209651 : int sdb_entry_to_hdb_entry(krb5_context context,
169 : const struct sdb_entry *s,
170 : hdb_entry *h)
171 : {
172 209651 : struct samba_kdc_entry *ske = s->skdc_entry;
173 : unsigned int i;
174 : int rc;
175 :
176 209651 : ZERO_STRUCTP(h);
177 :
178 209651 : rc = krb5_copy_principal(context,
179 209651 : s->principal,
180 209651 : &h->principal);
181 209651 : if (rc != 0) {
182 0 : return rc;
183 : }
184 :
185 209651 : h->kvno = s->kvno;
186 :
187 209651 : rc = sdb_keys_to_Keys(&s->keys, &h->keys);
188 209651 : if (rc != 0) {
189 0 : goto error;
190 : }
191 :
192 209651 : rc = sdb_event_to_Event(context,
193 : &s->created_by,
194 : &h->created_by);
195 209651 : if (rc != 0) {
196 0 : goto error;
197 : }
198 :
199 209651 : if (s->modified_by) {
200 0 : h->modified_by = malloc(sizeof(Event));
201 0 : if (h->modified_by == NULL) {
202 0 : rc = ENOMEM;
203 0 : goto error;
204 : }
205 :
206 0 : rc = sdb_event_to_Event(context,
207 0 : s->modified_by,
208 : h->modified_by);
209 0 : if (rc != 0) {
210 0 : goto error;
211 : }
212 : } else {
213 209651 : h->modified_by = NULL;
214 : }
215 :
216 209651 : if (s->valid_start != NULL) {
217 0 : h->valid_start = malloc(sizeof(KerberosTime));
218 0 : if (h->valid_start == NULL) {
219 0 : rc = ENOMEM;
220 0 : goto error;
221 : }
222 0 : *h->valid_start = *s->valid_start;
223 : } else {
224 209651 : h->valid_start = NULL;
225 : }
226 :
227 209651 : if (s->valid_end != NULL) {
228 0 : h->valid_end = malloc(sizeof(KerberosTime));
229 0 : if (h->valid_end == NULL) {
230 0 : rc = ENOMEM;
231 0 : goto error;
232 : }
233 0 : *h->valid_end = *s->valid_end;
234 : } else {
235 209651 : h->valid_end = NULL;
236 : }
237 :
238 209651 : if (s->pw_end != NULL) {
239 55042 : h->pw_end = malloc(sizeof(KerberosTime));
240 55042 : if (h->pw_end == NULL) {
241 0 : rc = ENOMEM;
242 0 : goto error;
243 : }
244 55042 : *h->pw_end = *s->pw_end;
245 : } else {
246 154609 : h->pw_end = NULL;
247 : }
248 :
249 209651 : if (s->max_life != NULL) {
250 206468 : h->max_life = malloc(sizeof(unsigned int));
251 206468 : if (h->max_life == NULL) {
252 0 : rc = ENOMEM;
253 0 : goto error;
254 : }
255 206468 : *h->max_life = *s->max_life;
256 : } else {
257 3183 : h->max_life = NULL;
258 : }
259 :
260 209651 : if (s->max_renew != NULL) {
261 206468 : h->max_renew = malloc(sizeof(unsigned int));
262 206468 : if (h->max_renew == NULL) {
263 0 : rc = ENOMEM;
264 0 : goto error;
265 : }
266 206468 : *h->max_renew = *s->max_renew;
267 : } else {
268 3183 : h->max_renew = NULL;
269 : }
270 :
271 209651 : sdb_flags_to_hdb_flags(&s->flags, &h->flags);
272 :
273 209651 : h->etypes = NULL;
274 209651 : if (s->etypes != NULL) {
275 207615 : h->etypes = malloc(sizeof(*h->etypes));
276 207615 : if (h->etypes == NULL) {
277 0 : rc = ENOMEM;
278 0 : goto error;
279 : }
280 :
281 207615 : h->etypes->len = s->etypes->len;
282 :
283 207615 : h->etypes->val = calloc(h->etypes->len, sizeof(int));
284 207615 : if (h->etypes->val == NULL) {
285 0 : rc = ENOMEM;
286 0 : goto error;
287 : }
288 :
289 560539 : for (i = 0; i < h->etypes->len; i++) {
290 352924 : h->etypes->val[i] = s->etypes->val[i];
291 : }
292 : }
293 :
294 209651 : h->session_etypes = NULL;
295 209651 : if (s->session_etypes != NULL) {
296 155025 : h->session_etypes = malloc(sizeof(*h->session_etypes));
297 155025 : if (h->session_etypes == NULL) {
298 0 : rc = ENOMEM;
299 0 : goto error;
300 : }
301 :
302 155025 : h->session_etypes->len = s->session_etypes->len;
303 :
304 155025 : h->session_etypes->val = calloc(h->session_etypes->len, sizeof(*h->session_etypes->val));
305 155025 : if (h->session_etypes->val == NULL) {
306 0 : rc = ENOMEM;
307 0 : goto error;
308 : }
309 :
310 593977 : for (i = 0; i < h->session_etypes->len; ++i) {
311 438952 : h->session_etypes->val[i] = s->session_etypes->val[i];
312 : }
313 : }
314 :
315 209651 : h->context = ske;
316 209651 : if (ske != NULL) {
317 207615 : ske->kdc_entry = h;
318 : }
319 209651 : return 0;
320 0 : error:
321 0 : free_hdb_entry(h);
322 0 : return rc;
323 : }
|