deref.c 5.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289
  1. /* $OpenLDAP$ */
  2. /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  3. *
  4. * Copyright 1998-2022 The OpenLDAP Foundation.
  5. * Portions Copyright 2008 Pierangelo Masarati.
  6. * All rights reserved.
  7. *
  8. * Redistribution and use in source and binary forms, with or without
  9. * modification, are permitted only as authorized by the OpenLDAP
  10. * Public License.
  11. *
  12. * A copy of this license is available in the file LICENSE in the
  13. * top-level directory of the distribution or, alternatively, at
  14. * <http://www.OpenLDAP.org/license.html>.
  15. */
  16. /* ACKNOWLEDGEMENTS:
  17. * This work was initially developed by Pierangelo Masarati
  18. * for inclusion in OpenLDAP Software.
  19. */
  20. #include "portable.h"
  21. #include <stdio.h>
  22. #include <ac/stdlib.h>
  23. #include <ac/string.h>
  24. #include <ac/time.h>
  25. #include "ldap-int.h"
  26. int
  27. ldap_create_deref_control_value(
  28. LDAP *ld,
  29. LDAPDerefSpec *ds,
  30. struct berval *value )
  31. {
  32. BerElement *ber = NULL;
  33. ber_tag_t tag;
  34. int i;
  35. if ( ld == NULL || value == NULL || ds == NULL )
  36. {
  37. if ( ld )
  38. ld->ld_errno = LDAP_PARAM_ERROR;
  39. return LDAP_PARAM_ERROR;
  40. }
  41. assert( LDAP_VALID( ld ) );
  42. value->bv_val = NULL;
  43. value->bv_len = 0;
  44. ld->ld_errno = LDAP_SUCCESS;
  45. ber = ldap_alloc_ber_with_options( ld );
  46. if ( ber == NULL ) {
  47. ld->ld_errno = LDAP_NO_MEMORY;
  48. return ld->ld_errno;
  49. }
  50. tag = ber_printf( ber, "{" /*}*/ );
  51. if ( tag == LBER_ERROR ) {
  52. ld->ld_errno = LDAP_ENCODING_ERROR;
  53. goto done;
  54. }
  55. for ( i = 0; ds[i].derefAttr != NULL; i++ ) {
  56. int j;
  57. tag = ber_printf( ber, "{s{" /*}}*/ , ds[i].derefAttr );
  58. if ( tag == LBER_ERROR ) {
  59. ld->ld_errno = LDAP_ENCODING_ERROR;
  60. goto done;
  61. }
  62. for ( j = 0; ds[i].attributes[j] != NULL; j++ ) {
  63. tag = ber_printf( ber, "s", ds[i].attributes[ j ] );
  64. if ( tag == LBER_ERROR ) {
  65. ld->ld_errno = LDAP_ENCODING_ERROR;
  66. goto done;
  67. }
  68. }
  69. tag = ber_printf( ber, /*{{*/ "}N}" );
  70. if ( tag == LBER_ERROR ) {
  71. ld->ld_errno = LDAP_ENCODING_ERROR;
  72. goto done;
  73. }
  74. }
  75. tag = ber_printf( ber, /*{*/ "}" );
  76. if ( tag == LBER_ERROR ) {
  77. ld->ld_errno = LDAP_ENCODING_ERROR;
  78. goto done;
  79. }
  80. if ( ber_flatten2( ber, value, 1 ) == -1 ) {
  81. ld->ld_errno = LDAP_NO_MEMORY;
  82. }
  83. done:;
  84. if ( ber != NULL ) {
  85. ber_free( ber, 1 );
  86. }
  87. return ld->ld_errno;
  88. }
  89. int
  90. ldap_create_deref_control(
  91. LDAP *ld,
  92. LDAPDerefSpec *ds,
  93. int iscritical,
  94. LDAPControl **ctrlp )
  95. {
  96. struct berval value;
  97. if ( ctrlp == NULL ) {
  98. ld->ld_errno = LDAP_PARAM_ERROR;
  99. return ld->ld_errno;
  100. }
  101. ld->ld_errno = ldap_create_deref_control_value( ld, ds, &value );
  102. if ( ld->ld_errno == LDAP_SUCCESS ) {
  103. ld->ld_errno = ldap_control_create( LDAP_CONTROL_X_DEREF,
  104. iscritical, &value, 0, ctrlp );
  105. if ( ld->ld_errno != LDAP_SUCCESS ) {
  106. LDAP_FREE( value.bv_val );
  107. }
  108. }
  109. return ld->ld_errno;
  110. }
  111. void
  112. ldap_derefresponse_free( LDAPDerefRes *dr )
  113. {
  114. for ( ; dr; ) {
  115. LDAPDerefRes *drnext = dr->next;
  116. LDAPDerefVal *dv;
  117. LDAP_FREE( dr->derefAttr );
  118. LDAP_FREE( dr->derefVal.bv_val );
  119. for ( dv = dr->attrVals; dv; ) {
  120. LDAPDerefVal *dvnext = dv->next;
  121. LDAP_FREE( dv->type );
  122. ber_bvarray_free( dv->vals );
  123. LDAP_FREE( dv );
  124. dv = dvnext;
  125. }
  126. LDAP_FREE( dr );
  127. dr = drnext;
  128. }
  129. }
  130. int
  131. ldap_parse_derefresponse_control(
  132. LDAP *ld,
  133. LDAPControl *ctrl,
  134. LDAPDerefRes **drp2 )
  135. {
  136. BerElementBuffer berbuf;
  137. BerElement *ber = (BerElement *)&berbuf;
  138. ber_tag_t tag;
  139. ber_len_t len;
  140. char *last;
  141. LDAPDerefRes *drhead = NULL, **drp;
  142. if ( ld == NULL || ctrl == NULL || drp2 == NULL ) {
  143. if ( ld )
  144. ld->ld_errno = LDAP_PARAM_ERROR;
  145. return LDAP_PARAM_ERROR;
  146. }
  147. /* Set up a BerElement from the berval returned in the control. */
  148. ber_init2( ber, &ctrl->ldctl_value, 0 );
  149. /* Extract the count and cookie from the control. */
  150. drp = &drhead;
  151. for ( tag = ber_first_element( ber, &len, &last );
  152. tag != LBER_DEFAULT;
  153. tag = ber_next_element( ber, &len, last ) )
  154. {
  155. LDAPDerefRes *dr;
  156. LDAPDerefVal **dvp;
  157. char *last2;
  158. dr = LDAP_CALLOC( 1, sizeof(LDAPDerefRes) );
  159. if ( dr == NULL ) {
  160. ldap_derefresponse_free( drhead );
  161. *drp2 = NULL;
  162. ld->ld_errno = LDAP_NO_MEMORY;
  163. return ld->ld_errno;
  164. }
  165. dvp = &dr->attrVals;
  166. tag = ber_scanf( ber, "{ao", &dr->derefAttr, &dr->derefVal );
  167. if ( tag == LBER_ERROR ) {
  168. goto done;
  169. }
  170. tag = ber_peek_tag( ber, &len );
  171. if ( tag == (LBER_CONSTRUCTED|LBER_CLASS_CONTEXT) ) {
  172. for ( tag = ber_first_element( ber, &len, &last2 );
  173. tag != LBER_DEFAULT;
  174. tag = ber_next_element( ber, &len, last2 ) )
  175. {
  176. LDAPDerefVal *dv;
  177. dv = LDAP_CALLOC( 1, sizeof(LDAPDerefVal) );
  178. if ( dv == NULL ) {
  179. ldap_derefresponse_free( drhead );
  180. LDAP_FREE( dr );
  181. *drp2 = NULL;
  182. ld->ld_errno = LDAP_NO_MEMORY;
  183. return ld->ld_errno;
  184. }
  185. tag = ber_scanf( ber, "{a[W]}", &dv->type, &dv->vals );
  186. if ( tag == LBER_ERROR ) {
  187. goto done;
  188. }
  189. *dvp = dv;
  190. dvp = &dv->next;
  191. }
  192. }
  193. tag = ber_scanf( ber, "}" );
  194. if ( tag == LBER_ERROR ) {
  195. goto done;
  196. }
  197. *drp = dr;
  198. drp = &dr->next;
  199. }
  200. tag = 0;
  201. done:;
  202. if ( tag == LBER_ERROR ) {
  203. if ( drhead != NULL ) {
  204. ldap_derefresponse_free( drhead );
  205. }
  206. *drp2 = NULL;
  207. ld->ld_errno = LDAP_DECODING_ERROR;
  208. } else {
  209. *drp2 = drhead;
  210. ld->ld_errno = LDAP_SUCCESS;
  211. }
  212. return ld->ld_errno;
  213. }
  214. int
  215. ldap_parse_deref_control(
  216. LDAP *ld,
  217. LDAPControl **ctrls,
  218. LDAPDerefRes **drp )
  219. {
  220. LDAPControl *c;
  221. if ( drp == NULL ) {
  222. ld->ld_errno = LDAP_PARAM_ERROR;
  223. return ld->ld_errno;
  224. }
  225. *drp = NULL;
  226. if ( ctrls == NULL ) {
  227. ld->ld_errno = LDAP_CONTROL_NOT_FOUND;
  228. return ld->ld_errno;
  229. }
  230. c = ldap_control_find( LDAP_CONTROL_X_DEREF, ctrls, NULL );
  231. if ( c == NULL ) {
  232. /* No deref control was found. */
  233. ld->ld_errno = LDAP_CONTROL_NOT_FOUND;
  234. return ld->ld_errno;
  235. }
  236. ld->ld_errno = ldap_parse_derefresponse_control( ld, c, drp );
  237. return ld->ld_errno;
  238. }