]> git.sur5r.net Git - openldap/blob - clients/tools/ldapmodrdn.c
Plug memory leaks from ldap_get_option().
[openldap] / clients / tools / ldapmodrdn.c
1 /* $OpenLDAP$ */
2 /*
3  * Copyright 1998-2002 The OpenLDAP Foundation, All Rights Reserved.
4  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
5  */
6 /* ldapmodrdn.c - generic program to modify an entry's RDN using LDAP.
7  *
8  * Support for MODIFYDN REQUEST V3 (newSuperior) by:
9  * 
10  * Copyright 1999, Juan C. Gomez, All rights reserved.
11  * This software is not subject to any license of Silicon Graphics 
12  * Inc. or Purdue University.
13  *
14  * Redistribution and use in source and binary forms are permitted
15  * without restriction or fee of any kind as long as this notice
16  * is preserved.
17  *
18  */
19
20 #include "portable.h"
21
22 #include <stdio.h>
23
24 #include <ac/stdlib.h>
25
26 #include <ac/ctype.h>
27 #include <ac/string.h>
28 #include <ac/unistd.h>
29
30 #include <ldap.h>
31 #include "lutil.h"
32 #include "lutil_ldap.h"
33 #include "ldap_defaults.h"
34
35 #include "common.h"
36
37
38 static char     *newSuperior = NULL;
39 static int   remove_old_RDN = 0;
40
41
42 static int domodrdn(
43     LDAP        *ld,
44     char        *dn,
45     char        *rdn,
46     char        *newSuperior,
47     int         remove );       /* flag: remove old RDN */
48
49 void
50 usage( void )
51 {
52         fprintf( stderr,
53 "Rename LDAP entries\n\n"
54 "usage: %s [options] [dn rdn]\n"
55 "       dn rdn: If given, rdn will replace the RDN of the entry specified by DN\n"
56 "               If not given, the list of modifications is read from stdin or\n"
57 "               from the file specified by \"-f file\" (see man page).\n"
58 "Rename options:\n"
59 "  -r         remove old RDN\n"
60 "  -s newsup  new superior entry\n"
61                  , prog );
62         tool_common_usage();
63         exit( EXIT_FAILURE );
64 }
65
66
67 const char options[] = "rs:" "cCd:D:e:f:h:H:IkKMnO:p:P:QR:U:vw:WxX:y:Y:Z";
68
69 int
70 handle_private_option( int i )
71 {
72         switch ( i ) {
73 #if 0
74                 int crit;
75                 char *control, *cvalue;
76         case 'E': /* modrdn controls */
77                 if( version == LDAP_VERSION2 ) {
78                         fprintf( stderr, "%s: -E incompatible with LDAPv%d\n",
79                                 prog, version );
80                         exit( EXIT_FAILURE );
81                 }
82
83                 /* should be extended to support comma separated list of
84                  *      [!]key[=value] parameters, e.g.  -E !foo,bar=567
85                  */
86
87                 crit = 0;
88                 cvalue = NULL;
89                 if( optarg[0] == '!' ) {
90                         crit = 1;
91                         optarg++;
92                 }
93
94                 control = strdup( optarg );
95                 if ( (cvalue = strchr( control, '=' )) != NULL ) {
96                         *cvalue++ = '\0';
97                 }
98                 fprintf( stderr, "Invalid modrdn control name: %s\n", control );
99                 usage();
100 #endif
101
102         case 'r':       /* remove old RDN */
103             remove_old_RDN++;
104             break;
105
106         case 's':       /* newSuperior */
107                 if( version == LDAP_VERSION2 ) {
108                         fprintf( stderr, "%s: -X incompatible with LDAPv%d\n",
109                                 prog, version );
110                         exit( EXIT_FAILURE );
111                 }
112             newSuperior = strdup( optarg );
113             version = LDAP_VERSION3;
114             break;
115
116         default:
117                 return 0;
118         }
119         return 1;
120 }
121
122
123 int
124 main(int argc, char **argv)
125 {
126     char                *entrydn = NULL, *rdn = NULL, buf[ 4096 ];
127     FILE                *fp;
128     LDAP                *ld;
129         int             rc, retval, havedn;
130
131     prog = lutil_progname( "ldapmodrdn", argc, argv );
132
133         tool_args( argc, argv );
134
135     havedn = 0;
136     if (argc - optind == 2) {
137         if (( rdn = strdup( argv[argc - 1] )) == NULL ) {
138             perror( "strdup" );
139             return( EXIT_FAILURE );
140         }
141         if (( entrydn = strdup( argv[argc - 2] )) == NULL ) {
142             perror( "strdup" );
143             return( EXIT_FAILURE );
144         }
145         ++havedn;
146     } else if ( argc - optind != 0 ) {
147         fprintf( stderr, "%s: invalid number of arguments (%d), "
148                 "only two allowed\n", prog, argc-optind );
149         usage();
150     }
151
152     if ( infile != NULL ) {
153         if (( fp = fopen( infile, "r" )) == NULL ) {
154             perror( infile );
155             return( EXIT_FAILURE );
156         }
157     } else {
158         fp = stdin;
159     }
160
161         ld = tool_conn_setup( 0, 0 );
162
163         if ( pw_file || want_bindpw ) {
164                 if ( pw_file ) {
165                         rc = lutil_get_filed_password( pw_file, &passwd );
166                         if( rc ) return EXIT_FAILURE;
167                 } else {
168                         passwd.bv_val = getpassphrase( "Enter LDAP Password: " );
169                         passwd.bv_len = passwd.bv_val ? strlen( passwd.bv_val ) : 0;
170                 }
171         }
172
173         tool_bind( ld );
174
175         if ( authzid || manageDSAit || noop )
176                 tool_server_controls( ld, NULL, 0 );
177
178     retval = rc = 0;
179     if (havedn)
180         retval = domodrdn( ld, entrydn, rdn, newSuperior, remove_old_RDN );
181     else while ((rc == 0 || contoper) && fgets(buf, sizeof(buf), fp) != NULL) {
182         if ( *buf != '\0' ) {   /* blank lines optional, skip */
183             buf[ strlen( buf ) - 1 ] = '\0';    /* remove nl */
184
185             if ( havedn ) {     /* have DN, get RDN */
186                 if (( rdn = strdup( buf )) == NULL ) {
187                     perror( "strdup" );
188                     return( EXIT_FAILURE );
189                 }
190                 rc = domodrdn(ld, entrydn, rdn, newSuperior, remove_old_RDN );
191                 if ( rc != 0 )
192                         retval = rc;
193                 havedn = 0;
194             } else if ( !havedn ) {     /* don't have DN yet */
195                 if (( entrydn = strdup( buf )) == NULL ) {
196                     perror( "strdup" );
197                     return( EXIT_FAILURE );
198                 }
199                 ++havedn;
200             }
201         }
202     }
203
204     ldap_unbind( ld );
205
206     return( retval );
207 }
208
209 static int domodrdn(
210     LDAP        *ld,
211     char        *dn,
212     char        *rdn,
213     char        *newSuperior,
214     int         remove ) /* flag: remove old RDN */
215 {
216         int rc, code, id;
217         char *matcheddn=NULL, *text=NULL, **refs=NULL;
218         LDAPMessage *res;
219
220     if ( verbose ) {
221                 printf( "Renaming \"%s\"\n", dn );
222                 printf( "\tnew rdn=\"%s\" (%s old rdn)\n",
223                         rdn, remove ? "delete" : "keep" );
224                 if( newSuperior != NULL ) {
225                         printf("\tnew parent=\"%s\"\n", newSuperior);
226                 }
227         }
228
229         if( not ) return LDAP_SUCCESS;
230
231         rc = ldap_rename( ld, dn, rdn, newSuperior, remove,
232                 NULL, NULL, &id );
233
234         if ( rc != LDAP_SUCCESS ) {
235                 fprintf( stderr, "%s: ldap_rename: %s (%d)\n",
236                         prog, ldap_err2string( rc ), rc );
237                 return rc;
238         }
239
240         rc = ldap_result( ld, LDAP_RES_ANY, LDAP_MSG_ALL, NULL, &res );
241         if ( rc < 0 ) {
242                 ldap_perror( ld, "ldapmodrdn: ldap_result" );
243                 return rc;
244         }
245
246         rc = ldap_parse_result( ld, res, &code, &matcheddn, &text, &refs, NULL, 1 );
247
248         if( rc != LDAP_SUCCESS ) {
249                 fprintf( stderr, "%s: ldap_parse_result: %s (%d)\n",
250                         prog, ldap_err2string( rc ), rc );
251                 return rc;
252         }
253
254         if( verbose || code != LDAP_SUCCESS ||
255                 (matcheddn && *matcheddn) || (text && *text) || (refs && *refs) )
256         {
257                 printf( "Rename Result: %s (%d)\n",
258                         ldap_err2string( code ), code );
259
260                 if( text && *text ) {
261                         printf( "Additional info: %s\n", text );
262                 }
263
264                 if( matcheddn && *matcheddn ) {
265                         printf( "Matched DN: %s\n", matcheddn );
266                 }
267
268                 if( refs ) {
269                         int i;
270                         for( i=0; refs[i]; i++ ) {
271                                 printf("Referral: %s\n", refs[i] );
272                         }
273                 }
274         }
275
276         ber_memfree( text );
277         ber_memfree( matcheddn );
278         ber_memvfree( (void **) refs );
279
280         return code;
281 }