## InfdAccountStorage InfdAccountStorage — Interface to user account database |

## Stability Level

Unstable, unless otherwise indicated

## Functions

InfdAccountStorageSupport | infd_account_storage_get_support ()
gboolean | infd_account_storage_supports ()
InfAclAccount * | infd_account_storage_lookup_accounts ()
InfAclAccount * | infd_account_storage_lookup_accounts_by_name ()
InfAclAccount * | infd_account_storage_list_accounts ()
InfAclAccountId | infd_account_storage_add_account ()
gboolean | infd_account_storage_remove_account ()
InfAclAccountId | infd_account_storage_login_by_certificate ()
InfAclAccountId | infd_account_storage_login_by_password ()
gboolean | infd_account_storage_set_certificate ()
gboolean | infd_account_storage_set_password ()
void | infd_account_storage_account_added ()
void | infd_account_storage_account_removed ()

## Signals

void | account-added | Run Last
void | account-removed | Run Last

## Types and Values

| InfdAccountStorage
struct | InfdAccountStorageInterface
enum | InfdAccountStorageSupport

## Object Hierarchy

        GFlags
        ╰── InfdAccountStorageSupport
        GInterface
        ╰── InfdAccountStorage

## Prerequisites

InfdAccountStorage requires GObject.

## Known Implementations

InfdAccountStorage is implemented by InfdFilesystemAccountStorage.

## Includes

    #include <libinfinity/server/infd-account-storage.h>

## Description

InfdAccountStorage provides an interface for InfdDirectory to access a database of user accounts. It provides methods to list and lookup available accounts, and to add and remove accounts.

Each account is uniquely identified by an account ID, InfAclAccount.id, and is assigned a human-readable name, InfAclAccount.name. Typically, most operations can be performed with the ID, and for example permissions for users are stored by refering to the account ID in InfdDirectory. The authentication storage can be used to look up a name for the ID, and it is responsible for storing the account information permanantly.

Interface implementations do not need to support every operation provided by the API of this interface, however if they support a certain operation, InfdDirectory takes advantage of it. The only required operation is to be able to look up an account name by its ID, and the reverse lookup, i.e. find all accounts with a given name. The `InfdAccountStorageInterface.get_support()` function returns a bitmask of the supported operations.

Implementations of this interface can couple the available accounts to various external sources, such as SQL databases, LDAP or PAM. Libinfinity also provides a standalone implementation of this interface, which stores the account list as a file in the file system, see InfdFilesystemAccountStorage.

## Functions

### infd_account_storage_get_support ()

    InfdAccountStorageSupport
    infd_account_storage_get_support (InfdAccountStorage *storage);

Returns a bitmask of operations supported by the account storage backend. If unsupported operations are attempted on `storage` , an `error` with code `INF_DIRECTORY_ERROR_OPERATION_UNSUPPORTED` will be generated.

#### Parameters

storage | A InfdAccountStorage. |

#### Returns

A bitmask of supported operations.

### infd_account_storage_supports ()

    gboolean
    infd_account_storage_supports (InfdAccountStorage *storage,
                                   InfdAccountStorageSupport support);

Checks whether support for all operations specified in `support` is available for `storage` . This is equivalent to calling `infd_account_storage_get_support()` and testing the returned value for containing the bits in `support` .

#### Parameters

storage | A InfdAccountStorage. |
support | A bitmask of operations to test. |

#### Returns

`TRUE` if all operations in `support` are supported or `FALSE` otherwise.

### infd_account_storage_lookup_accounts ()

    InfAclAccount *
    infd_account_storage_lookup_accounts (InfdAccountStorage *storage,
                                          const InfAclAccountId *accounts,
                                          guint n_accounts,
                                          GError **error);

Looks up the InfAclAccount structure for all IDs present in `accounts` . The return value is an array of InfAclAccount structures which is in the same order as the `accounts` array. If an element in the output array has the InfAclAccount.id field set to 0, it means that the account with the corresponding ID in the `accounts` array does not exist in `storage` .

#### Parameters

storage | A InfdAccountStorage. |
accounts | An array of InfAclAccountIds to look up. | [array length=n_accounts]
n_accounts | The number of elements in `accounts` . |
error | Location to store error information, if any, or `NULL`. |

#### Returns

An array of InfAclAccount structures with `n_accounts` entries. Free with `inf_acl_account_array_free()`.

[array length=n_accounts][transfer full]

### infd_account_storage_lookup_accounts_by_name ()

    InfAclAccount *
    infd_account_storage_lookup_accounts_by_name
                                   (InfdAccountStorage *storage,
                                    const gchar *name,
                                    guint *n_accounts,
                                    GError **error);

