static void op_remove(diversion *diversions, const char *file) { diversion *d; for (d = diversions; d; d = d->next) { if (strcmp(d->contest, file) == 0) { if (divertto && strcmp(d->altname, divertto) != 0) ohshit(_("mismatch on divert-to\n" "when removing '%s'\n" "found '%s"), infoa(file), infon(d)); if (package && strcmp(d->package, package) != 0) ohshit(_("mismatch on package\n" "when removing '%s'\n" "found '%s'"), infoa(file), infon(d)); if (!quiet) printf(_("Removing '%s'\n"), infon(d)); checkrename(d->altname, d->contest); dorename(d->altname, d->contest); diversions = diversions_remove(diversions, d); save(diversions); exit(0); } } if (!quiet) { printf(_("No diversion '%s', none removed"), infoa(file)); putchar('\n'); } exit(0); }
int cmd_mv(int argc, char *argv[]) { if (argc!=3) { warnx("Usage: mv oldfile newfile"); return 0; } dorename(argv[1], argv[2]); return 0; }
static void rename_proc(void) { char name1[NAMESIZE], name2[NAMESIZE]; int ct; for (ct=0; ct<NTRIES; ct++) { choose_name(name1, sizeof(name1)); choose_name(name2, sizeof(name2)); say("pid %2d: rename %s -> %s\n", (int)getpid(), name1, name2); dorename(name1, name2); } }
static int process_ldif_rec( char *rbuf, int linenum ) { char *line, *dn, *newrdn, *newsup; int rc, modop; int expect_modop, expect_sep; int deleteoldrdn; int new_entry, delete_entry, got_all; LDAPMod **pmods, *lm = NULL; int version; LDAPControl **pctrls; int i, j, k, lines, idn, nmods; struct berval *btype, *vals, **bvl, bv; char *freeval; unsigned char *mops = NULL; new_entry = ldapadd; rc = got_all = delete_entry = modop = expect_modop = 0; expect_sep = 0; version = 0; deleteoldrdn = 1; pmods = NULL; pctrls = NULL; dn = newrdn = newsup = NULL; lines = ldif_countlines( rbuf ); btype = ber_memcalloc( 1, (lines+1)*2*sizeof(struct berval)+lines ); if ( !btype ) return LDAP_NO_MEMORY; vals = btype+lines+1; freeval = (char *)(vals+lines+1); i = -1; while ( rc == 0 && ( line = ldif_getline( &rbuf )) != NULL ) { int freev; if ( *line == '\n' || *line == '\0' ) { break; } ++i; if ( line[0] == '-' && !line[1] ) { BER_BVZERO( btype+i ); freeval[i] = 0; continue; } if ( ( rc = ldif_parse_line2( line, btype+i, vals+i, &freev ) ) < 0 ) { fprintf( stderr, _("%s: invalid format (line %d) entry: \"%s\"\n"), prog, linenum+i, dn == NULL ? "" : dn ); rc = LDAP_PARAM_ERROR; break; } freeval[i] = freev; if ( dn == NULL ) { if ( linenum+i == 1 && BV_CASEMATCH( btype+i, &BV_VERSION )) { int v; if( vals[i].bv_len == 0 || lutil_atoi( &v, vals[i].bv_val) != 0 || v != 1 ) { fprintf( stderr, _("%s: invalid version %s, line %d (ignored)\n"), prog, vals[i].bv_val, linenum ); } version++; } else if ( BV_CASEMATCH( btype+i, &BV_DN )) { dn = vals[i].bv_val; idn = i; } /* skip all lines until we see "dn:" */ } } /* check to make sure there was a dn: line */ if ( !dn ) { rc = 0; goto leave; } lines = i+1; if( lines == 0 ) { rc = 0; goto leave; } if( version && lines == 1 ) { rc = 0; goto leave; } i = idn+1; /* Check for "control" tag after dn and before changetype. */ if ( BV_CASEMATCH( btype+i, &BV_CONTROL )) { /* Parse and add it to the list of controls */ rc = parse_ldif_control( vals+i, &pctrls ); if (rc != 0) { fprintf( stderr, _("%s: Error processing %s line, line %d: %s\n"), prog, BV_CONTROL.bv_val, linenum+i, ldap_err2string(rc) ); } i++; if ( i>= lines ) { short_input: fprintf( stderr, _("%s: Expecting more input after %s line, line %d\n"), prog, btype[i-1].bv_val, linenum+i ); rc = LDAP_PARAM_ERROR; goto leave; } } /* Check for changetype */ if ( BV_CASEMATCH( btype+i, &BV_CHANGETYPE )) { #ifdef LIBERAL_CHANGETYPE_MODOP /* trim trailing spaces (and log warning ...) */ int icnt; for ( icnt = vals[i].bv_len; --icnt > 0; ) { if ( !isspace( (unsigned char) vals[i].bv_val[icnt] ) ) { break; } } if ( ++icnt != vals[i].bv_len ) { fprintf( stderr, _("%s: illegal trailing space after" " \"%s: %s\" trimmed (line %d, entry \"%s\")\n"), prog, BV_CHANGETYPE.bv_val, vals[i].bv_val, linenum+i, dn ); vals[i].bv_val[icnt] = '\0'; } #endif /* LIBERAL_CHANGETYPE_MODOP */ if ( BV_CASEMATCH( vals+i, &BV_MODIFYCT )) { new_entry = 0; expect_modop = 1; } else if ( BV_CASEMATCH( vals+i, &BV_ADDCT )) { new_entry = 1; modop = LDAP_MOD_ADD; } else if ( BV_CASEMATCH( vals+i, &BV_MODRDNCT ) || BV_CASEMATCH( vals+i, &BV_MODDNCT ) || BV_CASEMATCH( vals+i, &BV_RENAMECT )) { i++; if ( i >= lines ) goto short_input; if ( !BV_CASEMATCH( btype+i, &BV_NEWRDN )) { fprintf( stderr, _("%s: expecting \"%s:\" but saw" " \"%s:\" (line %d, entry \"%s\")\n"), prog, BV_NEWRDN.bv_val, btype[i].bv_val, linenum+i, dn ); rc = LDAP_PARAM_ERROR; goto leave; } newrdn = vals[i].bv_val; i++; if ( i >= lines ) goto short_input; if ( !BV_CASEMATCH( btype+i, &BV_DELETEOLDRDN )) { fprintf( stderr, _("%s: expecting \"%s:\" but saw" " \"%s:\" (line %d, entry \"%s\")\n"), prog, BV_DELETEOLDRDN.bv_val, btype[i].bv_val, linenum+i, dn ); rc = LDAP_PARAM_ERROR; goto leave; } deleteoldrdn = ( vals[i].bv_val[0] == '0' ) ? 0 : 1; i++; if ( i < lines ) { if ( !BV_CASEMATCH( btype+i, &BV_NEWSUP )) { fprintf( stderr, _("%s: expecting \"%s:\" but saw" " \"%s:\" (line %d, entry \"%s\")\n"), prog, BV_NEWSUP.bv_val, btype[i].bv_val, linenum+i, dn ); rc = LDAP_PARAM_ERROR; goto leave; } newsup = vals[i].bv_val; i++; } got_all = 1; } else if ( BV_CASEMATCH( vals+i, &BV_DELETECT )) { got_all = delete_entry = 1; } else { fprintf( stderr, _("%s: unknown %s \"%s\" (line %d, entry \"%s\")\n"), prog, BV_CHANGETYPE.bv_val, vals[i].bv_val, linenum+i, dn ); rc = LDAP_PARAM_ERROR; goto leave; } i++; } else if ( ldapadd ) { /* missing changetype => add */ new_entry = 1; modop = LDAP_MOD_ADD; } else { expect_modop = 1; /* missing changetype => modify */ } if ( got_all ) { if ( i < lines ) { fprintf( stderr, _("%s: extra lines at end (line %d, entry \"%s\")\n"), prog, linenum+i, dn ); rc = LDAP_PARAM_ERROR; goto leave; } goto doit; } nmods = lines - i; idn = i; if ( new_entry ) { int fv; /* Make sure all attributes with multiple values are contiguous */ for (; i<lines; i++) { for (j=i+1; j<lines; j++) { if ( BV_CASEMATCH( btype+i, btype+j )) { nmods--; /* out of order, move intervening attributes down */ if ( j != i+1 ) { bv = vals[j]; fv = freeval[j]; for (k=j; k>i; k--) { btype[k] = btype[k-1]; vals[k] = vals[k-1]; freeval[k] = freeval[k-1]; } k++; btype[k] = btype[i]; vals[k] = bv; freeval[k] = fv; } i++; } } } /* Allocate space for array of mods, array of pointers to mods, * and array of pointers to values, allowing for NULL terminators * for the pointer arrays... */ lm = ber_memalloc( nmods * sizeof(LDAPMod) + (nmods+1) * sizeof(LDAPMod*) + (lines + nmods - idn) * sizeof(struct berval *)); pmods = (LDAPMod **)(lm+nmods); bvl = (struct berval **)(pmods+nmods+1); j = 0; k = -1; BER_BVZERO(&bv); for (i=idn; i<lines; i++) { if ( BV_CASEMATCH( btype+i, &BV_DN )) { fprintf( stderr, _("%s: attributeDescription \"%s\":" " (possible missing newline" " after line %d, entry \"%s\"?)\n"), prog, btype[i].bv_val, linenum+i - 1, dn ); } if ( !BV_CASEMATCH( btype+i, &bv )) { bvl[k++] = NULL; bv = btype[i]; lm[j].mod_op = LDAP_MOD_ADD | LDAP_MOD_BVALUES; lm[j].mod_type = bv.bv_val; lm[j].mod_bvalues = bvl+k; pmods[j] = lm+j; j++; } bvl[k++] = vals+i; } bvl[k] = NULL; pmods[j] = NULL; goto doit; } mops = ber_memalloc( lines+1 ); mops[lines] = M_SEP; mops[i-1] = M_SEP; for ( ; i<lines; i++ ) { if ( expect_modop ) { #ifdef LIBERAL_CHANGETYPE_MODOP /* trim trailing spaces (and log warning ...) */ int icnt; for ( icnt = vals[i].bv_len; --icnt > 0; ) { if ( !isspace( (unsigned char) vals[i].bv_val[icnt] ) ) break; } if ( ++icnt != vals[i].bv_len ) { fprintf( stderr, _("%s: illegal trailing space after" " \"%s: %s\" trimmed (line %d, entry \"%s\")\n"), prog, type, vals[i].bv_val, linenum+i, dn ); vals[i].bv_val[icnt] = '\0'; } #endif /* LIBERAL_CHANGETYPE_MODOP */ expect_modop = 0; expect_sep = 1; if ( BV_CASEMATCH( btype+i, &BV_MODOPADD )) { modop = LDAP_MOD_ADD; mops[i] = M_SEP; nmods--; } else if ( BV_CASEMATCH( btype+i, &BV_MODOPREPLACE )) { /* defer handling these since they might have no values. * Use the BVALUES flag to signal that these were * deferred. If values are provided later, this * flag will be switched off. */ modop = LDAP_MOD_REPLACE; mops[i] = modop | LDAP_MOD_BVALUES; btype[i] = vals[i]; } else if ( BV_CASEMATCH( btype+i, &BV_MODOPDELETE )) { modop = LDAP_MOD_DELETE; mops[i] = modop | LDAP_MOD_BVALUES; btype[i] = vals[i]; } else if ( BV_CASEMATCH( btype+i, &BV_MODOPINCREMENT )) { modop = LDAP_MOD_INCREMENT; mops[i] = M_SEP; nmods--; } else { /* no modify op: invalid LDIF */ fprintf( stderr, _("%s: modify operation type is missing at" " line %d, entry \"%s\"\n"), prog, linenum+i, dn ); rc = LDAP_PARAM_ERROR; goto leave; } bv = vals[i]; } else if ( expect_sep && BER_BVISEMPTY( btype+i )) { mops[i] = M_SEP; expect_sep = 0; expect_modop = 1; nmods--; } else { if ( !BV_CASEMATCH( btype+i, &bv )) { fprintf( stderr, _("%s: wrong attributeType at" " line %d, entry \"%s\"\n"), prog, linenum+i, dn ); rc = LDAP_PARAM_ERROR; goto leave; } mops[i] = modop; /* If prev op was deferred and matches this type, * clear the flag */ if ( (mops[i-1] & LDAP_MOD_BVALUES) && BV_CASEMATCH( btype+i, btype+i-1 )) { mops[i-1] = M_SEP; nmods--; } } } #if 0 /* we should faithfully encode the LDIF, not combine */ /* Make sure all modops with multiple values are contiguous */ for (i=idn; i<lines; i++) { if ( mops[i] == M_SEP ) continue; for (j=i+1; j<lines; j++) { if ( mops[j] == M_SEP || mops[i] != mops[j] ) continue; if ( BV_CASEMATCH( btype+i, btype+j )) { nmods--; /* out of order, move intervening attributes down */ if ( j != i+1 ) { int c; struct berval bv; char fv; c = mops[j]; bv = vals[j]; fv = freeval[j]; for (k=j; k>i; k--) { btype[k] = btype[k-1]; vals[k] = vals[k-1]; freeval[k] = freeval[k-1]; mops[k] = mops[k-1]; } k++; btype[k] = btype[i]; vals[k] = bv; freeval[k] = fv; mops[k] = c; } i++; } } } #endif /* Allocate space for array of mods, array of pointers to mods, * and array of pointers to values, allowing for NULL terminators * for the pointer arrays... */ lm = ber_memalloc( nmods * sizeof(LDAPMod) + (nmods+1) * sizeof(LDAPMod*) + (lines + nmods - idn) * sizeof(struct berval *)); pmods = (LDAPMod **)(lm+nmods); bvl = (struct berval **)(pmods+nmods+1); j = 0; k = -1; BER_BVZERO(&bv); mops[idn-1] = M_SEP; for (i=idn; i<lines; i++) { if ( mops[i] == M_SEP ) continue; if ( mops[i] != mops[i-1] || !BV_CASEMATCH( btype+i, &bv )) { bvl[k++] = NULL; bv = btype[i]; lm[j].mod_op = mops[i] | LDAP_MOD_BVALUES; lm[j].mod_type = bv.bv_val; if ( mops[i] & LDAP_MOD_BVALUES ) { lm[j].mod_bvalues = NULL; } else { lm[j].mod_bvalues = bvl+k; } pmods[j] = lm+j; j++; } bvl[k++] = vals+i; } bvl[k] = NULL; pmods[j] = NULL; doit: /* If default controls are set (as with -M option) and controls are specified in the LDIF file, we must add the default controls to the list of controls sent with the ldap operation. */ if ( rc == 0 ) { if (pctrls) { LDAPControl **defctrls = NULL; /* Default server controls */ LDAPControl **newctrls = NULL; ldap_get_option(ld, LDAP_OPT_SERVER_CONTROLS, &defctrls); if (defctrls) { int npc=0; /* Num of LDIF controls */ int ndefc=0; /* Num of default controls */ while (pctrls[npc]) npc++; /* Count LDIF controls */ while (defctrls[ndefc]) ndefc++; /* Count default controls */ newctrls = ber_memrealloc(pctrls, (npc+ndefc+1)*sizeof(LDAPControl*)); if (newctrls == NULL) { rc = LDAP_NO_MEMORY; } else { int i; pctrls = newctrls; for (i=npc; i<npc+ndefc; i++) { pctrls[i] = ldap_control_dup(defctrls[i-npc]); if (pctrls[i] == NULL) { rc = LDAP_NO_MEMORY; break; } } pctrls[npc+ndefc] = NULL; } ldap_controls_free(defctrls); /* Must be freed by library */ } } } if ( rc == 0 ) { if ( delete_entry ) { rc = dodelete( dn, pctrls ); } else if ( newrdn != NULL ) { rc = dorename( dn, newrdn, newsup, deleteoldrdn, pctrls ); } else { rc = domodify( dn, pmods, pctrls, new_entry ); } if ( rc == LDAP_SUCCESS ) { rc = 0; } } leave: if (pctrls != NULL) { ldap_controls_free( pctrls ); } if ( lm != NULL ) { ber_memfree( lm ); } if ( mops != NULL ) { ber_memfree( mops ); } for (i=lines-1; i>=0; i--) if ( freeval[i] ) ber_memfree( vals[i].bv_val ); ber_memfree( btype ); return( rc ); }
static void op_add(diversion *diversions, const char *file) { diversion *d; if (file[0] != '/') badusage(_("filename \"%s\" is not absolute"), file); if (strchr(file, '\n')) badusage(_("filename may not contain newlines")); struct stat file_stat; if (stat(file, &file_stat) == 0 && S_ISDIR(file_stat.st_mode)) badusage(_("Cannot divert directories")); if (!divertto) { static struct varbuf vb; varbufreset(&vb); varbufaddstr(&vb, file); varbufaddstr(&vb, ".distrib"); divertto = vb.buf; } if (divertto[0] != '/') badusage(_("filename \"%s\" is not absolute"), divertto); if (!package) package = ":"; diversions = invert_diversions_list(diversions); for (d = diversions; d; d = d->next) { if (strcmp(d->contest, file) == 0 || strcmp(d->altname, file) == 0 || strcmp(d->contest, divertto) == 0 || strcmp(d->altname, divertto) == 0) { if (strcmp(d->contest, file) == 0 && strcmp(d->altname, divertto) == 0 && strcmp(d->package, package) == 0) { if (!quiet) printf(_("Leaving '%s'\n"), infon(d)); exit(0); } else ohshit(_("'%s' clashes with '%s'"), infoa(file), infon(d)); } } d = nfmalloc(sizeof(diversion)); d->contest = file; d->altname = divertto; d->package = package; d->next = diversions; diversions = d; diversions = invert_diversions_list(diversions); if (!quiet) printf(_("Adding %s\n"), infon(d)); checkrename(file, divertto); save(diversions); dorename(file, divertto); exit(0); }
static int process_ldif_rec( char *rbuf, unsigned long linenum ) { LDIFRecord lr; int lrflags = ldapadd ? LDIF_DEFAULT_ADD : 0; int rc; struct berval rbuf_bv; #ifdef TEST_LDIF_API if ( getenv( "LDIF_ENTRIES_ONLY" ) ) { lrflags |= LDIF_ENTRIES_ONLY; } if ( getenv( "LDIF_NO_CONTROLS" ) ) { lrflags |= LDIF_NO_CONTROLS; } #endif /* TEST_LDIF_API */ rbuf_bv.bv_val = rbuf; rbuf_bv.bv_len = 0; /* not used */ rc = ldap_parse_ldif_record( &rbuf_bv, linenum, &lr, prog, lrflags ); /* If default controls are set (as with -M option) and controls are specified in the LDIF file, we must add the default controls to the list of controls sent with the ldap operation. */ if ( rc == 0 ) { if (lr.lr_ctrls) { LDAPControl **defctrls = NULL; /* Default server controls */ LDAPControl **newctrls = NULL; ldap_get_option(ld, LDAP_OPT_SERVER_CONTROLS, &defctrls); if (defctrls) { int npc=0; /* Num of LDIF controls */ int ndefc=0; /* Num of default controls */ while (lr.lr_ctrls[npc]) npc++; /* Count LDIF controls */ while (defctrls[ndefc]) ndefc++; /* Count default controls */ newctrls = ber_memrealloc(lr.lr_ctrls, (npc+ndefc+1)*sizeof(LDAPControl*)); if (newctrls == NULL) { rc = LDAP_NO_MEMORY; } else { int i; lr.lr_ctrls = newctrls; for (i=npc; i<npc+ndefc; i++) { lr.lr_ctrls[i] = ldap_control_dup(defctrls[i-npc]); if (lr.lr_ctrls[i] == NULL) { rc = LDAP_NO_MEMORY; break; } } lr.lr_ctrls[npc+ndefc] = NULL; } ldap_controls_free(defctrls); /* Must be freed by library */ } } } if ( rc == 0 ) { if ( LDAP_REQ_DELETE == lr.lr_op ) { rc = dodelete( &lr.lr_dn, lr.lr_ctrls ); } else if ( LDAP_REQ_RENAME == lr.lr_op ) { rc = dorename( &lr.lr_dn, &lr.lrop_newrdn, &lr.lrop_newsup, lr.lrop_delold, lr.lr_ctrls ); } else if ( ( LDAP_REQ_ADD == lr.lr_op ) || ( LDAP_REQ_MODIFY == lr.lr_op ) ) { rc = domodify( &lr.lr_dn, lr.lrop_mods, lr.lr_ctrls, LDAP_REQ_ADD == lr.lr_op ); } else { /* record skipped e.g. version: or comment or something we don't handle yet */ } if ( rc == LDAP_SUCCESS ) { rc = 0; } } ldap_ldif_record_done( &lr ); return( rc ); }
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 ); }