1*0Sstevel@tonic-gate /* 2*0Sstevel@tonic-gate * Copyright 2003 Sun Microsystems, Inc. All rights reserved. 3*0Sstevel@tonic-gate * Use is subject to license terms. 4*0Sstevel@tonic-gate */ 5*0Sstevel@tonic-gate 6*0Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 7*0Sstevel@tonic-gate 8*0Sstevel@tonic-gate /* 9*0Sstevel@tonic-gate * The contents of this file are subject to the Netscape Public 10*0Sstevel@tonic-gate * License Version 1.1 (the "License"); you may not use this file 11*0Sstevel@tonic-gate * except in compliance with the License. You may obtain a copy of 12*0Sstevel@tonic-gate * the License at http://www.mozilla.org/NPL/ 13*0Sstevel@tonic-gate * 14*0Sstevel@tonic-gate * Software distributed under the License is distributed on an "AS 15*0Sstevel@tonic-gate * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or 16*0Sstevel@tonic-gate * implied. See the License for the specific language governing 17*0Sstevel@tonic-gate * rights and limitations under the License. 18*0Sstevel@tonic-gate * 19*0Sstevel@tonic-gate * The Original Code is Mozilla Communicator client code, released 20*0Sstevel@tonic-gate * March 31, 1998. 21*0Sstevel@tonic-gate * 22*0Sstevel@tonic-gate * The Initial Developer of the Original Code is Netscape 23*0Sstevel@tonic-gate * Communications Corporation. Portions created by Netscape are 24*0Sstevel@tonic-gate * Copyright (C) 1998-1999 Netscape Communications Corporation. All 25*0Sstevel@tonic-gate * Rights Reserved. 26*0Sstevel@tonic-gate * 27*0Sstevel@tonic-gate * Contributor(s): 28*0Sstevel@tonic-gate */ 29*0Sstevel@tonic-gate 30*0Sstevel@tonic-gate /* ldapmodify.c - generic program to modify or add entries using LDAP */ 31*0Sstevel@tonic-gate 32*0Sstevel@tonic-gate #include "ldaptool.h" 33*0Sstevel@tonic-gate #include "fileurl.h" 34*0Sstevel@tonic-gate 35*0Sstevel@tonic-gate #ifdef SOLARIS_LDAP_CMD 36*0Sstevel@tonic-gate #include <locale.h> 37*0Sstevel@tonic-gate #include "ldif.h" 38*0Sstevel@tonic-gate #endif /* SOLARIS_LDAP_CMD */ 39*0Sstevel@tonic-gate 40*0Sstevel@tonic-gate #ifndef SOLARIS_LDAP_CMD 41*0Sstevel@tonic-gate #define gettext(s) s 42*0Sstevel@tonic-gate #endif 43*0Sstevel@tonic-gate 44*0Sstevel@tonic-gate static int newval, contoper, force, valsfromfiles, display_binary_values; 45*0Sstevel@tonic-gate static int ldif_version = -1; /* -1 => unknown version */ 46*0Sstevel@tonic-gate static char *rejfile = NULL; 47*0Sstevel@tonic-gate static char *bulkimport_suffix = NULL; 48*0Sstevel@tonic-gate static int ldapmodify_quiet = 0; 49*0Sstevel@tonic-gate 50*0Sstevel@tonic-gate #ifdef SOLARIS_LDAP_CMD 51*0Sstevel@tonic-gate static int error = 0, replace, nbthreads = 1; 52*0Sstevel@tonic-gate static int thr_create_errors = 0; 53*0Sstevel@tonic-gate static pthread_mutex_t read_mutex = {0}; 54*0Sstevel@tonic-gate static pthread_mutex_t wait_mutex = {0}; 55*0Sstevel@tonic-gate static pthread_cond_t wait_cond = {0}; 56*0Sstevel@tonic-gate #else 57*0Sstevel@tonic-gate /* 58*0Sstevel@tonic-gate * For Solaris, ld is defined local to process() because 59*0Sstevel@tonic-gate * multiple threads restricts Solaris from using a global 60*0Sstevel@tonic-gate * ld variable. 61*0Sstevel@tonic-gate * Solaris uses multiple threads to create multiple 62*0Sstevel@tonic-gate * ldap connections if nbthreads > 1 (i.e -l option). 63*0Sstevel@tonic-gate */ 64*0Sstevel@tonic-gate static LDAP *ld; 65*0Sstevel@tonic-gate #endif /* SOLARIS_LDAP_CMD */ 66*0Sstevel@tonic-gate 67*0Sstevel@tonic-gate #define LDAPMOD_MAXLINE 4096 68*0Sstevel@tonic-gate 69*0Sstevel@tonic-gate /* strings found in replog/LDIF entries (mostly lifted from slurpd/slurp.h) */ 70*0Sstevel@tonic-gate #define T_REPLICA_STR "replica" 71*0Sstevel@tonic-gate #define T_DN_STR "dn" 72*0Sstevel@tonic-gate #define T_VERSION_STR "version" 73*0Sstevel@tonic-gate #define T_CHANGETYPESTR "changetype" 74*0Sstevel@tonic-gate #define T_ADDCTSTR "add" 75*0Sstevel@tonic-gate #define T_MODIFYCTSTR "modify" 76*0Sstevel@tonic-gate #define T_DELETECTSTR "delete" 77*0Sstevel@tonic-gate #define T_RENAMECTSTR "rename" /* non-standard */ 78*0Sstevel@tonic-gate #define T_MODDNCTSTR "moddn" 79*0Sstevel@tonic-gate #define T_MODRDNCTSTR "modrdn" 80*0Sstevel@tonic-gate #define T_MODOPADDSTR "add" 81*0Sstevel@tonic-gate #define T_MODOPREPLACESTR "replace" 82*0Sstevel@tonic-gate #define T_MODOPDELETESTR "delete" 83*0Sstevel@tonic-gate #define T_MODSEPSTR "-" 84*0Sstevel@tonic-gate #define T_NEWRDNSTR "newrdn" 85*0Sstevel@tonic-gate #define T_NEWSUPERIORSTR "newsuperior" 86*0Sstevel@tonic-gate #define T_NEWPARENTSTR "newparent" 87*0Sstevel@tonic-gate #define T_DELETEOLDRDNSTR "deleteoldrdn" 88*0Sstevel@tonic-gate #define T_NEWSUPERIORSTR "newsuperior" 89*0Sstevel@tonic-gate #define T_NEWPARENTSTR "newparent" /* non-standard */ 90*0Sstevel@tonic-gate 91*0Sstevel@tonic-gate /* bulk import */ 92*0Sstevel@tonic-gate #define BULKIMPORT_START_OID "2.16.840.1.113730.3.5.7" 93*0Sstevel@tonic-gate #define BULKIMPORT_STOP_OID "2.16.840.1.113730.3.5.8" 94*0Sstevel@tonic-gate 95*0Sstevel@tonic-gate static int process( void *arg ); 96*0Sstevel@tonic-gate static void options_callback( int option, char *optarg ); 97*0Sstevel@tonic-gate static void addmodifyop( LDAPMod ***pmodsp, int modop, char *attr, 98*0Sstevel@tonic-gate char *value, int vlen ); 99*0Sstevel@tonic-gate static void freepmods( LDAPMod **pmods ); 100*0Sstevel@tonic-gate static char *read_one_record( FILE *fp ); 101*0Sstevel@tonic-gate static char *strdup_and_trim( char *s ); 102*0Sstevel@tonic-gate 103*0Sstevel@tonic-gate #ifdef SOLARIS_LDAP_CMD 104*0Sstevel@tonic-gate static int process_ldapmod_rec( LDAP *ld, char *rbuf ); 105*0Sstevel@tonic-gate static int process_ldif_rec( LDAP *ld, char *rbuf ); 106*0Sstevel@tonic-gate static int domodify( LDAP *ld, char *dn, LDAPMod **pmods, int newentry ); 107*0Sstevel@tonic-gate static int dodelete( LDAP *ld, char *dn ); 108*0Sstevel@tonic-gate static int dorename( LDAP *ld, char *dn, char *newrdn, char *newparent, 109*0Sstevel@tonic-gate int deleteoldrdn ); 110*0Sstevel@tonic-gate #else 111*0Sstevel@tonic-gate static int process_ldapmod_rec( char *rbuf ); 112*0Sstevel@tonic-gate static int process_ldif_rec( char *rbuf ); 113*0Sstevel@tonic-gate static int domodify( char *dn, LDAPMod **pmods, int newentry ); 114*0Sstevel@tonic-gate static int dodelete( char *dn ); 115*0Sstevel@tonic-gate static int dorename( char *dn, char *newrdn, char *newparent, 116*0Sstevel@tonic-gate int deleteoldrdn ); 117*0Sstevel@tonic-gate #endif /* SOLARIS_LDAP_CMD */ 118*0Sstevel@tonic-gate 119*0Sstevel@tonic-gate static void 120*0Sstevel@tonic-gate usage( void ) 121*0Sstevel@tonic-gate { 122*0Sstevel@tonic-gate fprintf( stderr, gettext("usage: %s [options]\n"), ldaptool_progname ); 123*0Sstevel@tonic-gate fprintf( stderr, gettext("options:\n") ); 124*0Sstevel@tonic-gate ldaptool_common_usage( 0 ); 125*0Sstevel@tonic-gate fprintf( stderr, gettext(" -c\t\tcontinuous mode (do not stop on errors)\n") ); 126*0Sstevel@tonic-gate fprintf( stderr, gettext(" -A\t\tdisplay non-ASCII values in conjunction with -v\n") ); 127*0Sstevel@tonic-gate fprintf( stderr, gettext(" -f file\tread modifications from file (default: standard input)\n") ); 128*0Sstevel@tonic-gate if ( strcmp( ldaptool_progname, "ldapmodify" ) == 0 ){ 129*0Sstevel@tonic-gate fprintf( stderr, gettext(" -a\t\tadd entries\n") ); 130*0Sstevel@tonic-gate } 131*0Sstevel@tonic-gate fprintf( stderr, gettext(" -b\t\tread values that start with / from files (for bin attrs)\n") ); 132*0Sstevel@tonic-gate fprintf( stderr, gettext(" -F\t\tforce application of all changes, regardless of\n") ); 133*0Sstevel@tonic-gate fprintf( stderr, gettext(" \t\treplica lines\n") ); 134*0Sstevel@tonic-gate fprintf( stderr, gettext(" -e rejfile\tsave rejected entries in \"rejfile\"\n") ); 135*0Sstevel@tonic-gate fprintf( stderr, gettext(" -B suffix\tbulk import to \"suffix\"\n")); 136*0Sstevel@tonic-gate fprintf( stderr, gettext(" -q\t\tbe quiet when adding/modifying entries\n") ); 137*0Sstevel@tonic-gate #ifdef SOLARIS_LDAP_CMD 138*0Sstevel@tonic-gate fprintf( stderr, gettext(" -r\t\treplace values\n")); 139*0Sstevel@tonic-gate fprintf( stderr, gettext(" -l nb-connections\tnumber of LDAP connections\n")); 140*0Sstevel@tonic-gate #endif /* SOLARIS_LDAP_CMD */ 141*0Sstevel@tonic-gate exit( LDAP_PARAM_ERROR ); 142*0Sstevel@tonic-gate } 143*0Sstevel@tonic-gate 144*0Sstevel@tonic-gate 145*0Sstevel@tonic-gate int 146*0Sstevel@tonic-gate main( int argc, char **argv ) 147*0Sstevel@tonic-gate { 148*0Sstevel@tonic-gate int optind, i; 149*0Sstevel@tonic-gate 150*0Sstevel@tonic-gate #ifdef SOLARIS_LDAP_CMD 151*0Sstevel@tonic-gate char *locale = setlocale(LC_ALL, ""); 152*0Sstevel@tonic-gate textdomain(TEXT_DOMAIN); 153*0Sstevel@tonic-gate #endif 154*0Sstevel@tonic-gate 155*0Sstevel@tonic-gate #ifdef notdef 156*0Sstevel@tonic-gate #ifdef HPUX11 157*0Sstevel@tonic-gate #ifndef __LP64__ 158*0Sstevel@tonic-gate _main( argc, argv); 159*0Sstevel@tonic-gate #endif /* __LP64_ */ 160*0Sstevel@tonic-gate #endif /* HPUX11 */ 161*0Sstevel@tonic-gate #endif 162*0Sstevel@tonic-gate 163*0Sstevel@tonic-gate valsfromfiles = display_binary_values = 0; 164*0Sstevel@tonic-gate 165*0Sstevel@tonic-gate #ifdef SOLARIS_LDAP_CMD 166*0Sstevel@tonic-gate optind = ldaptool_process_args( argc, argv, "aAbcFe:B:qrl:", 0, 167*0Sstevel@tonic-gate options_callback ); 168*0Sstevel@tonic-gate #else 169*0Sstevel@tonic-gate optind = ldaptool_process_args( argc, argv, "aAbcFe:B:q", 0, 170*0Sstevel@tonic-gate options_callback ); 171*0Sstevel@tonic-gate #endif /* SOLARIS_LDAP_CMD */ 172*0Sstevel@tonic-gate 173*0Sstevel@tonic-gate 174*0Sstevel@tonic-gate if ( optind == -1 ) { 175*0Sstevel@tonic-gate usage(); 176*0Sstevel@tonic-gate } 177*0Sstevel@tonic-gate 178*0Sstevel@tonic-gate if ( !newval && strcmp( ldaptool_progname, "ldapadd" ) == 0 ) { 179*0Sstevel@tonic-gate newval = 1; 180*0Sstevel@tonic-gate } 181*0Sstevel@tonic-gate 182*0Sstevel@tonic-gate if ( ldaptool_fp == NULL ) { 183*0Sstevel@tonic-gate ldaptool_fp = stdin; 184*0Sstevel@tonic-gate } 185*0Sstevel@tonic-gate 186*0Sstevel@tonic-gate if ( argc - optind != 0 ) { 187*0Sstevel@tonic-gate usage(); 188*0Sstevel@tonic-gate } 189*0Sstevel@tonic-gate 190*0Sstevel@tonic-gate #ifdef SOLARIS_LDAP_CMD 191*0Sstevel@tonic-gate /* trivial case */ 192*0Sstevel@tonic-gate if ( nbthreads == 1 ) 193*0Sstevel@tonic-gate return ( process(NULL) ); 194*0Sstevel@tonic-gate 195*0Sstevel@tonic-gate for ( i=0; i<nbthreads; ++i ) { 196*0Sstevel@tonic-gate if ( thr_create(NULL, 0, process, NULL, NULL, NULL) != 0 ) 197*0Sstevel@tonic-gate ++thr_create_errors; 198*0Sstevel@tonic-gate } 199*0Sstevel@tonic-gate 200*0Sstevel@tonic-gate if ( thr_create_errors < nbthreads ) 201*0Sstevel@tonic-gate while ( thr_join(0, NULL, NULL) == 0 ); 202*0Sstevel@tonic-gate else 203*0Sstevel@tonic-gate error = -1; 204*0Sstevel@tonic-gate return ( error ); 205*0Sstevel@tonic-gate #else 206*0Sstevel@tonic-gate return ( process(NULL) ); 207*0Sstevel@tonic-gate #endif /* SOLARIS_LDAP_CMD */ 208*0Sstevel@tonic-gate } 209*0Sstevel@tonic-gate 210*0Sstevel@tonic-gate #ifdef SOLARIS_LDAP_CMD 211*0Sstevel@tonic-gate #define exit(a) \ 212*0Sstevel@tonic-gate if (nbthreads > 1) { \ 213*0Sstevel@tonic-gate mutex_lock(&read_mutex); \ 214*0Sstevel@tonic-gate error |= a; \ 215*0Sstevel@tonic-gate mutex_unlock(&read_mutex); \ 216*0Sstevel@tonic-gate thr_exit(&error); \ 217*0Sstevel@tonic-gate } else { \ 218*0Sstevel@tonic-gate exit(a); \ 219*0Sstevel@tonic-gate } 220*0Sstevel@tonic-gate #endif /* SOLARIS_LDAP_CMD */ 221*0Sstevel@tonic-gate 222*0Sstevel@tonic-gate static int 223*0Sstevel@tonic-gate process( void *arg ) 224*0Sstevel@tonic-gate { 225*0Sstevel@tonic-gate char *rbuf, *saved_rbuf, *start, *p, *q; 226*0Sstevel@tonic-gate FILE *rfp = NULL; 227*0Sstevel@tonic-gate int rc, use_ldif, deref; 228*0Sstevel@tonic-gate LDAPControl *ldctrl; 229*0Sstevel@tonic-gate 230*0Sstevel@tonic-gate #ifdef SOLARIS_LDAP_CMD 231*0Sstevel@tonic-gate LDAP *ld; 232*0Sstevel@tonic-gate #endif /* SOLARIS_LDAP_CMD */ 233*0Sstevel@tonic-gate 234*0Sstevel@tonic-gate ld = ldaptool_ldap_init( 0 ); 235*0Sstevel@tonic-gate 236*0Sstevel@tonic-gate if ( !ldaptool_not ) { 237*0Sstevel@tonic-gate deref = LDAP_DEREF_NEVER; /* this seems prudent */ 238*0Sstevel@tonic-gate ldap_set_option( ld, LDAP_OPT_DEREF, &deref ); 239*0Sstevel@tonic-gate } 240*0Sstevel@tonic-gate 241*0Sstevel@tonic-gate ldaptool_bind( ld ); 242*0Sstevel@tonic-gate 243*0Sstevel@tonic-gate if (( ldctrl = ldaptool_create_manage_dsait_control()) != NULL ) { 244*0Sstevel@tonic-gate ldaptool_add_control_to_array( ldctrl, ldaptool_request_ctrls); 245*0Sstevel@tonic-gate } 246*0Sstevel@tonic-gate 247*0Sstevel@tonic-gate if ((ldctrl = ldaptool_create_proxyauth_control(ld)) !=NULL) { 248*0Sstevel@tonic-gate ldaptool_add_control_to_array( ldctrl, ldaptool_request_ctrls); 249*0Sstevel@tonic-gate } 250*0Sstevel@tonic-gate 251*0Sstevel@tonic-gate rc = 0; 252*0Sstevel@tonic-gate 253*0Sstevel@tonic-gate /* turn on bulk import?*/ 254*0Sstevel@tonic-gate if (bulkimport_suffix) { 255*0Sstevel@tonic-gate struct berval bv, *retdata; 256*0Sstevel@tonic-gate char *retoid; 257*0Sstevel@tonic-gate 258*0Sstevel@tonic-gate bv.bv_val = bulkimport_suffix; 259*0Sstevel@tonic-gate bv.bv_len = strlen(bulkimport_suffix); 260*0Sstevel@tonic-gate if ((rc = ldap_extended_operation_s(ld, 261*0Sstevel@tonic-gate BULKIMPORT_START_OID, &bv, NULL, 262*0Sstevel@tonic-gate NULL, &retoid, &retdata)) != 0) { 263*0Sstevel@tonic-gate fprintf(stderr, gettext("Error: unable to service " 264*0Sstevel@tonic-gate "extended operation request\n\t'%s' for " 265*0Sstevel@tonic-gate "bulk import\n\t(error:%d:'%s')\n"), 266*0Sstevel@tonic-gate BULKIMPORT_START_OID, rc, ldap_err2string(rc)); 267*0Sstevel@tonic-gate return (rc); 268*0Sstevel@tonic-gate } 269*0Sstevel@tonic-gate if (retoid) 270*0Sstevel@tonic-gate ldap_memfree(retoid); 271*0Sstevel@tonic-gate if (retdata) 272*0Sstevel@tonic-gate ber_bvfree(retdata); 273*0Sstevel@tonic-gate } 274*0Sstevel@tonic-gate 275*0Sstevel@tonic-gate while (( rc == 0 || contoper ) && 276*0Sstevel@tonic-gate ( rbuf = read_one_record( ldaptool_fp )) != NULL ) { 277*0Sstevel@tonic-gate /* 278*0Sstevel@tonic-gate * we assume record is ldif/slapd.replog if the first line 279*0Sstevel@tonic-gate * has a colon that appears to the left of any equal signs, OR 280*0Sstevel@tonic-gate * if the first line consists entirely of digits (an entry id) 281*0Sstevel@tonic-gate */ 282*0Sstevel@tonic-gate use_ldif = ( p = strchr( rbuf, ':' )) != NULL && 283*0Sstevel@tonic-gate ( q = strchr( rbuf, '\n' )) != NULL && p < q && 284*0Sstevel@tonic-gate (( q = strchr( rbuf, '=' )) == NULL || p < q ); 285*0Sstevel@tonic-gate 286*0Sstevel@tonic-gate start = rbuf; 287*0Sstevel@tonic-gate saved_rbuf = strdup( rbuf ); 288*0Sstevel@tonic-gate 289*0Sstevel@tonic-gate if ( !use_ldif && ( q = strchr( rbuf, '\n' )) != NULL ) { 290*0Sstevel@tonic-gate for ( p = rbuf; p < q; ++p ) { 291*0Sstevel@tonic-gate if ( !isdigit( *p )) { 292*0Sstevel@tonic-gate break; 293*0Sstevel@tonic-gate } 294*0Sstevel@tonic-gate } 295*0Sstevel@tonic-gate if ( p >= q ) { 296*0Sstevel@tonic-gate use_ldif = 1; 297*0Sstevel@tonic-gate start = q + 1; 298*0Sstevel@tonic-gate } 299*0Sstevel@tonic-gate } 300*0Sstevel@tonic-gate 301*0Sstevel@tonic-gate #ifdef SOLARIS_LDAP_CMD 302*0Sstevel@tonic-gate if ( use_ldif ) { 303*0Sstevel@tonic-gate rc = process_ldif_rec( ld, start ); 304*0Sstevel@tonic-gate } else { 305*0Sstevel@tonic-gate rc = process_ldapmod_rec( ld, start ); 306*0Sstevel@tonic-gate } 307*0Sstevel@tonic-gate #else 308*0Sstevel@tonic-gate if ( use_ldif ) { 309*0Sstevel@tonic-gate rc = process_ldif_rec( start ); 310*0Sstevel@tonic-gate } else { 311*0Sstevel@tonic-gate rc = process_ldapmod_rec( start ); 312*0Sstevel@tonic-gate } 313*0Sstevel@tonic-gate #endif /* SOLARIS_LDAP_CMD */ 314*0Sstevel@tonic-gate 315*0Sstevel@tonic-gate if ( rc != LDAP_SUCCESS && rejfile != NULL ) { 316*0Sstevel@tonic-gate /* Write this record to the reject file */ 317*0Sstevel@tonic-gate int newfile = 0; 318*0Sstevel@tonic-gate struct stat stbuf; 319*0Sstevel@tonic-gate if ( stat( rejfile, &stbuf ) < 0 ) { 320*0Sstevel@tonic-gate if ( errno == ENOENT ) { 321*0Sstevel@tonic-gate newfile = 1; 322*0Sstevel@tonic-gate } 323*0Sstevel@tonic-gate } 324*0Sstevel@tonic-gate if (( rfp = ldaptool_open_file( rejfile, "a" )) == NULL ) { 325*0Sstevel@tonic-gate fprintf( stderr, gettext("Cannot open error file \"%s\" - " 326*0Sstevel@tonic-gate "erroneous entries will not be saved\n"), rejfile ); 327*0Sstevel@tonic-gate rejfile = NULL; 328*0Sstevel@tonic-gate } else { 329*0Sstevel@tonic-gate if ( newfile == 0 ) { 330*0Sstevel@tonic-gate fputs( "\n", rfp ); 331*0Sstevel@tonic-gate } 332*0Sstevel@tonic-gate fprintf( rfp, gettext("# Error: %s\n"), ldap_err2string( rc )); 333*0Sstevel@tonic-gate fputs( saved_rbuf, rfp ); 334*0Sstevel@tonic-gate fclose( rfp ); 335*0Sstevel@tonic-gate rfp = NULL; 336*0Sstevel@tonic-gate } 337*0Sstevel@tonic-gate } 338*0Sstevel@tonic-gate 339*0Sstevel@tonic-gate free( rbuf ); 340*0Sstevel@tonic-gate free( saved_rbuf ); 341*0Sstevel@tonic-gate } 342*0Sstevel@tonic-gate ldaptool_reset_control_array( ldaptool_request_ctrls ); 343*0Sstevel@tonic-gate 344*0Sstevel@tonic-gate /* turn off bulk import?*/ 345*0Sstevel@tonic-gate if (bulkimport_suffix) { 346*0Sstevel@tonic-gate struct berval bv, *retdata; 347*0Sstevel@tonic-gate char *retoid; 348*0Sstevel@tonic-gate 349*0Sstevel@tonic-gate bv.bv_val = ""; 350*0Sstevel@tonic-gate bv.bv_len = 0; 351*0Sstevel@tonic-gate if ((rc = ldap_extended_operation_s(ld, 352*0Sstevel@tonic-gate BULKIMPORT_STOP_OID, &bv, NULL, 353*0Sstevel@tonic-gate NULL, &retoid, &retdata)) != 0) { 354*0Sstevel@tonic-gate 355*0Sstevel@tonic-gate fprintf(stderr, gettext("Error: unable to service " 356*0Sstevel@tonic-gate "extended operation request\n\t '%s' for " 357*0Sstevel@tonic-gate "bulk import\n\t(rc:%d:'%s')\n"), 358*0Sstevel@tonic-gate BULKIMPORT_STOP_OID, rc, ldap_err2string(rc)); 359*0Sstevel@tonic-gate return (rc); 360*0Sstevel@tonic-gate } 361*0Sstevel@tonic-gate if (retoid) 362*0Sstevel@tonic-gate ldap_memfree(retoid); 363*0Sstevel@tonic-gate if (retdata) 364*0Sstevel@tonic-gate ber_bvfree(retdata); 365*0Sstevel@tonic-gate } 366*0Sstevel@tonic-gate 367*0Sstevel@tonic-gate #ifdef SOLARIS_LDAP_CMD 368*0Sstevel@tonic-gate mutex_lock(&read_mutex); 369*0Sstevel@tonic-gate #endif 370*0Sstevel@tonic-gate ldaptool_cleanup( ld ); 371*0Sstevel@tonic-gate #ifdef SOLARIS_LDAP_CMD 372*0Sstevel@tonic-gate mutex_unlock(&read_mutex); 373*0Sstevel@tonic-gate #endif 374*0Sstevel@tonic-gate return( rc ); 375*0Sstevel@tonic-gate } 376*0Sstevel@tonic-gate 377*0Sstevel@tonic-gate 378*0Sstevel@tonic-gate static void 379*0Sstevel@tonic-gate options_callback( int option, char *optarg ) 380*0Sstevel@tonic-gate { 381*0Sstevel@tonic-gate switch( option ) { 382*0Sstevel@tonic-gate case 'a': /* add */ 383*0Sstevel@tonic-gate newval = 1; 384*0Sstevel@tonic-gate break; 385*0Sstevel@tonic-gate case 'b': /* read values from files (for binary attributes) */ 386*0Sstevel@tonic-gate valsfromfiles = 1; 387*0Sstevel@tonic-gate break; 388*0Sstevel@tonic-gate case 'A': /* display non-ASCII values when -v is used */ 389*0Sstevel@tonic-gate display_binary_values = 1; 390*0Sstevel@tonic-gate break; 391*0Sstevel@tonic-gate case 'c': /* continuous operation */ 392*0Sstevel@tonic-gate contoper = 1; 393*0Sstevel@tonic-gate break; 394*0Sstevel@tonic-gate case 'F': /* force all changes records to be used */ 395*0Sstevel@tonic-gate force = 1; 396*0Sstevel@tonic-gate break; 397*0Sstevel@tonic-gate case 'e': 398*0Sstevel@tonic-gate rejfile = strdup( optarg ); 399*0Sstevel@tonic-gate break; 400*0Sstevel@tonic-gate case 'B': /* bulk import option */ 401*0Sstevel@tonic-gate bulkimport_suffix = strdup( optarg ); 402*0Sstevel@tonic-gate break; 403*0Sstevel@tonic-gate case 'q': /* quiet mode on add/modify operations */ 404*0Sstevel@tonic-gate ldapmodify_quiet = 1; 405*0Sstevel@tonic-gate break; 406*0Sstevel@tonic-gate #ifdef SOLARIS_LDAP_CMD 407*0Sstevel@tonic-gate case 'r': /* default is to replace rather than add values */ 408*0Sstevel@tonic-gate replace = 1; 409*0Sstevel@tonic-gate break; 410*0Sstevel@tonic-gate case 'l': 411*0Sstevel@tonic-gate nbthreads = atoi(optarg); 412*0Sstevel@tonic-gate break; 413*0Sstevel@tonic-gate #endif /* SOLARIS_LDAP_CMD */ 414*0Sstevel@tonic-gate default: 415*0Sstevel@tonic-gate usage(); 416*0Sstevel@tonic-gate } 417*0Sstevel@tonic-gate } 418*0Sstevel@tonic-gate 419*0Sstevel@tonic-gate 420*0Sstevel@tonic-gate 421*0Sstevel@tonic-gate static int 422*0Sstevel@tonic-gate #ifdef SOLARIS_LDAP_CMD 423*0Sstevel@tonic-gate process_ldif_rec( LDAP *ld, char *rbuf ) 424*0Sstevel@tonic-gate #else 425*0Sstevel@tonic-gate process_ldif_rec( char *rbuf ) 426*0Sstevel@tonic-gate #endif 427*0Sstevel@tonic-gate { 428*0Sstevel@tonic-gate char *line, *dn, *type, *value, *newrdn, *newparent, *p; 429*0Sstevel@tonic-gate char *ctrl_oid=NULL, *ctrl_value=NULL; 430*0Sstevel@tonic-gate int ctrl_criticality=1; 431*0Sstevel@tonic-gate LDAPControl *ldctrl; 432*0Sstevel@tonic-gate int rc, linenum, vlen, modop, replicaport; 433*0Sstevel@tonic-gate int expect_modop, expect_sep, expect_chgtype_or_control, expect_newrdn; 434*0Sstevel@tonic-gate int expect_deleteoldrdn, expect_newparent, rename, moddn; 435*0Sstevel@tonic-gate int deleteoldrdn, saw_replica, use_record, new_entry, delete_entry; 436*0Sstevel@tonic-gate int got_all, got_value; 437*0Sstevel@tonic-gate LDAPMod **pmods; 438*0Sstevel@tonic-gate 439*0Sstevel@tonic-gate new_entry = newval; 440*0Sstevel@tonic-gate 441*0Sstevel@tonic-gate rc = got_all = saw_replica = delete_entry = expect_modop = 0; 442*0Sstevel@tonic-gate expect_deleteoldrdn = expect_newrdn = expect_newparent = expect_sep = 0; 443*0Sstevel@tonic-gate expect_chgtype_or_control = linenum = got_value = rename = moddn = 0; 444*0Sstevel@tonic-gate deleteoldrdn = 1; 445*0Sstevel@tonic-gate use_record = force; 446*0Sstevel@tonic-gate pmods = NULL; 447*0Sstevel@tonic-gate dn = newrdn = newparent = NULL; 448*0Sstevel@tonic-gate 449*0Sstevel@tonic-gate #ifdef SOLARIS_LDAP_CMD 450*0Sstevel@tonic-gate while ( rc == 0 && ( line = str_getline( &rbuf )) != NULL ) { 451*0Sstevel@tonic-gate #else 452*0Sstevel@tonic-gate while ( rc == 0 && ( line = ldif_getline( &rbuf )) != NULL ) { 453*0Sstevel@tonic-gate #endif /* SOLARIS_LDAP_CMD */ 454*0Sstevel@tonic-gate ++linenum; 455*0Sstevel@tonic-gate if ( expect_sep && strcasecmp( line, T_MODSEPSTR ) == 0 ) { 456*0Sstevel@tonic-gate expect_sep = 0; 457*0Sstevel@tonic-gate expect_modop = 1; 458*0Sstevel@tonic-gate 459*0Sstevel@tonic-gate /*If we see a separator in the input stream, 460*0Sstevel@tonic-gate but we didn't get a value from the last modify 461*0Sstevel@tonic-gate then we have to fill pmods with an empty value*/ 462*0Sstevel@tonic-gate if (modop == LDAP_MOD_REPLACE && !got_value){ 463*0Sstevel@tonic-gate addmodifyop( &pmods, modop, value, NULL, 0); 464*0Sstevel@tonic-gate } 465*0Sstevel@tonic-gate 466*0Sstevel@tonic-gate got_value = 0; 467*0Sstevel@tonic-gate continue; 468*0Sstevel@tonic-gate } 469*0Sstevel@tonic-gate 470*0Sstevel@tonic-gate #ifdef SOLARIS_LDAP_CMD 471*0Sstevel@tonic-gate if ( str_parse_line( line, &type, &value, &vlen ) < 0 ) { 472*0Sstevel@tonic-gate #else 473*0Sstevel@tonic-gate if ( ldif_parse_line( line, &type, &value, &vlen ) < 0 ) { 474*0Sstevel@tonic-gate #endif /* SOLARIS_LDAP_CMD */ 475*0Sstevel@tonic-gate fprintf( stderr, gettext("%s: invalid format (line %d of entry: %s)\n"), 476*0Sstevel@tonic-gate ldaptool_progname, linenum, dn == NULL ? "" : dn ); 477*0Sstevel@tonic-gate fprintf( stderr, gettext("%s: line contents: (%s)\n"), 478*0Sstevel@tonic-gate ldaptool_progname, line ); 479*0Sstevel@tonic-gate rc = LDAP_PARAM_ERROR; 480*0Sstevel@tonic-gate break; 481*0Sstevel@tonic-gate } 482*0Sstevel@tonic-gate 483*0Sstevel@tonic-gate evaluate_line: 484*0Sstevel@tonic-gate if ( dn == NULL ) { 485*0Sstevel@tonic-gate if ( !use_record && strcasecmp( type, T_REPLICA_STR ) == 0 ) { 486*0Sstevel@tonic-gate ++saw_replica; 487*0Sstevel@tonic-gate if (( p = strchr( value, ':' )) == NULL ) { 488*0Sstevel@tonic-gate replicaport = LDAP_PORT; 489*0Sstevel@tonic-gate } else { 490*0Sstevel@tonic-gate *p++ = '\0'; 491*0Sstevel@tonic-gate replicaport = atoi( p ); 492*0Sstevel@tonic-gate } 493*0Sstevel@tonic-gate if ( strcasecmp( value, ldaptool_host ) == 0 && 494*0Sstevel@tonic-gate replicaport == ldaptool_port ) { 495*0Sstevel@tonic-gate use_record = 1; 496*0Sstevel@tonic-gate } 497*0Sstevel@tonic-gate 498*0Sstevel@tonic-gate } else if ( strcasecmp( type, T_DN_STR ) == 0 ) { 499*0Sstevel@tonic-gate if (( dn = strdup( value )) == NULL ) { 500*0Sstevel@tonic-gate perror( "strdup" ); 501*0Sstevel@tonic-gate exit( LDAP_NO_MEMORY ); 502*0Sstevel@tonic-gate } 503*0Sstevel@tonic-gate expect_chgtype_or_control = 1; 504*0Sstevel@tonic-gate 505*0Sstevel@tonic-gate } else if ( strcasecmp( type, T_VERSION_STR ) == 0 ) { 506*0Sstevel@tonic-gate ldif_version = atoi( value ); 507*0Sstevel@tonic-gate if ( ldif_version != LDIF_VERSION_ONE ) { 508*0Sstevel@tonic-gate fprintf( stderr, gettext("%s: LDIF version %d is not supported;" 509*0Sstevel@tonic-gate " use version: %d\n"), ldaptool_progname, ldif_version, 510*0Sstevel@tonic-gate LDIF_VERSION_ONE ); 511*0Sstevel@tonic-gate exit( LDAP_PARAM_ERROR ); 512*0Sstevel@tonic-gate } 513*0Sstevel@tonic-gate if ( ldaptool_verbose ) { 514*0Sstevel@tonic-gate printf( gettext("Processing a version %d LDIF file...\n"), 515*0Sstevel@tonic-gate ldif_version ); 516*0Sstevel@tonic-gate } 517*0Sstevel@tonic-gate 518*0Sstevel@tonic-gate /* Now check if there's something left to process */ 519*0Sstevel@tonic-gate /* and if not, go get the new record, else continue */ 520*0Sstevel@tonic-gate if ( *rbuf == '\0' ) { 521*0Sstevel@tonic-gate return( 0 ); 522*0Sstevel@tonic-gate } 523*0Sstevel@tonic-gate 524*0Sstevel@tonic-gate } else if ( !saw_replica ) { 525*0Sstevel@tonic-gate printf( gettext("%s: skipping change record: no dn: line\n"), 526*0Sstevel@tonic-gate ldaptool_progname ); 527*0Sstevel@tonic-gate return( 0 ); 528*0Sstevel@tonic-gate } 529*0Sstevel@tonic-gate 530*0Sstevel@tonic-gate continue; /* skip all lines until we see "dn:" */ 531*0Sstevel@tonic-gate } 532*0Sstevel@tonic-gate 533*0Sstevel@tonic-gate if ( expect_chgtype_or_control ) { 534*0Sstevel@tonic-gate expect_chgtype_or_control = 0; 535*0Sstevel@tonic-gate if ( !use_record && saw_replica ) { 536*0Sstevel@tonic-gate printf( gettext("%s: skipping change record for entry: %s\n\t(LDAP host/port does not match replica: lines)\n"), 537*0Sstevel@tonic-gate ldaptool_progname, dn ); 538*0Sstevel@tonic-gate free( dn ); 539*0Sstevel@tonic-gate return( 0 ); 540*0Sstevel@tonic-gate } 541*0Sstevel@tonic-gate 542*0Sstevel@tonic-gate #ifndef SOLARIS_LDAP_CMD 543*0Sstevel@tonic-gate if ( strcasecmp( type, "control" ) == 0 ) { 544*0Sstevel@tonic-gate value = strdup_and_trim( value ); 545*0Sstevel@tonic-gate if (ldaptool_parse_ctrl_arg(value, ' ', &ctrl_oid, 546*0Sstevel@tonic-gate &ctrl_criticality, &ctrl_value, &vlen)) { 547*0Sstevel@tonic-gate usage(); 548*0Sstevel@tonic-gate } 549*0Sstevel@tonic-gate ldctrl = calloc(1,sizeof(LDAPControl)); 550*0Sstevel@tonic-gate if (ctrl_value) { 551*0Sstevel@tonic-gate rc = ldaptool_berval_from_ldif_value( ctrl_value, vlen, 552*0Sstevel@tonic-gate &(ldctrl->ldctl_value), 553*0Sstevel@tonic-gate 1 /* recognize file URLs */, 0 /* always try file */, 554*0Sstevel@tonic-gate 1 /* report errors */ ); 555*0Sstevel@tonic-gate if ((rc = ldaptool_fileurlerr2ldaperr( rc )) != LDAP_SUCCESS) { 556*0Sstevel@tonic-gate fprintf( stderr, gettext("Unable to parse %s\n"), ctrl_value); 557*0Sstevel@tonic-gate usage(); 558*0Sstevel@tonic-gate } 559*0Sstevel@tonic-gate } 560*0Sstevel@tonic-gate ldctrl->ldctl_oid = ctrl_oid; 561*0Sstevel@tonic-gate ldctrl->ldctl_iscritical = ctrl_criticality; 562*0Sstevel@tonic-gate ldaptool_add_control_to_array(ldctrl, ldaptool_request_ctrls); 563*0Sstevel@tonic-gate expect_chgtype_or_control = 1; 564*0Sstevel@tonic-gate continue; 565*0Sstevel@tonic-gate } 566*0Sstevel@tonic-gate #endif /* SOLARIS_LDAP_CMD */ 567*0Sstevel@tonic-gate 568*0Sstevel@tonic-gate if ( strcasecmp( type, T_CHANGETYPESTR ) == 0 ) { 569*0Sstevel@tonic-gate value = strdup_and_trim( value ); 570*0Sstevel@tonic-gate if ( strcasecmp( value, T_MODIFYCTSTR ) == 0 ) { 571*0Sstevel@tonic-gate new_entry = 0; 572*0Sstevel@tonic-gate expect_modop = 1; 573*0Sstevel@tonic-gate } else if ( strcasecmp( value, T_ADDCTSTR ) == 0 ) { 574*0Sstevel@tonic-gate new_entry = 1; 575*0Sstevel@tonic-gate modop = LDAP_MOD_ADD; 576*0Sstevel@tonic-gate } else if ( strcasecmp( value, T_MODRDNCTSTR ) == 0 ) { 577*0Sstevel@tonic-gate expect_newrdn = 1; 578*0Sstevel@tonic-gate moddn = 1; 579*0Sstevel@tonic-gate } else if ( strcasecmp( value, T_MODDNCTSTR ) == 0 ) { 580*0Sstevel@tonic-gate expect_newrdn = 1; 581*0Sstevel@tonic-gate moddn = 1; 582*0Sstevel@tonic-gate } else if ( strcasecmp( value, T_RENAMECTSTR ) == 0 ) { 583*0Sstevel@tonic-gate expect_newrdn = 1; 584*0Sstevel@tonic-gate rename = 1; 585*0Sstevel@tonic-gate } else if ( strcasecmp( value, T_DELETECTSTR ) == 0 ) { 586*0Sstevel@tonic-gate got_all = delete_entry = 1; 587*0Sstevel@tonic-gate } else { 588*0Sstevel@tonic-gate fprintf( stderr, 589*0Sstevel@tonic-gate gettext("%s: unknown %s \"%s\" (line %d of entry: %s)\n"), 590*0Sstevel@tonic-gate ldaptool_progname, T_CHANGETYPESTR, value, 591*0Sstevel@tonic-gate linenum, dn ); 592*0Sstevel@tonic-gate rc = LDAP_PARAM_ERROR; 593*0Sstevel@tonic-gate } 594*0Sstevel@tonic-gate free( value ); 595*0Sstevel@tonic-gate continue; 596*0Sstevel@tonic-gate } else if ( newval ) { /* missing changetype => add */ 597*0Sstevel@tonic-gate new_entry = 1; 598*0Sstevel@tonic-gate modop = LDAP_MOD_ADD; 599*0Sstevel@tonic-gate } else { 600*0Sstevel@tonic-gate /*The user MUST put in changetype: blah 601*0Sstevel@tonic-gate unless adding a new entry with either -a or ldapadd*/ 602*0Sstevel@tonic-gate fprintf(stderr, gettext("%s: Missing changetype operation specification.\n\tThe dn line must be followed by \"changetype: operation\"\n\t(unless ldapmodify is called with -a option)\n\twhere operation is add|delete|modify|modrdn|moddn|rename\n\t\"%s\" is not a valid changetype operation specification\n\t(line %d of entry %s)\n"), 603*0Sstevel@tonic-gate ldaptool_progname, type, linenum, dn); 604*0Sstevel@tonic-gate rc = LDAP_PARAM_ERROR; 605*0Sstevel@tonic-gate /*expect_modop = 1; missing changetype => modify */ 606*0Sstevel@tonic-gate } 607*0Sstevel@tonic-gate } 608*0Sstevel@tonic-gate 609*0Sstevel@tonic-gate if ( expect_modop ) { 610*0Sstevel@tonic-gate expect_modop = 0; 611*0Sstevel@tonic-gate expect_sep = 1; 612*0Sstevel@tonic-gate if ( strcasecmp( type, T_MODOPADDSTR ) == 0 ) { 613*0Sstevel@tonic-gate modop = LDAP_MOD_ADD; 614*0Sstevel@tonic-gate continue; 615*0Sstevel@tonic-gate } else if ( strcasecmp( type, T_MODOPREPLACESTR ) == 0 ) { 616*0Sstevel@tonic-gate modop = LDAP_MOD_REPLACE; 617*0Sstevel@tonic-gate continue; 618*0Sstevel@tonic-gate } else if ( strcasecmp( type, T_MODOPDELETESTR ) == 0 ) { 619*0Sstevel@tonic-gate modop = LDAP_MOD_DELETE; 620*0Sstevel@tonic-gate addmodifyop( &pmods, modop, value, NULL, 0 ); 621*0Sstevel@tonic-gate continue; 622*0Sstevel@tonic-gate #ifdef SOLARIS_LDAP_CMD 623*0Sstevel@tonic-gate } else { /* no modify op: use default */ 624*0Sstevel@tonic-gate modop = replace ? LDAP_MOD_REPLACE : LDAP_MOD_ADD; 625*0Sstevel@tonic-gate } 626*0Sstevel@tonic-gate #else 627*0Sstevel@tonic-gate } else { /*Bug 27479. Remove default add operation*/ 628*0Sstevel@tonic-gate fprintf(stderr, gettext("%s: Invalid parameter \"%s\" specified for changetype modify (line %d of entry %s)\n"), 629*0Sstevel@tonic-gate ldaptool_progname, type, linenum, dn); 630*0Sstevel@tonic-gate rc = LDAP_PARAM_ERROR; 631*0Sstevel@tonic-gate } 632*0Sstevel@tonic-gate #endif /* SOLARIS_LDAP_CMD */ 633*0Sstevel@tonic-gate 634*0Sstevel@tonic-gate } 635*0Sstevel@tonic-gate 636*0Sstevel@tonic-gate if ( expect_newrdn ) { 637*0Sstevel@tonic-gate if ( strcasecmp( type, T_NEWRDNSTR ) == 0 ) { 638*0Sstevel@tonic-gate if ( *value == '\0' ) { 639*0Sstevel@tonic-gate fprintf( stderr, 640*0Sstevel@tonic-gate gettext("%s: newrdn value missing (line %d of entry: %s)\n"), 641*0Sstevel@tonic-gate ldaptool_progname, linenum, dn == NULL ? "" : dn ); 642*0Sstevel@tonic-gate rc = LDAP_PARAM_ERROR; 643*0Sstevel@tonic-gate } else if (( newrdn = strdup( value )) == NULL ) { 644*0Sstevel@tonic-gate perror( "strdup" ); 645*0Sstevel@tonic-gate exit( LDAP_NO_MEMORY ); 646*0Sstevel@tonic-gate } else { 647*0Sstevel@tonic-gate expect_newrdn = 0; 648*0Sstevel@tonic-gate if ( rename ) { 649*0Sstevel@tonic-gate expect_newparent = 1; 650*0Sstevel@tonic-gate } else { 651*0Sstevel@tonic-gate expect_deleteoldrdn = 1; 652*0Sstevel@tonic-gate } 653*0Sstevel@tonic-gate } 654*0Sstevel@tonic-gate } else { 655*0Sstevel@tonic-gate fprintf( stderr, gettext("%s: expecting \"%s:\" but saw \"%s:\" (line %d of entry %s)\n"), 656*0Sstevel@tonic-gate ldaptool_progname, T_NEWRDNSTR, type, linenum, dn ); 657*0Sstevel@tonic-gate rc = LDAP_PARAM_ERROR; 658*0Sstevel@tonic-gate } 659*0Sstevel@tonic-gate } else if ( expect_newparent ) { 660*0Sstevel@tonic-gate expect_newparent = 0; 661*0Sstevel@tonic-gate if ( rename ) { 662*0Sstevel@tonic-gate expect_deleteoldrdn = 1; 663*0Sstevel@tonic-gate } 664*0Sstevel@tonic-gate if ( strcasecmp( type, T_NEWPARENTSTR ) == 0 665*0Sstevel@tonic-gate || strcasecmp( type, T_NEWSUPERIORSTR ) == 0 ) { 666*0Sstevel@tonic-gate if (( newparent = strdup( value )) == NULL ) { 667*0Sstevel@tonic-gate perror( "strdup" ); 668*0Sstevel@tonic-gate exit( LDAP_NO_MEMORY ); 669*0Sstevel@tonic-gate } 670*0Sstevel@tonic-gate } else { 671*0Sstevel@tonic-gate /* Since this is an optional argument for rename/moddn, cause 672*0Sstevel@tonic-gate * the current line to be re-evaluated if newparent doesn't 673*0Sstevel@tonic-gate * follow deleteoldrdn. 674*0Sstevel@tonic-gate */ 675*0Sstevel@tonic-gate newparent = NULL; 676*0Sstevel@tonic-gate goto evaluate_line; 677*0Sstevel@tonic-gate } 678*0Sstevel@tonic-gate } else if ( expect_deleteoldrdn ) { 679*0Sstevel@tonic-gate if ( strcasecmp( type, T_DELETEOLDRDNSTR ) == 0 ) { 680*0Sstevel@tonic-gate if ( *value == '\0' ) { 681*0Sstevel@tonic-gate fprintf( stderr, 682*0Sstevel@tonic-gate gettext("%s: missing 0 or 1 (line %d of entry: %s)\n"), 683*0Sstevel@tonic-gate ldaptool_progname, linenum, dn == NULL ? "" : dn ); 684*0Sstevel@tonic-gate rc = LDAP_PARAM_ERROR; 685*0Sstevel@tonic-gate } else { 686*0Sstevel@tonic-gate deleteoldrdn = ( *value == '0' ) ? 0 : 1; 687*0Sstevel@tonic-gate expect_deleteoldrdn = 0; 688*0Sstevel@tonic-gate if ( moddn ) { 689*0Sstevel@tonic-gate expect_newparent = 1; 690*0Sstevel@tonic-gate } 691*0Sstevel@tonic-gate } 692*0Sstevel@tonic-gate } else { 693*0Sstevel@tonic-gate fprintf( stderr, gettext("%s: expecting \"%s:\" but saw \"%s:\" (line %d of entry %s)\n"), 694*0Sstevel@tonic-gate ldaptool_progname, T_DELETEOLDRDNSTR, type, linenum, 695*0Sstevel@tonic-gate dn ); 696*0Sstevel@tonic-gate rc = LDAP_PARAM_ERROR; 697*0Sstevel@tonic-gate } 698*0Sstevel@tonic-gate got_all = 1; 699*0Sstevel@tonic-gate } else if ( got_all ) { 700*0Sstevel@tonic-gate fprintf( stderr, 701*0Sstevel@tonic-gate gettext("%s: extra lines at end (line %d of entry %s)\n"), 702*0Sstevel@tonic-gate ldaptool_progname, linenum, dn ); 703*0Sstevel@tonic-gate rc = LDAP_PARAM_ERROR; 704*0Sstevel@tonic-gate got_all = 1; 705*0Sstevel@tonic-gate } else { 706*0Sstevel@tonic-gate addmodifyop( &pmods, modop, type, value, vlen ); 707*0Sstevel@tonic-gate /*There was a value to replace*/ 708*0Sstevel@tonic-gate got_value = 1; 709*0Sstevel@tonic-gate 710*0Sstevel@tonic-gate } 711*0Sstevel@tonic-gate } 712*0Sstevel@tonic-gate 713*0Sstevel@tonic-gate if ( rc == 0 ) { 714*0Sstevel@tonic-gate if ( delete_entry ) { 715*0Sstevel@tonic-gate #ifdef SOLARIS_LDAP_CMD 716*0Sstevel@tonic-gate rc = dodelete( ld, dn ); 717*0Sstevel@tonic-gate #else 718*0Sstevel@tonic-gate rc = dodelete( dn ); 719*0Sstevel@tonic-gate #endif /* SOLARIS_LDAP_CMD */ 720*0Sstevel@tonic-gate } else if ( newrdn != NULL ) { 721*0Sstevel@tonic-gate #ifdef SOLARIS_LDAP_CMD 722*0Sstevel@tonic-gate rc = dorename( ld, dn, newrdn, newparent, deleteoldrdn ); 723*0Sstevel@tonic-gate #else 724*0Sstevel@tonic-gate rc = dorename( dn, newrdn, newparent, deleteoldrdn ); 725*0Sstevel@tonic-gate #endif /* SOLARIS_LDAP_CMD */ 726*0Sstevel@tonic-gate rename = 0; 727*0Sstevel@tonic-gate } else { 728*0Sstevel@tonic-gate 729*0Sstevel@tonic-gate /*Patch to fix Bug 22183 730*0Sstevel@tonic-gate If pmods is null, then there is no 731*0Sstevel@tonic-gate attribute to replace, so we alloc 732*0Sstevel@tonic-gate an empty pmods*/ 733*0Sstevel@tonic-gate if (modop == LDAP_MOD_REPLACE && !got_value && expect_sep){ 734*0Sstevel@tonic-gate addmodifyop( &pmods, modop, value, NULL, 0); 735*0Sstevel@tonic-gate }/*End Patch*/ 736*0Sstevel@tonic-gate 737*0Sstevel@tonic-gate 738*0Sstevel@tonic-gate #ifdef SOLARIS_LDAP_CMD 739*0Sstevel@tonic-gate rc = domodify( ld, dn, pmods, new_entry ); 740*0Sstevel@tonic-gate #else 741*0Sstevel@tonic-gate rc = domodify( dn, pmods, new_entry ); 742*0Sstevel@tonic-gate #endif /* SOLARIS_LDAP_CMD */ 743*0Sstevel@tonic-gate } 744*0Sstevel@tonic-gate 745*0Sstevel@tonic-gate if ( rc == LDAP_SUCCESS ) { 746*0Sstevel@tonic-gate rc = 0; 747*0Sstevel@tonic-gate } 748*0Sstevel@tonic-gate } 749*0Sstevel@tonic-gate 750*0Sstevel@tonic-gate if ( dn != NULL ) { 751*0Sstevel@tonic-gate free( dn ); 752*0Sstevel@tonic-gate } 753*0Sstevel@tonic-gate if ( newrdn != NULL ) { 754*0Sstevel@tonic-gate free( newrdn ); 755*0Sstevel@tonic-gate } 756*0Sstevel@tonic-gate if ( newparent != NULL ) { 757*0Sstevel@tonic-gate free( newparent ); 758*0Sstevel@tonic-gate } 759*0Sstevel@tonic-gate if ( pmods != NULL ) { 760*0Sstevel@tonic-gate freepmods( pmods ); 761*0Sstevel@tonic-gate } 762*0Sstevel@tonic-gate 763*0Sstevel@tonic-gate return( rc ); 764*0Sstevel@tonic-gate } 765*0Sstevel@tonic-gate 766*0Sstevel@tonic-gate 767*0Sstevel@tonic-gate static int 768*0Sstevel@tonic-gate #ifdef SOLARIS_LDAP_CMD 769*0Sstevel@tonic-gate process_ldapmod_rec( LDAP *ld, char *rbuf ) 770*0Sstevel@tonic-gate #else 771*0Sstevel@tonic-gate process_ldapmod_rec( char *rbuf ) 772*0Sstevel@tonic-gate #endif /* SOLARIS_LDAP_CMD */ 773*0Sstevel@tonic-gate { 774*0Sstevel@tonic-gate char *line, *dn, *p, *q, *attr, *value; 775*0Sstevel@tonic-gate int rc, linenum, modop; 776*0Sstevel@tonic-gate LDAPMod **pmods; 777*0Sstevel@tonic-gate 778*0Sstevel@tonic-gate pmods = NULL; 779*0Sstevel@tonic-gate dn = NULL; 780*0Sstevel@tonic-gate linenum = 0; 781*0Sstevel@tonic-gate line = rbuf; 782*0Sstevel@tonic-gate rc = 0; 783*0Sstevel@tonic-gate 784*0Sstevel@tonic-gate while ( rc == 0 && rbuf != NULL && *rbuf != '\0' ) { 785*0Sstevel@tonic-gate ++linenum; 786*0Sstevel@tonic-gate if (( p = strchr( rbuf, '\n' )) == NULL ) { 787*0Sstevel@tonic-gate rbuf = NULL; 788*0Sstevel@tonic-gate } else { 789*0Sstevel@tonic-gate if ( *(p-1) == '\\' ) { /* lines ending in '\' are continued */ 790*0Sstevel@tonic-gate strcpy( p - 1, p ); 791*0Sstevel@tonic-gate rbuf = p; 792*0Sstevel@tonic-gate continue; 793*0Sstevel@tonic-gate } 794*0Sstevel@tonic-gate *p++ = '\0'; 795*0Sstevel@tonic-gate rbuf = p; 796*0Sstevel@tonic-gate } 797*0Sstevel@tonic-gate 798*0Sstevel@tonic-gate if ( dn == NULL ) { /* first line contains DN */ 799*0Sstevel@tonic-gate if (( dn = strdup( line )) == NULL ) { 800*0Sstevel@tonic-gate perror( "strdup" ); 801*0Sstevel@tonic-gate exit( LDAP_NO_MEMORY ); 802*0Sstevel@tonic-gate } 803*0Sstevel@tonic-gate } else { 804*0Sstevel@tonic-gate if (( p = strchr( line, '=' )) == NULL ) { 805*0Sstevel@tonic-gate value = NULL; 806*0Sstevel@tonic-gate p = line + strlen( line ); 807*0Sstevel@tonic-gate } else { 808*0Sstevel@tonic-gate *p++ = '\0'; 809*0Sstevel@tonic-gate value = p; 810*0Sstevel@tonic-gate } 811*0Sstevel@tonic-gate 812*0Sstevel@tonic-gate for ( attr = line; *attr != '\0' && isspace( *attr ); ++attr ) { 813*0Sstevel@tonic-gate ; /* skip attribute leading white space */ 814*0Sstevel@tonic-gate } 815*0Sstevel@tonic-gate 816*0Sstevel@tonic-gate for ( q = p - 1; q > attr && isspace( *q ); --q ) { 817*0Sstevel@tonic-gate *q = '\0'; /* remove attribute trailing white space */ 818*0Sstevel@tonic-gate } 819*0Sstevel@tonic-gate 820*0Sstevel@tonic-gate if ( value != NULL ) { 821*0Sstevel@tonic-gate while ( isspace( *value )) { 822*0Sstevel@tonic-gate ++value; /* skip value leading white space */ 823*0Sstevel@tonic-gate } 824*0Sstevel@tonic-gate for ( q = value + strlen( value ) - 1; q > value && 825*0Sstevel@tonic-gate isspace( *q ); --q ) { 826*0Sstevel@tonic-gate *q = '\0'; /* remove value trailing white space */ 827*0Sstevel@tonic-gate } 828*0Sstevel@tonic-gate if ( *value == '\0' ) { 829*0Sstevel@tonic-gate value = NULL; 830*0Sstevel@tonic-gate } 831*0Sstevel@tonic-gate 832*0Sstevel@tonic-gate } 833*0Sstevel@tonic-gate 834*0Sstevel@tonic-gate if ( value == NULL && newval ) { 835*0Sstevel@tonic-gate fprintf( stderr, gettext("%s: missing value on line %d (attr is %s)\n"), 836*0Sstevel@tonic-gate ldaptool_progname, linenum, attr ); 837*0Sstevel@tonic-gate rc = LDAP_PARAM_ERROR; 838*0Sstevel@tonic-gate } else { 839*0Sstevel@tonic-gate switch ( *attr ) { 840*0Sstevel@tonic-gate case '-': 841*0Sstevel@tonic-gate modop = LDAP_MOD_DELETE; 842*0Sstevel@tonic-gate ++attr; 843*0Sstevel@tonic-gate break; 844*0Sstevel@tonic-gate case '+': 845*0Sstevel@tonic-gate modop = LDAP_MOD_ADD; 846*0Sstevel@tonic-gate ++attr; 847*0Sstevel@tonic-gate break; 848*0Sstevel@tonic-gate default: 849*0Sstevel@tonic-gate #ifdef SOLARIS_LDAP_CMD 850*0Sstevel@tonic-gate modop = replace ? LDAP_MOD_REPLACE : LDAP_MOD_ADD; 851*0Sstevel@tonic-gate #else 852*0Sstevel@tonic-gate /*Bug 27479. Remove the add default*/ 853*0Sstevel@tonic-gate fprintf(stderr, gettext("%s: Invalid parameter specified for changetype modify (line %d of entry %s)\n"), 854*0Sstevel@tonic-gate ldaptool_progname, linenum, dn); 855*0Sstevel@tonic-gate rc = LDAP_PARAM_ERROR; 856*0Sstevel@tonic-gate #endif /* SOLARIS_LDAP_CMD */ 857*0Sstevel@tonic-gate } 858*0Sstevel@tonic-gate 859*0Sstevel@tonic-gate addmodifyop( &pmods, modop, attr, value, 860*0Sstevel@tonic-gate ( value == NULL ) ? 0 : strlen( value )); 861*0Sstevel@tonic-gate } 862*0Sstevel@tonic-gate } 863*0Sstevel@tonic-gate 864*0Sstevel@tonic-gate line = rbuf; 865*0Sstevel@tonic-gate } 866*0Sstevel@tonic-gate 867*0Sstevel@tonic-gate if ( rc == 0 ) { 868*0Sstevel@tonic-gate if ( dn == NULL ) { 869*0Sstevel@tonic-gate rc = LDAP_PARAM_ERROR; 870*0Sstevel@tonic-gate #ifdef SOLARIS_LDAP_CMD 871*0Sstevel@tonic-gate } else if (( rc = domodify( ld, dn, pmods, newval )) == LDAP_SUCCESS ){ 872*0Sstevel@tonic-gate #else 873*0Sstevel@tonic-gate } else if (( rc = domodify( dn, pmods, newval )) == LDAP_SUCCESS ){ 874*0Sstevel@tonic-gate #endif /* SOLARIS_LDAP_CMD */ 875*0Sstevel@tonic-gate rc = 0; 876*0Sstevel@tonic-gate } 877*0Sstevel@tonic-gate } 878*0Sstevel@tonic-gate 879*0Sstevel@tonic-gate if ( pmods != NULL ) { 880*0Sstevel@tonic-gate freepmods( pmods ); 881*0Sstevel@tonic-gate } 882*0Sstevel@tonic-gate if ( dn != NULL ) { 883*0Sstevel@tonic-gate free( dn ); 884*0Sstevel@tonic-gate } 885*0Sstevel@tonic-gate 886*0Sstevel@tonic-gate return( rc ); 887*0Sstevel@tonic-gate } 888*0Sstevel@tonic-gate 889*0Sstevel@tonic-gate 890*0Sstevel@tonic-gate static void 891*0Sstevel@tonic-gate addmodifyop( LDAPMod ***pmodsp, int modop, char *attr, char *value, int vlen ) 892*0Sstevel@tonic-gate { 893*0Sstevel@tonic-gate LDAPMod **pmods; 894*0Sstevel@tonic-gate int i, j, rc; 895*0Sstevel@tonic-gate struct berval *bvp; 896*0Sstevel@tonic-gate 897*0Sstevel@tonic-gate pmods = *pmodsp; 898*0Sstevel@tonic-gate modop |= LDAP_MOD_BVALUES; 899*0Sstevel@tonic-gate 900*0Sstevel@tonic-gate i = 0; 901*0Sstevel@tonic-gate if ( pmods != NULL ) { 902*0Sstevel@tonic-gate for ( ; pmods[ i ] != NULL; ++i ) { 903*0Sstevel@tonic-gate if ( strcasecmp( pmods[ i ]->mod_type, attr ) == 0 && 904*0Sstevel@tonic-gate pmods[ i ]->mod_op == modop ) { 905*0Sstevel@tonic-gate break; 906*0Sstevel@tonic-gate } 907*0Sstevel@tonic-gate } 908*0Sstevel@tonic-gate } 909*0Sstevel@tonic-gate 910*0Sstevel@tonic-gate if ( pmods == NULL || pmods[ i ] == NULL ) { 911*0Sstevel@tonic-gate if (( pmods = (LDAPMod **)LDAPTOOL_SAFEREALLOC( pmods, (i + 2) * 912*0Sstevel@tonic-gate sizeof( LDAPMod * ))) == NULL ) { 913*0Sstevel@tonic-gate perror( "realloc" ); 914*0Sstevel@tonic-gate exit( LDAP_NO_MEMORY ); 915*0Sstevel@tonic-gate } 916*0Sstevel@tonic-gate *pmodsp = pmods; 917*0Sstevel@tonic-gate pmods[ i + 1 ] = NULL; 918*0Sstevel@tonic-gate if (( pmods[ i ] = (LDAPMod *)calloc( 1, sizeof( LDAPMod ))) 919*0Sstevel@tonic-gate == NULL ) { 920*0Sstevel@tonic-gate perror( "calloc" ); 921*0Sstevel@tonic-gate exit( LDAP_NO_MEMORY ); 922*0Sstevel@tonic-gate } 923*0Sstevel@tonic-gate pmods[ i ]->mod_op = modop; 924*0Sstevel@tonic-gate if (( pmods[ i ]->mod_type = strdup( attr )) == NULL ) { 925*0Sstevel@tonic-gate perror( "strdup" ); 926*0Sstevel@tonic-gate exit( LDAP_NO_MEMORY ); 927*0Sstevel@tonic-gate } 928*0Sstevel@tonic-gate } 929*0Sstevel@tonic-gate 930*0Sstevel@tonic-gate if ( value != NULL ) { 931*0Sstevel@tonic-gate j = 0; 932*0Sstevel@tonic-gate if ( pmods[ i ]->mod_bvalues != NULL ) { 933*0Sstevel@tonic-gate for ( ; pmods[ i ]->mod_bvalues[ j ] != NULL; ++j ) { 934*0Sstevel@tonic-gate ; 935*0Sstevel@tonic-gate } 936*0Sstevel@tonic-gate } 937*0Sstevel@tonic-gate if (( pmods[ i ]->mod_bvalues = (struct berval **) 938*0Sstevel@tonic-gate LDAPTOOL_SAFEREALLOC( pmods[ i ]->mod_bvalues, 939*0Sstevel@tonic-gate (j + 2) * sizeof( struct berval * ))) == NULL ) { 940*0Sstevel@tonic-gate perror( "realloc" ); 941*0Sstevel@tonic-gate exit( LDAP_NO_MEMORY ); 942*0Sstevel@tonic-gate } 943*0Sstevel@tonic-gate pmods[ i ]->mod_bvalues[ j + 1 ] = NULL; 944*0Sstevel@tonic-gate if (( bvp = (struct berval *)malloc( sizeof( struct berval ))) 945*0Sstevel@tonic-gate == NULL ) { 946*0Sstevel@tonic-gate perror( "malloc" ); 947*0Sstevel@tonic-gate exit( LDAP_NO_MEMORY ); 948*0Sstevel@tonic-gate } 949*0Sstevel@tonic-gate pmods[ i ]->mod_bvalues[ j ] = bvp; 950*0Sstevel@tonic-gate 951*0Sstevel@tonic-gate #ifdef notdef 952*0Sstevel@tonic-gate if (ldaptool_verbose) { 953*0Sstevel@tonic-gate printf(gettext("%s: value: %s vlen: %d\n"), "ldapmodify", value, vlen); 954*0Sstevel@tonic-gate } 955*0Sstevel@tonic-gate #endif 956*0Sstevel@tonic-gate rc = ldaptool_berval_from_ldif_value( value, vlen, bvp, 957*0Sstevel@tonic-gate ( ldif_version >= LDIF_VERSION_ONE ), valsfromfiles, 958*0Sstevel@tonic-gate 1 /* report errors */ ); 959*0Sstevel@tonic-gate if ( rc != LDAPTOOL_FILEURL_SUCCESS ) { 960*0Sstevel@tonic-gate exit( ldaptool_fileurlerr2ldaperr( rc )); 961*0Sstevel@tonic-gate } 962*0Sstevel@tonic-gate } 963*0Sstevel@tonic-gate } 964*0Sstevel@tonic-gate 965*0Sstevel@tonic-gate 966*0Sstevel@tonic-gate static int 967*0Sstevel@tonic-gate #ifdef SOLARIS_LDAP_CMD 968*0Sstevel@tonic-gate domodify( LDAP *ld, char *dn, LDAPMod **pmods, int newentry ) 969*0Sstevel@tonic-gate #else 970*0Sstevel@tonic-gate domodify( char *dn, LDAPMod **pmods, int newentry ) 971*0Sstevel@tonic-gate #endif /* SOLARIS_LDAP_CMD */ 972*0Sstevel@tonic-gate { 973*0Sstevel@tonic-gate int i, j, notascii, op; 974*0Sstevel@tonic-gate struct berval *bvp; 975*0Sstevel@tonic-gate 976*0Sstevel@tonic-gate if ( pmods == NULL ) { 977*0Sstevel@tonic-gate fprintf( stderr, gettext("%s: no attributes to change or add (entry %s)\n"), 978*0Sstevel@tonic-gate ldaptool_progname, dn ); 979*0Sstevel@tonic-gate return( LDAP_PARAM_ERROR ); 980*0Sstevel@tonic-gate } 981*0Sstevel@tonic-gate 982*0Sstevel@tonic-gate if ( ldaptool_verbose ) { 983*0Sstevel@tonic-gate for ( i = 0; pmods[ i ] != NULL; ++i ) { 984*0Sstevel@tonic-gate op = pmods[ i ]->mod_op & ~LDAP_MOD_BVALUES; 985*0Sstevel@tonic-gate printf( gettext("%s %s:\n"), op == LDAP_MOD_REPLACE ? 986*0Sstevel@tonic-gate gettext("replace") : op == LDAP_MOD_ADD ? 987*0Sstevel@tonic-gate gettext("add") : gettext("delete"), pmods[ i ]->mod_type ); 988*0Sstevel@tonic-gate if ( pmods[ i ]->mod_bvalues != NULL ) { 989*0Sstevel@tonic-gate for ( j = 0; pmods[ i ]->mod_bvalues[ j ] != NULL; ++j ) { 990*0Sstevel@tonic-gate bvp = pmods[ i ]->mod_bvalues[ j ]; 991*0Sstevel@tonic-gate notascii = 0; 992*0Sstevel@tonic-gate if ( !display_binary_values ) { 993*0Sstevel@tonic-gate notascii = !ldaptool_berval_is_ascii( bvp ); 994*0Sstevel@tonic-gate } 995*0Sstevel@tonic-gate if ( notascii ) { 996*0Sstevel@tonic-gate printf( gettext("\tNOT ASCII (%ld bytes)\n"), bvp->bv_len ); 997*0Sstevel@tonic-gate } else { 998*0Sstevel@tonic-gate printf( "\t%s\n", bvp->bv_val ); 999*0Sstevel@tonic-gate } 1000*0Sstevel@tonic-gate } 1001*0Sstevel@tonic-gate } 1002*0Sstevel@tonic-gate } 1003*0Sstevel@tonic-gate } 1004*0Sstevel@tonic-gate 1005*0Sstevel@tonic-gate if ( !ldapmodify_quiet) { 1006*0Sstevel@tonic-gate if ( newentry ) { 1007*0Sstevel@tonic-gate printf( gettext("%sadding new entry %s\n"), 1008*0Sstevel@tonic-gate ldaptool_not ? "!" : "", dn ); 1009*0Sstevel@tonic-gate } else { 1010*0Sstevel@tonic-gate printf( gettext("%smodifying entry %s\n"), 1011*0Sstevel@tonic-gate ldaptool_not ? "!" : "", dn ); 1012*0Sstevel@tonic-gate } 1013*0Sstevel@tonic-gate } 1014*0Sstevel@tonic-gate 1015*0Sstevel@tonic-gate if ( !ldaptool_not ) { 1016*0Sstevel@tonic-gate if ( newentry ) { 1017*0Sstevel@tonic-gate unsigned int sleep_interval = 2; /* seconds */ 1018*0Sstevel@tonic-gate 1019*0Sstevel@tonic-gate #ifdef SOLARIS_LDAP_CMD 1020*0Sstevel@tonic-gate /* Backward compatibility with old Solaris command */ 1021*0Sstevel@tonic-gate unsigned int nb = 0; 1022*0Sstevel@tonic-gate timestruc_t to; 1023*0Sstevel@tonic-gate while ((i = ldaptool_add_ext_s( ld, dn, pmods, 1024*0Sstevel@tonic-gate ldaptool_request_ctrls, NULL, "ldap_add" )) 1025*0Sstevel@tonic-gate != LDAP_SUCCESS) { 1026*0Sstevel@tonic-gate if (i == LDAP_BUSY) { 1027*0Sstevel@tonic-gate if ( sleep_interval > 3600 ) { 1028*0Sstevel@tonic-gate printf(gettext("ldap_add: Unable to complete " 1029*0Sstevel@tonic-gate "request. Server is too " 1030*0Sstevel@tonic-gate "busy servicing other " 1031*0Sstevel@tonic-gate "requests\n")); 1032*0Sstevel@tonic-gate break; 1033*0Sstevel@tonic-gate } 1034*0Sstevel@tonic-gate if ( !ldapmodify_quiet ) { 1035*0Sstevel@tonic-gate printf(gettext("ldap_add: LDAP_BUSY returned " 1036*0Sstevel@tonic-gate "by server. Will retry " 1037*0Sstevel@tonic-gate "operation in %d seconds\n"), 1038*0Sstevel@tonic-gate sleep_interval); 1039*0Sstevel@tonic-gate } 1040*0Sstevel@tonic-gate sleep( sleep_interval ); 1041*0Sstevel@tonic-gate sleep_interval *= 2; 1042*0Sstevel@tonic-gate } else if (i == LDAP_NO_SUCH_OBJECT) { 1043*0Sstevel@tonic-gate /* 1044*0Sstevel@tonic-gate * Wait for the parent entry to be created by 1045*0Sstevel@tonic-gate * another thread. Do not retry more than the 1046*0Sstevel@tonic-gate * number of threads. 1047*0Sstevel@tonic-gate */ 1048*0Sstevel@tonic-gate ++nb; 1049*0Sstevel@tonic-gate if (nb >= nbthreads) 1050*0Sstevel@tonic-gate break; 1051*0Sstevel@tonic-gate mutex_lock(&wait_mutex); 1052*0Sstevel@tonic-gate to.tv_sec = 5; 1053*0Sstevel@tonic-gate to.tv_nsec = 0; 1054*0Sstevel@tonic-gate if (cond_reltimedwait(&wait_cond, &wait_mutex, &to) 1055*0Sstevel@tonic-gate == ETIME) { 1056*0Sstevel@tonic-gate nb = nbthreads; /* last chance */ 1057*0Sstevel@tonic-gate } 1058*0Sstevel@tonic-gate mutex_unlock(&wait_mutex); 1059*0Sstevel@tonic-gate } else { 1060*0Sstevel@tonic-gate break; 1061*0Sstevel@tonic-gate } 1062*0Sstevel@tonic-gate } 1063*0Sstevel@tonic-gate cond_broadcast(&wait_cond); 1064*0Sstevel@tonic-gate #else 1065*0Sstevel@tonic-gate while ((i = ldaptool_add_ext_s( ld, dn, pmods, 1066*0Sstevel@tonic-gate ldaptool_request_ctrls, NULL, "ldap_add" )) 1067*0Sstevel@tonic-gate == LDAP_BUSY) { 1068*0Sstevel@tonic-gate if ( sleep_interval > 3600 ) { 1069*0Sstevel@tonic-gate printf("ldap_add: Unable to complete request. "); 1070*0Sstevel@tonic-gate printf("Server is too "); 1071*0Sstevel@tonic-gate printf("busy servicing other requests\n"); 1072*0Sstevel@tonic-gate break; 1073*0Sstevel@tonic-gate } 1074*0Sstevel@tonic-gate if ( !ldapmodify_quiet ) { 1075*0Sstevel@tonic-gate printf("ldap_add: LDAP_BUSY returned by server. "); 1076*0Sstevel@tonic-gate printf("Will retry operation "); 1077*0Sstevel@tonic-gate printf("in %d seconds\n", sleep_interval); 1078*0Sstevel@tonic-gate } 1079*0Sstevel@tonic-gate sleep( sleep_interval ); 1080*0Sstevel@tonic-gate sleep_interval *= 2; 1081*0Sstevel@tonic-gate } 1082*0Sstevel@tonic-gate #endif /* SOLARIS_LDAP_CMD */ 1083*0Sstevel@tonic-gate } else { 1084*0Sstevel@tonic-gate i = ldaptool_modify_ext_s( ld, dn, pmods, ldaptool_request_ctrls, 1085*0Sstevel@tonic-gate NULL, "ldap_modify" ); 1086*0Sstevel@tonic-gate } 1087*0Sstevel@tonic-gate if ( i == LDAP_SUCCESS && ldaptool_verbose ) { 1088*0Sstevel@tonic-gate printf( gettext("modify complete\n") ); 1089*0Sstevel@tonic-gate } 1090*0Sstevel@tonic-gate } else { 1091*0Sstevel@tonic-gate i = LDAP_SUCCESS; 1092*0Sstevel@tonic-gate } 1093*0Sstevel@tonic-gate 1094*0Sstevel@tonic-gate if ( !ldapmodify_quiet) { 1095*0Sstevel@tonic-gate putchar( '\n' ); 1096*0Sstevel@tonic-gate } 1097*0Sstevel@tonic-gate 1098*0Sstevel@tonic-gate return( i ); 1099*0Sstevel@tonic-gate } 1100*0Sstevel@tonic-gate 1101*0Sstevel@tonic-gate 1102*0Sstevel@tonic-gate static int 1103*0Sstevel@tonic-gate #ifdef SOLARIS_LDAP_CMD 1104*0Sstevel@tonic-gate dodelete( LDAP *ld, char *dn ) 1105*0Sstevel@tonic-gate #else 1106*0Sstevel@tonic-gate dodelete( char *dn ) 1107*0Sstevel@tonic-gate #endif /* SOLARIS_LDAP_CMD */ 1108*0Sstevel@tonic-gate { 1109*0Sstevel@tonic-gate int rc; 1110*0Sstevel@tonic-gate 1111*0Sstevel@tonic-gate printf( gettext("%sdeleting entry %s\n"), ldaptool_not ? "!" : "", dn ); 1112*0Sstevel@tonic-gate if ( !ldaptool_not ) { 1113*0Sstevel@tonic-gate if (( rc = ldaptool_delete_ext_s( ld, dn, ldaptool_request_ctrls, 1114*0Sstevel@tonic-gate NULL, "ldap_delete" )) == LDAP_SUCCESS && ldaptool_verbose ) { 1115*0Sstevel@tonic-gate printf( gettext("delete complete") ); 1116*0Sstevel@tonic-gate } 1117*0Sstevel@tonic-gate } else { 1118*0Sstevel@tonic-gate rc = LDAP_SUCCESS; 1119*0Sstevel@tonic-gate } 1120*0Sstevel@tonic-gate 1121*0Sstevel@tonic-gate putchar( '\n' ); 1122*0Sstevel@tonic-gate 1123*0Sstevel@tonic-gate return( rc ); 1124*0Sstevel@tonic-gate } 1125*0Sstevel@tonic-gate 1126*0Sstevel@tonic-gate 1127*0Sstevel@tonic-gate static int 1128*0Sstevel@tonic-gate #ifdef SOLARIS_LDAP_CMD 1129*0Sstevel@tonic-gate dorename( LDAP *ld, char *dn, char *newrdn, char *newparent, int deleteoldrdn ) 1130*0Sstevel@tonic-gate #else 1131*0Sstevel@tonic-gate dorename( char *dn, char *newrdn, char *newparent, int deleteoldrdn ) 1132*0Sstevel@tonic-gate #endif /* SOLARIS_LDAP_CMD */ 1133*0Sstevel@tonic-gate { 1134*0Sstevel@tonic-gate int rc; 1135*0Sstevel@tonic-gate 1136*0Sstevel@tonic-gate if ( ldaptool_verbose ) { 1137*0Sstevel@tonic-gate if ( newparent == NULL ) { 1138*0Sstevel@tonic-gate printf(deleteoldrdn ? 1139*0Sstevel@tonic-gate gettext("new RDN: %s (do not keep existing values)\n"): 1140*0Sstevel@tonic-gate gettext("new RDN: %s (keep existing values)\n")); 1141*0Sstevel@tonic-gate } else { 1142*0Sstevel@tonic-gate printf(deleteoldrdn ? 1143*0Sstevel@tonic-gate gettext("new RDN: %s, new parent %s ( do not keep existing values)\n"): 1144*0Sstevel@tonic-gate gettext("new RDN: %s, new parent %s ( keep existing values)\n")); 1145*0Sstevel@tonic-gate } 1146*0Sstevel@tonic-gate } 1147*0Sstevel@tonic-gate 1148*0Sstevel@tonic-gate printf( gettext("%smodifying RDN of entry %s%s\n"), 1149*0Sstevel@tonic-gate ldaptool_not ? "!" : "", dn, ( newparent == NULL ) ? "" : 1150*0Sstevel@tonic-gate gettext(" and/or moving it beneath a new parent\n") ); 1151*0Sstevel@tonic-gate 1152*0Sstevel@tonic-gate if ( !ldaptool_not ) { 1153*0Sstevel@tonic-gate if (( rc = ldaptool_rename_s( ld, dn, newrdn, newparent, deleteoldrdn, 1154*0Sstevel@tonic-gate ldaptool_request_ctrls, NULL, "ldap_rename" )) == LDAP_SUCCESS 1155*0Sstevel@tonic-gate && ldaptool_verbose ) { 1156*0Sstevel@tonic-gate printf( gettext("rename completed\n") ); 1157*0Sstevel@tonic-gate } 1158*0Sstevel@tonic-gate } else { 1159*0Sstevel@tonic-gate rc = LDAP_SUCCESS; 1160*0Sstevel@tonic-gate } 1161*0Sstevel@tonic-gate 1162*0Sstevel@tonic-gate putchar( '\n' ); 1163*0Sstevel@tonic-gate 1164*0Sstevel@tonic-gate return( rc ); 1165*0Sstevel@tonic-gate } 1166*0Sstevel@tonic-gate 1167*0Sstevel@tonic-gate 1168*0Sstevel@tonic-gate static void 1169*0Sstevel@tonic-gate freepmods( LDAPMod **pmods ) 1170*0Sstevel@tonic-gate { 1171*0Sstevel@tonic-gate int i; 1172*0Sstevel@tonic-gate 1173*0Sstevel@tonic-gate for ( i = 0; pmods[ i ] != NULL; ++i ) { 1174*0Sstevel@tonic-gate if ( pmods[ i ]->mod_bvalues != NULL ) { 1175*0Sstevel@tonic-gate ber_bvecfree( pmods[ i ]->mod_bvalues ); 1176*0Sstevel@tonic-gate } 1177*0Sstevel@tonic-gate if ( pmods[ i ]->mod_type != NULL ) { 1178*0Sstevel@tonic-gate free( pmods[ i ]->mod_type ); 1179*0Sstevel@tonic-gate } 1180*0Sstevel@tonic-gate free( pmods[ i ] ); 1181*0Sstevel@tonic-gate } 1182*0Sstevel@tonic-gate free( pmods ); 1183*0Sstevel@tonic-gate } 1184*0Sstevel@tonic-gate 1185*0Sstevel@tonic-gate 1186*0Sstevel@tonic-gate static char * 1187*0Sstevel@tonic-gate read_one_record( FILE *fp ) 1188*0Sstevel@tonic-gate { 1189*0Sstevel@tonic-gate int len, gotnothing; 1190*0Sstevel@tonic-gate char *buf, line[ LDAPMOD_MAXLINE ]; 1191*0Sstevel@tonic-gate int lcur, lmax; 1192*0Sstevel@tonic-gate 1193*0Sstevel@tonic-gate lcur = lmax = 0; 1194*0Sstevel@tonic-gate buf = NULL; 1195*0Sstevel@tonic-gate gotnothing = 1; 1196*0Sstevel@tonic-gate 1197*0Sstevel@tonic-gate #ifdef SOLARIS_LDAP_CMD 1198*0Sstevel@tonic-gate mutex_lock(&read_mutex); 1199*0Sstevel@tonic-gate 1200*0Sstevel@tonic-gate if (fp == NULL) { 1201*0Sstevel@tonic-gate mutex_unlock(&read_mutex); 1202*0Sstevel@tonic-gate return(NULL); 1203*0Sstevel@tonic-gate } 1204*0Sstevel@tonic-gate #endif 1205*0Sstevel@tonic-gate 1206*0Sstevel@tonic-gate while ( fgets( line, sizeof(line), fp ) != NULL ) { 1207*0Sstevel@tonic-gate if ( (len = strlen( line )) < 2 ) { 1208*0Sstevel@tonic-gate if ( gotnothing ) { 1209*0Sstevel@tonic-gate continue; 1210*0Sstevel@tonic-gate } else { 1211*0Sstevel@tonic-gate break; 1212*0Sstevel@tonic-gate } 1213*0Sstevel@tonic-gate } 1214*0Sstevel@tonic-gate 1215*0Sstevel@tonic-gate /* Check if the blank line starts with '\r' (CR) */ 1216*0Sstevel@tonic-gate if ( ((len = strlen( line )) == 2) && (line[0] == '\r') ) { 1217*0Sstevel@tonic-gate if ( gotnothing ) { 1218*0Sstevel@tonic-gate continue; 1219*0Sstevel@tonic-gate } else { 1220*0Sstevel@tonic-gate break; 1221*0Sstevel@tonic-gate } 1222*0Sstevel@tonic-gate } 1223*0Sstevel@tonic-gate 1224*0Sstevel@tonic-gate if ( *line == '#' ) { 1225*0Sstevel@tonic-gate continue; /* skip comment lines */ 1226*0Sstevel@tonic-gate } 1227*0Sstevel@tonic-gate 1228*0Sstevel@tonic-gate gotnothing = 0; 1229*0Sstevel@tonic-gate if ( lcur + len + 1 > lmax ) { 1230*0Sstevel@tonic-gate lmax = LDAPMOD_MAXLINE 1231*0Sstevel@tonic-gate * (( lcur + len + 1 ) / LDAPMOD_MAXLINE + 1 ); 1232*0Sstevel@tonic-gate if (( buf = (char *)LDAPTOOL_SAFEREALLOC( buf, lmax )) == NULL ) { 1233*0Sstevel@tonic-gate perror( "realloc" ); 1234*0Sstevel@tonic-gate #ifdef SOLARIS_LDAP_CMD 1235*0Sstevel@tonic-gate mutex_unlock(&read_mutex); 1236*0Sstevel@tonic-gate #endif 1237*0Sstevel@tonic-gate exit( LDAP_NO_MEMORY ); 1238*0Sstevel@tonic-gate } 1239*0Sstevel@tonic-gate } 1240*0Sstevel@tonic-gate strcpy( buf + lcur, line ); 1241*0Sstevel@tonic-gate lcur += len; 1242*0Sstevel@tonic-gate } 1243*0Sstevel@tonic-gate 1244*0Sstevel@tonic-gate #ifdef SOLARIS_LDAP_CMD 1245*0Sstevel@tonic-gate mutex_unlock(&read_mutex); 1246*0Sstevel@tonic-gate #endif 1247*0Sstevel@tonic-gate 1248*0Sstevel@tonic-gate return( buf ); 1249*0Sstevel@tonic-gate } 1250*0Sstevel@tonic-gate 1251*0Sstevel@tonic-gate 1252*0Sstevel@tonic-gate /* 1253*0Sstevel@tonic-gate * strdup and trim trailing blanks 1254*0Sstevel@tonic-gate */ 1255*0Sstevel@tonic-gate static char * 1256*0Sstevel@tonic-gate strdup_and_trim( char *s ) 1257*0Sstevel@tonic-gate { 1258*0Sstevel@tonic-gate char *p; 1259*0Sstevel@tonic-gate 1260*0Sstevel@tonic-gate if (( s = strdup( s )) == NULL ) { 1261*0Sstevel@tonic-gate perror( "strdup" ); 1262*0Sstevel@tonic-gate exit( LDAP_NO_MEMORY ); 1263*0Sstevel@tonic-gate } 1264*0Sstevel@tonic-gate 1265*0Sstevel@tonic-gate p = s + strlen( s ) - 1; 1266*0Sstevel@tonic-gate while ( p >= s && isspace( *p )) { 1267*0Sstevel@tonic-gate --p; 1268*0Sstevel@tonic-gate } 1269*0Sstevel@tonic-gate *++p = '\0'; 1270*0Sstevel@tonic-gate 1271*0Sstevel@tonic-gate return( s ); 1272*0Sstevel@tonic-gate } 1273