Mac installer: create a new command-line tool AddRemoveUser; updated ReadMe file

svn path=/trunk/boinc/; revision=19061
This commit is contained in:
Charlie Fenton 2009-09-17 10:42:13 +00:00
parent 984bb92280
commit de83121d90
4 changed files with 391 additions and 2 deletions

View File

@ -7773,3 +7773,16 @@ David 16 Sept 2009
client/
log_flags.cpp,h
schedule_op.cpp
Charlie 17 Sept 2009
- Mac installer: create a new command-line tool AddRemoveUser to add users
to or remove users from group boinc_master. It also adjusts the users'
login item and screensaver selection. Updated ReadMe file to explain
changes for Unicode and for OS 10.6 Snow Leopard.
mac_installer/
AddRemoveUser.cpp
ReadMe.rtf
mac_build/
boinc.xcodeproj/
project.pbxproj

View File

@ -27,6 +27,7 @@
DD45C4A10A53E73500E923D1 /* PBXTargetDependency */,
DDBD52900C16C3790074905B /* PBXTargetDependency */,
DD095D1F0F3B22DE000902F5 /* PBXTargetDependency */,
DDD3370C106224FF00867C7D /* PBXTargetDependency */,
);
name = Build_All;
productName = Build_All;
@ -300,6 +301,9 @@
DDC988FE0F3BD44100EE8D0E /* gui_rpc_client_ops.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DD73E34E08A0694000656EB1 /* gui_rpc_client_ops.cpp */; };
DDCF84080E1B7C0A005EDC45 /* DlgItemProperties.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DDCF84060E1B7C0A005EDC45 /* DlgItemProperties.cpp */; };
DDD095490A3EDF2D00C95BA4 /* switcher.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DDD095480A3EDF2D00C95BA4 /* switcher.cpp */; };
DDD3370A106224E800867C7D /* AddRemoveUser.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DDD33709106224E800867C7D /* AddRemoveUser.cpp */; };
DDD3370F10622C6C00867C7D /* LoginItemAPI.c in Sources */ = {isa = PBXBuildFile; fileRef = DD1277BE081F3E73007B5DE1 /* LoginItemAPI.c */; };
DDD3371310622D0800867C7D /* Carbon.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 20286C33FDCF999611CA2CEA /* Carbon.framework */; };
DDD52DCA0C03CAE6009B5FC0 /* ViewProjects.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DDD52DC40C03CAE6009B5FC0 /* ViewProjects.cpp */; };
DDD52DCC0C03CAE6009B5FC0 /* ViewTransfers.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DDD52DC60C03CAE6009B5FC0 /* ViewTransfers.cpp */; };
DDD52DCE0C03CAE6009B5FC0 /* ViewWork.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DDD52DC80C03CAE6009B5FC0 /* ViewWork.cpp */; };
@ -554,6 +558,13 @@
remoteGlobalIDString = DDD0953E0A3EDD2500C95BA4;
remoteInfo = switcher;
};
DDD3370B106224FF00867C7D /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 20286C28FDCF999611CA2CEA /* Project object */;
proxyType = 1;
remoteGlobalIDString = DDD336F51062235D00867C7D;
remoteInfo = AddRemoveUser;
};
DDFA60DC0CB338940037B88C /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 20286C28FDCF999611CA2CEA /* Project object */;
@ -892,6 +903,8 @@
DDCF84070E1B7C0A005EDC45 /* DlgItemProperties.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = DlgItemProperties.h; sourceTree = "<group>"; };
DDD0953F0A3EDD2500C95BA4 /* switcher */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = switcher; sourceTree = BUILT_PRODUCTS_DIR; };
DDD095480A3EDF2D00C95BA4 /* switcher.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; path = switcher.cpp; sourceTree = "<group>"; };
DDD337021062235D00867C7D /* AddRemoveUser */ = {isa = PBXFileReference; explicitFileType = "compiled.mach-o.executable"; includeInIndex = 0; path = AddRemoveUser; sourceTree = BUILT_PRODUCTS_DIR; };
DDD33709106224E800867C7D /* AddRemoveUser.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = AddRemoveUser.cpp; path = ../mac_installer/AddRemoveUser.cpp; sourceTree = SOURCE_ROOT; };
DDD52DC40C03CAE6009B5FC0 /* ViewProjects.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = ViewProjects.cpp; path = ../clientgui/ViewProjects.cpp; sourceTree = SOURCE_ROOT; };
DDD52DC50C03CAE6009B5FC0 /* ViewProjects.h */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.c.h; name = ViewProjects.h; path = ../clientgui/ViewProjects.h; sourceTree = SOURCE_ROOT; };
DDD52DC60C03CAE6009B5FC0 /* ViewTransfers.cpp */ = {isa = PBXFileReference; fileEncoding = 30; lastKnownFileType = sourcecode.cpp.cpp; name = ViewTransfers.cpp; path = ../clientgui/ViewTransfers.cpp; sourceTree = SOURCE_ROOT; };
@ -1094,6 +1107,14 @@
);
runOnlyForDeploymentPostprocessing = 0;
};
DDD336F81062235D00867C7D /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
DDD3371310622D0800867C7D /* Carbon.framework in Frameworks */,
);
runOnlyForDeploymentPostprocessing = 0;
};
DDD74D8507CF482E0065AC9D /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
@ -1142,6 +1163,7 @@
DDB874030C850BC800E0DE1F /* libboinc_graphics2.a */,
DDFA60D40CB337D40037B88C /* gfx_switcher */,
DD8916280F3B17E900DE5B1C /* boincscr */,
DDD337021062235D00867C7D /* AddRemoveUser */,
);
name = Products;
sourceTree = SOURCE_ROOT;
@ -1217,6 +1239,7 @@
DDF1F47A09822C3400482C89 /* preinstall */,
DDB8D5A5081FC8C700A5A1E8 /* postinstall */,
DD127880081F464E007B5DE1 /* postupgrade */,
DDD33709106224E800867C7D /* AddRemoveUser.cpp */,
);
name = mac_installer;
sourceTree = SOURCE_ROOT;
@ -1902,6 +1925,23 @@
productReference = DDD0953F0A3EDD2500C95BA4 /* switcher */;
productType = "com.apple.product-type.tool";
};
DDD336F51062235D00867C7D /* AddRemoveUser */ = {
isa = PBXNativeTarget;
buildConfigurationList = DDD336FA1062235D00867C7D /* Build configuration list for PBXNativeTarget "AddRemoveUser" */;
buildPhases = (
DDD336F61062235D00867C7D /* Sources */,
DDD336F81062235D00867C7D /* Frameworks */,
DDD336F91062235D00867C7D /* ShellScript */,
);
buildRules = (
);
dependencies = (
);
name = AddRemoveUser;
productName = SetVersion;
productReference = DDD337021062235D00867C7D /* AddRemoveUser */;
productType = "com.apple.product-type.tool";
};
DDD74D8607CF482E0065AC9D /* BOINC_Client */ = {
isa = PBXNativeTarget;
buildConfigurationList = DD9E2365091CBDAE0048316E /* Build configuration list for PBXNativeTarget "BOINC_Client" */;
@ -1990,6 +2030,7 @@
DD4688400C165F3C0089F500 /* Uninstaller */,
DDFA60C90CB337D40037B88C /* gfx_switcher */,
DD89161C0F3B17E900DE5B1C /* ss_app */,
DDD336F51062235D00867C7D /* AddRemoveUser */,
);
};
/* End PBXProject section */
@ -2257,6 +2298,21 @@
shellPath = /bin/sh;
shellScript = "# echo \"BuiltProductsDir = ${BUILT_PRODUCTS_DIR}\"\n# echo \"CONFIGURATIONTEMPDIR = ${CONFIGURATION_TEMP_DIR}\"\n# echo \"SRC ROOT = ${SRCROOT}\"\n# echo \"architecture = ${ARCHS}\"\n# echo \"native architecture = ${ARCHS}\"\n\"${BUILT_PRODUCTS_DIR}/SetVersion\"\n";
};
DDD336F91062235D00867C7D /* ShellScript */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
"$(SRCROOT)/../client/version.h",
);
outputPaths = (
"$(SRCROOT)/English.lproj/InfoPlist.strings",
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "# echo \"BuiltProductsDir = ${BUILT_PRODUCTS_DIR}\"\n# echo \"CONFIGURATIONTEMPDIR = ${CONFIGURATION_TEMP_DIR}\"\n# echo \"SRC ROOT = ${SRCROOT}\"\n# echo \"architecture = ${ARCHS}\"\n# echo \"native architecture = ${ARCHS}\"\n\"${BUILT_PRODUCTS_DIR}/SetVersion\"\n";
};
DDEE5E8E0D9112AF0056A99E /* ShellScript */ = {
isa = PBXShellScriptBuildPhase;
buildActionMask = 2147483647;
@ -2601,6 +2657,15 @@
);
runOnlyForDeploymentPostprocessing = 0;
};
DDD336F61062235D00867C7D /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
DDD3370A106224E800867C7D /* AddRemoveUser.cpp in Sources */,
DDD3370F10622C6C00867C7D /* LoginItemAPI.c in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
DDD74D8407CF482E0065AC9D /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
@ -2822,6 +2887,11 @@
target = DDD0953E0A3EDD2500C95BA4 /* switcher */;
targetProxy = DDD095500A3EE09900C95BA4 /* PBXContainerItemProxy */;
};
DDD3370C106224FF00867C7D /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
target = DDD336F51062235D00867C7D /* AddRemoveUser */;
targetProxy = DDD3370B106224FF00867C7D /* PBXContainerItemProxy */;
};
DDFA60DD0CB338940037B88C /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
target = DDFA60C90CB337D40037B88C /* gfx_switcher */;
@ -5066,6 +5136,62 @@
};
name = Deployment;
};
DDD336FB1062235D00867C7D /* Development */ = {
isa = XCBuildConfiguration;
buildSettings = {
PRODUCT_NAME = AddRemoveUser;
STRINGS_FILE_OUTPUT_ENCODING = "UTF-16";
};
name = Development;
};
DDD336FC1062235D00867C7D /* Dev_noSandbox */ = {
isa = XCBuildConfiguration;
buildSettings = {
PRODUCT_NAME = AddRemoveUser;
STRINGS_FILE_OUTPUT_ENCODING = "UTF-16";
};
name = Dev_noSandbox;
};
DDD336FD1062235D00867C7D /* ppc_Deployment */ = {
isa = XCBuildConfiguration;
buildSettings = {
PRODUCT_NAME = AddRemoveUser;
STRINGS_FILE_OUTPUT_ENCODING = "UTF-16";
};
name = ppc_Deployment;
};
DDD336FE1062235D00867C7D /* i386_Deployment */ = {
isa = XCBuildConfiguration;
buildSettings = {
PRODUCT_NAME = AddRemoveUser;
STRINGS_FILE_OUTPUT_ENCODING = "UTF-16";
};
name = i386_Deployment;
};
DDD336FF1062235D00867C7D /* Deployment */ = {
isa = XCBuildConfiguration;
buildSettings = {
PRODUCT_NAME = AddRemoveUser;
STRINGS_FILE_OUTPUT_ENCODING = "UTF-16";
};
name = Deployment;
};
DDD337001062235D00867C7D /* Deployment-no64 */ = {
isa = XCBuildConfiguration;
buildSettings = {
PRODUCT_NAME = AddRemoveUser;
STRINGS_FILE_OUTPUT_ENCODING = "UTF-16";
};
name = "Deployment-no64";
};
DDD337011062235D00867C7D /* Deploy_noSandbox */ = {
isa = XCBuildConfiguration;
buildSettings = {
PRODUCT_NAME = AddRemoveUser;
STRINGS_FILE_OUTPUT_ENCODING = "UTF-16";
};
name = Deploy_noSandbox;
};
DDFA60CE0CB337D40037B88C /* Development */ = {
isa = XCBuildConfiguration;
buildSettings = {
@ -5391,6 +5517,20 @@
defaultConfigurationIsVisible = 0;
defaultConfigurationName = ppc_Deployment;
};
DDD336FA1062235D00867C7D /* Build configuration list for PBXNativeTarget "AddRemoveUser" */ = {
isa = XCConfigurationList;
buildConfigurations = (
DDD336FB1062235D00867C7D /* Development */,
DDD336FC1062235D00867C7D /* Dev_noSandbox */,
DDD336FD1062235D00867C7D /* ppc_Deployment */,
DDD336FE1062235D00867C7D /* i386_Deployment */,
DDD336FF1062235D00867C7D /* Deployment */,
DDD337001062235D00867C7D /* Deployment-no64 */,
DDD337011062235D00867C7D /* Deploy_noSandbox */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = ppc_Deployment;
};
DDFA60CD0CB337D40037B88C /* Build configuration list for PBXNativeTarget "gfx_switcher" */ = {
isa = XCConfigurationList;
buildConfigurations = (

View File

@ -0,0 +1,229 @@
// This file is part of BOINC.
// http://boinc.berkeley.edu
// Copyright (C) 2009 University of California
//
// BOINC is free software; you can redistribute it and/or modify it
// under the terms of the GNU Lesser General Public License
// as published by the Free Software Foundation,
// either version 3 of the License, or (at your option) any later version.
//
// BOINC is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
// See the GNU Lesser General Public License for more details.
//
// You should have received a copy of the GNU Lesser General Public License
// along with BOINC. If not, see <http://www.gnu.org/licenses/>.
/* AddRemoveUser.cpp */
#include <Carbon/Carbon.h>
#include <unistd.h> // getlogin
#include <sys/types.h> // getpwname, getpwuid, getuid
#include <pwd.h> // getpwname, getpwuid, getuid
#include <grp.h> // getgrnam
#include "LoginItemAPI.h" //please take a look at LoginItemAPI.h for an explanation of the routines available to you.
void printUsage(void);
void SetLoginItem(Boolean addLogInItem);
static char * PersistentFGets(char *buf, size_t buflen, FILE *f);
int main(int argc, char *argv[])
{
Boolean AddUsers = false;
Boolean SetSavers = false;
Boolean isGroupMember;
Boolean saverIsSet = false;
passwd *pw;
uid_t saved_uid;
long OSVersion;
group grpBOINC_master, *grpBOINC_masterPtr;
char bmBuf[32768];
short index, i;
char *p;
char s[256];
FILE *f;
OSStatus err;
#ifndef _DEBUG
if (getuid() != 0) {
printf("This program must be run as root\n");
printUsage();
return 0;
}
#endif
if (argc < 3) {
printUsage();
return 0;
}
if (strcmp(argv[1], "-a") == 0) {
AddUsers = true;
} else if (strcmp(argv[1], "-s") == 0) {
AddUsers = true;
SetSavers = true;
} else if (strcmp(argv[1], "-r") != 0) {
printUsage();
return 0;
}
err = Gestalt(gestaltSystemVersion, &OSVersion);
if (err != noErr)
return err;
err = getgrnam_r("boinc_master", &grpBOINC_master, bmBuf, sizeof(bmBuf), &grpBOINC_masterPtr);
if (err) { // Should never happen unless buffer too small
puts("getgrnam(\"boinc_master\") failed\n");
return -1;
}
for (index=2; index<argc; index++) {
isGroupMember = false;
i = 0;
while ((p = grpBOINC_master.gr_mem[i]) != NULL) { // Step through all users in group boinc_master
if (strcmp(p, argv[index]) == 0) {
// User is a member of group boinc_master
isGroupMember = true;
break;
}
++i;
}
if ((!isGroupMember) && AddUsers) {
sprintf(s, "dscl . -merge /groups/boinc_master users %s", argv[index]);
system(s);
}
if (isGroupMember && (!AddUsers)) {
sprintf(s, "dscl . -delete /Groups/boinc_master GroupMembership %s", argv[index]);
system(s);
}
pw = getpwnam(argv[index]);
if (pw == NULL) {
printf("User %s not found.\n", argv[index]);
continue;
}
saved_uid = geteuid();
seteuid(pw->pw_uid); // Temporarily set effective uid to this user
SetLoginItem(AddUsers); // Set or remove login item for this user
if (OSVersion < 0x1060) {
sprintf(s, "sudo -u %s defaults -currentHost read com.apple.screensaver moduleName",
argv[index]);
} else {
sprintf(s, "sudo -u %s defaults -currentHost read com.apple.screensaver moduleDict -dict",
argv[index]);
}
f = popen(s, "r");
if (f) {
saverIsSet = false;
while (PersistentFGets(s, sizeof(s), f)) {
if (strstr(s, "BOINCSaver")) {
saverIsSet = true;
break;
}
}
pclose(f);
}
if ((!saverIsSet) && SetSavers) {
if (OSVersion < 0x1060) {
sprintf(s, "sudo -u %s defaults -currentHost write com.apple.screensaver moduleName BOINCSaver",
argv[index]);
system(s);
sprintf(s, "sudo -u %s defaults -currentHost write com.apple.screensaver modulePath \"/Library/Screen Savers/BOINCSaver.saver\"",
argv[index]);
system(s);
} else {
sprintf(s, "sudo -u %s defaults -currentHost write com.apple.screensaver moduleDict -dict moduleName BOINCSaver path \"/Library/Screen Savers/BOINCSaver.saver\"",
argv[index]);
system(s);
}
}
if (saverIsSet && (!AddUsers)) {
if (OSVersion < 0x1060) {
sprintf(s, "sudo -u %s defaults -currentHost write com.apple.screensaver moduleName Flurry",
argv[index]);
system(s);
sprintf(s, "sudo -u %s defaults -currentHost write com.apple.screensaver modulePath \"/System/Library/Screen Savers/Flurry.saver\"",
argv[index]);
system(s);
} else {
sprintf(s, "sudo -u %s defaults -currentHost write com.apple.screensaver moduleDict -dict moduleName Flurry path \"/System/Library/Screen Savers/Flurry.saver\"",
argv[index]);
system(s);
}
}
seteuid(saved_uid); // Set effective uid back to privileged user
}
return 0;
}
void printUsage() {
printf("Usage: sudo AddRemoveUser [-a | -s | -r] [user1 [user2 [user3...]]]\n");
printf(" -a: add users to those with permission to run BOINC Manager.\n");
printf(" -s: same as -a plus set users' screensaver to BOINC.\n");
printf(" -r: remove users' permission to run BOINC Manager, and \n");
printf(" if their screensaver was set to BOINC change it to Flurry.\n");
printf("\n");
}
void SetLoginItem(Boolean addLogInItem){
Boolean Success;
int NumberOfLoginItems, Counter;
char *p, *q;
Success = false;
NumberOfLoginItems = GetCountOfLoginItems(kCurrentUser);
// Search existing login items in reverse order, deleting any duplicates of ours
for (Counter = NumberOfLoginItems ; Counter > 0 ; Counter--)
{
p = ReturnLoginItemPropertyAtIndex(kCurrentUser, kApplicationNameInfo, Counter-1);
q = p;
while (*q)
{
// It is OK to modify the returned string because we "own" it
*q = toupper(*q); // Make it case-insensitive
q++;
}
if (strcmp(p, "BOINCMANAGER.APP") == 0) {
Success = RemoveLoginItemAtIndex(kCurrentUser, Counter-1);
}
}
if (addLogInItem) {
Success = AddLoginItemWithPropertiesToUser(kCurrentUser, "/Applications/BOINCManager.app", kHideOnLaunch);
}
}
static char * PersistentFGets(char *buf, size_t buflen, FILE *f) {
char *p = buf;
size_t len = buflen;
size_t datalen = 0;
*buf = '\0';
while (datalen < (buflen - 1)) {
fgets(p, len, f);
if (feof(f)) break;
if (ferror(f) && (errno != EINTR)) break;
if (strchr(buf, '\n')) break;
datalen = strlen(buf);
p = buf + datalen;
len -= datalen;
}
return (buf[0] ? buf : NULL);
}

View File

@ -1,4 +1,4 @@
{\rtf1\ansi\ansicpg1252\cocoartf949\cocoasubrtf460
{\rtf1\ansi\ansicpg1252\cocoartf949\cocoasubrtf540
{\fonttbl\f0\fswiss\fcharset0 Helvetica;}
{\colortbl;\red255\green255\blue255;}
\margl1440\margr1440\vieww9000\viewh9000\viewkind0
@ -12,6 +12,13 @@
\cf0 http://boinc.berkeley.edu/\
\pard\tx720\tx1440\tx2160\tx2880\tx3600\tx4320\tx5040\tx5760\tx6480\tx7200\tx7920\tx8640\ql\qnatural
\cf0 \
If you are upgrading from a version earlier than 6.8.0, you may see a message "Failed to convert file BOINC Manager Preferences to Unicode." This is due to our addition of full Unicode support to the BOINC Manager. If you get this message, you may need to readjust your column widths and other BOINC Manager view options, but no other problems will result. When you quit BOINC Manager, these settings will be saved in the new Unicode format.\
\
Due to new restrictions imposed by OS 10.6 Snow Leopard, there has been a change in BOINC's security implementation. Non-administrative users can no longer run BOINC Manager unless they are added to group boinc_master. As of BOINC 6.10.5, the BOINC installer asks whether or not you wish to allow this.\
\
For more options, please see the BOINC Macintosh administrator tools at:\
{\field{\*\fldinst{HYPERLINK "http://boinc.berkeley.edu/wiki/Tools_for_Mac_OS_X"}}{\fldrslt http://boinc.berkeley.edu/wiki/Tools_for_Mac_OS_X}}\
\
Starting with version 5.5.4, BOINC features new, stricter security measures. See the
\b Security
\b0 section below for important information.\
@ -86,7 +93,7 @@ Starting with version 5.5.4 of the BOINC Manager for the Macintosh, the BOINC in
\b boinc_project
\b0 (unless they were created by a previous installation of BOINC.)\
\
The installer automatically gives administrators (users who are members of the "admin" group) membership in the two new groups, so that they can easily manipulate BOINC files. Non-admin users are denied direct access to these files (except through BOINC Manager), protecting BOINC and its projects files. This is particularly useful where many people have access to the computer, as in a school computer lab.\
The installer automatically gives administrators (users who are members of the "admin" group) membership in the two new groups, so that they can easily manipulate BOINC files. Non-admin users are denied access to these files and to he BOINC Manager, protecting BOINC and its projects files. This is particularly useful where many people have access to the computer, as in a school computer lab.\
\
BOINC projects are given permission to access only project files, protecting your computer in the event someone downloads bad software from a bogus project, or in the unlikely case that a legitimate project's server is infiltrated by a cracker.\
\