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