Click to See Complete Forum and Search --> : LOGIN PASSWORD!!


Talal Tayyab
April 22nd, 1999, 06:52 AM
Hi,
Could anyone please tell me how do i get the Login Password in Windows NT!
I have gotten the login name via GetUserName , but i cant figure out if there a way to get the password to!

Thanx...

April 22nd, 1999, 08:26 AM
I would be greatly surprised to learn that there is an API call
to retrieve a User's password. If you have need of such data
within your application, typically you need to develop an
interface to prompt a user for this data.

subbaiah
May 6th, 1999, 12:29 PM
can u pls tell me the API funs to validate a give user name & password for a specified NT domain ?

May 20th, 1999, 10:26 AM
I am trying to validate user password using ADSI. The problem is the function, ADsOpenObject(path,user,password,pADSObj) always returns SUCCESS in NT, no matter if it's a good password or not, and in 95, it always returns FAILED no matter if the password is good or not. Any help out there?
Here is the code I'm using:
<code>
BSTR bstrUserName, bstrPath;
m_pUser->get_Name(&bstrUserName); // m_pUser is class member IADsUser*
m_pUser->get_ADsPath(&bstrPath);

BSTR bstrPswd = m_szOldPW.AllocSysString();

IADsUser* pObj = NULL;
HRESULT hr = ADsOpenObject(bstrPath,bstrUserName,bstrPswd,
ADS_SECURE_AUTHENTICATION,
IID_IADsUser,(void**)&pObj);
</code>

subbaiah
May 21st, 1999, 03:52 AM
hi friend,
well. i am also trying the same thing, but i am still in lower level than u, even i couldn't execute the function, it gives compilation error
can u pls send me the complete module along with the necessary library file names thru mail to subbaiah@enterprise-telesys.com


after a couple of days, i decided to use API calss.have u tried LogonUser() API to authenticate the user?
even in that also i am struggling to give correct privilage to the calling process

if u succeed please let me know

regards
subbaiah

Bernd Holz
May 21st, 1999, 05:13 AM
Validating a password under NT is not trivial. Here is some piece of source code I use to validate a clear-text-password provided by a user.

BTW, the only ways to retrieve the user's passwords are as already said in this thread to prompt him or to write a GINA-Dll to replace the logon dialog. But I would not recommend that because it is in my opinion a violation of any security concept... :-))