This function performs the "reverse" lookup: Given an account name, the function returns an array with all accounts that have this name. Many backends make sure that there cannot be duplicated names, in which case this can at most return one account, however in principle accounts with the same name are supported.

If there is no account with the given name, the function returns `NULL` and sets `n_accounts` to 0. If an error occurs, `NULL` is returned, `n_accounts` is undefined, and `error` is set. Therefore, to reliably find out whether a lookup error occured or this is no account with the given name, a non-`NULL` error pointer should be passed and checked after the function call.

#### Parameters

storage | A InfdAccountStorage. |
name | The name to look up. |
n_accounts | An output parameter holding the number of returned accounts. | [out]
error | Location to store error information, if any, or `NULL`. |

#### Returns

An array of InfAclAccount structures with length `n_accounts` , or `NULL` on error or when `n_accounts` is 0 or `error` is set. Free with `inf_acl_account_array_free()`.

[array length=n_accounts][transfer full]

### infd_account_storage_list_accounts ()

    InfAclAccount *
    infd_account_storage_list_accounts (InfdAccountStorage *storage,
                                        guint *n_accounts,
                                        GError **error);

Returns an array of all accounts in `storage` . The length of the array is stored in the output parameter `n_accounts` . The functions returns `NULL` and sets `n_accounts` to 0 if there are no accounts in `storage` . If there is an error, the function returns `NULL`, `n_accounts` is undefined, and `error` is set. Therefore, to reliably find out whether an error occurred or whether there are really no accounts present, a non-`NULL` error pointer should be passed and checked after the function call.

Note that this function might not be supported by the backend. See `infd_account_storage_get_support()`.

#### Parameters

storage | A InfdAccountStorage. |
n_accounts | An output parameter holding the number of accounts in `storage` . | [out]
error | Location to store error information, if any, or `NULL`. |

#### Returns

An array of InfAclAccount structures with length `n_accounts` , or `NULL` if `n_accounts` is 0 or `error` is set. Free with `inf_acl_account_array_free()`.

[array length=n_accounts][allow-none][transfer full]

### infd_account_storage_add_account ()

    InfAclAccountId
    infd_account_storage_add_account (InfdAccountStorage *storage,
                                      const gchar *name,
                                      gnutls_x509_crt_t *certs,
                                      guint n_certs,
                                      const gchar *password,
                                      GError **error);

Adds a new account to `storage` . The account will have the given name. The account ID is determined by the storage backend and if the operation is successful it is returned.

If the operation does not support storing certificates and/or passwords, the function will fail if `certs` or `password` are not set to `NULL`, respectively. Note also that this function might not be supported at all by the backend. See `infd_account_storage_get_support()`.

#### Parameters

storage | A InfdAccountStorage. |
name | The name of the new account. |
certs | An array of certificates that can be used to login to the new account, or `NULL`. | [array length=n_certs][allow-none]
n_certs | The length of the certificate array. |
password | A password that can be used to login to the new account, or `NULL`. | [allow-none]
error | Location to store error information, if any, or `NULL`. |

#### Returns

The InfAclAccountId of the added account, or 0 on error.

[transfer full]

### infd_account_storage_remove_account ()

    gboolean
    infd_account_storage_remove_account (InfdAccountStorage *storage,
                                         InfAclAccountId account,
                                         GError **error);

Removes the account with the given ID from `storage` .

Note that this function might not be supported by the backend. See `infd_account_storage_get_support()`.

#### Parameters

storage | A InfdAccountStorage. |
account | The ID of the account to remove. |
error | Location to store error information, if any, or `NULL`. |

#### Returns

`TRUE` on success or `FALSE` on error.

### infd_account_storage_login_by_certificate ()

    InfAclAccountId
    infd_account_storage_login_by_certificate
                                   (InfdAccountStorage *storage,
                                    gnutls_x509_crt_t cert,
                                    GError **error);

This function returns the ID of the account which belongs to the given client certificate. If there is no such account on an error occurs, the function returns 0, and, in the case of an error, `error` is set as well.

Note that this function might not be supported by the backend. See `infd_account_storage_get_support()`.

#### Parameters

storage | A InfdAccountStorage. |
cert | The certificate presented by the client. |
error | Location to store error information, if any, or `NULL`. |

#### Returns

The account ID of the account associated to `cert` , or 0 on error or if there is no such account.

[transfer full]

