#2037 Fix coverity bugs in kdb tools
Closed: Fixed None Opened 12 years ago by mkosek.

Discovered by Coverity scan

Bugs:

ipa_kdb_pwdpolicy.c:

krb5_error_code ipadb_get_pwd_policy(krb5_context kcontext, char *name,
 47                                     osa_policy_ent_t *policy)
 48{
 49    struct ipadb_context *ipactx;
 50    char *esc_name = NULL;
 51    char *src_filter = NULL;
 52    krb5_error_code kerr;
 53    LDAPMessage *res = NULL;
 54    LDAPMessage *lentry;
 55    osa_policy_ent_t pentry;
 56    uint32_t result;
 57    int ret;
 58
 59    ipactx = ipadb_get_context(kcontext);
 60    if (!ipactx) {
 61        return KRB5_KDB_DBNOTINITED;
 62    }
 63
 64    esc_name = ipadb_filter_escape(name, true);
 65    if (!esc_name) {
 66        return ENOMEM;
 67    }
 68
 69    ret = asprintf(&src_filter, POLICY_SEARCH_FILTER, esc_name);
 70    if (ret == -1) {
 71        kerr = KRB5_KDB_INTERNAL_ERROR;
 72        goto done;
 73    }
 74
 75    kerr = ipadb_simple_search(ipactx,
 76                               ipactx->realm_base, LDAP_SCOPE_SUBTREE,
 77                               src_filter, std_pwdpolicy_attrs, &res);
 78    if (kerr) {
 79        goto done;
 80    }
 81
 82    lentry = ldap_first_entry(ipactx->lcontext, res);
 83    if (!lentry) {
 84        kerr = KRB5_KDB_INTERNAL_ERROR;
 85        goto done;
 86    }
 87
CID 11026: Resource leak (RESOURCE_LEAK) [select defect]
CID 11027: Wrong sizeof argument (SIZEOF_MISMATCH)
Passing argument "8UL /* sizeof (osa_policy_ent_t) */" to function "calloc" and then 
casting the return value to "osa_policy_ent_t" is suspicious. Did you intend to use 
"sizeof(struct _osa_policy_ent_t)" instead of "sizeof (osa_policy_ent_t)" ?
 88    pentry = calloc(1, sizeof(osa_policy_ent_t));



46krb5_error_code ipadb_get_pwd_policy(krb5_context kcontext, char *name,
 47                                     osa_policy_ent_t *policy)
 48{
 49    struct ipadb_context *ipactx;
 50    char *esc_name = NULL;
 51    char *src_filter = NULL;
 52    krb5_error_code kerr;
 53    LDAPMessage *res = NULL;
 54    LDAPMessage *lentry;
 55    osa_policy_ent_t pentry;
 56    uint32_t result;
 57    int ret;
 58
 59    ipactx = ipadb_get_context(kcontext);
 60    if (!ipactx) {
 61        return KRB5_KDB_DBNOTINITED;
 62    }
 63
 64    esc_name = ipadb_filter_escape(name, true);
 65    if (!esc_name) {
 66        return ENOMEM;
 67    }
 68
 69    ret = asprintf(&src_filter, POLICY_SEARCH_FILTER, esc_name);
 70    if (ret == -1) {
 71        kerr = KRB5_KDB_INTERNAL_ERROR;
 72        goto done;
 73    }
 74
 75    kerr = ipadb_simple_search(ipactx,
 76                               ipactx->realm_base, LDAP_SCOPE_SUBTREE,
 77                               src_filter, std_pwdpolicy_attrs, &res);
 78    if (kerr) {
 79        goto done;
 80    }
 81
 82    lentry = ldap_first_entry(ipactx->lcontext, res);
 83    if (!lentry) {
 84        kerr = KRB5_KDB_INTERNAL_ERROR;
 85        goto done;
 86    }
 87
CID 11027: Wrong sizeof argument (SIZEOF_MISMATCH) [select defect]
CID 11026: Resource leak (RESOURCE_LEAK)
Calling allocation function "calloc".
Assigning: "pentry" = storage returned from "calloc(1UL, 8UL)".
 88    pentry = calloc(1, sizeof(osa_policy_ent_t));
At conditional (1): "!pentry" taking the false branch.
 89    if (!pentry) {
 90        kerr = ENOMEM;
 91        goto done;
 92    }
 93    pentry->version = 1;
At conditional (2): "0" taking the false branch.
 94    pentry->name = strdup(name);
At conditional (3): "!pentry->name" taking the true branch.
 95    if (!pentry->name) {
 96        kerr = ENOMEM;
 97        goto done;
 98    }
 99
100    /* FIXME: what to do with missing attributes ? */
101
102    ret = ipadb_ldap_attr_to_uint32(ipactx->lcontext, lentry,
103                                    "krbMinPwdLife", &result);
104    if (ret == 0) {
105        pentry->pw_min_life = result;
106    }
107
108    ret = ipadb_ldap_attr_to_uint32(ipactx->lcontext, lentry,
109                                    "krbMaxPwdLife", &result);
110    if (ret == 0) {
111        pentry->pw_max_life = result;
112    }
113
114    ret = ipadb_ldap_attr_to_uint32(ipactx->lcontext, lentry,
115                                    "krbPwdMinLength", &result);
116    if (ret == 0) {
117        pentry->pw_min_length = result;
118    }
119
120    ret = ipadb_ldap_attr_to_uint32(ipactx->lcontext, lentry,
121                                    "krbPwdMinDiffChars", &result);
122    if (ret == 0) {
123        pentry->pw_min_classes = result;
124    }
125
126    ret = ipadb_ldap_attr_to_uint32(ipactx->lcontext, lentry,
127                                    "krbPwdHistoryLength", &result);
128    if (ret == 0) {
129        pentry->pw_history_num = result;
130    }
131
132    ret = ipadb_ldap_attr_to_uint32(ipactx->lcontext, lentry,
133                                    "krbPwdMaxFailure", &result);
134    if (ret == 0) {
135        pentry->pw_max_fail = result;
136    }
137
138    ret = ipadb_ldap_attr_to_uint32(ipactx->lcontext, lentry,
139                                    "krbPwdFailureCountInterval", &result);
140    if (ret == 0) {
141        pentry->pw_failcnt_interval = result;
142    }
143
144    ret = ipadb_ldap_attr_to_uint32(ipactx->lcontext, lentry,
145                                    "krbPwdLockoutDuration", &result);
146    if (ret == 0) {
147        pentry->pw_lockout_duration = result;
148    }
149
150    *policy = pentry;
151
152done:
153    free(esc_name);
154    free(src_filter);
155    ldap_msgfree(res);
156
Variable "pentry" going out of scope leaks the storage it points to.
157    return kerr;

ipa_kdb_principals.c:

static krb5_error_code ipadb_parse_ldap_entry(krb5_context kcontext,
 344                                              char *principal,
 345                                              LDAPMessage *lentry,
 346                                              krb5_db_entry **kentry,
 347                                              uint32_t *polmask)
 348{
...
 547
CID 11025: Resource leak (RESOURCE_LEAK)
Calling allocation function "calloc".
Assigning: "ied" = storage returned from "calloc(1UL, 64UL)".
 548    ied = calloc(1, sizeof(struct ipadb_e_data));
At conditional (1): "!ied" taking the false branch.
 549    if (!ied) {
 550        kerr = ENOMEM;
 551        goto done;
 552    }
 553    ied->magic = IPA_E_DATA_MAGIC;
 554
 555    /* mark this as an ipa_user if it has the posixaccount objectclass */
 556    ret = ipadb_ldap_attr_has_value(lcontext, lentry,
 557                                    "objectClass", "posixAccount");
At conditional (2): "ret != 0" taking the true branch.
At conditional (3): "ret != 2" taking the true branch.
 558    if (ret != 0 && ret != ENOENT) {
 559        kerr = ret;
 560        goto done;
 561    }
 562    if (ret == 0) {
 563        ied->ipa_user = true;
 564    }
 565
 566    ret = ipadb_ldap_attr_to_str(lcontext, lentry,
 567                                 "krbPwdPolicyReference", &restring);
 568    switch (ret) {
 569    case ENOENT:
 570        /* use the default policy if ref. is not available */
 571        ret = asprintf(&restring,
 572                       "cn=global_policy,%s", ipactx->realm_base);
 573        if (ret == -1) {
 574            kerr = ENOMEM;
 575            goto done;
 576        }
 577    case 0:
 578        break;
 579    default:
 580        kerr = KRB5_KDB_INTERNAL_ERROR;
 581        goto done;
 582    }
 583    ied->pw_policy_dn = restring;
 584
 585    ret = ipadb_ldap_attr_to_strlist(lcontext, lentry,
 586                                     "passwordHistory", &restrlist);
 587    if (ret != 0 && ret != ENOENT) {
 588        kerr = KRB5_KDB_INTERNAL_ERROR;
 589        goto done;
 590    }
 591    if (ret == 0) {
 592        ied->pw_history = restrlist;
 593    }
 594
 595    ret = ipadb_ldap_attr_to_time_t(lcontext, lentry,
 596                                    "krbLastPwdChange", &restime);
 597    if (ret == 0) {
 598        krb5_int32 time32le = htole32((krb5_int32)restime);
 599
 600        kerr = ipadb_set_tl_data(entry,
 601                                 KRB5_TL_LAST_PWD_CHANGE,
 602                                 sizeof(time32le),
 603                                 (krb5_octet *)&time32le);
 604        if (kerr) {
 605            goto done;
 606        }
 607
 608        ied->last_pwd_change = restime;
 609    }
 610
 611    entry->e_data = (krb5_octet *)ied;
 612
 613    kerr = 0;
 614
 615done:
At conditional (4): "kerr" taking the true branch.
 616    if (kerr) {
 617        ipadb_free_principal(kcontext, entry);
 618        entry = NULL;
 619    }
 620    *kentry = entry;
Variable "ied" going out of scope leaks the storage it points to.
 621    return kerr;
 622}



 82static int ipadb_ldap_attr_to_tl_data(LDAP *lcontext, LDAPMessage *le,
  83                                      char *attrname,
  84                                      krb5_tl_data **result, int *num)
  85{
  86    struct berval **vals;
  87    krb5_tl_data *prev, *next;
  88    krb5_int16 be_type;
  89    int i;
  90    int ret = ENOENT;
  91
  92    *result = NULL;
  93    prev = NULL;
  94    vals = ldap_get_values_len(lcontext, le, attrname);
  95    if (vals) {
  96        for (i = 0; vals[i]; i++) {
CID 11024: Resource leak (RESOURCE_LEAK)
Calling allocation function "calloc".
Assigning: "next" = storage returned from "calloc(1UL, 24UL)".
  97            next = calloc(1, sizeof(krb5_tl_data));
At conditional (1): "!next" taking the false branch.
  98            if (!next) {
  99                ret = ENOMEM;
 100                goto done;
 101            }
 102
 103            /* fill tl_data struct with the data */
 104            memcpy(&be_type, vals[i]->bv_val, 2);
At conditional (2): "0" taking the false branch.
 105            next->tl_data_type = ntohs(be_type);
 106            next->tl_data_length = vals[i]->bv_len - 2;
 107            next->tl_data_contents = malloc(next->tl_data_length);
At conditional (3): "!next->tl_data_contents" taking the true branch.
 108            if (!next->tl_data_contents) {
 109                ret = ENOMEM;
 110                goto done;
 111            }
 112            memcpy(next->tl_data_contents,
 113                   vals[i]->bv_val + 2,
 114                   next->tl_data_length);
 115
 116            if (prev) {
 117                prev->tl_data_next = next;
 118            } else {
 119                *result = next;
 120            }
 121            prev = next;
 122        }
 123        *num = i;
 124        ret = 0;
 125
 126        ldap_value_free_len(vals);
 127    }
 128
 129done:
At conditional (4): "ret" taking the true branch.
 130    if (ret) {
At conditional (5): "*result" taking the true branch.
 131        if (*result) {
 132            prev = *result;
At conditional (6): "prev" taking the true branch.
 133            while (prev) {
Overwriting "next" in call "next = prev->tl_data_next" leaks the storage that "next" points to.
 134                next = prev->tl_data_next;
 135                free(prev);
 136                prev = next;
 137            }



188static int ipadb_ldap_attr_to_key_data(LDAP *lcontext, LDAPMessage *le,
 189                                       char *attrname,
 190                                       krb5_key_data **result, int *num,
 191                                       krb5_kvno *res_mkvno)
 192{
 193    struct berval **vals;
 194    krb5_key_data *keys = NULL;
 195    BerElement *be = NULL;
 196    void *tmp;
 197    int i = 0;
 198    int ret = ENOENT;
 199
 200    vals = ldap_get_values_len(lcontext, le, attrname);
 201    if (vals) {
 202        ber_tag_t tag;
 203        ber_int_t major_vno;
 204        ber_int_t minor_vno;
 205        ber_int_t kvno;
 206        ber_int_t mkvno;
 207        ber_int_t type;
 208        ber_tag_t seqtag;
 209        ber_len_t seqlen;
 210        ber_len_t setlen;
 211        ber_tag_t retag;
 212        ber_tag_t opttag;
 213        struct berval tval;
 214
 215        be = ber_alloc_t(LBER_USE_DER);
 216        if (!be) {
 217            return ENOMEM;
 218        }
 219
 220        /* reinit the ber element with the new val */
 221        ber_init2(be, vals[0], LBER_USE_DER);
 222
 223        /* fill key_data struct with the data */
 224        retag = ber_scanf(be, "{t[i]t[i]t[i]t[i]t[{",
 225                          &tag, &major_vno,
 226                          &tag, &minor_vno,
 227                          &tag, &kvno,
 228                          &tag, &mkvno,
 229                          &seqtag);
 230        if (retag == LBER_ERROR ||
 231                major_vno != 1 ||
 232                minor_vno != 1 ||
 233                seqtag != (LBER_CONSTRUCTED | LBER_CLASS_CONTEXT | 4)) {
 234            ret = EINVAL;
 235            goto done;
 236        }
 237
 238        retag = ber_skip_tag(be, &seqlen);
 239
 240        /* sequence of keys */
 241        for (i = 0; retag == LBER_SEQUENCE; i++) {
 242
CID 11023: Resource leak (RESOURCE_LEAK)
Calling allocation function "realloc".
Assigning: "tmp" = storage returned from "realloc(keys, (i + 1) * 32UL)".
 243            tmp = realloc(keys, (i + 1) * sizeof(krb5_key_data));
At conditional (1): "!tmp" taking the false branch.
 244            if (!tmp) {
 245                ret = ENOMEM;
 246                goto done;
 247            }
Assigning: "keys" = "tmp".
 248            keys = tmp;
 249
Variable "keys" is not freed or pointed-to in function "memset".
 250            memset(&keys[i], 0, sizeof(krb5_key_data));
 251
 252            keys[i].key_data_kvno = kvno;
 253
 254            /* do we have a salt type ? (optional) */
 255            retag = ber_scanf(be, "t", &opttag);
At conditional (2): "retag == 18446744073709551615UL" taking the true branch.
 256            if (retag == LBER_ERROR) {
 257                ret = EINVAL;
 258                goto done;
 259            }
 260            if (opttag == (LBER_CONSTRUCTED | LBER_CLASS_CONTEXT | 0)) {
 261                keys[i].key_data_ver = 2;
 262
 263                retag = ber_scanf(be, "[l{tl[i]",
 264                                  &seqlen, &tag, &setlen, &type);
 265                if (tag != (LBER_CONSTRUCTED | LBER_CLASS_CONTEXT | 0)) {
 266                    ret = EINVAL;
 267                    goto done;
 268                }
 269                keys[i].key_data_type[1] = type;
 270
 271                /* do we have salt data ? (optional) */
 272                if (seqlen > setlen + 2) {
 273                    retag = ber_scanf(be, "t[o]", &tag, &tval);
 274                    if (retag == LBER_ERROR ||
 275                        tag != (LBER_CONSTRUCTED | LBER_CLASS_CONTEXT | 1)) {
 276                        ret = EINVAL;
 277                        goto done;
 278                    }
 279                    keys[i].key_data_length[1] = tval.bv_len;
 280                    keys[i].key_data_contents[1] = (krb5_octet *)tval.bv_val;
 281                }
 282
 283                retag = ber_scanf(be, "}]t", &opttag);
 284                if (retag == LBER_ERROR) {
 285                    ret = EINVAL;
 286                    goto done;
 287                }
 288
 289            } else {
 290                keys[i].key_data_ver = 1;
 291            }
 292
 293            if (opttag != (LBER_CONSTRUCTED | LBER_CLASS_CONTEXT | 1)) {
 294                ret = EINVAL;
 295                goto done;
 296            }
 297
 298            /* get the key */
 299            retag = ber_scanf(be, "[{t[i]t[o]}]", &tag, &type, &tag, &tval);
 300            if (retag == LBER_ERROR) {
 301                ret = EINVAL;
 302                goto done;
 303            }
 304            keys[i].key_data_type[0] = type;
 305            keys[i].key_data_length[0] = tval.bv_len;
 306            keys[i].key_data_contents[0] = (krb5_octet *)tval.bv_val;
 307
 308            /* check for sk2params */
 309            retag = ber_peek_tag(be, &setlen);
 310            if (retag == (LBER_CONSTRUCTED | LBER_CLASS_CONTEXT | 2)) {
 311                /* not supported yet, skip */
 312                retag = ber_scanf(be, "t[x]}");
 313            } else {
 314                retag = ber_scanf(be, "}");
 315            }
 316            if (retag == LBER_ERROR) {
 317                ret = EINVAL;
 318                goto done;
 319            }
 320
 321            retag = ber_skip_tag(be, &seqlen);
 322        }
 323        *result = keys;
 324        *num = i;
 325        *res_mkvno = mkvno;
 326        ret = 0;
 327    }
 328
 329done:
 330    ber_free(be, 0); /* internal buffer is 'vals[0]' */
 331    ldap_value_free_len(vals);
At conditional (3): "ret" taking the true branch.
 332    if (ret) {
At conditional (4): "keys" taking the true branch.
At conditional (5): "i >= 0" taking the false branch.
 333        for (i -= 1; keys && i >= 0; i--) {
 334            free(keys[i].key_data_contents[0]);
 335            free(keys[i].key_data_contents[1]);
 336        }
 337        *result = NULL;
 338        *num = 0;
 339    }
Variable "keys" going out of scope leaks the storage it points to.
Variable "tmp" going out of scope leaks the storage it points to.
 340    return ret;
 341}
 342



1366static krb5_error_code ipadb_entry_to_mods(krb5_context kcontext,
1367                                           struct ipadb_mods *imods,
1368                                           krb5_db_entry *entry,
1369                                           char *principal,
1370                                           int mod_op)
1371{
...
1610        if (ied->ipa_user && ied->passwd && ied->pol.history_length) {
CID 11022: Resource leak (RESOURCE_LEAK)
Calling allocation function "ipapwd_generate_new_history" on "new_history". [show details]
1611            ret = ipapwd_generate_new_history(ied->passwd, now,
1612                                              ied->pol.history_length,
1613                                              ied->pw_history,
1614                                              &new_history, &nh_len);
At conditional (1): "ret" taking the false branch.
1615            if (ret) {
1616                kerr = ret;
1617                goto done;
1618            }
1619
Variable "new_history" is not freed or pointed-to in function "ipadb_get_ldap_mod_str_list". [show details]
1620            kerr = ipadb_get_ldap_mod_str_list(imods, "passwordHistory",
1621                                               new_history, nh_len, mod_op);
At conditional (2): "kerr" taking the true branch.
1622            if (kerr) {
Variable "new_history" going out of scope leaks the storage it points to.
1623                goto done;
1624            }
1625        }
Variable "new_history" going out of scope leaks the storage it points to.
1626    }
1627
1628    kerr = 0;
1629
1630done:
1631    return kerr;
1632}

util/ipa_pwd.c:

553int ipapwd_generate_new_history(char *password,
554                                time_t cur_time,
555                                int history_length,
556                                char **pwd_history,
557                                char ***new_pwd_history,
558                                int *new_pwd_hlen)
559{
560    unsigned char *hash = NULL;
561    unsigned int hash_len;
562    char *new_element;
563    char **ordered;
564    int c, i, n;
565    int len;
566    int ret;
567
568    if (history_length == 0) {
569        return EINVAL;
570    }
571
572    /* hardcode best hash we know about for now */
573    ret = ipapwd_hash_password(password, DEFAULT_HASH_TYPE, NULL,
574                               &hash, &hash_len);
575    if (ret != 0) {
576        return IPAPWD_POLICY_ERROR;
577    }
578
579    new_element = ipapwd_hash_to_history(cur_time, DEFAULT_HASH_TYPE,
580                                         hash, hash_len);
581    if (!new_element) {
582        ret = IPAPWD_POLICY_ERROR;
583        goto done;
584    }
585
586    for (c = 0; pwd_history && pwd_history[c]; c++) /* count */ ;
587
588    if (c < history_length) {
589        c = history_length;
590    }
591
CID 11021: Resource leak (RESOURCE_LEAK)
Calling allocation function "calloc".
Assigning: "ordered" = storage returned from "calloc(c + 1, 8UL)".
592    ordered = calloc(c + 1, sizeof(char *));
At conditional (1): "!ordered" taking the false branch.
593    if (!ordered) {
594        ret = IPAPWD_POLICY_ERROR;
595        goto done;
596    }
597
At conditional (2): "pwd_history" taking the true branch.
At conditional (3): "pwd_history[i]" taking the true branch.
At conditional (5): "pwd_history" taking the true branch.
At conditional (6): "pwd_history[i]" taking the true branch.
At conditional (8): "pwd_history" taking the true branch.
At conditional (9): "pwd_history[i]" taking the true branch.
598    for (i = 0, n = 0; pwd_history && pwd_history[i]; i++) {
599        len = strlen(pwd_history[i]);
At conditional (4): "len < 15" taking the true branch.
At conditional (7): "len < 15" taking the true branch.
At conditional (10): "len < 15" taking the false branch.
600        if (len < GENERALIZED_TIME_LENGTH) {
601            /* garbage, ignore */
602            continue;
603        }
At conditional (11): "0" taking the false branch.
604        ordered[n] = strdup(pwd_history[i]);
At conditional (12): "!ordered[n]" taking the true branch.
605        if (!ordered[n]) {
606            ret = IPAPWD_POLICY_ERROR;
607            goto done;
608        }
609        n++;
610    }
611
612    if (n) {
613        qsort(ordered, n, sizeof(char *), ipapwd_gentime_cmp);
614    }
615
616    if (n >= history_length) {
617        for (i = history_length; i < n; i++) {
618            free(ordered[i]);
619        }
620        n = history_length;
621    } else {
622        n++;
623    }
624    ordered[n - 1] = new_element;
625    ordered[n] = NULL;
626
627    *new_pwd_history = ordered;
628    *new_pwd_hlen = n;
629    ret = IPAPWD_POLICY_OK;
630
631done:
632    free(hash);
Variable "ordered" going out of scope leaks the storage it points to.
633    return ret;
634}

ipa_kdb_passwords.c:

krb5_error_code ipadb_change_pwd(krb5_context context,
167                                 krb5_keyblock *master_key,
168                                 krb5_key_salt_tuple *ks_tuple,
169                                 int ks_tuple_count, char *passwd,
170                                 int new_kvno, krb5_boolean keepold,
171                                 krb5_db_entry *db_entry)
172{
173    krb5_error_code kerr;
174    krb5_data pwd;
175    struct ipadb_context *ipactx;
176    struct ipadb_e_data *ied;
177    krb5_key_salt_tuple *fks = NULL;
178    int n_fks;
179    krb5_key_data *keys = NULL;
180    int n_keys;
181    krb5_key_data *tdata;
182    int t_keys;
183    int old_kvno;
184    int ret;
185    int i;
186
187    ipactx = ipadb_get_context(context);
188    if (!ipactx) {
189        return KRB5_KDB_DBNOTINITED;
190    }
191
192    if (!db_entry->e_data) {
193        if (!ipactx->override_restrictions) {
194            return EINVAL;
195        } else {
196            /* kadmin is creating a new principal */
CID 11020: Resource leak (RESOURCE_LEAK)
Calling allocation function "calloc".
Assigning: "ied" = storage returned from "calloc(1UL, 64UL)".
197            ied = calloc(1, sizeof(struct ipadb_e_data));
At conditional (1): "!ied" taking the false branch.
198            if (!ied) {
199                return ENOMEM;
200            }
201            ied->magic = IPA_E_DATA_MAGIC;
202            /* set the default policy on new entries */
203            ret = asprintf(&ied->pw_policy_dn,
204                           "cn=global_policy,%s", ipactx->realm_base);
At conditional (2): "ret == -1" taking the true branch.
205            if (ret == -1) {
Variable "ied" going out of scope leaks the storage it points to.
206                return ENOMEM;
207            }
208            db_entry->e_data = (krb5_octet *)ied;
209        }
210    }

ipa_kdb.c:

162int ipadb_get_connection(struct ipadb_context *ipactx)
163{
164    struct berval **vals = NULL;
165    struct timeval tv = { 5, 0 };
166    LDAPMessage *res = NULL;
167    LDAPMessage *first;
168    krb5_key_salt_tuple *kst;
169    int n_kst;
170    int ret;
171    int v3;
172    int i;
173    char **cvals = NULL;
174    int c = 0;
175
176    if (!ipactx->uri) {
177        return EINVAL;
178    }
179
180    /* free existing conneciton if any */
181    if (ipactx->lcontext) {
182        ldap_unbind_ext_s(ipactx->lcontext, NULL, NULL);
183        ipactx->lcontext = NULL;
184    }
185
186    ret = ldap_initialize(&ipactx->lcontext, ipactx->uri);
187    if (ret != LDAP_SUCCESS) {
188        goto done;
189    }
190
191    /* make sure we talk LDAPv3 */
192    v3 = LDAP_VERSION3;
193    ret = ldap_set_option(ipactx->lcontext, LDAP_OPT_PROTOCOL_VERSION, &v3);
194    if (ret != LDAP_OPT_SUCCESS) {
195        goto done;
196    }
197
198    ret = ldap_set_option(ipactx->lcontext,  LDAP_OPT_NETWORK_TIMEOUT, &tv);
199    if (ret != LDAP_OPT_SUCCESS) {
200        goto done;
201    }
202
203    ret = ldap_set_option(ipactx->lcontext,  LDAP_OPT_TIMEOUT, &tv);
204    if (ret != LDAP_OPT_SUCCESS) {
205        goto done;
206    }
207
208    ret = ldap_sasl_bind_s(ipactx->lcontext,
209                           NULL, "EXTERNAL",
210                           NULL, NULL, NULL, NULL);
211    if (ret != LDAP_SUCCESS) {
212        goto done;
213    }
214
215    /* TODO: search rootdse */
216
217    ret = ipadb_simple_search(ipactx,
218                              ipactx->realm_base, LDAP_SCOPE_BASE,
219                              "(objectclass=*)", NULL, &res);
220    if (ret) {
221        goto done;
222    }
223
224    first = ldap_first_entry(ipactx->lcontext, res);
225    if (!first) {
226        goto done;
227    }
228
229    vals = ldap_get_values_len(ipactx->lcontext, first,
230                               "krbSupportedEncSaltTypes");
231    if (!vals || !vals[0]) {
232        goto done;
233    }
234
235    for (c = 0; vals[c]; c++) /* count */ ;
CID 11019: Resource leak (RESOURCE_LEAK)
Calling allocation function "calloc".
Assigning: "cvals" = storage returned from "calloc(c, 8UL)".
236    cvals = calloc(c, sizeof(char *));
At conditional (1): "!cvals" taking the false branch.
237    if (!cvals) {
238        ret = ENOMEM;
239        goto done;
240    }
At conditional (2): "i < c" taking the true branch.
241    for (i = 0; i < c; i++) {
At conditional (3): "0" taking the false branch.
242        cvals[i] = strndup(vals[i]->bv_val, vals[i]->bv_len);
At conditional (4): "!cvals[i]" taking the true branch.
243        if (!cvals[i]) {
244            ret = ENOMEM;
245            goto done;
246        }
247    }
248
Variable "cvals" is not freed or pointed-to in function "parse_bval_key_salt_tuples". [show details]
249    ret = parse_bval_key_salt_tuples(ipactx->kcontext,
250                                     (const char * const *)cvals, c,
251                                     &kst, &n_kst);
252    if (ret) {
253        goto done;
254    }
255
256    if (ipactx->supp_encs) {
257        free(ipactx->supp_encs);
258    }
259    ipactx->supp_encs = kst;
260    ipactx->n_supp_encs = n_kst;
261
262    ret = 0;
263
264done:
At conditional (5): "ret" taking the true branch.
265    if (ret) {
At conditional (6): "ipactx->lcontext" taking the true branch.
266        if (ipactx->lcontext) {
267            ldap_unbind_ext_s(ipactx->lcontext, NULL, NULL);
268            ipactx->lcontext = NULL;
269        }
At conditional (7): "ret == -1" taking the false branch.
270        if (ret == LDAP_SERVER_DOWN) {
271            return ETIMEDOUT;
272        }
Variable "cvals" going out of scope leaks the storage it points to.
273        return EIO;
274    }
275
276    ldap_value_free_len(vals);
277    for (i = 0; i < c; i++) {
278        free(cvals[i]);
279    }
280    free(cvals);
281
282    return 0;
283}

Metadata Update from @mkosek:
- Issue assigned to simo
- Issue set to the milestone: FreeIPA 3.0 Core Effort - 2011/11

7 years ago

Login to comment on this ticket.

Metadata