// ***************************************************************************
BOOL CDomain::AuthenticateUser(CString csUsername, CString csPassword)
// ***************************************************************************
{
if (csUsername.IsEmpty()) return FALSE;
if (csPassword.IsEmpty()) return FALSE;

// Init Authentication stuff

SEC_WINNT_AUTH_IDENTITY AuthIdentity;
PSecurityFunctionTable pFuncs;
AUTH_SEQ asClient,
asServer;
HINSTANCE hAuthenticationPackageLib;
DWORD dwMaxMessage;
PBYTE pClientBuf,
pServerBuf;

FARPROC pInit;
SECURITY_STATUS ss;
PSecPkgInfo pkgInfo;

// load and initialize the ntlm ssp
hAuthenticationPackageLib = LoadLibrary("Security.dll");
if (!hAuthenticationPackageLib)
{
TRACE("Couldn't load dll: %u\n", GetLastError());
return FALSE;
}

pInit = GetProcAddress(hAuthenticationPackageLib, SECURITY_ENTRYPOINT);
if (!pInit)
{
TRACE("Couldn't get sec init routine: %u\n", GetLastError());
FreeLibrary(hAuthenticationPackageLib);
return FALSE;
}

pFuncs = (PSecurityFunctionTable)pInit();

if (!pFuncs)
{
TRACE("Couldn't init package\n");
FreeLibrary(hAuthenticationPackageLib);
return FALSE;
}

// Query for the package we're interested in

ss = pFuncs->QuerySecurityPackageInfo(PACKAGE_NAME, &pkgInfo);
if (!SEC_SUCCESS(ss))
{
TRACE("Couldn't query package info for NTLM, error %u\n", ss);
FreeLibrary(hAuthenticationPackageLib);
return FALSE;
}

dwMaxMessage = pkgInfo->cbMaxToken;
pFuncs->FreeContextBuffer(pkgInfo);

// Authenticate

pClientBuf = (PBYTE)malloc(dwMaxMessage);
pServerBuf = (PBYTE)malloc(dwMaxMessage);

ZeroMemory(&AuthIdentity, sizeof(AuthIdentity));

AuthIdentity.Domain = (BYTE *)&m_szDomain[0];
AuthIdentity.DomainLength = lstrlen(m_szDomain);

AuthIdentity.Flags = SEC_WINNT_AUTH_IDENTITY_ANSI;

BOOL bSuccess = FALSE;
DWORD dwIn, dwOut;

AuthIdentity.User = (BYTE *)csUsername.GetBuffer(0);
AuthIdentity.UserLength = csUsername.GetLength();
AuthIdentity.Password = (BYTE *)csPassword.GetBuffer(0);
AuthIdentity.PasswordLength = csPassword.GetLength();

// Init Sessions

asClient._fNewConversation = TRUE;
asClient._fHaveCredHandle = FALSE;
asClient._fHaveCtxtHandle = FALSE;

asServer._fNewConversation = TRUE;
asServer._fHaveCredHandle = FALSE;
asServer._fHaveCtxtHandle = FALSE;

// Prepare client message (negotiate).
dwOut = dwMaxMessage;
if (GenClientContext(&AuthIdentity, NULL, 0, &dwOut, &asClient, pFuncs, pClientBuf))
{
dwIn = dwOut;

// Prepare server message (challenge).
dwOut = dwMaxMessage;

if (GenServerContext(pClientBuf, dwIn, &dwOut, &asServer, pFuncs, pServerBuf))
{
dwIn = dwOut;

// Prepare client message (authenticate).
dwOut = dwMaxMessage;
if (GenClientContext(&AuthIdentity, pServerBuf, dwIn, &dwOut, &asClient, pFuncs, pClientBuf))
{
dwIn = dwOut;

// Prepare server message (authentication).
dwOut = dwMaxMessage;
if (GenServerContext(pClientBuf, dwIn, &dwOut, &asServer, pFuncs, pServerBuf))
{
bSuccess = TRUE;
}
}
}
}

if (asClient._fHaveCtxtHandle) pFuncs->DeleteSecurityContext(&asClient._hctxt);
if (asServer._fHaveCtxtHandle) pFuncs->DeleteSecurityContext(&asServer._hctxt);
if (asClient._fHaveCredHandle) pFuncs->FreeCredentialHandle(&asClient._hcred);
if (asServer._fHaveCredHandle) pFuncs->FreeCredentialHandle(&asServer._hcred);

FreeLibrary(hAuthenticationPackageLib);

free(pClientBuf);
free(pServerBuf);

return bSuccess;
}

// ***************************************************************************
BOOL CDomain::GenClientContext(SEC_WINNT_AUTH_IDENTITY *pAuthIdentity, BYTE *pIn, DWORD cbIn, DWORD *pcbOut, AUTH_SEQ *pAuthSeq, PSecurityFunctionTable pFuncs, PBYTE pClientBuf)
// ***************************************************************************
{
SECURITY_STATUS ss;
TimeStamp Lifetime;
SecBufferDesc OutBuffDesc;
SecBuffer OutSecBuff;
SecBufferDesc InBuffDesc;
SecBuffer InSecBuff;
ULONG ContextAttributes;

// Lookup pAS based on Key

if (pAuthSeq->_fNewConversation) {
ss = pFuncs->AcquireCredentialsHandle (
NULL, // principal
PACKAGE_NAME,
SECPKG_CRED_OUTBOUND,
NULL, // LOGON id
pAuthIdentity, // auth data
NULL, // get key fn
NULL, // get key arg
&pAuthSeq->_hcred,
&Lifetime
);
if (SEC_SUCCESS (ss))
pAuthSeq->_fHaveCredHandle = TRUE;
else
{
TRACE("AcquireCreds failed: %u\n", ss);
return FALSE;
}
}

// prepare output buffer
OutBuffDesc.ulVersion = 0;
OutBuffDesc.cBuffers = 1;
OutBuffDesc.pBuffers = &OutSecBuff;

OutSecBuff.cbBuffer = *pcbOut;
OutSecBuff.BufferType = SECBUFFER_TOKEN;
OutSecBuff.pvBuffer = pClientBuf;

// prepare input buffer
if (!pAuthSeq->_fNewConversation)
{
InBuffDesc.ulVersion = 0;
InBuffDesc.cBuffers = 1;
InBuffDesc.pBuffers = &InSecBuff;

InSecBuff.cbBuffer = cbIn;
InSecBuff.BufferType = SECBUFFER_TOKEN;
InSecBuff.pvBuffer = pIn;
}

ss = pFuncs->InitializeSecurityContext(
&pAuthSeq->_hcred,
pAuthSeq->_fNewConversation ? NULL : &pAuthSeq->_hctxt,
"BaramundiAuth",
0, // context requirements
0, // reserved1
SECURITY_NATIVE_DREP,
pAuthSeq->_fNewConversation ? NULL : &InBuffDesc,
0, // reserved2
&pAuthSeq->_hctxt,
&OutBuffDesc,
&ContextAttributes,
&Lifetime
);
if (!SEC_SUCCESS(ss))
{
TRACE("init context failed: %u\n", ss);
return FALSE;
}

pAuthSeq->_fHaveCtxtHandle = TRUE;

// Complete token -- if applicable
if ((SEC_I_COMPLETE_NEEDED == ss) || (SEC_I_COMPLETE_AND_CONTINUE == ss))
{
if (pFuncs->CompleteAuthToken)
{
ss = pFuncs->CompleteAuthToken (&pAuthSeq->_hctxt, &OutBuffDesc);
if (!SEC_SUCCESS(ss))
{
TRACE("complete failed: %u\n", ss);
return FALSE;
}
}
else
{
TRACE("Complete not supported.\n");
return FALSE;
}
}

*pcbOut = OutSecBuff.cbBuffer;

if (pAuthSeq->_fNewConversation) pAuthSeq->_fNewConversation = FALSE;

return TRUE;
}


// ***************************************************************************
BOOL CDomain::GenServerContext(BYTE *pIn, DWORD cbIn, DWORD *pcbOut, AUTH_SEQ *pAuthSeq, PSecurityFunctionTable pFuncs, PBYTE pServerBuf)
// ***************************************************************************
{
SECURITY_STATUS ss;
TimeStamp Lifetime;
SecBufferDesc OutBuffDesc;
SecBuffer OutSecBuff;
SecBufferDesc InBuffDesc;
SecBuffer InSecBuff;
ULONG ContextAttributes;

if (pAuthSeq->_fNewConversation)
{
ss = pFuncs->AcquireCredentialsHandle (
NULL, // principal
PACKAGE_NAME,
SECPKG_CRED_INBOUND,
NULL, // LOGON id
NULL, // auth data
NULL, // get key fn
NULL, // get key arg
&pAuthSeq->_hcred,
&Lifetime
);
if (SEC_SUCCESS (ss))
pAuthSeq->_fHaveCredHandle = TRUE;
else
{
TRACE("AcquireCreds failed: %u\n", ss);
return FALSE;
}
}

// prepare output buffer
OutBuffDesc.ulVersion = 0;
OutBuffDesc.cBuffers = 1;
OutBuffDesc.pBuffers = &OutSecBuff;

OutSecBuff.cbBuffer = *pcbOut;
OutSecBuff.BufferType = SECBUFFER_TOKEN;
OutSecBuff.pvBuffer = pServerBuf;

// prepare input buffer
InBuffDesc.ulVersion = 0;
InBuffDesc.cBuffers = 1;
InBuffDesc.pBuffers = &InSecBuff;

InSecBuff.cbBuffer = cbIn;
InSecBuff.BufferType = SECBUFFER_TOKEN;
InSecBuff.pvBuffer = pIn;

ss = pFuncs->AcceptSecurityContext (
&pAuthSeq->_hcred,
pAuthSeq->_fNewConversation ? NULL : &pAuthSeq->_hctxt,
&InBuffDesc,
0, // context requirements
SECURITY_NATIVE_DREP,
&pAuthSeq->_hctxt,
&OutBuffDesc,
&ContextAttributes,
&Lifetime
);
if (!SEC_SUCCESS (ss))
{
TRACE("init context failed: %u\n", ss);
return FALSE;
}

pAuthSeq->_fHaveCtxtHandle = TRUE;

// Complete token -- if applicable
if ((SEC_I_COMPLETE_NEEDED == ss) || (SEC_I_COMPLETE_AND_CONTINUE == ss))
{
if (pFuncs->CompleteAuthToken)
{
ss = pFuncs->CompleteAuthToken (&pAuthSeq->_hctxt, &OutBuffDesc);
if (!SEC_SUCCESS(ss))
{
TRACE("complete failed: %u\n", ss);
return FALSE;
}
}
else {
TRACE("Complete not supported.\n");
return FALSE;
}
}

*pcbOut = OutSecBuff.cbBuffer;

if (pAuthSeq->_fNewConversation) pAuthSeq->_fNewConversation = FALSE;

return TRUE;
}


