Access Denied error when running job in SQL Server Agent - sql-server

I am trying to get SQL Server Agent to run a program with arguments (as a Operating system CmdExec job step), but everytime it runs the job I receive the following error: The process could not be created for Step 1 of job, reason: Access is denied).
The research I did online indicated that this could be a permissions issue. I set up a new user account in Windows and gave it full permissions on the program I wanted to run, then mapped this user profile to the SQLSERVERAGENT profile within MS SQL but I still get this error.
Any help with this would be appreciated.

above steps worked for me
Enable XP_cmdshell
EXEC sp_configure 'show advanced options', 1
GO
RECONFIGURE
GO
EXEC sp_configure 'xp_cmdshell', 1
GO
RECONFIGURE
GO
Create credential
CREATE CREDENTIAL cmdshell_agent WITH IDENTITY = 'account_name', SECRET = 'password';
GO
Create proxy
USE [msdb]
GO
EXEC msdb.dbo.sp_add_proxy #proxy_name=N'tst_Proxy',#credential_name=N'cmdshell_agent', #enabled=1
GO
EXEC msdb.dbo.sp_grant_proxy_to_subsystem #proxy_name=N'tst_Proxy', #subsystem_id=3
GO
After this use tst_proxy in the sql agent job to run the job. Job ran successfull

I had the same problem, and the solution was embarrassingly simple: my path to the .exe was off. It's a little confusing that this reflects as an "Access Denied" error (because the Agent account doesn't really know that the file doesn't exist, just that it can't reach such a file).
One simple step you can take while troubleshooting is to run the exact command in a command window. Does it work as expected? How about if you log in using the Agent account?

First you'll need to make sure that XP_CMDSHELL is allowed.
exec sp_configure 'xp_cmdshell',1
go
reconfigure
You'll need to create a credential with the user you created.
Create a proxy referencing the credential you created. Give this proxy access to the "Operating System(CmdExec)" subsytem.
In the job step itself, make sure that it is executing as this proxy (Run as:).

Got the same error message. It turned out that the SQL Agent account did not have permissions on the Tools directory where sqlcmd.exe is located. Gave Read & Execute permissions to the SQL Agent Account, problem solved.

If you're running into this issue with SQL 2014 Maintenance Plans, even if the RunAs account and service accounts are fine (as confirmed in EXECUTE AS testing), then try the following:
Check the Local Connection authentication in the Maintenance Plan.
if it's set to an account & it's appropriate to do so, switch to Windows NT Authentication, save out the plan
if it's already on WinNT, switch to an account, save out the plan, go back in, switch to Windows NT Authentication, save out the plan again.
There was no logging anywhere that would catch this.  I was just thinking where else authentication could be involved, since the failures were around that, but everything was set up properly everywhere else....
As Grandma would say:  "It's always in the last place you look".  😏

We need to make sure that the account through which the job is being executed has full access to the folders/document involved in the job steps.
This should resolve the issue without adding the proxy.

Related

Database mail is not working in SQL Server

I have created a proc to send mail with attachment (attachment is from query result)
while running manually it working fine
Scheduled proc using Job. Where in job it is not sending any mail. Also job is not failing
Checked in sysmail_allitems but there is no entry for job mails but for manual run I can find entry.
I suspect some permission issue on service account which runs job.
Sending emails through the database requires some special privileges, it's likely that the account the Job executes under doesn't have them.
Check which SQL account is executing the job, then execute:
EXECUTE AS LOGIN = 'TheSQLLoginHere';
EXEC mySendMailSP;
You will see the missing privileges there. You can either supply them or change the account for that Job.

Execute SSIS package with proxy account from command line

