AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • 主页
  • 系统&网络
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • 主页
  • 系统&网络
    • 最新
    • 热门
    • 标签
  • Ubuntu
    • 最新
    • 热门
    • 标签
  • Unix
    • 最新
    • 标签
  • DBA
    • 最新
    • 标签
  • Computer
    • 最新
    • 标签
  • Coding
    • 最新
    • 标签
主页 / dba / 问题 / 284630
Accepted
Elena2020
Elena2020
Asked: 2021-02-04 08:50:04 +0800 CST2021-02-04 08:50:04 +0800 CST 2021-02-04 08:50:04 +0800 CST

如何允许某个域用户在远程 SQL 实例上创建数据库?

  • 772

我希望允许某个域用户能够在远程 SQL 实例上创建数据库。

哪些步骤是必要的,是否可以在 C# 应用程序中以编程方式执行这些步骤?

如果不存在,我应该先创建一个登录名,然后给它一个dbcreator服务器角色吗?

相关问题:SQL Server 2014 Express版中登录触发器的安全实现?

sql-server sql-server-2014
  • 2 2 个回答
  • 427 Views

2 个回答

  • Voted
  1. Best Answer
    J.D.
    2021-02-04T10:05:44+08:002021-02-04T10:05:44+08:00

    是的,您首先需要该域用户的登录名。如果他们只需要管理数据库(创建、更改、删​​除、恢复它们)的能力,那么服务器角色dbcreator就足够了。

    如果您预计多个域用户需要对此进行访问,那么您应该改为为相关的 Active Directory 组创建一个登录,这样您就不必不断地管理设置多个登录。然后,您将能够将该 AD 组映射到服务器角色dbcreator。(如果您希望域中的每个人都有权创建数据库,您甚至可以使用内置的“域用户”组。)

    至于如何在 C# 中实现这一点,有多种方法,这对于StackOverflow来说可能是一个更好的问题,因为它取决于您访问和查询服务器实例的方式。例如,使用ADO.NET ,您可以简单地编写一个 SQL 查询来检查当前用户的登录是否存在,如果不存在,则创建它并分配角色。或者,您甚至可以创建一个接收应用程序当前用户的过程,并为您处理该逻辑(这将更容易使用,具体取决于您使用的数据库访问框架)。但是,您可能会通过创建适当的 AD 组并将其映射到具有dbowner角色的登录名来最轻松地管理此问题。

    • 2
  2. Solomon Rutzky
    2021-02-10T13:41:55+08:002021-02-10T13:41:55+08:00

    “远程”到底是什么意思?意思是在网络上,只是没有托管在他们的计算机上?

    通常,您不需要为任何人或应用程序用户分配任何提升的权限。您只需要创建一个存储过程来执行此操作所需的非常具体的步骤,授予存储过程所需的权限,然后授予这个EXECUTE“创建数据库”存储过程的域用户。这样,域用户将没有任何实际提升的权限。如果存储过程只是创建一个数据库,那么这就是域用户能够做的所有事情,并且只能通过执行该存储过程。

    例如,假设您有一个像下面这样的存储过程,它在 DB 名称之前和之后强制使用两个下划线的命名约定(此示例还假设对象在[master]数据库中,我通常会尽量避免,但它确实简化了事情有点):

    GO
    CREATE 
    OR ALTER
    PROCEDURE dbo.[ExampleProc]
    (
        @DatabaseName sysname
    )
    AS
    SET NOCOUNT ON;
    
    DECLARE @AlteredName sysname = QUOTENAME(N'__' + @DatabaseName + N'__');
    
    DECLARE @SQL NVARCHAR(MAX) = N'CREATE DATABASE ' + @AlteredName + N'
        ALTER AUTHORIZATION ON DATABASE::' + @AlteredName + N' TO [sa];';
    
    EXEC(@SQL);
    GO
    

    (注意:数据库归创建它的登录名所有,因此我们更改了所有权,以便相同的登录名不能删除数据库)

    您需要做的就是以下几点:

    1. 允许域用户执行这个存储过程(此时域用户会因为没有创建数据库的权限而报错):
      GRANT EXECUTE ON dbo.[ExampleProc] TO [Domain\AccountWhoCreatesTheDBs];
      
    2. 创建证书(这将用于将代码/存储过程与权限链接):
      CREATE CERTIFICATE [Permission$CreateDatabase]
         ENCRYPTION BY PASSWORD = 'UseBetterPassword!'
         WITH SUBJECT = 'CREATE DATABASE permission',
         EXPIRY_DATE = '2099-12-31';
      
    3. 签署模块/存储过程(这会将存储过程链接到尚不存在的权限):
      ADD SIGNATURE
         TO [dbo].[ExampleProc]
         BY CERTIFICATE [Permission$CreateDatabase]
         WITH PASSWORD = 'UseBetterPassword!';
      
    4. 从证书创建登录(这将包含必要的权限,并链接到存储过程,因为登录是从刚刚用于签署存储过程的同一证书创建的):
      CREATE LOGIN [Permission$CreateDatabase]
         FROM CERTIFICATE [Permission$CreateDatabase];
      
    5. 将操作所需的权限应用于从证书创建的主体(在本例中为登录):
      ALTER SERVER ROLE [sysadmin] ADD MEMBER [Permission$CreateDatabase];
      
      此权限授予基于证书的登录,将授予存储过程,而不是域用户!需要此级别的权限才能将数据库所有权更改为sa,否则将基于证书的登录添加到dbcreator就可以了。

    完成后,域用户:

    • 将无法执行此操作:
      CREATE DATABASE [__TEST__];
      
    • 将能够执行此(成功):
      EXEC dbo.ExampleProc N'TEST';
      
    • 将无法执行此操作(由于更改了数据库的所有权):
      DROP DATABASE [__TEST__];
      

    请记住,在对存储过程(或任何模块)进行签名时,签名基于该模块的代码,因此如果该代码发生更改,则签名(和链接的权限)将丢失。这需要重新签署模块以获取权限,但这是一件好事,因为它确保在不提醒您(或某些 DBA)发生某些更改的情况下无法更改代码。

    有关更多详细信息/示例,请参阅我关于此主题的博客文章:

    • 无需将高级权限授予任何人即可安全轻松地使用高级权限:服务器级
    • 无需将高级权限授予任何人即可安全轻松地使用高级权限:数据库级别
    • 1