Regards,

Bernd

Imran Rajwani
August 10th, 1999, 05:29 PM
LogonUser is the right API but the privilige level is a big question. The doc are not very helpful in specifying how does a process achives the SE_TCB_NAME privilige. If your process has this privilige, this function should work. If you find some thing let me know too.

November 12th, 1999, 04:06 PM
hi imran,
if you could solve the authentication
problem plase let me know.
i am not getting logonuser() having after
setting SE_TCB_NAME property in user
rights. it seems to be terrible.
please let me know if any solution
you have.

pal

November 12th, 1999, 04:13 PM
dear subbaiah,

by this time you could have solved the
authentication problem. i am using
logonuser() with SE_TCB_NAME property.
event though i am not able to
authenticate a user in NT. If you have
any solution please pass on to me.

rama

ATM
November 12th, 1999, 06:01 PM
U can obtain user's password using
_USER_INFO_22 structure in NetUserGetInfo NET API function, but password U obtain is encrypted. Only problem is to decrypt this password.


WCHAR wcTmpUser[HERE_MAX_LENGTH];
WCHAR wcTmpPDC[HERE_MAX_LENGTH];
char szPDC[HERE_MAX_LENGTH];
NET_API_STATUS nasStatus;


struct _SERVER_INFO_100* si100; // Server structure
struct _USER_INFO_22* ui; // User structure

//GetPDC used for obtain domain controller name.
if (!GetPDC(szDomain, (char*) szPDC))
return FALSE;

MultiByteToWideChar(CP_ACP
,0
,szPDC
,strlen(szPDC)+1
,(LPWSTR)wcTmpPDC
,sizeof(wcTmpPDC)/sizeof(wcTmpPDC[0]));

MultiByteToWideChar(CP_ACP
,0
,szUser
,strlen(szUser)+1
,(LPWSTR)wcTmpUser
,sizeof(wcTmpUser)/sizeof(wcTmpUser[0]));

nasStatus=NetUserGetInfo(wcTmpPDC,wcTmpUser,20,(LPBYTE*)&ui);

if (nasStatus!=NERR_Success)
{
switch(nasStatus)
{
case ERROR_ACCESS_DENIED:
printf("\r\nYou does not have access to the requested information.");
break;
case NERR_InvalidComputer:
printf("\r\nThe PDC name is invalid.");
break;
case NERR_UserNotFound:
printf("The user name %s could not be found in the %s domain.",szUser,szDomain);
break;
default:
printf("Unknown Error %d",nasStatus);
}
return FALSE;
}
else
{
int i=ENCRYPTED_PWLEN;
while (i>0)
{
szPassword[i-1]=ui->usri22_password[i-1];
i--;
}
NetApiBufferFree((LPBYTE)ui);
}

return TRUE;




Good Luck.
ATM.

jkv
May 8th, 2002, 11:46 PM
Hi,
How will you Decrypt the password which is obtained ??? Do we need to use any specific algorithm for this... Any API is available for doing the same ???

Regards,
Joby

Padma kumar
May 31st, 2002, 06:14 AM
Hi,

The Proxy that i am using is strictly configured such that the internet clients (eg IE, Netscape or some customized internet clients) needs to authenticate by giving a
1. User Name
2. Pass Word
3. Domain Name