### infd_account_storage_login_by_password ()

    InfAclAccountId
    infd_account_storage_login_by_password
                                   (InfdAccountStorage *storage,
                                    const gchar *username,
                                    const gchar *password,
                                    GError **error);

This function returns the account ID which matches to the given username and password. If there is no such account or if the password is incorrect, the function returns 0. If an error occurs, the function returns 0 and `error` is set.

Note that when the password is incorrect, `error` is not set. It is only set if there was an internal error and the login procedure could not be carried out due to technical reasons, such as a database outage.

Note that this function might not be supported by the backend. See `infd_account_storage_get_support()`.

#### Parameters

storage | A InfdAccountStorage. |
username | The username of the account to log into. |
password | The password of the corresponding account. |
error | Location to store error information, if any. |

#### Returns

The account ID of the account associated to `username` if `password` is correct, or 0 otherwise.

[transfer full]

### infd_account_storage_set_certificate ()

    gboolean
    infd_account_storage_set_certificate (InfdAccountStorage *storage,
                                          InfAclAccountId account,
                                          gnutls_x509_crt_t *certs,
                                          guint n_certs,
                                          GError **error);

Changes the certificate(s) associated to the account with ID `account` . All certificates that are currently associated to it are removed, and the given certificates are associated instead. If `n_certs` is 0, there will be no associated certificates and login by certificate will be disabled for `account` .

Note that this function might not be supported by the backend. See `infd_account_storage_get_support()`.

#### Parameters

storage | A InfdAccountStorage. |
account | The ID of the account whose certificate to set. |
certs | An array of certificates, or `NULL` if n_certs is 0. | [array length=n_certs][allow-none]
n_certs | The number of certificates in the certificate array. |
error | Location to store error information, if any. |

#### Returns

`TRUE` if the operation was successful or `FALSE` if an error occured.

### infd_account_storage_set_password ()

    gboolean
    infd_account_storage_set_password (InfdAccountStorage *storage,
                                       InfAclAccountId account,
                                       const gchar *password,
                                       GError **error);

Changes the password for the account with the given ID. If this call succeeds, the new password will have to be provided to `infd_account_storage_login_by_password()` for the login to succeed. If `password` is `NULL`, the password will be unset and login by password will no longer be possible.

Note that this function might not be supported by the backend. See `infd_account_storage_get_support()`.

#### Parameters

storage | A InfdAccountStorage. |
account | The ID of the account whose password to change. |
password | The new password for the account, or `NULL`. |
error | Location to store error information, if any, or `NULL`. |

#### Returns

`TRUE` on success or `FALSE` on error.

### infd_account_storage_account_added ()

    void
    infd_account_storage_account_added (InfdAccountStorage *storage,
                                        const InfAclAccount *account);

Emits the “account-added” signal on `storage` . This should only be used by interface implementations.

#### Parameters

storage | A InfdAccountStorage. |
account | The InfAclAccount that was added to the storage. |

### infd_account_storage_account_removed ()

    void
    infd_account_storage_account_removed (InfdAccountStorage *storage,
                                          const InfAclAccount *account);

Emits the “account-removed” signal on `storage` . This should only be used by interface implementations.

#### Parameters

storage | A InfdAccountStorage. |
account | The InfAclAccount with the account information for the removed account. |

## Types and Values

### InfdAccountStorage

    typedef struct _InfdAccountStorage InfdAccountStorage;

InfdAccountStorage is an opaque data type. You should only access it via the public API functions.

### struct InfdAccountStorageInterface

    struct InfdAccountStorageInterface {
      InfdAccountStorageSupport (*get_support)(InfdAccountStorage* storage);

      InfAclAccount* (*lookup_accounts)(InfdAccountStorage* storage,
                                        const InfAclAccountId* accounts,
                                        guint n_accounts,
                                        GError** error);

      InfAclAccount* (*lookup_accounts_by_name)(InfdAccountStorage* storage,
                                                const gchar* name,
                                                guint* n_accounts,
                                                GError** error);

      InfAclAccount* (*list_accounts)(InfdAccountStorage* storage,
                                      guint* n_accounts,
                                      GError** error);

      InfAclAccountId (*add_account)(InfdAccountStorage* storage,
                                     const gchar* name,
                                     gnutls_x509_crt_t* certs,
                                     guint n_certs,
                                     const gchar* password,
                                     GError** error);

      gboolean (*remove_account)(InfdAccountStorage* storage,
                                 InfAclAccountId account,
                                 GError** error);

      InfAclAccountId (*login_by_certificate)(InfdAccountStorage* storage,
                                              gnutls_x509_crt_t cert,
                                              GError** error);

      InfAclAccountId (*login_by_password)(InfdAccountStorage* storage,
                                           const gchar* username,
                                           const gchar* password,
                                           GError** error);

      gboolean (*set_certificate)(InfdAccountStorage* storage,
                                  InfAclAccountId account,
                                  gnutls_x509_crt_t* certs,
                                  guint n_certs,
                                  GError** error);

      gboolean (*set_password)(InfdAccountStorage* storage,
                               InfAclAccountId account,
                               const gchar* password,
                               GError** error);

      /* Signals */
      void (*account_added)(InfdAccountStorage* storage,
                            const InfAclAccount* account);

      void (*account_removed)(InfdAccountStorage* storage,
                              const InfAclAccount* account);
    };

