Wednesday, January 13, 2010

Brazilian Frontier Wikipedia

Retrieve a SID or a login from Windows NatStar

I have recently for a project to add integrated authentication to an application NatStar: the objective being to avoid the user to enter a password if the Windows user logged on is authorized to use application.

user "Windows" can cover various technical information in this post I will discuss two: the login

  • Windows: The Windows account name used to log
  • the SID of the user: it is a concept Microsoft allows unique identification of a user (security ID)

The retrieval of this information and use since being NatStar not very simple, I propose in this post a detailed description of the mechanism.

Exercise is done under NatStar, it should not be very difficult to adapt if NS-DK.

functions MicroSoft

We'll use 5 functions from MicroSoft NatStar:

  • advapi32.GetUserNameA: This function is the starting point of the mechanism, it returns the login of the logged on user.
  • advapi32.LookupAccountNameA: This feature allows login from the recovered thanks to the previous function to retrieve a pointer to the SID structure.
  • Advapi32.ConvertSidToStringSidA: This function obtains the SID from the previous function recovered by a string corresponding to the CIS.
  • KERNEL32.GetLastError: This function retrieves the last error raised by Windows. The 3 previous position functions in case of trouble this error.
  • KERNEL32.LocalFree: This feature frees up some resources allocated by Windows. It will free the information returned by ConvertSidToStringSidA.

The first 3 functions return 0 if an error and a different value of 0 if all goes well.

LookupAccountName

This function has an unusual procedure: we must call it twice:

  1. once with a size 0 and a pointer to SID 0: then the function returns the size of the SID. It must then allocate space for the SID.
  2. the second call takes the address of the allocated space and the size of the buffer to fill. It then has a SID.

To make things worse, in the first case, we can ignore the return value: there is an error if the size is zero.

Mapping function in MicroSoft NatStar

To use the functions previously defined since NatStar we define the external function. To do this, we created a library service in which we add 5 functions.

For these 5 functions, the External radio button of the definition should be checked.

MSGETLASTERROR% GetLastError for

We start with the simplest. We edit the function definition. In the dialog "Modify Definition for Function or Instruction MSGETLASTERROR%" it says:

  • Result type: INT (4)
  • External: KERNEL32.GetLastError

This function failing parameter, there is nothing else to do.

MSLOCALFREE for LocalFree

We continue with a little more complicated. We edit the function definition. In the dialog "Modify Definition for Function or Instruction MSLOCALFREE" it says:

  • Result Type: POINTER
  • External: KERNEL32.LocalFree

This function has one parameter, so we add in the Parameters tab the following parameter:

  • Name: HMEM
  • We check: In
  • Type: POINTER
  • Size: empty

Think Append then press Ok so you do not lose your changes.

MSGETUSERNAME% for GetUserNameA

We continue with a little more complicated. We edit the function definition. In the dialog "Modify Definition for Function or Instruction MSGETUSERNAME%" it says:

  • Result type: INT (4)
  • External: advapi32.GetUserNameA

This function has two parameters, we therefore added in the Parameters tab the following parameters:

  • Name: lpBuffer $
  • checkmark is: Out
  • Type: CSTRING
  • Size: 255

Think Append then press Ok so you do not lose your changes, then add the second:

  • Name: nSize%
  • We check: In and Out
  • Type: INT
  • Size: 4

is the first parameter LpBuffer $, which will contain the name of the user's Windows account.

MSGETUSERSID% for LookupAccountName

We continue with a little more complicated. We edit the function definition. In the dialog "Modify Definition for Function or Instruction MSGETUSERSID%" it says:

  • Result type: INT (4)
  • External: advapi32.LookupAccountNameA

This function has seven parameters, we therefore added in the Parameters tab the following parameters:

  • Name: LPSYSTEMNAME
  • We check: In
  • Type: CSTRING
  • Size : 255

Pensez à appuyer sur Append puis Ok afin de ne pas perdre vos modifications, puis ajoutez le second :

  • Name : LPACCOUNTNAME
  • On coche : In
  • Type : CSTRING
  • Size : 255

