Home | History | Annotate | Line # | Download | only in kcm
      1 /*	$NetBSD: glue.c,v 1.4 2023/06/19 21:41:41 christos Exp $	*/
      2 
      3 /*
      4  * Copyright (c) 2005, PADL Software Pty Ltd.
      5  * All rights reserved.
      6  *
      7  * Redistribution and use in source and binary forms, with or without
      8  * modification, are permitted provided that the following conditions
      9  * are met:
     10  *
     11  * 1. Redistributions of source code must retain the above copyright
     12  *    notice, this list of conditions and the following disclaimer.
     13  *
     14  * 2. Redistributions in binary form must reproduce the above copyright
     15  *    notice, this list of conditions and the following disclaimer in the
     16  *    documentation and/or other materials provided with the distribution.
     17  *
     18  * 3. Neither the name of PADL Software nor the names of its contributors
     19  *    may be used to endorse or promote products derived from this software
     20  *    without specific prior written permission.
     21  *
     22  * THIS SOFTWARE IS PROVIDED BY PADL SOFTWARE AND CONTRIBUTORS ``AS IS'' AND
     23  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
     24  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
     25  * ARE DISCLAIMED.  IN NO EVENT SHALL PADL SOFTWARE OR CONTRIBUTORS BE LIABLE
     26  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
     27  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
     28  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
     29  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
     30  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
     31  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
     32  * SUCH DAMAGE.
     33  */
     34 
     35 #include "kcm_locl.h"
     36 
     37 __RCSID("$NetBSD: glue.c,v 1.4 2023/06/19 21:41:41 christos Exp $");
     38 
     39 /*
     40  * Server-side loopback glue for credentials cache operations; this
     41  * must be initialized with kcm_internal_ccache(), it is not for real
     42  * use. This entire file assumes the cache is locked, it does not do
     43  * any concurrency checking for multithread applications.
     44  */
     45 
     46 #define KCMCACHE(X)	((kcm_ccache)(X)->data.data)
     47 #define CACHENAME(X)	(KCMCACHE(X)->name)
     48 
     49 static const char *
     50 kcmss_get_name(krb5_context context,
     51 	       krb5_ccache id)
     52 {
     53     return CACHENAME(id);
     54 }
     55 
     56 static krb5_error_code
     57 kcmss_resolve(krb5_context context, krb5_ccache *id, const char *res)
     58 {
     59     return KRB5_FCC_INTERNAL;
     60 }
     61 
     62 static krb5_error_code
     63 kcmss_gen_new(krb5_context context, krb5_ccache *id)
     64 {
     65     return KRB5_FCC_INTERNAL;
     66 }
     67 
     68 static krb5_error_code
     69 kcmss_initialize(krb5_context context,
     70 		 krb5_ccache id,
     71 		 krb5_principal primary_principal)
     72 {
     73     krb5_error_code ret;
     74     kcm_ccache c = KCMCACHE(id);
     75 
     76     KCM_ASSERT_VALID(c);
     77 
     78     ret = kcm_zero_ccache_data_internal(context, c);
     79     if (ret)
     80 	return ret;
     81 
     82     ret = krb5_copy_principal(context, primary_principal,
     83 			      &c->client);
     84 
     85     return ret;
     86 }
     87 
     88 static krb5_error_code
     89 kcmss_close(krb5_context context,
     90 	    krb5_ccache id)
     91 {
     92     kcm_ccache c = KCMCACHE(id);
     93 
     94     KCM_ASSERT_VALID(c);
     95 
     96     id->data.data = NULL;
     97     id->data.length = 0;
     98 
     99     return 0;
    100 }
    101 
    102 static krb5_error_code
    103 kcmss_destroy(krb5_context context,
    104 	      krb5_ccache id)
    105 {
    106     krb5_error_code ret;
    107     kcm_ccache c = KCMCACHE(id);
    108 
    109     KCM_ASSERT_VALID(c);
    110 
    111     ret = kcm_ccache_destroy(context, CACHENAME(id));
    112 
    113     return ret;
    114 }
    115 
    116 static krb5_error_code
    117 kcmss_store_cred(krb5_context context,
    118 		 krb5_ccache id,
    119 		 krb5_creds *creds)
    120 {
    121     krb5_error_code ret;
    122     kcm_ccache c = KCMCACHE(id);
    123     krb5_creds *tmp;
    124 
    125     KCM_ASSERT_VALID(c);
    126 
    127     ret = kcm_ccache_store_cred_internal(context, c, creds, 1, &tmp);
    128 
    129     return ret;
    130 }
    131 
    132 static krb5_error_code
    133 kcmss_retrieve(krb5_context context,
    134 	       krb5_ccache id,
    135 	       krb5_flags which,
    136 	       const krb5_creds *mcred,
    137 	       krb5_creds *creds)
    138 {
    139     krb5_error_code ret;
    140     kcm_ccache c = KCMCACHE(id);
    141     krb5_creds *credp;
    142 
    143     KCM_ASSERT_VALID(c);
    144 
    145     ret = kcm_ccache_retrieve_cred_internal(context, c, which,
    146 					    mcred, &credp);
    147     if (ret)
    148 	return ret;
    149 
    150     ret = krb5_copy_creds_contents(context, credp, creds);
    151     if (ret)
    152 	return ret;
    153 
    154     return 0;
    155 }
    156 
    157 static krb5_error_code
    158 kcmss_get_principal(krb5_context context,
    159 		    krb5_ccache id,
    160 		    krb5_principal *principal)
    161 {
    162     krb5_error_code ret;
    163     kcm_ccache c = KCMCACHE(id);
    164 
    165     KCM_ASSERT_VALID(c);
    166 
    167     ret = krb5_copy_principal(context, c->client,
    168 			      principal);
    169 
    170     return ret;
    171 }
    172 
    173 static krb5_error_code
    174 kcmss_get_first (krb5_context context,
    175 		 krb5_ccache id,
    176 		 krb5_cc_cursor *cursor)
    177 {
    178     kcm_ccache c = KCMCACHE(id);
    179 
    180     KCM_ASSERT_VALID(c);
    181 
    182     *cursor = c->creds;
    183 
    184     return (*cursor == NULL) ? KRB5_CC_END : 0;
    185 }
    186 
    187 static krb5_error_code
    188 kcmss_get_next (krb5_context context,
    189 		krb5_ccache id,
    190 		krb5_cc_cursor *cursor,
    191 		krb5_creds *creds)
    192 {
    193     krb5_error_code ret;
    194     kcm_ccache c = KCMCACHE(id);
    195 
    196     KCM_ASSERT_VALID(c);
    197 
    198     ret = krb5_copy_creds_contents(context,
    199 				   &((struct kcm_creds *)cursor)->cred,
    200 				   creds);
    201     if (ret)
    202 	return ret;
    203 
    204     *cursor = ((struct kcm_creds *)cursor)->next;
    205     if (*cursor == 0)
    206 	ret = KRB5_CC_END;
    207 
    208     return ret;
    209 }
    210 
    211 static krb5_error_code
    212 kcmss_end_get (krb5_context context,
    213 	       krb5_ccache id,
    214 	       krb5_cc_cursor *cursor)
    215 {
    216     *cursor = NULL;
    217     return 0;
    218 }
    219 
    220 static krb5_error_code
    221 kcmss_remove_cred(krb5_context context,
    222 		  krb5_ccache id,
    223 		  krb5_flags which,
    224 		  krb5_creds *cred)
    225 {
    226     krb5_error_code ret;
    227     kcm_ccache c = KCMCACHE(id);
    228 
    229     KCM_ASSERT_VALID(c);
    230 
    231     ret = kcm_ccache_remove_cred_internal(context, c, which, cred);
    232 
    233     return ret;
    234 }
    235 
    236 static krb5_error_code
    237 kcmss_set_flags(krb5_context context,
    238 		krb5_ccache id,
    239 		krb5_flags flags)
    240 {
    241     return 0;
    242 }
    243 
    244 static krb5_error_code
    245 kcmss_get_version(krb5_context context,
    246 		  krb5_ccache id)
    247 {
    248     return 0;
    249 }
    250 
    251 static krb5_error_code
    252 kcmss_get_kdc_sec_offset(krb5_context context,
    253 			 krb5_ccache id,
    254 			 krb5_deltat *t)
    255 {
    256     kcm_ccache c = KCMCACHE(id);
    257 
    258     KCM_ASSERT_VALID(c);
    259 
    260     *t = c->kdc_offset;
    261 
    262     return 0;
    263 }
    264 
    265 static krb5_error_code
    266 kcmss_set_kdc_sec_offset(krb5_context context,
    267 			 krb5_ccache id, krb5_deltat t)
    268 {
    269     kcm_ccache c = KCMCACHE(id);
    270 
    271     KCM_ASSERT_VALID(c);
    272 
    273     c->kdc_offset = t;
    274 
    275     return 0;
    276 }
    277 
    278 static const krb5_cc_ops krb5_kcmss_ops = {
    279     .version =		KRB5_CC_OPS_VERSION,
    280     .prefix =		"KCM",
    281     .get_name =		kcmss_get_name,
    282     .resolve =		kcmss_resolve,
    283     .gen_new =		kcmss_gen_new,
    284     .init =		kcmss_initialize,
    285     .destroy =		kcmss_destroy,
    286     .close =		kcmss_close,
    287     .store =		kcmss_store_cred,
    288     .retrieve =		kcmss_retrieve,
    289     .get_princ =	kcmss_get_principal,
    290     .get_first =	kcmss_get_first,
    291     .get_next =		kcmss_get_next,
    292     .end_get =		kcmss_end_get,
    293     .remove_cred =	kcmss_remove_cred,
    294     .set_flags =	kcmss_set_flags,
    295     .get_version =	kcmss_get_version,
    296     .get_cache_first =	NULL,
    297     .get_cache_next =	NULL,
    298     .end_cache_get =	NULL,
    299     .move =		NULL,
    300     .get_default_name =	NULL,
    301     .set_default =	NULL,
    302     .lastchange =	NULL,
    303     .set_kdc_offset =	kcmss_set_kdc_sec_offset,
    304     .get_kdc_offset =	kcmss_get_kdc_sec_offset,
    305 };
    306 
    307 krb5_error_code
    308 kcm_internal_ccache(krb5_context context,
    309 		    kcm_ccache c,
    310 		    krb5_ccache id)
    311 {
    312     id->ops = &krb5_kcmss_ops;
    313     id->data.length = sizeof(*c);
    314     id->data.data = c;
    315 
    316     return 0;
    317 }
    318 
    319