Autor Thema: Policies in deutscher pubnames.ntf 9.0.1 bringen Client zum Crash  (Gelesen 1842 mal)

Offline Tode

  • Moderatoren
  • Gold Platin u.s.w. member:)
  • *****
  • Beiträge: 6.883
  • Geschlecht: Männlich
  • Geht nicht, gibt's (fast) nicht... *g*
ACHTUNG: Dieser Post ist lang und kein Aufruf zur Hilfe, sondern nur reine Information.

IBM hat es mal wieder geschafft, in einer lokalisierten pubnames.ntf zu viel zu übersetzen.
Diesmal sind es die Policy- Dokumente (u.a.), und diesmal hat das Ganze fatale Auswirkungen.

Zum Hintergrund: Der Bug ist wohl schon lange da (laut diesem Blogeintrag von Noteshexe seit 2014), aber war mir noch nicht über den Weg gelaufen.
IBM hat es in der 9.0.1er lokalierten pubnames.ntf geschafft, an etlichen Stellen den programmatisch verarbeiteten Wert "Enforce" durch das deutsche Wort "Zwingend" zu ersetzen.

In dieser Technote werden die betroffenen Masken aufgelistet und aufgezählt, was man alles korrigieren muss, damit der Fehler beseitigt ist.
Immerhin steht da auch, dass der Bug in 9.0.2 behoben sein wird... Puh: Glück gehabt...

Außerdem gibt es in der Technote einen Agenten, der die betroffenen Dokumente reparieren soll. Abgesehen von der Qualität des Agenten (Schreiben solche Dinge bei IBM eigentlich Praktikanten, oder wie ist eine Zeile "Dim flag,flag1,flag2 As Boolean" zu erklären?): Er behebt nur die Hälfte der Fehler... aber dazu gleich mehr.

Das Problem: Wenn man versucht, mit diesem Template benutzerdefinierte Policy- Werte in einer Desktop- Policy zu erstellen, dann werden diese einfach nicht zugewiesen.
Aber das ist das kleinere der beiden Übel. Wer sich schonmal mit Desktop- Policies auseinandergesetzt hat, der weiss, dass aus den Einstellungen, die man setzt, Felder im Policy- Dokument generiert werden.

So wird für die Verwaltete Einstellung "SametimeServer=chat.test.de; com.ibm.collaboration.realtime.community, Zwingend: SetOnce" ein item generiert, das folgenden Namen hat:

"$qual_com.ibm.collaboration.realtime.community, Zwingend_SametimeServer"

Richtig wäre: "SametimeServer=chat.test.de; com.ibm.collaboration.realtime.community, Enforce: SetOnce" und item Name:

"$qual_com.ibm.collaboration.realtime.community_SametimeServer"

Da findet also ein dringend benötigtes replacesubstring nicht statt.

So weit so schlecht.
Jetzt wird es aber richtig hässlich: Wird eine solche Policy an die Clients verteilt, dann scheint es so, dass der Prozess, der die Policies auswertet einen DXL- Export der Policy- Dokumente macht... Und das erste Beispiel resultiert in einem wunderschönen Client- Crash mit dem folgenden StackTrace:
Zitat
[ 1] 0x77c170d4 ntdll.KiFastSystemCallRet+0 (75c,493e0,0,6eebfdd0)
 [ 2] 0x7760c4d3 kernel32.WaitForSingleObjectEx+67 (75c,493e0,0,78490f4)
 [ 3] 0x7760c482 kernel32.WaitForSingleObject+18 (75c,493e0,6eeb2ad0,7849541)
@[ 4] 0x5f7316f2 nnotes.FRSendCommandToService+1266 (7849118,7849518,7849541,1)
@[ 5] 0x5f732b19 nnotes.OSRunExternalScript@8+1241 (7849890,1)
@[ 6] 0x5f73320c nnotes.FRTerminateWindowsResources+1260 (1,1010,1,0)
@[ 7] 0x5f733902 nnotes.OSFaultCleanupExt@24+1154 (1e56a70,1010,0,0,0,7849cb8)
@[ 8] 0x5f73397a nnotes.OSFaultCleanup@12+26 (0,1010,0)
@[ 9] 0x5f773467 nnotes.OSNTUnhandledExceptionFilter@4+263 (784d4f8)
@[10] 0x5f733f93 nnotes.Panic@4+883 (784d344)
@[11] 0x5f7394df nnotes.LockHandleExt@16+223 (0,784d538,784d544,0)
@[12] 0x5f512ef8 nnotes.OSLockObject@4+24 (60e2df4a)
@[13] 0x6236edd6 ndxlo.DxlNoteSource::WriteItemByBLOCKID+838 (784dc84,784dffc,7980548,784dc9c)
@[14] 0x6236f5f7 ndxlo.DxlNoteSource::WriteItems+1031 (784dffc,7980548,0,79473f8)
@[15] 0x62352238 ndxlo.DxlNoteSource::WriteDocumentNote+1064 (7940900,7945c48,79473f8,0)
@[16] 0x6236e3b5 ndxlo.DxlNoteSource::WriteNote+645 (7947400,7945c48,79473f8,797e8d8)
@[17] 0x6236f13c ndxlo.DxlNoteSource::GenerateDxl+316 (7945c48,797e8d8,79473f8,784e744)
@[18] 0x623570bd ndxlo.DxlSourceImpl::GenerateDxl+77 (7945c48,0,76c769c,7975f70)
@[19] 0x6235678c ndxlo.DxloImpl::GenerateDxl+524 (79473f8,7975f70,6315ba50,0)
@[20] 0x5fc799ef nnotes.DXLExportNote@16+143 (8002018e,639dfa20,7e,784f350)
@[21] 0x639e06d7 nnotesws.CEffectivePolicyRequest::Execute+2887 (784f63c,795b920,784f7a8,784f790)

