1/* 2 * Copyright (c) 1997 Metro Link Incorporated 3 * 4 * Permission is hereby granted, free of charge, to any person obtaining a 5 * copy of this software and associated documentation files (the "Software"), 6 * to deal in the Software without restriction, including without limitation 7 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 8 * and/or sell copies of the Software, and to permit persons to whom the 9 * Software is furnished to do so, subject to the following conditions: 10 * 11 * The above copyright notice and this permission notice shall be included in 12 * all copies or substantial portions of the Software. 13 * 14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 17 * THE X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 18 * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF 19 * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 20 * SOFTWARE. 21 * 22 * Except as contained in this notice, the name of the Metro Link shall not be 23 * used in advertising or otherwise to promote the sale, use or other dealings 24 * in this Software without prior written authorization from Metro Link. 25 * 26 */ 27/* 28 * Copyright (c) 1997-2003 by The XFree86 Project, Inc. 29 * 30 * Permission is hereby granted, free of charge, to any person obtaining a 31 * copy of this software and associated documentation files (the "Software"), 32 * to deal in the Software without restriction, including without limitation 33 * the rights to use, copy, modify, merge, publish, distribute, sublicense, 34 * and/or sell copies of the Software, and to permit persons to whom the 35 * Software is furnished to do so, subject to the following conditions: 36 * 37 * The above copyright notice and this permission notice shall be included in 38 * all copies or substantial portions of the Software. 39 * 40 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 41 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 42 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL 43 * THE COPYRIGHT HOLDER(S) OR AUTHOR(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR 44 * OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 45 * ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 46 * OTHER DEALINGS IN THE SOFTWARE. 47 * 48 * Except as contained in this notice, the name of the copyright holder(s) 49 * and author(s) shall not be used in advertising or otherwise to promote 50 * the sale, use or other dealings in this Software without prior written 51 * authorization from the copyright holder(s) and author(s). 52 */ 53 54#ifdef HAVE_XORG_CONFIG_H 55#include <xorg-config.h> 56#endif 57 58#include "os.h" 59#include "xf86Parser.h" 60#include "xf86tokens.h" 61#include "Configint.h" 62 63#include <unistd.h> 64#include <sys/types.h> 65#include <sys/wait.h> 66#include <errno.h> 67 68#if defined(HAVE_SETEUID) && defined(_POSIX_SAVED_IDS) && _POSIX_SAVED_IDS > 0 69#define HAS_SAVED_IDS_AND_SETEUID 70#endif 71#if defined(WIN32) 72#define HAS_NO_UIDS 73#endif 74 75static int 76doWriteConfigFile(const char *filename, XF86ConfigPtr cptr) 77{ 78 FILE *cf; 79 80 if ((cf = fopen(filename, "w")) == NULL) { 81 return 0; 82 } 83 84 if (cptr->conf_comment) 85 fprintf(cf, "%s\n", cptr->conf_comment); 86 87 xf86printLayoutSection(cf, cptr->conf_layout_lst); 88 89 if (cptr->conf_files != NULL) { 90 fprintf(cf, "Section \"Files\"\n"); 91 xf86printFileSection(cf, cptr->conf_files); 92 fprintf(cf, "EndSection\n\n"); 93 } 94 95 if (cptr->conf_modules != NULL) { 96 fprintf(cf, "Section \"Module\"\n"); 97 xf86printModuleSection(cf, cptr->conf_modules); 98 fprintf(cf, "EndSection\n\n"); 99 } 100 101 xf86printVendorSection(cf, cptr->conf_vendor_lst); 102 103 xf86printServerFlagsSection(cf, cptr->conf_flags); 104 105 xf86printInputSection(cf, cptr->conf_input_lst); 106 107 xf86printInputClassSection(cf, cptr->conf_inputclass_lst); 108 109 xf86printOutputClassSection(cf, cptr->conf_outputclass_lst); 110 111 xf86printVideoAdaptorSection(cf, cptr->conf_videoadaptor_lst); 112 113 xf86printModesSection(cf, cptr->conf_modes_lst); 114 115 xf86printMonitorSection(cf, cptr->conf_monitor_lst); 116 117 xf86printDeviceSection(cf, cptr->conf_device_lst); 118 119 xf86printScreenSection(cf, cptr->conf_screen_lst); 120 121 xf86printDRISection(cf, cptr->conf_dri); 122 123 xf86printExtensionsSection(cf, cptr->conf_extensions); 124 125 fclose(cf); 126 return 1; 127} 128 129int 130xf86writeConfigFile(const char *filename, XF86ConfigPtr cptr) 131{ 132#ifndef HAS_NO_UIDS 133 int ret; 134 135 if (getuid() != geteuid()) { 136 137#if !defined(HAS_SAVED_IDS_AND_SETEUID) 138 int pid, p; 139 int status; 140 void (*csig) (int); 141 142 /* Need to fork to change ruid without losing euid */ 143 csig = OsSignal(SIGCHLD, SIG_DFL); 144 switch ((pid = fork())) { 145 case -1: 146 ErrorF("xf86writeConfigFile(): fork failed (%s)\n", 147 strerror(errno)); 148 return 0; 149 case 0: /* child */ 150 if (setuid(getuid()) == -1) 151 FatalError("xf86writeConfigFile(): " 152 "setuid failed(%s)\n", strerror(errno)); 153 ret = doWriteConfigFile(filename, cptr); 154 exit(ret); 155 break; 156 default: /* parent */ 157 do { 158 p = waitpid(pid, &status, 0); 159 } while (p == -1 && errno == EINTR); 160 } 161 OsSignal(SIGCHLD, csig); 162 if (p != -1 && WIFEXITED(status) && WEXITSTATUS(status) == 0) 163 return 1; /* success */ 164 else 165 return 0; 166 167#else /* HAS_SAVED_IDS_AND_SETEUID */ 168 int ruid, euid; 169 170 ruid = getuid(); 171 euid = geteuid(); 172 173 if (seteuid(ruid) == -1) { 174 ErrorF("xf86writeConfigFile(): seteuid(%d) failed (%s)\n", 175 ruid, strerror(errno)); 176 return 0; 177 } 178 ret = doWriteConfigFile(filename, cptr); 179 180 if (seteuid(euid) == -1) { 181 ErrorF("xf86writeConfigFile(): seteuid(%d) failed (%s)\n", 182 euid, strerror(errno)); 183 } 184 return ret; 185 186#endif /* HAS_SAVED_IDS_AND_SETEUID */ 187 188 } 189 else 190#endif /* !HAS_NO_UIDS */ 191 return doWriteConfigFile(filename, cptr); 192} 193