Hi

I'm making a tool that would change the password on a remote
computer automatically. The problem now is that
NetUserChangePassword() fails with GetLastError() returning 2245
"The password you specified is not long enough". There is however
no such restrictions when changing the password manually.

It seems like the change succeeds randomly so i though it would
give the user a chance to enter other credentials. Thus i try this code:

if (!OpenProcessToken(GetCurrentProcess(), TOKEN_WRITE /*
TOKEN_ADJUST_PRIVILEGES */, &htoken)) return FALSE;
tp.PrivilegeCount=1; tp.Privileges->Attributes=SE_PRIVILEGE_ENABLED;
if (!LookupPrivilegeValue(g_szPCname, SE_TCB_NAME, &tp.Privileges->Luid))
return FALSE;
b=AdjustTokenPrivileges(htoken, FALSE, &tp, 0, NULL, NULL);
if (!LookupPrivilegeValue(g_szPCname, SE_CREATE_TOKEN_NAME,
&tp.Privileges->Luid)) return FALSE;
b=AdjustTokenPrivileges(htoken, FALSE, &tp, 0, NULL, NULL);
if (!LookupPrivilegeValue(g_szPCname, SE_ASSIGNPRIMARYTOKEN_NAME,
&tp.Privileges->Luid)) return FALSE;
b=AdjustTokenPrivileges(htoken, FALSE, &tp, 0, NULL, NULL);
if (!LookupPrivilegeValue(g_szPCname, SE_ENABLE_DELEGATION_NAME,
&tp.Privileges->Luid)) return FALSE;
b=AdjustTokenPrivileges(htoken, FALSE, &tp, 0, NULL, NULL);
if (!LookupPrivilegeValue(g_szPCname, SE_SECURITY_NAME,
&tp.Privileges->Luid)) return FALSE;
b=AdjustTokenPrivileges(htoken, FALSE, &tp, 0, NULL, NULL);
CloseHandle(htoken); htoken=INVALID_HANDLE_VALUE;
if (!b) return FALSE;
if (LogonUser(g_szWebUser, "NOE", g_szWebPW, LOGON32_LOGON_NETWORK /*
LOGON32_LOGON_INTERACTIVE */,
LOGON32_PROVIDER_DEFAULT, &htoken))
{ ImpersonateLoggedOnUser(htoken); return TRUE; }
dw=GetLastError();

This code fails at the LogonUser() line returning 1314
ERROR_PRIVILEGE_NOT_HELD
Does this mean that i don't have the SE_TCB_NAME privilege?
I have also tried with NULL as the first parameter to
LookupPrivilegeValue() but that doesn't help.

Also, does NetUserChangePassword() really support both
"computername" and "\\\\computername" as the first parameter?
The \\\\ -prefixed variant can be found in the help output of the
sample code but the API documentation just talks about null-
terminated Unicode string.
Here is my current code:

sprintf(sz, "\\\\%s", p_szPCname);
MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, sz, -1, szPCname,
sizeof(szPCname));
MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, g_szOldPW, -1, szOldPW,
sizeof(szOldPW));
MultiByteToWideChar(CP_ACP, MB_PRECOMPOSED, p_szPassword, -1, szNewPW,
sizeof(szNewPW));
nas=NetUserChangePassword(szPCname, L"SvcAccount", szOldPW, szNewPW);

If you also know how to set the password without knowing the
old password that would be great. Note that this shouldn't be a
security risk as it's protected by the logged on credentials (with
admin rights) and the MMC plugin is able to do it (and a hacker
could possibly potentially control MMC?).

- Sten