Hello,
I've searched the forums and have attempted to implement every recommended solution.
I've checked out the latest Gallery3 RC2 from GIT and the latest version of the ldap module from gallery3-contrib GIT.
Here is my identity.conf
$config["ldap"] = array(
"driver" => "ldap",
"allow_updates" => false,
"params" => array(
"groups" => array("SSEW_RWQ_IT"),
"everybody_group" => "SSEW_RWQ_IT",
"registered_users_group" => "SSEW_RWQ_IT",
"admins" => array("atowers"),
"group_domain" => "ou=Standard,ou=Groups,dc=mydomain,dc=com",
"user_domain" => "ou=Employees,ou=Users,dc=mydomain,dc=com"
)
);
I don't see a place to enter in an LDAP bind user. Our LDAP directory does not allow anonymous lookups. I've also created a test LDAP server that does allow anonymous lookups with no success. In all cases I receive a "DANG" error.
Here's the garbage that's in the logs.
2010-07-19 15:38:44 -07:00 --- error: Exception [ 0 ]: @todo NO_USER_LIBRARY_CONFIGURATION_FOR: ldap
/var/www/html/gallery/gallery3/modules/gallery/libraries/IdentityProvider.php [ 133 ]
#0 /var/www/html/gallery/gallery3/modules/gallery/libraries/IdentityProvider.php(43): IdentityProvider_Core->__construct()
#1 /var/www/html/gallery/gallery3/modules/gallery/helpers/identity.php(143): IdentityProvider_Core::instance()
#2 /var/www/html/gallery/gallery3/modules/gallery/helpers/identity.php(114): identity_Core::guest()
#3 /var/www/html/gallery/gallery3/modules/gallery/models/item.php(36): identity_Core::active_user()
#4 /var/www/html/gallery/gallery3/system/libraries/ORM.php(88): Item_Model->__construct(NULL)
#5 /var/www/html/gallery/gallery3/modules/gallery/helpers/model_cache.php(25): ORM_Core::factory('item')
#6 /var/www/html/gallery/gallery3/modules/gallery/helpers/item.php(211): model_cache_Core::get('item', 1)
#7 /var/www/html/gallery/gallery3/modules/gallery/helpers/identity.php(90): item_Core::root()
#8 /var/www/html/gallery/gallery3/modules/gallery/helpers/gallery_event.php(26): identity_Core::load_user()
#9 /var/www/html/gallery/gallery3/modules/gallery/helpers/module.php(349): gallery_event_Core::gallery_ready()
#10 /var/www/html/gallery/gallery3/modules/gallery/helpers/gallery.php(43): module_Core::event('gallery_ready')
#11 [internal function]: gallery_Core::ready(Array)
#12 /var/www/html/gallery/gallery3/system/core/Event.php(208): call_user_func_array(Array, Array)
#13 /var/www/html/gallery/gallery3/application/Bootstrap.php(58): Event_Core::run('system.ready')
#14 /var/www/html/gallery/gallery3/index.php(94): require('/var/www/html/g...'
I've seen a few posts with this same error. I haven't been able to get it working.
Any suggestions?
Posts: 7985
That "garbage" in the logs is pretty useful. It tells me that the code is not finding the correct config file. Can you verify that it's located at modules/ldap/config/identity.php ?
I wrote the LDAP module but I'm far from an LDAP expert so any guidance here is appreciated. If you can point me at the right PHP code to bind to your ldap, I can work that into the G3 module.
---
Problems? Check gallery3/var/logs
bugs/feature req's | upgrade to the latest code | use git
Posts: 12
Awesome! I love useful garbage...
We would need to pass this (http://www.php.net/manual/en/function.ldap-bind.php) to the ldap module. I believe you've already done the work to make this happen. It will just need two parameters (user DN and p/w) passed from identity.php to ldap.php.
here is the path to my identity.php
<Apache-DocumentRoot>gallery/gallery3/modules/ldap/config/identity.php
Is this the correct location? I only edited the file, do I need to move it to a different location?
Thanks for your response and great work on G3!!! I can't wait to use it.
-Brian
Posts: 7985
Ah, I bet I know what happened. We failed to properly do the LDAP install leaving your site in a weird state where the module isn't fully installed, but we've specified that it's active. So it's not looking in modules/ldap/config, but it's expecting there to be a $config["ldap"] in an identity.php file somewhere in the active module path. Let's see if we can verify that. Can you run this SQL statement? My sample output is included below
edit: I had a typo in the sql!
If the active column is set to 0, try setting it to 1.
I just updated the LDAP module to allow you to specify a u/p to ldap_bind in http://github.com/gallery/gallery3-contrib/commit/9f7907f9cbc42cd457e9ccd196b200319dc70a55 -- see if that works for you.
---
Problems? Check gallery3/var/logs
bugs/feature req's | upgrade to the latest code | use git
Posts: 12
You are awesome.... I will give it a shot now.
Posts: 12
I don't even see the LDAP module. I checked the box in the admin page and it went straight to the "Dang" error.
mysql> select * from modules;
+----+--------+-----------+---------+
| id | active | name | version |
+----+--------+-----------+---------+
| 1 | 1 | gallery | 30 |
| 3 | 1 | comment | 3 |
| 4 | 1 | organize | 1 |
| 5 | 1 | info | 1 |
| 6 | 1 | rest | 3 |
| 7 | 1 | rss | 1 |
| 8 | 1 | search | 1 |
| 9 | 1 | slideshow | 2 |
| 10 | 1 | tag | 2 |
+----+--------+-----------+---------+
9 rows in set (0.00 sec)
mysql>
Posts: 12
I had to remove the trailing "common <,>" from identity.conf for bind_password:
"bind_password" => NULL, to "bind_password" => NULL
Now I see ldap "active" 0, like you said. I'll set it to "1" and report back.
mysql> select * from modules;
+----+--------+-----------+---------+
| id | active | name | version |
+----+--------+-----------+---------+
| 1 | 1 | gallery | 30 |
| 11 | 0 | ldap | 1 |
| 3 | 1 | comment | 3 |
| 4 | 1 | organize | 1 |
| 5 | 1 | info | 1 |
| 6 | 1 | rest | 3 |
| 7 | 1 | rss | 1 |
| 8 | 1 | search | 1 |
| 9 | 1 | slideshow | 2 |
| 10 | 1 | tag | 2 |
+----+--------+-----------+---------+
10 rows in set (0.00 sec)
mysql>
Thanks for your help.
Posts: 12
I've made quite a bit of progress. I can confirm the bind user and password is functioning correctly. I've also made the required attribute changes to authenticate against Microsoft Active Directory. And can confirm successful authentication against AD.
I have a question about groups. In this function:
190 static function groups_for($user) { 191 if ($user->guest) { 192 return $user->groups; 193 } 194 195 $result = ldap_search(self::$_connection, self::$_params["group_domain"], 196 "(memberUid=$user->name)"); 197 198 $associated_groups = self::$_params["groups"]; 199 $groups = array(); 200 for ($entry_id = ldap_first_entry(self::$_connection, $result); 201 $entry_id != false; 202 $entry_id = ldap_next_entry(self::$_connection, $entry_id)) { 203 $group_id = ldap_get_values(self::$_connection, $entry_id, "gidNumber"); 204 $group_name = ldap_get_values(self::$_connection, $entry_id, "cn"); 205 if (in_array($group_name[0], $associated_groups)) { 206 $groups[] = new Ldap_Group($group_id[0], $group_name[0]); 207 } 208 } 209 return $groups; 210 }It appears you're only respecting the primary GID associated with the user object. I am able to provide this information in my AD environment via the RFC2307 POSIX attributes. However, the above function does not look at the actual group membership "memberof" attribute. Therefore, the only groups looked at are the ones in the "groups" array that match the user's primary GID. This means a user cannot be in the "registered users" group and another group at the same time.
Can you confirm, or clarify for me? I've been staring at Ldap.php for hours now
I will post the changes I made to support AD as well if you would like. A simple flag can be set in identity.conf to enable AD support.
Thanks for any help you can provide.
-Brian
Posts: 7985
I put line numbers in your code snippet so that we can refer to it.
I'm no LDAP expert but my test environment has about a zillion groups. So the config file lets you limit the ones that we care about to a manageable number. On line 200 we go through the list of groups that we got back from the request on line 195, then in line 205 we check to see if each group that the user is associated with is one that we care about. If it is, we consider it a "Gallery group".
Can you explain what's missing from this? It's easy to fix once I understand it
---
Problems? Check gallery3/var/logs
bugs/feature req's | upgrade to the latest code | use git
Posts: 12
Here is what I've come up with. It seems to work well.
I've changed the way it handles group discovery as well.
Original code:
$result = ldap_search(self::$_connection, self::$_params["group_domain"], "(memberUid=$user->name)");For what I can tell, the above code grabs all groups in the baseDN and searchs for memberships. This doesn't scale when hundreds of thousands of groups exist at the DN. The query can take minutes.
Instead, I find the membership of the user by looking at the user object itself rather than dump all of the groups. The "memberOf" attribute tells us this. This all holds true for OpenLDAP as well. Each user object has attributes in which provides group membership information.
This is my major change. I've made other changes as well so you'll probably want to do a diff (on my attachments) to see what I've done. The below code snippet looks at the user object for its group membership, we stick the values into the "$group_membership_DNs" array just like you did, however, the memberOf value is a DN--it must be converted to a CN for Gallery3. The AD specific attribute is "samaccountname" rather than "uid". I can confirm the attribute differences between AD and OpenLDAP to clean up the code a bit. I'm going to move the attributes out of Ldap.php and into identity.php. I'd like to have parameters that can easily be set in identity.conf for all required attributes. This will be LDAP server agnostic and won't take much work at all (I'm sure you know that).
$result = ldap_search(self::$_connection, self::$_params["group_basedn"],"(samaccountname=$user->name)"); $associated_groups = self::$_params["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_membership_DNs = ldap_get_values(self::$_connection, $entry_id, "memberof"); foreach ($group_membership_DNs as $group_to_convert) { $result = ldap_search(self::$_connection, self::$_params["group_basedn"],"(distinguishedname=$group_to_convert)"); $entry_id = ldap_first_entry(self::$_connection, $result); $group_id = ldap_get_values(self::$_connection, $entry_id, "gidnumber"); $group_name = ldap_get_values(self::$_connection, $entry_id, "samaccountname"); if (in_array($group_name[0], $associated_groups)) { $groups[] = new Ldap_Group($group_id[0], $group_name[0]); } } return $groups; }Here is my identity.conf:
$config["ldap"] = array( "driver" => "ldap", "allow_updates" => false, "params" => array( "groups" => array("4324_Gallery_Admins", "4234_Gallery_Everyone", "4234_Gallery_Registered_Users"), "everybody_group" => "4234_Gallery_Everyone", "registered_users_group" => "4234_Gallery_Registered_Users", "admins" => array("brianmiller"), "ldap_server" => "ldap://4234-addc1.phospher.com:3268", "group_basedn" => "dc=phospher,dc=com", "user_basedn" => "dc=phospher,dc=com", "bind_rdn" => "cn=ldapbind,ou=Service Accounts,ou=NWK,ou=US,ou=Americas,dc=phospher,dc=com", "bind_password" => "<sanitized password>" ) );My Gallery3 site is on its way up! yay!
Let me know what you think.
.
-Brian
Posts: 12
Here is an updated version with attribute configuration moved to identity.conf. I tested it with AD 2003 and 2008. Everything seems to work well.
Because I'm not familiar enough with the kohana framework and how everything works in gallery3--what would it take to add a new "maintenance task" to update the group list when adding a group to identity.conf. Currently, If I have for example:
"groups" => array("brian_album_rw", "brian_album_ro"),Then enable the LDAP module, everything is fine.
Later, I decide to give a family member a album, so I edit the identity.conf file to add a group.
"groups" => array("brian_album_rw", "brian_album_ro", "sister_album_rw", "sister_album_ro"),Now, if I were to "Edit permissions" of an album, all groups are missing. We need a task to "refresh" the group list. Again, I'm not familiar enough with G3 or the framework to really understand how this part works.
Correct me if I'm wrong, but I "think" it's this piece of code that does the group work.
in ldap_installer.php (I'm just guessing here).
static function initialize() { module::set_version("ldap", 1); $root = item::root(); foreach (IdentityProvider::instance()->groups() as $group) { module::event("group_created", $group); access::allow($group, "view", $root); access::allow($group, "view_full", $root); }Something happens during the installation of the ldap module that tells G3 the group is group to use.
See attached for my updated versions.
Posts: 7985
Ok, this looks awesome. The best way to proceed here would be if you could fork our contrib repo on Github and start editing your code such that we can just merge it back into the LDAP module. This would basically make you a developer on the LDAP module (which is warranted since you seem to know a whole lot more about it than I do!).
Basically, go to:
http://github.com/gallery/gallery3-contrib
Create an account on Github and make your own fork of gallery3-contrib, then commit your code changes back. I'll
Follow the instructions to get your own git clone. Then hack up the code as you see fit and commit your changes to your fork, and we'll merge them into the contrib repo. Then get a beer, and give yourself a pat on the back cause you'll be a Gallery developer!
As for a task to do the cleanup, I think that would be pretty easy. Take a look at modules/search/helpers/search_task.php for an example of how to write a simple maintenance task. We could have a task that just resyncs the groups -- I think all you have to do is look at the current groups and the ones in identity.php and generate "group_created" and "group_deleted" events as appropriate.
Let me know how it goes!
---
Problems? Check gallery3/var/logs
bugs/feature req's | upgrade to the latest code | use git
Posts: 12
Sounds good. I'm glad I can contribute something.
Because I dream bash syntax, I wrote a POC as a shell script first. The cutting, scraping and database stuff will obviously easily and elegantly be handled by the PHP framework. I believe the logic is solid.
Running the script will essentially "synchronize" what is in identity.php and the G3 database while checking to ensure the groups are valid in both G3 and LDAP.
It will remove groups from the G3 database if they do not exist in identity.php and will add them to the G3 database if they exist in identity.php but not in the database.
I've confirmed that it works correctly. Now to port it to PHP.
I will work on my first commit this weekend.
See attached for a peek.
-Brian
Posts: 7985
The bash code looks roughly right. Looking forward to seeing it in PHP!
---
Problems? Check gallery3/var/logs
bugs/feature req's | upgrade to the latest code | use git
Posts: 1
I followed the updated version and changed LDAP module according my AD environment,and installed it to gallery3/modules folder,but when I enable LDAP module ,I got the following message:
The following issue(s) have been identified:
Are you sure you want to change your Identity Provider? Continuing will delete all existing users.
when I clicked continue,the LDAP moudle was activated,but I could not login with any accounts(AD and local accounts),and when I checked MySQL gallery3 database,I found two tables "users" and "groups" were droped by LDAP moudle.
so I just want to know,is it normal? how to install LDAP moudle correctly?
Any advice will be appreciated.
Wade
Posts: 7985
@brianmiller: any progress?
@wadewell: You're following the right process, but it's hard to say what's going wrong. Can you let us know what's in your gallery3/var/logs logfiles?
---
Problems? Check gallery3/var/logs
bugs/feature req's | upgrade to the latest code | use git
Posts: 4
i have run into the same problem as @wadewei. i think the gallery3-contrib/3.0/modules/ldap installation process in borked.
installation fails with:
2010-12-01 02:00:42 +02:00 --- error: Kohana_PHP_Exception [ 64 ]: Cannot make non static method IdentityProvider_Driver::add_user_to_group() static in class IdentityProvider_Ldap_Driver
/secure/home/httpd/htdocs/gallery3/modules/ldap/libraries/drivers/IdentityProvider/Ldap.php [ 20 ]
#0 [internal function]: Kohana_PHP_Exception_Core::shutdown_handler(NULL)
#1 /secure/home/httpd/htdocs/gallery3/system/core/Event.php(208): call_user_func_array(Array, Array)
#2 /secure/home/httpd/htdocs/gallery3/system/core/Kohana.php(549): Event_Core::run('system.shutdown')
#3 [internal function]: Kohana_Core::shutdown()
#4 {main}
this leaves the installation hosed. i will have to re-do G2 import now, will know now better to take sqldumps. wasn't really expecting plugins to delete any existing data.. how is that good design again?
Posts: 7985
@lkraav: unofficial modules are dangerous and your mileage will vary. Furthermore, when you switched to it there was a big warning message (http://gallery.menalto.com/node/97018#comment-349769) that should make you think twice. If you're unhappy with our design choices, propose some new ones and help us improve the product. Else, you get what you pay for.
In the meantime, I just pushed a fix to the contrib ldap module to get rid of the PHP Exception you're seeing.
---
Problems? Check gallery3/var/logs
bugs/feature req's | upgrade to the latest code | use git
Posts: 4
re patches-welcome: absolutely, i will contribute. i only just got into looking at g2->g3 and there are only so many free work products i can concurrently support as well.. "good design?" question was somewhat more of a "although i think understand this correctly, do i really?" random thought. thanks for the push.
Posts: 7985
Awesome, thanks lkraav!
---
Problems? Check gallery3/var/logs
bugs/feature req's | upgrade to the latest code | use git