1 /* $NetBSD: glue.c,v 1.3 2018/04/06 19:57:03 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.3 2018/04/06 19:57:03 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