From 48fba74eb7519f190900c3aa4e5b1d02638d919a Mon Sep 17 00:00:00 2001 From: Jeffrey Altman Date: Mon, 23 Aug 2004 16:55:02 +0000 Subject: [PATCH] STABLE14-windows-admin-group-20040823 Update text files for 1.3.71 and describe the new Windows Authorization Group "AFS Client Admins" ==================== This delta was composed from multiple commits as part of the CVS->Git migration. The checkin message with each commit was inconsistent. The following are the additional commit messages. ==================== Add support for "AFS Client Admins" windows authortization group (cherry picked from commit 40d2f5f7c02e28cf471d284e5be9fb97c91d145a) --- doc/txt/winnotes/afs-changes-since-1.2.txt | 10 ++ doc/txt/winnotes/afs-install-notes.txt | 20 ++- doc/txt/winnotes/afs-issues.txt | 24 ++- src/WINNT/afsd/fs.c | 157 ++++++++++++------- src/WINNT/client_config/isadmin.cpp | 136 ++++++++++------ src/WINNT/install/NSIS/AdminGroup.cpp | 89 +++++++++++ src/WINNT/install/NSIS/NTMakefile | 8 +- src/WINNT/install/NSIS/OpenAFS.nsi | 10 +- src/WINNT/install/wix/custom/NTMakefile | 6 +- src/WINNT/install/wix/custom/afscustom.cpp | 68 ++++++++ src/WINNT/install/wix/custom/afscustom.h | 8 + src/WINNT/install/wix/lang/en_US/strings.wxl | 2 + src/WINNT/install/wix/lang/en_US/ui.wxi | 2 + src/WINNT/install/wix/openafs.wxs | 21 +++ src/config/NTMakefile.i386_nt40 | 8 +- 15 files changed, 438 insertions(+), 131 deletions(-) create mode 100644 src/WINNT/install/NSIS/AdminGroup.cpp diff --git a/doc/txt/winnotes/afs-changes-since-1.2.txt b/doc/txt/winnotes/afs-changes-since-1.2.txt index e11c196865..82c39b9721 100644 --- a/doc/txt/winnotes/afs-changes-since-1.2.txt +++ b/doc/txt/winnotes/afs-changes-since-1.2.txt @@ -1,4 +1,14 @@ Since 1.3.70: + * A new Windows authorization group "AFS Client Admins" is now + created and populated with the members of the "Administrators" + group. The group is used to determine which accounts on the + machine may be used to modify the AFS Client Configuration via + the UI and command line tools. afs_config.exe, fs.exe, + + * Modify the WinLogon Logoff Event Handler to query NT4 domain + controllers for the remote profile path if Active Directory + services are not available. + * Fix aklog.exe to not add the AFS ID to the username * PTS registration of new users to foreign cells has been added to diff --git a/doc/txt/winnotes/afs-install-notes.txt b/doc/txt/winnotes/afs-install-notes.txt index 92dac51595..9265625e53 100644 --- a/doc/txt/winnotes/afs-install-notes.txt +++ b/doc/txt/winnotes/afs-install-notes.txt @@ -1,4 +1,4 @@ -OpenAFS for Windows 1.3.70 Installation Notes +OpenAFS for Windows 1.3.71 Installation Notes --------------------------------------------- The OpenAFS for Windows product was very poorly maintained throughout the @@ -97,7 +97,7 @@ discover cell information when it is not located in the local CellServDB file (\Program Files\OpenAFS\Client\CellServDB). -5. OpenAFS for Windows 1.3.70 only supports Windows 2000, Windows XP, and +5. OpenAFS for Windows 1.3.71 only supports Windows 2000, Windows XP, and Windows 2003. Windows NT 4.0 and the entire Windows 9x/Me line are no longer supported. Older releases of OpenAFS are available for download if those operating systems must be supported. The last version with support @@ -216,9 +216,9 @@ Usage: aklog [-d] [[-cell | -c] cell [-k krb_realm]] No commandline arguments means authenticate to the local cell. -11. The AFS Server functionality provided with OpenAFS 1.3.70 might work but +11. The AFS Server functionality provided with OpenAFS 1.3.71 might work but should be considered highly experimental. It has not been thoroughly tested. -Any data which would cause pain if lost should be stored in an OpenAFS +Any data which would cause pain if lost should not be stored in an OpenAFS Server on Windows. A few notes on the usage of the AFS Client Service if it is going to be @@ -265,7 +265,7 @@ encrypted data transfer between the AFS client and the AFS servers. This is often referred to as "fcrypt" mode. -18. OpenAFS 1.3.70 adds support for authenticated SMB connections using +18. OpenAFS 1.3.71 adds support for authenticated SMB connections using either NTLM or GSS SPNEGO (NTLM, Kerberos 5, ...). In previous versions of OpenAFS the SMB connections were unauthenticated which left open the door for several security holes which could be used to obtain access to @@ -337,11 +337,21 @@ When installing under Terminal Server, you must execute the NSIS installer will result in AFS not running properly. The AFS Server should not be installed on a machine with Terminal Server installed. + 24. AFS is a Unix native file system. As such the OpenAFS client attempts to treat the files stored in AFS as they would be on Unix. File and directory names beginning with a "." are automatically given the Hidden attribute so they will not normally be displayed. + +25. As of 1.3.71, the OpenAFS for Windows client supports a local Windows +authorization group called "AFS Client Admins". This group is used in +place of the "Administrators" group to determine which users are allowed +to modify the AFS Client Service configuration via either afs_config.exe +or fs.exe. During installation this group is created and the current +contents of the Administrators group is copied. + + ------------------------------------------------------------------------ Reporting Bugs: diff --git a/doc/txt/winnotes/afs-issues.txt b/doc/txt/winnotes/afs-issues.txt index c640aba056..741e748bc9 100644 --- a/doc/txt/winnotes/afs-issues.txt +++ b/doc/txt/winnotes/afs-issues.txt @@ -175,26 +175,24 @@ List of unfunded projects: 12. miscellaneous 13. need to add support for all of the new registry values since 1.2.8 11. Identify why 16-bit DOS applications executed out of AFS fail - 12. Create new Windows Security Group to which users can be added for them to become AFS - Client Administrators - 13. Add support for configurable Icon file representing AFS folders within the Explorer Shell - 14. Documentation Documentation Documentation - 15. Large File support (> 2GB) - 16. Integrate KFW installation into the NSIS installer - 17. Add support for record locking to AFS (requires changes to the servers) - 18. Unicode enable the SMB/CIFS server. OEM Code Pages: + 12. Add support for configurable Icon file representing AFS folders within the Explorer Shell + 13. Documentation Documentation Documentation + 14. Large File support (> 2GB) + 15. Integrate KFW installation into the NSIS installer + 16. Add support for record locking to AFS (requires changes to the servers) + 17. Unicode enable the SMB/CIFS server. OEM Code Pages: 1. prevent the use of interoperable file names 2. force the use of paths no longer than 256 characters 3. force share names to be no longer than 13 characters 4. restrict authentication to ASCII only names and passwords - 19. Complete implementation of CIFS Remote Administration Protocol - 20. Correct the problems with overlapped writes which adversely affect + 18. Complete implementation of CIFS Remote Administration Protocol + 19. Correct the problems with overlapped writes which adversely affect Microsoft Office applications storing documents and temporary files within AFS volumes - 21. Add support for SMB/CIFS Digital Signatures - 22. Development of afsmap.exe tool to provide AFS aware NET USE functionality + 20. Add support for SMB/CIFS Digital Signatures + 21. Development of afsmap.exe tool to provide AFS aware NET USE functionality afsmap.exe [/PERSISTENT] afsmap.exe [/PERSISTENT] afsmap.exe /DELETE - 23. Write-through caching appears to be unsupported. Files copied to AFS + 22. Write-through caching appears to be unsupported. Files copied to AFS do not end up in the local cache. diff --git a/src/WINNT/afsd/fs.c b/src/WINNT/afsd/fs.c index ac32533db3..5e960c56a1 100644 --- a/src/WINNT/afsd/fs.c +++ b/src/WINNT/afsd/fs.c @@ -583,6 +583,8 @@ char *AclToString(acl) return mydata; } +#define AFSCLIENT_ADMIN_GROUPNAME "AFS Client Admins" + BOOL IsAdmin (void) { static BOOL fAdmin = FALSE; @@ -590,20 +592,54 @@ BOOL IsAdmin (void) if (!fTested) { - /* Obtain the SID for BUILTIN\Administrators. If this is Windows NT, - * expect this call to succeed; if it does not, we can presume that - * it's not NT and therefore the user always has administrative - * privileges. + /* Obtain the SID for the AFS client admin group. If the group does + * not exist, then assume we have AFS client admin privileges. */ PSID psidAdmin = NULL; - SID_IDENTIFIER_AUTHORITY auth = SECURITY_NT_AUTHORITY; + DWORD dwSize, dwSize2; + char pszAdminGroup[ MAX_COMPUTERNAME_LENGTH + sizeof(AFSCLIENT_ADMIN_GROUPNAME) + 2 ]; + char *pszRefDomain = NULL; + SID_NAME_USE snu = SidTypeGroup; + + dwSize = sizeof(pszAdminGroup); + + if (!GetComputerName(pszAdminGroup, &dwSize)) { + /* Can't get computer name. We return false in this case. + Retain fAdmin and fTested. This shouldn't happen.*/ + return FALSE; + } fTested = TRUE; - if (!AllocateAndInitializeSid (&auth, 2, SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_ADMINS, 0, 0, 0, 0, 0, 0, &psidAdmin)) + dwSize = 0; + dwSize2 = 0; + + strcat(pszAdminGroup,"\\"); + strcat(pszAdminGroup, AFSCLIENT_ADMIN_GROUPNAME); + + LookupAccountName(NULL, pszAdminGroup, NULL, &dwSize, NULL, &dwSize2, &snu); + /* that should always fail. */ + + if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) { + /* if we can't find the group, then we allow the operation */ fAdmin = TRUE; - else - { + return TRUE; + } + + if (dwSize == 0 || dwSize2 == 0) { + /* Paranoia */ + fAdmin = TRUE; + return TRUE; + } + + psidAdmin = (PSID)malloc(dwSize); memset(psidAdmin,0,dwSize); + pszRefDomain = (char *)malloc(dwSize2); + + if (!LookupAccountName(NULL, pszAdminGroup, psidAdmin, &dwSize, pszRefDomain, &dwSize2, &snu)) { + /* We can't lookup the group now even though we looked it up earlier. + Could this happen? */ + fAdmin = TRUE; + } else { /* Then open our current ProcessToken */ HANDLE hToken; @@ -624,13 +660,14 @@ BOOL IsAdmin (void) if (GetTokenInformation (hToken, TokenGroups, pGroups, dwSize, &dwSize)) { /* Look through the list of group SIDs and see if any of them - * matches the Administrator group SID. + * matches the AFS Client Admin group SID. */ size_t iGroup = 0; for (; (!fAdmin) && (iGroup < pGroups->GroupCount); ++iGroup) { - if (EqualSid (psidAdmin, pGroups->Groups[ iGroup ].Sid)) + if (EqualSid (psidAdmin, pGroups->Groups[ iGroup ].Sid)) { fAdmin = TRUE; + } } } @@ -639,8 +676,8 @@ BOOL IsAdmin (void) } } - if (psidAdmin) - FreeSid (psidAdmin); + free(psidAdmin); + free(pszRefDomain); } return fAdmin; @@ -1657,7 +1694,7 @@ register struct cmd_syndesc *as; { if ( checkserv.tinterval != 0 ) { #ifdef WIN32 if ( !IsAdmin() ) { - fprintf (stderr,"Permission denied: requires Administrator access.\n"); + fprintf (stderr,"Permission denied: requires AFS Client Administrator access.\n"); return EACCES; } #else /* WIN32 */ @@ -1769,7 +1806,7 @@ register struct cmd_syndesc *as; { #ifdef WIN32 if ( !IsAdmin() ) { - fprintf (stderr,"Permission denied: requires Administrator access.\n"); + fprintf (stderr,"Permission denied: requires AFS Client Administrator access.\n"); return EACCES; } #else /* WIN32 */ @@ -1883,7 +1920,7 @@ register struct cmd_syndesc *as; { #ifdef WIN32 if ( !IsAdmin() ) { - fprintf (stderr,"Permission denied: requires Administrator access.\n"); + fprintf (stderr,"Permission denied: requires AFS Client Administrator access.\n"); return EACCES; } #else /* WIN32 */ @@ -2104,7 +2141,7 @@ register struct cmd_syndesc *as; { if (ti) { #ifdef WIN32 if ( !IsAdmin() ) { - fprintf (stderr,"Permission denied: requires Administrator access.\n"); + fprintf (stderr,"Permission denied: requires AFS Client Administrator access.\n"); return EACCES; } #else /* WIN32 */ @@ -2171,7 +2208,7 @@ register struct cmd_syndesc *as; { #ifdef WIN32 if ( !IsAdmin() ) { - fprintf (stderr,"Permission denied: requires Administrator access.\n"); + fprintf (stderr,"Permission denied: requires AFS Client Administrator access.\n"); return EACCES; } #else /* WIN32 */ @@ -2311,7 +2348,7 @@ register struct cmd_syndesc *as; { #ifdef WIN32 if ( !IsAdmin() ) { - fprintf (stderr,"Permission denied: requires Administrator access.\n"); + fprintf (stderr,"Permission denied: requires AFS Client Administrator access.\n"); return EACCES; } #else /* WIN32 */ @@ -2567,7 +2604,7 @@ register struct cmd_syndesc *as; { #ifdef WIN32 if ( !IsAdmin() ) { - fprintf (stderr,"Permission denied: requires Administrator access.\n"); + fprintf (stderr,"Permission denied: requires AFS Client Administrator access.\n"); return EACCES; } #else /* WIN32 */ @@ -2724,7 +2761,7 @@ static TraceCmd(struct cmd_syndesc *asp) #ifdef WIN32 if ( !IsAdmin() ) { - fprintf (stderr,"Permission denied: requires Administrator access.\n"); + fprintf (stderr,"Permission denied: requires AFS Client Administrator access.\n"); return EACCES; } #else /* WIN32 */ @@ -2780,7 +2817,7 @@ struct cmd_syndesc *as; { #ifdef WIN32 if ( !IsAdmin() ) { - fprintf (stderr,"Permission denied: requires Administrator access.\n"); + fprintf (stderr,"Permission denied: requires AFS Client Administrator access.\n"); return EACCES; } #else /* WIN32 */ @@ -2845,7 +2882,7 @@ static afs_int32 SetCryptCmd(as) #ifdef WIN32 if ( !IsAdmin() ) { - fprintf (stderr,"Permission denied: requires Administrator access.\n"); + fprintf (stderr,"Permission denied: requires AFS Client Administrator access.\n"); return EACCES; } #else /* WIN32 */ @@ -3239,20 +3276,20 @@ static MemDumpCmd(struct cmd_syndesc *asp) static CSCPolicyCmd(struct cmd_syndesc *asp) { - struct cmd_item *ti; - char *share = NULL; + struct cmd_item *ti; + char *share = NULL; HKEY hkCSCPolicy; - for(ti=asp->parms[0].items; ti;ti=ti->next) { - share = ti->data; - if (share) - { - break; - } - } + for(ti=asp->parms[0].items; ti;ti=ti->next) { + share = ti->data; + if (share) + { + break; + } + } - if (share) - { + if (share) + { char *policy; RegCreateKeyEx( HKEY_LOCAL_MACHINE, @@ -3265,40 +3302,44 @@ static CSCPolicyCmd(struct cmd_syndesc *asp) &hkCSCPolicy, NULL ); - if ( !IsAdmin() || hkCSCPolicy == NULL ) { + if ( hkCSCPolicy == NULL ) { fprintf (stderr,"Permission denied: requires Administrator access.\n"); - if ( hkCSCPolicy ) - RegCloseKey(hkCSCPolicy); + return EACCES; + } + + if ( !IsAdmin() ) { + fprintf (stderr,"Permission denied: requires AFS Client Administrator access.\n"); + RegCloseKey(hkCSCPolicy); return EACCES; } policy = "manual"; - if (asp->parms[1].items) - policy = "manual"; - if (asp->parms[2].items) - policy = "programs"; - if (asp->parms[3].items) - policy = "documents"; - if (asp->parms[4].items) - policy = "disable"; + if (asp->parms[1].items) + policy = "manual"; + if (asp->parms[2].items) + policy = "programs"; + if (asp->parms[3].items) + policy = "documents"; + if (asp->parms[4].items) + policy = "disable"; RegSetValueEx( hkCSCPolicy, share, 0, REG_SZ, policy, strlen(policy)+1); - printf("CSC policy on share \"%s\" changed to \"%s\".\n\n", share, policy); - printf("Close all applications that accessed files on this share or restart AFS Client for the change to take effect.\n"); - } - else - { + printf("CSC policy on share \"%s\" changed to \"%s\".\n\n", share, policy); + printf("Close all applications that accessed files on this share or restart AFS Client for the change to take effect.\n"); + } + else + { DWORD dwIndex, dwPolicies; - char policyName[256]; - DWORD policyNameLen; + char policyName[256]; + DWORD policyNameLen; char policy[256]; DWORD policyLen; DWORD dwType; - /* list current csc policies */ - + /* list current csc policies */ + RegCreateKeyEx( HKEY_LOCAL_MACHINE, "SOFTWARE\\OpenAFS\\Client\\CSCPolicy", 0, @@ -3323,7 +3364,7 @@ static CSCPolicyCmd(struct cmd_syndesc *asp) NULL /* lpftLastWriteTime */ ); - printf("Current CSC policies:\n"); + printf("Current CSC policies:\n"); for ( dwIndex = 0; dwIndex < dwPolicies; dwIndex ++ ) { policyNameLen = sizeof(policyName); @@ -3331,10 +3372,10 @@ static CSCPolicyCmd(struct cmd_syndesc *asp) RegEnumValue( hkCSCPolicy, dwIndex, policyName, &policyNameLen, NULL, &dwType, policy, &policyLen); - printf(" %s = %s\n", policyName, policy); - } - } + printf(" %s = %s\n", policyName, policy); + } + } RegCloseKey(hkCSCPolicy); - return (0); + return (0); } diff --git a/src/WINNT/client_config/isadmin.cpp b/src/WINNT/client_config/isadmin.cpp index c2c1aca538..2013b7b9ca 100644 --- a/src/WINNT/client_config/isadmin.cpp +++ b/src/WINNT/client_config/isadmin.cpp @@ -50,63 +50,103 @@ BOOL IsWindowsNT (void) * */ +#define AFSCLIENT_ADMIN_GROUPNAME "AFS Client Admins" + BOOL IsAdmin (void) { - static BOOL fAdmin = FALSE; - static BOOL fTested = FALSE; - if (!fTested) - { - fTested = TRUE; + static BOOL fAdmin = FALSE; + static BOOL fTested = FALSE; - // Obtain the SID for BUILTIN\Administrators. If this is Windows NT, - // expect this call to succeed; if it does not, we can presume that - // it's not NT and therefore the user always has administrative - // privileges. - // - PSID psidAdmin = NULL; - SID_IDENTIFIER_AUTHORITY auth = SECURITY_NT_AUTHORITY; - if (!AllocateAndInitializeSid (&auth, 2, SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_ADMINS, 0, 0, 0, 0, 0, 0, &psidAdmin)) - fAdmin = TRUE; - else - { + if (!fTested) + { + /* Obtain the SID for the AFS client admin group. If the group does + * not exist, then assume we have AFS client admin privileges. + */ + PSID psidAdmin = NULL; + DWORD dwSize, dwSize2; + char pszAdminGroup[ MAX_COMPUTERNAME_LENGTH + sizeof(AFSCLIENT_ADMIN_GROUPNAME) + 2 ]; + char *pszRefDomain = NULL; + SID_NAME_USE snu = SidTypeGroup; - // Then open our current ProcessToken - // - HANDLE hToken; - if (OpenProcessToken (GetCurrentProcess(), TOKEN_QUERY, &hToken)) + dwSize = sizeof(pszAdminGroup); + + if (!GetComputerName(pszAdminGroup, &dwSize)) { + /* Can't get computer name. We return false in this case. + Retain fAdmin and fTested. This shouldn't happen.*/ + return FALSE; + } + + fTested = TRUE; + + dwSize = 0; + dwSize2 = 0; + + strcat(pszAdminGroup,"\\"); + strcat(pszAdminGroup, AFSCLIENT_ADMIN_GROUPNAME); + + LookupAccountName(NULL, pszAdminGroup, NULL, &dwSize, NULL, &dwSize2, &snu); + /* that should always fail. */ + + if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) { + /* if we can't find the group, then we allow the operation */ + fAdmin = TRUE; + return TRUE; + } + + if (dwSize == 0 || dwSize2 == 0) { + /* Paranoia */ + fAdmin = TRUE; + return TRUE; + } + + psidAdmin = (PSID) malloc(dwSize); memset(psidAdmin,0,dwSize); + pszRefDomain = (char *)malloc(dwSize2); + + if (!LookupAccountName(NULL, pszAdminGroup, psidAdmin, &dwSize, pszRefDomain, &dwSize2, &snu)) { + /* We can't lookup the group now even though we looked it up earlier. + Could this happen? */ + fAdmin = TRUE; + } else { + /* Then open our current ProcessToken */ + HANDLE hToken; + + if (OpenProcessToken (GetCurrentProcess(), TOKEN_QUERY, &hToken)) { - - // We'll have to allocate a chunk of memory to store the list of - // groups to which this user belongs; find out how much memory - // we'll need. - // - DWORD dwSize = 0; - GetTokenInformation (hToken, TokenGroups, NULL, dwSize, &dwSize); + /* We'll have to allocate a chunk of memory to store the list of + * groups to which this user belongs; find out how much memory + * we'll need. + */ + DWORD dwSize = 0; + PTOKEN_GROUPS pGroups; + + GetTokenInformation (hToken, TokenGroups, NULL, dwSize, &dwSize); - // Allocate that buffer, and read in the list of groups. - // - PTOKEN_GROUPS pGroups = (PTOKEN_GROUPS)Allocate (dwSize); - if (GetTokenInformation (hToken, TokenGroups, pGroups, dwSize, &dwSize)) - { - // Look through the list of group SIDs and see if any of them - // matches the Administrator group SID. - // - for (size_t iGroup = 0; (!fAdmin) && (iGroup < pGroups->GroupCount); ++iGroup) - { - if (EqualSid (psidAdmin, pGroups->Groups[ iGroup ].Sid)) - fAdmin = TRUE; - } - } + pGroups = (PTOKEN_GROUPS)malloc(dwSize); + + /* Allocate that buffer, and read in the list of groups. */ + if (GetTokenInformation (hToken, TokenGroups, pGroups, dwSize, &dwSize)) + { + /* Look through the list of group SIDs and see if any of them + * matches the AFS Client Admin group SID. + */ + size_t iGroup = 0; + for (; (!fAdmin) && (iGroup < pGroups->GroupCount); ++iGroup) + { + if (EqualSid (psidAdmin, pGroups->Groups[ iGroup ].Sid)) { + fAdmin = TRUE; + } + } + } - if (pGroups) - Free (pGroups); + if (pGroups) + free(pGroups); } - } + } - if (psidAdmin) - FreeSid (psidAdmin); - } + free(psidAdmin); + free(pszRefDomain); + } - return fAdmin; + return fAdmin; } diff --git a/src/WINNT/install/NSIS/AdminGroup.cpp b/src/WINNT/install/NSIS/AdminGroup.cpp new file mode 100644 index 0000000000..e3adcacceb --- /dev/null +++ b/src/WINNT/install/NSIS/AdminGroup.cpp @@ -0,0 +1,89 @@ +#include +#include +#include +#include + +#pragma comment(lib,"netapi32.lib") + +#define AFSCLIENT_ADMIN_GROUPNAMEW L"AFS Client Admins" +#define AFSCLIENT_ADMIN_COMMENTW L"AFS Client Administrators" + +UINT createAfsAdminGroup(void) { + LOCALGROUP_INFO_1 gInfo; + DWORD dwError; + NET_API_STATUS status; + + gInfo.lgrpi1_name = AFSCLIENT_ADMIN_GROUPNAMEW; + gInfo.lgrpi1_comment = AFSCLIENT_ADMIN_COMMENTW; + status = NetLocalGroupAdd(NULL, 1, (LPBYTE) &gInfo, &dwError); + + return status; +} + +UINT initializeAfsAdminGroup(void) { + PSID psidAdmin = NULL; + SID_IDENTIFIER_AUTHORITY auth = SECURITY_NT_AUTHORITY; + NET_API_STATUS status; + LOCALGROUP_MEMBERS_INFO_0 *gmAdmins = NULL; + DWORD dwNEntries, dwTEntries; + + status = NetLocalGroupGetMembers(NULL, L"Administrators", 0, (LPBYTE *) &gmAdmins, MAX_PREFERRED_LENGTH, &dwNEntries, &dwTEntries, NULL); + if(status) + return status; + + status = NetLocalGroupAddMembers(NULL, AFSCLIENT_ADMIN_GROUPNAMEW, 0, (LPBYTE) gmAdmins, dwNEntries); + + NetApiBufferFree( gmAdmins ); + + return status; +} + +UINT removeAfsAdminGroup(void) { + NET_API_STATUS status; + status = NetLocalGroupDel(NULL, AFSCLIENT_ADMIN_GROUPNAMEW); + return status; +} + +void showUsage(char * progname) { + printf( + "Usage: %s [-create | -remove]\n" + " -create : Create AFS Client Admins group and populate it with\n" + " the members of the Administrators group\n" + " -remove : Remove the AFS Client Admins group\n" + , progname); +} + +int main(int argc, char ** argv) { + + UINT rv = 0; + + if(argc < 2) { + showUsage(argv[0]); + return 1; + } + + if(stricmp(argv[1], "-create")) { + rv = createAfsAdminGroup(); + if(rv) { + if(rv != ERROR_ALIAS_EXISTS) { + fprintf(stderr, "%s: Can't create AFS Client Admin group. NetApi error %u\n", rv); + } else { + /* The group already exists. (Preserved config from a + prior install). */ + rv = 0; + } + } else { + rv = initializeAfsAdminGroup(); + if(rv) + fprintf(stderr, "%s: Can't populate AFS Client Admin group. NetApi error %u\n", rv); + } + } else if(stricmp(argv[1], "-remove")) { + removeAfsAdminGroup(); + rv = 0; + } else { + showUsage(argv[0]); + rv = 0; + } + + return rv; +} \ No newline at end of file diff --git a/src/WINNT/install/NSIS/NTMakefile b/src/WINNT/install/NSIS/NTMakefile index b90525f31f..69a67918f4 100644 --- a/src/WINNT/install/NSIS/NTMakefile +++ b/src/WINNT/install/NSIS/NTMakefile @@ -22,6 +22,12 @@ $(OUT)\Killer.obj: Killer.cpp $(EXEDIR)\Killer.exe: $(OUT)\Killer.obj $(EXECONLINK) $(OUT)\Killer.obj +$(OUT)\AdminGroup.obj: AdminGroup.cpp + $(C2OBJ) AdminGroup.cpp + +$(EXEDIR)\AdminGroup.exe: $(OUT)\AdminGroup.obj + $(EXECONLINK) $(OUT)\AdminGroup.obj + prebuild: !IF ("$(AFSDEV_BUILDTYPE)" == "FREE") !IF ("$(AFSVER_CL)"=="1310") @@ -81,7 +87,7 @@ prebuild: build: prebuild "C:\Program Files\NSIS\makensis.exe" /DINCLUDEDIR=$(OUT) OpenAFS.nsi -install: $(OUT)\Service.obj $(EXEDIR)\Service.exe $(OUT)\Killer.obj $(EXEDIR)\Killer.exe build +install: $(OUT)\Service.obj $(EXEDIR)\Service.exe $(OUT)\Killer.obj $(EXEDIR)\Killer.exe $(EXEDIR)\AdminGroup.exe build #clean: # $(DEL) $(OUT)\Service.obj diff --git a/src/WINNT/install/NSIS/OpenAFS.nsi b/src/WINNT/install/NSIS/OpenAFS.nsi index 658a9e68d6..9c53ae3bad 100644 --- a/src/WINNT/install/NSIS/OpenAFS.nsi +++ b/src/WINNT/install/NSIS/OpenAFS.nsi @@ -550,6 +550,10 @@ Section "AFS Client" secClient ; Get AFS CellServDB file Call afs.GetCellServDB + GetTempFileName $R0 + File /oname=$R0 "${AFS_WININSTALL_DIR}\AdminGroup.exe" + nsExec::Exec '$R0 -create' + !ifdef INSTALL_KFW ; Include Kerberos for Windows files in the installer... SetOutPath "$INSTDIR\kfw\bin\" @@ -625,7 +629,7 @@ Section "AFS Client" secClient ReadINIStr $R1 $2 "Field 13" "State" StrCmp $R1 "1" +1 +2 StrCpy $R2 "$R2-S" - + WriteRegStr HKLM "SOFTWARE\OpenAFS\Client" "AfscredsShortcutParams" "$R2" CreateShortCut "$SMPROGRAMS\OpenAFS\Client\Authentication.lnk" "$INSTDIR\Client\Program\afscreds.exe" "$R2" @@ -1699,6 +1703,10 @@ StartRemove: !ENDIF Delete "$INSTDIR\Client\afsdns.ini" + GetTempFileName $R0 + File /oname=$R0 "${AFS_WININSTALL_DIR}\AdminGroup.exe" + nsExec::Exec '$R0 -remove' + SkipDel: Delete "$WINDIR\afsd_init.log" Delete "$INSTDIR\Uninstall.exe" diff --git a/src/WINNT/install/wix/custom/NTMakefile b/src/WINNT/install/wix/custom/NTMakefile index 7c37a0d559..9e80bcc4c6 100644 --- a/src/WINNT/install/wix/custom/NTMakefile +++ b/src/WINNT/install/wix/custom/NTMakefile @@ -14,10 +14,12 @@ DLLEXPORTS=\ -EXPORT:ConfigureClientService \ -EXPORT:ConfigureServerService \ -EXPORT:AbortMsiImmediate \ - -EXPORT:UninstallNsisInstallation + -EXPORT:UninstallNsisInstallation \ + -EXPORT:CreateAFSClientAdminGroup \ + -EXPORT:RemoveAFSClientAdminGroup DLLLIBFILES=\ - msi.lib advapi32.lib + msi.lib advapi32.lib netapi32.lib LINK=link diff --git a/src/WINNT/install/wix/custom/afscustom.cpp b/src/WINNT/install/wix/custom/afscustom.cpp index 88a1f217ea..4a8c9f3db1 100644 --- a/src/WINNT/install/wix/custom/afscustom.cpp +++ b/src/WINNT/install/wix/custom/afscustom.cpp @@ -376,3 +376,71 @@ _cleanup: } return rv; } + +/* Create or remove the 'AFS Client Admins' group. Initially + it will hold members of the Administrator group. */ + +MSIDLLEXPORT CreateAFSClientAdminGroup( MSIHANDLE hInstall ) { + UINT rv; + rv = createAfsAdminGroup(); + if(rv) { + if(rv == ERROR_ALIAS_EXISTS) { + /* The group already exists, probably from a previous + installation. We let things be. */ + return ERROR_SUCCESS; + } + + ShowMsiError( hInstall, ERR_GROUP_CREATE_FAILED, rv ); + return rv; + } + + rv = initializeAfsAdminGroup(); + if(rv) + ShowMsiError( hInstall, ERR_GROUP_MEMBER_FAILED, rv ); + return rv; +} + +MSIDLLEXPORT RemoveAFSClientAdminGroup( MSIHANDLE hInstall ) { + removeAfsAdminGroup(); + return ERROR_SUCCESS; +} + +#define AFSCLIENT_ADMIN_GROUPNAMEW L"AFS Client Admins" +#define AFSCLIENT_ADMIN_COMMENTW L"AFS Client Administrators" + +UINT createAfsAdminGroup(void) { + LOCALGROUP_INFO_1 gInfo; + DWORD dwError; + NET_API_STATUS status; + + gInfo.lgrpi1_name = AFSCLIENT_ADMIN_GROUPNAMEW; + gInfo.lgrpi1_comment = AFSCLIENT_ADMIN_COMMENTW; + status = NetLocalGroupAdd(NULL, 1, (LPBYTE) &gInfo, &dwError); + + return status; +} + +UINT initializeAfsAdminGroup(void) { + PSID psidAdmin = NULL; + SID_IDENTIFIER_AUTHORITY auth = SECURITY_NT_AUTHORITY; + NET_API_STATUS status; + LOCALGROUP_MEMBERS_INFO_0 *gmAdmins = NULL; + DWORD dwNEntries, dwTEntries; + + status = NetLocalGroupGetMembers(NULL, L"Administrators", 0, (LPBYTE *) &gmAdmins, MAX_PREFERRED_LENGTH, &dwNEntries, &dwTEntries, NULL); + if(status) + return status; + + status = NetLocalGroupAddMembers(NULL, AFSCLIENT_ADMIN_GROUPNAMEW, 0, (LPBYTE) gmAdmins, dwNEntries); + + NetApiBufferFree( gmAdmins ); + + return status; +} + +UINT removeAfsAdminGroup(void) { + NET_API_STATUS status; + status = NetLocalGroupDel(NULL, AFSCLIENT_ADMIN_GROUPNAMEW); + return status; +} + diff --git a/src/WINNT/install/wix/custom/afscustom.h b/src/WINNT/install/wix/custom/afscustom.h index b9fb2af894..f8c0d796e2 100644 --- a/src/WINNT/install/wix/custom/afscustom.h +++ b/src/WINNT/install/wix/custom/afscustom.h @@ -38,6 +38,7 @@ SOFTWARE. #include #include #include +#include #define MSIDLLEXPORT UINT __stdcall @@ -63,12 +64,17 @@ SOFTWARE. #define ERR_SCS_FAILED 4003 #define ERR_ABORT 4004 #define ERR_NSS_FAILED 4005 +#define ERR_GROUP_CREATE_FAILED 4006 +#define ERR_GROUP_MEMBER_FAILED 4007 /* non-exported */ int npi_CheckAndAddRemove( LPTSTR, LPTSTR, int ); DWORD InstNetProvider(MSIHANDLE, int); void ShowMsiError(MSIHANDLE, DWORD, DWORD); DWORD ConfigService(int); +UINT createAfsAdminGroup(void); +UINT initializeAfsAdminGroup(void); +UINT removeAfsAdminGroup(void); /* exported */ MSIDLLEXPORT InstallNetProvider( MSIHANDLE ); @@ -77,5 +83,7 @@ MSIDLLEXPORT ConfigureClientService( MSIHANDLE ); MSIDLLEXPORT ConfigureServerService( MSIHANDLE ); MSIDLLEXPORT AbortMsiImmediate( MSIHANDLE ); MSIDLLEXPORT UninstallNsisInstallation( MSIHANDLE hInstall ); +MSIDLLEXPORT CreateAFSClientAdminGroup( MSIHANDLE hInstall ); +MSIDLLEXPORT RemoveAFSClientAdminGroup( MSIHANDLE hInstall ); #endif /*__afsMsiTools_H__*/ diff --git a/src/WINNT/install/wix/lang/en_US/strings.wxl b/src/WINNT/install/wix/lang/en_US/strings.wxl index d014960e74..45c1273418 100644 --- a/src/WINNT/install/wix/lang/en_US/strings.wxl +++ b/src/WINNT/install/wix/lang/en_US/strings.wxl @@ -42,6 +42,8 @@ Configuration of server service failed. System error [2] Installation aborted : [2] Uninstallation of the NSIS installation of OpenAFS failed with code [2] + Can't create AFS Client Admin group. NET_API_Error [2] + Can't add members to AFS Client Admin group. NET_API_Error [2] Installing loopback adapter Removing existing loopback adapter diff --git a/src/WINNT/install/wix/lang/en_US/ui.wxi b/src/WINNT/install/wix/lang/en_US/ui.wxi index 0a3f16f7c7..4e458dc52d 100644 --- a/src/WINNT/install/wix/lang/en_US/ui.wxi +++ b/src/WINNT/install/wix/lang/en_US/ui.wxi @@ -1037,6 +1037,8 @@ $(loc.ErrSCSFailed) $(loc.ErrAbort) $(loc.ErrNsisFailed) + $(loc.ErrCantCreateGroup) + $(loc.ErrCantAddMembers) $(loc.ActRemoveLoopback) $(loc.ActInstallLoopback) $(loc.ActRemoveNetProvider) diff --git a/src/WINNT/install/wix/openafs.wxs b/src/WINNT/install/wix/openafs.wxs index 159b088c0a..2ca393c788 100644 --- a/src/WINNT/install/wix/openafs.wxs +++ b/src/WINNT/install/wix/openafs.wxs @@ -153,6 +153,24 @@ BinaryKey="BIN_afsCustom" DllEntry="UninstallNsisInstallation" Execute="immediate" /> + + + &feaClient=2 &feaClient=3 &feaServer=3 + + &feaClient=3 + &feaClient=3 &feaClient=3 OR &feaServer=3 OR &feaClient=2 OR &feaServer=2 diff --git a/src/config/NTMakefile.i386_nt40 b/src/config/NTMakefile.i386_nt40 index 34d81c214a..2c0c56e03e 100644 --- a/src/config/NTMakefile.i386_nt40 +++ b/src/config/NTMakefile.i386_nt40 @@ -28,7 +28,8 @@ # ####### Special optional defines -!IFNDEF NO_CRTDBG #don't set _CRTDBG_MAP_ALLOC flag for some module compliations +!IFNDEF NO_CRTDBG +#don't set _CRTDBG_MAP_ALLOC flag for some module compliations #_CRTDBG_MAP_ALLOC=1 !ENDIF @@ -79,10 +80,11 @@ LIB = $(AFSDEV_LIB) #define used in WinNT/2000 installation and program version display AFSPRODUCT_VER_MAJOR=1 AFSPRODUCT_VER_MINOR=3 -AFSPRODUCT_VER_PATCH=7001 +AFSPRODUCT_VER_PATCH=7004 AFSPRODUCT_VER_BUILD=0 # For MSI installer, each major release should have a different GUID +# http://msdn.microsoft.com/library/en-us/msi/setup/changing_the_product_code.asp AFSPRODUCT_VER_GUID=CCAF9E14-976E-46C0-8A1B-A218EAB7ADC5 AFSPRODUCT_VERSION=$(AFSPRODUCT_VER_MAJOR).$(AFSPRODUCT_VER_MINOR).$(AFSPRODUCT_VER_PATCH) @@ -93,7 +95,7 @@ CELLSERVDB_INSTALL=CellServDB.GrandCentral CELLSERVDB_WEB=http://grand.central.org/dl/cellservdb/CellServDB TARGETOS = WINNT -# Define defaults folder locations +# Define defaults folder locations DEST=dest SRC=src OBJ=obj