openldap/clients/tools/ldapmodify.c

1224 lines
30 KiB
C
Raw Normal View History

/* $OpenLDAP$ */
Vienna Bulk Commit This commit includes many changes. All changes compile under NT but have not been tested under UNIX. A Summary of changes (likely incomplete): NT changes: Removed lint. Clean up configuration support for "Debug", "Release", "SDebug", and "SRelease" configurations. Share output directories for clients, libraries, and slapd. (maybe they should be combined further and moved to build/{,S}{Debug,Release}). Enable threading when _MT is defined. Enable debuging when _DEBUG is defined. Disable setting of NDEBUG under Release/SRelease. Asserts are disabled in <ac/assert.h> when LDAP_DEBUG is not defined. Added 'build/main.dsp' Master project. Removed non-slapd projects from slapd.dsp (see main.dsp). Removed replaced many uses of _WIN32 macro with feature based macros. ldap_cdefs.h changes #define LDAP_CONST const (see below) #define LDAP_F(type) LDAP_F_PRE type LDAP_F_POST To allow specifiers to be added before and after the type declaration. (For DLL handling) LBER/LDAP changes Namespace changes: s/lber_/ber_/ for here and there. s/NAME_ERROR/LDAP_NAME_ERROR/g Deleted NULLMSG and other NULL* macros for namespace reasons. "const" libraries. Installed headers (ie: lber.h, ldap.h) use LDAP_CONST macro. Normally set to 'const' when __STDC__. Can be set externally to enable/disable 'constification' of external interface. Internal interface always uses 'const'. Did not fix warnings in -lldif (in lieu of new LDIF parser). Added _ext API implementations (excepting search and bind). Need to implement ldap_int_get_controls() for reponses with controls. Added numberous assert() checks. LDAP_R _MT defines HAVE_NT_THREADS Added numberous assert() checks. Changed ldap_pthread_t back to unsigned long. Used cast to HANDLE in _join(). LDBM Replaced _WIN32 with HAVE_SYSLOG ud Added version string if MKVERSION is not defined. (MKVERSION needs to be set under UNIX). slapd Made connection sockbuf field a pointer to a sockbuf. This removed slap.h dependency on lber-int.h. lber-int.h now only included by those files needing to mess with the sockbuf. Used ber_* functions/macros to access sockbuf internals whenever possible. Added version string if MKVERSION is not defined. (MKVERSION needs to be set under UNIX). Removed FD_SET unsigned lint slapd/tools Used EXEEXT to added ".exe" to routines. Need to define EXEEXT under UNIX. ldappasswd Added ldappasswd.dsp. Ported to NT. Used getpid() to seed rand(). nt_debug Minor cleanup. Added "portable.h" include and used <ac/*.h> where appropriate. Added const to char* format argument.
1999-05-19 09:12:33 +08:00
/*
2002-01-05 05:17:25 +08:00
* Copyright 1998-2002 The OpenLDAP Foundation, All Rights Reserved.
Vienna Bulk Commit This commit includes many changes. All changes compile under NT but have not been tested under UNIX. A Summary of changes (likely incomplete): NT changes: Removed lint. Clean up configuration support for "Debug", "Release", "SDebug", and "SRelease" configurations. Share output directories for clients, libraries, and slapd. (maybe they should be combined further and moved to build/{,S}{Debug,Release}). Enable threading when _MT is defined. Enable debuging when _DEBUG is defined. Disable setting of NDEBUG under Release/SRelease. Asserts are disabled in <ac/assert.h> when LDAP_DEBUG is not defined. Added 'build/main.dsp' Master project. Removed non-slapd projects from slapd.dsp (see main.dsp). Removed replaced many uses of _WIN32 macro with feature based macros. ldap_cdefs.h changes #define LDAP_CONST const (see below) #define LDAP_F(type) LDAP_F_PRE type LDAP_F_POST To allow specifiers to be added before and after the type declaration. (For DLL handling) LBER/LDAP changes Namespace changes: s/lber_/ber_/ for here and there. s/NAME_ERROR/LDAP_NAME_ERROR/g Deleted NULLMSG and other NULL* macros for namespace reasons. "const" libraries. Installed headers (ie: lber.h, ldap.h) use LDAP_CONST macro. Normally set to 'const' when __STDC__. Can be set externally to enable/disable 'constification' of external interface. Internal interface always uses 'const'. Did not fix warnings in -lldif (in lieu of new LDIF parser). Added _ext API implementations (excepting search and bind). Need to implement ldap_int_get_controls() for reponses with controls. Added numberous assert() checks. LDAP_R _MT defines HAVE_NT_THREADS Added numberous assert() checks. Changed ldap_pthread_t back to unsigned long. Used cast to HANDLE in _join(). LDBM Replaced _WIN32 with HAVE_SYSLOG ud Added version string if MKVERSION is not defined. (MKVERSION needs to be set under UNIX). slapd Made connection sockbuf field a pointer to a sockbuf. This removed slap.h dependency on lber-int.h. lber-int.h now only included by those files needing to mess with the sockbuf. Used ber_* functions/macros to access sockbuf internals whenever possible. Added version string if MKVERSION is not defined. (MKVERSION needs to be set under UNIX). Removed FD_SET unsigned lint slapd/tools Used EXEEXT to added ".exe" to routines. Need to define EXEEXT under UNIX. ldappasswd Added ldappasswd.dsp. Ported to NT. Used getpid() to seed rand(). nt_debug Minor cleanup. Added "portable.h" include and used <ac/*.h> where appropriate. Added const to char* format argument.
1999-05-19 09:12:33 +08:00
* COPYING RESTRICTIONS APPLY, see COPYRIGHT file
*/
1998-08-09 08:43:13 +08:00
/* ldapmodify.c - generic program to modify or add entries using LDAP */
1998-10-25 09:41:42 +08:00
#include "portable.h"
1998-08-09 08:43:13 +08:00
#include <stdio.h>
1999-06-03 08:37:44 +08:00
#include <ac/stdlib.h>
1998-10-25 09:41:42 +08:00
1998-11-15 14:54:30 +08:00
#include <ac/ctype.h>
1999-01-21 06:01:14 +08:00
#include <ac/signal.h>
1998-10-25 09:41:42 +08:00
#include <ac/string.h>
#include <ac/unistd.h>
#ifdef HAVE_SYS_STAT_H
1998-08-09 08:43:13 +08:00
#include <sys/stat.h>
#endif
1998-10-25 09:41:42 +08:00
#ifdef HAVE_SYS_FILE_H
1998-08-09 08:43:13 +08:00
#include <sys/file.h>
1998-10-25 09:41:42 +08:00
#endif
#ifdef HAVE_FCNTL_H
1998-08-09 08:43:13 +08:00
#include <fcntl.h>
1998-10-25 09:41:42 +08:00
#endif
1998-08-09 08:43:13 +08:00
#include <ldap.h>
#include "lutil_ldap.h"
#include "ldif.h"
#include "ldap_defaults.h"
2001-12-20 05:19:41 +08:00
#include "ldap_log.h"
1998-08-09 08:43:13 +08:00
static char *prog;
static char *binddn = NULL;
static struct berval passwd = { 0, NULL };
2000-08-25 13:31:29 +08:00
static char *ldapuri = NULL;
static char *ldaphost = NULL;
static int ldapport = 0;
#ifdef HAVE_CYRUS_SASL
static unsigned sasl_flags = LDAP_SASL_AUTOMATIC;
static char *sasl_realm = NULL;
static char *sasl_authc_id = NULL;
static char *sasl_authz_id = NULL;
static char *sasl_mech = NULL;
static char *sasl_secprops = NULL;
#endif
static int use_tls = 0;
static int ldapadd, not, verbose, contoper, force;
2000-08-25 13:31:29 +08:00
static LDAP *ld = NULL;
1998-08-09 08:43:13 +08:00
#define LDAPMOD_MAXLINE 4096
/* strings found in replog/LDIF entries (mostly lifted from slurpd/slurp.h) */
#define T_VERSION_STR "version"
1998-08-09 08:43:13 +08:00
#define T_REPLICA_STR "replica"
#define T_DN_STR "dn"
#define T_CHANGETYPESTR "changetype"
#define T_ADDCTSTR "add"
#define T_MODIFYCTSTR "modify"
#define T_DELETECTSTR "delete"
#define T_MODRDNCTSTR "modrdn"
#define T_MODDNCTSTR "moddn"
#define T_RENAMECTSTR "rename"
1998-08-09 08:43:13 +08:00
#define T_MODOPADDSTR "add"
#define T_MODOPREPLACESTR "replace"
#define T_MODOPDELETESTR "delete"
#define T_MODSEPSTR "-"
#define T_NEWRDNSTR "newrdn"
#define T_DELETEOLDRDNSTR "deleteoldrdn"
#define T_NEWSUPSTR "newsuperior"
1998-08-09 08:43:13 +08:00
static void usage LDAP_P(( const char *prog )) LDAP_GCCATTR((noreturn));
static int process_ldif_rec LDAP_P(( char *rbuf, int count ));
2000-06-30 03:35:51 +08:00
static void addmodifyop LDAP_P((
LDAPMod ***pmodsp, int modop,
const char *attr,
struct berval *value ));
static int domodify LDAP_P((
const char *dn,
LDAPMod **pmods,
int newentry ));
static int dodelete LDAP_P((
const char *dn ));
static int dorename LDAP_P((
const char *dn,
const char *newrdn,
const char *newsup,
int deleteoldrdn ));
1998-10-25 09:41:42 +08:00
static char *read_one_record LDAP_P(( FILE *fp ));
static void
usage( const char *prog )
{
1999-06-01 10:07:57 +08:00
fprintf( stderr,
"Add or modify entries from an LDAP server\n\n"
"usage: %s [options]\n"
" The list of desired operations are read from stdin or from the file\n"
" specified by \"-f file\".\n"
"Add or modify options:\n"
2000-07-18 05:54:20 +08:00
" -a add values (default%s)\n"
" -F force all changes records to be used\n"
"Common options:\n"
" -d level set LDAP debugging level to `level'\n"
" -D binddn bind DN\n"
" -f file read operations from `file'\n"
" -h host LDAP server\n"
2000-09-06 02:52:10 +08:00
" -H URI LDAP Uniform Resource Indentifier(s)\n"
2000-07-18 05:54:20 +08:00
" -I use SASL Interactive mode\n"
" -k use Kerberos authentication\n"
" -K like -k, but do only step 1 of the Kerberos bind\n"
" -M enable Manage DSA IT control (-MM to make critical)\n"
2002-02-06 16:43:32 +08:00
" -n show what would be done but don't actually modify\n"
2000-07-18 05:54:20 +08:00
" -O props SASL security properties\n"
" -p port port on LDAP server\n"
" -P version procotol version (default: 3)\n"
" -Q use SASL Quiet mode\n"
" -R realm SASL realm\n"
2001-01-18 16:04:56 +08:00
" -U authcid SASL authentication identity\n"
2000-07-18 05:54:20 +08:00
" -v run in verbose mode (diagnostics to standard output)\n"
" -w passwd bind passwd (for simple authentication)\n"
" -W prompt for bind passwd\n"
" -x Simple authentication\n"
2001-01-18 16:04:56 +08:00
" -X authzid SASL authorization identity (\"dn:<dn>\" or \"u:<user>\")\n"
2000-07-18 05:54:20 +08:00
" -Y mech SASL mechanism\n"
" -Z Start TLS request (-ZZ to require successful response)\n"
, prog, (strcmp( prog, "ldapadd" ) ? " is to replace" : "") );
exit( EXIT_FAILURE );
}
1998-11-04 21:15:18 +08:00
int
main( int argc, char **argv )
1998-08-09 08:43:13 +08:00
{
char *infile, *rbuf, *start;
FILE *fp;
int rc, i, authmethod, version, want_bindpw, debug, manageDSAit, referrals;
int count;
1998-08-09 08:43:13 +08:00
if (( prog = strrchr( argv[ 0 ], *LDAP_DIRSEP )) == NULL ) {
prog = argv[ 0 ];
} else {
++prog;
}
/* Print usage when no parameters */
if( argc < 2 ) usage( prog );
/* strncmp instead of strcmp since NT binaries carry .exe extension */
2001-12-20 13:27:55 +08:00
ldapadd = ( strncmp( prog, "ldapadd", sizeof("ldapadd")-1 ) == 0 );
1998-08-09 08:43:13 +08:00
infile = NULL;
not = verbose = want_bindpw = debug = manageDSAit = referrals = 0;
authmethod = -1;
1998-12-29 13:33:34 +08:00
version = -1;
1998-08-09 08:43:13 +08:00
2000-09-07 09:15:52 +08:00
while (( i = getopt( argc, argv, "acrf:F"
"Cd:D:h:H:IkKMnO:p:P:QR:U:vw:WxX:Y:Z" )) != EOF )
{
switch( i ) {
/* Modify Options */
1998-08-09 08:43:13 +08:00
case 'a': /* add */
ldapadd = 1;
1998-08-09 08:43:13 +08:00
break;
case 'c': /* continuous operation */
1998-08-09 08:43:13 +08:00
contoper = 1;
break;
case 'f': /* read from file */
if( infile != NULL ) {
fprintf( stderr, "%s: -f previously specified\n", prog );
return EXIT_FAILURE;
}
infile = strdup( optarg );
break;
case 'F': /* force all changes records to be used */
force = 1;
break;
/* Common Options */
case 'C':
referrals++;
break;
case 'd':
debug |= atoi( optarg );
break;
case 'D': /* bind DN */
if( binddn != NULL ) {
fprintf( stderr, "%s: -D previously specified\n", prog );
return EXIT_FAILURE;
}
binddn = strdup( optarg );
break;
case 'h': /* ldap host */
2000-08-25 13:31:29 +08:00
if( ldapuri != NULL ) {
fprintf( stderr, "%s: -h incompatible with -H\n", prog );
2000-08-25 13:31:29 +08:00
return EXIT_FAILURE;
}
if( ldaphost != NULL ) {
fprintf( stderr, "%s: -h previously specified\n", prog );
return EXIT_FAILURE;
}
ldaphost = strdup( optarg );
break;
2000-08-25 13:31:29 +08:00
case 'H': /* ldap URI */
if( ldaphost != NULL ) {
fprintf( stderr, "%s: -H incompatible with -h\n", prog );
2000-08-25 13:31:29 +08:00
return EXIT_FAILURE;
}
if( ldapport ) {
fprintf( stderr, "%s: -H incompatible with -p\n", prog );
2000-08-25 13:31:29 +08:00
return EXIT_FAILURE;
}
if( ldapuri != NULL ) {
fprintf( stderr, "%s: -H previously specified\n", prog );
2000-08-25 13:31:29 +08:00
return EXIT_FAILURE;
}
ldapuri = strdup( optarg );
break;
case 'I':
#ifdef HAVE_CYRUS_SASL
if( version == LDAP_VERSION2 ) {
fprintf( stderr, "%s: -I incompatible with version %d\n",
prog, version );
return EXIT_FAILURE;
}
if( authmethod != -1 && authmethod != LDAP_AUTH_SASL ) {
fprintf( stderr, "%s: incompatible previous "
"authentication choice\n",
prog );
return EXIT_FAILURE;
}
authmethod = LDAP_AUTH_SASL;
version = LDAP_VERSION3;
sasl_flags = LDAP_SASL_INTERACTIVE;
break;
#else
fprintf( stderr, "%s: was not compiled with SASL support\n",
prog );
return( EXIT_FAILURE );
#endif
case 'k': /* kerberos bind */
#ifdef LDAP_API_FEATURE_X_OPENLDAP_V2_KBIND
if( version > LDAP_VERSION2 ) {
fprintf( stderr, "%s: -k incompatible with LDAPv%d\n",
prog, version );
return EXIT_FAILURE;
}
if( authmethod != -1 ) {
fprintf( stderr, "%s: -k incompatible with previous "
"authentication choice\n", prog );
return EXIT_FAILURE;
}
1998-12-15 04:39:02 +08:00
authmethod = LDAP_AUTH_KRBV4;
#else
fprintf( stderr, "%s: not compiled with Kerberos support\n", prog );
return EXIT_FAILURE;
1998-12-15 04:39:02 +08:00
#endif
break;
case 'K': /* kerberos bind, part one only */
#ifdef LDAP_API_FEATURE_X_OPENLDAP_V2_KBIND
if( version > LDAP_VERSION2 ) {
fprintf( stderr, "%s: -k incompatible with LDAPv%d\n",
prog, version );
return EXIT_FAILURE;
}
if( authmethod != -1 ) {
fprintf( stderr, "%s: incompatible with previous "
"authentication choice\n", prog );
return EXIT_FAILURE;
}
1998-12-15 04:39:02 +08:00
authmethod = LDAP_AUTH_KRBV41;
#else
fprintf( stderr, "%s: not compiled with Kerberos support\n", prog );
return( EXIT_FAILURE );
1998-12-15 04:39:02 +08:00
#endif
break;
case 'M':
/* enable Manage DSA IT */
if( version == LDAP_VERSION2 ) {
fprintf( stderr, "%s: -M incompatible with LDAPv%d\n",
prog, version );
return EXIT_FAILURE;
}
manageDSAit++;
version = LDAP_VERSION3;
break;
case 'n': /* print deletes, don't actually do them */
++not;
break;
case 'O':
#ifdef HAVE_CYRUS_SASL
if( sasl_secprops != NULL ) {
fprintf( stderr, "%s: -O previously specified\n", prog );
return EXIT_FAILURE;
}
if( version == LDAP_VERSION2 ) {
fprintf( stderr, "%s: -O incompatible with LDAPv%d\n",
prog, version );
return EXIT_FAILURE;
}
if( authmethod != -1 && authmethod != LDAP_AUTH_SASL ) {
fprintf( stderr, "%s: incompatible previous "
"authentication choice\n", prog );
return EXIT_FAILURE;
}
authmethod = LDAP_AUTH_SASL;
version = LDAP_VERSION3;
sasl_secprops = strdup( optarg );
#else
fprintf( stderr, "%s: not compiled with SASL support\n",
prog );
return( EXIT_FAILURE );
#endif
break;
case 'p':
if( ldapport ) {
fprintf( stderr, "%s: -p previously specified\n", prog );
return EXIT_FAILURE;
}
ldapport = atoi( optarg );
break;
1998-12-27 22:08:46 +08:00
case 'P':
switch( atoi(optarg) ) {
case 2:
if( version == LDAP_VERSION3 ) {
fprintf( stderr, "%s: -P 2 incompatible with version %d\n",
prog, version );
return EXIT_FAILURE;
}
1998-12-27 22:08:46 +08:00
version = LDAP_VERSION2;
break;
case 3:
if( version == LDAP_VERSION2 ) {
fprintf( stderr, "%s: -P 2 incompatible with version %d\n",
prog, version );
return EXIT_FAILURE;
}
1998-12-27 22:08:46 +08:00
version = LDAP_VERSION3;
break;
default:
fprintf( stderr, "%s: protocol version should be 2 or 3\n",
prog );
usage( prog );
return( EXIT_FAILURE );
} break;
case 'Q':
#ifdef HAVE_CYRUS_SASL
if( version == LDAP_VERSION2 ) {
fprintf( stderr, "%s: -Q incompatible with version %d\n",
prog, version );
return EXIT_FAILURE;
}
if( authmethod != -1 && authmethod != LDAP_AUTH_SASL ) {
fprintf( stderr, "%s: incompatible previous "
"authentication choice\n",
prog );
return EXIT_FAILURE;
}
authmethod = LDAP_AUTH_SASL;
version = LDAP_VERSION3;
sasl_flags = LDAP_SASL_QUIET;
break;
#else
2000-07-18 05:54:20 +08:00
fprintf( stderr, "%s: not compiled with SASL support\n",
prog );
return( EXIT_FAILURE );
#endif
case 'r': /* replace (obsolete) */
break;
case 'R':
#ifdef HAVE_CYRUS_SASL
if( sasl_realm != NULL ) {
fprintf( stderr, "%s: -R previously specified\n", prog );
return EXIT_FAILURE;
}
if( version == LDAP_VERSION2 ) {
fprintf( stderr, "%s: -R incompatible with version %d\n",
prog, version );
return EXIT_FAILURE;
}
if( authmethod != -1 && authmethod != LDAP_AUTH_SASL ) {
fprintf( stderr, "%s: incompatible previous "
"authentication choice\n",
prog );
return EXIT_FAILURE;
}
authmethod = LDAP_AUTH_SASL;
version = LDAP_VERSION3;
sasl_realm = strdup( optarg );
#else
2000-07-18 05:54:20 +08:00
fprintf( stderr, "%s: not compiled with SASL support\n",
prog );
return( EXIT_FAILURE );
#endif
break;
case 'U':
#ifdef HAVE_CYRUS_SASL
if( sasl_authc_id != NULL ) {
fprintf( stderr, "%s: -U previously specified\n", prog );
return EXIT_FAILURE;
}
if( version == LDAP_VERSION2 ) {
fprintf( stderr, "%s: -U incompatible with version %d\n",
prog, version );
return EXIT_FAILURE;
}
if( authmethod != -1 && authmethod != LDAP_AUTH_SASL ) {
fprintf( stderr, "%s: incompatible previous "
"authentication choice\n",
prog );
return EXIT_FAILURE;
}
authmethod = LDAP_AUTH_SASL;
version = LDAP_VERSION3;
sasl_authc_id = strdup( optarg );
#else
2000-07-18 05:54:20 +08:00
fprintf( stderr, "%s: not compiled with SASL support\n",
prog );
return( EXIT_FAILURE );
#endif
break;
case 'v': /* verbose mode */
verbose++;
break;
case 'w': /* password */
passwd.bv_val = strdup( optarg );
{
char* p;
2000-11-06 23:53:02 +08:00
for( p = optarg; *p != '\0'; p++ ) {
*p = '\0';
}
}
passwd.bv_len = strlen( passwd.bv_val );
break;
case 'W':
want_bindpw++;
break;
case 'Y':
#ifdef HAVE_CYRUS_SASL
if( sasl_mech != NULL ) {
fprintf( stderr, "%s: -Y previously specified\n", prog );
return EXIT_FAILURE;
}
if( version == LDAP_VERSION2 ) {
fprintf( stderr, "%s: -Y incompatible with version %d\n",
prog, version );
return EXIT_FAILURE;
}
if( authmethod != -1 && authmethod != LDAP_AUTH_SASL ) {
fprintf( stderr, "%s: incompatible with authentication choice\n", prog );
return EXIT_FAILURE;
}
authmethod = LDAP_AUTH_SASL;
version = LDAP_VERSION3;
sasl_mech = strdup( optarg );
#else
2000-07-18 05:54:20 +08:00
fprintf( stderr, "%s: not compiled with SASL support\n",
prog );
return( EXIT_FAILURE );
#endif
break;
case 'x':
if( authmethod != -1 && authmethod != LDAP_AUTH_SIMPLE ) {
fprintf( stderr, "%s: incompatible with previous "
"authentication choice\n", prog );
return EXIT_FAILURE;
}
authmethod = LDAP_AUTH_SIMPLE;
break;
case 'X':
#ifdef HAVE_CYRUS_SASL
if( sasl_authz_id != NULL ) {
fprintf( stderr, "%s: -X previously specified\n", prog );
return EXIT_FAILURE;
}
if( version == LDAP_VERSION2 ) {
fprintf( stderr, "%s: -X incompatible with LDAPv%d\n",
prog, version );
return EXIT_FAILURE;
}
if( authmethod != -1 && authmethod != LDAP_AUTH_SASL ) {
fprintf( stderr, "%s: -X incompatible with "
"authentication choice\n", prog );
return EXIT_FAILURE;
}
authmethod = LDAP_AUTH_SASL;
version = LDAP_VERSION3;
sasl_authz_id = strdup( optarg );
#else
fprintf( stderr, "%s: not compiled with SASL support\n",
prog );
return( EXIT_FAILURE );
#endif
break;
case 'Z':
#ifdef HAVE_TLS
if( version == LDAP_VERSION2 ) {
2000-07-18 05:54:20 +08:00
fprintf( stderr, "%s: -Z incompatible with version %d\n",
prog, version );
return EXIT_FAILURE;
}
version = LDAP_VERSION3;
use_tls++;
#else
fprintf( stderr, "%s: not compiled with TLS support\n",
prog );
return( EXIT_FAILURE );
#endif
break;
default:
2000-09-20 04:47:22 +08:00
fprintf( stderr, "%s: unrecognized option -%c\n",
2000-07-16 08:14:08 +08:00
prog, optopt );
usage( prog );
1998-08-09 08:43:13 +08:00
}
}
if (version == -1) {
version = LDAP_VERSION3;
}
if (authmethod == -1 && version > LDAP_VERSION2) {
2000-07-16 07:34:27 +08:00
#ifdef HAVE_CYRUS_SASL
authmethod = LDAP_AUTH_SASL;
2000-07-16 07:34:27 +08:00
#else
authmethod = LDAP_AUTH_SIMPLE;
#endif
}
if ( argc != optind )
usage( prog );
1998-08-09 08:43:13 +08:00
if ( infile != NULL ) {
if (( fp = fopen( infile, "r" )) == NULL ) {
perror( infile );
return( EXIT_FAILURE );
1998-08-09 08:43:13 +08:00
}
} else {
fp = stdin;
}
if ( debug ) {
if( ber_set_option( NULL, LBER_OPT_DEBUG_LEVEL, &debug ) != LBER_OPT_SUCCESS ) {
fprintf( stderr, "Could not set LBER_OPT_DEBUG_LEVEL %d\n", debug );
}
if( ldap_set_option( NULL, LDAP_OPT_DEBUG_LEVEL, &debug ) != LDAP_OPT_SUCCESS ) {
fprintf( stderr, "Could not set LDAP_OPT_DEBUG_LEVEL %d\n", debug );
}
ldif_debug = debug;
}
1998-08-09 08:43:13 +08:00
1999-01-21 06:01:14 +08:00
#ifdef SIGPIPE
(void) SIGNAL( SIGPIPE, SIG_IGN );
#endif
#ifdef NEW_LOGGING
lutil_log_initialize( argc, argv );
#endif
1999-01-21 06:01:14 +08:00
1998-08-09 08:43:13 +08:00
if ( !not ) {
2000-08-25 13:31:29 +08:00
if( ( ldaphost != NULL || ldapport ) && ( ldapuri == NULL ) ) {
if ( verbose ) {
fprintf( stderr, "ldap_init( %s, %d )\n",
ldaphost != NULL ? ldaphost : "<DEFAULT>",
ldapport );
}
2000-08-25 13:31:29 +08:00
ld = ldap_init( ldaphost, ldapport );
if( ld == NULL ) {
perror("ldapsearch: ldap_init");
return EXIT_FAILURE;
}
2000-08-25 13:31:29 +08:00
} else {
if ( verbose ) {
fprintf( stderr, "ldap_initialize( %s )\n",
ldapuri != NULL ? ldapuri : "<DEFAULT>" );
}
rc = ldap_initialize( &ld, ldapuri );
if( rc != LDAP_SUCCESS ) {
fprintf( stderr, "Could not create LDAP session handle (%d): %s\n",
rc, ldap_err2string(rc) );
return EXIT_FAILURE;
}
1998-08-09 08:43:13 +08:00
}
/* referrals */
if( ldap_set_option( ld, LDAP_OPT_REFERRALS,
referrals ? LDAP_OPT_ON : LDAP_OPT_OFF ) != LDAP_OPT_SUCCESS )
{
fprintf( stderr, "Could not set LDAP_OPT_REFERRALS %s\n",
referrals ? "on" : "off" );
return EXIT_FAILURE;
}
1998-08-09 08:43:13 +08:00
if (version == -1 ) {
2000-10-14 02:30:24 +08:00
version = LDAP_VERSION3;
}
if( ldap_set_option( ld, LDAP_OPT_PROTOCOL_VERSION, &version )
!= LDAP_OPT_SUCCESS )
{
fprintf( stderr, "Could not set LDAP_OPT_PROTOCOL_VERSION %d\n",
version );
2000-06-26 02:17:47 +08:00
return EXIT_FAILURE;
1998-12-29 13:33:34 +08:00
}
1998-12-27 22:08:46 +08:00
2001-08-28 08:35:34 +08:00
if ( use_tls && ( ldap_start_tls_s( ld, NULL, NULL ) != LDAP_SUCCESS )) {
2001-01-16 12:32:13 +08:00
ldap_perror( ld, "ldap_start_tls" );
if ( use_tls > 1 ) {
return( EXIT_FAILURE );
}
}
2000-06-14 11:07:33 +08:00
if (want_bindpw) {
passwd.bv_val = getpassphrase("Enter LDAP Password: ");
passwd.bv_len = passwd.bv_val ? strlen( passwd.bv_val ) : 0;
2000-06-14 11:07:33 +08:00
}
if ( authmethod == LDAP_AUTH_SASL ) {
#ifdef HAVE_CYRUS_SASL
void *defaults;
if( sasl_secprops != NULL ) {
rc = ldap_set_option( ld, LDAP_OPT_X_SASL_SECPROPS,
(void *) sasl_secprops );
if( rc != LDAP_OPT_SUCCESS ) {
fprintf( stderr,
"Could not set LDAP_OPT_X_SASL_SECPROPS: %s\n",
sasl_secprops );
return( EXIT_FAILURE );
}
}
defaults = lutil_sasl_defaults( ld,
sasl_mech,
sasl_realm,
sasl_authc_id,
passwd.bv_val,
sasl_authz_id );
rc = ldap_sasl_interactive_bind_s( ld, binddn,
sasl_mech, NULL, NULL,
sasl_flags, lutil_sasl_interact, defaults );
2000-05-16 10:16:54 +08:00
if( rc != LDAP_SUCCESS ) {
ldap_perror( ld, "ldap_sasl_interactive_bind_s" );
return( EXIT_FAILURE );
}
#else
2000-07-18 05:54:20 +08:00
fprintf( stderr, "%s: not compiled with SASL support\n",
prog );
return( EXIT_FAILURE );
#endif
1998-08-09 08:43:13 +08:00
}
else {
2000-05-16 10:16:54 +08:00
if ( ldap_bind_s( ld, binddn, passwd.bv_val, authmethod )
!= LDAP_SUCCESS ) {
ldap_perror( ld, "ldap_bind" );
return( EXIT_FAILURE );
}
}
1998-08-09 08:43:13 +08:00
}
rc = 0;
if ( manageDSAit ) {
int err;
LDAPControl c;
LDAPControl *ctrls[2];
ctrls[0] = &c;
ctrls[1] = NULL;
c.ldctl_oid = LDAP_CONTROL_MANAGEDSAIT;
c.ldctl_value.bv_val = NULL;
c.ldctl_value.bv_len = 0;
c.ldctl_iscritical = manageDSAit > 1;
2000-08-24 06:49:44 +08:00
err = ldap_set_option( ld, LDAP_OPT_SERVER_CONTROLS, ctrls );
if( err != LDAP_OPT_SUCCESS ) {
fprintf( stderr, "Could not set ManageDSAit %scontrol\n",
c.ldctl_iscritical ? "critical " : "" );
if( c.ldctl_iscritical ) {
exit( EXIT_FAILURE );
}
}
}
count = 0;
1998-08-09 08:43:13 +08:00
while (( rc == 0 || contoper ) &&
( rbuf = read_one_record( fp )) != NULL ) {
count++;
1998-08-09 08:43:13 +08:00
start = rbuf;
rc = process_ldif_rec( start, count );
1998-08-09 08:43:13 +08:00
if( rc )
fprintf( stderr, "ldif_record() = %d\n", rc );
free( rbuf );
1998-08-09 08:43:13 +08:00
}
if ( !not ) {
ldap_unbind( ld );
1998-08-09 08:43:13 +08:00
}
return( rc );
1998-08-09 08:43:13 +08:00
}
static int
process_ldif_rec( char *rbuf, int count )
1998-08-09 08:43:13 +08:00
{
2000-06-30 03:35:51 +08:00
char *line, *dn, *type, *newrdn, *newsup, *p;
int rc, linenum, modop, replicaport;
int expect_modop, expect_sep, expect_ct, expect_newrdn, expect_newsup;
1998-08-09 08:43:13 +08:00
int expect_deleteoldrdn, deleteoldrdn;
int saw_replica, use_record, new_entry, delete_entry, got_all;
LDAPMod **pmods;
int version;
2000-06-30 03:35:51 +08:00
struct berval val;
1998-08-09 08:43:13 +08:00
new_entry = ldapadd;
1998-08-09 08:43:13 +08:00
rc = got_all = saw_replica = delete_entry = modop = expect_modop = 0;
expect_deleteoldrdn = expect_newrdn = expect_newsup = 0;
expect_sep = expect_ct = 0;
1998-08-09 08:43:13 +08:00
linenum = 0;
version = 0;
1998-08-09 08:43:13 +08:00
deleteoldrdn = 1;
use_record = force;
pmods = NULL;
dn = newrdn = newsup = NULL;
1998-08-09 08:43:13 +08:00
while ( rc == 0 && ( line = ldif_getline( &rbuf )) != NULL ) {
1998-08-09 08:43:13 +08:00
++linenum;
1998-08-09 08:43:13 +08:00
if ( expect_sep && strcasecmp( line, T_MODSEPSTR ) == 0 ) {
expect_sep = 0;
expect_ct = 1;
continue;
}
2000-06-30 03:35:51 +08:00
if ( ldif_parse_line( line, &type, &val.bv_val, &val.bv_len ) < 0 ) {
fprintf( stderr, "%s: invalid format (line %d) entry: \"%s\"\n",
1998-08-09 08:43:13 +08:00
prog, linenum, dn == NULL ? "" : dn );
rc = LDAP_PARAM_ERROR;
break;
}
if ( dn == NULL ) {
if ( !use_record && strcasecmp( type, T_REPLICA_STR ) == 0 ) {
++saw_replica;
2000-06-30 03:35:51 +08:00
if (( p = strchr( val.bv_val, ':' )) == NULL ) {
replicaport = 0;
1998-08-09 08:43:13 +08:00
} else {
*p++ = '\0';
replicaport = atoi( p );
}
2000-06-30 03:35:51 +08:00
if ( ldaphost != NULL && strcasecmp( val.bv_val, ldaphost ) == 0 &&
1998-08-09 08:43:13 +08:00
replicaport == ldapport ) {
use_record = 1;
}
} else if ( count == 1 && linenum == 1 &&
strcasecmp( type, T_VERSION_STR ) == 0 )
{
2000-06-30 03:35:51 +08:00
if( val.bv_len == 0 || atoi(val.bv_val) != 1 ) {
fprintf( stderr, "%s: invalid version %s, line %d (ignored)\n",
2000-06-30 03:35:51 +08:00
prog, val.bv_val == NULL ? "(null)" : val.bv_val, linenum );
}
version++;
1998-08-09 08:43:13 +08:00
} else if ( strcasecmp( type, T_DN_STR ) == 0 ) {
2000-06-30 03:35:51 +08:00
if (( dn = strdup( val.bv_val ? val.bv_val : "" )) == NULL ) {
1998-08-09 08:43:13 +08:00
perror( "strdup" );
exit( EXIT_FAILURE );
1998-08-09 08:43:13 +08:00
}
expect_ct = 1;
}
1999-08-20 08:55:22 +08:00
goto end_line; /* skip all lines until we see "dn:" */
1998-08-09 08:43:13 +08:00
}
if ( expect_ct ) {
expect_ct = 0;
if ( !use_record && saw_replica ) {
printf( "%s: skipping change record for entry: %s\n"
"\t(LDAP host/port does not match replica: lines)\n",
1998-08-09 08:43:13 +08:00
prog, dn );
free( dn );
1999-08-20 08:55:22 +08:00
ber_memfree( type );
2000-06-30 03:35:51 +08:00
ber_memfree( val.bv_val );
1998-08-09 08:43:13 +08:00
return( 0 );
}
if ( strcasecmp( type, T_CHANGETYPESTR ) == 0 ) {
#ifdef LIBERAL_CHANGETYPE_MODOP
/* trim trailing spaces (and log warning ...) */
int icnt;
for ( icnt = val.bv_len; --icnt > 0; ) {
if ( !isspace( val.bv_val[icnt] ) ) {
break;
}
}
if ( ++icnt != val.bv_len ) {
fprintf( stderr, "%s: illegal trailing space after \"%s: %s\" trimmed (line %d of entry \"%s\")\n",
prog, T_CHANGETYPESTR, val.bv_val, linenum, dn );
val.bv_val[icnt] = '\0';
}
#endif /* LIBERAL_CHANGETYPE_MODOP */
2000-06-30 03:35:51 +08:00
if ( strcasecmp( val.bv_val, T_MODIFYCTSTR ) == 0 ) {
1998-08-09 08:43:13 +08:00
new_entry = 0;
expect_modop = 1;
2000-06-30 03:35:51 +08:00
} else if ( strcasecmp( val.bv_val, T_ADDCTSTR ) == 0 ) {
1998-08-09 08:43:13 +08:00
new_entry = 1;
2000-06-30 03:35:51 +08:00
} else if ( strcasecmp( val.bv_val, T_MODRDNCTSTR ) == 0
|| strcasecmp( val.bv_val, T_MODDNCTSTR ) == 0
|| strcasecmp( val.bv_val, T_RENAMECTSTR ) == 0)
{
1998-08-09 08:43:13 +08:00
expect_newrdn = 1;
2000-06-30 03:35:51 +08:00
} else if ( strcasecmp( val.bv_val, T_DELETECTSTR ) == 0 ) {
1998-08-09 08:43:13 +08:00
got_all = delete_entry = 1;
} else {
fprintf( stderr,
"%s: unknown %s \"%s\" (line %d of entry \"%s\")\n",
2000-06-30 03:35:51 +08:00
prog, T_CHANGETYPESTR, val.bv_val, linenum, dn );
1998-08-09 08:43:13 +08:00
rc = LDAP_PARAM_ERROR;
}
1999-08-20 08:55:22 +08:00
goto end_line;
} else if ( ldapadd ) { /* missing changetype => add */
1998-08-09 08:43:13 +08:00
new_entry = 1;
modop = LDAP_MOD_ADD;
} else {
expect_modop = 1; /* missing changetype => modify */
}
}
if ( expect_modop ) {
#ifdef LIBERAL_CHANGETYPE_MODOP
/* trim trailing spaces (and log warning ...) */
int icnt;
for ( icnt = val.bv_len; --icnt > 0; ) {
if ( !isspace( val.bv_val[icnt] ) ) {
break;
}
}
if ( ++icnt != val.bv_len ) {
fprintf( stderr, "%s: illegal trailing space after \"%s: %s\" trimmed (line %d of entry \"%s\")\n",
prog, type, val.bv_val, linenum, dn );
val.bv_val[icnt] = '\0';
}
#endif /* LIBERAL_CHANGETYPE_MODOP */
1998-08-09 08:43:13 +08:00
expect_modop = 0;
expect_sep = 1;
if ( strcasecmp( type, T_MODOPADDSTR ) == 0 ) {
modop = LDAP_MOD_ADD;
1999-08-20 08:55:22 +08:00
goto end_line;
1998-08-09 08:43:13 +08:00
} else if ( strcasecmp( type, T_MODOPREPLACESTR ) == 0 ) {
modop = LDAP_MOD_REPLACE;
2000-06-30 03:35:51 +08:00
addmodifyop( &pmods, modop, val.bv_val, NULL );
1999-08-20 08:55:22 +08:00
goto end_line;
1998-08-09 08:43:13 +08:00
} else if ( strcasecmp( type, T_MODOPDELETESTR ) == 0 ) {
modop = LDAP_MOD_DELETE;
2000-06-30 03:35:51 +08:00
addmodifyop( &pmods, modop, val.bv_val, NULL );
1999-08-20 08:55:22 +08:00
goto end_line;
1998-08-09 08:43:13 +08:00
} else { /* no modify op: use default */
modop = ldapadd ? LDAP_MOD_ADD : LDAP_MOD_REPLACE;
1998-08-09 08:43:13 +08:00
}
}
if ( expect_newrdn ) {
if ( strcasecmp( type, T_NEWRDNSTR ) == 0 ) {
2000-06-30 03:35:51 +08:00
if (( newrdn = strdup( val.bv_val ? val.bv_val : "" )) == NULL ) {
1998-08-09 08:43:13 +08:00
perror( "strdup" );
exit( EXIT_FAILURE );
1998-08-09 08:43:13 +08:00
}
expect_deleteoldrdn = 1;
expect_newrdn = 0;
} else {
fprintf( stderr, "%s: expecting \"%s:\" but saw \"%s:\" (line %d of entry \"%s\")\n",
1998-08-09 08:43:13 +08:00
prog, T_NEWRDNSTR, type, linenum, dn );
rc = LDAP_PARAM_ERROR;
}
} else if ( expect_deleteoldrdn ) {
if ( strcasecmp( type, T_DELETEOLDRDNSTR ) == 0 ) {
2000-06-30 03:35:51 +08:00
deleteoldrdn = ( *val.bv_val == '0' ) ? 0 : 1;
expect_deleteoldrdn = 0;
expect_newsup = 1;
1998-08-09 08:43:13 +08:00
got_all = 1;
} else {
fprintf( stderr, "%s: expecting \"%s:\" but saw \"%s:\" (line %d of entry \"%s\")\n",
1998-08-09 08:43:13 +08:00
prog, T_DELETEOLDRDNSTR, type, linenum, dn );
rc = LDAP_PARAM_ERROR;
}
} else if ( expect_newsup ) {
if ( strcasecmp( type, T_NEWSUPSTR ) == 0 ) {
2000-06-30 03:35:51 +08:00
if (( newsup = strdup( val.bv_val ? val.bv_val : "" )) == NULL ) {
perror( "strdup" );
exit( EXIT_FAILURE );
}
expect_newsup = 0;
} else {
fprintf( stderr, "%s: expecting \"%s:\" but saw \"%s:\" (line %d of entry \"%s\")\n",
prog, T_NEWSUPSTR, type, linenum, dn );
rc = LDAP_PARAM_ERROR;
}
1998-08-09 08:43:13 +08:00
} else if ( got_all ) {
fprintf( stderr,
"%s: extra lines at end (line %d of entry \"%s\")\n",
1998-08-09 08:43:13 +08:00
prog, linenum, dn );
rc = LDAP_PARAM_ERROR;
} else {
2000-06-30 03:35:51 +08:00
addmodifyop( &pmods, modop, type, val.bv_val == NULL ? NULL : &val );
1998-08-09 08:43:13 +08:00
}
1999-08-20 08:55:22 +08:00
end_line:
ber_memfree( type );
2000-06-30 03:35:51 +08:00
ber_memfree( val.bv_val );
1998-08-09 08:43:13 +08:00
}
if( linenum == 0 ) {
return 0;
}
if( version && linenum == 1 ) {
return 0;
}
1998-08-09 08:43:13 +08:00
if ( rc == 0 ) {
if ( delete_entry ) {
rc = dodelete( dn );
} else if ( newrdn != NULL ) {
2000-06-30 03:35:51 +08:00
rc = dorename( dn, newrdn, newsup, deleteoldrdn );
1998-08-09 08:43:13 +08:00
} else {
rc = domodify( dn, pmods, new_entry );
}
if ( rc == LDAP_SUCCESS ) {
rc = 0;
}
}
if ( dn != NULL ) {
free( dn );
}
if ( newrdn != NULL ) {
free( newrdn );
}
if ( pmods != NULL ) {
ldap_mods_free( pmods, 1 );
1998-08-09 08:43:13 +08:00
}
return( rc );
}
static void
2000-06-30 03:35:51 +08:00
addmodifyop(
LDAPMod ***pmodsp,
int modop,
const char *attr,
struct berval *val )
1998-08-09 08:43:13 +08:00
{
LDAPMod **pmods;
int i, j;
pmods = *pmodsp;
modop |= LDAP_MOD_BVALUES;
i = 0;
if ( pmods != NULL ) {
for ( ; pmods[ i ] != NULL; ++i ) {
if ( strcasecmp( pmods[ i ]->mod_type, attr ) == 0 &&
pmods[ i ]->mod_op == modop )
{
break;
}
}
1998-08-09 08:43:13 +08:00
}
if ( pmods == NULL || pmods[ i ] == NULL ) {
if (( pmods = (LDAPMod **)ber_memrealloc( pmods, (i + 2) *
sizeof( LDAPMod * ))) == NULL )
{
perror( "realloc" );
exit( EXIT_FAILURE );
1998-08-09 08:43:13 +08:00
}
*pmodsp = pmods;
pmods[ i + 1 ] = NULL;
1998-08-09 08:43:13 +08:00
pmods[ i ] = (LDAPMod *)ber_memcalloc( 1, sizeof( LDAPMod ));
if ( pmods[ i ] == NULL ) {
perror( "calloc" );
exit( EXIT_FAILURE );
1998-08-09 08:43:13 +08:00
}
pmods[ i ]->mod_op = modop;
pmods[ i ]->mod_type = ber_strdup( attr );
if ( pmods[ i ]->mod_type == NULL ) {
perror( "strdup" );
exit( EXIT_FAILURE );
}
1998-08-09 08:43:13 +08:00
}
2000-06-30 03:35:51 +08:00
if ( val != NULL ) {
j = 0;
if ( pmods[ i ]->mod_bvalues != NULL ) {
for ( ; pmods[ i ]->mod_bvalues[ j ] != NULL; ++j ) {
/* Empty */;
}
}
1998-08-09 08:43:13 +08:00
pmods[ i ]->mod_bvalues = (struct berval **) ber_memrealloc(
pmods[ i ]->mod_bvalues, (j + 2) * sizeof( struct berval * ));
if ( pmods[ i ]->mod_bvalues == NULL ) {
perror( "ber_realloc" );
exit( EXIT_FAILURE );
}
1998-08-09 08:43:13 +08:00
pmods[ i ]->mod_bvalues[ j + 1 ] = NULL;
2000-06-30 03:35:51 +08:00
pmods[ i ]->mod_bvalues[ j ] = ber_bvdup( val );
if ( pmods[ i ]->mod_bvalues[ j ] == NULL ) {
perror( "ber_bvdup" );
exit( EXIT_FAILURE );
}
1998-08-09 08:43:13 +08:00
}
}
static int
2000-06-30 03:35:51 +08:00
domodify(
const char *dn,
LDAPMod **pmods,
int newentry )
1998-08-09 08:43:13 +08:00
{
int i, j, k, notascii, op;
struct berval *bvp;
if ( pmods == NULL ) {
fprintf( stderr, "%s: no attributes to change or add (entry=\"%s\")\n",
1998-08-09 08:43:13 +08:00
prog, dn );
return( LDAP_PARAM_ERROR );
2000-10-04 06:05:28 +08:00
}
for ( i = 0; pmods[ i ] != NULL; ++i ) {
op = pmods[ i ]->mod_op & ~LDAP_MOD_BVALUES;
if( op == LDAP_MOD_ADD && ( pmods[i]->mod_bvalues == NULL )) {
fprintf( stderr,
"%s: attribute \"%s\" has no values (entry=\"%s\")\n",
prog, pmods[i]->mod_type, dn );
return LDAP_PARAM_ERROR;
}
1998-08-09 08:43:13 +08:00
}
if ( verbose ) {
for ( i = 0; pmods[ i ] != NULL; ++i ) {
op = pmods[ i ]->mod_op & ~LDAP_MOD_BVALUES;
printf( "%s %s:\n", op == LDAP_MOD_REPLACE ?
"replace" : op == LDAP_MOD_ADD ?
"add" : "delete", pmods[ i ]->mod_type );
if ( pmods[ i ]->mod_bvalues != NULL ) {
for ( j = 0; pmods[ i ]->mod_bvalues[ j ] != NULL; ++j ) {
bvp = pmods[ i ]->mod_bvalues[ j ];
notascii = 0;
1998-10-25 09:41:42 +08:00
for ( k = 0; (unsigned long) k < bvp->bv_len; ++k ) {
1998-08-09 08:43:13 +08:00
if ( !isascii( bvp->bv_val[ k ] )) {
notascii = 1;
break;
}
}
if ( notascii ) {
printf( "\tNOT ASCII (%ld bytes)\n", bvp->bv_len );
} else {
printf( "\t%s\n", bvp->bv_val );
}
}
}
}
}
if ( newentry ) {
printf( "%sadding new entry \"%s\"\n", not ? "!" : "", dn );
1998-08-09 08:43:13 +08:00
} else {
printf( "%smodifying entry \"%s\"\n", not ? "!" : "", dn );
1998-08-09 08:43:13 +08:00
}
if ( !not ) {
if ( newentry ) {
i = ldap_add_s( ld, dn, pmods );
} else {
i = ldap_modify_s( ld, dn, pmods );
}
if ( i != LDAP_SUCCESS ) {
/* print error message about failed update including DN */
fprintf( stderr, "%s: update failed: %s\n", prog, dn );
ldap_perror( ld, newentry ? "ldap_add" : "ldap_modify" );
1998-08-09 08:43:13 +08:00
} else if ( verbose ) {
printf( "modify complete\n" );
}
} else {
i = LDAP_SUCCESS;
}
putchar( '\n' );
return( i );
}
static int
2000-06-30 03:35:51 +08:00
dodelete(
const char *dn )
1998-08-09 08:43:13 +08:00
{
int rc;
printf( "%sdeleting entry \"%s\"\n", not ? "!" : "", dn );
1998-08-09 08:43:13 +08:00
if ( !not ) {
if (( rc = ldap_delete_s( ld, dn )) != LDAP_SUCCESS ) {
fprintf( stderr, "%s: delete failed: %s\n", prog, dn );
ldap_perror( ld, "ldap_delete" );
1998-08-09 08:43:13 +08:00
} else if ( verbose ) {
printf( "delete complete" );
}
} else {
rc = LDAP_SUCCESS;
}
putchar( '\n' );
return( rc );
}
static int
2000-06-30 03:35:51 +08:00
dorename(
const char *dn,
const char *newrdn,
const char* newsup,
int deleteoldrdn )
1998-08-09 08:43:13 +08:00
{
int rc;
printf( "%smodifying rdn of entry \"%s\"\n", not ? "!" : "", dn );
1998-08-09 08:43:13 +08:00
if ( verbose ) {
printf( "\tnew RDN: \"%s\" (%skeep existing values)\n",
1998-08-09 08:43:13 +08:00
newrdn, deleteoldrdn ? "do not " : "" );
}
if ( !not ) {
2000-06-30 03:35:51 +08:00
if (( rc = ldap_rename2_s( ld, dn, newrdn, newsup, deleteoldrdn ))
!= LDAP_SUCCESS )
{
fprintf( stderr, "%s: rename failed: %s\n", prog, dn );
ldap_perror( ld, "ldap_modrdn" );
1998-08-09 08:43:13 +08:00
} else {
printf( "modrdn completed\n" );
}
} else {
rc = LDAP_SUCCESS;
}
putchar( '\n' );
return( rc );
}
static char *
read_one_record( FILE *fp )
{
char *buf, line[ LDAPMOD_MAXLINE ];
int lcur, lmax;
lcur = lmax = 0;
buf = NULL;
while ( fgets( line, sizeof(line), fp ) != NULL ) {
int len = strlen( line );
2001-09-26 02:48:48 +08:00
if( len < 2 || ( len == 3 && *line == '\r' )) {
if( buf == NULL ) {
continue;
} else {
break;
}
}
if ( lcur + len + 1 > lmax ) {
lmax = LDAPMOD_MAXLINE
* (( lcur + len + 1 ) / LDAPMOD_MAXLINE + 1 );
if (( buf = (char *)realloc( buf, lmax )) == NULL ) {
perror( "realloc" );
exit( EXIT_FAILURE );
}
}
strcpy( buf + lcur, line );
lcur += len;
1998-08-09 08:43:13 +08:00
}
return( buf );
}