17c478bd9Sstevel@tonic-gate /* 2*ffc33b84SSreedhar Chalamalasetti - Sun Microsystems - Bangalore India * Copyright 2008 Sun Microsystems, Inc. All rights reserved. 37c478bd9Sstevel@tonic-gate * Use is subject to license terms. 47c478bd9Sstevel@tonic-gate */ 57c478bd9Sstevel@tonic-gate 67c478bd9Sstevel@tonic-gate /* 77c478bd9Sstevel@tonic-gate * The contents of this file are subject to the Netscape Public 87c478bd9Sstevel@tonic-gate * License Version 1.1 (the "License"); you may not use this file 97c478bd9Sstevel@tonic-gate * except in compliance with the License. You may obtain a copy of 107c478bd9Sstevel@tonic-gate * the License at http://www.mozilla.org/NPL/ 117c478bd9Sstevel@tonic-gate * 127c478bd9Sstevel@tonic-gate * Software distributed under the License is distributed on an "AS 137c478bd9Sstevel@tonic-gate * IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or 147c478bd9Sstevel@tonic-gate * implied. See the License for the specific language governing 157c478bd9Sstevel@tonic-gate * rights and limitations under the License. 167c478bd9Sstevel@tonic-gate * 177c478bd9Sstevel@tonic-gate * The Original Code is Mozilla Communicator client code, released 187c478bd9Sstevel@tonic-gate * March 31, 1998. 197c478bd9Sstevel@tonic-gate * 207c478bd9Sstevel@tonic-gate * The Initial Developer of the Original Code is Netscape 217c478bd9Sstevel@tonic-gate * Communications Corporation. Portions created by Netscape are 227c478bd9Sstevel@tonic-gate * Copyright (C) 1998-1999 Netscape Communications Corporation. All 237c478bd9Sstevel@tonic-gate * Rights Reserved. 247c478bd9Sstevel@tonic-gate * 257c478bd9Sstevel@tonic-gate * Contributor(s): 267c478bd9Sstevel@tonic-gate */ 277c478bd9Sstevel@tonic-gate 287c478bd9Sstevel@tonic-gate /* ldapmodify.c - generic program to modify or add entries using LDAP */ 297c478bd9Sstevel@tonic-gate 307c478bd9Sstevel@tonic-gate #include "ldaptool.h" 317c478bd9Sstevel@tonic-gate #include "fileurl.h" 327c478bd9Sstevel@tonic-gate 337c478bd9Sstevel@tonic-gate #ifdef SOLARIS_LDAP_CMD 347c478bd9Sstevel@tonic-gate #include <locale.h> 357c478bd9Sstevel@tonic-gate #include "ldif.h" 367c478bd9Sstevel@tonic-gate #endif /* SOLARIS_LDAP_CMD */ 377c478bd9Sstevel@tonic-gate 387c478bd9Sstevel@tonic-gate #ifndef SOLARIS_LDAP_CMD 397c478bd9Sstevel@tonic-gate #define gettext(s) s 407c478bd9Sstevel@tonic-gate #endif 417c478bd9Sstevel@tonic-gate 427c478bd9Sstevel@tonic-gate static int newval, contoper, force, valsfromfiles, display_binary_values; 437c478bd9Sstevel@tonic-gate static int ldif_version = -1; /* -1 => unknown version */ 447c478bd9Sstevel@tonic-gate static char *rejfile = NULL; 457c478bd9Sstevel@tonic-gate static char *bulkimport_suffix = NULL; 467c478bd9Sstevel@tonic-gate static int ldapmodify_quiet = 0; 477c478bd9Sstevel@tonic-gate 487c478bd9Sstevel@tonic-gate #ifdef SOLARIS_LDAP_CMD 497c478bd9Sstevel@tonic-gate static int error = 0, replace, nbthreads = 1; 507c478bd9Sstevel@tonic-gate static int thr_create_errors = 0; 517c478bd9Sstevel@tonic-gate static pthread_mutex_t read_mutex = {0}; 527c478bd9Sstevel@tonic-gate static pthread_mutex_t wait_mutex = {0}; 537c478bd9Sstevel@tonic-gate static pthread_cond_t wait_cond = {0}; 547c478bd9Sstevel@tonic-gate #else 557c478bd9Sstevel@tonic-gate /* 567c478bd9Sstevel@tonic-gate * For Solaris, ld is defined local to process() because 577c478bd9Sstevel@tonic-gate * multiple threads restricts Solaris from using a global 587c478bd9Sstevel@tonic-gate * ld variable. 597c478bd9Sstevel@tonic-gate * Solaris uses multiple threads to create multiple 607c478bd9Sstevel@tonic-gate * ldap connections if nbthreads > 1 (i.e -l option). 617c478bd9Sstevel@tonic-gate */ 627c478bd9Sstevel@tonic-gate static LDAP *ld; 637c478bd9Sstevel@tonic-gate #endif /* SOLARIS_LDAP_CMD */ 647c478bd9Sstevel@tonic-gate 657c478bd9Sstevel@tonic-gate #define LDAPMOD_MAXLINE 4096 667c478bd9Sstevel@tonic-gate 677c478bd9Sstevel@tonic-gate /* strings found in replog/LDIF entries (mostly lifted from slurpd/slurp.h) */ 687c478bd9Sstevel@tonic-gate #define T_REPLICA_STR "replica" 697c478bd9Sstevel@tonic-gate #define T_DN_STR "dn" 707c478bd9Sstevel@tonic-gate #define T_VERSION_STR "version" 717c478bd9Sstevel@tonic-gate #define T_CHANGETYPESTR "changetype" 727c478bd9Sstevel@tonic-gate #define T_ADDCTSTR "add" 737c478bd9Sstevel@tonic-gate #define T_MODIFYCTSTR "modify" 747c478bd9Sstevel@tonic-gate #define T_DELETECTSTR "delete" 757c478bd9Sstevel@tonic-gate #define T_RENAMECTSTR "rename" /* non-standard */ 767c478bd9Sstevel@tonic-gate #define T_MODDNCTSTR "moddn" 777c478bd9Sstevel@tonic-gate #define T_MODRDNCTSTR "modrdn" 787c478bd9Sstevel@tonic-gate #define T_MODOPADDSTR "add" 797c478bd9Sstevel@tonic-gate #define T_MODOPREPLACESTR "replace" 807c478bd9Sstevel@tonic-gate #define T_MODOPDELETESTR "delete" 817c478bd9Sstevel@tonic-gate #define T_MODSEPSTR "-" 827c478bd9Sstevel@tonic-gate #define T_NEWRDNSTR "newrdn" 837c478bd9Sstevel@tonic-gate #define T_NEWSUPERIORSTR "newsuperior" 847c478bd9Sstevel@tonic-gate #define T_NEWPARENTSTR "newparent" 857c478bd9Sstevel@tonic-gate #define T_DELETEOLDRDNSTR "deleteoldrdn" 867c478bd9Sstevel@tonic-gate #define T_NEWSUPERIORSTR "newsuperior" 877c478bd9Sstevel@tonic-gate #define T_NEWPARENTSTR "newparent" /* non-standard */ 887c478bd9Sstevel@tonic-gate 897c478bd9Sstevel@tonic-gate /* bulk import */ 907c478bd9Sstevel@tonic-gate #define BULKIMPORT_START_OID "2.16.840.1.113730.3.5.7" 917c478bd9Sstevel@tonic-gate #define BULKIMPORT_STOP_OID "2.16.840.1.113730.3.5.8" 927c478bd9Sstevel@tonic-gate 937c478bd9Sstevel@tonic-gate static int process( void *arg ); 947c478bd9Sstevel@tonic-gate static void options_callback( int option, char *optarg ); 957c478bd9Sstevel@tonic-gate static void addmodifyop( LDAPMod ***pmodsp, int modop, char *attr, 967c478bd9Sstevel@tonic-gate char *value, int vlen ); 977c478bd9Sstevel@tonic-gate static void freepmods( LDAPMod **pmods ); 987c478bd9Sstevel@tonic-gate static char *read_one_record( FILE *fp ); 997c478bd9Sstevel@tonic-gate static char *strdup_and_trim( char *s ); 1007c478bd9Sstevel@tonic-gate 1017c478bd9Sstevel@tonic-gate #ifdef SOLARIS_LDAP_CMD 1027c478bd9Sstevel@tonic-gate static int process_ldapmod_rec( LDAP *ld, char *rbuf ); 1037c478bd9Sstevel@tonic-gate static int process_ldif_rec( LDAP *ld, char *rbuf ); 1047c478bd9Sstevel@tonic-gate static int domodify( LDAP *ld, char *dn, LDAPMod **pmods, int newentry ); 1057c478bd9Sstevel@tonic-gate static int dodelete( LDAP *ld, char *dn ); 1067c478bd9Sstevel@tonic-gate static int dorename( LDAP *ld, char *dn, char *newrdn, char *newparent, 1077c478bd9Sstevel@tonic-gate int deleteoldrdn ); 1087c478bd9Sstevel@tonic-gate #else 1097c478bd9Sstevel@tonic-gate static int process_ldapmod_rec( char *rbuf ); 1107c478bd9Sstevel@tonic-gate static int process_ldif_rec( char *rbuf ); 1117c478bd9Sstevel@tonic-gate static int domodify( char *dn, LDAPMod **pmods, int newentry ); 1127c478bd9Sstevel@tonic-gate static int dodelete( char *dn ); 1137c478bd9Sstevel@tonic-gate static int dorename( char *dn, char *newrdn, char *newparent, 1147c478bd9Sstevel@tonic-gate int deleteoldrdn ); 1157c478bd9Sstevel@tonic-gate #endif /* SOLARIS_LDAP_CMD */ 1167c478bd9Sstevel@tonic-gate 1177c478bd9Sstevel@tonic-gate static void 1187c478bd9Sstevel@tonic-gate usage( void ) 1197c478bd9Sstevel@tonic-gate { 1207c478bd9Sstevel@tonic-gate fprintf( stderr, gettext("usage: %s [options]\n"), ldaptool_progname ); 1217c478bd9Sstevel@tonic-gate fprintf( stderr, gettext("options:\n") ); 1227c478bd9Sstevel@tonic-gate ldaptool_common_usage( 0 ); 1237c478bd9Sstevel@tonic-gate fprintf( stderr, gettext(" -c\t\tcontinuous mode (do not stop on errors)\n") ); 1247c478bd9Sstevel@tonic-gate fprintf( stderr, gettext(" -A\t\tdisplay non-ASCII values in conjunction with -v\n") ); 1257c478bd9Sstevel@tonic-gate fprintf( stderr, gettext(" -f file\tread modifications from file (default: standard input)\n") ); 1267c478bd9Sstevel@tonic-gate if ( strcmp( ldaptool_progname, "ldapmodify" ) == 0 ){ 1277c478bd9Sstevel@tonic-gate fprintf( stderr, gettext(" -a\t\tadd entries\n") ); 1287c478bd9Sstevel@tonic-gate } 1297c478bd9Sstevel@tonic-gate fprintf( stderr, gettext(" -b\t\tread values that start with / from files (for bin attrs)\n") ); 1307c478bd9Sstevel@tonic-gate fprintf( stderr, gettext(" -F\t\tforce application of all changes, regardless of\n") ); 1317c478bd9Sstevel@tonic-gate fprintf( stderr, gettext(" \t\treplica lines\n") ); 1327c478bd9Sstevel@tonic-gate fprintf( stderr, gettext(" -e rejfile\tsave rejected entries in \"rejfile\"\n") ); 1337c478bd9Sstevel@tonic-gate fprintf( stderr, gettext(" -B suffix\tbulk import to \"suffix\"\n")); 1347c478bd9Sstevel@tonic-gate fprintf( stderr, gettext(" -q\t\tbe quiet when adding/modifying entries\n") ); 1357c478bd9Sstevel@tonic-gate #ifdef SOLARIS_LDAP_CMD 1367c478bd9Sstevel@tonic-gate fprintf( stderr, gettext(" -r\t\treplace values\n")); 1377c478bd9Sstevel@tonic-gate fprintf( stderr, gettext(" -l nb-connections\tnumber of LDAP connections\n")); 1387c478bd9Sstevel@tonic-gate #endif /* SOLARIS_LDAP_CMD */ 1397c478bd9Sstevel@tonic-gate exit( LDAP_PARAM_ERROR ); 1407c478bd9Sstevel@tonic-gate } 1417c478bd9Sstevel@tonic-gate 1427c478bd9Sstevel@tonic-gate 1437c478bd9Sstevel@tonic-gate int 1447c478bd9Sstevel@tonic-gate main( int argc, char **argv ) 1457c478bd9Sstevel@tonic-gate { 1467c478bd9Sstevel@tonic-gate int optind, i; 147*ffc33b84SSreedhar Chalamalasetti - Sun Microsystems - Bangalore India int rc; 1487c478bd9Sstevel@tonic-gate 1497c478bd9Sstevel@tonic-gate #ifdef SOLARIS_LDAP_CMD 1507c478bd9Sstevel@tonic-gate char *locale = setlocale(LC_ALL, ""); 1517c478bd9Sstevel@tonic-gate textdomain(TEXT_DOMAIN); 1527c478bd9Sstevel@tonic-gate #endif 1537c478bd9Sstevel@tonic-gate 1547c478bd9Sstevel@tonic-gate #ifdef notdef 1557c478bd9Sstevel@tonic-gate #ifdef HPUX11 1567c478bd9Sstevel@tonic-gate #ifndef __LP64__ 1577c478bd9Sstevel@tonic-gate _main( argc, argv); 1587c478bd9Sstevel@tonic-gate #endif /* __LP64_ */ 1597c478bd9Sstevel@tonic-gate #endif /* HPUX11 */ 1607c478bd9Sstevel@tonic-gate #endif 1617c478bd9Sstevel@tonic-gate 1627c478bd9Sstevel@tonic-gate valsfromfiles = display_binary_values = 0; 1637c478bd9Sstevel@tonic-gate 1647c478bd9Sstevel@tonic-gate #ifdef SOLARIS_LDAP_CMD 1657c478bd9Sstevel@tonic-gate optind = ldaptool_process_args( argc, argv, "aAbcFe:B:qrl:", 0, 1667c478bd9Sstevel@tonic-gate options_callback ); 1677c478bd9Sstevel@tonic-gate #else 1687c478bd9Sstevel@tonic-gate optind = ldaptool_process_args( argc, argv, "aAbcFe:B:q", 0, 1697c478bd9Sstevel@tonic-gate options_callback ); 1707c478bd9Sstevel@tonic-gate #endif /* SOLARIS_LDAP_CMD */ 1717c478bd9Sstevel@tonic-gate 1727c478bd9Sstevel@tonic-gate 1737c478bd9Sstevel@tonic-gate if ( optind == -1 ) { 1747c478bd9Sstevel@tonic-gate usage(); 1757c478bd9Sstevel@tonic-gate } 1767c478bd9Sstevel@tonic-gate 1777c478bd9Sstevel@tonic-gate if ( !newval && strcmp( ldaptool_progname, "ldapadd" ) == 0 ) { 1787c478bd9Sstevel@tonic-gate newval = 1; 1797c478bd9Sstevel@tonic-gate } 1807c478bd9Sstevel@tonic-gate 1817c478bd9Sstevel@tonic-gate if ( ldaptool_fp == NULL ) { 1827c478bd9Sstevel@tonic-gate ldaptool_fp = stdin; 1837c478bd9Sstevel@tonic-gate } 1847c478bd9Sstevel@tonic-gate 1857c478bd9Sstevel@tonic-gate if ( argc - optind != 0 ) { 1867c478bd9Sstevel@tonic-gate usage(); 1877c478bd9Sstevel@tonic-gate } 1887c478bd9Sstevel@tonic-gate 1897c478bd9Sstevel@tonic-gate #ifdef SOLARIS_LDAP_CMD 1907c478bd9Sstevel@tonic-gate /* trivial case */ 191*ffc33b84SSreedhar Chalamalasetti - Sun Microsystems - Bangalore India if ( nbthreads == 1 ) { 192*ffc33b84SSreedhar Chalamalasetti - Sun Microsystems - Bangalore India rc = process(NULL); 193*ffc33b84SSreedhar Chalamalasetti - Sun Microsystems - Bangalore India /* check for and report output error */ 194*ffc33b84SSreedhar Chalamalasetti - Sun Microsystems - Bangalore India fflush( stdout ); 195*ffc33b84SSreedhar Chalamalasetti - Sun Microsystems - Bangalore India rc = ldaptool_check_ferror( stdout, rc, 196*ffc33b84SSreedhar Chalamalasetti - Sun Microsystems - Bangalore India gettext("output error (output might be incomplete)") ); 197*ffc33b84SSreedhar Chalamalasetti - Sun Microsystems - Bangalore India return( rc ); 198*ffc33b84SSreedhar Chalamalasetti - Sun Microsystems - Bangalore India } 1997c478bd9Sstevel@tonic-gate 2007c478bd9Sstevel@tonic-gate for ( i=0; i<nbthreads; ++i ) { 2017c478bd9Sstevel@tonic-gate if ( thr_create(NULL, 0, process, NULL, NULL, NULL) != 0 ) 2027c478bd9Sstevel@tonic-gate ++thr_create_errors; 2037c478bd9Sstevel@tonic-gate } 2047c478bd9Sstevel@tonic-gate 2057c478bd9Sstevel@tonic-gate if ( thr_create_errors < nbthreads ) 2067c478bd9Sstevel@tonic-gate while ( thr_join(0, NULL, NULL) == 0 ); 2077c478bd9Sstevel@tonic-gate else 2087c478bd9Sstevel@tonic-gate error = -1; 209*ffc33b84SSreedhar Chalamalasetti - Sun Microsystems - Bangalore India rc = error; 210*ffc33b84SSreedhar Chalamalasetti - Sun Microsystems - Bangalore India /* check for and report output error */ 211*ffc33b84SSreedhar Chalamalasetti - Sun Microsystems - Bangalore India fflush( stdout ); 212*ffc33b84SSreedhar Chalamalasetti - Sun Microsystems - Bangalore India rc = ldaptool_check_ferror( stdout, rc, 213*ffc33b84SSreedhar Chalamalasetti - Sun Microsystems - Bangalore India gettext("output error (output might be incomplete)") ); 214*ffc33b84SSreedhar Chalamalasetti - Sun Microsystems - Bangalore India return( rc ); 2157c478bd9Sstevel@tonic-gate #else 216*ffc33b84SSreedhar Chalamalasetti - Sun Microsystems - Bangalore India rc = process(NULL); 217*ffc33b84SSreedhar Chalamalasetti - Sun Microsystems - Bangalore India /* check for and report output error */ 218*ffc33b84SSreedhar Chalamalasetti - Sun Microsystems - Bangalore India fflush( stdout ); 219*ffc33b84SSreedhar Chalamalasetti - Sun Microsystems - Bangalore India rc = ldaptool_check_ferror( stdout, rc, 220*ffc33b84SSreedhar Chalamalasetti - Sun Microsystems - Bangalore India gettext("output error (output might be incomplete)") ); 221*ffc33b84SSreedhar Chalamalasetti - Sun Microsystems - Bangalore India return( rc ); 2227c478bd9Sstevel@tonic-gate #endif /* SOLARIS_LDAP_CMD */ 2237c478bd9Sstevel@tonic-gate } 2247c478bd9Sstevel@tonic-gate 2257c478bd9Sstevel@tonic-gate #ifdef SOLARIS_LDAP_CMD 2267c478bd9Sstevel@tonic-gate #define exit(a) \ 2277c478bd9Sstevel@tonic-gate if (nbthreads > 1) { \ 2287c478bd9Sstevel@tonic-gate mutex_lock(&read_mutex); \ 2297c478bd9Sstevel@tonic-gate error |= a; \ 2307c478bd9Sstevel@tonic-gate mutex_unlock(&read_mutex); \ 2317c478bd9Sstevel@tonic-gate thr_exit(&error); \ 2327c478bd9Sstevel@tonic-gate } else { \ 2337c478bd9Sstevel@tonic-gate exit(a); \ 2347c478bd9Sstevel@tonic-gate } 2357c478bd9Sstevel@tonic-gate #endif /* SOLARIS_LDAP_CMD */ 2367c478bd9Sstevel@tonic-gate 2377c478bd9Sstevel@tonic-gate static int 2387c478bd9Sstevel@tonic-gate process( void *arg ) 2397c478bd9Sstevel@tonic-gate { 2407c478bd9Sstevel@tonic-gate char *rbuf, *saved_rbuf, *start, *p, *q; 2417c478bd9Sstevel@tonic-gate FILE *rfp = NULL; 2427c478bd9Sstevel@tonic-gate int rc, use_ldif, deref; 2437c478bd9Sstevel@tonic-gate LDAPControl *ldctrl; 2447c478bd9Sstevel@tonic-gate 2457c478bd9Sstevel@tonic-gate #ifdef SOLARIS_LDAP_CMD 2467c478bd9Sstevel@tonic-gate LDAP *ld; 2477c478bd9Sstevel@tonic-gate #endif /* SOLARIS_LDAP_CMD */ 2487c478bd9Sstevel@tonic-gate 2497c478bd9Sstevel@tonic-gate ld = ldaptool_ldap_init( 0 ); 2507c478bd9Sstevel@tonic-gate 2517c478bd9Sstevel@tonic-gate if ( !ldaptool_not ) { 2527c478bd9Sstevel@tonic-gate deref = LDAP_DEREF_NEVER; /* this seems prudent */ 2537c478bd9Sstevel@tonic-gate ldap_set_option( ld, LDAP_OPT_DEREF, &deref ); 2547c478bd9Sstevel@tonic-gate } 2557c478bd9Sstevel@tonic-gate 2567c478bd9Sstevel@tonic-gate ldaptool_bind( ld ); 2577c478bd9Sstevel@tonic-gate 2587c478bd9Sstevel@tonic-gate if (( ldctrl = ldaptool_create_manage_dsait_control()) != NULL ) { 2597c478bd9Sstevel@tonic-gate ldaptool_add_control_to_array( ldctrl, ldaptool_request_ctrls); 2607c478bd9Sstevel@tonic-gate } 2617c478bd9Sstevel@tonic-gate 2627c478bd9Sstevel@tonic-gate if ((ldctrl = ldaptool_create_proxyauth_control(ld)) !=NULL) { 2637c478bd9Sstevel@tonic-gate ldaptool_add_control_to_array( ldctrl, ldaptool_request_ctrls); 2647c478bd9Sstevel@tonic-gate } 2657c478bd9Sstevel@tonic-gate 2667c478bd9Sstevel@tonic-gate rc = 0; 2677c478bd9Sstevel@tonic-gate 2687c478bd9Sstevel@tonic-gate /* turn on bulk import?*/ 2697c478bd9Sstevel@tonic-gate if (bulkimport_suffix) { 2707c478bd9Sstevel@tonic-gate struct berval bv, *retdata; 2717c478bd9Sstevel@tonic-gate char *retoid; 2727c478bd9Sstevel@tonic-gate 2737c478bd9Sstevel@tonic-gate bv.bv_val = bulkimport_suffix; 2747c478bd9Sstevel@tonic-gate bv.bv_len = strlen(bulkimport_suffix); 2757c478bd9Sstevel@tonic-gate if ((rc = ldap_extended_operation_s(ld, 2767c478bd9Sstevel@tonic-gate BULKIMPORT_START_OID, &bv, NULL, 2777c478bd9Sstevel@tonic-gate NULL, &retoid, &retdata)) != 0) { 2787c478bd9Sstevel@tonic-gate fprintf(stderr, gettext("Error: unable to service " 2797c478bd9Sstevel@tonic-gate "extended operation request\n\t'%s' for " 2807c478bd9Sstevel@tonic-gate "bulk import\n\t(error:%d:'%s')\n"), 2817c478bd9Sstevel@tonic-gate BULKIMPORT_START_OID, rc, ldap_err2string(rc)); 2827c478bd9Sstevel@tonic-gate return (rc); 2837c478bd9Sstevel@tonic-gate } 2847c478bd9Sstevel@tonic-gate if (retoid) 2857c478bd9Sstevel@tonic-gate ldap_memfree(retoid); 2867c478bd9Sstevel@tonic-gate if (retdata) 2877c478bd9Sstevel@tonic-gate ber_bvfree(retdata); 2887c478bd9Sstevel@tonic-gate } 2897c478bd9Sstevel@tonic-gate 2907c478bd9Sstevel@tonic-gate while (( rc == 0 || contoper ) && 2917c478bd9Sstevel@tonic-gate ( rbuf = read_one_record( ldaptool_fp )) != NULL ) { 2927c478bd9Sstevel@tonic-gate /* 2937c478bd9Sstevel@tonic-gate * we assume record is ldif/slapd.replog if the first line 2947c478bd9Sstevel@tonic-gate * has a colon that appears to the left of any equal signs, OR 2957c478bd9Sstevel@tonic-gate * if the first line consists entirely of digits (an entry id) 2967c478bd9Sstevel@tonic-gate */ 2977c478bd9Sstevel@tonic-gate use_ldif = ( p = strchr( rbuf, ':' )) != NULL && 2987c478bd9Sstevel@tonic-gate ( q = strchr( rbuf, '\n' )) != NULL && p < q && 2997c478bd9Sstevel@tonic-gate (( q = strchr( rbuf, '=' )) == NULL || p < q ); 3007c478bd9Sstevel@tonic-gate 3017c478bd9Sstevel@tonic-gate start = rbuf; 3027c478bd9Sstevel@tonic-gate saved_rbuf = strdup( rbuf ); 3037c478bd9Sstevel@tonic-gate 3047c478bd9Sstevel@tonic-gate if ( !use_ldif && ( q = strchr( rbuf, '\n' )) != NULL ) { 3057c478bd9Sstevel@tonic-gate for ( p = rbuf; p < q; ++p ) { 3067c478bd9Sstevel@tonic-gate if ( !isdigit( *p )) { 3077c478bd9Sstevel@tonic-gate break; 3087c478bd9Sstevel@tonic-gate } 3097c478bd9Sstevel@tonic-gate } 3107c478bd9Sstevel@tonic-gate if ( p >= q ) { 3117c478bd9Sstevel@tonic-gate use_ldif = 1; 3127c478bd9Sstevel@tonic-gate start = q + 1; 3137c478bd9Sstevel@tonic-gate } 3147c478bd9Sstevel@tonic-gate } 3157c478bd9Sstevel@tonic-gate 3167c478bd9Sstevel@tonic-gate #ifdef SOLARIS_LDAP_CMD 3177c478bd9Sstevel@tonic-gate if ( use_ldif ) { 3187c478bd9Sstevel@tonic-gate rc = process_ldif_rec( ld, start ); 3197c478bd9Sstevel@tonic-gate } else { 3207c478bd9Sstevel@tonic-gate rc = process_ldapmod_rec( ld, start ); 3217c478bd9Sstevel@tonic-gate } 3227c478bd9Sstevel@tonic-gate #else 3237c478bd9Sstevel@tonic-gate if ( use_ldif ) { 3247c478bd9Sstevel@tonic-gate rc = process_ldif_rec( start ); 3257c478bd9Sstevel@tonic-gate } else { 3267c478bd9Sstevel@tonic-gate rc = process_ldapmod_rec( start ); 3277c478bd9Sstevel@tonic-gate } 3287c478bd9Sstevel@tonic-gate #endif /* SOLARIS_LDAP_CMD */ 3297c478bd9Sstevel@tonic-gate 3307c478bd9Sstevel@tonic-gate if ( rc != LDAP_SUCCESS && rejfile != NULL ) { 3317c478bd9Sstevel@tonic-gate /* Write this record to the reject file */ 3327c478bd9Sstevel@tonic-gate int newfile = 0; 3337c478bd9Sstevel@tonic-gate struct stat stbuf; 3347c478bd9Sstevel@tonic-gate if ( stat( rejfile, &stbuf ) < 0 ) { 3357c478bd9Sstevel@tonic-gate if ( errno == ENOENT ) { 3367c478bd9Sstevel@tonic-gate newfile = 1; 3377c478bd9Sstevel@tonic-gate } 3387c478bd9Sstevel@tonic-gate } 3397c478bd9Sstevel@tonic-gate if (( rfp = ldaptool_open_file( rejfile, "a" )) == NULL ) { 3407c478bd9Sstevel@tonic-gate fprintf( stderr, gettext("Cannot open error file \"%s\" - " 3417c478bd9Sstevel@tonic-gate "erroneous entries will not be saved\n"), rejfile ); 3427c478bd9Sstevel@tonic-gate rejfile = NULL; 3437c478bd9Sstevel@tonic-gate } else { 3447c478bd9Sstevel@tonic-gate if ( newfile == 0 ) { 3457c478bd9Sstevel@tonic-gate fputs( "\n", rfp ); 3467c478bd9Sstevel@tonic-gate } 3477c478bd9Sstevel@tonic-gate fprintf( rfp, gettext("# Error: %s\n"), ldap_err2string( rc )); 3487c478bd9Sstevel@tonic-gate fputs( saved_rbuf, rfp ); 3497c478bd9Sstevel@tonic-gate fclose( rfp ); 3507c478bd9Sstevel@tonic-gate rfp = NULL; 3517c478bd9Sstevel@tonic-gate } 3527c478bd9Sstevel@tonic-gate } 3537c478bd9Sstevel@tonic-gate 3547c478bd9Sstevel@tonic-gate free( rbuf ); 3557c478bd9Sstevel@tonic-gate free( saved_rbuf ); 3567c478bd9Sstevel@tonic-gate } 3577c478bd9Sstevel@tonic-gate ldaptool_reset_control_array( ldaptool_request_ctrls ); 3587c478bd9Sstevel@tonic-gate 3597c478bd9Sstevel@tonic-gate /* turn off bulk import?*/ 3607c478bd9Sstevel@tonic-gate if (bulkimport_suffix) { 3617c478bd9Sstevel@tonic-gate struct berval bv, *retdata; 3627c478bd9Sstevel@tonic-gate char *retoid; 3637c478bd9Sstevel@tonic-gate 3647c478bd9Sstevel@tonic-gate bv.bv_val = ""; 3657c478bd9Sstevel@tonic-gate bv.bv_len = 0; 3667c478bd9Sstevel@tonic-gate if ((rc = ldap_extended_operation_s(ld, 3677c478bd9Sstevel@tonic-gate BULKIMPORT_STOP_OID, &bv, NULL, 3687c478bd9Sstevel@tonic-gate NULL, &retoid, &retdata)) != 0) { 3697c478bd9Sstevel@tonic-gate 3707c478bd9Sstevel@tonic-gate fprintf(stderr, gettext("Error: unable to service " 3717c478bd9Sstevel@tonic-gate "extended operation request\n\t '%s' for " 3727c478bd9Sstevel@tonic-gate "bulk import\n\t(rc:%d:'%s')\n"), 3737c478bd9Sstevel@tonic-gate BULKIMPORT_STOP_OID, rc, ldap_err2string(rc)); 3747c478bd9Sstevel@tonic-gate return (rc); 3757c478bd9Sstevel@tonic-gate } 3767c478bd9Sstevel@tonic-gate if (retoid) 3777c478bd9Sstevel@tonic-gate ldap_memfree(retoid); 3787c478bd9Sstevel@tonic-gate if (retdata) 3797c478bd9Sstevel@tonic-gate ber_bvfree(retdata); 3807c478bd9Sstevel@tonic-gate } 3817c478bd9Sstevel@tonic-gate 3827c478bd9Sstevel@tonic-gate #ifdef SOLARIS_LDAP_CMD 3837c478bd9Sstevel@tonic-gate mutex_lock(&read_mutex); 3847c478bd9Sstevel@tonic-gate #endif 3857c478bd9Sstevel@tonic-gate ldaptool_cleanup( ld ); 3867c478bd9Sstevel@tonic-gate #ifdef SOLARIS_LDAP_CMD 3877c478bd9Sstevel@tonic-gate mutex_unlock(&read_mutex); 3887c478bd9Sstevel@tonic-gate #endif 3897c478bd9Sstevel@tonic-gate return( rc ); 3907c478bd9Sstevel@tonic-gate } 3917c478bd9Sstevel@tonic-gate 3927c478bd9Sstevel@tonic-gate 3937c478bd9Sstevel@tonic-gate static void 3947c478bd9Sstevel@tonic-gate options_callback( int option, char *optarg ) 3957c478bd9Sstevel@tonic-gate { 3967c478bd9Sstevel@tonic-gate switch( option ) { 3977c478bd9Sstevel@tonic-gate case 'a': /* add */ 3987c478bd9Sstevel@tonic-gate newval = 1; 3997c478bd9Sstevel@tonic-gate break; 4007c478bd9Sstevel@tonic-gate case 'b': /* read values from files (for binary attributes) */ 4017c478bd9Sstevel@tonic-gate valsfromfiles = 1; 4027c478bd9Sstevel@tonic-gate break; 4037c478bd9Sstevel@tonic-gate case 'A': /* display non-ASCII values when -v is used */ 4047c478bd9Sstevel@tonic-gate display_binary_values = 1; 4057c478bd9Sstevel@tonic-gate break; 4067c478bd9Sstevel@tonic-gate case 'c': /* continuous operation */ 4077c478bd9Sstevel@tonic-gate contoper = 1; 4087c478bd9Sstevel@tonic-gate break; 4097c478bd9Sstevel@tonic-gate case 'F': /* force all changes records to be used */ 4107c478bd9Sstevel@tonic-gate force = 1; 4117c478bd9Sstevel@tonic-gate break; 4127c478bd9Sstevel@tonic-gate case 'e': 4137c478bd9Sstevel@tonic-gate rejfile = strdup( optarg ); 4147c478bd9Sstevel@tonic-gate break; 4157c478bd9Sstevel@tonic-gate case 'B': /* bulk import option */ 4167c478bd9Sstevel@tonic-gate bulkimport_suffix = strdup( optarg ); 4177c478bd9Sstevel@tonic-gate break; 4187c478bd9Sstevel@tonic-gate case 'q': /* quiet mode on add/modify operations */ 4197c478bd9Sstevel@tonic-gate ldapmodify_quiet = 1; 4207c478bd9Sstevel@tonic-gate break; 4217c478bd9Sstevel@tonic-gate #ifdef SOLARIS_LDAP_CMD 4227c478bd9Sstevel@tonic-gate case 'r': /* default is to replace rather than add values */ 4237c478bd9Sstevel@tonic-gate replace = 1; 4247c478bd9Sstevel@tonic-gate break; 4257c478bd9Sstevel@tonic-gate case 'l': 4267c478bd9Sstevel@tonic-gate nbthreads = atoi(optarg); 4277c478bd9Sstevel@tonic-gate break; 4287c478bd9Sstevel@tonic-gate #endif /* SOLARIS_LDAP_CMD */ 4297c478bd9Sstevel@tonic-gate default: 4307c478bd9Sstevel@tonic-gate usage(); 4317c478bd9Sstevel@tonic-gate } 4327c478bd9Sstevel@tonic-gate } 4337c478bd9Sstevel@tonic-gate 4347c478bd9Sstevel@tonic-gate 4357c478bd9Sstevel@tonic-gate 4367c478bd9Sstevel@tonic-gate static int 4377c478bd9Sstevel@tonic-gate #ifdef SOLARIS_LDAP_CMD 4387c478bd9Sstevel@tonic-gate process_ldif_rec( LDAP *ld, char *rbuf ) 4397c478bd9Sstevel@tonic-gate #else 4407c478bd9Sstevel@tonic-gate process_ldif_rec( char *rbuf ) 4417c478bd9Sstevel@tonic-gate #endif 4427c478bd9Sstevel@tonic-gate { 4437c478bd9Sstevel@tonic-gate char *line, *dn, *type, *value, *newrdn, *newparent, *p; 4447c478bd9Sstevel@tonic-gate char *ctrl_oid=NULL, *ctrl_value=NULL; 4457c478bd9Sstevel@tonic-gate int ctrl_criticality=1; 4467c478bd9Sstevel@tonic-gate LDAPControl *ldctrl; 4477c478bd9Sstevel@tonic-gate int rc, linenum, vlen, modop, replicaport; 4487c478bd9Sstevel@tonic-gate int expect_modop, expect_sep, expect_chgtype_or_control, expect_newrdn; 4497c478bd9Sstevel@tonic-gate int expect_deleteoldrdn, expect_newparent, rename, moddn; 4507c478bd9Sstevel@tonic-gate int deleteoldrdn, saw_replica, use_record, new_entry, delete_entry; 4517c478bd9Sstevel@tonic-gate int got_all, got_value; 4527c478bd9Sstevel@tonic-gate LDAPMod **pmods; 4537c478bd9Sstevel@tonic-gate 4547c478bd9Sstevel@tonic-gate new_entry = newval; 4557c478bd9Sstevel@tonic-gate 4567c478bd9Sstevel@tonic-gate rc = got_all = saw_replica = delete_entry = expect_modop = 0; 4577c478bd9Sstevel@tonic-gate expect_deleteoldrdn = expect_newrdn = expect_newparent = expect_sep = 0; 4587c478bd9Sstevel@tonic-gate expect_chgtype_or_control = linenum = got_value = rename = moddn = 0; 4597c478bd9Sstevel@tonic-gate deleteoldrdn = 1; 4607c478bd9Sstevel@tonic-gate use_record = force; 4617c478bd9Sstevel@tonic-gate pmods = NULL; 4627c478bd9Sstevel@tonic-gate dn = newrdn = newparent = NULL; 4637c478bd9Sstevel@tonic-gate 4647c478bd9Sstevel@tonic-gate #ifdef SOLARIS_LDAP_CMD 4657c478bd9Sstevel@tonic-gate while ( rc == 0 && ( line = str_getline( &rbuf )) != NULL ) { 4667c478bd9Sstevel@tonic-gate #else 4677c478bd9Sstevel@tonic-gate while ( rc == 0 && ( line = ldif_getline( &rbuf )) != NULL ) { 4687c478bd9Sstevel@tonic-gate #endif /* SOLARIS_LDAP_CMD */ 4697c478bd9Sstevel@tonic-gate ++linenum; 4707c478bd9Sstevel@tonic-gate if ( expect_sep && strcasecmp( line, T_MODSEPSTR ) == 0 ) { 4717c478bd9Sstevel@tonic-gate expect_sep = 0; 4727c478bd9Sstevel@tonic-gate expect_modop = 1; 4737c478bd9Sstevel@tonic-gate 4747c478bd9Sstevel@tonic-gate /*If we see a separator in the input stream, 4757c478bd9Sstevel@tonic-gate but we didn't get a value from the last modify 4767c478bd9Sstevel@tonic-gate then we have to fill pmods with an empty value*/ 4777c478bd9Sstevel@tonic-gate if (modop == LDAP_MOD_REPLACE && !got_value){ 4787c478bd9Sstevel@tonic-gate addmodifyop( &pmods, modop, value, NULL, 0); 4797c478bd9Sstevel@tonic-gate } 4807c478bd9Sstevel@tonic-gate 4817c478bd9Sstevel@tonic-gate got_value = 0; 4827c478bd9Sstevel@tonic-gate continue; 4837c478bd9Sstevel@tonic-gate } 4847c478bd9Sstevel@tonic-gate 4857c478bd9Sstevel@tonic-gate #ifdef SOLARIS_LDAP_CMD 4867c478bd9Sstevel@tonic-gate if ( str_parse_line( line, &type, &value, &vlen ) < 0 ) { 4877c478bd9Sstevel@tonic-gate #else 4887c478bd9Sstevel@tonic-gate if ( ldif_parse_line( line, &type, &value, &vlen ) < 0 ) { 4897c478bd9Sstevel@tonic-gate #endif /* SOLARIS_LDAP_CMD */ 4907c478bd9Sstevel@tonic-gate fprintf( stderr, gettext("%s: invalid format (line %d of entry: %s)\n"), 4917c478bd9Sstevel@tonic-gate ldaptool_progname, linenum, dn == NULL ? "" : dn ); 4927c478bd9Sstevel@tonic-gate fprintf( stderr, gettext("%s: line contents: (%s)\n"), 4937c478bd9Sstevel@tonic-gate ldaptool_progname, line ); 4947c478bd9Sstevel@tonic-gate rc = LDAP_PARAM_ERROR; 4957c478bd9Sstevel@tonic-gate break; 4967c478bd9Sstevel@tonic-gate } 4977c478bd9Sstevel@tonic-gate 4987c478bd9Sstevel@tonic-gate evaluate_line: 4997c478bd9Sstevel@tonic-gate if ( dn == NULL ) { 5007c478bd9Sstevel@tonic-gate if ( !use_record && strcasecmp( type, T_REPLICA_STR ) == 0 ) { 5017c478bd9Sstevel@tonic-gate ++saw_replica; 5027c478bd9Sstevel@tonic-gate if (( p = strchr( value, ':' )) == NULL ) { 5037c478bd9Sstevel@tonic-gate replicaport = LDAP_PORT; 5047c478bd9Sstevel@tonic-gate } else { 5057c478bd9Sstevel@tonic-gate *p++ = '\0'; 5067c478bd9Sstevel@tonic-gate replicaport = atoi( p ); 5077c478bd9Sstevel@tonic-gate } 5087c478bd9Sstevel@tonic-gate if ( strcasecmp( value, ldaptool_host ) == 0 && 5097c478bd9Sstevel@tonic-gate replicaport == ldaptool_port ) { 5107c478bd9Sstevel@tonic-gate use_record = 1; 5117c478bd9Sstevel@tonic-gate } 5127c478bd9Sstevel@tonic-gate 5137c478bd9Sstevel@tonic-gate } else if ( strcasecmp( type, T_DN_STR ) == 0 ) { 5147c478bd9Sstevel@tonic-gate if (( dn = strdup( value )) == NULL ) { 5157c478bd9Sstevel@tonic-gate perror( "strdup" ); 5167c478bd9Sstevel@tonic-gate exit( LDAP_NO_MEMORY ); 5177c478bd9Sstevel@tonic-gate } 5187c478bd9Sstevel@tonic-gate expect_chgtype_or_control = 1; 5197c478bd9Sstevel@tonic-gate 5207c478bd9Sstevel@tonic-gate } else if ( strcasecmp( type, T_VERSION_STR ) == 0 ) { 5217c478bd9Sstevel@tonic-gate ldif_version = atoi( value ); 5227c478bd9Sstevel@tonic-gate if ( ldif_version != LDIF_VERSION_ONE ) { 5237c478bd9Sstevel@tonic-gate fprintf( stderr, gettext("%s: LDIF version %d is not supported;" 5247c478bd9Sstevel@tonic-gate " use version: %d\n"), ldaptool_progname, ldif_version, 5257c478bd9Sstevel@tonic-gate LDIF_VERSION_ONE ); 5267c478bd9Sstevel@tonic-gate exit( LDAP_PARAM_ERROR ); 5277c478bd9Sstevel@tonic-gate } 5287c478bd9Sstevel@tonic-gate if ( ldaptool_verbose ) { 5297c478bd9Sstevel@tonic-gate printf( gettext("Processing a version %d LDIF file...\n"), 5307c478bd9Sstevel@tonic-gate ldif_version ); 5317c478bd9Sstevel@tonic-gate } 5327c478bd9Sstevel@tonic-gate 5337c478bd9Sstevel@tonic-gate /* Now check if there's something left to process */ 5347c478bd9Sstevel@tonic-gate /* and if not, go get the new record, else continue */ 5357c478bd9Sstevel@tonic-gate if ( *rbuf == '\0' ) { 5367c478bd9Sstevel@tonic-gate return( 0 ); 5377c478bd9Sstevel@tonic-gate } 5387c478bd9Sstevel@tonic-gate 5397c478bd9Sstevel@tonic-gate } else if ( !saw_replica ) { 5407c478bd9Sstevel@tonic-gate printf( gettext("%s: skipping change record: no dn: line\n"), 5417c478bd9Sstevel@tonic-gate ldaptool_progname ); 5427c478bd9Sstevel@tonic-gate return( 0 ); 5437c478bd9Sstevel@tonic-gate } 5447c478bd9Sstevel@tonic-gate 5457c478bd9Sstevel@tonic-gate continue; /* skip all lines until we see "dn:" */ 5467c478bd9Sstevel@tonic-gate } 5477c478bd9Sstevel@tonic-gate 5487c478bd9Sstevel@tonic-gate if ( expect_chgtype_or_control ) { 5497c478bd9Sstevel@tonic-gate expect_chgtype_or_control = 0; 5507c478bd9Sstevel@tonic-gate if ( !use_record && saw_replica ) { 5517c478bd9Sstevel@tonic-gate printf( gettext("%s: skipping change record for entry: %s\n\t(LDAP host/port does not match replica: lines)\n"), 5527c478bd9Sstevel@tonic-gate ldaptool_progname, dn ); 5537c478bd9Sstevel@tonic-gate free( dn ); 5547c478bd9Sstevel@tonic-gate return( 0 ); 5557c478bd9Sstevel@tonic-gate } 5567c478bd9Sstevel@tonic-gate 5577c478bd9Sstevel@tonic-gate #ifndef SOLARIS_LDAP_CMD 5587c478bd9Sstevel@tonic-gate if ( strcasecmp( type, "control" ) == 0 ) { 5597c478bd9Sstevel@tonic-gate value = strdup_and_trim( value ); 5607c478bd9Sstevel@tonic-gate if (ldaptool_parse_ctrl_arg(value, ' ', &ctrl_oid, 5617c478bd9Sstevel@tonic-gate &ctrl_criticality, &ctrl_value, &vlen)) { 5627c478bd9Sstevel@tonic-gate usage(); 5637c478bd9Sstevel@tonic-gate } 5647c478bd9Sstevel@tonic-gate ldctrl = calloc(1,sizeof(LDAPControl)); 5657c478bd9Sstevel@tonic-gate if (ctrl_value) { 5667c478bd9Sstevel@tonic-gate rc = ldaptool_berval_from_ldif_value( ctrl_value, vlen, 5677c478bd9Sstevel@tonic-gate &(ldctrl->ldctl_value), 5687c478bd9Sstevel@tonic-gate 1 /* recognize file URLs */, 0 /* always try file */, 5697c478bd9Sstevel@tonic-gate 1 /* report errors */ ); 5707c478bd9Sstevel@tonic-gate if ((rc = ldaptool_fileurlerr2ldaperr( rc )) != LDAP_SUCCESS) { 5717c478bd9Sstevel@tonic-gate fprintf( stderr, gettext("Unable to parse %s\n"), ctrl_value); 5727c478bd9Sstevel@tonic-gate usage(); 5737c478bd9Sstevel@tonic-gate } 5747c478bd9Sstevel@tonic-gate } 5757c478bd9Sstevel@tonic-gate ldctrl->ldctl_oid = ctrl_oid; 5767c478bd9Sstevel@tonic-gate ldctrl->ldctl_iscritical = ctrl_criticality; 5777c478bd9Sstevel@tonic-gate ldaptool_add_control_to_array(ldctrl, ldaptool_request_ctrls); 5787c478bd9Sstevel@tonic-gate expect_chgtype_or_control = 1; 5797c478bd9Sstevel@tonic-gate continue; 5807c478bd9Sstevel@tonic-gate } 5817c478bd9Sstevel@tonic-gate #endif /* SOLARIS_LDAP_CMD */ 5827c478bd9Sstevel@tonic-gate 5837c478bd9Sstevel@tonic-gate if ( strcasecmp( type, T_CHANGETYPESTR ) == 0 ) { 5847c478bd9Sstevel@tonic-gate value = strdup_and_trim( value ); 5857c478bd9Sstevel@tonic-gate if ( strcasecmp( value, T_MODIFYCTSTR ) == 0 ) { 5867c478bd9Sstevel@tonic-gate new_entry = 0; 5877c478bd9Sstevel@tonic-gate expect_modop = 1; 5887c478bd9Sstevel@tonic-gate } else if ( strcasecmp( value, T_ADDCTSTR ) == 0 ) { 5897c478bd9Sstevel@tonic-gate new_entry = 1; 5907c478bd9Sstevel@tonic-gate modop = LDAP_MOD_ADD; 5917c478bd9Sstevel@tonic-gate } else if ( strcasecmp( value, T_MODRDNCTSTR ) == 0 ) { 5927c478bd9Sstevel@tonic-gate expect_newrdn = 1; 5937c478bd9Sstevel@tonic-gate moddn = 1; 5947c478bd9Sstevel@tonic-gate } else if ( strcasecmp( value, T_MODDNCTSTR ) == 0 ) { 5957c478bd9Sstevel@tonic-gate expect_newrdn = 1; 5967c478bd9Sstevel@tonic-gate moddn = 1; 5977c478bd9Sstevel@tonic-gate } else if ( strcasecmp( value, T_RENAMECTSTR ) == 0 ) { 5987c478bd9Sstevel@tonic-gate expect_newrdn = 1; 5997c478bd9Sstevel@tonic-gate rename = 1; 6007c478bd9Sstevel@tonic-gate } else if ( strcasecmp( value, T_DELETECTSTR ) == 0 ) { 6017c478bd9Sstevel@tonic-gate got_all = delete_entry = 1; 6027c478bd9Sstevel@tonic-gate } else { 6037c478bd9Sstevel@tonic-gate fprintf( stderr, 6047c478bd9Sstevel@tonic-gate gettext("%s: unknown %s \"%s\" (line %d of entry: %s)\n"), 6057c478bd9Sstevel@tonic-gate ldaptool_progname, T_CHANGETYPESTR, value, 6067c478bd9Sstevel@tonic-gate linenum, dn ); 6077c478bd9Sstevel@tonic-gate rc = LDAP_PARAM_ERROR; 6087c478bd9Sstevel@tonic-gate } 6097c478bd9Sstevel@tonic-gate free( value ); 6107c478bd9Sstevel@tonic-gate continue; 6117c478bd9Sstevel@tonic-gate } else if ( newval ) { /* missing changetype => add */ 6127c478bd9Sstevel@tonic-gate new_entry = 1; 6137c478bd9Sstevel@tonic-gate modop = LDAP_MOD_ADD; 6147c478bd9Sstevel@tonic-gate } else { 6157c478bd9Sstevel@tonic-gate /*The user MUST put in changetype: blah 6167c478bd9Sstevel@tonic-gate unless adding a new entry with either -a or ldapadd*/ 6177c478bd9Sstevel@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"), 6187c478bd9Sstevel@tonic-gate ldaptool_progname, type, linenum, dn); 6197c478bd9Sstevel@tonic-gate rc = LDAP_PARAM_ERROR; 6207c478bd9Sstevel@tonic-gate /*expect_modop = 1; missing changetype => modify */ 6217c478bd9Sstevel@tonic-gate } 6227c478bd9Sstevel@tonic-gate } 6237c478bd9Sstevel@tonic-gate 6247c478bd9Sstevel@tonic-gate if ( expect_modop ) { 6257c478bd9Sstevel@tonic-gate expect_modop = 0; 6267c478bd9Sstevel@tonic-gate expect_sep = 1; 6277c478bd9Sstevel@tonic-gate if ( strcasecmp( type, T_MODOPADDSTR ) == 0 ) { 6287c478bd9Sstevel@tonic-gate modop = LDAP_MOD_ADD; 6297c478bd9Sstevel@tonic-gate continue; 6307c478bd9Sstevel@tonic-gate } else if ( strcasecmp( type, T_MODOPREPLACESTR ) == 0 ) { 6317c478bd9Sstevel@tonic-gate modop = LDAP_MOD_REPLACE; 6327c478bd9Sstevel@tonic-gate continue; 6337c478bd9Sstevel@tonic-gate } else if ( strcasecmp( type, T_MODOPDELETESTR ) == 0 ) { 6347c478bd9Sstevel@tonic-gate modop = LDAP_MOD_DELETE; 6357c478bd9Sstevel@tonic-gate addmodifyop( &pmods, modop, value, NULL, 0 ); 6367c478bd9Sstevel@tonic-gate continue; 6377c478bd9Sstevel@tonic-gate #ifdef SOLARIS_LDAP_CMD 6387c478bd9Sstevel@tonic-gate } else { /* no modify op: use default */ 6397c478bd9Sstevel@tonic-gate modop = replace ? LDAP_MOD_REPLACE : LDAP_MOD_ADD; 6407c478bd9Sstevel@tonic-gate } 6417c478bd9Sstevel@tonic-gate #else 6427c478bd9Sstevel@tonic-gate } else { /*Bug 27479. Remove default add operation*/ 6437c478bd9Sstevel@tonic-gate fprintf(stderr, gettext("%s: Invalid parameter \"%s\" specified for changetype modify (line %d of entry %s)\n"), 6447c478bd9Sstevel@tonic-gate ldaptool_progname, type, linenum, dn); 6457c478bd9Sstevel@tonic-gate rc = LDAP_PARAM_ERROR; 6467c478bd9Sstevel@tonic-gate } 6477c478bd9Sstevel@tonic-gate #endif /* SOLARIS_LDAP_CMD */ 6487c478bd9Sstevel@tonic-gate 6497c478bd9Sstevel@tonic-gate } 6507c478bd9Sstevel@tonic-gate 6517c478bd9Sstevel@tonic-gate if ( expect_newrdn ) { 6527c478bd9Sstevel@tonic-gate if ( strcasecmp( type, T_NEWRDNSTR ) == 0 ) { 6537c478bd9Sstevel@tonic-gate if ( *value == '\0' ) { 6547c478bd9Sstevel@tonic-gate fprintf( stderr, 6557c478bd9Sstevel@tonic-gate gettext("%s: newrdn value missing (line %d of entry: %s)\n"), 6567c478bd9Sstevel@tonic-gate ldaptool_progname, linenum, dn == NULL ? "" : dn ); 6577c478bd9Sstevel@tonic-gate rc = LDAP_PARAM_ERROR; 6587c478bd9Sstevel@tonic-gate } else if (( newrdn = strdup( value )) == NULL ) { 6597c478bd9Sstevel@tonic-gate perror( "strdup" ); 6607c478bd9Sstevel@tonic-gate exit( LDAP_NO_MEMORY ); 6617c478bd9Sstevel@tonic-gate } else { 6627c478bd9Sstevel@tonic-gate expect_newrdn = 0; 6637c478bd9Sstevel@tonic-gate if ( rename ) { 6647c478bd9Sstevel@tonic-gate expect_newparent = 1; 6657c478bd9Sstevel@tonic-gate } else { 6667c478bd9Sstevel@tonic-gate expect_deleteoldrdn = 1; 6677c478bd9Sstevel@tonic-gate } 6687c478bd9Sstevel@tonic-gate } 6697c478bd9Sstevel@tonic-gate } else { 6707c478bd9Sstevel@tonic-gate fprintf( stderr, gettext("%s: expecting \"%s:\" but saw \"%s:\" (line %d of entry %s)\n"), 6717c478bd9Sstevel@tonic-gate ldaptool_progname, T_NEWRDNSTR, type, linenum, dn ); 6727c478bd9Sstevel@tonic-gate rc = LDAP_PARAM_ERROR; 6737c478bd9Sstevel@tonic-gate } 6747c478bd9Sstevel@tonic-gate } else if ( expect_newparent ) { 6757c478bd9Sstevel@tonic-gate expect_newparent = 0; 6767c478bd9Sstevel@tonic-gate if ( rename ) { 6777c478bd9Sstevel@tonic-gate expect_deleteoldrdn = 1; 6787c478bd9Sstevel@tonic-gate } 6797c478bd9Sstevel@tonic-gate if ( strcasecmp( type, T_NEWPARENTSTR ) == 0 6807c478bd9Sstevel@tonic-gate || strcasecmp( type, T_NEWSUPERIORSTR ) == 0 ) { 6817c478bd9Sstevel@tonic-gate if (( newparent = strdup( value )) == NULL ) { 6827c478bd9Sstevel@tonic-gate perror( "strdup" ); 6837c478bd9Sstevel@tonic-gate exit( LDAP_NO_MEMORY ); 6847c478bd9Sstevel@tonic-gate } 6857c478bd9Sstevel@tonic-gate } else { 6867c478bd9Sstevel@tonic-gate /* Since this is an optional argument for rename/moddn, cause 6877c478bd9Sstevel@tonic-gate * the current line to be re-evaluated if newparent doesn't 6887c478bd9Sstevel@tonic-gate * follow deleteoldrdn. 6897c478bd9Sstevel@tonic-gate */ 6907c478bd9Sstevel@tonic-gate newparent = NULL; 6917c478bd9Sstevel@tonic-gate goto evaluate_line; 6927c478bd9Sstevel@tonic-gate } 6937c478bd9Sstevel@tonic-gate } else if ( expect_deleteoldrdn ) { 6947c478bd9Sstevel@tonic-gate if ( strcasecmp( type, T_DELETEOLDRDNSTR ) == 0 ) { 6957c478bd9Sstevel@tonic-gate if ( *value == '\0' ) { 6967c478bd9Sstevel@tonic-gate fprintf( stderr, 6977c478bd9Sstevel@tonic-gate gettext("%s: missing 0 or 1 (line %d of entry: %s)\n"), 6987c478bd9Sstevel@tonic-gate ldaptool_progname, linenum, dn == NULL ? "" : dn ); 6997c478bd9Sstevel@tonic-gate rc = LDAP_PARAM_ERROR; 7007c478bd9Sstevel@tonic-gate } else { 7017c478bd9Sstevel@tonic-gate deleteoldrdn = ( *value == '0' ) ? 0 : 1; 7027c478bd9Sstevel@tonic-gate expect_deleteoldrdn = 0; 7037c478bd9Sstevel@tonic-gate if ( moddn ) { 7047c478bd9Sstevel@tonic-gate expect_newparent = 1; 7057c478bd9Sstevel@tonic-gate } 7067c478bd9Sstevel@tonic-gate } 7077c478bd9Sstevel@tonic-gate } else { 7087c478bd9Sstevel@tonic-gate fprintf( stderr, gettext("%s: expecting \"%s:\" but saw \"%s:\" (line %d of entry %s)\n"), 7097c478bd9Sstevel@tonic-gate ldaptool_progname, T_DELETEOLDRDNSTR, type, linenum, 7107c478bd9Sstevel@tonic-gate dn ); 7117c478bd9Sstevel@tonic-gate rc = LDAP_PARAM_ERROR; 7127c478bd9Sstevel@tonic-gate } 7137c478bd9Sstevel@tonic-gate got_all = 1; 7147c478bd9Sstevel@tonic-gate } else if ( got_all ) { 7157c478bd9Sstevel@tonic-gate fprintf( stderr, 7167c478bd9Sstevel@tonic-gate gettext("%s: extra lines at end (line %d of entry %s)\n"), 7177c478bd9Sstevel@tonic-gate ldaptool_progname, linenum, dn ); 7187c478bd9Sstevel@tonic-gate rc = LDAP_PARAM_ERROR; 7197c478bd9Sstevel@tonic-gate got_all = 1; 7207c478bd9Sstevel@tonic-gate } else { 7217c478bd9Sstevel@tonic-gate addmodifyop( &pmods, modop, type, value, vlen ); 7227c478bd9Sstevel@tonic-gate /*There was a value to replace*/ 7237c478bd9Sstevel@tonic-gate got_value = 1; 7247c478bd9Sstevel@tonic-gate 7257c478bd9Sstevel@tonic-gate } 7267c478bd9Sstevel@tonic-gate } 7277c478bd9Sstevel@tonic-gate 7287c478bd9Sstevel@tonic-gate if ( rc == 0 ) { 7297c478bd9Sstevel@tonic-gate if ( delete_entry ) { 7307c478bd9Sstevel@tonic-gate #ifdef SOLARIS_LDAP_CMD 7317c478bd9Sstevel@tonic-gate rc = dodelete( ld, dn ); 7327c478bd9Sstevel@tonic-gate #else 7337c478bd9Sstevel@tonic-gate rc = dodelete( dn ); 7347c478bd9Sstevel@tonic-gate #endif /* SOLARIS_LDAP_CMD */ 7357c478bd9Sstevel@tonic-gate } else if ( newrdn != NULL ) { 7367c478bd9Sstevel@tonic-gate #ifdef SOLARIS_LDAP_CMD 7377c478bd9Sstevel@tonic-gate rc = dorename( ld, dn, newrdn, newparent, deleteoldrdn ); 7387c478bd9Sstevel@tonic-gate #else 7397c478bd9Sstevel@tonic-gate rc = dorename( dn, newrdn, newparent, deleteoldrdn ); 7407c478bd9Sstevel@tonic-gate #endif /* SOLARIS_LDAP_CMD */ 7417c478bd9Sstevel@tonic-gate rename = 0; 7427c478bd9Sstevel@tonic-gate } else { 7437c478bd9Sstevel@tonic-gate 7447c478bd9Sstevel@tonic-gate /*Patch to fix Bug 22183 7457c478bd9Sstevel@tonic-gate If pmods is null, then there is no 7467c478bd9Sstevel@tonic-gate attribute to replace, so we alloc 7477c478bd9Sstevel@tonic-gate an empty pmods*/ 7487c478bd9Sstevel@tonic-gate if (modop == LDAP_MOD_REPLACE && !got_value && expect_sep){ 7497c478bd9Sstevel@tonic-gate addmodifyop( &pmods, modop, value, NULL, 0); 7507c478bd9Sstevel@tonic-gate }/*End Patch*/ 7517c478bd9Sstevel@tonic-gate 7527c478bd9Sstevel@tonic-gate 7537c478bd9Sstevel@tonic-gate #ifdef SOLARIS_LDAP_CMD 7547c478bd9Sstevel@tonic-gate rc = domodify( ld, dn, pmods, new_entry ); 7557c478bd9Sstevel@tonic-gate #else 7567c478bd9Sstevel@tonic-gate rc = domodify( dn, pmods, new_entry ); 7577c478bd9Sstevel@tonic-gate #endif /* SOLARIS_LDAP_CMD */ 7587c478bd9Sstevel@tonic-gate } 7597c478bd9Sstevel@tonic-gate 7607c478bd9Sstevel@tonic-gate if ( rc == LDAP_SUCCESS ) { 7617c478bd9Sstevel@tonic-gate rc = 0; 7627c478bd9Sstevel@tonic-gate } 7637c478bd9Sstevel@tonic-gate } 7647c478bd9Sstevel@tonic-gate 7657c478bd9Sstevel@tonic-gate if ( dn != NULL ) { 7667c478bd9Sstevel@tonic-gate free( dn ); 7677c478bd9Sstevel@tonic-gate } 7687c478bd9Sstevel@tonic-gate if ( newrdn != NULL ) { 7697c478bd9Sstevel@tonic-gate free( newrdn ); 7707c478bd9Sstevel@tonic-gate } 7717c478bd9Sstevel@tonic-gate if ( newparent != NULL ) { 7727c478bd9Sstevel@tonic-gate free( newparent ); 7737c478bd9Sstevel@tonic-gate } 7747c478bd9Sstevel@tonic-gate if ( pmods != NULL ) { 7757c478bd9Sstevel@tonic-gate freepmods( pmods ); 7767c478bd9Sstevel@tonic-gate } 7777c478bd9Sstevel@tonic-gate 7787c478bd9Sstevel@tonic-gate return( rc ); 7797c478bd9Sstevel@tonic-gate } 7807c478bd9Sstevel@tonic-gate 7817c478bd9Sstevel@tonic-gate 7827c478bd9Sstevel@tonic-gate static int 7837c478bd9Sstevel@tonic-gate #ifdef SOLARIS_LDAP_CMD 7847c478bd9Sstevel@tonic-gate process_ldapmod_rec( LDAP *ld, char *rbuf ) 7857c478bd9Sstevel@tonic-gate #else 7867c478bd9Sstevel@tonic-gate process_ldapmod_rec( char *rbuf ) 7877c478bd9Sstevel@tonic-gate #endif /* SOLARIS_LDAP_CMD */ 7887c478bd9Sstevel@tonic-gate { 7897c478bd9Sstevel@tonic-gate char *line, *dn, *p, *q, *attr, *value; 7907c478bd9Sstevel@tonic-gate int rc, linenum, modop; 7917c478bd9Sstevel@tonic-gate LDAPMod **pmods; 7927c478bd9Sstevel@tonic-gate 7937c478bd9Sstevel@tonic-gate pmods = NULL; 7947c478bd9Sstevel@tonic-gate dn = NULL; 7957c478bd9Sstevel@tonic-gate linenum = 0; 7967c478bd9Sstevel@tonic-gate line = rbuf; 7977c478bd9Sstevel@tonic-gate rc = 0; 7987c478bd9Sstevel@tonic-gate 7997c478bd9Sstevel@tonic-gate while ( rc == 0 && rbuf != NULL && *rbuf != '\0' ) { 8007c478bd9Sstevel@tonic-gate ++linenum; 8017c478bd9Sstevel@tonic-gate if (( p = strchr( rbuf, '\n' )) == NULL ) { 8027c478bd9Sstevel@tonic-gate rbuf = NULL; 8037c478bd9Sstevel@tonic-gate } else { 8047c478bd9Sstevel@tonic-gate if ( *(p-1) == '\\' ) { /* lines ending in '\' are continued */ 8057c478bd9Sstevel@tonic-gate strcpy( p - 1, p ); 8067c478bd9Sstevel@tonic-gate rbuf = p; 8077c478bd9Sstevel@tonic-gate continue; 8087c478bd9Sstevel@tonic-gate } 8097c478bd9Sstevel@tonic-gate *p++ = '\0'; 8107c478bd9Sstevel@tonic-gate rbuf = p; 8117c478bd9Sstevel@tonic-gate } 8127c478bd9Sstevel@tonic-gate 8137c478bd9Sstevel@tonic-gate if ( dn == NULL ) { /* first line contains DN */ 8147c478bd9Sstevel@tonic-gate if (( dn = strdup( line )) == NULL ) { 8157c478bd9Sstevel@tonic-gate perror( "strdup" ); 8167c478bd9Sstevel@tonic-gate exit( LDAP_NO_MEMORY ); 8177c478bd9Sstevel@tonic-gate } 8187c478bd9Sstevel@tonic-gate } else { 8197c478bd9Sstevel@tonic-gate if (( p = strchr( line, '=' )) == NULL ) { 8207c478bd9Sstevel@tonic-gate value = NULL; 8217c478bd9Sstevel@tonic-gate p = line + strlen( line ); 8227c478bd9Sstevel@tonic-gate } else { 8237c478bd9Sstevel@tonic-gate *p++ = '\0'; 8247c478bd9Sstevel@tonic-gate value = p; 8257c478bd9Sstevel@tonic-gate } 8267c478bd9Sstevel@tonic-gate 8277c478bd9Sstevel@tonic-gate for ( attr = line; *attr != '\0' && isspace( *attr ); ++attr ) { 8287c478bd9Sstevel@tonic-gate ; /* skip attribute leading white space */ 8297c478bd9Sstevel@tonic-gate } 8307c478bd9Sstevel@tonic-gate 8317c478bd9Sstevel@tonic-gate for ( q = p - 1; q > attr && isspace( *q ); --q ) { 8327c478bd9Sstevel@tonic-gate *q = '\0'; /* remove attribute trailing white space */ 8337c478bd9Sstevel@tonic-gate } 8347c478bd9Sstevel@tonic-gate 8357c478bd9Sstevel@tonic-gate if ( value != NULL ) { 8367c478bd9Sstevel@tonic-gate while ( isspace( *value )) { 8377c478bd9Sstevel@tonic-gate ++value; /* skip value leading white space */ 8387c478bd9Sstevel@tonic-gate } 8397c478bd9Sstevel@tonic-gate for ( q = value + strlen( value ) - 1; q > value && 8407c478bd9Sstevel@tonic-gate isspace( *q ); --q ) { 8417c478bd9Sstevel@tonic-gate *q = '\0'; /* remove value trailing white space */ 8427c478bd9Sstevel@tonic-gate } 8437c478bd9Sstevel@tonic-gate if ( *value == '\0' ) { 8447c478bd9Sstevel@tonic-gate value = NULL; 8457c478bd9Sstevel@tonic-gate } 8467c478bd9Sstevel@tonic-gate 8477c478bd9Sstevel@tonic-gate } 8487c478bd9Sstevel@tonic-gate 8497c478bd9Sstevel@tonic-gate if ( value == NULL && newval ) { 8507c478bd9Sstevel@tonic-gate fprintf( stderr, gettext("%s: missing value on line %d (attr is %s)\n"), 8517c478bd9Sstevel@tonic-gate ldaptool_progname, linenum, attr ); 8527c478bd9Sstevel@tonic-gate rc = LDAP_PARAM_ERROR; 8537c478bd9Sstevel@tonic-gate } else { 8547c478bd9Sstevel@tonic-gate switch ( *attr ) { 8557c478bd9Sstevel@tonic-gate case '-': 8567c478bd9Sstevel@tonic-gate modop = LDAP_MOD_DELETE; 8577c478bd9Sstevel@tonic-gate ++attr; 8587c478bd9Sstevel@tonic-gate break; 8597c478bd9Sstevel@tonic-gate case '+': 8607c478bd9Sstevel@tonic-gate modop = LDAP_MOD_ADD; 8617c478bd9Sstevel@tonic-gate ++attr; 8627c478bd9Sstevel@tonic-gate break; 8637c478bd9Sstevel@tonic-gate default: 8647c478bd9Sstevel@tonic-gate #ifdef SOLARIS_LDAP_CMD 8657c478bd9Sstevel@tonic-gate modop = replace ? LDAP_MOD_REPLACE : LDAP_MOD_ADD; 8667c478bd9Sstevel@tonic-gate #else 8677c478bd9Sstevel@tonic-gate /*Bug 27479. Remove the add default*/ 8687c478bd9Sstevel@tonic-gate fprintf(stderr, gettext("%s: Invalid parameter specified for changetype modify (line %d of entry %s)\n"), 8697c478bd9Sstevel@tonic-gate ldaptool_progname, linenum, dn); 8707c478bd9Sstevel@tonic-gate rc = LDAP_PARAM_ERROR; 8717c478bd9Sstevel@tonic-gate #endif /* SOLARIS_LDAP_CMD */ 8727c478bd9Sstevel@tonic-gate } 8737c478bd9Sstevel@tonic-gate 8747c478bd9Sstevel@tonic-gate addmodifyop( &pmods, modop, attr, value, 8757c478bd9Sstevel@tonic-gate ( value == NULL ) ? 0 : strlen( value )); 8767c478bd9Sstevel@tonic-gate } 8777c478bd9Sstevel@tonic-gate } 8787c478bd9Sstevel@tonic-gate 8797c478bd9Sstevel@tonic-gate line = rbuf; 8807c478bd9Sstevel@tonic-gate } 8817c478bd9Sstevel@tonic-gate 8827c478bd9Sstevel@tonic-gate if ( rc == 0 ) { 8837c478bd9Sstevel@tonic-gate if ( dn == NULL ) { 8847c478bd9Sstevel@tonic-gate rc = LDAP_PARAM_ERROR; 8857c478bd9Sstevel@tonic-gate #ifdef SOLARIS_LDAP_CMD 8867c478bd9Sstevel@tonic-gate } else if (( rc = domodify( ld, dn, pmods, newval )) == LDAP_SUCCESS ){ 8877c478bd9Sstevel@tonic-gate #else 8887c478bd9Sstevel@tonic-gate } else if (( rc = domodify( dn, pmods, newval )) == LDAP_SUCCESS ){ 8897c478bd9Sstevel@tonic-gate #endif /* SOLARIS_LDAP_CMD */ 8907c478bd9Sstevel@tonic-gate rc = 0; 8917c478bd9Sstevel@tonic-gate } 8927c478bd9Sstevel@tonic-gate } 8937c478bd9Sstevel@tonic-gate 8947c478bd9Sstevel@tonic-gate if ( pmods != NULL ) { 8957c478bd9Sstevel@tonic-gate freepmods( pmods ); 8967c478bd9Sstevel@tonic-gate } 8977c478bd9Sstevel@tonic-gate if ( dn != NULL ) { 8987c478bd9Sstevel@tonic-gate free( dn ); 8997c478bd9Sstevel@tonic-gate } 9007c478bd9Sstevel@tonic-gate 9017c478bd9Sstevel@tonic-gate return( rc ); 9027c478bd9Sstevel@tonic-gate } 9037c478bd9Sstevel@tonic-gate 9047c478bd9Sstevel@tonic-gate 9057c478bd9Sstevel@tonic-gate static void 9067c478bd9Sstevel@tonic-gate addmodifyop( LDAPMod ***pmodsp, int modop, char *attr, char *value, int vlen ) 9077c478bd9Sstevel@tonic-gate { 9087c478bd9Sstevel@tonic-gate LDAPMod **pmods; 9097c478bd9Sstevel@tonic-gate int i, j, rc; 9107c478bd9Sstevel@tonic-gate struct berval *bvp; 9117c478bd9Sstevel@tonic-gate 9127c478bd9Sstevel@tonic-gate pmods = *pmodsp; 9137c478bd9Sstevel@tonic-gate modop |= LDAP_MOD_BVALUES; 9147c478bd9Sstevel@tonic-gate 9157c478bd9Sstevel@tonic-gate i = 0; 9167c478bd9Sstevel@tonic-gate if ( pmods != NULL ) { 9177c478bd9Sstevel@tonic-gate for ( ; pmods[ i ] != NULL; ++i ) { 9187c478bd9Sstevel@tonic-gate if ( strcasecmp( pmods[ i ]->mod_type, attr ) == 0 && 9197c478bd9Sstevel@tonic-gate pmods[ i ]->mod_op == modop ) { 9207c478bd9Sstevel@tonic-gate break; 9217c478bd9Sstevel@tonic-gate } 9227c478bd9Sstevel@tonic-gate } 9237c478bd9Sstevel@tonic-gate } 9247c478bd9Sstevel@tonic-gate 9257c478bd9Sstevel@tonic-gate if ( pmods == NULL || pmods[ i ] == NULL ) { 9267c478bd9Sstevel@tonic-gate if (( pmods = (LDAPMod **)LDAPTOOL_SAFEREALLOC( pmods, (i + 2) * 9277c478bd9Sstevel@tonic-gate sizeof( LDAPMod * ))) == NULL ) { 9287c478bd9Sstevel@tonic-gate perror( "realloc" ); 9297c478bd9Sstevel@tonic-gate exit( LDAP_NO_MEMORY ); 9307c478bd9Sstevel@tonic-gate } 9317c478bd9Sstevel@tonic-gate *pmodsp = pmods; 9327c478bd9Sstevel@tonic-gate pmods[ i + 1 ] = NULL; 9337c478bd9Sstevel@tonic-gate if (( pmods[ i ] = (LDAPMod *)calloc( 1, sizeof( LDAPMod ))) 9347c478bd9Sstevel@tonic-gate == NULL ) { 9357c478bd9Sstevel@tonic-gate perror( "calloc" ); 9367c478bd9Sstevel@tonic-gate exit( LDAP_NO_MEMORY ); 9377c478bd9Sstevel@tonic-gate } 9387c478bd9Sstevel@tonic-gate pmods[ i ]->mod_op = modop; 9397c478bd9Sstevel@tonic-gate if (( pmods[ i ]->mod_type = strdup( attr )) == NULL ) { 9407c478bd9Sstevel@tonic-gate perror( "strdup" ); 9417c478bd9Sstevel@tonic-gate exit( LDAP_NO_MEMORY ); 9427c478bd9Sstevel@tonic-gate } 9437c478bd9Sstevel@tonic-gate } 9447c478bd9Sstevel@tonic-gate 9457c478bd9Sstevel@tonic-gate if ( value != NULL ) { 9467c478bd9Sstevel@tonic-gate j = 0; 9477c478bd9Sstevel@tonic-gate if ( pmods[ i ]->mod_bvalues != NULL ) { 9487c478bd9Sstevel@tonic-gate for ( ; pmods[ i ]->mod_bvalues[ j ] != NULL; ++j ) { 9497c478bd9Sstevel@tonic-gate ; 9507c478bd9Sstevel@tonic-gate } 9517c478bd9Sstevel@tonic-gate } 9527c478bd9Sstevel@tonic-gate if (( pmods[ i ]->mod_bvalues = (struct berval **) 9537c478bd9Sstevel@tonic-gate LDAPTOOL_SAFEREALLOC( pmods[ i ]->mod_bvalues, 9547c478bd9Sstevel@tonic-gate (j + 2) * sizeof( struct berval * ))) == NULL ) { 9557c478bd9Sstevel@tonic-gate perror( "realloc" ); 9567c478bd9Sstevel@tonic-gate exit( LDAP_NO_MEMORY ); 9577c478bd9Sstevel@tonic-gate } 9587c478bd9Sstevel@tonic-gate pmods[ i ]->mod_bvalues[ j + 1 ] = NULL; 9597c478bd9Sstevel@tonic-gate if (( bvp = (struct berval *)malloc( sizeof( struct berval ))) 9607c478bd9Sstevel@tonic-gate == NULL ) { 9617c478bd9Sstevel@tonic-gate perror( "malloc" ); 9627c478bd9Sstevel@tonic-gate exit( LDAP_NO_MEMORY ); 9637c478bd9Sstevel@tonic-gate } 9647c478bd9Sstevel@tonic-gate pmods[ i ]->mod_bvalues[ j ] = bvp; 9657c478bd9Sstevel@tonic-gate 9667c478bd9Sstevel@tonic-gate #ifdef notdef 9677c478bd9Sstevel@tonic-gate if (ldaptool_verbose) { 9687c478bd9Sstevel@tonic-gate printf(gettext("%s: value: %s vlen: %d\n"), "ldapmodify", value, vlen); 9697c478bd9Sstevel@tonic-gate } 9707c478bd9Sstevel@tonic-gate #endif 9717c478bd9Sstevel@tonic-gate rc = ldaptool_berval_from_ldif_value( value, vlen, bvp, 9727c478bd9Sstevel@tonic-gate ( ldif_version >= LDIF_VERSION_ONE ), valsfromfiles, 9737c478bd9Sstevel@tonic-gate 1 /* report errors */ ); 9747c478bd9Sstevel@tonic-gate if ( rc != LDAPTOOL_FILEURL_SUCCESS ) { 9757c478bd9Sstevel@tonic-gate exit( ldaptool_fileurlerr2ldaperr( rc )); 9767c478bd9Sstevel@tonic-gate } 9777c478bd9Sstevel@tonic-gate } 9787c478bd9Sstevel@tonic-gate } 9797c478bd9Sstevel@tonic-gate 9807c478bd9Sstevel@tonic-gate 9817c478bd9Sstevel@tonic-gate static int 9827c478bd9Sstevel@tonic-gate #ifdef SOLARIS_LDAP_CMD 9837c478bd9Sstevel@tonic-gate domodify( LDAP *ld, char *dn, LDAPMod **pmods, int newentry ) 9847c478bd9Sstevel@tonic-gate #else 9857c478bd9Sstevel@tonic-gate domodify( char *dn, LDAPMod **pmods, int newentry ) 9867c478bd9Sstevel@tonic-gate #endif /* SOLARIS_LDAP_CMD */ 9877c478bd9Sstevel@tonic-gate { 9887c478bd9Sstevel@tonic-gate int i, j, notascii, op; 9897c478bd9Sstevel@tonic-gate struct berval *bvp; 9907c478bd9Sstevel@tonic-gate 9917c478bd9Sstevel@tonic-gate if ( pmods == NULL ) { 9927c478bd9Sstevel@tonic-gate fprintf( stderr, gettext("%s: no attributes to change or add (entry %s)\n"), 9937c478bd9Sstevel@tonic-gate ldaptool_progname, dn ); 9947c478bd9Sstevel@tonic-gate return( LDAP_PARAM_ERROR ); 9957c478bd9Sstevel@tonic-gate } 9967c478bd9Sstevel@tonic-gate 9977c478bd9Sstevel@tonic-gate if ( ldaptool_verbose ) { 9987c478bd9Sstevel@tonic-gate for ( i = 0; pmods[ i ] != NULL; ++i ) { 9997c478bd9Sstevel@tonic-gate op = pmods[ i ]->mod_op & ~LDAP_MOD_BVALUES; 10007c478bd9Sstevel@tonic-gate printf( gettext("%s %s:\n"), op == LDAP_MOD_REPLACE ? 10017c478bd9Sstevel@tonic-gate gettext("replace") : op == LDAP_MOD_ADD ? 10027c478bd9Sstevel@tonic-gate gettext("add") : gettext("delete"), pmods[ i ]->mod_type ); 10037c478bd9Sstevel@tonic-gate if ( pmods[ i ]->mod_bvalues != NULL ) { 10047c478bd9Sstevel@tonic-gate for ( j = 0; pmods[ i ]->mod_bvalues[ j ] != NULL; ++j ) { 10057c478bd9Sstevel@tonic-gate bvp = pmods[ i ]->mod_bvalues[ j ]; 10067c478bd9Sstevel@tonic-gate notascii = 0; 10077c478bd9Sstevel@tonic-gate if ( !display_binary_values ) { 10087c478bd9Sstevel@tonic-gate notascii = !ldaptool_berval_is_ascii( bvp ); 10097c478bd9Sstevel@tonic-gate } 10107c478bd9Sstevel@tonic-gate if ( notascii ) { 10117c478bd9Sstevel@tonic-gate printf( gettext("\tNOT ASCII (%ld bytes)\n"), bvp->bv_len ); 10127c478bd9Sstevel@tonic-gate } else { 10137c478bd9Sstevel@tonic-gate printf( "\t%s\n", bvp->bv_val ); 10147c478bd9Sstevel@tonic-gate } 10157c478bd9Sstevel@tonic-gate } 10167c478bd9Sstevel@tonic-gate } 10177c478bd9Sstevel@tonic-gate } 10187c478bd9Sstevel@tonic-gate } 10197c478bd9Sstevel@tonic-gate 10207c478bd9Sstevel@tonic-gate if ( !ldapmodify_quiet) { 10217c478bd9Sstevel@tonic-gate if ( newentry ) { 10227c478bd9Sstevel@tonic-gate printf( gettext("%sadding new entry %s\n"), 10237c478bd9Sstevel@tonic-gate ldaptool_not ? "!" : "", dn ); 10247c478bd9Sstevel@tonic-gate } else { 10257c478bd9Sstevel@tonic-gate printf( gettext("%smodifying entry %s\n"), 10267c478bd9Sstevel@tonic-gate ldaptool_not ? "!" : "", dn ); 10277c478bd9Sstevel@tonic-gate } 10287c478bd9Sstevel@tonic-gate } 10297c478bd9Sstevel@tonic-gate 10307c478bd9Sstevel@tonic-gate if ( !ldaptool_not ) { 10317c478bd9Sstevel@tonic-gate if ( newentry ) { 10327c478bd9Sstevel@tonic-gate unsigned int sleep_interval = 2; /* seconds */ 10337c478bd9Sstevel@tonic-gate 10347c478bd9Sstevel@tonic-gate #ifdef SOLARIS_LDAP_CMD 10357c478bd9Sstevel@tonic-gate /* Backward compatibility with old Solaris command */ 10367c478bd9Sstevel@tonic-gate unsigned int nb = 0; 10377c478bd9Sstevel@tonic-gate timestruc_t to; 10387c478bd9Sstevel@tonic-gate while ((i = ldaptool_add_ext_s( ld, dn, pmods, 10397c478bd9Sstevel@tonic-gate ldaptool_request_ctrls, NULL, "ldap_add" )) 10407c478bd9Sstevel@tonic-gate != LDAP_SUCCESS) { 10417c478bd9Sstevel@tonic-gate if (i == LDAP_BUSY) { 10427c478bd9Sstevel@tonic-gate if ( sleep_interval > 3600 ) { 10437c478bd9Sstevel@tonic-gate printf(gettext("ldap_add: Unable to complete " 10447c478bd9Sstevel@tonic-gate "request. Server is too " 10457c478bd9Sstevel@tonic-gate "busy servicing other " 10467c478bd9Sstevel@tonic-gate "requests\n")); 10477c478bd9Sstevel@tonic-gate break; 10487c478bd9Sstevel@tonic-gate } 10497c478bd9Sstevel@tonic-gate if ( !ldapmodify_quiet ) { 10507c478bd9Sstevel@tonic-gate printf(gettext("ldap_add: LDAP_BUSY returned " 10517c478bd9Sstevel@tonic-gate "by server. Will retry " 10527c478bd9Sstevel@tonic-gate "operation in %d seconds\n"), 10537c478bd9Sstevel@tonic-gate sleep_interval); 10547c478bd9Sstevel@tonic-gate } 10557c478bd9Sstevel@tonic-gate sleep( sleep_interval ); 10567c478bd9Sstevel@tonic-gate sleep_interval *= 2; 10577c478bd9Sstevel@tonic-gate } else if (i == LDAP_NO_SUCH_OBJECT) { 10587c478bd9Sstevel@tonic-gate /* 10597c478bd9Sstevel@tonic-gate * Wait for the parent entry to be created by 10607c478bd9Sstevel@tonic-gate * another thread. Do not retry more than the 10617c478bd9Sstevel@tonic-gate * number of threads. 10627c478bd9Sstevel@tonic-gate */ 10637c478bd9Sstevel@tonic-gate ++nb; 10647c478bd9Sstevel@tonic-gate if (nb >= nbthreads) 10657c478bd9Sstevel@tonic-gate break; 10667c478bd9Sstevel@tonic-gate mutex_lock(&wait_mutex); 10677c478bd9Sstevel@tonic-gate to.tv_sec = 5; 10687c478bd9Sstevel@tonic-gate to.tv_nsec = 0; 10697c478bd9Sstevel@tonic-gate if (cond_reltimedwait(&wait_cond, &wait_mutex, &to) 10707c478bd9Sstevel@tonic-gate == ETIME) { 10717c478bd9Sstevel@tonic-gate nb = nbthreads; /* last chance */ 10727c478bd9Sstevel@tonic-gate } 10737c478bd9Sstevel@tonic-gate mutex_unlock(&wait_mutex); 10747c478bd9Sstevel@tonic-gate } else { 10757c478bd9Sstevel@tonic-gate break; 10767c478bd9Sstevel@tonic-gate } 10777c478bd9Sstevel@tonic-gate } 10787c478bd9Sstevel@tonic-gate cond_broadcast(&wait_cond); 10797c478bd9Sstevel@tonic-gate #else 10807c478bd9Sstevel@tonic-gate while ((i = ldaptool_add_ext_s( ld, dn, pmods, 10817c478bd9Sstevel@tonic-gate ldaptool_request_ctrls, NULL, "ldap_add" )) 10827c478bd9Sstevel@tonic-gate == LDAP_BUSY) { 10837c478bd9Sstevel@tonic-gate if ( sleep_interval > 3600 ) { 10847c478bd9Sstevel@tonic-gate printf("ldap_add: Unable to complete request. "); 10857c478bd9Sstevel@tonic-gate printf("Server is too "); 10867c478bd9Sstevel@tonic-gate printf("busy servicing other requests\n"); 10877c478bd9Sstevel@tonic-gate break; 10887c478bd9Sstevel@tonic-gate } 10897c478bd9Sstevel@tonic-gate if ( !ldapmodify_quiet ) { 10907c478bd9Sstevel@tonic-gate printf("ldap_add: LDAP_BUSY returned by server. "); 10917c478bd9Sstevel@tonic-gate printf("Will retry operation "); 10927c478bd9Sstevel@tonic-gate printf("in %d seconds\n", sleep_interval); 10937c478bd9Sstevel@tonic-gate } 10947c478bd9Sstevel@tonic-gate sleep( sleep_interval ); 10957c478bd9Sstevel@tonic-gate sleep_interval *= 2; 10967c478bd9Sstevel@tonic-gate } 10977c478bd9Sstevel@tonic-gate #endif /* SOLARIS_LDAP_CMD */ 10987c478bd9Sstevel@tonic-gate } else { 10997c478bd9Sstevel@tonic-gate i = ldaptool_modify_ext_s( ld, dn, pmods, ldaptool_request_ctrls, 11007c478bd9Sstevel@tonic-gate NULL, "ldap_modify" ); 11017c478bd9Sstevel@tonic-gate } 11027c478bd9Sstevel@tonic-gate if ( i == LDAP_SUCCESS && ldaptool_verbose ) { 11037c478bd9Sstevel@tonic-gate printf( gettext("modify complete\n") ); 11047c478bd9Sstevel@tonic-gate } 11057c478bd9Sstevel@tonic-gate } else { 11067c478bd9Sstevel@tonic-gate i = LDAP_SUCCESS; 11077c478bd9Sstevel@tonic-gate } 11087c478bd9Sstevel@tonic-gate 11097c478bd9Sstevel@tonic-gate if ( !ldapmodify_quiet) { 11107c478bd9Sstevel@tonic-gate putchar( '\n' ); 11117c478bd9Sstevel@tonic-gate } 11127c478bd9Sstevel@tonic-gate 11137c478bd9Sstevel@tonic-gate return( i ); 11147c478bd9Sstevel@tonic-gate } 11157c478bd9Sstevel@tonic-gate 11167c478bd9Sstevel@tonic-gate 11177c478bd9Sstevel@tonic-gate static int 11187c478bd9Sstevel@tonic-gate #ifdef SOLARIS_LDAP_CMD 11197c478bd9Sstevel@tonic-gate dodelete( LDAP *ld, char *dn ) 11207c478bd9Sstevel@tonic-gate #else 11217c478bd9Sstevel@tonic-gate dodelete( char *dn ) 11227c478bd9Sstevel@tonic-gate #endif /* SOLARIS_LDAP_CMD */ 11237c478bd9Sstevel@tonic-gate { 11247c478bd9Sstevel@tonic-gate int rc; 11257c478bd9Sstevel@tonic-gate 11267c478bd9Sstevel@tonic-gate printf( gettext("%sdeleting entry %s\n"), ldaptool_not ? "!" : "", dn ); 11277c478bd9Sstevel@tonic-gate if ( !ldaptool_not ) { 11287c478bd9Sstevel@tonic-gate if (( rc = ldaptool_delete_ext_s( ld, dn, ldaptool_request_ctrls, 11297c478bd9Sstevel@tonic-gate NULL, "ldap_delete" )) == LDAP_SUCCESS && ldaptool_verbose ) { 11307c478bd9Sstevel@tonic-gate printf( gettext("delete complete") ); 11317c478bd9Sstevel@tonic-gate } 11327c478bd9Sstevel@tonic-gate } else { 11337c478bd9Sstevel@tonic-gate rc = LDAP_SUCCESS; 11347c478bd9Sstevel@tonic-gate } 11357c478bd9Sstevel@tonic-gate 11367c478bd9Sstevel@tonic-gate putchar( '\n' ); 11377c478bd9Sstevel@tonic-gate 11387c478bd9Sstevel@tonic-gate return( rc ); 11397c478bd9Sstevel@tonic-gate } 11407c478bd9Sstevel@tonic-gate 11417c478bd9Sstevel@tonic-gate 11427c478bd9Sstevel@tonic-gate static int 11437c478bd9Sstevel@tonic-gate #ifdef SOLARIS_LDAP_CMD 11447c478bd9Sstevel@tonic-gate dorename( LDAP *ld, char *dn, char *newrdn, char *newparent, int deleteoldrdn ) 11457c478bd9Sstevel@tonic-gate #else 11467c478bd9Sstevel@tonic-gate dorename( char *dn, char *newrdn, char *newparent, int deleteoldrdn ) 11477c478bd9Sstevel@tonic-gate #endif /* SOLARIS_LDAP_CMD */ 11487c478bd9Sstevel@tonic-gate { 11497c478bd9Sstevel@tonic-gate int rc; 11507c478bd9Sstevel@tonic-gate 11517c478bd9Sstevel@tonic-gate if ( ldaptool_verbose ) { 11527c478bd9Sstevel@tonic-gate if ( newparent == NULL ) { 11537c478bd9Sstevel@tonic-gate printf(deleteoldrdn ? 11547c478bd9Sstevel@tonic-gate gettext("new RDN: %s (do not keep existing values)\n"): 11557c478bd9Sstevel@tonic-gate gettext("new RDN: %s (keep existing values)\n")); 11567c478bd9Sstevel@tonic-gate } else { 11577c478bd9Sstevel@tonic-gate printf(deleteoldrdn ? 11587c478bd9Sstevel@tonic-gate gettext("new RDN: %s, new parent %s ( do not keep existing values)\n"): 11597c478bd9Sstevel@tonic-gate gettext("new RDN: %s, new parent %s ( keep existing values)\n")); 11607c478bd9Sstevel@tonic-gate } 11617c478bd9Sstevel@tonic-gate } 11627c478bd9Sstevel@tonic-gate 11637c478bd9Sstevel@tonic-gate printf( gettext("%smodifying RDN of entry %s%s\n"), 11647c478bd9Sstevel@tonic-gate ldaptool_not ? "!" : "", dn, ( newparent == NULL ) ? "" : 11657c478bd9Sstevel@tonic-gate gettext(" and/or moving it beneath a new parent\n") ); 11667c478bd9Sstevel@tonic-gate 11677c478bd9Sstevel@tonic-gate if ( !ldaptool_not ) { 11687c478bd9Sstevel@tonic-gate if (( rc = ldaptool_rename_s( ld, dn, newrdn, newparent, deleteoldrdn, 11697c478bd9Sstevel@tonic-gate ldaptool_request_ctrls, NULL, "ldap_rename" )) == LDAP_SUCCESS 11707c478bd9Sstevel@tonic-gate && ldaptool_verbose ) { 11717c478bd9Sstevel@tonic-gate printf( gettext("rename completed\n") ); 11727c478bd9Sstevel@tonic-gate } 11737c478bd9Sstevel@tonic-gate } else { 11747c478bd9Sstevel@tonic-gate rc = LDAP_SUCCESS; 11757c478bd9Sstevel@tonic-gate } 11767c478bd9Sstevel@tonic-gate 11777c478bd9Sstevel@tonic-gate putchar( '\n' ); 11787c478bd9Sstevel@tonic-gate 11797c478bd9Sstevel@tonic-gate return( rc ); 11807c478bd9Sstevel@tonic-gate } 11817c478bd9Sstevel@tonic-gate 11827c478bd9Sstevel@tonic-gate 11837c478bd9Sstevel@tonic-gate static void 11847c478bd9Sstevel@tonic-gate freepmods( LDAPMod **pmods ) 11857c478bd9Sstevel@tonic-gate { 11867c478bd9Sstevel@tonic-gate int i; 11877c478bd9Sstevel@tonic-gate 11887c478bd9Sstevel@tonic-gate for ( i = 0; pmods[ i ] != NULL; ++i ) { 11897c478bd9Sstevel@tonic-gate if ( pmods[ i ]->mod_bvalues != NULL ) { 11907c478bd9Sstevel@tonic-gate ber_bvecfree( pmods[ i ]->mod_bvalues ); 11917c478bd9Sstevel@tonic-gate } 11927c478bd9Sstevel@tonic-gate if ( pmods[ i ]->mod_type != NULL ) { 11937c478bd9Sstevel@tonic-gate free( pmods[ i ]->mod_type ); 11947c478bd9Sstevel@tonic-gate } 11957c478bd9Sstevel@tonic-gate free( pmods[ i ] ); 11967c478bd9Sstevel@tonic-gate } 11977c478bd9Sstevel@tonic-gate free( pmods ); 11987c478bd9Sstevel@tonic-gate } 11997c478bd9Sstevel@tonic-gate 12007c478bd9Sstevel@tonic-gate 12017c478bd9Sstevel@tonic-gate static char * 12027c478bd9Sstevel@tonic-gate read_one_record( FILE *fp ) 12037c478bd9Sstevel@tonic-gate { 12047c478bd9Sstevel@tonic-gate int len, gotnothing; 12057c478bd9Sstevel@tonic-gate char *buf, line[ LDAPMOD_MAXLINE ]; 12067c478bd9Sstevel@tonic-gate int lcur, lmax; 12077c478bd9Sstevel@tonic-gate 12087c478bd9Sstevel@tonic-gate lcur = lmax = 0; 12097c478bd9Sstevel@tonic-gate buf = NULL; 12107c478bd9Sstevel@tonic-gate gotnothing = 1; 12117c478bd9Sstevel@tonic-gate 12127c478bd9Sstevel@tonic-gate #ifdef SOLARIS_LDAP_CMD 12137c478bd9Sstevel@tonic-gate mutex_lock(&read_mutex); 12147c478bd9Sstevel@tonic-gate 12157c478bd9Sstevel@tonic-gate if (fp == NULL) { 12167c478bd9Sstevel@tonic-gate mutex_unlock(&read_mutex); 12177c478bd9Sstevel@tonic-gate return(NULL); 12187c478bd9Sstevel@tonic-gate } 12197c478bd9Sstevel@tonic-gate #endif 12207c478bd9Sstevel@tonic-gate 12217c478bd9Sstevel@tonic-gate while ( fgets( line, sizeof(line), fp ) != NULL ) { 12227c478bd9Sstevel@tonic-gate if ( (len = strlen( line )) < 2 ) { 12237c478bd9Sstevel@tonic-gate if ( gotnothing ) { 12247c478bd9Sstevel@tonic-gate continue; 12257c478bd9Sstevel@tonic-gate } else { 12267c478bd9Sstevel@tonic-gate break; 12277c478bd9Sstevel@tonic-gate } 12287c478bd9Sstevel@tonic-gate } 12297c478bd9Sstevel@tonic-gate 12307c478bd9Sstevel@tonic-gate /* Check if the blank line starts with '\r' (CR) */ 12317c478bd9Sstevel@tonic-gate if ( ((len = strlen( line )) == 2) && (line[0] == '\r') ) { 12327c478bd9Sstevel@tonic-gate if ( gotnothing ) { 12337c478bd9Sstevel@tonic-gate continue; 12347c478bd9Sstevel@tonic-gate } else { 12357c478bd9Sstevel@tonic-gate break; 12367c478bd9Sstevel@tonic-gate } 12377c478bd9Sstevel@tonic-gate } 12387c478bd9Sstevel@tonic-gate 12397c478bd9Sstevel@tonic-gate if ( *line == '#' ) { 12407c478bd9Sstevel@tonic-gate continue; /* skip comment lines */ 12417c478bd9Sstevel@tonic-gate } 12427c478bd9Sstevel@tonic-gate 12437c478bd9Sstevel@tonic-gate gotnothing = 0; 12447c478bd9Sstevel@tonic-gate if ( lcur + len + 1 > lmax ) { 12457c478bd9Sstevel@tonic-gate lmax = LDAPMOD_MAXLINE 12467c478bd9Sstevel@tonic-gate * (( lcur + len + 1 ) / LDAPMOD_MAXLINE + 1 ); 12477c478bd9Sstevel@tonic-gate if (( buf = (char *)LDAPTOOL_SAFEREALLOC( buf, lmax )) == NULL ) { 12487c478bd9Sstevel@tonic-gate perror( "realloc" ); 12497c478bd9Sstevel@tonic-gate #ifdef SOLARIS_LDAP_CMD 12507c478bd9Sstevel@tonic-gate mutex_unlock(&read_mutex); 12517c478bd9Sstevel@tonic-gate #endif 12527c478bd9Sstevel@tonic-gate exit( LDAP_NO_MEMORY ); 12537c478bd9Sstevel@tonic-gate } 12547c478bd9Sstevel@tonic-gate } 12557c478bd9Sstevel@tonic-gate strcpy( buf + lcur, line ); 12567c478bd9Sstevel@tonic-gate lcur += len; 12577c478bd9Sstevel@tonic-gate } 12587c478bd9Sstevel@tonic-gate 12597c478bd9Sstevel@tonic-gate #ifdef SOLARIS_LDAP_CMD 12607c478bd9Sstevel@tonic-gate mutex_unlock(&read_mutex); 12617c478bd9Sstevel@tonic-gate #endif 12627c478bd9Sstevel@tonic-gate 12637c478bd9Sstevel@tonic-gate return( buf ); 12647c478bd9Sstevel@tonic-gate } 12657c478bd9Sstevel@tonic-gate 12667c478bd9Sstevel@tonic-gate 12677c478bd9Sstevel@tonic-gate /* 12687c478bd9Sstevel@tonic-gate * strdup and trim trailing blanks 12697c478bd9Sstevel@tonic-gate */ 12707c478bd9Sstevel@tonic-gate static char * 12717c478bd9Sstevel@tonic-gate strdup_and_trim( char *s ) 12727c478bd9Sstevel@tonic-gate { 12737c478bd9Sstevel@tonic-gate char *p; 12747c478bd9Sstevel@tonic-gate 12757c478bd9Sstevel@tonic-gate if (( s = strdup( s )) == NULL ) { 12767c478bd9Sstevel@tonic-gate perror( "strdup" ); 12777c478bd9Sstevel@tonic-gate exit( LDAP_NO_MEMORY ); 12787c478bd9Sstevel@tonic-gate } 12797c478bd9Sstevel@tonic-gate 12807c478bd9Sstevel@tonic-gate p = s + strlen( s ) - 1; 12817c478bd9Sstevel@tonic-gate while ( p >= s && isspace( *p )) { 12827c478bd9Sstevel@tonic-gate --p; 12837c478bd9Sstevel@tonic-gate } 12847c478bd9Sstevel@tonic-gate *++p = '\0'; 12857c478bd9Sstevel@tonic-gate 12867c478bd9Sstevel@tonic-gate return( s ); 12877c478bd9Sstevel@tonic-gate } 1288