]> git.sur5r.net Git - openldap/blobdiff - clients/tools/ldapmodify.c
Allow arbitrary exop data to be base64 encoded
[openldap] / clients / tools / ldapmodify.c
index 25dfcdf2df5ee8bf577bb4af0d074d44697a6459..0a6ccb14b990179697d33f606215d44c970957a9 100644 (file)
@@ -2,7 +2,7 @@
 /* $OpenLDAP$ */
 /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
  *
- * Copyright 1998-2004 The OpenLDAP Foundation.
+ * Copyright 1998-2006 The OpenLDAP Foundation.
  * Portions Copyright 1998-2003 Kurt D. Zeilenga.
  * Portions Copyright 1998-2001 Net Boolean Incorporated.
  * Portions Copyright 2001-2003 IBM Corporation.
@@ -42,6 +42,7 @@
 #include <ac/ctype.h>
 #include <ac/string.h>
 #include <ac/unistd.h>
+#include <ac/time.h>
 
 #ifdef HAVE_SYS_STAT_H
 #include <sys/stat.h>
@@ -117,7 +118,7 @@ static int dorename LDAP_P((
 static int process_response(
        LDAP *ld,
        int msgid,
-       const char *opstr,
+       int res,
        const char *dn );
 static char *read_one_record LDAP_P(( FILE *fp ));
 
@@ -241,21 +242,25 @@ int
 main( int argc, char **argv )
 {
 #ifdef LDAP_GROUP_TRANSACTION
-       BerElement *txnber;
-       struct berval txnCookie = { 0, NULL };
+       BerElement      *txnber;
+       struct berval   txnCookie = { 0, NULL };
 #endif
        char            *rbuf, *start, *rejbuf = NULL;
        FILE            *fp, *rejfp;
        char            *matched_msg, *error_msg;
        int             rc, retval;
-       int count, len;
+       int             count, len;
+       int             i = 0;
+       LDAPControl     c[1];
+
 
-       tool_init();
        prog = lutil_progname( "ldapmodify", argc, argv );
 
        /* strncmp instead of strcmp since NT binaries carry .exe extension */
        ldapadd = ( strncasecmp( prog, "ldapadd", sizeof("ldapadd")-1 ) == 0 );
 
+       tool_init( ldapadd ? TOOL_ADD : TOOL_MODIFY );
+
        tool_args( argc, argv );
 
        if ( argc != optind ) usage();
@@ -280,9 +285,9 @@ main( int argc, char **argv )
 
        if ( debug ) ldif_debug = debug;
 
-       ld = tool_conn_setup( not, 0 );
+       ld = tool_conn_setup( dont, 0 );
 
-       if ( !not ) {
+       if ( !dont ) {
                if ( pw_file || want_bindpw ) {
                        if ( pw_file ) {
                                rc = lutil_get_filed_password( pw_file, &passwd );
@@ -302,25 +307,22 @@ main( int argc, char **argv )
                /* create transaction */
                rc = ldap_txn_create_s( ld, &txnCookiep, NULL, NULL );
                if( rc != LDAP_SUCCESS ) {
-                       ldap_perror( ld, "ldap_txn_create_s" );
+                       tool_perror( "ldap_txn_create_s", rc, NULL, NULL, NULL, NULL );
                        if( txn > 2 ) return EXIT_FAILURE;
                        txn = 0;
                }
        }
 #endif
 
-       if ( assertion || authzid || manageDSAit || noop || preread || postread
+       if ( 0
 #ifdef LDAP_GROUP_TRANSACTION
                || txn
 #endif
                )
        {
-               int err;
-               int i;
-               LDAPControl c[1];
-
 #ifdef LDAP_GROUP_TRANSACTION
                if( txn ) {
+                       int err;
                        txnber = ber_alloc_t( LBER_USE_DER );
                        if( txnber == NULL ) return EXIT_FAILURE;
 
@@ -339,10 +341,10 @@ main( int argc, char **argv )
                        i++;
                }
 #endif
-
-               tool_server_controls( ld, c, i );
        }
 
+       tool_server_controls( ld, c, i );
+
        rc = 0;
        count = 0;
        retval = 0;
@@ -397,21 +399,22 @@ main( int argc, char **argv )
                /* create transaction */
                rc = ldap_txn_end_s( ld, &txnCookie, !txnabort, NULL, NULL );
                if( rc != LDAP_SUCCESS ) {
-                       ldap_perror( ld, "ldap_txn_create_s" );
+                       tool_perror( "ldap_txn_create_s", rc, NULL, NULL, NULL, NULL );
                        if( txn > 2 ) return EXIT_FAILURE;
                        txn = 0;
                }
        }
 #endif
 
-       if ( !not ) {
-               ldap_unbind_ext( ld, NULL, NULL );
+       if ( !dont ) {
+               tool_unbind( ld );
        }
 
        if ( rejfp != NULL ) {
                fclose( rejfp );
        }
 
+       tool_destroy();
        return( retval );
 }
 
@@ -465,7 +468,12 @@ process_ldif_rec( char *rbuf, int count )
                                        replicaport = 0;
                                } else {
                                        *p++ = '\0';
-                                       replicaport = atoi( p );
+                                       if ( lutil_atoi( &replicaport, p ) != 0 ) {
+                                               fprintf( stderr, _("%s: unable to parse replica port \"%s\" (line %d) entry: \"%s\"\n"),
+                                                       prog, p, linenum, dn == NULL ? "" : dn );
+                                               rc = LDAP_PARAM_ERROR;
+                                               break;
+                                       }
                                }
                                if ( ldaphost != NULL &&
                                        strcasecmp( val.bv_val, ldaphost ) == 0 &&
@@ -473,10 +481,11 @@ process_ldif_rec( char *rbuf, int count )
                                {
                                        use_record = 1;
                                }
-               } else if ( count == 1 && linenum == 1 && 
+                       } else if ( count == 1 && linenum == 1 && 
                                strcasecmp( type, T_VERSION_STR ) == 0 )
                        {
-                               if( val.bv_len == 0 || atoi(val.bv_val) != 1 ) {
+                               int     v;
+                               if( val.bv_len == 0 || lutil_atoi( &v, val.bv_val) != 0 || v != 1 ) {
                                        fprintf( stderr,
                                                _("%s: invalid version %s, line %d (ignored)\n"),
                                                prog, val.bv_val, linenum );
@@ -645,6 +654,12 @@ process_ldif_rec( char *rbuf, int count )
                                prog, linenum, dn );
                        rc = LDAP_PARAM_ERROR;
                } else {
+                       if ( new_entry && strcasecmp( type, T_DN_STR ) == 0 ) {
+                               fprintf( stderr, _("%s: attributeDescription \"%s\":"
+                                       " (possible missing newline"
+                                               " after line %d of entry \"%s\"?)\n"),
+                                       prog, type, linenum - 1, dn );
+                       }
                        addmodifyop( &pmods, modop, type, &val );
                }
 
@@ -718,6 +733,9 @@ end_line:
        if ( newrdn != NULL ) {
                free( newrdn );
        }
+       if ( newsup != NULL ) {
+               free( newsup );
+       }
        if ( pmods != NULL ) {
                ldap_mods_free( pmods, 1 );
        }
@@ -955,47 +973,51 @@ domodify(
        }
 
        if ( pmods == NULL ) {
-               fprintf( stderr,
-                       _("%s: no attributes to change or add (entry=\"%s\")\n"),
-                       prog, dn );
-               return( LDAP_PARAM_ERROR );
-       } 
-
-       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;
-               }
-       }
+               /* implement "touch" (empty sequence)
+                * modify operation (note that there
+                * is no symmetry with the UNIX command,
+                * since \"touch\" on a non-existent entry
+                * will fail)*/
+               printf( "warning: no attributes to %sadd (entry=\"%s\")\n",
+                       newentry ? "" : "change or ", dn );
 
-       if ( verbose ) {
+       } else {
                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") :
-                                               op == LDAP_MOD_INCREMENT ?  _("increment") :
-                                                       op == LDAP_MOD_DELETE ?  _("delete") :
-                                                               _("unknown"),
-                               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;
-                                       for ( k = 0; (unsigned long) k < bvp->bv_len; ++k ) {
-                                               if ( !isascii( bvp->bv_val[ k ] )) {
-                                                       notascii = 1;
-                                                       break;
+                       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;
+                       }
+               }
+
+               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") :
+                                                       op == LDAP_MOD_INCREMENT ?  _("increment") :
+                                                               op == LDAP_MOD_DELETE ?  _("delete") :
+                                                                       _("unknown"),
+                                       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;
+                                               for ( k = 0; (unsigned long) k < bvp->bv_len; ++k ) {
+                                                       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 ( notascii ) {
-                                               printf( _("\tNOT ASCII (%ld bytes)\n"), bvp->bv_len );
-                                       } else {
-                                               printf( "\t%s\n", bvp->bv_val );
                                        }
                                }
                        }
@@ -1003,13 +1025,13 @@ domodify(
        }
 
        if ( newentry ) {
-               printf( "%sadding new entry \"%s\"\n", not ? "!" : "", dn );
+               printf( "%sadding new entry \"%s\"\n", dont ? "!" : "", dn );
        } else {
-               printf( "%smodifying entry \"%s\"\n", not ? "!" : "", dn );
+               printf( "%smodifying entry \"%s\"\n", dont ? "!" : "", dn );
        }
 
-       if ( !not ) {
-               int msgid;
+       if ( !dont ) {
+               int     msgid;
                if ( newentry ) {
                        rc = ldap_add_ext( ld, dn, pmods, pctrls, NULL, &msgid );
                } else {
@@ -1019,14 +1041,14 @@ domodify(
                if ( rc != 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" );
+                       tool_perror( newentry ? "ldap_add" : "ldap_modify", rc, NULL, NULL, NULL, NULL );
                        goto done;
                } else if ( verbose ) {
                        printf( _("modify complete\n") );
                }
 
                rc = process_response( ld, msgid,
-                       newentry ? "ldap_add" : "ldap_modify", dn );
+                       newentry ? LDAP_RES_ADD : LDAP_RES_MODIFY, dn );
 
        } else {
                rc = LDAP_SUCCESS;
@@ -1046,18 +1068,18 @@ dodelete(
        int     rc;
        int msgid;
 
-       printf( _("%sdeleting entry \"%s\"\n"), not ? "!" : "", dn );
-       if ( !not ) {
+       printf( _("%sdeleting entry \"%s\"\n"), dont ? "!" : "", dn );
+       if ( !dont ) {
                rc = ldap_delete_ext( ld, dn, pctrls, NULL, &msgid );
                if ( rc != LDAP_SUCCESS ) {
                        fprintf( stderr, _("%s: delete failed: %s\n"), prog, dn );
-                       ldap_perror( ld, "ldap_delete" );
+                       tool_perror( "ldap_delete", rc, NULL, NULL, NULL, NULL );
                        goto done;
                } else if ( verbose ) {
                        printf( _("delete complete") );
                }
 
-               rc = process_response( ld, msgid, "ldap_delete", dn );
+               rc = process_response( ld, msgid, LDAP_RES_DELETE, dn );
 
        } else {
                rc = LDAP_SUCCESS;
@@ -1080,23 +1102,23 @@ dorename(
        int     rc;
        int msgid;
 
-       printf( _("%smodifying rdn of entry \"%s\"\n"), not ? "!" : "", dn );
+       printf( _("%smodifying rdn of entry \"%s\"\n"), dont ? "!" : "", dn );
        if ( verbose ) {
                printf( _("\tnew RDN: \"%s\" (%skeep existing values)\n"),
                        newrdn, deleteoldrdn ? _("do not ") : "" );
        }
-       if ( !not ) {
+       if ( !dont ) {
                rc = ldap_rename( ld, dn, newrdn, newsup, deleteoldrdn,
                        pctrls, NULL, &msgid );
                if ( rc != LDAP_SUCCESS ) {
                        fprintf( stderr, _("%s: rename failed: %s\n"), prog, dn );
-                       ldap_perror( ld, "ldap_modrdn" );
+                       tool_perror( "ldap_modrdn", rc, NULL, NULL, NULL, NULL );
                        goto done;
                } else {
                        printf( _("modrdn completed\n") );
                }
 
-               rc = process_response( ld, msgid, "ldap_rename", dn );
+               rc = process_response( ld, msgid, LDAP_RES_RENAME, dn );
 
        } else {
                rc = LDAP_SUCCESS;
@@ -1107,29 +1129,90 @@ done:
        return( rc );
 }
 
+static const char *
+res2str( int res ) {
+       switch ( res ) {
+       case LDAP_RES_ADD:
+               return "ldap_add";
+       case LDAP_RES_DELETE:
+               return "ldap_delete";
+       case LDAP_RES_MODIFY:
+               return "ldap_modify";
+       case LDAP_RES_MODRDN:
+               return "ldap_modrdn";
+       default:
+               assert( 0 );
+       }
+
+       return "ldap_unknown";
+}
+
 static int process_response(
        LDAP *ld,
        int msgid,
-       const char *opstr,
+       int op,
        const char *dn )
 {
-       LDAPMessage *res;
-       int rc = LDAP_OTHER;
+       LDAPMessage     *res;
+       int             rc = LDAP_OTHER,
+                       msgtype;
+       struct timeval  tv = { 0, 0 };
 
-       if( ldap_result( ld, msgid,
+       for ( ; ; ) {
+               tv.tv_sec = 0;
+               tv.tv_usec = 100000;
+
+               rc = ldap_result( ld, msgid,
 #ifdef LDAP_GROUP_TRANSACTION
-               txn ? 0 : 1,
+                       txn ? LDAP_MSG_ONE : LDAP_MSG_ALL,
 #else
-               1,
+                       LDAP_MSG_ALL,
 #endif
-               NULL, &res ) == -1 ) {
-               ldap_get_option( ld, LDAP_OPT_ERROR_NUMBER, &rc );
-               return rc;
+                       &tv, &res );
+               if ( tool_check_abandon( ld, msgid ) ) {
+                       return LDAP_CANCELLED;
+               }
+
+               if ( rc == -1 ) {
+                       ldap_get_option( ld, LDAP_OPT_ERROR_NUMBER, &rc );
+                       return rc;
+               }
+
+               if ( rc != 0 ) {
+                       break;
+               }
        }
 
-       if( ldap_msgtype( res ) != LDAP_RES_INTERMEDIATE ) {
-               rc = ldap_result2error( ld, res, 1 );
-               if (rc) ldap_perror( ld, opstr );
+       msgtype = ldap_msgtype( res );
+       if ( msgtype != LDAP_RES_INTERMEDIATE ) {
+               int             err;
+               char            *text = NULL, *matched = NULL, **refs = NULL;
+               LDAPControl     **ctrls = NULL;
+
+               rc = ldap_parse_result( ld, res, &err, &matched, &text, &refs, &ctrls, 1 );
+               if ( rc == LDAP_SUCCESS ) {
+                       rc = err;
+               }
+               if ( rc != LDAP_SUCCESS ) {
+                       tool_perror( res2str( op ), rc, NULL, matched, text, refs );
+               } else if ( msgtype != op ) {
+                       fprintf( stderr, "%s: msgtype: expected %d got %d\n",
+                               res2str( op ), op, msgtype );
+                       rc = LDAP_OTHER;
+               }
+               if ( text ) {
+                       ldap_memfree( text );
+               }
+               if ( matched ) {
+                       ldap_memfree( matched );
+               }
+               if ( text ) {
+                       ber_memvfree( (void **)refs );
+               }
+               if ( ctrls != NULL ) {
+                       tool_print_ctrls( ld, ctrls );
+                       ldap_controls_free( ctrls );
+               }
                return rc;
        }