# realmd Internals

January, 2013

## Overview

realmd is an on-demand system D-Bus service, whose primary purpose is to enable Linux to work seamlessly out of the box with network authentication realms (like Kerberos, with primary focus on AD and IPA). Specifically, the realmd service supports discovering a domain, joining a domain, leaving a domain, and more.

Currently there is only support for Kerberos realms.

Some of the D-Bus clients that interact with realmd are:

- command line realm client

- gnome-control-center GUI client

- gdm

- anaconda

Realmd can be run in two different modes (with some slight changes in behavior depending on the mode)

- At install time (e.g. using an anaconda kickstart file). In this mode, since the system message bus may not be available, the realm client directly spawns realmd and communicates with it using the D-Bus peer protocol (i.e. without going through the message bus).

- After installation. In this mode, the system message bus is available and is used to forward messages from the realm client to realmd.

Realmd is typically used (whether at install time or afterwards) by a D-Bus client to discover the KDC for a Kerberos domain and to join the machine to that domain using membership software. This will involve changes on the server made by server software, as well as artifacts (keytab, configuration file) that are output by realmd on the machine for consumption by client software that will subsequently be responsible for Kerberos authentication.

For active-directory server software, realmd supports:

- sssd client software (with either adcli or samba membership software)

- winbind client software (with samba membership software).

For IPA server software, realmd supports:

- sssd client software (with 'ipa' membership software).

## Realmd Objects and Interfaces

A GDBusObject is associated with an object path and is essentially a container of GDBusInterfaces. On the service side, this is implemented using GDBusObjectSkeletons and GDBusInterfaceSkeletons (with corresponding GDBusObjectProxy and GDBusProxy components on the client side). The base GDBusObjectSkeletons used by realmd are RealmKerberos and RealmProvider (each with its own subclasses and interfaces). The objects are linked, in that a RealmProvider object creates a RealmKerberos object during the Discover process. The type of RealmKerberos object that is created depends on the type of RealmProvider that is used. Only those RealmKerberos objects that implement the RealmKerberosMembership GInterface can be used to join or leave a domain.

RealmKerberos

RealmDbusRealm

  supports Deconfigure and ChangeLoginPolicy methods

RealmDbusKerberosMembership

  supports Join and Leave methods

RealmDbusKerberos

  supports no methods (properties only)

RealmSamba

  implements RealmKerberosMembership

RealmSssd

  container for RealmSssdAd and RealmSssdIpa

  subclass: RealmSssdAd

    implements RealmKerberosMembership

  subclass: RealmSssdIpa

    implements RealmKerberosMembership

RealmProvider

RealmDbusProvider

  supports Discover method

RealmSambaProvider

  creates RealmSamba objects

RealmSssdProvider

  creates RealmSssdAd and RealmSssdIpa objects

RealmKerberosProvider

  creates RealmKerberos objects

RealmAllProvider

  aggregates other RealmProviders

## Discover method

The main purpose of the Discover method is to verify that a specified domain is valid, emitting logs and diagnostic information in the process. RealmProviders discover the authoritative KDCs for the specified domain by querying DNS for SRV records and creating appropriate RealmKerberos objects to encapsulate the KDC information. Certain types of RealmKerberos objects (i.e. RealmSamba and RealmSssdAd) can subsequently be used as part of the Join process.

RealmAllProvider is special in that it serves all realm types. A client that wants to use all of the RealmProviders (Samba, Sssd, Kerberos) can contact each RealmProvider (at its unique object path). Alternatively and usually, the client simply contacts the RealmAllProvider, which is special in that it serves as an aggregation point and container for all of the other RealmProviders. When Discover is called on RealmAllProvider, it calls the Discover methods of each of the other RealmProviders, collects the results (array of RealmKerberos objects), and returns an aggregated result (array of object paths pointing to RealmKerberos objects) to the client. The AllProvider also connects to a notify signal, so that if any of its sub-providers change state, AllProvider can also update its state accordingly.

## RealmProvider

A RealmProvider object supports the Discover method, and is characterized by:

- its object path (static)

- the combinations of {client, server, membership} software it supports for the Discover process

- the types of RealmKerberos objects it creates during the Discover process

- the file it uses to read/write configuration information

RealmSambaProvider

- object path: "/org/freedesktop/realmd/Samba"

- creates: RealmSamba objects

- config file read: smb.conf

- software supported: {winbind, active-directory, samba}

RealmSssdProvider

- object path: "/org/freedesktop/realmd/Sssd"

- creates: RealmSssdAd objects or RealmSssdIpa objects (depending on server-software)

- config file read: sssd.conf

- software supported

  - {sssd, active-directory, samba}

  - {sssd, active-directory, adcli}

  - {sssd, ipa, ipa}

RealmKerberosProvider

- object path: "/org/freedesktop/realmd/GenericKerberos"

- creates: RealmKerberos objects

- config file read: n/a

- software supported: none, so only used if client-software and server-software were not specified

RealmAllProvider

- object path: “/org/freedesktop/realmd”

- special RealmProvider that aggregates results (see Discover() method)

## Join method

