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