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** nsldap.c 82** 83** FACILITY: 84** 85** LDAP RPC locator 86** 87** ABSTRACT: 88** 89** This module supports locating RPC servers in LDAP directories. 90** Note: only a portion of the RPC NS API is implemented, and 91** this support is presently experimental. 92** 93*/ 94 95#if HAVE_CONFIG_H 96#include <config.h> 97#endif 98 99/* #define BUILD_RPC_NS_LDAP 1 */ 100 101#ifdef BUILD_RPC_NS_LDAP 102 103#include <commonp.h> /* Common declarations for all RPC runtime */ 104#include <com.h> /* Common communications services */ 105#include <comp.h> /* Private communications services */ 106 107#include <lber.h> 108#include <ldap.h> 109 110typedef struct rpc_ns_handle_s_t 111{ 112 unsigned32 cursor; 113 unsigned32 count; 114 unsigned_char_p_t *bindings; 115} rpc_ns_handle_rep_t, *rpc_ns_handle_rep_p_t; 116 117/* 118 * Turn a DCE name into an LDAP distinguished name. 119 * This needs to be fixed to support DCE CDS style 120 * names. 121 */ 122static void rpc_ns__ldap_crack_name(unsigned32 entry_name_syntax, 123 unsigned_char_p_t entry_name, 124 unsigned_char_p_t *dn, 125 unsigned32 *status) 126{ 127 switch (entry_name_syntax) { 128 /* /DC=com/DC=padl/DC=nt/CN=RpcServices/CN=foo */ 129 case rpc_c_ns_syntax_x500: { 130 char *tmp; 131 132 tmp = ldap_dcedn2dn(entry_name); 133 if (tmp == NULL) { 134 *status = rpc_s_invalid_name_syntax; 135 } else { 136 *status = rpc_s_ok; 137 *dn = rpc_stralloc(tmp); 138 } 139 } 140 /* CN=foo,CN=RpcServices,DC=nt,DC=padl,DC=com */ 141 case rpc_c_ns_syntax_ldap: 142 *dn = rpc_stralloc(entry_name); 143 break; 144 /* 145 * /.:/foo or 146 * /.../nt.padl.com/foo 147 */ 148 case rpc_c_ns_syntax_default: 149 case rpc_c_ns_syntax_dce: 150 /* need to do something about cell-relative names */ 151 default: 152 *status = rpc_s_unsupported_name_syntax; 153 break; 154 } 155} 156 157/* 158 * Create a new connection to the LDAP server. 159 */ 160static void rpc_ns__ldap_connect_to_server(LDAP **ld, 161 unsigned32 *status) 162{ 163 if (ldap_initialize(ld, "ldapi://") != LDAP_SUCCESS) { 164 *status = rpc_s_name_service_unavailable; 165 } else { 166 *status = rpc_s_ok; 167 } 168 169 if (*status == rpc_s_ok) { 170 if (ldap_sasl_bind_s(*ld, NULL, "EXTERNAL", 171 NULL, NULL, NULL, NULL) != LDAP_SUCCESS) 172 *status = rpc_s_name_service_unavailable; 173 } 174} 175 176/* 177 * Create an LDAP server container entry. 178 */ 179static void rpc_ns__ldap_export_server(LDAP *ld, 180 char *dn, 181 rpc_if_handle_t if_spec, 182 unsigned32 *status 183 ) 184{ 185 unsigned_char_p_t uuid = NULL; 186 rpc_if_id_t if_id; 187 LDAPMod *modV[4]; 188 LDAPMod modRpcNsObjectID, modObjectClass; 189 char *valueRpcNsObjectID[2], *valueObjectClass[3]; 190 191 rpc_if_inq_id(if_spec, &if_id, status); 192 if (*status != rpc_s_ok) { 193 return; 194 } 195 196 uuid_to_string(&if_id.uuid, &uuid, status); 197 if (*status != rpc_s_ok) { 198 return; 199 } 200 201 valueRpcNsObjectID[0] = uuid; 202 valueRpcNsObjectID[1] = NULL; 203 204 modRpcNsObjectID.mod_op = LDAP_MOD_ADD; 205 modRpcNsObjectID.mod_type = "rpcNsObjectID"; 206 modRpcNsObjectID.mod_values = valueRpcNsObjectID; 207 208 valueObjectClass[0] = "rpcServer"; 209 valueObjectClass[1] = "rpcEntry"; 210 valueObjectClass[2] = "top"; 211 212 modObjectClass.mod_op = LDAP_MOD_ADD; 213 modObjectClass.mod_type = "objectClass"; 214 modObjectClass.mod_values = valueObjectClass; 215 216 modV[0] = &modRpcNsObjectID; 217 modV[1] = &modObjectClass; 218 modV[2] = NULL; 219 220 if (ldap_add_s(ld, dn, modV) != LDAP_SUCCESS) { 221 *status = rpc_s_update_failed; 222 } else { 223 *status = rpc_s_ok; 224 } 225 226 rpc_string_free(&uuid, status); 227} 228 229/* 230 * Create or update an LDAP server binding entry. 231 */ 232static void rpc_ns__ldap_export_server_element_ext(LDAP *ld, 233 char *dn, 234 rpc_if_handle_t if_spec, 235 rpc_binding_vector_p_t vec, 236 int modop, 237 unsigned32 *status 238 ) 239{ 240 unsigned_char_p_t uuid = NULL; 241 unsigned_char_p_t interfaceID = NULL; 242 rpc_if_id_t if_id; 243 LDAPMod *modV[4]; 244 LDAPMod modRpcNsInterfaceID, modRpcNsBindings, modObjectClass; 245 char **valueRpcNsBindings = NULL; 246 char *valueRpcNsInterfaceID[2], *valueObjectClass[3]; 247 int rc; 248 unsigned i; 249 250 rpc_if_inq_id(if_spec, &if_id, status); 251 if (*status != rpc_s_ok) { 252 goto out; 253 } 254 255 /* Get the interface ID */ 256 uuid_to_string(&if_id.uuid, &uuid, status); 257 if (*status != rpc_s_ok) { 258 goto out; 259 } 260 261 RPC_MEM_ALLOC(interfaceID, unsigned_char_p_t, 262 strlen(uuid) + sizeof(",65535.65535"), 263 RPC_C_MEM_NSRESOLUTION, RPC_C_MEM_WAITOK); 264 265 sprintf(interfaceID, "%s,%hu.%hu", uuid, 266 if_id.vers_major, if_id.vers_minor); 267 268 valueRpcNsInterfaceID[0] = interfaceID; 269 valueRpcNsInterfaceID[1] = NULL; 270 271 modRpcNsInterfaceID.mod_op = LDAP_MOD_ADD; 272 modRpcNsInterfaceID.mod_type = "rpcNsInterfaceID"; 273 modRpcNsInterfaceID.mod_values = valueRpcNsInterfaceID; 274 275 RPC_MEM_ALLOC(valueRpcNsBindings, char **, 276 (vec->count * sizeof(char *)), 277 RPC_C_MEM_NSRESOLUTION, RPC_C_MEM_WAITOK); 278 memset(valueRpcNsBindings, 0, (vec->count * sizeof(unsigned_char_p_t))); 279 280 for (i = 0; i < vec->count; i++) { 281 rpc_binding_to_string_binding(vec->binding_h[i], 282 (unsigned_char_p_t *)&valueRpcNsBindings[i], status); 283 if (*status != rpc_s_ok) { 284 goto out; 285 } 286 } 287 valueRpcNsBindings[vec->count] = NULL; 288 289 modRpcNsBindings.mod_op = modop; 290 modRpcNsBindings.mod_type = "rpcNsBindings"; 291 modRpcNsBindings.mod_values = valueRpcNsBindings; 292 293 valueObjectClass[0] = "rpcServerElement"; 294 valueObjectClass[1] = "rpcEntry"; 295 valueObjectClass[2] = "top"; 296 297 modObjectClass.mod_op = modop; 298 modObjectClass.mod_type = "objectClass"; 299 modObjectClass.mod_values = valueObjectClass; 300 301 modV[0] = &modRpcNsInterfaceID; 302 modV[1] = &modRpcNsBindings; 303 modV[2] = &modObjectClass; 304 modV[3] = NULL; 305 306 if (modop == LDAP_MOD_ADD) { 307 rc = ldap_add_s(ld, dn, modV); 308 } else { 309 rc = ldap_modify_s(ld, dn, modV); 310 } 311 *status = (rc == LDAP_SUCCESS) ? rpc_s_ok : rpc_s_update_failed; 312 313out: 314 if (uuid != NULL) 315 free(uuid); 316 if (interfaceID != NULL) 317 free(interfaceID); 318 if (valueRpcNsBindings != NULL) { 319 char **p; 320 321 for (p = valueRpcNsBindings; *valueRpcNsBindings != NULL; p++) { 322 unsigned_char_p_t tmp = (unsigned_char_p_t)*p; 323 324 rpc_string_free(&tmp, status); 325 } 326 RPC_MEM_FREE(valueRpcNsBindings, RPC_C_MEM_NSRESOLUTION); 327 } 328} 329 330/* 331 * Create a new named server binding entry. 332 */ 333static void rpc_ns__ldap_export_server_element(LDAP *ld, 334 char *serverDN, 335 rpc_if_handle_t if_spec, 336 rpc_binding_vector_p_t vec, 337 unsigned32 *status 338 ) 339{ 340 unsigned_char_p_t dn = NULL, rdn = NULL; 341 idl_uuid_t rdnUuid; 342 343 /* Just create an arbitary UUID to name this entry. */ 344 uuid_create(&rdnUuid, status); 345 if (*status != rpc_s_ok) { 346 goto out; 347 } 348 349 uuid_to_string(&rdnUuid, &rdn, status); 350 if (*status != rpc_s_ok) { 351 goto out; 352 } 353 354 RPC_MEM_ALLOC(dn, unsigned_char_p_t, 355 strlen(serverDN) + strlen(rdn) + sizeof("CN=,"), 356 RPC_C_MEM_NSRESOLUTION, RPC_C_MEM_WAITOK); 357 358 sprintf(dn, "CN=%s,%s", rdn, serverDN); 359 360 rpc_ns__ldap_export_server_element_ext(ld, dn, if_spec, 361 vec, LDAP_MOD_ADD, status); 362 363out: 364 if (dn != NULL) { 365 RPC_MEM_FREE(dn, RPC_C_MEM_NSRESOLUTION); 366 } 367 368 if (rdn != NULL) { 369 rpc_string_free(&rdn, status); 370 } 371} 372 373static void rpc_ns__ldap_lookup_server_element(LDAP *ld, 374 unsigned_char_p_t serverDN, 375 rpc_if_handle_t if_spec, 376 unsigned_char_p_t *dn, 377 unsigned32 *status) 378{ 379 unsigned_char_p_t filter = NULL; 380 unsigned_char_p_t uuid = NULL; 381 rpc_if_id_t if_id; 382 LDAPMessage *msg = NULL, *e; 383 char *_dn; 384 size_t len; 385 386 rpc_if_inq_id(if_spec, &if_id, status); 387 if (*status != rpc_s_ok) { 388 goto out; 389 } 390 391 /* Get the interface ID */ 392 uuid_to_string(&if_id.uuid, &uuid, status); 393 if (*status != rpc_s_ok) { 394 goto out; 395 } 396 397 len = strlen(uuid); 398 len += sizeof("(&(objectClass=rpcServerElement)(rpcNsInterfaceID=,65535.65535))"); 399 400 RPC_MEM_ALLOC(filter, unsigned_char_p_t, len, 401 RPC_C_MEM_NSRESOLUTION, RPC_C_MEM_WAITOK); 402 403 sprintf(filter, "(&(objectClass=rpcServerElement)(rpcNsInterfaceID=%s,%hu.%hu))", 404 uuid, if_id.vers_major, if_id.vers_minor); 405 406 if (ldap_search_s(ld, serverDN, LDAP_SCOPE_ONELEVEL, 407 filter, NULL, 0, &msg) != LDAP_SUCCESS) { 408 *status = rpc_s_not_found; 409 goto out; 410 } 411 412 e = ldap_first_entry(ld, msg); 413 if (e == NULL) { 414 *status = rpc_s_not_found; 415 goto out; 416 } 417 418 _dn = ldap_get_dn(ld, e); 419 if (dn == NULL) { 420 *status = rpc_s_not_found; 421 goto out; 422 } 423 424 *dn = rpc_stralloc(_dn); 425 ldap_memfree(_dn); 426 427out: 428 if (filter != NULL) { 429 RPC_MEM_FREE(filter, RPC_C_MEM_NSRESOLUTION); 430 } 431 432 if (msg != NULL) { 433 ldap_msgfree(msg); 434 } 435 436 if (uuid != NULL) { 437 rpc_string_free(&uuid, status); 438 } 439} 440 441void rpc_ns_binding_export( 442 /* [in] */ unsigned32 entry_name_syntax, 443 /* [in] */ unsigned_char_p_t entry_name, 444 /* [in] */ rpc_if_handle_t if_spec, 445 /* [in] */ rpc_binding_vector_p_t binding_vector, 446 /* [in] */ uuid_vector_p_t object_uuid_vector ATTRIBUTE_UNUSED, 447 /* [out] */ unsigned32 *status 448) 449{ 450 LDAP *ld = NULL; 451 unsigned_char_p_t elementDN = NULL; 452 unsigned_char_p_t serverDN = NULL; 453 454 rpc_ns__ldap_connect_to_server(&ld, status); 455 if (*status != rpc_s_ok) { 456 goto out; 457 } 458 459 rpc_ns__ldap_crack_name(entry_name_syntax, entry_name, &serverDN, status); 460 if (*status != rpc_s_ok) { 461 goto out; 462 } 463 464 rpc_ns__ldap_lookup_server_element(ld, serverDN, if_spec, &elementDN, status); 465 if (*status != rpc_s_ok) { 466 rpc_ns__ldap_export_server(ld, serverDN, if_spec, status); 467 if (*status == rpc_s_ok) { 468 rpc_ns__ldap_export_server_element(ld, serverDN, 469 if_spec, binding_vector, status); 470 } 471 } else { 472 rpc_ns__ldap_export_server_element_ext(ld, elementDN, if_spec, 473 binding_vector, LDAP_MOD_REPLACE, status); 474 } 475 476out: 477 if (ld != NULL) { 478 ldap_unbind(ld); 479 } 480 if (elementDN != NULL) { 481 RPC_MEM_FREE(elementDN, RPC_C_MEM_NSRESOLUTION); 482 } 483 if (serverDN != NULL) { 484 RPC_MEM_FREE(serverDN, RPC_C_MEM_NSRESOLUTION); 485 } 486} 487 488static void rpc_ns__ldap_import_server_element(LDAP *ld, 489 unsigned_char_p_t serverDN, 490 rpc_if_handle_t if_spec, 491 rpc_ns_handle_t *ctx, 492 unsigned32 *status 493 ) 494{ 495 unsigned_char_p_t filter = NULL; 496 unsigned_char_p_t uuid = NULL; 497 rpc_if_id_t if_id; 498 LDAPMessage *msg = NULL, *e; 499 rpc_ns_handle_rep_t *rep; 500 unsigned_char_p_t *bindings; 501 size_t len; 502 503 rpc_if_inq_id(if_spec, &if_id, status); 504 if (*status != rpc_s_ok) { 505 goto out; 506 } 507 508 /* Get the interface ID */ 509 uuid_to_string(&if_id.uuid, &uuid, status); 510 if (*status != rpc_s_ok) { 511 goto out; 512 } 513 514 len = strlen(uuid); 515 len += sizeof("(&(objectClass=rpcServerElement)(rpcNsInterfaceID=,65535.65535))"); 516 RPC_MEM_ALLOC(filter, unsigned_char_p_t, len, 517 RPC_C_MEM_NSRESOLUTION, RPC_C_MEM_WAITOK); 518 519 sprintf(filter, "(&(objectClass=rpcServerElement)(rpcNsInterfaceID=%s,%hu.%hu))", 520 uuid, if_id.vers_major, if_id.vers_minor); 521 522 if (ldap_search_s(ld, serverDN, LDAP_SCOPE_ONELEVEL, 523 filter, NULL, 0, &msg) != LDAP_SUCCESS) { 524 *status = rpc_s_not_found; 525 goto out; 526 } 527 528 e = ldap_first_entry(ld, msg); 529 if (e == NULL) { 530 *status = rpc_s_not_found; 531 goto out; 532 } 533 534 bindings = (unsigned_char_p_t *)ldap_get_values(ld, e, "rpcNsBindings"); 535 if (bindings == NULL) { 536 *status = rpc_s_not_found; 537 goto out; 538 } 539 540 RPC_MEM_ALLOC(rep, rpc_ns_handle_rep_p_t, 541 sizeof(*rep), 542 RPC_C_MEM_NSRESOLUTION, RPC_C_MEM_WAITOK); 543 544 rep->count = ldap_count_values((char **)bindings); 545 rep->bindings = bindings; 546 rep->cursor = 0; 547 548 *ctx = (rpc_ns_handle_t)rep; 549 *status = rpc_s_ok; 550 551out: 552 if (filter != NULL) { 553 RPC_MEM_FREE(filter, RPC_C_MEM_NSRESOLUTION); 554 } 555 556 if (msg != NULL) { 557 ldap_msgfree(msg); 558 } 559} 560 561void 562rpc_ns_binding_import_begin( 563 /* [in] */ unsigned32 entry_name_syntax, 564 /* [in] */ unsigned_char_p_t entry_name, 565 /* [in] */ rpc_if_handle_t if_spec, 566 /* [in] */ uuid_p_t object_uuid ATTRIBUTE_UNUSED, 567 /* [out] */ rpc_ns_handle_t *import_context, 568 /* [out] */ unsigned32 *status 569) 570{ 571 unsigned_char_p_t serverDN = NULL; 572 LDAP *ld; 573 574 rpc_ns__ldap_connect_to_server(&ld, status); 575 if (*status != rpc_s_ok) { 576 goto out; 577 } 578 579 rpc_ns__ldap_crack_name(entry_name_syntax, entry_name, &serverDN, status); 580 if (*status != rpc_s_ok) { 581 goto out; 582 } 583 584 rpc_ns__ldap_import_server_element(ld, serverDN, if_spec, import_context, status); 585 586out: 587 if (serverDN != NULL) { 588 RPC_MEM_FREE(serverDN, RPC_C_MEM_NSRESOLUTION); 589 } 590 if (ld != NULL) { 591 ldap_unbind(ld); 592 } 593} 594 595void 596rpc_ns_binding_import_done( 597 /* [in, out] */ rpc_ns_handle_t *import_context, 598 /* [out] */ unsigned32 *status 599) 600{ 601 rpc_ns_handle_rep_t *rep = (rpc_ns_handle_rep_t *)import_context; 602 603 if (rep != NULL) { 604 unsigned_char_p_t *p; 605 606 for (p = rep->bindings; *p != NULL; p++) { 607 RPC_MEM_FREE(*p, RPC_C_MEM_NSRESOLUTION); 608 } 609 RPC_MEM_FREE(rep, RPC_C_MEM_NSRESOLUTION); 610 } 611 *status = rpc_s_ok; 612} 613 614void 615rpc_ns_mgmt_handle_set_exp_age( 616 /* [in] */ rpc_ns_handle_t ns_handle ATTRIBUTE_UNUSED, 617 /* [in] */ unsigned32 expiration_age ATTRIBUTE_UNUSED, 618 /* [out] */ unsigned32 *status 619 620) 621{ 622 *status = rpc_s_ok; 623} 624 625void 626rpc_ns_binding_import_next( 627 /* [in] */ rpc_ns_handle_t import_context, 628 /* [out] */ rpc_binding_handle_t *binding, 629 /* [out] */ unsigned32 *status 630 ) 631{ 632 rpc_ns_handle_rep_t *rep = (rpc_ns_handle_rep_t *)import_context; 633 634 if (rep->cursor < rep->count) { 635 rpc_binding_from_string_binding(rep->bindings[rep->cursor], 636 binding, status); 637 rep->cursor++; 638 } else { 639 *status = rpc_s_no_more_bindings; 640 } 641} 642 643void rpc_ns_binding_lookup_begin 644( 645 unsigned32 entry_name_syntax, 646 unsigned_char_p_t entry_name, 647 rpc_if_handle_t if_spec, 648 uuid_p_t object_uuid, 649 unsigned32 binding_max_count ATTRIBUTE_UNUSED, 650 rpc_ns_handle_t *lookup_context, 651 unsigned32 *status 652) 653{ 654 rpc_ns_binding_import_begin(entry_name_syntax, 655 entry_name, 656 if_spec, 657 object_uuid, 658 lookup_context, 659 status); 660} 661 662void rpc_ns_binding_lookup_done 663( 664 rpc_ns_handle_t *lookup_context, 665 unsigned32 *status 666) 667{ 668 rpc_ns_binding_import_done(lookup_context, status); 669} 670 671void rpc_ns_binding_lookup_next 672( 673 rpc_ns_handle_t lookup_context, 674 rpc_binding_vector_p_t *binding_vector, 675 unsigned32 *status 676) 677{ 678 rpc_ns_handle_rep_t *rep = (rpc_ns_handle_rep_t *) lookup_context; 679 680 if (rep->cursor == 0) { 681 unsigned32 size, i; 682 683 size = sizeof(rpc_binding_vector_t); 684 size += (rep->count - 1) * sizeof(rpc_binding_handle_t); 685 RPC_MEM_ALLOC(*binding_vector, rpc_binding_vector_p_t, 686 size, RPC_C_MEM_BINDING_VEC, RPC_C_MEM_WAITOK); 687 688 for (i = 0; i < rep->count; i++) { 689 rpc_binding_from_string_binding(rep->bindings[i], 690 &((*binding_vector)->binding_h[i]), status); 691 } 692 } else { 693 *status = rpc_s_no_more_bindings; 694 } 695} 696 697void rpc_ns_binding_unexport 698( 699 unsigned32 entry_name_syntax, 700 unsigned_char_p_t entry_name, 701 rpc_if_handle_t if_spec, 702 uuid_vector_p_t object_uuid_vector ATTRIBUTE_UNUSED, 703 unsigned32 *status 704) 705{ 706 LDAP *ld = NULL; 707 unsigned_char_p_t elementDN = NULL; 708 unsigned_char_p_t serverDN = NULL; 709 710 rpc_ns__ldap_connect_to_server(&ld, status); 711 if (*status != rpc_s_ok) { 712 goto out; 713 } 714 715 rpc_ns__ldap_crack_name(entry_name_syntax, entry_name, &serverDN, status); 716 if (*status != rpc_s_ok) { 717 goto out; 718 } 719 720 rpc_ns__ldap_lookup_server_element(ld, serverDN, if_spec, &elementDN, status); 721 if (*status == rpc_s_ok) { 722 if (ldap_delete_s(ld, elementDN) != LDAP_SUCCESS) { 723 *status = rpc_s_update_failed; 724 goto out; 725 } 726 } 727 if (ldap_delete_s(ld, serverDN) != LDAP_SUCCESS) { 728 *status = rpc_s_update_failed; 729 goto out; 730 } 731 732 *status = rpc_s_ok; 733 734out: 735 if (ld != NULL) { 736 ldap_unbind(ld); 737 } 738 if (elementDN != NULL) { 739 RPC_MEM_FREE(elementDN, RPC_C_MEM_NSRESOLUTION); 740 } 741 if (serverDN != NULL) { 742 RPC_MEM_FREE(serverDN, RPC_C_MEM_NSRESOLUTION); 743 } 744} 745 746#endif /* BUILD_RPC_NS_LDAP */ 747