]> git.sur5r.net Git - openldap/blob - clients/tools/ldapmodrdn.c
d7c98d3854d71d3e734dabe471f725d76c699797
[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] [-M[M]] [-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, manageDSAit;
51     char        *newSuperior=NULL;
52
53     infile = NULL;
54     not = contoper = verbose = remove = want_bindpw = debug = manageDSAit = 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, "WkKMcnvrh: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 'M':
120                 /* enable Manage DSA IT */
121                 manageDSAit++;
122                 break;
123         case 'W':
124                 want_bindpw++;
125                 break;
126         case 'P':
127                 switch( atoi(optarg) )
128                 {
129                 case 2:
130                         version = LDAP_VERSION2;
131                         break;
132                 case 3:
133                         version = LDAP_VERSION3;
134                         break;
135                 default:
136                         fprintf( stderr, "protocol version should be 2 or 3\n" );
137                     fprintf( stderr, usage, argv[0] );
138                     return( EXIT_FAILURE );
139                 }
140                 break;
141         default:
142             fprintf( stderr, usage, argv[0] );
143             return( EXIT_FAILURE );
144         }
145     }
146
147     if (newSuperior != NULL) {
148                 if (version == LDAP_VERSION2) {
149                         fprintf( stderr,
150                                 "%s: version conflict!, -s newSuperior requires LDAPv3\n",
151                                 myname);
152                         fprintf( stderr, usage, argv[0] );
153                         return( EXIT_FAILURE );
154                 }
155
156                 /* promote to LDAPv3 */
157                 version = LDAP_VERSION3;
158     }
159     
160     havedn = 0;
161     if (argc - optind == 2) {
162         if (( rdn = strdup( argv[argc - 1] )) == NULL ) {
163             perror( "strdup" );
164             return( EXIT_FAILURE );
165         }
166         if (( entrydn = strdup( argv[argc - 2] )) == NULL ) {
167             perror( "strdup" );
168             return( EXIT_FAILURE );
169         }
170         ++havedn;
171     } else if ( argc - optind != 0 ) {
172         fprintf( stderr, "%s: invalid number of arguments, only two allowed\n", myname);
173         fprintf( stderr, usage, argv[0] );
174         return( EXIT_FAILURE );
175     }
176
177     if ( infile != NULL ) {
178         if (( fp = fopen( infile, "r" )) == NULL ) {
179             perror( infile );
180             return( EXIT_FAILURE );
181         }
182     } else {
183         fp = stdin;
184     }
185
186         if ( debug ) {
187                 if( ber_set_option( NULL, LBER_OPT_DEBUG_LEVEL, &debug ) != LBER_OPT_SUCCESS ) {
188                         fprintf( stderr, "Could not set LBER_OPT_DEBUG_LEVEL %d\n", debug );
189                 }
190                 if( ldap_set_option( NULL, LDAP_OPT_DEBUG_LEVEL, &debug ) != LDAP_OPT_SUCCESS ) {
191                         fprintf( stderr, "Could not set LDAP_OPT_DEBUG_LEVEL %d\n", debug );
192                 }
193         }
194
195 #ifdef SIGPIPE
196         (void) SIGNAL( SIGPIPE, SIG_IGN );
197 #endif
198
199     if (( ld = ldap_init( ldaphost, ldapport )) == NULL ) {
200         perror( "ldap_init" );
201         return( EXIT_FAILURE );
202     }
203
204         /* this seems prudent */
205         {
206                 int deref = LDAP_DEREF_NEVER;
207                 ldap_set_option( ld, LDAP_OPT_DEREF, &deref);
208         }
209
210         if (want_bindpw)
211                 passwd = getpass("Enter LDAP Password: ");
212
213         if (version != -1 &&
214                 ldap_set_option( ld, LDAP_OPT_PROTOCOL_VERSION, &version ) != LDAP_OPT_SUCCESS)
215         {
216                 fprintf( stderr, "Could not set LDAP_OPT_PROTOCOL_VERSION %d\n", version );
217         }
218
219     if ( ldap_bind_s( ld, binddn, passwd, authmethod ) != LDAP_SUCCESS ) {
220         ldap_perror( ld, "ldap_bind" );
221         return( EXIT_FAILURE );
222     }
223
224         if ( manageDSAit ) {
225                 int err;
226                 LDAPControl c;
227                 LDAPControl *ctrls[2];
228                 ctrls[0] = &c;
229                 ctrls[1] = NULL;
230
231                 c.ldctl_oid = LDAP_CONTROL_MANAGEDSAIT;
232                 c.ldctl_value.bv_val = NULL;
233                 c.ldctl_value.bv_len = 0;
234                 c.ldctl_iscritical = manageDSAit > 1;
235
236                 err = ldap_set_option( ld, LDAP_OPT_SERVER_CONTROLS, &ctrls );
237
238                 if( err != LDAP_OPT_SUCCESS ) {
239                         fprintf( stderr, "Could not set Manage DSA IT Control\n" );
240                         if( c.ldctl_iscritical ) {
241                                 exit( EXIT_FAILURE );
242                         }
243                 }
244         }
245
246     rc = 0;
247     if (havedn)
248         rc = domodrdn(ld, entrydn, rdn, remove, newSuperior);
249     else while ((rc == 0 || contoper) && fgets(buf, sizeof(buf), fp) != NULL) {
250         if ( *buf != '\0' ) {   /* blank lines optional, skip */
251             buf[ strlen( buf ) - 1 ] = '\0';    /* remove nl */
252
253             if ( havedn ) {     /* have DN, get RDN */
254                 if (( rdn = strdup( buf )) == NULL ) {
255                     perror( "strdup" );
256                     return( EXIT_FAILURE );
257                 }
258                 rc = domodrdn(ld, entrydn, rdn, remove, newSuperior);
259                 havedn = 0;
260             } else if ( !havedn ) {     /* don't have DN yet */
261                 if (( entrydn = strdup( buf )) == NULL ) {
262                     perror( "strdup" );
263                     return( EXIT_FAILURE );
264                 }
265                 ++havedn;
266             }
267         }
268     }
269
270     ldap_unbind( ld );
271
272         /* UNREACHABLE */
273         return( rc );
274 }
275
276 static int domodrdn(
277     LDAP        *ld,
278     char        *dn,
279     char        *rdn,
280     int         remove,         /* flag: remove old RDN */
281     char        *newSuperior)
282 {
283     int i;
284
285     if ( verbose ) {
286         printf( "modrdn %s:\n\t%s\n", dn, rdn );
287         if (remove)
288             printf("removing old RDN\n");
289         else
290             printf("keeping old RDN\n");
291         if(newSuperior!=NULL)
292             printf("placing node under a new parent = %s\n", newSuperior);
293     }
294
295     if ( !not ) {
296         i = ldap_rename2_s( ld, dn, rdn, remove, newSuperior );
297         if ( i != LDAP_SUCCESS ) {
298             ldap_perror( ld, "ldap_rename2_s" );
299         } else if ( verbose ) {
300             printf( "modrdn complete\n" );
301         }
302     } else {
303         i = LDAP_SUCCESS;
304     }
305
306     return( i );
307 }