Si vous avez un parc avec des postes Windows, vous aimerez surement appliquer des GPO un jours ou l’autre en fonction des groupes. Voici comment j’ai réussi à émuler quelque chose de semblable.
J’ai suivi cette procédure premièrement pour monter le DC: http://www.howtoforge.com/openldap-samba-domain-controller-ubuntu7.10
Activer un logon script
Dans smb.conf, assurez vous d’avoir:
[global]
...
logon script = scripts\logon.bat
...
[netlogon]
comment = The domain logon service
path = /home/netlogon
public = no
writeable = no
browsable = no
Logon script
Dans /home/netlogon/scripts/logon.bat
@echo off
echo %time% > C:\time.txt
REM Yaay! Let's print an ascii art
type \\<THIS_SERVER>\netlogon\scripts\ascii_arts\tux.txt
REM Things are easier in VBS
cscript \\<THIS_SERVER>\netlogon\scripts\logon.vbs
echo %time% >> C:\time.txt
Je me suis fait demander: “Pourquoi VBS?”. La réponse est que c’est la seule façon de travailler avec Microsoft Office sur le sens du monde… malheureusement.
Avec le script suivant, nous pouvons lancer des sous scripts dans l’order désiré (ordre alphabétique). Dans /home/netlogon/scripts/logon.vbs
'
' This script runs every scripts in folder_name sorted by name
'
'On Error Resume Next
Main
Sub Main()
Dim fso, folder, files, sFolder
Dim objFile, strScriptCode
Set fso = CreateObject("Scripting.FileSystemObject")
Set objShell = Wscript.CreateObject("Wscript.Shell")
folder_name = "\\<THIS_SERVER>\netlogon\scripts\scripts.d\"
set fold = fso.getFolder(folder_name)
fileCount = fold.files.count
dim fNames()
redim fNames(fileCount)
cFcount = 0
for each file in fold.files
cFcount = cFcount + 1
fNames(cFcount) = lcase(file.name)
next
for tName = 1 to fileCount
for nName = (tName + 1) to fileCount
if strComp(fNames(tName),fNames(nName),0)=1 then
buffer = fNames(nName)
fNames(nName) = fNames(tName)
fNames(tName) = buffer
end if
next
next
for i = 1 to fileCount
script_name = folder_name & fNames(i)
wscript.stdout.writeline script_name
Set objFile = fso.OpenTextFile(script_name, 1)
strScriptCode = objFile.ReadAll
objFile.Close
Execute strScriptCode
next
End Sub
Le répertoire /home/netlogon/scripts/scripts.d contient les sous scripts. Un bon truc pour l’ordre alphabétique est de mettre des numéros devant les noms selon l’ordre dans lequel on veut qu’il soit exécuté (merci rc.d).
Émulation des GPO
Les GPO sont en fait des clé de registres appliqués sur une machine. Soit par utilisateur (HKEY_CURRENT_USER) ou pour toutes les machines (HKEY_LOCAL_MACHINE).
Donc pour appliquer les GPO, il suffit de faire un script qui applique des clés de registre. Encore une fois, le trie par ordre alphabétique est utile. Disons /home/netlogon/scripts/scripts.d/0001_update_registry.vbs
'
' This script runs every scripts in folder_name sorted by name
'
On Error Resume Next
update_registry
Sub update_registry()
Dim fso, folder, files, sFolder
Set fso = CreateObject("Scripting.FileSystemObject")
Set objShell = Wscript.CreateObject("Wscript.Shell")
folder_name = "\\<THIS_SERVER>\netlogon\scripts\registry_keys.d\"
set fold = fso.getFolder(folder_name)
fileCount = fold.files.count
dim fNames()
redim fNames(fileCount)
cFcount = 0
for each file in fold.files
cFcount = cFcount + 1
fNames(cFcount) = lcase(file.name)
next
for tName = 1 to fileCount
for nName = (tName + 1) to fileCount
if strComp(fNames(tName),fNames(nName),0)=1 then
buffer = fNames(nName)
fNames(nName) = fNames(tName)
fNames(tName) = buffer
end if
next
next
for i = 1 to fileCount
' First param is the command to run
' Second param is window visibility (0 hidden, 1 visible)
' Third param is if we need to wait the return of the command to continue
' http://msdn.microsoft.com/en-us/library/d5fk67ky(VS.85).aspx
objShell.Run "regedit.exe /S " & folder_name & fNames(i), 0, true
next
End Sub
Pour trouver quelle clé de registre nous devons changer pour appliquer un certain paramètre, il suffit d’utiliser l’outil Process Monitor de Microsoft. Il permet de voir en temps réel quels sont les accèes en lecture et en écriture sur les registres. En “sniffant” et en cliquand sur la “bonne case à cocher” de n’importe quelle application ou outil de configuration Windows, on voit quelle clé se modifie. On peut donc l’exporter avec l’outil regedit et l’appliquer avec notre script. L’avantage de cette technique est que contrairement aux GPO Microsoft il est possible d’appliquer n’importe quel changement sur n’importe quel paramètre de n’importe quelle application.
Voici un exemple qui active la prise de contrôle à distance sur les postes clients. Dans /home/netlogon/scripts/registry_keys.d/ créer un fichier (0050_enable_remote_desktop).
Windows Registry Editor Version 5.00</code>
[HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Terminal Server]
"fDenyTSConnections"=dword:00000000
*On note ici que ce n’est pas activate, mais deny… WTF?
Scripts par groupes
Parfois, il est utile de “connecter un lecteur réseau” sur une machine en fonction de son groupe ou d’appliquer tel paramètre sur une application que seul tel groupe pourrait avoir. Voici un script qui fait une requête dans l’arbre LDAP pour trouver tous les groupes de l’utilisateur courant pour ensuite lancer tous les sous scripts de ce groupe (encore avec l’orde alphabétique)
Dans /home/netlogon/scripts/scripts.d créer un nouveau script (0089_group_logon.vbs)
group_logon
Sub group_logon()
Set objShell = wscript.createObject("wscript.shell")
Set fso = CreateObject("Scripting.FileSystemObject")
username = objShell.ExpandEnvironmentStrings("%USERNAME%")
sUser = "logon_scripts"
sPassword = "PASSWORD"
sDN = "cn=" & sUser & ",dc=example,dc=com"
sRoot = "LDAP://<LDAP_SERVER>/dc=example,dc=com"
Dim oDS: Set oDS = GetObject("LDAP:")
Dim oAuth: Set oAuth = oDS.OpenDSObject(sRoot, sDN, sPassword, &H0200)
Dim oConn: Set oConn = CreateObject("ADODB.Connection")
oConn.Provider = "ADSDSOObject"
oConn.Open "Ads Provider", sDN, sPassword
dim fNames()
Dim rs
Set rs = oConn.Execute("<" & sRoot & ">;(&(objectClass=sambaGroupMapping)(memberUid="&username&"));cn;subtree")
Do while not rs.EOF
For Each vValue in RS.Fields(0).value
folder_name = "\\<THIS_SERVER>\netlogon\scripts\groups\"&vValue&".d\"
If fso.FolderExists(folder_name) Then
set fold = fso.getFolder(folder_name)
fileCount = fold.files.count
redim fNames(fileCount)
cFcount = 0
for each file in fold.files
cFcount = cFcount + 1
fNames(cFcount) = lcase(file.name)
next
for tName = 1 to fileCount
for nName = (tName + 1) to fileCount
if strComp(fNames(tName),fNames(nName),0)=1 then
buffer = fNames(nName)
fNames(nName) = fNames(tName)
fNames(tName) = buffer
end if
next
next
for i = 1 to fileCount
script_name = folder_name & fNames(i)
wscript.stdout.writeline script_name
Set objFile = fso.OpenTextFile(script_name, 1)
strScriptCode = objFile.ReadAll
objFile.Close
Execute strScriptCode
next
End if
next
rs.moveNext
Loop
End Sub
Ensuite on créer les répertoires en fonction des groupes. Si on ne veut pas de logon script pour un groupe, on ne crée pas de répertoire. Aussi simple que ça. Tout ça grâce à la ligne: If fso.FolderExists(folder_name) Then
Exemple de connexion de deux lecteurs réseau (le home et un autre) pour le groupe DouchEbag. Dans /home/netlogon/scripts/groups/DouchEbag.d (Un peu de respect pour la casse. On est sous Linux):
mount_netdrives
Sub mount_netdrives()
' Verifiy if drives are mounted, unmount them and remount them.
Dim objShell, objNet, checkDrive, objUser, CurrentUser, strGroup
Set objShell = WScript.CreateObject("WScript.Shell")
Set objNet = WScript.CreateObject("WScript.Network")
Set checkDrive = objNet.EnumNetworkDrives()
'Declare static drives letters here
Dim vecDriveLetter(2)
vecDriveLetter(0) = "J:"
vecDriveLetter(1) = "Z:"
'Declare static drives paths here
Dim vecRemotePath(2)
vecRemotePath(0) = "\\<FILE_SERVER>\"&objShell.ExpandEnvironmentStrings("%USERNAME%")
vecRemotePath(1) = "\\<MAYBE_ANOTHER_SERVER>\<SHARE>"
'Mount every drive (persistent mode)
For i = 0 To ubound(vecDriveLetter) - 1
' See http://msdn.microsoft.com/en-us/library/8kst88h6(VS.85).aspx
objNet.MapNetworkDrive vecDriveLetter(i), vecRemotePath(i), true
Next
End Sub
Il serait aussi possible d’appliquer le script de registres pour les groupes.
Déploiement de logiciels
Je vous conseille fortement WPKG.
Personellement je n’utilise pas leur agent (car il faut le déployer pour déployer…), mais j’utilise un script. Je le lance en dernier pour être certain que l’installation ne nuit pas trop au temps de login.
wpkg_command = "cscript \\<THIS_SERVER>\netlogon\wpkg\wpkg.js /synchronize /quiet /nonotify"
Set objShell = wscript.createObject("wscript.shell")
objShell.Run wpkg_command, 0, FALSE
Il ne resterait qu’à coder un GUI pour atteindre beaucoup de petites entreprises. Personnellement je trouve cette solution assez charmante, mais elle ne fera pas l’unanimité au niveau des sysadmins.