Hi,

I've been doing some tests with synapse's LdapSend and noticed that it has 
sesious issues with newer Delphis. Any dn, password or attribute value 
containing Unicode characters fails as synapse internally doesn't handle 
strings in a consistent way.

These problems are hidden as these scary lines are in the beginning of the pas 
files:

{$IFDEF UNICODE}
   {$WARN IMPLICIT_STRING_CAST OFF}
  {$WARN IMPLICIT_STRING_CAST_LOSS OFF}
   {$WARN SUSPICIOUS_TYPECAST OFF}
{$ENDIF}

If you uncomment those, you get tons of warnings and unfortunately many of them 
really do lose data.

I've made some changes to get LdapSend to work with the features I use. But I'd 
like to know what should be done, as all changes can't be backwards compatible.

First of all, I wrote two functions for converting Delphi Unicode strings to 
Utf8- or UCS2 strings:

function StringToRawUtf8(const S: String): RawByteString;
var Utf: Utf8String;
begin
  Utf:=S;
  SetLength(result,Length(Utf));
  Move(pAnsiChar(Utf)^,pAnsiChar(result)^,Length(result));
end;

function StringToRawUCS2(const S: String): RawByteString;
begin
  SetLength(result,Length(S)*2);
  Move(pChar(S)^,pAnsiChar(result)^,Length(result));
end;

Then we need a String-version of ASNObject too. This one makes sure that Data 
is converted to utf8 without losing anything.

function ASNObject(const Data: String; ASNType: Integer): AnsiString;
var RawData: RawByteString;
begin
  RawData := StringToRawUtf8(Data);
  Result := AnsiChar(ASNType) + ASNEncLen(Length(RawData)) + RawData;
end;

And another one for data, which needs to specifically be sent as UCS2. This is 
needed when you try to change unicodePwd in Active Directory:

function ASNObjectUnicode(const Data: String; ASNType: Integer): AnsiString;
var RawData: RawByteString;
begin
  RawData := StringToRawUCS2(Data);
  Result := AnsiChar(ASNType) + ASNEncLen(Length(RawData)) + RawData;
end;

Some parameters need to be changed in ldapsend.pas:

function Modify(obj: String; Op: TLDAPModifyOp; const Value: TLDAPAttribute): 
Boolean;  //obj as string
function Search(obj: String; TypesOnly: Boolean; Filter: String; //obj and 
filter as string

A better way of removing parentheses in TLDAPSend.TranslateFilter. Originally 
RPos screwed up the Value as it was passed as an AnsiString and RPos works on 
normal strings. As I changed Filter from AnsiString to String, the problem is 
not as big any more. However, the newer code is better as it handles multiple 
nested parentheses.

-  if Value[1] = '(' then
-  begin
-    x := RPos(')', Value);
-    s := Copy(Value, 2, x - 2);
-  end;
+  while (Length(s) > 0) and (s[1] = '(') and (s[Length(s)] = ')') do
+    s:=copy(s,2,Length(s)-2);

unicodePwd needs to be handled in a special way in TLDapSend.Search as the new 
password needs to have quotes and it has to be encoded in UCS2:

-  for n := 0 to Value.Count -1 do
-    s := s + ASNObject(Value[n], ASN1_OCTSTR);
+  for n := 0 to Value.Count -1 do begin
+    if CompareText(Value.AttributeName,'unicodePwd')=0 then
+      s := s + ASNObjectUnicode('"'+Value[n]+'"', ASN1_OCTSTR)
+    else
+      s := s + ASNObject(Value[n], ASN1_OCTSTR);
+  end;

And in TLDAPSend.Search we need to convert the Filter to utf8 before calling 
TranslateFilter:

-  t := TranslateFilter(Filter);
+  t := TranslateFilter(StringToRawUtf8(Filter));

Well, that's the beginning. As Synapse is used with old Delphis, new Delphis 
and Lazarus/FPC, the conversion functions need some ifdefs to handle 
everything, but I wanted to post these as examples before making any more 
changes.

Maybe the biggest question is the one breaking backwards compatibility: 
Changing a Unicode pwd. With current synapse code one has to make sure to 
encode the string already as pure Unicode and add the quotes. However, synapse 
itself removes the quotes usually from attribute values. This has worked by 
accident earlier as the last char of the new password is #0. I'd prefer 
changing the code so, that the new password is sent without quotes and LdapSend 
itself handles the special case encoding the password as AD wants it to be 
encoded.

Regards,

Jarto Tarpio
------------------------------------------------------------------------------
One dashboard for servers and applications across Physical-Virtual-Cloud 
Widest out-of-the-box monitoring support with 50+ applications
Performance metrics, stats and reports that give you Actionable Insights
Deep dive visibility with transaction tracing using APM Insight.
http://ad.doubleclick.net/ddm/clk/290420510;117567292;y
_______________________________________________
synalist-public mailing list
synalist-public@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/synalist-public

Reply via email to