]> git.sur5r.net Git - openldap/blob - clients/tools/ldapmodrdn.c
#define LDAP_LDIF to default to LDIF output
[openldap] / clients / tools / ldapmodrdn.c
1 /* $OpenLDAP$ */
2 /*
3  * Copyright 1998-1999 The OpenLDAP Foundation, All Rights Reserved.
4  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
5  */
6 /* ldapmodrdn.c - generic program to modify an entry's RDN using LDAP.
7  *
8  * Support for MODIFYDN REQUEST V3 (newSuperior) by:
9  * 
10  * Copyright 1999, Juan C. Gomez, All rights reserved.
11  * This software is not subject to any license of Silicon Graphics 
12  * Inc. or Purdue University.
13  *
14  * Redistribution and use in source and binary forms are permitted
15  * without restriction or fee of any kind as long as this notice
16  * is preserved.
17  *
18  */
19
20 #include "portable.h"
21
22 #include <stdio.h>
23
24 #include <ac/stdlib.h>
25
26 #include <ac/ctype.h>
27 #include <ac/signal.h>
28 #include <ac/string.h>
29 #include <ac/unistd.h>
30
31 #include <lber.h>
32 #include <ldap.h>
33
34 static char     *binddn = NULL;
35 static char     *passwd = NULL;
36 static char     *ldaphost = NULL;
37 static int      ldapport = 0;
38 static int      not, verbose, contoper;
39 static LDAP     *ld;
40
41 static int domodrdn(
42     LDAP        *ld,
43     char        *dn,
44     char        *rdn,
45     char        *newSuperior,
46     int         remove );       /* flag: remove old RDN */
47
48 int
49 main(int argc, char **argv)
50 {
51         char            *usage = "usage: %s [-nvkWc] [-M[M]] [-d debug-level] [-h ldaphost] [-P version] [-p ldapport] [-D binddn] [-w passwd] [ -f file | < entryfile | dn newrdn ] [-s newSuperior]\n";
52     char                *myname,*infile, *entrydn, *rdn, buf[ 4096 ];
53     FILE                *fp;
54         int             rc, i, remove, havedn, authmethod, version, want_bindpw, debug, manageDSAit;
55     char        *newSuperior=NULL;
56
57     infile = NULL;
58     not = contoper = verbose = remove = want_bindpw = debug = manageDSAit = 0;
59     authmethod = LDAP_AUTH_SIMPLE;
60         version = -1;
61
62     myname = (myname = strrchr(argv[0], '/')) == NULL ? argv[0] : ++myname;
63
64     while (( i = getopt( argc, argv, "WkKMcnvrh:P:p:D:w:d:f:s:" )) != EOF ) {
65         switch( i ) {
66         case 'k':       /* kerberos bind */
67 #ifdef LDAP_API_FEATURE_X_OPENLDAP_V2_KBIND
68                 authmethod = LDAP_AUTH_KRBV4;
69 #else
70                 fprintf (stderr, "%s was not compiled with Kerberos support\n", argv[0]);
71                 return( EXIT_FAILURE );
72 #endif
73             break;
74         case 'K':       /* kerberos bind, part one only */
75 #ifdef LDAP_API_FEATURE_X_OPENLDAP_V2_KBIND
76                 authmethod = LDAP_AUTH_KRBV41;
77 #else
78                 fprintf (stderr, "%s was not compiled with Kerberos support\n", argv[0]);
79                 return( EXIT_FAILURE );
80 #endif
81             break;
82         case 'c':       /* continuous operation mode */
83             ++contoper;
84             break;
85         case 'h':       /* ldap host */
86             ldaphost = strdup( optarg );
87             break;
88         case 'D':       /* bind DN */
89             binddn = strdup( optarg );
90             break;
91         case 's':       /* newSuperior */
92             newSuperior = strdup( optarg );
93             version = LDAP_VERSION3;    /* This option => force V3 */
94             break;
95         case 'w':       /* password */
96             passwd = strdup( optarg );
97                 {
98                         char* p;
99
100                         for( p = optarg; *p == '\0'; p++ ) {
101                                 *p = '*';
102                         }
103                 }
104             break;
105         case 'd':
106             debug |= atoi( optarg );
107             break;
108         case 'f':       /* read from file */
109             infile = strdup( optarg );
110             break;
111         case 'p':
112             ldapport = atoi( optarg );
113             break;
114         case 'n':       /* print adds, don't actually do them */
115             ++not;
116             break;
117         case 'v':       /* verbose mode */
118             verbose++;
119             break;
120         case 'r':       /* remove old RDN */
121             remove++;
122             break;
123         case 'M':
124                 /* enable Manage DSA IT */
125                 manageDSAit++;
126                 break;
127         case 'W':
128                 want_bindpw++;
129                 break;
130         case 'P':
131                 switch( atoi(optarg) )
132                 {
133                 case 2:
134                         version = LDAP_VERSION2;
135                         break;
136                 case 3:
137                         version = LDAP_VERSION3;
138                         break;
139                 default:
140                         fprintf( stderr, "protocol version should be 2 or 3\n" );
141                     fprintf( stderr, usage, argv[0] );
142                     return( EXIT_FAILURE );
143                 }
144                 break;
145         default:
146             fprintf( stderr, usage, argv[0] );
147             return( EXIT_FAILURE );
148         }
149     }
150
151         if( authmethod != LDAP_AUTH_SIMPLE ) {
152                 if( version == LDAP_VERSION3 ) {
153                         fprintf(stderr, "Kerberos requires LDAPv2\n");
154                         return EXIT_FAILURE;
155                 }
156                 version = LDAP_VERSION2;
157         }
158
159         if( manageDSAit ) {
160                 if( version == LDAP_VERSION2 ) {
161                         fprintf(stderr, "manage DSA control requires LDAPv3\n");
162                         return EXIT_FAILURE;
163                 }
164                 version = LDAP_VERSION3;
165         }
166
167     if (newSuperior != NULL) {
168                 if (version == LDAP_VERSION2) {
169                         fprintf( stderr,
170                                 "%s: version conflict!, -s newSuperior requires LDAPv3\n",
171                                 myname);
172                         fprintf( stderr, usage, argv[0] );
173                         return( EXIT_FAILURE );
174                 }
175
176                 /* promote to LDAPv3 */
177                 version = LDAP_VERSION3;
178     }
179     
180     havedn = 0;
181     if (argc - optind == 2) {
182         if (( rdn = strdup( argv[argc - 1] )) == NULL ) {
183             perror( "strdup" );
184             return( EXIT_FAILURE );
185         }
186         if (( entrydn = strdup( argv[argc - 2] )) == NULL ) {
187             perror( "strdup" );
188             return( EXIT_FAILURE );
189         }
190         ++havedn;
191     } else if ( argc - optind != 0 ) {
192         fprintf( stderr, "%s: invalid number of arguments, only two allowed\n", myname);
193         fprintf( stderr, usage, argv[0] );
194         return( EXIT_FAILURE );
195     }
196
197     if ( infile != NULL ) {
198         if (( fp = fopen( infile, "r" )) == NULL ) {
199             perror( infile );
200             return( EXIT_FAILURE );
201         }
202     } else {
203         fp = stdin;
204     }
205
206         if ( debug ) {
207                 if( ber_set_option( NULL, LBER_OPT_DEBUG_LEVEL, &debug ) != LBER_OPT_SUCCESS ) {
208                         fprintf( stderr, "Could not set LBER_OPT_DEBUG_LEVEL %d\n", debug );
209                 }
210                 if( ldap_set_option( NULL, LDAP_OPT_DEBUG_LEVEL, &debug ) != LDAP_OPT_SUCCESS ) {
211                         fprintf( stderr, "Could not set LDAP_OPT_DEBUG_LEVEL %d\n", debug );
212                 }
213         }
214
215 #ifdef SIGPIPE
216         (void) SIGNAL( SIGPIPE, SIG_IGN );
217 #endif
218
219     if (( ld = ldap_init( ldaphost, ldapport )) == NULL ) {
220         perror( "ldap_init" );
221         return( EXIT_FAILURE );
222     }
223
224         /* this seems prudent */
225         {
226                 int deref = LDAP_DEREF_NEVER;
227                 ldap_set_option( ld, LDAP_OPT_DEREF, &deref);
228         }
229         /* don't chase referrals */
230         ldap_set_option( ld, LDAP_OPT_REFERRALS, LDAP_OPT_OFF );
231
232
233         if (version != -1 &&
234                 ldap_set_option( ld, LDAP_OPT_PROTOCOL_VERSION, &version ) != LDAP_OPT_SUCCESS)
235         {
236                 fprintf( stderr, "Could not set LDAP_OPT_PROTOCOL_VERSION %d\n", version );
237         }
238
239         if (want_bindpw)
240                 passwd = getpass("Enter LDAP Password: ");
241
242     if ( ldap_bind_s( ld, binddn, passwd, authmethod ) != LDAP_SUCCESS ) {
243         ldap_perror( ld, "ldap_bind" );
244         return( EXIT_FAILURE );
245     }
246
247         if ( manageDSAit ) {
248                 int err;
249                 LDAPControl c;
250                 LDAPControl *ctrls[2];
251                 ctrls[0] = &c;
252                 ctrls[1] = NULL;
253
254                 c.ldctl_oid = LDAP_CONTROL_MANAGEDSAIT;
255                 c.ldctl_value.bv_val = NULL;
256                 c.ldctl_value.bv_len = 0;
257                 c.ldctl_iscritical = manageDSAit > 1;
258
259                 err = ldap_set_option( ld, LDAP_OPT_SERVER_CONTROLS, &ctrls );
260
261                 if( err != LDAP_OPT_SUCCESS ) {
262                         fprintf( stderr, "Could not set Manage DSA IT Control\n" );
263                         if( c.ldctl_iscritical ) {
264                                 exit( EXIT_FAILURE );
265                         }
266                 }
267         }
268
269     rc = 0;
270     if (havedn)
271         rc = domodrdn( ld, entrydn, rdn, newSuperior, remove );
272     else while ((rc == 0 || contoper) && fgets(buf, sizeof(buf), fp) != NULL) {
273         if ( *buf != '\0' ) {   /* blank lines optional, skip */
274             buf[ strlen( buf ) - 1 ] = '\0';    /* remove nl */
275
276             if ( havedn ) {     /* have DN, get RDN */
277                 if (( rdn = strdup( buf )) == NULL ) {
278                     perror( "strdup" );
279                     return( EXIT_FAILURE );
280                 }
281                 rc = domodrdn(ld, entrydn, rdn, newSuperior, remove );
282                 havedn = 0;
283             } else if ( !havedn ) {     /* don't have DN yet */
284                 if (( entrydn = strdup( buf )) == NULL ) {
285                     perror( "strdup" );
286                     return( EXIT_FAILURE );
287                 }
288                 ++havedn;
289             }
290         }
291     }
292
293     ldap_unbind( ld );
294
295         /* UNREACHABLE */
296         return( rc );
297 }
298
299 static int domodrdn(
300     LDAP        *ld,
301     char        *dn,
302     char        *rdn,
303     char        *newSuperior,
304     int         remove ) /* flag: remove old RDN */
305 {
306     int i;
307
308     if ( verbose ) {
309                 printf( "Renaming \"%s\"\n", dn );
310                 printf( "\tnew rdn=\"%s\" (%s old rdn)\n",
311                         rdn, remove ? "delete" : "keep" );
312                 if( newSuperior != NULL ) {
313                         printf("\tnew parent=\"%s\"\n", newSuperior);
314                 }
315         }
316
317     if ( !not ) {
318         i = ldap_rename2_s( ld, dn, rdn, newSuperior, remove );
319         if ( i != LDAP_SUCCESS ) {
320             ldap_perror( ld, "ldap_rename2_s" );
321         } else if ( verbose ) {
322             printf( "modrdn complete\n" );
323         }
324     } else {
325         i = LDAP_SUCCESS;
326     }
327
328     return( i );
329 }