g_acquire_cred.c revision 3dba6097f91d71408b4a7c824521f8f0687ab6ff
fa9e4066f08beec538e775443c5be79dd423fcabahrens/*
fa9e4066f08beec538e775443c5be79dd423fcabahrens * CDDL HEADER START
fa9e4066f08beec538e775443c5be79dd423fcabahrens *
fa9e4066f08beec538e775443c5be79dd423fcabahrens * The contents of this file are subject to the terms of the
441d80aa4f613b6298fc8bd3151f4be02dbf84fclling * Common Development and Distribution License (the "License").
441d80aa4f613b6298fc8bd3151f4be02dbf84fclling * You may not use this file except in compliance with the License.
fa9e4066f08beec538e775443c5be79dd423fcabahrens *
fa9e4066f08beec538e775443c5be79dd423fcabahrens * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
fa9e4066f08beec538e775443c5be79dd423fcabahrens * or http://www.opensolaris.org/os/licensing.
fa9e4066f08beec538e775443c5be79dd423fcabahrens * See the License for the specific language governing permissions
fa9e4066f08beec538e775443c5be79dd423fcabahrens * and limitations under the License.
fa9e4066f08beec538e775443c5be79dd423fcabahrens *
fa9e4066f08beec538e775443c5be79dd423fcabahrens * When distributing Covered Code, include this CDDL HEADER in each
fa9e4066f08beec538e775443c5be79dd423fcabahrens * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
fa9e4066f08beec538e775443c5be79dd423fcabahrens * If applicable, add the following below this CDDL HEADER, with the
fa9e4066f08beec538e775443c5be79dd423fcabahrens * fields enclosed by brackets "[]" replaced with your own identifying
fa9e4066f08beec538e775443c5be79dd423fcabahrens * information: Portions Copyright [yyyy] [name of copyright owner]
fa9e4066f08beec538e775443c5be79dd423fcabahrens *
fa9e4066f08beec538e775443c5be79dd423fcabahrens * CDDL HEADER END
fa9e4066f08beec538e775443c5be79dd423fcabahrens */
99653d4ee642c6528e88224f12409a5f23060994eschrock/*
fa9e4066f08beec538e775443c5be79dd423fcabahrens * Copyright 2007 Sun Microsystems, Inc. All rights reserved.
39c23413b8df94a95f67b34cfd4a4dfc3fd0b48deschrock * Use is subject to license terms.
fa9e4066f08beec538e775443c5be79dd423fcabahrens */
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens#pragma ident "%Z%%M% %I% %E% SMI"
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens/*
fa9e4066f08beec538e775443c5be79dd423fcabahrens * glue routine for gss_acquire_cred
fa9e4066f08beec538e775443c5be79dd423fcabahrens */
fa9e4066f08beec538e775443c5be79dd423fcabahrens#include <mechglueP.h>
fa9e4066f08beec538e775443c5be79dd423fcabahrens#include <stdio.h>
fa9e4066f08beec538e775443c5be79dd423fcabahrens#ifdef HAVE_STDLIB_H
fa9e4066f08beec538e775443c5be79dd423fcabahrens#include <stdlib.h>
fa9e4066f08beec538e775443c5be79dd423fcabahrens#endif
fa9e4066f08beec538e775443c5be79dd423fcabahrens#include <string.h>
fa9e4066f08beec538e775443c5be79dd423fcabahrens#include <errno.h>
fa9e4066f08beec538e775443c5be79dd423fcabahrens#include <time.h>
fa9e4066f08beec538e775443c5be79dd423fcabahrens/* local functions */
fa9e4066f08beec538e775443c5be79dd423fcabahrensstatic gss_OID_set create_actual_mechs(const gss_OID, int);
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrensstatic gss_OID_set
fa9e4066f08beec538e775443c5be79dd423fcabahrenscreate_actual_mechs(mechs_array, count)
ecd6cf800b63704be73fb264c3f5b6e0dafc068dmarks const gss_OID mechs_array;
ecd6cf800b63704be73fb264c3f5b6e0dafc068dmarks int count;
b1b8ab34de515a5e83206da22c3d7e563241b021lling{
fa9e4066f08beec538e775443c5be79dd423fcabahrens gss_OID_set actual_mechs;
fa9e4066f08beec538e775443c5be79dd423fcabahrens int i;
fa9e4066f08beec538e775443c5be79dd423fcabahrens OM_uint32 minor;
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens actual_mechs = (gss_OID_set) malloc(sizeof (gss_OID_set_desc));
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (!actual_mechs)
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (NULL);
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens actual_mechs->elements = (gss_OID)
fa9e4066f08beec538e775443c5be79dd423fcabahrens malloc(sizeof (gss_OID_desc) * count);
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (!actual_mechs->elements) {
99653d4ee642c6528e88224f12409a5f23060994eschrock free(actual_mechs);
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (NULL);
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens actual_mechs->count = 0;
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens for (i = 0; i < count; i++) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens actual_mechs->elements[i].elements = (void *)
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock malloc(mechs_array[i].length);
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (actual_mechs->elements[i].elements == NULL) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens (void) gss_release_oid_set(&minor, &actual_mechs);
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (NULL);
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
fa9e4066f08beec538e775443c5be79dd423fcabahrens g_OID_copy(&actual_mechs->elements[i], &mechs_array[i]);
fa9e4066f08beec538e775443c5be79dd423fcabahrens actual_mechs->count++;
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (actual_mechs);
fa9e4066f08beec538e775443c5be79dd423fcabahrens}
eaca9bbd5f5d1e4e554da4c7108e8a03c8c33481eschrock
eaca9bbd5f5d1e4e554da4c7108e8a03c8c33481eschrock
06eeb2ad640ce72d394ac521094bed7681044408ekOM_uint32
06eeb2ad640ce72d394ac521094bed7681044408ekgss_acquire_cred(minor_status,
b1b8ab34de515a5e83206da22c3d7e563241b021lling desired_name,
b1b8ab34de515a5e83206da22c3d7e563241b021lling time_req,
b1b8ab34de515a5e83206da22c3d7e563241b021lling desired_mechs,
fa9e4066f08beec538e775443c5be79dd423fcabahrens cred_usage,
fa9e4066f08beec538e775443c5be79dd423fcabahrens output_cred_handle,
fa9e4066f08beec538e775443c5be79dd423fcabahrens actual_mechs,
fa9e4066f08beec538e775443c5be79dd423fcabahrens time_rec)
fa9e4066f08beec538e775443c5be79dd423fcabahrens
99653d4ee642c6528e88224f12409a5f23060994eschrockOM_uint32 * minor_status;
fa9e4066f08beec538e775443c5be79dd423fcabahrensconst gss_name_t desired_name;
fa9e4066f08beec538e775443c5be79dd423fcabahrensOM_uint32 time_req;
fa9e4066f08beec538e775443c5be79dd423fcabahrensconst gss_OID_set desired_mechs;
fa9e4066f08beec538e775443c5be79dd423fcabahrensint cred_usage;
fa9e4066f08beec538e775443c5be79dd423fcabahrensgss_cred_id_t *output_cred_handle;
fa9e4066f08beec538e775443c5be79dd423fcabahrensgss_OID_set * actual_mechs;
fa9e4066f08beec538e775443c5be79dd423fcabahrensOM_uint32 * time_rec;
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens{
fa9e4066f08beec538e775443c5be79dd423fcabahrens OM_uint32 major = GSS_S_FAILURE;
65cd9f2809a015b46790a9c5c2ef992d56177624eschrock OM_uint32 initTimeOut, acceptTimeOut, outTime = GSS_C_INDEFINITE;
65cd9f2809a015b46790a9c5c2ef992d56177624eschrock gss_OID_set_desc default_OID_set;
65cd9f2809a015b46790a9c5c2ef992d56177624eschrock gss_OID_set mechs;
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock gss_OID_desc default_OID;
65cd9f2809a015b46790a9c5c2ef992d56177624eschrock gss_mechanism mech;
65cd9f2809a015b46790a9c5c2ef992d56177624eschrock int i;
65cd9f2809a015b46790a9c5c2ef992d56177624eschrock gss_union_cred_t creds;
65cd9f2809a015b46790a9c5c2ef992d56177624eschrock
06eeb2ad640ce72d394ac521094bed7681044408ek /* start by checking parameters */
65cd9f2809a015b46790a9c5c2ef992d56177624eschrock if (!minor_status)
65cd9f2809a015b46790a9c5c2ef992d56177624eschrock return (GSS_S_CALL_INACCESSIBLE_WRITE);
65cd9f2809a015b46790a9c5c2ef992d56177624eschrock *minor_status = 0;
65cd9f2809a015b46790a9c5c2ef992d56177624eschrock
65cd9f2809a015b46790a9c5c2ef992d56177624eschrock if (!output_cred_handle)
65cd9f2809a015b46790a9c5c2ef992d56177624eschrock return (GSS_S_CALL_INACCESSIBLE_WRITE | GSS_S_NO_CRED);
99653d4ee642c6528e88224f12409a5f23060994eschrock
65cd9f2809a015b46790a9c5c2ef992d56177624eschrock *output_cred_handle = GSS_C_NO_CREDENTIAL;
eaca9bbd5f5d1e4e554da4c7108e8a03c8c33481eschrock
b1b8ab34de515a5e83206da22c3d7e563241b021lling /* Set output parameters to NULL for now */
b1b8ab34de515a5e83206da22c3d7e563241b021lling if (actual_mechs)
b1b8ab34de515a5e83206da22c3d7e563241b021lling *actual_mechs = GSS_C_NULL_OID_SET;
65cd9f2809a015b46790a9c5c2ef992d56177624eschrock
65cd9f2809a015b46790a9c5c2ef992d56177624eschrock if (time_rec)
65cd9f2809a015b46790a9c5c2ef992d56177624eschrock *time_rec = 0;
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens /*
fa9e4066f08beec538e775443c5be79dd423fcabahrens * if desired_mechs equals GSS_C_NULL_OID_SET, then pick an
65cd9f2809a015b46790a9c5c2ef992d56177624eschrock * appropriate default. We use the first mechanism in the
fa9e4066f08beec538e775443c5be79dd423fcabahrens * mechansim list as the default. This set is created with
fa9e4066f08beec538e775443c5be79dd423fcabahrens * statics thus needs not be freed
fa9e4066f08beec538e775443c5be79dd423fcabahrens */
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (desired_mechs == GSS_C_NULL_OID_SET) {
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock mech = __gss_get_mechanism(NULL);
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock if (mech == NULL)
65cd9f2809a015b46790a9c5c2ef992d56177624eschrock return (GSS_S_BAD_MECH);
65cd9f2809a015b46790a9c5c2ef992d56177624eschrock
65cd9f2809a015b46790a9c5c2ef992d56177624eschrock mechs = &default_OID_set;
65cd9f2809a015b46790a9c5c2ef992d56177624eschrock default_OID_set.count = 1;
fa9e4066f08beec538e775443c5be79dd423fcabahrens default_OID_set.elements = &default_OID;
fa9e4066f08beec538e775443c5be79dd423fcabahrens default_OID.length = mech->mech_type.length;
65cd9f2809a015b46790a9c5c2ef992d56177624eschrock default_OID.elements = mech->mech_type.elements;
65cd9f2809a015b46790a9c5c2ef992d56177624eschrock } else
fa9e4066f08beec538e775443c5be79dd423fcabahrens mechs = desired_mechs;
65cd9f2809a015b46790a9c5c2ef992d56177624eschrock
99653d4ee642c6528e88224f12409a5f23060994eschrock if (mechs->count == NULL)
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (GSS_S_BAD_MECH);
65cd9f2809a015b46790a9c5c2ef992d56177624eschrock
65cd9f2809a015b46790a9c5c2ef992d56177624eschrock /* allocate the output credential structure */
65cd9f2809a015b46790a9c5c2ef992d56177624eschrock creds = (gss_union_cred_t)malloc(sizeof (gss_union_cred_desc));
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (creds == NULL)
65cd9f2809a015b46790a9c5c2ef992d56177624eschrock return (GSS_S_FAILURE);
65cd9f2809a015b46790a9c5c2ef992d56177624eschrock
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock /* initialize to 0s */
fa9e4066f08beec538e775443c5be79dd423fcabahrens (void) memset(creds, 0, sizeof (gss_union_cred_desc));
65cd9f2809a015b46790a9c5c2ef992d56177624eschrock
65cd9f2809a015b46790a9c5c2ef992d56177624eschrock /* for each requested mech attempt to obtain a credential */
65cd9f2809a015b46790a9c5c2ef992d56177624eschrock for (i = 0; i < mechs->count; i++) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens major = gss_add_cred(minor_status, (gss_cred_id_t)creds,
65cd9f2809a015b46790a9c5c2ef992d56177624eschrock desired_name,
fa9e4066f08beec538e775443c5be79dd423fcabahrens &mechs->elements[i],
65cd9f2809a015b46790a9c5c2ef992d56177624eschrock cred_usage, time_req, time_req, NULL,
65cd9f2809a015b46790a9c5c2ef992d56177624eschrock NULL, &initTimeOut, &acceptTimeOut);
06eeb2ad640ce72d394ac521094bed7681044408ek if (major == GSS_S_COMPLETE) {
06eeb2ad640ce72d394ac521094bed7681044408ek /* update the credential's time */
b1b8ab34de515a5e83206da22c3d7e563241b021lling if (cred_usage == GSS_C_ACCEPT) {
b1b8ab34de515a5e83206da22c3d7e563241b021lling if (outTime > acceptTimeOut)
b1b8ab34de515a5e83206da22c3d7e563241b021lling outTime = acceptTimeOut;
fa9e4066f08beec538e775443c5be79dd423fcabahrens } else if (cred_usage == GSS_C_INITIATE) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (outTime > initTimeOut)
fa9e4066f08beec538e775443c5be79dd423fcabahrens outTime = initTimeOut;
fa9e4066f08beec538e775443c5be79dd423fcabahrens } else {
fa9e4066f08beec538e775443c5be79dd423fcabahrens /*
2a6b87f07ac0c0b819179c84afe5a60afa04cfa5ek * time_rec is the lesser of the
fa9e4066f08beec538e775443c5be79dd423fcabahrens * init/accept times
65cd9f2809a015b46790a9c5c2ef992d56177624eschrock */
65cd9f2809a015b46790a9c5c2ef992d56177624eschrock if (initTimeOut > acceptTimeOut)
65cd9f2809a015b46790a9c5c2ef992d56177624eschrock outTime = (outTime > acceptTimeOut) ?
65cd9f2809a015b46790a9c5c2ef992d56177624eschrock acceptTimeOut : outTime;
65cd9f2809a015b46790a9c5c2ef992d56177624eschrock else
65cd9f2809a015b46790a9c5c2ef992d56177624eschrock outTime = (outTime > initTimeOut) ?
65cd9f2809a015b46790a9c5c2ef992d56177624eschrock initTimeOut : outTime;
e45ce728996d8e573eecb27f555fb86aaff0cafdahrens }
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock }
ea8dc4b6d2251b437950c0056bc626b311c73c27eschrock } /* for */
65cd9f2809a015b46790a9c5c2ef992d56177624eschrock
990b4856d0eaada6f8140335733a1b1771ed2746lling /* ensure that we have at least one credential element */
990b4856d0eaada6f8140335733a1b1771ed2746lling if (creds->count < 1) {
65cd9f2809a015b46790a9c5c2ef992d56177624eschrock free(creds);
65cd9f2809a015b46790a9c5c2ef992d56177624eschrock return (major);
65cd9f2809a015b46790a9c5c2ef992d56177624eschrock }
65cd9f2809a015b46790a9c5c2ef992d56177624eschrock
65cd9f2809a015b46790a9c5c2ef992d56177624eschrock /*
65cd9f2809a015b46790a9c5c2ef992d56177624eschrock * fill in output parameters
06eeb2ad640ce72d394ac521094bed7681044408ek * setup the actual mechs output parameter
ecd6cf800b63704be73fb264c3f5b6e0dafc068dmarks */
65cd9f2809a015b46790a9c5c2ef992d56177624eschrock if (actual_mechs != NULL) {
4c58d71403cebfaa40a572ff12b17668ebd56987darrenm if ((*actual_mechs = create_actual_mechs(creds->mechs_array,
2f8aaab38e6371ad39ed90a1211ba8921acbb4d5eschrock creds->count)) == NULL) {
2f8aaab38e6371ad39ed90a1211ba8921acbb4d5eschrock (void) gss_release_cred(minor_status,
2f8aaab38e6371ad39ed90a1211ba8921acbb4d5eschrock (gss_cred_id_t *)&creds);
2f8aaab38e6371ad39ed90a1211ba8921acbb4d5eschrock *minor_status = 0;
2f8aaab38e6371ad39ed90a1211ba8921acbb4d5eschrock return (GSS_S_FAILURE);
65cd9f2809a015b46790a9c5c2ef992d56177624eschrock }
65cd9f2809a015b46790a9c5c2ef992d56177624eschrock }
65cd9f2809a015b46790a9c5c2ef992d56177624eschrock
65cd9f2809a015b46790a9c5c2ef992d56177624eschrock if (time_rec)
990b4856d0eaada6f8140335733a1b1771ed2746lling *time_rec = outTime;
990b4856d0eaada6f8140335733a1b1771ed2746lling
65cd9f2809a015b46790a9c5c2ef992d56177624eschrock
441d80aa4f613b6298fc8bd3151f4be02dbf84fclling *output_cred_handle = (gss_cred_id_t)creds;
65cd9f2809a015b46790a9c5c2ef992d56177624eschrock return (GSS_S_COMPLETE);
441d80aa4f613b6298fc8bd3151f4be02dbf84fclling}
65cd9f2809a015b46790a9c5c2ef992d56177624eschrock
65cd9f2809a015b46790a9c5c2ef992d56177624eschrock/* V2 INTERFACE */
e45ce728996d8e573eecb27f555fb86aaff0cafdahrensOM_uint32
99653d4ee642c6528e88224f12409a5f23060994eschrockgss_add_cred(minor_status, input_cred_handle,
fa94a07fd0519b8abfd871ad8fe60e6bebe1e2bbbrendan desired_name, desired_mech, cred_usage,
65cd9f2809a015b46790a9c5c2ef992d56177624eschrock initiator_time_req, acceptor_time_req,
65cd9f2809a015b46790a9c5c2ef992d56177624eschrock output_cred_handle, actual_mechs,
65cd9f2809a015b46790a9c5c2ef992d56177624eschrock initiator_time_rec, acceptor_time_rec)
65cd9f2809a015b46790a9c5c2ef992d56177624eschrock OM_uint32 *minor_status;
eaca9bbd5f5d1e4e554da4c7108e8a03c8c33481eschrock const gss_cred_id_t input_cred_handle;
eaca9bbd5f5d1e4e554da4c7108e8a03c8c33481eschrock const gss_name_t desired_name;
eaca9bbd5f5d1e4e554da4c7108e8a03c8c33481eschrock const gss_OID desired_mech;
990b4856d0eaada6f8140335733a1b1771ed2746lling gss_cred_usage_t cred_usage;
b1b8ab34de515a5e83206da22c3d7e563241b021lling OM_uint32 initiator_time_req;
e45ce728996d8e573eecb27f555fb86aaff0cafdahrens OM_uint32 acceptor_time_req;
b1b8ab34de515a5e83206da22c3d7e563241b021lling gss_cred_id_t *output_cred_handle;
b1b8ab34de515a5e83206da22c3d7e563241b021lling gss_OID_set *actual_mechs;
b1b8ab34de515a5e83206da22c3d7e563241b021lling OM_uint32 *initiator_time_rec;
65cd9f2809a015b46790a9c5c2ef992d56177624eschrock OM_uint32 *acceptor_time_rec;
65cd9f2809a015b46790a9c5c2ef992d56177624eschrock{
65cd9f2809a015b46790a9c5c2ef992d56177624eschrock OM_uint32 status, time_req, time_rec, temp_minor_status;
65cd9f2809a015b46790a9c5c2ef992d56177624eschrock gss_mechanism mech;
65cd9f2809a015b46790a9c5c2ef992d56177624eschrock gss_union_name_t union_name = NULL;
65cd9f2809a015b46790a9c5c2ef992d56177624eschrock gss_union_cred_t union_cred, new_union_cred;
fa9e4066f08beec538e775443c5be79dd423fcabahrens gss_name_t internal_name = GSS_C_NO_NAME;
b1b8ab34de515a5e83206da22c3d7e563241b021lling gss_name_t allocated_name = GSS_C_NO_NAME;
b1b8ab34de515a5e83206da22c3d7e563241b021lling gss_cred_id_t cred = NULL;
b1b8ab34de515a5e83206da22c3d7e563241b021lling gss_OID new_mechs_array = NULL;
990b4856d0eaada6f8140335733a1b1771ed2746lling gss_cred_id_t *new_cred_array = NULL;
990b4856d0eaada6f8140335733a1b1771ed2746lling
b1b8ab34de515a5e83206da22c3d7e563241b021lling /* check input parameters */
b1b8ab34de515a5e83206da22c3d7e563241b021lling if (minor_status == NULL)
b1b8ab34de515a5e83206da22c3d7e563241b021lling return (GSS_S_CALL_INACCESSIBLE_WRITE);
b1b8ab34de515a5e83206da22c3d7e563241b021lling *minor_status = 0;
b1b8ab34de515a5e83206da22c3d7e563241b021lling
990b4856d0eaada6f8140335733a1b1771ed2746lling if (input_cred_handle == GSS_C_NO_CREDENTIAL &&
990b4856d0eaada6f8140335733a1b1771ed2746lling output_cred_handle == NULL)
990b4856d0eaada6f8140335733a1b1771ed2746lling return (GSS_S_CALL_INACCESSIBLE_WRITE | GSS_S_NO_CRED);
990b4856d0eaada6f8140335733a1b1771ed2746lling
990b4856d0eaada6f8140335733a1b1771ed2746lling if (output_cred_handle)
b1b8ab34de515a5e83206da22c3d7e563241b021lling *output_cred_handle = GSS_C_NO_CREDENTIAL;
b1b8ab34de515a5e83206da22c3d7e563241b021lling
b1b8ab34de515a5e83206da22c3d7e563241b021lling if (actual_mechs)
b1b8ab34de515a5e83206da22c3d7e563241b021lling *actual_mechs = NULL;
b1b8ab34de515a5e83206da22c3d7e563241b021lling
990b4856d0eaada6f8140335733a1b1771ed2746lling if (acceptor_time_rec)
b1b8ab34de515a5e83206da22c3d7e563241b021lling *acceptor_time_rec = 0;
b1b8ab34de515a5e83206da22c3d7e563241b021lling
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (initiator_time_rec)
fa9e4066f08beec538e775443c5be79dd423fcabahrens *initiator_time_rec = 0;
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens mech = __gss_get_mechanism(desired_mech);
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (!mech)
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (GSS_S_BAD_MECH);
99653d4ee642c6528e88224f12409a5f23060994eschrock else if (!mech->gss_acquire_cred)
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (GSS_S_UNAVAILABLE);
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (input_cred_handle == GSS_C_NO_CREDENTIAL) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens union_cred = malloc(sizeof (gss_union_cred_desc));
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (union_cred == NULL)
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (GSS_S_FAILURE);
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens (void) memset(union_cred, 0, sizeof (gss_union_cred_desc));
fa9e4066f08beec538e775443c5be79dd423fcabahrens } else {
fa9e4066f08beec538e775443c5be79dd423fcabahrens /* Input Cred is non-NULL */
fa9e4066f08beec538e775443c5be79dd423fcabahrens union_cred = (gss_union_cred_t)input_cred_handle;
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (__gss_get_mechanism_cred(union_cred, desired_mech) !=
fa9e4066f08beec538e775443c5be79dd423fcabahrens GSS_C_NO_CREDENTIAL) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens status = GSS_S_DUPLICATE_ELEMENT;
65cd9f2809a015b46790a9c5c2ef992d56177624eschrock goto errout;
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens /*
65cd9f2809a015b46790a9c5c2ef992d56177624eschrock * If no name was given, determine the name from the
fa9e4066f08beec538e775443c5be79dd423fcabahrens * existing credential.
fa9e4066f08beec538e775443c5be79dd423fcabahrens */
b1b8ab34de515a5e83206da22c3d7e563241b021lling if (desired_name == GSS_C_NO_NAME) {
b1b8ab34de515a5e83206da22c3d7e563241b021lling if (gss_import_name(minor_status,
990b4856d0eaada6f8140335733a1b1771ed2746lling &union_cred->auxinfo.name,
990b4856d0eaada6f8140335733a1b1771ed2746lling union_cred->auxinfo.name_type,
b1b8ab34de515a5e83206da22c3d7e563241b021lling &allocated_name) == GSS_S_COMPLETE &&
b1b8ab34de515a5e83206da22c3d7e563241b021lling (gss_canonicalize_name(minor_status,
b1b8ab34de515a5e83206da22c3d7e563241b021lling allocated_name,
b1b8ab34de515a5e83206da22c3d7e563241b021lling &mech->mech_type,
990b4856d0eaada6f8140335733a1b1771ed2746lling NULL) == GSS_S_COMPLETE)) {
990b4856d0eaada6f8140335733a1b1771ed2746lling internal_name = allocated_name;
b1b8ab34de515a5e83206da22c3d7e563241b021lling }
b1b8ab34de515a5e83206da22c3d7e563241b021lling } /* else, get the name from the desired_name below */
990b4856d0eaada6f8140335733a1b1771ed2746lling }
990b4856d0eaada6f8140335733a1b1771ed2746lling if (desired_name != GSS_C_NO_NAME) {
b1b8ab34de515a5e83206da22c3d7e563241b021lling /* may need to create a mechanism specific name */
b1b8ab34de515a5e83206da22c3d7e563241b021lling union_name = (gss_union_name_t)desired_name;
e9dbad6f263d5570ed7ff5443ec5b958af8c24d7eschrock
e9dbad6f263d5570ed7ff5443ec5b958af8c24d7eschrock if (union_name->mech_type &&
e9dbad6f263d5570ed7ff5443ec5b958af8c24d7eschrock g_OID_equal(union_name->mech_type,
e9dbad6f263d5570ed7ff5443ec5b958af8c24d7eschrock &mech->mech_type))
e9dbad6f263d5570ed7ff5443ec5b958af8c24d7eschrock internal_name = union_name->mech_name;
e9dbad6f263d5570ed7ff5443ec5b958af8c24d7eschrock else {
e9dbad6f263d5570ed7ff5443ec5b958af8c24d7eschrock if (__gss_import_internal_name(minor_status,
e9dbad6f263d5570ed7ff5443ec5b958af8c24d7eschrock &mech->mech_type, union_name,
fa9e4066f08beec538e775443c5be79dd423fcabahrens &allocated_name) != GSS_S_COMPLETE) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens status = GSS_S_BAD_NAME;
fa9e4066f08beec538e775443c5be79dd423fcabahrens goto errout;
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
8654d0253136055bd4cc2423d87378e8a37f2eb5perrin internal_name = allocated_name;
8654d0253136055bd4cc2423d87378e8a37f2eb5perrin }
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (cred_usage == GSS_C_ACCEPT)
afefbcddfd8caf5f3b2da510d9439471ab225040eschrock time_req = acceptor_time_req;
fa9e4066f08beec538e775443c5be79dd423fcabahrens else if (cred_usage == GSS_C_INITIATE)
fa9e4066f08beec538e775443c5be79dd423fcabahrens time_req = initiator_time_req;
fa9e4066f08beec538e775443c5be79dd423fcabahrens else if (cred_usage == GSS_C_BOTH)
fa9e4066f08beec538e775443c5be79dd423fcabahrens time_req = (acceptor_time_req > initiator_time_req) ?
fa9e4066f08beec538e775443c5be79dd423fcabahrens acceptor_time_req : initiator_time_req;
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens status = mech->gss_acquire_cred(mech->context, minor_status,
fa9e4066f08beec538e775443c5be79dd423fcabahrens internal_name, time_req,
afefbcddfd8caf5f3b2da510d9439471ab225040eschrock GSS_C_NULL_OID_SET, cred_usage,
8654d0253136055bd4cc2423d87378e8a37f2eb5perrin &cred, NULL, &time_rec);
8654d0253136055bd4cc2423d87378e8a37f2eb5perrin
8654d0253136055bd4cc2423d87378e8a37f2eb5perrin if (status != GSS_S_COMPLETE)
8654d0253136055bd4cc2423d87378e8a37f2eb5perrin goto errout;
8654d0253136055bd4cc2423d87378e8a37f2eb5perrin
8654d0253136055bd4cc2423d87378e8a37f2eb5perrin /* may need to set credential auxinfo structure */
8654d0253136055bd4cc2423d87378e8a37f2eb5perrin if (union_cred->auxinfo.creation_time == 0) {
99653d4ee642c6528e88224f12409a5f23060994eschrock union_cred->auxinfo.creation_time = time(NULL);
8654d0253136055bd4cc2423d87378e8a37f2eb5perrin union_cred->auxinfo.time_rec = time_rec;
8654d0253136055bd4cc2423d87378e8a37f2eb5perrin union_cred->auxinfo.cred_usage = cred_usage;
afefbcddfd8caf5f3b2da510d9439471ab225040eschrock
afefbcddfd8caf5f3b2da510d9439471ab225040eschrock /*
fa9e4066f08beec538e775443c5be79dd423fcabahrens * If internal_name is GSS_C_NO_NAME a cred with no associated
fa9e4066f08beec538e775443c5be79dd423fcabahrens * name was requested: don't set auxinfo.name or auxinfo.name_type.
990b4856d0eaada6f8140335733a1b1771ed2746lling */
990b4856d0eaada6f8140335733a1b1771ed2746lling if (internal_name != GSS_C_NO_NAME) {
990b4856d0eaada6f8140335733a1b1771ed2746lling if ((status = mech->gss_display_name(mech->context,
990b4856d0eaada6f8140335733a1b1771ed2746lling &temp_minor_status, internal_name,
990b4856d0eaada6f8140335733a1b1771ed2746lling &union_cred->auxinfo.name,
990b4856d0eaada6f8140335733a1b1771ed2746lling &union_cred->auxinfo.name_type)) !=
990b4856d0eaada6f8140335733a1b1771ed2746lling GSS_S_COMPLETE)
990b4856d0eaada6f8140335733a1b1771ed2746lling goto errout;
990b4856d0eaada6f8140335733a1b1771ed2746lling }
990b4856d0eaada6f8140335733a1b1771ed2746lling }
990b4856d0eaada6f8140335733a1b1771ed2746lling
990b4856d0eaada6f8140335733a1b1771ed2746lling /* now add the new credential elements */
990b4856d0eaada6f8140335733a1b1771ed2746lling new_mechs_array = (gss_OID)
990b4856d0eaada6f8140335733a1b1771ed2746lling malloc(sizeof (gss_OID_desc) * (union_cred->count+1));
990b4856d0eaada6f8140335733a1b1771ed2746lling
990b4856d0eaada6f8140335733a1b1771ed2746lling new_cred_array = (gss_cred_id_t *)
990b4856d0eaada6f8140335733a1b1771ed2746lling malloc(sizeof (gss_cred_id_t) * (union_cred->count+1));
990b4856d0eaada6f8140335733a1b1771ed2746lling
990b4856d0eaada6f8140335733a1b1771ed2746lling if (!new_mechs_array || !new_cred_array) {
990b4856d0eaada6f8140335733a1b1771ed2746lling status = GSS_S_FAILURE;
990b4856d0eaada6f8140335733a1b1771ed2746lling goto errout;
990b4856d0eaada6f8140335733a1b1771ed2746lling }
990b4856d0eaada6f8140335733a1b1771ed2746lling
990b4856d0eaada6f8140335733a1b1771ed2746lling if (acceptor_time_rec)
990b4856d0eaada6f8140335733a1b1771ed2746lling if (cred_usage == GSS_C_ACCEPT || cred_usage == GSS_C_BOTH)
990b4856d0eaada6f8140335733a1b1771ed2746lling *acceptor_time_rec = time_rec;
990b4856d0eaada6f8140335733a1b1771ed2746lling if (initiator_time_rec)
2f8aaab38e6371ad39ed90a1211ba8921acbb4d5eschrock if (cred_usage == GSS_C_INITIATE || cred_usage == GSS_C_BOTH)
990b4856d0eaada6f8140335733a1b1771ed2746lling *initiator_time_rec = time_rec;
990b4856d0eaada6f8140335733a1b1771ed2746lling
990b4856d0eaada6f8140335733a1b1771ed2746lling /*
990b4856d0eaada6f8140335733a1b1771ed2746lling * OK, expand the mechanism array and the credential array
990b4856d0eaada6f8140335733a1b1771ed2746lling */
990b4856d0eaada6f8140335733a1b1771ed2746lling (void) memcpy(new_mechs_array, union_cred->mechs_array,
990b4856d0eaada6f8140335733a1b1771ed2746lling sizeof (gss_OID_desc) * union_cred->count);
990b4856d0eaada6f8140335733a1b1771ed2746lling (void) memcpy(new_cred_array, union_cred->cred_array,
990b4856d0eaada6f8140335733a1b1771ed2746lling sizeof (gss_cred_id_t) * union_cred->count);
990b4856d0eaada6f8140335733a1b1771ed2746lling
990b4856d0eaada6f8140335733a1b1771ed2746lling new_cred_array[union_cred->count] = cred;
990b4856d0eaada6f8140335733a1b1771ed2746lling if ((new_mechs_array[union_cred->count].elements =
990b4856d0eaada6f8140335733a1b1771ed2746lling malloc(mech->mech_type.length)) == NULL)
990b4856d0eaada6f8140335733a1b1771ed2746lling goto errout;
990b4856d0eaada6f8140335733a1b1771ed2746lling
fa9e4066f08beec538e775443c5be79dd423fcabahrens g_OID_copy(&new_mechs_array[union_cred->count],
fa9e4066f08beec538e775443c5be79dd423fcabahrens &mech->mech_type);
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (actual_mechs) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens *actual_mechs = create_actual_mechs(new_mechs_array,
fa9e4066f08beec538e775443c5be79dd423fcabahrens union_cred->count + 1);
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (*actual_mechs == NULL) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens free(new_mechs_array[union_cred->count].elements);
fa9e4066f08beec538e775443c5be79dd423fcabahrens goto errout;
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (output_cred_handle == NULL) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens free(union_cred->mechs_array);
99653d4ee642c6528e88224f12409a5f23060994eschrock free(union_cred->cred_array);
99653d4ee642c6528e88224f12409a5f23060994eschrock new_union_cred = union_cred;
fa9e4066f08beec538e775443c5be79dd423fcabahrens } else {
fa9e4066f08beec538e775443c5be79dd423fcabahrens new_union_cred = malloc(sizeof (gss_union_cred_desc));
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (new_union_cred == NULL) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens free(new_mechs_array[union_cred->count].elements);
fa9e4066f08beec538e775443c5be79dd423fcabahrens goto errout;
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
fa9e4066f08beec538e775443c5be79dd423fcabahrens *new_union_cred = *union_cred;
fa9e4066f08beec538e775443c5be79dd423fcabahrens *output_cred_handle = (gss_cred_id_t)new_union_cred;
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens new_union_cred->mechs_array = new_mechs_array;
99653d4ee642c6528e88224f12409a5f23060994eschrock new_union_cred->cred_array = new_cred_array;
fa9e4066f08beec538e775443c5be79dd423fcabahrens new_union_cred->count++;
fa9e4066f08beec538e775443c5be79dd423fcabahrens
99653d4ee642c6528e88224f12409a5f23060994eschrock /* We're done with the internal name. Free it if we allocated it. */
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (allocated_name)
fa9e4066f08beec538e775443c5be79dd423fcabahrens (void) __gss_release_internal_name(&temp_minor_status,
fa9e4066f08beec538e775443c5be79dd423fcabahrens &mech->mech_type,
99653d4ee642c6528e88224f12409a5f23060994eschrock &allocated_name);
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens return (GSS_S_COMPLETE);
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrenserrout:
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (new_mechs_array)
fa9e4066f08beec538e775443c5be79dd423fcabahrens free(new_mechs_array);
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (new_cred_array)
fa9e4066f08beec538e775443c5be79dd423fcabahrens free(new_cred_array);
fa9e4066f08beec538e775443c5be79dd423fcabahrens
99653d4ee642c6528e88224f12409a5f23060994eschrock if (cred != NULL && mech->gss_release_cred)
fa9e4066f08beec538e775443c5be79dd423fcabahrens mech->gss_release_cred(mech->context,
fa9e4066f08beec538e775443c5be79dd423fcabahrens &temp_minor_status, &cred);
fa9e4066f08beec538e775443c5be79dd423fcabahrens
99653d4ee642c6528e88224f12409a5f23060994eschrock if (allocated_name)
fa9e4066f08beec538e775443c5be79dd423fcabahrens (void) __gss_release_internal_name(&temp_minor_status,
fa9e4066f08beec538e775443c5be79dd423fcabahrens &mech->mech_type,
fa9e4066f08beec538e775443c5be79dd423fcabahrens &allocated_name);
fa9e4066f08beec538e775443c5be79dd423fcabahrens
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (input_cred_handle == GSS_C_NO_CREDENTIAL && union_cred) {
fa9e4066f08beec538e775443c5be79dd423fcabahrens if (union_cred->auxinfo.name.value)
fa9e4066f08beec538e775443c5be79dd423fcabahrens free(union_cred->auxinfo.name.value);
99653d4ee642c6528e88224f12409a5f23060994eschrock free(union_cred);
fa9e4066f08beec538e775443c5be79dd423fcabahrens }
fa9e4066f08beec538e775443c5be79dd423fcabahrens
088e9d477eee66081e407fbc5a33c4da25f66f6aeschrock return (status);
fa9e4066f08beec538e775443c5be79dd423fcabahrens}
fa9e4066f08beec538e775443c5be79dd423fcabahrens