The virtual methods and default signal handlers of InfdAccountStorage. Implementing these allows an infinote server to set a specific source of user accounts.

#### Members

`get_support` () | Virtual function to get the list of supported operations on the backend. |
`lookup_accounts` () | Virtual function to look up account by their identifier. |
`lookup_accounts_by_name` () | Virtual function to reverse-lookup an account identifier when given the account name. |
`list_accounts` () | Virtual function to obtain a list of all available accounts. Can be `NULL` if not supported by the backend. |
`add_account` () | Virtual function to add a new account. Can be `NULL` if not supported by the backend. |
`remove_account` () | Virtual function to remove an existing account. Can be `NULL` if not supported by the backend. |
`login_by_certificate` () | Virtual function to look up the account associated with a given certificate. Can be `NULL` if not supported by the backend. |
`login_by_password` () | Virtual function to check a username and password, and return the associated account. Can be `NULL` if not supported by the backend. |
`set_certificate` () | Set the certificate to be associated to a given account, or `NULL` if not supported. |
`set_password` () | Set the password for a given account, or `NULL` if not supported. |
`account_added` () | Default signal handler for the “account-added” signal. |
`account_removed` () | Default signal handler for the “account-removed” signal. |

### enum InfdAccountStorageSupport

This enumeration specifies operations that might or might not be supported by a particular InfdAccountStorage implementation. Looking up an account by ID or name must always be supported.

#### Members

INFD_ACCOUNT_STORAGE_SUPPORT_NOTIFICATION | Whether the “account-added” and “account-removed” signals are emitted when accounts are added or removed externally. |
INFD_ACCOUNT_STORAGE_SUPPORT_LIST_ACCOUNTS | Whether obtaining a full list of available accounts is supported. |
INFD_ACCOUNT_STORAGE_SUPPORT_ADD_ACCOUNT | Whether adding a new account to the storage is supported. |
INFD_ACCOUNT_STORAGE_SUPPORT_REMOVE_ACCOUNT | Whether removing an existing account from the storage is supported. |
INFD_ACCOUNT_STORAGE_SUPPORT_CERTIFICATE_LOGIN | Whether the account storage supports authenticating users via client certificates. |
INFD_ACCOUNT_STORAGE_SUPPORT_PASSWORD_LOGIN | Whether the account storage supports authenticating users via username and password. |
INFD_ACCOUNT_STORAGE_SUPPORT_CERTIFICATE_CHANGE | Whether the account storage supports changing the certificate associated to a user. |
INFD_ACCOUNT_STORAGE_SUPPORT_PASSWORD_CHANGE | Whether the account storage supports changing a user's password. |

## Signal Details

### The `“account-added”` signal

    void
    user_function (InfdAccountStorage *storage,
                   InfAclAccount      *info,
                   gpointer            user_data)

This signal is emitted whenever an account has been added to the account storage. However, the signal is only emitted if the storage implementations supports the `INFD_ACCOUNT_STORAGE_SUPPORT_NOTIFICATION` support flag.

#### Parameters

storage | The InfdAccountStorage emitting the signal. |
info | The InfAclAccount containing the account ID and account name of the added account. |
user_data | user data set when the signal handler was connected. |

Flags: Run Last

### The `“account-removed”` signal

    void
    user_function (InfdAccountStorage *storage,
                   InfAclAccount      *info,
                   gpointer            user_data)

This signal is emitted whenever an account has been permanently removed from the storage. However, the signal is only emitted if the storage implementations supports the `INFD_ACCOUNT_STORAGE_SUPPORT_NOTIFICATION` support flag.

#### Parameters

storage | The InfdAccountStorage emitting the signal. |
info | The InfAclAccount containing the account ID and account name of the removed account. |
user_data | user data set when the signal handler was connected. |

Flags: Run Last

## See Also

InfdDirectory, InfdFilesystemAccountStorage