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