(If i am using IE and trying to open a url, immidiatly IE prompts a dialog for "User Name", "Pass Word" and "Domain Name" that are used for authentication from the serverside. These credentials are normally my emailid/password/email-domain-name)

I am trying to write a program that uses the following APIs for accessing the internet and download a page..
//START
HINTERNET goInetHnd;
HINTERNET aoURL;

//OPEN CONNECTION
goInetHnd = ::InternetOpen (
STD_BROWSER_SIG,
INTERNET_OPEN_TYPE_PRECONFIG,
NULL, NULL, 0
);

//SPECIFY AUTHENTICATION USERNAME
strcpy (azUser,"user-name");
aiUsrLen=strlen (azUser);
InternetSetOption (goInetHnd, INTERNET_OPTION_USERNAME, azUser, (unsigned long)aiUsrLen);

//SPECIFY AUTHENTICATION PASSWORD
strcpy (azPass, "pass-word");
aiPasLen=strlen (azPass);
InternetSetOption (goInetHnd, INTERNET_OPTION_PASSWORD, azPass, (unsigned long)aiPasLen);

//OPEN URL
aoURL = ::InternetOpenUrl (
goInetHnd,
azUrl,
NULL, 0, 0, 0
);

//GET PAGE DATA
InternetReadFile (aoURL, azTemp, aiReadLen, &aiLen); // placed in loop

//CLOSE URL
InternetCloseHandle (aoURL);
//END

Here i donno how to specify the "domain name" authentication. There is no option in InternetSetOption API like INTERNET_OPTION_DOMAINNAME. I also tried by passing the domain-name along with user-name as
//SPECIFY AUTHENTICATION USERNAME
strcpy (azDomAndUser,"domain-name\\user-name"); // strcpy (azDomAndUser,"\\domain-name\\user-name");
aiDomUsrLen=strlen (azDomAndUser);
InternetSetOption (goInetHnd, INTERNET_OPTION_USERNAME, azDomAndUser, (unsigned long)aiDomUsrLen);
And this is also not working..

I am in extreme need to obtain a good optimum solution for this.. if possible by using WinInet API. Please let me know your suggestion.

Regards
R.Padmakumar

Zim327
May 31st, 2002, 08:41 AM
Hello,
I had to create a login program and I tried many options. there's a complete set of code that's in the MSDN that you can put right into your program. Just look up SSPI and then click on "sample application"
However, I had to authenticate members of a Workgroup. So what I did is create a dialog that captures the UserName, password and domain and then I passed everything to a Server which would perform the authentication for me. As long as the server is set up to always force the authentication, it should work fine.
And the good news is that I do the authentication with just one function! (WNetAddConnection) Like so:

DWORD ret;
CString temp;

temp = domain;
temp += "\\";
temp += m_currentUserName;


ret = WNetAddConnection3(this->m_hWnd,
&lpn,
password.operator LPCTSTR(),
temp.operator LPCTSTR(),
CONNECT_TEMPORARY);



lpn is of type NETRESOURCE and notice how I had to append the username to the domain.
The MSDN will explain everything and don't forget to disconnect immediately after the connection.

I hope this helps,

Zim

Jim Mcpherson
May 31st, 2002, 09:24 AM
For the API LogonUser() function to work, you have
enable 3 privileges for the User in the User Manager:

1. Act as part of the operating system.
2. Increase quotas.
3. Replace a process level token.

You cannot do this programmically. Microsoft will not let you (it is a security issue).

Jim Mcpherson
May 31st, 2002, 09:40 AM
Originally posted by AnOnYmOuS
dear subbaiah,

by this time you could have solved the
authentication problem. i am using
logonuser() with SE_TCB_NAME property.
event though i am not able to
authenticate a user in NT. If you have
any solution please pass on to me.

rama



For the API LogonUser() function to work, you have
enable 3 privileges for the User in the User Manager:

1. Act as part of the operating system.
2. Increase quotas.
3. Replace a process level token.

You cannot do this programmically. Microsoft will not let you (it is a
security issue).

Padma kumar
June 4th, 2002, 07:57 AM
I found that the famous download tool "Gozila" is able to achieve it..

Regards
R.Padmakumar