SQL Server - Restore Database in Different Workgroup - Fix Windows Users - sql-server

Does anyone know how to fix up orphaned local Windows users in a SQL database?
I'm attempting to backup and restore a database to a different machine. Neither machine is in a domain - they are in different workgroups. Several Windows users have permissions in the database on the source machine and in order to facilitate reconnecting the users in the target machine, I've set up users with the same usernames (but different passwords) there.
Unfortunately this doesn't work. The database users are restored somewhat uselessly not just as [user name] but as [source machine name]\[user name], preventing linking of accounts on the target machine. Does anyone know how it's possible to reconnect those users to the correct windows accounts? I did the usual Googling, but the information available is generally for connecting orphaned SQL users, not for connecting orphaned local Windows users.

A summary of conversations around this subject ...
At our site we "drop" the users and add them back in appropriately. To make this easier on ourselves we have users in a domain group (or groups), and then grant appropriate access priveleges to those groups.
If this (moving databases) is a reasonably common occurrence it's usually best to create a script to do this - a colleague has generated such a script by querying the sysuers table along the lines of
SELECT 'some appropriate text for this user' + name FROM dbo.sysusers where sid is not null.
He then pastes the results of that query into another query window and saves that as the script

You'll need to use sp_change_users_login - the actual call will depend on your version of SQL - here's a link to M/S ref
sp_users_login documentation
and Troubleshott Orphaned Users

Related

SQL Server Management Studio - cannot log in with an account I know should work

Our business has just changed Active Directories and the domain changed, from "YMS" to "YMSNET". So I used to be able to log in with "YMS\tkol" and I can now log in with "YMSNET\tkol" (these usernames and domains are faked for the purpose of example), but when I log in as that now, I can't actually expand any of the databases or look at any of the tables, I can just see a list of the database names. When I try to expand a database in the UI it says "This database is not accessible (Object Explorer)."
Now I have another user, called "sqluser", and I keep trying to use that user to log in as well by changing the Authentication Method to SQL Server Authentication rather than Windows Authentication. But I get Microsoft SQL Server, Error: 4064
Now I know this sqluser user exists and the password is correct, because I can authenticate to the server and successfully interact with the tables from an external process on a separate computer on the same network (node.js, package mssql). And I used the query on the accepted answer on this question, and found my sqluser is there, with roles db_accessadmin, db_ddladmin, db_owner. And yet it still won't let me log in with that user in the SQL Server Management Studio UI
How can I get this working again and log in with my sqluser account? Or add the appropriate permissions for my YMSNET\tkol account?
--- edit ---
My first idea is that, because I can log into the UI with YMSNET\tkol, but I can interact with the databases externally with sqluser, that there is some query or command I can run with sqluser that will add permissions for YMSNET\tkol so that that user can now look at all the databases and tables. I don't know which commands I'd run for that.
It can be because your account's default database is mapped to some another db which is not available for you, for instance, you have no permissions there, or that database not exists anymore etc.
Your organization DBA can fix it by:
ALTER LOGIN [sqluser] WITH DEFAULT_DATABASE = [rightDB]
Default db name can be checked by:
select default_database_name from sys.server_principals
where name = 'sqluser'
This property can be overridden by opening "Options" of SSMS connection window and specifying it explicitly:

What user does SSMS database creation run under?

I have a (S:\) drive with permissions for only myself and the SYSTEM user.
I just downloaded SQL SERVER EXPRESS 2017, and when I go to create a new database, it cannot see that drive as a place to create the database.
I tried giving the Everyone group full permissions on the drive, and then it showed up as a place to make the new database.
I am wondering what user I need to actually give permissions too, as it is clearly not running under my user, since my user has full control on the drive, and it's not running as SYSTEM, since that user has full control of the drive. I don't want to give "Everyone" permissions to the drive.
Note: Doing a bit more experiments, after removing the Everyone permissions, I went looking through my users list (in the Security tab of the Drive properties), and the only user that looks to have anything to do with SQL is SQLServer2005SQLBrowserUser${myUserName}, but giving this user full control did not allow SSMS to see the drive again.
Run this query:
SELECT * FROM sys.dm_server_services
And you will see current available services on your SQL Server instance and the account mapped to each one. Add permissions to the one that's below the servicename: SQL Server (MSSQLSERVER), it will be most likely NT Service\MSSQLSERVER.
If you use Jobs on the Agent, you will need to give permissions to that account also.

How to set password for SQL Server DB

How do I set up a database so that one does not have access to it? Even with installing SQL Server Management Studio on local machine.
In SQL Server with Windows user or sa can access all databases. How do you limit the access DB of the users?
For assuming that SQL Server is installed on the local machine, not on the server
You can try Single User Mode.
From the linked MSDN article:
Single-user mode specifies that only one user at a time can access the database and is generally used for maintenance actions.
Edit: You edited your question. Now it sounds more like you're asking about Security instead of how to limit the database to one user.
You can edit a user's security in SQL Server Management Studio by drilling down into Security > Logins. There you will see all logins to your instance. You can right click these entries and select Properties to made updates. The easiest way to completely bar a user from accessing any of the databases on the server is by selecting "Disabled" from the "Status" tab.
Well, if you really want to limit this to just one user, there is a simple way (but a bit risky).
Your Windows user is included in the group BuiltinAdministrators. If you really want to remove your Windows user, rerun the installation process and during the setup just change the users in those group.
But beware, you should provide another user, which has access to your database otherwise you end up with a database server without access to it.
Ater that, setup a database login and grant him access to the database you desire.
In the end, you can disable the sa login. This will prevent access with the sa account. But you should have a user which can manage logins and more. Otherwise you have no chance to recreate the password or any other administrative tasks.

XP_DirTree in SQL Server

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.

Get list of databases user has access to

I have a SQL Server 2008 instance with several databases and I'm currently writing a C# application to access those databases. In this app, the end user can select a database they want to connect to.
I already have a list of all databases on the server, how can I limit that list to those databases the user can log in to? Or, how can I query that list?
There's a lot of databases, but each user can only access some of them, so trying to connect and catching the Exception is probably not a good idea.
Fyi: The server is configured for Windows authentication only, and the logins to the server are created for Windows' user groups (not individual users).
You can query all databases from sys.sysdatabases, and check if the user has access with HAS_DBACCESS:
SELECT name
FROM sys.sysdatabases
WHERE HAS_DBACCESS(name) = 1
Maybe as an alternative to Andomars answer (which I like!) you could interrogate Active Directory to see if the user is a member of a valid group for your database. I suspect this would mean you would have to maintain some Windows Group to Database Name lookup.
You can use the system stored procedure sp_helplogins 'User Name'

Resources