The primary goal of joining a machine to a domain is to enroll the machine with the domain's KDC, thereby enabling subsequent Kerberos user authentication. This results in the creation of a secret shared between the machine and KDC (i.e. a keytab), as well as changes to the appropriate configuration file on the machine. Conversely, the primary goal of leaving a domain is to unenroll the machine from the domain's KDC, removing the keytab and removing the changes that were previously made to the appropriate configuration file during enrollment. Both the join and leave operations require appropriate credentials, where each credential is represented by the credential owner and the credential type. Different RealmKerberos objects support different credentials, and different credentials may be supported for join and leave. Before performing the join, any required packages or files are installed.

Possible credential owners: admin, user, computer, none

Possible credential types: password, secret (otp), automatic (default/system creds)

## RealmKerberos

A RealmKerberos object supports the Join, Leave, Deconfigure, and ChangeLoginPolicy methods. It is characterized by:

- its object path (dynamic, per realm)

- the membership software it supports

- the configuration file it modifies

- the packages it requires to be installed

- the credentials it supports: {owner, type}

RealmSamba

- object path example: /realmd/Samba/example.com_4

- membership software supported: samba

- config file modified: smb.conf

- required packages: samba, winbind

- credentials supported:

  - {admin, password}

  - {user, password}

  - {none, automatic}

RealmSssdAd

- object path example: /realmd/Sssd/example.com_4

- membership software supported: samba, adcli (but only for certain credentials: see below)

- config file modified: sssd.conf

- required_packages: sssd, adcli, samba (depends on membership software)

- credentials supported:

  - {admin, password} // supported by both samba (default) and adcli

  - {user, password} // supported only by samba

  - {none, automatic} // supported only by adcli

  - {none, secret} // supported only by adcli; note that these are supported for join, but not leave

RealmSssdIpa

- has a dynamically generated object path upon realm creation.

- membership software supported: ipa

- config file modified: sssd.conf

- required_packages: sssd, freeipa-client

- credentials supported:

  - {admin, password}

  - {none, secret} // one time password

## Exporting Realmd Objects and Interfaces

When realmd starts up (realm-daemon.c:main), it registers each of its RealmProviders (except RealmAllProvider) with its GDBusObjectManagerServer, which in turn exports (onto a specific object path) the GDBusInterfaces for each RealmProvider onto the GDBusConnection. As RealmKerberos objects are dynamically created, they are similarly registered with the Object Manager and exported.

Note that only GDBusInterfaces that are exported onto the GDBusConnection are capable of receiving method call messages from the client. When a message is received by the worker thread of the service's GDBusConnection, the message's {object_path, iface_name} are mapped to a GDBusInterfaceSkeleton, which emits a signal. The enclosing GDBusObjectSkeleton catches the signal and executes the callback registered for that signal (usually set in RealmProvider's constructed method).

Since RealmAllProvider is just an aggregation point, it is not managed by the GDBusObjectManagerServer,but it is directly exported onto the GDBusConnection using g_dbus_connection_register_object(). The ObjectManager and Service objects are also directly exported onto the GDBusConnection.

The following is a subset of objects and interfaces registered with the GDBusObjectManagerServer and/or exported onto the GDBusConnection.

GDBusConnection: stores {object_path, iface_name} => GDBusInterfaceSkeleton

- {/org/freedesktop/realmd, org.freedesktop.realmd.Provider} => RealmDbusProviderSkeleton(“All”)

- {/org/freedesktop/realmd, org.freedesktop.realmd.Service} => RealmDbusServiceSkeleton

- {/org/freedesktop/realmd, org.freedesktop.DBus.ObjectManager} => GDBusObjectManagerServer

GDBusObjectManagerServer: stores object_path => GDBusObjectSkeleton

- /org/freedesktop/realmd/Sssd => RealmSssdProvider

- /org/freedesktop/realmd/Samba => RealmSambaProvider

- /org/freedesktop/realmd/GenericKerberos => RealKerberosProvider

- /org/freedesktop/realmd/Sssd/example.com_4 => RealmSssdAd

## Example Provider

realmd includes a rough example provider, which can be used as a mock provider for testing against. It is disabled by default. The example provider discovers realms that match `*example.com`.

Set the `example` setting to `yes` in the `[providers]` section of the settings to enable it.

    [providers]
    example = yes
    # example = no

Some settings of the example provider.

    [example]
    # What domain to return for a default discovery
    default = default.example.com
    # How long to delay a successful discovery, in seconds
    example-discovery-delay = 1.3
    # How long to delay a unsuccessful disocvery
    example-non-discovery-delay = 0.9

You can tweak various options per example realm.

    [default.example.com]
    # Mock administrator account required to join
    example-administrator = Administrator
    # Password for above mock admin account
    example-password = bureaucracy
    # How long to delay when joining this domain, in seconds.
    example-join-delay = 2.5
    # How long to delay when leaving
    example-leave-delay = 1
    # Whether to disallow leaving without a password
    example-no-auto-leave = yes

## Missing

- Description of ChangeLoginPolicy method

- Description of all the methods for the Service object

- Details of realmd.conf (man page, perhaps)

- Details of configuration files (sssd.conf, smb.conf) and relevant entries