开发者

.NET Folder Permission Issue

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 logFilePa开发者_运维知识库th)
{
    //! 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();
}


My money is on this not being a .Net issue but a problem with the SQL Server...

Here's my guess (from here)

From http://www.fmsinc.com/freE/NewTips/SQL/SQLtip9.asp

While only local devices are shown in Enterprise Manager’s Backup/Restore dialogs, there is a way to create or restore a SQL Server database backup on a network file share. Creating or restoring a database backup on a network file share requires the following prerequisites:

1) The SQL Server services, on the Server containing the instance of SQL Server, must be running under a domain-level account (e.g. A Domain Administrator account). This is accomplished by changing the "Log On" properties for the services named "MSSQLSERVER" and "SQLSERVERAGENT" on the server running SQL Server (not your local instance). When you have completed changing the log on information for these 2 services, you will need to restart the "MSSQLSERVER" service on that server. Note that this will ask if you want to restart the "SQLSERVERAGENT" as well - Answer: Yes.

2) The SQL Server service account must have FULL CONTROL rights to the file system folder and to the share. That means you need to have a shared location in which the logon account you specified in 1 (above) has full control rights.

3) The file share should only be accessed via UNC name. Mapped drives may not be consistently visible to the SQL Service.

4) You cannot specify the path by using the browse ellipses (...). You must type the fully qualified path


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!


I've tested your code "RestoreDatabase" without any modification of permissions on my computer and it works for me. Visual Studio 2008 SP1, SQL 2008 Express SP1, Windows 7 x64.

I hope this helps you.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