1/* $OpenLDAP$ */ 2/* This work is part of OpenLDAP Software <http://www.openldap.org/>. 3 * 4 * Copyright 1998-2011 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 19#include "portable.h" 20 21#include <stdio.h> 22#include <ac/stdlib.h> 23 24#include <ac/socket.h> 25#include <ac/string.h> 26#include <ac/time.h> 27 28#include "ldap-int.h" 29 30char * 31ldap_first_attribute( LDAP *ld, LDAPMessage *entry, BerElement **berout ) 32{ 33 int rc; 34 ber_tag_t tag; 35 ber_len_t len = 0; 36 char *attr; 37 BerElement *ber; 38 39 Debug( LDAP_DEBUG_TRACE, "ldap_first_attribute\n", 0, 0, 0 ); 40 41 assert( ld != NULL ); 42 assert( LDAP_VALID( ld ) ); 43 assert( entry != NULL ); 44 assert( berout != NULL ); 45 46 *berout = NULL; 47 48 ber = ldap_alloc_ber_with_options( ld ); 49 if( ber == NULL ) { 50 return NULL; 51 } 52 53 *ber = *entry->lm_ber; 54 55 /* 56 * Skip past the sequence, dn, sequence of sequence leaving 57 * us at the first attribute. 58 */ 59 60 tag = ber_scanf( ber, "{xl{" /*}}*/, &len ); 61 if( tag == LBER_ERROR ) { 62 ld->ld_errno = LDAP_DECODING_ERROR; 63 ber_free( ber, 0 ); 64 return NULL; 65 } 66 67 /* set the length to avoid overrun */ 68 rc = ber_set_option( ber, LBER_OPT_REMAINING_BYTES, &len ); 69 if( rc != LBER_OPT_SUCCESS ) { 70 ld->ld_errno = LDAP_LOCAL_ERROR; 71 ber_free( ber, 0 ); 72 return NULL; 73 } 74 75 if ( ber_pvt_ber_remaining( ber ) == 0 ) { 76 assert( len == 0 ); 77 ber_free( ber, 0 ); 78 return NULL; 79 } 80 assert( len != 0 ); 81 82 /* snatch the first attribute */ 83 tag = ber_scanf( ber, "{ax}", &attr ); 84 if( tag == LBER_ERROR ) { 85 ld->ld_errno = LDAP_DECODING_ERROR; 86 ber_free( ber, 0 ); 87 return NULL; 88 } 89 90 *berout = ber; 91 return attr; 92} 93 94/* ARGSUSED */ 95char * 96ldap_next_attribute( LDAP *ld, LDAPMessage *entry, BerElement *ber ) 97{ 98 ber_tag_t tag; 99 char *attr; 100 101 Debug( LDAP_DEBUG_TRACE, "ldap_next_attribute\n", 0, 0, 0 ); 102 103 assert( ld != NULL ); 104 assert( LDAP_VALID( ld ) ); 105 assert( entry != NULL ); 106 assert( ber != NULL ); 107 108 if ( ber_pvt_ber_remaining( ber ) == 0 ) { 109 return NULL; 110 } 111 112 /* skip sequence, snarf attribute type, skip values */ 113 tag = ber_scanf( ber, "{ax}", &attr ); 114 if( tag == LBER_ERROR ) { 115 ld->ld_errno = LDAP_DECODING_ERROR; 116 return NULL; 117 } 118 119 return attr; 120} 121 122/* Fetch attribute type and optionally fetch values. The type 123 * and values are referenced in-place from the BerElement, they are 124 * not dup'd into malloc'd memory. 125 */ 126/* ARGSUSED */ 127int 128ldap_get_attribute_ber( LDAP *ld, LDAPMessage *entry, BerElement *ber, 129 BerValue *attr, BerVarray *vals ) 130{ 131 ber_tag_t tag; 132 int rc = LDAP_SUCCESS; 133 134 Debug( LDAP_DEBUG_TRACE, "ldap_get_attribute_ber\n", 0, 0, 0 ); 135 136 assert( ld != NULL ); 137 assert( LDAP_VALID( ld ) ); 138 assert( entry != NULL ); 139 assert( ber != NULL ); 140 assert( attr != NULL ); 141 142 attr->bv_val = NULL; 143 attr->bv_len = 0; 144 145 if ( ber_pvt_ber_remaining( ber ) ) { 146 ber_len_t siz = sizeof( BerValue ); 147 148 /* skip sequence, snarf attribute type */ 149 tag = ber_scanf( ber, vals ? "{mM}" : "{mx}", attr, vals, 150 &siz, 0 ); 151 if( tag == LBER_ERROR ) { 152 rc = ld->ld_errno = LDAP_DECODING_ERROR; 153 } 154 } 155 156 return rc; 157} 158