1 0 stevel /* 2 0 stevel * CDDL HEADER START 3 0 stevel * 4 0 stevel * The contents of this file are subject to the terms of the 5 6855 johnlev * Common Development and Distribution License (the "License"). 6 6855 johnlev * You may not use this file except in compliance with the License. 7 0 stevel * 8 0 stevel * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 0 stevel * or http://www.opensolaris.org/os/licensing. 10 0 stevel * See the License for the specific language governing permissions 11 0 stevel * and limitations under the License. 12 0 stevel * 13 0 stevel * When distributing Covered Code, include this CDDL HEADER in each 14 0 stevel * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 0 stevel * If applicable, add the following below this CDDL HEADER, with the 16 0 stevel * fields enclosed by brackets "[]" replaced with your own identifying 17 0 stevel * information: Portions Copyright [yyyy] [name of copyright owner] 18 0 stevel * 19 0 stevel * CDDL HEADER END 20 0 stevel */ 21 0 stevel /* 22 10598 Glenn * Copyright 2009 Sun Microsystems, Inc. All rights reserved. 23 0 stevel * Use is subject to license terms. 24 0 stevel */ 25 0 stevel 26 0 stevel /* 27 0 stevel * GSSAPI library stub module for gssd. 28 0 stevel */ 29 0 stevel 30 0 stevel #include <mechglueP.h> 31 0 stevel #include "gssd_prot.h" 32 0 stevel #include <rpc/rpc.h> 33 0 stevel 34 0 stevel #include <sys/systm.h> 35 0 stevel #include <sys/types.h> 36 0 stevel #include <sys/cmn_err.h> 37 0 stevel #include <sys/kmem.h> 38 0 stevel #include <gssapi/kgssapi_defs.h> 39 0 stevel #include <sys/debug.h> 40 0 stevel 41 0 stevel #ifdef GSSDEBUG 42 0 stevel /* 43 0 stevel * Kernel kgssd module debugging aid. The global variable "gss_log" 44 0 stevel * is a bit mask which allows various types of debugging messages 45 0 stevel * to be printed out. 46 0 stevel * 47 0 stevel * gss_log & 1 will cause actual failures to be printed. 48 0 stevel * gss_log & 2 will cause informational messages to be 49 0 stevel * printed on the client side of kgssd. 50 0 stevel * gss_log & 4 will cause informational messages to be 51 0 stevel * printed on the server side of kgssd. 52 0 stevel * gss_log & 8 will cause informational messages to be 53 0 stevel * printed on both client and server side of kgssd. 54 0 stevel */ 55 0 stevel 56 0 stevel uint_t gss_log = 1; 57 0 stevel 58 0 stevel #endif /* GSSDEBUG */ 59 0 stevel 60 0 stevel #ifdef DEBUG 61 0 stevel extern void prom_printf(); 62 0 stevel #endif 63 0 stevel 64 0 stevel char *server = "localhost"; 65 0 stevel 66 0 stevel static OM_uint32 kgss_sign_wrapped(void *, OM_uint32 *, gss_ctx_id_t, int, 67 0 stevel gss_buffer_t, gss_buffer_t, OM_uint32); 68 0 stevel 69 0 stevel static OM_uint32 kgss_verify_wrapped(void *, OM_uint32 *, gss_ctx_id_t, 70 0 stevel gss_buffer_t, gss_buffer_t, int *qop_state, OM_uint32); 71 0 stevel 72 0 stevel /* EXPORT DELETE START */ 73 0 stevel static OM_uint32 kgss_seal_wrapped(void *, OM_uint32 *, gss_ctx_id_t, 74 0 stevel int, int, gss_buffer_t, int *, gss_buffer_t, OM_uint32); 75 0 stevel 76 0 stevel static OM_uint32 kgss_unseal_wrapped(void *, OM_uint32 *, gss_ctx_id_t, 77 0 stevel gss_buffer_t, gss_buffer_t, int *conf_state, int *qop_state, 78 0 stevel OM_uint32); 79 0 stevel /* EXPORT DELETE END */ 80 0 stevel 81 0 stevel static OM_uint32 kgss_delete_sec_context_wrapped(void *, OM_uint32 *, 82 0 stevel gssd_ctx_id_t *, gss_buffer_t, OM_uint32); 83 0 stevel 84 0 stevel static void __kgss_reset_mech(gss_mechanism *, gss_OID); 85 0 stevel 86 0 stevel #define DEFAULT_MINOR_STAT ((OM_uint32) ~0) 87 0 stevel 88 0 stevel OM_uint32 89 0 stevel kgss_acquire_cred_wrapped(minor_status, 90 0 stevel desired_name, 91 0 stevel time_req, 92 0 stevel desired_mechs, 93 0 stevel cred_usage, 94 0 stevel output_cred_handle, 95 0 stevel actual_mechs, 96 0 stevel time_rec, 97 0 stevel uid, 98 0 stevel gssd_cred_verifier) 99 0 stevel OM_uint32 *minor_status; 100 0 stevel const gss_name_t desired_name; 101 0 stevel OM_uint32 time_req; 102 0 stevel const gss_OID_set desired_mechs; 103 0 stevel int cred_usage; 104 0 stevel gssd_cred_id_t *output_cred_handle; 105 0 stevel gss_OID_set *actual_mechs; 106 0 stevel OM_uint32 *time_rec; 107 0 stevel uid_t uid; 108 0 stevel OM_uint32 *gssd_cred_verifier; 109 0 stevel { 110 0 stevel CLIENT *clnt; 111 0 stevel 112 0 stevel OM_uint32 minor_status_temp; 113 0 stevel gss_buffer_desc external_name; 114 0 stevel gss_OID name_type; 115 0 stevel enum clnt_stat client_stat; 116 0 stevel int i; 117 0 stevel 118 0 stevel gss_acquire_cred_arg arg; 119 0 stevel gss_acquire_cred_res res; 120 0 stevel 121 0 stevel /* get the client handle to GSSD */ 122 0 stevel 123 0 stevel if ((clnt = getgssd_handle()) == NULL) { 124 0 stevel GSSLOG(1, "kgss_acquire_cred: can't connect to server on %s\n", 125 0 stevel server); 126 0 stevel return (GSS_S_FAILURE); 127 0 stevel } 128 0 stevel 129 0 stevel /* convert the desired name from internal to external format */ 130 0 stevel 131 0 stevel if (gss_display_name(&minor_status_temp, desired_name, &external_name, 132 0 stevel &name_type) != GSS_S_COMPLETE) { 133 0 stevel 134 0 stevel *minor_status = (OM_uint32) minor_status_temp; 135 0 stevel killgssd_handle(clnt); 136 0 stevel GSSLOG0(1, "kgss_acquire_cred: display name failed\n"); 137 0 stevel return ((OM_uint32) GSS_S_FAILURE); 138 0 stevel } 139 0 stevel 140 0 stevel 141 0 stevel /* copy the procedure arguments into the rpc arg parameter */ 142 0 stevel 143 0 stevel arg.uid = (OM_uint32) uid; 144 0 stevel 145 0 stevel arg.desired_name.GSS_BUFFER_T_len = (uint_t)external_name.length; 146 0 stevel arg.desired_name.GSS_BUFFER_T_val = (char *)external_name.value; 147 0 stevel 148 0 stevel arg.name_type.GSS_OID_len = 149 0 stevel name_type == GSS_C_NULL_OID ? 150 0 stevel 0 : (uint_t)name_type->length; 151 0 stevel 152 0 stevel arg.name_type.GSS_OID_val = 153 0 stevel name_type == GSS_C_NULL_OID ? 154 0 stevel (char *)NULL : (char *)name_type->elements; 155 0 stevel 156 0 stevel arg.time_req = time_req; 157 0 stevel 158 0 stevel if (desired_mechs != GSS_C_NULL_OID_SET) { 159 0 stevel arg.desired_mechs.GSS_OID_SET_len = 160 0 stevel (uint_t)desired_mechs->count; 161 0 stevel arg.desired_mechs.GSS_OID_SET_val = (GSS_OID *) 162 0 stevel MALLOC(sizeof (GSS_OID) * desired_mechs->count); 163 0 stevel 164 0 stevel for (i = 0; i < desired_mechs->count; i++) { 165 0 stevel arg.desired_mechs.GSS_OID_SET_val[i].GSS_OID_len = 166 0 stevel (uint_t)desired_mechs->elements[i].length; 167 0 stevel arg.desired_mechs.GSS_OID_SET_val[i].GSS_OID_val = 168 0 stevel (char *)MALLOC(desired_mechs->elements[i].length); 169 0 stevel (void) memcpy( 170 0 stevel arg.desired_mechs.GSS_OID_SET_val[i].GSS_OID_val, 171 0 stevel desired_mechs->elements[i].elements, 172 0 stevel desired_mechs->elements[i].length); 173 0 stevel } 174 0 stevel } else 175 0 stevel arg.desired_mechs.GSS_OID_SET_len = 0; 176 0 stevel 177 0 stevel arg.cred_usage = cred_usage; 178 0 stevel 179 0 stevel /* call the remote procedure */ 180 0 stevel 181 0 stevel bzero((caddr_t)&res, sizeof (res)); 182 0 stevel client_stat = gss_acquire_cred_1(&arg, &res, clnt); 183 0 stevel 184 0 stevel (void) gss_release_buffer(&minor_status_temp, &external_name); 185 0 stevel if (desired_mechs != GSS_C_NULL_OID_SET) { 186 0 stevel for (i = 0; i < desired_mechs->count; i++) 187 0 stevel FREE(arg.desired_mechs.GSS_OID_SET_val[i].GSS_OID_val, 188 0 stevel arg.desired_mechs.GSS_OID_SET_val[i].GSS_OID_len); 189 0 stevel FREE(arg.desired_mechs.GSS_OID_SET_val, 190 0 stevel arg.desired_mechs.GSS_OID_SET_len * sizeof (GSS_OID)); 191 0 stevel } 192 0 stevel 193 0 stevel if (client_stat != RPC_SUCCESS) { 194 0 stevel 195 0 stevel /* 196 0 stevel * if the RPC call times out, null out all return arguments, 197 0 stevel * set minor_status to its maximum value, and return 198 0 stevel * GSS_S_FAILURE 199 0 stevel */ 200 0 stevel 201 0 stevel if (minor_status != NULL) 202 0 stevel *minor_status = DEFAULT_MINOR_STAT; 203 0 stevel if (output_cred_handle != NULL) 204 0 stevel *output_cred_handle = NULL; 205 0 stevel if (actual_mechs != NULL) 206 0 stevel *actual_mechs = NULL; 207 0 stevel if (time_rec != NULL) 208 0 stevel *time_rec = 0; 209 0 stevel 210 0 stevel killgssd_handle(clnt); 211 0 stevel GSSLOG0(1, "kgss_acquire_cred: RPC call times out\n"); 212 0 stevel return (GSS_S_FAILURE); 213 0 stevel } 214 0 stevel 215 0 stevel /* copy the rpc results into the return arguments */ 216 0 stevel 217 0 stevel if (minor_status != NULL) 218 0 stevel *minor_status = res.minor_status; 219 0 stevel 220 0 stevel if (output_cred_handle != NULL && 221 0 stevel (res.status == GSS_S_COMPLETE)) { 222 0 stevel *output_cred_handle = 223 0 stevel *((gssd_cred_id_t *)res.output_cred_handle.GSS_CRED_ID_T_val); 224 0 stevel *gssd_cred_verifier = res.gssd_cred_verifier; 225 0 stevel } 226 0 stevel 227 0 stevel if (res.status == GSS_S_COMPLETE && 228 0 stevel res.actual_mechs.GSS_OID_SET_len != 0 && 229 0 stevel actual_mechs != NULL) { 230 0 stevel *actual_mechs = (gss_OID_set) MALLOC(sizeof (gss_OID_set_desc)); 231 0 stevel (*actual_mechs)->count = 232 0 stevel (int)res.actual_mechs.GSS_OID_SET_len; 233 0 stevel (*actual_mechs)->elements = (gss_OID) 234 0 stevel MALLOC(sizeof (gss_OID_desc) * (*actual_mechs)->count); 235 0 stevel 236 0 stevel for (i = 0; i < (*actual_mechs)->count; i++) { 237 0 stevel (*actual_mechs)->elements[i].length = (OM_uint32) 238 0 stevel res.actual_mechs.GSS_OID_SET_val[i].GSS_OID_len; 239 0 stevel (*actual_mechs)->elements[i].elements = 240 0 stevel (void *) MALLOC((*actual_mechs)->elements[i].length); 241 0 stevel (void) memcpy((*actual_mechs)->elements[i].elements, 242 0 stevel res.actual_mechs.GSS_OID_SET_val[i].GSS_OID_val, 243 0 stevel (*actual_mechs)->elements[i].length); 244 0 stevel } 245 0 stevel } else { 246 0 stevel if (res.status == GSS_S_COMPLETE && 247 0 stevel actual_mechs != NULL) 248 0 stevel (*actual_mechs) = NULL; 249 0 stevel } 250 0 stevel 251 0 stevel if (time_rec != NULL) 252 0 stevel *time_rec = res.time_rec; 253 0 stevel 254 0 stevel /* 255 0 stevel * free the memory allocated for the results and return with the status 256 0 stevel * received in the rpc call 257 0 stevel */ 258 0 stevel 259 0 stevel clnt_freeres(clnt, xdr_gss_acquire_cred_res, (caddr_t)&res); 260 0 stevel killgssd_handle(clnt); 261 0 stevel return (res.status); 262 0 stevel 263 0 stevel } 264 0 stevel 265 0 stevel OM_uint32 266 0 stevel kgss_acquire_cred(minor_status, 267 0 stevel desired_name, 268 0 stevel time_req, 269 0 stevel desired_mechs, 270 0 stevel cred_usage, 271 0 stevel output_cred_handle, 272 0 stevel actual_mechs, 273 0 stevel time_rec, 274 0 stevel uid) 275 0 stevel OM_uint32 *minor_status; 276 0 stevel const gss_name_t desired_name; 277 0 stevel OM_uint32 time_req; 278 0 stevel const gss_OID_set desired_mechs; 279 0 stevel int cred_usage; 280 0 stevel gss_cred_id_t *output_cred_handle; 281 0 stevel gss_OID_set *actual_mechs; 282 0 stevel OM_uint32 *time_rec; 283 0 stevel uid_t uid; 284 0 stevel { 285 0 stevel 286 0 stevel OM_uint32 err; 287 0 stevel struct kgss_cred *kcred; 288 0 stevel 289 0 stevel kcred = KGSS_CRED_ALLOC(); 290 0 stevel *output_cred_handle = (gss_cred_id_t)kcred; 291 0 stevel err = kgss_acquire_cred_wrapped(minor_status, desired_name, time_req, 292 0 stevel desired_mechs, cred_usage, &kcred->gssd_cred, actual_mechs, 293 0 stevel time_rec, uid, &kcred->gssd_cred_verifier); 294 0 stevel if (GSS_ERROR(err)) { 295 0 stevel KGSS_CRED_FREE(kcred); 296 0 stevel *output_cred_handle = GSS_C_NO_CREDENTIAL; 297 0 stevel } 298 0 stevel return (err); 299 0 stevel } 300 0 stevel 301 0 stevel OM_uint32 302 0 stevel kgss_add_cred_wrapped(minor_status, 303 0 stevel input_cred_handle, 304 0 stevel gssd_cred_verifier, 305 0 stevel desired_name, 306 0 stevel desired_mech_type, 307 0 stevel cred_usage, 308 0 stevel initiator_time_req, 309 0 stevel acceptor_time_req, 310 0 stevel actual_mechs, 311 0 stevel initiator_time_rec, 312 0 stevel acceptor_time_rec, 313 0 stevel uid) 314 0 stevel OM_uint32 *minor_status; 315 0 stevel gssd_cred_id_t input_cred_handle; 316 0 stevel OM_uint32 gssd_cred_verifier; 317 0 stevel gss_name_t desired_name; 318 0 stevel gss_OID desired_mech_type; 319 0 stevel int cred_usage; 320 0 stevel int initiator_time_req; 321 0 stevel int acceptor_time_req; 322 0 stevel gss_OID_set *actual_mechs; 323 0 stevel OM_uint32 *initiator_time_rec; 324 0 stevel OM_uint32 *acceptor_time_rec; 325 0 stevel uid_t uid; 326 0 stevel { 327 0 stevel CLIENT *clnt; 328 0 stevel 329 0 stevel OM_uint32 minor_status_temp; 330 0 stevel gss_buffer_desc external_name; 331 0 stevel gss_OID name_type; 332 0 stevel int i; 333 0 stevel 334 0 stevel gss_add_cred_arg arg; 335 0 stevel gss_add_cred_res res; 336 0 stevel 337 0 stevel 338 0 stevel /* 339 0 stevel * NULL the params here once 340 0 stevel * If there are errors then we won't 341 0 stevel * have to do it for every error 342 0 stevel * case 343 0 stevel */ 344 0 stevel 345 0 stevel if (minor_status != NULL) 346 0 stevel *minor_status = DEFAULT_MINOR_STAT; 347 0 stevel if (actual_mechs != NULL) 348 0 stevel *actual_mechs = NULL; 349 0 stevel if (initiator_time_rec != NULL) 350 0 stevel *initiator_time_rec = 0; 351 0 stevel if (acceptor_time_rec != NULL) 352 0 stevel *acceptor_time_rec = 0; 353 0 stevel /* get the client handle to GSSD */ 354 0 stevel 355 0 stevel if ((clnt = getgssd_handle()) == NULL) { 356 0 stevel GSSLOG(1, "kgss_add_cred: can't connect to server on %s\n", 357 0 stevel server); 358 0 stevel return (GSS_S_FAILURE); 359 0 stevel } 360 0 stevel 361 0 stevel 362 0 stevel /* convert the desired name from internal to external format */ 363 0 stevel 364 0 stevel if (gss_display_name(&minor_status_temp, desired_name, &external_name, 365 0 stevel &name_type) != GSS_S_COMPLETE) { 366 0 stevel 367 0 stevel *minor_status = (OM_uint32) minor_status_temp; 368 0 stevel killgssd_handle(clnt); 369 0 stevel GSSLOG0(1, "kgss_acquire_cred: display name failed\n"); 370 0 stevel return ((OM_uint32) GSS_S_FAILURE); 371 0 stevel } 372 0 stevel 373 0 stevel 374 0 stevel /* copy the procedure arguments into the rpc arg parameter */ 375 0 stevel 376 0 stevel arg.uid = (OM_uint32)uid; 377 0 stevel arg.input_cred_handle.GSS_CRED_ID_T_len = 378 0 stevel input_cred_handle == 379 0 stevel (gssd_cred_id_t)GSS_C_NO_CREDENTIAL ? 380 0 stevel 0 : (uint_t)sizeof (gssd_cred_id_t); 381 0 stevel arg.input_cred_handle.GSS_CRED_ID_T_val = (char *)&input_cred_handle; 382 0 stevel arg.gssd_cred_verifier = gssd_cred_verifier; 383 0 stevel arg.desired_name.GSS_BUFFER_T_len = (uint_t)external_name.length; 384 0 stevel arg.desired_name.GSS_BUFFER_T_val = (char *)external_name.value; 385 0 stevel arg.name_type.GSS_OID_len = 386 0 stevel name_type == GSS_C_NULL_OID ? 387 0 stevel 0 : (uint_t)name_type->length; 388 0 stevel arg.name_type.GSS_OID_val = 389 0 stevel name_type == GSS_C_NULL_OID ? 390 0 stevel (char *)NULL : (char *)name_type->elements; 391 0 stevel 392 0 stevel arg.desired_mech_type.GSS_OID_len = 393 0 stevel (uint_t)(desired_mech_type != GSS_C_NULL_OID ? 394 0 stevel desired_mech_type->length : 0); 395 0 stevel arg.desired_mech_type.GSS_OID_val = 396 0 stevel (char *)(desired_mech_type != GSS_C_NULL_OID ? 397 0 stevel desired_mech_type->elements : 0); 398 0 stevel arg.cred_usage = cred_usage; 399 0 stevel arg.initiator_time_req = initiator_time_req; 400 0 stevel arg.acceptor_time_req = acceptor_time_req; 401 0 stevel 402 0 stevel /* call the remote procedure */ 403 0 stevel 404 0 stevel bzero((caddr_t)&res, sizeof (res)); 405 0 stevel if (gss_add_cred_1(&arg, &res, clnt) != RPC_SUCCESS) { 406 0 stevel 407 0 stevel /* 408 0 stevel * if the RPC call times out, null out all return arguments, 409 0 stevel * set minor_status to its maximum value, and return 410 0 stevel * GSS_S_FAILURE 411 0 stevel */ 412 0 stevel 413 0 stevel killgssd_handle(clnt); 414 0 stevel (void) gss_release_buffer(&minor_status_temp, &external_name); 415 0 stevel GSSLOG0(1, "kgss_add_cred: RPC call times out\n"); 416 0 stevel return (GSS_S_FAILURE); 417 0 stevel } 418 0 stevel 419 0 stevel /* free the allocated memory for the flattened name */ 420 0 stevel 421 0 stevel (void) gss_release_buffer(&minor_status_temp, &external_name); 422 0 stevel 423 0 stevel /* copy the rpc results into the return arguments */ 424 0 stevel 425 0 stevel if (minor_status != NULL) 426 0 stevel *minor_status = res.minor_status; 427 0 stevel 428 0 stevel if (res.status == GSS_S_COMPLETE && 429 0 stevel res.actual_mechs.GSS_OID_SET_len != 0 && 430 0 stevel actual_mechs != NULL) { 431 0 stevel *actual_mechs = (gss_OID_set) MALLOC(sizeof (gss_OID_set_desc)); 432 0 stevel (*actual_mechs)->count = 433 0 stevel (int)res.actual_mechs.GSS_OID_SET_len; 434 0 stevel (*actual_mechs)->elements = (gss_OID) 435 0 stevel MALLOC(sizeof (gss_OID_desc) * (*actual_mechs)->count); 436 0 stevel 437 0 stevel for (i = 0; i < (*actual_mechs)->count; i++) { 438 0 stevel (*actual_mechs)->elements[i].length = (OM_uint32) 439 0 stevel res.actual_mechs.GSS_OID_SET_val[i].GSS_OID_len; 440 0 stevel (*actual_mechs)->elements[i].elements = 441 0 stevel (void *) MALLOC((*actual_mechs)->elements[i].length); 442 0 stevel (void) memcpy((*actual_mechs)->elements[i].elements, 443 0 stevel res.actual_mechs.GSS_OID_SET_val[i].GSS_OID_val, 444 0 stevel (*actual_mechs)->elements[i].length); 445 0 stevel } 446 0 stevel } else { 447 0 stevel if (res.status == GSS_S_COMPLETE && actual_mechs != NULL) 448 0 stevel (*actual_mechs) = NULL; 449 0 stevel } 450 0 stevel if (initiator_time_rec != NULL) 451 0 stevel *initiator_time_rec = res.acceptor_time_rec; 452 0 stevel if (acceptor_time_rec != NULL) 453 0 stevel *acceptor_time_rec = res.acceptor_time_rec; 454 0 stevel 455 0 stevel /* 456 0 stevel * free the memory allocated for the results and return with the status 457 0 stevel * received in the rpc call 458 0 stevel */ 459 0 stevel 460 0 stevel clnt_freeres(clnt, xdr_gss_add_cred_res, (caddr_t)&res); 461 0 stevel killgssd_handle(clnt); 462 0 stevel return (res.status); 463 0 stevel 464 0 stevel } 465 0 stevel 466 0 stevel OM_uint32 467 0 stevel kgss_add_cred(minor_status, 468 0 stevel input_cred_handle, 469 0 stevel desired_name, 470 0 stevel desired_mech_type, 471 0 stevel cred_usage, 472 0 stevel initiator_time_req, 473 0 stevel acceptor_time_req, 474 0 stevel actual_mechs, 475 0 stevel initiator_time_rec, 476 0 stevel acceptor_time_rec, 477 0 stevel uid) 478 0 stevel OM_uint32 *minor_status; 479 0 stevel gss_cred_id_t input_cred_handle; 480 0 stevel gss_name_t desired_name; 481 0 stevel gss_OID desired_mech_type; 482 0 stevel int cred_usage; 483 0 stevel int initiator_time_req; 484 0 stevel int acceptor_time_req; 485 0 stevel gss_OID_set *actual_mechs; 486 0 stevel OM_uint32 *initiator_time_rec; 487 0 stevel OM_uint32 *acceptor_time_rec; 488 0 stevel uid_t uid; 489 0 stevel { 490 0 stevel 491 0 stevel OM_uint32 err; 492 0 stevel OM_uint32 gssd_cred_verifier; 493 0 stevel gssd_cred_id_t gssd_input_cred_handle; 494 0 stevel 495 0 stevel if (input_cred_handle != GSS_C_NO_CREDENTIAL) { 496 0 stevel gssd_cred_verifier = KCRED_TO_CREDV(input_cred_handle); 497 0 stevel gssd_input_cred_handle = KCRED_TO_CRED(input_cred_handle); 498 0 stevel } else 499 0 stevel gssd_input_cred_handle = (gssd_cred_id_t)GSS_C_NO_CREDENTIAL; 500 0 stevel 501 0 stevel err = kgss_add_cred_wrapped(minor_status, gssd_input_cred_handle, 502 0 stevel gssd_cred_verifier, desired_name, desired_mech_type, 503 0 stevel cred_usage, initiator_time_req, acceptor_time_req, 504 0 stevel actual_mechs, initiator_time_rec, 505 0 stevel acceptor_time_rec, uid); 506 0 stevel return (err); 507 0 stevel } 508 0 stevel 509 0 stevel 510 0 stevel OM_uint32 511 0 stevel kgss_release_cred_wrapped(minor_status, 512 0 stevel cred_handle, 513 0 stevel uid, 514 0 stevel gssd_cred_verifier) 515 0 stevel OM_uint32 *minor_status; 516 0 stevel gssd_cred_id_t *cred_handle; 517 0 stevel uid_t uid; 518 0 stevel OM_uint32 gssd_cred_verifier; 519 0 stevel { 520 0 stevel CLIENT *clnt; 521 0 stevel 522 0 stevel gss_release_cred_arg arg; 523 0 stevel gss_release_cred_res res; 524 0 stevel 525 0 stevel 526 0 stevel /* get the client handle to GSSD */ 527 0 stevel 528 0 stevel if ((clnt = getgssd_handle()) == NULL) { 529 0 stevel GSSLOG(1, "kgss_release_cred: can't connect to server on %s\n", 530 0 stevel server); 531 0 stevel return (GSS_S_FAILURE); 532 0 stevel } 533 0 stevel 534 0 stevel /* copy the procedure arguments into the rpc arg parameter */ 535 0 stevel 536 0 stevel arg.uid = (OM_uint32)uid; 537 0 stevel arg.gssd_cred_verifier = gssd_cred_verifier; 538 0 stevel 539 0 stevel if (cred_handle != NULL) { 540 0 stevel arg.cred_handle.GSS_CRED_ID_T_len = 541 0 stevel (uint_t)sizeof (gssd_cred_id_t); 542 0 stevel arg.cred_handle.GSS_CRED_ID_T_val = (char *)cred_handle; 543 0 stevel } else 544 0 stevel arg.cred_handle.GSS_CRED_ID_T_len = 0; 545 0 stevel 546 0 stevel /* call the remote procedure */ 547 0 stevel 548 0 stevel bzero((caddr_t)&res, sizeof (res)); 549 0 stevel if (gss_release_cred_1(&arg, &res, clnt) != RPC_SUCCESS) { 550 0 stevel 551 0 stevel /* 552 0 stevel * if the RPC call times out, null out all return arguments, set 553 0 stevel * minor_status to its maximum value, and return GSS_S_FAILURE 554 0 stevel */ 555 0 stevel 556 0 stevel if (minor_status != NULL) 557 0 stevel *minor_status = DEFAULT_MINOR_STAT; 558 0 stevel if (cred_handle != NULL) 559 0 stevel *cred_handle = NULL; 560 0 stevel 561 0 stevel killgssd_handle(clnt); 562 0 stevel GSSLOG0(1, "kgss_release_cred: RPC call times out\n"); 563 0 stevel return (GSS_S_FAILURE); 564 0 stevel } 565 0 stevel 566 0 stevel /* if the release succeeded, null out the cred_handle */ 567 0 stevel 568 0 stevel if (res.status == GSS_S_COMPLETE && cred_handle != NULL) 569 0 stevel *cred_handle = NULL; 570 0 stevel 571 0 stevel /* copy the rpc results into the return arguments */ 572 0 stevel 573 0 stevel if (minor_status != NULL) 574 0 stevel *minor_status = res.minor_status; 575 0 stevel 576 0 stevel /* return with status returned in rpc call */ 577 0 stevel 578 0 stevel killgssd_handle(clnt); 579 0 stevel 580 0 stevel return (res.status); 581 0 stevel 582 0 stevel } 583 0 stevel 584 0 stevel OM_uint32 585 0 stevel kgss_release_cred(minor_status, 586 0 stevel cred_handle, 587 0 stevel uid) 588 0 stevel OM_uint32 *minor_status; 589 0 stevel gss_cred_id_t *cred_handle; 590 0 stevel uid_t uid; 591 0 stevel 592 0 stevel { 593 0 stevel 594 0 stevel OM_uint32 err; 595 0 stevel struct kgss_cred *kcred; 596 0 stevel 597 0 stevel if (*cred_handle == GSS_C_NO_CREDENTIAL) 598 0 stevel return (GSS_S_COMPLETE); 599 0 stevel else 600 0 stevel kcred = KCRED_TO_KGSS_CRED(*cred_handle); 601 0 stevel 602 0 stevel err = kgss_release_cred_wrapped(minor_status, &kcred->gssd_cred, 603 0 stevel uid, kcred->gssd_cred_verifier); 604 0 stevel KGSS_CRED_FREE(kcred); 605 0 stevel *cred_handle = GSS_C_NO_CREDENTIAL; 606 0 stevel return (err); 607 0 stevel } 608 0 stevel 609 0 stevel static OM_uint32 610 0 stevel kgss_init_sec_context_wrapped( 611 0 stevel OM_uint32 *minor_status, 612 0 stevel const gssd_cred_id_t claimant_cred_handle, 613 0 stevel OM_uint32 gssd_cred_verifier, 614 0 stevel gssd_ctx_id_t *context_handle, 615 0 stevel OM_uint32 *gssd_context_verifier, 616 0 stevel const gss_name_t target_name, 617 0 stevel const gss_OID mech_type, 618 0 stevel int req_flags, 619 0 stevel OM_uint32 time_req, 620 0 stevel const gss_channel_bindings_t input_chan_bindings, 621 0 stevel const gss_buffer_t input_token, 622 0 stevel gss_OID *actual_mech_type, 623 0 stevel gss_buffer_t output_token, 624 0 stevel int *ret_flags, 625 0 stevel OM_uint32 *time_rec, 626 0 stevel uid_t uid) 627 0 stevel { 628 0 stevel CLIENT *clnt; 629 0 stevel 630 0 stevel OM_uint32 minor_status_temp; 631 0 stevel gss_buffer_desc external_name; 632 0 stevel gss_OID name_type; 633 0 stevel 634 0 stevel gss_init_sec_context_arg arg; 635 0 stevel gss_init_sec_context_res res; 636 0 stevel 637 0 stevel /* get the client handle to GSSD */ 638 0 stevel 639 0 stevel if ((clnt = getgssd_handle()) == NULL) { 640 0 stevel GSSLOG(1, 641 0 stevel "kgss_init_sec_context: can't connect to server on %s\n", 642 0 stevel server); 643 0 stevel return (GSS_S_FAILURE); 644 0 stevel } 645 0 stevel 646 0 stevel /* convert the target name from internal to external format */ 647 0 stevel 648 0 stevel if (gss_display_name(&minor_status_temp, target_name, 649 0 stevel &external_name, &name_type) != GSS_S_COMPLETE) { 650 0 stevel 651 0 stevel *minor_status = (OM_uint32) minor_status_temp; 652 0 stevel killgssd_handle(clnt); 653 0 stevel GSSLOG0(1, "kgss_init_sec_context: can't display name\n"); 654 0 stevel return ((OM_uint32) GSS_S_FAILURE); 655 0 stevel } 656 0 stevel 657 0 stevel 658 0 stevel /* copy the procedure arguments into the rpc arg parameter */ 659 0 stevel 660 0 stevel arg.uid = (OM_uint32)uid; 661 0 stevel 662 0 stevel arg.context_handle.GSS_CTX_ID_T_len = 663 0 stevel *context_handle == (gssd_ctx_id_t)GSS_C_NO_CONTEXT ? 664 0 stevel 0 : (uint_t)sizeof (gssd_ctx_id_t); 665 0 stevel arg.context_handle.GSS_CTX_ID_T_val = (char *)context_handle; 666 0 stevel 667 0 stevel arg.gssd_context_verifier = *gssd_context_verifier; 668 0 stevel 669 0 stevel arg.claimant_cred_handle.GSS_CRED_ID_T_len = 670 0 stevel claimant_cred_handle == (gssd_cred_id_t)GSS_C_NO_CREDENTIAL ? 671 0 stevel 0 : (uint_t)sizeof (gssd_cred_id_t); 672 0 stevel arg.claimant_cred_handle.GSS_CRED_ID_T_val = 673 0 stevel (char *)&claimant_cred_handle; 674 0 stevel arg.gssd_cred_verifier = gssd_cred_verifier; 675 0 stevel 676 0 stevel arg.target_name.GSS_BUFFER_T_len = (uint_t)external_name.length; 677 0 stevel arg.target_name.GSS_BUFFER_T_val = (char *)external_name.value; 678 0 stevel 679 0 stevel arg.name_type.GSS_OID_len = 680 0 stevel name_type == GSS_C_NULL_OID ? 681 0 stevel 0 : (uint_t)name_type->length; 682 0 stevel 683 0 stevel arg.name_type.GSS_OID_val = 684 0 stevel name_type == GSS_C_NULL_OID ? 685 0 stevel (char *)NULL : (char *)name_type->elements; 686 0 stevel 687 0 stevel arg.mech_type.GSS_OID_len = (uint_t)(mech_type != GSS_C_NULL_OID ? 688 0 stevel mech_type->length : 0); 689 0 stevel arg.mech_type.GSS_OID_val = (char *)(mech_type != GSS_C_NULL_OID ? 690 0 stevel mech_type->elements : 0); 691 0 stevel 692 0 stevel arg.req_flags = req_flags; 693 0 stevel 694 0 stevel arg.time_req = time_req; 695 0 stevel 696 0 stevel if (input_chan_bindings != GSS_C_NO_CHANNEL_BINDINGS) { 697 0 stevel arg.input_chan_bindings.present = YES; 698 0 stevel arg.input_chan_bindings.initiator_addrtype = 699 0 stevel input_chan_bindings->initiator_addrtype; 700 0 stevel arg.input_chan_bindings.initiator_address.GSS_BUFFER_T_len = 701 0 stevel (uint_t)input_chan_bindings->initiator_address.length; 702 0 stevel arg.input_chan_bindings.initiator_address.GSS_BUFFER_T_val = 703 0 stevel (void *)input_chan_bindings->initiator_address.value; 704 0 stevel arg.input_chan_bindings.acceptor_addrtype = 705 0 stevel input_chan_bindings->acceptor_addrtype; 706 0 stevel arg.input_chan_bindings.acceptor_address.GSS_BUFFER_T_len = 707 0 stevel (uint_t)input_chan_bindings->acceptor_address.length; 708 0 stevel arg.input_chan_bindings.acceptor_address.GSS_BUFFER_T_val = 709 0 stevel (void *)input_chan_bindings->acceptor_address.value; 710 0 stevel arg.input_chan_bindings.application_data.GSS_BUFFER_T_len = 711 0 stevel (uint_t)input_chan_bindings->application_data.length; 712 0 stevel arg.input_chan_bindings.application_data.GSS_BUFFER_T_val = 713 0 stevel (void *)input_chan_bindings->application_data.value; 714 0 stevel } else { 715 0 stevel arg.input_chan_bindings.present = NO; 716 0 stevel arg.input_chan_bindings.initiator_addrtype = 0; 717 0 stevel arg.input_chan_bindings.initiator_address.GSS_BUFFER_T_len = 0; 718 0 stevel arg.input_chan_bindings.initiator_address.GSS_BUFFER_T_val = 0; 719 0 stevel arg.input_chan_bindings.acceptor_addrtype = 0; 720 0 stevel arg.input_chan_bindings.acceptor_address.GSS_BUFFER_T_len = 0; 721 0 stevel arg.input_chan_bindings.acceptor_address.GSS_BUFFER_T_val = 0; 722 0 stevel arg.input_chan_bindings.application_data.GSS_BUFFER_T_len = 0; 723 0 stevel arg.input_chan_bindings.application_data.GSS_BUFFER_T_val = 0; 724 0 stevel } 725 0 stevel 726 0 stevel arg.input_token.GSS_BUFFER_T_len = 727 0 stevel (uint_t)(input_token != GSS_C_NO_BUFFER ? 728 0 stevel input_token->length : 0); 729 0 stevel arg.input_token.GSS_BUFFER_T_val = 730 0 stevel (char *)(input_token != GSS_C_NO_BUFFER ? 731 0 stevel input_token->value : 0); 732 0 stevel 733 0 stevel /* call the remote procedure */ 734 0 stevel 735 0 stevel bzero((caddr_t)&res, sizeof (res)); 736 0 stevel if (gss_init_sec_context_1(&arg, &res, clnt) != RPC_SUCCESS) { 737 0 stevel 738 0 stevel /* 739 0 stevel * if the RPC call times out, null out all return arguments, set 740 0 stevel * minor_status to its maximum value, and return GSS_S_FAILURE 741 0 stevel */ 742 0 stevel 743 0 stevel if (minor_status != NULL) 744 0 stevel *minor_status = DEFAULT_MINOR_STAT; 745 0 stevel if (actual_mech_type != NULL) 746 0 stevel *actual_mech_type = NULL; 747 0 stevel if (output_token != NULL) 748 0 stevel output_token->length = 0; 749 0 stevel if (ret_flags != NULL) 750 0 stevel *ret_flags = 0; 751 0 stevel if (time_rec != NULL) 752 0 stevel *time_rec = 0; 753 0 stevel 754 0 stevel killgssd_handle(clnt); 755 0 stevel (void) gss_release_buffer(&minor_status_temp, &external_name); 756 0 stevel GSSLOG0(1, "kgss_init_sec_context: RPC call times out\n"); 757 0 stevel return (GSS_S_FAILURE); 758 0 stevel } 759 0 stevel 760 0 stevel /* free the allocated memory for the flattened name */ 761 0 stevel 762 0 stevel (void) gss_release_buffer(&minor_status_temp, &external_name); 763 0 stevel 764 0 stevel if (minor_status != NULL) 765 0 stevel *minor_status = res.minor_status; 766 0 stevel 767 10598 Glenn if (output_token != NULL && res.output_token.GSS_BUFFER_T_val != NULL) { 768 10598 Glenn output_token->length = 769 10598 Glenn (size_t)res.output_token.GSS_BUFFER_T_len; 770 10598 Glenn output_token->value = 771 10598 Glenn (void *)MALLOC(output_token->length); 772 10598 Glenn (void) memcpy(output_token->value, 773 10598 Glenn res.output_token.GSS_BUFFER_T_val, 774 10598 Glenn output_token->length); 775 10598 Glenn } 776 10598 Glenn 777 0 stevel /* if the call was successful, copy out the results */ 778 0 stevel if (res.status == (OM_uint32) GSS_S_COMPLETE || 779 0 stevel res.status == (OM_uint32) GSS_S_CONTINUE_NEEDED) { 780 0 stevel /* 781 0 stevel * if the return code is GSS_S_CONTINUE_NEEDED 782 0 stevel * ignore all return parameters except for 783 0 stevel * status codes, output token and context handle. 784 0 stevel */ 785 0 stevel *context_handle = 786 0 stevel *((gssd_ctx_id_t *) 787 0 stevel res.context_handle.GSS_CTX_ID_T_val); 788 0 stevel *gssd_context_verifier = res.gssd_context_verifier; 789 0 stevel 790 0 stevel if (res.status == GSS_S_COMPLETE) { 791 0 stevel if (actual_mech_type != NULL) { 792 0 stevel *actual_mech_type = 793 0 stevel (gss_OID) MALLOC(sizeof (gss_OID_desc)); 794 0 stevel (*actual_mech_type)->length = 795 0 stevel (OM_UINT32) 796 0 stevel res.actual_mech_type.GSS_OID_len; 797 0 stevel (*actual_mech_type)->elements = 798 0 stevel (void *) 799 0 stevel MALLOC((*actual_mech_type)->length); 800 0 stevel (void) memcpy((*actual_mech_type)->elements, 801 0 stevel (void *) 802 0 stevel res.actual_mech_type.GSS_OID_val, 803 0 stevel (*actual_mech_type)->length); 804 0 stevel } 805 0 stevel 806 0 stevel 807 0 stevel if (ret_flags != NULL) 808 0 stevel *ret_flags = res.ret_flags; 809 0 stevel 810 0 stevel if (time_rec != NULL) 811 0 stevel *time_rec = res.time_rec; 812 0 stevel } 813 0 stevel } 814 0 stevel 815 0 stevel /* 816 0 stevel * free the memory allocated for the results and return with the status 817 0 stevel * received in the rpc call 818 0 stevel */ 819 0 stevel 820 0 stevel clnt_freeres(clnt, xdr_gss_init_sec_context_res, (caddr_t)&res); 821 0 stevel killgssd_handle(clnt); 822 0 stevel return (res.status); 823 0 stevel 824 0 stevel } 825 0 stevel 826 0 stevel static struct gss_config default_gc = { 827 0 stevel { 0, NULL}, 828 0 stevel NULL, 829 0 stevel NULL, 830 0 stevel 0, 831 0 stevel /* EXPORT DELETE START */ /* CRYPT DELETE START */ 832 0 stevel kgss_unseal_wrapped, 833 0 stevel /* EXPORT DELETE END */ /* CRYPT DELETE END */ 834 0 stevel NULL, /* kgss_delete_sec_context_wrapped */ 835 0 stevel /* EXPORT DELETE START */ /* CRYPT DELETE START */ 836 0 stevel kgss_seal_wrapped, 837 0 stevel /* EXPORT DELETE END */ /* CRYPT DELETE END */ 838 0 stevel NULL, /* kgss_import_sec_context */ 839 0 stevel /* EXPORT DELETE START */ 840 0 stevel /* CRYPT DELETE START */ 841 0 stevel #if 0 842 0 stevel /* CRYPT DELETE END */ 843 0 stevel kgss_seal_wrapped, 844 0 stevel kgss_unseal_wrapped, 845 0 stevel /* CRYPT DELETE START */ 846 0 stevel #endif 847 0 stevel /* CRYPT DELETE END */ 848 0 stevel /* EXPORT DELETE END */ 849 0 stevel kgss_sign_wrapped, 850 0 stevel kgss_verify_wrapped 851 0 stevel }; 852 0 stevel 853 0 stevel void 854 0 stevel kgss_free_oid(gss_OID oid) 855 0 stevel { 856 0 stevel FREE(oid->elements, oid->length); 857 0 stevel FREE(oid, sizeof (gss_OID_desc)); 858 0 stevel } 859 0 stevel 860 0 stevel OM_uint32 861 0 stevel kgss_init_sec_context( 862 0 stevel OM_uint32 *minor_status, 863 0 stevel const gss_cred_id_t claimant_cred_handle, 864 0 stevel gss_ctx_id_t *context_handle, 865 0 stevel const gss_name_t target_name, 866 0 stevel const gss_OID mech_type, 867 0 stevel int req_flags, 868 0 stevel OM_uint32 time_req, 869 0 stevel const gss_channel_bindings_t input_chan_bindings, 870 0 stevel const gss_buffer_t input_token, 871 0 stevel gss_OID *actual_mech_type, 872 0 stevel gss_buffer_t output_token, 873 0 stevel int *ret_flags, 874 0 stevel OM_uint32 *time_rec, 875 0 stevel uid_t uid) 876 0 stevel { 877 0 stevel OM_uint32 err; 878 0 stevel struct kgss_ctx *kctx; 879 0 stevel gss_OID amt; 880 0 stevel gssd_cred_id_t gssd_cl_cred_handle; 881 0 stevel OM_uint32 gssd_cred_verifier; 882 0 stevel 883 0 stevel /* 884 0 stevel * If this is an initial call, we'll need to create the 885 0 stevel * wrapper struct that contains kernel state information, and 886 0 stevel * a reference to the handle from gssd. 887 0 stevel */ 888 0 stevel if (*context_handle == GSS_C_NO_CONTEXT) { 889 0 stevel kctx = KGSS_ALLOC(); 890 0 stevel /* 891 0 stevel * The default gss-mechanism struct as pointers to 892 0 stevel * the sign/seal/verify/unseal routines that make 893 0 stevel * upcalls to gssd. 894 0 stevel */ 895 0 stevel kctx->mech = &default_gc; 896 0 stevel kctx->gssd_ctx = (gssd_ctx_id_t)GSS_C_NO_CONTEXT; 897 0 stevel *context_handle = (gss_ctx_id_t)kctx; 898 0 stevel } else 899 0 stevel kctx = (struct kgss_ctx *)*context_handle; 900 0 stevel 901 0 stevel if (claimant_cred_handle != GSS_C_NO_CREDENTIAL) { 902 0 stevel gssd_cred_verifier = KCRED_TO_CREDV(claimant_cred_handle); 903 0 stevel gssd_cl_cred_handle = KCRED_TO_CRED(claimant_cred_handle); 904 0 stevel } else 905 0 stevel gssd_cl_cred_handle = (gssd_cred_id_t)GSS_C_NO_CREDENTIAL; 906 0 stevel 907 0 stevel /* 908 0 stevel * We need to know the resulting mechanism oid, so allocate 909 0 stevel * it if the caller won't. 910 0 stevel */ 911 0 stevel if (actual_mech_type == NULL) 912 0 stevel actual_mech_type = &amt; 913 0 stevel 914 0 stevel err = kgss_init_sec_context_wrapped(minor_status, gssd_cl_cred_handle, 915 0 stevel gssd_cred_verifier, &kctx->gssd_ctx, &kctx->gssd_ctx_verifier, 916 0 stevel target_name, mech_type, req_flags, time_req, 917 0 stevel input_chan_bindings, input_token, actual_mech_type, 918 0 stevel output_token, ret_flags, time_rec, uid); 919 0 stevel 920 0 stevel if (GSS_ERROR(err)) { 921 0 stevel KGSS_FREE(kctx); 922 0 stevel *context_handle = GSS_C_NO_CONTEXT; 923 0 stevel } else if (err == GSS_S_COMPLETE) { 924 0 stevel /* 925 0 stevel * Now check if there is a kernel module for this 926 0 stevel * mechanism OID. If so, set the gss_mechanism structure 927 0 stevel * in the wrapper context to point to the kernel mech. 928 0 stevel */ 929 0 stevel __kgss_reset_mech(&kctx->mech, *actual_mech_type); 930 0 stevel 931 0 stevel /* 932 0 stevel * If the mech oid was allocated for us, free it. 933 0 stevel */ 934 0 stevel if (&amt == actual_mech_type) { 935 0 stevel kgss_free_oid(amt); 936 0 stevel } 937 0 stevel } 938 0 stevel return (err); 939 0 stevel } 940 0 stevel 941 0 stevel static OM_uint32 942 0 stevel kgss_accept_sec_context_wrapped( 943 0 stevel OM_uint32 *minor_status, 944 0 stevel gssd_ctx_id_t *context_handle, 945 0 stevel OM_uint32 *gssd_context_verifier, 946 0 stevel const gssd_cred_id_t verifier_cred_handle, 947 0 stevel OM_uint32 gssd_cred_verifier, 948 0 stevel const gss_buffer_t input_token, 949 0 stevel const gss_channel_bindings_t input_chan_bindings, 950 0 stevel gss_buffer_t src_name, 951 0 stevel gss_OID *mech_type, 952 0 stevel gss_buffer_t output_token, 953 0 stevel int *ret_flags, 954 0 stevel OM_uint32 *time_rec, 955 0 stevel gss_cred_id_t *delegated_cred_handle, 956 0 stevel uid_t uid) 957 0 stevel { 958 0 stevel CLIENT *clnt; 959 0 stevel 960 0 stevel gss_accept_sec_context_arg arg; 961 0 stevel gss_accept_sec_context_res res; 962 0 stevel struct kgss_cred *kcred; 963 0 stevel 964 0 stevel /* get the client handle to GSSD */ 965 0 stevel 966 0 stevel if ((clnt = getgssd_handle()) == NULL) { 967 0 stevel GSSLOG(1, 968 0 stevel "kgss_accept_sec_context: can't connect to server on %s\n", 969 0 stevel server); 970 0 stevel return (GSS_S_FAILURE); 971 0 stevel } 972 0 stevel 973 0 stevel /* copy the procedure arguments into the rpc arg parameter */ 974 0 stevel 975 0 stevel arg.uid = (OM_uint32)uid; 976 0 stevel 977 0 stevel arg.context_handle.GSS_CTX_ID_T_len = 978 0 stevel *context_handle == (gssd_ctx_id_t)GSS_C_NO_CONTEXT ? 979 0 stevel 0 : (uint_t)sizeof (gssd_ctx_id_t); 980 0 stevel arg.context_handle.GSS_CTX_ID_T_val = (char *)context_handle; 981 0 stevel arg.gssd_context_verifier = *gssd_context_verifier; 982 0 stevel 983 0 stevel arg.verifier_cred_handle.GSS_CRED_ID_T_len = 984 0 stevel verifier_cred_handle == 985 0 stevel (gssd_cred_id_t)GSS_C_NO_CREDENTIAL ? 986 0 stevel 0 : (uint_t)sizeof (gssd_cred_id_t); 987 0 stevel arg.verifier_cred_handle.GSS_CRED_ID_T_val = 988 0 stevel (char *)&verifier_cred_handle; 989 0 stevel arg.gssd_cred_verifier = gssd_cred_verifier; 990 0 stevel 991 0 stevel arg.input_token_buffer.GSS_BUFFER_T_len = 992 0 stevel (uint_t)(input_token != GSS_C_NO_BUFFER ? 993 0 stevel input_token->length : 0); 994 0 stevel arg.input_token_buffer.GSS_BUFFER_T_val = 995 0 stevel (char *)(input_token != GSS_C_NO_BUFFER ? 996 0 stevel input_token->value : 0); 997 0 stevel 998 0 stevel if (input_chan_bindings != GSS_C_NO_CHANNEL_BINDINGS) { 999 0 stevel arg.input_chan_bindings.present = YES; 1000 0 stevel arg.input_chan_bindings.initiator_addrtype = 1001 0 stevel input_chan_bindings->initiator_addrtype; 1002 0 stevel arg.input_chan_bindings.initiator_address.GSS_BUFFER_T_len = 1003 0 stevel (uint_t)input_chan_bindings->initiator_address.length; 1004 0 stevel arg.input_chan_bindings.initiator_address.GSS_BUFFER_T_val = 1005 0 stevel (void *)input_chan_bindings->initiator_address.value; 1006 0 stevel arg.input_chan_bindings.acceptor_addrtype = 1007 0 stevel input_chan_bindings->acceptor_addrtype; 1008 0 stevel arg.input_chan_bindings.acceptor_address.GSS_BUFFER_T_len = 1009 0 stevel (uint_t)input_chan_bindings->acceptor_address.length; 1010 0 stevel arg.input_chan_bindings.acceptor_address.GSS_BUFFER_T_val = 1011 0 stevel (void *)input_chan_bindings->acceptor_address.value; 1012 0 stevel arg.input_chan_bindings.application_data.GSS_BUFFER_T_len = 1013 0 stevel (uint_t)input_chan_bindings->application_data.length; 1014 0 stevel arg.input_chan_bindings.application_data.GSS_BUFFER_T_val = 1015 0 stevel (void *)input_chan_bindings->application_data.value; 1016 0 stevel } else { 1017 0 stevel 1018 0 stevel arg.input_chan_bindings.present = NO; 1019 0 stevel arg.input_chan_bindings.initiator_addrtype = 0; 1020 0 stevel arg.input_chan_bindings.initiator_address.GSS_BUFFER_T_len = 0; 1021 0 stevel arg.input_chan_bindings.initiator_address.GSS_BUFFER_T_val = 0; 1022 0 stevel arg.input_chan_bindings.acceptor_addrtype = 0; 1023 0 stevel arg.input_chan_bindings.acceptor_address.GSS_BUFFER_T_len = 0; 1024 0 stevel arg.input_chan_bindings.acceptor_address.GSS_BUFFER_T_val = 0; 1025 0 stevel arg.input_chan_bindings.application_data.GSS_BUFFER_T_len = 0; 1026 0 stevel arg.input_chan_bindings.application_data.GSS_BUFFER_T_val = 0; 1027 0 stevel } 1028 0 stevel 1029 0 stevel /* set the return parameters in case of errors.... */ 1030 0 stevel if (minor_status != NULL) 1031 0 stevel *minor_status = DEFAULT_MINOR_STAT; 1032 0 stevel if (src_name != NULL) { 1033 0 stevel src_name->length = 0; 1034 0 stevel src_name->value = NULL; 1035 0 stevel } 1036 0 stevel if (mech_type != NULL) 1037 0 stevel *mech_type = NULL; 1038 0 stevel if (output_token != NULL) 1039 0 stevel output_token->length = 0; 1040 0 stevel if (ret_flags != NULL) 1041 0 stevel *ret_flags = 0; 1042 0 stevel if (time_rec != NULL) 1043 0 stevel *time_rec = 0; 1044 0 stevel if (delegated_cred_handle != NULL) 1045 0 stevel *delegated_cred_handle = NULL; 1046 0 stevel 1047 0 stevel /* call the remote procedure */ 1048 0 stevel 1049 0 stevel bzero((caddr_t)&res, sizeof (res)); 1050 0 stevel if (gss_accept_sec_context_1(&arg, &res, clnt) != RPC_SUCCESS) { 1051 0 stevel killgssd_handle(clnt); 1052 0 stevel GSSLOG0(1, "kgss_accept_sec_context: RPC call times out\n"); 1053 0 stevel return (GSS_S_FAILURE); 1054 0 stevel } 1055 0 stevel 1056 10598 Glenn if (minor_status != NULL) 1057 10598 Glenn *minor_status = res.minor_status; 1058 10598 Glenn 1059 10598 Glenn if (output_token != NULL && res.output_token.GSS_BUFFER_T_val != NULL) { 1060 10598 Glenn output_token->length = 1061 10598 Glenn res.output_token.GSS_BUFFER_T_len; 1062 10598 Glenn output_token->value = 1063 10598 Glenn (void *) MALLOC(output_token->length); 1064 10598 Glenn (void) memcpy(output_token->value, 1065 10598 Glenn res.output_token.GSS_BUFFER_T_val, 1066 10598 Glenn output_token->length); 1067 10598 Glenn } 1068 10598 Glenn 1069 0 stevel /* if the call was successful, copy out the results */ 1070 0 stevel 1071 0 stevel if (res.status == (OM_uint32) GSS_S_COMPLETE || 1072 0 stevel res.status == (OM_uint32) GSS_S_CONTINUE_NEEDED) { 1073 0 stevel 1074 0 stevel /* 1075 0 stevel * the only parameters that are ready when we 1076 0 stevel * get GSS_S_CONTINUE_NEEDED are: minor, ctxt_handle, 1077 0 stevel * and the output token to send to the peer. 1078 0 stevel */ 1079 0 stevel 1080 0 stevel *context_handle = *((gssd_ctx_id_t *) 1081 0 stevel res.context_handle.GSS_CTX_ID_T_val); 1082 0 stevel *gssd_context_verifier = res.gssd_context_verifier; 1083 0 stevel 1084 0 stevel /* these other parameters are only ready upon GSS_S_COMPLETE */ 1085 0 stevel if (res.status == (OM_uint32) GSS_S_COMPLETE) { 1086 0 stevel 1087 0 stevel if (src_name != NULL) { 1088 0 stevel src_name->length = res.src_name.GSS_BUFFER_T_len; 1089 0 stevel src_name->value = res.src_name.GSS_BUFFER_T_val; 1090 0 stevel res.src_name.GSS_BUFFER_T_val = NULL; 1091 0 stevel res.src_name.GSS_BUFFER_T_len = 0; 1092 0 stevel } 1093 0 stevel 1094 0 stevel /* 1095 0 stevel * move mech type returned to mech_type 1096 0 stevel * for gss_import_name_for_mech() 1097 0 stevel */ 1098 0 stevel if (mech_type != NULL) { 1099 0 stevel *mech_type = (gss_OID) 1100 0 stevel MALLOC(sizeof (gss_OID_desc)); 1101 0 stevel (*mech_type)->length = 1102 0 stevel (OM_UINT32) res.mech_type.GSS_OID_len; 1103 0 stevel (*mech_type)->elements = 1104 0 stevel (void *) MALLOC((*mech_type)->length); 1105 0 stevel (void) memcpy((*mech_type)->elements, 1106 0 stevel res.mech_type.GSS_OID_val, 1107 0 stevel (*mech_type)->length); 1108 0 stevel } 1109 0 stevel 1110 0 stevel if (ret_flags != NULL) 1111 0 stevel *ret_flags = res.ret_flags; 1112 0 stevel 1113 0 stevel if (time_rec != NULL) 1114 0 stevel *time_rec = res.time_rec; 1115 0 stevel 1116 0 stevel if ((delegated_cred_handle != NULL) && 1117 0 stevel (res.delegated_cred_handle.GSS_CRED_ID_T_len 1118 0 stevel != 0)) { 1119 0 stevel kcred = KGSS_CRED_ALLOC(); 1120 0 stevel kcred->gssd_cred = 1121 0 stevel *((gssd_cred_id_t *) 1122 0 stevel res.delegated_cred_handle.GSS_CRED_ID_T_val); 1123 0 stevel kcred->gssd_cred_verifier = 1124 0 stevel res.gssd_context_verifier; 1125 0 stevel *delegated_cred_handle = (gss_cred_id_t)kcred; 1126 0 stevel } 1127 0 stevel 1128 0 stevel } 1129 0 stevel } 1130 0 stevel 1131 0 stevel 1132 0 stevel /* 1133 0 stevel * free the memory allocated for the results and return with the status 1134 0 stevel * received in the rpc call 1135 0 stevel */ 1136 0 stevel 1137 0 stevel clnt_freeres(clnt, xdr_gss_accept_sec_context_res, (caddr_t)&res); 1138 0 stevel killgssd_handle(clnt); 1139 0 stevel return (res.status); 1140 0 stevel 1141 0 stevel } 1142 0 stevel 1143 0 stevel OM_uint32 1144 0 stevel kgss_accept_sec_context( 1145 0 stevel OM_uint32 *minor_status, 1146 0 stevel gss_ctx_id_t *context_handle, 1147 0 stevel const gss_cred_id_t verifier_cred_handle, 1148 0 stevel const gss_buffer_t input_token, 1149 0 stevel const gss_channel_bindings_t input_chan_bindings, 1150 0 stevel gss_buffer_t src_name, 1151 0 stevel gss_OID *mech_type, 1152 0 stevel gss_buffer_t output_token, 1153 0 stevel int *ret_flags, 1154 0 stevel OM_uint32 *time_rec, 1155 0 stevel gss_cred_id_t *delegated_cred_handle, 1156 0 stevel uid_t uid) 1157 0 stevel { 1158 0 stevel OM_uint32 err; 1159 0 stevel struct kgss_ctx *kctx; 1160 0 stevel gss_OID mt; 1161 0 stevel OM_uint32 gssd_cred_verifier; 1162 0 stevel gssd_cred_id_t gssd_ver_cred_handle; 1163 0 stevel 1164 0 stevel 1165 0 stevel /* 1166 0 stevel * See kgss_init_sec_context() to get an idea of what is going 1167 0 stevel * on here. 1168 0 stevel */ 1169 0 stevel if (mech_type == NULL) 1170 0 stevel mech_type = &mt; 1171 0 stevel 1172 0 stevel if (*context_handle == GSS_C_NO_CONTEXT) { 1173 0 stevel kctx = KGSS_ALLOC(); 1174 0 stevel kctx->mech = &default_gc; 1175 0 stevel kctx->gssd_ctx = (gssd_ctx_id_t)GSS_C_NO_CONTEXT; 1176 0 stevel *context_handle = (gss_ctx_id_t)kctx; 1177 0 stevel } else 1178 0 stevel kctx = (struct kgss_ctx *)*context_handle; 1179 0 stevel 1180 0 stevel if (verifier_cred_handle != GSS_C_NO_CREDENTIAL) { 1181 0 stevel gssd_cred_verifier = KCRED_TO_CREDV(verifier_cred_handle); 1182 0 stevel gssd_ver_cred_handle = KCRED_TO_CRED(verifier_cred_handle); 1183 0 stevel } else 1184 0 stevel gssd_ver_cred_handle = (gssd_cred_id_t)GSS_C_NO_CREDENTIAL; 1185 0 stevel 1186 0 stevel err = kgss_accept_sec_context_wrapped(minor_status, 1187 0 stevel &kctx->gssd_ctx, &kctx->gssd_ctx_verifier, 1188 0 stevel gssd_ver_cred_handle, gssd_cred_verifier, 1189 0 stevel input_token, input_chan_bindings, src_name, 1190 0 stevel mech_type, output_token, ret_flags, 1191 0 stevel time_rec, delegated_cred_handle, uid); 1192 0 stevel 1193 0 stevel if (GSS_ERROR(err)) { 1194 0 stevel KGSS_FREE(kctx); 1195 0 stevel *context_handle = GSS_C_NO_CONTEXT; 1196 0 stevel 1197 0 stevel } else if (err == GSS_S_COMPLETE) { 1198 0 stevel __kgss_reset_mech(&kctx->mech, *mech_type); 1199 0 stevel 1200 0 stevel /* 1201 0 stevel * If the mech oid was allocated for us, free it. 1202 0 stevel */ 1203 0 stevel if (&mt == mech_type) { 1204 0 stevel kgss_free_oid(mt); 1205 0 stevel } 1206 0 stevel } 1207 0 stevel 1208 0 stevel return (err); 1209 0 stevel } 1210 0 stevel 1211 0 stevel OM_uint32 1212 0 stevel kgss_process_context_token(minor_status, 1213 0 stevel context_handle, 1214 0 stevel token_buffer, 1215 0 stevel uid) 1216 0 stevel OM_uint32 *minor_status; 1217 0 stevel const gss_ctx_id_t context_handle; 1218 0 stevel gss_buffer_t token_buffer; 1219 0 stevel uid_t uid; 1220 0 stevel { 1221 0 stevel CLIENT *clnt; 1222 0 stevel OM_uint32 gssd_context_verifier; 1223 0 stevel gssd_ctx_id_t gssd_ctx_handle; 1224 0 stevel gss_process_context_token_arg arg; 1225 0 stevel gss_process_context_token_res res; 1226 0 stevel 1227 0 stevel gssd_context_verifier = KGSS_CTX_TO_GSSD_CTXV(context_handle); 1228 0 stevel gssd_ctx_handle = (gssd_ctx_id_t)KGSS_CTX_TO_GSSD_CTX(context_handle); 1229 0 stevel 1230 0 stevel /* get the client handle to GSSD */ 1231 0 stevel 1232 0 stevel if ((clnt = getgssd_handle()) == NULL) { 1233 0 stevel GSSLOG(1, 1234 0 stevel "kgss_process_context_token: can't connect to server on %s\n", 1235 0 stevel server); 1236 0 stevel return (GSS_S_FAILURE); 1237 0 stevel } 1238 0 stevel 1239 0 stevel /* copy the procedure arguments into the rpc arg parameter */ 1240 0 stevel 1241 0 stevel arg.uid = (OM_uint32) uid; 1242 0 stevel 1243 0 stevel arg.context_handle.GSS_CTX_ID_T_len = (uint_t)sizeof (gssd_ctx_id_t); 1244 0 stevel arg.context_handle.GSS_CTX_ID_T_val = (char *)&gssd_ctx_handle; 1245 0 stevel arg.gssd_context_verifier = gssd_context_verifier; 1246 0 stevel arg.token_buffer.GSS_BUFFER_T_len = (uint_t)token_buffer->length; 1247 0 stevel arg.token_buffer.GSS_BUFFER_T_val = (char *)token_buffer->value; 1248 0 stevel 1249 0 stevel /* call the remote procedure */ 1250 0 stevel 1251 0 stevel bzero(&res, sizeof (res)); 1252 0 stevel 1253 0 stevel if (gss_process_context_token_1(&arg, &res, clnt) != RPC_SUCCESS) { 1254 0 stevel 1255 0 stevel /* 1256 0 stevel * if the RPC call times out, null out all return arguments, set 1257 0 stevel * minor_status to its maximum value, and return GSS_S_FAILURE 1258 0 stevel */ 1259 0 stevel 1260 0 stevel if (minor_status != NULL) 1261 0 stevel *minor_status = DEFAULT_MINOR_STAT; 1262 0 stevel GSSLOG0(1, "kgss_process_context_token: RPC call times out\n"); 1263 0 stevel killgssd_handle(clnt); 1264 0 stevel return (GSS_S_FAILURE); 1265 0 stevel } 1266 0 stevel 1267 0 stevel /* copy the rpc results into the return arguments */ 1268 0 stevel 1269 0 stevel if (minor_status != NULL) 1270 0 stevel *minor_status = res.minor_status; 1271 0 stevel 1272 0 stevel /* return with status returned in rpc call */ 1273 0 stevel 1274 0 stevel killgssd_handle(clnt); 1275 0 stevel return (res.status); 1276 0 stevel 1277 0 stevel } 1278 0 stevel 1279 0 stevel /*ARGSUSED*/ 1280 0 stevel static OM_uint32 1281 0 stevel kgss_delete_sec_context_wrapped(void *private, 1282 0 stevel OM_uint32 *minor_status, 1283 0 stevel gssd_ctx_id_t *context_handle, 1284 0 stevel gss_buffer_t output_token, 1285 0 stevel OM_uint32 gssd_context_verifier) 1286 0 stevel 1287 0 stevel 1288 0 stevel { 1289 0 stevel CLIENT *clnt; 1290 0 stevel 1291 0 stevel gss_delete_sec_context_arg arg; 1292 0 stevel gss_delete_sec_context_res res; 1293 0 stevel 1294 0 stevel 1295 0 stevel /* get the client handle to GSSD */ 1296 0 stevel 1297 0 stevel if ((clnt = getgssd_handle()) == NULL) { 1298 0 stevel GSSLOG(1, 1299 0 stevel "kgss_delete_sec_context: can't connect to server on %s\n", 1300 0 stevel server); 1301 0 stevel return (GSS_S_FAILURE); 1302 0 stevel } 1303 0 stevel 1304 0 stevel /* copy the procedure arguments into the rpc arg parameter */ 1305 0 stevel 1306 0 stevel arg.context_handle.GSS_CTX_ID_T_len = 1307 0 stevel *context_handle == (gssd_ctx_id_t)GSS_C_NO_CONTEXT ? 1308 0 stevel 0 : (uint_t)sizeof (gssd_ctx_id_t); 1309 0 stevel arg.context_handle.GSS_CTX_ID_T_val = (char *)context_handle; 1310 0 stevel 1311 0 stevel arg.gssd_context_verifier = gssd_context_verifier; 1312 0 stevel 1313 0 stevel /* call the remote procedure */ 1314 0 stevel 1315 0 stevel bzero((caddr_t)&res, sizeof (res)); 1316 0 stevel if (gss_delete_sec_context_1(&arg, &res, clnt) != RPC_SUCCESS) { 1317 0 stevel 1318 0 stevel /* 1319 0 stevel * if the RPC call times out, null out all return arguments, set 1320 0 stevel * minor_status to its maximum value, and return GSS_S_FAILURE 1321 0 stevel */ 1322 0 stevel 1323 0 stevel if (minor_status != NULL) 1324 0 stevel *minor_status = DEFAULT_MINOR_STAT; 1325 0 stevel if (context_handle != NULL) 1326 0 stevel *context_handle = NULL; 1327 0 stevel if (output_token != NULL) 1328 0 stevel output_token->length = 0; 1329 0 stevel 1330 0 stevel killgssd_handle(clnt); 1331 0 stevel GSSLOG0(1, "kgssd_delete_sec_context: RPC call times out\n"); 1332 0 stevel return (GSS_S_FAILURE); 1333 0 stevel } 1334 0 stevel 1335 0 stevel /* copy the rpc results into the return arguments */ 1336 0 stevel 1337 0 stevel if (minor_status != NULL) 1338 0 stevel *minor_status = res.minor_status; 1339 0 stevel 1340 0 stevel if (res.context_handle.GSS_CTX_ID_T_len == 0) 1341 0 stevel *context_handle = NULL; 1342 0 stevel else 1343 0 stevel *context_handle = 1344 0 stevel *((gssd_ctx_id_t *)res.context_handle.GSS_CTX_ID_T_val); 1345 0 stevel 1346 0 stevel if (output_token != NULL) { 1347 0 stevel output_token->length = res.output_token.GSS_BUFFER_T_len; 1348 0 stevel output_token->value = res.output_token.GSS_BUFFER_T_val; 1349 0 stevel res.output_token.GSS_BUFFER_T_len = 0; 1350 0 stevel res.output_token.GSS_BUFFER_T_val = NULL; 1351 0 stevel } 1352 0 stevel 1353 0 stevel /* 1354 0 stevel * free the memory allocated for the results and return with the status 1355 0 stevel * received in the rpc call 1356 0 stevel */ 1357 0 stevel 1358 0 stevel clnt_freeres(clnt, xdr_gss_delete_sec_context_res, (caddr_t)&res); 1359 0 stevel killgssd_handle(clnt); 1360 0 stevel return (res.status); 1361 0 stevel 1362 0 stevel } 1363 0 stevel 1364 0 stevel OM_uint32 1365 0 stevel kgss_delete_sec_context( 1366 0 stevel OM_uint32 *minor_status, 1367 0 stevel gss_ctx_id_t *context_handle, 1368 0 stevel gss_buffer_t output_token) 1369 0 stevel { 1370 0 stevel OM_uint32 err; 1371 0 stevel struct kgss_ctx *kctx; 1372 0 stevel 1373 0 stevel if (*context_handle == GSS_C_NO_CONTEXT) { 1374 0 stevel GSSLOG0(8, "kgss_delete_sec_context: Null context handle \n"); 1375 0 stevel return (GSS_S_COMPLETE); 1376 0 stevel } else 1377 0 stevel kctx = (struct kgss_ctx *)*context_handle; 1378 0 stevel 1379 0 stevel if (kctx->ctx_imported == FALSE) { 1380 0 stevel if (kctx->gssd_ctx == (gssd_ctx_id_t)GSS_C_NO_CONTEXT) { 1381 0 stevel KGSS_FREE(kctx); 1382 0 stevel *context_handle = GSS_C_NO_CONTEXT; 1383 0 stevel return (GSS_S_COMPLETE); 1384 0 stevel } 1385 0 stevel err = kgss_delete_sec_context_wrapped( 1386 0 stevel KCTX_TO_PRIVATE(*context_handle), 1387 0 stevel minor_status, 1388 0 stevel &kctx->gssd_ctx, 1389 0 stevel output_token, 1390 0 stevel kctx->gssd_ctx_verifier); 1391 0 stevel } else { 1392 0 stevel if (kctx->gssd_i_ctx == (gss_ctx_id_t)GSS_C_NO_CONTEXT) { 1393 0 stevel KGSS_FREE(kctx); 1394 0 stevel *context_handle = GSS_C_NO_CONTEXT; 1395 0 stevel return (GSS_S_COMPLETE); 1396 0 stevel } 1397 0 stevel err = KGSS_DELETE_SEC_CONTEXT(minor_status, kctx, 1398 0 stevel &kctx->gssd_i_ctx, output_token); 1399 0 stevel } 1400 0 stevel KGSS_FREE(kctx); 1401 0 stevel *context_handle = GSS_C_NO_CONTEXT; 1402 0 stevel return (err); 1403 0 stevel 1404 0 stevel } 1405 0 stevel 1406 0 stevel 1407 0 stevel OM_uint32 1408 0 stevel kgss_export_sec_context_wrapped(minor_status, 1409 0 stevel context_handle, 1410 0 stevel output_token, 1411 0 stevel gssd_context_verifier) 1412 0 stevel OM_uint32 *minor_status; 1413 0 stevel gssd_ctx_id_t *context_handle; 1414 0 stevel gss_buffer_t output_token; 1415 0 stevel OM_uint32 gssd_context_verifier; 1416 0 stevel { 1417 0 stevel CLIENT *clnt; 1418 0 stevel gss_export_sec_context_arg arg; 1419 0 stevel gss_export_sec_context_res res; 1420 0 stevel 1421 0 stevel 1422 0 stevel /* get the client handle to GSSD */ 1423 0 stevel 1424 0 stevel if ((clnt = getgssd_handle()) == NULL) { 1425 0 stevel GSSLOG(1, "kgss_export_sec_context_wrapped :" 1426 0 stevel " can't connect to server on %s\n", server); 1427 0 stevel return (GSS_S_FAILURE); 1428 0 stevel } 1429 0 stevel 1430 0 stevel /* copy the procedure arguments into the rpc arg parameter */ 1431 0 stevel 1432 0 stevel arg.context_handle.GSS_CTX_ID_T_len = (uint_t)sizeof (gssd_ctx_id_t); 1433 0 stevel arg.context_handle.GSS_CTX_ID_T_val = (char *)context_handle; 1434 0 stevel arg.gssd_context_verifier = gssd_context_verifier; 1435 0 stevel 1436 0 stevel /* call the remote procedure */ 1437 0 stevel 1438 0 stevel (void) memset(&res, 0, sizeof (res)); 1439 0 stevel if (gss_export_sec_context_1(&arg, &res, clnt) != RPC_SUCCESS) { 1440 0 stevel 1441 0 stevel /* 1442 0 stevel * if the RPC call times out, null out all return arguments, 1443 0 stevel * set minor_status to its maximum value, and return 1444 0 stevel * GSS_S_FAILURE 1445 0 stevel */ 1446 0 stevel 1447 0 stevel if (minor_status != NULL) 1448 0 stevel *minor_status = DEFAULT_MINOR_STAT; 1449 0 stevel if (context_handle != NULL) 1450 0 stevel *context_handle = NULL; 1451 0 stevel if (output_token != NULL) 1452 0 stevel output_token->length = 0; 1453 0 stevel killgssd_handle(clnt); 1454 0 stevel GSSLOG0(1, 1455 0 stevel "kgss_export_sec_context_wrapped: RPC call times out\n"); 1456 0 stevel return (GSS_S_FAILURE); 1457 0 stevel } 1458 0 stevel 1459 0 stevel /* copy the rpc results into the return arguments */ 1460 0 stevel 1461 0 stevel if (minor_status != NULL) 1462 0 stevel *minor_status = res.minor_status; 1463 0 stevel 1464 0 stevel if (res.context_handle.GSS_CTX_ID_T_len == 0) 1465 0 stevel *context_handle = NULL; 1466 0 stevel else 1467 0 stevel *context_handle = 1468 0 stevel *((gssd_ctx_id_t *)res.context_handle.GSS_CTX_ID_T_val); 1469 0 stevel 1470 0 stevel if (output_token != NULL) { 1471 0 stevel output_token->length = res.output_token.GSS_BUFFER_T_len; 1472 0 stevel output_token->value = 1473 0 stevel (void *) MALLOC(output_token->length); 1474 0 stevel (void) memcpy(output_token->value, 1475 0 stevel res.output_token.GSS_BUFFER_T_val, 1476 0 stevel output_token->length); 1477 0 stevel } 1478 0 stevel 1479 0 stevel /* 1480 0 stevel * free the memory allocated for the results and return with the status 1481 0 stevel * received in the rpc call 1482 0 stevel */ 1483 0 stevel 1484 0 stevel clnt_freeres(clnt, xdr_gss_export_sec_context_res, (caddr_t)&res); 1485 0 stevel killgssd_handle(clnt); 1486 0 stevel return (res.status); 1487 0 stevel 1488 0 stevel } 1489 0 stevel 1490 0 stevel OM_uint32 1491 0 stevel kgss_export_sec_context(minor_status, 1492 0 stevel context_handle, 1493 0 stevel output_token) 1494 0 stevel OM_uint32 *minor_status; 1495 0 stevel gss_ctx_id_t context_handle; 1496 0 stevel gss_buffer_t output_token; 1497 0 stevel { 1498 0 stevel struct kgss_ctx *kctx; 1499 0 stevel 1500 0 stevel if (context_handle == GSS_C_NO_CONTEXT) 1501 0 stevel return (GSS_S_FAILURE); 1502 0 stevel else 1503 0 stevel kctx = (struct kgss_ctx *)context_handle; 1504 0 stevel 1505 0 stevel 1506 0 stevel 1507 0 stevel /* 1508 0 stevel * If there is a kernel module then import_sec context must be 1509 0 stevel * supported and we make an upcall to export_sec_context. 1510 0 stevel * If there is no kernel module then we return an error 1511 0 stevel */ 1512 0 stevel 1513 0 stevel *minor_status = 0; 1514 0 stevel 1515 0 stevel if (kctx->mech->gss_import_sec_context) { 1516 0 stevel GSSLOG0(8, "kgss_export_sec_context: Kernel mod available \n"); 1517 0 stevel return (kgss_export_sec_context_wrapped(minor_status, 1518 0 stevel &kctx->gssd_ctx, 1519 0 stevel output_token, 1520 0 stevel kctx->gssd_ctx_verifier)); 1521 0 stevel 1522 0 stevel } else { 1523 0 stevel 1524 0 stevel /* 1525 0 stevel * This is not the right error value; instead of 1526 0 stevel * inventing new error we return GSS_S_NAME_NOT_MN 1527 0 stevel * This error is not returned by the export routine 1528 0 stevel */ 1529 0 stevel 1530 0 stevel GSSLOG0(8, "kgss_export_sec_context: Kernel mod " 1531 0 stevel "unavailable \n"); 1532 0 stevel return (GSS_S_NAME_NOT_MN); 1533 0 stevel } 1534 0 stevel 1535 0 stevel } 1536 0 stevel 1537 0 stevel OM_uint32 1538 0 stevel kgss_import_sec_context(minor_status, 1539 0 stevel interprocess_token, 1540 0 stevel context_handle) 1541 0 stevel 1542 0 stevel OM_uint32 * minor_status; 1543 0 stevel const gss_buffer_t interprocess_token; 1544 0 stevel gss_ctx_id_t context_handle; 1545 0 stevel 1546 0 stevel { 1547 0 stevel OM_uint32 status; 1548 0 stevel struct kgss_ctx *kctx; 1549 0 stevel 1550 0 stevel size_t length; 1551 0 stevel char *p; 1552 0 stevel gss_buffer_desc token; 1553 0 stevel gss_ctx_id_t internal_ctx_id; 1554 0 stevel kctx = (struct kgss_ctx *)context_handle; 1555 0 stevel 1556 0 stevel if (kctx->gssd_ctx != (gssd_ctx_id_t)GSS_C_NO_CONTEXT) { 1557 0 stevel return (GSS_S_FAILURE); 1558 0 stevel } 1559 0 stevel 1560 0 stevel if (!(KCTX_TO_MECH(context_handle)->gss_import_sec_context)) { 1561 0 stevel 1562 0 stevel /* 1563 0 stevel * This should never happen 1564 0 stevel * If Kernel import sec context does not exist the export 1565 0 stevel * sec context should have caught this and returned an error 1566 0 stevel * and the caller should not have called this routine 1567 0 stevel */ 1568 0 stevel GSSLOG0(1, "import_sec_context called improperly\n"); 1569 0 stevel return (GSS_S_FAILURE); 1570 0 stevel } 1571 0 stevel *minor_status = 0; 1572 0 stevel 1573 0 stevel if (interprocess_token->length == 0 || interprocess_token->value == 0) 1574 0 stevel return (GSS_S_DEFECTIVE_TOKEN); 1575 0 stevel 1576 0 stevel status = GSS_S_FAILURE; 1577 0 stevel 1578 0 stevel p = interprocess_token->value; 1579 0 stevel length = *p++; 1580 0 stevel length = (length << 8) + *p++; 1581 0 stevel length = (length << 8) + *p++; 1582 0 stevel length = (length << 8) + *p++; 1583 0 stevel 1584 0 stevel p += length; 1585 0 stevel 1586 0 stevel token.length = interprocess_token->length - 4 - length; 1587 0 stevel token.value = p; 1588 0 stevel 1589 0 stevel /* 1590 0 stevel * select the approprate underlying mechanism routine and 1591 0 stevel * call it. 1592 0 stevel */ 1593 0 stevel 1594 0 stevel status = KGSS_IMPORT_SEC_CONTEXT(minor_status, &token, kctx, 1595 0 stevel &internal_ctx_id); 1596 0 stevel 1597 0 stevel if (status == GSS_S_COMPLETE) { 1598 0 stevel KCTX_TO_I_CTX(kctx) = internal_ctx_id; 1599 0 stevel kctx->ctx_imported = TRUE; 1600 0 stevel return (GSS_S_COMPLETE); 1601 0 stevel } else 1602 0 stevel return (status); 1603 0 stevel } 1604 0 stevel 1605 0 stevel /*ARGSUSED*/ 1606 0 stevel OM_uint32 1607 0 stevel kgss_context_time(minor_status, 1608 0 stevel context_handle, 1609 0 stevel time_rec, 1610 0 stevel uid) 1611 0 stevel OM_uint32 *minor_status; 1612 0 stevel const gss_ctx_id_t context_handle; 1613 0 stevel OM_uint32 *time_rec; 1614 0 stevel uid_t uid; 1615 0 stevel { 1616 0 stevel return (GSS_S_FAILURE); 1617 0 stevel } 1618 0 stevel 1619 0 stevel /*ARGSUSED*/ 1620 0 stevel static OM_uint32 1621 0 stevel kgss_sign_wrapped(void *private, 1622 0 stevel OM_uint32 *minor_status, 1623 0 stevel const gss_ctx_id_t ctx_handle, 1624 0 stevel int qop_req, 1625 0 stevel const gss_buffer_t message_buffer, 1626 0 stevel gss_buffer_t msg_token, 1627 0 stevel OM_uint32 gssd_context_verifier) 1628 0 stevel { 1629 0 stevel CLIENT *clnt; 1630 0 stevel gssd_ctx_id_t context_handle; 1631 0 stevel 1632 0 stevel gss_sign_arg arg; 1633 0 stevel gss_sign_res res; 1634 0 stevel context_handle = (gssd_ctx_id_t)KCTX_TO_GSSD_CTX(ctx_handle); 1635 0 stevel /* get the client handle to GSSD */ 1636 0 stevel 1637 0 stevel if ((clnt = getgssd_handle()) == NULL) { 1638 0 stevel GSSLOG(1, "kgss_sign: can't connect to server on %s\n", server); 1639 0 stevel return (GSS_S_FAILURE); 1640 0 stevel } 1641 0 stevel 1642 0 stevel /* copy the procedure arguments into the rpc arg parameter */ 1643 0 stevel 1644 0 stevel arg.context_handle.GSS_CTX_ID_T_len = (uint_t)sizeof (gssd_ctx_id_t); 1645 0 stevel arg.context_handle.GSS_CTX_ID_T_val = (char *)&context_handle; 1646 0 stevel 1647 0 stevel arg.context_handle.GSS_CTX_ID_T_len = (uint_t)sizeof (gssd_ctx_id_t); 1648 0 stevel arg.context_handle.GSS_CTX_ID_T_val = (char *)&context_handle; 1649 0 stevel arg.gssd_context_verifier = gssd_context_verifier; 1650 0 stevel 1651 0 stevel arg.qop_req = qop_req; 1652 0 stevel 1653 0 stevel arg.message_buffer.GSS_BUFFER_T_len = (uint_t)message_buffer->length; 1654 0 stevel arg.message_buffer.GSS_BUFFER_T_val = (char *)message_buffer->value; 1655 0 stevel 1656 0 stevel /* call the remote procedure */ 1657 0 stevel 1658 0 stevel bzero((caddr_t)&res, sizeof (res)); 1659 0 stevel if (gss_sign_1(&arg, &res, clnt) != RPC_SUCCESS) { 1660 0 stevel 1661 0 stevel /* 1662 0 stevel * if the RPC call times out, null out all return arguments, set 1663 0 stevel * minor_status to its maximum value, and return GSS_S_FAILURE 1664 0 stevel */ 1665 0 stevel 1666 0 stevel if (minor_status != NULL) 1667 0 stevel *minor_status = DEFAULT_MINOR_STAT; 1668 0 stevel if (msg_token != NULL) 1669 0 stevel msg_token->length = 0; 1670 0 stevel 1671 0 stevel killgssd_handle(clnt); 1672 0 stevel GSSLOG0(1, "kgss_sign: RPC call times out\n"); 1673 0 stevel return (GSS_S_FAILURE); 1674 0 stevel } 1675 0 stevel 1676 0 stevel /* copy the rpc results into the return arguments */ 1677 0 stevel 1678 0 stevel if (minor_status != NULL) 1679 0 stevel *minor_status = res.minor_status; 1680 0 stevel 1681 0 stevel if (msg_token != NULL) { 1682 0 stevel msg_token->length = res.msg_token.GSS_BUFFER_T_len; 1683 0 stevel msg_token->value = (void *) MALLOC(msg_token->length); 1684 0 stevel (void) memcpy(msg_token->value, res.msg_token.GSS_BUFFER_T_val, 1685 0 stevel msg_token->length); 1686 0 stevel } 1687 0 stevel 1688 0 stevel /* 1689 0 stevel * free the memory allocated for the results and return with the status 1690 0 stevel * received in the rpc call 1691 0 stevel */ 1692 0 stevel 1693 0 stevel clnt_freeres(clnt, xdr_gss_sign_res, (caddr_t)&res); 1694 0 stevel killgssd_handle(clnt); 1695 0 stevel return (res.status); 1696 0 stevel 1697 0 stevel } 1698 0 stevel 1699 0 stevel OM_uint32 1700 0 stevel kgss_sign( 1701 0 stevel OM_uint32 *minor_status, 1702 0 stevel const gss_ctx_id_t context_handle, 1703 0 stevel int qop_req, 1704 0 stevel const gss_buffer_t message_buffer, 1705 0 stevel gss_buffer_t msg_token) 1706 0 stevel { 1707 0 stevel if (context_handle == GSS_C_NO_CONTEXT) 1708 0 stevel return (GSS_S_FAILURE); 1709 0 stevel return (KGSS_SIGN(minor_status, context_handle, qop_req, 1710 0 stevel message_buffer, msg_token)); 1711 0 stevel } 1712 0 stevel 1713 0 stevel /*ARGSUSED*/ 1714 0 stevel static OM_uint32 1715 0 stevel kgss_verify_wrapped(void *private, 1716 0 stevel OM_uint32 *minor_status, 1717 0 stevel const gss_ctx_id_t ctx_handle, 1718 0 stevel const gss_buffer_t message_buffer, 1719 0 stevel const gss_buffer_t token_buffer, 1720 0 stevel int *qop_state, 1721 0 stevel OM_uint32 gssd_context_verifier) 1722 0 stevel { 1723 0 stevel CLIENT *clnt; 1724 0 stevel 1725 0 stevel gssd_ctx_id_t context_handle; 1726 0 stevel gss_verify_arg arg; 1727 0 stevel gss_verify_res res; 1728 0 stevel 1729 0 stevel context_handle = (gssd_ctx_id_t)KCTX_TO_GSSD_CTX(ctx_handle); 1730 0 stevel 1731 0 stevel /* get the client handle to GSSD */ 1732 0 stevel 1733 0 stevel if ((clnt = getgssd_handle()) == NULL) { 1734 0 stevel GSSLOG(1, "kgss_verify: can't connect to server on %s\n", 1735 0 stevel server); 1736 0 stevel return (GSS_S_FAILURE); 1737 0 stevel } 1738 0 stevel 1739 0 stevel /* copy the procedure arguments into the rpc arg parameter */ 1740 0 stevel 1741 0 stevel arg.context_handle.GSS_CTX_ID_T_len = (uint_t)sizeof (gss_ctx_id_t); 1742 0 stevel arg.context_handle.GSS_CTX_ID_T_val = (char *)&context_handle; 1743 0 stevel 1744 0 stevel arg.context_handle.GSS_CTX_ID_T_len = (uint_t)sizeof (gssd_ctx_id_t); 1745 0 stevel arg.context_handle.GSS_CTX_ID_T_val = (char *)&context_handle; 1746 0 stevel arg.gssd_context_verifier = gssd_context_verifier; 1747 0 stevel 1748 0 stevel arg.message_buffer.GSS_BUFFER_T_len = (uint_t)message_buffer->length; 1749 0 stevel arg.message_buffer.GSS_BUFFER_T_val = (char *)message_buffer->value; 1750 0 stevel 1751 0 stevel arg.token_buffer.GSS_BUFFER_T_len = (uint_t)token_buffer->length; 1752 0 stevel arg.token_buffer.GSS_BUFFER_T_val = (char *)token_buffer->value; 1753 0 stevel 1754 0 stevel /* call the remote procedure */ 1755 0 stevel 1756 0 stevel bzero((caddr_t)&res, sizeof (res)); 1757 0 stevel if (gss_verify_1(&arg, &res, clnt) != RPC_SUCCESS) { 1758 0 stevel 1759 0 stevel /* 1760 0 stevel * if the RPC call times out, null out all return arguments, set 1761 0 stevel * minor_status to its maximum value, and return GSS_S_FAILURE 1762 0 stevel */ 1763 0 stevel 1764 0 stevel if (minor_status != NULL) 1765 0 stevel *minor_status = DEFAULT_MINOR_STAT; 1766 0 stevel if (qop_state != NULL) 1767 0 stevel *qop_state = 0; 1768 0 stevel 1769 0 stevel killgssd_handle(clnt); 1770 0 stevel GSSLOG0(1, "kgss_verify: RPC call times out\n"); 1771 0 stevel return (GSS_S_FAILURE); 1772 0 stevel } 1773 0 stevel 1774 0 stevel /* copy the rpc results into the return arguments */ 1775 0 stevel 1776 0 stevel if (minor_status != NULL) 1777 0 stevel *minor_status = res.minor_status; 1778 0 stevel 1779 0 stevel if (qop_state != NULL) 1780 0 stevel *qop_state = res.qop_state; 1781 0 stevel 1782 0 stevel /* return with status returned in rpc call */ 1783 0 stevel 1784 0 stevel killgssd_handle(clnt); 1785 0 stevel return (res.status); 1786 0 stevel 1787 0 stevel } 1788 0 stevel 1789 0 stevel OM_uint32 1790 0 stevel kgss_verify(OM_uint32 *minor_status, 1791 0 stevel const gss_ctx_id_t context_handle, 1792 0 stevel const gss_buffer_t message_buffer, 1793 0 stevel const gss_buffer_t token_buffer, 1794 0 stevel int *qop_state) 1795 0 stevel { 1796 0 stevel if (context_handle == GSS_C_NO_CONTEXT) 1797 0 stevel return (GSS_S_FAILURE); 1798 0 stevel return (KGSS_VERIFY(minor_status, context_handle, 1799 0 stevel message_buffer, 1800 0 stevel token_buffer, 1801 0 stevel qop_state)); 1802 0 stevel } 1803 0 stevel 1804 0 stevel /* EXPORT DELETE START */ 1805 0 stevel 1806 0 stevel /*ARGSUSED*/ 1807 0 stevel static OM_uint32 1808 0 stevel kgss_seal_wrapped(void *private, 1809 0 stevel OM_uint32 *minor_status, 1810 0 stevel const gss_ctx_id_t ctx_handle, 1811 0 stevel int conf_req_flag, 1812 0 stevel int qop_req, 1813 0 stevel const gss_buffer_t input_message_buffer, 1814 0 stevel int *conf_state, 1815 0 stevel gss_buffer_t output_message_buffer, 1816 0 stevel OM_uint32 gssd_context_verifier) 1817 0 stevel { 1818 0 stevel CLIENT *clnt; 1819 0 stevel gssd_ctx_id_t context_handle; 1820 0 stevel 1821 0 stevel gss_seal_arg arg; 1822 0 stevel gss_seal_res res; 1823 0 stevel 1824 0 stevel context_handle = (gssd_ctx_id_t)KCTX_TO_GSSD_CTX(ctx_handle); 1825 0 stevel 1826 0 stevel /* get the client handle to GSSD */ 1827 0 stevel 1828 0 stevel if ((clnt = getgssd_handle()) == NULL) { 1829 0 stevel GSSLOG(1, "kgss_seal: can't connect to server on %s\n", server); 1830 0 stevel return (GSS_S_FAILURE); 1831 0 stevel } 1832 0 stevel 1833 0 stevel /* copy the procedure arguments into the rpc arg parameter */ 1834 0 stevel 1835 0 stevel arg.context_handle.GSS_CTX_ID_T_len = (uint_t)sizeof (gss_ctx_id_t); 1836 0 stevel arg.context_handle.GSS_CTX_ID_T_val = (char *)&context_handle; 1837 0 stevel 1838 0 stevel arg.context_handle.GSS_CTX_ID_T_len = (uint_t)sizeof (OM_uint32); 1839 0 stevel arg.context_handle.GSS_CTX_ID_T_val = (char *)&context_handle; 1840 0 stevel arg.gssd_context_verifier = gssd_context_verifier; 1841 0 stevel 1842 0 stevel arg.conf_req_flag = conf_req_flag; 1843 0 stevel 1844 0 stevel arg.qop_req = qop_req; 1845 0 stevel 1846 0 stevel arg.input_message_buffer.GSS_BUFFER_T_len = 1847 0 stevel (uint_t)input_message_buffer->length; 1848 0 stevel 1849 0 stevel arg.input_message_buffer.GSS_BUFFER_T_val = 1850 0 stevel (char *)input_message_buffer->value; 1851 0 stevel 1852 0 stevel /* call the remote procedure */ 1853 0 stevel 1854 0 stevel bzero((caddr_t)&res, sizeof (res)); 1855 0 stevel if (gss_seal_1(&arg, &res, clnt) != RPC_SUCCESS) { 1856 0 stevel 1857 0 stevel /* 1858 0 stevel * if the RPC call times out, null out all return arguments, set 1859 0 stevel * minor_status to its maximum value, and return GSS_S_FAILURE 1860 0 stevel */ 1861 0 stevel 1862 0 stevel if (minor_status != NULL) 1863 0 stevel *minor_status = DEFAULT_MINOR_STAT; 1864 0 stevel if (conf_state != NULL) 1865 0 stevel *conf_state = 0; 1866 0 stevel if (output_message_buffer != NULL) 1867 0 stevel output_message_buffer->length = 0; 1868 0 stevel 1869 0 stevel killgssd_handle(clnt); 1870 0 stevel GSSLOG0(1, "kgss_seal: RPC call times out\n"); 1871 0 stevel return (GSS_S_FAILURE); 1872 0 stevel } 1873 0 stevel 1874 0 stevel /* copy the rpc results into the return arguments */ 1875 0 stevel 1876 0 stevel if (minor_status != NULL) 1877 0 stevel *minor_status = res.minor_status; 1878 0 stevel 1879 0 stevel if (conf_state != NULL) 1880 0 stevel *conf_state = res.conf_state; 1881 0 stevel 1882 0 stevel if (output_message_buffer != NULL) { 1883 0 stevel output_message_buffer->length = 1884 0 stevel res.output_message_buffer.GSS_BUFFER_T_len; 1885 0 stevel 1886 0 stevel output_message_buffer->value = 1887 0 stevel (void *) MALLOC(output_message_buffer->length); 1888 0 stevel (void) memcpy(output_message_buffer->value, 1889 0 stevel res.output_message_buffer.GSS_BUFFER_T_val, 1890 0 stevel output_message_buffer->length); 1891 0 stevel } 1892 0 stevel 1893 0 stevel /* 1894 0 stevel * free the memory allocated for the results and return with the status 1895 0 stevel * received in the rpc call 1896 0 stevel */ 1897 0 stevel 1898 0 stevel clnt_freeres(clnt, xdr_gss_seal_res, (caddr_t)&res); 1899 0 stevel killgssd_handle(clnt); 1900 0 stevel return (res.status); 1901 0 stevel } 1902 0 stevel 1903 0 stevel /*ARGSUSED*/ 1904 0 stevel OM_uint32 1905 0 stevel kgss_seal(OM_uint32 *minor_status, 1906 0 stevel const gss_ctx_id_t context_handle, 1907 0 stevel int conf_req_flag, 1908 0 stevel int qop_req, 1909 0 stevel const gss_buffer_t input_message_buffer, 1910 0 stevel int *conf_state, 1911 0 stevel gss_buffer_t output_message_buffer) 1912 0 stevel 1913 0 stevel { 1914 0 stevel if (context_handle == GSS_C_NO_CONTEXT) 1915 0 stevel return (GSS_S_FAILURE); 1916 0 stevel return (KGSS_SEAL(minor_status, context_handle, 1917 0 stevel conf_req_flag, qop_req, 1918 0 stevel input_message_buffer, conf_state, 1919 0 stevel output_message_buffer)); 1920 0 stevel } 1921 0 stevel 1922 0 stevel /*ARGSUSED*/ 1923 0 stevel static OM_uint32 1924 0 stevel kgss_unseal_wrapped(void *private, 1925 0 stevel OM_uint32 *minor_status, 1926 0 stevel const gss_ctx_id_t ctx_handle, 1927 0 stevel const gss_buffer_t input_message_buffer, 1928 0 stevel gss_buffer_t output_message_buffer, 1929 0 stevel int *conf_state, 1930 0 stevel int *qop_state, 1931 0 stevel OM_uint32 gssd_context_verifier) 1932 0 stevel { 1933 0 stevel CLIENT *clnt; 1934 0 stevel 1935 0 stevel gss_unseal_arg arg; 1936 0 stevel gss_unseal_res res; 1937 0 stevel gssd_ctx_id_t context_handle; 1938 0 stevel 1939 0 stevel context_handle = (gssd_ctx_id_t)KCTX_TO_GSSD_CTX(ctx_handle); 1940 0 stevel 1941 0 stevel /* get the client handle to GSSD */ 1942 0 stevel 1943 0 stevel if ((clnt = getgssd_handle()) == NULL) { 1944 0 stevel GSSLOG(1, "kgss_unseal: can't connect to server on %s\n", 1945 0 stevel server); 1946 0 stevel return (GSS_S_FAILURE); 1947 0 stevel } 1948 0 stevel 1949 0 stevel /* copy the procedure arguments into the rpc arg parameter */ 1950 0 stevel 1951 0 stevel arg.context_handle.GSS_CTX_ID_T_len = (uint_t)sizeof (gss_ctx_id_t); 1952 0 stevel arg.context_handle.GSS_CTX_ID_T_val = (char *)&context_handle; 1953 0 stevel 1954 0 stevel arg.context_handle.GSS_CTX_ID_T_len = (uint_t)sizeof (gssd_ctx_id_t); 1955 0 stevel arg.context_handle.GSS_CTX_ID_T_val = (char *)&context_handle; 1956 0 stevel arg.gssd_context_verifier = gssd_context_verifier; 1957 0 stevel 1958 0 stevel arg.input_message_buffer.GSS_BUFFER_T_len = 1959 0 stevel (uint_t)input_message_buffer->length; 1960 0 stevel 1961 0 stevel arg.input_message_buffer.GSS_BUFFER_T_val = 1962 0 stevel (char *)input_message_buffer->value; 1963 0 stevel 1964 0 stevel /* call the remote procedure */ 1965 0 stevel 1966 0 stevel bzero((caddr_t)&res, sizeof (res)); 1967 0 stevel if (gss_unseal_1(&arg, &res, clnt) != RPC_SUCCESS) { 1968 0 stevel 1969 0 stevel /* 1970 0 stevel * if the RPC call times out, null out all return arguments, set 1971 0 stevel * minor_status to its maximum value, and return GSS_S_FAILURE 1972 0 stevel */ 1973 0 stevel 1974 0 stevel if (minor_status != NULL) 1975 0 stevel *minor_status = DEFAULT_MINOR_STAT; 1976 0 stevel if (output_message_buffer != NULL) 1977 0 stevel output_message_buffer->length = 0; 1978 0 stevel if (conf_state != NULL) 1979 0 stevel *conf_state = 0; 1980 0 stevel if (qop_state != NULL) 1981 0 stevel *qop_state = 0; 1982 0 stevel 1983 0 stevel killgssd_handle(clnt); 1984 0 stevel GSSLOG0(1, "kgss_unseal: RPC call times out\n"); 1985 0 stevel return (GSS_S_FAILURE); 1986 0 stevel } 1987 0 stevel 1988 0 stevel /* copy the rpc results into the return arguments */ 1989 0 stevel 1990 0 stevel if (minor_status != NULL) 1991 0 stevel *minor_status = res.minor_status; 1992 0 stevel 1993 0 stevel if (output_message_buffer != NULL) { 1994 0 stevel output_message_buffer->length = 1995 0 stevel res.output_message_buffer.GSS_BUFFER_T_len; 1996 0 stevel 1997 0 stevel output_message_buffer->value = 1998 0 stevel (void *) MALLOC(output_message_buffer->length); 1999 0 stevel (void) memcpy(output_message_buffer->value, 2000 0 stevel res.output_message_buffer.GSS_BUFFER_T_val, 2001 0 stevel output_message_buffer->length); 2002 0 stevel } 2003 0 stevel 2004 0 stevel if (conf_state != NULL) 2005 0 stevel *conf_state = res.conf_state; 2006 0 stevel 2007 0 stevel if (qop_state != NULL) 2008 0 stevel *qop_state = res.qop_state; 2009 0 stevel 2010 0 stevel /* 2011 0 stevel * free the memory allocated for the results and return with the 2012 0 stevel * status received in the rpc call 2013 0 stevel */ 2014 0 stevel 2015 0 stevel clnt_freeres(clnt, xdr_gss_unseal_res, (caddr_t)&res); 2016 0 stevel killgssd_handle(clnt); 2017 0 stevel return (res.status); 2018 0 stevel } 2019 0 stevel 2020 0 stevel OM_uint32 2021 0 stevel kgss_unseal(OM_uint32 *minor_status, 2022 0 stevel const gss_ctx_id_t context_handle, 2023 0 stevel const gss_buffer_t input_message_buffer, 2024 0 stevel const gss_buffer_t output_message_buffer, 2025 0 stevel int *conf_state, 2026 0 stevel int *qop_state) 2027 0 stevel { 2028 0 stevel 2029 0 stevel if (context_handle == GSS_C_NO_CONTEXT) 2030 0 stevel return (GSS_S_FAILURE); 2031 0 stevel 2032 0 stevel return (KGSS_UNSEAL(minor_status, context_handle, input_message_buffer, 2033 0 stevel output_message_buffer, conf_state, qop_state)); 2034 0 stevel } 2035 0 stevel 2036 0 stevel /* EXPORT DELETE END */ 2037 0 stevel 2038 0 stevel OM_uint32 2039 0 stevel kgss_display_status(minor_status, 2040 0 stevel status_value, 2041 0 stevel status_type, 2042 0 stevel mech_type, 2043 0 stevel message_context, 2044 0 stevel status_string, 2045 0 stevel uid) 2046 0 stevel OM_uint32 *minor_status; 2047 0 stevel OM_uint32 status_value; 2048 0 stevel int status_type; 2049 0 stevel const gss_OID mech_type; 2050 0 stevel int *message_context; 2051 0 stevel gss_buffer_t status_string; 2052 0 stevel uid_t uid; 2053 0 stevel { 2054 0 stevel CLIENT *clnt; 2055 0 stevel 2056 0 stevel gss_display_status_arg arg; 2057 0 stevel gss_display_status_res res; 2058 0 stevel 2059 0 stevel /* get the client handle to GSSD */ 2060 0 stevel 2061 0 stevel if ((clnt = getgssd_handle()) == NULL) { 2062 0 stevel GSSLOG(1, "kgss_display_status: can't connect to server on %s\n", 2063 0 stevel server); 2064 0 stevel return (GSS_S_FAILURE); 2065 0 stevel } 2066 0 stevel 2067 0 stevel /* copy the procedure arguments into the rpc arg parameter */ 2068 0 stevel 2069 0 stevel arg.uid = (OM_uint32) uid; 2070 0 stevel 2071 0 stevel arg.status_value = status_value; 2072 0 stevel arg.status_type = status_type; 2073 0 stevel 2074 0 stevel arg.mech_type.GSS_OID_len = (uint_t)(mech_type != GSS_C_NULL_OID ? 2075 0 stevel mech_type->length : 0); 2076 0 stevel arg.mech_type.GSS_OID_val = (char *)(mech_type != GSS_C_NULL_OID ? 2077 0 stevel mech_type->elements : 0); 2078 0 stevel 2079 0 stevel arg.message_context = *message_context; 2080 0 stevel 2081 0 stevel /* call the remote procedure */ 2082 0 stevel 2083 0 stevel if (message_context != NULL) 2084 0 stevel *message_context = 0; 2085 0 stevel if (status_string != NULL) { 2086 0 stevel status_string->length = 0; 2087 0 stevel status_string->value = NULL; 2088 0 stevel } 2089 0 stevel 2090 0 stevel bzero((caddr_t)&res, sizeof (res)); 2091 0 stevel if (gss_display_status_1(&arg, &res, clnt) != RPC_SUCCESS) { 2092 0 stevel 2093 0 stevel /* 2094 0 stevel * if the RPC call times out, null out all return arguments, set 2095 0 stevel * minor_status to its maximum value, and return GSS_S_FAILURE 2096 0 stevel */ 2097 0 stevel 2098 0 stevel if (minor_status != NULL) 2099 0 stevel *minor_status = DEFAULT_MINOR_STAT; 2100 0 stevel 2101 0 stevel killgssd_handle(clnt); 2102 0 stevel GSSLOG0(1, "kgss_display_status: RPC call time out\n"); 2103 0 stevel return (GSS_S_FAILURE); 2104 0 stevel } 2105 0 stevel 2106 0 stevel 2107 0 stevel /* now process the results and pass them back to the caller */ 2108 0 stevel 2109 0 stevel if (res.status == GSS_S_COMPLETE) { 2110 0 stevel if (minor_status != NULL) 2111 0 stevel *minor_status = res.minor_status; 2112 0 stevel if (message_context != NULL) 2113 0 stevel *message_context = res.message_context; 2114 0 stevel if (status_string != NULL) { 2115 0 stevel status_string->length = 2116 0 stevel (size_t)res.status_string.GSS_BUFFER_T_len; 2117 0 stevel status_string->value = 2118 0 stevel (void *) MALLOC(status_string->length); 2119 0 stevel (void) memcpy(status_string->value, 2120 0 stevel res.status_string.GSS_BUFFER_T_val, 2121 0 stevel status_string->length); 2122 0 stevel } 2123 0 stevel } 2124 0 stevel 2125 0 stevel clnt_freeres(clnt, xdr_gss_display_status_res, (caddr_t)&res); 2126 0 stevel killgssd_handle(clnt); 2127 0 stevel return (res.status); 2128 0 stevel } 2129 0 stevel 2130 0 stevel /*ARGSUSED*/ 2131 0 stevel OM_uint32 2132 0 stevel kgss_indicate_mechs(minor_status, 2133 0 stevel mech_set, 2134 0 stevel uid) 2135 0 stevel OM_uint32 *minor_status; 2136 0 stevel gss_OID_set *mech_set; 2137 0 stevel uid_t uid; 2138 0 stevel { 2139 0 stevel CLIENT *clnt; 2140 0 stevel void *arg; 2141 0 stevel gss_indicate_mechs_res res; 2142 0 stevel int i; 2143 0 stevel 2144 0 stevel /* get the client handle to GSSD */ 2145 0 stevel 2146 0 stevel if ((clnt = getgssd_handle()) == NULL) { 2147 0 stevel GSSLOG(1, "kgss_indicate_mechs: can't connect to server on %s\n", 2148 0 stevel server); 2149 0 stevel return (GSS_S_FAILURE); 2150 0 stevel } 2151 0 stevel 2152 0 stevel bzero((caddr_t)&res, sizeof (res)); 2153 0 stevel if (gss_indicate_mechs_1(&arg, &res, clnt) != RPC_SUCCESS) { 2154 0 stevel 2155 0 stevel /* 2156 0 stevel * if the RPC call times out, null out all return arguments, set 2157 0 stevel * minor_status to its maximum value, and return GSS_S_FAILURE 2158 0 stevel */ 2159 0 stevel 2160 0 stevel if (minor_status != NULL) 2161 0 stevel *minor_status = DEFAULT_MINOR_STAT; 2162 0 stevel if (mech_set != NULL) 2163 0 stevel *mech_set = NULL; 2164 0 stevel 2165 0 stevel killgssd_handle(clnt); 2166 0 stevel GSSLOG0(1, "kgss_indicate_mechs: RPC call times out\n"); 2167 0 stevel return (GSS_S_FAILURE); 2168 0 stevel } 2169 0 stevel 2170 0 stevel /* copy the rpc results into the return arguments */ 2171 0 stevel 2172 0 stevel if (minor_status != NULL) 2173 0 stevel *minor_status = res.minor_status; 2174 0 stevel 2175 0 stevel if (mech_set != NULL) { 2176 0 stevel *mech_set = (gss_OID_set) MALLOC(sizeof (gss_OID_set_desc)); 2177 0 stevel (*mech_set)->count = res.mech_set.GSS_OID_SET_len; 2178 0 stevel (*mech_set)->elements = (void *) 2179 0 stevel MALLOC ((*mech_set)->count * sizeof (gss_OID_desc)); 2180 0 stevel for (i = 0; i < (*mech_set)->count; i++) { 2181 0 stevel (*mech_set)->elements[i].length = 2182 0 stevel res.mech_set.GSS_OID_SET_val[i].GSS_OID_len; 2183 0 stevel (*mech_set)->elements[i].elements = (void *) 2184 0 stevel MALLOC ((*mech_set)->elements[i].length); 2185 0 stevel (void) memcpy((*mech_set)->elements[i].elements, 2186 0 stevel res.mech_set.GSS_OID_SET_val[i].GSS_OID_val, 2187 0 stevel (*mech_set)->elements[i].length); 2188 0 stevel } 2189 0 stevel } 2190 0 stevel 2191 0 stevel /* 2192 0 stevel * free the memory allocated for the results and return with the status 2193 0 stevel * received in the rpc call 2194 0 stevel */ 2195 0 stevel 2196 0 stevel clnt_freeres(clnt, xdr_gss_indicate_mechs_res, (caddr_t)&res); 2197 0 stevel killgssd_handle(clnt); 2198 0 stevel return (res.status); 2199 0 stevel } 2200 0 stevel 2201 0 stevel 2202 0 stevel OM_uint32 2203 0 stevel kgss_inquire_cred_wrapped(minor_status, 2204 0 stevel cred_handle, 2205 0 stevel gssd_cred_verifier, 2206 0 stevel name, 2207 0 stevel lifetime, 2208 0 stevel cred_usage, 2209 0 stevel mechanisms, 2210 0 stevel uid) 2211 0 stevel OM_uint32 *minor_status; 2212 0 stevel const gssd_cred_id_t cred_handle; 2213 0 stevel OM_uint32 gssd_cred_verifier; 2214 0 stevel gss_name_t *name; 2215 0 stevel OM_uint32 *lifetime; 2216 0 stevel int *cred_usage; 2217 0 stevel gss_OID_set *mechanisms; 2218 0 stevel uid_t uid; 2219 0 stevel { 2220 0 stevel CLIENT *clnt; 2221 0 stevel 2222 0 stevel OM_uint32 minor_status_temp; 2223 0 stevel gss_buffer_desc external_name; 2224 0 stevel gss_OID_desc name_type; 2225 0 stevel int i; 2226 0 stevel 2227 0 stevel gss_inquire_cred_arg arg; 2228 0 stevel gss_inquire_cred_res res; 2229 0 stevel 2230 0 stevel /* 2231 0 stevel * NULL the params here once 2232 0 stevel * If there are errors then we won't 2233 0 stevel * have to do it for every error 2234 0 stevel * case 2235 0 stevel */ 2236 0 stevel if (minor_status != NULL) 2237 0 stevel *minor_status = DEFAULT_MINOR_STAT; 2238 0 stevel if (name != NULL) 2239 0 stevel *name = NULL; 2240 0 stevel if (lifetime != NULL) 2241 0 stevel *lifetime = 0; 2242 0 stevel if (cred_usage != NULL) 2243 0 stevel *cred_usage = 0; 2244 0 stevel if (mechanisms != NULL) 2245 0 stevel *mechanisms = NULL; 2246 0 stevel 2247 0 stevel /* get the client handle to GSSD */ 2248 0 stevel 2249 0 stevel if ((clnt = getgssd_handle()) == NULL) { 2250 0 stevel GSSLOG(1, "kgss_inquire_cred: can't connect to server on %s\n", 2251 0 stevel server); 2252 0 stevel return (GSS_S_FAILURE); 2253 0 stevel } 2254 0 stevel 2255 0 stevel 2256 0 stevel /* copy the procedure arguments into the rpc arg parameter */ 2257 0 stevel 2258 0 stevel arg.uid = (OM_uint32) uid; 2259 0 stevel 2260 0 stevel arg.cred_handle.GSS_CRED_ID_T_len = 2261 0 stevel cred_handle == (gssd_cred_id_t)GSS_C_NO_CREDENTIAL ? 2262 0 stevel 0 : (uint_t)sizeof (gssd_cred_id_t); 2263 0 stevel arg.cred_handle.GSS_CRED_ID_T_val = (char *)&cred_handle; 2264 0 stevel arg.gssd_cred_verifier = gssd_cred_verifier; 2265 0 stevel 2266 0 stevel /* call the remote procedure */ 2267 0 stevel 2268 0 stevel bzero((caddr_t)&res, sizeof (res)); 2269 0 stevel if (gss_inquire_cred_1(&arg, &res, clnt) != RPC_SUCCESS) { 2270 0 stevel 2271 0 stevel /* 2272 0 stevel * if the RPC call times out 2273 0 stevel * kill the handle and return GSS_S_FAILURE 2274 0 stevel * the parameters have been set to NULL already 2275 0 stevel */ 2276 0 stevel 2277 0 stevel killgssd_handle(clnt); 2278 0 stevel GSSLOG0(1, "kgss_inquire_cred: RPC call times out\n"); 2279 0 stevel return (GSS_S_FAILURE); 2280 0 stevel } 2281 0 stevel 2282 0 stevel /* copy the rpc results into the return arguments */ 2283 0 stevel 2284 0 stevel if (minor_status != NULL) 2285 0 stevel *minor_status = res.minor_status; 2286 0 stevel 2287 0 stevel /* convert name from external to internal format */ 2288 0 stevel 2289 0 stevel if (name != NULL) { 2290 0 stevel external_name.length = res.name.GSS_BUFFER_T_len; 2291 0 stevel external_name.value = res.name.GSS_BUFFER_T_val; 2292 0 stevel 2293 0 stevel /* 2294 0 stevel * we can pass a pointer to res structure 2295 0 stevel * since gss_import_name treats the name_type 2296 0 stevel * parameter as read only and performs a copy 2297 0 stevel */ 2298 0 stevel 2299 0 stevel name_type.length = res.name_type.GSS_OID_len; 2300 0 stevel name_type.elements = (void *)res.name_type.GSS_OID_val; 2301 0 stevel 2302 0 stevel if (gss_import_name(&minor_status_temp, &external_name, 2303 0 stevel &name_type, name) != GSS_S_COMPLETE) { 2304 0 stevel 2305 0 stevel *minor_status = (OM_uint32) minor_status_temp; 2306 0 stevel clnt_freeres(clnt, xdr_gss_inquire_cred_res, 2307 0 stevel (caddr_t)&res); 2308 0 stevel killgssd_handle(clnt); 2309 0 stevel GSSLOG0(1, "kgss_inquire_cred: import name fails\n"); 2310 0 stevel return ((OM_uint32) GSS_S_FAILURE); 2311 0 stevel } 2312 0 stevel } 2313 0 stevel 2314 0 stevel if (lifetime != NULL) 2315 0 stevel *lifetime = res.lifetime; 2316 0 stevel 2317 0 stevel if (cred_usage != NULL) 2318 0 stevel *cred_usage = res.cred_usage; 2319 0 stevel 2320 0 stevel if (res.status == GSS_S_COMPLETE && 2321 0 stevel res.mechanisms.GSS_OID_SET_len != 0 && 2322 0 stevel mechanisms != NULL) { 2323 0 stevel *mechanisms = (gss_OID_set) MALLOC(sizeof (gss_OID_set_desc)); 2324 0 stevel (*mechanisms)->count = 2325 0 stevel (int)res.mechanisms.GSS_OID_SET_len; 2326 0 stevel (*mechanisms)->elements = (gss_OID) 2327 0 stevel MALLOC(sizeof (gss_OID_desc) * (*mechanisms)->count); 2328 0 stevel 2329 0 stevel for (i = 0; i < (*mechanisms)->count; i++) { 2330 0 stevel (*mechanisms)->elements[i].length = (OM_uint32) 2331 0 stevel res.mechanisms.GSS_OID_SET_val[i].GSS_OID_len; 2332 0 stevel (*mechanisms)->elements[i].elements = 2333 0 stevel (void *) MALLOC((*mechanisms)->elements[i].length); 2334 0 stevel (void) memcpy((*mechanisms)->elements[i].elements, 2335 0 stevel res.mechanisms.GSS_OID_SET_val[i].GSS_OID_val, 2336 0 stevel (*mechanisms)->elements[i].length); 2337 0 stevel } 2338 0 stevel } else { 2339 0 stevel if (res.status == GSS_S_COMPLETE && 2340 0 stevel mechanisms != NULL) 2341 0 stevel (*mechanisms) = NULL; 2342 0 stevel } 2343 0 stevel /* 2344 0 stevel * free the memory allocated for the results and return with the status 2345 0 stevel * received in the rpc call 2346 0 stevel */ 2347 0 stevel 2348 0 stevel clnt_freeres(clnt, xdr_gss_inquire_cred_res, (caddr_t)&res); 2349 0 stevel killgssd_handle(clnt); 2350 0 stevel return (res.status); 2351 0 stevel 2352 0 stevel } 2353 0 stevel 2354 0 stevel OM_uint32 2355 0 stevel kgss_inquire_cred(minor_status, 2356 0 stevel cred_handle, 2357 0 stevel name, 2358 0 stevel lifetime, 2359 0 stevel cred_usage, 2360 0 stevel mechanisms, 2361 0 stevel uid) 2362 0 stevel OM_uint32 *minor_status; 2363 0 stevel const gss_cred_id_t cred_handle; 2364 0 stevel gss_name_t *name; 2365 0 stevel OM_uint32 *lifetime; 2366 0 stevel int *cred_usage; 2367 0 stevel gss_OID_set * mechanisms; 2368 0 stevel uid_t uid; 2369 0 stevel { 2370 0 stevel 2371 0 stevel OM_uint32 gssd_cred_verifier; 2372 0 stevel OM_uint32 gssd_cred_handle; 2373 0 stevel 2374 0 stevel gssd_cred_verifier = KCRED_TO_CREDV(cred_handle); 2375 0 stevel gssd_cred_handle = KCRED_TO_CRED(cred_handle); 2376 0 stevel 2377 0 stevel return (kgss_inquire_cred_wrapped(minor_status, 2378 0 stevel gssd_cred_handle, gssd_cred_verifier, 2379 0 stevel name, lifetime, cred_usage, mechanisms, uid)); 2380 0 stevel } 2381 0 stevel 2382 0 stevel OM_uint32 2383 0 stevel kgss_inquire_cred_by_mech_wrapped(minor_status, 2384 0 stevel cred_handle, 2385 0 stevel gssd_cred_verifier, 2386 0 stevel mech_type, 2387 0 stevel uid) 2388 0 stevel OM_uint32 *minor_status; 2389 0 stevel gssd_cred_id_t cred_handle; 2390 0 stevel OM_uint32 gssd_cred_verifier; 2391 0 stevel gss_OID mech_type; 2392 0 stevel uid_t uid; 2393 0 stevel { 2394 0 stevel CLIENT *clnt; 2395 0 stevel 2396 0 stevel gss_inquire_cred_by_mech_arg arg; 2397 0 stevel gss_inquire_cred_by_mech_res res; 2398 0 stevel 2399 0 stevel /* get the client handle to GSSD */ 2400 0 stevel 2401 0 stevel if ((clnt = getgssd_handle()) == NULL) { 2402 0 stevel GSSLOG(1, "kgss_inquire_cred: can't connect to server on %s\n", 2403 0 stevel server); 2404 0 stevel return (GSS_S_FAILURE); 2405 0 stevel } 2406 0 stevel 2407 0 stevel 2408 0 stevel /* copy the procedure arguments into the rpc arg parameter */ 2409 0 stevel 2410 0 stevel arg.uid = (OM_uint32) uid; 2411 0 stevel 2412 0 stevel arg.cred_handle.GSS_CRED_ID_T_len = 2413 0 stevel cred_handle == (gssd_cred_id_t)GSS_C_NO_CREDENTIAL ? 2414 0 stevel 0 : (uint_t)sizeof (gssd_cred_id_t); 2415 0 stevel arg.cred_handle.GSS_CRED_ID_T_val = (char *)&cred_handle; 2416 0 stevel arg.gssd_cred_verifier = gssd_cred_verifier; 2417 0 stevel 2418 0 stevel arg.mech_type.GSS_OID_len = 2419 0 stevel (uint_t)(mech_type != GSS_C_NULL_OID ? 2420 0 stevel mech_type->length : 0); 2421 0 stevel arg.mech_type.GSS_OID_val = 2422 0 stevel (char *)(mech_type != GSS_C_NULL_OID ? 2423 0 stevel mech_type->elements : 0); 2424 0 stevel /* call the remote procedure */ 2425 0 stevel 2426 0 stevel bzero((caddr_t)&res, sizeof (res)); 2427 0 stevel if (gss_inquire_cred_by_mech_1(&arg, &res, clnt) != RPC_SUCCESS) { 2428 0 stevel 2429 0 stevel /* 2430 0 stevel * if the RPC call times out, null out all return arguments, set 2431 0 stevel * minor_status to its maximum value, and return GSS_S_FAILURE 2432 0 stevel */ 2433 0 stevel 2434 0 stevel if (minor_status != NULL) 2435 0 stevel *minor_status = DEFAULT_MINOR_STAT; 2436 0 stevel killgssd_handle(clnt); 2437 0 stevel GSSLOG0(1, "kgss_inquire_cred: RPC call times out\n"); 2438 0 stevel return (GSS_S_FAILURE); 2439 0 stevel } 2440 0 stevel 2441 0 stevel /* copy the rpc results into the return arguments */ 2442 0 stevel 2443 0 stevel if (minor_status != NULL) 2444 0 stevel *minor_status = res.minor_status; 2445 0 stevel 2446 0 stevel clnt_freeres(clnt, xdr_gss_inquire_cred_by_mech_res, (caddr_t)&res); 2447 0 stevel killgssd_handle(clnt); 2448 0 stevel return (res.status); 2449 0 stevel 2450 0 stevel } 2451 0 stevel 2452 0 stevel OM_uint32 2453 0 stevel kgss_inquire_cred_by_mech(minor_status, 2454 0 stevel cred_handle, 2455 0 stevel mech_type, 2456 0 stevel uid) 2457 0 stevel OM_uint32 *minor_status; 2458 0 stevel gss_cred_id_t cred_handle; 2459 0 stevel gss_OID mech_type; 2460 0 stevel uid_t uid; 2461 0 stevel { 2462 0 stevel 2463 0 stevel OM_uint32 gssd_cred_verifier; 2464 0 stevel OM_uint32 gssd_cred_handle; 2465 0 stevel 2466 0 stevel gssd_cred_verifier = KCRED_TO_CREDV(cred_handle); 2467 0 stevel gssd_cred_handle = KCRED_TO_CRED(cred_handle); 2468 0 stevel 2469 0 stevel return (kgss_inquire_cred_by_mech_wrapped(minor_status, 2470 0 stevel gssd_cred_handle, gssd_cred_verifier, 2471 0 stevel mech_type, uid)); 2472 0 stevel } 2473 0 stevel 2474 0 stevel OM_uint32 2475 0 stevel kgsscred_expname_to_unix_cred(expName, uidOut, gidOut, gids, gidsLen, uid) 2476 0 stevel const gss_buffer_t expName; 2477 0 stevel uid_t *uidOut; 2478 0 stevel gid_t *gidOut; 2479 0 stevel gid_t *gids[]; 2480 0 stevel int *gidsLen; 2481 0 stevel uid_t uid; 2482 0 stevel { 2483 0 stevel CLIENT *clnt; 2484 0 stevel gsscred_expname_to_unix_cred_arg args; 2485 0 stevel gsscred_expname_to_unix_cred_res res; 2486 0 stevel 2487 0 stevel /* check input/output parameters */ 2488 0 stevel if (expName == NULL || expName->value == NULL) 2489 0 stevel return (GSS_S_CALL_INACCESSIBLE_READ); 2490 0 stevel 2491 0 stevel if (uidOut == NULL) 2492 0 stevel return (GSS_S_CALL_INACCESSIBLE_WRITE); 2493 0 stevel 2494 0 stevel /* NULL out output parameters */ 2495 0 stevel *uidOut = UID_NOBODY; 2496 0 stevel if (gidsLen) 2497 0 stevel *gidsLen = 0; 2498 0 stevel 2499 0 stevel if (gids) 2500 0 stevel *gids = NULL; 2501 0 stevel 2502 0 stevel /* get the client handle to gssd */ 2503 0 stevel if ((clnt = getgssd_handle()) == NULL) 2504 0 stevel { 2505 0 stevel GSSLOG(1, "kgsscred_expname_to_unix_cred:" 2506 0 stevel " can't connect to server on %s\n", server); 2507 0 stevel return (GSS_S_FAILURE); 2508 0 stevel } 2509 0 stevel 2510 0 stevel /* copy the procedure arguments */ 2511 0 stevel args.uid = uid; 2512 0 stevel args.expname.GSS_BUFFER_T_val = expName->value; 2513 0 stevel args.expname.GSS_BUFFER_T_len = expName->length; 2514 0 stevel 2515 0 stevel /* null out the return buffer and call the remote proc */ 2516 0 stevel bzero(&res, sizeof (res)); 2517 0 stevel 2518 0 stevel if (gsscred_expname_to_unix_cred_1(&args, &res, clnt) != RPC_SUCCESS) 2519 0 stevel { 2520 0 stevel killgssd_handle(clnt); 2521 0 stevel GSSLOG0(1, 2522 0 stevel "kgsscred_expname_to_unix_cred: RPC call times out\n"); 2523 0 stevel return (GSS_S_FAILURE); 2524 0 stevel } 2525 0 stevel 2526 0 stevel /* copy the results into the result parameters */ 2527 0 stevel if (res.major == GSS_S_COMPLETE) 2528 0 stevel { 2529 0 stevel *uidOut = res.uid; 2530 0 stevel if (gidOut) 2531 0 stevel *gidOut = res.gid; 2532 0 stevel if (gids && gidsLen) 2533 0 stevel { 2534 0 stevel *gids = res.gids.GSSCRED_GIDS_val; 2535 0 stevel *gidsLen = res.gids.GSSCRED_GIDS_len; 2536 0 stevel res.gids.GSSCRED_GIDS_val = NULL; 2537 0 stevel res.gids.GSSCRED_GIDS_len = 0; 2538 0 stevel } 2539 0 stevel } 2540 0 stevel 2541 0 stevel /* free RPC results */ 2542 0 stevel clnt_freeres(clnt, xdr_gsscred_expname_to_unix_cred_res, (caddr_t)&res); 2543 0 stevel killgssd_handle(clnt); 2544 0 stevel 2545 0 stevel return (res.major); 2546 0 stevel } /* kgsscred_expname_to_unix_cred */ 2547 0 stevel 2548 0 stevel OM_uint32 2549 0 stevel kgsscred_name_to_unix_cred(intName, mechType, uidOut, gidOut, gids, 2550 0 stevel gidsLen, uid) 2551 0 stevel const gss_name_t intName; 2552 0 stevel const gss_OID mechType; 2553 0 stevel uid_t *uidOut; 2554 0 stevel gid_t *gidOut; 2555 0 stevel gid_t *gids[]; 2556 0 stevel int *gidsLen; 2557 0 stevel uid_t uid; 2558 0 stevel { 2559 0 stevel CLIENT *clnt; 2560 0 stevel gsscred_name_to_unix_cred_arg args; 2561 0 stevel gsscred_name_to_unix_cred_res res; 2562 0 stevel OM_uint32 major, minor; 2563 0 stevel gss_OID nameOid; 2564 0 stevel gss_buffer_desc flatName = GSS_C_EMPTY_BUFFER; 2565 0 stevel 2566 0 stevel /* check the input/output parameters */ 2567 0 stevel if (intName == NULL || mechType == NULL) 2568 0 stevel return (GSS_S_CALL_INACCESSIBLE_READ); 2569 0 stevel 2570 0 stevel if (uidOut == NULL) 2571 0 stevel return (GSS_S_CALL_INACCESSIBLE_WRITE); 2572 0 stevel 2573 0 stevel /* NULL out the output parameters */ 2574 0 stevel *uidOut = UID_NOBODY; 2575 0 stevel if (gids) 2576 0 stevel *gids = NULL; 2577 0 stevel 2578 0 stevel if (gidsLen) 2579 0 stevel *gidsLen = 0; 2580 0 stevel 2581 0 stevel /* get the client handle to gssd */ 2582 0 stevel if ((clnt = getgssd_handle()) == NULL) 2583 0 stevel { 2584 0 stevel GSSLOG(1, 2585 0 stevel "kgsscred_name_to_unix_cred: can't connect to server %s\n", 2586 0 stevel server); 2587 0 stevel return (GSS_S_FAILURE); 2588 0 stevel } 2589 0 stevel 2590 0 stevel /* convert the name to flat representation */ 2591 0 stevel if ((major = gss_display_name(&minor, intName, &flatName, &nameOid)) 2592 0 stevel != GSS_S_COMPLETE) 2593 0 stevel { 2594 0 stevel killgssd_handle(clnt); 2595 0 stevel GSSLOG0(1, "kgsscred_name_to_unix_cred: display name failed\n"); 2596 0 stevel return (major); 2597 0 stevel } 2598 0 stevel 2599 0 stevel /* set the rpc parameters */ 2600 0 stevel args.uid = uid; 2601 0 stevel args.pname.GSS_BUFFER_T_len = flatName.length; 2602 0 stevel args.pname.GSS_BUFFER_T_val = flatName.value; 2603 0 stevel args.name_type.GSS_OID_len = nameOid->length; 2604 0 stevel args.name_type.GSS_OID_val = nameOid->elements; 2605 0 stevel args.mech_type.GSS_OID_len = mechType->length; 2606 0 stevel args.mech_type.GSS_OID_val = mechType->elements; 2607 0 stevel 2608 0 stevel /* call the remote procedure */ 2609 0 stevel bzero(&res, sizeof (res)); 2610 0 stevel if (gsscred_name_to_unix_cred_1(&args, &res, clnt) != RPC_SUCCESS) { 2611 0 stevel killgssd_handle(clnt); 2612 0 stevel (void) gss_release_buffer(&minor, &flatName); 2613 0 stevel GSSLOG0(1, "kgsscred_name_to_unix_cred: RPC call times out\n"); 2614 0 stevel return (GSS_S_FAILURE); 2615 0 stevel } 2616 0 stevel 2617 0 stevel /* delete the flat name buffer */ 2618 0 stevel (void) gss_release_buffer(&minor, &flatName); 2619 0 stevel 2620 0 stevel /* copy the output parameters on output */ 2621 0 stevel if (res.major == GSS_S_COMPLETE) { 2622 0 stevel *uidOut = res.uid; 2623 0 stevel 2624 0 stevel if (gidOut) 2625 0 stevel *gidOut = res.gid; 2626 0 stevel if (gids && gidsLen) { 2627 0 stevel *gids = res.gids.GSSCRED_GIDS_val; 2628 0 stevel *gidsLen = res.gids.GSSCRED_GIDS_len; 2629 0 stevel res.gids.GSSCRED_GIDS_val = NULL; 2630 0 stevel res.gids.GSSCRED_GIDS_len = 0; 2631 0 stevel } 2632 0 stevel } 2633 0 stevel 2634 0 stevel /* delete RPC allocated memory */ 2635 0 stevel clnt_freeres(clnt, xdr_gsscred_name_to_unix_cred_res, (caddr_t)&res); 2636 0 stevel killgssd_handle(clnt); 2637 0 stevel 2638 0 stevel return (res.major); 2639 0 stevel } /* kgsscred_name_to_unix_cred */ 2640 0 stevel 2641 0 stevel OM_uint32 2642 0 stevel kgss_get_group_info(puid, gidOut, gids, gidsLen, uid) 2643 0 stevel const uid_t puid; 2644 0 stevel gid_t *gidOut; 2645 0 stevel gid_t *gids[]; 2646 0 stevel int *gidsLen; 2647 0 stevel uid_t uid; 2648 0 stevel { 2649 0 stevel CLIENT *clnt; 2650 0 stevel gss_get_group_info_arg args; 2651 0 stevel gss_get_group_info_res res; 2652 0 stevel 2653 0 stevel 2654 0 stevel /* check the output parameters */ 2655 0 stevel if (gidOut == NULL || gids == NULL || gidsLen == NULL) 2656 0 stevel return (GSS_S_CALL_INACCESSIBLE_WRITE); 2657 0 stevel 2658 0 stevel /* get the client GSSD handle */ 2659 0 stevel if ((clnt = getgssd_handle()) == NULL) { 2660 0 stevel GSSLOG(1, 2661 0 stevel "kgss_get_group_info: can't connect to server on %s\n", 2662 0 stevel server); 2663 0 stevel return (GSS_S_FAILURE); 2664 0 stevel } 2665 0 stevel 2666 0 stevel /* set the input parameters */ 2667 0 stevel args.uid = uid; 2668 0 stevel args.puid = puid; 2669 0 stevel 2670 0 stevel /* call the remote procedure */ 2671 0 stevel bzero(&res, sizeof (res)); 2672 0 stevel if (gss_get_group_info_1(&args, &res, clnt) != RPC_SUCCESS) { 2673 0 stevel killgssd_handle(clnt); 2674 0 stevel GSSLOG0(1, "kgss_get_group_info: RPC call times out\n"); 2675 0 stevel return (GSS_S_FAILURE); 2676 0 stevel } 2677 0 stevel 2678 0 stevel /* copy the results */ 2679 0 stevel if (res.major == GSS_S_COMPLETE) { 2680 0 stevel *gidOut = res.gid; 2681 0 stevel *gids = res.gids.GSSCRED_GIDS_val; 2682 0 stevel *gidsLen = res.gids.GSSCRED_GIDS_len; 2683 0 stevel res.gids.GSSCRED_GIDS_val = NULL; 2684 0 stevel res.gids.GSSCRED_GIDS_len = 0; 2685 0 stevel } 2686 0 stevel 2687 0 stevel /* no results to free */ 2688 0 stevel killgssd_handle(clnt); 2689 0 stevel 2690 0 stevel return (res.major); 2691 0 stevel } /* kgss_get_group_info */ 2692 0 stevel 2693 0 stevel static char * 2694 0 stevel kgss_get_kmod(gss_OID mech_oid) 2695 0 stevel { 2696 0 stevel CLIENT *clnt; 2697 0 stevel gss_get_kmod_arg args; 2698 0 stevel gss_get_kmod_res res; 2699 0 stevel 2700 0 stevel 2701 0 stevel /* get the client GSSD handle */ 2702 0 stevel if ((clnt = getgssd_handle()) == NULL) { 2703 0 stevel GSSLOG(1, "kgss_get_kmod: can't connect to server on %s\n", 2704 0 stevel server); 2705 0 stevel return (NULL); 2706 0 stevel } 2707 0 stevel 2708 0 stevel /* set the input parameters */ 2709 0 stevel args.mech_oid.GSS_OID_len = mech_oid->length; 2710 0 stevel args.mech_oid.GSS_OID_val = mech_oid->elements; 2711 0 stevel 2712 0 stevel /* call the remote procedure */ 2713 0 stevel bzero(&res, sizeof (res)); 2714 0 stevel if (gss_get_kmod_1(&args, &res, clnt) != RPC_SUCCESS) { 2715 0 stevel killgssd_handle(clnt); 2716 0 stevel GSSLOG0(1, "gss_get_kmod_1: RPC call times out\n"); 2717 0 stevel return (NULL); 2718 0 stevel } 2719 0 stevel /* no results to free */ 2720 0 stevel killgssd_handle(clnt); 2721 0 stevel 2722 0 stevel if (res.module_follow == TRUE) { 2723 0 stevel return (res.gss_get_kmod_res_u.modname); 2724 0 stevel } else 2725 0 stevel return (NULL); 2726 0 stevel } /* kgss_get_kmod */ 2727 0 stevel 2728 0 stevel static gss_mechanism kgss_mech_head; 2729 0 stevel static gss_mechanism kgss_mech_tail; 2730 0 stevel kmutex_t __kgss_mech_lock; 2731 0 stevel 2732 0 stevel /* 2733 0 stevel * See if there is kernel mechanism module, and if so, attempt to 2734 0 stevel * load it and reset the pointer (gss_mechanism) to the sign/seal/etc. 2735 0 stevel * entry points to that of the kernel module. 2736 0 stevel */ 2737 0 stevel static void 2738 0 stevel __kgss_reset_mech(gss_mechanism *mechp, gss_OID mech_oid) 2739 0 stevel { 2740 0 stevel gss_mechanism mech; 2741 0 stevel char *kmod; 2742 0 stevel 2743 0 stevel /* 2744 0 stevel * We can search the list without a mutex, becuase the list never 2745 0 stevel * shrinks and we always add to the end. 2746 0 stevel */ 2747 0 stevel mech = __kgss_get_mechanism(mech_oid); 2748 0 stevel if (mech) { 2749 0 stevel *mechp = mech; 2750 0 stevel return; 2751 0 stevel } 2752 0 stevel 2753 0 stevel /* 2754 0 stevel * Get the module name from the kernel. 2755 0 stevel */ 2756 0 stevel kmod = kgss_get_kmod(mech_oid); 2757 0 stevel 2758 0 stevel if (kmod) { 2759 6855 johnlev extern int modload(const char *, const char *); 2760 0 stevel if (modload("misc/kgss", kmod) < 0) { 2761 0 stevel /* 2762 0 stevel * Modload of 'kmod' failed, so log an 2763 0 stevel * appropriate comment 2764 0 stevel */ 2765 0 stevel cmn_err(CE_NOTE, "kgss_reset_mech: Algorithm modload " 2766 0 stevel "(%s) failed. Userland gssd will now handle " 2767 0 stevel "all GSSAPI calls, which may result in " 2768 0 stevel "reduced performance.\n", kmod); 2769 0 stevel }; 2770 0 stevel 2771 0 stevel /* 2772 0 stevel * Allocated in the XDR routine called by gss_get_kmod_1(). 2773 0 stevel */ 2774 0 stevel FREE(kmod, strlen(kmod)+1); 2775 0 stevel 2776 0 stevel mech = __kgss_get_mechanism(mech_oid); 2777 0 stevel if (mech) { 2778 0 stevel *mechp = mech; 2779 0 stevel } 2780 0 stevel 2781 0 stevel /* 2782 0 stevel * If for some reason the module load didn't take, 2783 0 stevel * we return anyway and hope that the next context 2784 0 stevel * creation succeeds. 2785 0 stevel */ 2786 0 stevel return; 2787 0 stevel } 2788 0 stevel 2789 0 stevel 2790 0 stevel /* 2791 0 stevel * No kernel module, so enter this mech oid into the list 2792 0 stevel * using the default sign/seal/etc. operations that upcall to 2793 0 stevel * gssd. 2794 0 stevel */ 2795 0 stevel mutex_enter(&__kgss_mech_lock); 2796 0 stevel mech = __kgss_get_mechanism(mech_oid); 2797 0 stevel if (mech) { 2798 0 stevel mutex_exit(&__kgss_mech_lock); 2799 0 stevel *mechp = mech; 2800 0 stevel return; 2801 0 stevel } 2802 0 stevel 2803 0 stevel /* 2804 0 stevel * Allocate space for the mechanism entry. 2805 0 stevel */ 2806 0 stevel mech = kmem_zalloc(sizeof (struct gss_config), KM_SLEEP); 2807 0 stevel 2808 0 stevel /* 2809 0 stevel * Copy basic information from default mechanism struct. 2810 0 stevel */ 2811 0 stevel *mech = default_gc; 2812 0 stevel 2813 0 stevel /* 2814 0 stevel * Record the real mech OID. 2815 0 stevel */ 2816 0 stevel mech->mech_type.length = mech_oid->length; 2817 0 stevel mech->mech_type.elements = MALLOC(mech_oid->length); 2818 0 stevel bcopy(mech_oid->elements, mech->mech_type.elements, mech_oid->length); 2819 0 stevel 2820 0 stevel /* 2821 0 stevel * Add it to the table. 2822 0 stevel */ 2823 0 stevel __kgss_add_mechanism(mech); 2824 0 stevel mutex_exit(&__kgss_mech_lock); 2825 0 stevel *mechp = mech; 2826 0 stevel } 2827 0 stevel 2828 0 stevel /* 2829 0 stevel * Called with __kgss_mech_lock held. 2830 0 stevel */ 2831 0 stevel void 2832 0 stevel __kgss_add_mechanism(gss_mechanism mech) 2833 0 stevel { 2834 0 stevel gss_mechanism tmp; 2835 0 stevel 2836 0 stevel tmp = kgss_mech_tail; 2837 0 stevel kgss_mech_tail = mech; 2838 0 stevel 2839 0 stevel if (tmp != NULL) 2840 0 stevel tmp->next = mech; 2841 0 stevel 2842 0 stevel if (kgss_mech_head == NULL) 2843 0 stevel kgss_mech_head = mech; 2844 0 stevel } 2845 0 stevel 2846 0 stevel /* 2847 0 stevel * given the mechs_array and a mechanism OID, return the 2848 0 stevel * pointer to the mechanism, or NULL if that mechanism is 2849 0 stevel * not supported. 2850 0 stevel */ 2851 0 stevel gss_mechanism 2852 0 stevel __kgss_get_mechanism(gss_OID type) 2853 0 stevel { 2854 0 stevel gss_mechanism mech; 2855 0 stevel 2856 0 stevel mech = kgss_mech_head; 2857 0 stevel 2858 0 stevel /* 2859 0 stevel * Note that a reader can scan this list without the mutex held. 2860 0 stevel * This is safe because we always append, and never shrink the list. 2861 0 stevel * Moreover, the entry is fully initialized before it is ever 2862 0 stevel * added to the list. 2863 0 stevel */ 2864 0 stevel while (mech != NULL) { 2865 0 stevel if ((mech->mech_type.length == type->length) && 2866 0 stevel (bcmp(mech->mech_type.elements, type->elements, 2867 0 stevel type->length) == 0)) 2868 0 stevel return (mech); 2869 0 stevel 2870 0 stevel mech = mech->next; 2871 0 stevel } 2872 0 stevel return (NULL); 2873 0 stevel } 2874