Failure to execute msdb.dbo.sp_send_dbmail - sql

I am getting this error:
Msg 229, Level 14, State 5, Procedure sp_send_dbmail, Line 1
The EXECUTE permission was denied on the object 'sp_send_dbmail', database 'msdb', schema 'dbo'.
The relevant part of the code:
/****** Object: StoredProcedure [dbo].[dbo.STATUSCHANGE_EMAILALERT] ******/
EXEC msdb.dbo.sp_send_dbmail
#recipients = 'Test#gmail.com', -- Group Email
#subject = 'Employee Status Update',
#profile_name ='Test#gmail.com', -- Setup the profile name group
#body = #body,
#body_format = 'HTML';

Found nice and easy fix that worked for me here:
If your SQL applications can’t send email using database mail (I assume you already have DBMail Account and Profile setup), there are two things to set:
SQL MANAGEMENT STUDIO > MANAGEMENT > DATABASE MAIL > right click and
select CONFIGURE… > select MANAGE PROFILE SECURITY > SQL MANAGEMENT
put a check on PUBLIC option
click on DEFAULT PROFILE and set it to YES
STUDIO > DATABASES > SYSTEM DATABASES > right click on MSDB and
select NEW QUERY > then enter > grant execute on sp_send_dbmail to
public and click OK

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:
EXEC msdb.dbo.sp_addrolemember #rolename = 'DatabaseMailUserRole'
,#membername = '<user or role name>';
GO

Grant execute permission on sp_send_dbmail to the user executing the stored procedure, or add them to the role msdb.DatabaseMailUser .

Ok, just to add to this topic since this was really good information, but still didn't completely solve my problem. If I ran the query in SSMS, it worked once I was granted permission to execute the sp_send_dbmail procedure in msdb. However, when a job was running as my user, it would still fail.
Read through a lot of stuff to get to the conclusion that you need to make sure the sid for the owner in your DB matches the owner sid in the master DB:
--To get owner SID recorded in the master database for the current database
SELECT owner_sid FROM sys.databases WHERE database_id=DB_ID()
--To get the owner SID recorded for the current database owner
SELECT sid FROM sys.database_principals WHERE name=N'dbo'
Even though I had given access to the msdb and execute rights on the sp_send_dbmail, it was still having issues related to the database being untrustworthy and that the owner sids didn't match. Consequently, I had to the Trustworthy on for the database I was running in and fix the ownership issue:
ALTER DATABASE my_db SET TRUSTWORTHY ON;
ALTER AUTHORIZATION ON Database::my_db TO [domain\user];
I had to go through a lot of ferreting around to finally find this write-up which is much more enlightening.

I accidentally changed the "Run As" option for the SQL Agent Job - Step from "[User]" to "(Not Specified)". That caused my Job to start working.

