|
How can I create a new windows user ?
Anybody knows?
Thanks
|
|
|
|
|
hi.
the example does not running on my machine. sorry.
the problem:
DWORD dwRes = ::SetEntriesInAcl(cCountOfExplicitEntries, pListOfExplicitEntries, m_pACL, &paclNew);
returns ErrorCode 87 (Invalid Parameter).
But I don't know which parameter is wrong.
I don't know, but the methode "InitializeAcl" is never called. is this right ?
who is allocating the memory for m_pACL ?
Thank you for your help
best regards
emmi
|
|
|
|
|
|
Hi Peter:
In your sample code, you set KEY_READ TO "everyone" in first section of code and the return value of RegCreateKeyEx()in secod section of code is 5 under any acconts except administrator, which means err_access_fail.
ea[0] = CExplicitAccess(KEY_READ, SET_ACCESS, NO_INHERITANCE,
CTrustee(TRUSTEE_IS_WELL_KNOWN_GROUP,
CSid(CSid::WST_EVERYONE)));
RegCreateKeyEx(HKEY_CURRENT_USER, "mykey1", 0, "", 0,
KEY_READ | KEY_WRITE, sa, &hKey, &dwDisposition);
After take off KEY_WRITE in RegCreateKeyEx(), it works fine to read value from the mykey1. However, is there any way that can read/write
value under "everyone".
OS I tested is Win XP home edition.
Thanks,
JP
|
|
|
|
|
I had a problem where an application run as Administrator created a LOCAL_MACHINE key, but when the application was run as a non-adminstrator account, the app could not read the key. I assume this means that the default security was set that way on purpose.
By using this code, I just set the ACL to allow Everyone full access to the key, so the application could read/write the key no matter what user was running the app. Just what I needed... THANKS!
|
|
|
|
|
How can i list on C++ the ACL of file, thank U so much
Osirix
|
|
|
|
|
Does anyone know how to programatically change permissions of an existing registry key?
The return code of RegCreateKeyEx(HKEY_LOCAL_MACHINE, sKey, 0, "", 0, KEY_ALL_ACCESS, sa, &hKey, &dwDisposition) is 0, but nothing was changed in the registry.
The value of dwDisposition says me that I have opened an existing key (==REG_OPENED_EXISTING_KEY).
If I then try to change the key with RegSetKeySecurity I get return code 87.
What could be wrong ???
|
|
|
|
|
// Use the security attributes to set the security descriptor
// when you create a key.
lRes = RegCreateKeyEx(HKEY_LOCAL_MACHINE, directory, 0, "", 0,
KEY_READ | KEY_WRITE, &sa, &hkSub, &dwDisposition);
//In case key already existed:
//Close the key
//Open the key
//Change Permissions
//Why?? I don't know...
if (hkSub)
{
RegCloseKey(hkSub);
RegOpenKey(HKEY_LOCAL_MACHINE, directory, &hkSub);
if (hkSub)
{
RegSetKeySecurity(hkSub,DACL_SECURITY_INFORMATION, pSD);
}
}
law
|
|
|
|
|
Hi!
What is pSD in your code? I test it but it doesn't work, RegSetKeySecurity doesn't return ERROR_SUCCESS and my key permissions remains the same.
Thks in advance!
Appstmd
http://www.atlence.com
|
|
|
|
|
Does anyone know how to programatically change registry permissions in accordance with a security template like the NSA's.
An example is:
"machine\system\currentcontrolset\hardware profiles",0,"D:PAR(A;CI;KA;;;BA)(A;CIIO;KA;;;CO)(A;CI;KA;;;SY)(A;CI;KR;;;BU)"
|
|
|
|
|
When cleaning up memory allocated via new [] should use delete [] So delete m_pSid; should be: delete [] m_pSid;
Same goes for m_pSD although there is a problem if constructor CSecurityDescriptor(PSECURITY_DESCRIPTOR pSD) is used and pointer passed was not allocated via new [] .
John Curtis.
Fatlab Software.
|
|
|
|
|
Is there any api to find out the list of all the logged on user and machine name from Primary Domain Controller
HArish Chouksey
Software Engineer
Learnet India Limited
Mumbai-India
|
|
|
|
|
NetSessionEnum would do that.
Peter
|
|
|
|
|
NetSessionEnum is having a bug, it will only give latest sessions. it will expires some old session. can u give some other way.
HArish Chouksey
Software Engineer
Learnet India Limited
Mumbai-India
|
|
|
|
|
Hi
I want to get a notification when a user gets hismself locked out by any reason.
How do I do that?
TIA
Ahaz
|
|
|
|
|
Dear Peter Kenyon,
Hi, thanks for your good source for freeing programmer from confusing APIs.
I have an ISAPI dll that processes some incoming web requests, sometimes I should write a text into a file that is located in the system partition of my hard disk, but my function that must create a file or write some contents to it returns an error number equal to 5.
So when I add the user IUser_systemname to the list of users for that directory, I can do last activities. So my question is how can change the code to place the user into directory's user list.
I have such problem in changing the registery contents during processing a web request that is associated to an ISAPI dll.
Thanks,
Mohammad Reza Hemmati
|
|
|
|
|
Dear Peter Kenyon,
Hi, thanks for your good source for freeing programmer from confusing APIs.
I have an ISAPI dll that processes some incoming web requests, sometimes I should write a text into a file that is located in the system partition of my hard disk, but my function that must create a file or write some contents to it returns an error number equal to 5.
So when I add the user IUser_systemname to the list of users for that directory, I can do last activities. So my question is how can change the code to place the user into directory's user list.
I have such problem in changing the registery contents during processing a web request that is associated to an ISAPI dll.
Thanks,
Mohammad Reza Hemmati
|
|
|
|
|
Since you seem to have extensive knowledge with the security APIs, I'd like to ask you this question. Given a username and password, how do you verify that they're valid for login into an NT machine?
Thanks for your time and congratulations on your great work!
Regards,
Alvaro
|
|
|
|
|
Here's a member function for a class that i made. It validates a user!
// Performs users authentication, sets the user token if successful
bool CWin32WorkUnit::VerifyUser(char *user,char *password)
{
if (m_hUserToken)
CloseHandle(m_hUserToken);
if (LogonUser(user,".",password,LOGON32_LOGON_BATCH,LOGON32_PROVIDER_DEFAULT,&m_hUserToken))
return true;
return false;
}
The m_hUserToken is a HANDLE member
You will have to have the required privileges to do this. Here's what I did.
// This function will attempt to add a privilege to the current user
bool CWin32SocketServer::AddPrivilege(LPTSTR pStrPrivilege)
{
LSA_OBJECT_ATTRIBUTES ObjectAttributes;
WCHAR wszString[128];
DWORD wszStringLength;
LSA_UNICODE_STRING lsaszServer;
NTSTATUS ntsResult;
LSA_HANDLE lsahPolicyHandle;
PSID pSid;
SID_NAME_USE nameUse;
TCHAR userName[256],domain[256];
DWORD len=sizeof(userName);
DWORD lenD=sizeof(domain);
bool bRet=false;
// first determine which user we are
GetUserName(userName,&len);
// Object attributes are reserved, so initalize to zeroes.
ZeroMemory(&ObjectAttributes, sizeof(ObjectAttributes));
//Initialize an LSA_UNICODE_STRING structure to the server name.
// The server machine is just . for the local machine
wcscpy(wszString,L".");
wszStringLength = wcslen(wszString);
lsaszServer.Buffer = wszString;
lsaszServer.Length = (USHORT) wszStringLength * sizeof(WCHAR);
lsaszServer.MaximumLength=(USHORT)(wszStringLength+1) * sizeof(WCHAR);
// Attempt to open the policy.
ntsResult = LsaOpenPolicy(&lsaszServer,&ObjectAttributes,POLICY_CREATE_ACCOUNT | POLICY_LOOKUP_NAMES,&lsahPolicyHandle);
// lookup the SID of the current user, will return size of structure
LookupAccountName(NULL,userName,NULL,&len,domain,&lenD,&nameUse);
// allocate it
pSid=new BYTE[len];
if (pSid)
{
// lookup again, get the SID
lenD=sizeof(domain);
LookupAccountName(NULL,userName,pSid,&len,domain,&lenD,&nameUse);
//Initialize an LSA_UNICODE_STRING structure to the token to add
MultiByteToWideChar(CP_ACP,0,pStrPrivilege,-1,wszString,sizeof(wszString));
wszStringLength = wcslen(wszString);
lsaszServer.Buffer = wszString;
lsaszServer.Length = (USHORT) wszStringLength * sizeof(WCHAR);
lsaszServer.MaximumLength=(USHORT)(wszStringLength+1) * sizeof(WCHAR);
// attempt to add it
ntsResult=LsaAddAccountRights(lsahPolicyHandle,pSid,&lsaszServer,1);
if (ntsResult == 0) // success
bRet=true;
delete [] pSid;
}
//Freeing the policy object handle
LsaClose(lsahPolicyHandle);
return bRet;
}
// This function enables the privilege for the user (if the user has the privilege
// to start!) If the user doesn't have the privilege, it attempts to add it
bool CWin32SocketServer::EnablePrivilege(LPTSTR pStrPrivilege)
{
char error[1024];
HANDLE hProcessToken;
TOKEN_PRIVILEGES privilege;
bool bRes=false;
// open our process token
if (OpenProcessToken(GetCurrentProcess(),TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY,&hProcessToken))
{
// initialize the structure of our token
privilege.PrivilegeCount=1;
privilege.Privileges[0].Attributes=SE_PRIVILEGE_ENABLED | SE_PRIVILEGE_USED_FOR_ACCESS;
LookupPrivilegeValue(NULL,pStrPrivilege,&privilege.Privileges[0].Luid);
// do the adjustment, enable it
AdjustTokenPrivileges(hProcessToken,FALSE,&privilege,0,0,0);
// check the result
if (GetLastError() != ERROR_SUCCESS)
{
// didn't work! try to add it to the current account
if (!AddPrivilege(pStrPrivilege))
{
// if we can't add it and can't enable it, we're screwed
strcpy(error,"I was unable to add privilege ");
strcat(error,pStrPrivilege);
strcat(error,".\r\nThis program will not be able to be run ever");
MessageBox(NULL,error,NULL,MB_OK);
// get outta here!
ExitProcess(-1);
}
bRes=false;
}
else
{
bRes=true;
}
// close the process token
CloseHandle(hProcessToken);
}
return bRes;
}
Then when i run the app, in say InitApp(), i execute this code
bool bReboot=false;
// enable privleges so people can be validated
if (!EnablePrivilege(SE_TCB_NAME))
bReboot=true;
if (!EnablePrivilege(SE_CHANGE_NOTIFY_NAME))
bReboot=true;
if (!EnablePrivilege(SE_ASSIGNPRIMARYTOKEN_NAME))
bReboot=true;
if (!EnablePrivilege(SE_INCREASE_QUOTA_NAME))
bReboot=true;
if (bReboot)
{
// i must reboot to change
MessageBox(NULL,"You must logoff for privilege changes to take effect\r\nPress OK to logoff now",NULL,MB_OK);
// do the reboot now
ExitWindowsEx(EWX_LOGOFF,0);
return false;
}
|
|
|
|
|
Thanks for your help!
I had also posted this question in CodeGuru and was lucky to receive an equally great response. Here's the link to it. I went ahead and implemented the second option. It was a bit of a pain since I had to dig out code from the SockAuth sample, but it works fine (without ever needing to reboot).
Thanks again,
Alvaro
|
|
|
|
|
Hi! could u post the codeguru link again, it seems broken !!!
thanks in advantage
|
|
|
|
|
This is his question:
http://www.codeguru.com/cgi-bin/bbs/wt/showpost.pl?Board=vc&Number=196139&page=0&view=collapsed&sb=5&category=
|
|
|
|
|
When I call acl.SetEntriesInAcl, the function fails. The
error message from Windows states "invalid SID". I have
looked everywhere ( msdn, VC help, CodeGuru, Deja, ect.)
and have not been able to find out what I'm doing wrong.
I want to delete a registry key in Win2000 but I keep coming
up against this wall.
Here is the function:
BOOL CRegInfo::UnlockKey(CString keyName)
{
// Initialize a EXPLICIT_ACCESS structure for ADMINISTRATORS
// Assign KEY_ALL_ACCESS priviliges to Administrators
EXPLICIT_ACCESS ea[2];
ea[0] = CExplicitAccess(KEY_READ,SET_ACCESS,NO_INHERITANCE,
CTrustee(TRUSTEE_IS_WELL_KNOWN_GROUP,
CSid(CSid::WST_EVERYONE)));
ea[1] = CExplicitAccess(KEY_ALL_ACCESS,SET_ACCESS,NO_INHERITANCE,
CTrustee(TRUSTEE_IS_GROUP,
CSid(CSid::WST_LOCALADMINS)));
// Create a new ACL and set the EA entries in it
CAcl acl;
DWORD result = ERROR_SUCCESS;
// THIS IS WHERE THE CODE FAILS!!!
result = acl.SetEntriesInAcl(2, ea);
if( result== ERROR_SUCCESS)
{
// Initialize a security descriptor and add our ACL to it
CSecurityDescriptor sd;
if(sd.SetSecurityDescriptorDacl(TRUE,
acl,
FALSE) )
{
// Initialize a security attributes structure
CSecurityAttributes sa(sd, FALSE);
// Use the security attributes to set the security descriptor
// when you create a key
DWORD disposition;
HKEY hKey;
if(RegCreateKeyEx(m_currentKey,
keyName,
0,
0,
0,
KEY_READ | KEY_WRITE,
sa,
&hKey,
&disposition) == ERROR_SUCCESS)
{
m_currentKey = hKey;
return TRUE;
}
}
}
DisplayErrorMsg(GetLastError() );
return FALSE;
}
Any help would be greatly appreciated..
|
|
|
|
|
Hi,
When you use code like the following:
CTrustee trSomebody(TRUSTEE_IS_WELL_KNOWN_GROUP, CSid(CSid::WST_ADMINS));
the CSid is a temporary object which is deleted as soon as the next line executes. Instead, you should create the objects separately. Eg:
BOOL CRegInfo::UnlockKey(CString keyName)
{
CSid sidEveryone(CSid::WST_EVERYONE);
CSid sidAdmins(CSid::WST_LOCALADMINS);
CTrustee trEveryone(TRUSTEE_IS_WELL_KNOWN_GROUP, sidEveryone);
CTrustee trAdmins(TRUSTEE_IS_GROUP, sidAdmins);
EXPLICIT_ACCESS ea[2];
ea[0] = CExplicitAccess(KEY_READ, SET_ACCESS, NO_INHERITANCE, trEveryone);
ea[1] = CExplicitAccess(KEY_ALL_ACCESS, SET_ACCESS, NO_INHERITANCE, trAdmins);
.....
Pete
|
|
|
|
|
You just need to add copy constructors and assignment operators to your classes, then temp objects will work, as they should.
|
|
|
|
|