Sign in to follow this  
Followers 0
Mat

_UserExt - Logging in and out.

39 posts in this topic

#1 ·  Posted (edited)

I've been meaning to do this for a while, and I don't see why i didn't as its pretty simple. I actually got my act togethor after a brief exchange with the saint about how to log into another user (look for everyday scripts - chat forum - end of page 3).

The functions as it stands:

; _UserSetAutoLogon

; _UserRemoveAutoLogon

; _UserIsValid

; _UserLogInToOtherDirect

*New*

; _UserAutoLogBackUp

; _UserAutoLogRestore

*Even Newer*

; _UserPasswordIsBlank ==> ResNullius

; _UserPasswordIsValid ==> Storme

The 4th is more a script than a function, but I added it becouse its pretty useful, and was the reason I wrote the rest!

_UserIsValid is a remake of JSThePatriots _ComputerGetUsers from his computer management UDF. It is the one function that could actually be useful to someone! ^_^

Other thanks to the saint. as mentioned.

Here it is Downloads so far: 568324

I have also made 2 examples on how to use this effectively. The first is a lot simpler than the second, which tries to mimic the standard xp logon screen.

Have a nice day!

MDiesel

Edited by mdiesel

Share this post


Link to post
Share on other sites



#2 ·  Posted (edited)

Looks like you've done a fine job!

Two things of note though.

1) You should definitely give a strong warning about what might go wrong, and provide details on how to deal with it (i.e. by holding down the SHIFT key during bootup / logoff / login). Setting a wrong password, will also give a login prompt. Another failsafe, is to create a .reg file backup first time around, which can be used by an admin to restore settings.

2) I don't see the implementation of the reg key to keep an internet connection alive while logging into another user ('KeepRasConnections' I think).

Edited by TheSaint

AutoIt.4.Life Clubrooms - Life is like a Donut (secret key)

Make sure brain is in gear before opening mouth!
Remember, what is not said, can be just as important as what is said.

Spoiler

What is the Secret Key? Life is like a Donut

If I put effort into communication, I expect you to read properly & fully, or just not comment.
Ignoring those who try to divert conversation with irrelevancies.
If I'm intent on insulting you or being rude, I will be obvious, not ambiguous about it.
I'm only big and bad, to those who have an over-active imagination.

I may have the Artistic Liesense ;) to disagree with you. TheSaint's Toolbox (be advised many downloads are not working due to ISP screwup with my storage)

userbar.png

Share this post


Link to post
Share on other sites

Thanks!

The irst one I am aware of, and where possible have put warnings. I was thinking of having restore + backup functions, and im wrking on it.

The second I did not know about, and sounds very useful, so I will build that in asap. propbably tommorrow.

Share this post


Link to post
Share on other sites

G'day mdiesel

Can I suggest you add a "checkUserCredentials" function to your UDF to check "userid/password".

Check out this tread http://www.autoitscript.com/forum/index.php?showtopic=92240 for all the details.

I've been using it in one of my scripts for a while now and it works very well. Except it can't validate a user with no password.

Anyone know how to check that a user has a password or not? Would be a usefull addition to the "checkUserCredentials" to get around problem (ie no password).

Thanks

John Morrison

Share this post


Link to post
Share on other sites

#5 ·  Posted (edited)

G'day mdiesel

Can I suggest you add a "checkUserCredentials" function to your UDF to check "userid/password".

Check out this tread http://www.autoitscript.com/forum/index.php?showtopic=92240 for all the details.

I've been using it in one of my scripts for a while now and it works very well. Except it can't validate a user with no password.

Anyone know how to check that a user has a password or not? Would be a usefull addition to the "checkUserCredentials" to get around problem (ie no password).

Thanks

John Morrison

I overcome all this in my Shutdown Options program, by storing user passwords and admin password for the program (encrypted in the settings ini). Obviously each user has to provide their own password, and other users cannot login to them unless they don't have a password set.

