예제 #1
0
        public OperationResult DeleteRoleForUser(string serverAddress, string username,
                                                 string password, string catalog, string loginUsername, string roleName)
        {
            if (string.IsNullOrWhiteSpace(serverAddress))
            {
                throw new ArgumentNullException(nameof(serverAddress));
            }

            if (string.IsNullOrWhiteSpace(username))
            {
                throw new ArgumentNullException(nameof(username));
            }

            if (string.IsNullOrWhiteSpace(password))
            {
                throw new ArgumentNullException(nameof(password));
            }

            if (string.IsNullOrWhiteSpace(loginUsername))
            {
                throw new ArgumentNullException(nameof(loginUsername));
            }

            var hasInvalidSymbols = SqlStringValidator.HasInvalidSymbols(loginUsername);

            if (hasInvalidSymbols)
            {
                return(new OperationResult(false, "The username contains illegal characters"));
            }

            var isInjectionAttempt = SqlStringValidator.HasInjectionCommand(loginUsername);

            if (isInjectionAttempt)
            {
                return(new OperationResult(false, "The username contains illegal characters"));
            }

            var isValidRole = SqlStringValidator.IsValidRole(roleName);

            if (!isValidRole)
            {
                return(new OperationResult(false, "The given role does not exist in SQL"));
            }

            var connectionString = ConnectionStringBuilder.FromCredentials(serverAddress, username, password, catalog);

            using (var connection = new SqlConnection(connectionString))
            {
                connection.Open();

                var hasCatalogUser = HasUserInDatabase(loginUsername, connection);

                if (!hasCatalogUser)
                {
                    return(new OperationResult(false, "The given user does not have this role in the target database"));
                }

                using (var command = new SqlCommand("sp_droprolemember", connection))
                {
                    command.CommandType = CommandType.StoredProcedure;

                    command.Parameters
                    .Add("@membername", loginUsername)
                    .Add("@rolename", roleName);

                    using (var _ = command.ExecuteReader())
                    {
                        // Nothing much to do here
                    }
                }

                const string ROLES_IN_DATABASE_SQL =
                    "SELECT COUNT(*) FROM sys.database_role_members dbrolemembers "
                    + "INNER JOIN sys.database_principals dbprincipals ON dbprincipals.principal_id = dbrolemembers.role_principal_id "
                    + "INNER JOIN sys.database_principals dbuserprincipals ON dbuserprincipals.principal_id = dbrolemembers.member_principal_id "
                    + "WHERE dbuserprincipals.name = @loginUsername";

                bool hasOtherRolesInDatabase;

                using (var command = new SqlCommand(ROLES_IN_DATABASE_SQL, connection))
                {
                    command.Parameters
                    .Add("@loginUsername", loginUsername);

                    using (var reader = command.ExecuteReader())
                    {
                        reader.Read();

                        hasOtherRolesInDatabase = reader.GetInt32(0) >= 1;
                    }
                }

                if (!hasOtherRolesInDatabase)
                {
                    using (var command = new SqlCommand($"DROP USER [{loginUsername}]", connection))
                    {
                        command.ExecuteNonQuery();
                    }
                }
            }

            return(new OperationResult(true));
        }
예제 #2
0
        public OperationResult AddRoleForUser(string serverAddress, string username,
                                              string password, string catalog, string loginUsername, string roleName)
        {
            if (string.IsNullOrWhiteSpace(serverAddress))
            {
                throw new ArgumentNullException(nameof(serverAddress));
            }

            if (string.IsNullOrWhiteSpace(username))
            {
                throw new ArgumentNullException(nameof(username));
            }

            if (string.IsNullOrWhiteSpace(password))
            {
                throw new ArgumentNullException(nameof(password));
            }

            if (string.IsNullOrWhiteSpace(loginUsername))
            {
                throw new ArgumentNullException(nameof(loginUsername));
            }

            var hasInvalidSymbols = SqlStringValidator.HasInvalidSymbols(loginUsername);

            if (hasInvalidSymbols)
            {
                return(new OperationResult(false, "The username contains illegal characters"));
            }

            var isInjectionAttempt = SqlStringValidator.HasInjectionCommand(loginUsername);

            if (isInjectionAttempt)
            {
                return(new OperationResult(false, "The username contains illegal characters"));
            }

            var isValidRole = SqlStringValidator.IsValidRole(roleName);

            if (!isValidRole)
            {
                return(new OperationResult(false, "The given role does not exist in SQL"));
            }

            var connectionString = ConnectionStringBuilder.FromCredentials(serverAddress, username, password, catalog);

            using (var connection = new SqlConnection(connectionString))
            {
                connection.Open();

                var hasCatalogUser = HasUserInDatabase(loginUsername, connection);

                if (!hasCatalogUser)
                {
                    // If the user doesn't have a mapping, we need to create a user
                    // in the target database prior to adding the role
                    using (var command = new SqlCommand($"CREATE USER [{loginUsername}] FOR LOGIN {loginUsername}", connection))
                    {
                        command.ExecuteNonQuery();
                    }
                }

                using (var command = new SqlCommand("sp_addrolemember", connection))
                {
                    command.CommandType = CommandType.StoredProcedure;

                    command.Parameters
                    .Add("@membername", loginUsername)
                    .Add("@rolename", roleName);

                    using (var _ = command.ExecuteReader())
                    {
                        // Nothing much to do here
                    }
                }
            }

            return(new OperationResult(true));
        }