1 /* vi: set et sw=4 ts=4 cino=t0,(0: */
2 /* -*- Mode: C; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
4 * This file is part of gsignond
6 * Copyright (C) 2012 Intel Corporation.
8 * Contact: Imran Zaman <imran.zaman@linux.intel.com>
10 * This library is free software; you can redistribute it and/or
11 * modify it under the terms of the GNU Lesser General Public
12 * License as published by the Free Software Foundation; either
13 * version 2.1 of the License, or (at your option) any later version.
15 * This library is distributed in the hope that it will be useful, but
16 * WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 * Lesser General Public License for more details.
20 * You should have received a copy of the GNU Lesser General Public
21 * License along with this library; if not, write to the Free Software
22 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
31 #include "gsignond/gsignond-log.h"
32 #include "gsignond/gsignond-config.h"
33 #include "common/db/gsignond-db-error.h"
34 #include "gsignond-db-metadata-database.h"
36 #define RETURN_IF_NOT_OPEN(obj, retval) \
37 if (gsignond_db_sql_database_is_open (obj) == FALSE) { \
38 GError* last_error = gsignond_db_create_error( \
39 GSIGNOND_DB_ERROR_NOT_OPEN,\
41 DBG("MetadataDB is not available"); \
42 gsignond_db_sql_database_set_last_error(obj,\
47 #define GSIGNOND_DB_METADATA_DATABASE_GET_PRIVATE(obj) \
48 (G_TYPE_INSTANCE_GET_PRIVATE ((obj),\
49 GSIGNOND_DB_TYPE_METADATA_DATABASE, \
50 GSignondDbMetadataDatabasePrivate))
52 G_DEFINE_TYPE (GSignondDbMetadataDatabase, gsignond_db_metadata_database,
53 GSIGNOND_DB_TYPE_SQL_DATABASE);
55 struct _GSignondDbMetadataDatabasePrivate
66 static GParamSpec *properties[N_PROPERTIES] = { NULL, };
69 _set_property (GObject *object, guint prop_id, const GValue *value,
72 GSignondDbMetadataDatabase *self = GSIGNOND_DB_METADATA_DATABASE (object);
76 g_assert (self->config == NULL);
77 self->config = g_value_dup_object (value);
80 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
85 _get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec)
87 GSignondDbMetadataDatabase *self = GSIGNOND_DB_METADATA_DATABASE (object);
91 g_value_set_object (value, self->config);
94 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
99 _gsignond_db_metadata_database_open (
100 GSignondDbSqlDatabase *obj,
101 const gchar *filename,
105 _gsignond_db_metadata_database_create (
106 GSignondDbSqlDatabase *obj);
109 _gsignond_db_metadata_database_clear (
110 GSignondDbSqlDatabase *obj);
113 * @enum GSignondIdentityFlags
114 * Flags for the identity to be stored into db
116 enum GSignondIdentityFlags {
117 GSignondIdentityFlag_Validated = 0x0001,
118 GSignondIdentityFlag_RememberSecret = 0x0002,
119 GSignondIdentityFlag_UserNameIsSecret = 0x0004,
129 return g_strcmp0 (a,b);
133 _gsignond_db_metadata_database_list_to_sequence (GList *list)
135 GSequence *seq = NULL;
136 seq = g_sequence_new ((GDestroyNotify)g_free);
137 list = g_list_first (list);
138 for ( ; list != NULL; list = g_list_next (list)) {
139 g_sequence_insert_sorted (seq, (gchar *) list->data,
140 (GCompareDataFunc)_compare_strings, NULL);
146 _gsignond_db_metadata_database_read_identity (
148 GSignondIdentityInfo *identity)
152 gsignond_identity_info_set_caption (identity,
153 (const gchar *)sqlite3_column_text (stmt, 0));
155 flags = sqlite3_column_int (stmt, 2);
157 gsignond_identity_info_set_username_secret (identity,
158 flags & GSignondIdentityFlag_UserNameIsSecret);
160 if (flags & GSignondIdentityFlag_UserNameIsSecret) {
161 gsignond_identity_info_set_caption (identity, "");
163 gsignond_identity_info_set_username (identity,
164 (const gchar *)sqlite3_column_text (stmt, 1));
167 gsignond_identity_info_set_store_secret (identity,
168 flags & GSignondIdentityFlag_RememberSecret);
170 gsignond_identity_info_set_validated (identity,
171 flags & GSignondIdentityFlag_Validated);
173 gsignond_identity_info_set_identity_type (identity,
174 sqlite3_column_int (stmt, 3));
180 _gsignond_db_metadata_database_exec (
181 GSignondDbMetadataDatabase *self,
182 const gchar *query_format,
185 gboolean ret = FALSE;
189 g_return_val_if_fail (query_format != NULL, FALSE);
191 va_start (args, query_format);
192 query = sqlite3_vmprintf (query_format, args);
195 ret = gsignond_db_sql_database_exec (
196 GSIGNOND_DB_SQL_DATABASE (self),
198 sqlite3_free (query);
205 _gsignond_db_metadata_database_get_sequence (
206 GSignondDbMetadataDatabase *self,
207 const gchar *query_format,
210 GSequence *seq = NULL;
215 g_return_val_if_fail (query_format != NULL, NULL);
217 va_start (args, query_format);
218 query = sqlite3_vmprintf (query_format, args);
221 list = gsignond_db_sql_database_query_exec_string_list (
222 GSIGNOND_DB_SQL_DATABASE (self),
224 sqlite3_free (query);
225 seq = _gsignond_db_metadata_database_list_to_sequence (list);
226 g_list_free (list); /*list elements are owned by sequence*/
232 _gsignond_db_metadata_database_update_credentials (
233 GSignondDbMetadataDatabase *self,
234 GSignondIdentityInfo *identity)
240 const gchar *caption= NULL, *username = NULL;
241 gboolean ret = FALSE;
243 g_return_val_if_fail (GSIGNOND_DB_IS_METADATA_DATABASE (self), 0);
244 g_return_val_if_fail (identity != NULL, 0);
246 if (gsignond_identity_info_get_validated (identity) )
247 flags |= GSignondIdentityFlag_Validated;
248 if (gsignond_identity_info_get_store_secret (identity) )
249 flags |= GSignondIdentityFlag_RememberSecret;
250 if (gsignond_identity_info_get_is_username_secret (identity) ) {
251 flags |= GSignondIdentityFlag_UserNameIsSecret;
253 username = gsignond_identity_info_get_username (identity);
255 caption = gsignond_identity_info_get_caption (identity);
257 id = gsignond_identity_info_get_id (identity);
258 type = gsignond_identity_info_get_identity_type (identity);
259 if (!gsignond_identity_info_get_is_identity_new (identity)) {
260 query = sqlite3_mprintf ("UPDATE IDENTITY SET caption = %Q, "
261 "username = %Q, flags = %u, type = %u WHERE id = %u;",
262 caption ?caption : "",username? username : "", flags, type, id);
264 query = sqlite3_mprintf ("INSERT INTO IDENTITY "
265 "(caption, username, flags, type) "
266 "VALUES(%Q, %Q, %u, %u);",
267 caption ?caption : "",username? username : "", flags, type);
269 ret = gsignond_db_sql_database_exec (
270 GSIGNOND_DB_SQL_DATABASE (self),
272 sqlite3_free (query);
277 if (gsignond_identity_info_get_is_identity_new (identity)) {
278 id = gsignond_db_sql_database_get_last_insert_rowid (
279 GSIGNOND_DB_SQL_DATABASE (self));
285 _gsignond_db_metadata_database_update_realms (
286 GSignondDbMetadataDatabase *self,
287 GSignondIdentityInfo *identity,
291 GSequenceIter *iter = NULL;
293 g_return_val_if_fail (GSIGNOND_DB_IS_METADATA_DATABASE (self), FALSE);
294 g_return_val_if_fail (identity != NULL, FALSE);
296 if (realms && g_sequence_get_length (realms) > 0) {
298 if (!gsignond_identity_info_get_is_identity_new (identity)) {
299 /* remove realms list */
300 DBG ("Remove old realms from DB as identity is not new");
301 _gsignond_db_metadata_database_exec (self,
302 "DELETE FROM REALMS WHERE identity_id = %u;", id);
306 iter = g_sequence_get_begin_iter (realms);
307 while (!g_sequence_iter_is_end (iter)) {
308 if (!_gsignond_db_metadata_database_exec (self,
309 "INSERT OR IGNORE INTO REALMS (identity_id, realm) "
311 id, (const gchar *)g_sequence_get (iter))) {
312 DBG ("Insert realms to DB failed");
315 iter = g_sequence_iter_next (iter);
322 _gsignond_db_metadata_database_insert_methods (
323 GSignondDbMetadataDatabase *self,
324 GSignondIdentityInfo *identity,
327 GSequenceIter *mech_iter = NULL;
328 GHashTableIter method_iter;
329 const gchar *method = NULL;
330 GSequence *mechanisms = NULL;
332 g_return_val_if_fail (GSIGNOND_DB_IS_METADATA_DATABASE (self), FALSE);
333 g_return_val_if_fail (identity != NULL, FALSE);
335 if (!methods || g_hash_table_size (methods) <=0) {
336 DBG ("no authentication methods found to store identity");
340 g_hash_table_iter_init (&method_iter, methods);
341 while (g_hash_table_iter_next (&method_iter,
343 (gpointer)&mechanisms))
345 if (!_gsignond_db_metadata_database_exec ( self,
346 "INSERT OR IGNORE INTO METHODS (method) "
349 DBG ("Insert methods to DB failed");
352 /* mechanisms insert */
353 mech_iter = g_sequence_get_begin_iter (mechanisms);
354 while (!g_sequence_iter_is_end (mech_iter)) {
355 if (!_gsignond_db_metadata_database_exec (self,
356 "INSERT OR IGNORE INTO MECHANISMS (mechanism) "
358 g_sequence_get (mech_iter))) {
359 DBG ("Insert mechanisms to DB failed");
362 mech_iter = g_sequence_iter_next (mech_iter);
370 _gsignond_db_metadata_database_update_acl (
371 GSignondDbMetadataDatabase *self,
372 GSignondIdentityInfo *identity,
373 GSignondSecurityContextList *acl)
375 GSignondSecurityContextList *list = NULL;
376 GSignondSecurityContext *ctx = NULL;
378 g_return_val_if_fail (GSIGNOND_DB_IS_METADATA_DATABASE (self), FALSE);
379 g_return_val_if_fail (identity != NULL, FALSE);
381 if (!acl || g_list_length (acl) <= 0) {
382 DBG ("NULL acl or no acl to be added to DB");
386 for (list = acl; list != NULL; list = g_list_next (list)) {
387 ctx = (GSignondSecurityContext *) list->data;
388 _gsignond_db_metadata_database_exec (self,
389 "INSERT OR IGNORE INTO SECCTX (sysctx, appctx) "
391 ctx->sys_ctx, ctx->app_ctx);
397 _gsignond_db_metadata_database_update_owner (
398 GSignondDbMetadataDatabase *self,
399 GSignondIdentityInfo *identity,
400 GSignondSecurityContext *owner)
402 g_return_val_if_fail (GSIGNOND_DB_IS_METADATA_DATABASE (self), FALSE);
403 g_return_val_if_fail (identity != NULL, FALSE);
406 DBG ("no owner to be added to DB");
410 if (owner->sys_ctx && strlen (owner->sys_ctx) > 0) {
411 _gsignond_db_metadata_database_exec (self,
412 "INSERT OR IGNORE INTO "
413 "SECCTX (sysctx, appctx) "
415 owner->sys_ctx, owner->app_ctx);
422 _gsignond_db_metadata_database_dispose (GObject *gobject)
424 g_return_if_fail (GSIGNOND_DB_IS_METADATA_DATABASE (gobject));
425 GSignondDbMetadataDatabase *self = GSIGNOND_DB_METADATA_DATABASE (gobject);
428 g_object_unref (self->config);
432 /* Chain up to the parent class */
433 G_OBJECT_CLASS (gsignond_db_metadata_database_parent_class)->dispose (
438 gsignond_db_metadata_database_class_init (
439 GSignondDbMetadataDatabaseClass *klass)
441 GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
443 gobject_class->set_property = _set_property;
444 gobject_class->get_property = _get_property;
445 gobject_class->dispose = _gsignond_db_metadata_database_dispose;
447 properties[PROP_CONFIG] = g_param_spec_object ("config",
449 "Configuration object",
450 GSIGNOND_TYPE_CONFIG,
451 G_PARAM_CONSTRUCT_ONLY |
453 G_PARAM_STATIC_STRINGS);
454 g_object_class_install_properties (gobject_class, N_PROPERTIES, properties);
456 GSignondDbSqlDatabaseClass *sql_class =
457 GSIGNOND_DB_SQL_DATABASE_CLASS (klass);
459 sql_class->create = _gsignond_db_metadata_database_create;
460 sql_class->clear = _gsignond_db_metadata_database_clear;
465 gsignond_db_metadata_database_init (
466 GSignondDbMetadataDatabase *self)
472 * gsignond_db_metadata_database_new:
474 * @config: (transfer none) #GSignondConfig config data
476 * Creates new #GSignondDbMetadataDatabase object
478 * Returns : (transfer full) the #GSignondDbMetadataDatabase object
480 GSignondDbMetadataDatabase *
481 gsignond_db_metadata_database_new (GSignondConfig *config)
483 return GSIGNOND_DB_METADATA_DATABASE (
484 g_object_new (GSIGNOND_DB_TYPE_METADATA_DATABASE,
485 "config", config, NULL));
489 _gsignond_db_metadata_database_open (
490 GSignondDbSqlDatabase *obj,
491 const gchar *filename,
494 const gchar *dir = NULL;
495 gchar *db_filename = NULL;
496 gboolean ret = FALSE;
497 gint dir_created = 0;
498 GSignondDbMetadataDatabase *self = NULL;
500 self = GSIGNOND_DB_METADATA_DATABASE (obj);
502 g_return_val_if_fail (self, FALSE);
504 if (!filename || strlen (filename) <= 0) {
505 ERR ("Missing Metadata DB filename");
508 dir = gsignond_config_get_string (self->config,
509 GSIGNOND_CONFIG_GENERAL_SECURE_DIR);
511 ERR ("Invalid Metadata DB directory");
514 db_filename = g_build_filename (dir, filename, NULL);
516 ERR ("Invalid Metadata DB filename");
520 dir_created = g_mkdir_with_parents (dir, S_IRWXU);
521 if (dir_created != 0) {
522 ERR ("Metadata DB directory does not exist");
526 ret = gsignond_db_sql_database_open (obj, db_filename, flags);
529 g_free (db_filename);
534 _gsignond_db_metadata_database_create (
535 GSignondDbSqlDatabase *obj)
537 const gchar *queries = NULL;
538 g_return_val_if_fail (GSIGNOND_DB_IS_METADATA_DATABASE (obj), FALSE);
539 RETURN_IF_NOT_OPEN (obj, FALSE);
543 queries = "PRAGMA foreign_keys = 1;";
544 if (!gsignond_db_sql_database_exec (obj, queries)) {
545 ERR ("Metadata DB enabling foreign keys failed");
549 gsignond_db_sql_database_query_exec_int (obj, "PRAGMA foreign_keys;",
552 ERR ("Metadata DB - foreign keys not enabled");
556 version = gsignond_db_sql_database_get_db_version(obj,
557 "PRAGMA user_version;");
559 DBG ("Metadata DB is already created with with version (%d) and "
560 "foreign keys enabled (%d)", version, fk_enabled);
564 queries = "PRAGMA user_version = 1;";
565 if (!gsignond_db_sql_database_exec (obj, queries)) {
566 DBG ("Metadata DB setting version failed");
570 version = gsignond_db_sql_database_get_db_version(obj,
571 "PRAGMA user_version;");
572 DBG ("Metadata DB is to be created with version (%d) and foreign keys "
573 "enabled(%d)", version, fk_enabled);
576 "CREATE TABLE IDENTITY"
577 "(id INTEGER PRIMARY KEY AUTOINCREMENT,"
583 "CREATE TABLE METHODS"
584 "(id INTEGER PRIMARY KEY AUTOINCREMENT,"
585 "method TEXT UNIQUE);"
587 "CREATE TABLE MECHANISMS"
588 "(id INTEGER PRIMARY KEY AUTOINCREMENT,"
589 "mechanism TEXT UNIQUE);"
591 "CREATE TABLE SECCTX"
592 "(id INTEGER PRIMARY KEY AUTOINCREMENT,"
595 "CONSTRAINT tokc UNIQUE(sysctx, appctx) ON CONFLICT REPLACE);"
597 "CREATE INDEX sysidx ON SECCTX(sysctx);"
598 "CREATE INDEX appidx ON SECCTX(appctx);"
600 "CREATE TABLE REALMS"
601 "(identity_id INTEGER CONSTRAINT fk_identity_id "
602 "REFERENCES IDENTITY(id) ON DELETE CASCADE,"
605 "PRIMARY KEY (identity_id, realm, hostname));"
608 "(rowid INTEGER PRIMARY KEY AUTOINCREMENT,"
609 "identity_id INTEGER CONSTRAINT fk_identity_id REFERENCES "
610 "IDENTITY(id) ON DELETE CASCADE,"
611 "method_id INTEGER CONSTRAINT fk_method_id REFERENCES "
613 "mechanism_id INTEGER CONSTRAINT fk_mechanism_id "
614 "REFERENCES MECHANISMS(id),"
615 "secctx_id INTEGER CONSTRAINT fk_secctx_id REFERENCES "
619 "(identity_id INTEGER CONSTRAINT fk_identity_id "
620 "REFERENCES IDENTITY(id) ON DELETE CASCADE,"
621 "secctx_id INTEGER CONSTRAINT fk_secctx_id REFERENCES "
624 "PRIMARY KEY (identity_id, secctx_id, ref));"
627 "(rowid INTEGER PRIMARY KEY AUTOINCREMENT,"
628 "identity_id INTEGER CONSTRAINT fk_identity_id "
629 "REFERENCES IDENTITY(id) ON DELETE CASCADE,"
630 "secctx_id INTEGER CONSTRAINT fk_secctx_id REFERENCES SECCTX(id) "
633 // Triggers for deleting orphan SECCTX entries
634 "CREATE TRIGGER fkdstale_ACL_secctx_id_SECCTX_id"
635 "BEFORE DELETE ON [ACL]"
637 " DELETE FROM SECCTX WHERE SECCTX.id = OLD.secctx_id AND "
638 " (SELECT COUNT(*) FROM REFS WHERE "
639 " REFS.secctx_id = OLD.secctx_id) == 0 AND "
640 " (SELECT COUNT(*) FROM OWNER WHERE "
641 " OWNER.secctx_id = OLD.secctx_id) == 0;"
644 "CREATE TRIGGER fkdstale_REFS_secctx_id_SECCTX_id"
645 "BEFORE DELETE ON [REFS]"
647 " DELETE FROM SECCTX WHERE SECCTX.id = OLD.secctx_id AND "
648 " (SELECT COUNT(*) FROM ACL WHERE "
649 " ACL.secctx_id = OLD.secctx_id) == 0 AND "
650 " (SELECT COUNT(*) FROM OWNER WHERE "
651 " OWNER.secctx_id = OLD.secctx_id) == 0;"
654 "CREATE TRIGGER fkdstale_OWNER_secctx_id_SECCTX_id"
655 "BEFORE DELETE ON [OWNER]"
657 " DELETE FROM SECCTX WHERE SECCTX.id = OLD.secctx_id AND "
658 " (SELECT COUNT(*) FROM ACL WHERE "
659 " ACL.secctx_id = OLD.secctx_id) == 0 AND "
660 " (SELECT COUNT(*) FROM REFS WHERE "
661 " REFS.secctx_id = OLD.secctx_id) == 0;"
664 #ifdef ENABLE_DB_ACL_TRIGGERS
665 // Trigger for deleting orphan METHODS entries
666 "CREATE TRIGGER fkdstale_ACL_method_id_METHODS_id"
667 "BEFORE DELETE ON [ACL]"
669 " DELETE FROM METHODS WHERE METHODS.id = OLD.method_id AND "
670 " (SELECT COUNT(*) FROM ACL WHERE "
671 " ACL.method_id = OLD.method_id) == 1;"
674 // Trigger for deleting orphan MECHANISMS entries
675 "CREATE TRIGGER fkdstale_ACL_mechanism_id_MECHANISMS_id"
676 "BEFORE DELETE ON [ACL]"
678 " DELETE FROM MECHANISMS WHERE MECHANISMS.id = OLD.mechanism_id "
679 " AND (SELECT COUNT(*) FROM ACL WHERE "
680 " ACL.mechanism_id = OLD.mechanism_id) == 1;"
685 * triggers generated with
686 * http://www.rcs-comp.com/site/index.php/view/Utilities-
687 * SQLite_foreign_key_trigger_generator
689 /* insert triggers to force foreign keys support */
690 // Foreign Key Preventing insert
691 "CREATE TRIGGER fki_REALMS_identity_id_IDENTITY_id"
692 "BEFORE INSERT ON [REALMS]"
694 " SELECT RAISE(ROLLBACK, 'insert on table REALMS violates foreign "
695 "key constraint fki_REALMS_identity_id_IDENTITY_id')"
696 " WHERE NEW.identity_id IS NOT NULL AND (SELECT id FROM IDENTITY "
697 "WHERE id = NEW.identity_id) IS NULL;"
700 // Foreign key preventing update
701 "CREATE TRIGGER fku_REALMS_identity_id_IDENTITY_id"
702 "BEFORE UPDATE ON [REALMS]"
704 " SELECT RAISE(ROLLBACK, 'update on table REALMS violates "
705 "foreign key constraint fku_REALMS_identity_id_IDENTITY_id')"
706 " WHERE NEW.identity_id IS NOT NULL AND (SELECT id FROM "
707 "IDENTITY WHERE id = NEW.identity_id) IS NULL;"
710 // Foreign Key Preventing insert
711 "CREATE TRIGGER fki_ACL_identity_id_IDENTITY_id"
712 "BEFORE INSERT ON [ACL]"
714 " SELECT RAISE(ROLLBACK, 'insert on table ACL violates foreign "
715 "key constraint fki_ACL_identity_id_IDENTITY_id')"
716 " WHERE NEW.identity_id IS NOT NULL AND (SELECT id FROM IDENTITY "
717 "WHERE id = NEW.identity_id) IS NULL;"
720 // Foreign key preventing update
721 "CREATE TRIGGER fku_ACL_identity_id_IDENTITY_id"
722 "BEFORE UPDATE ON [ACL]"
724 " SELECT RAISE(ROLLBACK, 'update on table ACL violates foreign "
725 "key constraint fku_ACL_identity_id_IDENTITY_id')"
726 " WHERE NEW.identity_id IS NOT NULL AND (SELECT id FROM "
727 "IDENTITY WHERE id = NEW.identity_id) IS NULL;"
730 // Foreign Key Preventing insert
731 "CREATE TRIGGER fki_ACL_method_id_METHODS_id"
732 "BEFORE INSERT ON [ACL]"
734 " SELECT RAISE(ROLLBACK, 'insert on table ACL violates foreign "
735 "key constraint fki_ACL_method_id_METHODS_id')"
736 " WHERE NEW.method_id IS NOT NULL AND (SELECT id FROM METHODS "
737 "WHERE id = NEW.method_id) IS NULL;"
740 // Foreign key preventing update
741 "CREATE TRIGGER fku_ACL_method_id_METHODS_id"
742 "BEFORE UPDATE ON [ACL]"
744 " SELECT RAISE(ROLLBACK, 'update on table ACL violates foreign "
745 "key constraint fku_ACL_method_id_METHODS_id')"
746 " WHERE NEW.method_id IS NOT NULL AND (SELECT id FROM METHODS "
747 "WHERE id = NEW.method_id) IS NULL;"
750 // Foreign Key Preventing insert
751 "CREATE TRIGGER fki_ACL_mechanism_id_MECHANISMS_id"
752 "BEFORE INSERT ON [ACL]"
754 " SELECT RAISE(ROLLBACK, 'insert on table ACL violates foreign "
755 "key constraint fki_ACL_mechanism_id_MECHANISMS_id')"
756 " WHERE NEW.mechanism_id IS NOT NULL AND (SELECT id FROM "
757 "MECHANISMS WHERE id = NEW.mechanism_id) IS NULL;"
760 // Foreign key preventing update
761 "CREATE TRIGGER fku_ACL_mechanism_id_MECHANISMS_id"
762 "BEFORE UPDATE ON [ACL]"
764 " SELECT RAISE(ROLLBACK, 'update on table ACL violates foreign "
765 "key constraint fku_ACL_mechanism_id_MECHANISMS_id')"
766 " WHERE NEW.mechanism_id IS NOT NULL AND (SELECT id FROM "
767 "MECHANISMS WHERE id = NEW.mechanism_id) IS NULL;"
770 // Foreign Key Preventing insert
771 "CREATE TRIGGER fki_ACL_secctx_id_SECCTX_id"
772 "BEFORE INSERT ON [ACL]"
774 " SELECT RAISE(ROLLBACK, 'insert on table ACL violates foreign "
775 "key constraint fki_ACL_secctx_id_SECCTX_id')"
776 " WHERE NEW.secctx_id IS NOT NULL AND (SELECT id FROM SECCTX "
777 "WHERE id = NEW.secctx_id) IS NULL;"
780 // Foreign key preventing update
781 "CREATE TRIGGER fku_ACL_secctx_id_SECCTX_id"
782 "BEFORE UPDATE ON [ACL]"
784 " SELECT RAISE(ROLLBACK, 'update on table ACL violates foreign "
785 "key constraint fku_ACL_secctx_id_SECCTX_id')"
786 " WHERE NEW.secctx_id IS NOT NULL AND (SELECT id FROM SECCTX "
787 "WHERE id = NEW.secctx_id) IS NULL;"
790 // Foreign Key Preventing insert
791 "CREATE TRIGGER fki_REFS_identity_id_IDENTITY_id"
792 "BEFORE INSERT ON [REFS]"
794 " SELECT RAISE(ROLLBACK, 'insert on table REFS violates foreign "
795 "key constraint fki_REFS_identity_id_IDENTITY_id')"
796 " WHERE NEW.identity_id IS NOT NULL AND (SELECT id FROM IDENTITY "
797 "WHERE id = NEW.identity_id) IS NULL;"
800 // Foreign key preventing update
801 "CREATE TRIGGER fku_REFS_identity_id_IDENTITY_id"
802 "BEFORE UPDATE ON [REFS]"
804 " SELECT RAISE(ROLLBACK, 'update on table REFS violates foreign "
805 "key constraint fku_REFS_identity_id_IDENTITY_id')"
806 " WHERE NEW.identity_id IS NOT NULL AND (SELECT id FROM "
807 "IDENTITY WHERE id = NEW.identity_id) IS NULL;"
810 // Foreign Key Preventing insert
811 "CREATE TRIGGER fki_REFS_secctx_id_SECCTX_id"
812 "BEFORE INSERT ON [REFS]"
814 " SELECT RAISE(ROLLBACK, 'insert on table REFS violates foreign "
815 "key constraint fki_REFS_secctx_id_SECCTX_id')"
816 " WHERE NEW.secctx_id IS NOT NULL AND (SELECT id FROM SECCTX "
817 "WHERE id = NEW.secctx_id) IS NULL;"
820 // Foreign key preventing update
821 "CREATE TRIGGER fku_REFS_secctx_id_SECCTX_id"
822 "BEFORE UPDATE ON [REFS]"
824 " SELECT RAISE(ROLLBACK, 'update on table REFS violates foreign "
825 "key constraint fku_REFS_secctx_id_SECCTX_id')"
826 " WHERE NEW.secctx_id IS NOT NULL AND (SELECT id FROM SECCTX "
827 "WHERE id = NEW.secctx_id) IS NULL;"
830 // Foreign Key Preventing insert
831 "CREATE TRIGGER fki_OWNER_identity_id_IDENTITY_id"
832 "BEFORE INSERT ON [OWNER]"
834 " SELECT RAISE(ROLLBACK, 'insert on table OWNER violates "
835 "foreign key constraint fki_OWNER_identity_id_IDENTITY_id')"
836 " WHERE NEW.identity_id IS NOT NULL AND (SELECT id FROM "
837 "IDENTITY WHERE id = NEW.identity_id) IS NULL;"
840 // Foreign key preventing update
841 "CREATE TRIGGER fku_OWNER_identity_id_IDENTITY_id"
842 "BEFORE UPDATE ON [OWNER]"
844 " SELECT RAISE(ROLLBACK, 'update on table OWNER violates "
845 "foreign key constraint fku_OWNER_identity_id_IDENTITY_id')"
846 " WHERE NEW.identity_id IS NOT NULL AND (SELECT id FROM "
847 "IDENTITY WHERE id = NEW.identity_id) IS NULL;"
850 // Foreign Key Preventing insert
851 "CREATE TRIGGER fki_OWNER_secctx_id_SECCTX_id"
852 "BEFORE INSERT ON [OWNER]"
854 " SELECT RAISE(ROLLBACK, 'insert on table OWNER violates foreign "
855 "key constraint fki_OWNER_secctx_id_SECCTX_id')"
856 " WHERE NEW.secctx_id IS NOT NULL AND (SELECT id FROM SECCTX "
857 "WHERE id = NEW.secctx_id) IS NULL;"
860 // Foreign key preventing update
861 "CREATE TRIGGER fku_OWNER_secctx_id_SECCTX_id"
862 "BEFORE UPDATE ON [OWNER]"
864 " SELECT RAISE(ROLLBACK, 'update on table OWNER violates "
865 "foreign key constraint fku_OWNER_secctx_id_SECCTX_id')"
866 " WHERE NEW.secctx_id IS NOT NULL AND (SELECT id FROM SECCTX "
867 "WHERE id = NEW.secctx_id) IS NULL;"
871 return gsignond_db_sql_database_transaction_exec (obj, queries);
875 _gsignond_db_metadata_database_clear (
876 GSignondDbSqlDatabase *obj)
878 const gchar *queries = NULL;
880 g_return_val_if_fail (GSIGNOND_DB_IS_METADATA_DATABASE (obj), FALSE);
881 RETURN_IF_NOT_OPEN (obj, FALSE);
884 "DELETE FROM IDENTITY;"
885 "DELETE FROM METHODS;"
886 "DELETE FROM MECHANISMS;"
888 "DELETE FROM REALMS;"
889 "DELETE FROM SECCTX;"
890 "DELETE FROM OWNER;";
892 return gsignond_db_sql_database_transaction_exec (obj, queries);
896 * gsignond_db_metadata_database_open:
898 * @self: instance of #GSignondDbMetadataDatabase
900 * Opens a connection to DB.
902 * Returns: TRUE if successful, FALSE otherwise.
905 gsignond_db_metadata_database_open (GSignondDbMetadataDatabase *self)
907 const gchar *filename = NULL;
909 g_return_val_if_fail (GSIGNOND_DB_IS_METADATA_DATABASE (self), FALSE);
911 if (gsignond_db_sql_database_is_open (GSIGNOND_DB_SQL_DATABASE (self)))
914 filename = gsignond_config_get_string (self->config,
915 GSIGNOND_CONFIG_DB_METADATA_DB_FILENAME);
917 return _gsignond_db_metadata_database_open (
918 GSIGNOND_DB_SQL_DATABASE (self), filename,
919 SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE);
923 * gsignond_db_metadata_database_insert_method:
925 * @self: instance of #GSignondDbMetadataDatabase
926 * @method: the method to be inserted
927 * @method_id: (transfer none) id of the method inserted
929 * Inserts the method into the db.
931 * Returns: TRUE if successful, FALSE otherwise
934 gsignond_db_metadata_database_insert_method (
935 GSignondDbMetadataDatabase *self,
940 gboolean ret = FALSE;
943 g_return_val_if_fail (GSIGNOND_DB_IS_METADATA_DATABASE (self), FALSE);
944 g_return_val_if_fail (method != NULL, FALSE);
945 RETURN_IF_NOT_OPEN (GSIGNOND_DB_SQL_DATABASE (self), FALSE);
947 query = sqlite3_mprintf ("INSERT INTO METHODS (method) "
950 ret = gsignond_db_sql_database_transaction_exec (
951 GSIGNOND_DB_SQL_DATABASE (self), query);
952 sqlite3_free (query);
954 DBG ("Retrieve method id for the inserted method");
955 *method_id = gsignond_db_metadata_database_get_method_id (self, method);
961 * gsignond_db_metadata_database_get_method_id:
963 * @self: instance of #GSignondDbMetadataDatabase
964 * @method: the method to be fetched
966 * Fetches the id of the specified method.
968 * Returns: the method if successful, 0 otherwise
971 gsignond_db_metadata_database_get_method_id (
972 GSignondDbMetadataDatabase *self,
978 g_return_val_if_fail (GSIGNOND_DB_IS_METADATA_DATABASE (self), FALSE);
979 g_return_val_if_fail (method != NULL, FALSE);
980 RETURN_IF_NOT_OPEN (GSIGNOND_DB_SQL_DATABASE (self), method_id);
982 query = sqlite3_mprintf ("SELECT id FROM METHODS "
983 "WHERE method = %Q;",
985 gsignond_db_sql_database_query_exec_int (
986 GSIGNOND_DB_SQL_DATABASE (self),
989 sqlite3_free (query);
991 return (guint32) method_id;
995 * gsignond_db_metadata_database_get_methods:
997 * @self: instance of #GSignondDbMetadataDatabase
998 * @identity_id: the id of the identity
999 * @sec_ctx: the security context
1001 * Fetches the list of the methods with the specified identity id.
1003 * Returns: (transfer full) the list if successful, NULL otherwise.
1004 * When done list should be freed with g_list_free_full (list, g_free)
1007 gsignond_db_metadata_database_get_methods (
1008 GSignondDbMetadataDatabase *self,
1009 const guint32 identity_id,
1010 GSignondSecurityContext* sec_ctx)
1012 gchar *query = NULL;
1013 GList *methods = NULL;
1015 g_return_val_if_fail (GSIGNOND_DB_IS_METADATA_DATABASE (self), NULL);
1016 g_return_val_if_fail (sec_ctx != NULL, NULL);
1017 RETURN_IF_NOT_OPEN (GSIGNOND_DB_SQL_DATABASE (self), NULL);
1019 if (sec_ctx->sys_ctx && strlen (sec_ctx->sys_ctx) <= 0) {
1020 query = sqlite3_mprintf ("SELECT DISTINCT METHODS.method FROM "
1021 "( ACL JOIN METHODS ON ACL.method_id = METHODS.id ) "
1022 "WHERE ACL.identity_id = %u;",
1025 query = sqlite3_mprintf ("SELECT DISTINCT METHODS.method FROM "
1026 "( ACL JOIN METHODS ON ACL.method_id = METHODS.id ) "
1027 "WHERE ACL.identity_id = %u AND ACL.secctx_id = "
1028 "(SELECT id FROM SECCTX "
1029 "WHERE sysctx = %Q AND appctx = %Q);",
1030 identity_id, sec_ctx->sys_ctx, sec_ctx->app_ctx);
1033 methods = gsignond_db_sql_database_query_exec_string_list (
1034 GSIGNOND_DB_SQL_DATABASE (self),
1036 sqlite3_free (query);
1042 * gsignond_db_metadata_database_update_identity:
1044 * @self: instance of #GSignondDbMetadataDatabase
1045 * @identity: the identity #GSignondIdentityInfo object
1047 * Updates the database with the data in the identity.
1049 * Returns: the id of the identity if successful, 0 otherwise
1052 gsignond_db_metadata_database_update_identity (
1053 GSignondDbMetadataDatabase *self,
1054 GSignondIdentityInfo *identity)
1056 GSignondDbSqlDatabase *sql = NULL;
1059 GHashTable *methods = NULL;
1060 GSequence *realms = NULL;
1061 GSignondSecurityContextList *acl = NULL, *list = NULL;
1062 GSignondSecurityContext *owner = NULL;
1063 GHashTableIter method_iter;
1064 const gchar *method = NULL;
1065 GSequence *mechanisms = NULL;
1067 g_return_val_if_fail (GSIGNOND_DB_IS_METADATA_DATABASE (self), 0);
1068 g_return_val_if_fail (identity != NULL, 0);
1069 RETURN_IF_NOT_OPEN (GSIGNOND_DB_SQL_DATABASE (self), id);
1071 sql = GSIGNOND_DB_SQL_DATABASE (self);
1072 if (!gsignond_db_sql_database_start_transaction (sql)) {
1077 id = _gsignond_db_metadata_database_update_credentials (self, identity);
1079 DBG ("Update credentials failed");
1080 gsignond_db_sql_database_rollback_transaction (sql);
1084 if (!gsignond_identity_info_get_is_identity_new (identity)) {
1085 DBG ("Remove old acl and owner list as identity is not new");
1087 _gsignond_db_metadata_database_exec (self,
1088 "DELETE FROM ACL WHERE identity_id = %u;", id);
1091 _gsignond_db_metadata_database_exec (self,
1092 "DELETE FROM OWNER WHERE identity_id = %u;", id);
1096 methods = gsignond_identity_info_get_methods (identity);
1097 if (!_gsignond_db_metadata_database_insert_methods (self, identity,
1099 DBG ("Update methods failed");
1103 realms = gsignond_identity_info_get_realms (identity);
1104 if (!_gsignond_db_metadata_database_update_realms (self,
1105 identity, id, realms)) {
1106 DBG ("Update realms failed");
1107 gsignond_db_sql_database_rollback_transaction (sql);
1112 acl = gsignond_identity_info_get_access_control_list (identity);
1113 if (!_gsignond_db_metadata_database_update_acl (self, identity, acl)) {
1114 DBG ("Update acl failed");
1115 gsignond_db_sql_database_rollback_transaction (sql);
1120 owner = gsignond_identity_info_get_owner (identity);
1121 if (!_gsignond_db_metadata_database_update_owner (self, identity, owner)){
1122 DBG ("Update owner failed");
1123 gsignond_db_sql_database_rollback_transaction (sql);
1128 /* ACL insert, this will do basically identity level ACL */
1129 g_hash_table_iter_init (&method_iter, methods);
1130 while (g_hash_table_iter_next (&method_iter, (gpointer)&method,
1131 (gpointer)&mechanisms)) {
1133 if (g_list_length (acl) > 0) {
1134 for (list = acl; list != NULL; list = g_list_next (list)) {
1135 GSequenceIter *mech_iter = NULL;
1136 GSignondSecurityContext *ctx = NULL;
1138 ctx = (GSignondSecurityContext *) list->data;
1139 mech_iter = g_sequence_get_begin_iter (mechanisms);
1140 while (!g_sequence_iter_is_end (mech_iter)) {
1141 _gsignond_db_metadata_database_exec (self,
1142 "INSERT OR REPLACE INTO ACL "
1143 "(identity_id, method_id, mechanism_id, secctx_id) "
1145 "( SELECT id FROM METHODS WHERE method = %Q ),"
1146 "( SELECT id FROM MECHANISMS WHERE mechanism= %Q ),"
1147 " ( SELECT id FROM SECCTX WHERE sysctx = %Q "
1148 "AND appctx = %Q));",
1149 id, method, g_sequence_get (mech_iter),
1150 ctx->sys_ctx, ctx->app_ctx);
1151 mech_iter = g_sequence_iter_next (mech_iter);
1153 if (g_sequence_get_length (mechanisms) <= 0) {
1154 _gsignond_db_metadata_database_exec (self,
1155 "INSERT OR REPLACE INTO ACL "
1156 "(identity_id, method_id, secctx_id) "
1158 "( SELECT id FROM METHODS WHERE method = %Q),"
1159 "( SELECT id FROM SECCTX WHERE sysctx = %Q AND "
1161 id, method, ctx->sys_ctx, ctx->app_ctx);
1166 GSequenceIter *mech_iter = NULL;
1167 mech_iter = g_sequence_get_begin_iter (mechanisms);
1168 while (!g_sequence_iter_is_end (mech_iter)) {
1169 _gsignond_db_metadata_database_exec (self,
1170 "INSERT OR REPLACE INTO ACL "
1171 "(identity_id, method_id, mechanism_id) "
1173 "( SELECT id FROM METHODS WHERE method = %Q ),"
1174 "( SELECT id FROM MECHANISMS WHERE mechanism= %Q ));",
1175 id, method, g_sequence_get (mech_iter));
1176 mech_iter = g_sequence_iter_next (mech_iter);
1178 if (g_sequence_get_length (mechanisms) <= 0) {
1179 _gsignond_db_metadata_database_exec (self,
1180 "INSERT OR REPLACE INTO ACL (identity_id, method_id) "
1182 "( SELECT id FROM METHODS WHERE method = %Q ));",
1187 /* insert acl in case where methods are missing */
1188 if (g_hash_table_size (methods) <= 0) {
1189 for (list = acl; list != NULL; list = g_list_next (list)) {
1190 GSignondSecurityContext *ctx = NULL;
1192 ctx = (GSignondSecurityContext *) list->data;
1193 _gsignond_db_metadata_database_exec (self,
1194 "INSERT OR REPLACE INTO ACL "
1195 "(identity_id, secctx_id) "
1197 "( SELECT id FROM SECCTX WHERE sysctx = %Q AND "
1199 id, ctx->sys_ctx, ctx->app_ctx);
1204 _gsignond_db_metadata_database_exec (self,
1205 "INSERT OR REPLACE INTO OWNER "
1206 "(identity_id, secctx_id) "
1208 "( SELECT id FROM SECCTX WHERE sysctx = %Q AND appctx = %Q ));",
1209 id, owner->sys_ctx, owner->app_ctx);
1211 if (gsignond_db_sql_database_commit_transaction (sql)) {
1212 DBG ("Identity updated");
1217 if (methods) g_hash_table_unref (methods);
1218 if (realms) g_sequence_free (realms);
1219 if (acl) gsignond_security_context_list_free (acl);
1220 if (owner) gsignond_security_context_free (owner);
1226 * gsignond_db_metadata_database_update_identity:
1228 * @self: instance of #GSignondDbMetadataDatabase
1229 * @identity_id: the id of the identity
1231 * Reads the identity data from the database based on the given id.
1233 * Returns: (transfer full) the #GSignondIdentityInfo identity if successful,
1236 GSignondIdentityInfo *
1237 gsignond_db_metadata_database_get_identity (
1238 GSignondDbMetadataDatabase *self,
1239 const guint32 identity_id)
1241 GSignondIdentityInfo *identity = NULL;
1242 gchar *query = NULL;
1244 GSequence *realms = NULL, *mechanisms = NULL;
1245 GHashTable *methods = NULL, *tuples = NULL;
1246 GHashTableIter iter;
1247 gchar *method = NULL;
1249 GSignondSecurityContextList *acl = NULL;
1250 GSignondSecurityContext *owner = NULL;
1252 g_return_val_if_fail (GSIGNOND_DB_IS_METADATA_DATABASE (self), NULL);
1253 RETURN_IF_NOT_OPEN (GSIGNOND_DB_SQL_DATABASE (self), NULL);
1255 identity = gsignond_identity_info_new ();
1256 query = sqlite3_mprintf ("SELECT caption, username, flags, type "
1257 "FROM IDENTITY WHERE id = %u;",
1259 rows = gsignond_db_sql_database_query_exec (GSIGNOND_DB_SQL_DATABASE (self),
1260 query, (GSignondDbSqlDatabaseQueryCallback)
1261 _gsignond_db_metadata_database_read_identity,
1263 sqlite3_free (query);
1264 if (G_UNLIKELY (rows <= 0)) {
1265 DBG ("Fetch IDENTITY failed");
1266 gsignond_identity_info_unref (identity);
1269 gsignond_identity_info_set_id (identity, identity_id);
1272 realms = _gsignond_db_metadata_database_get_sequence (self,
1273 "SELECT realm FROM REALMS "
1274 "WHERE identity_id = %u;",
1277 gsignond_identity_info_set_realms (identity, realms);
1278 g_sequence_free (realms);
1282 acl = gsignond_db_metadata_database_get_accesscontrol_list (self,
1285 gsignond_identity_info_set_access_control_list (identity, acl);
1286 gsignond_security_context_list_free (acl);
1290 owner = gsignond_db_metadata_database_get_owner (self,
1293 gsignond_identity_info_set_owner (identity, owner);
1294 gsignond_security_context_free (owner);
1298 query = sqlite3_mprintf ("SELECT DISTINCT ACL.method_id, METHODS.method "
1299 "FROM ( ACL JOIN METHODS ON ACL.method_id = METHODS.id ) "
1300 "WHERE ACL.identity_id = %u;",
1302 tuples = gsignond_db_sql_database_query_exec_int_string_tuple (
1303 GSIGNOND_DB_SQL_DATABASE (self),
1305 sqlite3_free (query);
1308 methods = g_hash_table_new_full ((GHashFunc)g_str_hash,
1309 (GEqualFunc)g_str_equal,
1310 (GDestroyNotify)g_free,
1311 (GDestroyNotify)g_sequence_free);
1312 g_hash_table_iter_init(&iter, tuples);
1313 while (g_hash_table_iter_next (&iter, (gpointer *)&method_id,
1314 (gpointer *)&method)) {
1316 mechanisms = _gsignond_db_metadata_database_get_sequence (self,
1317 "SELECT DISTINCT MECHANISMS.mechanism FROM "
1318 "( MECHANISMS JOIN ACL ON ACL.mechanism_id = MECHANISMS.id ) "
1319 "WHERE ACL.method_id = %u AND ACL.identity_id = %u;",
1320 method_id, identity_id);
1321 g_hash_table_insert(methods, g_strdup(method), mechanisms);
1323 g_hash_table_destroy (tuples);
1324 gsignond_identity_info_set_methods (identity, methods);
1325 g_hash_table_destroy (methods);
1332 * gsignond_db_metadata_database_get_identities:
1334 * @self: instance of #GSignondDbMetadataDatabase
1335 * @filter: (transfer none) filter to apply (supported filters: Owner, Type & Caption)
1337 * Reads all the identities that are matched by applying @filter,
1338 * from the database into a list.
1340 * Returns: (transfer full) the list #GSignondIdentityInfoList if successful,
1341 * NULL otherwise. When done the list should be freed with
1342 * gsignond_identity_info_list_free
1344 GSignondIdentityInfoList *
1345 gsignond_db_metadata_database_get_identities (
1346 GSignondDbMetadataDatabase *self,
1347 GSignondDictionary *filter)
1349 GSignondIdentityInfoList *identities = NULL;
1350 gchar *owner_query = NULL;
1351 gchar *caption_query = NULL;
1352 gchar *type_query = NULL;
1353 gchar *query = NULL;
1357 g_return_val_if_fail (GSIGNOND_DB_IS_METADATA_DATABASE (self), FALSE);
1358 RETURN_IF_NOT_OPEN (GSIGNOND_DB_SQL_DATABASE (self), NULL);
1361 GVariant *owner_var = NULL;
1362 const gchar *caption = NULL;
1364 gboolean append_where = TRUE;
1366 if ((owner_var = gsignond_dictionary_get (filter, "Owner"))) {
1367 GSignondSecurityContext *owner_ctx =
1368 gsignond_security_context_from_variant(owner_var);
1369 owner_query = sqlite3_mprintf ("WHERE id IN "
1370 "(SELECT identity_id FROM owner WHERE secctx_id = "
1371 "(SELECT id FROM secctx WHERE sysctx=%Q AND appctx=%Q))",
1372 gsignond_security_context_get_system_context(owner_ctx),
1373 gsignond_security_context_get_application_context(owner_ctx));
1374 gsignond_security_context_free (owner_ctx);
1375 append_where = FALSE;
1378 if ((caption = gsignond_dictionary_get_string (filter, "Caption"))) {
1379 caption_query = sqlite3_mprintf (" %s caption like '%s%%'",
1380 append_where ? "WHERE" : "AND", caption);
1381 append_where = FALSE;
1384 if (gsignond_dictionary_get_int32 (filter, "Type", &type)) {
1385 type_query = sqlite3_mprintf (" %s type = %d",
1386 append_where ? "WHERE" : "AND", type);
1387 append_where = FALSE;
1391 query = sqlite3_mprintf ("SELECT id FROM IDENTITY %s%s%s ORDER BY id",
1392 owner_query ? owner_query : "",
1393 caption_query ? caption_query : "",
1394 type_query ? type_query : "");
1395 sqlite3_free(owner_query);
1396 sqlite3_free(caption_query);
1397 sqlite3_free(type_query);
1399 ids = gsignond_db_sql_database_query_exec_int_array (
1400 GSIGNOND_DB_SQL_DATABASE (self),
1402 sqlite3_free (query);
1404 DBG ("No identity found");
1408 for (i=0; i < ids->len; i++) {
1409 GSignondIdentityInfo *identity = NULL;
1410 identity = gsignond_db_metadata_database_get_identity (self,
1411 g_array_index (ids, gint, i));
1413 identities = g_list_append (identities, identity);
1416 g_array_free (ids, TRUE);
1421 * gsignond_db_metadata_database_remove_identity:
1423 * @self: instance of #GSignondDbMetadataDatabase
1424 * @identity_id: the id of the identity
1426 * Removes the identity data from the database based on the given id.
1428 * Returns: TRUE if successful,FALSE otherwise.
1431 gsignond_db_metadata_database_remove_identity (
1432 GSignondDbMetadataDatabase *self,
1433 const guint32 identity_id)
1435 gchar *queries = NULL;
1436 gboolean ret = FALSE;
1438 g_return_val_if_fail (GSIGNOND_DB_IS_METADATA_DATABASE (self), FALSE);
1439 RETURN_IF_NOT_OPEN (GSIGNOND_DB_SQL_DATABASE (self), FALSE);
1441 /* Triggers should handle the cleanup of other tables */
1442 queries = sqlite3_mprintf ("DELETE FROM IDENTITY WHERE id = %u;",
1444 ret = gsignond_db_sql_database_transaction_exec (
1445 GSIGNOND_DB_SQL_DATABASE (self), queries);
1446 sqlite3_free (queries);
1452 * gsignond_db_metadata_database_insert_reference:
1454 * @self: instance of #GSignondDbMetadataDatabase
1455 * @identity_id: the id of the identity
1456 * @ref_owner: the owner security context
1457 * @reference: reference for the given identity
1459 * Insert reference into the database for the given identity id.
1461 * Returns: TRUE if successful,FALSE otherwise.
1464 gsignond_db_metadata_database_insert_reference (
1465 GSignondDbMetadataDatabase *self,
1466 const guint32 identity_id,
1467 const GSignondSecurityContext *ref_owner,
1468 const gchar *reference)
1470 GSignondDbSqlDatabase *sql = NULL;
1472 g_return_val_if_fail (GSIGNOND_DB_IS_METADATA_DATABASE (self), 0);
1473 g_return_val_if_fail (ref_owner != NULL && reference != NULL, FALSE);
1474 RETURN_IF_NOT_OPEN (GSIGNOND_DB_SQL_DATABASE (self), FALSE);
1476 sql = GSIGNOND_DB_SQL_DATABASE (self);
1477 if (!gsignond_db_sql_database_start_transaction (sql)) {
1478 DBG ("Start transaction failed");
1482 if (!_gsignond_db_metadata_database_exec (self,
1483 "INSERT OR IGNORE INTO SECCTX (sysctx, appctx) "
1484 "VALUES ( %Q, %Q );", ref_owner->sys_ctx, ref_owner->app_ctx)) {
1485 DBG ("Insertion SECCTX to DB failed");
1486 gsignond_db_sql_database_rollback_transaction (sql);
1489 if (!_gsignond_db_metadata_database_exec (self,
1490 "INSERT OR REPLACE INTO REFS "
1491 "(identity_id, secctx_id, ref) "
1493 "( SELECT id FROM SECCTX "
1494 "WHERE sysctx = %Q AND appctx = %Q), %Q );",
1495 identity_id, ref_owner->sys_ctx, ref_owner->app_ctx, reference)) {
1496 DBG ("Insertion to REFS failed");
1497 gsignond_db_sql_database_rollback_transaction (sql);
1501 return gsignond_db_sql_database_commit_transaction (sql);
1505 * gsignond_db_metadata_database_remove_reference:
1507 * @self: instance of #GSignondDbMetadataDatabase
1508 * @identity_id: the id of the identity
1509 * @ref_owner: the owner security context
1510 * @reference: reference for the given identity
1512 * Removes reference from the database for the given identity id.
1514 * Returns: TRUE if successful,FALSE otherwise.
1517 gsignond_db_metadata_database_remove_reference (
1518 GSignondDbMetadataDatabase *self,
1519 const guint32 identity_id,
1520 const GSignondSecurityContext *ref_owner,
1521 const gchar *reference)
1523 GSignondDbSqlDatabase *sql = NULL;
1525 gboolean ret = TRUE;
1528 g_return_val_if_fail (GSIGNOND_DB_IS_METADATA_DATABASE (self), 0);
1529 g_return_val_if_fail (ref_owner != NULL, FALSE);
1530 RETURN_IF_NOT_OPEN (GSIGNOND_DB_SQL_DATABASE (self), FALSE);
1532 sql = GSIGNOND_DB_SQL_DATABASE (self);
1533 if (!gsignond_db_sql_database_start_transaction (sql)) {
1534 DBG ("Start transaction failed");
1538 refs = gsignond_db_metadata_database_get_references (self,
1539 identity_id, ref_owner);
1541 len = g_list_length (refs);
1542 if (reference && !g_list_find_custom (refs, reference,
1543 (GCompareFunc)g_strcmp0))
1545 g_list_free_full (refs, (GDestroyNotify)g_free);
1546 if (len <= 0 || !ret) {
1547 DBG ("No ref found");
1548 gsignond_db_sql_database_rollback_transaction (sql);
1552 if (!reference || strlen (reference) <= 0) {
1553 ret = _gsignond_db_metadata_database_exec (self,
1555 "WHERE identity_id = %u AND "
1556 "secctx_id = ( SELECT id FROM SECCTX "
1557 "WHERE sysctx = %Q AND appctx = %Q );",
1558 identity_id, ref_owner->sys_ctx, ref_owner->app_ctx);
1560 ret = _gsignond_db_metadata_database_exec (self,
1562 "WHERE identity_id = %u AND "
1563 "secctx_id = ( SELECT id FROM SECCTX "
1564 "WHERE sysctx = %Q AND appctx = %Q ) "
1566 identity_id, ref_owner->sys_ctx, ref_owner->app_ctx, reference);
1569 DBG ("Delete refs from DB failed");
1570 gsignond_db_sql_database_rollback_transaction (sql);
1574 return gsignond_db_sql_database_commit_transaction (sql);
1578 * gsignond_db_metadata_database_get_references:
1580 * @self: instance of #GSignondDbMetadataDatabase
1581 * @identity_id: the id of the identity
1582 * @ref_owner: the owner security context
1584 * Gets references from the database for the given identity id.
1586 * Returns: (transfer full) the list #GList if successful,
1587 * NULL otherwise. When done the list should be freed with
1588 * g_list_free_full (list, g_free)
1591 gsignond_db_metadata_database_get_references (
1592 GSignondDbMetadataDatabase *self,
1593 const guint32 identity_id,
1594 const GSignondSecurityContext* ref_owner)
1596 gchar *query = NULL;
1599 g_return_val_if_fail (GSIGNOND_DB_IS_METADATA_DATABASE (self), NULL);
1600 g_return_val_if_fail (ref_owner != NULL, NULL);
1601 RETURN_IF_NOT_OPEN (GSIGNOND_DB_SQL_DATABASE (self), NULL);
1603 if (!ref_owner->sys_ctx || strlen (ref_owner->sys_ctx) <= 0) {
1604 query = sqlite3_mprintf ("SELECT ref FROM REFS "
1605 "WHERE identity_id = %u;",
1608 query = sqlite3_mprintf ("SELECT ref FROM REFS "
1609 "WHERE identity_id = %u AND "
1610 "secctx_id = (SELECT id FROM SECCTX "
1611 "WHERE sysctx = %Q AND appctx = %Q );",
1612 identity_id, ref_owner->sys_ctx, ref_owner->app_ctx );
1614 list = gsignond_db_sql_database_query_exec_string_list (
1615 GSIGNOND_DB_SQL_DATABASE (self),
1617 sqlite3_free (query);
1622 * gsignond_db_metadata_database_get_accesscontrol_list:
1624 * @self: instance of #GSignondDbMetadataDatabase
1625 * @identity_id: the id of the identity whose access control list is needed
1627 * Gets all the access control list from the database into a list.
1629 * Returns: (transfer full) the list #GSignondSecurityContextList if successful,
1630 * NULL otherwise. When done the list should be freed with
1631 * gsignond_identity_info_list_free
1633 GSignondSecurityContextList *
1634 gsignond_db_metadata_database_get_accesscontrol_list(
1635 GSignondDbMetadataDatabase *self,
1636 const guint32 identity_id)
1638 GSignondSecurityContextList *list = NULL;
1639 GHashTable *tuples = NULL;
1640 gchar *query = NULL;
1641 GHashTableIter iter;
1642 const gchar *sysctx = NULL, *appctx = NULL;
1643 GSignondSecurityContext *ctx = NULL;
1645 g_return_val_if_fail (GSIGNOND_DB_IS_METADATA_DATABASE (self), FALSE);
1646 RETURN_IF_NOT_OPEN (GSIGNOND_DB_SQL_DATABASE (self), NULL);
1648 query = sqlite3_mprintf ("SELECT sysctx, appctx FROM SECCTX "
1650 "(SELECT secctx_id FROM ACL WHERE identity_id = %u);",
1652 tuples = gsignond_db_sql_database_query_exec_string_tuple (
1653 GSIGNOND_DB_SQL_DATABASE (self),
1655 sqlite3_free (query);
1658 g_hash_table_iter_init(&iter, tuples);
1659 while (g_hash_table_iter_next (&iter, (gpointer *)&sysctx,
1660 (gpointer *)&appctx)) {
1661 ctx = gsignond_security_context_new_from_values (sysctx, appctx);
1662 list = g_list_append (list, ctx);
1664 g_hash_table_unref (tuples);
1670 * gsignond_db_metadata_database_get_owner:
1672 * @self: instance of #GSignondDbMetadataDatabase
1673 * @identity_id: the id of the identity whose owner list is needed
1675 * Gets the onwer of identity referred by @identity_id from the database.
1677 * Returns: (transfer full) the #GSignondSecurityContext if successful,
1678 * NULL otherwise. When done the list should be freed with
1679 * gsignond_identity_info_unref
1681 GSignondSecurityContext *
1682 gsignond_db_metadata_database_get_owner(
1683 GSignondDbMetadataDatabase *self,
1684 const guint32 identity_id)
1686 GHashTable *tuples = NULL;
1687 gchar *query = NULL;
1688 GSignondSecurityContext *ctx = NULL;
1690 g_return_val_if_fail (GSIGNOND_DB_IS_METADATA_DATABASE (self), FALSE);
1691 RETURN_IF_NOT_OPEN (GSIGNOND_DB_SQL_DATABASE (self), NULL);
1693 query = sqlite3_mprintf ("SELECT sysctx, appctx FROM SECCTX "
1695 "(SELECT secctx_id FROM OWNER WHERE identity_id = %u);",
1697 tuples = gsignond_db_sql_database_query_exec_string_tuple (
1698 GSIGNOND_DB_SQL_DATABASE (self),
1700 sqlite3_free (query);
1703 GHashTableIter iter;
1704 const gchar *sysctx = NULL, *appctx = NULL;
1705 g_hash_table_iter_init(&iter, tuples);
1706 while (g_hash_table_iter_next (&iter, (gpointer *)&sysctx,
1707 (gpointer *)&appctx)) {
1708 ctx = gsignond_security_context_new_from_values (sysctx, appctx);
1711 g_hash_table_unref (tuples);