prosta idea [nie zawsze wykonalna] – wedle podręcznikowego przydzielania uprawnień i zarządzania grupami polega na tym, że dla każdego udziału na FS tworzona jest grupa security-domain local – np. Share_FS01_RW_public. tej grupie nadawane są uprawnienia [w tym przypadq RW] a całe zarządzanie przydzielaniem uprawnień polega na dodaniu grupy funkcyjnej do grupy dostępowej. przykład w praktyce:

  1. zakładam w AD jednostkę organizacyjną OU=AccessGroups
  2. zakładam w AD jednostkę organizacyjną OU=Accounting
  3. zakładam grupę funkcyjną security-global ‘Accounting’ i dodaję odpowiednich userów). te 3 kroki oczywiście definiują miniaturkę podstawowego środowiska lab
  4. księgowość musi mieć swój prywatny katalog na FS więc:
  1. zakładam grupę Security-Domain Local o nazwie “AG_FS01_RW_Accounting” w OU-AccessGroups – to przykładowa notacja która pozwala w łatwy sposób odróżnić grupy dostępowe od innych, zawiera nazwę serwera, którego dotyczy, uprawnienia [dzięki temu można łatwo odróżniać grupy RW od R] oraz jakiego udziału dotyczą.
  2. zakładam katalog ‘Accounting’ na FS01 i publiqję go jako ‘\FS01Accouting’
  3. jedyne uprawnienia jakie zakładam na katalogu to “authenticated users:M” na poziomie udziału oraz “AG_FS01_RW_Accounting:RW” na poziomie NTFS
  4. teraz aby nadać uprawnienia do katalogu wystarczy, że dodam grupę ‘Accounting’ do ‘AG_FS01_RW_Accounting’

wadą takiego rozwiązania jest niezliczona ilość grup w złożonym środowisq – a więc czasem podręcznikowe rozwiązanie nie może być zastosowane. zalet jednak jest bardzo dużo:

  • wszystko zarządzane z jednego miejsca za pomocą ADUaC bez potrzeby logowania/sprawdzania na serwerach plików
  • ..czyli centralizacja zarządzania uprawnieniami
  • łatwość delegacji zarządzania uprawnieniami
  • utrzymywanie spójnej, prostej struktury: przejrzystość
  • prostota automatyzacji mapowania: ujednolicone/uniwersalne skrypty mapowania
  • automatyczne mapowanie dysków dla użytkowników zaraz po dodaniu do grupy funkcyjnej

poniżej zamieszczam przykładowy skrypt logowania mapujący dyski, który ma możliwość mapowania na podstawie przynależności do grupy. ponieważ użytkownicy nie należą bezpośrednio do grupy dostępowej, sprawdzany jest drugi poziom zagnieżdżenia – atrybut memberof. jest możliwość włączenia rekursywnego sprawdzania zagnieżdżenia ale ma to kilka mankamentów:

  • jest dość powolne w realnym środowisq, gdzie grup jest sporo
  • istnieje niebezpieczeństwo przypadkowego zmapowania katalogu z powodu powiązań pomiędzy grupami
'*******************************************************************************
'* map network drives lib for logon script                                     *
'*   can be used to map multiple drives. possible error handling               *
'*   user must have proper permissions - providing credentials not handled     *
'*                    nexorek(at)gmail.com           25.iii.2kd                *
'*EXAMPLE USE:                                                                 *
'*addMapping "m","\192.168.1.100c$"                                          *
'*addMapping "n","\192.168.1.100d$"                                          *
'*mapNetworkDrives                                                             *
'*                                                                             *
'*EXECUTE WITH ERROR HANDLING:                                                 *
'*addMapping "m","\192.168.1.100c$"                                          *
'*addMapping "n","\192.168.1.100d$"                                          *
'*if mapNetworkDrives<>0 then                                                  *
'* wscript.echo "do something with "&mapNetworkDrives                          *
'*else                                                                         *
'* wscript.echo "netdrives mapped successfully"                                *
'*end if                                                                       *
'*                                                                             *
'*MAP USER-named DRIVE                                                         *
'*addMapping "h","\servershare"&logonName                                   *
'*                                                                             *
'*CONDITIONAL MAP DRIVE ON USER MEMBERSHIP                                     *
'*if isMember("group name") then addMapping "s","\serversharename"           *
'*                                                                             *
'*******************************************************************************
ON ERROR RESUME NEXT
Const FileServer="\put.servername.here"

