1 /* $NetBSD: getvalues.c,v 1.2 2020/08/11 13:15:37 christos Exp $ */ 2 3 /* $OpenLDAP$ */ 4 /* This work is part of OpenLDAP Software <http://www.openldap.org/>. 5 * 6 * Copyright 1998-2020 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 <sys/cdefs.h> 22 __RCSID("$NetBSD: getvalues.c,v 1.2 2020/08/11 13:15:37 christos Exp $"); 23 24 #include "portable.h" 25 26 #include <stdio.h> 27 28 #include <ac/stdlib.h> 29 30 #include <ac/ctype.h> 31 #include <ac/socket.h> 32 #include <ac/string.h> 33 #include <ac/time.h> 34 35 #include "ldap-int.h" 36 37 char ** 38 ldap_get_values( LDAP *ld, LDAPMessage *entry, LDAP_CONST char *target ) 39 { 40 BerElement ber; 41 char *attr; 42 int found = 0; 43 char **vals; 44 45 assert( ld != NULL ); 46 assert( LDAP_VALID( ld ) ); 47 assert( entry != NULL ); 48 assert( target != NULL ); 49 50 Debug( LDAP_DEBUG_TRACE, "ldap_get_values\n", 0, 0, 0 ); 51 52 ber = *entry->lm_ber; 53 54 /* skip sequence, dn, sequence of, and snag the first attr */ 55 if ( ber_scanf( &ber, "{x{{a" /*}}}*/, &attr ) == LBER_ERROR ) { 56 ld->ld_errno = LDAP_DECODING_ERROR; 57 return( NULL ); 58 } 59 60 if ( strcasecmp( target, attr ) == 0 ) 61 found = 1; 62 63 /* break out on success, return out on error */ 64 while ( ! found ) { 65 LDAP_FREE(attr); 66 attr = NULL; 67 68 if ( ber_scanf( &ber, /*{*/ "x}{a" /*}*/, &attr ) == LBER_ERROR ) { 69 ld->ld_errno = LDAP_DECODING_ERROR; 70 return( NULL ); 71 } 72 73 if ( strcasecmp( target, attr ) == 0 ) 74 break; 75 76 } 77 78 LDAP_FREE(attr); 79 attr = NULL; 80 81 /* 82 * if we get this far, we've found the attribute and are sitting 83 * just before the set of values. 84 */ 85 86 if ( ber_scanf( &ber, "[v]", &vals ) == LBER_ERROR ) { 87 ld->ld_errno = LDAP_DECODING_ERROR; 88 return( NULL ); 89 } 90 91 return( vals ); 92 } 93 94 struct berval ** 95 ldap_get_values_len( LDAP *ld, LDAPMessage *entry, LDAP_CONST char *target ) 96 { 97 BerElement ber; 98 char *attr; 99 int found = 0; 100 struct berval **vals; 101 102 assert( ld != NULL ); 103 assert( LDAP_VALID( ld ) ); 104 assert( entry != NULL ); 105 assert( target != NULL ); 106 107 Debug( LDAP_DEBUG_TRACE, "ldap_get_values_len\n", 0, 0, 0 ); 108 109 ber = *entry->lm_ber; 110 111 /* skip sequence, dn, sequence of, and snag the first attr */ 112 if ( ber_scanf( &ber, "{x{{a" /* }}} */, &attr ) == LBER_ERROR ) { 113 ld->ld_errno = LDAP_DECODING_ERROR; 114 return( NULL ); 115 } 116 117 if ( strcasecmp( target, attr ) == 0 ) 118 found = 1; 119 120 /* break out on success, return out on error */ 121 while ( ! found ) { 122 LDAP_FREE( attr ); 123 attr = NULL; 124 125 if ( ber_scanf( &ber, /*{*/ "x}{a" /*}*/, &attr ) == LBER_ERROR ) { 126 ld->ld_errno = LDAP_DECODING_ERROR; 127 return( NULL ); 128 } 129 130 if ( strcasecmp( target, attr ) == 0 ) 131 break; 132 } 133 134 LDAP_FREE( attr ); 135 attr = NULL; 136 137 /* 138 * if we get this far, we've found the attribute and are sitting 139 * just before the set of values. 140 */ 141 142 if ( ber_scanf( &ber, "[V]", &vals ) == LBER_ERROR ) { 143 ld->ld_errno = LDAP_DECODING_ERROR; 144 return( NULL ); 145 } 146 147 return( vals ); 148 } 149 150 int 151 ldap_count_values( char **vals ) 152 { 153 int i; 154 155 if ( vals == NULL ) 156 return( 0 ); 157 158 for ( i = 0; vals[i] != NULL; i++ ) 159 ; /* NULL */ 160 161 return( i ); 162 } 163 164 int 165 ldap_count_values_len( struct berval **vals ) 166 { 167 return( ldap_count_values( (char **) vals ) ); 168 } 169 170 void 171 ldap_value_free( char **vals ) 172 { 173 LDAP_VFREE( vals ); 174 } 175 176 void 177 ldap_value_free_len( struct berval **vals ) 178 { 179 ber_bvecfree( vals ); 180 } 181 182 char ** 183 ldap_value_dup( char *const *vals ) 184 { 185 char **new; 186 int i; 187 188 if( vals == NULL ) { 189 return NULL; 190 } 191 192 for( i=0; vals[i]; i++ ) { 193 ; /* Count the number of values */ 194 } 195 196 if( i == 0 ) { 197 return NULL; 198 } 199 200 new = LDAP_MALLOC( (i+1)*sizeof(char *) ); /* Alloc array of pointers */ 201 if( new == NULL ) { 202 return NULL; 203 } 204 205 for( i=0; vals[i]; i++ ) { 206 new[i] = LDAP_STRDUP( vals[i] ); /* Dup each value */ 207 if( new[i] == NULL ) { 208 LDAP_VFREE( new ); 209 return NULL; 210 } 211 } 212 new[i] = NULL; 213 214 return new; 215 } 216 217