Jump to content

LDAP Byte return - is not recognized


ptrex
 Share

Recommended Posts

@all

I just ran into this nice article, which might explain what it is about (incl. Examples) :

You Can't Convert Data Structures To Strings In VBScript Without Breaking A Few Eggs

I haven't read it yet, but it look like a good lead.

I will play around with it.

I hope you all do the same.

Link to comment
Share on other sites

  • Replies 58
  • Created
  • Last Reply

Top Posters In This Topic

Top Posters In This Topic

are you speaking of the VBscript executed without the GetInfoEx statement?

can somebody explain me what this GetInfoEx statement is suppose to do?

Looking for it, but haven't found it yet. And we two different versions of VBScript code that will work, one uses that method and the other doesn't.

The OP from the topic that started this posted some MS VBScript that works without that.

The method in that is perhaps more straight forward:

CODE
On Error Resume Next

Dim arrLogonHoursBytes(20)

Dim arrLogonHoursBits(167)

arrDayOfWeek = Array _

("Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat")

Set objUser = GetObject _

("LDAP://CN=Joe Bloggs,OU=MyUsers,DC=domain,DC=com")

arrLogonHours = objUser.Get("logonHours")

For i = 1 To LenB(arrLogonHours)

WScript.Echo "length - " & LenB(arrLogonHours)

arrLogonHoursBytes(i-1) = AscB(MidB(arrLogonHours, i, 1))

' WScript.Echo "MidB returns: " & MidB(arrLogonHours, i, 1)

' WScript.Echo "arrLogonHoursBytes: " & arrLogonHoursBytes(i-1)

' wscript.echo vbcrlf

Next

intCounter = 0

intLoopCounter = 0

WScript.echo "Day Byte 1 Byte 2 Byte 3"

For Each LogonHourByte In arrLogonHoursBytes

arrLogonHourBits = GetLogonHourBits(LogonHourByte)

If intCounter = 0 Then

WScript.STDOUT.Write arrDayOfWeek(intLoopCounter) & Space(2)

intLoopCounter = intLoopCounter + 1

End If

For Each LogonHourBit In arrLogonHourBits

WScript.STDOUT.Write LogonHourBit

intCounter = 1 + intCounter

If intCounter = 8 or intCounter = 16 Then

Wscript.STDOUT.Write Space(1)

End If

If intCounter = 24 Then

WScript.echo vbCr

intCounter = 0

End If

Next

Next

Function GetLogonHourBits(x)

Dim arrBits(7)

For i = 7 to 0 Step -1

If x And 2^i Then

arrBits(i) = 1

Else

arrBits(i) = 0

End If

Next

GetLogonHourBits = arrBits

End Function

The part we started out trying to match in AutoIt is simply:

Set objUser = GetObject _
("LDAP://CN=Joe Bloggs,OU=MyUsers,DC=domain,DC=com")
arrLogonHours = objUser.Get("logonHours")

The other VBScript I posted is the one using the function you are talking about:

' Retrieve the user's logonHours attribute.
objUser.GetInfoEx Array("logonHours"), 0
bytLogonHours = objUser.Get("logonHours")

I've run both on a Win2K3 AD domain with a user configured for logon hours restrictions, and they both work. In the first script, we can't seem to get anything returned to $arrLogonHours after translating to AutoIt, and in the second we have no idea how to translate 'objUser.GetInfoEx Array("logonHours"), 0' to AutoIt, as you pointed out.

Still looking for a reference online when I get spare moments...

Edited by PsaltyDS
Valuater's AutoIt 1-2-3, Class... Is now in Session!For those who want somebody to write the script for them: RentACoder"Any technology distinguishable from magic is insufficiently advanced." -- Geek's corollary to Clarke's law
Link to comment
Share on other sites

Link to comment
Share on other sites

@PsaltyDS

No good examples !!

The Devs need non LDAP related examples so they can test in a non AD environment.

Please provide only these.

Thanks

Yeah, I got that. They were not meant as examples to work with, rather to show that the objUser.GetInfoEx Array("logonHours"), 0 method jpm asked about is not used in both, and so may not be central to the issue.

<_<

Valuater's AutoIt 1-2-3, Class... Is now in Session!For those who want somebody to write the script for them: RentACoder"Any technology distinguishable from magic is insufficiently advanced." -- Geek's corollary to Clarke's law
Link to comment
Share on other sites