So essentially, if all users have a password set for logging in, then a user can only auto login/reboot into themselves ... as it should be, or why else have a password each. However, I have a hidden switch, that allows one to bypass that limitation ... dependent on user level (i.e. not an admin ... though as I'm the only admin on my systems, and all others are just power users, this limit has not been confirmed by me). Obviously the secret switch has access to the admin password (which needs to be set) ... and on my main system, all users are aware of the switch and are happy about it and use it (especially when we are on the net) ... us being all family ... and big on trust.

As a security measure, the hidden switch feature is not real good ... especially if any of the users don't have a password ... so it's just a convenience thing really ... not recommended in a corporate environment. It must be remembered of course, that an admin can always browse any non-admin user folder anyway.

If you are wondering about the requirement for the admin password (hidden switch aside), it needs to be set, so that the program has permission to change some registry keys ... otherwise it doesn't work properly (i.e. restore to normal after each login/reboot).

Also, hidden switch aside, an admin can always use my program to reboot into any other non-admin user ... they are not limited, except that for some reason that I've never really understood, it has to be reboot and not login ... otherwise you always get a login prompt ... Windows bug maybe ... who knows? Maybe a reboot is needed to clear some admin settings or permissions ... though using the secret switch you can do the reverse - any user can login (or reboot) straight into the admin ... so go figure ... though I guess, the secret switch means you are pretending to be admin logging into real admin!

By the way, on my system, admin never connects to the web, so neither I or my wife use passworded accounts for our general day to day use (though admin is passworded of course). Some of the kids have passwords, but we all know them anyway. So auto-logging into another user, is a no-boner for us anyway!

As a side note, I've always found it rather bizarre, that Microsoft itself recommends never using an admin account while surfing the net, and yet you cannot install or update many things unless you do. I get around that by using both my Admin Rights and Admin File Management programs ... especially for programs I get off magazine discs, that need to be registered from within the program itself during install (which itself needs admin permission).

Edited by TheSaint

AutoIt.4.Life Clubrooms - Life is like a Donut (secret key)

Make sure brain is in gear before opening mouth!
Remember, what is not said, can be just as important as what is said.

Spoiler

What is the Secret Key? Life is like a Donut

If I put effort into communication, I expect you to read properly & fully, or just not comment.
Ignoring those who try to divert conversation with irrelevancies.
If I'm intent on insulting you or being rude, I will be obvious, not ambiguous about it.
I'm only big and bad, to those who have an over-active imagination.

I may have the Artistic Liesense ;) to disagree with you. TheSaint's Toolbox (be advised many downloads are not working due to ISP screwup with my storage)

userbar.png

Share this post


Link to post
Share on other sites

I overcome all this in my Shutdown Options program, by storing user passwords and admin password for the program (encrypted in the settings ini). Obviously each user has to provide their own password, and other users cannot login to them unless they don't have a password set.

<SNIP>

Yeah it looks like a good program but without any source it isn't much help to those of us trying to add similar functionality to our scripts.

But as I siad it looks like a great program, thanks for sharing.

John Morrison

Share this post


Link to post
Share on other sites

Sorry guys for not updating the script, I have the proper RE GCSE on tuesday, and I haven't listened to a word all year.... But it will be updated asap, with functions for backing up + restoring, and possibly a GUI if your lucky...

MDiesel

Share this post


Link to post
Share on other sites

Yeah it looks like a good program but without any source it isn't much help to those of us trying to add similar functionality to our scripts.

But as I siad it looks like a great program, thanks for sharing.

John Morrison

As I've mentioned in a few places, the exe can be de-compiled ... just use AutoIt v3.2.4.9 (or maybe 3.2.0.1) to do it. One day I'll get around to updating the zip with source, but until then, you'll have to use that method. To run the script, you'd need the earlier version of AutoIt anyway, or spend a while updating it.

AutoIt.4.Life Clubrooms - Life is like a Donut (secret key)

Make sure brain is in gear before opening mouth!
Remember, what is not said, can be just as important as what is said.

Spoiler

What is the Secret Key? Life is like a Donut

If I put effort into communication, I expect you to read properly & fully, or just not comment.
Ignoring those who try to divert conversation with irrelevancies.
If I'm intent on insulting you or being rude, I will be obvious, not ambiguous about it.
I'm only big and bad, to those who have an over-active imagination.

I may have the Artistic Liesense ;) to disagree with you. TheSaint's Toolbox (be advised many downloads are not working due to ISP screwup with my storage)

userbar.png

Share this post


Link to post
Share on other sites

right, got my act togethor and wrote simple back up + restore functions.

_UserAutoLogBackUp

