1/* 2 * Copyright (c) 2000-2004 Apple Computer, Inc. All rights reserved. 3 * 4 * @APPLE_LICENSE_HEADER_START@ 5 * 6 * This file contains Original Code and/or Modifications of Original Code 7 * as defined in and that are subject to the Apple Public Source License 8 * Version 2.0 (the 'License'). You may not use this file except in 9 * compliance with the License. Please obtain a copy of the License at 10 * http://www.opensource.apple.com/apsl/ and read it before using this 11 * file. 12 * 13 * The Original Code and all software distributed under the License are 14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER 15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, 16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, 17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. 18 * Please see the License for the specific language governing rights and 19 * limitations under the License. 20 * 21 * @APPLE_LICENSE_HEADER_END@ 22 */ 23 24#include <mach/mach.h> 25#include <mach/mach_error.h> 26#include <servers/bootstrap.h> 27#include <sys/types.h> 28#include <sys/wait.h> 29#include <sys/errno.h> 30#include <sys/mount.h> 31#include <unistd.h> 32#include <stdlib.h> 33#include <asl.h> 34#include <stdio.h> 35#include "load_webdavfs.h" 36 37#include "webdavfs_load_kext.h" 38#include "webdavfs_load_kextServer.h" 39 40/*****************************************************************************/ 41 42/* Local Definitions */ 43 44#define CFENVFORMATSTRING "__CF_USER_TEXT_ENCODING=0x%X:0:0" 45 46union MaxMsgSize { 47 union __RequestUnion__webdavfs_load_kext_subsystem req; 48 union __ReplyUnion__webdavfs_load_kext_subsystem rep; 49}; 50 51/*****************************************************************************/ 52 53static int LoadKext(const char *inKextPath) 54{ 55 int pid; 56 int result = -1; 57 union wait status; 58 59 pid = fork(); 60 if (pid == 0) 61 { 62 char CFUserTextEncodingEnvSetting[sizeof(CFENVFORMATSTRING) + 20]; 63 char *env[] = {CFUserTextEncodingEnvSetting, "", (char *) 0 }; 64 65 /* 66 * Create a new environment with a definition of __CF_USER_TEXT_ENCODING to work 67 * around CF's interest in the user's home directory (which could be networked, 68 * causing recursive references through automount). Make sure we include the uid 69 * since CF will check for this when deciding if to look in the home directory. 70 */ 71 snprintf(CFUserTextEncodingEnvSetting, sizeof(CFUserTextEncodingEnvSetting), CFENVFORMATSTRING, getuid()); 72 73 result = execle(KEXT_LOAD_PATH, KEXT_LOAD_PATH, inKextPath, NULL, env); 74 /* We can only get here if the exec failed */ 75 _exit (errno); 76 } 77 78 if (pid == -1) 79 { 80 result = errno; 81 goto Return; 82 } 83 84 /* Success! */ 85 if ((wait4(pid, (int *) &status, 0, NULL) == pid) && (WIFEXITED(status))) 86 { 87 result = status.w_retcode; 88 } 89 else 90 { 91 result = EIO; 92 } 93 94Return: 95 96 return (result); 97} 98 99/*****************************************************************************/ 100 101kern_return_t do_load_kext(mach_port_t test_port __attribute__((unused)), string_t kextname) 102{ 103 int error = KERN_SUCCESS; 104 struct vfsconf vfc; 105 106 if(geteuid() != 0) 107 { 108 asl_log(NULL, NULL, ASL_LEVEL_ERR, "Need to be root to load kext euid = %d!\n", geteuid()); 109 return EACCES; 110 } 111 112 if (strcmp(kextname, WEBDAVFS_VFSNAME) == 0) { 113 if (getvfsbyname(WEBDAVFS_VFSNAME, &vfc) != 0) 114 error = LoadKext(WEBDAV_KEXT_PATH); 115 } else 116 error = ENOENT; 117 118 return error; 119 120} 121 122/*****************************************************************************/ 123 124static mach_port_t checkin_or_register(const char *bname) 125{ 126 kern_return_t kr; 127 mach_port_t mp; 128 129 /* If we're started by launchd or the old mach_init */ 130 kr = bootstrap_check_in(bootstrap_port, (const char *)bname, &mp); 131 if (kr == KERN_SUCCESS) 132 return mp; 133 /* If not then get out */ 134 exit(EXIT_FAILURE); 135} 136 137/*****************************************************************************/ 138 139int main(void) 140{ 141 mach_msg_size_t mxmsgsz = (mach_msg_size_t)(sizeof(union MaxMsgSize) + MAX_TRAILER_SIZE); 142 mach_port_t mp = checkin_or_register(WEBDAVFS_LOAD_KEXT_BOOTSTRAP_NAME); 143 kern_return_t kr; 144 145 kr = mach_msg_server_once(webdavfs_load_kext_server, mxmsgsz, mp, 0); 146 if (kr != KERN_SUCCESS) { 147 asl_log(NULL, NULL, ASL_LEVEL_DEBUG, "mach_msg_server(mp): %s\n", mach_error_string(kr)); 148 exit(EXIT_FAILURE); 149 } 150 151 exit(EXIT_SUCCESS); 152} 153 154/*****************************************************************************/ 155