1 /* 2 * Copyright 2005 Sun Microsystems, Inc. All rights reserved. 3 * Use is subject to license terms. 4 */ 5 6 /* ldapmodrdn.c - generic program to modify an entry's RDN using LDAP */ 7 8 #include <stdio.h> 9 #include <string.h> 10 #include <stdlib.h> 11 #include <locale.h> 12 #include <ctype.h> 13 #include <lber.h> 14 #include <ldap.h> 15 #include <locale.h> 16 #include "ldaptool.h" 17 18 static int contoper, remove_oldrdn; 19 static LDAP *ld; 20 21 static int domodrdn( LDAP *ld, char *dn, char *rdn, char *newsuperior, 22 int remove_oldrdn); 23 static void options_callback( int option, char *optarg ); 24 25 static void usage( void ) 26 { 27 fprintf(stderr, gettext("usage: %s [options] [dn newrdn [newsuperior]]\n"), ldaptool_progname); 28 fprintf( stderr, gettext("options:\n")); 29 ldaptool_common_usage( 0 ); 30 fprintf( stderr, gettext(" -c\t\tcontinuous mode\n") ); 31 fprintf( stderr, gettext(" -r\t\tremove old RDN from the entries\n")); 32 fprintf( stderr, gettext(" -f file\tread changes from `file'\n") ); 33 exit(LDAP_PARAM_ERROR ); 34 } 35 36 int 37 main(int argc, char **argv ) 38 { 39 char *myname, *entrydn, *rdn, buf[ 4096 ]; 40 int rc, havedn, deref, optind; 41 char * L_newParent = NULL; 42 int haverdn = 0; 43 44 int L_protoVersion = LDAP_VERSION3; 45 46 char *locale = setlocale(LC_ALL, ""); 47 textdomain(TEXT_DOMAIN); 48 ldaplogconfigf(NULL); 49 50 51 contoper = remove_oldrdn = 0; 52 53 if ((myname = strrchr(argv[0], '/')) == NULL) 54 myname = argv[0]; 55 else 56 ++myname; 57 58 optind = ldaptool_process_args( argc, argv, "cr", 0, options_callback); 59 60 if ( optind == -1 ) { 61 usage(); 62 } 63 64 if ( ldaptool_fp == NULL ) { 65 ldaptool_fp = stdin; 66 } 67 68 havedn = 0; 69 if (argc - optind == 3) /* accept as arguments: dn rdn newsuperior */ 70 { 71 if (( L_newParent = strdup( argv[argc - 1] )) == NULL ) 72 { 73 perror( "strdup" ); 74 exit( LDAP_NO_MEMORY ); 75 } 76 77 if (( rdn = strdup( argv[argc - 2] )) == NULL ) 78 { 79 perror( "strdup" ); 80 exit( LDAP_NO_MEMORY ); 81 } 82 83 if (( entrydn = strdup( argv[argc - 3] )) == NULL ) 84 { 85 perror( "strdup" ); 86 exit( LDAP_NO_MEMORY ); 87 } 88 ++havedn; 89 } 90 else if (argc - optind == 2) /* accept as arguments: dn rdn */ 91 { 92 if (( rdn = strdup( argv[argc - 1] )) == NULL ) 93 { 94 perror( "strdup" ); 95 exit( LDAP_NO_MEMORY ); 96 } 97 98 if (( entrydn = strdup( argv[argc - 2] )) == NULL ) 99 { 100 perror( "strdup" ); 101 exit( 1 ); 102 } 103 ++havedn; 104 } 105 else if ( argc - optind != 0 ) 106 { 107 fprintf( stderr, gettext("%s: invalid number of arguments, only two or three allowed\n"), myname); 108 usage(); 109 exit( 1 ); 110 } 111 112 ld = ldaptool_ldap_init (0); 113 114 if ( !ldaptool_not ) { 115 deref = LDAP_DEREF_NEVER; /* this seems prudent */ 116 ldap_set_option( ld, LDAP_OPT_DEREF, &deref ); 117 } 118 119 ldaptool_bind( ld ); 120 121 rc = 0; 122 if (havedn) 123 { 124 rc = domodrdn(ld, entrydn, rdn, L_newParent, remove_oldrdn); 125 } 126 else while ( (rc == 0 || contoper) && 127 (fgets(buf, sizeof(buf), ldaptool_fp) != NULL) ) 128 129 { 130 /* 131 * The format of the file is one of the following: 132 * dn 133 * rdn 134 * newsuperior 135 * <blank lines...> 136 * OR 137 * dn 138 * rdn 139 * <blank lines...> 140 * both types of sequences can be found in the file 141 */ 142 143 if ( (strlen(buf) == 1) && (ldaptool_fp == stdin) ) 144 break; 145 146 buf[ strlen( buf ) - 1 ] = '\0'; /* remove nl */ 147 if ( *buf != '\0' ) /* blank lines optional, skip */ 148 { 149 if ( haverdn ) /* first type of sequence */ 150 { 151 if (( L_newParent = strdup( buf )) == NULL ) 152 { 153 perror( "strdup" ); 154 exit( LDAP_NO_MEMORY ); 155 } 156 if ( L_newParent && (L_protoVersion == LDAP_VERSION) ) 157 { 158 printf( gettext("LDAP Server is V2: <newsuperior> argument is ignored...\n") ); 159 L_newParent = NULL; 160 } 161 rc = domodrdn(ld, entrydn, rdn, L_newParent, remove_oldrdn); 162 haverdn = 0; 163 } 164 else if ( havedn ) /* have DN, get RDN */ 165 { 166 if (( rdn = strdup( buf )) == NULL ) 167 { 168 perror( "strdup" ); 169 exit( LDAP_NO_MEMORY ); 170 } 171 havedn = 0; 172 ++haverdn; 173 } 174 else if ( !havedn ) /* don't have DN yet */ 175 { 176 if (( entrydn = strdup( buf )) == NULL) 177 { 178 perror( "strdup" ); 179 exit( LDAP_NO_MEMORY ); 180 } 181 ++havedn; 182 } 183 } 184 else 185 { 186 printf(gettext("kex: new line %d\n"), rc); 187 if ( haverdn ) /* second type of sequence */ 188 { 189 rc = domodrdn(ld, entrydn, rdn, NULL, remove_oldrdn); 190 haverdn = 0; 191 } 192 } 193 } 194 if ( (rc == 0 || contoper) && haverdn ) /* second type of sequence */ 195 { 196 rc = domodrdn(ld, entrydn, rdn, NULL, remove_oldrdn); 197 haverdn = 0; 198 } 199 200 ldaptool_cleanup( ld ); 201 202 exit( rc ); 203 } 204 205 static void 206 options_callback( int option, char *optarg ) 207 { 208 switch( option ) { 209 case 'c': /* continuous operation mode */ 210 ++contoper; 211 break; 212 case 'r': /* remove old RDN */ 213 ++remove_oldrdn; 214 break; 215 default: 216 usage(); 217 } 218 } 219 220 static int 221 domodrdn( LDAP *ld, char *dn, char *rdn, char *newsuperior, int remove_oldrdn ) 222 { 223 int rc = LDAP_SUCCESS; 224 225 if ( ldaptool_verbose ) 226 printf( gettext("new RDN: %1$s (%2$skeep existing values)\n"), 227 rdn, remove_oldrdn ? "do not " : "" ); 228 229 printf( gettext("%1$srenaming entry %2$s\n"), 230 ldaptool_not ? "!" : "", dn ); 231 232 if ( !ldaptool_not ) 233 { 234 rc = ldap_rename_s( ld, dn, rdn, newsuperior, remove_oldrdn, NULL, NULL ); 235 if ( rc != LDAP_SUCCESS ) 236 fprintf(stderr, gettext("ldap_rename_s: %s\n"), ldap_err2string(rc)); 237 else if ( ldaptool_verbose ) 238 printf( gettext("rename completed\n") ); 239 } 240 241 putchar('\n'); 242 243 return( rc ); 244 } 245