Yeah, I got that. They were not meant as examples to work with, rather to show that the objUser.GetInfoEx Array("logonHours"), 0 method jpm asked about is not used in both, and so may not be central to the issue.

Found more info on MSDN. Seems the whole point to the .GetInfoEx method is to cache attributes in one call. Later references can get the same properties of the object without any additional network overhead:

; Retrieve the user's distinguishedname and logonHours attributes into cache.
$avProps = _ArrayCreate("DistinguishedName", "logonHours") ; create array of properties to get
$objUser.GetInfoEx($avProps, 0) ; Second param is reserved and must be 0

; This call and the next require no more network activity because the values were cached above
MsgBox(64, "DName", "DName = " & $objUser.Get("DistinguishedName"))
$arrLogonHours = $objUser.Get("logonHours")

Doesn't help figure out the byte array, but illuminates the .GetInfoEx call.

<_<

Edited by PsaltyDS
Valuater's AutoIt 1-2-3, Class... Is now in Session!For those who want somebody to write the script for them: RentACoder"Any technology distinguishable from magic is insufficiently advanced." -- Geek's corollary to Clarke's law
Link to comment
Share on other sites

Doesn't help figure out the byte array, but illuminates the .GetInfoEx call.

It may be helpfull to simply the problem abit...

The issue is simply that it doesn't keep the value it should (or that the users wants)-

Here's a simple example, the autoit code gives 0 for the string length (nothings there)

$objUser=ObjGet ("LDAP://cn=User,ou=OU,dc=DOMAIN,dc=COM")
$ret = $objUser.logonHours
MsgBox(0,"","Length-"&StringLen($ret))

The vbs code gives a number (somthing is there)-

Set objUser = GetObject ("LDAP://cn=User,ou=OU,dc=DOMAIN,dc=COM")
ret = objUser.logonHours
WScript.Echo "length - " & Len(ret)

(This assumes you have somthing set for the user in question)

Hopefully this may expediate the process...

Link to comment
Share on other sites

It may be helpfull to simply the problem abit...

The issue is simply that it doesn't keep the value it should (or that the users wants)-

Here's a simple example, the autoit code gives 0 for the string length (nothings there)

$objUser=ObjGet ("LDAP://cn=User,ou=OU,dc=DOMAIN,dc=COM")
$ret = $objUser.logonHours
MsgBox(0,"","Length-"&StringLen($ret))

The vbs code gives a number (somthing is there)-

Set objUser = GetObject ("LDAP://cn=User,ou=OU,dc=DOMAIN,dc=COM")
ret = objUser.logonHours
WScript.Echo "length - " & Len(ret)

(This assumes you have somthing set for the user in question)

Hopefully this may expediate the process...

I don't know if StringLen() would tell you anything about a returned Binary or Array, but the issue is that so many of the Smart People® likely to figure it out don't have AD domains to try it on. Would be nice to find another instance of this kind of byte array in a COM interface that a standalone WinXP workstation has. More eyes on the problem then...

<_<

Valuater's AutoIt 1-2-3, Class... Is now in Session!For those who want somebody to write the script for them: RentACoder"Any technology distinguishable from magic is insufficiently advanced." -- Geek's corollary to Clarke's law
Link to comment
Share on other sites

Yeah, I got that. They were not meant as examples to work with, rather to show that the objUser.GetInfoEx Array("logonHours"), 0 method jpm asked about is not used in both, and so may not be central to the issue.

<_<

Thanks,

so I can forgot about GetInfoEx having an impact on the next statement.

Now as I say an example without AD will be helpfull for me to debug

Link to comment
Share on other sites

It may be helpfull to simply the problem abit...

The issue is simply that it doesn't keep the value it should (or that the users wants)-

Here's a simple example, the autoit code gives 0 for the string length (nothings there)

$objUser=ObjGet ("LDAP://cn=User,ou=OU,dc=DOMAIN,dc=COM")
$ret = $objUser.logonHours
MsgBox(0,"","Length-"&StringLen($ret))

The vbs code gives a number (somthing is there)-

Set objUser = GetObject ("LDAP://cn=User,ou=OU,dc=DOMAIN,dc=COM")
ret = objUser.logonHours
WScript.Echo "length - " & Len(ret)

(This assumes you have somthing set for the user in question)

