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