]> git.sur5r.net Git - openldap/blob - clients/tools/ldapmodrdn.c
Changes from HEAD for beta
[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
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, _("Rename LDAP entries\n\n"));
53         fprintf( stderr, _("usage: %s [options] [dn rdn]\n"), prog);
54         fprintf( stderr, _("    dn rdn: If given, rdn will replace the RDN of the entry specified by DN\n"));
55         fprintf( stderr, _("            If not given, the list of modifications is read from stdin or\n"));
56         fprintf( stderr, _("            from the file specified by \"-f file\" (see man page).\n"));
57         fprintf( stderr, _("Rename options:\n"));
58         fprintf( stderr, _("  -r         remove old RDN\n"));
59         fprintf( stderr, _("  -s newsup  new superior entry\n"));
60         tool_common_usage();
61         exit( EXIT_FAILURE );
62 }
63
64
65 const char options[] = "rs:"
66         "cCd:D:e:f:h:H:IkKMnO:p:P:QR:U:vVw:WxX:y:Y:Z";
67
68 int
69 handle_private_option( int i )
70 {
71         switch ( i ) {
72 #if 0
73                 int crit;
74                 char *control, *cvalue;
75         case 'E': /* modrdn controls */
76                 if( protocol == LDAP_VERSION2 ) {
77                         fprintf( stderr, _("%s: -E incompatible with LDAPv%d\n"),
78                                 prog, version );
79                         exit( EXIT_FAILURE );
80                 }
81
82                 /* should be extended to support comma separated list of
83                  *      [!]key[=value] parameters, e.g.  -E !foo,bar=567
84                  */
85
86                 crit = 0;
87                 cvalue = NULL;
88                 if( optarg[0] == '!' ) {
89                         crit = 1;
90                         optarg++;
91                 }
92
93                 control = strdup( optarg );
94                 if ( (cvalue = strchr( control, '=' )) != NULL ) {
95                         *cvalue++ = '\0';
96                 }
97                 fprintf( stderr, _("Invalid modrdn control name: %s\n"), control );
98                 usage();
99 #endif
100
101         case 'r':       /* remove old RDN */
102             remove_old_RDN++;
103             break;
104
105         case 's':       /* newSuperior */
106                 if( protocol == LDAP_VERSION2 ) {
107                         fprintf( stderr, _("%s: -X incompatible with LDAPv%d\n"),
108                                 prog, protocol );
109                         exit( EXIT_FAILURE );
110                 }
111             newSuperior = strdup( optarg );
112             protocol = LDAP_VERSION3;
113             break;
114
115         default:
116                 return 0;
117         }
118         return 1;
119 }
120
121
122 int
123 main(int argc, char **argv)
124 {
125     char                *entrydn = NULL, *rdn = NULL, buf[ 4096 ];
126     FILE                *fp;
127     LDAP                *ld;
128         int             rc, retval, havedn;
129
130     tool_init();
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), only two allowed\n"), prog, argc-optind );
148         usage();
149     }
150
151     if ( infile != NULL ) {
152         if (( fp = fopen( infile, "r" )) == NULL ) {
153             perror( infile );
154             return( EXIT_FAILURE );
155         }
156     } else {
157         fp = stdin;
158     }
159
160         ld = tool_conn_setup( 0, 0 );
161
162         if ( pw_file || want_bindpw ) {
163                 if ( pw_file ) {
164                         rc = lutil_get_filed_password( pw_file, &passwd );
165                         if( rc ) return EXIT_FAILURE;
166                 } else {
167                         passwd.bv_val = getpassphrase( _("Enter LDAP Password: ") );
168                         passwd.bv_len = passwd.bv_val ? strlen( passwd.bv_val ) : 0;
169                 }
170         }
171
172         tool_bind( ld );
173
174         if ( assertion || authzid || manageDSAit || noop ) {
175                 tool_server_controls( ld, NULL, 0 );
176         }
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 }