⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 waruserauthwin32nt.cpp

📁 ftpserver very good sample
💻 CPP
📖 第 1 页 / 共 2 页
字号:
#include "StdAfx.h"#include "WarUserAuthWin32Nt.h"   // class implemented#include "WarWinntLsa.h"#ifndef WAR_USER_AUTHDATA_WIN32_NT_H#   include "WarUserAuthDataWin32Nt.h"#endif#ifndef WAR_LOG_H#   include <WarLog.h>#endif#ifndef WAR_WIN32_NT_H#   include "WarWin32Nt.h"#endif#ifndef WAR_INCLUDED_TCHAR_H#   define WAR_INCLUDED_TCHAR_H#   include <tchar.h>#endif#ifndef WAR_SVR_PROTOCOL_H#   include "WarSvrProtocol.h"#endifusing namespace std;#ifdef UNICODE#   define U2T(a) a#else#   define U2T(a) WarCollector<char>(a).GetValue().c_str()#endif#define MY_SERVER (IsUsingLocalMachine() ? NULL : GetAuthServer().GetValue().c_str())/////////////////////////////// PUBLIC /////////////////////////////////////////============================= LIFECYCLE ====================================WarUserAuthWin32Nt::WarUserAuthWin32Nt()//: mAnonUserPasswd(netstr_t::SM_ERASE)  {}// WarUserAuthWin32NtWarUserAuthWin32Nt::~WarUserAuthWin32Nt(){}// ~WarUserAuthWin32Nt//============================= OPERATORS ====================================//============================= OPERATIONS ===================================void WarUserAuthWin32Nt::Create(const WarWin32Registry& regKey,                                const bool doValidateGroup){        // Duplicate the regkey    mRegRoot.Create(regKey.GetRef());    if (doValidateGroup)    {        // Fix FTP-group        ValidateAndFixGroup(GetAuthGroup().GetValue());        ValidateAndCheckAnonUser();    }}WarUserAuthWin32Nt::WarLoginResultE WarUserAuthWin32Nt::Login(        WarSvrProtocol& fromServer,        war_ccsysstr_t virtualHost,         war_ccsysstr_t userName,         war_ccsysstr_t userPasswd,        war_authdata_ptr_t& authDataPtr,        bool &isAuthorative){    WarLog err_log(WARLOG_ERROR, "WarUserAuthWin32Nt::Login()");    WarLog debug_log(WARLOG_DEBUG, "WarUserAuthWin32Nt::Login()");    bool have_domain = false, is_anon = false;    WarCollector<TCHAR> anon_username,         anon_passwd(WarCollector<TCHAR>::SM_ERASE);    if (!userName || !*userName)    {        if (IsAnonAllowed())        {            if (!userPasswd || !*userPasswd)                return LF_NEED_EMAIL_AS_PWD;            anon_username << GetAnonUser().GetValue();            anon_passwd << GetAnonPasswd().GetValue();            userName = anon_username.GetValue().c_str();            userPasswd = anon_passwd.GetValue().c_str();            is_anon = true;        }        else        {            if (debug_log)            {                debug_log << "The NT/Windows 2000 auth module is configured not "                    "to allow anonymous logins. Passing the anonymous login "                    "request to the next auth handler."                    << war_endl;            }                                    return LF_CALLER_NOT_AUTHENTICATED;        }    }    basic_string<TCHAR> name = userName;    basic_string<TCHAR> domain = _T(".");    string::size_type pos = name.find('@');    if (pos != string.npos)    {        // Domain is provided        domain = name.substr(pos +1);        name.erase(pos);        have_domain = true;    }    WarCollector<TCHAR> login_name, login_domain,         login_passwd(WarCollector<TCHAR>::SM_ERASE);    login_name = name;    login_domain = domain;    login_passwd = userPasswd;    HANDLE user_handle = NULL;    // Check if the user exists in the "FTP-Users" group    LPBYTE result_buffer = NULL;    DWORD num_entries = 0, total_entries = 0;    netstr_t net_username;        if (have_domain)        net_username << login_domain.GetValue() << '\\';    net_username << login_name.GetValue();        NET_API_STATUS net_result;            if (!is_anon)    {        net_result = ::NetUserGetLocalGroups(            MY_SERVER,            net_username.GetValue().c_str(),            0,            LG_INCLUDE_INDIRECT,            &result_buffer,            MAX_PREFERRED_LENGTH,            &num_entries,            &total_entries);        netstr_t ftp_group = GetAuthGroup();                switch(net_result)        {        case NERR_Success:            // Scan for the requiered group            {                PGROUP_USERS_INFO_0 pgroup = (PGROUP_USERS_INFO_0)result_buffer;                for(DWORD i = 0; i < num_entries; i++, pgroup++)                {                    if (::_wcsicmp(pgroup->grui0_name,                         ftp_group.GetValue().c_str()) == 0)                        break;                }                                ::NetApiBufferFree(result_buffer);                                if (i == num_entries)                {                    if (debug_log)                    {                        debug_log << "The user "                            << userName                            << " was found in the NT user database, but is "                            "denied access, as he/she is not a member "                            "of the local \""                             << ftp_group.GetValue()                             << "\" group."                            << war_endl;                    }                                        return LF_ACCESS_DENIED;                }            }            break;        case ERROR_ACCESS_DENIED:            err_log << "The program is missing NT creditials to execute NetUserGetGroups(). NT authentication cannot be performed!"                << WarError(WAR_ERR_SYSTEM_CALL_FAILED, ERROR_ACCESS_DENIED)                << war_endl;            WarThrow(WarError(WAR_ERR_SYSTEM_CALL_FAILED, ERROR_ACCESS_DENIED), NULL);            break;        case NERR_UserNotFound:            if (debug_log)            {                debug_log << "The user "                    << userName                    << " was not found in the NT user database."                    << war_endl;            }            return LF_USER_NOT_FOUND; // Not found        }    }    if (!userPasswd || !*userPasswd)        return LF_NEED_PASSWORD;    if (!::LogonUser((LPTSTR)login_name.GetValue().c_str(),         (LPTSTR)login_domain.GetValue().c_str(),        (LPTSTR)login_passwd.GetValue().c_str(),        LOGON32_LOGON_BATCH, /*LOGON32_LOGON_NETWORK*/        LOGON32_PROVIDER_DEFAULT,        &user_handle))    {        if (debug_log)        {            WarSystemError system_err;            debug_log << "The user "                << userName                << " was denied access. "                << system_err                << war_endl;            if (system_err.SystemError() == ERROR_PRIVILEGE_NOT_HELD)            {                err_log << "Failed to authenticate the user due to "                    "a missing privilege. The most likely reason is "                    "that the process running the server is missing the "                    "\"Act as part of the operating system\" privilege. "                    "Please check the local security policy on the machine! "                    << system_err                    << war_endl;                return LF_CONFIGURATION_ERROR;            }                    }        return LF_ACCESS_DENIED;    }    // Get the users SID     SID_AND_ATTRIBUTES *psa = NULL;    DWORD psa_len = 0;    if (!::GetTokenInformation(user_handle,         TokenUser,        psa,        0,        &psa_len))    {        WarSystemError sys_err;        if (sys_err.SystemError() != ERROR_INSUFFICIENT_BUFFER)        {               err_log << "user was authenticated, but the first call to GetTokenInformation() failed."                << sys_err                << war_endl;                        ::CloseHandle(user_handle);                        return LF_INTERNAL_ERROR;        }    }    vector<char> psa_buf(psa_len);    psa = (SID_AND_ATTRIBUTES *)&psa_buf[0];    if (!::GetTokenInformation(user_handle,         TokenUser,        psa,        psa_len,        &psa_len))    {        WarSystemError sys_err;        err_log << "user was authenticated, but the second call to GetTokenInformation() failed."            << sys_err            << war_endl;        ::CloseHandle(user_handle);        return LF_INTERNAL_ERROR;    }    try    {            user_data_ptr_t my_auth_ptr = CreateDataHandle(psa->Sid,             userName, user_handle, is_anon);                my_auth_ptr->LoadOptions(fromServer.GetProperties().mOptions);        authDataPtr = (war_authdata_ptr_t &)my_auth_ptr;    }    catch(WarException)    {        // Clean up        ::CloseHandle(user_handle);        return LF_INTERNAL_ERROR;    }    // The user is logged on!    if (debug_log)    {        debug_log << "The user ";        if (is_anon)            debug_log << "[anonymous] ";                debug_log << userName            << " has logged on to Windows NT/2000."            << war_endl;    }    return LF_OK;}WarUserAuthWin32Nt::user_data_ptr_t  WarUserAuthWin32Nt::CreateDataHandle(PSID pUserSid,                                     war_ccsysstr_t userName,                                     HANDLE hLoginHandle,                                     bool isAnonymous)                                     throw(WarException){    WarLog err_log(WARLOG_ERROR, "WarUserAuthWin32Nt::CreateDataHandle()");        // Open/create the users registry key    TCHAR sid_string[MAX_PATH];    *sid_string = 0;    DWORD sid_string_len = MAX_PATH;    if (!WarGetTextualSid(pUserSid, sid_string, &sid_string_len))    {        WarSystemError sys_err;               err_log << "The call to GetTextualSid() failed."            << sys_err            << war_endl;        WarThrow(sys_err, NULL);    }    WarUserAuthDataWin32Nt *pnew_win32handle = new WarUserAuthDataWin32Nt;    try    {        pnew_win32handle->mLogonHandle = hLoginHandle;                war_registrypath_t reg_path;        reg_path << mRegRoot.GetRef().GetPath().GetPath()            << WAR_SYSSLASH << WAR_WINNT_REG_USERS            << WAR_SYSSLASH << sid_string;                pnew_win32handle->mRegRoot.Create(WarWin32Registry::open_t(            mRegRoot, reg_path));        pnew_win32handle->mRegRoot.SetValue(WAR_WINNT_REG_NAME,             WarCollector<TCHAR>(userName).GetValue().c_str());        if (!pnew_win32handle->mRegRoot.HaveValue(WAR_WINNT_REG_ENABLE))            pnew_win32handle->mRegRoot.SetValue(WAR_WINNT_REG_ENABLE, true);        WarCollector<char> user_name;        if (isAnonymous)        {            user_name << "Anonymous";        }        else        {            user_name << userName;        }        pnew_win32handle->SetUserName(user_name.GetValue().c_str());        pnew_win32handle->mIsAnonymous = isAnonymous;    }    catch(WarException& e)    {        delete pnew_win32handle;        throw e;    }    return pnew_win32handle;}void WarUserAuthWin32Nt::SetUsingLocalMachine(const bool doSet) throw(WarException){    mRegRoot.SetValue(WAR_WINNT_AUTH_SERVER_LOCAL, doSet);}void WarUserAuthWin32Nt::SetAnonNeedEmailAsPasswd(const bool doSet) throw(WarException){    mRegRoot.SetValue(WAR_WINNT_AUTH_ANON_PWDEMAIL, doSet);}void WarUserAuthWin32Nt::SetEnableAnon(const bool doEnable) throw(WarException){    mRegRoot.SetValue(WAR_WINNT_AUTH_ALLOW_ANON, doEnable);}void WarUserAuthWin32Nt::SetAuthServer(const netstr_t& strName) throw(WarException){    ::RegSetValueExW(mRegRoot.GetNodeKey(), L"Auth Server",        0, REG_SZ,         (LPBYTE)(strName.GetValue().c_str()),         strName.GetValue().size() * sizeof(WCHAR));}void WarUserAuthWin32Nt::SetAuthGroup(const netstr_t& strName) throw(WarException){    ::RegSetValueExW(mRegRoot.GetNodeKey(), L"FTP Group",        0, REG_SZ,         (LPBYTE)(strName.GetValue().c_str()),         strName.GetValue().size() * sizeof(WCHAR));}void WarUserAuthWin32Nt::SetAnonUser(const netstr_t& strName) throw(WarException){    ::RegSetValueExW(mRegRoot.GetNodeKey(), L"Anonymous User",        0, REG_SZ,         (LPBYTE)(strName.GetValue().c_str()),         strName.GetValue().size() * sizeof(WCHAR));}void WarUserAuthWin32Nt::SetAnonPasswd(const netstr_t& strName) throw(WarException){    ::RegSetValueExW(mRegRoot.GetNodeKey(), L"Anonymous Password",        0, REG_SZ,         (LPBYTE)(strName.GetValue().c_str()),         strName.GetValue().size() * sizeof(WCHAR));    WarCollector<TCHAR> passwd_buf(WarCollector<wchar_t>::SM_ERASE);    passwd_buf = strName;    mRegRoot.SetValue(WAR_WINNT_AUTH_ANON_PASSWD,         passwd_buf.GetValue(), true);}void WarUserAuthWin32Nt::CreateUser(war_ccsysstr_t userName,                                     war_ccsysstr_t userPasswd,                                    const bool doEnable)                                    throw(WarException){    USER_INFO_1 ui;    memset(&ui, 0, sizeof(ui));    netstr_t user_name = userName,         user_passwd = userPasswd;    ui.usri1_name = (LPWSTR)user_name.GetValue().c_str();    ui.usri1_password = (LPWSTR)user_passwd.GetValue().c_str();    ui.usri1_priv = USER_PRIV_USER;    ui.usri1_flags = UF_SCRIPT         | UF_DONT_EXPIRE_PASSWD         | UF_DONT_REQUIRE_PREAUTH         | UF_NORMAL_ACCOUNT;        NET_API_STATUS result = ::NetUserAdd(MY_SERVER, 1, (LPBYTE)&ui, NULL);    if (NERR_Success != result)    {        WarLog err_log(WARLOG_ERROR, "WarUserAuthWin32Nt::CreateUser()");        WarError err = MapErrorCode(result);        err_log << "Failed to create user \""            << userName            << "\". "            << err            << war_endl;        WarThrow(err, NULL);    }}void WarUserAuthWin32Nt::DeleteUser(war_ccsysstr_t userName)throw(WarException){    netstr_t user_name = userName;    NET_API_STATUS result = ::NetUserDel(        MY_SERVER, user_name.GetValue().c_str());    if (NERR_Success != result)    {        WarLog err_log(WARLOG_ERROR, "WarUserAuthWin32Nt::DeleteUser()");        WarError err = MapErrorCode(result);        err_log << "Failed to delete user \""

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -