我正在编写一个可以更改已登录用户密码的c ++程序(该计算机上只有一个用户),并且该程序将在该计算机上作为服务运行,我找到了一个方法NetUserSetInfo
做这项工作和我选择NetUserSetInfo
的原因是我不想提供旧密码,找到我的代码
void chpwd::initialize() // function that initialize params of NetUserSetInfo
{
cout<<"initializing"<<endl;
string un=getenv("USERDOMAIN");
un+="\\";
un+=getenv("USERNAME"); //"USERDOMAIN\USERNAME", I gave name also,since the target machine won't be in domain
wstring uname=wstring(un.begin(),un.end());
wUserName=(wchar_t*)uname.c_str();
wcout<<wUserName<<endl;
wComputerName=_wgetenv (L"COMPUTERNAME");
wcout<<wComputerName<<endl;
string pw(p.genpassword());
cout<<"pw "<<pw<<endl;
wstring pwd=wstring(pw.begin(),pw.end());
wcout.flush();
wNewPassword=const_cast<LPWSTR>(pwd.c_str());
wcout<<wNewPassword<<endl;
}
bool chpwd::chngpwd() //funtion that changes password
{
initialize();
do
{
pi1003.usri1003_password = wNewPassword;
wcout.flush();
wcout<<wNewPassword<<endl;
nas = NetUserSetInfo(
wComputerName, // computer name
wUserName, // username
1003, // info level
(LPBYTE)&pi1003, // new info
NULL
);
if(nas != NERR_Success)
{
DisplayErrorText(nas);
l.logic_log(l.time(),"Error occured while reseting password \n old password \""+p.prevp+"\" retains");
}
Sleep(1000);
}while(nas != NERR_Success);
return 1;
}
当我运行代码时,params被正确初始化,但是我在更改密码时遇到The username could not be found.
错误,我没有真正得到这个错误,我给出的用户名是正确的,我也执行了某个机器中的代码不在任何域下并具有管理员权限,但仍然相同,任何人都可以指出我出了什么问题。
bool chpwd::chngpwd()
{
wstring uname = _wgetenv(L"USERDNSDOMAIN");
uname += L"@";
uname += _wgetenv(L"USERNAME");
wcout << L"un " << uname << endl;//OP-Rixxxx.com@Richy_G
wstring cname = _wgetenv (L"COMPUTERNAME");
wcout << L"cn " << cname << endl;//TExxxxM
wstring pwd;
string pw = p.genpassword();//eadjbic3
int len = MultiByteToWideChar(CP_ACP, 0, pw.c_str(), pw.length(), NULL, 0);
if (len > 0)
{
pwd.resize(len);
MultiByteToWideChar(CP_ACP, 0, pw.c_str(), pw.length(), &pwd[0], len);
}
wcout << L"pw " << pwd << endl;
do
{
pi1003.usri1003_password = const_cast<LPWSTR>(pwd.c_str());;
//wcout.flush();
//wcout<<wNewPassword<<endl;
nas = NetUserSetInfo(
cname.c_str(), // computer name
uname.c_str(), // username
1003, // info level
(LPBYTE)&pi1003, // new info
NULL
);
if(nas != NERR_Success)
{
DisplayErrorText(nas);
l.logic_log(l.time(),"Error occured while reseting password \n old password \""+p.prevp+"\" retains");
}
Sleep(1000);
}while(nas != NERR_Success);
return 1;
}
同样,变量是用适当的值获得的,但仍然如此 说
user name couldn't be found
答案 0 :(得分:1)
使用wstring(iterator,iterator)
不是将Ansi编码的std::string
转换为Unicode std::wstring
的正确方法。这只适用于ASCII字符,其他字符将无法正确转换。请改用MultiByteToWideChar()
或等效词,或使用_wgetenv()
代替getenv()
。
但更重要的是,您应该将所有initialize()
代码直接移动到chngpwd()
并删除所有中间变量。当wUserName
退出时,您正在使用局部变量中超出范围的数据初始化wNewPassword
和initialize()
。因此,当它们传递给NetUserSetInfo()
时,它们会指向无效的内存。
尝试更像这样的事情:
bool chpwd::chngpwd()
{
wstring uname = _wgetenv(L"USERDOMAIN");
uname += L"\\";
uname += _wgetenv(L"USERNAME");
wcout << L"un " << uname << endl;
wstring cname = _wgetenv (L"COMPUTERNAME");
wcout << L"cn " << cname << endl;
wstring pwd;
string pw = p.genpassword();
int len = MultiByteToWideChar(CP_ACP, 0, pw.c_str(), pw.length(), NULL, 0);
if (len > 0)
{
pwd.resize(len);
MultiByteToWideChar(CP_ACP, 0, pw.c_str(), pw.length(), &pwd[0], len);
}
wcout << L"pw " << pwd << endl;
USER_INFO_1003 pi1003;
pi1003.usri1003_password = const_cast<LPWSTR>(pwd.c_str());
NET_API_STATUS nas;
do
{
nas = NetUserSetInfoW(
cname.c_str(), // computer name
uname.c_str(), // username
1003, // info level
(LPBYTE)&pi1003, // new info
NULL
);
if (nas == NERR_Success) break;
DisplayErrorText(nas);
l.logic_log(l.time(), "Error occured while reseting password \n old password \"" + p.prevp + "\" retains");
Sleep(1000);
}
while (true);
return 1;
}