LCOV - code coverage report
Current view: top level - third_party/heimdal/lib/krb5 - mcache.c (source / functions) Hit Total Coverage
Test: coverage report for master 2f515e9b Lines: 202 297 68.0 %
Date: 2024-04-21 15:09:00 Functions: 20 25 80.0 %

          Line data    Source code
       1             : /*
       2             :  * Copyright (c) 1997-2004 Kungliga Tekniska Högskolan
       3             :  * (Royal Institute of Technology, Stockholm, Sweden).
       4             :  * All rights reserved.
       5             :  *
       6             :  * Portions Copyright (c) 2009 Apple Inc. All rights reserved.
       7             :  *
       8             :  * Redistribution and use in source and binary forms, with or without
       9             :  * modification, are permitted provided that the following conditions
      10             :  * are met:
      11             :  *
      12             :  * 1. Redistributions of source code must retain the above copyright
      13             :  *    notice, this list of conditions and the following disclaimer.
      14             :  *
      15             :  * 2. Redistributions in binary form must reproduce the above copyright
      16             :  *    notice, this list of conditions and the following disclaimer in the
      17             :  *    documentation and/or other materials provided with the distribution.
      18             :  *
      19             :  * 3. Neither the name of the Institute nor the names of its contributors
      20             :  *    may be used to endorse or promote products derived from this software
      21             :  *    without specific prior written permission.
      22             :  *
      23             :  * THIS SOFTWARE IS PROVIDED BY THE INSTITUTE AND CONTRIBUTORS ``AS IS'' AND
      24             :  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
      25             :  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
      26             :  * ARE DISCLAIMED.  IN NO EVENT SHALL THE INSTITUTE OR CONTRIBUTORS BE LIABLE
      27             :  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
      28             :  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
      29             :  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
      30             :  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
      31             :  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
      32             :  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
      33             :  * SUCH DAMAGE.
      34             :  */
      35             : 
      36             : #include "krb5_locl.h"
      37             : 
      38             : typedef struct krb5_mcache {
      39             :     char *name;
      40             :     unsigned int refcnt;
      41             :     unsigned int anonymous:1;
      42             :     unsigned int dead:1;
      43             :     krb5_principal primary_principal;
      44             :     struct link {
      45             :         krb5_creds cred;
      46             :         struct link *next;
      47             :     } *creds;
      48             :     struct krb5_mcache *next;
      49             :     time_t mtime;
      50             :     krb5_deltat kdc_offset;
      51             :     HEIMDAL_MUTEX mutex;
      52             : } krb5_mcache;
      53             : 
      54             : static HEIMDAL_MUTEX mcc_mutex = HEIMDAL_MUTEX_INITIALIZER;
      55             : static struct krb5_mcache *mcc_head;
      56             : 
      57             : #define MCACHE(X)       ((krb5_mcache *)(X)->data.data)
      58             : 
      59             : #define MISDEAD(X)      ((X)->dead)
      60             : 
      61             : static krb5_error_code KRB5_CALLCONV
      62      102114 : mcc_get_name_2(krb5_context context,
      63             :                krb5_ccache id,
      64             :                const char **name,
      65             :                const char **col,
      66             :                const char **sub)
      67             : {
      68      102114 :     if (name)
      69      102114 :         *name = MCACHE(id)->name;
      70      102114 :     if (col)
      71           0 :         *col = NULL;
      72      102114 :     if (sub)
      73           0 :         *sub = MCACHE(id)->name;
      74      102114 :     return 0;
      75             : }
      76             : 
      77             : static krb5_error_code
      78      284100 : mcc_alloc(krb5_context context, const char *name, krb5_mcache **out)
      79             : {
      80        3849 :     krb5_mcache *m, *m_c;
      81      284100 :     size_t counter = 0;
      82      284100 :     int ret = 0;
      83      284100 :     unsigned create_anonymous = 0;
      84             : 
      85      284100 :     *out = NULL;
      86      284100 :     ALLOC(m, 1);
      87      284100 :     if(m == NULL)
      88           0 :         return krb5_enomem(context);
      89             : 
      90      284100 : again:
      91      284100 :     if (counter > 3) {
      92           0 :         free(m->name);
      93           0 :         free(m);
      94           0 :         return EAGAIN; /* XXX */
      95             :     }
      96      284100 :     if(name == NULL) {
      97       23113 :         ret = asprintf(&m->name, "u%p-%llu", m, (unsigned long long)counter);
      98      260987 :     } else if (strcmp(name, "anonymous") == 0) {
      99       48843 :         ret = asprintf(&m->name, "anonymous-%p-%llu", m, (unsigned long long)counter);
     100       48843 :         create_anonymous = 1;
     101             :     } else {
     102      212144 :         m->name = strdup(name);
     103             :     }
     104      284100 :     if(ret < 0 || m->name == NULL) {
     105           0 :         free(m);
     106           0 :         return krb5_enomem(context);
     107             :     }
     108             : 
     109             :     /* check for dups first */
     110        3849 :     HEIMDAL_MUTEX_lock(&mcc_mutex);
     111     1229737 :     for (m_c = mcc_head; m_c != NULL; m_c = m_c->next)
     112     1066291 :         if (strcmp(m->name, m_c->name) == 0)
     113      119188 :             break;
     114      284100 :     if (m_c) {
     115      120654 :         if (name && !create_anonymous) {
     116             :             /* We raced with another thread to create this cache */
     117      120654 :             free(m->name);
     118      120654 :             free(m);
     119      120654 :             m = m_c;
     120        1466 :             HEIMDAL_MUTEX_lock(&(m->mutex));
     121      120654 :             m->refcnt++;
     122      120654 :             HEIMDAL_MUTEX_unlock(&(m->mutex));
     123             :         } else {
     124             :             /* How likely are we to conflict on new_unique anyways?? */
     125           0 :             counter++;
     126           0 :             free(m->name);
     127           0 :             m->name = NULL;
     128           0 :             HEIMDAL_MUTEX_unlock(&mcc_mutex);
     129           0 :             goto again;
     130             :         }
     131        1466 :         HEIMDAL_MUTEX_unlock(&mcc_mutex);
     132      120654 :         *out = m;
     133      120654 :         return 0;
     134             :     }
     135             : 
     136      163446 :     m->anonymous = create_anonymous;
     137      163446 :     m->dead = 0;
     138      163446 :     m->refcnt = 1;
     139      163446 :     m->primary_principal = NULL;
     140      163446 :     m->creds = NULL;
     141      163446 :     m->mtime = time(NULL);
     142      163446 :     m->kdc_offset = 0;
     143      163446 :     m->next = mcc_head;
     144        2383 :     HEIMDAL_MUTEX_init(&(m->mutex));
     145      163446 :     mcc_head = m;
     146        2383 :     HEIMDAL_MUTEX_unlock(&mcc_mutex);
     147      163446 :     *out = m;
     148      163446 :     return 0;
     149             : }
     150             : 
     151             : static krb5_error_code KRB5_CALLCONV
     152      260987 : mcc_resolve_2(krb5_context context,
     153             :               krb5_ccache *id,
     154             :               const char *res,
     155             :               const char *sub)
     156             : {
     157        3849 :     krb5_error_code ret;
     158        3849 :     krb5_mcache *m;
     159             : 
     160      264836 :     if ((ret = mcc_alloc(context, sub && *sub ? sub : res, &m)))
     161           0 :         return ret;
     162             : 
     163      260987 :     (*id)->data.data = m;
     164      260987 :     (*id)->data.length = sizeof(*m);
     165             : 
     166      260987 :     return 0;
     167             : }
     168             : 
     169             : 
     170             : static krb5_error_code KRB5_CALLCONV
     171       23113 : mcc_gen_new(krb5_context context, krb5_ccache *id)
     172             : {
     173           0 :     krb5_error_code ret;
     174           0 :     krb5_mcache *m;
     175             : 
     176       23113 :     if ((ret = mcc_alloc(context, NULL, &m)))
     177           0 :         return ret;
     178             : 
     179       23113 :     (*id)->data.data = m;
     180       23113 :     (*id)->data.length = sizeof(*m);
     181             : 
     182       23113 :     return 0;
     183             : }
     184             : 
     185             : static void KRB5_CALLCONV
     186      385651 : mcc_destroy_internal(krb5_context context,
     187             :                      krb5_mcache *m)
     188             : {
     189        5646 :     struct link *l;
     190             : 
     191      385651 :     if (m->primary_principal != NULL) {
     192      228627 :         krb5_free_principal (context, m->primary_principal);
     193      228627 :         m->primary_principal = NULL;
     194             :     }
     195      385651 :     m->dead = 1;
     196             : 
     197      385651 :     l = m->creds;
     198      715760 :     while (l != NULL) {
     199        5422 :         struct link *old;
     200             : 
     201      330109 :         krb5_free_cred_contents (context, &l->cred);
     202      330109 :         old = l;
     203      330109 :         l = l->next;
     204      330109 :         free (old);
     205             :     }
     206             : 
     207      385651 :     m->creds = NULL;
     208      385651 :     return;
     209             : }
     210             : 
     211             : static krb5_error_code KRB5_CALLCONV
     212      229784 : mcc_initialize(krb5_context context,
     213             :                krb5_ccache id,
     214             :                krb5_principal primary_principal)
     215             : {
     216      229784 :     krb5_mcache *m = MCACHE(id);
     217      229784 :     krb5_error_code ret = 0;
     218        3264 :     HEIMDAL_MUTEX_lock(&(m->mutex));
     219      229784 :     heim_assert(m->refcnt != 0, "resurection released mcache");
     220             :     /*
     221             :      * It's important to destroy any existing
     222             :      * creds here, that matches the baheviour
     223             :      * of all other backends and also the
     224             :      * MEMORY: backend in MIT.
     225             :      */
     226      229784 :     mcc_destroy_internal(context, m);
     227      229784 :     m->dead = 0;
     228      229784 :     m->kdc_offset = 0;
     229      229784 :     m->mtime = time(NULL);
     230      229784 :     ret = krb5_copy_principal (context,
     231             :                                primary_principal,
     232             :                                &m->primary_principal);
     233        3264 :     HEIMDAL_MUTEX_unlock(&(m->mutex));
     234      229784 :     return ret;
     235             : }
     236             : 
     237             : static int
     238      282562 : mcc_close_internal(krb5_mcache *m)
     239             : {
     240        3842 :     HEIMDAL_MUTEX_lock(&(m->mutex));
     241      282562 :     heim_assert(m->refcnt != 0, "closed dead cache mcache");
     242      282562 :     if (--m->refcnt != 0) {
     243             :         HEIMDAL_MUTEX_unlock(&(m->mutex));
     244      102170 :         return 0;
     245             :     }
     246      178927 :     if (MISDEAD(m)) {
     247      155847 :         free(m->name);
     248        2377 :         HEIMDAL_MUTEX_unlock(&(m->mutex));
     249      155847 :         return 1;
     250             :     }
     251             :     HEIMDAL_MUTEX_unlock(&(m->mutex));
     252       23080 :     return 0;
     253             : }
     254             : 
     255             : static krb5_error_code KRB5_CALLCONV
     256      282562 : mcc_close(krb5_context context,
     257             :           krb5_ccache id)
     258             : {
     259      282562 :     krb5_mcache *m = MCACHE(id);
     260             : 
     261      282562 :     if (mcc_close_internal(MCACHE(id))) {
     262        2377 :         HEIMDAL_MUTEX_destroy(&(m->mutex));
     263      155847 :         krb5_data_free(&id->data);
     264             :     }
     265      282562 :     return 0;
     266             : }
     267             : 
     268             : static krb5_error_code KRB5_CALLCONV
     269      155867 : mcc_destroy(krb5_context context,
     270             :             krb5_ccache id)
     271             : {
     272      155867 :     krb5_mcache **n, *m = MCACHE(id);
     273             : 
     274        2382 :     HEIMDAL_MUTEX_lock(&mcc_mutex);
     275        2382 :     HEIMDAL_MUTEX_lock(&(m->mutex));
     276      155867 :     if (m->refcnt == 0)
     277             :     {
     278           0 :         HEIMDAL_MUTEX_unlock(&(m->mutex));
     279           0 :         HEIMDAL_MUTEX_unlock(&mcc_mutex);
     280           0 :         krb5_abortx(context, "mcc_destroy: refcnt already 0");
     281             :     }
     282             : 
     283      155867 :     if (!MISDEAD(m)) {
     284             :         /* if this is an active mcache, remove it from the linked
     285             :            list, and free all data */
     286      278906 :         for(n = &mcc_head; n && *n; n = &(*n)->next) {
     287      278906 :             if(m == *n) {
     288      155867 :                 *n = m->next;
     289      155867 :                 break;
     290             :             }
     291             :         }
     292      155867 :         mcc_destroy_internal(context, m);
     293             :     }
     294        2382 :     HEIMDAL_MUTEX_unlock(&(m->mutex));
     295        2382 :     HEIMDAL_MUTEX_unlock(&mcc_mutex);
     296      155867 :     return 0;
     297             : }
     298             : 
     299             : static krb5_error_code KRB5_CALLCONV
     300      334343 : mcc_store_cred(krb5_context context,
     301             :                krb5_ccache id,
     302             :                krb5_creds *creds)
     303             : {
     304      334343 :     krb5_mcache *m = MCACHE(id);
     305        5425 :     krb5_error_code ret;
     306        5425 :     struct link *l;
     307             : 
     308        5425 :     HEIMDAL_MUTEX_lock(&(m->mutex));
     309      334343 :     if (MISDEAD(m))
     310             :     {
     311             :         HEIMDAL_MUTEX_unlock(&(m->mutex));
     312           0 :         return ENOENT;
     313             :     }
     314             : 
     315      334343 :     l = malloc (sizeof(*l));
     316      334343 :     if (l == NULL)
     317           0 :         return krb5_enomem(context);
     318      334343 :     l->next = m->creds;
     319      334343 :     m->creds = l;
     320      334343 :     memset (&l->cred, 0, sizeof(l->cred));
     321      334343 :     ret = krb5_copy_creds_contents (context, creds, &l->cred);
     322      334343 :     if (ret) {
     323           0 :         m->creds = l->next;
     324           0 :         free (l);
     325           0 :         HEIMDAL_MUTEX_unlock(&(m->mutex));
     326           0 :         return ret;
     327             :     }
     328      334343 :     m->mtime = time(NULL);
     329        5425 :         HEIMDAL_MUTEX_unlock(&(m->mutex));
     330      334343 :     return 0;
     331             : }
     332             : 
     333             : static krb5_error_code KRB5_CALLCONV
     334      798592 : mcc_get_principal(krb5_context context,
     335             :                   krb5_ccache id,
     336             :                   krb5_principal *principal)
     337             : {
     338      798592 :     krb5_mcache *m = MCACHE(id);
     339      798592 :     krb5_error_code ret = 0;
     340             : 
     341       15472 :     HEIMDAL_MUTEX_lock(&(m->mutex));
     342      798592 :     if (MISDEAD(m) || m->primary_principal == NULL) {
     343             :         HEIMDAL_MUTEX_unlock(&(m->mutex));
     344       19527 :         return ENOENT;
     345             :     }
     346      779065 :     ret = krb5_copy_principal (context,
     347      763593 :                                m->primary_principal,
     348             :                                principal);
     349       15472 :     HEIMDAL_MUTEX_unlock(&(m->mutex));
     350      779065 :     return ret;
     351             : }
     352             : 
     353             : static krb5_error_code KRB5_CALLCONV
     354      710512 : mcc_get_first (krb5_context context,
     355             :                 krb5_ccache id,
     356             :                 krb5_cc_cursor *cursor)
     357             : {
     358      710512 :     krb5_mcache *m = MCACHE(id);
     359             : 
     360       15043 :     HEIMDAL_MUTEX_lock(&(m->mutex));
     361      710512 :     if (MISDEAD(m)) {
     362             :         HEIMDAL_MUTEX_unlock(&(m->mutex));
     363           0 :         return ENOENT;
     364             :     }
     365      710512 :     *cursor = m->creds;
     366             : 
     367       15043 :     HEIMDAL_MUTEX_unlock(&(m->mutex));
     368      710512 :     return 0;
     369             : }
     370             : 
     371             : static krb5_error_code KRB5_CALLCONV
     372     1900851 : mcc_get_next (krb5_context context,
     373             :               krb5_ccache id,
     374             :               krb5_cc_cursor *cursor,
     375             :               krb5_creds *creds)
     376             : {
     377     1900851 :     krb5_mcache *m = MCACHE(id);
     378       40465 :     struct link *l;
     379             : 
     380       40465 :     HEIMDAL_MUTEX_lock(&(m->mutex));
     381     1900851 :     if (MISDEAD(m)) {
     382             :         HEIMDAL_MUTEX_unlock(&(m->mutex));
     383           0 :         return ENOENT;
     384             :     }
     385       40465 :     HEIMDAL_MUTEX_unlock(&(m->mutex));
     386             : 
     387     1900851 :     l = *cursor;
     388     1900851 :     if (l != NULL) {
     389     1579710 :         *cursor = l->next;
     390     1579710 :         return krb5_copy_creds_contents (context,
     391     1579710 :                                          &l->cred,
     392             :                                          creds);
     393             :     } else
     394      314932 :         return KRB5_CC_END;
     395             : }
     396             : 
     397             : static krb5_error_code KRB5_CALLCONV
     398      710512 : mcc_end_get (krb5_context context,
     399             :              krb5_ccache id,
     400             :              krb5_cc_cursor *cursor)
     401             : {
     402      710512 :     return 0;
     403             : }
     404             : 
     405             : static krb5_error_code KRB5_CALLCONV
     406       85817 : mcc_remove_cred(krb5_context context,
     407             :                  krb5_ccache id,
     408             :                  krb5_flags which,
     409             :                  krb5_creds *mcreds)
     410             : {
     411       85817 :     krb5_mcache *m = MCACHE(id);
     412        1466 :     struct link **q, *p;
     413             : 
     414        1466 :     HEIMDAL_MUTEX_lock(&(m->mutex));
     415             : 
     416      171634 :     for(q = &m->creds, p = *q; p; p = *q) {
     417       85817 :         if(krb5_compare_creds(context, which, mcreds, &p->cred)) {
     418           0 :             *q = p->next;
     419           0 :             krb5_free_cred_contents(context, &p->cred);
     420           0 :             free(p);
     421           0 :             m->mtime = time(NULL);
     422             :         } else
     423       85817 :             q = &p->next;
     424             :     }
     425        1466 :     HEIMDAL_MUTEX_unlock(&(m->mutex));
     426       85817 :     return 0;
     427             : }
     428             : 
     429             : static krb5_error_code KRB5_CALLCONV
     430           0 : mcc_set_flags(krb5_context context,
     431             :               krb5_ccache id,
     432             :               krb5_flags flags)
     433             : {
     434           0 :     return 0; /* XXX */
     435             : }
     436             : 
     437             : struct mcache_iter {
     438             :     krb5_mcache *cache;
     439             : };
     440             : 
     441             : static krb5_mcache *
     442          52 : mcc_get_cache_find_next_internal(krb5_mcache *next)
     443             : {
     444           0 :     HEIMDAL_MUTEX_lock(&mcc_mutex);
     445          52 :     for (; next != NULL && next->anonymous; next = next->next) {
     446             :         /* noop: iterate over all anonymous entries */
     447           0 :     }
     448          52 :     if (next != NULL) {
     449           0 :         HEIMDAL_MUTEX_lock(&(next->mutex));
     450           0 :         next->refcnt++;
     451           0 :         HEIMDAL_MUTEX_unlock(&(next->mutex));
     452           0 :         next = next->next;
     453             :     }
     454           0 :     HEIMDAL_MUTEX_unlock(&mcc_mutex);
     455             : 
     456          52 :     return next;
     457             : }
     458             : 
     459             : static krb5_error_code KRB5_CALLCONV
     460          52 : mcc_get_cache_first(krb5_context context, krb5_cc_cursor *cursor)
     461             : {
     462           0 :     struct mcache_iter *iter;
     463             : 
     464          52 :     iter = calloc(1, sizeof(*iter));
     465          52 :     if (iter == NULL)
     466           0 :         return krb5_enomem(context);
     467             : 
     468          52 :     iter->cache = mcc_get_cache_find_next_internal(mcc_head);
     469             : 
     470          52 :     *cursor = iter;
     471          52 :     return 0;
     472             : }
     473             : 
     474             : static krb5_error_code KRB5_CALLCONV
     475          52 : mcc_get_cache_next(krb5_context context, krb5_cc_cursor cursor, krb5_ccache *id)
     476             : {
     477          52 :     struct mcache_iter *iter = cursor;
     478           0 :     krb5_error_code ret;
     479           0 :     krb5_mcache *m;
     480             : 
     481          52 :     if (iter->cache == NULL)
     482          52 :         return KRB5_CC_END;
     483             : 
     484           0 :     m = iter->cache;
     485           0 :     iter->cache = mcc_get_cache_find_next_internal(m);
     486             : 
     487           0 :     ret = _krb5_cc_allocate(context, &krb5_mcc_ops, id);
     488           0 :     if (ret)
     489           0 :         return ret;
     490             : 
     491           0 :     (*id)->data.data = m;
     492           0 :     (*id)->data.length = sizeof(*m);
     493             : 
     494           0 :     return 0;
     495             : }
     496             : 
     497             : static krb5_error_code KRB5_CALLCONV
     498          52 : mcc_end_cache_get(krb5_context context, krb5_cc_cursor cursor)
     499             : {
     500          52 :     struct mcache_iter *iter = cursor;
     501             : 
     502          52 :     if (iter->cache)
     503           0 :         mcc_close_internal(iter->cache);
     504          52 :     iter->cache = NULL;
     505          52 :     free(iter);
     506          52 :     return 0;
     507             : }
     508             : 
     509             : static krb5_error_code KRB5_CALLCONV
     510           0 : mcc_move(krb5_context context, krb5_ccache from, krb5_ccache to)
     511             : {
     512           0 :     krb5_mcache *mfrom = MCACHE(from), *mto = MCACHE(to);
     513           0 :     struct link *creds;
     514           0 :     krb5_principal principal;
     515           0 :     krb5_mcache **n;
     516             : 
     517           0 :     HEIMDAL_MUTEX_lock(&mcc_mutex);
     518             : 
     519             :     /* drop the from cache from the linked list to avoid lookups */
     520           0 :     for(n = &mcc_head; n && *n; n = &(*n)->next) {
     521           0 :         if(mfrom == *n) {
     522           0 :             *n = mfrom->next;
     523           0 :             break;
     524             :         }
     525             :     }
     526             : 
     527           0 :     HEIMDAL_MUTEX_lock(&(mfrom->mutex));
     528           0 :     HEIMDAL_MUTEX_lock(&(mto->mutex));
     529             :     /* swap creds */
     530           0 :     creds = mto->creds;
     531           0 :     mto->creds = mfrom->creds;
     532           0 :     mfrom->creds = creds;
     533             :     /* swap principal */
     534           0 :     principal = mto->primary_principal;
     535           0 :     mto->primary_principal = mfrom->primary_principal;
     536           0 :     mfrom->primary_principal = principal;
     537             : 
     538           0 :     mto->mtime = mfrom->mtime = time(NULL);
     539             : 
     540           0 :     HEIMDAL_MUTEX_unlock(&(mfrom->mutex));
     541           0 :     HEIMDAL_MUTEX_unlock(&(mto->mutex));
     542           0 :     HEIMDAL_MUTEX_unlock(&mcc_mutex);
     543             : 
     544           0 :     krb5_cc_destroy(context, from);
     545           0 :     return 0;
     546             : }
     547             : 
     548             : static krb5_error_code KRB5_CALLCONV
     549           0 : mcc_default_name(krb5_context context, char **str)
     550             : {
     551           0 :     *str = strdup("MEMORY:");
     552           0 :     if (*str == NULL)
     553           0 :         return krb5_enomem(context);
     554           0 :     return 0;
     555             : }
     556             : 
     557             : static krb5_error_code KRB5_CALLCONV
     558           0 : mcc_lastchange(krb5_context context, krb5_ccache id, krb5_timestamp *mtime)
     559             : {
     560           0 :     krb5_mcache *m = MCACHE(id);
     561           0 :     HEIMDAL_MUTEX_lock(&(m->mutex));
     562           0 :     *mtime = m->mtime;
     563           0 :     HEIMDAL_MUTEX_unlock(&(m->mutex));
     564           0 :     return 0;
     565             : }
     566             : 
     567             : static krb5_error_code KRB5_CALLCONV
     568           0 : mcc_set_kdc_offset(krb5_context context, krb5_ccache id, krb5_deltat kdc_offset)
     569             : {
     570           0 :     krb5_mcache *m = MCACHE(id);
     571           0 :     HEIMDAL_MUTEX_lock(&(m->mutex));
     572           0 :     m->kdc_offset = kdc_offset;
     573           0 :     HEIMDAL_MUTEX_unlock(&(m->mutex));
     574           0 :     return 0;
     575             : }
     576             : 
     577             : static krb5_error_code KRB5_CALLCONV
     578       21592 : mcc_get_kdc_offset(krb5_context context, krb5_ccache id, krb5_deltat *kdc_offset)
     579             : {
     580       21592 :     krb5_mcache *m = MCACHE(id);
     581         623 :     HEIMDAL_MUTEX_lock(&(m->mutex));
     582       21592 :     *kdc_offset = m->kdc_offset;
     583         623 :     HEIMDAL_MUTEX_unlock(&(m->mutex));
     584       21592 :     return 0;
     585             : }
     586             : 
     587             : 
     588             : /**
     589             :  * Variable containing the MEMORY based credential cache implemention.
     590             :  *
     591             :  * @ingroup krb5_ccache
     592             :  */
     593             : 
     594             : KRB5_LIB_VARIABLE const krb5_cc_ops krb5_mcc_ops = {
     595             :     KRB5_CC_OPS_VERSION_5,
     596             :     "MEMORY",
     597             :     NULL,
     598             :     NULL,
     599             :     mcc_gen_new,
     600             :     mcc_initialize,
     601             :     mcc_destroy,
     602             :     mcc_close,
     603             :     mcc_store_cred,
     604             :     NULL, /* mcc_retrieve */
     605             :     mcc_get_principal,
     606             :     mcc_get_first,
     607             :     mcc_get_next,
     608             :     mcc_end_get,
     609             :     mcc_remove_cred,
     610             :     mcc_set_flags,
     611             :     NULL,
     612             :     mcc_get_cache_first,
     613             :     mcc_get_cache_next,
     614             :     mcc_end_cache_get,
     615             :     mcc_move,
     616             :     mcc_default_name,
     617             :     NULL,
     618             :     mcc_lastchange,
     619             :     mcc_set_kdc_offset,
     620             :     mcc_get_kdc_offset,
     621             :     mcc_get_name_2,
     622             :     mcc_resolve_2
     623             : };

Generated by: LCOV version 1.14