Passons au troisième :

  • Name : SID
  • On coche : In
  • Type : POINTER
  • Size : vide

Passons au quatrième :

  • Name : CBSID
  • On coche : In et Out
  • Type : INT
  • Size : 4

Passons au cinquième :

  • Name: REFERENCEDDOMAINNAME
  • On Car: Out
  • Type: CString
  • Size: 255

Passons au sixième:

  • Name: CCHREFERENCEDDOMAINNAME
  • On Car: In et Out
  • Type: INT
  • Size: 4

Passons au septième:

  • Name: Peuser
  • On Car: Out
  • Type: INT
  • Size: 4

3ieme C'est le parametre qui correspond in au SID SID Windows pointeur . C'est qui cette valeur utilisée avec will MSCONVERTSIDTOSTRINGSID% to retrieve the corresponding string.

MSCONVERTSIDTOSTRINGSID% for ConvertSidToStringSidA

We finish with the most complicated. Before you edit the definition of this function, we create a new segment PSTRSID that will be used to retrieve the value that contains the string.

Note that the function MicroSoft says this parameter in C + + as: BOOL

ConvertSidToStringSid (

__init Sid PSID, LPTSTR *

__out StringSid

)

The StringSid is a pointer to a pointer to a string. To do the same thing, we need an intermediate segment.

This segment is very simple, it has only one Field:

  • Name: STRINGSID $
  • Type: CSTRING
  • Size: 255
  • It checks the box Reference (beware this is very important)

We can now edit the function definition. In the dialog "Modify Definition for Function or Instruction MSCONVERTSIDTOSTRINGSID%" it says:

  • Result type: INT (4)
  • External: advapi32.ConvertSidToStringSidA

This function has two parameters, we therefore added in the Parameters tab the following parameters:

  • Name: SID
  • We check: In
  • Type: POINTER
  • Size: empty

Think Append then press Ok so you do not lose your changes, then add the second:

  • Name: STRINGSID
  • We check: Out
  • Type: PSTRSID (c is the segment it created previously appeared in the party is in order alphabetically)
  • Size: empty

is the first parameter is the pointer to SID SID Windows recovered from the previous function.

The second parameter will retrieve the string with: L_SID_USER_WINDOWS.STRINGSID $ L_SID_USER_WINDOWS if the value is retrieved as the second parameter.

Using Functions

We defined external functions that allow the appeal of Microsoft services, we will now use these services.

Recovery Windows login

This first step is simple:

  1. We initialize variables
  2. We call the function MSGETUSERNAME%
  3. is verified that there was no error

What gives NCL:

CSTRING LOCAL Buffer $
LOCAL LOCAL int int
SizeBuffer% Return%

Local USER_WINDOWS $ cstring (255)

USER_WINDOWS $ $ =''=''
L_LPBUFFER
SizeBuffer% = 255; buffer size = 0% Return

Return% = MSGETUSERNAME% (Buffer $ SizeBuffer%)

; If the return is different 0 then everything is OK If
Return% \u0026lt;> 0
USER_WINDOWS $ = $ skip L_LPBUFFER

Endif

The value retrieved in the variable $ is the USER_WINDOWS Windows user login. It can be used to check database if that user has the right to connect to your application.

Recovery Windows SID

The Windows login is easy to recover, it has a functional significance for users, but it is less permanent than the SID, if the user changes the login result a wedding for example, the Windows account is changed but not its SID. Its disadvantage is that the SID is a number incomprehensible without any functional sense.

It may also be interesting to retrieve the SID for interviewing other security services, but we will not discuss this point.

To use the SID, you must first retrieve the $ USER_WINDOWS. Then added the following code:

Return% = 0 =''
L_LPSYSTEMNAME $
SizeBuffer% = 0; buffer size =''
L_LPSYSTEMNAME $
L_CCHREFERENCEDDOMAINNAME% = 255; size buffer

; The first function call with a 3rd parameter to 0, returns the size of the structure PSID (SizeBuffer%) =%
Back MSGETUSERSID% (L_LPSYSTEMNAME $ USER_WINDOWS $ 0, SizeBuffer% L_REFERENCEDDOMAINNAME $ L_CCHREFERENCEDDOMAINNAME% L_PSID_NAME_USE%)
things_trace "first call SizeBuffer% =" &% SizeBuffer

