]> git.sur5r.net Git - openldap/blob - clients/tools/ldapmodrdn.c
9e0b92072666ebec2c494b4b7ec569be2ea94fee
[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 #include <stdlib.h>
19
20 #include <ac/ctype.h>
21 #include <ac/signal.h>
22 #include <ac/string.h>
23 #include <ac/unistd.h>
24
25 #include <lber.h>
26 #include <ldap.h>
27
28 static char     *binddn = NULL;
29 static char     *passwd = NULL;
30 static char     *base = NULL;
31 static char     *ldaphost = NULL;
32 static int      ldapport = 0;
33 static int      not, verbose, contoper;
34 static LDAP     *ld;
35
36 #define safe_realloc( ptr, size )       ( (ptr) == NULL ? malloc( size ) : \
37                                          realloc( ptr, size ))
38
39 static int domodrdn LDAP_P((
40     LDAP        *ld,
41     char        *dn,
42     char        *rdn,
43     int         remove,         /* flag: remove old RDN */
44     char        *newSuperior));
45
46 int
47 main(int argc, char **argv)
48 {
49         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";
50     char                *myname,*infile, *entrydn, *rdn, buf[ 4096 ];
51     FILE                *fp;
52         int             rc, i, remove, havedn, authmethod, version, want_bindpw, debug;
53     char        *newSuperior=NULL;
54
55     infile = NULL;
56     not = contoper = verbose = remove = want_bindpw = debug = 0;
57     authmethod = LDAP_AUTH_SIMPLE;
58         version = -1;
59
60     myname = (myname = strrchr(argv[0], '/')) == NULL ? argv[0] : ++myname;
61
62     while (( i = getopt( argc, argv, "WkKcnvrh:P:p:D:w:d:f:s:" )) != EOF ) {
63         switch( i ) {
64         case 'k':       /* kerberos bind */
65 #ifdef HAVE_KERBEROS
66                 authmethod = LDAP_AUTH_KRBV4;
67 #else
68                 fprintf (stderr, "%s was not compiled with Kerberos support\n", argv[0]);
69 #endif
70             break;
71         case 'K':       /* kerberos bind, part one only */
72 #ifdef HAVE_KERBEROS
73                 authmethod = LDAP_AUTH_KRBV41;
74 #else
75                 fprintf (stderr, "%s was not compiled with Kerberos support\n", argv[0]);
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             break;
94         case 'd':
95             debug |= atoi( optarg );
96             break;
97         case 'f':       /* read from file */
98             infile = strdup( optarg );
99             break;
100         case 'p':
101             ldapport = atoi( optarg );
102             break;
103         case 'n':       /* print adds, don't actually do them */
104             ++not;
105             break;
106         case 'v':       /* verbose mode */
107             verbose++;
108             break;
109         case 'r':       /* remove old RDN */
110             remove++;
111             break;
112         case 'W':
113                 want_bindpw++;
114                 break;
115         case 'P':
116                 switch(optarg[0])
117                 {
118                 case '2':
119                         version = LDAP_VERSION2;
120                         break;
121                 case '3':
122                         version = LDAP_VERSION3;
123                         break;
124                 }
125                 break;
126         default:
127             fprintf( stderr, usage, argv[0] );
128             exit( 1 );
129         }
130     }
131
132     if ((newSuperior != NULL) && (version != LDAP_VERSION3))
133     {
134         fprintf( stderr,
135                  "%s: version conflict!, -s newSuperior requires LDAP v3\n",
136                  myname);
137         fprintf( stderr, usage, argv[0] );
138         exit( 1 );
139     }
140     
141     havedn = 0;
142     if (argc - optind == 2) {
143         if (( rdn = strdup( argv[argc - 1] )) == NULL ) {
144             perror( "strdup" );
145             exit( 1 );
146         }
147         if (( entrydn = strdup( argv[argc - 2] )) == NULL ) {
148             perror( "strdup" );
149             exit( 1 );
150         }
151         ++havedn;
152     } else if ( argc - optind != 0 ) {
153         fprintf( stderr, "%s: invalid number of arguments, only two allowed\n", myname);
154         fprintf( stderr, usage, argv[0] );
155         exit( 1 );
156     }
157
158     if ( infile != NULL ) {
159         if (( fp = fopen( infile, "r" )) == NULL ) {
160             perror( infile );
161             exit( 1 );
162         }
163     } else {
164         fp = stdin;
165     }
166
167         if ( debug ) {
168                 lber_set_option( NULL, LBER_OPT_DEBUG_LEVEL, &debug );
169                 ldap_set_option( NULL, LDAP_OPT_DEBUG_LEVEL, &debug );
170         }
171
172 #ifdef SIGPIPE
173         (void) SIGNAL( SIGPIPE, SIG_IGN );
174 #endif
175
176     if (( ld = ldap_init( ldaphost, ldapport )) == NULL ) {
177         perror( "ldap_init" );
178         exit( 1 );
179     }
180
181         /* this seems prudent */
182         {
183                 int deref = LDAP_DEREF_NEVER;
184                 ldap_set_option( ld, LDAP_OPT_DEREF, &deref);
185         }
186
187         if (want_bindpw)
188                 passwd = getpass("Enter LDAP Password: ");
189
190         if( version != -1) {
191                 ldap_set_option( ld, LDAP_OPT_PROTOCOL_VERSION, &version );
192         }
193
194     if ( ldap_bind_s( ld, binddn, passwd, authmethod ) != LDAP_SUCCESS ) {
195         ldap_perror( ld, "ldap_bind" );
196         exit( 1 );
197     }
198
199     rc = 0;
200     if (havedn)
201         rc = domodrdn(ld, entrydn, rdn, remove, newSuperior);
202     else while ((rc == 0 || contoper) && fgets(buf, sizeof(buf), fp) != NULL) {
203         if ( *buf != '\0' ) {   /* blank lines optional, skip */
204             buf[ strlen( buf ) - 1 ] = '\0';    /* remove nl */
205
206             if ( havedn ) {     /* have DN, get RDN */
207                 if (( rdn = strdup( buf )) == NULL ) {
208                     perror( "strdup" );
209                     exit( 1 );
210                 }
211                 rc = domodrdn(ld, entrydn, rdn, remove, newSuperior);
212                 havedn = 0;
213             } else if ( !havedn ) {     /* don't have DN yet */
214                 if (( entrydn = strdup( buf )) == NULL ) {
215                     perror( "strdup" );
216                     exit( 1 );
217                 }
218                 ++havedn;
219             }
220         }
221     }
222
223     ldap_unbind( ld );
224
225     exit( rc );
226
227         /* UNREACHABLE */
228         return(0);
229 }
230
231 static int domodrdn(
232     LDAP        *ld,
233     char        *dn,
234     char        *rdn,
235     int         remove,         /* flag: remove old RDN */
236     char        *newSuperior)
237 {
238     int i;
239
240     if ( verbose ) {
241         printf( "modrdn %s:\n\t%s\n", dn, rdn );
242         if (remove)
243             printf("removing old RDN\n");
244         else
245             printf("keeping old RDN\n");
246         if(newSuperior!=NULL)
247             printf("placing node under a new parent = %s\n", newSuperior);
248     }
249
250     if ( !not ) {
251         i = ldap_rename2_s( ld, dn, rdn, remove, newSuperior );
252         if ( i != LDAP_SUCCESS ) {
253             ldap_perror( ld, "ldap_rename2_s" );
254         } else if ( verbose ) {
255             printf( "modrdn complete\n" );
256         }
257     } else {
258         i = LDAP_SUCCESS;
259     }
260
261     return( i );
262 }