void dacl_sort_into_canonical_order(struct security_ace *srclist, unsigned int num_aces) { unsigned int i; if (!srclist || num_aces == 0) return; /* Sort so that non-inherited ACE's come first. */ TYPESAFE_QSORT(srclist, num_aces, nt_ace_inherit_comp); /* Find the boundary between non-inherited ACEs. */ for (i = 0; i < num_aces; i++ ) { struct security_ace *curr_ace = &srclist[i]; if (curr_ace->flags & SEC_ACE_FLAG_INHERITED_ACE) break; } /* i now points at entry number of the first inherited ACE. */ /* Sort the non-inherited ACEs. */ TYPESAFE_QSORT(srclist, i, nt_ace_canon_comp); /* Now sort the inherited ACEs. */ TYPESAFE_QSORT(&srclist[i], num_aces - i, nt_ace_canon_comp); }
void web_set_lang(const char *lang_string) { char **lang_list, **count; struct pri_list *pl; int lang_num, i; /* build the lang list */ lang_list = str_list_make_v3(talloc_tos(), lang_string, ", \t\r\n"); if (!lang_list) return; /* sort the list by priority */ lang_num = 0; count = lang_list; while (*count && **count) { count++; lang_num++; } pl = SMB_MALLOC_ARRAY(struct pri_list, lang_num); if (!pl) { return; } for (i = 0; i < lang_num; i++) { char *pri_code; if ((pri_code=strstr(lang_list[i], ";q="))) { *pri_code = '\0'; pri_code += 3; sscanf(pri_code, "%f", &(pl[i].pri)); } else { pl[i].pri = 1; } pl[i].string = SMB_STRDUP(lang_list[i]); } TALLOC_FREE(lang_list); TYPESAFE_QSORT(pl, lang_num, qsort_cmp_list); /* it's not an error to not initialise - we just fall back to the default */ for (i = 0; i < lang_num; i++) { if (lang_tdb_init(pl[i].string)) break; } for (i = 0; i < lang_num; i++) { SAFE_FREE(pl[i].string); } SAFE_FREE(pl); return; }
static bool open_and_sort_dir(vfs_handle_struct *handle, struct dirsort_privates *data) { unsigned int i = 0; unsigned int total_count = 0; data->number_of_entries = 0; if (get_sorted_dir_mtime(handle, data, &data->mtime) == false) { return false; } while (SMB_VFS_NEXT_READDIR(handle, data->source_directory, NULL) != NULL) { total_count++; } if (total_count == 0) { return false; } /* Open the underlying directory and count the number of entries Skip back to the beginning as we'll read it again */ SMB_VFS_NEXT_REWINDDIR(handle, data->source_directory); /* Set up an array and read the directory entries into it */ TALLOC_FREE(data->directory_list); /* destroy previous cache if needed */ data->directory_list = talloc_zero_array(data, struct dirent, total_count); if (!data->directory_list) { return false; } for (i = 0; i < total_count; i++) { struct dirent *dp = SMB_VFS_NEXT_READDIR(handle, data->source_directory, NULL); if (dp == NULL) { break; } data->directory_list[i] = *dp; } data->number_of_entries = i; /* Sort the directory entries by name */ TYPESAFE_QSORT(data->directory_list, data->number_of_entries, compare_dirent); return true; }
static bool open_and_sort_dir (vfs_handle_struct *handle) { SMB_STRUCT_DIRENT *dp; struct stat dir_stat; long current_pos; struct dirsort_privates *data = NULL; SMB_VFS_HANDLE_GET_DATA(handle, data, struct dirsort_privates, return false); data->number_of_entries = 0; if (fstat(data->fd, &dir_stat) == 0) { data->mtime = dir_stat.st_mtime; } while (SMB_VFS_NEXT_READDIR(handle, data->source_directory, NULL) != NULL) { data->number_of_entries++; } /* Open the underlying directory and count the number of entries Skip back to the beginning as we'll read it again */ SMB_VFS_NEXT_REWINDDIR(handle, data->source_directory); /* Set up an array and read the directory entries into it */ SAFE_FREE(data->directory_list); /* destroy previous cache if needed */ data->directory_list = (SMB_STRUCT_DIRENT *)SMB_MALLOC( data->number_of_entries * sizeof(SMB_STRUCT_DIRENT)); if (!data->directory_list) { return false; } current_pos = data->pos; data->pos = 0; while ((dp = SMB_VFS_NEXT_READDIR(handle, data->source_directory, NULL)) != NULL) { data->directory_list[data->pos++] = *dp; } /* Sort the directory entries by name */ data->pos = current_pos; TYPESAFE_QSORT(data->directory_list, data->number_of_entries, compare_dirent); return true; }
/* load only the value names into memory to enable searching */ WERROR value_list_load_quick(struct value_list *vl, struct registry_key *key) { uint32_t nvalues; uint32_t idx; struct value_item *vitem, *new_items; WERROR rv; multilist_set_data(vl->list, NULL); vl->nvalues = 0; TALLOC_FREE(vl->values); nvalues = get_num_values(vl, key); if (nvalues == 0) { return WERR_OK; } new_items = talloc_zero_array(vl, struct value_item, nvalues); if (new_items == NULL) { return WERR_NOMEM; } for (idx = 0; idx < nvalues; ++idx) { vitem = &new_items[idx]; rv = reg_key_get_value_by_index(new_items, key, idx, &vitem->value_name, &vitem->type, &vitem->data); if (!W_ERROR_IS_OK(rv)) { talloc_free(new_items); return rv; } } TYPESAFE_QSORT(new_items, nvalues, vitem_cmp); vl->nvalues = nvalues; vl->values = new_items; return rv; }
static struct dom_usr *get_domain_userlist(TALLOC_CTX *mem_ctx) { struct sessionid *session_list = NULL; char *machine_name, *p, *nm; const char *sep; struct dom_usr *users, *tmp; int i, num_users, num_sessions; sep = lp_winbind_separator(); if (!sep) { sep = "\\"; } num_sessions = list_sessions(mem_ctx, &session_list); if (num_sessions == 0) { errno = 0; return NULL; } users = talloc_array(mem_ctx, struct dom_usr, num_sessions); if (users == NULL) { TALLOC_FREE(session_list); return NULL; } for (i=num_users=0; i<num_sessions; i++) { if (!session_list[i].username || !session_list[i].remote_machine) { continue; } p = strpbrk(session_list[i].remote_machine, "./"); if (p) { *p = '\0'; } machine_name = talloc_asprintf_strupper_m( users, "%s", session_list[i].remote_machine); if (machine_name == NULL) { DEBUG(10, ("talloc_asprintf failed\n")); continue; } if (strcmp(machine_name, lp_netbios_name()) == 0) { p = session_list[i].username; nm = strstr(p, sep); if (nm) { /* * "domain+name" format so split domain and * name components */ *nm = '\0'; nm += strlen(sep); users[num_users].domain = talloc_asprintf_strupper_m(users, "%s", p); users[num_users].name = talloc_strdup(users, nm); } else { /* * Simple user name so get domain from smb.conf */ users[num_users].domain = talloc_strdup(users, lp_workgroup()); users[num_users].name = talloc_strdup(users, p); } users[num_users].login_time = session_list[i].connect_start; num_users++; } TALLOC_FREE(machine_name); } TALLOC_FREE(session_list); tmp = talloc_realloc(mem_ctx, users, struct dom_usr, num_users); if (tmp == NULL) { return NULL; } users = tmp; /* Sort the user list by time, oldest first */ TYPESAFE_QSORT(users, num_users, dom_user_cmp); errno = 0; return users; }
/* create the sorted accessor arrays for the schema */ int dsdb_setup_sorted_accessors(struct ldb_context *ldb, struct dsdb_schema *schema) { struct dsdb_class *cur; struct dsdb_attribute *a; unsigned int i; unsigned int num_int_id; int ret; /* free all caches */ dsdb_sorted_accessors_free(schema); /* count the classes */ for (i=0, cur=schema->classes; cur; i++, cur=cur->next) /* noop */ ; schema->num_classes = i; /* setup classes_by_* */ schema->classes_by_lDAPDisplayName = talloc_array(schema, struct dsdb_class *, i); schema->classes_by_governsID_id = talloc_array(schema, struct dsdb_class *, i); schema->classes_by_governsID_oid = talloc_array(schema, struct dsdb_class *, i); schema->classes_by_cn = talloc_array(schema, struct dsdb_class *, i); if (schema->classes_by_lDAPDisplayName == NULL || schema->classes_by_governsID_id == NULL || schema->classes_by_governsID_oid == NULL || schema->classes_by_cn == NULL) { goto failed; } for (i=0, cur=schema->classes; cur; i++, cur=cur->next) { schema->classes_by_lDAPDisplayName[i] = cur; schema->classes_by_governsID_id[i] = cur; schema->classes_by_governsID_oid[i] = cur; schema->classes_by_cn[i] = cur; } /* sort the arrays */ TYPESAFE_QSORT(schema->classes_by_lDAPDisplayName, schema->num_classes, dsdb_compare_class_by_lDAPDisplayName); TYPESAFE_QSORT(schema->classes_by_governsID_id, schema->num_classes, dsdb_compare_class_by_governsID_id); TYPESAFE_QSORT(schema->classes_by_governsID_oid, schema->num_classes, dsdb_compare_class_by_governsID_oid); TYPESAFE_QSORT(schema->classes_by_cn, schema->num_classes, dsdb_compare_class_by_cn); /* now build the attribute accessor arrays */ /* count the attributes * and attributes with msDS-IntId set */ num_int_id = 0; for (i=0, a=schema->attributes; a; i++, a=a->next) { if (a->msDS_IntId != 0) { num_int_id++; } } schema->num_attributes = i; schema->num_int_id_attr = num_int_id; /* setup attributes_by_* */ schema->attributes_by_lDAPDisplayName = talloc_array(schema, struct dsdb_attribute *, i); schema->attributes_by_attributeID_id = talloc_array(schema, struct dsdb_attribute *, i); schema->attributes_by_msDS_IntId = talloc_array(schema, struct dsdb_attribute *, num_int_id); schema->attributes_by_attributeID_oid = talloc_array(schema, struct dsdb_attribute *, i); schema->attributes_by_linkID = talloc_array(schema, struct dsdb_attribute *, i); if (schema->attributes_by_lDAPDisplayName == NULL || schema->attributes_by_attributeID_id == NULL || schema->attributes_by_msDS_IntId == NULL || schema->attributes_by_attributeID_oid == NULL || schema->attributes_by_linkID == NULL) { goto failed; } num_int_id = 0; for (i=0, a=schema->attributes; a; i++, a=a->next) { schema->attributes_by_lDAPDisplayName[i] = a; schema->attributes_by_attributeID_id[i] = a; schema->attributes_by_attributeID_oid[i] = a; schema->attributes_by_linkID[i] = a; /* append attr-by-msDS-IntId values */ if (a->msDS_IntId != 0) { schema->attributes_by_msDS_IntId[num_int_id] = a; num_int_id++; } } SMB_ASSERT(num_int_id == schema->num_int_id_attr); /* sort the arrays */ TYPESAFE_QSORT(schema->attributes_by_lDAPDisplayName, schema->num_attributes, dsdb_compare_attribute_by_lDAPDisplayName); TYPESAFE_QSORT(schema->attributes_by_attributeID_id, schema->num_attributes, dsdb_compare_attribute_by_attributeID_id); TYPESAFE_QSORT(schema->attributes_by_msDS_IntId, schema->num_int_id_attr, dsdb_compare_attribute_by_msDS_IntId); TYPESAFE_QSORT(schema->attributes_by_attributeID_oid, schema->num_attributes, dsdb_compare_attribute_by_attributeID_oid); TYPESAFE_QSORT(schema->attributes_by_linkID, schema->num_attributes, dsdb_compare_attribute_by_linkID); dsdb_setup_attribute_shortcuts(ldb, schema); ret = schema_fill_constructed(schema); if (ret != LDB_SUCCESS) { dsdb_sorted_accessors_free(schema); return ret; } return LDB_SUCCESS; failed: dsdb_sorted_accessors_free(schema); return ldb_oom(ldb); }
/* sort the elements of a message by name */ void ldb_msg_sort_elements(struct ldb_message *msg) { TYPESAFE_QSORT(msg->elements, msg->num_elements, ldb_msg_element_compare_name); }
int ldb_msg_find_common_values(struct ldb_context *ldb, TALLOC_CTX *mem_ctx, struct ldb_message_element *el, struct ldb_message_element *el2, uint32_t options) { struct ldb_val *values; struct ldb_val *values2; unsigned int i, j, k, n_values; bool remove_duplicates = options & LDB_MSG_FIND_COMMON_REMOVE_DUPLICATES; if ((options & ~LDB_MSG_FIND_COMMON_REMOVE_DUPLICATES) != 0) { return LDB_ERR_OPERATIONS_ERROR; } if (strcmp(el->name, el2->name) != 0) { return LDB_ERR_INAPPROPRIATE_MATCHING; } if (el->num_values == 0 || el2->num_values == 0) { return LDB_SUCCESS; } /* With few values, it is better to do the brute-force search than the clever search involving tallocs, memcpys, sorts, etc. */ if (MIN(el->num_values, el2->num_values) == 1 || MAX(el->num_values, el2->num_values) < LDB_DUP_QUADRATIC_THRESHOLD) { for (i = 0; i < el2->num_values; i++) { for (j = 0; j < el->num_values; j++) { if (ldb_val_equal_exact(&el->values[j], &el2->values[i])) { if (! remove_duplicates) { return \ LDB_ERR_ATTRIBUTE_OR_VALUE_EXISTS; } /* With the remove_duplicates flag, we resolve the intersection by removing the offending one from el. */ el->num_values--; for (k = j; k < el->num_values; k++) { el->values[k] = \ el->values[k + 1]; } j--; /* rewind */ } } } return LDB_SUCCESS; } values = talloc_array(mem_ctx, struct ldb_val, el->num_values); if (values == NULL) { return LDB_ERR_OPERATIONS_ERROR; } values2 = talloc_array(mem_ctx, struct ldb_val, el2->num_values); if (values2 == NULL) { return LDB_ERR_OPERATIONS_ERROR; } memcpy(values, el->values, el->num_values * sizeof(struct ldb_val)); memcpy(values2, el2->values, el2->num_values * sizeof(struct ldb_val)); TYPESAFE_QSORT(values, el->num_values, ldb_val_cmp); TYPESAFE_QSORT(values2, el2->num_values, ldb_val_cmp); /* el->n_values may diverge from the number of values in the sorted list when the remove_duplicates flag is used. */ n_values = el->num_values; i = 0; j = 0; while (i != n_values && j < el2->num_values) { int ret = ldb_val_cmp(&values[i], &values2[j]); if (ret < 0) { i++; } else if (ret > 0) { j++; } else { /* we have a collision */ if (! remove_duplicates) { TALLOC_FREE(values); TALLOC_FREE(values2); return LDB_ERR_ATTRIBUTE_OR_VALUE_EXISTS; } /* With the remove_duplicates flag we need to find this in the original list and remove it, which is inefficient but hopefully rare. */ for (k = 0; k < el->num_values; k++) { if (ldb_val_equal_exact(&el->values[k], &values[i])) { break; } } el->num_values--; for (; k < el->num_values; k++) { el->values[k] = el->values[k + 1]; } i++; } } TALLOC_FREE(values); TALLOC_FREE(values2); return LDB_SUCCESS; }
int ldb_msg_find_duplicate_val(struct ldb_context *ldb, TALLOC_CTX *mem_ctx, const struct ldb_message_element *el, struct ldb_val **duplicate, uint32_t options) { unsigned int i, j; struct ldb_val *val; if (options != 0) { return LDB_ERR_OPERATIONS_ERROR; } *duplicate = NULL; /* If there are not many values, it is best to avoid the talloc overhead and just do a brute force search. */ if (el->num_values < LDB_DUP_QUADRATIC_THRESHOLD) { for (j = 0; j < el->num_values; j++) { val = &el->values[j]; for ( i = j + 1; i < el->num_values; i++) { if (ldb_val_equal_exact(val, &el->values[i])) { *duplicate = val; return LDB_SUCCESS; } } } } else { struct ldb_val *values; values = talloc_array(mem_ctx, struct ldb_val, el->num_values); if (values == NULL) { return LDB_ERR_OPERATIONS_ERROR; } memcpy(values, el->values, el->num_values * sizeof(struct ldb_val)); TYPESAFE_QSORT(values, el->num_values, ldb_val_cmp); for (i = 1; i < el->num_values; i++) { if (ldb_val_equal_exact(&values[i], &values[i - 1])) { /* find the original location */ for (j = 0; j < el->num_values; j++) { if (ldb_val_equal_exact(&values[i], &el->values[j]) ) { *duplicate = &el->values[j]; break; } } talloc_free(values); if (*duplicate == NULL) { /* how we got here, I don't know */ return LDB_ERR_OPERATIONS_ERROR; } return LDB_SUCCESS; } } talloc_free(values); } return LDB_SUCCESS; }