]> git.sur5r.net Git - openldap/blob - clients/tools/ldapdelete.c
6ad029a00f9246d432fa89cf64c7e7da346a57c0
[openldap] / clients / tools / ldapdelete.c
1 /* ldapdelete.c - simple program to delete an entry using LDAP */
2 /* $OpenLDAP$ */
3 /*
4  * Copyright 1998-1999 The OpenLDAP Foundation, All Rights Reserved.
5  * COPYING RESTRICTIONS APPLY, see COPYRIGHT file
6  */
7
8 #include "portable.h"
9
10 #include <stdio.h>
11
12 #include <ac/stdlib.h>
13 #include <ac/ctype.h>
14
15 #include <ac/signal.h>
16 #include <ac/string.h>
17 #include <ac/unistd.h>
18
19 #include <lber.h>
20 #include <ldap.h>
21
22 static char     *binddn = NULL;
23 static char     *passwd = NULL;
24 static char     *ldaphost = NULL;
25 static int      ldapport = 0;
26 static int  prune = 0;
27 static int      not, verbose, contoper;
28 static LDAP     *ld;
29
30 static int dodelete LDAP_P((
31     LDAP        *ld,
32     char        *dn));
33
34 static int deletechildren LDAP_P(( LDAP *ld,
35                                    char *dn ));
36
37 int
38 main( int argc, char **argv )
39 {
40         char            *usage = "usage: %s [-n] [-v] [-k] [-W] [-M[M]] [-r] [-d debug-level] [-f file] [-h ldaphost] [-P version] [-p ldapport] [-D binddn] [-w passwd] [dn]...\n";
41     char                buf[ 4096 ];
42     FILE                *fp;
43         int             i, rc, authmethod, want_bindpw, version, debug, manageDSAit;
44
45     not = verbose = contoper = want_bindpw = debug = manageDSAit = 0;
46     fp = NULL;
47     authmethod = LDAP_AUTH_SIMPLE;
48         version = -1;
49
50     while (( i = getopt( argc, argv, "WMnvkKcrh:P:p:D:w:d:f:" )) != EOF ) {
51         switch( i ) {
52         case 'k':       /* kerberos bind */
53 #ifdef LDAP_API_FEATURE_X_OPENLDAP_V2_KBIND
54                 authmethod = LDAP_AUTH_KRBV4;
55 #else
56                 fprintf (stderr, "%s was not compiled with Kerberos support\n", argv[0]);
57                 fprintf( stderr, usage, argv[0] );
58                 return( EXIT_FAILURE );
59 #endif
60             break;
61         case 'K':       /* kerberos bind, part one only */
62 #ifdef LDAP_API_FEATURE_X_OPENLDAP_V2_KBIND
63                 authmethod = LDAP_AUTH_KRBV41;
64 #else
65                 fprintf (stderr, "%s was not compiled with Kerberos support\n", argv[0]);
66                 fprintf( stderr, usage, argv[0] );
67                 return( EXIT_FAILURE );
68 #endif
69             break;
70         case 'c':       /* continuous operation mode */
71             ++contoper;
72             break;
73         case 'h':       /* ldap host */
74             ldaphost = strdup( optarg );
75             break;
76         case 'D':       /* bind DN */
77             binddn = strdup( optarg );
78             break;
79         case 'w':       /* password */
80             passwd = strdup( optarg );
81                 {
82                         char* p;
83
84                         for( p = optarg; *p == '\0'; p++ ) {
85                                 *p = '*';
86                         }
87                 }
88             break;
89         case 'f':       /* read DNs from a file */
90             if (( fp = fopen( optarg, "r" )) == NULL ) {
91                 perror( optarg );
92                 exit( EXIT_FAILURE );
93             }
94             break;
95         case 'd':
96             debug |= atoi( optarg );
97             break;
98         case 'p':
99             ldapport = atoi( optarg );
100             break;
101         case 'n':       /* print deletes, don't actually do them */
102             ++not;
103             break;
104         case 'r':
105                 prune = 1;
106                 break;
107         case 'v':       /* verbose mode */
108             verbose++;
109             break;
110         case 'M':
111                 /* enable Manage DSA IT */
112                 manageDSAit++;
113                 break;
114         case 'W':
115                 want_bindpw++;
116                 break;
117         case 'P':
118                 switch( atoi(optarg) )
119                 {
120                 case 2:
121                         version = LDAP_VERSION2;
122                         break;
123                 case 3:
124                         version = LDAP_VERSION3;
125                         break;
126                 default:
127                         fprintf( stderr, "protocol version should be 2 or 3\n" );
128                     fprintf( stderr, usage, argv[0] );
129                     return( EXIT_FAILURE );
130                 }
131                 break;
132         default:
133             fprintf( stderr, usage, argv[0] );
134             return( EXIT_FAILURE );
135         }
136     }
137
138         if( authmethod != LDAP_AUTH_SIMPLE ) {
139                 if( version == LDAP_VERSION3 ) {
140                         fprintf(stderr, "Kerberos requires LDAPv2\n");
141                         return EXIT_FAILURE;
142                 }
143                 version = LDAP_VERSION2;
144         }
145
146         if( manageDSAit ) {
147                 if( version == LDAP_VERSION2 ) {
148                         fprintf(stderr, "manage DSA control requires LDAPv3\n");
149                         return EXIT_FAILURE;
150                 }
151                 version = LDAP_VERSION3;
152         }
153
154     if ( fp == NULL ) {
155         if ( optind >= argc ) {
156             fp = stdin;
157         }
158     }
159
160         if ( debug ) {
161                 if( ber_set_option( NULL, LBER_OPT_DEBUG_LEVEL, &debug ) != LBER_OPT_SUCCESS ) {
162                         fprintf( stderr, "Could not set LBER_OPT_DEBUG_LEVEL %d\n", debug );
163                 }
164                 if( ldap_set_option( NULL, LDAP_OPT_DEBUG_LEVEL, &debug ) != LDAP_OPT_SUCCESS ) {
165                         fprintf( stderr, "Could not set LDAP_OPT_DEBUG_LEVEL %d\n", debug );
166                 }
167         }
168
169 #ifdef SIGPIPE
170         (void) SIGNAL( SIGPIPE, SIG_IGN );
171 #endif
172
173     if (( ld = ldap_init( ldaphost, ldapport )) == NULL ) {
174         perror( "ldap_init" );
175         return( EXIT_FAILURE );
176     }
177
178         {
179                 /* this seems prudent */
180                 int deref = LDAP_DEREF_NEVER;
181                 ldap_set_option( ld, LDAP_OPT_DEREF, &deref );
182         }
183
184         /* don't chase referrals */
185         ldap_set_option( ld, LDAP_OPT_REFERRALS, LDAP_OPT_OFF );
186
187         if (version != -1 &&
188                 ldap_set_option( ld, LDAP_OPT_PROTOCOL_VERSION, &version ) != LDAP_OPT_SUCCESS)
189         {
190                 fprintf( stderr, "Could not set LDAP_OPT_PROTOCOL_VERSION %d\n", version );
191         }
192
193         if (want_bindpw)
194                 passwd = getpass("Enter LDAP Password: ");
195
196     if ( ldap_bind_s( ld, binddn, passwd, authmethod ) != LDAP_SUCCESS ) {
197         ldap_perror( ld, "ldap_bind" );
198         return( EXIT_FAILURE );
199     }
200
201         if ( manageDSAit ) {
202                 int err;
203                 LDAPControl c;
204                 LDAPControl *ctrls[2];
205                 ctrls[0] = &c;
206                 ctrls[1] = NULL;
207
208                 c.ldctl_oid = LDAP_CONTROL_MANAGEDSAIT;
209                 c.ldctl_value.bv_val = NULL;
210                 c.ldctl_value.bv_len = 0;
211                 c.ldctl_iscritical = manageDSAit > 1;
212
213                 err = ldap_set_option( ld, LDAP_OPT_SERVER_CONTROLS, &ctrls );
214
215                 if( err != LDAP_OPT_SUCCESS ) {
216                         fprintf( stderr, "Could not set Manage DSA IT Control\n" );
217                         if( c.ldctl_iscritical ) {
218                                 exit( EXIT_FAILURE );
219                         }
220                 }
221         }
222
223         rc = 0;
224     if ( fp == NULL ) {
225         for ( ; optind < argc; ++optind ) {
226             rc = dodelete( ld, argv[ optind ] );
227         }
228     } else {
229         while ((rc == 0 || contoper) && fgets(buf, sizeof(buf), fp) != NULL) {
230             buf[ strlen( buf ) - 1 ] = '\0';    /* remove trailing newline */
231             if ( *buf != '\0' ) {
232                 rc = dodelete( ld, buf );
233             }
234         }
235     }
236
237     ldap_unbind( ld );
238
239         return( rc );
240 }
241
242
243 static int dodelete(
244     LDAP        *ld,
245     char        *dn)
246 {
247     int rc;
248
249     if ( verbose ) {
250         printf( "%sdeleting entry \"%s\"\n",
251                 (not ? "!" : ""), dn );
252     }
253     if ( not ) {
254         rc = LDAP_SUCCESS;
255     } else {
256                 /* If prune is on, remove a whole subtree.  Delete the children of the
257                  * DN recursively, then the DN requested.
258                  */
259                 if ( prune ) deletechildren( ld, dn );
260                 if (( rc = ldap_delete_s( ld, dn )) != LDAP_SUCCESS ) {
261                         ldap_perror( ld, "ldap_delete" );
262         } else if ( verbose ) {
263             printf( "\tremoved\n" );
264         }
265     }
266
267     return( rc );
268 }
269
270 /*
271  * Delete all the children of an entry recursively until leaf nodes are reached.
272  *
273  */
274 static int deletechildren( LDAP *ld,
275                            char *dn )
276 {
277     LDAPMessage *res, *e;
278     int entries;
279     int rc;
280         int timeout = 30 * 10000;
281
282     ldap_set_option( ld, LDAP_OPT_TIMEOUT, &timeout );
283     if ( verbose ) printf ( "deleting children of: %s\n", dn );
284     /*
285      * Do a one level search at dn for children.  For each, delete its children.
286      */
287     if ( ldap_search_s( ld, dn, LDAP_SCOPE_ONELEVEL, "(objectclass=*)", NULL, 0, &res ) == -1 )
288     {
289         ldap_perror( ld, "ldap_search" );
290                 ldap_get_option( ld, LDAP_OPT_ERROR_NUMBER, &rc );
291         return( rc );
292     }
293
294     entries = ldap_count_entries( ld, res );
295     if ( entries > 0 )
296     {
297         int i;
298
299         for (e = ldap_first_entry( ld, res ), i = 0; e != NULL;
300              e = ldap_next_entry( ld, e ), i++ )
301         {
302             if ( (rc = deletechildren( ld, ldap_get_dn( ld, e) )) == -1 )
303             {
304                 ldap_perror( ld, "ldap_prune" );
305                 return rc;
306             }
307             if ( verbose )
308             {
309                 printf( "\tremoving %s\n", ldap_get_dn( ld, e ) );
310             }
311             if ( rc = ldap_delete_s( ld, ldap_get_dn( ld, e ) ) == -1 )
312             {
313                 ldap_perror( ld, "ldap_delete" );
314                 return rc;
315             }
316             else if ( verbose )
317             {
318                 printf( "\t%s removed\n", ldap_get_dn( ld, e ) );
319             }
320         }
321     }
322     ldap_msgfree( res );
323     return rc;
324 }