diff --git a/modules/ldap/config/gallery.ldif b/modules/ldap/config/gallery.ldif new file mode 100644 index 00000000..db33c494 --- /dev/null +++ b/modules/ldap/config/gallery.ldif @@ -0,0 +1,70 @@ +dn: ou=people,dc=gallery,dc=local +objectClass: organizationalUnit +ou: people + +dn: ou=groups,dc=gallery,dc=local +objectClass: organizationalUnit +ou: groups + +dn: ou=systems,dc=gallery,dc=local +objectClass: organizationalUnit +ou: systems + +dn: uid=jdoe,ou=people,dc=gallery,dc=local +objectClass: inetOrgPerson +objectClass: posixAccount +uid: jdoe +sn: Doe +givenname: John +cn: John Doe +userpassword: {SSHA}76qIsKTflGM6dj0f5c5olnD9ltKKXAFE +displayName: John Doe +homeDirectory: /home/jdoe +uidnumber: 1000 +gidnumber: 10000 +mail: jdoe@gallery.local + +dn: uid=hwallbanger,ou=people,dc=gallery,dc=local +objectClass: inetOrgPerson +objectClass: posixAccount +uid: hwallbanger +sn: Wallbanger +givenname: Harvey +cn: Harvey Wallbanger +userpassword: {SSHA}084H+FFr6s/anIoaIhI+O8OaH2u0MIBL +displayName: Harvey Wallbanger +homeDirectory: /home/hwallbanger +uidnumber: 1001 +gidnumber: 10001 +mail: hwallbanger@gallery.local + +dn: uid=rnail,ou=people,dc=gallery,dc=local +objectClass: inetOrgPerson +objectClass: posixAccount +uid: rnail +sn: Nail +givenname: Rusty +cn: Rusty Nail +userpassword: {SSHA}wXVdpfbP6n9LwoLxrB+NvY2oDN1j/M2z +displayName: Rusty Nail +homeDirectory: /home/rnail +uidnumber: 1002 +gidnumber: 10001 +mail: rnail@gallery.local + +dn: cn=admins,ou=groups,dc=gallery,dc=local +objectclass: posixGroup +cn: admins +gidnumber: 10000 +memberuid: jdoe + +dn: cn=users,ou=groups,dc=gallery,dc=local +objectclass: posixGroup +cn: users +gidnumber: 10001 +memberuid: jdoe +memberuid: hwallbanger +memberuid: rnail + + + diff --git a/modules/ldap/config/identity.php b/modules/ldap/config/identity.php new file mode 100644 index 00000000..87bc79a1 --- /dev/null +++ b/modules/ldap/config/identity.php @@ -0,0 +1,45 @@ + "ldap", + "allow_updates" => false, + "params" => array( + "groups" => array("admins", "users", "guest"), + "everybody_group" => "guest", + "registered_users_group" => "users", + "admins" => array("jdoe"), + "url" => "ldap://127.0.0./", + "group_domain" => "ou=groups,dc=gallery,dc=local", + "user_domain" => "ou=people,dc=gallery,dc=local" + ) +); diff --git a/modules/ldap/controllers/admin_ldap.php b/modules/ldap/controllers/admin_ldap.php deleted file mode 100644 index 8f206bd0..00000000 --- a/modules/ldap/controllers/admin_ldap.php +++ /dev/null @@ -1,64 +0,0 @@ -content = new View("admin_ldap.html"); - $view->content->config = Kohana::config("ldap"); - print $view; - } - - public function activate() { - access::verify_csrf(); - - - if (module::get_var("gallery", "user_group_storage", "Gallery3") == "Gallery3") { - // @todo: we should have an API for these - foreach (ORM::factory("group")->find_all() as $group) { - $group->delete(); - } - foreach (ORM::factory("user")->find_all() as $user) { - $user->delete(); - } - } - - // Create LDAP groups - foreach (Kohana::config("ldap.groups") as $group_name) { - $group = ldap::lookup_group_by_name($group_name); - module::event("group_created", $group); - } - - // Fix up permissions. - $root = item::root(); - $everybody = ldap::everybody_group(); - access::allow($everybody, "view", $root); - access::allow($everybody, "view_full", $root); - $registered_users = ldap::registered_users_group(); - access::allow($registered_users, "view", $root); - access::allow($registered_users, "view_full", $root); - - // Switch authentication - module::set_var("gallery", "user_group_storage", "Ldap"); - - // Logout and go back to the top level - user::logout(); - url::redirect(item::root()->abs_url()); - } -} \ No newline at end of file diff --git a/modules/ldap/helpers/ldap.php b/modules/ldap/helpers/ldap.php deleted file mode 100644 index 45cae297..00000000 --- a/modules/ldap/helpers/ldap.php +++ /dev/null @@ -1,115 +0,0 @@ - 0) { - return new Ldap_User_Model($entries[0]); - } - return null; - } - - static function lookup_user($id) { - $result = ldap_search(ldap::connection(), - Kohana::config("ldap.user_domain"), - "uidNumber=$id"); - $entries = ldap_get_entries(ldap::connection(), $result); - if ($entries["count"] > 0) { - return new Ldap_User_Model($entries[0]); - } - return null; - } - - static function validate_group($input) { - if (!self::lookup_group_by_name($input->value)) { - $input->add_error("invalid_group", 1); - } - } - - static function groups_for($user) { - $result = ldap_search(ldap::connection(), - Kohana::config("ldap.group_domain"), - "(memberUid=$user->name)"); - - $associated_groups = Kohana::config("ldap.groups"); - $groups = array(); - for ($entry_id = ldap_first_entry(ldap::connection(), $result); - $entry_id != false; - $entry_id = ldap_next_entry(ldap::connection(), $entry_id)) { - $group_id = ldap_get_values(ldap::connection(), $entry_id, "gidNumber"); - $group_name = ldap_get_values(ldap::connection(), $entry_id, "cn"); - if (in_array($group_name[0], $associated_groups)) { - $groups[] = new Ldap_Group_Model($group_id[0], $group_name[0]); - } - } - return $groups; - } - - static function guest() { - return new Ldap_Guest_Model(); - } - - public function everybody_group() { - return ldap::lookup_group_by_name(Kohana::config("ldap.everybody_group")); - } - - public function registered_users_group() { - return ldap::lookup_group_by_name(Kohana::config("ldap.registered_users_group")); - } -} diff --git a/modules/ldap/helpers/ldap_event.php b/modules/ldap/helpers/ldap_event.php deleted file mode 100644 index 91217f3f..00000000 --- a/modules/ldap/helpers/ldap_event.php +++ /dev/null @@ -1,28 +0,0 @@ -get("settings_menu") - ->append(Menu::factory("link") - ->id("ldap") - ->label(t("LDAP")) - ->url(url::site("admin/ldap"))); - } -} diff --git a/modules/ldap/models/ldap_guest.php b/modules/ldap/helpers/ldap_installer.php similarity index 64% rename from modules/ldap/models/ldap_guest.php rename to modules/ldap/helpers/ldap_installer.php index 645ec095..825da9fa 100644 --- a/modules/ldap/models/ldap_guest.php +++ b/modules/ldap/helpers/ldap_installer.php @@ -17,20 +17,24 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston, MA 02110-1301, USA. */ -class Ldap_Guest_Model { - public $id = 0; - public $guest = true; - public $admin = false; - public $locale = null; - public $name = "Guest"; +class ldap_installer { + static function install() { + } - public function __get($key) { - switch($key) { - case "groups": - return array(ldap::everybody_group()); + static function uninstall() { + // Delete all users and groups so that we give other modules an opportunity to clean up + foreach (ORM::factory("user")->find_all() as $user) { + $user->delete(); + } - default: - throw new Exception("@todo UNKNOWN_KEY ($key)"); + foreach (ORM::factory("group")->find_all() as $group) { + $group->delete(); + } + + try { + Session::instance()->destroy(); + } catch (Exception $e) { + // We don't care if there was a problem destroying the session. } } -} +} \ No newline at end of file diff --git a/modules/ldap/libraries/drivers/Identity/Ldap.php b/modules/ldap/libraries/drivers/Identity/Ldap.php new file mode 100644 index 00000000..e0cdbfaa --- /dev/null +++ b/modules/ldap/libraries/drivers/Identity/Ldap.php @@ -0,0 +1,223 @@ +_params["url"]); + ldap_bind(self::$_connection); + } + + /** + * @see Identity_Driver::guest. + */ + public function guest() { + if (empty(self::$_guest_user)) { + self::$_guest_user = new Ldap_User(); + self::$_guest_user->id = 0; + self::$_guest_user->name = "Guest"; + self::$_guest_user->guest = true; + self::$_guest_user->admin = false; + self::$_guest_user->locale = null; + self::$_guest_user->groups = array($this->everybody()); + } + return self::$_guest_user; + } + + /** + * @see Identity_Driver::create_user. + */ + public function create_user($name, $full_name, $password) { + throw new Exception("@todo INVALID OPERATION"); + } + + /** + * @see Identity_Driver::is_correct_password. + */ + public function is_correct_password($user, $password) { + $valid = $user->password; + + // Try phpass first, since that's what we generate. + if (strlen($valid) == 34) { + require_once(MODPATH . "user/lib/PasswordHash.php"); + $hashGenerator = new PasswordHash(10, true); + return $hashGenerator->CheckPassword($password, $valid); + } + + $salt = substr($valid, 0, 4); + // Support both old (G1 thru 1.4.0; G2 thru alpha-4) and new password schemes: + $guess = (strlen($valid) == 32) ? md5($password) : ($salt . md5($salt . $password)); + if (!strcmp($guess, $valid)) { + return true; + } + + // Passwords with <&"> created by G2 prior to 2.1 were hashed with entities + $sanitizedPassword = html::specialchars($password, false); + $guess = (strlen($valid) == 32) ? md5($sanitizedPassword) + : ($salt . md5($salt . $sanitizedPassword)); + if (!strcmp($guess, $valid)) { + return true; + } + + return false; + } + + /** + * @see Identity_Driver::lookup_user. + */ + public function lookup_user($id) { + $result = ldap_search(self::$_connection, self::$_params["user_domain"], "uidNumber=$id"); + $entries = ldap_get_entries(self::$_connection, $result); + if ($entries["count"] > 0) { + $cn_entry = ldap_get_values(self::$_connection, $entry_id, "cn"); + return new Ldap_User($entries[0]); + } + return null; + } + + /** + * @see Identity_Driver::lookup_user_by_name. + */ + public function lookup_user_by_name($name) { + $result = ldap_search(self::$_connection, self::$_params["user_domain"], "uid=$name"); + $entries = ldap_get_entries(self::$_connection, $result); + if ($entries["count"] > 0) { + $cn_entry = ldap_get_values(self::$_connection, $entry_id, "cn"); + return new Ldap_User($entries[0]); + } + return null; + } + + /** + * @see Identity_Driver::create_group. + */ + public function create_group($name) { + throw new Exception("@todo INVALID OPERATION"); + } + + /** + * @see Identity_Driver::everybody. + */ + public function everybody() { + return ldap::lookup_group_by_name(self::$_params["everybody_group"]); + } + + /** + * @see Identity_Driver::registered_users. + */ + public function registered_users() { + return ldap::lookup_group_by_name(self::$_params["registered_users_group"]); + } + + /** + * @see Identity_Driver::lookup_group_by_name. + */ + static function lookup_group_by_name($name) { + $result = ldap_search(self::$_connection, self::$_params["group_domain"], "cn=$name"); + $entry_id = ldap_first_entry(, $result); + if ($entry_id) { + $cn_entry = ldap_get_values(self::$_connection, $entry_id, "cn"); + $gid_number_entry = ldap_get_values(self::$_connection, $entry_id, "gidNumber"); + return new Ldap_Group_Model($gid_number_entry[0], $cn_entry[0]); + } + return null; + } + + /** + * @see Identity_Driver::get_user_list. + */ + public function get_user_list($ids) { + throw new Exception("@todo NOT IMPLEMENTED"); + } + + static function groups_for($user) { + $result = ldap_search(self::$_connection, self::$_params["group_domain"], + "(memberUid=$user->name)"); + + $associated_groups = Kohana::config("ldap.groups"); + $groups = array(); + for ($entry_id = ldap_first_entry(self::$_connection, $result); + $entry_id != false; + $entry_id = ldap_next_entry(self::$_connection, $entry_id)) { + $group_id = ldap_get_values(self::$_connection, $entry_id, "gidNumber"); + $group_name = ldap_get_values(self::$_connection, $entry_id, "cn"); + if (in_array($group_name[0], $associated_groups)) { + $groups[] = new Ldap_Group($group_id[0], $group_name[0]); + } + } + return $groups; + } +} // End Identity Gallery Driver + +class Ldap_User implements User_Definition { + private $ldap_entry; + + public function __construct($ldap_entry=null) { + $this->ldap_entry = $ldap_entry; + } + + public function display_name() { + return $this->ldap_entry["displayname"][0]; + } + + public function __get($key) { + switch($key) { + case "name": + return $this->ldap_entry["uid"][0]; + + case "guest": + return false; + + case "id": + return $this->ldap_entry["uidnumber"][0]; + + case "groups": + return Identity_Ldap::Driver::groups_for($this); + + case "locale": // @todo + return null; + + case "admin": + return in_array($this->ldap_entry["uid"][0], Kohana::config("ldap.admins")); + + default: + throw new Exception("@todo UNKNOWN_KEY ($key)"); + } + } + } + +class Ldap_Group implements Group_Definition { + public $id; + public $name; + + public function __construct($id, $name) { + $this->id = $id; + $this->name = $name; + $this->special = false; + } +} diff --git a/modules/ldap/models/ldap_group.php b/modules/ldap/models/ldap_group.php deleted file mode 100644 index 22e2ae4b..00000000 --- a/modules/ldap/models/ldap_group.php +++ /dev/null @@ -1,28 +0,0 @@ -id = $id; - $this->name = $name; - } -} diff --git a/modules/ldap/models/ldap_user.php b/modules/ldap/models/ldap_user.php deleted file mode 100644 index baaf8459..00000000 --- a/modules/ldap/models/ldap_user.php +++ /dev/null @@ -1,58 +0,0 @@ -ldap_entry = $ldap_entry; - } - - public function display_name() { - return $this->ldap_entry["displayname"][0]; - } - - public function __get($key) { - switch($key) { - case "name": - return $this->ldap_entry["uid"][0]; - - case "guest": - return false; - - case "login_count": - return 0; - - case "id": - return $this->ldap_entry["uidnumber"][0]; - - case "groups": - return ldap::groups_for($this); - - case "locale": // @todo - return null; - - case "admin": - return in_array($this->ldap_entry["uid"][0], Kohana::config("ldap.admins")); - - default: - throw new Exception("@todo UNKNOWN_KEY ($key)"); - } - } -} diff --git a/modules/ldap/views/admin_ldap.html.php b/modules/ldap/views/admin_ldap.html.php deleted file mode 100644 index e8080449..00000000 --- a/modules/ldap/views/admin_ldap.html.php +++ /dev/null @@ -1,60 +0,0 @@ - -
- = t("LDAP is an alternate authentication system. When you switch to it, all your Gallery3 users and groups will be deleted and you'll use users and groups from your LDAP directory.") ?> -
- -- = t("Your current LDAP configuration is:") ?> -
-- = t("Base LDAP url") ?> - | -- = $config["url"] ?> - | -
- = t("Group LDAP Domain") ?> - | -- = $config["group_domain"] ?> - | -
- = t("User LDAP Domain") ?> - | -- = $config["user_domain"] ?> - | -
- = t("Groups") ?> - | -- = join(", ", $config["groups"]) ?> - | -
- = t("Admin users") ?> - | -- = join(", ", $config["admins"]) ?> - | -
- = t("Upon activation, all existing users and groups will be deleted. The groups listed above and all available users will be associated with Gallery 3. You will be logged in as the %username user. There is no undo!", array("username" => $config["admins"][0])) ?> -
- - ">activate -