xref: /netbsd-src/external/bsd/openldap/dist/libraries/libldap/getattr.c (revision 404fbe5fb94ca1e054339640cabb2801ce52dd30)
1 /* $OpenLDAP: pkg/ldap/libraries/libldap/getattr.c,v 1.35.2.3 2008/02/11 23:26:41 kurt Exp $ */
2 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
3  *
4  * Copyright 1998-2008 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 
30 char *
31 ldap_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 */
95 char *
96 ldap_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 */
127 int
128 ldap_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