LCOV - code coverage report
Current view: top level - source4/heimdal/lib/krb5 - keytab_memory.c (source / functions) Hit Total Coverage
Test: coverage report for abartlet/fix-coverage dd10fb34 Lines: 73 90 81.1 %
Date: 2021-09-23 10:06:22 Functions: 8 8 100.0 %

          Line data    Source code
       1             : /*
       2             :  * Copyright (c) 1997 - 2001 Kungliga Tekniska Högskolan
       3             :  * (Royal Institute of Technology, Stockholm, Sweden).
       4             :  * All rights reserved.
       5             :  *
       6             :  * Redistribution and use in source and binary forms, with or without
       7             :  * modification, are permitted provided that the following conditions
       8             :  * are met:
       9             :  *
      10             :  * 1. Redistributions of source code must retain the above copyright
      11             :  *    notice, this list of conditions and the following disclaimer.
      12             :  *
      13             :  * 2. Redistributions in binary form must reproduce the above copyright
      14             :  *    notice, this list of conditions and the following disclaimer in the
      15             :  *    documentation and/or other materials provided with the distribution.
      16             :  *
      17             :  * 3. Neither the name of the Institute nor the names of its contributors
      18             :  *    may be used to endorse or promote products derived from this software
      19             :  *    without specific prior written permission.
      20             :  *
      21             :  * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
      22             :  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
      23             :  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
      24             :  * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
      25             :  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
      26             :  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
      27             :  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
      28             :  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
      29             :  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
      30             :  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
      31             :  * SUCH DAMAGE.
      32             :  */
      33             : 
      34             : #include "krb5_locl.h"
      35             : 
      36             : /* memory operations -------------------------------------------- */
      37             : 
      38             : struct mkt_data {
      39             :     krb5_keytab_entry *entries;
      40             :     int num_entries;
      41             :     char *name;
      42             :     int refcount;
      43             :     struct mkt_data *next;
      44             : };
      45             : 
      46             : /* this mutex protects mkt_head, ->refcount, and ->next
      47             :  * content is not protected (name is static and need no protection)
      48             :  */
      49             : static HEIMDAL_MUTEX mkt_mutex = HEIMDAL_MUTEX_INITIALIZER;
      50             : static struct mkt_data *mkt_head;
      51             : 
      52             : 
      53             : static krb5_error_code KRB5_CALLCONV
      54        4025 : mkt_resolve(krb5_context context, const char *name, krb5_keytab id)
      55             : {
      56             :     struct mkt_data *d;
      57             : 
      58             :     HEIMDAL_MUTEX_lock(&mkt_mutex);
      59             : 
      60        4299 :     for (d = mkt_head; d != NULL; d = d->next)
      61        2784 :         if (strcmp(d->name, name) == 0)
      62        2510 :             break;
      63        4025 :     if (d) {
      64        2510 :         if (d->refcount < 1)
      65           0 :             krb5_abortx(context, "Double close on memory keytab, "
      66             :                         "refcount < 1 %d", d->refcount);
      67        2510 :         d->refcount++;
      68        2510 :         id->data = d;
      69             :         HEIMDAL_MUTEX_unlock(&mkt_mutex);
      70        2510 :         return 0;
      71             :     }
      72             : 
      73        1515 :     d = calloc(1, sizeof(*d));
      74        1515 :     if(d == NULL) {
      75             :         HEIMDAL_MUTEX_unlock(&mkt_mutex);
      76           0 :         krb5_set_error_message(context, ENOMEM,
      77           0 :                                N_("malloc: out of memory", ""));
      78           0 :         return ENOMEM;
      79             :     }
      80        1515 :     d->name = strdup(name);
      81        1515 :     if (d->name == NULL) {
      82             :         HEIMDAL_MUTEX_unlock(&mkt_mutex);
      83           0 :         free(d);
      84           0 :         krb5_set_error_message(context, ENOMEM,
      85           0 :                                N_("malloc: out of memory", ""));
      86           0 :         return ENOMEM;
      87             :     }
      88        1515 :     d->entries = NULL;
      89        1515 :     d->num_entries = 0;
      90        1515 :     d->refcount = 1;
      91        1515 :     d->next = mkt_head;
      92        1515 :     mkt_head = d;
      93             :     HEIMDAL_MUTEX_unlock(&mkt_mutex);
      94        1515 :     id->data = d;
      95        1515 :     return 0;
      96             : }
      97             : 
      98             : static krb5_error_code KRB5_CALLCONV
      99        3983 : mkt_close(krb5_context context, krb5_keytab id)
     100             : {
     101        3983 :     struct mkt_data *d = id->data, **dp;
     102             :     int i;
     103             : 
     104             :     HEIMDAL_MUTEX_lock(&mkt_mutex);
     105        3983 :     if (d->refcount < 1)
     106           0 :         krb5_abortx(context,
     107             :                     "krb5 internal error, memory keytab refcount < 1 on close");
     108             : 
     109        3983 :     if (--d->refcount > 0) {
     110             :         HEIMDAL_MUTEX_unlock(&mkt_mutex);
     111        2488 :         return 0;
     112             :     }
     113        1495 :     for (dp = &mkt_head; *dp != NULL; dp = &(*dp)->next) {
     114        1495 :         if (*dp == d) {
     115        1495 :             *dp = d->next;
     116        1495 :             break;
     117             :         }
     118             :     }
     119             :     HEIMDAL_MUTEX_unlock(&mkt_mutex);
     120             : 
     121        1495 :     free(d->name);
     122       10808 :     for(i = 0; i < d->num_entries; i++)
     123        9313 :         krb5_kt_free_entry(context, &d->entries[i]);
     124        1495 :     free(d->entries);
     125        1495 :     free(d);
     126        1495 :     return 0;
     127             : }
     128             : 
     129             : static krb5_error_code KRB5_CALLCONV
     130        3228 : mkt_get_name(krb5_context context,
     131             :              krb5_keytab id,
     132             :              char *name,
     133             :              size_t namesize)
     134             : {
     135        3228 :     struct mkt_data *d = id->data;
     136        3228 :     strlcpy(name, d->name, namesize);
     137        3228 :     return 0;
     138             : }
     139             : 
     140             : static krb5_error_code KRB5_CALLCONV
     141        3235 : mkt_start_seq_get(krb5_context context,
     142             :                   krb5_keytab id,
     143             :                   krb5_kt_cursor *c)
     144             : {
     145             :     /* XXX */
     146        3235 :     c->fd = 0;
     147        3235 :     return 0;
     148             : }
     149             : 
     150             : static krb5_error_code KRB5_CALLCONV
     151        7084 : mkt_next_entry(krb5_context context,
     152             :                krb5_keytab id,
     153             :                krb5_keytab_entry *entry,
     154             :                krb5_kt_cursor *c)
     155             : {
     156        7084 :     struct mkt_data *d = id->data;
     157        7084 :     if(c->fd >= d->num_entries)
     158        2227 :         return KRB5_KT_END;
     159        4853 :     return krb5_kt_copy_entry_contents(context, &d->entries[c->fd++], entry);
     160             : }
     161             : 
     162             : static krb5_error_code KRB5_CALLCONV
     163        1790 : mkt_end_seq_get(krb5_context context,
     164             :                 krb5_keytab id,
     165             :                 krb5_kt_cursor *cursor)
     166             : {
     167        1790 :     return 0;
     168             : }
     169             : 
     170             : static krb5_error_code KRB5_CALLCONV
     171        9461 : mkt_add_entry(krb5_context context,
     172             :               krb5_keytab id,
     173             :               krb5_keytab_entry *entry)
     174             : {
     175        9461 :     struct mkt_data *d = id->data;
     176             :     krb5_keytab_entry *tmp;
     177        9461 :     tmp = realloc(d->entries, (d->num_entries + 1) * sizeof(*d->entries));
     178        9461 :     if(tmp == NULL) {
     179           0 :         krb5_set_error_message(context, ENOMEM,
     180           0 :                                N_("malloc: out of memory", ""));
     181           0 :         return ENOMEM;
     182             :     }
     183        9461 :     d->entries = tmp;
     184        9461 :     return krb5_kt_copy_entry_contents(context, entry,
     185        9461 :                                        &d->entries[d->num_entries++]);
     186             : }
     187             : 
     188             : static krb5_error_code KRB5_CALLCONV
     189          16 : mkt_remove_entry(krb5_context context,
     190             :                  krb5_keytab id,
     191             :                  krb5_keytab_entry *entry)
     192             : {
     193          16 :     struct mkt_data *d = id->data;
     194             :     krb5_keytab_entry *e, *end;
     195          16 :     int found = 0;
     196             : 
     197          16 :     if (d->num_entries == 0) {
     198           0 :         krb5_clear_error_message(context);
     199           0 :         return KRB5_KT_NOTFOUND;
     200             :     }
     201             : 
     202             :     /* do this backwards to minimize copying */
     203         213 :     for(end = d->entries + d->num_entries, e = end - 1; e >= d->entries; e--) {
     204         197 :         if(krb5_kt_compare(context, e, entry->principal,
     205         197 :                            entry->vno, entry->keyblock.keytype)) {
     206          16 :             krb5_kt_free_entry(context, e);
     207          32 :             memmove(e, e + 1, (end - e - 1) * sizeof(*e));
     208          32 :             memset(end - 1, 0, sizeof(*end));
     209          16 :             d->num_entries--;
     210          16 :             end--;
     211          16 :             found = 1;
     212             :         }
     213             :     }
     214          16 :     if (!found) {
     215           0 :         krb5_clear_error_message (context);
     216           0 :         return KRB5_KT_NOTFOUND;
     217             :     }
     218          16 :     e = realloc(d->entries, d->num_entries * sizeof(*d->entries));
     219          16 :     if(e != NULL || d->num_entries == 0)
     220          16 :         d->entries = e;
     221           0 :     return 0;
     222             : }
     223             : 
     224             : const krb5_kt_ops krb5_mkt_ops = {
     225             :     "MEMORY",
     226             :     mkt_resolve,
     227             :     mkt_get_name,
     228             :     mkt_close,
     229             :     NULL, /* destroy */
     230             :     NULL, /* get */
     231             :     mkt_start_seq_get,
     232             :     mkt_next_entry,
     233             :     mkt_end_seq_get,
     234             :     mkt_add_entry,
     235             :     mkt_remove_entry
     236             : };

Generated by: LCOV version 1.13