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
27 #include "gsignond/gsignond-log.h"
28 #include "gsignond/gsignond-credentials.h"
29 #include "common/db/gsignond-db-error.h"
30 #include "common/gsignond-identity-info-internal.h"
31 #include "gsignond-db-credentials-database.h"
33 #define GSIGNOND_DB_CREDENTIALS_DATABASE_GET_PRIVATE(obj) \
34 (G_TYPE_INSTANCE_GET_PRIVATE ((obj),\
35 GSIGNOND_DB_TYPE_CREDENTIALS_DATABASE, \
36 GSignondDbCredentialsDatabasePrivate))
38 G_DEFINE_TYPE (GSignondDbCredentialsDatabase, gsignond_db_credentials_database,
41 struct _GSignondDbCredentialsDatabasePrivate
43 GSignondDbMetadataDatabase *metadata_db;
54 static GParamSpec *properties[N_PROPERTIES] = { NULL, };
57 _set_property (GObject *object, guint prop_id, const GValue *value,
60 GSignondDbCredentialsDatabase *self =
61 GSIGNOND_DB_CREDENTIALS_DATABASE (object);
65 g_assert (self->config == NULL);
66 self->config = g_value_dup_object (value);
69 g_assert (self->secret_storage == NULL);
70 self->secret_storage = g_value_dup_object (value);
73 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
78 _get_property (GObject *object, guint prop_id, GValue *value, GParamSpec *pspec)
80 GSignondDbCredentialsDatabase *self =
81 GSIGNOND_DB_CREDENTIALS_DATABASE (object);
85 g_value_set_object (value, self->config);
88 g_value_set_object (value, self->secret_storage);
91 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
96 _gsignond_db_credentials_database_dispose (GObject *gobject)
98 g_return_if_fail (GSIGNOND_DB_IS_CREDENTIALS_DATABASE (gobject));
99 GSignondDbCredentialsDatabase *self =
100 GSIGNOND_DB_CREDENTIALS_DATABASE (gobject);
103 g_object_unref (self->config);
106 if (self->secret_storage) {
107 g_object_unref (self->secret_storage);
108 self->secret_storage = NULL;
110 if (self->priv->metadata_db) {
111 g_object_unref (self->priv->metadata_db);
112 self->priv->metadata_db = NULL;
114 G_OBJECT_CLASS (gsignond_db_credentials_database_parent_class)->dispose (
119 gsignond_db_credentials_database_class_init (
120 GSignondDbCredentialsDatabaseClass *klass)
122 GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
124 gobject_class->set_property = _set_property;
125 gobject_class->get_property = _get_property;
126 gobject_class->dispose = _gsignond_db_credentials_database_dispose;
128 properties[PROP_CONFIG] = g_param_spec_object (
131 "Configuration object",
132 GSIGNOND_TYPE_CONFIG,
133 G_PARAM_CONSTRUCT_ONLY |
135 G_PARAM_STATIC_STRINGS);
136 properties[PROP_STORAGE] = g_param_spec_object (
139 "Secure Storage object",
140 GSIGNOND_TYPE_SECRET_STORAGE,
141 G_PARAM_CONSTRUCT_ONLY |
143 G_PARAM_STATIC_STRINGS);
144 g_object_class_install_properties (gobject_class, N_PROPERTIES, properties);
146 g_type_class_add_private (klass,
147 sizeof (GSignondDbCredentialsDatabasePrivate));
151 gsignond_db_credentials_database_init (
152 GSignondDbCredentialsDatabase *self)
154 self->priv = GSIGNOND_DB_CREDENTIALS_DATABASE_GET_PRIVATE (self);
156 self->secret_storage = NULL;
157 self->priv->metadata_db = NULL;
161 * gsignond_db_credentials_database_new:
163 * @config: (transfer none) the #GSignondConfig object
164 * @storage: (transfer none) the #GSignondSecretStorage object
166 * Creates new #GSignondDbCredentialsDatabase object
168 * Returns: (transfer full) the #GSignondDbCredentialsDatabase object
170 GSignondDbCredentialsDatabase *
171 gsignond_db_credentials_database_new (
172 GSignondConfig *config,
173 GSignondSecretStorage *storage)
176 GSignondDbCredentialsDatabase *self = NULL;
177 self = GSIGNOND_DB_CREDENTIALS_DATABASE (
178 g_object_new (GSIGNOND_DB_TYPE_CREDENTIALS_DATABASE,
185 self->priv->metadata_db = gsignond_db_metadata_database_new (
187 if (self->priv->metadata_db) {
188 gsignond_db_metadata_database_open (self->priv->metadata_db);
195 * gsignond_db_credentials_database_open_secret_storage:
197 * @self: instance of #GSignondDbCredentialsDatabase
199 * Opens (and initializes) secret storage.
201 * Returns: TRUE if successful, FALSE otherwise.
204 gsignond_db_credentials_database_open_secret_storage (
205 GSignondDbCredentialsDatabase *self)
207 g_return_val_if_fail (GSIGNOND_DB_IS_CREDENTIALS_DATABASE (self), FALSE);
208 g_return_val_if_fail (self->secret_storage != NULL, FALSE);
210 return gsignond_secret_storage_open_db (self->secret_storage);
214 * gsignond_db_credentials_database_close_secret_storage:
216 * @self: instance of #GSignondDbCredentialsDatabase
218 * Closes the secret storage.
220 * Returns: TRUE if successful, FALSE otherwise.
223 gsignond_db_credentials_database_close_secret_storage (
224 GSignondDbCredentialsDatabase *self)
226 g_return_val_if_fail (GSIGNOND_DB_IS_CREDENTIALS_DATABASE (self), FALSE);
227 g_return_val_if_fail (self->secret_storage != NULL, FALSE);
229 return gsignond_secret_storage_close_db (self->secret_storage);
233 * gsignond_db_credentials_database_is_open_secret_storage:
235 * @self: instance of #GSignondDbCredentialsDatabase
237 * Checks if secret storage is open or not.
239 * Returns: TRUE if secret storage is open, FALSE otherwise.
242 gsignond_db_credentials_database_is_open_secret_storage (
243 GSignondDbCredentialsDatabase *self)
245 g_return_val_if_fail (GSIGNOND_DB_IS_CREDENTIALS_DATABASE (self), FALSE);
246 g_return_val_if_fail (self->secret_storage != NULL, FALSE);
248 return gsignond_secret_storage_is_open_db (self->secret_storage);
252 * gsignond_db_credentials_database_clear:
254 * @self: instance of #GSignondDbCredentialsDatabase
256 * Clears the credentials database.
258 * Returns: TRUE if secret storage is open, FALSE otherwise.
261 gsignond_db_credentials_database_clear (GSignondDbCredentialsDatabase *self)
263 g_return_val_if_fail (GSIGNOND_DB_IS_CREDENTIALS_DATABASE (self), FALSE);
264 g_return_val_if_fail (self->secret_storage != NULL, FALSE);
266 return gsignond_secret_storage_clear_db (self->secret_storage) &&
267 gsignond_db_sql_database_clear (
268 GSIGNOND_DB_SQL_DATABASE (self->priv->metadata_db));
272 * gsignond_db_credentials_database_load_identity:
274 * @self: instance of #GSignondDbCredentialsDatabase
275 * @identity_id: the id of the identity
276 * @query_secret: whether to query the password or not
278 * Fetches the info associated with the specified identity id.
280 * Returns: (transfer full) the info #GSignondIdentityInfo if successful,
281 * NULL otherwise. When done, it should be freed with
282 * gsignond_identity_info_unref (identity)
284 GSignondIdentityInfo *
285 gsignond_db_credentials_database_load_identity (
286 GSignondDbCredentialsDatabase *self,
287 const guint32 identity_id,
288 gboolean query_secret)
290 GSignondIdentityInfo *identity = NULL;
291 gboolean is_un_sec = FALSE;
292 gboolean is_pwd_sec = FALSE;
294 g_return_val_if_fail (GSIGNOND_DB_IS_CREDENTIALS_DATABASE (self), NULL);
296 identity = gsignond_db_metadata_database_get_identity (
297 self->priv->metadata_db, identity_id);
302 !gsignond_identity_info_get_is_identity_new (identity) &&
303 gsignond_db_credentials_database_is_open_secret_storage (self)) {
305 is_un_sec = gsignond_identity_info_get_is_username_secret (identity);
306 is_pwd_sec = gsignond_identity_info_get_store_secret (identity);
307 if (is_un_sec || is_pwd_sec) {
308 GSignondCredentials * creds;
309 creds = gsignond_secret_storage_load_credentials (
310 self->secret_storage, identity_id);
313 gsignond_identity_info_set_username (identity,
314 gsignond_credentials_get_username (creds));
316 gsignond_identity_info_set_secret (identity,
317 gsignond_credentials_get_password (creds));
318 g_object_unref (creds);
322 /* Reseting the edit state to NONE as its newly loaded identity */
323 gsignond_identity_info_reset_edit_flags (identity, IDENTITY_INFO_PROP_NONE);
329 * gsignond_db_credentials_database_load_identities:
331 * @self: instance of #GSignondDbCredentialsDatabase
332 * @filter: (transfer none) filter to apply. Currently supported filters:
333 * ("Owner":GSignondSecurtityContext *context) - Identities matched with this 'context'
334 * ("Type":guint32 type) - Identities matched with 'type'
335 * ("Caption":gchar *caption) - Identties matched/start with 'caption'
337 * Fetches the list of the identities.
339 * Returns: (transfer full) the list if successful, NULL otherwise.
340 * When done list should be freed with gsignond_identity_info_list_free (list)
342 GSignondIdentityInfoList *
343 gsignond_db_credentials_database_load_identities (
344 GSignondDbCredentialsDatabase *self,
345 GSignondDictionary *filter)
347 g_return_val_if_fail (GSIGNOND_DB_IS_CREDENTIALS_DATABASE (self), NULL);
349 return gsignond_db_metadata_database_get_identities (
350 self->priv->metadata_db, filter);
354 * gsignond_db_credentials_database_update_identity:
356 * @self: instance of #GSignondDbCredentialsDatabase
357 * @identity: the identity info which needs to be inserted to db
358 * @store_secret: flag to indicate whether to store the secret or not
360 * Updates the identity info in the credentials database.
362 * Returns: the id of the updated identity, 0 otherwise.
365 gsignond_db_credentials_database_update_identity (
366 GSignondDbCredentialsDatabase *self,
367 GSignondIdentityInfo* identity)
371 g_return_val_if_fail (GSIGNOND_DB_IS_CREDENTIALS_DATABASE (self), FALSE);
373 id = gsignond_db_metadata_database_update_identity (self->priv->metadata_db,
378 /* Reseting the edit state to NONE as all the changes are stored in db. */
379 gsignond_identity_info_reset_edit_flags (identity, IDENTITY_INFO_PROP_NONE);
381 if (gsignond_db_credentials_database_is_open_secret_storage (self)) {
382 GSignondCredentials *creds = NULL;
383 gboolean un_sec, pwd_sec;
384 const gchar *tmp_str = NULL;
386 creds = gsignond_credentials_new ();
387 gsignond_credentials_set_id (creds, id);
389 pwd_sec = gsignond_identity_info_get_store_secret (identity) &&
390 (tmp_str = gsignond_identity_info_get_secret (identity));
392 gsignond_credentials_set_password (creds, tmp_str);
395 un_sec = gsignond_identity_info_get_is_username_secret (identity) &&
396 (tmp_str = gsignond_identity_info_get_username (identity));
398 gsignond_credentials_set_username (creds, tmp_str);
401 if (un_sec || pwd_sec) {
402 DBG ("Add credentials to secret storage");
403 gsignond_secret_storage_update_credentials (
404 self->secret_storage, creds);
406 g_object_unref (creds);
413 * gsignond_db_credentials_database_remove_identity:
415 * @self: instance of #GSignondDbCredentialsDatabase
416 * @identity: the identity info which needs to be removed
418 * Removes the identity info from the credentials database.
420 * Returns: TRUE if successful, FALSE otherwise.
423 gsignond_db_credentials_database_remove_identity (
424 GSignondDbCredentialsDatabase *self,
425 const guint32 identity_id)
427 g_return_val_if_fail (GSIGNOND_DB_IS_CREDENTIALS_DATABASE (self), FALSE);
429 if (!gsignond_db_credentials_database_is_open_secret_storage (self)) {
430 DBG ("Remove failed as DB is not open");
433 return gsignond_secret_storage_remove_credentials (
434 self->secret_storage,
436 gsignond_db_metadata_database_remove_identity (
437 self->priv->metadata_db,
442 * gsignond_db_credentials_database_check_secret:
444 * @self: instance of #GSignondDbCredentialsDatabase
445 * @identity_id: the id of the identity
446 * @username: the username of the identity
447 * @secret: the secret of the identity
449 * Checks the identity info from the credentials database.
451 * Returns: TRUE if successful, FALSE otherwise.
454 gsignond_db_credentials_database_check_secret (
455 GSignondDbCredentialsDatabase *self,
456 const guint32 identity_id,
457 const gchar *username,
460 GSignondIdentityInfo *identity = NULL;
461 gboolean check = FALSE;
463 g_return_val_if_fail (GSIGNOND_DB_IS_CREDENTIALS_DATABASE (self), FALSE);
465 if (!gsignond_db_credentials_database_is_open_secret_storage (self)) {
466 DBG ("Check failed as DB is not open");
470 identity = gsignond_db_metadata_database_get_identity (
471 self->priv->metadata_db, identity_id);
473 GSignondCredentials *creds = NULL;
475 creds = gsignond_credentials_new ();
476 gsignond_credentials_set_id (creds, identity_id);
477 gsignond_credentials_set_password (creds, secret);
478 if (gsignond_identity_info_get_is_username_secret (identity)) {
479 DBG ("Check credentials from storage");
480 gsignond_credentials_set_username (creds, username);
481 check = gsignond_secret_storage_check_credentials (
482 self->secret_storage, creds);
484 gsignond_credentials_set_username (creds, "");
485 check = g_strcmp0 (username,
486 gsignond_identity_info_get_username (identity)) == 0 &&
487 gsignond_secret_storage_check_credentials (
488 self->secret_storage, creds);
490 g_object_unref (creds);
491 gsignond_identity_info_unref (identity);
497 * gsignond_db_credentials_database_load_data:
499 * @self: instance of #GSignondDbCredentialsDatabase
500 * @identity_id: the id of the identity
501 * @method: the name of the method
503 * Fetches the data associated with the identity id and method.
505 * Returns: (transfer full) the data if successful, NULL otherwise.
506 * When done data should be freed with g_hash_table_unref (data)
509 gsignond_db_credentials_database_load_data (
510 GSignondDbCredentialsDatabase *self,
511 const guint32 identity_id,
514 guint32 method_id = 0;
516 g_return_val_if_fail (GSIGNOND_DB_IS_CREDENTIALS_DATABASE (self), NULL);
517 g_return_val_if_fail (method != NULL, NULL);
519 if (identity_id == 0 ||
520 !gsignond_db_credentials_database_is_open_secret_storage (self)) {
521 DBG ("Load data failed - invalid id (%d)/secret storage not opened",
526 method_id = gsignond_db_metadata_database_get_method_id (
527 self->priv->metadata_db,
529 if (method_id == 0) {
530 DBG ("Load data failed - invalid method id");
533 return gsignond_secret_storage_load_data (self->secret_storage,
534 identity_id, method_id);
538 * gsignond_db_credentials_database_update_data:
540 * @self: instance of #GSignondDbCredentialsDatabase
541 * @identity_id: the id of the identity
542 * @method: the name of the method
543 * @data: the data to be stored
545 * Stores/updates the data associated with the identity id and method.
547 * Returns: (transfer full) the data if successful, NULL otherwise.
548 * When done data should be freed with g_hash_table_unref (data)
551 gsignond_db_credentials_database_update_data (
552 GSignondDbCredentialsDatabase *self,
553 const guint32 identity_id,
557 guint32 method_id = 0;
559 g_return_val_if_fail (GSIGNOND_DB_IS_CREDENTIALS_DATABASE (self), FALSE);
560 g_return_val_if_fail (method != NULL && data != NULL, FALSE);
562 if (identity_id == 0 ||
563 !gsignond_db_credentials_database_is_open_secret_storage (self)) {
564 DBG ("Update data failed - invalid id(%d)/secret storage not opened",
569 method_id = gsignond_db_metadata_database_get_method_id (
570 self->priv->metadata_db,
572 if (method_id == 0) {
573 if (!gsignond_db_metadata_database_insert_method (
574 self->priv->metadata_db,
577 DBG ("Update data failed - insertion of method to DB failed");
581 return gsignond_secret_storage_update_data (self->secret_storage,
582 identity_id, method_id, data);
586 * gsignond_db_credentials_database_remove_data:
588 * @self: instance of #GSignondDbCredentialsDatabase
589 * @identity_id: the id of the identity
590 * @method: the name of the method
592 * Fetches the data associated with the identity id and method.
594 * Returns: (transfer full) the data if successful, NULL otherwise.
595 * When done data should be freed with g_hash_table_unref (data)
598 gsignond_db_credentials_database_remove_data (
599 GSignondDbCredentialsDatabase *self,
600 const guint32 identity_id,
603 guint32 method_id = 0;
605 g_return_val_if_fail (GSIGNOND_DB_IS_CREDENTIALS_DATABASE (self), FALSE);
607 if (identity_id == 0 ||
608 !gsignond_db_credentials_database_is_open_secret_storage (self)) {
609 DBG ("Remove data failed - invalid id (%d)/secret storage not opened",
614 if (method && strlen (method) > 0) {
615 method_id = gsignond_db_metadata_database_get_method_id (
616 self->priv->metadata_db,
618 if (method_id == 0) {
619 DBG ("Remove data failed - method not found");
623 return gsignond_secret_storage_remove_data (self->secret_storage,
624 identity_id, method_id);
628 * gsignond_db_credentials_database_get_methods:
630 * @self: instance of #GSignondDbCredentialsDatabase
631 * @identity_id: the id of the identity
632 * @sec_ctx: the security context
634 * Fetches the list of the methods associated with the specified identity id.
636 * Returns: (transfer full) the list if successful, NULL otherwise.
637 * When done list should be freed with g_list_free_full (list, g_free)
640 gsignond_db_credentials_database_get_methods (
641 GSignondDbCredentialsDatabase *self,
642 const guint32 identity_id,
643 GSignondSecurityContext* sec_ctx)
645 g_return_val_if_fail (GSIGNOND_DB_IS_CREDENTIALS_DATABASE (self), NULL);
647 return gsignond_db_metadata_database_get_methods (self->priv->metadata_db,
648 identity_id, sec_ctx);
652 * gsignond_db_credentials_database_insert_reference:
654 * @self: instance of #GSignondDbCredentialsDatabase
655 * @identity_id: the id of the identity
656 * @ref_owner: the owner security context
657 * @reference: reference for the given identity
659 * Insert reference into the database for the given identity id.
661 * Returns: TRUE if successful,FALSE otherwise.
664 gsignond_db_credentials_database_insert_reference (
665 GSignondDbCredentialsDatabase *self,
666 const guint32 identity_id,
667 const GSignondSecurityContext *ref_owner,
668 const gchar *reference)
670 g_return_val_if_fail (GSIGNOND_DB_IS_CREDENTIALS_DATABASE (self), FALSE);
672 return gsignond_db_metadata_database_insert_reference (
673 self->priv->metadata_db, identity_id, ref_owner,reference);
677 * gsignond_db_credentials_database_remove_reference:
679 * @self: instance of #GSignondDbCredentialsDatabase
680 * @identity_id: the id of the identity
681 * @ref_owner: the owner security context
682 * @reference: reference for the given identity
684 * Removes reference from the database for the given identity id.
686 * Returns: TRUE if successful,FALSE otherwise.
689 gsignond_db_credentials_database_remove_reference (
690 GSignondDbCredentialsDatabase *self,
691 const guint32 identity_id,
692 const GSignondSecurityContext *ref_owner,
693 const gchar *reference)
695 g_return_val_if_fail (GSIGNOND_DB_IS_CREDENTIALS_DATABASE (self), FALSE);
697 return gsignond_db_metadata_database_remove_reference (
698 self->priv->metadata_db, identity_id, ref_owner, reference);
702 * gsignond_db_credentials_database_get_references:
704 * @self: instance of #GSignondDbCredentialsDatabase
705 * @identity_id: the id of the identity
706 * @ref_owner: the owner security context
708 * Gets references from the database for the given identity id.
710 * Returns: (transfer full) the list #GList if successful,
711 * NULL otherwise. When done the list should be freed with
712 * g_list_free_full (list, g_free)
715 gsignond_db_credentials_database_get_references (
716 GSignondDbCredentialsDatabase *self,
717 const guint32 identity_id,
718 const GSignondSecurityContext* ref_owner)
720 g_return_val_if_fail (GSIGNOND_DB_IS_CREDENTIALS_DATABASE (self), NULL);
722 return gsignond_db_metadata_database_get_references (
723 self->priv->metadata_db, identity_id, ref_owner);
727 * gsignond_db_credentials_database_get_accesscontrol_list:
729 * @self: instance of #GSignondDbCredentialsDatabase
730 * @identity_id: the id of the identity whose access control list is needed
732 * Gets all the access control list from the database into a list.
734 * Returns: (transfer full) the list #GSignondSecurityContextList if successful,
735 * NULL otherwise. When done the list should be freed with
736 * gsignond_identity_info_list_free
738 GSignondSecurityContextList *
739 gsignond_db_credentials_database_get_accesscontrol_list(
740 GSignondDbCredentialsDatabase *self,
741 const guint32 identity_id)
743 g_return_val_if_fail (GSIGNOND_DB_IS_CREDENTIALS_DATABASE (self), NULL);
745 return gsignond_db_metadata_database_get_accesscontrol_list (
746 self->priv->metadata_db, identity_id);
750 * gsignond_db_credentials_database_get_owner:
752 * @self: instance of #GSignondDbCredentialsDatabase
753 * @identity_id: the id of the identity whose owner list is needed
755 * Gets the onwer of the identity referred by @identity_id from the database.
757 * Returns: (transfer full) the list #GSignondSecurityContext if successful,
758 * NULL otherwise. When done the list should be freed with
759 * gsignond_identity_info_unref
761 GSignondSecurityContext *
762 gsignond_db_credentials_database_get_owner(
763 GSignondDbCredentialsDatabase *self,
764 const guint32 identity_id)
766 g_return_val_if_fail (GSIGNOND_DB_IS_CREDENTIALS_DATABASE (self), NULL);
768 return gsignond_db_metadata_database_get_owner (
769 self->priv->metadata_db, identity_id);
773 * gsignond_db_credentials_database_get_identity_owner:
775 * @self: instance of #GSignondDbCredentialsDatabase
776 * @identity_id: the id of the identity whose owner is needed
778 * Gets the owner from the database for the given identity id.
780 * Returns: (transfer full) the #GSignondSecurityContext if successful,
781 * NULL otherwise. When done the context, it should be freed with
782 * gsignond_identity_info_unref
784 GSignondSecurityContext *
785 gsignond_db_credentials_database_get_identity_owner (
786 GSignondDbCredentialsDatabase *self,
787 const guint32 identity_id)
789 GSignondSecurityContext *ctx = NULL;
791 g_return_val_if_fail (GSIGNOND_DB_IS_CREDENTIALS_DATABASE (self), NULL);
793 ctx = gsignond_db_metadata_database_get_owner (
794 self->priv->metadata_db, identity_id);
799 gsignond_db_credentials_database_get_last_error (
800 GSignondDbCredentialsDatabase *self)
802 g_return_val_if_fail (self && GSIGNOND_DB_IS_CREDENTIALS_DATABASE (self), NULL);
804 return gsignond_db_sql_database_get_last_error (
805 GSIGNOND_DB_SQL_DATABASE (self->priv->metadata_db));