Hopefully this may expediate the process...

What is the value returned under VB?

can you verify that the AutoIt script is not returning an error with the com error catching?

Stringlen($ret) will always work but will me meaningless if a failure has occured.

<_<

Link to comment
Share on other sites

@All

We are running in circles here.

The problem was already discussed in the DEV's Forum +/- 1 year ago as it seems.

Assigning COM array to DllStruct

The Example posted by PaulIA should run on a local machine.

Nevertheless the problem was acknowledged, it was never fixed.

Valik points out that the problem lies in the shortcomming of the COM functionality. And thus SVenP is the one to take a look at it (if he is still around ?!)

So here ends my investigation. Over the the Devs.

Regards,

ptrex

Link to comment
Share on other sites

@All

We are running in circles here.

The problem was already discussed in the DEV's Forum +/- 1 year ago as it seems.

Assigning COM array to DllStruct

Interesting... the SID comes up formated wrong in VBScipt and this might be why: You Can't Convert Data Structures To Strings In VBScript Without Breaking A Few Eggs

...Which prints out {7E00E500-2000-BA25-4026-410054004500}

Which is also wrong. What's wrong this time?

The logical format of a GUID in memory is not in the same order as the bytes are in the string. A GUID stored in binary format in memory is a sixteen byte structure in the following format:

DWORD-WORD-WORD-BYTE BYTE-BYTE BYTE BYTE BYTE BYTE BYTE

So what? Why does that matter?

It matters because a WORD consists of two bytes, but they are stored in memory in order from the least to the most significant on my Intel machine. Same with the four-byte DWORD.

; ...

...We need to decode that thing into the correct order:

He's talking about GUIDs but I'm betting the same scheme or something similar applies to SIDs, and maybe even to the LogonHours. This was his VBScript method to deal with reformatting the data:

Function GuidToString(ByteArray)
  Dim Binary, S
  Binary = CStr(ByteArray)
  S = "{"
  S = S & HexByte(AscB(MidB(Binary, 4, 1)))
  S = S & HexByte(AscB(MidB(Binary, 3, 1)))
  S = S & HexByte(AscB(MidB(Binary, 2, 1)))
  S = S & HexByte(AscB(MidB(Binary, 1, 1)))
  S = S & "-"  
  S = S & HexByte(AscB(MidB(Binary, 6, 1)))
  S = S & HexByte(AscB(MidB(Binary, 5, 1)))
  S = S & "-"  
  S = S & HexByte(AscB(MidB(Binary, 8, 1)))
  S = S & HexByte(AscB(MidB(Binary, 7, 1)))
  S = S & "-"  
  S = S & HexByte(AscB(MidB(Binary, 9, 1)))
  S = S & HexByte(AscB(MidB(Binary, 10, 1)))
  S = S & "-"  
  S = S & HexByte(AscB(MidB(Binary, 11, 1)))
  S = S & HexByte(AscB(MidB(Binary, 12, 1)))
  S = S & HexByte(AscB(MidB(Binary, 13, 1)))
  S = S & HexByte(AscB(MidB(Binary, 14, 1)))
  S = S & HexByte(AscB(MidB(Binary, 15, 1)))
  S = S & HexByte(AscB(MidB(Binary, 16, 1)))
  S = S & "}"
  GuidToString = S
End Function

Which prints out {00E5007E-0020-25BA-4026-410054004500}, the correct string.

The function we don't have an equivilent for in AutoIt may just be CStr().

<_<

Edited by PsaltyDS
Valuater's AutoIt 1-2-3, Class... Is now in Session!For those who want somebody to write the script for them: RentACoder"Any technology distinguishable from magic is insufficiently advanced." -- Geek's corollary to Clarke's law
Link to comment
Share on other sites

Link to comment
Share on other sites

@GaryFrost

This is not solving the problem.

We are not looking for a UUID generator.

But a solution to retrieva an LDAP Byte Array return value.

Thanks anyhowe

regards

ptrex

Your looking for a returned byte array, that was a populated structure.

Wonder would the same problem apply to a dll call that returns the address of an array of DWORD values?

if so, then TBM_GETPTICS of a TrackBar (slider) control returns that.

SciTE for AutoItDirections for Submitting Standard UDFs

 

Don't argue with an idiot; people watching may not be able to tell the difference.

 

Link to comment
Share on other sites

