/*
* Copyright 2008 Sun Microsystems, Inc. All rights reserved.
* Use is subject to license terms.
*/
/*
* The contents of this file are subject to the Netscape Public
* License Version 1.1 (the "License"); you may not use this file
* except in compliance with the License. You may obtain a copy of
* the License at http://www.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS
* IS" basis, WITHOUT WARRANTY OF ANY KIND, either express or
* implied. See the License for the specific language governing
* rights and limitations under the License.
*
* The Original Code is Mozilla Communicator client code, released
* March 31, 1998.
*
* The Initial Developer of the Original Code is Netscape
* Communications Corporation. Portions created by Netscape are
* Copyright (C) 1998-1999 Netscape Communications Corporation. All
* Rights Reserved.
*
* Contributor(s):
*/
/* ldapmodify.c - generic program to modify or add entries using LDAP */
#include "ldaptool.h"
#include "fileurl.h"
#ifdef SOLARIS_LDAP_CMD
#include <locale.h>
#include "ldif.h"
#endif /* SOLARIS_LDAP_CMD */
#ifndef SOLARIS_LDAP_CMD
#define gettext(s) s
#endif
static int ldapmodify_quiet = 0;
#ifdef SOLARIS_LDAP_CMD
static int thr_create_errors = 0;
#else
/*
* For Solaris, ld is defined local to process() because
* multiple threads restricts Solaris from using a global
* ld variable.
* Solaris uses multiple threads to create multiple
* ldap connections if nbthreads > 1 (i.e -l option).
*/
#endif /* SOLARIS_LDAP_CMD */
/* bulk import */
static char *strdup_and_trim( char *s );
#ifdef SOLARIS_LDAP_CMD
int deleteoldrdn );
#else
static int process_ldapmod_rec( char *rbuf );
static int process_ldif_rec( char *rbuf );
int deleteoldrdn );
#endif /* SOLARIS_LDAP_CMD */
static void
usage( void )
{
ldaptool_common_usage( 0 );
}
#ifdef SOLARIS_LDAP_CMD
#endif /* SOLARIS_LDAP_CMD */
exit( LDAP_PARAM_ERROR );
}
int
{
int optind, i;
int rc;
#ifdef SOLARIS_LDAP_CMD
#endif
#ifdef notdef
#ifdef HPUX11
#ifndef __LP64__
#endif /* __LP64_ */
#endif /* HPUX11 */
#endif
#ifdef SOLARIS_LDAP_CMD
#else
#endif /* SOLARIS_LDAP_CMD */
if ( optind == -1 ) {
usage();
}
newval = 1;
}
if ( ldaptool_fp == NULL ) {
ldaptool_fp = stdin;
}
usage();
}
#ifdef SOLARIS_LDAP_CMD
/* trivial case */
if ( nbthreads == 1 ) {
/* check for and report output error */
gettext("output error (output might be incomplete)") );
return( rc );
}
for ( i=0; i<nbthreads; ++i ) {
}
if ( thr_create_errors < nbthreads )
else
error = -1;
/* check for and report output error */
gettext("output error (output might be incomplete)") );
return( rc );
#else
/* check for and report output error */
gettext("output error (output might be incomplete)") );
return( rc );
#endif /* SOLARIS_LDAP_CMD */
}
#ifdef SOLARIS_LDAP_CMD
#define exit(a) \
if (nbthreads > 1) { \
mutex_lock(&read_mutex); \
error |= a; \
mutex_unlock(&read_mutex); \
} else { \
exit(a); \
}
#endif /* SOLARIS_LDAP_CMD */
static int
{
#ifdef SOLARIS_LDAP_CMD
#endif /* SOLARIS_LDAP_CMD */
ld = ldaptool_ldap_init( 0 );
if ( !ldaptool_not ) {
}
ldaptool_bind( ld );
}
}
rc = 0;
/* turn on bulk import?*/
if (bulkimport_suffix) {
char *retoid;
"extended operation request\n\t'%s' for "
"bulk import\n\t(error:%d:'%s')\n"),
return (rc);
}
if (retoid)
if (retdata)
}
/*
* we assume record is ldif/slapd.replog if the first line
* has a colon that appears to the left of any equal signs, OR
* if the first line consists entirely of digits (an entry id)
*/
for ( p = rbuf; p < q; ++p ) {
if ( !isdigit( *p )) {
break;
}
}
if ( p >= q ) {
use_ldif = 1;
start = q + 1;
}
}
#ifdef SOLARIS_LDAP_CMD
if ( use_ldif ) {
} else {
}
#else
if ( use_ldif ) {
} else {
}
#endif /* SOLARIS_LDAP_CMD */
/* Write this record to the reject file */
int newfile = 0;
newfile = 1;
}
}
"erroneous entries will not be saved\n"), rejfile );
} else {
if ( newfile == 0 ) {
}
}
}
free( saved_rbuf );
}
/* turn off bulk import?*/
if (bulkimport_suffix) {
char *retoid;
"extended operation request\n\t '%s' for "
"bulk import\n\t(rc:%d:'%s')\n"),
return (rc);
}
if (retoid)
if (retdata)
}
#ifdef SOLARIS_LDAP_CMD
#endif
ldaptool_cleanup( ld );
#ifdef SOLARIS_LDAP_CMD
#endif
return( rc );
}
static void
{
switch( option ) {
case 'a': /* add */
newval = 1;
break;
case 'b': /* read values from files (for binary attributes) */
valsfromfiles = 1;
break;
case 'A': /* display non-ASCII values when -v is used */
break;
case 'c': /* continuous operation */
contoper = 1;
break;
case 'F': /* force all changes records to be used */
force = 1;
break;
case 'e':
break;
case 'B': /* bulk import option */
break;
ldapmodify_quiet = 1;
break;
#ifdef SOLARIS_LDAP_CMD
case 'r': /* default is to replace rather than add values */
replace = 1;
break;
case 'l':
break;
#endif /* SOLARIS_LDAP_CMD */
default:
usage();
}
}
static int
#ifdef SOLARIS_LDAP_CMD
#else
process_ldif_rec( char *rbuf )
#endif
{
deleteoldrdn = 1;
use_record = force;
#ifdef SOLARIS_LDAP_CMD
#else
#endif /* SOLARIS_LDAP_CMD */
++linenum;
expect_sep = 0;
expect_modop = 1;
/*If we see a separator in the input stream,
but we didn't get a value from the last modify
then we have to fill pmods with an empty value*/
}
got_value = 0;
continue;
}
#ifdef SOLARIS_LDAP_CMD
#else
#endif /* SOLARIS_LDAP_CMD */
break;
}
++saw_replica;
} else {
*p++ = '\0';
replicaport = atoi( p );
}
replicaport == ldaptool_port ) {
use_record = 1;
}
perror( "strdup" );
exit( LDAP_NO_MEMORY );
}
if ( ldif_version != LDIF_VERSION_ONE ) {
exit( LDAP_PARAM_ERROR );
}
if ( ldaptool_verbose ) {
ldif_version );
}
/* Now check if there's something left to process */
/* and if not, go get the new record, else continue */
if ( *rbuf == '\0' ) {
return( 0 );
}
} else if ( !saw_replica ) {
return( 0 );
}
continue; /* skip all lines until we see "dn:" */
}
if ( expect_chgtype_or_control ) {
if ( !use_record && saw_replica ) {
printf( gettext("%s: skipping change record for entry: %s\n\t(LDAP host/port does not match replica: lines)\n"),
ldaptool_progname, dn );
return( 0 );
}
#ifndef SOLARIS_LDAP_CMD
usage();
}
if (ctrl_value) {
&(ldctrl->ldctl_value),
1 /* recognize file URLs */, 0 /* always try file */,
1 /* report errors */ );
usage();
}
}
continue;
}
#endif /* SOLARIS_LDAP_CMD */
new_entry = 0;
expect_modop = 1;
new_entry = 1;
expect_newrdn = 1;
moddn = 1;
expect_newrdn = 1;
moddn = 1;
expect_newrdn = 1;
rename = 1;
} else {
gettext("%s: unknown %s \"%s\" (line %d of entry: %s)\n"),
}
continue;
} else if ( newval ) { /* missing changetype => add */
new_entry = 1;
} else {
/*The user MUST put in changetype: blah
unless adding a new entry with either -a or ldapadd*/
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"),
/*expect_modop = 1; missing changetype => modify */
}
}
if ( expect_modop ) {
expect_modop = 0;
expect_sep = 1;
continue;
continue;
continue;
#ifdef SOLARIS_LDAP_CMD
} else { /* no modify op: use default */
}
#else
} else { /*Bug 27479. Remove default add operation*/
fprintf(stderr, gettext("%s: Invalid parameter \"%s\" specified for changetype modify (line %d of entry %s)\n"),
}
#endif /* SOLARIS_LDAP_CMD */
}
if ( expect_newrdn ) {
if ( *value == '\0' ) {
gettext("%s: newrdn value missing (line %d of entry: %s)\n"),
perror( "strdup" );
exit( LDAP_NO_MEMORY );
} else {
expect_newrdn = 0;
if ( rename ) {
expect_newparent = 1;
} else {
expect_deleteoldrdn = 1;
}
}
} else {
}
} else if ( expect_newparent ) {
expect_newparent = 0;
if ( rename ) {
expect_deleteoldrdn = 1;
}
perror( "strdup" );
exit( LDAP_NO_MEMORY );
}
} else {
* the current line to be re-evaluated if newparent doesn't
* follow deleteoldrdn.
*/
goto evaluate_line;
}
} else if ( expect_deleteoldrdn ) {
if ( *value == '\0' ) {
gettext("%s: missing 0 or 1 (line %d of entry: %s)\n"),
} else {
expect_deleteoldrdn = 0;
if ( moddn ) {
expect_newparent = 1;
}
}
} else {
dn );
}
got_all = 1;
} else if ( got_all ) {
gettext("%s: extra lines at end (line %d of entry %s)\n"),
got_all = 1;
} else {
/*There was a value to replace*/
got_value = 1;
}
}
if ( rc == 0 ) {
if ( delete_entry ) {
#ifdef SOLARIS_LDAP_CMD
#else
#endif /* SOLARIS_LDAP_CMD */
#ifdef SOLARIS_LDAP_CMD
#else
#endif /* SOLARIS_LDAP_CMD */
rename = 0;
} else {
/*Patch to fix Bug 22183
If pmods is null, then there is no
attribute to replace, so we alloc
an empty pmods*/
}/*End Patch*/
#ifdef SOLARIS_LDAP_CMD
#else
#endif /* SOLARIS_LDAP_CMD */
}
if ( rc == LDAP_SUCCESS ) {
rc = 0;
}
}
}
}
}
}
return( rc );
}
static int
#ifdef SOLARIS_LDAP_CMD
#else
process_ldapmod_rec( char *rbuf )
#endif /* SOLARIS_LDAP_CMD */
{
linenum = 0;
rc = 0;
++linenum;
} else {
if ( *(p-1) == '\\' ) { /* lines ending in '\' are continued */
strcpy( p - 1, p );
rbuf = p;
continue;
}
*p++ = '\0';
rbuf = p;
}
perror( "strdup" );
exit( LDAP_NO_MEMORY );
}
} else {
} else {
*p++ = '\0';
value = p;
}
; /* skip attribute leading white space */
}
*q = '\0'; /* remove attribute trailing white space */
}
++value; /* skip value leading white space */
}
isspace( *q ); --q ) {
*q = '\0'; /* remove value trailing white space */
}
if ( *value == '\0' ) {
}
}
} else {
switch ( *attr ) {
case '-':
++attr;
break;
case '+':
++attr;
break;
default:
#ifdef SOLARIS_LDAP_CMD
#else
/*Bug 27479. Remove the add default*/
fprintf(stderr, gettext("%s: Invalid parameter specified for changetype modify (line %d of entry %s)\n"),
#endif /* SOLARIS_LDAP_CMD */
}
}
}
}
if ( rc == 0 ) {
#ifdef SOLARIS_LDAP_CMD
#else
#endif /* SOLARIS_LDAP_CMD */
rc = 0;
}
}
}
}
return( rc );
}
static void
{
int i, j, rc;
i = 0;
break;
}
}
}
perror( "realloc" );
exit( LDAP_NO_MEMORY );
}
== NULL ) {
perror( "calloc" );
exit( LDAP_NO_MEMORY );
}
perror( "strdup" );
exit( LDAP_NO_MEMORY );
}
}
j = 0;
;
}
}
perror( "realloc" );
exit( LDAP_NO_MEMORY );
}
== NULL ) {
perror( "malloc" );
exit( LDAP_NO_MEMORY );
}
#ifdef notdef
if (ldaptool_verbose) {
}
#endif
1 /* report errors */ );
if ( rc != LDAPTOOL_FILEURL_SUCCESS ) {
}
}
}
static int
#ifdef SOLARIS_LDAP_CMD
#else
#endif /* SOLARIS_LDAP_CMD */
{
ldaptool_progname, dn );
return( LDAP_PARAM_ERROR );
}
if ( ldaptool_verbose ) {
notascii = 0;
if ( !display_binary_values ) {
}
if ( notascii ) {
} else {
}
}
}
}
}
if ( !ldapmodify_quiet) {
if ( newentry ) {
} else {
}
}
if ( !ldaptool_not ) {
if ( newentry ) {
#ifdef SOLARIS_LDAP_CMD
/* Backward compatibility with old Solaris command */
unsigned int nb = 0;
!= LDAP_SUCCESS) {
if (i == LDAP_BUSY) {
if ( sleep_interval > 3600 ) {
"request. Server is too "
"busy servicing other "
"requests\n"));
break;
}
if ( !ldapmodify_quiet ) {
"by server. Will retry "
"operation in %d seconds\n"),
}
sleep( sleep_interval );
sleep_interval *= 2;
} else if (i == LDAP_NO_SUCH_OBJECT) {
/*
* Wait for the parent entry to be created by
* another thread. Do not retry more than the
* number of threads.
*/
++nb;
break;
== ETIME) {
}
} else {
break;
}
}
#else
== LDAP_BUSY) {
if ( sleep_interval > 3600 ) {
printf("ldap_add: Unable to complete request. ");
printf("Server is too ");
printf("busy servicing other requests\n");
break;
}
if ( !ldapmodify_quiet ) {
printf("ldap_add: LDAP_BUSY returned by server. ");
printf("Will retry operation ");
}
sleep( sleep_interval );
sleep_interval *= 2;
}
#endif /* SOLARIS_LDAP_CMD */
} else {
NULL, "ldap_modify" );
}
if ( i == LDAP_SUCCESS && ldaptool_verbose ) {
}
} else {
i = LDAP_SUCCESS;
}
if ( !ldapmodify_quiet) {
putchar( '\n' );
}
return( i );
}
static int
#ifdef SOLARIS_LDAP_CMD
#else
#endif /* SOLARIS_LDAP_CMD */
{
int rc;
if ( !ldaptool_not ) {
}
} else {
rc = LDAP_SUCCESS;
}
putchar( '\n' );
return( rc );
}
static int
#ifdef SOLARIS_LDAP_CMD
#else
#endif /* SOLARIS_LDAP_CMD */
{
int rc;
if ( ldaptool_verbose ) {
gettext("new RDN: %s (do not keep existing values)\n"):
gettext("new RDN: %s (keep existing values)\n"));
} else {
gettext("new RDN: %s, new parent %s ( do not keep existing values)\n"):
gettext("new RDN: %s, new parent %s ( keep existing values)\n"));
}
}
if ( !ldaptool_not ) {
&& ldaptool_verbose ) {
}
} else {
rc = LDAP_SUCCESS;
}
putchar( '\n' );
return( rc );
}
static void
{
int i;
}
}
}
}
static char *
{
gotnothing = 1;
#ifdef SOLARIS_LDAP_CMD
return(NULL);
}
#endif
if ( gotnothing ) {
continue;
} else {
break;
}
}
/* Check if the blank line starts with '\r' (CR) */
if ( gotnothing ) {
continue;
} else {
break;
}
}
if ( *line == '#' ) {
continue; /* skip comment lines */
}
gotnothing = 0;
perror( "realloc" );
#ifdef SOLARIS_LDAP_CMD
#endif
exit( LDAP_NO_MEMORY );
}
}
}
#ifdef SOLARIS_LDAP_CMD
#endif
return( buf );
}
/*
* strdup and trim trailing blanks
*/
static char *
strdup_and_trim( char *s )
{
char *p;
perror( "strdup" );
exit( LDAP_NO_MEMORY );
}
p = s + strlen( s ) - 1;
while ( p >= s && isspace( *p )) {
--p;
}
*++p = '\0';
return( s );
}