@[22] 0x651c2536 nxpm.CXmlRequestProcessor::ProcessRequestExt+838 (4d22724,795b870,0,0)
@[23] 0x651c1572 nxpm.CXmlRequestProcessor::ProcessRequest+34 (4d22724,167,784f8dc,784f8c8)
@[24] 0x63b90f0d nnotesws.WCTBackgroundMsgThread+1101 (0,0,0,0)
@[25] 0x5f69b621 nnotes.ThreadWrapper@4+225 (0)
 [26] 0x7760ef1c kernel32.BaseThreadInitThunk+18 (0,704f320d,0,0)
 [27] 0x77c33b53 ntdll.RtlInitializeExceptionChain+239 (5f69b540,0,0,0)
 [28] 0x77c33b26 ntdll.RtlInitializeExceptionChain+194 (5f69b540,0,0,0)

Das heisst: Die falschen Policy- Einstellungen mit einem deutschen Template- gemacht, und jeder Client, der diese Policy bekommt, crasht unweigerlich, und das bei jedem Start, weil Policies sofort beim Start gezogen werden. Es hilft dann nur:
  • Basic- Client starten
  • Policies aus ($Policies) löschen
  • Client wieder normal starten

Jetzt zurück zum Script: Das führt zwar ein Replace in allen betroffenen FELDWERTEN durch, lässt aber die fehlerhaften FELDER in den Policy- Dokumenten drin. Hilft also nicht wirklich.
Ihr könnt das Script aber wie folgt ergänzen (rote Schrift), um die Crash- verursachenden Felder aus den Policies zu entfernen.
Ich habe absichtlich den "Stil" des Codes nicht verändert, um meine Aussage von oben (von wegen Praktikanten) zu belegen...

Zitat
   Dim ss As New NotesSession
   Dim db As NotesDatabase
   Dim doc As NotesDocument
   Dim doccol As NotesDocumentCollection
   Dim v,v1,v2 As Variant
   Dim i As Integer
   Dim flag,flag1,flag2,flag3 As Boolean
   Dim strItemName As String
   
   i = 0
   Set db = ss.Currentdatabase
   Set doccol= db.Unprocesseddocuments
   Set doc = doccol.Getfirstdocument()
   While Not doc Is Nothing
      If doc.form(0) = "PolicyDesktop" Then
         v=doc.Getitemvalue("Parameters")
         flag = True
         ForAll x In v
            If InStr(x,"Zwingend") Then
               i = i+1
               flag=False
            End If
         End ForAll
         v1=doc.Getitemvalue("LocParameters")
         flag1 = True
         ForAll x In v1
            If InStr(x,"Zwingend") Then
               i = i+1
               flag1=False
            End If
         End ForAll
         v2=doc.Getitemvalue("EclipseParameters")
         flag2 = True
         ForAll x In v2
            If InStr(x,"Zwingend") Then
               i = i+1
               flag2=False
            End If
         End ForAll
         If flag = False Then
            v=Replace(v,"Zwingend","Enforce")
            Call doc.Replaceitemvalue("Parameters", v)
            Call doc.Save(1, 1)
         End If
         If flag1 = False Then
            v1=Replace(v1,"Zwingend","Enforce")
            Call doc.Replaceitemvalue("LocParameters", v1)
            Call doc.Save(1, 1)
         End If
         If flag2 = False Then
            v2=Replace(v2,"Zwingend","Enforce")
            Call doc.Replaceitemvalue("EclipseParameters", v2)
            Call doc.Save(1, 1)
         End If
         '>>>>>>>> BEREINIGE FEHLERHAFTE FELDER
         flag3 = True
         ForAll item In doc.Items
            strItemName = LCase( item.Name )
            If Left( strItemName, 6 ) = "$qual_" Then
               If InStr( strItemName, "zwingend" ) > 0 Then
                  flag3 = False
                  item.SaveToDisk = False
                  i = i + 1
               End If
            End If
         End ForAll
         '<<<<<<< ENDE BEREINIGE FEHLERHAFTE FELDER

         If flag=False Or flag1=False Or flag2=False Or flag3=False Then
            Call doc.Computewithform(True,True)
            Call doc.Save(True,False,True)
         End If
      End If
      Set doc = doccol.Getnextdocument(doc)
   Wend
   MsgBox("The replacing action completed, total " + CStr(i) + " occurences were changed!" )
