I don't know if it should be like this. When I'm trying to do anything with xp_cmdshell procedure it almost every time gives me Access Denied.
For example I can't create new .txt file, can't create new user, nothing. I'm logged in with windows administrator user.
Is there any way to run this procedure with administrator privileges?
XP_CmdShell will execute under the context of the Service Account running the SQL Server Service. The service account needs the permissions to the external resources.
Could I point out however, that enabling xp_cmdshell is not a good idea. It opens lots of security holes. For example, if your app has an unknown volnerability to SQL injection, a hacker could do all sorts on your network that you rather avoid.
If you must use external resources then better approaches would include a CLR procedure or calling a Job that executes a CMDEXEC step.
xp_cmdshell executed by a windows login is executing under an impersonation context. as such any access of a remote resource (eg. access a file on a share, an operation on AD like adding an user) will fall under the constrained delegation restrictions, likely resulting in a access denied because constrained delegation is probably not to be configured on all those resources.
Related
I have a requirement to give a functionality for a non technical user to run the Agent job / stored procedure. It's just one stored procedure.
I do not want to the user to install SQL Server, nor do I want to give him any additional permissions. Indirect permissions (proxy or running through a server) are fine as long as the user won't be able to see the password.
I believe Osql does this but then I have to type username n password in batch file and that compromises security.
Is there any other way? Can this be achieved with SSRS?
To cut through you can script SP execution with Powershell and use integrated security to authenticate user on SQL server. Check this thread how to do that.
Please keep in mind that giving direct access to SQL server is a bad idea from security perspective, so you must limit its permissions with a specific role and grant execution only for that particular procedure.
Alternative to #Illia way is to create a simple web-app with (say) .net. It's probably less than 15 mins task for a .net developer to connect to SQL server and provide a button to execute one or more stored procedures. You can manage the access via integrated security of the app specific user id and password and is probably more easy for a non-tech user. See here.
I was finally able to achieve with less overhead using a SSRS report. Created a report to run the Stored proc whenever the report is opened. This way I was able to achieve the security part too. Thanks for the answers everyone.
Variations to this have been asked. I have no problem searching a local directory with the below piece of code.
EXEC MASTER.sys.xp_dirtree 'C:\', 1, 1
When I switch the path to a network location the results are empty.
EXEC MASTER.sys.xp_dirtree '\\Server\Folder', 1, 1
I first thought maybe it was something to do with permissions. I added the SQL Server Service to the ACL list on the shared volume as well as the security group.
Any help or direction to point me in is greatly appreciated or even another way to get a list of files in a directory and sub directories.
[Edited]
The two things to look out for are:
Make certain that the Log On account for the SQL Server service (the service typically listed as "SQL Server (MSSQLSERVER)" in the Services list) has rights to that network share.
UPDATE
The problem ended up being that the O.P. was running the SQL Server service as a local system account. So, the O.P. created a domain account for SQL Server, assigned that new domain account as the Log On As account for the SQL Server service, and granted that domain account the proper NTFS permissions.
Please note that this might have also been fixable while keeping the SQL Service running as a local system account by adding the server itself that SQL Server is running on to the NTFS permissions. This should usually be possible by specifying the server name followed by a dollar sign ($). For example: MySqlServer01$. Of course, this then gives that NTFS permission to all services on that server that are running as a local system account, and this might not be desirable. Hence, it is still preferable to create a domain account for the SQL Server service to run as (which is a good practice in any case!).
It sounds like this has been done, so it should be tested by logging onto windows directly as that account and attempting to go to that specific network path.
Make sure that the Login in SQL Server that is executing xp_dirtree has "sysadmin" rights:
This can be done directly by adding the account to the sysadmin server role, or
Sign a stored procedure that runs xp_dirtree:
Create a certificate in [master]
Create a login based on that certificate
Add the certificate-based login to the sysadmin server role
Backup the certificate
Restore the certificate into whatever database has, or will have, the stored procedure that runs xp_dirtree
Sign the stored procedure that runs xp_dirtree, using ADD SIGNATURE and the certificate that was just restored
GRANT EXECUTE on that stored procedure to the user(s) and/or role(s) that should be executing this.
Just to have it stated, another option is to do away with xp_dirtree altogether and instead use SQLCLR. There is probably sample C# code on various blogs. There are also a few CodePlex projects that have file system functions and might also provide a pre-compiled assembly for those that don't want to deal with compiling. And, there is also the SQL# library that has several filesystem functions including File_GetDirectoryListing which is a TVF (meaning: you can use it in a SELECT statement with a WHERE condition rather than needing to dump all columns and all rows into a temp table first). It is also fully-streamed which means it is very fast, even for 100k or more files. Please note that the FILE_* functions are only in the Full version (i.e. not free) and I am the creator of SQL#, but it does handle this situation quite nicely.
In the past this command would work:
EXEC [linkedServerName].msdb.dbo.sp_start_job #job_name = 'test2'
Now I have to use the impersonate login and add the SQL service account (referenced in local login to impersonate) of calling server onto called server and giving it SA privilege: think I am doing something wrong, it shouldn't be so complicated should it?
Without the SA privilege on the impersonating account added to the remote server I receive error:
The EXECUTE permission was denied on the object 'sp_start_job', database 'msdb', schema 'dbo'.
Thank you
it shouldn't be so complicated should it?
This isn't any more complicated than the task you're doing. It's pretty basic security. If you want an account to be able to do things on a server, the account needs to have the proper access to that server. I'm not sure why you think it should be otherwise. Setting up proxy accounts isn't the most straightforward, but scheduling jobs from a remote server instead of the local agent isn't the most straightforward task, either.
Per the doc a user needs to be a member of the sysadmin, SQLAgentUserRole, SQLAgentReaderRole, or SQLAgentOperatorRole to be able to call sp_start_job.
The alternative is to configure the linked server to use a fixed security context or map a security context instead of impersonating one. This can be configured on the Security page of the Linked Server properties. Note that the account used for a fixed context still needs to be a member of one of the above roles to execute sp_start_job.
I've got an application which is running under under the credentials of the local user. However, I would like to allow this application access to a MSSQL database using specific credentials.
This isn't a problem if I use an SQL login, however I would like to use a specific Windows account for which I have the username (along with the domain) and password. Note that I do NOT wish to run the entire application using these credentials.
Is this at all possible? This SO question seems to suggest that using Integrated Security=SSPI in the connection string WITH Windows credentials specified will allow me to login to the database as that user, however I was not able to do this on my test machine.
Given how the SQL Server Management Studio logs into databases (i.e. it uses the current credentials or specified SQL credentials, but doesn't seem to permit specified Windows credentials) I'm thinking this cannot be done, but I would like a confirmation of this...
You could deal with this as the SQL Server end
by encapsulating the tasks that need done under the other account in a stored procedure created using the "EXECUTE AS Clause"
Create Proc sp_Dosomething_As_specific_user
WITH EXECUTE AS '{SpecificUser}'
BEGIN
/*Do Something*/
END
and allow the user account execute permissions on that
GRANT EXEC ON sp_Dosomething_As_specific_user TO {Actual_User}
For fuller details on the "EXECUTE AS" clause look at this
http://msdn.microsoft.com/en-us/library/ms188354.aspx
This means that you've limited the user to running only a specifically predefined action or set of actions as the other user as opposed to a general permission to let them impersonate the other user
Which is going to help keep whoever is responsible for IT security happy
I'm trying to set up a CLR stored procedure to be run from a service broker queue so that the CLR stored procedure runs as the database owner.
I've tried all sorts of combinations but can't get this to work without logging in as the user (with username and password) in the CLR stored procedure.
The CLR Stored procedure is accessing the file system and I only want it to be able to access folders allowed for the windows user that owns the database.
You will never be able to access resources outside SQL Server without providing the password to Windows. EXECUTE AS is only trusted inside the engine, Windows (and hence the file system) has absolutely zero reasons to trust this impersonation sham.
There is one special construct in SQL to facilitate impersonation at os level: CREATE CREDENTIAL, but they work only when mapping a SQL login to a Windows login. Since in your case there is no SQL login to start with, I'm not sure whether you can get SQL Server credentials to work.