1*0Sstevel@tonic-gate /* 2*0Sstevel@tonic-gate * 3*0Sstevel@tonic-gate * Portions Copyright %G% Sun Microsystems, Inc. 4*0Sstevel@tonic-gate * All Rights Reserved 5*0Sstevel@tonic-gate * 6*0Sstevel@tonic-gate */ 7*0Sstevel@tonic-gate 8*0Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 9*0Sstevel@tonic-gate 10*0Sstevel@tonic-gate /* 11*0Sstevel@tonic-gate * Copyright (c) 1990 Regents of the University of Michigan. 12*0Sstevel@tonic-gate * All rights reserved. 13*0Sstevel@tonic-gate * 14*0Sstevel@tonic-gate * modify.c 15*0Sstevel@tonic-gate */ 16*0Sstevel@tonic-gate 17*0Sstevel@tonic-gate #ifndef lint 18*0Sstevel@tonic-gate static char copyright[] = "@(#) Copyright (c) 1990 Regents of the University of Michigan.\nAll rights reserved.\n"; 19*0Sstevel@tonic-gate #endif 20*0Sstevel@tonic-gate 21*0Sstevel@tonic-gate #include <stdio.h> 22*0Sstevel@tonic-gate #include <string.h> 23*0Sstevel@tonic-gate 24*0Sstevel@tonic-gate #ifdef MACOS 25*0Sstevel@tonic-gate #include "macos.h" 26*0Sstevel@tonic-gate #endif /* MACOS */ 27*0Sstevel@tonic-gate 28*0Sstevel@tonic-gate #if !defined( MACOS ) && !defined( DOS ) 29*0Sstevel@tonic-gate #include <sys/types.h> 30*0Sstevel@tonic-gate #include <sys/socket.h> 31*0Sstevel@tonic-gate #endif 32*0Sstevel@tonic-gate 33*0Sstevel@tonic-gate #include "lber.h" 34*0Sstevel@tonic-gate #include "ldap.h" 35*0Sstevel@tonic-gate #include "ldap-private.h" 36*0Sstevel@tonic-gate #include "ldap-int.h" 37*0Sstevel@tonic-gate 38*0Sstevel@tonic-gate BerElement * ldap_build_modify_req(LDAP *ld, char *dn, LDAPMod ** mods, LDAPControl **serverctrls) 39*0Sstevel@tonic-gate { 40*0Sstevel@tonic-gate BerElement *ber; 41*0Sstevel@tonic-gate int i, rc; 42*0Sstevel@tonic-gate 43*0Sstevel@tonic-gate /* 44*0Sstevel@tonic-gate * A modify request looks like this: 45*0Sstevel@tonic-gate * ModifyRequest ::= SEQUENCE { 46*0Sstevel@tonic-gate * object DistinguishedName, 47*0Sstevel@tonic-gate * modifications SEQUENCE OF SEQUENCE { 48*0Sstevel@tonic-gate * operation ENUMERATED { 49*0Sstevel@tonic-gate * add (0), 50*0Sstevel@tonic-gate * delete (1), 51*0Sstevel@tonic-gate * replace (2) 52*0Sstevel@tonic-gate * }, 53*0Sstevel@tonic-gate * modification SEQUENCE { 54*0Sstevel@tonic-gate * type AttributeType, 55*0Sstevel@tonic-gate * values SET OF AttributeValue 56*0Sstevel@tonic-gate * } 57*0Sstevel@tonic-gate * } 58*0Sstevel@tonic-gate * } 59*0Sstevel@tonic-gate */ 60*0Sstevel@tonic-gate /* create a message to send */ 61*0Sstevel@tonic-gate if ( (ber = alloc_ber_with_options( ld )) == NULLBER ) { 62*0Sstevel@tonic-gate return( NULLBER ); 63*0Sstevel@tonic-gate } 64*0Sstevel@tonic-gate if ( ber_printf( ber, "{it{s{", ++ld->ld_msgid, LDAP_REQ_MODIFY, dn ) 65*0Sstevel@tonic-gate == -1 ) { 66*0Sstevel@tonic-gate ld->ld_errno = LDAP_ENCODING_ERROR; 67*0Sstevel@tonic-gate ber_free( ber, 1 ); 68*0Sstevel@tonic-gate return( NULLBER ); 69*0Sstevel@tonic-gate } 70*0Sstevel@tonic-gate 71*0Sstevel@tonic-gate /* for each modification to be performed... */ 72*0Sstevel@tonic-gate for ( i = 0; mods[i] != NULL; i++ ) { 73*0Sstevel@tonic-gate if (( mods[i]->mod_op & LDAP_MOD_BVALUES) != 0 ) { 74*0Sstevel@tonic-gate rc = ber_printf( ber, "{e{s[V]}}", 75*0Sstevel@tonic-gate mods[i]->mod_op & ~LDAP_MOD_BVALUES, 76*0Sstevel@tonic-gate mods[i]->mod_type, mods[i]->mod_bvalues ); 77*0Sstevel@tonic-gate } else { 78*0Sstevel@tonic-gate rc = ber_printf( ber, "{e{s[v]}}", mods[i]->mod_op, 79*0Sstevel@tonic-gate mods[i]->mod_type, mods[i]->mod_values ); 80*0Sstevel@tonic-gate } 81*0Sstevel@tonic-gate 82*0Sstevel@tonic-gate if ( rc == -1 ) { 83*0Sstevel@tonic-gate ld->ld_errno = LDAP_ENCODING_ERROR; 84*0Sstevel@tonic-gate ber_free( ber, 1 ); 85*0Sstevel@tonic-gate return( NULLBER ); 86*0Sstevel@tonic-gate } 87*0Sstevel@tonic-gate } 88*0Sstevel@tonic-gate 89*0Sstevel@tonic-gate if ( ber_printf( ber, "}}" ) == -1 ) { 90*0Sstevel@tonic-gate ld->ld_errno = LDAP_ENCODING_ERROR; 91*0Sstevel@tonic-gate ber_free( ber, 1 ); 92*0Sstevel@tonic-gate return( NULLBER ); 93*0Sstevel@tonic-gate } 94*0Sstevel@tonic-gate 95*0Sstevel@tonic-gate /* LDAPv3 */ 96*0Sstevel@tonic-gate /* Code controls if any */ 97*0Sstevel@tonic-gate if (serverctrls && serverctrls[0]) { 98*0Sstevel@tonic-gate if (ldap_controls_code(ber, serverctrls) != LDAP_SUCCESS){ 99*0Sstevel@tonic-gate ld->ld_errno = LDAP_ENCODING_ERROR; 100*0Sstevel@tonic-gate ber_free( ber, 1 ); 101*0Sstevel@tonic-gate return( NULLBER ); 102*0Sstevel@tonic-gate } 103*0Sstevel@tonic-gate } else if (ld->ld_srvctrls && ld->ld_srvctrls[0]) { 104*0Sstevel@tonic-gate /* Otherwise, is there any global server ctrls ? */ 105*0Sstevel@tonic-gate if (ldap_controls_code(ber, ld->ld_srvctrls) != LDAP_SUCCESS){ 106*0Sstevel@tonic-gate ld->ld_errno = LDAP_ENCODING_ERROR; 107*0Sstevel@tonic-gate ber_free( ber, 1 ); 108*0Sstevel@tonic-gate return( NULLBER ); 109*0Sstevel@tonic-gate } 110*0Sstevel@tonic-gate } 111*0Sstevel@tonic-gate 112*0Sstevel@tonic-gate if ( ber_printf( ber, "}" ) == -1 ) { 113*0Sstevel@tonic-gate ld->ld_errno = LDAP_ENCODING_ERROR; 114*0Sstevel@tonic-gate ber_free( ber, 1 ); 115*0Sstevel@tonic-gate return( NULLBER ); 116*0Sstevel@tonic-gate } 117*0Sstevel@tonic-gate return (ber); 118*0Sstevel@tonic-gate } 119*0Sstevel@tonic-gate 120*0Sstevel@tonic-gate /* 121*0Sstevel@tonic-gate * ldap_modify - initiate an ldap (and X.500) modify operation. Parameters: 122*0Sstevel@tonic-gate * 123*0Sstevel@tonic-gate * ld LDAP descriptor 124*0Sstevel@tonic-gate * dn DN of the object to modify 125*0Sstevel@tonic-gate * mods List of modifications to make. This is null-terminated 126*0Sstevel@tonic-gate * array of struct ldapmod's, specifying the modifications 127*0Sstevel@tonic-gate * to perform. 128*0Sstevel@tonic-gate * 129*0Sstevel@tonic-gate * Example: 130*0Sstevel@tonic-gate * LDAPMod *mods[] = { 131*0Sstevel@tonic-gate * { LDAP_MOD_ADD, "cn", { "babs jensen", "babs", 0 } }, 132*0Sstevel@tonic-gate * { LDAP_MOD_REPLACE, "sn", { "jensen", 0 } }, 133*0Sstevel@tonic-gate * 0 134*0Sstevel@tonic-gate * } 135*0Sstevel@tonic-gate * msgid = ldap_modify( ld, dn, mods ); 136*0Sstevel@tonic-gate */ 137*0Sstevel@tonic-gate int 138*0Sstevel@tonic-gate ldap_modify( LDAP *ld, char *dn, LDAPMod **mods ) 139*0Sstevel@tonic-gate { 140*0Sstevel@tonic-gate BerElement *ber; 141*0Sstevel@tonic-gate int rv; 142*0Sstevel@tonic-gate 143*0Sstevel@tonic-gate #ifdef _REENTRANT 144*0Sstevel@tonic-gate LOCK_LDAP(ld); 145*0Sstevel@tonic-gate #endif 146*0Sstevel@tonic-gate 147*0Sstevel@tonic-gate Debug( LDAP_DEBUG_TRACE, catgets(slapdcat, 1, 192, "ldap_modify\n"), 0, 0, 0 ); 148*0Sstevel@tonic-gate 149*0Sstevel@tonic-gate if ((ber = ldap_build_modify_req(ld, dn, mods, NULL)) == NULLBER){ 150*0Sstevel@tonic-gate #ifdef _REENTRANT 151*0Sstevel@tonic-gate UNLOCK_LDAP(ld); 152*0Sstevel@tonic-gate #endif 153*0Sstevel@tonic-gate return (-1); 154*0Sstevel@tonic-gate } 155*0Sstevel@tonic-gate 156*0Sstevel@tonic-gate /* send the message */ 157*0Sstevel@tonic-gate rv = send_initial_request( ld, LDAP_REQ_MODIFY, dn, ber ); 158*0Sstevel@tonic-gate #ifdef _REENTRANT 159*0Sstevel@tonic-gate UNLOCK_LDAP(ld); 160*0Sstevel@tonic-gate #endif 161*0Sstevel@tonic-gate return ( rv ); 162*0Sstevel@tonic-gate } 163*0Sstevel@tonic-gate 164*0Sstevel@tonic-gate int 165*0Sstevel@tonic-gate ldap_modify_s( LDAP *ld, char *dn, LDAPMod **mods ) 166*0Sstevel@tonic-gate { 167*0Sstevel@tonic-gate int msgid; 168*0Sstevel@tonic-gate LDAPMessage *res; 169*0Sstevel@tonic-gate 170*0Sstevel@tonic-gate if ( (msgid = ldap_modify( ld, dn, mods )) == -1 ) 171*0Sstevel@tonic-gate return( ld->ld_errno ); 172*0Sstevel@tonic-gate 173*0Sstevel@tonic-gate if ( ldap_result( ld, msgid, 1, (struct timeval *) NULL, &res ) == -1 ) 174*0Sstevel@tonic-gate return( ld->ld_errno ); 175*0Sstevel@tonic-gate 176*0Sstevel@tonic-gate return( ldap_result2error( ld, res, 1 ) ); 177*0Sstevel@tonic-gate } 178*0Sstevel@tonic-gate 179*0Sstevel@tonic-gate /* ldapv3 API extensions */ 180*0Sstevel@tonic-gate 181*0Sstevel@tonic-gate int ldap_modify_ext(LDAP *ld, char *dn, LDAPMod **mods, 182*0Sstevel@tonic-gate LDAPControl **serverctrls, LDAPControl **clientctrls, int *msgidp) 183*0Sstevel@tonic-gate { 184*0Sstevel@tonic-gate BerElement *ber; 185*0Sstevel@tonic-gate int i, rc; 186*0Sstevel@tonic-gate int rv; 187*0Sstevel@tonic-gate 188*0Sstevel@tonic-gate #ifdef _REENTRANT 189*0Sstevel@tonic-gate LOCK_LDAP(ld); 190*0Sstevel@tonic-gate #endif 191*0Sstevel@tonic-gate 192*0Sstevel@tonic-gate Debug( LDAP_DEBUG_TRACE, catgets(slapdcat, 1, 192, "ldap_modify\n"), 0, 0, 0 ); 193*0Sstevel@tonic-gate 194*0Sstevel@tonic-gate if ((ber = ldap_build_modify_req(ld, dn, mods, serverctrls)) == NULLBER){ 195*0Sstevel@tonic-gate rv = ld->ld_errno; 196*0Sstevel@tonic-gate if (rv == LDAP_SUCCESS) 197*0Sstevel@tonic-gate rv = LDAP_OTHER; 198*0Sstevel@tonic-gate #ifdef _REENTRANT 199*0Sstevel@tonic-gate UNLOCK_LDAP(ld); 200*0Sstevel@tonic-gate #endif 201*0Sstevel@tonic-gate return (rv); 202*0Sstevel@tonic-gate } 203*0Sstevel@tonic-gate 204*0Sstevel@tonic-gate /* send the message */ 205*0Sstevel@tonic-gate rv = send_initial_request( ld, LDAP_REQ_MODIFY, dn, ber ); 206*0Sstevel@tonic-gate if (rv == -1){ 207*0Sstevel@tonic-gate rv = ld->ld_errno; 208*0Sstevel@tonic-gate if (rv == LDAP_SUCCESS){ 209*0Sstevel@tonic-gate rv = LDAP_OTHER; 210*0Sstevel@tonic-gate } 211*0Sstevel@tonic-gate #ifdef _REENTRANT 212*0Sstevel@tonic-gate UNLOCK_LDAP(ld); 213*0Sstevel@tonic-gate #endif 214*0Sstevel@tonic-gate return (rv); 215*0Sstevel@tonic-gate } 216*0Sstevel@tonic-gate *msgidp = rv; 217*0Sstevel@tonic-gate #ifdef _REENTRANT 218*0Sstevel@tonic-gate UNLOCK_LDAP(ld); 219*0Sstevel@tonic-gate #endif 220*0Sstevel@tonic-gate return ( LDAP_SUCCESS ); 221*0Sstevel@tonic-gate } 222*0Sstevel@tonic-gate 223*0Sstevel@tonic-gate 224*0Sstevel@tonic-gate int ldap_modify_ext_s(LDAP *ld, char *dn, LDAPMod **mods, 225*0Sstevel@tonic-gate LDAPControl **serverctrls, LDAPControl **clientctrls) 226*0Sstevel@tonic-gate { 227*0Sstevel@tonic-gate int msgid; 228*0Sstevel@tonic-gate int retcode = LDAP_SUCCESS; 229*0Sstevel@tonic-gate LDAPMessage *res; 230*0Sstevel@tonic-gate 231*0Sstevel@tonic-gate if ((retcode = ldap_modify_ext(ld, dn, mods, serverctrls, clientctrls, &msgid)) != LDAP_SUCCESS) 232*0Sstevel@tonic-gate return (retcode); 233*0Sstevel@tonic-gate if (ldap_result(ld, msgid, 1, (struct timeval *)NULL, &res ) == -1) 234*0Sstevel@tonic-gate return (ld->ld_errno ); 235*0Sstevel@tonic-gate 236*0Sstevel@tonic-gate #ifdef _REENTRANT 237*0Sstevel@tonic-gate LOCK_LDAP(ld); 238*0Sstevel@tonic-gate #endif 239*0Sstevel@tonic-gate retcode = ldap_parse_result(ld, res, &ld->ld_errno, &ld->ld_matched, &ld->ld_error, 240*0Sstevel@tonic-gate &ld->ld_referrals, &ld->ld_ret_ctrls, 1); 241*0Sstevel@tonic-gate if (retcode == LDAP_SUCCESS) 242*0Sstevel@tonic-gate retcode = ld->ld_errno; 243*0Sstevel@tonic-gate #ifdef _REENTRANT 244*0Sstevel@tonic-gate UNLOCK_LDAP(ld); 245*0Sstevel@tonic-gate #endif 246*0Sstevel@tonic-gate return (retcode); 247*0Sstevel@tonic-gate } 248*0Sstevel@tonic-gate 249