If (SizeBuffer% \u0026lt;= 0)
things_trace "ERROR MSGETUSERSID% 1% = GetLastError "& String (MsGetLastError% 16)
Else New
SizeBuffer% L_PSID
; Gets the point of the structure of the USER SID Windows
Back MSGETUSERSID% =% (L_LPSYSTEMNAME $ USER_WINDOWS $ L_PSID, SizeBuffer% L_REFERENCEDDOMAINNAME $ L_CCHREFERENCEDDOMAINNAME% L_PSID_NAME_USE%) & #

160 if (Return% = 0)
things_trace "ERROR during the 2nd MSGETUSERSID%% = GetLastError "& String (MsGetLastError% 16)
Else
; Convert Point structure SID Windows USER chain
Back MSCONVERTSIDTOSTRINGSID% =% (L_PSID, L_SID_USER_WINDOWS)
if (Return % = 0)
things_trace "ERROR of MSCONVERTSIDTOSTRINGSID%% = GetLastError "& String (MsGetLastError% 16)
Else
SID_USER_WINDOWS $ = L_SID_USER_WINDOWS . STRINGSID $
things_trace "$ SID_USER_WINDOWS = "& $ SID_USER_WINDOWS

& # 160;; must free the string retrieved
; P = MSLocalFree (@ L_SID_USER_WINDOWS.STRINGSID $)
; things_trace "Profit LocalSystem free =" & P & & String (MsGetLastError% 16)
& # 160; endif

endif
dispose L_PSID
endif

For it to work, you must add at the beginning of the following statements:

LOCAL L_PSID point, point P
Local L_PSID_NAME_USE%
int int L_CCHREFERENCEDDOMAINNAME%
Local Local Local CSTRING L_LPSYSTEMNAME $
CSTRING L_REFERENCEDDOMAINNAME $
Local PSTRSID L_SID_USER_WINDOWS

value recovered in SID_USER_WINDOWS $ is the string corresponding to the identifier of the CIS.

Note the use of syntax: String (MsGetLastError%, 16). The GetLastError returns an error code. This error code is a numerical but usually appears in the literature as hexadecimal. This syntax is used to draw the hexadecimal code directly.

parameter compilation

Compiling the above code to be able to request from linking with the library advapi32.dll. This DLL system is available on all computers and requires no further deployment.

The compilation requires access to its EDGE. To make this possible, we must modify the LIB environment variable and add the two following directories (in case of MSVC 8):

  • C: \\ Program Files \\ Microsoft Visual Studio 8 \\ VC \\ PlatformSDK \\ Lib
  • C: \\ Program Files \\ Microsoft Visual Studio 8 \\ VC

NatStar If you use directly (without NsaConfig) is enough.

Through use of NsaConfig where the launch and environmental work NatStar depends on the configuration NsaConfig, it is necessary to modify the file C: \\ CASS \\ INI \\ wspmgr . ini:

  1. envvar adding in the statement the following two variables and MsSdklib COMPPATH (it's essential that the following definitions are taken into account.
  2. then adding the two lines following definition in the following statement envvar
    • MsSdklib = C: \\ Program Files \\ Microsoft Visual Studio 8 \\ VC \\ PlatformSDK \\ Lib
    • COMPPATH = C: \\ Program Files \\ Microsoft Visual Studio 8 \\ VC
  3. then modifying the LIB statement to read:
    • LIB =% NS-GLOB% \\ CLASSES \\ LIB;% NS-GLOB% \\ SERVICES \\ LIB; COMPPATH%% \\ LIB; MsSdklib%%%% NATSTARPATH \\ LIB;% LIB%

Conclusion I hope this post has been helpful. It shows that it is possible to implement integrated authentication in an application or NS-DK NatStar even if it is not obvious. We note in passing that the complexity comes mainly from MicroSoft API available (I know, I'm technical director Nat System and probably a little biased).

0 comments:

Post a Comment