Dim dictMappings
Dim oADSystemInfo
Dim oUser, groupList, loginName, dictGroups, g
dim tempname

'*******************************************************************************
'*                                 MAIN                                        *
'*******************************************************************************
'used for store information about mapping drives
set dictMappings=CreateObject("Scripting.Dictionary")

'Object for user/computer information
set oADSystemInfo=CreateObject("ADSystemInfo")
'USER
set oUser=GetObject("LDAP://"&oADSystemInfo.UserName)
loginName=oUser.SAMAccountName
'USER GROUPS MEMBERSHIP
set dictGroups=CreateObject("Scripting.Dictionary")
groupList=oUser.getEx("memberOf")
for each g in groupList
  if not strcomp(lcase( left( getObject("LDAP://"&g).objectCategory,8) ),"cn=group" ) then
    enumGroupsInGroup("LDAP://"&g)
  end if
  tempname=lcase(mid(g,4,InStr(g,",")-4))
  if not dictGroups.exists(tempname) then dictGroups.add tempname, g
next

'PUT MAPPINGS HERE. example:
if isMember("AG_FS01_RW_Accounting") then addMapping "i","\FS01Accounting"
mapNetworkDrives

'*******************************************************************************
'*                              SUBS'N'FUNCS                                   *
'*******************************************************************************
Sub addMapping(drvLetter, srvPath)
  dictMappings.add ucase(drvLetter)&":", srvPath
End Sub

Function mapNetworkDrives()
  ON ERROR RESUME NEXT
  Dim wshNetwork
  Dim AllDrives, i

  Set WshNetwork = WScript.CreateObject("WScript.Network")
  Set AllDrives = WshNetwork.EnumNetworkDrives()

  For each i in dictMappings
    'unmap before mapping - just to be sure that drive letter is not used
     if dictMappings.Exists(i) then
       WShNetwork.RemoveNetworkDrive AllDrives.Item(i)
     end if
    WShNetwork.MapNetworkDrive i, dictMappings(i)
    mapNetworkDrives=cstr(hex(err.number))
  next
End Function

Function isMember(gName)
  if dictGroups.Exists(lcase(gName)) then
    isMember=TRUE
  else
    isMember=FALSE
  end if
End Function

Sub enumGroupsInGroup(gname)
  ON ERROR RESUME NEXT
  Dim grpList, gentry

  grpList=getObject(gname).getEx("memberOf")
  for each gentry in grpList
    if not strcomp(lcase( left( getObject("LDAP://"&gentry).objectCategory,8) ),"cn=group" ) then
      dictGroups.add lcase(mid(gentry,4,InStr(gentry,",")-4)), gentry
      'next line is recursion for multilevel nesting. for performance purposes assumed 2-level structure
      'so it is disabled. there should be no more then second-level nesting for permissions
      'in fact it can be even dengerous - someone may have accidently mapped drive  
      'enumGroupsInGroup("LDAP://"&gentry)
    end if
  next

End Sub

jak się okazuje, czasem teoria przekłada się na praktykę – mówię tu o podręcznikowym projektowaniu grup (global/domain local i standardowe AGDLP).

eN.

-o((:: sprEad the l0ve ::))o-

Comments (3)

  1. domel

    Odpowiedz

    @GT
    a próbowałeś kiedyś robić skrypty logowania w PS? Działa to niestety niesamowicie wolno w ustawieniach standardowych (powershell długo się uruchamia :( )

    A VBS, to i tak ciągle jeden z moich ulubionych języków ;) w połączeniu z WMI może wszystko ;D

Zostaw komentarz

Twój adres e-mail nie zostanie opublikowany. Wymagane pola są oznaczone *

Time limit is exhausted. Please reload CAPTCHA.