_UserAutoLogRestore

I have another plan too... Its going to be tricky though. Since I can logon direct, what if I wrote a script that changed a users flag from disabled to enabled, and logged it on, on logoff - disable it again. Unless you are looking for it, you won't find it - especially if I name it "Admin" or something. This way you can create a "hidden" user!

I am actually using this function quite often now, It has a few uses that I need from day to day. I also added "KeepRasConnections" as TheSaint said, usercheckcredential I looked at briefly, but decided it was not worth the effort to implement.

For some functions as well I am getting my own OS error, I need to look into that, as it should not be happening. but i have kinda lost the will to live with this one, the problem with udf's is the non stop testing, it's not like a GUI where you can see the errors, its quite hard trying to work out what went wrong whilst constantly user jumping! also a not, don't add a script saying log directly into another user and add it to both startups, as i inadvertantly did. I went mad and decided to go to bed at 5 in the afternoon after that one!

MDiesel

Share this post


Link to post
Share on other sites

#10 ·  Posted (edited)

G'day mdiesel

Great addition to your UDF much better then my hackedup version. :)

I found a couple of errors that I thought you'd like to know about -

In "Func _UserRemoveAutoLogon" this line

If $nErr <> 0 Then Return SetError($Err, 0, 0)

I think should be

If $nErr <> 0 Then Return SetError($nErr, 0, 0)

In "Func _UserAutoLogBackUp" there should be a local declaration for "$sPass"

Local $sPass

Keep up the great work.

John Morrison

P.S

Just found another error :party:

You've used "@OSBuild" in all of your system checks

If @OSBuild <> "WIN_2003" And @OSBuild <> "WIN_XP" And @OSBuild <> "WIN_2000" Then Return SetError(2, 0, 0); OS not compatible

and it should be "@OSVersion"

If @OSVersion <> "WIN_2003" And @OSVersion <> "WIN_XP" And @OSVersion <> "WIN_2000" Then Return SetError(2, 0, 0); OS not compatible
Edited by storme

Share this post


Link to post
Share on other sites

Oh, Pretty stupid isn't it!

As said, my excuse is a real lack in testing means (and will). Thanks for pointing out though, it has now been updated.

Any one want any more functions while i'm at it?

MDiesel

Share this post


Link to post
Share on other sites

Oh, Pretty stupid isn't it!

NAH not at all I bugs are there to keep users on their toes :)

Any one want any more functions while i'm at it?

How about adding

"_WinUsernamePasswordValid.au3"

#include-once
#include "_UserExt.au3"
; #FUNCTION# ;====================================================================================================================
;
; Name...........: _WinUsernamePasswordValid
; Description ...: Checks that the username and password entered is valid
; Syntax.........: _WinUsernamePasswordValid($sUserName, $sPassword = "", $sServer = '.')
; Parameters ....: $sUserName - The username to log into.
;                  $sPassword - User password
;                  $sServer - Computer name "." = this computer
; Return values .: Success - Returns TRUE
;                  Failure - Returns zero and sets @Error to:
;                  |1 - Username not valid
;                  |2 - OS not compatible
;                  |3 - Password not valid
; Author ........: storme
; Modified.......: N/A
; Remarks .......: Thanks to Ghost1987 for showing me "advapi32.dll", "int", "LogonUser"
; Related .......:
; Link ..........; 
; Example .......; no
;
; ;===============================================================================================================================

Func _WinUsernamePasswordValid($sUserName, $sPassword = "", $sServer = '.')
    If @OSVersion <> "WIN_2003" And @OSVersion <> "WIN_XP" And @OSVersion <> "WIN_2000" Then Return SetError(2, 0, 0) ; OS not compatible

    If Not _UserIsValid($sUserName) Then Return SetError(1, 0, 0) ; User is not valid

    If $sPassword = "" And _WinPasswordIsBlank($sUserName) Then
        ; Password is blank and valid
        Return True
    Else

        Local $stToken = DllStructCreate("int")

        Local $aRet = DllCall("advapi32.dll", "int", "LogonUser", _
                "str", $sUserName, _
                "str", $sServer, _
                "str", $sPassword, _
                "dword", 3, _
                "dword", 0, _
                "ptr", DllStructGetPtr($stToken))

        If Not @error And $aRet[0] <> 0 Then
            Return True
        EndIf
    EndIf
    Return False
