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