1/* 2 * Copyright (c) 2010 Apple Inc. All rights reserved. 3 * 4 * @APPLE_LICENSE_HEADER_START@ 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 3. Neither the name of Apple Inc. ("Apple") nor the names of its 16 * contributors may be used to endorse or promote products derived from 17 * this software without specific prior written permission. 18 * 19 * THIS SOFTWARE IS PROVIDED BY APPLE AND ITS CONTRIBUTORS "AS IS" AND ANY 20 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 21 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 22 * DISCLAIMED. IN NO EVENT SHALL APPLE OR ITS CONTRIBUTORS BE LIABLE FOR ANY 23 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 24 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 25 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 26 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 28 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 29 * 30 * Portions of this software have been released under the following terms: 31 * 32 * (c) Copyright 1989-1993 OPEN SOFTWARE FOUNDATION, INC. 33 * (c) Copyright 1989-1993 HEWLETT-PACKARD COMPANY 34 * (c) Copyright 1989-1993 DIGITAL EQUIPMENT CORPORATION 35 * 36 * To anyone who acknowledges that this file is provided "AS IS" 37 * without any express or implied warranty: 38 * permission to use, copy, modify, and distribute this file for any 39 * purpose is hereby granted without fee, provided that the above 40 * copyright notices and this notice appears in all source code copies, 41 * and that none of the names of Open Software Foundation, Inc., Hewlett- 42 * Packard Company or Digital Equipment Corporation be used 43 * in advertising or publicity pertaining to distribution of the software 44 * without specific, written prior permission. Neither Open Software 45 * Foundation, Inc., Hewlett-Packard Company nor Digital 46 * Equipment Corporation makes any representations about the suitability 47 * of this software for any purpose. 48 * 49 * Copyright (c) 2007, Novell, Inc. All rights reserved. 50 * Redistribution and use in source and binary forms, with or without 51 * modification, are permitted provided that the following conditions 52 * are met: 53 * 54 * 1. Redistributions of source code must retain the above copyright 55 * notice, this list of conditions and the following disclaimer. 56 * 2. Redistributions in binary form must reproduce the above copyright 57 * notice, this list of conditions and the following disclaimer in the 58 * documentation and/or other materials provided with the distribution. 59 * 3. Neither the name of Novell Inc. nor the names of its contributors 60 * may be used to endorse or promote products derived from this 61 * this software without specific prior written permission. 62 * 63 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY 64 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 65 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 66 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR CONTRIBUTORS BE LIABLE FOR ANY 67 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 68 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 69 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND 70 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 71 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 72 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 73 * 74 * @APPLE_LICENSE_HEADER_END@ 75 */ 76 77/* 78** 79** NAME 80** 81** gssauth.c 82** 83** FACILITY: 84** 85** Remote Procedure Call (RPC) 86** 87** ABSTRACT: 88** 89** Client-side support of kerberos module. 90** 91** 92*/ 93 94#include <config.h> 95 96#if defined(AUTH_GSS_NEGOTIATE) && AUTH_GSS_NEGOTIATE 97 98#include <gssauth.h> 99 100INTERNAL unsigned32 rpc_g_gssauth_alloc_count = 0; 101INTERNAL unsigned32 rpc_g_gssauth_free_count = 0; 102 103INTERNAL rpc_auth_rpc_prot_epv_p_t rpc_g_gssauth_negotiate_rpc_prot_epv[RPC_C_PROTOCOL_ID_MAX]; 104INTERNAL rpc_auth_rpc_prot_epv_p_t rpc_g_gssauth_mskrb_rpc_prot_epv[RPC_C_PROTOCOL_ID_MAX]; 105INTERNAL rpc_auth_rpc_prot_epv_p_t rpc_g_gssauth_winnt_rpc_prot_epv[RPC_C_PROTOCOL_ID_MAX]; 106INTERNAL rpc_auth_rpc_prot_epv_p_t rpc_g_gssauth_netlogon_rpc_prot_epv[RPC_C_PROTOCOL_ID_MAX]; 107 108INTERNAL void rpc__gssauth_negotiate_bnd_set_auth ( 109 unsigned_char_p_t /* in */ /*server_princ_name*/, 110 rpc_authn_level_t /* in */ /*authn_level*/, 111 rpc_auth_identity_handle_t /* in */ /*auth_identity*/, 112 rpc_authz_protocol_id_t /* in */ /*authz_protocol*/, 113 rpc_binding_handle_t /* in */ /*binding_h*/, 114 rpc_auth_info_p_t /* out */ * /*auth_info*/, 115 unsigned32 /* out */ * /*st*/ 116 ); 117 118INTERNAL void rpc__gssauth_mskrb_bnd_set_auth ( 119 unsigned_char_p_t /* in */ /*server_princ_name*/, 120 rpc_authn_level_t /* in */ /*authn_level*/, 121 rpc_auth_identity_handle_t /* in */ /*auth_identity*/, 122 rpc_authz_protocol_id_t /* in */ /*authz_protocol*/, 123 rpc_binding_handle_t /* in */ /*binding_h*/, 124 rpc_auth_info_p_t /* out */ * /*auth_info*/, 125 unsigned32 /* out */ * /*st*/ 126 ); 127 128INTERNAL void rpc__gssauth_winnt_bnd_set_auth ( 129 unsigned_char_p_t /* in */ /*server_princ_name*/, 130 rpc_authn_level_t /* in */ /*authn_level*/, 131 rpc_auth_identity_handle_t /* in */ /*auth_identity*/, 132 rpc_authz_protocol_id_t /* in */ /*authz_protocol*/, 133 rpc_binding_handle_t /* in */ /*binding_h*/, 134 rpc_auth_info_p_t /* out */ * /*auth_info*/, 135 unsigned32 /* out */ * /*st*/ 136 ); 137 138INTERNAL void rpc__gssauth_netlogon_bnd_set_auth ( 139 unsigned_char_p_t /* in */ /*server_princ_name*/, 140 rpc_authn_level_t /* in */ /*authn_level*/, 141 rpc_auth_identity_handle_t /* in */ /*auth_identity*/, 142 rpc_authz_protocol_id_t /* in */ /*authz_protocol*/, 143 rpc_binding_handle_t /* in */ /*binding_h*/, 144 rpc_auth_info_p_t /* out */ * /*auth_info*/, 145 unsigned32 /* out */ * /*st*/ 146 ); 147 148INTERNAL void rpc__gssauth_srv_reg_auth ( 149 unsigned_char_p_t /* in */ /*server_princ_name*/, 150 rpc_auth_key_retrieval_fn_t /* in */ /*get_key_func*/, 151 dce_pointer_t /* in */ /*arg*/, 152 unsigned32 /* out */ * /*st*/ 153 ); 154 155INTERNAL void rpc__gssauth_mgt_inq_def ( 156 unsigned32 /* out */ * /*authn_level*/, 157 unsigned32 /* out */ * /*st*/ 158 ); 159 160INTERNAL void rpc__gssauth_inq_my_princ_name ( 161 unsigned32 /* in */ /*princ_name_size*/, 162 unsigned_char_p_t /* out */ /*princ_name*/, 163 unsigned32 /* out */ * /*st*/ 164 ); 165 166INTERNAL void rpc__gssauth_free_info ( 167 rpc_auth_info_p_t /* in/out */ * /*info*/ 168 ); 169 170INTERNAL void rpc__gssauth_free_key ( 171 rpc_key_info_p_t /* in/out */ * /*info*/ 172 ); 173 174INTERNAL error_status_t rpc__gssauth_resolve_identity ( 175 rpc_auth_identity_handle_t /* in */ /* in_identity*/, 176 rpc_auth_identity_handle_t /* out */ * /*out_identity*/ 177 ); 178 179INTERNAL void rpc__gssauth_release_identity ( 180 rpc_auth_identity_handle_t /* in/out */ * /*identity*/ 181 ); 182 183INTERNAL void rpc__gssauth_inq_sec_context ( 184 rpc_auth_info_p_t /* in */ /*auth_info*/, 185 void /* out */ ** /*mech_context*/, 186 unsigned32 /* out */ * /*stp*/ 187 ); 188 189INTERNAL void rpc__gssauth_inq_access_token( 190 rpc_auth_info_p_t auth_info, 191 rpc_access_token_p_t* token, 192 unsigned32 *stp 193 ); 194 195INTERNAL rpc_auth_epv_t rpc_g_gssauth_negotiate_epv = 196{ 197 rpc__gssauth_negotiate_bnd_set_auth, 198 rpc__gssauth_srv_reg_auth, 199 rpc__gssauth_mgt_inq_def, 200 rpc__gssauth_inq_my_princ_name, 201 rpc__gssauth_free_info, 202 rpc__gssauth_free_key, 203 rpc__gssauth_resolve_identity, 204 rpc__gssauth_release_identity, 205 rpc__gssauth_inq_sec_context, 206 rpc__gssauth_inq_access_token 207}; 208 209INTERNAL rpc_auth_epv_t rpc_g_gssauth_mskrb_epv = 210{ 211 rpc__gssauth_mskrb_bnd_set_auth, 212 rpc__gssauth_srv_reg_auth, 213 rpc__gssauth_mgt_inq_def, 214 rpc__gssauth_inq_my_princ_name, 215 rpc__gssauth_free_info, 216 rpc__gssauth_free_key, 217 rpc__gssauth_resolve_identity, 218 rpc__gssauth_release_identity, 219 rpc__gssauth_inq_sec_context, 220 rpc__gssauth_inq_access_token 221}; 222 223INTERNAL rpc_auth_epv_t rpc_g_gssauth_winnt_epv = 224{ 225 rpc__gssauth_winnt_bnd_set_auth, 226 rpc__gssauth_srv_reg_auth, 227 rpc__gssauth_mgt_inq_def, 228 rpc__gssauth_inq_my_princ_name, 229 rpc__gssauth_free_info, 230 rpc__gssauth_free_key, 231 rpc__gssauth_resolve_identity, 232 rpc__gssauth_release_identity, 233 rpc__gssauth_inq_sec_context, 234 rpc__gssauth_inq_access_token 235}; 236 237INTERNAL rpc_auth_epv_t rpc_g_gssauth_netlogon_epv = 238{ 239 rpc__gssauth_netlogon_bnd_set_auth, 240 rpc__gssauth_srv_reg_auth, 241 rpc__gssauth_mgt_inq_def, 242 rpc__gssauth_inq_my_princ_name, 243 rpc__gssauth_free_info, 244 rpc__gssauth_free_key, 245 rpc__gssauth_resolve_identity, 246 rpc__gssauth_release_identity, 247 rpc__gssauth_inq_sec_context, 248 rpc__gssauth_inq_access_token 249}; 250 251/* 252 * R P C _ _ G S S A U T H _ B N D _ S E T _ A U T H 253 * 254 */ 255 256INTERNAL void rpc__gssauth_bnd_set_auth 257( 258 unsigned_char_p_t server_name, 259 rpc_authn_level_t level, 260 rpc_authn_protocol_id_t authn_protocol, 261 rpc_auth_identity_handle_t auth_ident, 262 rpc_authz_protocol_id_t authz_prot, 263 rpc_binding_handle_t binding_h, 264 rpc_auth_info_p_t *infop, 265 unsigned32 *stp 266) 267{ 268 unsigned32 st; 269 rpc_gssauth_info_p_t gssauth_info; 270 unsigned_char_p_t str_server_name; 271 gss_name_t gss_server_name; 272 OM_uint32 maj_stat; 273 OM_uint32 min_stat; 274 275 RPC_DBG_PRINTF(rpc_e_dbg_auth, RPC_C_CN_DBG_AUTH_ROUTINE_TRACE, 276 ("(rpc__gssauth_bnd_set_auth)\n")); 277 278 rpc_g_gssauth_alloc_count++; 279 RPC_MEM_ALLOC(gssauth_info, 280 rpc_gssauth_info_p_t, 281 sizeof (*gssauth_info), 282 RPC_C_MEM_GSSAUTH_INFO, 283 RPC_C_MEM_WAITOK); 284 memset (gssauth_info, 0, sizeof(*gssauth_info)); 285 286 if ((authz_prot != rpc_c_authz_name) && 287 (authz_prot != rpc_c_authz_gss_name)) { 288 st = rpc_s_authn_authz_mismatch; 289 goto poison; 290 } 291 292 if ((level != rpc_c_authn_level_connect) && 293 (level != rpc_c_authn_level_pkt_integrity) && 294 (level != rpc_c_authn_level_pkt_privacy)) { 295 st = rpc_s_unsupported_authn_level; 296 goto poison; 297 } 298 299 /* 300 * If no server principal name was specified, go ask for it. 301 */ 302 if (authz_prot == rpc_c_authz_name) { 303 gss_buffer_desc input_name; 304 305 if (server_name == NULL) { 306 rpc_mgmt_inq_server_princ_name(binding_h, 307 authn_protocol, 308 &str_server_name, 309 &st); 310 if (st != rpc_s_ok) { 311 goto poison; 312 } 313 } else { 314 str_server_name = rpc_stralloc(server_name); 315 } 316 317 input_name.value = (void *)str_server_name; 318 input_name.length = strlen((char *)str_server_name); 319 320 maj_stat = gss_import_name(&min_stat, 321 &input_name, 322 GSS_KRB5_NT_PRINCIPAL_NAME, 323 &gss_server_name); 324 if (GSS_ERROR(maj_stat)) { 325 char msg[256]; 326 rpc__gssauth_error_map(maj_stat, min_stat, GSS_C_NO_OID, 327 msg, sizeof(msg), &st); 328 RPC_DBG_PRINTF(rpc_e_dbg_auth, RPC_C_CN_DBG_AUTH_GENERAL, 329 ("(rpc__gssauth_bnd_set_auth): import: %s\n", msg)); 330 goto poison; 331 } 332 } else if (authz_prot == rpc_c_authz_gss_name) { 333 gss_buffer_desc output_name; 334 335 gss_server_name = (gss_name_t)server_name; 336 server_name = NULL; 337 338 if (gss_server_name == GSS_C_NO_NAME) { 339 /* 340 * the caller passes GSS_C_NO_NAME, we'll pass it down 341 * later, if the caller wants an autolookup 342 * rpc_c_authz_name should be used 343 */ 344 gss_server_name = GSS_C_NO_NAME; 345 str_server_name = NULL; 346 } else { 347 maj_stat = gss_duplicate_name(&min_stat, 348 gss_server_name, 349 &gss_server_name); 350 if (maj_stat != GSS_S_COMPLETE) { 351 char msg[256]; 352 rpc__gssauth_error_map(maj_stat, min_stat, GSS_C_NO_OID, 353 msg, sizeof(msg), &st); 354 RPC_DBG_PRINTF(rpc_e_dbg_auth, RPC_C_CN_DBG_AUTH_GENERAL, 355 ("(rpc__gssauth_bnd_set_auth): duplicate: %s\n", msg)); 356 goto poison; 357 } 358 359 maj_stat = gss_display_name(&min_stat, 360 gss_server_name, 361 &output_name, 362 NULL); 363 if (maj_stat != GSS_S_COMPLETE) { 364 char msg[256]; 365 rpc__gssauth_error_map(maj_stat, min_stat, GSS_C_NO_OID, 366 msg, sizeof(msg), &st); 367 RPC_DBG_PRINTF(rpc_e_dbg_auth, RPC_C_CN_DBG_AUTH_GENERAL, 368 ("(rpc__gssauth_bnd_set_auth): display: %s\n", msg)); 369 goto poison; 370 } 371 372 RPC_MEM_ALLOC(str_server_name, 373 unsigned_char_p_t, 374 output_name.length + 1, 375 RPC_C_MEM_STRING, 376 RPC_C_MEM_WAITOK); 377 rpc__strncpy(str_server_name, 378 output_name.value, 379 output_name.length); 380 381 gss_release_buffer(&min_stat, &output_name); 382 } 383 } 384 385 RPC_DBG_PRINTF(rpc_e_dbg_auth, RPC_C_CN_DBG_AUTH_GENERAL, 386 ("(rpc__gssauth_bnd_set_auth) %p created (now %d active)\n", 387 gssauth_info, rpc_g_gssauth_alloc_count - rpc_g_gssauth_free_count)); 388 389 if (auth_ident != NULL) { 390 gss_OID desired_mech = GSS_C_NO_OID; 391 392 rpc__gssauth_select_mech(&min_stat, authn_protocol, &desired_mech); 393 394 assert(gssauth_info->gss_creds == GSS_C_NO_CREDENTIAL); 395 396 maj_stat = gss_add_cred(&min_stat, 397 (const gss_cred_id_t)auth_ident, 398 GSS_C_NO_NAME, 399 desired_mech, 400 GSS_C_INITIATE, 401 GSS_C_INDEFINITE, 402 GSS_C_INDEFINITE, 403 &gssauth_info->gss_creds, 404 NULL, 405 NULL, 406 NULL); 407 if (GSS_ERROR(maj_stat)) { 408 char msg[256]; 409 rpc__gssauth_error_map(maj_stat, min_stat, GSS_C_NO_OID, 410 msg, sizeof(msg), &st); 411 RPC_DBG_PRINTF(rpc_e_dbg_auth, RPC_C_CN_DBG_AUTH_GENERAL, 412 ("(rpc__gssauth_bnd_set_auth): add_cred: %s\n", msg)); 413 goto poison; 414 } 415 } 416 417 gssauth_info->gss_server_name = gss_server_name; 418 gssauth_info->auth_info.server_princ_name = str_server_name; 419 gssauth_info->auth_info.authn_level = level; 420 gssauth_info->auth_info.authn_protocol = authn_protocol; 421 gssauth_info->auth_info.authz_protocol = authz_prot; 422 gssauth_info->auth_info.is_server = false; 423 gssauth_info->auth_info.u.auth_identity = (rpc_auth_identity_handle_t)gssauth_info->gss_creds; 424 425 gssauth_info->auth_info.refcount = 1; 426 427 *infop = &gssauth_info->auth_info; 428 *stp = rpc_s_ok; 429 return; 430 431poison: 432 *infop = &gssauth_info->auth_info; 433 *stp = st; 434 return; 435} 436 437INTERNAL void rpc__gssauth_negotiate_bnd_set_auth 438( 439 unsigned_char_p_t server_name, 440 rpc_authn_level_t level, 441 rpc_auth_identity_handle_t auth_ident, 442 rpc_authz_protocol_id_t authz_prot, 443 rpc_binding_handle_t binding_h, 444 rpc_auth_info_p_t *infop, 445 unsigned32 *stp 446) 447{ 448 RPC_DBG_PRINTF(rpc_e_dbg_auth, RPC_C_CN_DBG_AUTH_ROUTINE_TRACE, 449 ("(rpc__gssauth_negotiate_bnd_set_auth)\n")); 450 451 rpc__gssauth_bnd_set_auth(server_name, 452 level, 453 rpc_c_authn_gss_negotiate, 454 auth_ident, 455 authz_prot, 456 binding_h, 457 infop, 458 stp); 459} 460 461INTERNAL void rpc__gssauth_mskrb_bnd_set_auth 462( 463 unsigned_char_p_t server_name, 464 rpc_authn_level_t level, 465 rpc_auth_identity_handle_t auth_ident, 466 rpc_authz_protocol_id_t authz_prot, 467 rpc_binding_handle_t binding_h, 468 rpc_auth_info_p_t *infop, 469 unsigned32 *stp 470) 471{ 472 RPC_DBG_PRINTF(rpc_e_dbg_auth, RPC_C_CN_DBG_AUTH_ROUTINE_TRACE, 473 ("(rpc__gssauth_mskrb_bnd_set_auth)\n")); 474 475 rpc__gssauth_bnd_set_auth(server_name, 476 level, 477 rpc_c_authn_gss_mskrb, 478 auth_ident, 479 authz_prot, 480 binding_h, 481 infop, 482 stp); 483} 484 485INTERNAL void rpc__gssauth_winnt_bnd_set_auth 486( 487 unsigned_char_p_t server_name, 488 rpc_authn_level_t level, 489 rpc_auth_identity_handle_t auth_ident, 490 rpc_authz_protocol_id_t authz_prot, 491 rpc_binding_handle_t binding_h, 492 rpc_auth_info_p_t *infop, 493 unsigned32 *stp 494) 495{ 496 RPC_DBG_PRINTF(rpc_e_dbg_auth, RPC_C_CN_DBG_AUTH_ROUTINE_TRACE, 497 ("(rpc__gssauth_winntmskrb_bnd_set_auth)\n")); 498 499 rpc__gssauth_bnd_set_auth(server_name, 500 level, 501 rpc_c_authn_winnt, 502 auth_ident, 503 authz_prot, 504 binding_h, 505 infop, 506 stp); 507} 508 509INTERNAL void rpc__gssauth_netlogon_bnd_set_auth 510( 511 unsigned_char_p_t server_name, 512 rpc_authn_level_t level, 513 rpc_auth_identity_handle_t auth_ident, 514 rpc_authz_protocol_id_t authz_prot, 515 rpc_binding_handle_t binding_h, 516 rpc_auth_info_p_t *infop, 517 unsigned32 *stp 518) 519{ 520 RPC_DBG_PRINTF(rpc_e_dbg_auth, RPC_C_CN_DBG_AUTH_ROUTINE_TRACE, 521 ("(rpc__gssauth_netlogon_bnd_set_auth)\n")); 522 523 rpc__gssauth_bnd_set_auth(server_name, 524 level, 525 rpc_c_authn_netlogon, 526 auth_ident, 527 authz_prot, 528 binding_h, 529 infop, 530 stp); 531} 532 533INTERNAL void rpc__gssauth_negotiate_init 534( 535 rpc_auth_epv_p_t *epv, 536 rpc_auth_rpc_prot_epv_tbl_t *rpc_prot_epv, 537 unsigned32 *st 538) 539{ 540 unsigned32 prot_id; 541 rpc_auth_rpc_prot_epv_t *prot_epv; 542 543 RPC_DBG_PRINTF(rpc_e_dbg_auth, RPC_C_CN_DBG_AUTH_ROUTINE_TRACE, 544 ("(rpc__gssauth_negotiate_init)\n")); 545 546 /* 547 * Initialize the RPC-protocol-specific EPVs for the RPC protocols 548 * we work with (ncacn). 549 */ 550 /* for now only ncacn, that's what windows uses */ 551 prot_id = rpc__gssauth_negotiate_cn_init (&prot_epv, st); 552 if (*st == rpc_s_ok) { 553 rpc_g_gssauth_negotiate_rpc_prot_epv[prot_id] = prot_epv; 554 } 555 556 /* 557 * Return information for this gss_negotiate (SPNEGO) authentication service. 558 */ 559 *epv = &rpc_g_gssauth_negotiate_epv; 560 *rpc_prot_epv = rpc_g_gssauth_negotiate_rpc_prot_epv; 561 562 *st = 0; 563} 564 565INTERNAL void rpc__gssauth_mskrb_init 566( 567 rpc_auth_epv_p_t *epv, 568 rpc_auth_rpc_prot_epv_tbl_t *rpc_prot_epv, 569 unsigned32 *st 570) 571{ 572 unsigned32 prot_id; 573 rpc_auth_rpc_prot_epv_t *prot_epv; 574 575 RPC_DBG_PRINTF(rpc_e_dbg_auth, RPC_C_CN_DBG_AUTH_ROUTINE_TRACE, 576 ("(rpc__gssauth_mskrb_init)\n")); 577 578 /* 579 * Initialize the RPC-protocol-specific EPVs for the RPC protocols 580 * we work with (ncacn). 581 */ 582 /* for now only ncacn, that's what windows uses */ 583 prot_id = rpc__gssauth_mskrb_cn_init (&prot_epv, st); 584 if (*st == rpc_s_ok) { 585 rpc_g_gssauth_mskrb_rpc_prot_epv[prot_id] = prot_epv; 586 } 587 588 /* 589 * Return information for this (KRB5) authentication service. 590 */ 591 *epv = &rpc_g_gssauth_mskrb_epv; 592 *rpc_prot_epv = rpc_g_gssauth_mskrb_rpc_prot_epv; 593 594 *st = 0; 595} 596 597INTERNAL void rpc__gssauth_winnt_init 598( 599 rpc_auth_epv_p_t *epv, 600 rpc_auth_rpc_prot_epv_tbl_t *rpc_prot_epv, 601 unsigned32 *st 602) 603{ 604 unsigned32 prot_id; 605 rpc_auth_rpc_prot_epv_t *prot_epv; 606 607 RPC_DBG_PRINTF(rpc_e_dbg_auth, RPC_C_CN_DBG_AUTH_ROUTINE_TRACE, 608 ("(rpc__gssauth_winnt_init)\n")); 609 610 /* 611 * Initialize the RPC-protocol-specific EPVs for the RPC protocols 612 * we work with (ncacn). 613 */ 614 /* for now only ncacn, that's what windows uses */ 615 prot_id = rpc__gssauth_winnt_cn_init (&prot_epv, st); 616 if (*st == rpc_s_ok) { 617 rpc_g_gssauth_winnt_rpc_prot_epv[prot_id] = prot_epv; 618 } 619 620 /* 621 * Return information for this (KRB5) authentication service. 622 */ 623 *epv = &rpc_g_gssauth_winnt_epv; 624 *rpc_prot_epv = rpc_g_gssauth_winnt_rpc_prot_epv; 625 626 *st = 0; 627} 628 629INTERNAL void rpc__gssauth_netlogon_init 630( 631 rpc_auth_epv_p_t *epv, 632 rpc_auth_rpc_prot_epv_tbl_t *rpc_prot_epv, 633 unsigned32 *st 634) 635{ 636 unsigned32 prot_id; 637 rpc_auth_rpc_prot_epv_t *prot_epv; 638 639 RPC_DBG_PRINTF(rpc_e_dbg_auth, RPC_C_CN_DBG_AUTH_ROUTINE_TRACE, 640 ("(rpc__gssauth_netlogon_init)\n")); 641 642 /* 643 * Initialize the RPC-protocol-specific EPVs for the RPC protocols 644 * we work with (ncacn). 645 */ 646 /* for now only ncacn, that's what windows uses */ 647 prot_id = rpc__gssauth_netlogon_cn_init (&prot_epv, st); 648 if (*st == rpc_s_ok) { 649 rpc_g_gssauth_netlogon_rpc_prot_epv[prot_id] = prot_epv; 650 } 651 652 /* 653 * Return information for this (KRB5) authentication service. 654 */ 655 *epv = &rpc_g_gssauth_netlogon_epv; 656 *rpc_prot_epv = rpc_g_gssauth_netlogon_rpc_prot_epv; 657 658 *st = 0; 659} 660/* 661 * R P C _ _ G S S A U T H _ F R E E _ I N F O 662 * 663 * Free info. 664 */ 665 666INTERNAL void rpc__gssauth_free_info 667( 668 rpc_auth_info_p_t *info 669) 670{ 671 rpc_gssauth_info_p_t gssauth_info = (rpc_gssauth_info_p_t)*info ; 672 const char *info_type; 673 674 RPC_DBG_PRINTF(rpc_e_dbg_auth, RPC_C_CN_DBG_AUTH_ROUTINE_TRACE, 675 ("(rpc__gssauth_free_info)\n")); 676 677 info_type = (*info)->is_server?"server":"client"; 678 679 if (gssauth_info->auth_info.server_princ_name != NULL) { 680 unsigned32 st; 681 rpc_string_free(&gssauth_info->auth_info.server_princ_name, &st); 682 } 683 684 if (gssauth_info->gss_server_name != GSS_C_NO_NAME) { 685 OM_uint32 min_stat; 686 gss_release_name(&min_stat, &gssauth_info->gss_server_name); 687 gssauth_info->gss_server_name = GSS_C_NO_NAME; 688 } 689 690 if (gssauth_info->gss_creds != GSS_C_NO_CREDENTIAL) { 691 OM_uint32 min_stat; 692 gss_release_cred(&min_stat, &gssauth_info->gss_creds); 693 gssauth_info->gss_creds = GSS_C_NO_CREDENTIAL; 694 } 695 696 memset(gssauth_info, 0x69, sizeof(*gssauth_info)); 697 RPC_MEM_FREE(gssauth_info, RPC_C_MEM_GSSAUTH_INFO); 698 699 rpc_g_gssauth_free_count++; 700 701 RPC_DBG_PRINTF(rpc_e_dbg_auth, RPC_C_CN_DBG_AUTH_GENERAL, 702 ("(rpc__gssauth_free_info) freeing %s auth_info (now %d active).\n", 703 info_type, rpc_g_gssauth_alloc_count - rpc_g_gssauth_free_count)); 704 705 *info = NULL; 706} 707 708/* 709 * R P C _ _ G S S A U T H _ M G T _ I N Q _ D E F 710 * 711 * Return default authentication level 712 * 713 * !!! should read this from a config file. 714 */ 715 716INTERNAL void rpc__gssauth_mgt_inq_def 717( 718 unsigned32 *authn_level, 719 unsigned32 *stp 720) 721{ 722 RPC_DBG_PRINTF(rpc_e_dbg_auth, RPC_C_CN_DBG_AUTH_ROUTINE_TRACE, 723 ("(rpc__gssauth_mgt_inq_def)\n")); 724 725 *authn_level = rpc_c_authn_level_pkt_privacy; 726 *stp = rpc_s_ok; 727} 728 729/* 730 * R P C _ _ G S S A U T H _ S R V _ R E G _ A U T H 731 * 732 */ 733 734INTERNAL void rpc__gssauth_srv_reg_auth 735( 736 unsigned_char_p_t server_name ATTRIBUTE_UNUSED, 737 rpc_auth_key_retrieval_fn_t get_key_func ATTRIBUTE_UNUSED, 738 dce_pointer_t arg ATTRIBUTE_UNUSED, 739 unsigned32 *stp 740) 741{ 742 RPC_DBG_PRINTF(rpc_e_dbg_auth, RPC_C_CN_DBG_AUTH_ROUTINE_TRACE, 743 ("(rpc__gssauth_srv_reg_auth)\n")); 744 745 *stp = rpc_s_ok; 746} 747 748/* 749 * R P C _ _ G S S A U T H _ I N Q _ M Y _ P R I N C _ N A M E 750 * 751 * All this doesn't matter for this module, but we need the placebo. 752 */ 753 754INTERNAL void rpc__gssauth_inq_my_princ_name 755( 756 unsigned32 name_size, 757 unsigned_char_p_t name, 758 unsigned32 *stp 759) 760{ 761 RPC_DBG_PRINTF(rpc_e_dbg_auth, RPC_C_CN_DBG_AUTH_ROUTINE_TRACE, 762 ("(rpc__gssauth_inq_my_princ_name)\n")); 763 764 if (name_size > 0) { 765 rpc__strncpy(name, (unsigned char *)"", name_size - 1); 766 } 767 *stp = rpc_s_ok; 768} 769 770/* 771 * R P C _ _ G S S A U T H _ F R E E _ KEY 772 * 773 * Free key. 774 */ 775 776INTERNAL void rpc__gssauth_free_key 777( 778 rpc_key_info_p_t *info ATTRIBUTE_UNUSED 779) 780{ 781 RPC_DBG_PRINTF(rpc_e_dbg_auth, RPC_C_CN_DBG_AUTH_ROUTINE_TRACE, 782 ("(rpc__gssauth_free_key)\n")); 783} 784 785/* 786 * R P C _ _ G S S A U T H _ R E S O L V E _ I D E N T I T Y 787 * 788 * Resolve identity. 789 */ 790 791INTERNAL error_status_t rpc__gssauth_resolve_identity 792( 793 rpc_auth_identity_handle_t in_identity, 794 rpc_auth_identity_handle_t *out_identity 795) 796{ 797 RPC_DBG_PRINTF(rpc_e_dbg_auth, RPC_C_CN_DBG_AUTH_ROUTINE_TRACE, 798 ("(rpc__gssauth_resolve_identity)\n")); 799 800 *out_identity = in_identity; 801 return 0; 802} 803 804/* 805 * R P C _ _ G S S A U T H _ R E L E A S E _ I D E N T I T Y 806 * 807 * Release identity. 808 */ 809 810INTERNAL void rpc__gssauth_release_identity 811( 812 rpc_auth_identity_handle_t *identity ATTRIBUTE_UNUSED 813) 814{ 815 RPC_DBG_PRINTF(rpc_e_dbg_auth, RPC_C_CN_DBG_AUTH_ROUTINE_TRACE, 816 ("(rpc__gssauth_release_identity)\n")); 817} 818 819void rpc__gssauth_init_func(void) 820{ 821 static rpc_authn_protocol_id_elt_t auth[4] = { 822 { /* 0 */ 823 rpc__gssauth_negotiate_init, 824 rpc_c_authn_gss_negotiate, 825 dce_c_rpc_authn_protocol_gss_negotiate, 826 NULL, 827 rpc_g_gssauth_negotiate_rpc_prot_epv 828 }, 829 { /* 1 */ 830 rpc__gssauth_mskrb_init, 831 rpc_c_authn_gss_mskrb, 832 dce_c_rpc_authn_protocol_gss_mskrb, 833 NULL, 834 rpc_g_gssauth_mskrb_rpc_prot_epv 835 }, 836 { /* 2 */ 837 rpc__gssauth_winnt_init, 838 rpc_c_authn_winnt, 839 dce_c_rpc_authn_protocol_winnt, 840 NULL, 841 rpc_g_gssauth_winnt_rpc_prot_epv 842 }, 843 { /* 3 */ 844 rpc__gssauth_netlogon_init, 845 rpc_c_authn_netlogon, 846 dce_c_rpc_authn_protocol_netlogon, 847 NULL, 848 rpc_g_gssauth_netlogon_rpc_prot_epv 849 } 850 }; 851 852 RPC_DBG_PRINTF(rpc_e_dbg_auth, RPC_C_CN_DBG_AUTH_ROUTINE_TRACE, 853 ("(rpc__module_init_func)\n")); 854 855 rpc__register_authn_protocol(auth, sizeof(auth)/sizeof(auth[0])); 856} 857 858/* 859 * R P C _ _ G S S A U T H _ I N Q _ S E C _ C O N T E X T 860 * 861 * Inq sec context. 862 */ 863 864INTERNAL void rpc__gssauth_inq_sec_context 865( 866 rpc_auth_info_p_t auth_info, 867 void **mech_context, 868 unsigned32 *stp 869) 870{ 871 rpc_gssauth_info_p_t gssauth_info = NULL; 872 rpc_gssauth_cn_info_p_t gssauth_cn_info = NULL; 873 874 RPC_DBG_PRINTF(rpc_e_dbg_auth, RPC_C_CN_DBG_AUTH_ROUTINE_TRACE, 875 ("(rpc__gssauth_inq_sec_context)\n")); 876 877 gssauth_info = (rpc_gssauth_info_p_t)auth_info; 878 gssauth_cn_info = gssauth_info->cn_info; 879 880 *mech_context = (void*)gssauth_cn_info->gss_ctx; 881 *stp = rpc_s_ok; 882} 883 884INTERNAL void rpc__gssauth_inq_access_token( 885 rpc_auth_info_p_t auth_info ATTRIBUTE_UNUSED, 886 rpc_access_token_p_t* token, 887 unsigned32 *stp 888 ) 889{ 890 *token = NULL; 891 *stp = rpc_s_not_supported; 892} 893 894static struct { 895 rpc_authn_protocol_id_t authn_protocol; 896 gss_OID_desc gss_oid; 897} rpc__gssauth_mechanisms[] = { 898 { /* SPNEGO mechanism */ 899 rpc_c_authn_gss_negotiate, 900 { 6, (void *)"\053\006\001\005\005\002" }, 901 }, 902 { /* Kerberos mechanism */ 903 rpc_c_authn_gss_mskrb, 904 { 9, (void *)"\052\206\110\206\367\022\001\002\002" }, 905 }, 906 { /* NTLM mechanism */ 907 rpc_c_authn_winnt, 908 { 10, (void *)"\x2b\x06\x01\x04\x01\x82\x37\x02\x02\x0a" }, 909 }, 910 { /* NetLogon secure channel mechanism (private) */ 911 rpc_c_authn_netlogon, 912 { 6, (void *)"\x2a\x85\x70\x2b\x0e\x02" }, 913 }, 914}; 915 916PRIVATE OM_uint32 rpc__gssauth_select_mech 917( 918 OM_uint32 *min_stat, 919 rpc_authn_protocol_id_t authn_protocol, 920 gss_OID *req_mech 921) 922{ 923 gss_OID selected_mech = GSS_C_NO_OID; 924 size_t i; 925 926 *min_stat = 0; 927 928 for (i = 0; 929 i < sizeof(rpc__gssauth_mechanisms)/sizeof(rpc__gssauth_mechanisms[0]); 930 i++) 931 { 932 if (rpc__gssauth_mechanisms[i].authn_protocol == authn_protocol) { 933 selected_mech = &rpc__gssauth_mechanisms[i].gss_oid; 934 break; 935 } 936 } 937 938 if (selected_mech == GSS_C_NO_OID) 939 return GSS_S_UNAVAILABLE; 940 941 *req_mech = selected_mech; 942 return GSS_S_COMPLETE; 943} 944 945#endif /* defined(AUTH_GSS_NEGOTIATE) && AUTH_GSS_NEGOTIATE */ 946