From Fedora Project Wiki

This is a page to cover the current schema and how to implement it and the modifications that are required for the new account system in LDAP or in SQL

Current Schema

person id, username, email, human_name, gpg_keyid, ssh_key, password, comments, postal_address, telephone, facsimile, affiliation, creation, approval_status, internal_comments, wiki_prefs, ircnick

project_group id, name, owner_id, group_type, needs_sponsor, user_can_remove, prerequisite_id, joinmsg

role person_id, project_group_id, role_type, role_domain, role_status, internal_comments, sponsor_id (Points to a person), creation (TIMESTAMP), approval (TIMESTAMP)

Problems with the current schema

  • Cannot make groups members of a group
  • Cannot have multiple email addresses


LDAP

A new schema must be made, however, most information can be mapped from existing schemas.

Thanks to http://directoryproject.isc.ucsb.edu/schema/inetorgperson.html for some of the info.

The new fedoraPerson schema. inetOrgPerson is a superior.

Person Schema

Required Attributes

Attribute name Description Mapping from DB
objectClass Defines the object classes for the entry.
cn (commonName) The person’s common name. human name
sn (surname) The person’s surname, or last name. human name
mail The person's email address email

Custom Required Attributes

fedoraPersonSshKey Person's public ssh key ssh_key
fedoraPersonCreationDate the creation date of the person object creation

Allowed Attributes

Attribute name Description Mapping from DB
description Text description of the person. internal comments
fax (facsimileTelephoneNumber) The person’s fax number. facsimile
givenName The person’s given, or first, name. human name
mail The person’s email address. email
o (organizationName) Organization to which the person belongs. affiliation
ou (organizationUnitName) Organizational unit to which the person belongs. don't know yet
postalAddress The person’s mailing address. postal address
telephoneNumber The person’s telephone number. telephone
userPassword Password with which the entry can bind to the directory. password

Custom Allowed Attributes

Attribute name Description Mapping from DB
fedoraPersonApprovalStatus The person's approval status approval_status
fedoraPersonIrcNick The person's irc nick ircnick
fedoraPersonBugzillaMail The bugzilla email for the person none
fedoraPersonKeyId Stores a user’s certificate in cleartext. gpg_key id

Attributes Not Carried over from the Original Person Schema

wikiprefs


Group Schema

Required Attributes

Attribute name Description Mapping from DB
cn The name of the group name
fedoraGroupOwner owner of the group owner_id

Allowed Attributes

Attribute name Description Mapping from DB
fedoraGroupJoinMsg Message given upon joining a group joinmsg
fedoraGroupUserCanRemove boolean indicating if a user can remove the group user_can_remove
fedoraGroupType Type of group eg. cvs, bugzilla, shell group_type
fedoraGroupNeedsSponsor Boolean indicating if the group needs a sponsor needs_sponsor
fedoraGroupRequires Prerequisites of this Group prerequisite_id


Role Schema

Required Attributes

Attribute name Description Mapping from DB
cn The name of the role project_group_id role_type person_id

Allowed Attributes

Attribute name Description Mapping from DB
fedoraRoleType the type of role. eg user, administrator role_type
fedoraRoleDomain The domain of the role role_domain ( this is always blank in the current db )
fedoraRoleApprovalStatus the approval status of a role approval_status
fedoraRoleSponsor the sponsor for the role sponsor_id (this was a forign key )
fedoraRoleCreationDate The creation date of the role creation
fedoraRoleApprovalDate The approval date of the role approval


Attributes Not Carried over from the Original Role Schema

internal_comments


Proposed LDAP schema

LDAP is good at representing properties of an object, but it's not good at representing relationships between objects. This LDAP schema tries to implement the features we have in the present account system with an LDAP directory:

dc=fedoraproject,dc=org (standard schema)
|- ou=People (organisationalUnit)
|  |- uid=abompard (inetOrgPerson + a few added attributes)
|  |  |- cn=group1 (custom: fedoraRole)
|  |  |- cn=group2 (custom: fedoraRole)
|  |  <code>- cn=group3 (custom: fedoraRole)
|  <code>- uid=lyz (inetOrgPerson + a few added attributes)
|     <code>- cn=group1 (custom: fedoraRole)
|
<code>- ou=Groups (organisationalUnit)
|- cn=group1 (custom: fedoraGroup)
<code>- cn=group2 (custom: fedoraGroup)

etc, you get the idea. The custom objectClasses would be where the magic is.

The fedoraMembership objectClass would basically be a mapping of the role table. It would be able to contain the following attributes:

  • cn (the group name)
  • role_type
  • role_domain
  • role_status
  • internal_comments
  • sponsor (points to the sponsor's DN)
  • creation (date)
  • approval (date)

I think it should also have an uid attribute where the uid of the person would be repeated. It duplicates information but it makes it much easier to list the members of a group. With the uid it's just a matter of searching for (&(objectClass=fedoraMembership)(cn=group1)) and retrieving only the uid attribute, while without it you have to do the same search and to go up one level for each entry. I think many applications can be configured for group listing by giving a search string, but can't do anything more complicated.

The bad side is obviously that it duplicates information.

To get the uid attribute we can have the fedoraMembership objectClass heritate of the uidObject objectClass, which has just this attribute, or add it specifically. My opinion is that the duplication is a necessary evil here, and can be masked by the interface we'll write to avoid user mistake.

The fedoraGroup objectClass would basically be a mapping of the project_group table. It would contain the following attributes:

  • owner (the owner's DN)
  • group_type
  • needs_sponsor
  • user_can_remove (will be handled by ACLs, but we need to clue the interface about it)
  • prerequisite_id (no idea what that is, so maybe not)
  • joinmsg

It would not be a groupOfNames. The membership information is stored as described earlier. It would more be information about the group itself.

This structure has the following benefits:

  • we're close to the inetOrgPerson objectClass, which many apps expect
  • it is close to what we have now (basically a mapping) so it won't be hard to adapt it
  • we can add fields to the schema in the future if we need more info about the relationship between the user and the group
  • when a user is removed, all its memberships are removed at the same time since they're sub-entries, so no stale pointers.
  • we don't hardcode the available role_types (some of my earler proposals did this)

I see the following shortcomings:

  • having information about the user in a subentry of this user looks strange (inhabitual) in an LDAP directory.
  • it duplicates some information
  • maybe mapping too closely the workings of a relational database to a hierarchical directory will cause problems in the future

About the two problems with the current schema:

  • "Cannot have multiple email addresses": LDAP solves it by itself
  • "Cannot make groups members of a group": I don't have a perfect solution for that right now. We could add a fedoraMembership sub-entry to the fedoraGroup entries, that would work and be consistent, but the uid attribute in the fedoraMembership sub-entry would be empty then (since it doesn't apply to a user), it would have to have a cn attribute instead, so we can't make the uid attribute mandatory. A solution to this would be to make a generic fedoraMembership objectClass and two fedoraUserMembership and fedoraGroupMembership objectClasses which would inherit it and bring the user or group specific attributes.

Any comment on fedora-infrastructure-list would be very appreciated.

Other Attributes to Add

User

  • uid -- For other databases to use as a reference to the person
  • system account -- boolean, whether the account is for a real person or for a system account (which shouldn't be able to login)

group

  • gid -- For other databases to use as a reference to the group.
  • email address -- (Can be a mailing list that most members of the group are in or an alias that sends to everyone in the group)

SQL

The current schema is ok, but we need to adress the issues. To fix the multiple email address issue a table can be made email person_id email_address The primary key would be the combination of the id and address.

I'm a little less sure on the making groups a member of other groups issue.