Should this whole topic be moved from Bug Reports to Feature Requests? It's starting to look like what we want is not something fixed but rather something new for AutoIt.

<_<

Valuater's AutoIt 1-2-3, Class... Is now in Session!For those who want somebody to write the script for them: RentACoder"Any technology distinguishable from magic is insufficiently advanced." -- Geek's corollary to Clarke's law
Link to comment
Share on other sites

What is the value returned under VB?

can you verify that the AutoIt script is not returning an error with the com error catching?

Stringlen($ret) will always work but will me meaningless if a failure has occured.

The number returned is based on the values in the attribute so it can vary (usually from 8-14)

Here is a new example using the same object from the old link... this one shows the no com error occurs in autoit but more importantly it uses a non-active directory example in it's simple form-

ObjEvent("AutoIt.Error","MyErrFunc") 
$objUser=ObjGet ("WinNT://localhost/Administrator,user")
$ret = $objUser.objectSID
MsgBox(0,"","Length-"&StringLen($ret))

func MyErrFunc()
    MsgBox(0,"Error","Somthing happened")
EndFunc

This AutoIt script leaves a seemingly blank value for $ret

Set objUser = GetObject ("WinNT://localhost/Administrator,user")
ret = objUser.objectSID
WScript.Echo "length - " & Len(ret)

This VB code returns a 14 for me.

Although the return type isn't a string per se, it is somthing, so when stringlen() is ran on it, it should return the length of the binary data intuprted as a string (as in VB). Although this was just a simple method to show that it doesn't really contain any value so far as we can tell, a more involved anylysis should show the same thing.

Link to comment
Share on other sites

Should this whole topic be moved from Bug Reports to Feature Requests? It's starting to look like what we want is not something fixed but rather something new for AutoIt.

<_<

It's not a bug, and it doesn't need to be requested again. I remember the thread linked previously, I had some exchange with SvenP aftewards, although I don't recall what we said. I may still have the PMs and if I think of it, I may look for them later.

At any rate, this isn't a bug and it doesn't need to be requested again. It'll be implemented when it's implemented is about all I can say. Clearly it's a little use feature of COM so there's no priority to getting it added.

Link to comment
Share on other sites

@Valik

Clearly it's a little use feature of COM so there's no priority to getting it added.

I wouldn't say that !!

I ran into 3 thread last week only, where people ran into this limitation while scripting.

And of course if it doesn't work, it's of course little uised.

Anyhow thanks for looking into this matter again.

And we'll be patient waiting for the champagne bottle to be opened some time. <_<

Regards

ptrex

Edited by ptrex
Link to comment
Share on other sites

As I am not a Com expert I added 2 functions to handle those objects

$bool=IsObjArray($obj) and $array=ObjGetArray($obj)

I am sure the COM dev expert will challenge but well that solve the SID/"longhours" issue

Will delivered in 3.2.9.5

Link to comment
Share on other sites

@Valik

I wouldn't say that !!

I ran into 3 thread last week only, where people ran into this limitation while scripting.

And of course if it doesn't work, it's of course little uised.

Anyhow thanks for looking into this matter again.

And we'll be patient waiting for the champagne bottle to be opened some time. <_<

Regards

ptrex

Well, given that not even the developers knew if the feature was implemented or not, I think that's a pretty clear sign that not too many people are missing the feature since nobody is really clamoring for it and the status of the feature hasn't changed since I was last active.

As I am not a Com expert I added 2 functions to handle those objects

$bool=IsObjArray($obj) and $array=ObjGetArray($obj)

I am sure the COM dev expert will challenge but well that solve the SID/"longhours" issue

Will delivered in 3.2.9.5

Consider this the challenge. At best, that is simply a work-around. SAFEARRAY (byte or otherwise) should be handled natively in a way that makes most sense for the data-type in question. For byte array's, this may be returning a DllStruct automatically. Ideally, it would be returned in a format more native to AutoIt, but I must read SvenP's responses to my questions to see why that wasn't done.

This is a case where it's better to do it right the first time or do nothing at all rather than do something that's clearly going to be changed. Also, while not exactly ideal, there already is a work-around. Instantiate the VBS object to do this particular bit of processing and package up the data using VBS and return it to AutoIt as a string or some other suitable format. It's ugly, but functional, and doesn't require us to add temporary measures to help out 5 people.

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...