Merge pull request #136 from radiorabe/feature/freeipa-auth
FreeIPA Auth Adaptor for LibreTime
This commit is contained in:
commit
8f372f5610
|
@ -0,0 +1,117 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Auth adaptor for FreeIPA
|
||||||
|
*/
|
||||||
|
|
||||||
|
class LibreTime_Auth_Adaptor_FreeIpa implements Zend_Auth_Adapter_Interface {
|
||||||
|
/**
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
private $username;
|
||||||
|
/**
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
private $password;
|
||||||
|
/**
|
||||||
|
* @var Application_Model_User
|
||||||
|
*/
|
||||||
|
private $user;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* username from form
|
||||||
|
*
|
||||||
|
* @return self
|
||||||
|
*/
|
||||||
|
function setIdentity($username) {
|
||||||
|
$this->username = $username;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* password from form
|
||||||
|
*
|
||||||
|
* This is ignored by FreeIPA but needs to get passed for completeness
|
||||||
|
*
|
||||||
|
* @return self
|
||||||
|
*/
|
||||||
|
function setCredential($password) {
|
||||||
|
$this->password = $password;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if apache logged the user and get data from ldap
|
||||||
|
*
|
||||||
|
* @return Zend_Auth_Result
|
||||||
|
*/
|
||||||
|
function authenticate()
|
||||||
|
{
|
||||||
|
if (array_key_exists('EXTERNAL_AUTH_ERROR', $_SERVER)) {
|
||||||
|
return new Zend_Auth_Result(Zend_Auth_Result::FAILURE, null, array($_SERVER['EXTERNAL_AUTH_ERROR']));
|
||||||
|
}
|
||||||
|
if (!array_key_exists('REMOTE_USER', $_SERVER)) {
|
||||||
|
return new Zend_Auth_Result(Zend_Auth_Result::FAILURE, null);
|
||||||
|
}
|
||||||
|
// success, the user is good since the service populated the REMOTE_USER
|
||||||
|
$remoteUser = $_SERVER['REMOTE_USER'];
|
||||||
|
|
||||||
|
$subj = CcSubjsQuery::create()->findOneByDbLogin($remoteUser);
|
||||||
|
$subjId =null;
|
||||||
|
if ($subj) {
|
||||||
|
$subjId = $subj->getDBId();
|
||||||
|
}
|
||||||
|
|
||||||
|
if ($subjId) {
|
||||||
|
$user = new Application_Model_User($subjId);
|
||||||
|
} else {
|
||||||
|
// upsert the user on login for first time users
|
||||||
|
$user = new Application_Model_User('');
|
||||||
|
}
|
||||||
|
|
||||||
|
// Always zap any local info with new info from ipa
|
||||||
|
$user->setLogin($remoteUser);
|
||||||
|
|
||||||
|
// Use a random password for IPA users, reset on each login... I may change this to get set to the IPA pass but hate that it is being stored as md5 behind the scenes
|
||||||
|
// gets rescrambled on each succeful login for security purposes
|
||||||
|
$ipaDummyPass = bin2hex(openssl_random_pseudo_bytes(10));
|
||||||
|
$user->setPassword($ipaDummyPass);
|
||||||
|
|
||||||
|
// grab user info from LDAP
|
||||||
|
$userParts = explode('@', $remoteUser);
|
||||||
|
$userInfo = LibreTime_Model_FreeIpa::GetUserInfo($userParts[0]);
|
||||||
|
|
||||||
|
$user->setType($userInfo['type']);
|
||||||
|
$user->setFirstName($userInfo['first_name']);
|
||||||
|
$user->setLastName($userInfo['last_name']);
|
||||||
|
$user->setEmail($userInfo['email']);
|
||||||
|
$user->setCellPhone($userInfo['cell_phone']);
|
||||||
|
$user->setSkype($userInfo['skype']);
|
||||||
|
$user->setJabber($userInfo['jabber']);
|
||||||
|
$user->save();
|
||||||
|
$this->user = $user;
|
||||||
|
try {
|
||||||
|
return new Zend_Auth_Result(Zend_Auth_Result::SUCCESS, $user);
|
||||||
|
} catch (Exception $e) {
|
||||||
|
// exception occured
|
||||||
|
return new Zend_Auth_Result(Zend_Auth_Result::FAILURE, null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* return dummy object for internal auth handling
|
||||||
|
*
|
||||||
|
* we need to build a dummpy object since the auth layer knows nothing about the db
|
||||||
|
*
|
||||||
|
* @return stdClass
|
||||||
|
*/
|
||||||
|
public function getResultRowObject() {
|
||||||
|
$o = new \stdClass;
|
||||||
|
$o->id = $this->user->getId();
|
||||||
|
$o->username = $this->user->getLogin();
|
||||||
|
$o->password = $this->user->getPassword();
|
||||||
|
$o->real_name = implode(' ', array($this->user->getFirstName(), $this->user->getLastName()));
|
||||||
|
$o->type = $this->user->getType();
|
||||||
|
$o->login = $this->user->getLogin();
|
||||||
|
return $o;
|
||||||
|
}
|
||||||
|
}
|
|
@ -76,6 +76,10 @@ class Application_Common_GoogleAnalytics
|
||||||
/** Return true if the user used to be on a trial plan and was just converted to a paid plan. */
|
/** Return true if the user used to be on a trial plan and was just converted to a paid plan. */
|
||||||
public static function didPaidConversionOccur($request)
|
public static function didPaidConversionOccur($request)
|
||||||
{
|
{
|
||||||
|
if (LIBRETIME_ENABLE_GOOGLE_ANALYTICS !== true) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
$userInfo = Zend_Auth::getInstance()->getStorage()->read();
|
$userInfo = Zend_Auth::getInstance()->getStorage()->read();
|
||||||
if ($userInfo) {
|
if ($userInfo) {
|
||||||
$user = new Application_Model_User($userInfo->id);
|
$user = new Application_Model_User($userInfo->id);
|
||||||
|
|
|
@ -37,6 +37,11 @@ class Config {
|
||||||
$CC_CONFIG['dev_env'] = 'production';
|
$CC_CONFIG['dev_env'] = 'production';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
$CC_CONFIG['auth'] = 'local';
|
||||||
|
if (isset($values['general']['auth'])) {
|
||||||
|
$CC_CONFIG['auth'] = $values['general']['auth'];
|
||||||
|
}
|
||||||
|
|
||||||
//Backported static_base_dir default value into saas for now.
|
//Backported static_base_dir default value into saas for now.
|
||||||
if (array_key_exists('static_base_dir', $values['general'])) {
|
if (array_key_exists('static_base_dir', $values['general'])) {
|
||||||
$CC_CONFIG['staticBaseDir'] = $values['general']['static_base_dir'];
|
$CC_CONFIG['staticBaseDir'] = $values['general']['static_base_dir'];
|
||||||
|
@ -64,7 +69,7 @@ class Config {
|
||||||
|
|
||||||
$CC_CONFIG['cache_ahead_hours'] = $values['general']['cache_ahead_hours'];
|
$CC_CONFIG['cache_ahead_hours'] = $values['general']['cache_ahead_hours'];
|
||||||
|
|
||||||
// Database config
|
// Database config
|
||||||
$CC_CONFIG['dsn']['username'] = $values['database']['dbuser'];
|
$CC_CONFIG['dsn']['username'] = $values['database']['dbuser'];
|
||||||
$CC_CONFIG['dsn']['password'] = $values['database']['dbpass'];
|
$CC_CONFIG['dsn']['password'] = $values['database']['dbpass'];
|
||||||
$CC_CONFIG['dsn']['hostspec'] = $values['database']['host'];
|
$CC_CONFIG['dsn']['hostspec'] = $values['database']['host'];
|
||||||
|
@ -92,6 +97,21 @@ class Config {
|
||||||
$CC_CONFIG['facebook-app-api-key'] = $globalAirtimeConfigValues['facebook']['facebook_app_api_key'];
|
$CC_CONFIG['facebook-app-api-key'] = $globalAirtimeConfigValues['facebook']['facebook_app_api_key'];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ldap config
|
||||||
|
if (array_key_exists('ldap', $values)) {
|
||||||
|
$CC_CONFIG['ldap_hostname'] = $values['ldap']['hostname'];
|
||||||
|
$CC_CONFIG['ldap_binddn'] = $values['ldap']['binddn'];
|
||||||
|
$CC_CONFIG['ldap_password'] = $values['ldap']['password'];
|
||||||
|
$CC_CONFIG['ldap_account_domain'] = $values['ldap']['account_domain'];
|
||||||
|
$CC_CONFIG['ldap_basedn'] = $values['ldap']['basedn'];
|
||||||
|
$CC_CONFIG['ldap_groupmap_guest'] = $values['ldap']['groupmap_guest'];
|
||||||
|
$CC_CONFIG['ldap_groupmap_host'] = $values['ldap']['groupmap_host'];
|
||||||
|
$CC_CONFIG['ldap_groupmap_program_manager'] = $values['ldap']['groupmap_program_manager'];
|
||||||
|
$CC_CONFIG['ldap_groupmap_admin'] = $values['ldap']['groupmap_admin'];
|
||||||
|
$CC_CONFIG['ldap_groupmap_superadmin'] = $values['ldap']['groupmap_superadmin'];
|
||||||
|
$CC_CONFIG['ldap_filter_field'] = $values['ldap']['filter_field'];
|
||||||
|
}
|
||||||
|
|
||||||
if(isset($values['demo']['demo'])){
|
if(isset($values['demo']['demo'])){
|
||||||
$CC_CONFIG['demo'] = $values['demo']['demo'];
|
$CC_CONFIG['demo'] = $values['demo']['demo'];
|
||||||
}
|
}
|
||||||
|
|
|
@ -76,7 +76,10 @@ class Application_Model_Auth
|
||||||
public static function getAuthAdapter()
|
public static function getAuthAdapter()
|
||||||
{
|
{
|
||||||
$CC_CONFIG = Config::getConfig();
|
$CC_CONFIG = Config::getConfig();
|
||||||
|
if ($CC_CONFIG['auth'] !== 'local') {
|
||||||
|
return self::getCustomAuthAdapter($CC_CONFIG['auth']);
|
||||||
|
}
|
||||||
|
|
||||||
// Database config
|
// Database config
|
||||||
$db = Zend_Db::factory('PDO_' . $CC_CONFIG['dsn']['phptype'], array(
|
$db = Zend_Db::factory('PDO_' . $CC_CONFIG['dsn']['phptype'], array(
|
||||||
'host' => $CC_CONFIG['dsn']['hostspec'],
|
'host' => $CC_CONFIG['dsn']['hostspec'],
|
||||||
|
@ -95,6 +98,15 @@ class Application_Model_Auth
|
||||||
return $authAdapter;
|
return $authAdapter;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets an alternative Adapter that does not need to auth agains a databse table
|
||||||
|
*
|
||||||
|
* @return object
|
||||||
|
*/
|
||||||
|
public static function getCustomAuthAdapter($adaptor) {
|
||||||
|
return new $adaptor();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get random string
|
* Get random string
|
||||||
*
|
*
|
||||||
|
|
|
@ -0,0 +1,74 @@
|
||||||
|
<?php
|
||||||
|
|
||||||
|
class LibreTime_Model_FreeIpa {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* get userinfo in the format needed by the Auth Adaptor
|
||||||
|
*
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public static function GetUserInfo($username)
|
||||||
|
{
|
||||||
|
$config = Config::getConfig();
|
||||||
|
$conn = self::_getLdapConnection();
|
||||||
|
|
||||||
|
$ldapResults = $conn->search(sprintf('%s=%s', $config['ldap_filter_field'], $username, $config['ldap_basedn']));
|
||||||
|
|
||||||
|
if ($ldapResults->count() !== 1) {
|
||||||
|
throw new Exception('Could not find logged user in LDAP');
|
||||||
|
}
|
||||||
|
$ldapUser = $ldapResults->getFirst();
|
||||||
|
|
||||||
|
$groupMap = array(
|
||||||
|
UTYPE_GUEST => $config['ldap_groupmap_guest'],
|
||||||
|
UTYPE_HOST => $config['ldap_groupmap_host'],
|
||||||
|
UTYPE_PROGRAM_MANAGER => $config['ldap_groupmap_program_manager'],
|
||||||
|
UTYPE_ADMIN => $config['ldap_groupmap_admin'],
|
||||||
|
UTYPE_SUPERADMIN => $config['ldap_groupmap_superadmin'],
|
||||||
|
);
|
||||||
|
$type = UTYPE_GUEST;
|
||||||
|
foreach ($groupMap as $groupType => $group) {
|
||||||
|
if (in_array($group, $ldapUser['memberof'])) {
|
||||||
|
$type = $groupType;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// grab first value for multivalue field
|
||||||
|
$firstName = $ldapUser['givenname'][0];
|
||||||
|
$lastName = $ldapUser['sn'][0];
|
||||||
|
$mail = $ldapUser['mail'][0];
|
||||||
|
|
||||||
|
// return full user info for auth adapter
|
||||||
|
return array(
|
||||||
|
'type' => $type,
|
||||||
|
'first_name' => $firstName,
|
||||||
|
'last_name' => $lastName,
|
||||||
|
'email' => $mail,
|
||||||
|
'cell_phone' => '', # empty since I did not find it in ldap
|
||||||
|
'skype' => '', # empty until we decide on a field
|
||||||
|
'jabber' => '' # empty until we decide on a field
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Bind to ldap so we can fetch additional user info
|
||||||
|
*
|
||||||
|
* @return Zend_Ldap
|
||||||
|
*/
|
||||||
|
private static function _getLdapConnection()
|
||||||
|
{
|
||||||
|
$config = Config::getConfig();
|
||||||
|
|
||||||
|
$options = array(
|
||||||
|
'host' => $config['ldap_hostname'],
|
||||||
|
'username' => $config['ldap_binddn'],
|
||||||
|
'password' => $config['ldap_password'],
|
||||||
|
'bindRequiresDn' => true,
|
||||||
|
'accountDomainName' => $config['ldap_account_domain'],
|
||||||
|
'baseDn' => $config['ldap_basedn']
|
||||||
|
);
|
||||||
|
$conn = new Zend_Ldap($options);
|
||||||
|
$conn->connect();
|
||||||
|
return $conn;
|
||||||
|
}
|
||||||
|
}
|
|
@ -42,6 +42,11 @@
|
||||||
# station_id: The Airtime station name.
|
# station_id: The Airtime station name.
|
||||||
# Only used in saas, needed for compatibility.
|
# Only used in saas, needed for compatibility.
|
||||||
#
|
#
|
||||||
|
# auth: Auth adaptor to user
|
||||||
|
# Set to local to use the default db auth or specifiy
|
||||||
|
# a class like LibreTime_Auth_Adaptor_FreeIpa to replace
|
||||||
|
# the built-in adaptor
|
||||||
|
#
|
||||||
[general]
|
[general]
|
||||||
api_key =
|
api_key =
|
||||||
web_server_user = www-data
|
web_server_user = www-data
|
||||||
|
@ -51,6 +56,7 @@ base_dir = /
|
||||||
cache_ahead_hours = 1
|
cache_ahead_hours = 1
|
||||||
airtime_dir =
|
airtime_dir =
|
||||||
station_id =
|
station_id =
|
||||||
|
auth = local
|
||||||
#
|
#
|
||||||
# ----------------------------------------------------------------------
|
# ----------------------------------------------------------------------
|
||||||
|
|
||||||
|
@ -308,3 +314,38 @@ soundcloud_redirect_uri = http://libretime.example.org/soundcloud_callback.php
|
||||||
facebook_app_id = 0
|
facebook_app_id = 0
|
||||||
facebook_app_url = http://example.org
|
facebook_app_url = http://example.org
|
||||||
facebook_app_api_key = 0
|
facebook_app_api_key = 0
|
||||||
|
|
||||||
|
#
|
||||||
|
# ----------------------------------------------------------------------
|
||||||
|
# L D A P
|
||||||
|
# ----------------------------------------------------------------------
|
||||||
|
#
|
||||||
|
# hostname: Hostname of LDAP server
|
||||||
|
#
|
||||||
|
# binddn: Complete DN of user used to bind to LDAP
|
||||||
|
#
|
||||||
|
# password: Password for binddn user
|
||||||
|
#
|
||||||
|
# account_domain: Domain part of username
|
||||||
|
#
|
||||||
|
# basedn: base search DN
|
||||||
|
#
|
||||||
|
# filter_field: Name of the uid field for searching
|
||||||
|
# Usually uid, may be cn
|
||||||
|
#
|
||||||
|
# groupmap_*: Map LibreTime user types to LDAP groups
|
||||||
|
# Lets LibreTime assign user types based on the
|
||||||
|
# group a given user is in.
|
||||||
|
#
|
||||||
|
[ldap]
|
||||||
|
hostname = ldap.example.org
|
||||||
|
binddn = 'uid=libretime,cn=sysaccounts,cn=etc,dc=int,dc=example,dc=org'
|
||||||
|
password = hackme
|
||||||
|
account_domain = INT.EXAMPLE.ORG
|
||||||
|
basedn = 'cn=users,cn=accounts,dc=int,dc=example,dc=org'
|
||||||
|
filter_field = uid
|
||||||
|
groupmap_guest = 'cn=guest,cn=groups,cn=accounts,dc=int,dc=example,dc=org'
|
||||||
|
groupmap_host = 'cn=host,cn=groups,cn=accounts,dc=int,dc=example,dc=org'
|
||||||
|
groupmap_program_manager = 'cn=program_manager,cn=groups,cn=accounts,dc=int,dc=example,dc=org'
|
||||||
|
groupmap_admin = 'cn=admins,cn=groups,cn=accounts,dc=int,dc=example,dc=org'
|
||||||
|
groupmap_superadmin = 'cn=superadmin,cn=groups,cn=accounts,dc=int,dc=example,dc=org'
|
||||||
|
|
|
@ -33,3 +33,16 @@ time_between_retries = 60
|
||||||
soundcloud_client_id = 0
|
soundcloud_client_id = 0
|
||||||
soundcloud_client_secret = 0
|
soundcloud_client_secret = 0
|
||||||
soundcloud_redirect_uri = http://soundcloud.example.org/redirect
|
soundcloud_redirect_uri = http://soundcloud.example.org/redirect
|
||||||
|
|
||||||
|
[ldap]
|
||||||
|
hostname = ldap.example.org
|
||||||
|
binddn = 'uid=libretime,cn=sysaccounts,cn=etc,dc=int,dc=example,dc=org'
|
||||||
|
password = hackme
|
||||||
|
account_domain = INT.EXAMPLE.ORG
|
||||||
|
basedn = 'cn=users,cn=accounts,dc=int,dc=example,dc=org'
|
||||||
|
filter_field = uid
|
||||||
|
groupmap_guest = 'cn=guest,cn=groups,cn=accounts,dc=int,dc=example,dc=org'
|
||||||
|
groupmap_host = 'cn=host,cn=groups,cn=accounts,dc=int,dc=example,dc=org'
|
||||||
|
groupmap_program_manager = 'cn=program_manager,cn=groups,cn=accounts,dc=int,dc=example,dc=org'
|
||||||
|
groupmap_admin = 'cn=admins,cn=groups,cn=accounts,dc=int,dc=example,dc=org'
|
||||||
|
groupmap_superadmin = 'cn=superadmin,cn=groups,cn=accounts,dc=int,dc=example,dc=org'
|
||||||
|
|
|
@ -0,0 +1,102 @@
|
||||||
|
You can configure LibreTime to delegate all authentication to a FreeIPA server.
|
||||||
|
|
||||||
|
This allows you users to use their existing FreeIPA credentials. For this to
|
||||||
|
work you need to configure Apache to use `mod_authnz_pam` and `mod_intercept_form_submit`.
|
||||||
|
|
||||||
|
## Apache configuration
|
||||||
|
|
||||||
|
After installing the needed modules you can set up Apache to intercept form logins and
|
||||||
|
check them against pam.
|
||||||
|
|
||||||
|
```apache
|
||||||
|
<Location /login>
|
||||||
|
InterceptFormPAMService http-libretime
|
||||||
|
InterceptFormLogin username
|
||||||
|
InterceptFormPassword password
|
||||||
|
InterceptFormLoginSkip admin
|
||||||
|
InterceptFormPasswordRedact on
|
||||||
|
InterceptFormLoginRealms INT.RABE.CH
|
||||||
|
Require pam-account http-libretime
|
||||||
|
</Location>
|
||||||
|
|
||||||
|
<Location />
|
||||||
|
<RequireAny>
|
||||||
|
<RequireAny>
|
||||||
|
Require pam-account http-libretime
|
||||||
|
Require all granted
|
||||||
|
</RequireAny>
|
||||||
|
<RequireAll>
|
||||||
|
Require expr %{REQUEST_URI} =~ /(index.php|login|favicon.ico|js|css|locale)/
|
||||||
|
Require all granted
|
||||||
|
</RequireAll>
|
||||||
|
</RequireAny>
|
||||||
|
</Location>
|
||||||
|
```
|
||||||
|
|
||||||
|
## PAM configuration
|
||||||
|
|
||||||
|
The above configuration expects a PAM configuration for the `http-libretime` service.
|
||||||
|
|
||||||
|
To confiure this you need to create the file `/etc/pam.d/http-libretime` with the following contents.
|
||||||
|
|
||||||
|
```
|
||||||
|
auth required pam_sss.so
|
||||||
|
account required pam_sss.so
|
||||||
|
```
|
||||||
|
|
||||||
|
## LDAP configuration
|
||||||
|
|
||||||
|
LibreTime needs direct access to LDAP so it can fetch additional information. It does so with
|
||||||
|
a [system account](https://www.freeipa.org/page/HowTo/LDAP#System_Accounts) that you need to
|
||||||
|
set up beforehand.
|
||||||
|
|
||||||
|
You can configure everything pertaining to how LibreTime accesses LDAP in
|
||||||
|
`/etc/airtime/airtime.conf`. The default file has the following values you need to change.
|
||||||
|
|
||||||
|
```ini
|
||||||
|
#
|
||||||
|
# ----------------------------------------------------------------------
|
||||||
|
# L D A P
|
||||||
|
# ----------------------------------------------------------------------
|
||||||
|
#
|
||||||
|
# hostname: Hostname of LDAP server
|
||||||
|
#
|
||||||
|
# binddn: Complete DN of user used to bind to LDAP
|
||||||
|
#
|
||||||
|
# password: Password for binddn user
|
||||||
|
#
|
||||||
|
# account_domain: Domain part of username
|
||||||
|
#
|
||||||
|
# basedn: base search DN
|
||||||
|
#
|
||||||
|
# filter_field: Name of the uid field for searching
|
||||||
|
# Usually uid, may be cn
|
||||||
|
#
|
||||||
|
# groupmap_*: Map LibreTime user types to LDAP groups
|
||||||
|
# Lets LibreTime assign user types based on the
|
||||||
|
# group a given user is in.
|
||||||
|
#
|
||||||
|
[ldap]
|
||||||
|
hostname = ldap.example.org
|
||||||
|
binddn = 'uid=libretime,cn=sysaccounts,cn=etc,dc=int,dc=example,dc=org'
|
||||||
|
password = hackme
|
||||||
|
account_domain = INT.EXAMPLE.ORG
|
||||||
|
basedn = 'cn=users,cn=accounts,dc=int,dc=example,dc=org'
|
||||||
|
filter_field = uid
|
||||||
|
groupmap_guest = 'cn=guest,cn=groups,cn=accounts,dc=int,dc=example,dc=org'
|
||||||
|
groupmap_host = 'cn=host,cn=groups,cn=accounts,dc=int,dc=example,dc=org'
|
||||||
|
groupmap_program_manager = 'cn=program_manager,cn=groups,cn=accounts,dc=int,dc=example,dc=org'
|
||||||
|
groupmap_admin = 'cn=admins,cn=groups,cn=accounts,dc=int,dc=example,dc=org'
|
||||||
|
groupmap_superadmin = 'cn=superadmin,cn=groups,cn=accounts,dc=int,dc=example,dc=org'
|
||||||
|
```
|
||||||
|
|
||||||
|
## Enable FreeIPA auth
|
||||||
|
|
||||||
|
After everything is set up properly you can enable FreeIPA auth in `airtime.conf`:
|
||||||
|
|
||||||
|
```
|
||||||
|
[general]
|
||||||
|
auth = LibreTime_Auth_Adaptor_FreeIpa
|
||||||
|
```
|
||||||
|
|
||||||
|
You should now be able to use your FreeIPA credentials to log in to LibreTime.
|
|
@ -69,6 +69,7 @@ pages:
|
||||||
- 'LibreTime API authentication': manual/airtime-api-authentication/index.md
|
- 'LibreTime API authentication': manual/airtime-api-authentication/index.md
|
||||||
- 'Secure login with SSL or TLS': manual/secure-login-with-ssl/index.md
|
- 'Secure login with SSL or TLS': manual/secure-login-with-ssl/index.md
|
||||||
- 'Icecast statistics with Piwik': manual/icecast-statistics-with-piwik/index.md
|
- 'Icecast statistics with Piwik': manual/icecast-statistics-with-piwik/index.md
|
||||||
|
- 'FreeIPA Authentication': freeipa.md
|
||||||
- 'Development':
|
- 'Development':
|
||||||
- 'Testing': testing.md
|
- 'Testing': testing.md
|
||||||
- 'Vagrant': vagrant.md
|
- 'Vagrant': vagrant.md
|
||||||
|
|
Loading…
Reference in New Issue