getattr.c 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157
  1. /* $OpenLDAP$ */
  2. /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  3. *
  4. * Copyright 1998-2022 The OpenLDAP Foundation.
  5. * All rights reserved.
  6. *
  7. * Redistribution and use in source and binary forms, with or without
  8. * modification, are permitted only as authorized by the OpenLDAP
  9. * Public License.
  10. *
  11. * A copy of this license is available in the file LICENSE in the
  12. * top-level directory of the distribution or, alternatively, at
  13. * <http://www.OpenLDAP.org/license.html>.
  14. */
  15. /* Portions Copyright (c) 1990 Regents of the University of Michigan.
  16. * All rights reserved.
  17. */
  18. #include "portable.h"
  19. #include <stdio.h>
  20. #include <ac/stdlib.h>
  21. #include <ac/socket.h>
  22. #include <ac/string.h>
  23. #include <ac/time.h>
  24. #include "ldap-int.h"
  25. char *
  26. ldap_first_attribute( LDAP *ld, LDAPMessage *entry, BerElement **berout )
  27. {
  28. int rc;
  29. ber_tag_t tag;
  30. ber_len_t len = 0;
  31. char *attr;
  32. BerElement *ber;
  33. Debug0( LDAP_DEBUG_TRACE, "ldap_first_attribute\n" );
  34. assert( ld != NULL );
  35. assert( LDAP_VALID( ld ) );
  36. assert( entry != NULL );
  37. assert( berout != NULL );
  38. *berout = NULL;
  39. ber = ldap_alloc_ber_with_options( ld );
  40. if( ber == NULL ) {
  41. return NULL;
  42. }
  43. *ber = *entry->lm_ber;
  44. /*
  45. * Skip past the sequence, dn, sequence of sequence leaving
  46. * us at the first attribute.
  47. */
  48. tag = ber_scanf( ber, "{xl{" /*}}*/, &len );
  49. if( tag == LBER_ERROR ) {
  50. ld->ld_errno = LDAP_DECODING_ERROR;
  51. ber_free( ber, 0 );
  52. return NULL;
  53. }
  54. /* set the length to avoid overrun */
  55. rc = ber_set_option( ber, LBER_OPT_REMAINING_BYTES, &len );
  56. if( rc != LBER_OPT_SUCCESS ) {
  57. ld->ld_errno = LDAP_LOCAL_ERROR;
  58. ber_free( ber, 0 );
  59. return NULL;
  60. }
  61. if ( ber_pvt_ber_remaining( ber ) == 0 ) {
  62. assert( len == 0 );
  63. ber_free( ber, 0 );
  64. return NULL;
  65. }
  66. assert( len != 0 );
  67. /* snatch the first attribute */
  68. tag = ber_scanf( ber, "{ax}", &attr );
  69. if( tag == LBER_ERROR ) {
  70. ld->ld_errno = LDAP_DECODING_ERROR;
  71. ber_free( ber, 0 );
  72. return NULL;
  73. }
  74. *berout = ber;
  75. return attr;
  76. }
  77. /* ARGSUSED */
  78. char *
  79. ldap_next_attribute( LDAP *ld, LDAPMessage *entry, BerElement *ber )
  80. {
  81. ber_tag_t tag;
  82. char *attr;
  83. Debug0( LDAP_DEBUG_TRACE, "ldap_next_attribute\n" );
  84. assert( ld != NULL );
  85. assert( LDAP_VALID( ld ) );
  86. assert( entry != NULL );
  87. assert( ber != NULL );
  88. if ( ber_pvt_ber_remaining( ber ) == 0 ) {
  89. return NULL;
  90. }
  91. /* skip sequence, snarf attribute type, skip values */
  92. tag = ber_scanf( ber, "{ax}", &attr );
  93. if( tag == LBER_ERROR ) {
  94. ld->ld_errno = LDAP_DECODING_ERROR;
  95. return NULL;
  96. }
  97. return attr;
  98. }
  99. /* Fetch attribute type and optionally fetch values. The type
  100. * and values are referenced in-place from the BerElement, they are
  101. * not dup'd into malloc'd memory.
  102. */
  103. /* ARGSUSED */
  104. int
  105. ldap_get_attribute_ber( LDAP *ld, LDAPMessage *entry, BerElement *ber,
  106. BerValue *attr, BerVarray *vals )
  107. {
  108. ber_tag_t tag;
  109. int rc = LDAP_SUCCESS;
  110. Debug0( LDAP_DEBUG_TRACE, "ldap_get_attribute_ber\n" );
  111. assert( ld != NULL );
  112. assert( LDAP_VALID( ld ) );
  113. assert( entry != NULL );
  114. assert( ber != NULL );
  115. assert( attr != NULL );
  116. attr->bv_val = NULL;
  117. attr->bv_len = 0;
  118. if ( ber_pvt_ber_remaining( ber ) ) {
  119. ber_len_t siz = sizeof( BerValue );
  120. /* skip sequence, snarf attribute type */
  121. tag = ber_scanf( ber, vals ? "{mM}" : "{mx}", attr, vals,
  122. &siz, (ber_len_t)0 );
  123. if( tag == LBER_ERROR ) {
  124. rc = ld->ld_errno = LDAP_DECODING_ERROR;
  125. }
  126. }
  127. return rc;
  128. }