sql server sp_send_dbmail - sql-server

I am using SQL Server's sp_send_dbmail stored procedure to send mail via the database.
But when I execute that procedure it's shutting down the db mail procedure. I tried to start it again by sysmail_start_sp. But it's again shutting down in 7-8 seconds.
I tried with the code below:
EXEC msdb..sp_send_dbmail #profile_name = 'Test',
#recipients = 'abc#gmail.com',
#subject = 'test mail',
#body_format = 'HTML',
#body = 'test mail',
#from_address = 'xyz#yahoo.com'
When I tried to check the error log I found the below error:
Message:
The read on the database failed. Reason: The error description is
'Whitespace is not allowed at this location.'.Data:
System.Collections.ListDictionaryInternalTargetSite:
Microsoft.SqlServer.Management.SqlIMail.Server.Objects.QueueItem
GetQueueItemFromCommand(System.Data.SqlClient.SqlCommand)HelpLink:
NULLSource: DatabaseMailEngineStackTrace
Information===================
Also when I checked sql email log history I found this error:
Mail not queued. Database Mail is stopped. Use sysmail_start_sp to start Database
Mail.

Whenever you try to send Test mail from Database mail; it throws below error message:
Msg 14641, Level 16, State 1, Procedure sp_send_dbmail, Mail not
queued. Database Mail is stopped. Use sysmail_start_sp to start
Database Mail.
First of all make sure that Service Broker Message Delivery in Databases is enabled by executing the following command in SSMS:
SELECT is_broker_enabled FROM sys.databases WHERE name = 'msdb'
If the result of above query is 0, then activate the service broker.
Activating Service Broker allows messages to be delivered to the database. A Service Broker endpoint must be created to send and receive messages from outside of the instance.
To activate Service Broker in a database use the following command:
USE master ;
GO
ALTER DATABASE DatabaseName SET ENABLE_BROKER ;
GO
If the Service Broker is enabled then confirm whether Database Mail is enabled or not by executing below queries in SQL Server Management Studio:
sp_configure 'show advanced', 1
GO
RECONFIGURE
GO
sp_configure
GO
If the result set shows run_value as 1 then Database Mail is enabled.
If the Database Mail option is disabled then run the below queries to enable it:
sp_configure 'Database Mail XPs', 1;
GO
RECONFIGURE;
GO
sp_configure 'show advanced', 0;
GO
RECONFIGURE;
GO
Once the Database Mail is enabled then to start Database Mail External Program use the below mentioned query on msdb database:
USE msdb ;
EXEC msdb.dbo.sysmail_start_sp;
To confirm that Database Mail External Program is started, run the query mentioned below :
EXEC msdb.dbo.sysmail_help_status_sp;
If the Database Mail external program is started then check the status of mail queue using below statement:
EXEC msdb.dbo.sysmail_help_queue_sp #queue_type = 'mail';

There are few things to troubleshoot, firstly check to make sure database Mail is enabled by executing the following
SELECT is_broker_enabled FROM sys.databases WHERE name = 'msdb'
If the result of above is 0, activate the service broker by following this guide
If the result of above is 1, then check the status of Database Mail, execute the following statement:
EXECUTE dbo.sysmail_help_status_sp
To start Database Mail in a mail host database, run the following command in the msdb database:
EXECUTE dbo.sysmail_start_sp

Related

Created remote server link to Azure, but dbo schema is not shown

I am developing a web application which in production connects to an Azure database but in my local environment connects to a SQL Server running in Docker. I would like my local database to link to the Azure database so that I can easily copy data from production. I was able to successfully link via these commands:
EXEC sp_addlinkedserver
#server='remote',
#srvproduct='',
#provider='sqlncli',
#datasrc='mydb.database.windows.net',
#location='',
#provstr='',
#catalog='mydb';
EXEC sp_addlinkedsrvlogin
#rmtsrvname = 'remote',
#useself = 'false',
#rmtuser = 'my_username',
#rmtpassword = 'my_password';
EXEC sp_serveroption 'remote', 'rpc out', true;
...however although I can connect and am using the same username & password used by the app itself which works, I cannot see my objects in the dbo schema, only sys and INFORMATION_SCHEMA.
Why am I unable to see [remote].[mydb].[dbo].* objects when linking to a remote Azure database? I get this error when attempting to SELECT:
Msg 7314, Level 16, State 1, Line 1
The OLE DB provider "MSOLEDBSQL" for linked server "remote" does not contain the table ""mydb"."dbo"."my_table"". The table either does not exist or the current user does not have permissions on that table.
Have you looked at the table's permissions?
It appears to be a permissions problem. Your query is correct.
As a piece of advice, try connecting the server using a specific user who has been granted select permission on particular table/database.
GRANT select ON DATABASE::database_name TO username;
GO
Data from Azure sql database:
Output from Linked service:

SQL proxy account credentials Error code - 0, Status code - 0

I want to create a proxy user that will be able to run xp_cmdshell tasks like an administrator user does.
Note: I don't want to give this new user sysadmin permissions!
When I login from administrator, I can create the credentials for the proxy user and when I run select * From sys.credentials I can see the created credential there but when I try to run a simple xp_cmdshell task from the testuser like EXECUTE MASTER ..XP_CMDSHELL 'echo HI'
it gives an error like:
The server principal "testuser" is not able to access the database "master" under the current security context.
From the administrator side I tried:
EXEC sp_configure 'show advanced options', 1
RECONFIGURE
GO
EXEC sp_configure 'xp_cmdshell', 1
RECONFIGURE
GRANT EXECUTE ON xp_cmdshell TO [testuser]
create credential xp_cmdshell_proxy_account with identity = 'test\testuser', secret = 'test123'
When I run all these statements they all give me a successful response but if I try to run the credential like : EXEC sp_xp_cmdshell_proxy_account 'test\testuser','test123';
I get an error saying:
An error occurred during the execution of sp_xp_cmdshell_proxy_account. Possible reasons: the provided account was invalid or the '##xp_cmdshell_proxy_account##' credential could not be created. Error code: 0(null), Error Status: 0.
Can you help me and tell me what I am missing here?

