Blog de ILINFO

Trucs et astuces

Blog ILINFO Active DIrectory MIIS LDAP ADAM PCA PRA BCP DRP

Log in

DDNS par un serveur DHCP

by Emmanuel Dreux avril 18, 2009 17:05

Voici un billet dédié à la mise en place de dynamic update DNS réalisé par les serveurs DHCP en lieu et place du client, ceci afin de restreindre les permissions d'écriture sur les zones DNS.

1. Rappel du paramétrage du client

Pour que le client réalise son enregistrement DNS dynamique, il faut que la case "Enregistrer les adresses de cette connexion dans le système DNS" soit cochée.

Le client enregistre alors ses entrées dans le domaine spécifié par le suffixe DNS principal de cette machine.

Lorsque la case “Utiliser le suffixe DNS de cette connexion pour l’enregistrement DNS” est cochée, la station s’enregistre également dans la zone mentionnée dans le champs “Suffixe DNS pour cette connexion”, ce qui permet de réaliser des doubles enregistrements.



Pour que la station de travail ou le serveur ne tente pas un enregistrement dynamique, il faut que la case “Enregistrer les adresses de cette connexion dans le système DNS” soit décochée.Pour les postes configurés en DHCP, il est alors possible  de configurer le DHCP pour qu’il réalise l’enregistrement DNS à la place du client.

2. Configuration du DHCP

L'activation du DDNS par le serveur DHCP peut être configuré au niveau du scope ou au niveau du serveur DHCP.

Il faut activer le DDNS et demander l’enregistrement même pour les hosts qui n’en font pas la demande.

Par exemple, pour activer le DDNS pour tous les scopes hébergés par le serveur DHCP, configurez le DDNS au niveau du serveur DHCP.

Configurez les options suivantes:

 

L’enregistrement aura lieu dans le domaine mentionné par l’option 15 du scope DHCP. 



3. Déploiement des paramètres par GPO

La désactivation de "Enregistrer les adresses de cette connexion dans le système DNS" peut être réalisée par GPO, il faut désactiver Dynamic Update et Register PTR Records.

4. Permissions sur les zones DNS

Par défaut, à la création d'une zone DNS intégrée AD, le groupe Tout le mondea les permissions de rajouter des entrées et modifier et supprimer ses propres entrées, ceci afin que le dynamic Update puisse ajouter des entrées.

Pour restreindre les permissions, il faut donc retirer à tout le monde les permissions de créer des entrées.

Il faut ensuite autoriser les serveurs DHCP à ajouter des entrées et modifier ses enregistrements. C'est le cas par défaut si les DHCP sont installés sur des controleurs de domaine.

Si ce n'est pas le cas, un groupe contenant les serveurs DHCP peut être autorisé à créer/modifier/supprimer des entrées DNS.

Dans les paramètres du serveur DHCP, iles est également possible de spécifier le compte utilisateur qui sera utilisé pour réaliser les enregistrements dynamiques. Ce compte devra avoir les permissions nécessaires pour gérer les enregistrements DNS.

Note: Lors du DDNS réalisé par DHCP, celui-ci devra avoir le droit d'écraser (mettre à jour) des enregistrements existant, donc simplement créer des enregistrements et modifier ses propres enregistrements (par le biais de SELF) est insuffisant.

5. Scavenging

Il est interessant en même temps que la mise en place du DDNS de mettre en place le nettoyage automatique des enregistrements crées par DDNS (Scavenging).

Le scavenging doit être activé au niveau du serveur DNS (sur 1 seul , car les suppressions se répliquent  aux autres), et également sur chaque zone gérée.

Les valeurs par défaut de 7 jours peuvent être conservées.

Lorsque le scanvenging est activé, seuls les enregistrements crées par dynamic update sont touchés, un enregistrement statique ne sera jamais supprimé.

Pour gérer celà, le scavenging s'appuie sur un timestamp lié à l'enregistrement, et ce timestamp n'est crée que lors de la création par DDNS.

Si vous avez des doutes sur les enregistrements qui risquent d'être supprimés lors de l'activation du scavenging, vous pouvez lister les entrées d'une zone à l'aide de dnscmd.exe et lister celle qui possèdent un entrée [aging].

ex: dnscmd dnsserver /enumrecords dnszone @ > dnsdump.txt

puis findstr /i "aging" dnsdump.txt > aging.txt

Actuellement noté 5.0 par 1 personne(s)

  • Currently 5/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Tags: , ,

