END_TEST START_TEST (check_fs_rid_set_scan) { fs_rid_set *s = fs_rid_set_new(); fail_unless(s != NULL); int i=0; int ELTS = 10000; for (i=1; i <= ELTS; i++) { fs_rid_set_add(s, (fs_rid) i); if ((i % 2 == 0) || (i % 5 == 0)) fs_rid_set_add(s, (fs_rid) i); } int pass=0; for (pass=0; pass < 2; pass++) { fs_rid_set_rewind(s); fs_rid e = FS_RID_NULL; int count = 0; while((e = fs_rid_set_next(s)) != FS_RID_NULL) { count = count + 1; fail_if(e <= 0 || e > (ELTS)); } fail_if(count != ELTS); } fs_rid_set_free(s); }
END_TEST START_TEST (check_fs_rid_set_add_contains) { fs_rid_set *s = fs_rid_set_new(); fail_unless(s != NULL); int i=0; for (i=0; i < 1e4; i++) { fs_rid_set_add(s, i); } for (i=0; i < 1e4; i++) { fail_if(!fs_rid_set_contains(s,i)); } fs_rid_set_free(s); }
/** * It wraps up the bind operation to discard rows from the result that cannot be accessed. */ int fs_bind_cache_wrapper_intl_acl(fs_query_state *qs, fs_query *q, int all, int flags, fs_rid_vector *rids[4], fs_rid_vector ***result, int offset, int limit) { int flags_copy = flags; int ndiscarded = 0; if (fsp_is_acl_enabled(qs->link)) { flags = flags | FS_BIND_MODEL; } int ret = fs_bind_cache_wrapper_intl(qs, q, all, flags, rids, result, offset, limit); if (fsp_is_acl_enabled(qs->link) && (*result)) { unsigned char *rows_discarded = NULL; /* TODO probably this can be done with one iteration of results */ fs_rid_set *inv_acl = no_access_for_user(qs->link->acl_system_info,q->apikey_rid); ndiscarded = fs_mark_discard_rows((*result)[0], inv_acl, &rows_discarded); if (inv_acl) fs_rid_set_free(inv_acl); int slots = fs_slots_n(flags_copy); if (!(flags_copy & FS_BIND_MODEL) && (flags & FS_BIND_MODEL)) { fs_rid_vector **result_copy = calloc(slots, sizeof(fs_rid_vector)); for (int i=0;i<slots;i++) result_copy[i] = (*result)[i+1]; fs_rid_vector_free((*result)[0]); free(*result); *result = result_copy; } if (ndiscarded) { fs_rid_vector **rows = *result; int count = fs_rid_vector_length(rows[0]); int shifts = 0; for (int i=0; i < count; i++) { for (int s=0;s<slots;s++) rows[s]->data[i-shifts] = rows[s]->data[i]; if (!fs_bit_array_get(rows_discarded, i)) shifts++; } for (int s=0;s<slots;s++) { rows[s]->length -= ndiscarded; } } if (rows_discarded) fs_bit_array_destroy(rows_discarded); } return ret - ndiscarded; }
/** * It loads the acl system info from the system:config graph. * Due to link->acl_system_info manipulation this function should be * under mutex conditions. */ int fs_acl_load_system_info(fsp_link *link) { if (!fsp_acl_needs_reload(link)) return 0; int flags = FS_BIND_SUBJECT | FS_BIND_PREDICATE | FS_BIND_OBJECT | FS_BIND_BY_SUBJECT; fs_rid_vector *mrids = fs_rid_vector_new_from_args(1, fs_c.system_config); fs_rid_vector *srids = fs_rid_vector_new(0); fs_rid_vector *prids = fs_rid_vector_new_from_args(2, fs_c.fs_acl_admin, fs_c.fs_acl_access_by); fs_rid_vector *orids = fs_rid_vector_new(0); fs_rid_vector **result = NULL; fsp_bind_limit_all(link, flags, mrids, srids, prids, orids, &result, -1, -1); fs_rid_vector_free(mrids); fs_rid_vector_free(srids); fs_rid_vector_free(prids); fs_rid_vector_free(orids); int admin_users_count = 0; fs_acl_system_info *acl_system_info = link->acl_system_info; if (result && result[0]) { if (!acl_system_info->acl_graph_hash || acl_system_info->admin_user_set) link->acl_system_info = acl_system_info; if (acl_system_info->acl_graph_hash) { g_hash_table_steal(acl_system_info->acl_graph_hash, &fs_c.system_config); g_hash_table_destroy(acl_system_info->acl_graph_hash); acl_system_info->acl_graph_hash = NULL; } acl_system_info->acl_graph_hash = g_hash_table_new_full(fs_rid_hash,fs_rid_equal, acl_key_destroyed, acl_value_destroyed); if (acl_system_info->admin_user_set) { fs_rid_set_free(acl_system_info->admin_user_set); acl_system_info->admin_user_set = NULL; } acl_system_info->admin_user_set = fs_rid_set_new(); for (int row = 0; row < result[0]->length; row++) { if(result[1]->data[row] == fs_c.fs_acl_access_by) { /* if pred is acl_access_by then subject is the graph and object is the user rid */ gpointer users_set_ref = NULL; fs_rid_set *users_set = NULL; if (!(users_set_ref=g_hash_table_lookup(acl_system_info->acl_graph_hash, &result[0]->data[row]))) { users_set = fs_rid_set_new(); fs_rid *rid_graph = malloc(sizeof(fs_rid)); *rid_graph = result[0]->data[row]; g_hash_table_insert(acl_system_info->acl_graph_hash, rid_graph, users_set); } else users_set = (fs_rid_set *) users_set_ref; fs_rid_set_add(users_set, result[2]->data[row]); } else if (result[1]->data[row] == fs_c.fs_acl_admin) { /* if admin predicate then object contains the admin user rid id */ fs_rid_set_add(acl_system_info->admin_user_set, result[2]->data[row]); admin_users_count++; } } if (admin_users_count == 0) { fs_error(LOG_ERR,"Added default admin user %s",FS_ACL_DEFAULT_ADMIN); fs_rid_set_add(acl_system_info->admin_user_set, fs_c.fs_acl_default_admin); } /* only admin users can access system:config */ g_hash_table_insert(acl_system_info->acl_graph_hash, &fs_c.system_config, acl_system_info->admin_user_set); } fsp_acl_reloaded(link); if (result) { for (int i=0;i<3;i++) { fs_rid_vector_free(result[i]); } free(result); } return 1; }
static void acl_value_destroyed(gpointer pdata) { fs_rid_set *data = (fs_rid_set *) pdata; fs_rid_set_free(data); }