Exemple #1
0
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);
}
Exemple #2
0
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;
}
Exemple #3
0
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;
}
Exemple #4
0
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;
}
Exemple #6
0
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;
}
Exemple #7
0
/*
  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);
}
Exemple #8
0
/*
  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);
}
Exemple #9
0
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;
}
Exemple #10
0
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;
}