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