LCOV - code coverage report
Current view: top level - third_party/heimdal/lib/krb5 - keytab_memory.c (source / functions) Hit Total Coverage
Test: coverage report for master 2f515e9b Lines: 78 95 82.1 %
Date: 2024-04-21 15:09:00 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        5811 : mkt_resolve(krb5_context context, const char *name, krb5_keytab id)
      55             : {
      56           2 :     struct mkt_data *d;
      57             : 
      58           2 :     HEIMDAL_MUTEX_lock(&mkt_mutex);
      59             : 
      60        6040 :     for (d = mkt_head; d != NULL; d = d->next)
      61        3829 :         if (strcmp(d->name, name) == 0)
      62        3600 :             break;
      63        5811 :     if (d) {
      64        3600 :         if (d->refcount < 1)
      65           0 :             krb5_abortx(context, "Double close on memory keytab, "
      66             :                         "refcount < 1 %d", d->refcount);
      67        3600 :         d->refcount++;
      68        3600 :         id->data = d;
      69           0 :         HEIMDAL_MUTEX_unlock(&mkt_mutex);
      70        3600 :         return 0;
      71             :     }
      72             : 
      73        2211 :     d = calloc(1, sizeof(*d));
      74        2211 :     if(d == NULL) {
      75           0 :         HEIMDAL_MUTEX_unlock(&mkt_mutex);
      76           0 :         return krb5_enomem(context);
      77             :     }
      78        2211 :     d->name = strdup(name);
      79        2211 :     if (d->name == NULL) {
      80           0 :         HEIMDAL_MUTEX_unlock(&mkt_mutex);
      81           0 :         free(d);
      82           0 :         return krb5_enomem(context);
      83             :     }
      84        2211 :     d->entries = NULL;
      85        2211 :     d->num_entries = 0;
      86        2211 :     d->refcount = 1;
      87        2211 :     d->next = mkt_head;
      88        2211 :     mkt_head = d;
      89           2 :     HEIMDAL_MUTEX_unlock(&mkt_mutex);
      90        2211 :     id->data = d;
      91        2211 :     return 0;
      92             : }
      93             : 
      94             : static krb5_error_code KRB5_CALLCONV
      95        5777 : mkt_close(krb5_context context, krb5_keytab id)
      96             : {
      97        5777 :     struct mkt_data *d = id->data, **dp;
      98           0 :     int i;
      99             : 
     100           0 :     HEIMDAL_MUTEX_lock(&mkt_mutex);
     101        5777 :     if (d->refcount < 1)
     102           0 :         krb5_abortx(context,
     103             :                     "krb5 internal error, memory keytab refcount < 1 on close");
     104             : 
     105        5777 :     if (--d->refcount > 0) {
     106             :         HEIMDAL_MUTEX_unlock(&mkt_mutex);
     107        3582 :         return 0;
     108             :     }
     109        2195 :     for (dp = &mkt_head; *dp != NULL; dp = &(*dp)->next) {
     110        2195 :         if (*dp == d) {
     111        2195 :             *dp = d->next;
     112        2195 :             break;
     113             :         }
     114             :     }
     115           0 :     HEIMDAL_MUTEX_unlock(&mkt_mutex);
     116             : 
     117        2195 :     free(d->name);
     118       18026 :     for(i = 0; i < d->num_entries; i++)
     119       15831 :         krb5_kt_free_entry(context, &d->entries[i]);
     120        2195 :     free(d->entries);
     121        2195 :     free(d);
     122        2195 :     return 0;
     123             : }
     124             : 
     125             : static krb5_error_code KRB5_CALLCONV
     126        4470 : mkt_get_name(krb5_context context,
     127             :              krb5_keytab id,
     128             :              char *name,
     129             :              size_t namesize)
     130             : {
     131        4470 :     struct mkt_data *d = id->data;
     132        4470 :     strlcpy(name, d->name, namesize);
     133        4470 :     return 0;
     134             : }
     135             : 
     136             : static krb5_error_code KRB5_CALLCONV
     137        4642 : mkt_start_seq_get(krb5_context context,
     138             :                   krb5_keytab id,
     139             :                   krb5_kt_cursor *c)
     140             : {
     141             :     /* XXX */
     142        4642 :     c->fd = 0;
     143        4642 :     return 0;
     144             : }
     145             : 
     146             : static krb5_error_code KRB5_CALLCONV
     147       10463 : mkt_next_entry(krb5_context context,
     148             :                krb5_keytab id,
     149             :                krb5_keytab_entry *entry,
     150             :                krb5_kt_cursor *c)
     151             : {
     152       10463 :     struct mkt_data *d = id->data;
     153       10463 :     if(c->fd >= d->num_entries)
     154        3305 :         return KRB5_KT_END;
     155        7154 :     return krb5_kt_copy_entry_contents(context, &d->entries[c->fd++], entry);
     156             : }
     157             : 
     158             : static krb5_error_code KRB5_CALLCONV
     159        4638 : mkt_end_seq_get(krb5_context context,
     160             :                 krb5_keytab id,
     161             :                 krb5_kt_cursor *cursor)
     162             : {
     163        4638 :     return 0;
     164             : }
     165             : 
     166             : static krb5_error_code KRB5_CALLCONV
     167       15951 : mkt_add_entry(krb5_context context,
     168             :               krb5_keytab id,
     169             :               krb5_keytab_entry *entry)
     170             : {
     171       15951 :     struct mkt_data *d = id->data;
     172          22 :     krb5_keytab_entry *tmp;
     173       15951 :     tmp = realloc(d->entries, (d->num_entries + 1) * sizeof(*d->entries));
     174       15951 :     if (tmp == NULL)
     175           0 :         return krb5_enomem(context);
     176       15951 :     d->entries = tmp;
     177       15951 :     return krb5_kt_copy_entry_contents(context, entry,
     178       15951 :                                        &d->entries[d->num_entries++]);
     179             : }
     180             : 
     181             : static krb5_error_code KRB5_CALLCONV
     182          16 : mkt_remove_entry(krb5_context context,
     183             :                  krb5_keytab id,
     184             :                  krb5_keytab_entry *entry)
     185             : {
     186          16 :     struct mkt_data *d = id->data;
     187          16 :     krb5_keytab_entry *e, *end;
     188          16 :     int found = 0;
     189             : 
     190          16 :     if (d->num_entries == 0) {
     191           0 :         krb5_clear_error_message(context);
     192           0 :         return KRB5_KT_NOTFOUND;
     193             :     }
     194             : 
     195             :     /* do this backwards to minimize copying */
     196         213 :     for(end = d->entries + d->num_entries, e = end - 1; e >= d->entries; e--) {
     197         197 :         if(krb5_kt_compare(context, e, entry->principal,
     198         197 :                            entry->vno, entry->keyblock.keytype)) {
     199          16 :             krb5_kt_free_entry(context, e);
     200          16 :             memmove(e, e + 1, (end - e - 1) * sizeof(*e));
     201          16 :             memset(end - 1, 0, sizeof(*end));
     202          16 :             d->num_entries--;
     203          16 :             end--;
     204          16 :             found = 1;
     205             :         }
     206             :     }
     207          16 :     if (!found) {
     208           0 :         krb5_clear_error_message (context);
     209           0 :         return KRB5_KT_NOTFOUND;
     210             :     }
     211          16 :     e = realloc(d->entries, d->num_entries * sizeof(*d->entries));
     212          16 :     if(e != NULL || d->num_entries == 0)
     213          16 :         d->entries = e;
     214           0 :     return 0;
     215             : }
     216             : 
     217             : const krb5_kt_ops krb5_mkt_ops = {
     218             :     "MEMORY",
     219             :     mkt_resolve,
     220             :     mkt_get_name,
     221             :     mkt_close,
     222             :     NULL, /* destroy */
     223             :     NULL, /* get */
     224             :     mkt_start_seq_get,
     225             :     mkt_next_entry,
     226             :     mkt_end_seq_get,
     227             :     mkt_add_entry,
     228             :     mkt_remove_entry,
     229             :     NULL,
     230             :     0
     231             : };

Generated by: LCOV version 1.14