diff --git a/servers/slapd/back-ldif/ldif.c b/servers/slapd/back-ldif/ldif.c index ae71753f8e..9928c38b9e 100644 --- a/servers/slapd/back-ldif/ldif.c +++ b/servers/slapd/back-ldif/ldif.c @@ -33,7 +33,7 @@ struct ldif_info { struct berval li_base_path; - ID tool_current; + ID tool_current; Entry ** tool_entries; int tool_put_entry_flag; int tool_numentries; @@ -81,14 +81,15 @@ ldif_cf( ConfigArgs *c ) return 1; } -static char * -dn2path(struct berval * dn, struct berval * rootdn, struct berval * base_path) +static void +dn2path(struct berval * dn, struct berval * rootdn, struct berval * base_path, + struct berval *res) { - char *result = ch_malloc( dn->bv_len + base_path->bv_len + 2 + - STRLENOF( LDIF )); char *ptr, *sep, *end; - ptr = lutil_strcopy( result, base_path->bv_val ); + res->bv_len = dn->bv_len + base_path->bv_len + 1 + STRLENOF( LDIF ); + res->bv_val = ch_malloc( res->bv_len + 1 ); + ptr = lutil_strcopy( res->bv_val, base_path->bv_val ); *ptr++ = LDAP_DIRSEP[0]; ptr = lutil_strcopy( ptr, rootdn->bv_val ); end = dn->bv_val + dn->bv_len - rootdn->bv_len - 1; @@ -99,10 +100,9 @@ dn2path(struct berval * dn, struct berval * rootdn, struct berval * base_path) end = sep; } strcpy(ptr, LDIF); - return result; } -static char * slurp_file(int fd) { +static char * slurp_file(int fd) { int entry_buf_size = 40 * ENTRY_BUFF_INCREMENT; int read_chars_total = 0; int read_chars = 0; @@ -111,29 +111,29 @@ static char * slurp_file(int fd) { char * entry_pos = entry; while(1) { - if(entry_size - read_chars_total == 0) { - entry = (char *) realloc(entry, sizeof(char) * 2 * entry_size); - entry_size = 2 * entry_size; - } - read_chars = read(fd, (void *) entry_pos, entry_size - read_chars_total); - if(read_chars == -1) { - SLAP_FREE(entry); - return NULL; - } - entry_pos += read_chars; - if(read_chars == 0) { - if(entry_size - read_chars_total > 0) + if(entry_size - read_chars_total == 0) { + entry = (char *) realloc(entry, sizeof(char) * 2 * entry_size); + entry_size = 2 * entry_size; + } + read_chars = read(fd, (void *) entry_pos, entry_size - read_chars_total); + if(read_chars == -1) { + SLAP_FREE(entry); + return NULL; + } + entry_pos += read_chars; + if(read_chars == 0) { + if(entry_size - read_chars_total > 0) entry[read_chars_total] = '\0'; - else { + else { entry = (char *) realloc(entry, sizeof(char) * entry_size + 1); entry_size = entry_size + 1; entry[read_chars_total] = '\0'; - } - break; - } - else { - read_chars_total += read_chars; - } + } + break; + } + else { + read_chars_total += read_chars; + } } return entry; } @@ -145,48 +145,48 @@ static int spew_file(int fd, char * spew) { char * spewptr = spew; while(written < len) { - writeres = write(fd, spewptr, len - written); - if(writeres == -1) { - perror("could not spew write"); - return -1; - } - else { - spewptr += writeres; - written += writeres; - } + writeres = write(fd, spewptr, len - written); + if(writeres == -1) { + perror("could not spew write"); + return -1; + } + else { + spewptr += writeres; + written += writeres; + } } return writeres; } -static int spew_entry(Entry * e, char * path) { +static int spew_entry(Entry * e, struct berval * path) { int rs; int openres; int spew_res; int entry_length; char * entry_as_string; - openres = open(path, O_WRONLY | O_CREAT, S_IRUSR | S_IWUSR); + openres = open(path->bv_val, O_WRONLY | O_CREAT, S_IRUSR | S_IWUSR); if(openres == -1) { - if(errno == ENOENT) - rs = LDAP_NO_SUCH_OBJECT; - else - rs = LDAP_UNWILLING_TO_PERFORM; + if(errno == ENOENT) + rs = LDAP_NO_SUCH_OBJECT; + else + rs = LDAP_UNWILLING_TO_PERFORM; } else { - entry_as_string = entry2str(e, &entry_length); - if(entry_as_string == NULL) { - rs = LDAP_UNWILLING_TO_PERFORM; - close(openres); - } - else { - spew_res = spew_file(openres, entry_as_string); - close(openres); - if(spew_res == -1) - rs = LDAP_UNWILLING_TO_PERFORM; - else - rs = LDAP_SUCCESS; - } - } + entry_as_string = entry2str(e, &entry_length); + if(entry_as_string == NULL) { + rs = LDAP_UNWILLING_TO_PERFORM; + close(openres); + } + else { + spew_res = spew_file(openres, entry_as_string); + close(openres); + if(spew_res == -1) + rs = LDAP_UNWILLING_TO_PERFORM; + else + rs = LDAP_SUCCESS; + } + } return rs; } @@ -196,132 +196,144 @@ static Entry * get_entry_for_fd(int fd) { /* error reading file */ if(entry == NULL) { - goto return_value; + goto return_value; } ldentry = str2entry(entry); return_value: if(fd != -1) { - if(close(fd) != 0) { - /* log error */ - } + if(close(fd) != 0) { + /* log error */ + } } if(entry != NULL) - SLAP_FREE(entry); + SLAP_FREE(entry); return ldentry; } static Entry * get_entry(struct berval * dn, struct berval * rootdn, struct berval * base_path) { - char * path = (char *) dn2path(dn, rootdn, base_path); - int fd = open(path, O_RDONLY); + struct berval path; + int fd; + dn2path(dn, rootdn, base_path, &path); + fd = open(path.bv_val, O_RDONLY); /* error opening file (mebbe should log error) */ if(fd == -1) { - perror("failed to open file"); - goto return_value; + perror("failed to open file"); } - goto return_value; - return_value: - if(path != NULL) - SLAP_FREE(path); + if(path.bv_val != NULL) + SLAP_FREE(path.bv_val); return get_entry_for_fd(fd); } -/* takes a base path and a filename and opens that file */ -static int fd_for_path_components(char * base, char * name) { - char * absolutepath; - int fd; - absolutepath = (char *) SLAP_MALLOC(sizeof(char) * - (strlen(base) + - strlen(name) + 2)); - absolutepath[0] = '\0'; - strcat(absolutepath, base); - strcat(absolutepath, LDAP_DIRSEP); - strcat(absolutepath, name); - fd = open(absolutepath, O_RDONLY); - SLAP_FREE(absolutepath); - return fd; +static void fullpath(struct berval *base, char *name, struct berval *res) { + char *ptr; + res->bv_len = strlen(name) + base->bv_len + 1; + res->bv_val = ch_malloc( res->bv_len + 1 ); + strcpy(res->bv_val, base->bv_val); + ptr = res->bv_val + base->bv_len; + *ptr++ = LDAP_DIRSEP[0]; + strcpy(ptr, name); } -static Entry ** r_enum_tree(Entry ** entries, int *elen, int *eind, char * path) { - DIR * dir_of_path = opendir(path); +static Entry ** r_enum_tree(Entry ** entries, int *elen, int *eind, + struct berval * path, int scope) { + DIR * dir_of_path = opendir(path->bv_val); int fd; struct dirent * dir; - char * newpath; Entry * e; + struct berval fpath; if(entries == NULL) { - entries = (Entry **) SLAP_MALLOC(sizeof(Entry *) * ENTRY_BUFF_INCREMENT); - *elen = ENTRY_BUFF_INCREMENT; + entries = (Entry **) SLAP_MALLOC(sizeof(Entry *) * ENTRY_BUFF_INCREMENT); + *elen = ENTRY_BUFF_INCREMENT; } if(dir_of_path == NULL) {/* can't open directory */ - perror("failed to open directory"); - return entries; + perror("failed to open directory"); + return entries; } + BER_BVZERO(&fpath); + while(1) { - dir = readdir(dir_of_path); - if(dir == NULL) break; /* end of the directory */ - if(dir->d_type == DT_REG) { /* regular file, read the entry into memory */ - if(! (*eind < *elen)) { /* grow entries if necessary */ - entries = (Entry **) SLAP_REALLOC(entries, sizeof(Entry *) * (*elen) * 2); - *elen = *elen * 2; - } - fd = fd_for_path_components(path, dir->d_name); - if(fd != -1) { - e = get_entry_for_fd(fd); - if(e != NULL) { - entries[*eind] = e; - *eind = *eind + 1; - } - else - perror("failed to read entry"); - } - else - perror("failed to open fd"); - } - else if(dir->d_type == DT_DIR) { - if(! (strcasecmp(dir->d_name, ".") == 0 || strcasecmp(dir->d_name, "..") == 0)) { - newpath = (char *) SLAP_MALLOC(sizeof(char) * - (strlen(path) + strlen(dir->d_name) + 2)); - newpath[0] = '\0'; - strcat(newpath, path); - strcat(newpath, LDAP_DIRSEP); - strcat(newpath, dir->d_name); - entries = r_enum_tree(entries, elen, eind, newpath); - SLAP_FREE(newpath); - } - } + if (fpath.bv_val) { + free(fpath.bv_val); + fpath.bv_val = NULL; + } + dir = readdir(dir_of_path); + if(dir == NULL) break; /* end of the directory */ + if(dir->d_name[0] == '.') continue; /* skip '.' and '..' */ + if(dir->d_type == DT_UNKNOWN) { /* must stat to determine... */ + struct stat stbuf; + fullpath( path, dir->d_name, &fpath ); + if (stat(fpath.bv_val, &stbuf)) { + perror("stat"); + continue; + } + if ( S_ISREG(stbuf.st_mode) ) dir->d_type = DT_REG; + else if ( S_ISDIR(stbuf.st_mode) ) dir->d_type = DT_DIR; + } + if(dir->d_type == DT_REG) { /* regular file, read the entry into memory */ + if ( scope == LDAP_SCOPE_ONELEVEL ) continue; + if(! (*eind < *elen)) { /* grow entries if necessary */ + entries = (Entry **) SLAP_REALLOC(entries, sizeof(Entry *) * (*elen) * 2); + *elen = *elen * 2; + } + if ( !fpath.bv_val ) + fullpath( path, dir->d_name, &fpath ); + fd = open( fpath.bv_val, O_RDONLY ); + SLAP_FREE(fpath.bv_val); + fpath.bv_val = NULL; + if(fd != -1) { + e = get_entry_for_fd(fd); + if(e != NULL) { + entries[*eind] = e; + *eind = *eind + 1; + } + else + perror("failed to read entry"); + } + else + perror("failed to open fd"); + } + else if(dir->d_type == DT_DIR) { + if ( scope == LDAP_SCOPE_BASE ) continue; + if ( !fpath.bv_val ) + fullpath( path, dir->d_name, &fpath ); + entries = r_enum_tree(entries, elen, eind, &fpath, + scope == LDAP_SCOPE_ONELEVEL ? LDAP_SCOPE_BASE : scope); + } } closedir(dir_of_path); return entries; } -static Entry ** enum_tree(struct berval * path, int * length) { +static Entry ** enum_tree(struct berval * path, int * length, int scope) { int index = 0; - return r_enum_tree(NULL, &index, length, path->bv_val); + return r_enum_tree(NULL, &index, length, path, scope); } -static char * get_parent_path(char * dnpath) { - int dnpathlen = strlen(dnpath); - char * result; +/* Get the parent path plus the LDIF suffix */ +static void get_parent_path(struct berval * dnpath, struct berval *res) { + int dnpathlen = dnpath->bv_len; int i; for(i = dnpathlen;i>0;i--) /* find the first path seperator */ - if(dnpath[i] == LDAP_DIRSEP[0]) - break; - result = ch_malloc( i + 1 ); - strncpy(result, dnpath, i); - result[i] = '\0'; - return result; + if(dnpath->bv_val[i] == LDAP_DIRSEP[0]) + break; + res->bv_len = i; + res->bv_val = ch_malloc( res->bv_len + 1 + STRLENOF(LDIF) ); + strncpy(res->bv_val, dnpath->bv_val, i); + strcpy(res->bv_val+i, LDIF); + res->bv_val[i] = '\0'; } -static int apply_modify_to_entry(Entry * entry, - Modifications * modlist, - Operation * op, - SlapReply * rs) +static int apply_modify_to_entry(Entry * entry, + Modifications * modlist, + Operation * op, + SlapReply * rs) { char textbuf[SLAP_TEXT_BUFLEN]; size_t textlen = sizeof textbuf; @@ -331,65 +343,65 @@ static int apply_modify_to_entry(Entry * entry, Attribute *save_attrs; if (!acl_check_modlist(op, entry, modlist)) { - return LDAP_INSUFFICIENT_ACCESS; + return LDAP_INSUFFICIENT_ACCESS; } /* save_attrs = entry->e_attrs; Why? - entry->e_attrs = attrs_dup(entry->e_attrs); */ + entry->e_attrs = attrs_dup(entry->e_attrs); */ for (; modlist != NULL; modlist = modlist->sml_next) { - mods = &modlist->sml_mod; + mods = &modlist->sml_mod; - switch (mods->sm_op) { - case LDAP_MOD_ADD: - rc = modify_add_values(entry, mods, - get_permissiveModify(op), - &rs->sr_text, textbuf, - textlen); - break; + switch (mods->sm_op) { + case LDAP_MOD_ADD: + rc = modify_add_values(entry, mods, + get_permissiveModify(op), + &rs->sr_text, textbuf, + textlen); + break; - case LDAP_MOD_DELETE: - rc = modify_delete_values(entry, mods, - get_permissiveModify(op), - &rs->sr_text, textbuf, + case LDAP_MOD_DELETE: + rc = modify_delete_values(entry, mods, + get_permissiveModify(op), + &rs->sr_text, textbuf, textlen); - break; + break; - case LDAP_MOD_REPLACE: - rc = modify_replace_values(entry, mods, - get_permissiveModify(op), - &rs->sr_text, textbuf, + case LDAP_MOD_REPLACE: + rc = modify_replace_values(entry, mods, + get_permissiveModify(op), + &rs->sr_text, textbuf, textlen); - break; - case LDAP_MOD_INCREMENT: - break; - case SLAP_MOD_SOFTADD: - mods->sm_op = LDAP_MOD_ADD; - rc = modify_add_values(entry, mods, - get_permissiveModify(op), - &rs->sr_text, textbuf, - textlen); - mods->sm_op = SLAP_MOD_SOFTADD; - if (rc == LDAP_TYPE_OR_VALUE_EXISTS) { + break; + case LDAP_MOD_INCREMENT: + break; + case SLAP_MOD_SOFTADD: + mods->sm_op = LDAP_MOD_ADD; + rc = modify_add_values(entry, mods, + get_permissiveModify(op), + &rs->sr_text, textbuf, + textlen); + mods->sm_op = SLAP_MOD_SOFTADD; + if (rc == LDAP_TYPE_OR_VALUE_EXISTS) { rc = LDAP_SUCCESS; - } - break; - default: - break; - } - if(rc != LDAP_SUCCESS) break; + } + break; + default: + break; + } + if(rc != LDAP_SUCCESS) break; } if(rc == LDAP_SUCCESS) { - if ( mods->sm_desc == slap_schema.si_ad_objectClass ) { - entry->e_ocflags = 0; - } - /* check that the entry still obeys the schema */ - rc = entry_schema_check(op->o_bd, entry, - save_attrs, &rs->sr_text, - textbuf, textlen); + if ( mods->sm_desc == slap_schema.si_ad_objectClass ) { + entry->e_ocflags = 0; + } + /* check that the entry still obeys the schema */ + rc = entry_schema_check(op->o_bd, entry, + save_attrs, &rs->sr_text, + textbuf, textlen); } return rc; } @@ -409,35 +421,35 @@ ldif_back_bind( Operation *op, SlapReply *rs ) /* no object is found for them */ if(entry == NULL) { - if(be_isroot_pw(op)) { - return_val = LDAP_SUCCESS; - goto return_result; - } - else if(be_root_dn(op->o_bd)) { - return_val = LDAP_INVALID_CREDENTIALS; - rs->sr_err = LDAP_INVALID_CREDENTIALS; - goto return_result; - } - else { - rs->sr_err = LDAP_NO_SUCH_OBJECT; - return_val = 1; - goto return_result; - } + if(be_isroot_pw(op)) { + return_val = LDAP_SUCCESS; + goto return_result; + } + else if(be_root_dn(op->o_bd)) { + return_val = LDAP_INVALID_CREDENTIALS; + rs->sr_err = LDAP_INVALID_CREDENTIALS; + goto return_result; + } + else { + rs->sr_err = LDAP_NO_SUCH_OBJECT; + return_val = 1; + goto return_result; + } } /* they don't have userpassword */ if((a = attr_find(entry->e_attrs, password)) == NULL) { - rs->sr_err = LDAP_INAPPROPRIATE_AUTH; - return_val = 1; - goto return_result; + rs->sr_err = LDAP_INAPPROPRIATE_AUTH; + return_val = 1; + goto return_result; } /* authentication actually failed */ if(slap_passwd_check(op, entry, a, &op->oq_bind.rb_cred, - &rs->sr_text) != 0) { - rs->sr_err = LDAP_INVALID_CREDENTIALS; - return_val = 1; - goto return_result; + &rs->sr_text) != 0) { + rs->sr_err = LDAP_INVALID_CREDENTIALS; + return_val = 1; + goto return_result; } /* let the front-end send success */ @@ -447,9 +459,9 @@ ldif_back_bind( Operation *op, SlapReply *rs ) return_result: ldap_pvt_thread_mutex_unlock(&ni->li_mutex); if(return_val != 0) - send_ldap_result( op, rs ); + send_ldap_result( op, rs ); if(entry != NULL) - entry_free(entry); + entry_free(entry); return return_val; } @@ -461,27 +473,27 @@ static int ldif_back_search(Operation *op, SlapReply *rs) Entry ** entries = NULL; ldap_pvt_thread_mutex_lock(&ni->li_mutex); - entries = (Entry **) enum_tree(&ni->li_base_path, &numentries); + entries = (Entry **) enum_tree(&ni->li_base_path, &numentries, op->ors_scope); if(entries != NULL) { - for(i=0;iors_filter) == LDAP_COMPARE_TRUE) { - rs->sr_entry = entries[i]; - rs->sr_attrs = op->ors_attrs; - rs->sr_flags = REP_ENTRY_MODIFIABLE; - send_search_entry(op, rs); - } - entry_free(entries[i]); - } - SLAP_FREE(entries); - rs->sr_err = LDAP_SUCCESS; - ldap_pvt_thread_mutex_unlock(&ni->li_mutex); - send_ldap_result(op, rs); + for(i=0;iors_filter) == LDAP_COMPARE_TRUE) { + rs->sr_entry = entries[i]; + rs->sr_attrs = op->ors_attrs; + rs->sr_flags = REP_ENTRY_MODIFIABLE; + send_search_entry(op, rs); + } + entry_free(entries[i]); + } + SLAP_FREE(entries); + rs->sr_err = LDAP_SUCCESS; + ldap_pvt_thread_mutex_unlock(&ni->li_mutex); + send_ldap_result(op, rs); } else { - rs->sr_err = LDAP_BUSY; - ldap_pvt_thread_mutex_unlock(&ni->li_mutex); - send_ldap_result(op, rs); + rs->sr_err = LDAP_BUSY; + ldap_pvt_thread_mutex_unlock(&ni->li_mutex); + send_ldap_result(op, rs); } return 0; @@ -490,206 +502,196 @@ static int ldif_back_search(Operation *op, SlapReply *rs) static int ldif_back_add(Operation *op, SlapReply *rs) { struct ldif_info *ni = (struct ldif_info *) op->o_bd->be_private; Entry * e = op->ora_e; - Attribute *save_attrs; struct berval dn = e->e_nname; - char * leaf_path = NULL; - char * base = NULL; - char * base_ldif = NULL; + struct berval leaf_path = BER_BVNULL; struct stat stats; int statres; char textbuf[SLAP_TEXT_BUFLEN]; size_t textlen = sizeof textbuf; + rs->sr_err = entry_schema_check(op->o_bd, e, + NULL, &rs->sr_text, textbuf, textlen); + if ( rs->sr_err != LDAP_SUCCESS ) goto send_res; + ldap_pvt_thread_mutex_lock(&ni->li_mutex); - ldap_pvt_thread_mutex_lock(&entry2str_mutex); - leaf_path = (char *) dn2path(&dn, &op->o_bd->be_nsuffix[0], &ni->li_base_path); + dn2path(&dn, &op->o_bd->be_nsuffix[0], &ni->li_base_path, &leaf_path); - /* save_attrs = e->e_attrs; why? - e->e_attrs = attrs_dup(e->e_attrs);*/ + if(leaf_path.bv_val != NULL) { + struct berval base = BER_BVNULL; + /* build path to container and ldif of container */ + get_parent_path(&leaf_path, &base); - if(leaf_path != NULL) { - char * tmp; - /* build path to container, and path to ldif of container */ - base = (char *) get_parent_path(leaf_path); - base_ldif = (char *) SLAP_MALLOC(sizeof(char) * (strlen(base) + 6)); - tmp = (char *) lutil_strcopy(base_ldif, base); - lutil_strcopy(tmp, LDIF); - - rs->sr_err = entry_schema_check(op->o_bd, e, - save_attrs, - &rs->sr_text, - textbuf, textlen); - if(rs->sr_err == LDAP_SUCCESS) { - statres = stat(base, &stats); /* check if container exists */ - if(statres == -1 && errno == ENOENT) { /* container missing */ - statres = stat(base_ldif, &stats); /* check for leaf node */ - if(statres == -1 && errno == ENOENT) { - rs->sr_err = LDAP_NO_SUCH_OBJECT; /* parent doesn't exist */ + statres = stat(base.bv_val, &stats); /* check if container exists */ + if(statres == -1 && errno == ENOENT) { /* container missing */ + base.bv_val[base.bv_len] = '.'; + statres = stat(base.bv_val, &stats); /* check for leaf node */ + base.bv_val[base.bv_len] = '\0'; + if(statres == -1 && errno == ENOENT) { + rs->sr_err = LDAP_NO_SUCH_OBJECT; /* parent doesn't exist */ + } + else if(statres != -1) { /* create parent */ + int mkdirres = mkdir(base.bv_val, 0750); + if(mkdirres == -1) { + rs->sr_err = LDAP_UNWILLING_TO_PERFORM; + } + } + else + rs->sr_err = LDAP_UNWILLING_TO_PERFORM; + }/* container was possibly created, move on to add the entry */ + if(rs->sr_err == LDAP_SUCCESS) { + statres = stat(leaf_path.bv_val, &stats); + if(statres == -1 && errno == ENOENT) { + ldap_pvt_thread_mutex_lock(&entry2str_mutex); + rs->sr_err = (int) spew_entry(e, &leaf_path); + ldap_pvt_thread_mutex_unlock(&entry2str_mutex); + } + else /* it already exists */ + rs->sr_err = LDAP_ALREADY_EXISTS; + } + SLAP_FREE(base.bv_val); + SLAP_FREE(leaf_path.bv_val); } - else if(statres != -1) { /* create parent */ - int mkdirres = mkdir(base, 0750); - if(mkdirres == -1) { - rs->sr_err = LDAP_UNWILLING_TO_PERFORM; - } - } - else - rs->sr_err = LDAP_UNWILLING_TO_PERFORM; - }/* container was possibly created, move on to add the entry */ - if(rs->sr_err == LDAP_SUCCESS) { - statres = stat(leaf_path, &stats); - if(statres == -1 && errno == ENOENT) { - rs->sr_err = (int) spew_entry(e, leaf_path); - } - else /* it already exists */ - rs->sr_err = LDAP_ALREADY_EXISTS; - } - } - } ldap_pvt_thread_mutex_unlock(&ni->li_mutex); - ldap_pvt_thread_mutex_unlock(&entry2str_mutex); - send_ldap_result(op, rs); - if(leaf_path != NULL) - SLAP_FREE(leaf_path); - if(base != NULL) - SLAP_FREE(base); - if(base_ldif != NULL) - SLAP_FREE(base_ldif); +send_res: + send_ldap_result(op, rs); return 0; } static int ldif_back_modify(Operation *op, SlapReply *rs) { struct ldif_info *ni = (struct ldif_info *) op->o_bd->be_private; Modifications * modlst = op->orm_modlist; - char * path = NULL; + struct berval path = BER_BVNULL; Entry * entry = NULL; int spew_res; ldap_pvt_thread_mutex_lock(&ni->li_mutex); - ldap_pvt_thread_mutex_lock(&entry2str_mutex); - path = (char *) dn2path(&op->o_req_ndn, &op->o_bd->be_nsuffix[0], &ni->li_base_path); - entry = (Entry *) get_entry(&op->o_req_ndn, &op->o_bd->be_nsuffix[0], &ni->li_base_path); + dn2path(&op->o_req_ndn, &op->o_bd->be_nsuffix[0], &ni->li_base_path, + &path); + entry = (Entry *) get_entry(&op->o_req_ndn, &op->o_bd->be_nsuffix[0], + &ni->li_base_path); if(entry != NULL) { - rs->sr_err = apply_modify_to_entry(entry, modlst, op, rs); - if(rs->sr_err == LDAP_SUCCESS) { - spew_res = spew_entry(entry, path); - if(spew_res == -1) { - perror("could not output entry"); - rs->sr_err = LDAP_UNWILLING_TO_PERFORM; - } - } + rs->sr_err = apply_modify_to_entry(entry, modlst, op, rs); + if(rs->sr_err == LDAP_SUCCESS) { + ldap_pvt_thread_mutex_lock(&entry2str_mutex); + spew_res = spew_entry(entry, &path); + ldap_pvt_thread_mutex_unlock(&entry2str_mutex); + if(spew_res == -1) { + perror("could not output entry"); + rs->sr_err = LDAP_UNWILLING_TO_PERFORM; + } + } } else { - rs->sr_err = LDAP_NO_SUCH_OBJECT; + rs->sr_err = LDAP_NO_SUCH_OBJECT; } - if(path != NULL) - SLAP_FREE(path); if(entry != NULL) - entry_free(entry); + entry_free(entry); + if(path.bv_val != NULL) + SLAP_FREE(path.bv_val); rs->sr_text = NULL; ldap_pvt_thread_mutex_unlock(&ni->li_mutex); - ldap_pvt_thread_mutex_unlock(&entry2str_mutex); send_ldap_result(op, rs); return 0; } static int ldif_back_delete(Operation *op, SlapReply *rs) { struct ldif_info *ni = (struct ldif_info *) op->o_bd->be_private; - char * path = NULL; + struct berval path = BER_BVNULL; int res = 0; ldap_pvt_thread_mutex_lock(&ni->li_mutex); - path = (char *) dn2path(&op->o_req_ndn, &op->o_bd->be_nsuffix[0], &ni->li_base_path); - res = unlink(path); + dn2path(&op->o_req_ndn, &op->o_bd->be_nsuffix[0], &ni->li_base_path, &path); + res = unlink(path.bv_val); if(res == -1) { - if(errno == ENOENT) - rs->sr_err = LDAP_NO_SUCH_OBJECT; - else - rs->sr_err = LDAP_UNWILLING_TO_PERFORM; + if(errno == ENOENT) + rs->sr_err = LDAP_NO_SUCH_OBJECT; + else + rs->sr_err = LDAP_UNWILLING_TO_PERFORM; } else - rs->sr_err = LDAP_SUCCESS; + rs->sr_err = LDAP_SUCCESS; - SLAP_FREE(path); + SLAP_FREE(path.bv_val); ldap_pvt_thread_mutex_unlock(&ni->li_mutex); send_ldap_result(op, rs); return 0; } -static int is_leaf_node(char * path) { - DIR * nonleafnode; - int path_len = strlen(path); - char * nonleafpath = (char *) SLAP_MALLOC(sizeof(char) * path_len + 1); +static int is_leaf_node(struct berval * path) { + DIR * nonleafnode; + int path_len = path->bv_len; int res; - strncpy(nonleafpath, path, path_len); - nonleafpath[path_len - 5] = '\0'; - nonleafnode = opendir(nonleafpath); + path->bv_val[path->bv_len - STRLENOF(LDIF)] = '\0'; + nonleafnode = opendir(path->bv_val); + path->bv_val[path->bv_len - STRLENOF(LDIF)] = '.'; if(nonleafnode == NULL) { - res = 1; + res = 1; } else { - closedir(nonleafnode); - res = 0; + closedir(nonleafnode); + res = 0; } - SLAP_FREE(nonleafpath); return res; } -static int move_entry(Entry * entry, struct berval * ndn, - struct berval * newndn, struct berval * rootdn, - struct berval * base_path) { +static int move_entry(Entry * entry, struct berval * ndn, + struct berval * newndn, struct berval * rootdn, + struct berval * base_path) { int res; int exists_res; - char * path = (char *) dn2path(ndn, rootdn, base_path); - char * newpath = (char *) dn2path(newndn, rootdn, base_path); - int path_len = strlen(path); + struct berval path; + struct berval newpath; - if((entry == NULL || path == NULL) || newpath == NULL) { /* some object doesn't exist */ - res = LDAP_NO_SUCH_OBJECT; + dn2path(ndn, rootdn, base_path, &path); + dn2path(newndn, rootdn, base_path, &newpath); + + if((entry == NULL || path.bv_val == NULL) || newpath.bv_val == NULL) { + /* some object doesn't exist */ + res = LDAP_NO_SUCH_OBJECT; } - else if(! is_leaf_node(path)) { /* entry is not a leaf node */ - res = LDAP_NOT_ALLOWED_ON_NONLEAF; + else if(! is_leaf_node(&path)) { /* entry is not a leaf node */ + res = LDAP_NOT_ALLOWED_ON_NONLEAF; } else { /* do the modrdn */ - exists_res = open(newpath, O_RDONLY); - if(exists_res == -1 && errno == ENOENT) { - res = spew_entry(entry, newpath); - if(res != -1) { - /* if this fails we should log something bad */ - res = unlink(path); - res = LDAP_SUCCESS; - } - else { - if(errno == ENOENT) - res = LDAP_NO_SUCH_OBJECT; - else - res = LDAP_UNWILLING_TO_PERFORM; - unlink(newpath); /* in case file was created */ - } - } - else if(exists_res) { - int close_res; - res = LDAP_ALREADY_EXISTS; - close_res = close(exists_res); - if(close_res == -1) { - /* log heinous error */ - } - } - else { - res = LDAP_UNWILLING_TO_PERFORM; - } + exists_res = open(newpath.bv_val, O_RDONLY); + if(exists_res == -1 && errno == ENOENT) { + res = spew_entry(entry, &newpath); + if(res != -1) { + /* if this fails we should log something bad */ + res = unlink(path.bv_val); + res = LDAP_SUCCESS; + } + else { + if(errno == ENOENT) + res = LDAP_NO_SUCH_OBJECT; + else + res = LDAP_UNWILLING_TO_PERFORM; + unlink(newpath.bv_val); /* in case file was created */ + } + } + else if(exists_res) { + int close_res = close(exists_res); + res = LDAP_ALREADY_EXISTS; + if(close_res == -1) { + /* log heinous error */ + } + } + else { + res = LDAP_UNWILLING_TO_PERFORM; + } } - if(path != NULL) - SLAP_FREE(path); - if(newpath != NULL) - SLAP_FREE(newpath); + if(newpath.bv_val != NULL) + SLAP_FREE(newpath.bv_val); + if(path.bv_val != NULL) + SLAP_FREE(path.bv_val); return res; } @@ -710,26 +712,26 @@ static int ldif_back_modrdn(Operation *op, SlapReply *rs) { /* build the mods to the entry */ if(entry != NULL) { - if(ldap_bv2rdn(&op->oq_modrdn.rs_newrdn, &new_rdn, (char **)&rs->sr_text, - LDAP_DN_FORMAT_LDAP)) { - rs->sr_err = LDAP_INVALID_DN_SYNTAX; - } - else if(op->oq_modrdn.rs_deleteoldrdn && - ldap_bv2rdn(&op->o_req_dn, &old_rdn, (char **)&rs->sr_text, + if(ldap_bv2rdn(&op->oq_modrdn.rs_newrdn, &new_rdn, (char **)&rs->sr_text, + LDAP_DN_FORMAT_LDAP)) { + rs->sr_err = LDAP_INVALID_DN_SYNTAX; + } + else if(op->oq_modrdn.rs_deleteoldrdn && + ldap_bv2rdn(&op->o_req_dn, &old_rdn, (char **)&rs->sr_text, LDAP_DN_FORMAT_LDAP)) { - rs->sr_err = LDAP_OTHER; - } - else { /* got both rdns successfully, ready to build mods */ - if(slap_modrdn2mods(op, rs, entry, old_rdn, new_rdn, &mods) != LDAP_SUCCESS) { + rs->sr_err = LDAP_OTHER; + } + else { /* got both rdns successfully, ready to build mods */ + if(slap_modrdn2mods(op, rs, entry, old_rdn, new_rdn, &mods) != LDAP_SUCCESS) { rs->sr_err = LDAP_UNWILLING_TO_PERFORM; - } - else { /* built mods successfully */ + } + else { /* built mods successfully */ /* build new dn, and new ndn for the entry */ if(op->oq_modrdn.rs_newSup != NULL) /* new superior */ - p_dn = *op->oq_modrdn.rs_newSup; + p_dn = *op->oq_modrdn.rs_newSup; else - p_dn = slap_empty_bv; + p_dn = slap_empty_bv; dnParent(&entry->e_name, &p_dn); build_new_dn(&new_dn, &p_dn, &op->oq_modrdn.rs_newrdn, NULL); dnNormalize( 0, NULL, NULL, &new_dn, &bv, op->o_tmpmemctx ); @@ -740,21 +742,21 @@ static int ldif_back_modrdn(Operation *op, SlapReply *rs) { /* perform the modifications */ res = apply_modify_to_entry(entry, mods, op, rs); if(res == LDAP_SUCCESS) { - rs->sr_err = move_entry(entry, &op->o_req_ndn, - &new_ndn, - &op->o_bd->be_nsuffix[0], - &ni->li_base_path); + rs->sr_err = move_entry(entry, &op->o_req_ndn, + &new_ndn, + &op->o_bd->be_nsuffix[0], + &ni->li_base_path); } else - rs->sr_err = res; - } - } + rs->sr_err = res; + } + } } else /* entry was null */ - rs->sr_err = LDAP_NO_SUCH_OBJECT; + rs->sr_err = LDAP_NO_SUCH_OBJECT; if(entry != NULL) - entry_free(entry); + entry_free(entry); rs->sr_text = ""; ldap_pvt_thread_mutex_unlock(&ni->li_mutex); ldap_pvt_thread_mutex_unlock(&entry2str_mutex); @@ -771,36 +773,36 @@ static int ldif_back_compare(Operation *op, SlapReply *rs) { e = (Entry *) get_entry(&op->o_req_ndn, &op->o_bd->be_nsuffix[0], &ni->li_base_path); if(e != NULL) { - for(a = attrs_find( e->e_attrs, op->oq_compare.rs_ava->aa_desc ); + for(a = attrs_find( e->e_attrs, op->oq_compare.rs_ava->aa_desc ); a != NULL; a = attrs_find( a->a_next, op->oq_compare.rs_ava->aa_desc )) - { + { rs->sr_err = LDAP_COMPARE_FALSE; if (value_find_ex(op->oq_compare.rs_ava->aa_desc, - SLAP_MR_ATTRIBUTE_VALUE_NORMALIZED_MATCH | - SLAP_MR_ASSERTED_VALUE_NORMALIZED_MATCH, - a->a_nvals, &op->oq_compare.rs_ava->aa_value, - op->o_tmpmemctx ) == 0) - { - rs->sr_err = LDAP_COMPARE_TRUE; - break; - } - } + SLAP_MR_ATTRIBUTE_VALUE_NORMALIZED_MATCH | + SLAP_MR_ASSERTED_VALUE_NORMALIZED_MATCH, + a->a_nvals, &op->oq_compare.rs_ava->aa_value, + op->o_tmpmemctx ) == 0) + { + rs->sr_err = LDAP_COMPARE_TRUE; + break; + } + } } else { - rs->sr_err = LDAP_NO_SUCH_OBJECT; + rs->sr_err = LDAP_NO_SUCH_OBJECT; } if(e != NULL) - entry_free(e); + entry_free(e); ldap_pvt_thread_mutex_unlock(&ni->li_mutex); send_ldap_result(op, rs); return 0; } static int ldif_tool_entry_open(BackendDB * be, int mode) { - struct ldif_info *ni = (struct ldif_info *) be->be_private; + struct ldif_info *ni = (struct ldif_info *) be->be_private; ni->tool_entries = NULL; ni->tool_numentries = 0; ni->tool_current = 0; @@ -809,116 +811,106 @@ static int ldif_tool_entry_open(BackendDB * be, int mode) { } static int ldif_tool_entry_close(BackendDB * be) { - struct ldif_info *ni = (struct ldif_info *) be->be_private; + struct ldif_info *ni = (struct ldif_info *) be->be_private; int i; /*if(ni->tool_entries != NULL) { - for(i=0;itool_numentries;i++) { - SLAP_FREE(ni->tool_entries[i]); - }*/ + for(i=0;itool_numentries;i++) { + SLAP_FREE(ni->tool_entries[i]); + }*/ SLAP_FREE(ni->tool_entries); return 0; } static ID ldif_tool_entry_first(BackendDB *be) { - struct ldif_info *ni = (struct ldif_info *) be->be_private; + struct ldif_info *ni = (struct ldif_info *) be->be_private; ID id = 1; /* first entry in the array of entries shifted by one */ ni->tool_current = 1; if(ni->tool_entries == NULL || ni->tool_put_entry_flag) { - ni->tool_entries = (Entry **) enum_tree(&ni->li_base_path, &ni->tool_numentries); - ni->tool_put_entry_flag = 0; + ni->tool_entries = (Entry **) enum_tree(&ni->li_base_path, &ni->tool_numentries, LDAP_SCOPE_SUBTREE); + ni->tool_put_entry_flag = 0; } return id; } static ID ldif_tool_entry_next(BackendDB *be) { - struct ldif_info *ni = (struct ldif_info *) be->be_private; + struct ldif_info *ni = (struct ldif_info *) be->be_private; ni->tool_current += 1; if(ni->tool_put_entry_flag) { - ni->tool_entries = (Entry **) enum_tree(&ni->li_base_path, &ni->tool_numentries); - ni->tool_put_entry_flag = 0; + ni->tool_entries = (Entry **) enum_tree(&ni->li_base_path, &ni->tool_numentries, LDAP_SCOPE_SUBTREE); + ni->tool_put_entry_flag = 0; } if(ni->tool_current > ni->tool_numentries) - return NOID; + return NOID; else - return ni->tool_current; + return ni->tool_current; } static Entry * ldif_tool_entry_get(BackendDB * be, ID id) { - struct ldif_info *ni = (struct ldif_info *) be->be_private; + struct ldif_info *ni = (struct ldif_info *) be->be_private; Entry * e; if(id > ni->tool_numentries || id < 1) - return NULL; + return NULL; else { - e = ni->tool_entries[id - 1]; - ni->tool_entries[id - 1] = NULL; - return e; + e = ni->tool_entries[id - 1]; + ni->tool_entries[id - 1] = NULL; + return e; } } static ID ldif_tool_entry_put(BackendDB * be, Entry * e, struct berval *text) { - struct ldif_info *ni = (struct ldif_info *) be->be_private; - Attribute *save_attrs; + struct ldif_info *ni = (struct ldif_info *) be->be_private; + Attribute *save_attrs; struct berval dn = e->e_nname; - char * leaf_path = NULL; - char * base = NULL; - char * base_ldif = NULL; + struct berval leaf_path = BER_BVNULL; struct stat stats; int statres; char textbuf[SLAP_TEXT_BUFLEN]; size_t textlen = sizeof textbuf; int res = LDAP_SUCCESS; - leaf_path = (char *) dn2path(&dn, &be->be_nsuffix[0], &ni->li_base_path); + dn2path(&dn, &be->be_nsuffix[0], &ni->li_base_path, &leaf_path); - /* save_attrs = e->e_attrs; why? - e->e_attrs = attrs_dup(e->e_attrs);*/ + if(leaf_path.bv_val != NULL) { + struct berval base = BER_BVNULL; + /* build path to container, and path to ldif of container */ + get_parent_path(&leaf_path, &base); - if(leaf_path != NULL) { - char * tmp; - /* build path to container, and path to ldif of container */ - base = (char *) get_parent_path(leaf_path); - base_ldif = (char *) SLAP_MALLOC(sizeof(char) * (strlen(base) + 6)); - tmp = (char *) lutil_strcopy(base_ldif, base); - lutil_strcopy(tmp, LDIF); - - statres = stat(base, &stats); /* check if container exists */ - if(statres == -1 && errno == ENOENT) { /* container missing */ - statres = stat(base_ldif, &stats); /* check for leaf node */ - if(statres == -1 && errno == ENOENT) { - res = LDAP_NO_SUCH_OBJECT; /* parent doesn't exist */ - } - else if(statres != -1) { /* create parent */ - int mkdirres = mkdir(base, 0750); - if(mkdirres == -1) { - res = LDAP_UNWILLING_TO_PERFORM; - } - } - else - res = LDAP_UNWILLING_TO_PERFORM; - }/* container was possibly created, move on to add the entry */ - if(res == LDAP_SUCCESS) { - statres = stat(leaf_path, &stats); - if(statres == -1 && errno == ENOENT) { - res = (int) spew_entry(e, leaf_path); - } - else /* it already exists */ - res = LDAP_ALREADY_EXISTS; - } + statres = stat(base.bv_val, &stats); /* check if container exists */ + if(statres == -1 && errno == ENOENT) { /* container missing */ + base.bv_val[base.bv_len] = '.'; + statres = stat(base.bv_val, &stats); /* check for leaf node */ + base.bv_val[base.bv_len] = '\0'; + if(statres == -1 && errno == ENOENT) { + res = LDAP_NO_SUCH_OBJECT; /* parent doesn't exist */ + } + else if(statres != -1) { /* create parent */ + int mkdirres = mkdir(base.bv_val, 0750); + if(mkdirres == -1) { + res = LDAP_UNWILLING_TO_PERFORM; + } + } + else + res = LDAP_UNWILLING_TO_PERFORM; + }/* container was possibly created, move on to add the entry */ + if(res == LDAP_SUCCESS) { + statres = stat(leaf_path.bv_val, &stats); + if(statres == -1 && errno == ENOENT) { + res = (int) spew_entry(e, &leaf_path); + } + else /* it already exists */ + res = LDAP_ALREADY_EXISTS; + } + SLAP_FREE(base.bv_val); + SLAP_FREE(leaf_path.bv_val); } - if(leaf_path != NULL) - SLAP_FREE(leaf_path); - if(base != NULL) - SLAP_FREE(base); - if(base_ldif != NULL) - SLAP_FREE(base_ldif); if(res == LDAP_SUCCESS) { - ni->tool_put_entry_flag = 1; - return 1; + ni->tool_put_entry_flag = 1; + return 1; } else - return NOID; + return NOID; } static int @@ -935,8 +927,8 @@ ldif_back_db_init( BackendDB *be ) static int ldif_back_db_destroy( - Backend *be - ) + Backend *be + ) { struct ldif_info *ni = be->be_private; ldap_pvt_thread_mutex_destroy(&ni->li_mutex); @@ -946,21 +938,21 @@ ldif_back_db_destroy( static int ldif_back_db_open( - Backend *be - ) + Backend *be + ) { struct ldif_info *ni = (struct ldif_info *) be->be_private; if( BER_BVISEMPTY(&ni->li_base_path)) {/* missing base path */ - fprintf(stderr, "missing base path for back-ldif\n"); - return 1; + fprintf(stderr, "missing base path for back-ldif\n"); + return 1; } return 0; } int ldif_back_initialize( - BackendInfo *bi - ) + BackendInfo *bi + ) { int rc;