相关问题

  • SQL Server - 使用聚集索引时如何存储数据页

  • 我需要为每种类型的查询使用单独的索引,还是一个多列索引可以工作?

  • 什么时候应该使用唯一约束而不是唯一索引?

  • 死锁的主要原因是什么,可以预防吗?

  • 如何确定是否需要或需要索引

Sidebar

Stats

  • 问题 205573
  • 回答 270741
  • 最佳答案 135370
  • 用户 68524
  • 热门
  • 回答
  • Marko Smith

    连接到 PostgreSQL 服务器:致命:主机没有 pg_hba.conf 条目

    • 12 个回答
  • Marko Smith

    如何让sqlplus的输出出现在一行中?

    • 3 个回答
  • Marko Smith

    选择具有最大日期或最晚日期的日期

    • 3 个回答
  • Marko Smith

    如何列出 PostgreSQL 中的所有模式?

    • 4 个回答
  • Marko Smith

    列出指定表的所有列

    • 5 个回答
  • Marko Smith

    如何在不修改我自己的 tnsnames.ora 的情况下使用 sqlplus 连接到位于另一台主机上的 Oracle 数据库

    • 4 个回答
  • Marko Smith

    你如何mysqldump特定的表?

    • 4 个回答
  • Marko Smith

    使用 psql 列出数据库权限

    • 10 个回答
  • Marko Smith

    如何从 PostgreSQL 中的选择查询中将值插入表中?

    • 4 个回答
  • Marko Smith

    如何使用 psql 列出所有数据库和表?

    • 7 个回答
  • Martin Hope
    Jin 连接到 PostgreSQL 服务器:致命:主机没有 pg_hba.conf 条目 2014-12-02 02:54:58 +0800 CST
  • Martin Hope
    Stéphane 如何列出 PostgreSQL 中的所有模式? 2013-04-16 11:19:16 +0800 CST
  • Martin Hope
    Mike Walsh 为什么事务日志不断增长或空间不足? 2012-12-05 18:11:22 +0800 CST
  • Martin Hope
    Stephane Rolland 列出指定表的所有列 2012-08-14 04:44:44 +0800 CST
  • Martin Hope
    haxney MySQL 能否合理地对数十亿行执行查询? 2012-07-03 11:36:13 +0800 CST
  • Martin Hope
    qazwsx 如何监控大型 .sql 文件的导入进度? 2012-05-03 08:54:41 +0800 CST
  • Martin Hope
    markdorison 你如何mysqldump特定的表? 2011-12-17 12:39:37 +0800 CST
  • Martin Hope
    Jonas 如何使用 psql 对 SQL 查询进行计时? 2011-06-04 02:22:54 +0800 CST
  • Martin Hope
    Jonas 如何从 PostgreSQL 中的选择查询中将值插入表中? 2011-05-28 00:33:05 +0800 CST
  • Martin Hope
    Jonas 如何使用 psql 列出所有数据库和表? 2011-02-18 00:45:49 +0800 CST

热门标签

sql-server mysql postgresql sql-server-2014 sql-server-2016 oracle sql-server-2008 database-design query-performance sql-server-2017

Explore

  • 主页
  • 问题
    • 最新
    • 热门
  • 标签
  • 帮助

Footer

AskOverflow.Dev

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve