-: 0:Source:g_acquire_cred.c -: 0:Graph:/var/tsitkova/Sources/v10/trunk/src/lib/gssapi/mechglue/g_acquire_cred.so.gcno -: 0:Data:/var/tsitkova/Sources/v10/trunk/src/lib/gssapi/mechglue/g_acquire_cred.so.gcda -: 0:Runs:1069 -: 0:Programs:1 -: 1:/* #pragma ident "@(#)g_acquire_cred.c 1.22 04/02/23 SMI" */ -: 2: -: 3:/* -: 4: * Copyright 1996 by Sun Microsystems, Inc. -: 5: * -: 6: * Permission to use, copy, modify, distribute, and sell this software -: 7: * and its documentation for any purpose is hereby granted without fee, -: 8: * provided that the above copyright notice appears in all copies and -: 9: * that both that copyright notice and this permission notice appear in -: 10: * supporting documentation, and that the name of Sun Microsystems not be used -: 11: * in advertising or publicity pertaining to distribution of the software -: 12: * without specific, written prior permission. Sun Microsystems makes no -: 13: * representations about the suitability of this software for any -: 14: * purpose. It is provided "as is" without express or implied warranty. -: 15: * -: 16: * SUN MICROSYSTEMS DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, -: 17: * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO -: 18: * EVENT SHALL SUN MICROSYSTEMS BE LIABLE FOR ANY SPECIAL, INDIRECT OR -: 19: * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF -: 20: * USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR -: 21: * OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR -: 22: * PERFORMANCE OF THIS SOFTWARE. -: 23: */ -: 24: -: 25:/* -: 26: * glue routine for gss_acquire_cred -: 27: */ -: 28: -: 29:#include "mglueP.h" -: 30:#include -: 31:#ifdef HAVE_STDLIB_H -: 32:#include -: 33:#endif -: 34:#include -: 35:#include -: 36:#include -: 37: -: 38:static OM_uint32 290: 39:val_acq_cred_args( -: 40: OM_uint32 *minor_status, -: 41: gss_name_t desired_name, -: 42: OM_uint32 time_req, -: 43: gss_OID_set desired_mechs, -: 44: int cred_usage, -: 45: gss_cred_id_t *output_cred_handle, -: 46: gss_OID_set *actual_mechs, -: 47: OM_uint32 *time_rec) -: 48:{ -: 49: -: 50: /* Initialize outputs. */ -: 51: 290: 52: if (minor_status != NULL) 290: 53: *minor_status = 0; -: 54: 290: 55: if (output_cred_handle != NULL) 290: 56: *output_cred_handle = GSS_C_NO_CREDENTIAL; -: 57: 290: 58: if (actual_mechs != NULL) 157: 59: *actual_mechs = GSS_C_NULL_OID_SET; -: 60: 290: 61: if (time_rec != NULL) #####: 62: *time_rec = 0; -: 63: -: 64: /* Validate arguments. */ -: 65: 290: 66: if (minor_status == NULL) #####: 67: return (GSS_S_CALL_INACCESSIBLE_WRITE); -: 68: 290: 69: if (output_cred_handle == NULL) #####: 70: return (GSS_S_CALL_INACCESSIBLE_WRITE); -: 71: 290: 72: if (cred_usage != GSS_C_ACCEPT -: 73: && cred_usage != GSS_C_INITIATE -: 74: && cred_usage != GSS_C_BOTH) { #####: 75: if (minor_status) { #####: 76: *minor_status = EINVAL; #####: 77: map_errcode(minor_status); -: 78: } #####: 79: return GSS_S_FAILURE; -: 80: } -: 81: 290: 82: return (GSS_S_COMPLETE); -: 83:} -: 84: -: 85: -: 86:OM_uint32 KRB5_CALLCONV 290: 87:gss_acquire_cred(minor_status, -: 88: desired_name, -: 89: time_req, -: 90: desired_mechs, -: 91: cred_usage, -: 92: output_cred_handle, -: 93: actual_mechs, -: 94: time_rec) -: 95: -: 96:OM_uint32 * minor_status; -: 97:gss_name_t desired_name; -: 98:OM_uint32 time_req; -: 99:gss_OID_set desired_mechs; -: 100:int cred_usage; -: 101:gss_cred_id_t * output_cred_handle; -: 102:gss_OID_set * actual_mechs; -: 103:OM_uint32 * time_rec; -: 104: -: 105:{ 290: 106: OM_uint32 major = GSS_S_FAILURE, tmpMinor; 290: 107: OM_uint32 initTimeOut, acceptTimeOut, outTime = GSS_C_INDEFINITE; 290: 108: gss_OID_set mechs = GSS_C_NO_OID_SET; -: 109: unsigned int i; 290: 110: gss_union_cred_t creds = NULL; -: 111: 290: 112: major = val_acq_cred_args(minor_status, -: 113: desired_name, -: 114: time_req, -: 115: desired_mechs, -: 116: cred_usage, -: 117: output_cred_handle, -: 118: actual_mechs, -: 119: time_rec); 290: 120: if (major != GSS_S_COMPLETE) #####: 121: goto cleanup; -: 122: -: 123: /* -: 124: * if desired_mechs equals GSS_C_NULL_OID_SET, then try to -: 125: * acquire credentials for all mechanisms. -: 126: */ 290: 127: if (desired_mechs == GSS_C_NULL_OID_SET) { 133: 128: major = gss_indicate_mechs(minor_status, &mechs); 133: 129: if (major != GSS_S_COMPLETE) #####: 130: goto cleanup; -: 131: } else 157: 132: mechs = desired_mechs; -: 133: 290: 134: if (mechs->count == 0) { #####: 135: major = GSS_S_BAD_MECH; #####: 136: goto cleanup; -: 137: } -: 138: -: 139: /* allocate the output credential structure */ 290: 140: creds = (gss_union_cred_t)calloc(1, sizeof (gss_union_cred_desc)); 290: 141: if (creds == NULL) { #####: 142: major = GSS_S_FAILURE; #####: 143: *minor_status = ENOMEM; #####: 144: goto cleanup; -: 145: } -: 146: 290: 147: creds->count = 0; 290: 148: creds->loopback = creds; -: 149: -: 150: /* for each requested mech attempt to obtain a credential */ 1565: 151: for (i = 0, major = GSS_S_UNAVAILABLE; i < mechs->count; i++) { 2550: 152: major = gss_add_cred(minor_status, (gss_cred_id_t)creds, -: 153: desired_name, 2550: 154: &mechs->elements[i], -: 155: cred_usage, time_req, time_req, NULL, -: 156: NULL, &initTimeOut, &acceptTimeOut); 1275: 157: if (major == GSS_S_COMPLETE) { -: 158: /* update the credential's time */ 1275: 159: if (cred_usage == GSS_C_ACCEPT) { 1137: 160: if (outTime > acceptTimeOut) 129: 161: outTime = acceptTimeOut; 138: 162: } else if (cred_usage == GSS_C_INITIATE) { 138: 163: if (outTime > initTimeOut) 40: 164: outTime = initTimeOut; -: 165: } else { -: 166: /* -: 167: * time_rec is the lesser of the -: 168: * init/accept times -: 169: */ #####: 170: if (initTimeOut > acceptTimeOut) #####: 171: outTime = (outTime > acceptTimeOut) ? -: 172: acceptTimeOut : outTime; -: 173: else #####: 174: outTime = (outTime > initTimeOut) ? -: 175: initTimeOut : outTime; -: 176: } -: 177: } -: 178: } /* for */ -: 179: -: 180: /* ensure that we have at least one credential element */ 290: 181: if (creds->count < 1) #####: 182: goto cleanup; 290: 183: major = GSS_S_COMPLETE; -: 184: -: 185: /* -: 186: * fill in output parameters -: 187: * setup the actual mechs output parameter -: 188: */ 290: 189: if (actual_mechs != NULL) { -: 190: gss_OID_set_desc oids; -: 191: 157: 192: oids.count = creds->count; 157: 193: oids.elements = creds->mechs_array; -: 194: 157: 195: major = generic_gss_copy_oid_set(minor_status, &oids, actual_mechs); 157: 196: if (GSS_ERROR(major)) #####: 197: goto cleanup; -: 198: } -: 199: 290: 200: if (time_rec) #####: 201: *time_rec = outTime; -: 202: 290: 203: *output_cred_handle = (gss_cred_id_t)creds; -: 204: -: 205:cleanup: 290: 206: if (GSS_ERROR(major)) #####: 207: gss_release_cred(&tmpMinor, (gss_cred_id_t *)&creds); 290: 208: if (desired_mechs == GSS_C_NO_OID_SET) 133: 209: generic_gss_release_oid_set(&tmpMinor, &mechs); -: 210: 290: 211: return (major); -: 212:} -: 213: -: 214:static OM_uint32 1275: 215:val_add_cred_args( -: 216: OM_uint32 *minor_status, -: 217: gss_cred_id_t input_cred_handle, -: 218: gss_name_t desired_name, -: 219: gss_OID desired_mech, -: 220: gss_cred_usage_t cred_usage, -: 221: OM_uint32 initiator_time_req, -: 222: OM_uint32 acceptor_time_req, -: 223: gss_cred_id_t *output_cred_handle, -: 224: gss_OID_set *actual_mechs, -: 225: OM_uint32 *initiator_time_rec, -: 226: OM_uint32 *acceptor_time_rec) -: 227:{ -: 228: -: 229: /* Initialize outputs. */ -: 230: 1275: 231: if (minor_status != NULL) 1275: 232: *minor_status = 0; -: 233: 1275: 234: if (output_cred_handle != NULL) #####: 235: *output_cred_handle = GSS_C_NO_CREDENTIAL; -: 236: 1275: 237: if (actual_mechs != NULL) #####: 238: *actual_mechs = GSS_C_NO_OID_SET; -: 239: 1275: 240: if (acceptor_time_rec != NULL) 1275: 241: *acceptor_time_rec = 0; -: 242: 1275: 243: if (initiator_time_rec != NULL) 1275: 244: *initiator_time_rec = 0; -: 245: -: 246: /* Validate arguments. */ -: 247: 1275: 248: if (minor_status == NULL) #####: 249: return (GSS_S_CALL_INACCESSIBLE_WRITE); -: 250: 1275: 251: if (input_cred_handle == GSS_C_NO_CREDENTIAL && -: 252: output_cred_handle == NULL) #####: 253: return (GSS_S_CALL_INACCESSIBLE_WRITE | GSS_S_NO_CRED); -: 254: 1275: 255: if (cred_usage != GSS_C_ACCEPT -: 256: && cred_usage != GSS_C_INITIATE -: 257: && cred_usage != GSS_C_BOTH) { #####: 258: if (minor_status) { #####: 259: *minor_status = EINVAL; #####: 260: map_errcode(minor_status); -: 261: } #####: 262: return GSS_S_FAILURE; -: 263: } -: 264: 1275: 265: return (GSS_S_COMPLETE); -: 266:} -: 267: -: 268: -: 269:/* V2 KRB5_CALLCONV */ -: 270:OM_uint32 KRB5_CALLCONV 1275: 271:gss_add_cred(minor_status, input_cred_handle, -: 272: desired_name, desired_mech, cred_usage, -: 273: initiator_time_req, acceptor_time_req, -: 274: output_cred_handle, actual_mechs, -: 275: initiator_time_rec, acceptor_time_rec) -: 276: OM_uint32 *minor_status; -: 277: gss_cred_id_t input_cred_handle; -: 278: gss_name_t desired_name; -: 279: gss_OID desired_mech; -: 280: gss_cred_usage_t cred_usage; -: 281: OM_uint32 initiator_time_req; -: 282: OM_uint32 acceptor_time_req; -: 283: gss_cred_id_t *output_cred_handle; -: 284: gss_OID_set *actual_mechs; -: 285: OM_uint32 *initiator_time_rec; -: 286: OM_uint32 *acceptor_time_rec; -: 287:{ -: 288: OM_uint32 status, temp_minor_status; -: 289: OM_uint32 time_req, time_rec; -: 290: gss_union_name_t union_name; -: 291: gss_union_cred_t new_union_cred, union_cred; 1275: 292: gss_name_t internal_name = GSS_C_NO_NAME; 1275: 293: gss_name_t allocated_name = GSS_C_NO_NAME; -: 294: gss_mechanism mech; 1275: 295: gss_cred_id_t cred = NULL; 1275: 296: gss_OID new_mechs_array = NULL; 1275: 297: gss_cred_id_t * new_cred_array = NULL; -: 298: 1275: 299: status = val_add_cred_args(minor_status, -: 300: input_cred_handle, -: 301: desired_name, -: 302: desired_mech, -: 303: cred_usage, -: 304: initiator_time_req, -: 305: acceptor_time_req, -: 306: output_cred_handle, -: 307: actual_mechs, -: 308: initiator_time_rec, -: 309: acceptor_time_rec); 1275: 310: if (status != GSS_S_COMPLETE) #####: 311: return (status); -: 312: 1275: 313: mech = gssint_get_mechanism(desired_mech); 1275: 314: if (!mech) #####: 315: return GSS_S_BAD_MECH; 1275: 316: else if (!mech->gss_acquire_cred) #####: 317: return (GSS_S_UNAVAILABLE); -: 318: 1275: 319: if (input_cred_handle == GSS_C_NO_CREDENTIAL) { #####: 320: union_cred = malloc(sizeof (gss_union_cred_desc)); #####: 321: if (union_cred == NULL) #####: 322: return (GSS_S_FAILURE); -: 323: #####: 324: (void) memset(union_cred, 0, sizeof (gss_union_cred_desc)); -: 325: -: 326: /* for default credentials we will use GSS_C_NO_NAME */ #####: 327: internal_name = GSS_C_NO_NAME; -: 328: } else { 1275: 329: union_cred = (gss_union_cred_t)input_cred_handle; 1275: 330: if (gssint_get_mechanism_cred(union_cred, desired_mech) != -: 331: GSS_C_NO_CREDENTIAL) #####: 332: return (GSS_S_DUPLICATE_ELEMENT); -: 333: -: 334: /* may need to create a mechanism specific name */ 1275: 335: if (desired_name) { 1089: 336: union_name = (gss_union_name_t)desired_name; 1089: 337: if (union_name->mech_type && #####: 338: g_OID_equal(union_name->mech_type, -: 339: &mech->mech_type)) #####: 340: internal_name = union_name->mech_name; -: 341: else { 1089: 342: if (gssint_import_internal_name(minor_status, 1089: 343: &mech->mech_type, union_name, -: 344: &allocated_name) != GSS_S_COMPLETE) #####: 345: return (GSS_S_BAD_NAME); 1089: 346: internal_name = allocated_name; -: 347: } -: 348: } -: 349: } -: 350: -: 351: 1275: 352: if (cred_usage == GSS_C_ACCEPT) 1137: 353: time_req = acceptor_time_req; 138: 354: else if (cred_usage == GSS_C_INITIATE) 138: 355: time_req = initiator_time_req; #####: 356: else if (cred_usage == GSS_C_BOTH) #####: 357: time_req = (acceptor_time_req > initiator_time_req) ? -: 358: acceptor_time_req : initiator_time_req; -: 359: else #####: 360: time_req = 0; -: 361: 1275: 362: status = mech->gss_acquire_cred(minor_status, -: 363: internal_name, time_req, -: 364: GSS_C_NULL_OID_SET, cred_usage, -: 365: &cred, NULL, &time_rec); -: 366: 1275: 367: if (status != GSS_S_COMPLETE) { #####: 368: map_error(minor_status, mech); #####: 369: goto errout; -: 370: } -: 371: -: 372: /* now add the new credential elements */ 1275: 373: new_mechs_array = (gss_OID) -: 374: malloc(sizeof (gss_OID_desc) * (union_cred->count+1)); -: 375: 1275: 376: new_cred_array = (gss_cred_id_t *) -: 377: malloc(sizeof (gss_cred_id_t) * (union_cred->count+1)); -: 378: 1275: 379: if (!new_mechs_array || !new_cred_array) { #####: 380: status = GSS_S_FAILURE; #####: 381: goto errout; -: 382: } -: 383: 1275: 384: if (acceptor_time_rec) 1275: 385: if (cred_usage == GSS_C_ACCEPT || cred_usage == GSS_C_BOTH) 1137: 386: *acceptor_time_rec = time_rec; 1275: 387: if (initiator_time_rec) 1275: 388: if (cred_usage == GSS_C_INITIATE || cred_usage == GSS_C_BOTH) 138: 389: *initiator_time_rec = time_rec; -: 390: -: 391: /* -: 392: * OK, expand the mechanism array and the credential array -: 393: */ 1275: 394: (void) memcpy(new_mechs_array, union_cred->mechs_array, -: 395: sizeof (gss_OID_desc) * union_cred->count); 1275: 396: (void) memcpy(new_cred_array, union_cred->cred_array, -: 397: sizeof (gss_cred_id_t) * union_cred->count); -: 398: 1275: 399: new_cred_array[union_cred->count] = cred; 2550: 400: if ((new_mechs_array[union_cred->count].elements = 1275: 401: malloc(mech->mech_type.length)) == NULL) #####: 402: goto errout; -: 403: 1275: 404: g_OID_copy(&new_mechs_array[union_cred->count], -: 405: &mech->mech_type); -: 406: 1275: 407: if (actual_mechs != NULL) { -: 408: gss_OID_set_desc oids; -: 409: #####: 410: oids.count = union_cred->count + 1; #####: 411: oids.elements = new_mechs_array; -: 412: #####: 413: status = generic_gss_copy_oid_set(minor_status, &oids, actual_mechs); #####: 414: if (GSS_ERROR(status)) { #####: 415: free(new_mechs_array[union_cred->count].elements); #####: 416: goto errout; -: 417: } -: 418: } -: 419: 1275: 420: if (output_cred_handle == NULL) { 1275: 421: free(union_cred->mechs_array); 1275: 422: free(union_cred->cred_array); 1275: 423: new_union_cred = union_cred; -: 424: } else { #####: 425: new_union_cred = malloc(sizeof (gss_union_cred_desc)); #####: 426: if (new_union_cred == NULL) { #####: 427: free(new_mechs_array[union_cred->count].elements); #####: 428: goto errout; -: 429: } #####: 430: *new_union_cred = *union_cred; #####: 431: *output_cred_handle = (gss_cred_id_t)new_union_cred; -: 432: } -: 433: 1275: 434: new_union_cred->mechs_array = new_mechs_array; 1275: 435: new_union_cred->cred_array = new_cred_array; 1275: 436: new_union_cred->count++; 1275: 437: new_union_cred->loopback = new_union_cred; -: 438: -: 439: /* We're done with the internal name. Free it if we allocated it. */ -: 440: 1275: 441: if (allocated_name) 1089: 442: (void) gssint_release_internal_name(&temp_minor_status, 1089: 443: &mech->mech_type, -: 444: &allocated_name); -: 445: 1275: 446: return (GSS_S_COMPLETE); -: 447: -: 448:errout: #####: 449: if (new_mechs_array) #####: 450: free(new_mechs_array); #####: 451: if (new_cred_array) #####: 452: free(new_cred_array); -: 453: #####: 454: if (cred != NULL && mech->gss_release_cred) #####: 455: mech->gss_release_cred(&temp_minor_status, &cred); -: 456: #####: 457: if (allocated_name) #####: 458: (void) gssint_release_internal_name(&temp_minor_status, #####: 459: &mech->mech_type, -: 460: &allocated_name); -: 461: #####: 462: if (input_cred_handle == GSS_C_NO_CREDENTIAL && union_cred) #####: 463: free(union_cred); -: 464: #####: 465: return (status); -: 466:}