add.c 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263
  1. /* add.c */
  2. /* $OpenLDAP$ */
  3. /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  4. *
  5. * Copyright 1998-2022 The OpenLDAP Foundation.
  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. /* Portions Copyright (c) 1990 Regents of the University of Michigan.
  17. * All rights reserved.
  18. */
  19. #include "portable.h"
  20. #include <stdio.h>
  21. #include <ac/socket.h>
  22. #include <ac/string.h>
  23. #include <ac/time.h>
  24. #include "ldap-int.h"
  25. /* An LDAP Add Request/Response looks like this:
  26. * AddRequest ::= [APPLICATION 8] SEQUENCE {
  27. * entry LDAPDN,
  28. * attributes AttributeList }
  29. *
  30. * AttributeList ::= SEQUENCE OF attribute Attribute
  31. *
  32. * Attribute ::= PartialAttribute(WITH COMPONENTS {
  33. * ...,
  34. * vals (SIZE(1..MAX))})
  35. *
  36. * PartialAttribute ::= SEQUENCE {
  37. * type AttributeDescription,
  38. * vals SET OF value AttributeValue }
  39. *
  40. * AttributeDescription ::= LDAPString
  41. * -- Constrained to <attributedescription> [RFC4512]
  42. *
  43. * AttributeValue ::= OCTET STRING
  44. *
  45. * AddResponse ::= [APPLICATION 9] LDAPResult
  46. * (Source: RFC 4511)
  47. */
  48. /*
  49. * ldap_add - initiate an ldap add operation. Parameters:
  50. *
  51. * ld LDAP descriptor
  52. * dn DN of the entry to add
  53. * mods List of attributes for the entry. This is a null-
  54. * terminated array of pointers to LDAPMod structures.
  55. * only the type and values in the structures need be
  56. * filled in.
  57. *
  58. * Example:
  59. * LDAPMod *attrs[] = {
  60. * { 0, "cn", { "babs jensen", "babs", 0 } },
  61. * { 0, "sn", { "jensen", 0 } },
  62. * { 0, "objectClass", { "person", 0 } },
  63. * 0
  64. * }
  65. * msgid = ldap_add( ld, dn, attrs );
  66. */
  67. int
  68. ldap_add( LDAP *ld, LDAP_CONST char *dn, LDAPMod **attrs )
  69. {
  70. int rc;
  71. int msgid;
  72. rc = ldap_add_ext( ld, dn, attrs, NULL, NULL, &msgid );
  73. if ( rc != LDAP_SUCCESS )
  74. return -1;
  75. return msgid;
  76. }
  77. BerElement *
  78. ldap_build_add_req(
  79. LDAP *ld,
  80. const char *dn,
  81. LDAPMod **attrs,
  82. LDAPControl **sctrls,
  83. LDAPControl **cctrls,
  84. ber_int_t *msgidp )
  85. {
  86. BerElement *ber;
  87. int i, rc;
  88. /* create a message to send */
  89. if ( (ber = ldap_alloc_ber_with_options( ld )) == NULL ) {
  90. return( NULL );
  91. }
  92. LDAP_NEXT_MSGID(ld, *msgidp);
  93. rc = ber_printf( ber, "{it{s{", /* '}}}' */
  94. *msgidp, LDAP_REQ_ADD, dn );
  95. if ( rc == -1 ) {
  96. ld->ld_errno = LDAP_ENCODING_ERROR;
  97. ber_free( ber, 1 );
  98. return( NULL );
  99. }
  100. /* allow attrs to be NULL ("touch"; should fail...) */
  101. if ( attrs ) {
  102. /* for each attribute in the entry... */
  103. for ( i = 0; attrs[i] != NULL; i++ ) {
  104. if ( ( attrs[i]->mod_op & LDAP_MOD_BVALUES) != 0 ) {
  105. int j;
  106. if ( attrs[i]->mod_bvalues == NULL ) {
  107. ld->ld_errno = LDAP_PARAM_ERROR;
  108. ber_free( ber, 1 );
  109. return( NULL );
  110. }
  111. for ( j = 0; attrs[i]->mod_bvalues[ j ] != NULL; j++ ) {
  112. if ( attrs[i]->mod_bvalues[ j ]->bv_val == NULL ) {
  113. ld->ld_errno = LDAP_PARAM_ERROR;
  114. ber_free( ber, 1 );
  115. return( NULL );
  116. }
  117. }
  118. rc = ber_printf( ber, "{s[V]N}", attrs[i]->mod_type,
  119. attrs[i]->mod_bvalues );
  120. } else {
  121. if ( attrs[i]->mod_values == NULL ) {
  122. ld->ld_errno = LDAP_PARAM_ERROR;
  123. ber_free( ber, 1 );
  124. return( NULL );
  125. }
  126. rc = ber_printf( ber, "{s[v]N}", attrs[i]->mod_type,
  127. attrs[i]->mod_values );
  128. }
  129. if ( rc == -1 ) {
  130. ld->ld_errno = LDAP_ENCODING_ERROR;
  131. ber_free( ber, 1 );
  132. return( NULL );
  133. }
  134. }
  135. }
  136. if ( ber_printf( ber, /*{{*/ "N}N}" ) == -1 ) {
  137. ld->ld_errno = LDAP_ENCODING_ERROR;
  138. ber_free( ber, 1 );
  139. return( NULL );
  140. }
  141. /* Put Server Controls */
  142. if( ldap_int_put_controls( ld, sctrls, ber ) != LDAP_SUCCESS ) {
  143. ber_free( ber, 1 );
  144. return( NULL );
  145. }
  146. if ( ber_printf( ber, /*{*/ "N}" ) == -1 ) {
  147. ld->ld_errno = LDAP_ENCODING_ERROR;
  148. ber_free( ber, 1 );
  149. return( NULL );
  150. }
  151. return( ber );
  152. }
  153. /*
  154. * ldap_add_ext - initiate an ldap extended add operation. Parameters:
  155. *
  156. * ld LDAP descriptor
  157. * dn DN of the entry to add
  158. * mods List of attributes for the entry. This is a null-
  159. * terminated array of pointers to LDAPMod structures.
  160. * only the type and values in the structures need be
  161. * filled in.
  162. * sctrl Server Controls
  163. * cctrl Client Controls
  164. * msgidp Message ID pointer
  165. *
  166. * Example:
  167. * LDAPMod *attrs[] = {
  168. * { 0, "cn", { "babs jensen", "babs", 0 } },
  169. * { 0, "sn", { "jensen", 0 } },
  170. * { 0, "objectClass", { "person", 0 } },
  171. * 0
  172. * }
  173. * rc = ldap_add_ext( ld, dn, attrs, NULL, NULL, &msgid );
  174. */
  175. int
  176. ldap_add_ext(
  177. LDAP *ld,
  178. LDAP_CONST char *dn,
  179. LDAPMod **attrs,
  180. LDAPControl **sctrls,
  181. LDAPControl **cctrls,
  182. int *msgidp )
  183. {
  184. BerElement *ber;
  185. int rc;
  186. ber_int_t id;
  187. Debug0( LDAP_DEBUG_TRACE, "ldap_add_ext\n" );
  188. assert( ld != NULL );
  189. assert( LDAP_VALID( ld ) );
  190. assert( dn != NULL );
  191. assert( msgidp != NULL );
  192. /* check client controls */
  193. rc = ldap_int_client_controls( ld, cctrls );
  194. if( rc != LDAP_SUCCESS ) return rc;
  195. ber = ldap_build_add_req( ld, dn, attrs, sctrls, cctrls, &id );
  196. if( !ber )
  197. return ld->ld_errno;
  198. /* send the message */
  199. *msgidp = ldap_send_initial_request( ld, LDAP_REQ_ADD, dn, ber, id );
  200. if(*msgidp < 0)
  201. return ld->ld_errno;
  202. return LDAP_SUCCESS;
  203. }
  204. int
  205. ldap_add_ext_s(
  206. LDAP *ld,
  207. LDAP_CONST char *dn,
  208. LDAPMod **attrs,
  209. LDAPControl **sctrls,
  210. LDAPControl **cctrls )
  211. {
  212. int msgid, rc;
  213. LDAPMessage *res;
  214. rc = ldap_add_ext( ld, dn, attrs, sctrls, cctrls, &msgid );
  215. if ( rc != LDAP_SUCCESS )
  216. return( rc );
  217. if ( ldap_result( ld, msgid, LDAP_MSG_ALL, (struct timeval *) NULL, &res ) == -1 || !res )
  218. return( ld->ld_errno );
  219. return( ldap_result2error( ld, res, 1 ) );
  220. }
  221. int
  222. ldap_add_s( LDAP *ld, LDAP_CONST char *dn, LDAPMod **attrs )
  223. {
  224. return ldap_add_ext_s( ld, dn, attrs, NULL, NULL );
  225. }