xref: /netbsd-src/external/bsd/openldap/dist/libraries/libldap/getattr.c (revision b1c86f5f087524e68db12794ee9c3e3da1ab17a0)
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