SetupDiOpenDeviceInterface returns ERROR_INVALID_USER_BUFFER in C#

by Emmanuel Dreux avril 16, 2009 00:30

Lors du développement de l'outil USBLIST disponible en téléchargement sur mon site, je me suis arraché les cheveux pendant un bon moment sur l'appel de SetupDiOpenDeviceInterface en CSHARP  (C#). En effet cette API n'est pas exposée dans ce langage et il faut appeler la fonction native de setupapi.dll par pinvoke. Cependant tous mes appels se sont soldés par une erreur ERROR_INVALID_USER_BUFFER sans comprendre pourquoi. Les recheches sur Internet et les questions sur les forums se sont révélées infructueuses et aucun exemple de code source fonctionnel n'était disponible pour s'en inspirer.

Le seul moyen de trouver la cause du problème a été de développer un exemple en C++ et de comparer son exécution en assembleur avec le programme en C# pour comprendre les différences.

Voici les extraits clés de la session de debugging:

SP_DEVICE_INTERFACE_DATA DeviceInterfaceData;
DeviceInterfaceData.cbSize =
sizeof(DeviceInterfaceData);[...]
if (SetupDiOpenDeviceInterface(
 DeviceInfoSet,
 lpdbv2->dbcc_name,
 0,
 &DeviceInterfaceData
 )== 0)

Au breakpoint suivant, l'instruction compare la taille de DeviceInterfaceData.cbSize. Le registre ecx contient la valeur de la donnée.

eax=76d9c680 ebx=76d9c65c ecx=0012fa14 edx=00000000 esi=00000000 edi=001e2c28
eip=76cbca46 esp=0012f460 ebp=0012f464 iopl=0         nv up ei pl zr na pe nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000246
SETUPAPI!DeviceInterfaceDataFromNode+0x3a:
76cbca46 83391c          cmp     dword ptr [ecx],1Ch  ds:0023:0012fa14=0000001c
0:000> dd ecx
0012fa14  0000001c cccccccc cccccccc cccccccc
0012fa24  cccccccc cccccccc cccccccc cccccccc
0012fa34  cccccccc 001e2c28 cccccccc cccccccc
0012fa44  001e22f8 cccccccc cccccccc cccccccc
0012fa54  cccccccc cccccccc 001e22f8 cccccccc
0012fa64  cccccccc cccccccc cccccccc cccccccc
0012fa74  cccccccc cccccccc cccccccc cccccccc
0012fa84  cccccccc cccccccc cccccccc cccccccc


Le même code en # (apparemment)!

SP_DEVINFO_DATA DeviceInfoData = new SP_DEVINFO_DATA(); // Note it should be SP_DEVICE_INTERFACE_DATA but the structures are identical
// DeviceInfoData.cbSize = Marshal.SizeOf(DeviceInfoData);
DeviceInfoData.cbSize = 28;
if (!SetupDiOpenDeviceInterfaceA(
    hDev,
    // dvi.dbcc_name,
    @"\\?\USB#VID_07AB&PID_FCCA#FW520_200000000000B703#{a5dcbf10-6530-11d2-901f-00c04fb951ed}",
    0,
    ref DeviceInfoData))

Le breakpoint à la même instruction:

0:000> t
Breakpoint 1 hit
eax=76d9c680 ebx=76d9c65c ecx=002aeaac edx=00000000 esi=00000000 edi=005f70c0
eip=76cbca46 esp=002ae820 ebp=002ae824 iopl=0         nv up ei pl zr na pe nc
cs=001b  ss=0023  ds=0023  es=0023  fs=003b  gs=0000             efl=00000246
setupapi!DeviceInterfaceDataFromNode+0x3a:
76cbca46 83391c          cmp     dword ptr [ecx],1Ch  ds:0023:002aeaac=00612a18

0:000> dd 002aeaac
002aeaac  00612a18 00196fd8 5c3f5c5c 23425355
002aeabc  5f444956 42413730 44495026 4343465f
002aeacc  57462341 5f303235 30303032 30303030
002aeadc  30303030 33303742 35617b23 66626364
002aeaec  362d3031 2d303335 32643131 3130392d
002aeafc  30302d66 66343063 31353962 007d6465
002aeb0c  00196c00 002aeb24 79e7b080 00000006
002aeb1c  00196ca8 00000006 002aeb30 79e7b06b
0:000> dd poi(ecx)
00612a18  0000001c 00000000 00000000 00000000
00612a28  00000000 00000000 00000000 abababab
00612a38  abababab feeefeee 00000000 00000000
00612a48  63574a97 00000e3e 00612ae0 00581fc0

Forcément, ça plante  car ecx ne contient pas 0000001C mais l'adresse mémoire où est stocké 1C. La fonction sort donc en erreur et retourne 0x6f8 ERROR_INVALID_USER_BUFFER

Pour résumer,
En C++ , ecx contient la longueur de la structure.

En c#, par contre, ecx contient l'adresse mémoire de la longueur de la structure.

Pour résoudre le problème, il a suffit de remplacer la classe SP_DEVINFO_DATA par une structure qui n'a donc pas besoin d'être instanciée.

Le code source est disponible ici: http://www.ilinfo.fr/docs/DeviceInformation.cs

Post Original : http://social.msdn.microsoft.com/Forums/en-US/csharplanguage/thread/2eca9b5d-fd96-4181-943f-3157a09020f0

 

 

 

 

Soyez le premier à noter ce billet

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Tags: , , ,

c# | Développement

Problème restauration des comptes associés aux keytab

by Emmanuel Dreux avril 10, 2009 21:26

Contexte:

Un administrateur a mis en place une solution de SSO pour que des utilisateurs d'un domaine Active Directory puissent s'authentifer en Kerberos auprès d'applications JAVA ou aurpès d'applications hébergées sur des machines Unix ou Linux.

Dans ce contexte, des comptes SSO ont été crées dans l'Active Directory.
Il s'agit de comptes de service pour lesquels un keytab a été généré à l'aide de la commande Ktpass.exe (ktpass -princ 'value' -mappuser domain\svcaccount etc.)

Lors de l'éxécution de la commande, le mot de passe du compte de service est modifié et la clé de chiffrement contenue dans le keytab est dérivée du mot de passe.

Un numéro de version du mot de passe appelé kvno est également stocké dans le keytab. Il doit correspondre au numéro de version contenu dans les tickets générés par les KDC. Le KDC récupère le numéro de version depuis l'attribut msDS-KeyVersionNumber. Cet attribut msDS-KeyVersionNumber est un attribut construit (constructed attribute) dont la valeur est égale à une metadonnée de l'attribut UnicodePwd.

 

Problème:

Lors d'une restauration autoritaire (authoritative restore), la métadonnée de l'attribut UnicodePwd est incrémentée de 100 000.

Celà a une double conséquence:

1.  le msDS-KeyVersionNumber (= kvno) est également incrémenté de 100 000 et ne correspond donc plus au numéro de version stocké dans le keytab. En d'autres termes, celà invalide le keytab existant qu'il faut alors regénérer.

2. Le kvno est originellement codé sur 8 bit et accepte des valeus de 0 à 255. Les valeurs supérieures sont alors mal perçues selon les implémentations kerberos. L'implémentation MIT par exemple accepte des kvno > 255 alors que l'implémentation de Vintela (Quest) ne les accepte pas.

Dans un cas de PRA (plan de reprise d'activité, DRP en anglais), où il faut procéder à une restauration autoritaire d'annuaire, il faut alors regénérer tous les keytab des comptes SSO Kerberos Unix et les réinstaller dans chaque application. Si la stack kerberos n'accepte pas les kvno > 255, il faut alors supprimer tous les comptes SSO et les recréer.

 

Contournements:

Vintella accepte des keytab avec un kvno à -1 et dans ce cas ignore si les numéros de version ne correspondent pas (ce n'est pas applicable pour l'implémentation MIT).

Il est donc possible d'éditer les fichiers keytab existants avec un éditeur héxadécimal et de forcer la valeur kvno à FF.

Il est également possible de générer un keytab avec la valeur kvno à -1, pour cela utiliser l'option de ktpass /kvno 255.

 Finalement, il est possible de forcer l'active directory à revenir à la mode Windows 2000 c'est à dire ne jamais incrémenter le  msDS-KeyVersionNumber et lui forcer la valeur à 1 systématiquement.

Pour celà, il faut modifier au niveau de la forêt dans la partition configuration l'attribut dsheuristics.

voir http://support.microsoft.com/kb/870987/en-us

 

Demande de fix :

Une demande de fix (CDCR = Critical Design Change Request) a été formulée auprès de Microsoft.

Ce billet sera mis à jour lorsqu'un statut final sera apporté par Microsoft.

Actuellement noté 5.0 par 1 personne(s)

  • Currently 5/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Tags: , , , ,

Active Directory | SSO