Home | History | Annotate | Line # | Download | only in tools
ldapmodrdn.c revision 1.1.1.6.6.1
      1  1.1.1.6.6.1    martin /*	$NetBSD: ldapmodrdn.c,v 1.1.1.6.6.1 2019/08/10 06:17:06 martin Exp $	*/
      2      1.1.1.2     lukem 
      3          1.1     lukem /* ldapmodrdn.c - generic program to modify an entry's RDN using LDAP */
      4      1.1.1.4      tron /* $OpenLDAP$ */
      5          1.1     lukem /* This work is part of OpenLDAP Software <http://www.openldap.org/>.
      6          1.1     lukem  *
      7  1.1.1.6.6.1    martin  * Copyright 1998-2019 The OpenLDAP Foundation.
      8          1.1     lukem  * Portions Copyright 1998-2003 Kurt D. Zeilenga.
      9          1.1     lukem  * Portions Copyright 1998-2001 Net Boolean Incorporated.
     10          1.1     lukem  * Portions Copyright 2001-2003 IBM Corporation.
     11          1.1     lukem  * All rights reserved.
     12          1.1     lukem  *
     13          1.1     lukem  * Redistribution and use in source and binary forms, with or without
     14          1.1     lukem  * modification, are permitted only as authorized by the OpenLDAP
     15          1.1     lukem  * Public License.
     16          1.1     lukem  *
     17          1.1     lukem  * A copy of this license is available in the file LICENSE in the
     18          1.1     lukem  * top-level directory of the distribution or, alternatively, at
     19          1.1     lukem  * <http://www.OpenLDAP.org/license.html>.
     20          1.1     lukem  */
     21          1.1     lukem /* Portions Copyright 1999, Juan C. Gomez, All rights reserved.
     22          1.1     lukem  * This software is not subject to any license of Silicon Graphics
     23          1.1     lukem  * Inc. or Purdue University.
     24          1.1     lukem  *
     25          1.1     lukem  * Redistribution and use in source and binary forms are permitted
     26          1.1     lukem  * without restriction or fee of any kind as long as this notice
     27          1.1     lukem  * is preserved.
     28          1.1     lukem  */
     29          1.1     lukem /* Portions Copyright (c) 1992-1996 Regents of the University of Michigan.
     30          1.1     lukem  * All rights reserved.
     31          1.1     lukem  *
     32          1.1     lukem  * Redistribution and use in source and binary forms are permitted
     33          1.1     lukem  * provided that this notice is preserved and that due credit is given
     34          1.1     lukem  * to the University of Michigan at Ann Arbor.  The name of the
     35          1.1     lukem  * University may not be used to endorse or promote products derived
     36          1.1     lukem  * from this software without specific prior written permission.  This
     37          1.1     lukem  * software is provided ``as is'' without express or implied warranty.
     38          1.1     lukem  */
     39          1.1     lukem /* ACKNOWLEDGEMENTS:
     40          1.1     lukem  * This work was originally developed by the University of Michigan
     41          1.1     lukem  * (as part of U-MICH LDAP).  Additional significant contributors
     42          1.1     lukem  * include:
     43      1.1.1.2     lukem  *	Kurt D. Zeilenga
     44      1.1.1.2     lukem  *	Juan C Gomez
     45          1.1     lukem  */
     46          1.1     lukem 
     47          1.1     lukem 
     48      1.1.1.5  christos #include <sys/cdefs.h>
     49  1.1.1.6.6.1    martin __RCSID("$NetBSD: ldapmodrdn.c,v 1.1.1.6.6.1 2019/08/10 06:17:06 martin Exp $");
     50      1.1.1.5  christos 
     51          1.1     lukem #include "portable.h"
     52          1.1     lukem 
     53          1.1     lukem #include <stdio.h>
     54          1.1     lukem 
     55          1.1     lukem #include <ac/stdlib.h>
     56          1.1     lukem 
     57          1.1     lukem #include <ac/ctype.h>
     58          1.1     lukem #include <ac/string.h>
     59          1.1     lukem #include <ac/unistd.h>
     60          1.1     lukem #include <ac/socket.h>
     61          1.1     lukem #include <ac/time.h>
     62          1.1     lukem 
     63          1.1     lukem #include <ldap.h>
     64          1.1     lukem #include "lutil.h"
     65          1.1     lukem #include "lutil_ldap.h"
     66          1.1     lukem #include "ldap_defaults.h"
     67          1.1     lukem 
     68          1.1     lukem #include "common.h"
     69          1.1     lukem 
     70          1.1     lukem 
     71          1.1     lukem static char	*newSuperior = NULL;
     72          1.1     lukem static int   remove_old_RDN = 0;
     73          1.1     lukem 
     74          1.1     lukem 
     75          1.1     lukem static int domodrdn(
     76      1.1.1.2     lukem 	LDAP	*ld,
     77      1.1.1.2     lukem 	char	*dn,
     78      1.1.1.2     lukem 	char	*rdn,
     79      1.1.1.2     lukem 	char	*newSuperior,
     80      1.1.1.2     lukem 	int		remove );	/* flag: remove old RDN */
     81          1.1     lukem 
     82          1.1     lukem void
     83          1.1     lukem usage( void )
     84          1.1     lukem {
     85          1.1     lukem 	fprintf( stderr, _("Rename LDAP entries\n\n"));
     86          1.1     lukem 	fprintf( stderr, _("usage: %s [options] [dn rdn]\n"), prog);
     87          1.1     lukem 	fprintf( stderr, _("	dn rdn: If given, rdn will replace the RDN of the entry specified by DN\n"));
     88          1.1     lukem 	fprintf( stderr, _("		If not given, the list of modifications is read from stdin or\n"));
     89          1.1     lukem 	fprintf( stderr, _("		from the file specified by \"-f file\" (see man page).\n"));
     90          1.1     lukem 	fprintf( stderr, _("Rename options:\n"));
     91      1.1.1.2     lukem  	fprintf( stderr, _("  -c         continuous operation mode (do not stop on errors)\n"));
     92      1.1.1.2     lukem  	fprintf( stderr, _("  -f file    read operations from `file'\n"));
     93      1.1.1.2     lukem  	fprintf( stderr, _("  -M         enable Manage DSA IT control (-MM to make critical)\n"));
     94      1.1.1.2     lukem  	fprintf( stderr, _("  -P version protocol version (default: 3)\n"));
     95      1.1.1.2     lukem 	fprintf( stderr, _("  -r		 remove old RDN\n"));
     96          1.1     lukem 	fprintf( stderr, _("  -s newsup  new superior entry\n"));
     97          1.1     lukem 	tool_common_usage();
     98          1.1     lukem 	exit( EXIT_FAILURE );
     99          1.1     lukem }
    100          1.1     lukem 
    101          1.1     lukem 
    102          1.1     lukem const char options[] = "rs:"
    103      1.1.1.2     lukem 	"cd:D:e:f:h:H:IMnNO:o:p:P:QR:U:vVw:WxX:y:Y:Z";
    104          1.1     lukem 
    105          1.1     lukem int
    106          1.1     lukem handle_private_option( int i )
    107          1.1     lukem {
    108          1.1     lukem 	switch ( i ) {
    109          1.1     lukem #if 0
    110          1.1     lukem 		int crit;
    111          1.1     lukem 		char *control, *cvalue;
    112          1.1     lukem 	case 'E': /* modrdn extensions */
    113          1.1     lukem 		if( protocol == LDAP_VERSION2 ) {
    114          1.1     lukem 			fprintf( stderr, _("%s: -E incompatible with LDAPv%d\n"),
    115          1.1     lukem 				prog, version );
    116          1.1     lukem 			exit( EXIT_FAILURE );
    117          1.1     lukem 		}
    118          1.1     lukem 
    119          1.1     lukem 		/* should be extended to support comma separated list of
    120          1.1     lukem 		 *	[!]key[=value] parameters, e.g.  -E !foo,bar=567
    121          1.1     lukem 		 */
    122          1.1     lukem 
    123          1.1     lukem 		crit = 0;
    124          1.1     lukem 		cvalue = NULL;
    125          1.1     lukem 		if( optarg[0] == '!' ) {
    126          1.1     lukem 			crit = 1;
    127          1.1     lukem 			optarg++;
    128          1.1     lukem 		}
    129          1.1     lukem 
    130          1.1     lukem 		control = strdup( optarg );
    131          1.1     lukem 		if ( (cvalue = strchr( control, '=' )) != NULL ) {
    132          1.1     lukem 			*cvalue++ = '\0';
    133          1.1     lukem 		}
    134          1.1     lukem 		fprintf( stderr, _("Invalid modrdn extension name: %s\n"), control );
    135          1.1     lukem 		usage();
    136          1.1     lukem #endif
    137          1.1     lukem 
    138          1.1     lukem 	case 'r':	/* remove old RDN */
    139      1.1.1.2     lukem 		remove_old_RDN++;
    140      1.1.1.2     lukem 		break;
    141          1.1     lukem 
    142          1.1     lukem 	case 's':	/* newSuperior */
    143          1.1     lukem 		if( protocol == LDAP_VERSION2 ) {
    144          1.1     lukem 			fprintf( stderr, _("%s: -X incompatible with LDAPv%d\n"),
    145          1.1     lukem 				prog, protocol );
    146          1.1     lukem 			exit( EXIT_FAILURE );
    147          1.1     lukem 		}
    148      1.1.1.2     lukem 		newSuperior = strdup( optarg );
    149      1.1.1.2     lukem 		protocol = LDAP_VERSION3;
    150      1.1.1.2     lukem 		break;
    151          1.1     lukem 
    152          1.1     lukem 	default:
    153          1.1     lukem 		return 0;
    154          1.1     lukem 	}
    155          1.1     lukem 	return 1;
    156          1.1     lukem }
    157          1.1     lukem 
    158          1.1     lukem 
    159          1.1     lukem int
    160          1.1     lukem main(int argc, char **argv)
    161          1.1     lukem {
    162      1.1.1.2     lukem 	char		*entrydn = NULL, *rdn = NULL, buf[ 4096 ];
    163      1.1.1.2     lukem 	FILE		*fp = NULL;
    164      1.1.1.4      tron 	LDAP		*ld = NULL;
    165          1.1     lukem 	int		rc, retval, havedn;
    166          1.1     lukem 
    167      1.1.1.2     lukem 	tool_init( TOOL_MODRDN );
    168      1.1.1.2     lukem 	prog = lutil_progname( "ldapmodrdn", argc, argv );
    169          1.1     lukem 
    170          1.1     lukem 	tool_args( argc, argv );
    171          1.1     lukem 
    172      1.1.1.2     lukem 	havedn = 0;
    173      1.1.1.2     lukem 	if (argc - optind == 2) {
    174      1.1.1.2     lukem 		if (( rdn = strdup( argv[argc - 1] )) == NULL ) {
    175      1.1.1.2     lukem 			perror( "strdup" );
    176      1.1.1.2     lukem 			retval = EXIT_FAILURE;
    177      1.1.1.2     lukem 			goto fail;
    178      1.1.1.2     lukem 		}
    179      1.1.1.2     lukem 		if (( entrydn = strdup( argv[argc - 2] )) == NULL ) {
    180      1.1.1.2     lukem 			perror( "strdup" );
    181      1.1.1.2     lukem 			retval = EXIT_FAILURE;
    182      1.1.1.2     lukem 			goto fail;
    183      1.1.1.2     lukem 		}
    184      1.1.1.2     lukem 		++havedn;
    185      1.1.1.2     lukem 	} else if ( argc - optind != 0 ) {
    186      1.1.1.2     lukem 		fprintf( stderr, _("%s: invalid number of arguments (%d), only two allowed\n"), prog, argc-optind );
    187      1.1.1.2     lukem 		usage();
    188      1.1.1.2     lukem 	}
    189      1.1.1.2     lukem 
    190      1.1.1.2     lukem 	if ( infile != NULL ) {
    191      1.1.1.2     lukem 		if (( fp = fopen( infile, "r" )) == NULL ) {
    192      1.1.1.2     lukem 			perror( infile );
    193      1.1.1.2     lukem 			retval = EXIT_FAILURE;
    194      1.1.1.2     lukem 			goto fail;
    195      1.1.1.2     lukem 		}
    196      1.1.1.2     lukem 	} else {
    197      1.1.1.2     lukem 		fp = stdin;
    198      1.1.1.2     lukem 	}
    199          1.1     lukem 
    200          1.1     lukem 	ld = tool_conn_setup( 0, 0 );
    201          1.1     lukem 
    202          1.1     lukem 	tool_bind( ld );
    203          1.1     lukem 
    204          1.1     lukem 	tool_server_controls( ld, NULL, 0 );
    205          1.1     lukem 
    206      1.1.1.2     lukem 	retval = rc = 0;
    207      1.1.1.2     lukem 	if (havedn)
    208      1.1.1.2     lukem 		retval = domodrdn( ld, entrydn, rdn, newSuperior, remove_old_RDN );
    209      1.1.1.2     lukem 	else while ((rc == 0 || contoper) && fgets(buf, sizeof(buf), fp) != NULL) {
    210      1.1.1.2     lukem 		if ( *buf != '\n' ) {	/* blank lines optional, skip */
    211      1.1.1.2     lukem 			buf[ strlen( buf ) - 1 ] = '\0';	/* remove nl */
    212      1.1.1.2     lukem 
    213      1.1.1.2     lukem 			if ( havedn ) {	/* have DN, get RDN */
    214      1.1.1.2     lukem 				if (( rdn = strdup( buf )) == NULL ) {
    215      1.1.1.2     lukem 					perror( "strdup" );
    216      1.1.1.2     lukem 					retval = EXIT_FAILURE;
    217      1.1.1.2     lukem 					goto fail;
    218      1.1.1.2     lukem 				}
    219      1.1.1.2     lukem 				rc = domodrdn(ld, entrydn, rdn, newSuperior, remove_old_RDN );
    220      1.1.1.2     lukem 				if ( rc != 0 )
    221      1.1.1.2     lukem 					retval = rc;
    222      1.1.1.2     lukem 				havedn = 0;
    223      1.1.1.2     lukem 				free( rdn ); rdn = NULL;
    224      1.1.1.2     lukem 				free( entrydn ); entrydn = NULL;
    225      1.1.1.2     lukem 			} else if ( !havedn ) {	/* don't have DN yet */
    226      1.1.1.2     lukem 				if (( entrydn = strdup( buf )) == NULL ) {
    227      1.1.1.2     lukem 					retval = EXIT_FAILURE;
    228      1.1.1.2     lukem 					goto fail;
    229      1.1.1.2     lukem 				}
    230      1.1.1.2     lukem 				++havedn;
    231      1.1.1.2     lukem 			}
    232      1.1.1.2     lukem 		}
    233          1.1     lukem 	}
    234          1.1     lukem 
    235      1.1.1.2     lukem fail:
    236      1.1.1.2     lukem 	if ( fp && fp != stdin ) fclose( fp );
    237      1.1.1.2     lukem 	if ( entrydn ) free( entrydn );
    238      1.1.1.2     lukem 	if ( rdn ) free( rdn );
    239      1.1.1.4      tron 	tool_exit( ld, retval );
    240          1.1     lukem }
    241          1.1     lukem 
    242          1.1     lukem static int domodrdn(
    243      1.1.1.2     lukem 	LDAP	*ld,
    244      1.1.1.2     lukem 	char	*dn,
    245      1.1.1.2     lukem 	char	*rdn,
    246      1.1.1.2     lukem 	char	*newSuperior,
    247      1.1.1.2     lukem 	int		remove ) /* flag: remove old RDN */
    248          1.1     lukem {
    249          1.1     lukem 	int rc, code, id;
    250          1.1     lukem 	char *matcheddn=NULL, *text=NULL, **refs=NULL;
    251          1.1     lukem 	LDAPControl **ctrls = NULL;
    252          1.1     lukem 	LDAPMessage *res;
    253          1.1     lukem 
    254      1.1.1.2     lukem 	if ( verbose ) {
    255          1.1     lukem 		printf( _("Renaming \"%s\"\n"), dn );
    256          1.1     lukem 		printf( _("\tnew rdn=\"%s\" (%s old rdn)\n"),
    257          1.1     lukem 			rdn, remove ? _("delete") : _("keep") );
    258          1.1     lukem 		if( newSuperior != NULL ) {
    259          1.1     lukem 			printf(_("\tnew parent=\"%s\"\n"), newSuperior);
    260          1.1     lukem 		}
    261          1.1     lukem 	}
    262          1.1     lukem 
    263          1.1     lukem 	if( dont ) return LDAP_SUCCESS;
    264          1.1     lukem 
    265          1.1     lukem 	rc = ldap_rename( ld, dn, rdn, newSuperior, remove,
    266          1.1     lukem 		NULL, NULL, &id );
    267          1.1     lukem 
    268          1.1     lukem 	if ( rc != LDAP_SUCCESS ) {
    269          1.1     lukem 		fprintf( stderr, "%s: ldap_rename: %s (%d)\n",
    270          1.1     lukem 			prog, ldap_err2string( rc ), rc );
    271          1.1     lukem 		return rc;
    272          1.1     lukem 	}
    273          1.1     lukem 
    274          1.1     lukem 	for ( ; ; ) {
    275          1.1     lukem 		struct timeval	tv = { 0, 0 };
    276          1.1     lukem 
    277          1.1     lukem 		if ( tool_check_abandon( ld, id ) ) {
    278          1.1     lukem 			return LDAP_CANCELLED;
    279          1.1     lukem 		}
    280          1.1     lukem 
    281          1.1     lukem 		tv.tv_sec = 0;
    282          1.1     lukem 		tv.tv_usec = 100000;
    283          1.1     lukem 
    284          1.1     lukem 		rc = ldap_result( ld, LDAP_RES_ANY, LDAP_MSG_ALL, &tv, &res );
    285          1.1     lukem 		if ( rc < 0 ) {
    286          1.1     lukem 			tool_perror( "ldap_result", rc, NULL, NULL, NULL, NULL );
    287          1.1     lukem 			return rc;
    288          1.1     lukem 		}
    289          1.1     lukem 
    290          1.1     lukem 		if ( rc != 0 ) {
    291          1.1     lukem 			break;
    292          1.1     lukem 		}
    293          1.1     lukem 	}
    294          1.1     lukem 
    295          1.1     lukem 	rc = ldap_parse_result( ld, res, &code, &matcheddn, &text, &refs, &ctrls, 1 );
    296          1.1     lukem 
    297          1.1     lukem 	if( rc != LDAP_SUCCESS ) {
    298          1.1     lukem 		fprintf( stderr, "%s: ldap_parse_result: %s (%d)\n",
    299          1.1     lukem 			prog, ldap_err2string( rc ), rc );
    300          1.1     lukem 		return rc;
    301          1.1     lukem 	}
    302          1.1     lukem 
    303          1.1     lukem 	if( verbose || code != LDAP_SUCCESS ||
    304          1.1     lukem 		(matcheddn && *matcheddn) || (text && *text) || (refs && *refs) )
    305          1.1     lukem 	{
    306          1.1     lukem 		printf( _("Rename Result: %s (%d)\n"),
    307          1.1     lukem 			ldap_err2string( code ), code );
    308          1.1     lukem 
    309          1.1     lukem 		if( text && *text ) {
    310          1.1     lukem 			printf( _("Additional info: %s\n"), text );
    311          1.1     lukem 		}
    312          1.1     lukem 
    313          1.1     lukem 		if( matcheddn && *matcheddn ) {
    314          1.1     lukem 			printf( _("Matched DN: %s\n"), matcheddn );
    315          1.1     lukem 		}
    316          1.1     lukem 
    317          1.1     lukem 		if( refs ) {
    318          1.1     lukem 			int i;
    319          1.1     lukem 			for( i=0; refs[i]; i++ ) {
    320          1.1     lukem 				printf(_("Referral: %s\n"), refs[i] );
    321          1.1     lukem 			}
    322          1.1     lukem 		}
    323          1.1     lukem 	}
    324          1.1     lukem 
    325          1.1     lukem 	if (ctrls) {
    326          1.1     lukem 		tool_print_ctrls( ld, ctrls );
    327          1.1     lukem 		ldap_controls_free( ctrls );
    328      1.1.1.2     lukem 	}
    329          1.1     lukem 
    330          1.1     lukem 	ber_memfree( text );
    331          1.1     lukem 	ber_memfree( matcheddn );
    332          1.1     lukem 	ber_memvfree( (void **) refs );
    333          1.1     lukem 
    334          1.1     lukem 	return code;
    335          1.1     lukem }
    336