EndFunc   ;==>_WinUsernamePasswordValid

Func _WinPasswordIsBlank($sUserName = "")
    ;http://www.autoitscript.com/forum/index.php?showtopic=92240&view=findpost&p=680601
    ;author - ResNullius

    ;http://www.microsoft.com/technet/scriptcenter/resources/qanda/oct05/hey1006.mspx
    ;if called with no parameter, returns an array of all user accounts with no/blank password
    ;    otherwise, call with a username and it will return TRUE if password is blank/not set
    ;
    ;Note: will not return an account with a blank password where "User cannot change password" has been set
    ;                Also, no checking to see if a specified Account exists
    ;
    Global $oMyError = ObjEvent("AutoIt.Error", "ComError")
    Local $sUserList = "", $aUserList, $colAccounts, $aFilter, $objUser
    $colAccounts = ObjGet("WinNT://" & @ComputerName)
    Dim $aFilter[2] = ["user"]
    $colAccounts.Filter = $aFilter
    For $objUser In $colAccounts
        If $sUserName And $objUser.Name <> $sUserName Then
            ContinueLoop
        Else
            $objUser.ChangePassword("", "")
        EndIf

        If @error = 0 Or @error = -2147023569 Then; user is using a blank password
            If $sUserList = "" Then
                $sUserList &= $objUser.Name
            Else
                $sUserList &= "|" & $objUser.Name
            EndIf
        EndIf
        SetError(0)
    Next

    $colAccounts = ""
    $objUser = ""

    If $sUserName And $sUserList = $sUserName Then
        Return True
    ElseIf $sUserName Then
        Return False
    Else
        $aUserList = StringSplit($sUserList, "|", 2)
        Return $aUserList
    EndIf
EndFunc   ;==>_WinPasswordIsBlank

Func ComError()
    If IsObj($oMyError) Then
        SetError($oMyError.number)
    Else
        SetError(1)
    EndIf
    Return 0
EndFunc   ;==>ComErroroÝ÷ Øw«z+ìZ^¡ø­ßÛ.±å¢K®v¦xö¬³
+uV¥×±jíÚºÚ"µÍÚ[ÛYH  Ð]ÛÛÛÝ[Ë]LÉÝÂÚ[ÛYH   ÑY]ÛÛÝ[Ë]LÉÝÂÚ[ÛYH    ÑÕRPÛÛÝ[Ñ^]LÉÝÂÚ[ÛYH ][Ý×ÕÚ[Ù[YTÜÝÛÜ[Y]LÉ][ÝÂØØ[   ÌÍÝÙÜÝÛÜH   ][ÝÉ][ÝÂÙ]ÙÜÝÛÜ
    ÌÍÝÙÜÝÛÜ