I need to run SSIS2016 package from older SSIS (another server) because of extending legacy system. The package runs fine from SQL Agent, but I am unable to run it using tsql or DTEXEC. The problem is that package is unable to access network even when run in elevated cmd (under sysadmin)
I am able to access network drive from account I am running package (admin)
I know that package runs fine when it is run from Sql agent under same account.
The package runs fine when file is saved to local temp folder (both DTEXEC and TSQL)
The package fails to save file to network when run using execute is SSMS, TSQL or DTEXEC.
DTEXEC /ISSERVER "\SSISDB\XXXX\Exports\package.dtsx" /SERVER "." /Par
"$Package::FilePath(String)";"C:\TEMP"
From all what I have read on internet, it seems that the only way to run SSIS2016 package is by using SQL Agent and jobs.
I am surprised by the fact that DTEXEC ignores the security context of account which execute the command line.
Is there a way to force it to use proxy account?
I find it hard to believe, that only way to run package with permission to network is to use Sql agent and jobs.
Thank you.
p.s. Here is good article about running packages, but it completely omits network access problem.
EDIT 2019-06-10
I applied MSSQL2016 CU7 and restarted the server.
After this,
Iam able to save file to network using DTEXEC command ran on local server (logged as sysadmin)
Iam able to save file to network using sp ran from local server (logged as sysadmin)
I cant save file to network drive when logged as sysadmin on different machine. The error is
Flat File Destination failed the pre-execute phase and returned error
code 0xC020200E.
Cannot open the datafile ..
there is also warning "Access is denied" in data flow which should save the file.
Source code of stored procedure
DECLARE #execution_id BIGINT;
EXEC [SSISDB].[catalog].[create_execution]
#package_name = N'package.dtsx',
#execution_id = #execution_id OUTPUT,
#folder_name = N'XXXX',
#project_name = N'Exports',
#use32bitruntime = False,
#reference_id = NULL;
SELECT #execution_id;
DECLARE #var0 SQL_VARIANT = N'\\NETWORK\PATH\Export\test_files';
EXEC [SSISDB].[catalog].[set_execution_parameter_value]
#execution_id,
#object_type = 30,
#parameter_name = N'FilePath',
#parameter_value = #var0;
DECLARE #var1 SMALLINT = 1;
EXEC [SSISDB].[catalog].[set_execution_parameter_value]
#execution_id,
#object_type = 50,
#parameter_name = N'LOGGING_LEVEL',
#parameter_value = #var1;
EXEC [SSISDB].[catalog].[start_execution]
#execution_id;
I also added System::UserName to log on start of package and I see correct account.
I assume, that problem might be in double hop as #Piotr mentions.
Iam digging the fileserver logs to see.
EDIT2 2019-06-10
Ok. After much dancing around I can narrow problem down to delegation executing user rights to CIFS.
What i did
Setup a share on dev computer
Create package with scriptask which tries to create test file and get security context of calling user WindowsIdentity.GetCurrent().Name
Then I ran stored procedure with code above in scenario that always ended by access denied.
Until I enabled anonymous access (using this article), the package was not able to save file.
AFAIK we have enabled only MSSQLSvc kerberos delegation.
Closure:
The problem is caused by behaviour of SSIS catalog, when called from TSQL, which gets users security context, but in order to work this properly, when accessing netwrok shares, you need to setup Kerberos delegation for CIFS also.
I was not able to do this in our environment, so I reverted back to xp_cmdshell.
Thanks to all for support.

What permissions do you need to run jobs via SQL Agent?

I've googled my issue all weekend, but can't seem to solve the problem
So basically, I have a query, when I run it manually in a query window, it works fine and my job executes, resulting in an email being sent. However, when I set up a schedule, I get the following error:
If you can't read it, the error message says,
"The job failed. The job was invoked by Schedule 9. The last step to run was step 1."
Then underneath it says,
"Executed as user 'adminName(not sa)'. Failed to initialize sqlcmd library with error number -2147467259 (SQLSTATE 42000) (Error 22050). The step failed"
So I log in with user sa, and apparently this user needs to have SQL Agent permissions in the msdb database. According to this screenshot, sa is the owner:
So since sa is the owner, it would mean it has all the SQL Agent related permissions, right? Furthermore, the code I'm using executes from the CompanyDB, so I think perhaps this may be the issue. If I look at properties, under sa, I get this window:
So the CompanyDB is unchecked for user sa, so in order to allow sa to query CompanyDB in SQL Agent, what permissions would it need? I'm assuming this is the issue, but I'm not really sure, I can't seem to figure it out, any help is greatly appreciated.
Jobs should have dbAdmin permissions. That being said, it depends on whether you wrote to the db, update, or just send the email.
The better option would be to create a webservice and call it when you want to send the email.

Login failed for user 'NT AUTHORITY\ANONYMOUS LOGON' - MS SQL Server - possibility of being unable to solve the issue

Why not asking on dba.stackexchange: the description says it is for professionals, which I am not and SO has its "for enthusiasts" part.
I have an error
"Login failed for user 'NT AUTHORITY\ANONYMOUS LOGON'"
This is a common error with several possible reasons and solutions. The problem is that I have no knowledge of the database and server administration and credentials authentication topics, thus I will need to spend some significant time understanding what is being said and proposed.
Before I do that I would like to ask if it might be possible for me not to be able to solve the problem due to technical limitations. I will describe the situation in more detail now.
There is an MS SQL Server A with database Adb and table dbo.At. I can read from it. There is also an MS SQL Server B. I can read and write here.
I have MS SQL Server Management Studio 2012 open on my computer. I have a connection with server A open with query "select * from Adb.dbo.At" which works just fine. The connection used Windows Authentication.
I have a connection with server B (Windows Authentication as well) with query "select * from A.Adb.dbo.At" which results in the aforementioned error.
At this point I do have read access to A, I have read and write access to B. I can export data from A and then import it to B using my computer, i.e. I can do a kind of a copy paste and I will end up having what I want. There is no insurmountable wall between these 2 servers with me being the middle man. I simply would like to make it easier. Before I dwell on SPNs, delegations, Kerberos, Active Directory and whatnot I would like to ask if, assuming that I have nothing more than read on A and read/write on B, I might not be able to solve the issue?
It seems I have a "double hop" problem.
https://blogs.technet.microsoft.com/askds/2008/06/13/understanding-kerberos-double-hop/
I have found a workaround. I can use Server Agent on server B. Using this I can use the server to perform some actions, for example query other servers. The Agent jobs are of a specific type (like T-SQL script). For specific job types the Agent can run the jobs in "run as" mode (requires a proxy). I created a proxy referring to my normal Windows login. Sadly T-SQL script type job cannot be executed in "run as" mode. But PowerShell type job can. PowerShell can also execute SQL statements. Thus I have created PowerShell job running with proxy with the command being:
SQLCMD -Q "select * into Bdb.dbo.Bt from A.dbA.dbo.At" -E
This solved my problem.

Service Broker queue message [duplicate]