Gruss
Torsten (Tode)

P.S.: Da mein Nickname immer mal wieder für Verwirrung sorgt: Tode hat NICHTS mit Tod zu tun. So klingt es einfach, wenn ein 2- Jähriger versucht "Torsten" zu sagen... das klingt dann so: "Tooode" (langes O, das r, s und n werden verschluckt, das t wird zum badischen d)

Offline Tode

  • Moderatoren
  • Gold Platin u.s.w. member:)
  • *****
  • Beiträge: 6.883
  • Geschlecht: Männlich
  • Geht nicht, gibt's (fast) nicht... *g*
Damit ich nicht nur gemeckert habe... So hätte ich den Code geschrieben... Verbesserungsvorschläge gerne erwünscht ;)
Das geht natürlich wesentlich kürzer, ich wollte aber den "Errorcounter" aus dem Ursprungscode beibehalten...
Code
	On Error GoTo ErrorRoutine
	'-----------------------------------------------------------------------------------------------------------------------------------
	Dim ss As New NotesSession
	Dim db As NotesDatabase
	Dim doccol As NotesDocumentCollection
	Dim doc As NotesDocument
	Dim intCount As Integer

	Dim varCheckItemNames As Variant
	Dim varCheckValues As Variant
	Dim varGoodValues As Variant
	Dim strItemName As String
	Dim blnItemShouldBeChanged As Boolean
	Dim blnDocHasChanged As Boolean
	
	Const BADSTRING = "Zwingend"
	Const GOODSTRING = "Enforce" 
	
	varCheckItemNames = Split( "Parameters,LocParameters,EclipseParameters", "," )
	
	intCount = 0
	Set db = ss.Currentdatabase
	Set doccol= db.Unprocesseddocuments
	Set doc = doccol.Getfirstdocument()
	While Not doc Is Nothing
		If doc.form(0) = "PolicyDesktop" Then
			'>>>>>>>> BEREINIGE FEHLERHAFTE FELDINHALTE
			ForAll strCheckItemName In varCheckItemNames
				varCheckValues = doc.Getitemvalue( strCheckItemName )
				blnItemShouldBeChanged = False
				ForAll strCheckValue In varCheckValues
					If InStr( strCheckValue, BADSTRING ) > 0 Then
						intCount = intCount + 1
						blnItemShouldBeChanged = True
						Exit Forall
					End If
				End ForAll
				If blnItemShouldBeChanged = True Then
					blnDocHasChanged = True
					varGoodValues = Replace( varCheckValues, BADSTRING, GOODSTRING )
					Call doc.Replaceitemvalue( strCheckItemName, varGoodValues )
				End If
			End ForAll
			'<<<<<<< ENDE BEREINIGE FEHLERHAFTE FELDINHALTE
			'>>>>>>>> BEREINIGE FEHLERHAFTE FELDER
			ForAll item In doc.Items
				strItemName = LCase( item.Name )
				If Left( strItemName, 6 ) = "$qual_" Then
					If InStr( strItemName, lcase( BADSTRING ) ) > 0 Then
						item.SaveToDisk = False
						blnDocHasChanged = True
						intCount = intCount + 1
					End If
				End If
			End ForAll
			'<<<<<<< ENDE BEREINIGE FEHLERHAFTE FELDER
			If blnDocHasChanged = True Then
				Call doc.Computewithform(True,True)
				Call doc.Save(True,False,True)
			End If
		End If
		Set doc = doccol.Getnextdocument(doc)
	Wend
	MsgBox("The replacing action completed, total " + CStr(intCount) + " occurences were changed!" )
	'-----------------------------------------------------------------------------------------------------------------------------------
EndOfRoutine:
	Exit Sub
ErrorRoutine:
	MessageBox "Error: " & Err & ", " & Error & " in line " & Erl
	Resume EndOfRoutine
« Letzte Änderung: 02.03.16 - 18:31:58 von Tode »
Gruss
Torsten (Tode)

P.S.: Da mein Nickname immer mal wieder für Verwirrung sorgt: Tode hat NICHTS mit Tod zu tun. So klingt es einfach, wenn ein 2- Jähriger versucht "Torsten" zu sagen... das klingt dann so: "Tooode" (langes O, das r, s und n werden verschluckt, das t wird zum badischen d)

Offline Andrew Harder

  • Senior Mitglied
  • ****
  • Beiträge: 295
  • Geschlecht: Männlich
Finde es sehr kollegial von Dir, Danke für die Warnung.
Dein Code ist eindeutig besser, weil lesbarer und für ein Forum würde ich das "Why", statt "What" auch ignorieren, da es hier den Patch auf einen Blick sehr anschaulich macht.
Insofern wäre kürzer hier höchstwahrscheinlich nicht besser.
Andy

 

Impressum Atnotes.de  -  Powered by Syslords Solutions  -  Datenschutz