MASARYK UNIVERSITY FACULTY}w¡¢£¤¥¦§¨  OF I !"#$%&'()+,-./012345

OpenLMI provider for management of the SSSD client components

MASTERTHESIS

Pavel Brezinaˇ

Brno, spring 2014 Declaration

Hereby I declare, that this paper is my original authorial work, which I have worked out by my own. All sources, references and literature used or ex- cerpted during elaboration of this work are properly cited and listed in com- plete reference to the due source.

Pavel Brezinaˇ

Advisor: RNDr. Jan Kasprzak

i Acknowledgement

I would like to thank my supervisor for his guidance, Ing. Jakub Hrozek for his great mentoring and RNDr. Anna Jonášová and other OpenLMI devel- opers for all their help.

ii Abstract

The goal of this thesis is to create an SSSD provider for the OpenLMI project, which would allow a local and remote management of the funda- mental parts of the SSSD system service through the OpenLMI interface.

iii Keywords

SSSD, OpenLMI, WBEM, CIM, management, administration

iv Contents

1 Introduction ...... 3 1.1 Goal of this thesis ...... 3 1.2 Thesis organization ...... 4 2 Web-Based Enterprise Management ...... 5 2.1 Architecture ...... 5 2.1.1 Components ...... 6 2.1.2 Workflow ...... 8 2.2 Common Information Model ...... 8 2.2.1 CIM Infrastructure Specification ...... 8 2.2.2 CIM Schema ...... 9 2.2.3 Managed Object Format ...... 9 2.3 Overview of existing implementations ...... 13 2.3.1 SBLIM ...... 13 2.3.2 WBEM Services ...... 13 2.3.3 Windows Management Instrumentation ...... 14 2.3.4 OpenLMI ...... 14 3 OpenLMI ...... 15 3.1 LMI Providers ...... 15 3.2 LMI Shell ...... 16 3.2.1 Using the shell ...... 16 3.3 LMI Scripts ...... 21 3.3.1 Examples ...... 21 4 System Security Services ...... 23 4.1 Main features ...... 23 4.2 Architecture ...... 24 4.3 Cache management ...... 26 4.3.1 Record expiration ...... 27 4.3.2 Negative cache ...... 27 4.3.3 Mid-point refresh ...... 27 4.3.4 Periodic updates ...... 28 4.3.5 Fast in-memory cache ...... 29 4.3.6 Caching of sudo rules ...... 29 4.4 Data Providers ...... 31 4.5 Responders ...... 32 4.6 Client applications and libraries ...... 33

1 5 Implementation of OpenLMI SSSD provider ...... 34 5.1 CIM Schema for OpenLMI SSSD provider ...... 34 5.1.1 CIM concepts ...... 34 5.1.2 First revision ...... 35 5.1.3 Final schema ...... 37 5.1.4 Designing classes for SSSD components ...... 40 5.1.5 Designing classes for SSSD domains and subdomains 42 5.2 Considered solutions ...... 44 5.2.1 OpenLMI provider is self-sufficient ...... 44 5.2.2 OpenLMI provider and new SSSD responder . . . . 45 5.2.3 OpenLMI provider and SSSD InfoPipe responder . . 47 5.3 InfoPipe responder ...... 48 5.3.1 D-Bus interface ...... 49 5.4 Modifying configuration ...... 52 5.4.1 Augeas ...... 52 5.4.2 Application in SSSD ...... 53 5.5 Simple SSSD D-Bus API ...... 53 5.5.1 Example usage ...... 55 5.6 SSSD provider for OpenLMI ...... 56 5.7 SSSD OpenLMI scripts ...... 57 5.7.1 Command interface ...... 57 6 Conclusion ...... 59 A SSSD CIM schema: MOF ...... 60

2 1 Introduction

Administration of production and internal servers or workstations in a large enterprise environment is a very difficult task that requires many system experts skilled in various system components. Basically every element of the company IT infrastructure provides different tools for its configuration and monitoring. The system administrator has to be aware of many config- uration formats, understand different settings of managed services and then he or she has to find a way how to distribute every single change to each component across all managed computer systems. The Web-Based Enterprise Management (WBEM)1is an open standard that aims at unification of the IT infrastructure management in an enterprise environment. It covers many areas of management and provides tools to further expand its abilities to support new components. Every component is managed by a piece of software called provider that exports its configura- tion and monitoring options into an object oriented interface. One particular implementation of this standard is the OpenLMI. The OpenLMI2is an open source project that aims to bring WBEM closer to -powered systems by creating providers for standard Linux components such as service and software management, network and firewall configuration, disk maintenance etc.

1.1 Goal of this thesis

The goal of this thesis is to create an OpenLMI provider for System Se- curity Services Daemon3(SSSD). SSSD is a system service that manages remote identities and policy information stored in a directory server and im- plements a sophisticated caching mechanisms to make this data available in offline scenarios. Every identity and policy object is associated with a do- main. The domain is a logical unit, a container for related objects. SSSD supports multiple domains to be managed on one machine.

1. http://dmtf.org/standards/wbem 2. http://www.openlmi.org/ 3. https://fedorahosted.org/sssd

3 1. INTRODUCTION

The thesis should implement the most fundamental parts of SSSD configu- ration, in particular:

• to enable and disable domains and services

• changing debug level of SSSD components

• to provide basic information about managed domains

1.2 Thesis organization

The second chapter describes the Web-Based Enterprise Management stan- dard in detail. It goes through its architecture and incorporated standards such as Common Information Model and Managed Object Format. Small part is also devoted to existing implementations of this standard. The third chapter is dedicated to the OpenLMI project. It describes its benefits, user interface and introduces several examples of its usage. The next part is about the SSSD service. It thoroughly describes its architec- ture, components and caching mechanisms. And finally the fifth chapter de- scribes the implementation of the SSSD provider for OpenLMI – its design, pieces and important interfaces.

4 2 Web-Based Enterprise Management

Web-Based Enterprise Management (WBEM) is an open standard devel- oped by Distributed Management Task Force (DMTF)1organization. It aims to unify management of system resources in distributed computing envi- ronments – from a low level process, network or storage management to a higher level view on the system state and configuration of specific compo- nents and provided services. Every managed element is looked upon as an object with attributes and methods. WBEM defines how the objects look like, how to transfer their representation over a network and how to call methods on these objects. It also defines a standard set of supported resources and provides base tem- plates to help extending this set with proprietary or open solutions. To achieve its goal, WBEM widely reuses other DMTF standards, mainly Common Information Model (CIM) which provides the tools for descrip- tion of managed elements as objects and introduces basic concepts of how to work with them. It is, however, quite loose on implementation details as it does not specify several key things to make the management really indepen- dent on underlying technologies and software components. For example, it does not specify a protocol to transfer objects over a network or any spe- cific server architecture. WBEM is basically a standardized implementation of CIM which eliminates these weak points by defining new standards like CIM-XML[6] transfer protocol or by declaring that a server has to be split into a controller and providers that take care of selected components. Besides these it also incorporates other standards that help WBEM to fit into enterprise environments such as Service Location Protocol[7] to lo- cate WBEM servers inside a corporate network or Uniform Resource Iden- tifier[8] to identify and distinguish every managed resource.

2.1 Architecture

Web-Based Enterprise Management standard consists of several key com- ponents: WBEM server and providers, communication protocol and CIM schema. It does not specify any particular user interface, therefore any kind of command line, graphical or browser user interface can be used to manage

1. A standard development organization: http://www.dmtf.org

5 2. WEB-BASED ENTERPRISE MANAGEMENT remote resources. The architecture is illustrated in Figure 2.1.

Access CIM Control Schema

User CIM-XML WBEM Server Interface over HTTP

Provider ... Provider

Operating System Interface

Managed System Resources

Figure 2.1: Architecture of WBEM

2.1.1 Components This section briefly describes the fundamental components of WBEM stan- dard in the bottom-up order.

CIM schema CIM schema defines a set of managed objects. It describes how the objects look like: what attributes do they have, what methods they support and what are the relationships among those objects. For this purpose Common Infor-

6 2. WEB-BASED ENTERPRISE MANAGEMENT mation Model standard and its conceptual object oriented language called Managed Object Format (MOF) are used. More information on these stan- dards can be found in Section 2.2.

WBEM provider Provider is a server module that implements selected components of the CIM schema. It basically creates a mapping between re- sources into a format understood by the server. Many providers are depen- dent on underlying operating system, since each system has usually different interface to access its objects – especially the low level ones.

WBEM server WBEM server, which is also often called CIM Object Monitor (CIMOM), is the access point between a client and the providers. It handles user au- thentication and authorization and it uses the schema to route commands and data into a particular provider and to call selected method to complete the operation. Depending on implementation, it may also contain a simple persistent database to be used by the providers.

Provider interface The WBEM standard itself does not specify any particular programming in- terface between the providers and CIMOM thus basically every implemen- tation defines its own API. Therefore one provider can not be used across multiple implementations of WBEM server. Since this was proven to be a huge disadvantage in a real world experience a new standard defining the API emerged under The Open Group1consortium. The API is referred to as Common Manageability Programming Interface[11] (CMPI) and it is sup- ported by most of the modern CIMOM implementations with the exception of some proprietary solutions. Providers written for CMPI are mostly or even completely independent on the server underneath. For communication between a client and the server the CIM objects and commands are packed into an XML format (so called CIM-XML) and the payload is being transferred over a standard HTTP protocol.

1. http://www.opengroup.org

7 2. WEB-BASED ENTERPRISE MANAGEMENT

2.1.2 Workflow At first, the operator will issue a command through selected user interface. This command is packed into a CIM-XML format and sent over an HTTP protocol to the WBEM server. The server then performs user authentica- tion and checks whether the user is authorized to perform the desired com- mand. If the access is granted to the user, the server reads the CIM schema and decides to which provider should be the command forwarded. The re- quest is then processed by the selected provider, the result is returned to the server and the server sends it back to the client – again using CIM-XML over HTTP. The returned value can be either a simple value (number, string, boolean, . . . ), some of the predefined error codes (access denied, operation not supported, invalid arguments, . . . ) or the whole object described by its attributes.

2.2 Common Information Model

Common Information Model (CIM) is an open standard that defines how to represent managed resources as a set of objects and relationships among them and how to exchange information about these elements between mul- tiple parties. CIM is split into two parts: the Infrastructure Specification (2.2.1) and the CIM schema (2.2.2). Infrastructure Specification defines architecture and concepts of CIM. The schema is then a huge set of predefined classes that pursue the needs of enterprise environments.

2.2.1 CIM Infrastructure Specification CIM Infrastructure Specification[2] defines how to describe managed ele- ments using an object oriented approach. Every element is an instance of some class. A class defines attributes that provide information on the object and methods that represent an operation on the object which may result in altering the object state. Any relationship between two objects is declared as an association. As- sociation is a special class that contains references to two or more instances of some (not necessarily distinct) classes. It can model all one to one, one to many and many to many relations. Common Information Model also supports polymorphism, thus any class

8 2. WEB-BASED ENTERPRISE MANAGEMENT or association can be derived from or marked as abstract (i. e. it can not be instantiated). The definition language use to describe CIM elements is called Managed Object Format. The fundamental syntax of this language is described in Section 2.2.3.

