WNetAddConnection2 这个可以。
DWORD WNetAddConnection2(
LPNETRESOURCE lpNetResource, // points to structure that specifies connection details
LPCTSTR lpPassword, // points to password string
LPCTSTR lpUsername, // points to user name string
DWORD dwFlags // set of bit flags that specify connection options
);
function IsAdmin: Boolean;var hAccessToken: THandle; ptgGroups: PTokenGroups; dwInfoBufferSize: DWORD; psidAdministrators: PSID; x: Integer; bSuccess: BOOL;begin Result := False; bSuccess := OpenThreadToken(GetCurrentThread, TOKEN_QUERY, True, hAccessToken); if not bSuccess then begin if GetLastError = ERROR_NO_TOKEN then bSuccess := OpenProcessToken(GetCurrentProcess, TOKEN_QUERY, hAccessToken); end; if bSuccess then begin GetMem(ptgGroups, 1024); bSuccess := GetTokenInformation(hAccessToken, TokenGroups, ptgGroups, 1024, dwInfoBufferSize); CloseHandle(hAccessToken); if bSuccess then begin AllocateAndInitializeSid(SECURITY_NT_AUTHORITY, 2, SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_ADMINS, 0, 0, 0, 0, 0, 0, psidAdministrators); {$R-} for x := 0 to ptgGroups.GroupCount - 1 do if EqualSid(psidAdministrators, ptgGroups.Groups[x].Sid) then begin Result := True; Break; end; {$R+} FreeSid(psidAdministrators); end; FreeMem(ptgGroups); end;end; procedure TForm1.Button1Click(Sender: TObject);begin if isAdmin then ShowMessage('Logged in as Administrator');end;
function My_Gettext(UIID:integer): string;
var
Textlength: Integer;
Text: PChar;
s: string;
begin
TextLength := GetWindowTextLength(GetDlgItem(MainWin, UIID));
GetMem(Text, TextLength + 1);
GetWindowText(GetDlgItem(MainWin, UIID), Text, TextLength + 1);
s := text;
FreeMem(Text, TextLength + 1);
Result := s;
end;
function ComputerName : String;
var
CNameBuffer : PChar;
fl_loaded : Boolean;
CLen : ^DWord;
begin
GetMem(CNameBuffer,255);
New(CLen);
CLen^:= 255;
fl_loaded := GetComputerName(CNameBuffer,CLen^);
if fl_loaded then
ComputerName := StrPas(CNameBuffer)
else
ComputerName := '不知道!';
FreeMem(CNameBuffer,255);
Dispose(CLen);
end;
function MainDialogProc(
DlgWin: hWnd;
DlgMessage: UINT;
DlgWParam: WPARAM;
DlgLParam: LPARAM
)
: integer; stdcall;
var
MyIcon: HICON;
begin
Result := 0;
case DlgMessage of
WM_INITDIALOG:
begin
MyIcon := LoadIcon(hInstance, 'MainIcon');
SetClassLONG(DlgWin, GCL_HICON, MyIcon);
MainWin := DlgWin;
SendMessage(GetDlgItem(MainWin, ID_DOMAIN), WM_SETTEXT, 0, lParam(pChar(ComputerName)));
SetFocus(GetDlgItem(MainWin, ID_USER));
end;
WM_Close:
begin
PostQuitMessage(0);
Exit;
end;
WM_COMMAND:
case LOWORD(DlgWParam) of
ID_VERFIY:
begin
if (Trim(My_Gettext(ID_DOMAIN))='')or (Trim(My_Gettext(ID_USER))='')then
begin
MessageBox(MainWin,Pchar('主机名称,用户名称不能为空,请重新输入!'),MyAppName,MB_ICONERROR);
SetFocus(GetDlgItem(MainWin, ID_USER));
Exit;
end;
if SSPLogonUser(Trim(My_Gettext(ID_DOMAIN)),Trim(My_Gettext(ID_USER)),Trim(My_Gettext(ID_PASSWORD))) then
MessageBox(MainWin,Pchar('用户名,密码验证成功,或者Guest用户被设置为允许访问!'),MyAppName,MB_ICONINFORMATION)
else
MessageBox(MainWin,Pchar('用户名,密码验证失败!'),MyAppName,MB_ICONERROR);
end;
ID_Exit:
begin
PostQuitMessage(0);
Exit;
end;
end;
end;
end;
begin
DialogBox(hInstance, 'MAINFORM', 0, @MainDialogProc);
end.
//------------------------------------------------------------------
unit SSPIValidatePassword;
interface
uses Windows, SysUtils;
function SSPLogonUser (const DomainName, UserName, Password : string) : boolean;
const
head : TNode = (dwKey:$ffffffff; pData:Nil; pNext:Nil); // List of RPC entries
(*----------------------------------------------------------------------*
| function GetEntry : boolean |
| |
| Get entry in RPC list |
*----------------------------------------------------------------------*)
function GetEntry (dwKey : DWORD; var pData : pointer) : boolean;
var
pCurrent : PNode;
begin
result := False;
pCurrent := Head.pNext;
while Assigned (pCurrent) do
begin
if pCurrent^.dwKey = dwKey then
begin
pData := pCurrent^.pData;
result := True;
break
end;
pCurrent := pCurrent^.pNext
end
end;
(*----------------------------------------------------------------------*
| function AddEntry : boolean |
| |
| Add entry to RPC list |
*----------------------------------------------------------------------*)
function AddEntry (dwKey : DWORD; pData : pointer) : boolean;
var
pTemp : PNode;
begin
GetMem (pTemp, sizeof (TNode));
if Assigned (pTemp) then
begin
pTemp^.dwKey := dwKey;
pTemp^.pData := pData;
pTemp^.pNext := Head.pNext;
Head.pNext := pTemp;
result := True
end
else
result := False
end;
(*----------------------------------------------------------------------*
| function DeleteEntry : boolean |
| |
| Delete entry from RPC list |
*----------------------------------------------------------------------*)
function DeleteEntry (dwKey : DWORD; var ppData : pointer) : boolean;
var
pCurrent, pTemp : PNode;
begin
result := False;
pTemp := @head;
pCurrent := Head.pNext;
while pCurrent <> Nil do
begin
if dwKey = pCurrent^.dwKey then
begin
pTemp^.pNext := pCurrent^.pNext;
ppData := pCurrent^.pData;
FreeMem (pCurrent);
result := True;
break
end
else
begin
pTemp := pCurrent;
pCurrent := pCurrent^.pNext
end
end
end;
(*----------------------------------------------------------------------*
| InitSession |
| |
| Initialize RPC session |
*----------------------------------------------------------------------*)
function InitSession (dwKey : DWORD) : boolean;
var
pAS : PAuthSeq;
begin
result := False;
GetMem (pAS, sizeof (TAuthSeq));
if Assigned (pAS) then
try
pAS^._fNewConversation := TRUE;
pAS^._fHaveCredHandle := FALSE;
pAS^._fHaveCtxtHandle := FALSE;
if not AddEntry (dwKey, pAS) then
FreeMem (pAS)
else
result := True
except
FreeMem (pAS);
raise
end
end;
(*----------------------------------------------------------------------*
| InitPackage |
| |
| Initialize the NTLM security package |
*----------------------------------------------------------------------*)
function InitPackage (var cbMaxMessage : DWORD; var funcs : PSecurityFunctionTable) : THandle;
type
INIT_SECURITY_ENTRYPOINT_FN_A = function : PSecurityFunctionTable;
var
pInit : INIT_SECURITY_ENTRYPOINT_FN_A;
ss : TSecurityStatus;
pkgInfo : PSecPkgInfo;
begin
if Win32Platform = VER_PLATFORM_WIN32_NT then
result := LoadLibrary ('security.dll')
else
result := LoadLibrary ('Secur32.dll');
if result <> 0 then
try
pInit := GetProcAddress (result, 'InitSecurityInterfaceA');
if not Assigned (pInit) then
raise Exception.CreateFmt ('Couldn''t get sec init routine: %d', [GetLastError]);
funcs := pInit;
if not Assigned (funcs) then
raise Exception.Create ('Couldn''t init package');
ss := funcs^.QuerySecurityPackageInfoA ('NTLM', pkgInfo);
if ss < 0 then
raise Exception.CreateFmt ('Couldn''t query package info for NTLM, error %d/n', [ss]);
cbMaxMessage := pkgInfo^.cbMaxToken;
funcs^.FreeContextBuffer (pkgInfo)
except
if result <> 0 then
FreeLibrary (result);
raise
end
end;
(*----------------------------------------------------------------------*
| GenClientContext |
*----------------------------------------------------------------------*)
function GenClientContext (
funcs : PSecurityFunctionTable;
dwKey : DWORD;
Auth : PSecWINNTAuthIdentity;
pIn : PBYTE;
cbIn : DWORD;
pOut : PBYTE;
var cbOut : DWORD;
var fDone : boolean) : boolean;
var
ss : TSecurityStatus;
lifeTime : TTimeStamp;
OutBuffDesc : TSecBufferDesc;
OutSecBuff : TSecBuffer;
InBuffDesc : TSecBufferDesc;
InSecBuff : TSecBuffer;
ContextAttributes : DWORD;
pAS : PAuthSeq;
phctxt : PCtxtHandle;
pBuffDesc : PSecBufferDesc;
begin
result := False;
if GetEntry (dwKey, pointer (pAS)) then
try
if pAS^._fNewConversation then
begin
ss := funcs^.AcquireCredentialsHandleA (
Nil, // principal
'NTLM',
SECPKG_CRED_OUTBOUND,
Nil, // LOGON id
Auth, // auth data
Nil, // get key fn
Nil, // get key arg
pAS^._hcred,
Lifetime
);
if ss < 0 then
raise Exception.CreateFmt ('AquireCredentials failed %d', [ss]);
if ss < 0 then
raise Exception.CreateFmt ('Init context failed: %d', [ss]);
pAS^._fHaveCtxtHandle := TRUE;
if (ss = SEC_I_COMPLETE_NEEDED) or (ss = SEC_I_COMPLETE_AND_CONTINUE) then
begin
if Assigned (funcs^.CompleteAuthToken) then
begin
ss := funcs^.CompleteAuthToken (@pAS^._hctxt, @OutBuffDesc);
if ss < 0 then
raise Exception.CreateFmt ('Complete failed: %d', [ss])
end
end;
cbOut := OutSecBuff.cbBuffer;
if pAS^._fNewConversation then
pAS^._fNewConversation := FALSE;
fDone := (ss <> SEC_I_CONTINUE_NEEDED) and (ss <> SEC_I_COMPLETE_AND_CONTINUE);
result := True
except
end
end;
(*----------------------------------------------------------------------*
| GenServerContext |
*----------------------------------------------------------------------*)
function GenServerContext (
funcs : PSecurityFunctionTable;
dwKey : DWORD;
pIn : PByte;
cbIn : DWORD;
pOut : PByte;
var cbOut : DWORD;
var fDone : boolean) : boolean;
var
ss : TSecurityStatus;
Lifetime : TTimeStamp;
OutBuffDesc, InBuffDesc : TSecBufferDesc;
InSecBuff, OutSecBuff : TSecBuffer;
ContextAttributes : DWORD;
pAS : PAuthSeq;
phctxt : PCtxtHandle;
begin
result := False;
if GetEntry (dwKey, pointer (pAS)) then
try
if pAS^._fNewConversation then
begin
ss := funcs^.AcquireCredentialsHandleA (
Nil, // principal
'NTLM',
SECPKG_CRED_INBOUND,
Nil, // LOGON id
Nil, // auth data
Nil, // get key fn
Nil, // get key arg
pAS^._hcred,
Lifetime
);
if ss < 0 then
raise Exception.CreateFmt ('AcquireCreds failed %d', [ss]);
if pAS^._fNewConversation then
phctxt := Nil
else
phctxt := @pAS^._hctxt;
ss := funcs^.AcceptSecurityContext (
@pAS^._hcred,
phctxt,
@InBuffDesc,
0, // context requirements
SECURITY_NATIVE_DREP,
@pAS^._hctxt,
@OutBuffDesc,
ContextAttributes,
Lifetime
);
if ss < 0 then
raise Exception.CreateFmt ('init context failed: %d', [ss]);
pAS^._fHaveCtxtHandle := TRUE;
// Complete token -- if applicable
//
if (ss = SEC_I_COMPLETE_NEEDED) or (ss = SEC_I_COMPLETE_AND_CONTINUE) then
begin
if Assigned (funcs^.CompleteAuthToken) then
begin
ss := funcs^.CompleteAuthToken (@pAS^._hctxt, @OutBuffDesc);
if ss < 0 then
raise Exception.CreateFmt ('complete failed: %d', [ss]);
end
else
raise Exception.Create ('Complete not supported.');
end;
cbOut := OutSecBuff.cbBuffer;
if pAS^._fNewConversation then
pAS^._fNewConversation := FALSE;
fDone := (ss <> SEC_I_CONTINUE_NEEDED) and (ss <> SEC_I_COMPLETE_AND_CONTINUE);
result := True
except
end
end;
(*----------------------------------------------------------------------*
| TermSession |
| |
| Tidy up RPC session |
*----------------------------------------------------------------------*)
function TermSession (funcs : PSecurityFunctionTable; dwKey : DWORD) : boolean;
var
pAS : PAuthSeq;
begin
result := False;
if DeleteEntry (dwKey, pointer (pAS)) then
begin
if pAS^._fHaveCtxtHandle then
funcs^.DeleteSecurityContext (@pAS^._hctxt);
if pAS^._fHaveCredHandle then
funcs^.FreeCredentialHandle (@pAS^._hcred);
freemem (pAS);
result := True
end
end;
(*----------------------------------------------------------------------*
| SSPLogonUser |
| |
| Validate password for user/domain. Returns true if the password is |
| valid. |
*----------------------------------------------------------------------*)
function SSPLogonUser (const DomainName, UserName, Password : string) : boolean;
var
done : boolean;
cbOut, cbIn : DWORD;
AuthIdentity : TSecWINNTAuthIdentity;
session0OK, session1OK : boolean;
packageHandle : THandle;
if session0OK and session1OK and (packageHandle <> 0) then
begin
GetMem (pClientBuf, cbMaxMessage);
GetMem (pServerBuf, cbMaxMessage);
FillChar (AuthIdentity, sizeof(AuthIdentity), 0);
if DomainName <> '' then
begin
AuthIdentity.Domain := PChar (DomainName);
AuthIdentity.DomainLength := Length (DomainName)
end;
if UserName <> '' then
begin
AuthIdentity.User := PChar (UserName);
AuthIdentity.UserLength := Length (UserName);
end;
if Password <> '' then
begin
AuthIdentity.Password := PChar (Password);
AuthIdentity.PasswordLength := Length (Password)
end;