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