2.2.2 CIM Schema CIM Schema is a conceptual model that describes many classes and associ- ations to cover most of the needs of enterprise environments. The schema is split into three categories: Core Schema, Common Schemas and Extension Schemas[1]. The Core Schema is a base model. It provides classes and associations that are shareable within all areas of management. Those elements usually serve as base classes to be derived from to create more precise description of specific resources. An example of such a class is CIM_ManagedElement which provides basic information about the managed element such as its name, description and generation. This class should be on top of an inheri- tance tree for all managed elements. Common Schemas provide more specific classes for common manage- ment areas such as network configuration, processes and services mainte- nance, storage, databases, accounts, etc. These classes, however, are de- signed generically enough to be independent on any underlying technology and lack any vendor-specific characteristics. For example CIM_Account is used to represent user accounts and it declares attributes like name, last login time, password expiration but it does not provide anything system specific like a UNIX login shell. The last category Extension Schemas contains vendor specific exten- sions to the Common Schemas which became a part of the standard. For example CIM_UnixFile representing a UNIX file or CIM_J2eeJVM describ- ing Java Virtual Machine utilized by a J2EE server.

2.2.3 Managed Object Format Managed Object Format[5] (MOF) is a conceptual object oriented language based upon UML, that supports many typical features of object oriented languages such as classes, structures, enumerations and qualifiers (annota- tions). However, CIM itself uses only a subset of this language. It supports

9 2. WEB-BASED ENTERPRISE MANAGEMENT

only qualifiers and simple class definitions, where attributes can be defined only as a primitive type or a reference to a class in case of an association.

Class declaration Class declaration follows a common syntax of modern object oriented lan- guages. This syntax is enriched by qualifiers which can be applied to every class, attribute, method or method argument declaration. 1 [qualifiers] 2 class ClassName : SuperClass 3 { 4 [qualifiers] 5 type AttributeName; 6 ... 7 8 type MethodName([qualifiers] type ArgName, ...); 9 ... 10 }; Listing 2.1: MOF class declaration Qualifiers are a widely used concept in CIM, since they are not only used as guidelines for code editors but their main purpose is to specify the nature of the qualified element – how it should be interpreted, value range and other conditions. For example, an argument may be marked as an input or output. At- tribute may be qualified as a Bitmap, meaning that every bit of the attribute has some specific interpretation. Another qualifier called BitValues can specify how the bits shall be interpreted. It may also be used to specify the minimum (MinValue) or maximum value (MaxValue) of a numeric at- tribute or argument. Very common qualifier is Description that provides documentation of the class element. Another important qualifier is Key that marks an attribute or a set of attributes as unique in all existing instances of the same class and it is used as a part of the instance address. The following example shows an abstract class representing a person. This class cannot be instantiated and serves as a base class for classes Man and Woman. 1 [Abstract, 2 Description("Class representing a human beeing.")] 3 class Person 4 {

10 2. WEB-BASED ENTERPRISE MANAGEMENT

5 [Key] 6 uint32 NationalIdentificationNumber 7 8 string FirstName; 9 string LastName; 10 11 [MinValue(1), MaxValue(31)] 12 uint32 DayOfBirth; 13 14 [MinValue(1), MaxValue(12)] 15 uint32 MonthOfBirth; 16 17 uint32 YearOfBirth; 18 19 uint32 ComputeAge(); 20 }; 21 22 class Man : Person 23 { 24 25 } 26 27 class Woman : Person 28 { 29 string BirthLastName; 30 } Listing 2.2: MOF example: Person

Association declaration Association is declared in the same way as a class with addition of the Association qualifier. This qualifier allows inclusion of references into the class declaration. References are marked with REF keyword. Besides refer- ences, associations can also have attributes and methods in the same way as classes can. Cardinality of a relation can be controlled by Min and Max qualifiers specifying minimum and maximum cardinality respectively. Those quali- fiers are associated with each reference. The next example will create an association between previous classes Man and Woman symbolizing their marriage. The qualifier Max(1) declares the marriage as monogamy. The association also have an attribute represent- ing number of children that came up from this marriage.

11 2. WEB-BASED ENTERPRISE MANAGEMENT

1 [Association, 2 Description("Married couples.")] 3 class MarriedCouples 4 { 5 [Key, Max(1)] 6 Man REF Husband; 7 8 [Max(1)] 9 Women REF Wife; 10 11 uint32 NumberOfChildren; 12 }; Listing 2.3: MOF example: association

Instance declaration It is possible to create an instance of a class or an association directly using MOF syntax. The following example will create an instance of a man and a woman and marry them. 1 instance of Man as $Adam 2 { 3 NationalIdentificationNumber = 8807014142; 4 FirstName = "Adam"; 5 LastName = "Hunt"; 6 7 DayOfBirth = 1; 8 MonthOfBirth = 7; 9 YearOfBirth = 1988; 10 }; 11 12 instance of Woman as $Eva 13 { 14 NationalIdentificationNumber = 9053141122; 15 FirstName = "Eva"; 16 LastName = "Hunt"; 17 18 DayOfBirth = 14; 19 MonthOfBirth = 3; 20 YearOfBirth = 1990; 21 22 BirthLastName = "Abott"; 23 }; 24

12 2. WEB-BASED ENTERPRISE MANAGEMENT

25 instance of MarriedPersons 26 { 27 Husband = $Adam; 28 Wife = $Eva; 29 30 NumberOfChildren = 0; 31 }; Listing 2.4: MOF example: instantiation

2.3 Overview of existing implementations

Several open source and proprietary projects exist that implement the Web- Based Enterprise Management on a different scale. A brief overview of the most notable ones follows.

2.3.1 SBLIM

SBLIM1(pronounced Sublime; acronym for Standards Based Linux Instru- mentation for Manageability) is a collection of open source system man- agement tools that enables WBEM on Linux systems. It brings the whole set of components from a client through a set of providers and and Java language bindings to a server. An interesting feature of this project is the CIMOM: Small Footprint CIM Broker (SFCB) that has a memory footprint less than one megabyte which makes it possible to run it on small embedded systems.

2.3.2 WBEM Services

WBEM Services2is an open source implementation of full WBEM stack written in Java language. It also brings several supplementary developer tools such as code generator which converts CIM schema written in MOF into a Java source code, graphical schema browser and many examples.

1. http://sblim.wiki.sourceforge.net 2. http://wbemservices.sourceforge.net

13 2. WEB-BASED ENTERPRISE MANAGEMENT

2.3.3 Windows Management Instrumentation Windows Management Instrumentation (WMI) is a Microsoft’s proprietary implementation. Even though it is highly based on WBEM standard, it is not completely compatible and it requires providers to be specially written only for WMI using COM/DCOM API interface since WMI does not support CMPI.

2.3.4 OpenLMI OpenLMI1(Open Linux Management Infrastructure) is an emerging open source project that brings together multiple existing pieces of WBEM stack and also adds several new tools like an LMI shell with Python based syntax. Besides that it brings many Linux specific providers and more are about to come. OpenLMI aims to be a new standard for Linux environments that will redefine the current ways of configuration of system components.

1. http://openlmi.org

14 3 OpenLMI

OpenLMI (Open Linux Management Infrastructure) is a set of tools that simplifies monitoring and management of Linux machines through the WBEM technology. Its goal is to unify configuration of all fundamental parts of Linux system, thus reducing the needs to understand the syntax and seman- tics of configuration files for every service. OpenLMI uses Open Pegasus as underlying WBEM implementation and adds several new providers that cover many important areas of common ad- ministration tasks like disk partitioning, network configuration, users and groups management, software installation and maintenance, event log, hard- ware information, etc. The project also provides several new client tools. Besides the low level API and language bindings for C/C++, Java and Python it brings especially the LMI shell which is a client application that reflects all CIM objects into the Python language. This enables full access to remote objects and allows to use them natively in Python code. It also offers a set of LMI scripts that implements the most common tasks and completely hides the complexity of WBEM under simple commands.

Main features • Open source project with active development

• Linux-specific set of providers

• Python-based LMI shell

• Simplifies common task with single commands

• API for C/C++, Java and Python

3.1 LMI Providers

OpenLMI project aims at delivering CIM providers that implements classes for monitoring and configuration of fundamental parts of Linux systems. These classes can be simply recognized in the CIM schema since the names of all classes developed for this project start with LMI_ prefix.

15 3. OPENLMI

OpenLMI version 0.4.21contains the following providers: network, storage, fan, hardware, logicalfile, power, service, software, journald and realmd.

3.2 LMI Shell

The LMI shell is a client application for OpenLMI. It works as a Python in- terpreter therefore it is capable of running any code written in this language. All remote CIM objects are reflected into a native Python objects, thus they can be simply accessed by using the language constructs. As a consequence of this feature, the operator does not have to deal with the complexity of WBEM communication mechanisms and data formats. The only knowledge required to use the shell is an elementary Python syn- tax and basic programming skills. However, the more fluent in the Python language the operator is the more powerful the shell becomes. The following section introduces some fundamental concepts of access- ing OpenLMI from the shell.

3.2.1 Using the shell This section contains set of example WBEM calls invoked from LMI shell environment and explanation of fundamental concepts of the shell. To enter the shell in the interactive mode run the following command: $ lmishell

It is often useful to also append --verbose or --more-verbose arguments to the lmishell command to get some tracing and debugging information.

Establishing connection Before we start working with the providers we have to establish connection with a WBEM server. 1 $ lmishell 2 > conn = connect("", "", "")

You can run any Python code in LMI shell. Therefore, to test whether the connection was successful or not we can use one of the following com- mands:

1. The current OpenLMI release at the time of this thesis.

16 3. OPENLMI

1 > isinstance(conn, LMIConnection) 2 True 3 > conn is None 4 False

Now when we have successfully established the connection with CIMOM, we can start querying registered providers. The LMI shell reflects CIM , classes and object into the Python environment and makes those elements accessible via the instance of LMIConnection. In our examples, the CIM namespace is located at conn.root.cimv2 path and all CIM classes registered withing the Object Manager are avail- able under this namespace – e. g. class LMI_Service can be accessed as conn.root.cimv2.LMI_Service. We will shorten the namespace part to ns, for the purpose of our exam- ples. Thus the class will be accessible as ns.LMI_Service. We can achieve this in the shell with a simple assignment: 1 > ns = conn.root.cimv2

There are several useful built-in functions in the shell that simplifies the manipulation with CIM objects and their associations.

Documentation Documentation is a key property of WBEM world, since there are many classes with a lot of constrained properties and methods. This section intro- duces few ways how to obtain useful information. Shell command help() will print description for the LMI shell. If it is run with an object as an argument, it will display verbose information about the Python (not CIM) object (e. g. ns.LMI_Service). Detailed information about the selected CIM class can be displayed by running .doc() command. For example, if we want to see the de- scription of LMI_Service, we will execute ns.LMI_Service.doc().

Acquiring class instances Instances of CIM classes provide information on the managed elements. We have two simple ways of transferring these objects from the WBEM server to client. Those are the following static methods that are present in each class:

