]> git.sur5r.net Git - openldap/blob - clients/tools/ldapdelete.c
6351df28c86bd6ba7d34b599de194c88ab8990f6
[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 HAVE_KERBEROS
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 HAVE_KERBEROS
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 ( fp == NULL ) {
139         if ( optind >= argc ) {
140             fp = stdin;
141         }
142     }
143
144         if ( debug ) {
145                 if( ber_set_option( NULL, LBER_OPT_DEBUG_LEVEL, &debug ) != LBER_OPT_SUCCESS ) {
146                         fprintf( stderr, "Could not set LBER_OPT_DEBUG_LEVEL %d\n", debug );
147                 }
148                 if( ldap_set_option( NULL, LDAP_OPT_DEBUG_LEVEL, &debug ) != LDAP_OPT_SUCCESS ) {
149                         fprintf( stderr, "Could not set LDAP_OPT_DEBUG_LEVEL %d\n", debug );
150                 }
151         }
152
153 #ifdef SIGPIPE
154         (void) SIGNAL( SIGPIPE, SIG_IGN );
155 #endif
156
157     if (( ld = ldap_init( ldaphost, ldapport )) == NULL ) {
158         perror( "ldap_init" );
159         return( EXIT_FAILURE );
160     }
161
162         {
163                 /* this seems prudent */
164                 int deref = LDAP_DEREF_NEVER;
165                 ldap_set_option( ld, LDAP_OPT_DEREF, &deref );
166         }
167
168         /* don't chase referrals */
169         ldap_set_option( ld, LDAP_OPT_REFERRALS, LDAP_OPT_OFF );
170
171         if (want_bindpw)
172                 passwd = getpass("Enter LDAP Password: ");
173
174         if (version != -1 &&
175                 ldap_set_option( ld, LDAP_OPT_PROTOCOL_VERSION, &version ) != LDAP_OPT_SUCCESS)
176         {
177                 fprintf( stderr, "Could not set LDAP_OPT_PROTOCOL_VERSION %d\n", version );
178         }
179
180     if ( ldap_bind_s( ld, binddn, passwd, authmethod ) != LDAP_SUCCESS ) {
181         ldap_perror( ld, "ldap_bind" );
182         return( EXIT_FAILURE );
183     }
184
185         if ( manageDSAit ) {
186                 int err;
187                 LDAPControl c;
188                 LDAPControl *ctrls[2];
189                 ctrls[0] = &c;
190                 ctrls[1] = NULL;
191
192                 c.ldctl_oid = LDAP_CONTROL_MANAGEDSAIT;
193                 c.ldctl_value.bv_val = NULL;
194                 c.ldctl_value.bv_len = 0;
195                 c.ldctl_iscritical = manageDSAit > 1;
196
197                 err = ldap_set_option( ld, LDAP_OPT_SERVER_CONTROLS, &ctrls );
198
199                 if( err != LDAP_OPT_SUCCESS ) {
200                         fprintf( stderr, "Could not set Manage DSA IT Control\n" );
201                         if( c.ldctl_iscritical ) {
202                                 exit( EXIT_FAILURE );
203                         }
204                 }
205         }
206
207         rc = 0;
208     if ( fp == NULL ) {
209         for ( ; optind < argc; ++optind ) {
210             rc = dodelete( ld, argv[ optind ] );
211         }
212     } else {
213         while ((rc == 0 || contoper) && fgets(buf, sizeof(buf), fp) != NULL) {
214             buf[ strlen( buf ) - 1 ] = '\0';    /* remove trailing newline */
215             if ( *buf != '\0' ) {
216                 rc = dodelete( ld, buf );
217             }
218         }
219     }
220
221     ldap_unbind( ld );
222
223         return( rc );
224 }
225
226
227 static int dodelete(
228     LDAP        *ld,
229     char        *dn)
230 {
231     int rc;
232
233     if ( verbose ) {
234         printf( "%sdeleting entry \"%s\"\n",
235                 (not ? "!" : ""), dn );
236     }
237     if ( not ) {
238         rc = LDAP_SUCCESS;
239     } else {
240                 /* If prune is on, remove a whole subtree.  Delete the children of the
241                  * DN recursively, then the DN requested.
242                  */
243                 if ( prune ) deletechildren( ld, dn );
244                 if (( rc = ldap_delete_s( ld, dn )) != LDAP_SUCCESS ) {
245                         ldap_perror( ld, "ldap_delete" );
246         } else if ( verbose ) {
247             printf( "\tremoved\n" );
248         }
249     }
250
251     return( rc );
252 }
253
254 /*
255  * Delete all the children of an entry recursively until leaf nodes are reached.
256  *
257  */
258 static int deletechildren( LDAP *ld,
259                            char *dn )
260 {
261     LDAPMessage *res, *e;
262     int entries;
263     int rc;
264         int timeout = 30 * 10000;
265
266     ldap_set_option( ld, LDAP_OPT_TIMEOUT, &timeout );
267     if ( verbose ) printf ( "deleting children of: %s\n", dn );
268     /*
269      * Do a one level search at dn for children.  For each, delete its children.
270      */
271     if ( ldap_search_s( ld, dn, LDAP_SCOPE_ONELEVEL, "objectclass=*", NULL, 0, &res ) == -1 )
272     {
273         ldap_perror( ld, "ldap_search" );
274                 ldap_get_option( ld, LDAP_OPT_ERROR_NUMBER, &rc );
275         return( rc );
276     }
277
278     entries = ldap_count_entries( ld, res );
279     if ( entries > 0 )
280     {
281         int i;
282
283         for (e = ldap_first_entry( ld, res ), i = 0; e != NULL;
284              e = ldap_next_entry( ld, e ), i++ )
285         {
286             if ( (rc = deletechildren( ld, ldap_get_dn( ld, e) )) == -1 )
287             {
288                 ldap_perror( ld, "ldap_prune" );
289                 return rc;
290             }
291             if ( verbose )
292             {
293                 printf( "\tremoving %s\n", ldap_get_dn( ld, e ) );
294             }
295             if ( rc = ldap_delete_s( ld, ldap_get_dn( ld, e ) ) == -1 )
296             {
297                 ldap_perror( ld, "ldap_delete" );
298                 return rc;
299             }
300             else if ( verbose )
301             {
302                 printf( "\t%s removed\n", ldap_get_dn( ld, e ) );
303             }
304         }
305     }
306     ldap_msgfree( res );
307     return rc;
308 }