I just had user 1 getting an 'access denied' error. This shouldn't happen by definition, but finding out where it came from was a bit of a pain, so I wrote the following function:

/**
 * Implementation of hook_watchdog().
 * 
 * If an 'access denied' error is logged for user 1, then something is
 * seriously wrong: provide a backtrace so the user can see where the
 * error is generated.
 */
function devel_watchdog($log_entry) {
  if ($log_entry['type'] == 'access denied' && $log_entry['user']->uid == 1) {
    $trace = debug_backtrace();
    // Pop the stack up to the drupal_access_denied() call.
    while (isset($trace[0]) && (empty($trace[0]['function']) || $trace[0]['function'] != 'drupal_access_denied')) {
      array_shift($trace);
    }
    dsm($trace, t('ACCESS DENIED error generated for user 1, backtrace'));
  }
}

Could this be generally useful enough to go into Devel? I don't think it would need a setting to enable/disable, it could be active all of the time.

(Would be nice if we could commit #498028: kprint_r omits name on krumo output so that the introductory line ($name in dsm()) is actually displayed...)

Comments

robertjd’s picture

Hi salvis, I am experiencing a problem where user 1 is getting access denied while trying to login. I would like to try this function you have written but I am not familiar with the devel module, could you let me know where this function should be placed?

Cheers,
Robert

salvis’s picture

Anywhere in the devel.module file, e.g. append it at the end.

Let us know how it goes.

robertjd’s picture

Thanks salivs.

It turns out my error is coming through with a uid of 0, had to drop the test on uid in your if to see that. I've pasted the $log_entry below. I don't get any traceback information printed to output. The problem is this: when admin tries to login using Firefox they are logged in (and a session created), but then upon redirect to user/1, they get the access denied.

Array
(
    [type] => access denied
    [message] => user/1
    [variables] => 
    [severity] => 4
    [link] => 
    [user] => stdClass Object
        (
            [uid] => 0
            [hostname] => ::1
            [roles] => Array
                (
                    [1] => anonymous user
                )

            [session] => 
            [cache] => 0
        )

    [request_uri] => http://localhost/jb/user/1
    [referer] => http://localhost/jb/user/login
    [ip] => ::1
    [timestamp] => 1256224300
)
salvis’s picture

The backtrace is displayed only for users with the 'access devel information' permission.

Your problem may be caused by not accepting cookies. However, this is outside of the scope of this issue.

kabarca’s picture

This is an old post but just for the records, there's a module we have build that allow you to backtrace your code and see where the access denied happened http://drupal.org/project/adb

salvis’s picture

Status: Needs review » Closed (won't fix)

kabarca: The description of your adb module says it works only for nodes. If you get Access Denied for nodes, you want to know why -- where rarely gives you any useful information.

For the why, we have the Devel Node Access module, which is part of Devel.

I started this issue because my user 1 got Access Denied on a non-node page, which was a bit hairy to trace back to its source, especially without a debugger. For those rare cases we now have the Fix Core module.

And it really happens very very rarely, so it's not an issue for Devel anymore.