Exemplo n.º 1
0
static char *
get_add_entry( char *filename, LDAPMod ***mods )
{
	FILE    *fp;
	char    *entry = NULL;

	if ( (fp = fopen( filename, "r" )) != NULL ) {
		char  line[BUFSIZ];

		if ( fgets( line, BUFSIZ, fp )) {
			char *nl;

			if (( nl = strchr( line, '\r' )) || ( nl = strchr( line, '\n' )))
				*nl = '\0';
			nl = line;
			if ( !strncasecmp( nl, "dn: ", 4 ))
				nl += 4;
			entry = strdup( nl );

		}

		while ( fgets( line, BUFSIZ, fp )) {
			char	*nl;
			char	*value;

			if (( nl = strchr( line, '\r' )) || ( nl = strchr( line, '\n' )))
				*nl = '\0';

			if ( *line == '\0' ) break;
			if ( !( value = strchr( line, ':' ))) break;

			*value++ = '\0'; 
			while ( *value && isspace( (unsigned char) *value ))
				value++;

			addmodifyop( mods, LDAP_MOD_ADD, line, value, strlen( value ));

		}
		fclose( fp );
	}

	return( entry );
}
Exemplo n.º 2
0
process_ldif_rec( char *rbuf )
#endif
{
    char	*line, *dn, *type, *value, *newrdn, *newparent, *p;
    char	*ctrl_oid=NULL, *ctrl_value=NULL;
    int 	ctrl_criticality=1;
    LDAPControl *ldctrl;
    int		rc, linenum, vlen, modop, replicaport;
    int		expect_modop, expect_sep, expect_chgtype_or_control, expect_newrdn;
    int		expect_deleteoldrdn, expect_newparent, rename, moddn;
    int		deleteoldrdn, saw_replica, use_record, new_entry, delete_entry;
    int         got_all, got_value;
    LDAPMod	**pmods;

    new_entry = newval;

    rc = got_all = saw_replica = delete_entry = expect_modop = 0;
    expect_deleteoldrdn = expect_newrdn = expect_newparent = expect_sep = 0;
    expect_chgtype_or_control = linenum = got_value = rename = moddn = 0;
    deleteoldrdn = 1;
    use_record = force;
    pmods = NULL;
    dn = newrdn = newparent = NULL;

#ifdef SOLARIS_LDAP_CMD
    while ( rc == 0 && ( line = str_getline( &rbuf )) != NULL ) {
#else
    while ( rc == 0 && ( line = ldif_getline( &rbuf )) != NULL ) {
#endif	/* SOLARIS_LDAP_CMD */
	++linenum;
	if ( expect_sep && strcasecmp( line, T_MODSEPSTR ) == 0 ) {
	    expect_sep = 0;
	    expect_modop = 1;
	    
	    /*If we see a separator in the input stream,
	     but we didn't get a value from the last modify
	     then we have to fill pmods with an empty value*/
	    if (modop == LDAP_MOD_REPLACE && !got_value){
	      addmodifyop( &pmods, modop, value, NULL, 0);
	    }

	    got_value = 0;
	    continue;
	}
	
#ifdef SOLARIS_LDAP_CMD
	if ( str_parse_line( line, &type, &value, &vlen ) < 0 ) {
#else
	if ( ldif_parse_line( line, &type, &value, &vlen ) < 0 ) {
#endif	/* SOLARIS_LDAP_CMD */
	    fprintf( stderr, gettext("%s: invalid format (line %d of entry: %s)\n"),
		    ldaptool_progname, linenum, dn == NULL ? "" : dn );
	    fprintf( stderr, gettext("%s: line contents: (%s)\n"),
		    ldaptool_progname, line );
	    rc = LDAP_PARAM_ERROR;
	    break;
	}

evaluate_line:
	if ( dn == NULL ) {
	    if ( !use_record && strcasecmp( type, T_REPLICA_STR ) == 0 ) {
		++saw_replica;
		if (( p = strchr( value, ':' )) == NULL ) {
		    replicaport = LDAP_PORT;
		} else {
		    *p++ = '\0';
		    replicaport = atoi( p );
		}
		if ( strcasecmp( value, ldaptool_host ) == 0 &&
			replicaport == ldaptool_port ) {
		    use_record = 1;
		}

	    } else if ( strcasecmp( type, T_DN_STR ) == 0 ) {
		if (( dn = strdup( value )) == NULL ) {
		    perror( "strdup" );
		    exit( LDAP_NO_MEMORY );
		}
		expect_chgtype_or_control = 1;

	    } else if ( strcasecmp( type, T_VERSION_STR ) == 0 ) {
		ldif_version = atoi( value );
		if ( ldif_version != LDIF_VERSION_ONE ) {
		    fprintf( stderr, gettext("%s:  LDIF version %d is not supported;"
			" use version: %d\n"), ldaptool_progname, ldif_version,
			LDIF_VERSION_ONE );
		    exit( LDAP_PARAM_ERROR );
		}
		if ( ldaptool_verbose ) {
		    printf( gettext("Processing a version %d LDIF file...\n"),
			    ldif_version );
		}
		
		/* Now check if there's something left to process   */
		/* and if not, go get the new record, else continue */
		if ( *rbuf == '\0' ) {
			return( 0 );
		}

	    } else if ( !saw_replica ) {
		printf( gettext("%s: skipping change record: no dn: line\n"),
			ldaptool_progname );
		return( 0 );
	    }

	    continue; /* skip all lines until we see "dn:" */
	}

	if ( expect_chgtype_or_control ) {
	    expect_chgtype_or_control = 0;
	    if ( !use_record && saw_replica ) {
		printf( gettext("%s: skipping change record for entry: %s\n\t(LDAP host/port does not match replica: lines)\n"),
			ldaptool_progname, dn );
		free( dn );
		return( 0 );
	    }

#ifndef SOLARIS_LDAP_CMD
	    if ( strcasecmp( type, "control" ) == 0 ) {
		value = strdup_and_trim( value );
		if (ldaptool_parse_ctrl_arg(value, ' ', &ctrl_oid, 
			&ctrl_criticality, &ctrl_value, &vlen)) {
			    usage();
		}
        	ldctrl = calloc(1,sizeof(LDAPControl));
        	if (ctrl_value) {
        	    rc = ldaptool_berval_from_ldif_value( ctrl_value, vlen,
			 &(ldctrl->ldctl_value),
			 1 /* recognize file URLs */, 0 /* always try file */,
            		 1 /* report errors */ );
        	    if ((rc = ldaptool_fileurlerr2ldaperr( rc )) != LDAP_SUCCESS) {
            		fprintf( stderr, gettext("Unable to parse %s\n"), ctrl_value);
            		usage();
        	    }
        	}
        	ldctrl->ldctl_oid = ctrl_oid;
        	ldctrl->ldctl_iscritical = ctrl_criticality;
        	ldaptool_add_control_to_array(ldctrl, ldaptool_request_ctrls);
		expect_chgtype_or_control = 1;
		continue;
	    }
#endif /* SOLARIS_LDAP_CMD */

	    if ( strcasecmp( type, T_CHANGETYPESTR ) == 0 ) {
		value = strdup_and_trim( value );
		if ( strcasecmp( value, T_MODIFYCTSTR ) == 0 ) {
		    new_entry = 0;
		    expect_modop = 1;
		} else if ( strcasecmp( value, T_ADDCTSTR ) == 0 ) {
		    new_entry = 1;
		    modop = LDAP_MOD_ADD;
		} else if ( strcasecmp( value, T_MODRDNCTSTR ) == 0 ) {
		    expect_newrdn = 1;
		    moddn = 1;
		} else if ( strcasecmp( value, T_MODDNCTSTR ) == 0 ) {
		    expect_newrdn = 1;
		    moddn = 1;
		} else if ( strcasecmp( value, T_RENAMECTSTR ) == 0 ) {
		    expect_newrdn = 1;
		    rename = 1;
		} else if ( strcasecmp( value, T_DELETECTSTR ) == 0 ) {
		    got_all = delete_entry = 1;
		} else {
		    fprintf( stderr,
			    gettext("%s:  unknown %s \"%s\" (line %d of entry: %s)\n"),
			    ldaptool_progname, T_CHANGETYPESTR, value,
			    linenum, dn );
		    rc = LDAP_PARAM_ERROR;
		}
		free( value );
		continue;
	    } else if ( newval ) {		/*  missing changetype => add */
		new_entry = 1;
		modop = LDAP_MOD_ADD;
	    } else {
	      /*The user MUST put in changetype: blah
	       unless adding a new entry with either -a or ldapadd*/
		fprintf(stderr, gettext("%s: Missing changetype operation specification.\n\tThe dn line must be followed by \"changetype: operation\"\n\t(unless ldapmodify is called with -a option)\n\twhere operation is add|delete|modify|modrdn|moddn|rename\n\t\"%s\" is not a valid changetype operation specification\n\t(line %d of entry %s)\n"), 
		ldaptool_progname, type, linenum, dn);
		rc = LDAP_PARAM_ERROR;
		/*expect_modop = 1;	 missing changetype => modify */
	    }
	}

	if ( expect_modop ) {
	    expect_modop = 0;
	    expect_sep = 1;
	    if ( strcasecmp( type, T_MODOPADDSTR ) == 0 ) {
		modop = LDAP_MOD_ADD;
		continue;
	    } else if ( strcasecmp( type, T_MODOPREPLACESTR ) == 0 ) {
		modop = LDAP_MOD_REPLACE;
		continue;
	    } else if ( strcasecmp( type, T_MODOPDELETESTR ) == 0 ) {
		modop = LDAP_MOD_DELETE;
		addmodifyop( &pmods, modop, value, NULL, 0 );
		continue;
#ifdef SOLARIS_LDAP_CMD
	    }  else { /* no modify op: use default */
		modop = replace ? LDAP_MOD_REPLACE : LDAP_MOD_ADD;
	    }
#else
	    }  else { /*Bug 27479. Remove default add operation*/ 
	      fprintf(stderr, gettext("%s: Invalid parameter \"%s\" specified for changetype modify (line %d of entry %s)\n"), 
		      ldaptool_progname, type, linenum, dn);
	      rc = LDAP_PARAM_ERROR;
	    }
#endif	/* SOLARIS_LDAP_CMD */

	  }

	if ( expect_newrdn ) {
	    if ( strcasecmp( type, T_NEWRDNSTR ) == 0 ) {
		if ( *value == '\0' ) {
		    fprintf( stderr,
			    gettext("%s: newrdn value missing (line %d of entry: %s)\n"),
			    ldaptool_progname, linenum, dn == NULL ? "" : dn );
		    rc = LDAP_PARAM_ERROR;
		} else if (( newrdn = strdup( value )) == NULL ) {
		    perror( "strdup" );
		    exit( LDAP_NO_MEMORY );
		} else {
		    expect_newrdn = 0;
		    if ( rename ) {
			expect_newparent = 1;
		    } else {
			expect_deleteoldrdn = 1;
		    }
		}
	    } else {
		fprintf( stderr, gettext("%s: expecting \"%s:\" but saw \"%s:\" (line %d of entry %s)\n"),
			ldaptool_progname, T_NEWRDNSTR, type, linenum, dn );
		rc = LDAP_PARAM_ERROR;
	    }
	} else if ( expect_newparent ) {
	    expect_newparent = 0;
	    if ( rename ) {
		expect_deleteoldrdn = 1;
	    }
	    if ( strcasecmp( type, T_NEWPARENTSTR ) == 0
		    || strcasecmp( type, T_NEWSUPERIORSTR ) == 0 ) {
		if (( newparent = strdup( value )) == NULL ) {
		    perror( "strdup" );
		    exit( LDAP_NO_MEMORY );
		}
	    } else {
		/* Since this is an optional argument for rename/moddn, cause
		 * the current line to be re-evaluated if newparent doesn't
		 * follow deleteoldrdn.
		 */
		newparent = NULL;  
		goto evaluate_line;
	    }
	} else if ( expect_deleteoldrdn ) {
	    if ( strcasecmp( type, T_DELETEOLDRDNSTR ) == 0 ) {
		if ( *value == '\0' ) {
		    fprintf( stderr,
			    gettext("%s: missing 0 or 1 (line %d of entry: %s)\n"),
			    ldaptool_progname, linenum, dn == NULL ? "" : dn );
		    rc = LDAP_PARAM_ERROR;
		} else {
		    deleteoldrdn = ( *value == '0' ) ? 0 : 1;
		    expect_deleteoldrdn = 0;
		    if ( moddn ) {
			expect_newparent = 1;
		    }
		}
	    } else {
		fprintf( stderr, gettext("%s: expecting \"%s:\" but saw \"%s:\" (line %d of entry %s)\n"),
			ldaptool_progname, T_DELETEOLDRDNSTR, type, linenum,
			dn );
		rc = LDAP_PARAM_ERROR;
	    }
	    got_all = 1;
	} else if ( got_all ) {
	    fprintf( stderr,
		    gettext("%s: extra lines at end (line %d of entry %s)\n"),
		    ldaptool_progname, linenum, dn );
	    rc = LDAP_PARAM_ERROR;
	    got_all = 1;
	} else {
	    addmodifyop( &pmods, modop, type, value, vlen );
	    /*There was a value to replace*/
	    got_value = 1;

	}
    }

    if ( rc == 0 ) {
	if ( delete_entry ) {
#ifdef SOLARIS_LDAP_CMD
	    rc = dodelete( ld, dn );
#else
	    rc = dodelete( dn );
#endif	/* SOLARIS_LDAP_CMD */
	} else if ( newrdn != NULL ) {
#ifdef SOLARIS_LDAP_CMD
	    rc = dorename( ld, dn, newrdn, newparent, deleteoldrdn );
#else
	    rc = dorename( dn, newrdn, newparent, deleteoldrdn );
#endif	/* SOLARIS_LDAP_CMD */
	    rename = 0;
	} else {

	  /*Patch to fix Bug 22183
	    If pmods is null, then there is no
	    attribute to replace, so we alloc
	    an empty pmods*/
	  if (modop == LDAP_MOD_REPLACE && !got_value && expect_sep){
	    addmodifyop( &pmods, modop, value, NULL, 0);
	  }/*End Patch*/
	  
	  
#ifdef SOLARIS_LDAP_CMD
	  rc = domodify( ld, dn, pmods, new_entry );
#else
	  rc = domodify( dn, pmods, new_entry );
#endif	/* SOLARIS_LDAP_CMD */
	}

	if ( rc == LDAP_SUCCESS ) {
	    rc = 0;
	}
    }

    if ( dn != NULL ) {
	free( dn );
    }
    if ( newrdn != NULL ) {
	free( newrdn );
    }
    if ( newparent != NULL ) {
	free( newparent );
    }
    if ( pmods != NULL ) {
	freepmods( pmods );
    }

    return( rc );
}


static int
#ifdef SOLARIS_LDAP_CMD
process_ldapmod_rec( LDAP *ld, char *rbuf )
#else
process_ldapmod_rec( char *rbuf )
#endif	/* SOLARIS_LDAP_CMD */
{
    char	*line, *dn, *p, *q, *attr, *value;
    int		rc, linenum, modop;
    LDAPMod	**pmods;

    pmods = NULL;
    dn = NULL;
    linenum = 0;
    line = rbuf;
    rc = 0;

    while ( rc == 0 && rbuf != NULL && *rbuf != '\0' ) {
	++linenum;
	if (( p = strchr( rbuf, '\n' )) == NULL ) {
	    rbuf = NULL;
	} else {
	    if ( *(p-1) == '\\' ) {	/* lines ending in '\' are continued */
		strcpy( p - 1, p );
		rbuf = p;
		continue;
	    }
	    *p++ = '\0';
	    rbuf = p;
	}

	if ( dn == NULL ) {	/* first line contains DN */
	    if (( dn = strdup( line )) == NULL ) {
		perror( "strdup" );
		exit( LDAP_NO_MEMORY );
	    }
	} else {
	    if (( p = strchr( line, '=' )) == NULL ) {
		value = NULL;
		p = line + strlen( line );
	    } else {
		*p++ = '\0';
		value = p;
	    }

	    for ( attr = line; *attr != '\0' && isspace( *attr ); ++attr ) {
		;	/* skip attribute leading white space */
	    }

	    for ( q = p - 1; q > attr && isspace( *q ); --q ) {
		*q = '\0';	/* remove attribute trailing white space */
	    }

	    if ( value != NULL ) {
		while ( isspace( *value )) {
		    ++value;		/* skip value leading white space */
		}
		for ( q = value + strlen( value ) - 1; q > value &&
			isspace( *q ); --q ) {
		    *q = '\0';	/* remove value trailing white space */
		}
		if ( *value == '\0' ) {
		    value = NULL;
		}

	    }

	    if ( value == NULL && newval ) {
		fprintf( stderr, gettext("%s: missing value on line %d (attr is %s)\n"),
			ldaptool_progname, linenum, attr );
		rc = LDAP_PARAM_ERROR;
	    } else {
		 switch ( *attr ) {
		case '-':
		    modop = LDAP_MOD_DELETE;
		    ++attr;
		    break;
		case '+':
		    modop = LDAP_MOD_ADD;
		    ++attr;
		    break;
		default:
#ifdef SOLARIS_LDAP_CMD
		    modop = replace ? LDAP_MOD_REPLACE : LDAP_MOD_ADD;
#else
		    /*Bug 27479. Remove the add default*/
		      fprintf(stderr, gettext("%s: Invalid parameter specified for changetype modify (line %d of entry %s)\n"), 
		      ldaptool_progname, linenum, dn);
		      rc = LDAP_PARAM_ERROR;
#endif	/* SOLARIS_LDAP_CMD */
		}

		addmodifyop( &pmods, modop, attr, value,
			( value == NULL ) ? 0 : strlen( value ));
	    }
	}

	line = rbuf;
    }

    if ( rc == 0 ) {
	if ( dn == NULL ) {
	    rc = LDAP_PARAM_ERROR;
#ifdef SOLARIS_LDAP_CMD
	} else if (( rc = domodify( ld, dn, pmods, newval )) == LDAP_SUCCESS ){
#else
	} else if (( rc = domodify( dn, pmods, newval )) == LDAP_SUCCESS ){
#endif	/* SOLARIS_LDAP_CMD */
	  rc = 0;
	}
      }
    
    if ( pmods != NULL ) {
	freepmods( pmods );
    }
    if ( dn != NULL ) {
	free( dn );
    }

    return( rc );
}