references.c 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147
  1. /* references.c */
  2. /* $OpenLDAP$ */
  3. /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  4. *
  5. * Copyright 1998-2022 The OpenLDAP Foundation.
  6. * All rights reserved.
  7. *
  8. * Redistribution and use in source and binary forms, with or without
  9. * modification, are permitted only as authorized by the OpenLDAP
  10. * Public License.
  11. *
  12. * A copy of this license is available in the file LICENSE in the
  13. * top-level directory of the distribution or, alternatively, at
  14. * <http://www.OpenLDAP.org/license.html>.
  15. */
  16. #include "portable.h"
  17. #include <stdio.h>
  18. #include <ac/stdlib.h>
  19. #include <ac/socket.h>
  20. #include <ac/string.h>
  21. #include <ac/time.h>
  22. #include "ldap-int.h"
  23. LDAPMessage *
  24. ldap_first_reference( LDAP *ld, LDAPMessage *chain )
  25. {
  26. assert( ld != NULL );
  27. assert( LDAP_VALID( ld ) );
  28. assert( chain != NULL );
  29. return chain->lm_msgtype == LDAP_RES_SEARCH_REFERENCE
  30. ? chain
  31. : ldap_next_reference( ld, chain );
  32. }
  33. LDAPMessage *
  34. ldap_next_reference( LDAP *ld, LDAPMessage *ref )
  35. {
  36. assert( ld != NULL );
  37. assert( LDAP_VALID( ld ) );
  38. assert( ref != NULL );
  39. for (
  40. ref = ref->lm_chain;
  41. ref != NULL;
  42. ref = ref->lm_chain )
  43. {
  44. if( ref->lm_msgtype == LDAP_RES_SEARCH_REFERENCE ) {
  45. return( ref );
  46. }
  47. }
  48. return( NULL );
  49. }
  50. int
  51. ldap_count_references( LDAP *ld, LDAPMessage *chain )
  52. {
  53. int i;
  54. assert( ld != NULL );
  55. assert( LDAP_VALID( ld ) );
  56. for ( i = 0; chain != NULL; chain = chain->lm_chain ) {
  57. if( chain->lm_msgtype == LDAP_RES_SEARCH_REFERENCE ) {
  58. i++;
  59. }
  60. }
  61. return( i );
  62. }
  63. int
  64. ldap_parse_reference(
  65. LDAP *ld,
  66. LDAPMessage *ref,
  67. char ***referralsp,
  68. LDAPControl ***serverctrls,
  69. int freeit)
  70. {
  71. BerElement be;
  72. char **refs = NULL;
  73. int rc;
  74. assert( ld != NULL );
  75. assert( LDAP_VALID( ld ) );
  76. assert( ref != NULL );
  77. if( ref->lm_msgtype != LDAP_RES_SEARCH_REFERENCE ) {
  78. return LDAP_PARAM_ERROR;
  79. }
  80. /* make a private copy of BerElement */
  81. AC_MEMCPY(&be, ref->lm_ber, sizeof(be));
  82. if ( ber_scanf( &be, "{v" /*}*/, &refs ) == LBER_ERROR ) {
  83. rc = LDAP_DECODING_ERROR;
  84. goto free_and_return;
  85. }
  86. if ( serverctrls == NULL ) {
  87. rc = LDAP_SUCCESS;
  88. goto free_and_return;
  89. }
  90. if ( ber_scanf( &be, /*{*/ "}" ) == LBER_ERROR ) {
  91. rc = LDAP_DECODING_ERROR;
  92. goto free_and_return;
  93. }
  94. rc = ldap_pvt_get_controls( &be, serverctrls );
  95. free_and_return:
  96. if( referralsp != NULL ) {
  97. /* provide references regardless of return code */
  98. *referralsp = refs;
  99. } else {
  100. LDAP_VFREE( refs );
  101. }
  102. if( freeit ) {
  103. ldap_msgfree( ref );
  104. }
  105. if( rc != LDAP_SUCCESS ) {
  106. ld->ld_errno = rc;
  107. if( ld->ld_matched != NULL ) {
  108. LDAP_FREE( ld->ld_matched );
  109. ld->ld_matched = NULL;
  110. }
  111. if( ld->ld_error != NULL ) {
  112. LDAP_FREE( ld->ld_error );
  113. ld->ld_error = NULL;
  114. }
  115. }
  116. return rc;
  117. }