Bug Summary

File:daemons/ipa-kdb/ipa_kdb.c
Warning:line 378, column 26
Array access (from variable 'cvals') results in a null pointer dereference

Annotated Source Code

Press '?' to see keyboard shortcuts

clang -cc1 -triple x86_64-unknown-linux-gnu -analyze -disable-free -disable-llvm-verifier -discard-value-names -main-file-name ipa_kdb.c -analyzer-store=region -analyzer-opt-analyze-nested-blocks -analyzer-checker=core -analyzer-checker=apiModeling -analyzer-checker=unix -analyzer-checker=deadcode -analyzer-checker=security.insecureAPI.UncheckedReturn -analyzer-checker=security.insecureAPI.getpw -analyzer-checker=security.insecureAPI.gets -analyzer-checker=security.insecureAPI.mktemp -analyzer-checker=security.insecureAPI.mkstemp -analyzer-checker=security.insecureAPI.vfork -analyzer-checker=nullability.NullPassedToNonnull -analyzer-checker=nullability.NullReturnedFromNonnull -analyzer-output plist -w -setup-static-analyzer -mrelocation-model pic -pic-level 2 -mthread-model posix -mframe-pointer=all -fmath-errno -fno-rounding-math -masm-verbose -mconstructor-aliases -munwind-tables -target-cpu x86-64 -dwarf-column-info -fno-split-dwarf-inlining -debugger-tuning=gdb -resource-dir /usr/lib64/clang/10.0.0 -D HAVE_CONFIG_H -I . -I ../.. -I . -I ../../util -D PREFIX="/usr/local" -D BINDIR="/usr/local/bin" -D LIBDIR="/usr/local/lib" -D LIBEXECDIR="/usr/local/libexec" -D DATADIR="/usr/local/share" -D LDAPIDIR="/run" -I /usr/include/samba-4.0 -D _GNU_SOURCE=1 -D HAVE_IMMEDIATE_STRUCTURES=1 -I /usr/include/nss3 -I /usr/include/nspr4 -I /usr/include/nspr4 -I /usr/include/nss3 -I /usr/include/nspr4 -D __STDC_WANT_LIB_EXT1__=1 -D _DEFAULT_SOURCE=1 -D _POSIX_C_SOURCE=200809L -D PIC -internal-isystem /usr/local/include -internal-isystem /usr/lib64/clang/10.0.0/include -internal-externc-isystem /include -internal-externc-isystem /usr/include -fdebug-compilation-dir /home/heimes/redhat/freeipa/daemons/ipa-kdb -ferror-limit 19 -fmessage-length 0 -fgnuc-version=4.2.1 -fobjc-runtime=gcc -fdiagnostics-show-option -analyzer-output=html -faddrsig -o /home/heimes/redhat/freeipa/report/2020-06-05-101548-295465-1 -x c ipa_kdb.c
1/*
2 * MIT Kerberos KDC database backend for FreeIPA
3 *
4 * Authors: Simo Sorce <ssorce@redhat.com>
5 *
6 * Copyright (C) 2011 Simo Sorce, Red Hat
7 * see file 'COPYING' for use and warranty information
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 * You should have received a copy of the GNU General Public License
20 * along with this program. If not, see <http://www.gnu.org/licenses/>.
21 */
22
23#include <talloc.h>
24#include <sys/utsname.h>
25
26#include "ipa_kdb.h"
27#include "ipa_krb5.h"
28
29#define IPADB_GLOBAL_CONFIG_CACHE_TIME60 60
30
31struct ipadb_context *ipadb_get_context(krb5_context kcontext)
32{
33 void *db_ctx;
34 krb5_error_code kerr;
35
36 kerr = krb5_db_get_context(kcontext, &db_ctx);
37 if (kerr != 0) {
38 return NULL((void*)0);
39 }
40
41 return (struct ipadb_context *)db_ctx;
42}
43
44static void ipadb_context_free(krb5_context kcontext,
45 struct ipadb_context **ctx)
46{
47 struct ipadb_global_config *cfg;
48 size_t c;
49
50 if (*ctx != NULL((void*)0)) {
51 free((*ctx)->uri);
52 free((*ctx)->base);
53 free((*ctx)->realm_base);
54 free((*ctx)->accounts_base);
55 free((*ctx)->kdc_hostname);
56 /* ldap free lcontext */
57 if ((*ctx)->lcontext) {
58 ldap_unbind_ext_s((*ctx)->lcontext, NULL((void*)0), NULL((void*)0));
59 }
60 free((*ctx)->supp_encs);
61 free((*ctx)->def_encs);
62 ipadb_mspac_struct_free(&(*ctx)->mspac);
63 krb5_free_principal(kcontext, (*ctx)->local_tgs);
64 krb5_free_default_realm(kcontext, (*ctx)->realm);
65
66 cfg = &(*ctx)->config;
67 for (c = 0; cfg->authz_data && cfg->authz_data[c]; c++) {
68 free(cfg->authz_data[c]);
69 }
70 free(cfg->authz_data);
71
72#ifdef HAVE_KRB5_CERTAUTH_PLUGIN1
73 ipa_certauth_free_moddata(&((*ctx)->certauth_moddata));
74#endif
75
76 free(*ctx);
77 *ctx = NULL((void*)0);
78 }
79}
80
81#define LDAPI_URI_PREFIX"ldapi://" "ldapi://"
82#define LDAPI_PATH_PREFIX"%2fslapd-" "%2fslapd-"
83#define SOCKET_SUFFIX".socket" ".socket"
84#define APPEND_PATH_PART(pos, part)do { int partlen = strlen(part); strncpy(pos, part, partlen +
1); p += partlen; } while (0)
\
85 do { \
86 int partlen = strlen(part); \
87 strncpy(pos, part, partlen + 1); \
88 p += partlen; \
89 } while (0)
90
91static char *ipadb_realm_to_ldapi_uri(char *realm)
92{
93 char *uri = NULL((void*)0);
94 char *p;
95 const char *q;
96 int len;
97
98 /* uri length, assume worst case for LDAPIDIR */
99 len = strlen(LDAPI_URI_PREFIX"ldapi://") + strlen(LDAPIDIR"/run") * 3
100 + strlen(LDAPI_PATH_PREFIX"%2fslapd-") + strlen(realm)
101 + strlen(SOCKET_SUFFIX".socket") + 1;
102
103 /* worst case they are all '/' to escape */
104 uri = malloc(len);
105 if (!uri) {
106 return NULL((void*)0);
107 }
108 p = uri;
109
110 APPEND_PATH_PART(p, LDAPI_URI_PREFIX)do { int partlen = strlen("ldapi://"); strncpy(p, "ldapi://",
partlen + 1); p += partlen; } while (0)
;
111
112 /* copy path and escape '/' to '%2f' */
113 for (q = LDAPIDIR"/run"; *q; q++) {
114 if (*q == '/') {
115 memcpy(p, "%2f", 3);
116 p += 3;
117 } else {
118 *p = *q;
119 p++;
120 }
121 }
122
123 APPEND_PATH_PART(p, LDAPI_PATH_PREFIX)do { int partlen = strlen("%2fslapd-"); strncpy(p, "%2fslapd-"
, partlen + 1); p += partlen; } while (0)
;
124
125 /* copy realm and convert '.' to '-' */
126 for (q = realm; *q; q++) {
127 if (*q == '.') {
128 *p = '-';
129 } else {
130 *p = *q;
131 }
132 p++;
133 }
134
135 /* terminate string */
136 APPEND_PATH_PART(p, SOCKET_SUFFIX)do { int partlen = strlen(".socket"); strncpy(p, ".socket", partlen
+ 1); p += partlen; } while (0)
;
137
138 return uri;
139}
140
141/* in IPA the base is always derived from the realm name */
142static char *ipadb_get_base_from_realm(krb5_context kcontext)
143{
144 krb5_error_code kerr;
145 char *realm = NULL((void*)0);
146 char *base = NULL((void*)0);
147 char *tmp;
148 size_t bi, ri;
149 size_t len;
150
151 kerr = krb5_get_default_realm(kcontext, &realm);
152 if (kerr != 0) {
153 return NULL((void*)0);
154 }
155
156 bi = 3;
157 len = strlen(realm) + 3 + 1;
158
159 base = malloc(len);
160 if (!base) {
161 goto done;
162 }
163 strcpy(base, "dc=");
164
165 /* convert EXAMPLE.COM in dc=example,dc=com */
166 for (ri = 0; realm[ri]; ri++) {
167 if (realm[ri] == '.') {
168 len += 4;
169 tmp = realloc(base, len);
170 if (!tmp) {
171 free(base);
172 base = NULL((void*)0);
173 goto done;
174 }
175 base = tmp;
176 strcpy(&base[bi], ",dc=");
177 bi += 4;
178 } else {
179 base[bi] = tolower(realm[ri]);
180 bi++;
181 }
182 }
183 base[bi] = '\0';
184
185done:
186 krb5_free_default_realm(kcontext, realm);
187 return base;
188}
189
190static const struct {
191 const char *name;
192 enum ipadb_user_auth flag;
193} userauth_table[] = {
194 { "disabled", IPADB_USER_AUTH_DISABLED },
195 { "password", IPADB_USER_AUTH_PASSWORD },
196 { "radius", IPADB_USER_AUTH_RADIUS },
197 { "otp", IPADB_USER_AUTH_OTP },
198 { "pkinit", IPADB_USER_AUTH_PKINIT },
199 { "hardened", IPADB_USER_AUTH_HARDENED },
200 { }
201};
202
203void ipadb_parse_user_auth(LDAP *lcontext, LDAPMessage *le,
204 enum ipadb_user_auth *userauth)
205{
206 struct berval **vals;
207 int i, j;
208
209 *userauth = IPADB_USER_AUTH_NONE;
210 vals = ldap_get_values_len(lcontext, le, IPA_USER_AUTH_TYPE"ipaUserAuthType");
211 if (!vals)
212 return;
213
214 for (i = 0; vals[i]; i++) {
215 for (j = 0; userauth_table[j].name; j++) {
216 if (strcasecmp(vals[i]->bv_val, userauth_table[j].name) == 0) {
217 *userauth |= userauth_table[j].flag;
218 break;
219 }
220 }
221 }
222
223 ldap_value_free_len(vals);
224}
225
226static int ipadb_load_global_config(struct ipadb_context *ipactx)
227{
228 char *attrs[] = { "ipaConfigString", IPA_KRB_AUTHZ_DATA_ATTR"ipaKrbAuthzData",
229 IPA_USER_AUTH_TYPE"ipaUserAuthType", NULL((void*)0) };
230 struct berval **vals = NULL((void*)0);
231 LDAPMessage *res = NULL((void*)0);
232 LDAPMessage *first;
233 char *base = NULL((void*)0);
234 int ret;
235 char **authz_data_list;
236
237 if (!ipactx || !ipactx->lcontext) {
238 return EINVAL22;
239 }
240
241 ret = asprintf(&base, "cn=ipaConfig,cn=etc,%s", ipactx->base);
242 if (ret == -1) {
243 ret = ENOMEM12;
244 goto done;
245 }
246
247 ret = ipadb_simple_search(ipactx, base, LDAP_SCOPE_BASE((ber_int_t) 0x0000),
248 "(objectclass=*)", attrs, &res);
249 if (ret) {
250 goto done;
251 }
252
253 first = ldap_first_entry(ipactx->lcontext, res);
254 if (!first) {
255 /* no results, set nothing */
256 ret = 0;
257 goto done;
258 }
259
260 /* Check for permitted authentication types. */
261 ipadb_parse_user_auth(ipactx->lcontext, res, &ipactx->config.user_auth);
262
263 /* Load config strings. */
264 vals = ldap_get_values_len(ipactx->lcontext, first, "ipaConfigString");
265 if (vals) {
266 ipactx->config.disable_last_success = false0;
267 ipactx->config.disable_lockout = false0;
268 for (int i = 0; vals[i]; i++) {
269 if (strncasecmp("KDC:Disable Last Success",
270 vals[i]->bv_val, vals[i]->bv_len) == 0) {
271 ipactx->config.disable_last_success = true1;
272 continue;
273 } else if (strncasecmp("KDC:Disable Lockout",
274 vals[i]->bv_val, vals[i]->bv_len) == 0) {
275 ipactx->config.disable_lockout = true1;
276 continue;
277 } else if (strncasecmp("KDC:Disable Default Preauth for SPNs",
278 vals[i]->bv_val, vals[i]->bv_len) == 0) {
279 ipactx->config.disable_preauth_for_spns = true1;
280 }
281 }
282 }
283
284 /* Load authz data. */
285 ret = ipadb_ldap_attr_to_strlist(ipactx->lcontext, first,
286 IPA_KRB_AUTHZ_DATA_ATTR"ipaKrbAuthzData", &authz_data_list);
287 if (ret == 0) {
288 if (ipactx->config.authz_data != NULL((void*)0)) {
289 for (int i = 0; ipactx->config.authz_data[i]; i++)
290 free(ipactx->config.authz_data[i]);
291 free(ipactx->config.authz_data);
292 }
293
294 ipactx->config.authz_data = authz_data_list;
295 } else if (ret != ENOENT2)
296 goto done;
297
298 /* Success! */
299 ipactx->config.last_update = time(NULL((void*)0));
300 ret = 0;
301
302done:
303 ldap_value_free_len(vals);
304 ldap_msgfree(res);
305 free(base);
306 return ret;
307}
308
309const struct ipadb_global_config *
310ipadb_get_global_config(struct ipadb_context *ipactx)
311{
312 time_t now = 0;
313 int ret;
314
315 if (time(&now) != (time_t)-1 &&
316 now - ipactx->config.last_update > IPADB_GLOBAL_CONFIG_CACHE_TIME60) {
317 if (!ipactx->lcontext) {
318 ret = ipadb_get_connection(ipactx);
319 if (ret != 0)
320 return NULL((void*)0);
321 }
322 ret = ipadb_load_global_config(ipactx);
323 if (ret != 0)
324 return NULL((void*)0);
325 }
326
327 return &ipactx->config;
328}
329
330int ipadb_get_enc_salt_types(struct ipadb_context *ipactx,
331 LDAPMessage *entry, char *attr,
332 krb5_key_salt_tuple **enc_salt_types,
333 int *n_enc_salt_types)
334{
335 struct berval **vals = NULL((void*)0);
336 char **cvals = NULL((void*)0);
337 int c = 0;
338 int i;
339 int ret = 0;
340 krb5_key_salt_tuple *kst;
341 int n_kst;
342
343 vals = ldap_get_values_len(ipactx->lcontext, entry, attr);
344 if (!vals || !vals[0]) {
40
Assuming 'vals' is non-null
41
Assuming the condition is false
42
Taking false branch
345 goto done;
346 }
347
348 for (c = 0; vals[c]; c++) /* count */ ;
43
Loop condition is true. Entering loop body
44
Loop condition is false. Execution continues on line 349
349 cvals = calloc(c, sizeof(char *));
45
Value assigned to 'cvals'
350 if (!cvals) {
46
Assuming 'cvals' is null
47
Assuming pointer value is null
48
Taking true branch
351 ret = ENOMEM12;
352 goto done;
49
Control jumps to line 377
353 }
354 for (i = 0; i < c; i++) {
355 cvals[i] = strndup(vals[i]->bv_val, vals[i]->bv_len);
356 if (!cvals[i]) {
357 ret = ENOMEM12;
358 goto done;
359 }
360 }
361
362 ret = parse_bval_key_salt_tuples(ipactx->kcontext,
363 (const char * const *)cvals, c,
364 &kst, &n_kst);
365 if (ret) {
366 goto done;
367 }
368
369 if (*enc_salt_types) {
370 free(*enc_salt_types);
371 }
372
373 *enc_salt_types = kst;
374 *n_enc_salt_types = n_kst;
375
376done:
377 ldap_value_free_len(vals);
378 for (i = 0; i
49.1
'i' is < 'c'
< c && cvals[i]; i++) {
50
Array access (from variable 'cvals') results in a null pointer dereference
379 free(cvals[i]);
380 }
381 free(cvals);
382 return ret;
383}
384
385int ipadb_get_connection(struct ipadb_context *ipactx)
386{
387 struct timeval tv = { 5, 0 };
388 LDAPMessage *res = NULL((void*)0);
389 LDAPMessage *first;
390 int ret;
391 int v3;
392
393 if (!ipactx->uri) {
21
Assuming field 'uri' is non-null
22
Taking false branch
394 return EINVAL22;
395 }
396
397 /* free existing conneciton if any */
398 if (ipactx->lcontext) {
23
Assuming field 'lcontext' is null
24
Taking false branch
399 ldap_unbind_ext_s(ipactx->lcontext, NULL((void*)0), NULL((void*)0));
400 ipactx->lcontext = NULL((void*)0);
401 }
402
403 ret = ldap_initialize(&ipactx->lcontext, ipactx->uri);
404 if (ret != LDAP_SUCCESS0x00) {
25
Assuming 'ret' is equal to LDAP_SUCCESS
26
Taking false branch
405 goto done;
406 }
407
408 /* make sure we talk LDAPv3 */
409 v3 = LDAP_VERSION33;
410 ret = ldap_set_option(ipactx->lcontext, LDAP_OPT_PROTOCOL_VERSION0x0011, &v3);
411 if (ret != LDAP_OPT_SUCCESS0) {
27
Assuming 'ret' is equal to LDAP_OPT_SUCCESS
28
Taking false branch
412 goto done;
413 }
414
415 ret = ldap_set_option(ipactx->lcontext, LDAP_OPT_NETWORK_TIMEOUT0x5005, &tv);
416 if (ret != LDAP_OPT_SUCCESS0) {
29
Assuming 'ret' is equal to LDAP_OPT_SUCCESS
30
Taking false branch
417 goto done;
418 }
419
420 ret = ldap_set_option(ipactx->lcontext, LDAP_OPT_TIMEOUT0x5002, &tv);
421 if (ret != LDAP_OPT_SUCCESS0) {
31
Assuming 'ret' is equal to LDAP_OPT_SUCCESS
32
Taking false branch
422 goto done;
423 }
424
425 ret = ldap_sasl_bind_s(ipactx->lcontext,
426 NULL((void*)0), "EXTERNAL",
427 NULL((void*)0), NULL((void*)0), NULL((void*)0), NULL((void*)0));
428 if (ret != LDAP_SUCCESS0x00) {
33
Assuming 'ret' is equal to LDAP_SUCCESS
34
Taking false branch
429 goto done;
430 }
431
432 /* TODO: search rootdse */
433
434 ret = ipadb_simple_search(ipactx,
435 ipactx->realm_base, LDAP_SCOPE_BASE((ber_int_t) 0x0000),
436 "(objectclass=*)", NULL((void*)0), &res);
437 if (ret) {
35
Assuming 'ret' is 0
36
Taking false branch
438 goto done;
439 }
440
441 first = ldap_first_entry(ipactx->lcontext, res);
442 if (!first) {
37
Assuming 'first' is non-null
38
Taking false branch
443 goto done;
444 }
445
446 /* defaults first, this is used to tell what default enc:salts to use
447 * for kadmin password changes */
448 ret = ipadb_get_enc_salt_types(ipactx, first, "krbDefaultEncSaltTypes",
39
Calling 'ipadb_get_enc_salt_types'
449 &ipactx->def_encs, &ipactx->n_def_encs);
450 if (ret) {
451 goto done;
452 }
453
454 /* supported enc salt types, use to tell kadmin what to accept
455 * but also to detect if kadmin is requesting the default set */
456 ret = ipadb_get_enc_salt_types(ipactx, first, "krbSupportedEncSaltTypes",
457 &ipactx->supp_encs, &ipactx->n_supp_encs);
458 if (ret) {
459 goto done;
460 }
461
462 /* get additional options */
463 ret = ipadb_load_global_config(ipactx);
464 if (ret) {
465 goto done;
466 }
467
468 /* get adtrust options using default refresh interval */
469 ret = ipadb_reinit_mspac(ipactx, false0);
470 if (ret && ret != ENOENT2) {
471 /* TODO: log that there is an issue with adtrust settings */
472 if (ipactx->lcontext == NULL((void*)0)) {
473 /* for some reason ldap connection was reset in ipadb_reinit_mspac
474 * and is no longer established => failure of ipadb_get_connection
475 */
476 goto done;
477 }
478 }
479
480 ret = 0;
481
482done:
483 ldap_msgfree(res);
484
485 if (ret) {
486 if (ipactx->lcontext) {
487 ldap_unbind_ext_s(ipactx->lcontext, NULL((void*)0), NULL((void*)0));
488 ipactx->lcontext = NULL((void*)0);
489 }
490 if (ret == LDAP_SERVER_DOWN(-1)) {
491 return ETIMEDOUT110;
492 }
493 return EIO5;
494 }
495
496 return 0;
497}
498
499static krb5_principal ipadb_create_local_tgs(krb5_context kcontext,
500 struct ipadb_context *ipactx)
501{
502 krb5_principal tgtp;
503 unsigned int length = strlen(ipactx->realm);
504 krb5_error_code kerr = 0;
505
506 kerr = krb5_build_principal_ext(kcontext, &tgtp,
507 length,
508 ipactx->realm,
509 KRB5_TGS_NAME_SIZE6,
510 KRB5_TGS_NAME"krbtgt",
511 length,
512 ipactx->realm, 0);
513 if (kerr != 0) {
514 return NULL((void*)0);
515 }
516
517 return tgtp;
518}
519
520/* INTERFACE */
521
522static krb5_error_code ipadb_init_library(void)
523{
524 return 0;
525}
526
527static krb5_error_code ipadb_fini_library(void)
528{
529 return 0;
530}
531
532static krb5_error_code ipadb_init_module(krb5_context kcontext,
533 char *conf_section,
534 char **db_args, int mode)
535{
536 struct ipadb_context *ipactx;
537 krb5_error_code kerr;
538 int ret;
539 int i;
540 struct utsname uname_data;
541
542 /* make sure the context is freed to avoid leaking it */
543 ipactx = ipadb_get_context(kcontext);
544 ipadb_context_free(kcontext, &ipactx);
545
546 ipactx = calloc(1, sizeof(struct ipadb_context));
547 if (!ipactx) {
2
Assuming 'ipactx' is non-null
3
Taking false branch
548 return ENOMEM12;
549 }
550 ipactx->magic = IPA_CONTEXT_MAGIC0x0c027ea7;
551
552 /* only check for unsupported 'temporary' value for now */
553 for (i = 0; db_args != NULL((void*)0) && db_args[i] != NULL((void*)0); i++) {
4
Assuming 'db_args' is equal to NULL
554
555 if (strncmp(db_args[i], IPA_SETUP"ipa-setup-override-restrictions", sizeof(IPA_SETUP"ipa-setup-override-restrictions")) == 0) {
556 ipactx->override_restrictions = true1;
557 }
558
559 if (strncmp(db_args[i], "temporary", 9) == 0) {
560 krb5_set_error_message(kcontext, EINVAL22,
561 "Plugin requires -update argument!");
562 ret = EINVAL22;
563 goto fail;
564 }
565 }
566
567 ipactx->kcontext = kcontext;
568
569 kerr = krb5_get_default_realm(kcontext, &ipactx->realm);
570 if (kerr != 0) {
5
Assuming 'kerr' is equal to 0
6
Taking false branch
571 ret = EINVAL22;
572 goto fail;
573 }
574
575 ipactx->uri = ipadb_realm_to_ldapi_uri(ipactx->realm);
576 if (!ipactx->uri) {
7
Assuming field 'uri' is non-null
8
Taking false branch
577 ret = ENOMEM12;
578 goto fail;
579 }
580
581 ipactx->local_tgs = ipadb_create_local_tgs(kcontext, ipactx);
582 if (!ipactx->local_tgs) {
9
Assuming field 'local_tgs' is non-null
10
Taking false branch
583 ret = ENOMEM12;
584 goto fail;
585 }
586
587 ipactx->base = ipadb_get_base_from_realm(kcontext);
588 if (!ipactx->base
10.1
Field 'base' is non-null
) {
11
Taking false branch
589 ret = ENOMEM12;
590 goto fail;
591 }
592
593 ret = asprintf(&ipactx->realm_base, "cn=%s,cn=kerberos,%s",
594 ipactx->realm, ipactx->base);
595 if (ret == -1) {
12
Assuming the condition is false
13
Taking false branch
596 ret = ENOMEM12;
597 goto fail;
598 }
599
600 ret = asprintf(&ipactx->accounts_base, "cn=accounts,%s", ipactx->base);
601 if (ret == -1) {
14
Assuming the condition is false
15
Taking false branch
602 ret = ENOMEM12;
603 goto fail;
604 }
605
606 ret = uname(&uname_data);
607 if (ret) {
16
Assuming 'ret' is 0
17
Taking false branch
608 ret = EINVAL22;
609 goto fail;
610 }
611
612 ipactx->kdc_hostname = strdup(uname_data.nodename);
613 if (!ipactx->kdc_hostname) {
18
Assuming field 'kdc_hostname' is non-null
19
Taking false branch
614 ret = ENOMEM12;
615 goto fail;
616 }
617
618 ret = ipadb_get_connection(ipactx);
20
Calling 'ipadb_get_connection'
619 if (ret != 0) {
620 /* Not a fatal failure, as the LDAP server may be temporarily down. */
621 krb5_klog_syslog(LOG_INFO6,
622 "Didn't connect to LDAP on startup: %d", ret);
623 }
624
625 kerr = krb5_db_set_context(kcontext, ipactx);
626 if (kerr != 0) {
627 ret = EACCES13;
628 goto fail;
629 }
630
631 return 0;
632
633fail:
634 ipadb_context_free(kcontext, &ipactx);
635 return ret;
636}
637
638static krb5_error_code ipadb_fini_module(krb5_context kcontext)
639{
640 struct ipadb_context *ipactx;
641
642 ipactx = ipadb_get_context(kcontext);
643 ipadb_context_free(kcontext, &ipactx);
644 talloc_free(talloc_autofree_context())_talloc_free(talloc_autofree_context(), "ipa_kdb.c" ":" "644"
)
;
645
646 return 0;
647}
648
649static krb5_error_code ipadb_create(krb5_context kcontext,
650 char *conf_section,
651 char **db_args)
652{
653 return ipadb_init_module(kcontext, conf_section, db_args, 0);
1
Calling 'ipadb_init_module'
654}
655
656static krb5_error_code ipadb_get_age(krb5_context kcontext,
657 char *db_name, time_t *age)
658{
659 /* just return the current time for now,
660 * until we can use persistent searches and have
661 * a better estimate */
662 *age = time(NULL((void*)0));
663 return 0;
664}
665
666/* KDB Virtual Table */
667
668/* We explicitly want to keep different ABI tables below separate. */
669/* Do not merge them together. Older ABI does not need to be updated */
670
671#if (KRB5_KDB_DAL_MAJOR_VERSION8 == 6) && !defined(HAVE_KDB_FREEPRINCIPAL_EDATA1)
672kdb_vftabl kdb_function_table = {
673 .maj_ver = KRB5_KDB_DAL_MAJOR_VERSION8,
674 .min_ver = 0,
675 .init_library = ipadb_init_library,
676 .fini_library = ipadb_fini_library,
677 .init_module = ipadb_init_module,
678 .fini_module = ipadb_fini_module,
679 .create = ipadb_create,
680 .get_age = ipadb_get_age,
681 .get_principal = ipadb_get_principal,
682 .put_principal = ipadb_put_principal,
683 .delete_principal = ipadb_delete_principal,
684 .iterate = ipadb_iterate,
685 .create_policy = ipadb_create_pwd_policy,
686 .get_policy = ipadb_get_pwd_policy,
687 .put_policy = ipadb_put_pwd_policy,
688 .iter_policy = ipadb_iterate_pwd_policy,
689 .delete_policy = ipadb_delete_pwd_policy,
690 .fetch_master_key = ipadb_fetch_master_key,
691 .store_master_key_list = ipadb_store_master_key_list,
692 .change_pwd = ipadb_change_pwd,
693 .sign_authdata = ipadb_sign_authdata,
694 .check_transited_realms = ipadb_check_transited_realms,
695 .check_policy_as = ipadb_check_policy_as,
696 .audit_as_req = ipadb_audit_as_req,
697 .check_allowed_to_delegate = ipadb_check_allowed_to_delegate
698};
699#endif
700
701#if ((KRB5_KDB_DAL_MAJOR_VERSION8 == 6) || \
702 (KRB5_KDB_DAL_MAJOR_VERSION8 == 7)) && \
703 defined(HAVE_KDB_FREEPRINCIPAL_EDATA1)
704kdb_vftabl kdb_function_table = {
705 .maj_ver = KRB5_KDB_DAL_MAJOR_VERSION8,
706 .min_ver = 1,
707 .init_library = ipadb_init_library,
708 .fini_library = ipadb_fini_library,
709 .init_module = ipadb_init_module,
710 .fini_module = ipadb_fini_module,
711 .create = ipadb_create,
712 .get_age = ipadb_get_age,
713 .get_principal = ipadb_get_principal,
714 .put_principal = ipadb_put_principal,
715 .delete_principal = ipadb_delete_principal,
716 .iterate = ipadb_iterate,
717 .create_policy = ipadb_create_pwd_policy,
718 .get_policy = ipadb_get_pwd_policy,
719 .put_policy = ipadb_put_pwd_policy,
720 .iter_policy = ipadb_iterate_pwd_policy,
721 .delete_policy = ipadb_delete_pwd_policy,
722 .fetch_master_key = ipadb_fetch_master_key,
723 .store_master_key_list = ipadb_store_master_key_list,
724 .change_pwd = ipadb_change_pwd,
725 .sign_authdata = ipadb_sign_authdata,
726 .check_transited_realms = ipadb_check_transited_realms,
727 .check_policy_as = ipadb_check_policy_as,
728 .audit_as_req = ipadb_audit_as_req,
729 .check_allowed_to_delegate = ipadb_check_allowed_to_delegate,
730 /* The order is important, DAL version 6.1 added
731 * the free_principal_e_data callback */
732 .free_principal_e_data = ipadb_free_principal_e_data,
733};
734#endif
735
736#if (KRB5_KDB_DAL_MAJOR_VERSION8 == 8)
737/* Version 8 adds several arguments here. However, if we want to actually use
738 * them in mspac, we really ought to drop support for older DAL versions. */
739static inline krb5_error_code
740stub_sign_authdata(krb5_context context, unsigned int flags,
741 krb5_const_principal client_princ,
742 krb5_const_principal server_princ, krb5_db_entry *client,
743 krb5_db_entry *server, krb5_db_entry *header_server,
744 krb5_db_entry *local_tgt, krb5_keyblock *client_key,
745 krb5_keyblock *server_key, krb5_keyblock *header_key,
746 krb5_keyblock *local_tgt_key, krb5_keyblock *session_key,
747 krb5_timestamp authtime, krb5_authdata **tgt_auth_data,
748 void *ad_info, krb5_data ***auth_indicators,
749 krb5_authdata ***signed_auth_data)
750{
751 krb5_db_entry *krbtgt = header_server ? header_server : local_tgt;
752 krb5_keyblock *krbtgt_key = header_key ? header_key : local_tgt_key;
753
754 if (flags & KRB5_KDB_FLAG_CONSTRAINED_DELEGATION0x00000200) {
755 client = header_server;
756 krbtgt = local_tgt;
757 krbtgt_key = local_tgt_key;
758 }
759
760 return ipadb_sign_authdata(context, flags, client_princ, client, server,
761 krbtgt, client_key, server_key, krbtgt_key,
762 session_key, authtime, tgt_auth_data,
763 signed_auth_data);
764}
765
766kdb_vftabl kdb_function_table = {
767 .maj_ver = KRB5_KDB_DAL_MAJOR_VERSION8,
768 .min_ver = 0,
769 .init_library = ipadb_init_library,
770 .fini_library = ipadb_fini_library,
771 .init_module = ipadb_init_module,
772 .fini_module = ipadb_fini_module,
773 .create = ipadb_create,
774 .get_age = ipadb_get_age,
775 .get_principal = ipadb_get_principal,
776 .put_principal = ipadb_put_principal,
777 .delete_principal = ipadb_delete_principal,
778 .iterate = ipadb_iterate,
779 .create_policy = ipadb_create_pwd_policy,
780 .get_policy = ipadb_get_pwd_policy,
781 .put_policy = ipadb_put_pwd_policy,
782 .iter_policy = ipadb_iterate_pwd_policy,
783 .delete_policy = ipadb_delete_pwd_policy,
784 .fetch_master_key = ipadb_fetch_master_key,
785 .store_master_key_list = ipadb_store_master_key_list,
786 .change_pwd = ipadb_change_pwd,
787 .sign_authdata = stub_sign_authdata,
788 .check_transited_realms = ipadb_check_transited_realms,
789 .check_policy_as = ipadb_check_policy_as,
790 .audit_as_req = ipadb_audit_as_req,
791 .check_allowed_to_delegate = ipadb_check_allowed_to_delegate,
792 .free_principal_e_data = ipadb_free_principal_e_data,
793 .get_s4u_x509_principal = NULL((void*)0),
794 .allowed_to_delegate_from = NULL((void*)0),
795 .get_authdata_info = NULL((void*)0),
796 .free_authdata_info = NULL((void*)0),
797};
798#endif
799
800#if (KRB5_KDB_DAL_MAJOR_VERSION8 != 6) && \
801 (KRB5_KDB_DAL_MAJOR_VERSION8 != 7) && \
802 (KRB5_KDB_DAL_MAJOR_VERSION8 != 8)
803#error unsupported DAL major version
804#endif