Search code examples
sql-serverpermissionsjobs

Job (step) fails when run as dbo(sa?)


I create a job. I add a single step with the following code:

insert joblog select getdate(),SUSER_NAME(),current_user    
exec msdb.dbo.sp_send_dbmail ...

The job's owner is sa. I, as a dev, do not have sa access, but I do have sysadmin. So I change the job's owner to sa.

The job runs fine and the email gets sent. The [joblog] table which I have created to help me understand things shows

suser_name=NT SERVICE\SQLSERVERAGENT
current_user=dbo

Now if I go to the agent's UI, edit the (single) job step, choose page "advanced", and fill the "Run as user" to "dbo", I receive EXECUTE denied on sp_send_dbmail. [joblog] gets one line with

susername=sa
current_user=dbo

What is the reason for the error? sa obviously can run the proc. Not only that; NT SERVICE\SQLSERVERAGENT also can!

My wild guess is that despite the suser_name inserted in my table, the "run as user" "chooses" dbo as a user in the target db but without any login associated with it, not even NT SERVICE\SQLSERVERAGENT.


Solution

  • When impersonating a USER, in this case dbo, then any external database references will fail. A USER is a database object, and so your impersonation is limited to being scoped within the database. As you are attempting to reference msdb.dbo.sp_send_dbmail you are, presumably, using 3 part naming as your aren't in msdb (which I wouldn't expect you do, as you are INSERTing into a table, and that shouldn't really be done in a system database).

    As for why you get sa, that's because that's the LOGIN that the dbo USER is linked to. If the dbo user was linked to a different LOGIN you would get a different LOGIN's name. This does not, however, mean that you can impersonate that LOGIN by impersonating a USER; you strictly cannot do this. As the OP mentions is the comments, this is documented.

    The "fix" would be that if you need impersonation, you impersonate a LOGIN, not a USER, that has access to all the databases you need to access for the specific job.