I found here the right solution for me.
You need to add your user (let's say mailuser) to msdb and give this user rights to run dbmail:
USE msdb;
CREATE USER mailuser FOR LOGIN mailuser;
EXEC sp_addrolemember 'DatabaseMailUserRole', 'mailuser'

Related

SQL Trigger to grant 'dbowner' permissions upon new DB creation

I put together the following SQL script to create a trigger when a new DB is created, to grant db_owner permissions to a specific account:
CREATE TRIGGER ddl_trig_database
ON ALL SERVER
FOR CREATE_DATABASE
AS
DECLARE #DatabaseName NVARCHAR(128), #SQL NVARCHAR(4000)
SELECT #DatabaseName = EVENTDATA().value('(/EVENT_INSTANCE/DatabaseName)[1]','NVARCHAR(128)');
SET #SQL = '
USE ' + #DatabaseName + ';
EXEC sp_addrolemember N''db_owner'', N''[accountname]'';'
EXEC(#SQL)
However, I get the following error when I try to create a new DB to test this Trigger:
Message: User or role '[accountname]' does not exist in this database.
Could not find database ID 45, name '45'. The database may be offline.
Wait a few minutes and try again.
I put this together using some examples found on the web. It appears that the Trigger is occurring right when DB is being created, instead of running after DB has been created. Is there a way to delay it?
Few things to be mentioned here:
The trigger is executed AFTER the database is created as this is the default behaviour
Not being able to find the database may point to lack of required permissions. Make sure you have enough permission by impersonating as a user that has been granted enough permissions i.e. some database owner. Use the WITH EXECUSE AS clause.
Make sure you have the "[accountname]" existing at the new DB or at the server level (depends what kind of account you are trying to add). You can add a database user, database role, Windows login, or Windows group.
References:
https://msdn.microsoft.com/en-us/library/ms189799.aspx
https://msdn.microsoft.com/en-us/library/ms187750.aspx
SQL Server 2008 - Does a trigger run with the same permissions as the login/user?

SQL Server User Mapping Error 15023

I try to map my other DB to a user by going to Security > Logins > right click someuser > Properties > User Mapping > Select DB > set as db_owner and then ok, but I keep on getting an error saying
User, group, or role 'someuser' already exists in the current database. (Microsoft SQL Server, Error: 15023)
What is causing the error, and how do I map that user to the database?
To fix the user and login mapping you need to open a query window in the SQL Server Management Studio. Enter the following two lines and replace myDB with the database name and myUser with the correct user name:
USE myDB
EXEC sp_change_users_login 'Auto_Fix', 'myUser'
If run successfully you should get an output like this one:
The row for user '****' will be fixed by updating its login link to a login already in existence.
The number of orphaned users fixed by updating users was 1.
The number of orphaned users fixed by adding new logins and then updating users was 0.**
Your user should now be mapped correctly.
Edit:
New way to Resolve/Fix an Orphaned User:
In the master database, use the CREATE LOGIN statement with the SID option to recreate a missing login, providing the SID of the database user.
CREATE LOGIN <login_name>
WITH PASSWORD = '<use_a_strong_password_here>',
SID = <SID>;
To map an orphaned user to a login which already exists in master, execute the ALTER USER statement in the user database, specifying the login name.
ALTER USER <user_name> WITH Login = <login_name>;
When you recreate a missing login, the user can access the database using the password provided. Then the user can alter the password of the login account by using the ALTER LOGIN statement.
ALTER LOGIN <login_name> WITH PASSWORD = '<enterStrongPasswordHere>';
if it is just one or two users, then easiest way is to drop the database user from the restored database, remap the database user to the server login using SSMS. If the server login does not exist then just create it, map the user.
Option 2: If you are migrating a large number of users, use sp_help_revlogin. sp_help_revlogin is a Microsoft supplied stored procedure that will help migrate logins from one server to another, including passwords and SIDs. Here is a good article about it SP_HELP_REVLOGIN : http://www.databasejournal.com/features/mssql/article.php/2228611/Migrating-Logins-from-One-SQL-Server-to-Another.htm
Code patches to help use it :
run following T-SQL Query in Query Analyzer. This will return all the existing users in database in result pan.
USE YourDB
GO
EXEC sp_change_users_login 'Report'
GO
Run following T-SQL Query in Query Analyzer to associate login with the username. ‘Auto_Fix’ attribute will create the user in SQL Server instance if it does not exist. In following example ‘ColdFusion’ is UserName, ‘cf’ is Password. Auto-Fix links a user entry in the sysusers table in the current database to a login of the same name in sysxlogins.
USE YourDB
GO
EXEC sp_change_users_login 'Auto_Fix', 'ColdFusion', NULL, 'cf'
GO
Run following T-SQL Query in Query Analyzer to associate login with the username. ‘Update_One’ links the specified user in the current database to login. login must already exist. user and login must be specified. password must be NULL or not specified
USE YourDB
GO
EXEC sp_change_users_login 'update_one', 'ColdFusion', 'ColdFusion'
GO
2) If login account has permission to drop other users, run following T-SQL in Query Analyzer. This will drop the user.
USE YourDB
GO
EXEC sp_dropuser 'ColdFusion'
GO
Create the same user again in the database without any error.
If you assign permissions to a database user without mapping it to the database first, it throws the error you mentioned.
You should be able to delete the user, map it to the database and then assign the user to the db_owner role.
First drop your user, then execute the script below:
USE [YOURDB]
GO
CREATE USER [USERNAME] FOR LOGIN [USERNAME]
GO
USE [YOURDB]
GO
ALTER USER [USERNAME] WITH DEFAULT_SCHEMA=[dbo]
GO
I had the problem when I was trying to copy a production database to a local test database. In SSMS, I made sure to disconnect from the production server before executing scripts on the local. However, even though I thought I had disconnected, someone pointed out that the title of the production database was still there, and I got errors that objects were already there. The solution was to totally exit from SSMS and start it again, only connecting to the local test database that time.
you can solve problem by expand database ->Security -> Users
and delete the user 'someuser' ,after that go to user mapping and assign.
this problem happen some times because the database user 'someuser' was deleted from 'Logins' in Security section in SSMS and the database still own this user
Create failed for User (Microsoft.SqlServer.Smo)
SQL Server Error User, group, or role already exists in the current database. (Microsoft SQL Server, Error: 15023)
To fix above error delete user under each database individually

Problems using WITH EXECUTE AS OWNER with Trigger

I just implemented the WITH EXECUTE AS OWNER code on a new table trigger and now regular users who insert to the table are receiving the following error: Cannot execute as the database principal because the principal "dbo" does not exist, cannot be impersonated, or you do not have permission.
Users who are setup as sysadmins have no problem inserting to the table, no errors. What type of rights need to be granted to users/roles in order for them to be able to use WITH EXECUTE AS OWNER?
Apparently problem was unrelated to permissions after all but instead related to the fact that "dbo does not exist". Current db owner was set to an old login which no longer exists.
Fixed this by running the following SQL statement:
ALTER DATABASE [DB]
SET SINGLE_USER
GO
EXEC sp_changedbowner 'sa'
GO
ALTER DATABASE [DB]
SET MULTI_USER

How to grant sendmail permission to sql server user?

I have a database user which is the owner of the database. The application requirement is to send mail using database mail of sql server .
Is there any way that I can add grant only send mail permission to that user?
I have a user named testuser having server roles public and is db_owner for 1 database. Please tell me the way that I don`t need to give sysadmin serverroles to that user.
Please try with the below 2 options.
USE msdb;
--add our user
CREATE USER ClarkKent FOR LOGIN ClarkKent;
--give this user rights to use dbmail
exec sp_addrolemember 'DatabaseMailUserRole', 'ClarkKent'
now if we know ClarkKent is getting his authorization from a windows group, then you add that windows group as a user, and add that group to the same role;
USE msdb;
--add our user via a group we know he is in
CREATE USER 'mydomain\BusinessGroup' FOR LOGIN 'mydomain\BusinessGroup';
--give this GROUP rights to use dbmail
exec sp_addrolemember 'DatabaseMailUserRole', 'mydomain\BusinessGroup'
you need add 'DatabasemailUserRole' for MSDB database to user
You need to assign the login (or a role) to the mail profile after adding it to the database mail role. For the script below, a default of one may need to be set, instead of zero.
use msdb
exec sp_addrolemember 'DatabaseMailUserRole', 'sqlUser'
EXECUTE msdb.dbo.sysmail_add_principalprofile_sp
#principal_name = 'sqlUser',
#profile_name = 'sqlMailProfileName',
#is_default = 0

Creating database SQL script with login no password SQL Server 2005

I am trying to run some scripts from C# and I have a script createdb.sql.
When I execute it I get an error because login failed for mycompany\myname
This is the script
Use Master
-- Drop the database if it already exists
IF EXISTS (SELECT name
FROM sys.databases
WHERE name = N'TestDB')
BEGIN
ALTER DATABASE TestDB SET SINGLE_USER WITH ROLLBACK IMMEDIATE
DROP DATABASE TestDB
CREATE DATABASE TestDB
ALTER DATABASE TestDB SET MULTI_USER
END
ELSE
BEGIN
CREATE DATABASE TestDB
What do I need to do to create a simple login as well?
Thanks
"mycompany\myname" looks like a domain login.
For "Windows security" SQL takes the currently logged on user, it's difficult to impersonate another user to run SQL commands (but not impossible).
You can create a simpler SQL Login by following the instructions here this will allow you to supply credentials in the connection string
You'll need to assign the Windows user sysadmin permissions (or at least greater security permissions) to be able to do that in the master database.