On a site running pathauto, ldap_integration, and securesite, new users initially receive an "Access Denied" page when trying to access the site home page on initial account creation/log in. Reloading the page makes it display fine. I've traced this problem back to (possibly) pathauto. For securesite and ldap_integration to work well together, I use the patch from http://drupal.org/node/97197#comment-467296. Thus, the user registration process goes something like this:
1) User accesses site
2) User gets HTTP auth dialog
3) User submits credentials
4) Securesite.module calls _ldapauth_user_authenticate(), which is pretty much like user_authenticate, but without requiring @address in the user name for external (LDAP) users
5) _ldapauth_user_authenticate() calls _ldapauth_save_user(), which calls user_save()
6) user_save() fires hook_user(), which fires pathauto_user()
7) pathauto_user() calls pathauto_create_alias(), which calls _pathauto_set_alias(), which calls _pathauto_path_is_callback(), which calls menu_get_menu()
8) menu_get_menu() builds the menu (and associated permissions), but *doesn't* use the normal user access checks and does some magic instead
So, it's really somewhere in menu.inc where the permission fails (and I can't figure out which permission it is). The problem seems to be that the global $user isn't updated until after user_save() returns, which won't happen until after the menu is built. At that point, the user has already been denied access, thus they can't access the site without reloading the page.
My current work-around is to add a 'global $user' in user_save() before hook_user($op = 'insert') is fired. Thus, the global $user variable (used by the menu code) has the current user object before user_save() returns and everything works fine. But that's a big, ugly hack and I'd rather find a better solution.
Granted, I'm not sure this problem is in pathauto, but it does trigger it. Disabling pathauto solves this issue.
| Comment | File | Size | Author |
|---|---|---|---|
| #12 | contrib-5.securesite.access-denied2.junyor.patch | 2.01 KB | junyor |
| #10 | contrib-5.securesite.access-denied.junyor.patch | 1.85 KB | junyor |
| #10 | contrib-5.securesite.access-denied-install.junyor.patch | 269 bytes | junyor |
| #3 | pathauto_user_access_denied_secure_193733.patch | 899 bytes | greggles |
Comments
Comment #1
gregglesWhat about adding the global $user into the pathauto_user hook? If that fixes it then it's small enough that it seems like a reasonable solution.
I also wonder if/how this works in D6 where the menu was pretty well re-worked...?
Comment #2
junyor commentedYes! That took care of it. Thank you! I put the "global $user" at the top of the function.
Comment #3
gregglesApplied to DRUPAL-5--2.
Needs to be applied to HEAD.
Comment #4
gregglesit seems I forgot to commit this to the 5.x branch but just committed it there as well...
Comment #5
(not verified) commentedAutomatically closed -- issue fixed for two weeks with no activity.
Comment #6
gregglesI think this actually broke the scenario of admins editing someone else's username - http://drupal.org/node/214724
Can we (you) fix this in core instead? Otherwise, can you come up with a patch that will fix this in Pathauto without messing up that scenario? It's hard for me to test this (no access to an ldap server that I know of) so I'm really hoping you can help. Thanks.
Comment #7
junyor commentedYes, I'll give this some more thought. Do you know why that bug occurred?
Comment #8
gregglesat least partially because $user is a variable in the function signature, which gets passed the $user for the hook_user operation which we then promptly replaced with the global $user. It may be sufficient to change $user to $account in the function signature and then elsewhere throughout the function.
Comment #9
junyor commentedI've just confirmed that the same problem will happen when using securesite.module and drupal.module for external user authentication. That may provide a setup you can use to replicate the problem. I'll continue to investigate this issue. I see two solutions right now:
1) Change the way pathauto creates the alias, i.e. doing it maybe on hook_user register instead of hook_user insert.
2) Further debug securesite.module to see if the global $user var is set when it shouldn't be, causing the menu building to trigger for the wrong user.
Comment #10
junyor commentedAttached is a new attempt to fix this bug. Additional investigation today (thank you, greggles!) showed that the problem was caused by Securesite using 'global $user' in securesite_init(), then not updating the $user object until after hook_user insert was called. This patch is a bit of a hack, since it adds a boolean to the $user object to determine if Securesite initiated authentication, then updates the global $user object in hook_user if the boolean is TRUE. I'll continue testing, but I believe this takes care of the problem with no ill effects, just ugly code. So hook_user in securesite fires before hook_user in pathauto, I'm updating the weight of securesite in securesite.install, which is also attached.
Comment #11
junyor commentedActually, the install file shouldn't be necessary as pathauto should use weight = 1. In my install, its weight is 0 for some reason.
Comment #12
junyor commentedUpdated patch to latest DRUPAL-5 branch.
I'm really not happy with this hack and no one else seems to have run into this, so I'm going to mark this wontfix for now and just apply the patch locally for the site that's having this problem.