I am learning how to use the Service Broker of SQL Server 2008 R2. When following the tutorial Completing a Conversation in a Single Database. Following the Lesson 1, I have successfully created the message types, contract, the queues and services. Following the Lesson 2, I have probably sent the message. However, when trying to receive the message, I get the NULL for the ReceivedRequestMsg instead of the sent content.
When looking at the sys.transmission_queue, the transmission_status for the message says:
An exception occurred while enqueueing a message in the target queue. Error: 15517, State: 1. Cannot execute as the database principal because the principal "dbo" does not exist, this type of principal cannot be impersonated, or you do not have permission.
I have installed SQL Server using the Windows login like Mycomp\Petr. I am using that login also for the lessons.
Can you guess what is the problem? What should I check and or set to make it working?
Edited 2012/07/16: For helping to reproduce the problem, here is what I did. Can you reproduce the error if you follow the next steps?
Firstly, I am using Windows 7 Enterprise SP1, and Microsoft SQL Server 2008 R2, Developer Edition, 64-bit (ver. 10.50.2500.0, Root Directory located at C:\Program Files\Microsoft SQL Server\MSSQL10_50.SQL_PRIKRYL05\MSSQL).
Following the tutorial advice, I have downloaded the AdventureWorks2008R2_Data.mdf sample database, and copied it into C:\Program Files\Microsoft SQL Server\MSSQL10_50.SQL_PRIKRYL05\MSSQL\DATA\AdventureWorks2008R2_Data.mdf
The SQL Server Management Studio had to be launched "As Administrator" to be able to attach the data later. Then I connected the SQL Server.
Right click on Databases, context menu Attach..., button Add..., pointed to AdventureWorks2008R2_Data.mdf + OK. Then selected the AdventureWorks2008R2_Log.ldf from the grid below (reported as Not found) and pressed the Remove... button. After pressing OK, the database was attached and the AdventureWorks2008R2_log.LDF was created automatically.
The following queries were used for looking at "Service Broker enabled/disabled", and for enabling (the Service Broker was enabled successfully for the database):
USE master;
GO
SELECT name, is_broker_enabled FROM sys.databases;
GO
ALTER DATABASE AdventureWorks2008R2
SET ENABLE_BROKER
WITH ROLLBACK IMMEDIATE;
GO
SELECT name, is_broker_enabled FROM sys.databases;
GO
Then, following the tutorial, the queries below were executed to create the message types, the contract, the queues, and the services:
USE AdventureWorks2008R2;
GO
CREATE MESSAGE TYPE
[//AWDB/1DBSample/RequestMessage]
VALIDATION = WELL_FORMED_XML;
CREATE MESSAGE TYPE
[//AWDB/1DBSample/ReplyMessage]
VALIDATION = WELL_FORMED_XML;
GO
CREATE CONTRACT [//AWDB/1DBSample/SampleContract]
([//AWDB/1DBSample/RequestMessage]
SENT BY INITIATOR,
[//AWDB/1DBSample/ReplyMessage]
SENT BY TARGET
);
GO
CREATE QUEUE TargetQueue1DB;
CREATE SERVICE
[//AWDB/1DBSample/TargetService]
ON QUEUE TargetQueue1DB
([//AWDB/1DBSample/SampleContract]);
GO
CREATE QUEUE InitiatorQueue1DB;
CREATE SERVICE
[//AWDB/1DBSample/InitiatorService]
ON QUEUE InitiatorQueue1DB;
GO
So far, so good.
Then the following queries are used to look at the queues (now empty when used):
USE AdventureWorks2008R2;
GO
SELECT * FROM InitiatorQueue1DB WITH (NOLOCK);
SELECT * FROM TargetQueue1DB WITH (NOLOCK);
SELECT * FROM sys.transmission_queue;
GO
The problem manifests when the message is sent:
BEGIN TRANSACTION;
BEGIN DIALOG #InitDlgHandle
FROM SERVICE
[//AWDB/1DBSample/InitiatorService]
TO SERVICE
N'//AWDB/1DBSample/TargetService'
ON CONTRACT
[//AWDB/1DBSample/SampleContract]
WITH
ENCRYPTION = OFF;
SELECT #RequestMsg =
N'<RequestMsg>Message for Target service.</RequestMsg>';
SEND ON CONVERSATION #InitDlgHandle
MESSAGE TYPE
[//AWDB/1DBSample/RequestMessage]
(#RequestMsg);
SELECT #RequestMsg AS SentRequestMsg;
COMMIT TRANSACTION;
GO
When looking at the queues, the Initiator... and the Target... queues are empty, and the sent message can be found in sys.transmission_queue with the above mentioned error reported via the transmission_status.
alter authorization on database::[<your_SSB_DB>] to [sa];
The EXECUTE AS infrastructure requires dbo to map to a valid login. Service Broker uses the EXECUTE AS infrastructure to deliver the messages. A typical scenario that runs into this problem is a corporate laptop when working from home. You log in to the laptop using cached credentials, and you log in into the SQL using the same Windows cached credentials. You issue a CREATE DATABASE and the dbo gets mapped to your corporate domain account. However, the EXECUTE AS infrastructre cannot use the Windows cached accounts, it requires direct connectivity to the Active Directory. The maddening part is that things work fine the next day at office (your laptop is again in the corp network and can access to AD...). You go home in the evening, continue with Lesson 3... and all of the sudden it doesn't work anymore. Make the whole thing seem flimsy and unreliable. Is just the fact that AD conectivity is needed...
Another scenatio that leads to the same problem is caused by the fact that databases reteint the SID of their creator (the Windows login that issues the CREATE DATABASE) when restored or attached. If you used a local account PC1\Fred when you create the DB and then copy/attach the database to PC2, the account is invalid on PC2 (it is scoped to PC1, of course). Again, not much is affected but EXECUTE AS is, and this causes Service Broker to give the error you see.
And last example is when the DB is created by a user that later leaves the company and the AD account gets deleted. Seems like revenge from his part, but he's innocent. The production DB just stops working, simply because it's his SID that the dbo maps too. Fun...
By simply changing the dbo to sa login you fix this whole EXECUTE AS thing and all the moving parts that depend on it (and SSB is probably the biggest dependency) start working.
You would need to grant receive on your target queue to your login. And it should work!
USE [YourDatabase]
GRANT RECEIVE ON [dbo].[YourTargetQueue]
TO [Mycomp\Petr];
GO
And you also need to grant send for your user, permission on Target Service should be sufficient, but let's enable on both services for the future.
USE AdventureWorks2008R2 ;
GO
GRANT SEND ON SERVICE::[//AWDB/1DBSample/InitiatorService]
TO [Mycomp\Petr] ;
GO
GRANT SEND ON SERVICE::[//AWDB/1DBSample/TargetService]
TO [Mycomp\Petr] ;
GO

Resources