[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[GNUnet-SVN] r897 - in GNUnet/src: conf include util/win
From: |
durner |
Subject: |
[GNUnet-SVN] r897 - in GNUnet/src: conf include util/win |
Date: |
Sun, 12 Jun 2005 03:44:27 -0700 (PDT) |
Author: durner
Date: 2005-06-12 03:44:17 -0700 (Sun, 12 Jun 2005)
New Revision: 897
Modified:
GNUnet/src/conf/wizard_util.c
GNUnet/src/include/winproc.h
GNUnet/src/util/win/win.cc
GNUnet/src/util/win/winproc.c
Log:
improve Windows service account
Modified: GNUnet/src/conf/wizard_util.c
===================================================================
--- GNUnet/src/conf/wizard_util.c 2005-06-11 09:11:14 UTC (rev 896)
+++ GNUnet/src/conf/wizard_util.c 2005-06-12 10:44:17 UTC (rev 897)
@@ -148,7 +148,7 @@
{
if (IsWinNT())
{
- char szErr[250];
+ char *err;
DWORD dwErr;
switch(InstallAsService(username))
@@ -157,25 +157,40 @@
case 1:
break;
case 2:
- dwErr = GetLastError();
- SetErrnoFromWinError(dwErr);
- sprintf(szErr, _("Error: can't open Service Control
Manager: %s (%i)\n"),
- _win_strerror(errno), dwErr);
-
- MessageBox(GetActiveWindow(), szErr,
_("Error"), MB_ICONSTOP | MB_OK);
- return 0;
+ err = winErrorStr(_("Can't open Service
Control Manager"),
+ GetLastError());
case 3:
dwErr = GetLastError();
- SetErrnoFromWinError(dwErr);
- sprintf(szErr, _("Error: can't create service: %s
(#%i)\n"),
- _win_strerror(errno), dwErr);
-
- MessageBox(GetActiveWindow(), szErr,
_("Error"), MB_ICONSTOP | MB_OK);
- return 0;
+ if (dwErr != ERROR_SERVICE_EXISTS)
+ {
+ err = winErrorStr(_("Can't
create service"),
+ GetLastError());
+ }
+ break;
default:
- MessageBox(GetActiveWindow(),
_("Unknown error"), _("Error"),
- MB_ICONSTOP | MB_OK);
+ err = winErrorStr(_("Unknown error"),
+ GetLastError());
}
+
+ if (!err || dwErr == ERROR_SERVICE_EXISTS)
+ {
+ char szHome[_MAX_PATH + 1];
+
+ plibc_conv_to_win_path("/", szHome);
+
+ if (!AddPathAccessRights(szHome, username,
GENERIC_ALL))
+ {
+ err = winErrorStr(_("Error changing the
permissions of the GNUnet directory"),
+ GetLastError());
+ }
+ }
+
+ if (err && dwErr != ERROR_SERVICE_EXISTS)
+ {
+ MessageBox(GetActiveWindow(), err, _("Error"),
MB_ICONSTOP | MB_OK);
+ free(err);
+ return 0;
+ }
}
else
{
Modified: GNUnet/src/include/winproc.h
===================================================================
--- GNUnet/src/include/winproc.h 2005-06-11 09:11:14 UTC (rev 896)
+++ GNUnet/src/include/winproc.h 2005-06-12 10:44:17 UTC (rev 897)
@@ -43,6 +43,7 @@
#include <sys/param.h> /* #define BYTE_ORDER */
#include <Ntsecapi.h>
#include <lm.h>
+#include <Aclapi.h>
#include "gnunet_util.h"
#include "platform.h"
@@ -99,6 +100,26 @@
typedef BOOL WINAPI (*TLookupAccountName) (LPCTSTR lpSystemName, LPCTSTR
lpAccountName,
PSID Sid, LPDWORD cbSid, LPTSTR ReferencedDomainName,
LPDWORD cchReferencedDomainName, PSID_NAME_USE peUse);
+
+typedef BOOL WINAPI (*TGetFileSecurity) (LPCTSTR lpFileName,
+ SECURITY_INFORMATION RequestedInformation, PSECURITY_DESCRIPTOR
pSecurityDescriptor,
+ DWORD nLength, LPDWORD lpnLengthNeeded);
+typedef BOOL WINAPI (*TInitializeSecurityDescriptor) (PSECURITY_DESCRIPTOR
pSecurityDescriptor,
+ DWORD dwRevision);
+typedef BOOL WINAPI (*TGetSecurityDescriptorDacl) (PSECURITY_DESCRIPTOR
pSecurityDescriptor,
+ LPBOOL lpbDaclPresent, PACL* pDacl, LPBOOL lpbDaclDefaulted);
+typedef BOOL WINAPI (*TGetAclInformation) (PACL pAcl, LPVOID pAclInformation,
+ DWORD nAclInformationLength, ACL_INFORMATION_CLASS dwAclInformationClass);
+typedef BOOL WINAPI (*TInitializeAcl) (PACL pAcl, DWORD nAclLength, DWORD
dwAclRevision);
+typedef BOOL WINAPI (*TGetAce) (PACL pAcl, DWORD dwAceIndex, LPVOID* pAce);
+typedef BOOL WINAPI (*TEqualSid) (PSID pSid1, PSID pSid2);
+typedef BOOL WINAPI (*TAddAce) (PACL pAcl, DWORD dwAceRevision, DWORD
dwStartingAceIndex,
+ LPVOID pAceList, DWORD nAceListLength);
+typedef BOOL WINAPI (*TAddAccessAllowedAce) (PACL pAcl, DWORD dwAceRevision,
+ DWORD AccessMask, PSID pSid);
+typedef BOOL WINAPI (*TSetNamedSecurityInfo) (LPTSTR pObjectName,
SE_OBJECT_TYPE ObjectType,
+ SECURITY_INFORMATION SecurityInfo, PSID psidOwner, PSID psidGroup, PACL
pDacl,
+ PACL pSacl);
extern TNtQuerySystemInformation GNNtQuerySystemInformation;
extern TGetIfEntry GNGetIfEntry;
@@ -123,6 +144,16 @@
extern TLsaRemoveAccountRights GNLsaRemoveAccountRights;
extern TLsaClose GNLsaClose;
extern TLookupAccountName GNLookupAccountName;
+extern TGetFileSecurity GNGetFileSecurity;
+extern TInitializeSecurityDescriptor GNInitializeSecurityDescriptor;
+extern TGetSecurityDescriptorDacl GNGetSecurityDescriptorDacl;
+extern TGetAclInformation GNGetAclInformation;
+extern TInitializeAcl GNInitializeAcl;
+extern TGetAce GNGetAce;
+extern TEqualSid GNEqualSid;
+extern TAddAce GNAddAce;
+extern TAddAccessAllowedAce GNAddAccessAllowedAce;
+extern TSetNamedSecurityInfo GNSetNamedSecurityInfo;
BOOL CreateShortcut(const char *pszSrc, const char *pszDest);
@@ -130,6 +161,8 @@
long QueryRegistry(HKEY hMainKey, char *pszKey, char *pszSubKey,
char *pszBuffer, long *pdLength);
int ListNICs(void (*callback) (char *, int));
+BOOL AddPathAccessRights(char *lpszFileName, char *lpszAccountName,
+ DWORD dwAccessMask);
void GNInitWinEnv();
void GNShutdownWinEnv();
Modified: GNUnet/src/util/win/win.cc
===================================================================
--- GNUnet/src/util/win/win.cc 2005-06-11 09:11:14 UTC (rev 896)
+++ GNUnet/src/util/win/win.cc 2005-06-12 10:44:17 UTC (rev 897)
@@ -32,6 +32,10 @@
#include <ntdef.h>
+#ifndef INHERITED_ACE
+#define INHERITED_ACE 0x10
+#endif
+
extern "C" {
/**
@@ -218,7 +222,7 @@
hService = GNCreateService(hManager, "GNUnet", "GNUnet", 0,
SERVICE_WIN32_OWN_PROCESS, SERVICE_AUTO_START, SERVICE_ERROR_NORMAL, szEXE,
- NULL, NULL, NULL, user, user);
+ NULL, NULL, NULL, user, NULL);
if (user)
free(user);
@@ -450,7 +454,6 @@
memset(&ui, 0, sizeof(ui));
ui.usri1_name = wszName;
- ui.usri1_password = wszName; /* account is locked anyway */
ui.usri1_priv = USER_PRIV_USER;
ui.usri1_comment = wszDesc;
ui.usri1_flags = UF_SCRIPT;
@@ -460,7 +463,7 @@
if (nStatus != NERR_Success && nStatus != NERR_UserExists)
return 2;
- ui2.usri1008_flags = UF_ACCOUNTDISABLE | UF_PASSWD_CANT_CHANGE |
+ ui2.usri1008_flags = UF_PASSWD_NOTREQD | UF_PASSWD_CANT_CHANGE |
UF_DONT_EXPIRE_PASSWD;
GNNetUserSetInfo(NULL, wszName, 1008, (LPBYTE)&ui2, NULL);
@@ -473,22 +476,323 @@
if (_SetPrivilegeOnAccount(hPolicy, pSID, L"SeServiceLogonRight", TRUE)
!= STATUS_SUCCESS)
return 4;
+ _SetPrivilegeOnAccount(hPolicy, pSID, L"SeDenyInteractiveLogonRight",
TRUE);
+ _SetPrivilegeOnAccount(hPolicy, pSID, L"SeDenyBatchLogonRight", TRUE);
+ _SetPrivilegeOnAccount(hPolicy, pSID, L"SeDenyNetworkLogonRight", TRUE);
+
GNLsaClose(hPolicy);
return 0;
}
+/**
+ * @brief Grant permission to a file
+ * @param lpszFileName the name of the file or directory
+ * @param lpszAccountName the user account
+ * @param the desired access (e.g. GENERIC_ALL)
+ * @return TRUE on success
+ * @remark based on
http://support.microsoft.com/default.aspx?scid=KB;EN-US;Q102102&
+ */
+BOOL AddPathAccessRights(char *lpszFileName, char *lpszAccountName,
+ DWORD dwAccessMask)
+{
+ /* SID variables. */
+ SID_NAME_USE snuType;
+ TCHAR * szDomain = NULL;
+ DWORD cbDomain = 0;
+ LPVOID pUserSID = NULL;
+ DWORD cbUserSID = 0;
+
+ /* File SD variables. */
+ PSECURITY_DESCRIPTOR pFileSD = NULL;
+ DWORD cbFileSD = 0;
+
+ /* New SD variables. */
+ SECURITY_DESCRIPTOR newSD;
+
+ /* ACL variables. */
+ PACL pACL = NULL;
+ BOOL fDaclPresent;
+ BOOL fDaclDefaulted;
+ ACL_SIZE_INFORMATION AclInfo;
+
+ /* New ACL variables. */
+ PACL pNewACL = NULL;
+ DWORD cbNewACL = 0;
+
+ /* Temporary ACE. */
+ LPVOID pTempAce = NULL;
+ UINT CurrentAceIndex = 0;
+
+ UINT newAceIndex = 0;
+
+ /* Assume function will fail. */
+ BOOL fResult = FALSE;
+ BOOL fAPISuccess;
+
+ SECURITY_INFORMATION secInfo = DACL_SECURITY_INFORMATION;
+
+ /**
+ * STEP 1: Get SID of the account name specified.
+ */
+ fAPISuccess = GNLookupAccountName(NULL, lpszAccountName,
+ pUserSID, &cbUserSID, szDomain, &cbDomain, &snuType);
+
+ /* API should have failed with insufficient buffer. */
+ if (fAPISuccess)
+ goto end;
+ else if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) {
+ goto end;
+ }
+
+ pUserSID = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, cbUserSID);
+ if (!pUserSID) {
+ goto end;
+ }
+
+ szDomain = (TCHAR *) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
cbDomain * sizeof(TCHAR));
+ if (!szDomain) {
+ goto end;
+ }
+
+ fAPISuccess = GNLookupAccountName(NULL, lpszAccountName,
+ pUserSID, &cbUserSID, szDomain, &cbDomain, &snuType);
+ if (!fAPISuccess) {
+ goto end;
+ }
+
+ /**
+ * STEP 2: Get security descriptor (SD) of the file specified.
+ */
+ fAPISuccess = GNGetFileSecurity(lpszFileName,
+ secInfo, pFileSD, 0, &cbFileSD);
+
+ /* API should have failed with insufficient buffer. */
+ if (fAPISuccess)
+ goto end;
+ else if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) {
+ goto end;
+ }
+
+ pFileSD = (PSECURITY_DESCRIPTOR) HeapAlloc(GetProcessHeap(),
HEAP_ZERO_MEMORY,
+ cbFileSD);
+ if (!pFileSD) {
+ goto end;
+ }
+
+ fAPISuccess = GNGetFileSecurity(lpszFileName,
+ secInfo, pFileSD, cbFileSD, &cbFileSD);
+ if (!fAPISuccess) {
+ goto end;
+ }
+
+ /**
+ * STEP 3: Initialize new SD.
+ */
+ if (!GNInitializeSecurityDescriptor(&newSD,
+ SECURITY_DESCRIPTOR_REVISION)) {
+ goto end;
+ }
+
+ /**
+ * STEP 4: Get DACL from the old SD.
+ */
+ if (!GNGetSecurityDescriptorDacl(pFileSD, &fDaclPresent, &pACL,
+ &fDaclDefaulted)) {
+ goto end;
+ }
+
+ /**
+ * STEP 5: Get size information for DACL.
+ */
+ AclInfo.AceCount = 0; // Assume NULL DACL.
+ AclInfo.AclBytesFree = 0;
+ AclInfo.AclBytesInUse = sizeof(ACL);
+
+ if (pACL == NULL)
+ fDaclPresent = FALSE;
+
+ /* If not NULL DACL, gather size information from DACL. */
+ if (fDaclPresent) {
+
+ if (!GNGetAclInformation(pACL, &AclInfo,
+ sizeof(ACL_SIZE_INFORMATION), AclSizeInformation)) {
+ goto end;
+ }
+ }
+
+ /**
+ * STEP 6: Compute size needed for the new ACL.
+ */
+ cbNewACL = AclInfo.AclBytesInUse + sizeof(ACCESS_ALLOWED_ACE)
+ + GetLengthSid(pUserSID) - sizeof(DWORD);
+
+ /**
+ * STEP 7: Allocate memory for new ACL.
+ */
+ pNewACL = (PACL) HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY,
cbNewACL);
+ if (!pNewACL) {
+ goto end;
+ }
+
+ /**
+ * STEP 8: Initialize the new ACL.
+ */
+ if (!GNInitializeAcl(pNewACL, cbNewACL, ACL_REVISION2)) {
+ goto end;
+ }
+
+ /**
+ * STEP 9 If DACL is present, copy all the ACEs from the old DACL
+ * to the new DACL.
+ *
+ * The following code assumes that the old DACL is
+ * already in Windows 2000 preferred order. To conform
+ * to the new Windows 2000 preferred order, first we will
+ * copy all non-inherited ACEs from the old DACL to the
+ * new DACL, irrespective of the ACE type.
+ */
+
+ newAceIndex = 0;
+
+ if (fDaclPresent && AclInfo.AceCount) {
+
+ for (CurrentAceIndex = 0;
+ CurrentAceIndex < AclInfo.AceCount;
+ CurrentAceIndex++) {
+
+ /**
+ * TEP 10: Get an ACE.
+ */
+ if (!GNGetAce(pACL, CurrentAceIndex, &pTempAce)) {
+ goto end;
+ }
+
+ /**
+ * STEP 11: Check if it is a non-inherited ACE.
+ * If it is an inherited ACE, break from the loop so
+ * that the new access allowed non-inherited ACE can
+ * be added in the correct position, immediately after
+ * all non-inherited ACEs.
+ */
+ if (((ACCESS_ALLOWED_ACE *)pTempAce)->Header.AceFlags
+ & INHERITED_ACE)
+ break;
+
+ /**
+ * STEP 12: Skip adding the ACE, if the SID matches
+ * with the account specified, as we are going to
+ * add an access allowed ACE with a different access
+ * mask.
+ */
+ if (GNEqualSid(pUserSID,
+ &(((ACCESS_ALLOWED_ACE *)pTempAce)->SidStart)))
+ continue;
+
+ /**
+ * STEP 13: Add the ACE to the new ACL.
+ */
+ if (!GNAddAce(pNewACL, ACL_REVISION, MAXDWORD, pTempAce,
+ ((PACE_HEADER) pTempAce)->AceSize)) {
+ goto end;
+ }
+
+ newAceIndex++;
+ }
+ }
+
+ /**
+ * STEP 14: Add the access-allowed ACE to the new DACL.
+ * The new ACE added here will be in the correct position,
+ * immediately after all existing non-inherited ACEs.
+ */
+ if (!GNAddAccessAllowedAce(pNewACL, ACL_REVISION2, dwAccessMask,
+ pUserSID)) {
+ goto end;
+ }
+
+ /**
+ * STEP 14.5: Make new ACE inheritable
+ */
+ if (!GetAce(pNewACL, newAceIndex, &pTempAce))
+ goto end;
+ ((ACCESS_ALLOWED_ACE *)pTempAce)->Header.AceFlags |=
+ (CONTAINER_INHERIT_ACE | OBJECT_INHERIT_ACE);
+
+ /**
+ * STEP 15: To conform to the new Windows 2000 preferred order,
+ * we will now copy the rest of inherited ACEs from the
+ * old DACL to the new DACL.
+ */
+ if (fDaclPresent && AclInfo.AceCount) {
+
+ for (;
+ CurrentAceIndex < AclInfo.AceCount;
+ CurrentAceIndex++) {
+
+ /**
+ * STEP 16: Get an ACE.
+ */
+ if (!GNGetAce(pACL, CurrentAceIndex, &pTempAce)) {
+ goto end;
+ }
+
+ /**
+ * STEP 17: Add the ACE to the new ACL.
+ */
+ if (!GNAddAce(pNewACL, ACL_REVISION, MAXDWORD, pTempAce,
+ ((PACE_HEADER) pTempAce)->AceSize)) {
+ goto end;
+ }
+ }
+ }
+
+ /**
+ * STEP 18: Set permissions
+ */
+ if (GNSetNamedSecurityInfo(lpszFileName, SE_FILE_OBJECT,
+ DACL_SECURITY_INFORMATION, NULL, NULL, pNewACL, NULL) != ERROR_SUCCESS)
{
+ goto end;
+ }
+
+ fResult = TRUE;
+
+end:
+
+ /**
+ * STEP 19: Free allocated memory
+ */
+ if (pUserSID)
+ HeapFree(GetProcessHeap(), 0, pUserSID);
+
+ if (szDomain)
+ HeapFree(GetProcessHeap(), 0, szDomain);
+
+ if (pFileSD)
+ HeapFree(GetProcessHeap(), 0, pFileSD);
+
+ if (pNewACL)
+ HeapFree(GetProcessHeap(), 0, pNewACL);
+
+ return fResult;
+}
+
char *winErrorStr(char *prefix, DWORD dwErr)
{
char *err, *ret;
+ int mem;
- FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM,
+ if (! FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM,
NULL, dwErr, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR) &err,
- 0, NULL );
+ 0, NULL ))
+ {
+ err = "";
+ }
- ret = (char *) malloc(strlen(err) + strlen(prefix) + 20);
+ mem = strlen(err) + strlen(prefix) + 20;
+ ret = (char *) malloc(mem);
- sprintf(ret, "%s: %s (#%u)", prefix, err, dwErr);
+ snprintf(ret, mem, "%s: %s (#%u)", prefix, err, dwErr);
LocalFree(err);
Modified: GNUnet/src/util/win/winproc.c
===================================================================
--- GNUnet/src/util/win/winproc.c 2005-06-11 09:11:14 UTC (rev 896)
+++ GNUnet/src/util/win/winproc.c 2005-06-12 10:44:17 UTC (rev 897)
@@ -54,6 +54,16 @@
TLsaRemoveAccountRights GNLsaRemoveAccountRights;
TLsaClose GNLsaClose;
TLookupAccountName GNLookupAccountName;
+TGetFileSecurity GNGetFileSecurity;
+TInitializeSecurityDescriptor GNInitializeSecurityDescriptor;
+TGetSecurityDescriptorDacl GNGetSecurityDescriptorDacl;
+TGetAclInformation GNGetAclInformation;
+TInitializeAcl GNInitializeAcl;
+TGetAce GNGetAce;
+TEqualSid GNEqualSid;
+TAddAce GNAddAce;
+TAddAccessAllowedAce GNAddAccessAllowedAce;
+TSetNamedSecurityInfo GNSetNamedSecurityInfo;
/**
* Log (panic) messages from PlibC
@@ -139,6 +149,27 @@
GetProcAddress(hAdvapi, "LsaClose");
GNLookupAccountName = (TLookupAccountName)
GetProcAddress(hAdvapi, "LookupAccountNameA");
+
+ GNGetFileSecurity = (TGetFileSecurity)
+ GetProcAddress(hAdvapi, "GetFileSecurityA");
+ GNInitializeSecurityDescriptor = (TInitializeSecurityDescriptor)
+ GetProcAddress(hAdvapi, "InitializeSecurityDescriptor");
+ GNGetSecurityDescriptorDacl = (TGetSecurityDescriptorDacl)
+ GetProcAddress(hAdvapi, "GetSecurityDescriptorDacl");
+ GNGetAclInformation = (TGetAclInformation)
+ GetProcAddress(hAdvapi, "GetAclInformation");
+ GNInitializeAcl = (TInitializeAcl)
+ GetProcAddress(hAdvapi, "InitializeAcl");
+ GNGetAce = (TGetAce)
+ GetProcAddress(hAdvapi, "GetAce");
+ GNEqualSid = (TEqualSid)
+ GetProcAddress(hAdvapi, "EqualSid");
+ GNAddAce = (TAddAce)
+ GetProcAddress(hAdvapi, "AddAce");
+ GNAddAccessAllowedAce = (TAddAccessAllowedAce)
+ GetProcAddress(hAdvapi, "AddAccessAllowedAce");
+ GNSetNamedSecurityInfo = (TSetNamedSecurityInfo)
+ GetProcAddress(hAdvapi, "SetNamedSecurityInfoA");
}
else
{
@@ -157,6 +188,17 @@
GNLsaRemoveAccountRights = NULL;
GNLsaClose = NULL;
GNLookupAccountName = NULL;
+
+ GNGetFileSecurity = NULL;
+ GNInitializeSecurityDescriptor = NULL;
+ GNGetSecurityDescriptorDacl = NULL;
+ GNGetAclInformation = NULL;
+ GNInitializeAcl = NULL;
+ GNGetAce = NULL;
+ GNEqualSid = NULL;
+ GNAddAce = NULL;
+ GNAddAccessAllowedAce = NULL;
+ GNSetNamedSecurityInfo = NULL;
}
/* Account function */
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- [GNUnet-SVN] r897 - in GNUnet/src: conf include util/win,
durner <=