gnunet-svn
[Top][All Lists]
Advanced

[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 */





reply via email to

[Prev in Thread] Current Thread [Next in Thread]