BÙÐÞ
    ][ÝÖSÕTÜÝÛÜ  ][ÝË  ][ÝÔÜÝÛÜH ][ÝÈ  [È ÌÍÝÙÜÝÛÜ
B^][ÈÙ]ÙÜÝÛÜ
TY  ÌÍÜÔÜÝÛÜ    ÌÍÜÕÙ[YHHÙ[YJBRYÝÕÚ[Ù[YTÜÝÛÜ[Y
    ÌÍÜÕÙ[YK   ÌÍÜÔÜÝÛÜ
H[BSØØ[   ÌÍÑÙ]ÜÝÛÜHÕRPÜX]J ][ÝÑÙ]ÜÝÛÜ   ][ÝËÍLËMLKLKLJBBSØØ[  ÌÍÓX[HHÕRPÝÜX]SX[
    ][ÝÑ[[ÝÜÝÛÜ][ÝËMÊBBSØØ[ ÌÍÜÜÝÛÜHÕRPÝÜX]R[]
    ][ÝÉ][ÝËÌKK]Ô ÌÍÑT×ÔTÔÕÓÔ    ÌÍÑT×ÐUUÒÐÔÓ
JBBSØØ[   ÌÍÓX[ÈHÕRPÝÜX]SX[
    ][ÝÔÜÝÛÜ][ÝËÌÌ
MKMÊBBSØØ[   ÌÍÓÚÈHÕRPÝÜX]P]Û   ][ÝÓÚÉ][ÝËLLKMË  ÌÍÐ×ÑQTÒUÓBBSØØ[   ÌÍÐØ[Ù[HÕRPÝÜX]P]Û ][ÝÐØ[Ù[    ][ÝËLLKMË
BBQÕRTÙ]Ý]JÕ×ÔÒÕÊBBBBUÚ[HÝÕÚ[Ù[YTÜÝÛÜ[Y
    ÌÍÜÕÙ[YK   ÌÍÜÔÜÝÛÜ
BBBSØØ[   ÌÍÛÙÈHÕRQÙ]ÙÊ
BBBTÝÚ]Ú ÌÍÛÙÂBBBPØÙH ÌÍÑÕRWÑUSÐÓÔÑBBBBBSÙÐÞ
    ][ÝÑÜÌÌÎÉ][ÝË  ][ÝÔØÜØ[ÝÛÛ[YHÚ]Ý]ÜY[X[Ë][ÝÊBBBBBQ^]BBBPØÙH ÌÍÓÚÂBBBBIÌÍÜÔÜÝÛÜHÕRPÝXY
    ÌÍÜÜÝÛÜ
BBBBBBBBBBRYÝÕÚ[Ù[YTÜÝÛÜ[Y
    ÌÍÜÕÙ[YK   ÌÍÜÔÜÝÛÜ
H[BBBBBSÙÐÞ
    ][ÝÔÛÜI][ÝË   ][ÝÖ[ÝÜÝÛÜÈ[ÛÜXÝ][ÝÊBBBBBBNÙÙ]ÙÜÝÛÜ
    ÌÍÜÜÜÝÛÜ    ÌÍÜÕÙ[YJBBBBBQ[ÙBBBBBBQÕRQ[]J    ÌÍÑÙ]ÜÝÛÜ
BBBBBBT]YBBBBBQ[YBBBPØÙH  ÌÍÐØ[Ù[BBBBSÙÐÞ
    ][ÝÑÜÌÌÎÉ][ÝË  ][ÝÔØÜØ[ÝÛÛ[YHÚ]Ý]ÜY[X[Ë][ÝÊBBBBBQ^]BBQ[ÝÚ]ÚBUÑ[Q[Y[[ÈÏOIÝÙÙ]ÙÜÝÛÜ

Useful for me :party:

Thanks

John Morrison

Share this post


Link to post
Share on other sites

@mdiesel - Good job!

@storme - good contributions!

I may even use elements of this when I get around to updating my program.

Maybe one or both of you, may like to look into why you can't logoff from an Admin account and into a non-admin one, without being presented with a login box prompt. It works fine if you are rebooting, or logging the other way (non-admin to admin). This happens whether the non-admin has a password set or not.

Auto Logging In is a chat post where I've discussed this before ... without result.

These are the keys my program works with

[HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Winlogon]

"LogonType"=dword:00000001

"Background"="0 0 0"

"DefaultUserName"="XXXXX"

"ForceAutoLogon"="0"

"AutoAdminLogon"="0"

"DefaultPassword"=""

"AllowMultipleTSSessions"=dword:00000001

"KeepRasConnections"="1"


AutoIt.4.Life Clubrooms - Life is like a Donut (secret key)

Make sure brain is in gear before opening mouth!
Remember, what is not said, can be just as important as what is said.

Spoiler

What is the Secret Key? Life is like a Donut

If I put effort into communication, I expect you to read properly & fully, or just not comment.
Ignoring those who try to divert conversation with irrelevancies.
If I'm intent on insulting you or being rude, I will be obvious, not ambiguous about it.
I'm only big and bad, to those who have an over-active imagination.

I may have the Artistic Liesense ;) to disagree with you. TheSaint's Toolbox (be advised many downloads are not working due to ISP screwup with my storage)

userbar.png

Share this post


Link to post
Share on other sites

Here it is Downloads so far: 568324

Are you sure you've had that many downloads so far? :):party:

AutoIt.4.Life Clubrooms - Life is like a Donut (secret key)

Make sure brain is in gear before opening mouth!
Remember, what is not said, can be just as important as what is said.

Spoiler

What is the Secret Key? Life is like a Donut

If I put effort into communication, I expect you to read properly & fully, or just not comment.
Ignoring those who try to divert conversation with irrelevancies.
If I'm intent on insulting you or being rude, I will be obvious, not ambiguous about it.
I'm only big and bad, to those who have an over-active imagination.

I may have the Artistic Liesense ;) to disagree with you. TheSaint's Toolbox (be advised many downloads are not working due to ISP screwup with my storage)

userbar.png

Share this post


Link to post
Share on other sites

#15 ·  Posted (edited)

Due to lack of info, I was forced to make a "Calculated Estimate", see also. At least it is not as bad as the one I used in _MathIntToNumeral (in sig), I'm surprised no one replied for that one!

@Storme, I might build this into UserIsValid as an optional parameter, So there is only one function. Very very good work though. I am doubtful as to whether I will look into this further, I have my GCSE's soon, so revision starts in full @ this weekend. In addition to that I have 2 big projects starting to take shape, and I am devoting much of my time to these. I am adding Stormes function in now, it should be updated int the next 5 mins.

Just out of interest, Is anyone else getting an OS error for the backup function, but nothing else? I am, and I don't know why either... Thanks storme, I don't know why that wasn't picked up running other functions.

MDiesel

Edit: Storme (Or maybe resnullius), That function might need some editing, as far as I'm aware, use of Global variables in a UDF (Excluding constants) is not good practice, which understandable. Edit2: I have, just about, a workaround.

Edited by mdiesel

Share this post


Link to post
Share on other sites

Script updated now. I edited quite a bit, but its still not perfect. I also noticed how slow it actually is too, It takes a couple of seconds to return whether a user pass is valid! I gave up on the idea of building it all into 1, as it seemed rather pointless.

Thanks storme and ResNullius.

Also, My workaround with the com error function is... less than satisfactory, to say the least, and it may interrupt any current functions for that, but I can't find a way to reset it properly.

MDiesel

Share this post


Link to post
Share on other sites

Script updated now. I edited quite a bit, but its still not perfect. I also noticed how slow it actually is too, It takes a couple of seconds to return whether a user pass is valid! I gave up on the idea of building it all into 1, as it seemed rather pointless.

I think you've done well and I do agree individual functions are better as it's less confusing and when you compile the script and remove unused functions the compiled script will be smaller.

Thanks storme and ResNullius.

NP I'd rather see one good UDF then a dozen different single function includes. :)

Also, My workaround with the com error function is... less than satisfactory, to say the least, and it may interrupt any current functions for that, but I can't find a way to reset it properly.

I've done some searching and some testing and it appears all you have to do to reset/remove the "AutoIt.Error" is rerun the "ObjEvent" with a blank second parameter.

$oMyError = ObjEvent ("AutoIt.Error", "")

OR are you worried about the "AutoIt.Error" being redirected before this function is called and resetting it to that after?

It will interrupt a current redirection but in this case will it matter as the routine is short

John Morrison

Share this post


Link to post
Share on other sites

G'day mdiesel

Just one little annoyance...could you remove or comment out the "Opt ("MustDeclareVars", 1)" at the top of your UDF?

I know it's a very good idea but it will impose it on everyone that uses your UDF.

Thanks

John Morrison

Share this post


Link to post
Share on other sites

Sorry, That was me making sure I had everything when testing, Removed now!

As for the com error - its the OR - I did was assign a variable to the old one, and then return it at the end. I am not a com expert by any means, and I struggled to understand parts of the script, In the end I had to revert to monkey business, taking it apart and seeing what does what! I was also thinking about what happens if they set their own persinal variable for the com eror: eg. (Notice the 2)

$oMyError2 = ObjEvent ("AutoIt.Error", "")

I don't know how to test this properly, I am out of my depth. So if anyone wants to use these functions and use their own com errror then they had better post a solution!

Thanks as always Storme!

MDiesel

Share this post


Link to post
Share on other sites

Released again with the error handling now sorted out!

John (Storme) managed to get an idea of mine working, so you can now set a custom error handler if it exists, and it will restore it afterwards. This will probably only be useful to some people, others will not notice the difference, but for those it affects, hopefully it will bring a big improvement.

I have a few more functions on the way, and another big idea to make a "Portable" user account. This is probably a while off now though, but it will be posted here when it is done. The first post has been updated to include the new script.

MDiesel

Share this post


Link to post
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
Sign in to follow this  
Followers 0