17 3. OPENLMI

.instances() This method returns an array of all instances of class .

.instance_names() This method is very similar to the first one except it returns smaller objects that contain only key properties of given class. It may be used to reduce data transfer and operation time when you are interested only in a small amount of instances but you need to filter them out first. These methods have an optional parameter of dictionary type that speci- fies conditions that the returned instances have to fulfill. It is used to per- form a simple search in the set of instances. The argument is in the form {’Property’: ’value’, ...}. Sometimes it is desirable to get only one instance, usually when we search for a unique combination of properties. For this purpose the previous methods have also their equivalents that return only one instance and that the first one found. The methods are:

.first_instance() .first_instance_name() Sometimes it is enough to work only with key properties of the object and then the instance name suffice, but it may be simply converted to full in- stance when needed with .to_instance() method.

Finding associations

As described in 2.2.1: CIM Infrastructure Specification, associations repre- sents relationships between objects. There are two ways of working with these associations. We can either ask “What objects are associated with this instance?” or “Which associations is this object part of?”. Each instance provides methods that allow the operator to ask precisely those questions. These methods are:

.associators() This method returns all objects that are associated with the given object (i. e. it returns end-points of an association).

.references() This method returns all associations that contains reference to the object (i. e. it returns instances of association classes).

18 3. OPENLMI

Similar to instances there are equivalent methods that return only the first found element: first_associator() and first_reference(). These methods may take several parameters. One of these parameters is ResultClass which specifies which object types shall be looked up. More arguments can be found in OpenLMI documentation.

Managing system services

System services are represented as instances of LMI_Service class. This class provides basic information about the service and methods to change the state of the service – i. e. start, stop, enable, disable, etc. At first we will list names of all services that are currently running on the system. The state of the service is accessible through Status property and the value that symbolizes a correctly running service is OK. 1 > for service in ns.LMI_Service.instances(): 2 ... if service.Status == "OK": 3 ... print service.Name 4 ... 5 -logind.service 6 autofs.service 7 systemd-vconsole-setup.service 8 systemd-random-seed.service 9 lvm2-lvmetad.service 10 abrtd.service 11 ...

We can also left filtering of the instances on OpenLMI by providing a dic- tionary argument to instances() or first_instance() method. 1 > filter = {’Status’: ’OK’} 2 > for service in ns.LMI_Service.instances(filter): 3 ... print service.Name 4 ... 5 systemd-logind.service 6 autofs.service 7 systemd-vconsole-setup.service 8 systemd-random-seed.service 9 lvm2-lvmetad.service 10 abrtd.service 11 ... 12 > print ns.LMI_Service.first_instance(filter).Name 13 systemd-logind.service

19 3. OPENLMI

Now we will try to restart all services that are in a wrong state. 1 > filter = {’Status’: ’Error’} 2 > for service in ns.LMI_Service.instances(filter): 3 ... print "Restarting service %s" % service.Name 4 ... service.RestartService() 5 ...

The following example will enable firewalld service on system startup. 1 > filter = {’Name’: ’firewalld.service’} 2 > service = ns.LMI_Service.first_instance(filter) 3 > service.TurnServiceOn()

Managing accounts

Users on the system are represented by LMI_Account class and groups are instances of LMI_Group. Every user and group is associated with an instance of LMI_Identity which serves as a container for both users and groups. The purpose of this class is to have all system identities contained in one place. The next code will list all users that are present on the system and whose password is about to expire within the next two days. 1 > for user in ns.LMI_Account.instances(): 2 ... if user.PasswordExpirationWarning is not None \ 3 ... and user.PasswordExpirationWarning <= 2: 4 ... print user.Name 5 ... 6 pbrezina

The following example will print all groups that user pbrezina is a member of. At first, we need to acquire instance of this user’s account. Then we have to find the identity the user is associated with. Next we use this identity to find all associated groups. We use first_associator() and associators() methods to find de- sired objects that are associated with our user and identity respectively. The attribute ResultClass specifies the type of which the end point of our as- sociation should be. 1 > filter = {’Name’: ’pbrezina’} 2 > acc = ns.LMI_Account.first_instance(filter) 3 > ident = acc.first_associator(ResultClass=’LMI_Identity’) 4 > for group in ident.associators(ResultClass=’LMI_Group’): 5 ... print group.Name

20 3. OPENLMI

6 ... 7 vmusers 8 pbrezina

3.3 LMI Scripts

The CIM providers implement a very low level reflection of managed el- ements and even though OpenLMI shell does its best, learning to use the providers directly through the shell takes a non-trivial amount of time (es- pecially if one is not even familiar with the Python language) and achieving one simple goal usually requires to use several commands from looking up the instances and their association to invoking multiple methods. The OpenLMI project has a support for so called OpenLMI scripts which are written in Python and are executed through lmi command from a com- mand line. These scripts have the full power that is available in the shell and they are supposed to help an administrator to achieve the most common tasks with only one command. OpenLMI team develops and maintains a set of scripts for the existing providers. For example managing services or accounts remotely through OpenLMI is as simple as if one is connected to the host through ssh. The following section introduces few examples of this feature.

3.3.1 Examples The first example shows how to print available commands and their usage. There is one universal command help for this purpose. 1 $ lmi help 2 Commands: 3 hwinfo - Display hardware information. 4 power - System power state management. 5 service - System service management. 6 user - POSIX user information and management. 7 8 For more informations about particular command type: 9 help 10 11 $ lmi help service 12 System service management. 13

21 3. OPENLMI

14 Usage: 15 lmi service list [(--enabled | --disabled)] 16 ...

The next listing contains an example of how to list enabled services and their state and how to obtain information about a user. 1 $ lmi -h --user service list --enabled 2 password: 3 Name Status 4 abrtd Running 5 acpid Running 6 auditd Running 7 autofs Running 8 ntpd Stopped - OK 9 ... 10 11 $ lmi -h --user user show pbrezina 12 password: 13 Name UID Home Login shell Password last change 14 pbrezina 529 /home/pbrezina /bin/bash 2013/10/10

Instead of providing only one host to connect to, we can provide a whole set of hosts and execute the same command on each host at once. The following example demonstrates this ability by rebooting all machines listed in file. 1 $ cat hosts 2 host1.example.com 3 host2.example.com 4 ... 5 hostN.example.com 6 7 $ lmi --hosts-file hosts --user --same-credentials \ 8 > power reboot 9 password:

Parameter --same-credentials will ensure that the password provided at the first prompt will be used to authenticate on every host from the file, instead of asking for each host separately.

22 4 System Security Services Daemon

System Security Services Daemon (SSSD)1 is a set of background processes responsible for providing and caching identity2 and policy3 objects from a central directory server. Its main goal is to cache this information so it re- mains available in an offline mode (when the directory server is not acces- sible) but still keeps serving up to date data when possible. Since communi- cation with the remote directory server is slow in general, there is always a compromise between data accuracy and a response speed. SSSD puts stress on a response speed for publicly accessible data, but tries to be as much accurate as possible with information that brings up potentional security-sensitive decisions. For example, identity information such as user names and group membership are always returned from cache, unless the records are expired. On the other hand, user authentication is always performed directly against the directory server (or Kerberos) as long as it is reachable. Also data remain in the cache until SSSD is positive that it was removed from database, thus the scenario when a user is unable to login into his or her laptop because it was offline for a long time and cached data has expired simply can not happen. Besides many more features, this caching mechanism is one of the biggest advantage over nslcd4.

4.1 Main features

SSSD is an open source project with a very active upstream development and community. Since it has already mastered fundamental identity tasks, the current focus is mainly on the field of Active Directory integration – or in other words, using UNIX-based systems as clients in the Microsoft Windows domain. SSSD has many mature features, here is a list of the most important ones: • An open source project with an active upstream development and community

1. SSSD upstream: https://fedorahosted.org/sssd 2. User and groups, services, automounter maps. . . 3. Sudo rules, SSH host keys, . . . 4. De facto standard daemon that caches NSS-LDAP results, which is currently being replaced by SSSD on many Linux distributions.

23 4. SYSTEM SECURITY SERVICES DAEMON

• More predictable caching mechanism than nslcd • In addition to identity information it, also manages services, autofs maps, sudo rules, SSH host keys • Integration with Kerberos – automatic ticket renewal, seemingless ticket request during transition to online mode, . . . • Integration with FreeIPA – IPA sites, host based access control, cross- domain trusts, . . . • Integration with Active Directory – AD sites, trusts, SID to POSIX ID mapping, evaluation of token groups, . . . • Dynamic DNS updates

4.2 Architecture

SSSD consists of multiple processes running on the system level and several client libraries. The processes are: monitor, one or more data providers and one or more responders. Graphical representation of all those parts can be seen in Figure 4.1.

Monitor Monitor can be considered as some sort of SSSD manager. It is responsible for the life cycle of all the other processes – it starts them, signals them, kills them and also reboots them in case of an error.

Data providers The task of a data provider (often also called a back-end) is to fetch data from the directory server, store them in cache and keep them up to date. Depending on the object type, records may be downloaded either per re- quest triggered by responder or some other outer event or it can be done periodically in the background. There is one data provider running for each domain. Domain is a logical unit, a container for identities and other objects that usually belong to one organizational unit – for example a company or a uni- versity. The domain can be topologically associated with another domain

24 4. SYSTEM SECURITY SERVICES DAEMON called subdomain, which is used typically to increase granularity of the or- ganizational unit like dividing a company-wide domain into subdomains, one per each company’s branch.

Responders

Responders represent supported services like NSS1user and group maps, sudo policy, PAM authentication, etc. Each service has its own responder. A responder listens for a client’s request and when the request comes, it searches the cache and reports requested records back to the client. A notable fact is that responders never perform any kind of communi- cation with a remote service. If they need to look up an object that is not yet present in the cache or the cache content is outdated and needs refresh- ing the responder only contacts a data provider responsible for the desired object and populates the cache with updated information.

Client libraries

Finally, the client libraries are light-weight libraries that implement a plug- gable interface of target application. Its only goal is to be a middle-man between the application and SSSD responder, i. e. it packs a request into a protocol implemented by the selected responder and then unpacks the reply and return the response to the caller.

Inter-process communication

Different parts of SSSD use different inter-process communication methods. Monitor communicates with other processes either via signals or it uses D- Bus for more sophisticated messages. Communication between responders and data providers is performed through D-Bus protocol only. On the other hand, communication of client libraries and responders is done via sockets to keep client libraries as light-weight as possible.

1. Name Service Switch, a mechanism that allows to specify different data sources for standard system services.

25 4. SYSTEM SECURITY SERVICES DAEMON

Monitor LDAP

Id Auth Chpass Access

Sudo Autofs Subdom Host Cache

Data Provider

nss pam sudo autofs ssh pac

Responders

Fast in-memory cache

client library

NSS, PAM, . . .

Figure 4.1: Architecture of SSSD

4.3 Cache management

As it was already said, the cache is populated by data providers and con- sumed by responders. This is due to asynchronous nature of SSSD – one process can still serve data to other clients while simultaneously the other process stores a new record or updates an existing records.

26 4. SYSTEM SECURITY SERVICES DAEMON

