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