bahrep
bahrep

Reputation: 30662

How to allow to steal locks only to a specific Active Directory domain group with VisualSVN Server?

Development team that uses Subversion's locking feature and VisualSVN Server with Active Directory authentication (Integrated Windows Authentication or Basic Authentication) may need to restrict anyone except administrators to steal locks.

Such task can be achieved with a pre-lock hook. However since the authentication relies on Active Directory users and groups, writing such a script can be a bit tricky.

Also there may be other cases when certain AD users' actions must be processed by a hook script differently based on their AD domain groups membership.

Is there any sample that show how to check AD domain group membership with a Subversion hook?

Upvotes: 1

Views: 717

Answers (1)

bahrep
bahrep

Reputation: 30662

You can check AD group membership with the sample PowerShell pre-lock hook script provided below.

The pre-lock.ps1 PowerShell script checks whether the user is a member of the Administrators Active Directory group and denies to steal lock if the user is not a member of the group.

Put both pre-lock.bat and pre-lock.ps1 into your repository 'hooks' folder, e.g. C:\Repositories\repository\hooks\.

pre-lock.ps1

# Function check if $user is a member of $group
function Check-GroupMembership
{
  param([string]$group, [string]$user)

  $server = get-content env:COMPUTERNAME
  $query = [ADSI]("WinNT://$server/$group,group")

  $ulist = $query.psbase.invoke("Members") |`
           %{$_.GetType().InvokeMember("Name", 'GetProperty', $null, $_, $null)}

  $ulist -contains $user
}

# Store hook arguments into variables with mnemonic names
$repos     = $args[0]
$path      = $args[1]
$user      = $args[2]
$comment   = $args[3]
$steallock = $args[4]

# Build path to svnlook.exe
$svnlook = "$env:VISUALSVN_SERVER\bin\svnlook.exe"

# Get the lock description
$lockdescr = (&"$svnlook" lock $repos $path)

# Find owner name
foreach ($str in $lockdescr)
{
  if ($str.StartsWith("Owner: "))
  {
    $owner = $str.Substring(7)

    # We find lock owner's name and it is not the user name
    if ($owner -ne "" -and $owner -ne $user)
    {
      # If the $user is a member of 'Administrators'
      # group allow to steal the lock
      if (-not (Check-GroupMembership "Administrators" $user))
      {
        [Console]::Error.WriteLine("Error: $path already locked by $owner.")
        exit 1
      }
    }

    exit 0
  }
}

exit 0

pre-lock.bat

@echo off
set PWSH=%SystemRoot%\System32\WindowsPowerShell\v1.0\powershell.exe
%PWSH% %1\hooks\pre-lock.ps1 %1 %2 %3 %4 %5
if errorlevel 1 exit %errorlevel%

Upvotes: 1

Related Questions