SSSD has implemented several caching techniques that aim to improve the ratio between data consistency and response speed. Since every object type requires a little bit individual approach, not all mechanisms are always used. This section will introduce all methods from the basic expiration time and negative cache through mid-point refresh and all the way to sophisticated out of band and background periodic updates.

4.3.1 Record expiration Record expiration is the most basic approach to the cache management. Simply put, each entry in the cache has associated a timestamp after which the entry is marked as expired – but not invalid. When a client requests an expired object, the further actions depend on immediate accessibility of the directory server. If SSSD is in the online mode – it can connect to the server – it will first update the object and then return it. However, if the server is unreachable, SSSD will simply return what is contained within the cache. Expired records are only deleted from the cache if SSSD will not find them on the directory server. Thus as long as SSSD is in the offline mode, they will remain accessible and usable.

4.3.2 Negative cache Negative cache is a special in-memory cache for negative results. If the re- quested record is not found, it is stored in the negative cache for a short time span, making all subsequent requests that hit this period much faster since they immediately return a negative result to the client. Some special users and groups are stored in this cache permanently for the whole SSSD life time. This is usually used to filter out local users and groups which are not handled by SSSD. For example the root account is present in the negative cache by default. Therefore any request for informa- tion about root quickly shortcuts to “entry not found” result, making the caller try the next NSS passwd source.

4.3.3 Mid-point refresh Mid-point refresh is an out of band refresh in the middle of the expiration period. If a request is raised before the record is expired but after a config- ured percent of its expiration time is reached, the cached object is returned

27 4. SYSTEM SECURITY SERVICES DAEMON immediately. However, at the same time it is also being refreshed at the background. This mechanism guarantees a cache-hit for objects that are being fre- quently requested, making the queries fast, without contacting any remote server.

4.3.4 Periodic updates Periodic updates are events triggered periodically on the background by a data provider. They purpose is to update a larger set of records at once or to download all new records that are not yet contained within the cache. These updates usually use entryUSN1attribute or the last modification timestamp of an entry to detect those objects that were modified or newly added on the server since the last update was performed. Currently the following periodic updates are implemented: enumeration, refresh of records that are about to expire and refresh of sudo rules. The last one is described in its own section (4.3.6: Caching of sudo rules).

Enumeration Enumeration is a special task that simply stores and keeps up to date all records of standard NSS maps like users, groups and services. It is used to speed up those commands that enumerate over all or potentially many objects at once – for example listing /home directory or running getent passwd command. If all users had to be yet downloaded from the LDAP server, it could take a very long time to be finished, depending on the size of the environment. This task will pre-fetch them, making those commands much faster – from several minutes (or even tens of minutes) to a few sec- onds. This, however, comes with a price. Periodic updates of thousands of users and groups and they membership evaluation trigger significant amount of network traffic and processor time on both server and client side. Thus enumeration is disabled in SSSD by default and administrators are in gen- eral discouraged from using it unless really necessary.

1. A special attribute supported by modern directory servers. It contains a unique number that represents modification sequence of records stored on the server. Id est record with lower entryUSN value is older than record with higher value.

28 4. SYSTEM SECURITY SERVICES DAEMON

Nearly expired records This is a very specific periodic update. Its intention is to keep all records in the cache up to date in such a way that these records never expire. It takes all records that are about to expire within the next period and re-downloads them. At the time of this thesis, this refresh type is only implemented for net- groups. Its purpose is to reduce the user login time in large enterprise envi- ronments with thousands of netgroups organised in a complex nested topol- ogy. Without this update, a user signing in may trigger a refresh of all these expired netgroups which may take several minutes. That is unacceptable, enabling this update type reduces the login time back to seconds.

4.3.5 Fast in-memory cache In addition to the standard SSSD cache, users and groups also use a small in-memory cache that is accessible directly by client libraries. This cache may be understood as L1-L3 cache memories used in modern processors. If a client library finds requested object in the in-memory cache, it re- turns the record directly without communicating with the proper responder. Records stored in this cache have a relatively short lifetime – only few min- utes – after that the records are invalid and need to be fetched again from the responder. The purpose of this cache is to make listing commands as fast as pos- sible, since it often queries same user or group over and over again thus cutting down the communication between the client library and responder to necessary minimum is a nice benefit.

4.3.6 Caching of sudo rules Sudo rules are very specific objects from the point of cache management. They create a potential security risk since you do not want to allow a user to use sudo unless he is really supposed to. However, at the same time it is not possible to go directly to a server every time when sudo is used, as it is done with user authentication, since the nature of sudo is that there are usually several successive sudo commands in a short time thus it is simply not acceptable to wait several seconds at each command – a cache has to be used.

29 4. SYSTEM SECURITY SERVICES DAEMON

This makes caching of sudo rules quite a challenge because they are sup- posed to be as much up to date as possible but also keeping good respon- siveness of a sudo command. For this purpose, a combination of periodic and event based updates was designed. These updates are called full refresh, smart refresh, rules refresh and out of band full refresh of sudo rules. Each of them has different purpose and their explanation follows.

Full refresh

Full refresh is a periodic task and does exactly what its name suggest – it downloads a complete image of sudo rules stored on the server and replaces everything that is contained withing the cache with new content. This refresh is used mainly to detect rules that were removed from the server and make sure that those rules are also deleted from the cache. Possible disadvantage is that the full refresh may produce a non-trivial network traffic, depanding on the size of the environment, thus this refresh is supposed to have a long period – by default 6 hours is used.

Smart refresh

Smart refresh is another periodic update. It is responsible for keeping cur- rent rules stored in the cache up to date and expanding the cache with newly added rules. It uses the entryUSN attribute or the last modification times- tamp if the first one is not present to detect those modified or new rules. Unlike full refresh, smart refresh never deletes any rules from the cache. And since it checks only for a difference it usually creates only a negligible network usage so it is possible to run this refresh type frequently.

Rules refresh

This type corresponds to the basic record expiration. When a user wants to perform a sudo command, sudo responder retrieves all rules that can be possibly applied to this user and issues an update request for all expired rules from this set. Purpose of this refresh is to ensure that SSSD does not allow any unauthorized access (i. e. when a rule was removed from the server).

30 4. SYSTEM SECURITY SERVICES DAEMON

Out of band full refresh Sudo rules are usually very stable, they are rarely modified and rarely deleted. Thus when SSSD detects that one rule has been deleted, it takes it as a sign that more changes could have been done on the server. Therefore when the rules refresh ends up with removing a rule from the cache an out of band full refresh is triggered ensuring the cache consistency.

Summary of sudo refresh types All sudo refresh methods are usually used altogether to provide the best pos- sible experience when running sudo with SSSD as its data source. However, it is important for administrators to understand how they work separately so they can configure the daemon appropriately for needs of their environment. The Table 4.1 compares the most important features of those refresh types.

When it is triggered (by default) Full refresh every six hours or when a rule is deleted from the cache Smart refresh every fifteen minutes Rules refresh when user runs sudo, rules expires after ninety minutes

What is its purpose Full refresh to keep the cache consistent Smart refresh store new a update modified rules Rules refresh do not grant user more privilege

What operations does it perform Full refresh insert, delete Smart refresh insert, modify Rules refresh modify, delete

Table 4.1: Comparison of sudo rules refresh methods

4.4 Data Providers

Main purpose of a data provider is to populate the cache with the required data and keep those information as much up to date as it is possible. Another

31 4. SYSTEM SECURITY SERVICES DAEMON

and not any less important task is to perform user authentication directly against the remote server. It is the most privileged process in SSSD since it is the only one that is permitted to write data into the cache and it is also the only part of the daemon that is actually allowed to communicate with remote resources like Active Directory, IPA or a pure directory server, Kerberos server, etc. Data provider internally consists from several modules. Each module is responsible for different task. For example, the identity module manages user accounts and groups, the authentication module performs authentica- tion, the access module checks if a user have enough permissions to sign into a local machine, the sudo module caches sudo rules, etc. Every module can use a different data source, or back-end in SSSD’s terminology. The back-end usually specifies a type of directory server used: either a classical LDAP server, IPA or Active Directory. However, some modules also allow a special back-ends, especially those that deal with the user authorization. For example the authentication module can be config- ured either to perform bind against the directory server or to acquire Ker- beros ticket. Access provider can use the advanced LDAP based access con- trol list or simple user and group white list or black list.

4.5 Responders

The key task of responder processes is to satisfy all requests from clients with corresponding information stored within the cache. Compared to data providers where each process represents one domain and maintains data for all of its supported services, responders works in exactly opposite direction. One responder exists for every enabled SSSD service (NSS, PAM, sudo, etc.), that reads the service-related data from multiple domains. The multi-domain search works as a first match method. Responder iter- ates through domains and the first domain that contains the requested object is used unless a fully qualified object name is provided (i. e. both object name and domain name) – in that case only the given domain is searched. Listing 4.1 shows a pseudocode for multi-domain search of user by name. 1 responder receives a request containing username 2 for each domain 3 user := lookup user by username in domain; 4 if user is not found or is expired 5 let data provider of this domain look it up;

32 4. SYSTEM SECURITY SERVICES DAEMON

6 user := lookup user by username in domain; 7 if user is not found 8 continue; 9 fi 10 fi 11 12 return user; 13 end for Listing 4.1: Multi-domain lookup (get user by name)

It is worth to note that the responder has the cache opened only in read-only mode and it never contacts any remote server. If it finds out that some record should be refreshed or that it does not have all information that is required to satisfy the client’s request it triggers an update process in the data provider of the selected domain. When the update is finished it reads the cache again for new data.

4.6 Client applications and libraries

Client applications are third party applications, consumers of SSSD man- aged data. They usually provide a pluggable interface that is used to extend their functionality or to choose different data source. SSSD implements this interface in a client library that is then dynamically loaded by target pro- grams. The library is supposed to be as light-weight as possible to minimize necessary overhead, therefore it tries to be very small and does not use any additional dependencies unless they are really required. The goal of such a library is to be a middle-man between the SSSD re- sponder and the consumer. Some of the client libraries (like libsss_nss) implement an additional level of caching, but the main purpose is only to communicate with the proper responder to obtain requested data and trans- fer this information in a format that is understood by the destined applica- tion. When compared to communication inside SSSD where the D-Bus pro- tocol is used to transfer commands and data, to speed thing up the commu- nication between the client library and responder is performed via a socket, using a wired protocol appropriately selected for the type of transferred data.

33 5 Implementation of OpenLMI SSSD provider

The goal of this thesis is to implement an SSSD provider for the OpenLMI project. The provider is supposed to export an interface to configure the most fundamental parts of the SSSD daemon and to retrieve basic information about managed domains. The required features of the provider are:

• to enable and disable domains and services

• changing debug level of SSSD components

• to provide basic information about managed domains

This chapter will first describe the designed CIM schema for the SSSD, which specifies the provider interface. Then it will briefly introduce sev- eral considered but abandoned solutions and finally it will describe the final implementation design in detail.

5.1 CIM Schema for OpenLMI SSSD provider

The first step to creation of a new OpenLMI (or CIM in general) provider is to create a CIM schema – a conceptual model of the managed element. The model is described in Managed Object Format language (see section 2.2.3: Managed Object Format for details).

5.1.1 CIM concepts Even though the MOF is an object oriented language, it is not recommended to use the same concepts and techniques to design classes that represent the managed objects as we are used to from object oriented programming languages. In programming languages, we usually hide the complexity of an object in private properties and methods and then we export a public interface that provides a higher level model for this object so it is simple to use. It is not very common to provide a public access to properties, instead the interface usually includes several getter and setter methods to retrieve and modify content of given property. On the contrary, properties of CIM objects are all public and they are usually accessed directly without the use of any additional getter or setter

34 5. IMPLEMENTATION OF OPENLMISSSD PROVIDER

method. The created model is supposed to be a very low level and it should reflect the managed elements and their relationships as accurately as possi- ble. The model should not provide any methods just to simplify common tasks that are not very straightforward in WBEM. It is something I have struggled with for a long time, since this makes it impossible to use this technology without any knowledge and it is not simple to learn the basics. In the first iteration I tried to create methods that would return all instances of services and domains associated with the SSSD, however this was denied by the OpenLMI upstream since that is what association classes are for (see 3.2.1: Finding associations).

5.1.2 First revision The following definition is a small part of my very first iteration of the SSSD CIM schema, which wrongly follows my experience from programming languages. It shows the difference between CIM concepts and OOP. 1 class LMI_SSSD 2 { 3 [Static] 4 uint32 GetServices([Out] LMI_SSSD_Service REF services[]); 5 6 [Static] 7 uint32 GetBackends([Out] LMI_SSSD_Backend REF backends[]); 8 }; Listing 5.1: First model that breaks the CIM conventions

There are several issues with this model. At first, every CIM class is sup- posed to inherit from one of the existing classes – either the most generic CIM_ManagedElement or any other more concrete class that fits our needs. This looks like a reasonable requirement, however these classes define a lot of additional properties and methods that our class inherits, but we most certainly do not need all of them. It is an unfortunate, but common practice that the provider for the new class does not implement most of the inherited elements. The second issue is that the class contains methods that should be ei- ther completely omitted1or if some relationship exist between SSSD and

1. Since we can do the same by fetching all instances of LMI_SSSD_Service and LMI_- SSSD_Backend classes. See 3.2.1: Acquiring class instances 35 5. IMPLEMENTATION OF OPENLMISSSD PROVIDER

services/back-ends it is supposed to be implemented as an association and accessed through built in .associators() or .references() methods. The last issue is just a naming convention triviality. Names of all man- aged services should contain Service suffix, therefore the proper name for our daemon is LMI_SSSDService. The following definition is a correction of the previous model that fol- lows the CIM concepts and it is taken from the final version of the SSSD CIM schema.

1 class LMI_SSSDService : CIM_Service 2 { 3 4 }; 5 6 [Abstract, Description("Base class for SSSD’s components.")] 7 class LMI_SSSDComponent : CIM_ManagedElement 8 { 9 /* common properties and methods */ 10 }; 11 12 /* The SSSDService is taken so we had to choose an 13 * equivalent word from SSSD terminology. */ 14 class LMI_SSSDResponder : LMI_SSSDComponent 15 { 16 /* responder specific properties and methods */ 17 }; 18 19 class LMI_SSSDBackend : LMI_SSSDComponent 20 { 21 /* back-end specific properties and methods */ 22 }; 23 24 [Association] 25 class LMI_SSSDAvailableResponders 26 { 27 [Key, Min(1), Max(1)] 28 LMI_SSSDService REF SSSD; 29 30 [Key] 31 LMI_SSSDResponder REF Responder; 32 }; 33 34 [Association] 35 class LMI_SSSDAvailableBackends

36 5. IMPLEMENTATION OF OPENLMISSSD PROVIDER

36 { 37 [Key, Min(1), Max(1)] 38 LMI_SSSDService REF SSSD; 39 40 [Key] 41 LMI_SSSDBackend REF Backend; 42 };

Listing 5.2: Corrected model

5.1.3 Final schema

This section will present an UML diagram of the final version of the SSSD CIM schema and describe its important components. This version was ac- cepted by OpenLMI developers. The full definition in MOF language can be found in Appendix A: SSSD CIM schema: MOF.

UML Diagram

The UML diagram describes classes and their relationships contained within the CIM schema. It does not contain properties and methods. Inheritance is symbolized by the solid red line with arrow and the association between two classes is marked with the solid red line that connects those classes and also with the red dashed line that connects this relation with proper association class.

37 5. IMPLEMENTATION OF OPENLMISSSD PROVIDER

CIM_System CIM_HostedDependency

CIM_ComputerSystem CIM_EnabledLogicalElement CIM_HostedService

CIM_Service LMI_HostedSSSDService

LMI_SSSDService

CIM_ManagedElement LMI_SSSDAvailableComponent

LMI_SSSDAvailableDomain LMI_SSSDComponent LMI_SSSDMonitor

LMI_SSSDResponder LMI_SSSDBackend

LMI_SSSDBackendDomain

LMI_SSSDDomain LMI_SSSDProvider

LMI_SSSDBackendProvider

LMI_SSSDDomainSubdomain

Figure 5.1: UML diagram for SSSD CIM schema 38 5. IMPLEMENTATION OF OPENLMISSSD PROVIDER

New classes

LMI_SSSDService This class represents the SSSD service, it inherits properties and meth- ods from CIM_Service. It contains information about the service such as name, state name of the system it is running on, etc. LMI_SSSDComponent LMI_SSSDMonitor LMI_SSSDResponder LMI_SSSDBackend These classes represent one of the SSSD component – currently imple- mented as separate process. LMI_SSSDComponent is the base class for the monitor, responder and back-end classes and it provides information about the component such as its type and debug level. It also defines methods for managing these components: changing debug level either permanently or only until the SSSD service is restarted and enable or disable the component. LMI_SSSDProvider This class describes a module that is used within a back-end for data managements. It contains two string properties: data type (id, auth, sudo, access, autofs, . . . ) and the module that is used to manage this kind of data (ldap, ipa, ad, . . . ). LMI_SSSDDomain This class provides information about an SSSD domain or an auto- discovered subdomain. It contains read-only properties that describe the domain name, its primary and backup servers, name of the parent do- main (in case the domain is a subdomain), format of fully qualified user name1(or object name in general), minimal and maximal value allowed for user and group identification number, etc.

New associations

LMI_SSSDAvailableComponent This association class reflects the relationship between SSSD and its components. LMI_SSSDBackendDomain

1. For example, whether a user name is printed as name@domain or DOMAIN\name.

39 5. IMPLEMENTATION OF OPENLMISSSD PROVIDER

Each back-end maintains one top level SSSD domain and its subdo- mains. This class models a one to one relation between a back-end com- ponent and the top level SSSD domain managed by this back-end. LMI_SSSDBackendProvider This class represents configured provider modules in given back-ends. LMI_SSSDAvailableDomain All domains and subdomains are associated with the SSSD service through this relation. LMI_SSSDDomainSubdomain This association is between two LMI_SSSDDomain objects and it models a domains hierarchy and topology.

5.1.4 Designing classes for SSSD components Originally, I wanted to keep the class names closer to the terminology that is common amongst SSSD users, i. e. services and domains instead of re- sponders and back-ends which are very developer-centric words. However, I saw several issues with these names:

• the name LMI_SSSDService is already used to represent the whole SSSD service,

• the name LMI_SSSDDomain is reserved for domains,

• reponders and back-ends are separate components that are used to manage services and domains thus there is a relation between those words but they are not identical,

• one back-end maintains one domain and all of its subdomains, how- ever process-related properties are set per-backend not per domain and subdomain,

• services and domains are logical components which should not deal with process-related properties like debug level.

The name “components” was chosen so it does not imply any particular implementation of the component.

40 5. IMPLEMENTATION OF OPENLMISSSD PROVIDER

The properties of the base class LMI_SSSDComponents (see the following listing) are read only and configuration changes are made through several methods, even though this design does not strictly follow the CIM concepts. There are two methods for changing the debug level: one that allows you to set the level permanently and one that changes the level only until the SSSD is restarted and it is switched back to the original value after the restart. Since those are two different use cases I wanted to differentiate them by method names instead of providing only one method (for temporary change) and allow the permanent change through property set. Switching the component between enabled and disabled state is also done through method calls even though it could be simply performed by set- ting the boolean property IsEnabled to the desired value. However, SSSD does not support this kind of change on the fly. I wanted to highlight the fact that the change is not visible until the service is restarted by using methods.

1 [Version("0.1.0"), Provider("cmpi:cmpiLMI_SSSD"), 2 Abstract, Description("Base class for SSSD’s components.")] 3 class LMI_SSSDComponent : CIM_ManagedElement 4 { 5 [Key, Description("Name of the SSSD component.")] 6 string Name; 7 8 [Description("Type of the SSSD component."), 9 ValueMap { "0", "1", "2" }, 10 Values { "Monitor", "Responder", "Backend" }] 11 uint16 Type; 12 13 [BitValues{"Reserved", 14 "Reserved", 15 "Reserved", 16 "Reserved", 17 "Fatal failures", 18 "Critical failures", 19 "Operation failures", 20 "Minor failures", 21 "Configuration settings", 22 "Function data", 23 "Trace function", 24 "Reserved", 25 "Trace libraries", 26 "Trace internal", 27 "Trace all", 28 "Reserved"},

41 5. IMPLEMENTATION OF OPENLMISSSD PROVIDER

29 Description("Debug level used within this component.")] 30 uint16 DebugLevel; 31 32 [Description("True if this process is enabled at SSSD " 33 "startup and false otherwise.")] 34 boolean IsEnabled; 35 36 [Description("Permanently change debug level of " 37 "this component."), 38 ValueMap { "0", "1", "2", "3" }, 39 Values { "Success", "Failed", "Invalid arguments", 40 "I/O error" }] 41 uint32 SetDebugLevelPermanently([In] uint16 debug_level); 42 43 [Description("Change debug level of this component " 44 "but switch it back to the original " 45 "value when SSSD is restarted."), 46 ValueMap { "0", "1", "2", "3" }, 47 Values { "Success", "Failed", "Invalid arguments", 48 "I/O error" }] 49 uint32 SetDebugLevelTemporarily([In] uint16 debug_level); 50 51 [Description("Enable this component. " 52 "SSSD has to be restarted in order " 53 "this change to take any effect."), 54 ValueMap { "0", "1", "3" }, 55 Values { "Success", "Failed", "I/O error" }] 56 uint32 Enable(); 57 58 [Description("Disable this component. " 59 "SSSD has to be restarted in order " 60 "this change to take any effect."), 61 ValueMap { "0", "1", "3" }, 62 Values { "Success", "Failed", "I/O error" }] 63 uint32 Disable(); 64 }; Listing 5.3: Base class for SSSD components

5.1.5 Designing classes for SSSD domains and subdomains I wanted to create separate classes for domains and subdomains at first. However, from the SSSD point of view the only real difference between those two units is that domains are created manually in the SSSD configu-

42 5. IMPLEMENTATION OF OPENLMISSSD PROVIDER

ration file but subdomains are auto-discovered through the Active Directory or FreeIPA mechanisms. Hence the term subdomain refers only to the fact that it is not present in a configuration file and that it inherits few properties from its parent domain, besides that there is no other important difference from the system side. Therefore I squashed both domains and subdomains into one class called LMI_SSSDDomain so they are treated in the same way. The class provides properties that will distinguish them if needed and that allows to build a domain topology in LMI_SSSDDomainSubdomain association. 1 [Version("0.1.0"), Provider("cmpi:cmpiLMI_SSSD"), 2 Description("SSSD domain.")] 3 class LMI_SSSDDomain : CIM_ManagedElement 4 { 5 [Key, Description("Name of the domain.")] 6 string Name; 7 8 /* ... */ 9 10 [Description("Name of the parent domain. It is not set " 11 "if this domain is on top of the domain " 12 "hierarchy.")] 13 string ParentDomain; 14 15 [Description("True if this is an autodiscovered " 16 "subdomain.")] 17 boolean IsSubdomain; 18 19 /* ... */ 20 }; 21 22 [Version("0.1.0"), Provider("cmpi:cmpiLMI_SSSD"), 23 Association, Description("All subdomains associated " 24 "with given parent domain.")] 25 class LMI_SSSDDomainSubdomain 26 { 27 [Key, Max(1)] 28 LMI_SSSDDomain REF ParentDomain; 29 30 [Key] 31 LMI_SSSDDomain REF Subdomain; 32 }; Listing 5.4: Class representing SSSD domains

43 5. IMPLEMENTATION OF OPENLMISSSD PROVIDER

The association can build relationships between domain and subdomain as well as between two subdomains. The following tree is an example of a domain hierarchy that can be created by iterating the instances of the assso- ciation class. Domain example.com is a top level domain defined in SSSD configuration file, other domains are auto-discovered subdomains.

example.com

us.example.com

bos.us.example.com ny.us.example.com was.us.example.com

Figure 5.2: Example domain hierarchy

5.2 Considered solutions

The SSSD OpenLMI provider has to be able to modify the SSSD configu- ration file (changing debug level, enabling and disabling components) and it also needs to read data cached in SSSD (information about subdomains). There are several possible ways to achieve this. This sections presents some considered solutions and examines their advantages and disadvantages.

5.2.1 OpenLMI provider is self-sufficient

The SSSD provider for OpenLMI may have a direct access to configura- tion file and SSSD internal database (cache). The database is in ldb format, which is a local LDAP-like database stored in a single file. SSSD does not provide any API to modify their configuration so the provider can either parse it manually or it can use some universal and proved open source library like Augeas to do the work.

44 5. IMPLEMENTATION OF OPENLMISSSD PROVIDER

SSSD configuration file

SSSD OpenLMI provider

SSSD DB

Figure 5.3: Self-sufficient SSSD provider for OpenLMI

Advantages • Simple to implement.

• It is only one independent component, no inter-process communica- tion is performed under the hood.

Disadvantages • The provider uses internal resources of SSSD.

• Every change made to the format of the database or the configuration file may break the provider.

• If the database or configuration format change rapidly (they may be completely replaced by something else), it requires the provider to be rewritten completely.

• The database contains cached data, which may be expired. The provider does not have any tools to invoke refresh of the cached records.

5.2.2 OpenLMI provider and new SSSD responder This approach requires a completely new SSSD responder (see section 4.5), for instance an LMI responder, that would create an access point for the OpenLMI provider. The responder would serve data from the cache and ensure that the returned records are up to date. It may also provide methods to modify the configuration.

45 5. IMPLEMENTATION OF OPENLMISSSD PROVIDER

The communication between the OpenLMI provider and LMI responder would be performed through sockets using a newly crafted wire protocol which is the standard solution for inter-process communication between the SSSD responders and their clients. The communication would be wrapped into a new client library (see section 4.6: Client applications and libraries).

SSSD configuration file socket client library

SSSD OpenLMI LMI responder provider

SSSD DB

Figure 5.4: SSSD provider for OpenLMI with LMI responder

Advantages • OpenLMI provider uses SSSD’s public API to access data and modify the configuration.

• Changes done in the internal SSSD resources does not break the OpenLMI provider as long as the exported API is maintained.

• LMI responder ensures that the return records are up to date.

• SSSD has an internal framework to simplify development of new re- sponders and client libraries.

Disadvantages • New responder, client library and protocol has to be developed.

• Inter-proccess communication between the OpenLMI provider and LMI responder.

• New API to maintain on SSSD side.

• Harder for implementation.

46 5. IMPLEMENTATION OF OPENLMISSSD PROVIDER

5.2.3 OpenLMI provider and SSSD InfoPipe responder Within the time when I was working on my thesis, the SSSD upstream started to develop a new responder called the InfoPipe (often also called the D-Bus responder). This responder is conceptually very different from the others, since its purpose is not to serve selected data to one particular ap- plication but to provide access to miscellaneous areas of the cache through D-Bus interface to any application that wants to use it. I thought this may be a good opportunity to step in and instead of cre- ating a new responder that would be specifically crafted for OpenLMI re- quirements the provider would communicate with this InfoPipe responder.

SSSD configuration file D-Bus client library

SSSD OpenLMI InfoPipe responder provider

SSSD DB

Figure 5.5: SSSD provider for OpenLMI with the InfoPipe responder

Advantages • OpenLMI provider uses SSSD’s public API to access data and modify the configuration.

• Changes done in the internal SSSD resources does not break the OpenLMI provider as long as the exported API is maintained.

• InfoPipe responder ensures that the returned records are up to date.

• InfoPipe responder can be used by many applications.

Disadvantages • Inter-proccess communication between the OpenLMI provider and the InfoPipe responder.

47 5. IMPLEMENTATION OF OPENLMISSSD PROVIDER

• D-Bus is a very complex and hard to use technology through existing C language . • Since the InfoPipe responder is conceptually new, SSSD does not pro- vide any existing framework for its development. • It is a contribution to a component that is under active development, this requires a lot of team work and communication with the upstream since I am not the sole developer. • Hard to be implemented.

Even though the list of disadvantages of this solution contains several im- portant points that make the implementation rather complicated, I think that the advantages are quite nice and fully compensate the negatives. Especially the fact that my contribution will be used by many potential applications and not only the OpenLMI project. For this reason I chose this as the final so- lution for the implementation of the SSSD provider for OpenLMI and it is described in detail in the following sections also with my particular contri- butions to the responder.

5.3 InfoPipe responder

The current SSSD version contains several responders that are used as a data source for standard UNIX services. Those responders serve data for identity information through NSS maps (passwd, group, etc.), user authentication through PAM library, autofs mounts, sudo rules and more. All these services are standardized and have precisely defined what in- formation do they present. If some application needs some more informa- tion that is available in the directory server, it needs to contact the server to retrieve it. However it looses the caching ability of SSSD. The main purpose of the InfoPipe responder is to provide extended infor- mation from the cache through the D-Bus interface. In the future it should also become an ultimate tool that would provide interface to acquire any cached SSSD object and methods for manipulation with SSSD configura- tion. The InfoPipe responder is under active development, in the time of this thesis. I saw an opportunity to use it in the OpenLMI provider thus I stepped in and helped with the development. My effort included:

48 5. IMPLEMENTATION OF OPENLMISSSD PROVIDER

• definition of the D-Bus interface required by the OpenLMI provider (see 5.3.1: D-Bus interface)

• refining other parts of the interface

• unifying naming conventions of methods and properties

• giving advices for design and implementation decisions

• reviewing codes of other developers to ensure its quality

• contributing with a new code and bug fixes

• creating a new public library called libsss_dbus that hides D-Bus complexity under simple to use API (see 5.5: Simple SSSD D-Bus API)

• creating a new internal library libsss_config for configuration changes (see 5.4: Modifying configuration)

5.3.1 D-Bus interface This section presents the D-Bus interface implemented in the InfoPipe re- sponder that was created for the purpose of the OpenLMI provider. The interface loosely follows the SSSD CIM schema (see Appendix A: SSSD CIM schema: MOF for the complete schema).

Object paths An object path unambiguously identifies a D-Bus object. It has to be a unique string across the bus. The convention is to separate each component of the path by slash. /org/freedesktop/sssd/infopipe/Components/monitor /org/freedesktop/sssd/infopipe/Components/Responders/@name /org/freedesktop/sssd/infopipe/Components/Backends/@name These object paths point to SSSD component objects: the monitor, re- sponders and back-ends. Since there may be many responders and back- ends they are each organized under a subpath and distinguished by a name. /org/freedesktop/sssd/infopipe/Domains/@name

49 5. IMPLEMENTATION OF OPENLMISSSD PROVIDER

This path identifies SSSD domain and subdomain objects. The name parameter is the name of the domain.

InfoPipe interface The InfoPipe interface contains methods to retrieve the list of object paths of desired type or to find a path of particular object. Name of this interface is: org.freedesktop.sssd.infopipe and it defines the following methods: array of object paths ListComponents() array of object paths ListResponders() array of object paths ListBackends() These methods return a list of object paths of all components, responders or back-ends respectively. object path FindMonitor() Returns an object path of SSSD monitor. object path FindResponderByName(string name) object path FindBackendByName(string name) Returns the object path of the responder or backend respectively that has the given name. array of object paths ListDomains() Returns the list of object paths of all available domains or subdomains. array of object paths ListSubdomainsByDomain(String name) Returns the list of object paths of all domains that have the given domain name as the parent domain. object path FindDomainByName(String name) Returns the object path that represents the given domain. These methods are used to get identification of an object so we can invoke methods on this object or fetch its properties. The object paths would have to be hard coded without these routines.

Component interface

Interface org.freedesktop.sssd.infopipe.Components defines methods and properties for SSSD components. These methods are called on objects that belongs to /org/freedesktop/sssd/Components path. void Enable() void Disable()

50 5. IMPLEMENTATION OF OPENLMISSSD PROVIDER

Enables or disables the component. void ChangeDebugLevel(uint32 debug_level) Changes the debug level of the component to a new value. string name Name of the SSSD component. uint32 debug_level Current debug level of the component. boolean enabled True if the component is enabled, false otherwise. string type Type of the component. It is an enumeration type that can contain one of the following values: “monitor”, “responder” or “backend”.

Domain interface

Objects implementing org.freedesktop.sssd.infopipe.Domains inter- face has to provide the following properties: string name Name of the domain. string[] primary_servers string[] backup_servers List of primary and backup servers used by the domain. uint32 min_id uint32 max_id Minimum and maximum allowed value for user and identification num- ber. string realm If the domain uses Kerberos for authentication, this property contains the name of the Kerberos realm. string forest If this domain is part of Active Directory forest, this property contains the name of the forest. string login_format string fully_qualified_name_format Name format strings. They define what format is expected for user log in and how the name is presented in fully qualified format.

51 5. IMPLEMENTATION OF OPENLMISSSD PROVIDER

boolean enumerable Whether this domain can be enumerated or not. boolean use_fully_qualified_names True if this domain always requires fully qualified format of object names. boolean subdomain object path parent_domain If this domain is an auto-discovered subdomain the subdomain property is true and parent_domain contains the object path of its parent.

