diff --git a/src/platform/DARWIN/AFSPreference/AFSPropertyManager.h b/src/platform/DARWIN/AFSPreference/AFSPropertyManager.h index b775aac75a..edc1dbcf9e 100644 --- a/src/platform/DARWIN/AFSPreference/AFSPropertyManager.h +++ b/src/platform/DARWIN/AFSPreference/AFSPropertyManager.h @@ -258,10 +258,9 @@ /*! @function writeCacheInfo @abstract Write the cache info down the file - @param filePath where to write the CacheInfo @result return the execution error */ --(int) writeCacheInfo:(NSString*)filePath; +-(int) writeCacheInfo; /*! @function readAfsdOption @@ -292,14 +291,6 @@ @param filePath path of the new file with afs.conf file format */ -(int) readNewAfsdOption:(NSString*)filePath; -/*! - @function writeAfsdOption - @abstract <#(description)#> - @discussion <#(description)#> - @param <#(name) (description)#> - @result <#(description)#> - */ --(int) writeAfsdOption:(NSString*)filePath; /*! @function writeOldAfsdOption @abstract Write the cache manager parameter to file @@ -307,13 +298,12 @@ @param filePath file path for file to write into @result <#(description)#> */ --(int) writeOldAfsdOption:(NSString*)filePath; +-(int) writeOldAfsdOption; /*! @function writeNewAfsdOption @abstract Write the cache parameter to a file with the new format - @param filePath file path where write into */ --(int) writeNewAfsdOption:(NSString*)filePath; +-(int) writeNewAfsdOption; /*! @function getAfsVersion @abstract Return the string representing the afs version diff --git a/src/platform/DARWIN/AFSPreference/AFSPropertyManager.m b/src/platform/DARWIN/AFSPreference/AFSPropertyManager.m index 71626764ab..30d0d99087 100644 --- a/src/platform/DARWIN/AFSPreference/AFSPropertyManager.m +++ b/src/platform/DARWIN/AFSPreference/AFSPropertyManager.m @@ -402,7 +402,7 @@ // ------------------------------------------------------------------------------- // writeCacheInfo: // ------------------------------------------------------------------------------- --(int) writeCacheInfo:(NSString*)filePath +-(int) writeCacheInfo { NSNumber *tmpNum = nil; NSMutableString *cacheInfoContent = [[NSMutableString alloc] init]; @@ -427,10 +427,7 @@ userInfo:nil]; [cacheInfoContent appendString:[tmpNum stringValue]]; - [cacheInfoContent writeToFile: [filePath stringByExpandingTildeInPath] - atomically: YES - encoding: NSASCIIStringEncoding - error: nil]; + [TaskUtil executePrivTaskWrite:@"/etc/cacheinfo" data:cacheInfoContent]; [cacheInfoContent release]; return noErr; @@ -580,31 +577,10 @@ } -// ------------------------------------------------------------------------------- -// writeCacheInfo: -// ------------------------------------------------------------------------------- --(int) writeAfsdOption:(NSString*)filePath -{ - int result = 0; - @try{ - if(useAfsdConfVersion) { - result = [self writeNewAfsdOption:filePath]; - } else { - result = [self writeOldAfsdOption:filePath]; - } - - }@catch(NSException *e){ - @throw e; - }@finally{ - - } - return result; -} - // ------------------------------------------------------------------------------- // writeOldAfsdOption: // ------------------------------------------------------------------------------- --(int) writeOldAfsdOption:(NSString*)filePath; +-(int) writeOldAfsdOption { NSMutableString *oldConfFileContent = [[[NSMutableString alloc] init] autorelease]; //add afsd param @@ -614,12 +590,9 @@ [oldConfFileContent appendString:@"\n"]; //write content on file - [oldConfFileContent writeToFile: [filePath stringByExpandingTildeInPath] - atomically: YES - encoding: NSASCIIStringEncoding - error: nil]; + [TaskUtil executePrivTaskWrite:AFSD_OLD_PREFERENCE_FILE data:oldConfFileContent]; + return noErr; - } // ------------------------------------------------------------------------------- @@ -629,7 +602,7 @@ // AFS_POST_INIT=afs_server_prefs // AFS_PRE_SHUTDOWN= // ------------------------------------------------------------------------------- --(int) writeNewAfsdOption:(NSString*)filePath +-(int) writeNewAfsdOption { NSMutableString *newConfFileContent = [[[NSMutableString alloc] init] autorelease]; @@ -652,10 +625,8 @@ [newConfFileContent appendString:@"\n"]; //Write to file - [newConfFileContent writeToFile: [filePath stringByExpandingTildeInPath] - atomically: YES - encoding: NSASCIIStringEncoding - error: nil]; + [TaskUtil executePrivTaskWrite:AFSD_NEW_PREFERENCE_FILE data:newConfFileContent]; + return noErr; } @@ -1108,8 +1079,6 @@ // ------------------------------------------------------------------------------- -(void) saveConfigurationFiles:(BOOL) makeBackup { - NSError *err; - NSMutableString *filePath = [[NSMutableString alloc] initWithCapacity:256]; NSMutableString *cellServDBString = [[NSMutableString alloc] initWithCapacity:256]; NSMutableString *theseCellString = [[NSMutableString alloc] initWithCapacity:256]; DBCellElement *cellElement = nil; @@ -1118,14 +1087,6 @@ @try{ [self exceptionOnInvalidPath]; - // ThisCell - [filePath setString: @"/tmp/ThisCell"]; - [cellName writeToFile: [filePath stringByExpandingTildeInPath] - atomically:YES - encoding: NSASCIIStringEncoding - error:nil]; - // CellServDB - for(int idx = 0; idx < [cellList count]; idx++){ cellElement = [cellList objectAtIndex:idx]; [cellServDBString appendString:[cellElement description]]; @@ -1135,45 +1096,18 @@ } } - - [filePath setString: @"/tmp/CellServDB"]; - [cellServDBString writeToFile: [filePath stringByExpandingTildeInPath] - atomically:YES - encoding: NSUTF8StringEncoding - error:&err]; - - [filePath setString: @"/tmp/TheseCells"]; - [theseCellString writeToFile: [filePath stringByExpandingTildeInPath] - atomically:YES - encoding: NSUTF8StringEncoding - error:&err]; - if(makeBackup) [self backupConfigurationFiles]; - // install ThisCell - [filePath setString: installationPath]; - [filePath appendString: @"/etc/ThisCell"]; - [self installConfigurationFile:@"/tmp/ThisCell" - destPath:filePath]; - - // install CellServDB - [filePath setString: installationPath]; - [filePath appendString: @"/etc/CellServDB"]; - [self installConfigurationFile:@"/tmp/CellServDB" - destPath:filePath]; - - // install CellServDB - [filePath setString: installationPath]; - [filePath appendString: @"/etc/TheseCells"]; - [self installConfigurationFile:@"/tmp/TheseCells" - destPath:filePath]; + [TaskUtil executePrivTaskWrite:@"/etc/ThisCell" data:cellName]; + [TaskUtil executePrivTaskWrite:@"/etc/CellServDB" data:cellServDBString]; + [TaskUtil executePrivTaskWrite:@"/etc/TheseCells" data:theseCellString]; } @catch (NSException *e) { @throw e; }@finally { // dispose all variable used - if(filePath) [filePath release]; if(cellServDBString) [cellServDBString release]; + if(theseCellString) [theseCellString release]; } } @@ -1188,12 +1122,6 @@ @try{ [self exceptionOnInvalidPath]; - // cacheinfo file creation - [self writeCacheInfo:@"/tmp/cacheinfo"]; - - //afsd.option or afs.conf file creation - [self writeAfsdOption:useAfsdConfVersion?AFSD_TMP_NEW_PREFERENCE_FILE:AFSD_TMP_OLD_PREFERENCE_FILE]; - // backup original file if(makeBackup) { //cacheinfo @@ -1206,18 +1134,17 @@ [TaskUtil executePrivTaskBackup:AFSD_OLD_PREFERENCE_FILE]; } } + + // cacheinfo + [self writeCacheInfo]; - // install cacheinfo - [filePath setString:installationPath]; - [filePath appendString: @"/etc/cacheinfo"]; - [self installConfigurationFile:@"/tmp/cacheinfo" - destPath:filePath]; - - // install afsd.conf or afs.conf configuration file - [filePath setString: installationPath]; - [filePath appendString: useAfsdConfVersion?AFSD_NEW_PREFERENCE_FILE:AFSD_OLD_PREFERENCE_FILE]; - [self installConfigurationFile:useAfsdConfVersion?AFSD_TMP_NEW_PREFERENCE_FILE:AFSD_TMP_OLD_PREFERENCE_FILE - destPath:filePath]; + if (useAfsdConfVersion) { + // afs.conf + [self writeNewAfsdOption]; + } else { + // afsd.options + [self writeOldAfsdOption]; + } } @catch (NSException *e) { @throw e; diff --git a/src/platform/DARWIN/AFSPreference/TaskUtil.h b/src/platform/DARWIN/AFSPreference/TaskUtil.h index 7819b8edab..e3b511c25d 100644 --- a/src/platform/DARWIN/AFSPreference/TaskUtil.h +++ b/src/platform/DARWIN/AFSPreference/TaskUtil.h @@ -17,7 +17,8 @@ +(NSString*) searchExecutablePath:(NSString*)unixCommand; +(NSString*) executeTaskSearchingPath:(NSString*)unixCommand args:(NSArray*)args; +(NSString*) executeTask:(NSString*) taskName arguments:(NSArray *)args; -+(int) executePrivTask:(const char *)task filename:(char *)filename; ++(int) executePrivTask:(const char *)task filename:(char *)filename data:(char *)data; +(int) executePrivTask:(const char *)task; +(int) executePrivTaskBackup:(NSString *)filename; ++(int) executePrivTaskWrite:(NSString *)filename data:(NSString *)data; @end diff --git a/src/platform/DARWIN/AFSPreference/TaskUtil.m b/src/platform/DARWIN/AFSPreference/TaskUtil.m index 84b57fd7f7..b26f7f5dd8 100644 --- a/src/platform/DARWIN/AFSPreference/TaskUtil.m +++ b/src/platform/DARWIN/AFSPreference/TaskUtil.m @@ -85,8 +85,11 @@ * * @param[in] task The name of the task to perform (e.g. "startup_enable"). * See privhelper.c:ProcessRequest for what tasks we define. - * @param[in] filename Used for the "backup" task. Don't specify this with - * executePrivTask; use executePrivTaskBackup instead. + * @param[in] filename Used for the "backup"/"write" tasks. Don't specify this with + * executePrivTask; use executePrivTaskBackup or + * executePrivTaskWrite instead. + * @param[in] data Used for the "write" task. Don't specify this with + * executePrivTask; use executePrivTaskWrite instead. * * @returns Return status of the task * @retval 0 success @@ -94,7 +97,7 @@ * @retval nonzero The return value of system() of a failed command for the * task. */ -+(int) executePrivTask:(const char *)task filename:(char *)filename { ++(int) executePrivTask:(const char *)task filename:(char *)filename data:(char *)data { int status = -1; OSErr autherr = [[AuthUtil shared] autorize]; @@ -140,6 +143,9 @@ if (filename != NULL) { xpc_dictionary_set_string(msg, "filename", filename); } + if (data != NULL) { + xpc_dictionary_set_string(msg, "data", data); + } xpc_object_t reply = xpc_connection_send_message_with_reply_sync(conn, msg); if (reply == NULL) { @@ -166,10 +172,14 @@ } +(int) executePrivTask:(const char *)task { - return [self executePrivTask:task filename:NULL]; + return [self executePrivTask:task filename:NULL data:NULL]; } +(int) executePrivTaskBackup:(NSString *)filename { - return [self executePrivTask:"backup" filename:[filename UTF8String]]; + return [self executePrivTask:"backup" filename:[filename UTF8String] data:NULL]; +} + ++(int) executePrivTaskWrite:(NSString *)filename data:(NSString *)data { + return [self executePrivTask:"write" filename:[filename UTF8String] data:[data UTF8String]]; } @end diff --git a/src/platform/DARWIN/PrivilegedHelper/privhelper.c b/src/platform/DARWIN/PrivilegedHelper/privhelper.c index dde338c998..1a9669e29f 100644 --- a/src/platform/DARWIN/PrivilegedHelper/privhelper.c +++ b/src/platform/DARWIN/PrivilegedHelper/privhelper.c @@ -293,6 +293,68 @@ BackupFile(const char *filename) return code; } +/* + * Writes the given "data" into "filename". + */ +static int +WriteFile(const char *filename, const char *data) +{ + int code; + char *path = NULL; + char *tmp_path = NULL; + FILE *fh = NULL; + + path = GetFullPath("write", filename); + if (path == NULL) { + goto error; + } + + code = asprintf(&tmp_path, "%s.tmp", path); + if (code < 0) { + tmp_path = NULL; + mem_error(); + goto error; + } + + fh = fopen(tmp_path, "w"); + if (fh == NULL) { + code = errno; + syslog(LOG_WARNING, "%s: Cannot open %s for writing, errno %d", + PRIVHELPER_ID, tmp_path, code); + goto error; + } + + if (fputs(data, fh) == EOF) { + syslog(LOG_ERR, "%s: Error writing to %s", PRIVHELPER_ID, tmp_path); + goto error; + } + + if (fclose(fh) == EOF) { + syslog(LOG_ERR, "%s: Error closing %s", PRIVHELPER_ID, tmp_path); + goto error; + } + fh = NULL; + + code = RunCommand(1, "/usr/sbin/chown", "root:wheel", tmp_path, NULL); + if (code != 0) { + goto done; + } + + code = RunCommand(1, "/bin/mv", "-f", tmp_path, path); + + done: + free(path); + free(tmp_path); + if (fh != NULL) { + fclose(fh); + } + return code; + + error: + code = -1; + goto done; +} + /** * Run the requested privileged task. * @@ -314,6 +376,9 @@ BackupFile(const char *filename) * - backup: Make a backup copy of the configuration file named in the argument * "filename". This copies file "X" to "X.afscommander_bk". * + * - write: Write data to a given file. The filename is given in the argument + * "filename"; the data to write is in the argument "data". + * * @param[in] task The name of the requested task. * @param[in] event The XPC dictionary containing other task-specific * arguments. @@ -349,6 +414,24 @@ ProcessRequest(const char *task, xpc_object_t event) return -1; } return BackupFile(filename); + + } else if (strcmp(task, "write") == 0) { + const char *filename; + const char *data; + + filename = xpc_dictionary_get_string(event, "filename"); + if (filename == NULL) { + syslog(LOG_WARNING, "%s: Task 'write' missing filename", PRIVHELPER_ID); + return -1; + } + + data = xpc_dictionary_get_string(event, "data"); + if (data == NULL) { + syslog(LOG_WARNING, "%s: Task 'write' missing data", PRIVHELPER_ID); + return -1; + } + + return WriteFile(filename, data); } syslog(LOG_WARNING, "%s: Received unknown task '%s'", PRIVHELPER_ID, task);