Check if a user can run the RECONFIGURE statement

I'm using SQL Server Express on AWS and, when trying to change the MAXDOP via a T-SQL query, I got an error stating
Database Error: [Microsoft][SQL Server Native Client 11.0][SQL
Server]User does not have permission to perform this action. (37000:
15,247) ... You do not have permission to run the RECONFIGURE
statement (37000: 5,812).
I suppose this can also happen on SQL Server instances that are not on AWS, it seems to be a user permission problem.
Is there a way to programmatically check if a user can (or cannot) run the RECONFIGURE statement, preferably running a T-SQL query on SQL Server >= 2014?
The RECONFIGURE statement requires the server-level ALTER SETTINGS permission. The fn_my_permissions TVF can be used programmatically to check if the current user has the permission:
IF NOT EXISTS(
SELECT 1
FROM fn_my_permissions(NULL, 'server')
WHERE permission_name = N'ALTER SETTINGS'
)
BEGIN
PRINT N'Current user does not have ALTER SETTINGS permission needed for RECONFIGURE statement';
END;
Alternatively per the comment by #lptr, one can use the HAS_PERMS_BY_NAME scalar function:
IF HAS_PERMS_BY_NAME(NULL, NULL, 'ALTER SETTINGS') = 0
BEGIN
PRINT N'Current user does not have ALTER SETTINGS permission needed for RECONFIGURE statement';
END;

Checking sp_send_email permission before executing

In my stored procedure, I send emails with sp_send_email. My stored procedure will be run in different environments; some will have emailing enabled, some won't.
If I run sp_send_email without it being enabled, I (quite rightly) get this error message
SQL Server blocked access to procedure 'dbo.sp_send_dbmail' of component 'Database Mail XPs' because this component is turned off as part of the security configuration for this server.
I want to check whether emailing is enabled first, so I can avoid the error by doing the following:
IF #is_enabled
BEGIN
EXEC sp_send_email ...
END
How do I correctly set #is_enabled?
You can query sys.configurations
IF EXISTS (SELECT *
FROM sys.configurations
WHERE name = 'Database Mail XPs' AND value_in_use = 1)
PRINT 'enabled'
ELSE
PRINT 'no luck'
The downside is that it may not be visible to non-sysadmin users because of "MetaData Visibility"
sp_configure 'show advanced options', 1;
GO
RECONFIGURE;
GO
sp_configure 'Database Mail XPs';
GO
The sp_send_mail falls under the 'Database Mail XPs' umbrella. You application may not have the rights to run sp_configure and RECONFIGURE, so in the end you may be better if you simply try to invoke the sp_send_mail and handle the error.
BOL says:
To send Database mail, users must be a user in the msdb database and a member of the DatabaseMailUserRole database role in the msdb database. To add msdb users or groups to this role use SQL Server Management Studio or execute the following statement for the user or role that needs to send Database Mail.
So, you can give to user the appropriate role:
EXEC msdb.dbo.sp_addrolemember #rolename = 'DatabaseMailUserRole'
,#membername = '<user or role name>'; GO

How to set up access to MSSQL 2005 Database Mail?

I've just setup Database mail within MSSQL 2005. I have been able to send email from an administrator account on the server and through a SQL Server Agent job. But, I unable to send email when I tried to send email via a login that just has access to a database for our web application.
What is the best way to set up access to Database Mail?
I have 2 senerios where I want to send email.
Schedule a job through SQL Server Agent to run a Stored Procedure that does some process and then sends an email. (this hasn't been a problem)
Have a stored procedure invoked from a web application that calls another stored procedure which could send an email. (this is were my permissions issue is)
Possible Solutions
The only way that I have found to grant permission to a login is to map the login to the msdb database and grant the public and DatabaseMailUserRole. This really concerns me as I would assume that this gives to much access to the msdb database.
Store the email I want to send in a table and then have a SQL Server Agent job look at that table every so often to send any queued emails. This way the database login for the web application does not execute the [msdb].[dbo].[sp_ send _dbmail] call and thus does not need any permission to the msdb database.
Are there any other solutions?
You should be able to create a stored procedure WITH EXECUTE AS OWNER option so it runs in the context of the owner rather than the caller.
CREATE PROCEDURE [dbo].[sp_SendMail]
(
#To nvarchar(1000),
#Subject nvarchar(100),
#Body nvarchar(max)
)
WITH EXECUTE AS OWNER
AS
BEGIN
exec msdb.dbo.sp_send_dbmail #profile_name = 'MailProfile',
#recipients = #To,
#subject = #Subject,
#body = #Body
END
I'm trying to do the same but executing
GRANT EXECUTE ON dbo.sp_SendMail TO User1
is not fixing this issue. Only thing which is making this procedure to work is not adding
EXECUTE AS OWNER
(I'm creating it with "WITH ENCRYPTION" only) and adding user which will be running this procedure to msdb DatabaseMailUserRole role:
USE msdb
GO
EXEC sp_adduser #loginame='USERNAME', #grpname='DatabaseMailUserRole'
GO
Thanks

Resources