5.4 Modifying configuration

SSSD currently does not provide any public or internal C API to modify its configuration file. Therefore I created a small unit tested internal library libsss_config that implements the set of configuration changes needed by the OpenLMI provider. I used the Augeas to parse, modify and save the configuration file.

5.4.1 Augeas Augeas1 is an open source library that provides a simple API to parse and modify basically all possible types of configuration files. The modification tries to not break the file formatting (spaces, new lines, etc.) and preserves comments. The API is unified for all consumers. These features are achieved by so called lenses. A lens defines a gram- mar for a configuration file. Augeas uses custom grammar language that is based on the ML functional language. The lens is used to transform the configuration file into a tree where nodes represent options and leaves are their values. The library provides API to modify the tree. A reverse transformation is then used to produce a new configuration file. Each node is identified by a path that consists of node names separated by slash. The following listing shows a sample SSSD configuration and its representation in Augeas. 1 [sssd] 2 services = nss, pam

1. http://augeas.net

52 5. IMPLEMENTATION OF OPENLMISSSD PROVIDER

3 domains = LDAP 4 debug_level = 0x0ff0 5 6 [domain/LDAP] 7 debug_level = 0x0ff0 8 id_provider = ldap 9 ldap_uri = _srv_ 10 11 Augeas tree: 12 /files/etc/sssd/sssd.conf 13 /files/etc/sssd/sssd.conf/target[1] = "sssd" 14 /files/etc/sssd/sssd.conf/target[1]/services = "nss, pam" 15 /files/etc/sssd/sssd.conf/target[1]/domains = "LDAP" 16 /files/etc/sssd/sssd.conf/target[1]/debug_level = "0x0ff0" 17 /files/etc/sssd/sssd.conf/target[2] = "domain/LDAP" 18 /files/etc/sssd/sssd.conf/target[2]/debug_level = "0x0ff0" 19 /files/etc/sssd/sssd.conf/target[2]/id_provider = "ldap" 20 /files/etc/sssd/sssd.conf/target[2]/ldap_uri = "_srv_" Listing 5.5: Augeas tree of sssd.conf

5.4.2 Application in SSSD

The libsss_config is used in the InfoPipe responder to implement meth- ods that manipulate with SSSD component settings. This library makes Augeas a new dependency of SSSD and that for both build-time and run- time cases. I made the library optional but enabled by default to allow the latest SSSD to be run even on systems where the Augeas is not present. If the SSSD is built without Augeas then the methods in the InfoPipe provider that uses libsss_config return an error code explaining that the operation is not supported.

5.5 Simple SSSD D-Bus API

The available C D-Bus API provided by libdbus is very complex, low level and difficult. Especially when we start dealing with non basic types (num- bers and strings) such as variants and dictionaries (where iterators has to be used) the number of code lines increases dramatically and makes the code seemingly chaotic. Other available D-Bus bindings such as dbus-glib or its successor GDBus provide a little bit higher level approach however they bring many Gnome libraries as a project dependency and require a developer

53 5. IMPLEMENTATION OF OPENLMISSSD PROVIDER to understand lots of Gnome-related features such as GLib Object System, thus they may not be always a correct choice. Nevertheless, even the higher level approach of these libraries is not something an unskilled programmer wants to deal with. The CMPI interface used by OpenLMI providers is quite difficult on its own and I wanted to keep the provider code as clean and transparent as possible. Therefore I chose to hide the D-Bus complexity in a separate module but instead of doing it just for my purpose I decided to design its API very thoroughly so other possible applications may benefit from it as well. The libsss_dbus is a new SSSD public library to be used by external applications. It is specifically designed to simplify communication with the InfoPipe responder. The library hides most of the D-Bus complexity and caveats under the hood of a simple and ready to use API. The library is by no means a replacement for libdbus or GDBus as it is only designed to be used with the SSSD’s InfoPipe and only for the most common tasks such as retrieving object properties. It is definitely not supposed to provide a general purpose D-Bus API. The main features of this library are:

• easy to establish and close a connection to the InfoPipe bus

• automatic and type safe unpacking of object properties

• one simple call to fetch single property of an object

• one simple call to fetch all object properties

• one simple call to invoke InfoPipe Find* method and retrieve object path from the result

• one simple call to invoke InfoPipe List* method and retrieve the array of object paths from the result

• implements several complex and common tasks as a one liner

• the functionality is thoroughly unit tested

54 5. IMPLEMENTATION OF OPENLMISSSD PROVIDER

5.5.1 Example usage

The following listing contains an example usage of the libsss_dbus library that focuses on retrieving an object property, namely the debug level of the SSSD monitor. At first it opens a connection to the system bus, then it finds the object path for the monitor component. The next step is to fetch all properties of the object (it is also possible to fetch only one property). The properties are stored in sss_dbus_attr opaque structure. The last step is to retrieve the debug level from the attributes. 1 sss_dbus_attr **attrs = NULL; 2 sss_dbus_ctx *ctx = NULL; 3 sss_dbus_error ret; 4 char *path = NULL; 5 uint32_t level; 6 7 /* establish connection to the system bus */ 8 ret = sss_dbus_init(&ctx); 9 if (ret != SSS_DBUS_OK) { 10 /* handle error */ 11 } 12 13 /* find the SSSD monitor */ 14 ret = sss_dbus_invoke_find(ctx, "Monitor", &path, 15 DBUS_TYPE_INVALID); 16 if (ret != SSS_DBUS_OK) { 17 /* handle error: 18 * out of memory, error communication with D-Bus, ... */ 19 } 20 21 /* retrieve all properties of the monitor 22 from the components interface */ 23 ret = sss_dbus_fetch_all_attrs(ctx, path, 24 SSS_DBUS_IFACE_COMPONENTS, &attrs); 25 if (ret != SSS_DBUS_OK) { 26 /* handle error: 27 * out of memory, error communication with D-Bus, ... */ 28 } 29 30 ret = sss_dbus_find_attr_as_uint32(attrs, "debug_level", 31 &level); 32 if (ret != SSS_DBUS_OK) { 33 /* handle error: type error or attribute not found */ 34 }

55 5. IMPLEMENTATION OF OPENLMISSSD PROVIDER

35 36 /* free resources */ 37 sss_dbus_free_string(ctx, &path); 38 sss_dbus_free_attrs(ctx, &attrs); 39 sss_dbus_free(&ctx); 40 41 printf("The monitor current debug level is %#.4x\n", 42 debug_level); Listing 5.6: Print debug level of the SSSD monitor

5.6 SSSD provider for OpenLMI

The provider implements the SSSD CIM schema. It uses libsss_dbus for communication with the InfoPipe responder to fetch the required informa- tion about domains and components and to call methods for modification of the SSSD configuration. This approach made the provider rather minimal- istic, clear and transparent. It is just a middleman between the operator and SSSD. The implementation of the provider consists of four steps: 1. to design CIM schema and describe it in MOF language 2. to generate skeleton of CMPI interface 3. implement instance enumeration 4. implement methods

I used the KonkretCMPI1 tool to generate the C source files skeletons for CMPI interface from MOF. This tool does not generate a pure CMPI code but transforms it to a concrete domain that simplifies the work with CMPI objects. The API generates functions to pack and unpack a C structure that rep- resents given class from the schema into and from a CMPI object. It also provides functions for manipulation with CMPI data types. KonkretCMPI also generates stubs for methods defined inside the MOF file. Besides the custom methods it also generates special functions for each class that handle instance enumeration. These routines generates new in- stances and packs them into CMPI return value.

1. http://konkretcmpi.org

56 5. IMPLEMENTATION OF OPENLMISSSD PROVIDER 5.7 SSSD OpenLMI scripts

The OpenLMI provider tries to reflect the SSSD quite accurately and it uses very developer-centric terminology to achieve this. I developed a set of OpenLMI scripts (refer to 3.3: LMI Scripts for more information) that brings the SSSD provider closer to an administrator. I switched the terminology to be equivalent to the one the administrators are used to, i. e. services instead of responders and domains instead of back- ends. It was not possible to make these terms interchangeable in the CIM schema, but it was doable in the scripts interface. The scripts define new commands for lmi utility to manage the SSSD system daemon, its domains and services and to provide some information about them. The functionality is separated into three commands: sssd, sssd-domain and sssd-service and these commands implement all set of features:

• SSSD daemon status and restart (through OpenLMI Service provider)

• changing debug level of selected components (either permanently or only temporarily until the SSSD is restarted)

• listing domains and services

• printing information about domains, subdomains and services

• enable or disable selected domain or service

5.7.1 Command interface The following listing contains the command interface that is presented to the administrator when he uses lmi. 1 # print SSSD service status using LMI_Service provider 2 lmi sssd status 3 4 # restart SSSD service using LMI_Service provider 5 lmi sssd restart 6 7 # change debug level for selected components 8 # (all by default), either permanently (default) or 9 # temporarily until the SSSD is restarted 10 lmi sssd set-debug-level [--until-restart] 11 [--monitor] [--services=svc1,...] [--domains=dom1,...]

57 5. IMPLEMENTATION OF OPENLMISSSD PROVIDER

12 13 # list SSSD domains with basic information 14 # (name, enabled/disabled, id provider, debug level) 15 lmi sssd-domain list [--enabled|--disabled] 16 17 # print all information about the domain 18 lmi sssd-domain show 19 20 # enable selected domain 21 lmi sssd-domain enable 22 23 # disable selected domain 24 lmi sssd-domain disable 25 26 # list SSSD services with basic information 27 # (name, enabled/disabled, id provider, debug level) 28 lmi sssd-service list [--enabled|--disabled] 29 30 # print all information about the service 31 lmi sssd-service show 32 33 # enable selected service 34 lmi sssd-service enable 35 36 # disable selected service 37 lmi sssd-service disable Listing 5.7: SSSD OpenLMI commands

58 6 Conclusion

Web-Based Enterprise Management is a very complex and difficult stan- dard combined from many important pieces. I found the existing documen- tation and articles on this topic quite unsatisfying and my primary source of knowledge was the standard specification. It took me a long time to fully understand all parts of the standard and to realize how they are put together. The OpenLMI project brings WBEM closer to the system administrators by providing simplistic approach to the system management. The project currently supports only a small part of all important Linux services, however I think it already contains enough Linux-specific CIM providers to get the attention. Working on the SSSD provider for OpenLMI was a huge challenge. One of the most challenging task was to develop a new CIM schema. It is probably the most important piece of the thesis since it is a public interface for administrators. It had to be designed in a way that will satisfy different worlds: from the OpenLMI and SSSD developers to the end users. The de- sign had to be done in an extensible way, since the result of this thesis covers only the most fundamental parts of SSSD and it will be further expanded. Developing the provider required many non-existing pieces. Apart from the expected contribution to the OpenLMI project I also contributed to the SSSD. I performed a code review of the whole new InfoPipe responder to ensure its qualities; designed a big amount of its interface and implement the complete functionality for domains and SSSD components. Besides that the upstream also accepted the new public library that I created together with the new internal library for configuration changes. Both libraries are thoroughly unit tested. I also sent a small patch that fixed the grammar for SSSD configuration file in Augeas. All my contribution was accepted in OpenLMI, SSSD and Augeas up- streams. I must admit I was sceptical at first, but now I find the OpenLMI to be a very useful open source project with a great future. And even though the first version of the provider is ready for deployment, the work on the provider is far from over and I am looking forward to further contribution.

