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