I’m making a software that tries to restore a database to sql server, but for that, i need Full Control over the folder that will host .mdf and .ldf files, I’m using the System.Security.AccessControl classes to give Full control for everyone but its not working!
I just don’t know why its happening… The app aplies the rules ok, but when it reaches the restore database part, it throws an exception telling me “The Operating system Returned a error (error 5, Access Denied)”. My code is as follows:
public static void GiveDirFullPermissionEveryoneDotNet(String dir)
{
GiveDirFullPermissionDotNet(dir, new String[] { @"TODOS", @"EVERYONE", @"BUILTIN/Users", @"Users", @"NT AUTHORITY\NETWORK SERVICE", @"NETWORK", @"Administrators", @"Administrator", @"Administradores", @"Administrador", @"SYSTEM" });
}
public static void GiveDirFullPermissionDotNet(String dir, String[] users)
{
DirectorySecurity dirSec = Directory.GetAccessControl(dir);
FileSystemAccessRule fsar;
foreach (String userAtual in users)
{
try
{
fsar = new FileSystemAccessRule(userAtual
, FileSystemRights.FullControl
, InheritanceFlags.ContainerInherit | InheritanceFlags.ObjectInherit
, PropagationFlags.InheritOnly
, AccessControlType.Allow);
dirSec.AddAccessRule(fsar);
}
catch (Exception)
{
continue;
}
}
Directory.SetAccessControl(dir, dirSec);
}
I tried it the shell way, using “CACLS.EXE”, but some windows versions its “ICACLS.EXE” (thanks great brains at Microsoft taking care of portability for us developers!). So I really want to do it the .NET way, please help.
EDIT:
I’ll post here my RestoreDatabase method, the exception is thrown at “sqlRestore.SqlRestore(sqlServer);” line
public void RestoreDatabase(string databaseName,
string filePath,
string serverName,
string userName,
string password,
string dataFilePath,
string logFilePath)
{
//! Classe de restauração do SQL server
Restore sqlRestore = new Restore();
//! adicionando o arquivo indicado ao Restore
BackupDeviceItem deviceItem = new BackupDeviceItem(filePath, DeviceType.File);
sqlRestore.Devices.Add(deviceItem);
sqlRestore.Database = databaseName;
ServerConnection connection;
//! Se passou string vazia no usuário, tenta Windows Authentication
if (userName == "")
{
SqlConnection sqlCon = new SqlConnection(@"Data Source=" + serverName + @"; Integrated Security=True;");
connection = new ServerConnection(sqlCon);
}
//! Se passou login de usuário, tenta Server Autentication
else
connection = new ServerConnection(serverName, userName, password);
Server sqlServer = new Server(connection);
Database db = sqlServer.Databases[databaseName];
sqlRestore.Action = RestoreActionType.Database;
string dataFileLocation = dataFilePath + databaseName + ".mdf";
string logFileLocation = logFilePath + databaseName + "_Log.ldf";
db = sqlServer.Databases[databaseName];
RelocateFile rf = new RelocateFile(databaseName, dataFileLocation);
sqlRestore.RelocateFiles.Add(new RelocateFile(databaseName, dataFileLocation));
sqlRestore.RelocateFiles.Add(new RelocateFile(databaseName + "_log", logFileLocation));
sqlRestore.ReplaceDatabase = true;
sqlRestore.Complete += new ServerMessageEventHandler(sqlRestoreComplete);
sqlRestore.PercentCompleteNotification = 10;
sqlRestore.PercentComplete += new PercentCompleteEventHandler(sqlRestorePercentComplete);
sqlRestore.SqlRestore(sqlServer);
db = sqlServer.Databases[databaseName];
db.SetOnline();
sqlServer.Refresh();
}
I just found the answer by myself…
in my method “RestoreDatabase”, when I set “RelocateFile” instances inside the “Restore” class, I’m saying to sql server move the .mdf and .ldf files to a new folder pointed by me, until now it sounds fine, as I give full permissions to everyone in the folder that will receive the files.
BUT thats where the problem begins: SQL Server create both .mdf and .ldf files inside its default data folder usign its own user (this one having full control over the SQL’s default data folder) BUT (again) when he moves the files after the restore is complete, he uses another user, and this user must have permissions over the SQL’s default data folder. What happen if this user hasn’t the needed permissions? The answer is: “Exactly whats happening to me: ‘The Operating system Returned a error (error 5, Access Denied)'”.
To solve this problem I login to SQL server, query for the SQL default data folder location and set full control to it. After that, everything goes fine =]
Wish this help someone with the same problem!
Thanks for everyone who tried to help!