59 A SSSD CIM schema: MOF

1 [Version("0.1.0"), Provider("cmpi:cmpiLMI_SSSD"), 2 Description("System Security Services Daemon")] 3 class LMI_SSSDService : CIM_Service 4 { 5 6 }; 7 8 [Version("0.1.0"), Provider("cmpi:cmpiLMI_SSSD"), 9 Abstract, Description("Base class for SSSD’s components.")] 10 class LMI_SSSDComponent : CIM_ManagedElement 11 { 12 [Key, Description("Name of the SSSD component.")] 13 string Name; 14 15 [Description("Type of the SSSD component."), 16 ValueMap { "0", "1", "2" }, 17 Values { "Monitor", "Responder", "Backend" }] 18 uint16 Type; 19 20 [BitValues{"Reserved", 21 "Reserved", 22 "Reserved", 23 "Reserved", 24 "Fatal failures", 25 "Critical failures", 26 "Operation failures", 27 "Minor failures", 28 "Configuration settings", 29 "Function data", 30 "Trace function", 31 "Reserved", 32 "Trace libraries", 33 "Trace internal", 34 "Trace all", 35 "Reserved"}, 36 Description("Debug level used within this component.")] 37 uint16 DebugLevel; 38 39 [Description("True if this process is enabled at SSSD startup and false " 40 "otherwise.")] 41 boolean IsEnabled;

60 A.SSSDCIM SCHEMA:MOF

42 43 [Description("Permanently change debug level of this component."), 44 ValueMap { "0", "1", "2", "3" }, 45 Values { "Success", "Failed", "Invalid arguments", "I/O error" }] 46 uint32 SetDebugLevelPermanently([In] uint16 debug_level) ; 47 48 [Description("Change debug level of this component but switch it back " 49 "to the original value when SSSD is restarted."), 50 ValueMap { "0", "1", "2", "3" }, 51 Values { "Success", "Failed", "Invalid arguments", "I/O error" }] 52 uint32 SetDebugLevelTemporarily([In] uint16 debug_level) ; 53 54 [Description("Enable this component. SSSD has to be restarted in order " 55 "this change to take any effect."), 56 ValueMap { "0", "1", "3" }, 57 Values { "Success", "Failed", "I/O error" }] 58 uint32 Enable(); 59 60 [Description("Disable this component. SSSD has to be restarted in order " 61 "this change to take any effect."), 62 ValueMap { "0", "1", "3" }, 63 Values { "Success", "Failed", "I/O error" }] 64 uint32 Disable(); 65 }; 66 67 [Version("0.1.0"), Provider("cmpi:cmpiLMI_SSSD"), 68 Description("SSSD monitor. An SSSD component that executes the other " 69 "components and makes sure they stay running. This component " 70 "can not be disabled.")] 71 class LMI_SSSDMonitor : LMI_SSSDComponent 72 { 73 74 }; 75

61 A.SSSDCIM SCHEMA:MOF

76 [Version("0.1.0"), Provider("cmpi:cmpiLMI_SSSD"), 77 Description("SSSD responder. An SSSD component that implements one of the " 78 "supported services and provides data to clients.")] 79 class LMI_SSSDResponder : LMI_SSSDComponent 80 { 81 82 }; 83 84 [Version("0.1.0"), Provider("cmpi:cmpiLMI_SSSD"), 85 Description("SSSD backend. An SSSD component that manages data from one " 86 "domain and its subdomains.")] 87 class LMI_SSSDBackend : LMI_SSSDComponent 88 { 89 90 }; 91 92 [Version("0.1.0"), Provider("cmpi:cmpiLMI_SSSD"), 93 Description("Data provider module information.")] 94 class LMI_SSSDProvider : CIM_ManagedElement 95 { 96 [Key, Description("Name of data class handled by the provider.")] 97 string Type; 98 99 [Key, Description("Name of the module that provides the desired data.")] 100 string Module; 101 }; 102 103 [Version("0.1.0"), Provider("cmpi:cmpiLMI_SSSD"), 104 Description("SSSD domain.")] 105 class LMI_SSSDDomain : CIM_ManagedElement 106 { 107 [Key, Description("Name of the domain.")] 108 string Name; 109 110 [Description("List of primary servers for this domain.") ] 111 string PrimaryServers[]; 112 113 [Description("List of backup servers for this domain.")] 114 string BackupServers[];

62 A.SSSDCIM SCHEMA:MOF

115 116 [Description("Main provider for this domain.")] 117 string Provider; 118 119 [Description("The Kerberos realm this domain is configured with.")] 120 string Realm; 121 122 [Description("The domain forest this domain belongs to." )] 123 string Forest; 124 125 [Description("Name of the parent domain. It is not set if this " 126 "domain is on top of the domain hierarchy." )] 127 string ParentDomain; 128 129 [Description("True if this is an autodiscovered subdomain.")] 130 boolean IsSubdomain; 131 132 [Description("Minimum UID and GID value for this domain. ")] 133 uint32 MinId; 134 135 [Description("Maximum UID and GID value for this domain. ")] 136 uint32 MaxId; 137 138 [Description("True if this domain supports enumeration." )] 139 boolean Enumerate; 140 141 [Description("True if objects from this domain can be accessed only via " 142 "fully qualified name.")] 143 boolean UseFullyQualifiedNames; 144 145 [Description("The login format this domain expects.")] 146 string LoginFormat; 147 148 [Description("Format of fully qualified name this domain uses.")] 149 string FullyQualifiedNameFormat;

63 A.SSSDCIM SCHEMA:MOF

150 }; 151 152 [Version("0.1.0"), Provider("cmpi:cmpiLMI_SSSD"), Association, 153 Description("All available SSSD components.")] 154 class LMI_SSSDAvailableComponent 155 { 156 [Key, Min(1), Max(1)] 157 LMI_SSSDService REF SSSD; 158 159 [Key] 160 LMI_SSSDComponent REF Component; 161 }; 162 163 [Version("0.1.0"), Provider("cmpi:cmpiLMI_SSSD"), Association, 164 Description("Data provider modules configured for given backend.")] 165 class LMI_SSSDBackendProvider 166 { 167 [Key, Max(1)] 168 LMI_SSSDBackend REF Backend; 169 170 [Key] 171 LMI_SSSDProvider REF Provider; 172 }; 173 174 [Version("0.1.0"), Provider("cmpi:cmpiLMI_SSSD"), Association, 175 Description("All domains managed by SSSD.")] 176 class LMI_SSSDAvailableDomain 177 { 178 [Key, Min(1), Max(1)] 179 LMI_SSSDService REF SSSD; 180 181 [Key] 182 LMI_SSSDDomain REF Domain; 183 }; 184 185 [Version("0.1.0"), Provider("cmpi:cmpiLMI_SSSD"), Association, 186 Description("All top level domains associated with given backend.")] 187 class LMI_SSSDBackendDomain 188 {

64 A.SSSDCIM SCHEMA:MOF

189 [Key, Max(1)] 190 LMI_SSSDBackend REF Backend; 191 192 [Key, Max(1)] 193 LMI_SSSDDomain REF Domain; 194 }; 195 196 [Version("0.1.0"), Provider("cmpi:cmpiLMI_SSSD"), Association, 197 Description("All subdomains associated with given parent domain.")] 198 class LMI_SSSDDomainSubdomain 199 { 200 [Key, Max(1)] 201 LMI_SSSDDomain REF ParentDomain; 202 203 [Key] 204 LMI_SSSDDomain REF Subdomain; 205 }; 206 207 [Version("0.1.0"), Provider("cmpi:cmpiLMI_SSSD"), Association] 208 class LMI_HostedSSSDService: CIM_HostedService 209 { 210 [Override("Antecedent"), 211 Description("The hosting System.") ] 212 CIM_ComputerSystem REF Antecedent; 213 214 [Override("Dependent"), 215 Description("Instance of SSSD service.")] 216 LMI_SSSDService REF Dependent; 217 };

65 Bibliography

[1] Distributed Management Task Force, Inc. CIM FAQ. [online]. URL: http : / / dmtf . org / about / faq / cim _ faq (visited on 05/10/2014). [2] Distributed Management Task Force, Inc. CIM Infrastructure Spec- ification, Version 2.7.0. [online]. URL: http : / / dmtf . org / sites/default/files/standards/documents/DSP0004_ 2.7.0.pdf (visited on 05/10/2014). [3] Distributed Management Task Force, Inc. CIM Metamodel, Version 3.0.0. [online]. URL: http://dmtf.org/sites/default/ files/standards/documents/DSP0004_3.0.0.pdf (visited on 05/10/2014). [4] Distributed Management Task Force, Inc. CIM Operations over HTTP , Version 1.4.0. [online]. URL: http : / / dmtf . org / sites / default/files/standards/documents/DSP0200_1. 4.0.pdf (visited on 05/10/2014). [5] Distributed Management Task Force, Inc. Managed Object Format Specification, Version 3.0.0. [online]. URL: http://dmtf.org/ sites/default/files/standards/documents/DSP0221_ 3.0.0.pdf (visited on 05/10/2014). [6] Distributed Management Task Force, Inc. Representation of CIM in XML, Version 2.4.0. [online]. URL: http://dmtf.org/sites/ default/files/standards/documents/DSP0201_2. 4.0.pdf (visited on 05/10/2014). [7] Distributed Management Task Force, Inc. WBEM Discovery Using the Service Location Protocol, Version 1.0.1. [online]. URL: http: //dmtf.org/sites/default/files/standards/documents/ DSP0205_1.0.1.pdf (visited on 05/10/2014). [8] Distributed Management Task Force, Inc. WBEM URI Mapping, Ver- sion 1.0.1. [online]. URL: http://dmtf.org/sites/default/ files/standards/documents/DSP0207_1.0.1.pdf (visited on 05/10/2014).

66 BIBLIOGRAPHY

[9] Distributed Management Task Force, Inc. Web-Based Enterprise Man- agement (WBEM) FAQs. [online]. URL: http : / / dmtf . org / about/faq/wbem_faq (visited on 05/10/2014). [10] Samuel P. Harbison, Guy L. Steele. C: A Reference Manual. 5th ed. Prentice Hall PTR, 2002. ISBN: 978-0130895929. [11] The Open Group. Systems Management: Common Manageability Programming Interface (CMPI). [online]. URL: https://www2. opengroup.org/ogsys/jsp/publications/PublicationDetails. jsp?publicationid=12003 (visited on 11/13/2013). [12] Wikipedia. Common Information Model. [online]. URL: http:// en.wikipedia.org/wiki/Common_Information_Model_ (computing) (visited on 11/13/2013). [13] Wikipedia. Web-Based Enterprise Management. [online]. URL: http: //en.wikipedia.org/wiki/Web-Based_Enterprise_ Management (visited on 11/13/2013).

67