1/* 2 * This program is free software; you can redistribute it and/or 3 * modify it under the terms of the GNU General Public License as 4 * published by the Free Software Foundation; either version 2 of 5 * the License, or (at your option) any later version. 6 * 7 * This program is distributed in the hope that it will be useful, 8 * but WITHOUT ANY WARRANTY; without even the implied warranty of 9 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 10 * GNU General Public License for more details. 11 * 12 * You should have received a copy of the GNU General Public License 13 * along with this program; if not, write to the Free Software 14 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, 15 * MA 02111-1307 USA 16 */ 17/*************************************************************************** 18 * LPRng - An Extended Print Spooler System 19 * 20 * Copyright 1988-2003, Patrick Powell, San Diego, CA 21 * papowell@lprng.com 22 * See LICENSE for conditions of use. 23 * 24 ***************************************************************************/ 25 26 static char *const _id = 27"$Id: initialize.c,v 1.1.1.1 2008/10/15 03:28:26 james26_jang Exp $"; 28 29#include "lp.h" 30#include "defs.h" 31#include "initialize.h" 32#include "getopt.h" 33#include "child.h" 34#include "gethostinfo.h" 35#include "proctitle.h" 36#include "getqueue.h" 37#include "errorcodes.h" 38/**** ENDINCLUDE ****/ 39 40#ifdef IS_AUX 41# include <compat.h> 42#endif 43#if defined (HAVE_LOCALE_H) 44# include <locale.h> 45#endif 46 47#ifdef HAVE_ARPA_NAMESER_H 48#include <arpa/nameser.h> 49#endif 50 51#ifdef HAVE_RESOLV_H 52#include <resolv.h> 53#endif 54 55 56/*************************************************************************** 57 * general initialization. 58 * This should NOT do any network operations 59 ***************************************************************************/ 60 61void Initialize(int argc, char *argv[], char *envp[], int debugchar ) 62{ 63 char *s; 64 int fd; 65 66 67 /* the gettext facility has been shown to be able to be used to 68 * compromize setuid programs. 69 * remove the slightest possibility of NLSPATH being used in a root 70 * environment 71 */ 72 if( getuid() == ROOTUID || geteuid() == ROOTUID ){ 73#if defined(HAVE_UNSETENV) 74 unsetenv("NLSPATH"); 75#elif defined(HAVE_SETENV) 76 setenv("NLSPATH","",1); 77#elif defined(HAVE_PUTENV) 78 putenv("NLSPATH="); 79#else 80# error require one of unsetenv(), setenv(), or putenv() 81#endif 82 } 83 84 DEBUG1("Initialize: starting"); 85 86 if( argc > 1 ){ 87 s = argv[1]; 88 if( s[0] == '-' && s[1] == debugchar ){ 89 if( s[2] ){ 90 Parse_debug(s+2,1); 91 } else { 92 Parse_debug(argv[2],1); 93 } 94 } 95 } 96 97 if(DEBUGL3){ 98 struct stat statb; 99 int i; 100 LOGDEBUG("Initialize: starting with open fd's"); 101 for( i = 0; i < 20; ++i ){ 102 if( fstat(i,&statb) == 0 ){ 103 LOGDEBUG(" fd %d (0%o)", i, statb.st_mode&S_IFMT); 104 } 105 } 106 } 107 /* 108 open /dev/null on fd 0, 1, 2, 3, 4, if neccessary 109 This must be done before using any other database access 110 functions, as they may open a socket and leave it open. 111 */ 112 if( (fd = open( "/dev/null", O_RDWR, 0600 )) < 0 ){ 113 LOGERR_DIE(LOG_CRIT) "Initialize: cannot open '/dev/null'" ); 114 } 115 Max_open(fd); 116 DEBUG1("Initialize: /dev/null fd %d", fd ); 117 if( Is_server ) while( fd < 5 ){ 118 if( (fd = dup(fd)) < 0 ){ 119 LOGERR_DIE(LOG_CRIT) "Initialize: main cannot dup '/dev/null'" ); 120 } 121 Max_open(fd); 122 } 123 close(fd); 124 125 initsetproctitle( argc, argv, envp ); 126 Name = "UNKNOWN"; 127 if( argv && argv[0] ){ 128 Name = argv[0]; 129 if( (s = strrchr(Name,'/')) ) Name = s+1; 130 } 131 /* set the umask so that you create safe files */ 132 umask( 0077 ); 133 134#ifdef IS_AUX 135 /******************************************** 136 * Apparently this needs to be done for AUX 137 *******************************************/ 138 /* A/UX needs this to be more BSD-compatible. */ 139 setcompat (COMPAT_BSDPROT); 140 set42sig(); 141#endif 142 143 /* set suid information */ 144 Setup_uid(); 145 146 if(DEBUGL3){ 147 struct stat statb; 148 int i; 149 LOGDEBUG("Initialize: before setlocale"); 150 for( i = 0; i < 20; ++i ){ 151 if( fstat(i,&statb) == 0 ){ 152 LOGDEBUG(" fd %d (0%o)", i, statb.st_mode&S_IFMT); 153 } 154 } 155 } 156#if defined (HAVE_LOCALE_H) 157 setlocale(LC_ALL, ""); 158#endif 159 /* FPRINTF(STDERR,"LOCALEDIR '" LOCALEDIR "'\n"); FPRINTF(STDERR,"PACKAGE '" PACKAGE "'\n"); */ 160 bindtextdomain (PACKAGE, LOCALEDIR); 161 textdomain (PACKAGE); 162 163 if(DEBUGL3){ 164 struct stat statb; 165 int i; 166 LOGDEBUG("Initialize: ending with open fd's"); 167 for( i = 0; i < 20; ++i ){ 168 if( fstat(i,&statb) == 0 ){ 169 LOGDEBUG(" fd %d (0%o)", i, statb.st_mode&S_IFMT); 170 } 171 } 172 } 173 174} 175 176void Setup_configuration() 177{ 178 char *s; 179 struct line_list raw; 180 struct line_list order; 181 182 /* Get default configuration file information */ 183#ifdef DMALLOC 184 extern int _dmalloc_outfile_fd; 185 extern char *_dmalloc_logpath; 186 char buffer[SMALLBUFFER]; 187 188 safestrdup("DMALLOC",__FILE__,__LINE__); 189 if( _dmalloc_logpath && _dmalloc_outfile_fd < 0 ){ 190 _dmalloc_outfile_fd = open( _dmalloc_logpath, O_WRONLY | O_CREAT | O_TRUNC, 0666); 191 Max_open(_dmalloc_outfile_fd); 192 } 193 SNPRINTF(buffer,sizeof(buffer))"*** Setup_configuration: pid %d\n", getpid() ); 194 Write_fd_str(_dmalloc_outfile_fd,buffer); 195 DEBUG1("Setup_configuration: _dmalloc_outfile fd %d", _dmalloc_outfile_fd); 196#endif 197 198 Init_line_list(&raw); 199 Init_line_list(&order); 200 Clear_config(); 201 202 203 DEBUG1("Setup_configuration: starting, Allow_getenv %d", 204 Allow_getenv_DYN ); 205 206 /* get the configuration file information if there is any */ 207 if( Allow_getenv_DYN ){ 208 if( getuid() == ROOTUID || geteuid() == ROOTUID ){ 209 FPRINTF( STDERR, 210 "%s: WARNING- LPD_CONF environment variable option enabled\n" 211 " and running as root! You have an exposed security breach!\n" 212 " Recompile without -DGETENV or do not run clients as ROOT\n", 213 Name ); 214 exit(1); 215 } 216 if( (s = getenv( LPD_CONF )) ){ 217 Set_DYN(&Config_file_DYN, s); 218 } 219 } 220 221 DEBUG1("Setup_configuration: Configuration file '%s'", Config_file_DYN ); 222 DEBUG1("Setup_configuration: Require_configfiles_DYN '%d'", 223 Require_configfiles_DYN ); 224 225 Get_config( Is_server || Require_configfiles_DYN, Config_file_DYN ); 226 227 Reset_daemonuid(); 228 if( Is_server ){ 229 Setdaemon_group(); 230 To_daemon(); 231 } else { 232 s = Get_user_information(); 233 Set_DYN( &Logname_DYN, s ); 234 if(s) free(s); s = 0; 235 } 236 DEBUG1( "Is_server %d, DaemonUID %d, DaemonGID %d, UID %d, EUID %d, GID %d, EGID %d", 237 Is_server, DaemonUID, DaemonGID, 238 getuid(), geteuid(), getgid(), getegid() ); 239 240 DEBUG1("Setup_configuration: Host '%s', ShortHost '%s', user '%s'", 241 FQDNHost_FQDN, ShortHost_FQDN, Logname_DYN ); 242 243#ifdef ORIGINAL_DEBUG//JY@1020 244 if(DEBUGL2) Dump_parms( "Setup_configuration - final values", Pc_var_list ); 245#endif 246 247 if( Is_server ){ 248 DEBUG2("Setup_configuration: Printcap_path '%s'", Printcap_path_DYN ); 249 Getprintcap_pathlist( 1, &raw, &PC_filters_line_list, 250 Printcap_path_DYN ); 251 DEBUG2("Setup_configuration: Lpd_printcap_path '%s'", Lpd_printcap_path_DYN ); 252 Getprintcap_pathlist( 0, &raw, &PC_filters_line_list, 253 Lpd_printcap_path_DYN ); 254 DEBUG2("Setup_configuration: Printer_perms_path '%s'", Printer_perms_path_DYN ); 255 Getprintcap_pathlist( 1, &RawPerm_line_list, &Perm_filters_line_list, 256 Printer_perms_path_DYN ); 257 Free_line_list(&Perm_line_list); 258 Merge_line_list(&Perm_line_list,&RawPerm_line_list,0,0,0); 259 } else { 260 DEBUG2("Setup_configuration: Printcap_path '%s'", Printcap_path_DYN ); 261 Getprintcap_pathlist( Require_configfiles_DYN, 262 &raw, &PC_filters_line_list, 263 Printcap_path_DYN ); 264 } 265 Build_printcap_info( &PC_names_line_list, &PC_order_line_list, 266 &PC_info_line_list, &raw, &Host_IP ); 267 /* now we can free up the raw list */ 268 Free_line_list( &raw ); 269 270 /* now we get the user level information */ 271 DEBUG2("Setup_configuration: User_printcap '%s'", User_printcap_DYN ); 272 if( !Is_server && User_printcap_DYN && (s = getenv("HOME")) ){ 273 s = Make_pathname( s, User_printcap_DYN ); 274 DEBUG2("Setup_configuration: User_printcap '%s'", s ); 275 Getprintcap_pathlist( 0, &raw, 0, s ); 276 Build_printcap_info( &PC_names_line_list, &order, 277 &PC_info_line_list, &raw, &Host_IP ); 278 Free_line_list( &raw ); 279 if( s ) free(s); s = 0; 280 /* now we append the names from the order list */ 281 if( order.count > 0 ){ 282 int i; 283 /* append the found ones, remove duplicates */ 284 for( i = 0; i < PC_order_line_list.count; ++i ){ 285 int j; 286 int found = 0; 287 s = PC_order_line_list.list[i]; 288 for( j = 0; !found && j < order.count; ++j ){ 289 found = !strcmp(s, order.list[j]); 290 } 291 if( !found ){ 292 Add_line_list(&order,s,0,0,0); 293 } 294 } 295 Free_line_list( &PC_order_line_list ); 296 for( i = 0; i < order.count; ++i ){ 297 s = order.list[i]; 298 Add_line_list(&PC_order_line_list,s,0,0,0); 299 } 300 } 301 Free_line_list( &order ); 302 } 303#ifdef ORIGINAL_DEBUG//JY@1020 304 if(DEBUGL3){ 305 Dump_line_list("Setup_configuration: PC names", &PC_names_line_list ); 306 Dump_line_list("Setup_configuration: PC order", &PC_order_line_list ); 307 Dump_line_list("Setup_configuration: PC info", &PC_info_line_list ); 308 /* 309 Dump_line_list("Setup_configuration: User_PC names", &User_PC_names_line_list ); 310 Dump_line_list("Setup_configuration: User_PC order", &User_PC_order_line_list ); 311 Dump_line_list("Setup_configuration: User_PC info", &User_PC_info_line_list ); 312 */ 313 Dump_line_list("Setup_configuration: Raw Perms", &RawPerm_line_list ); 314 Dump_line_list("Setup_configuration: Perms", &Perm_line_list ); 315 } 316#endif 317} 318 319/* 320 * char *Get_user_information(void) 321 * OUTPUT: dynamic alloc string 322 * - returns user name 323 */ 324char *Get_user_information( void ) 325{ 326 char *name = 0; 327 char uid_msg[32]; 328 uid_t uid = OriginalRUID; 329 330 struct passwd *pw_ent; 331 332 /* get the password file entry */ 333 if( (pw_ent = getpwuid( uid )) ){ 334 name = pw_ent->pw_name; 335 } 336 if( name == 0 ) name = getenv( "LOGNAME" ); 337 if( name == 0 ) name = getenv( "USER" ); 338 if( name == 0 ){ 339 SNPRINTF( uid_msg, sizeof(uid_msg)) "UID_%d", uid ); 340 name = uid_msg; 341 } 342 name = safestrdup(name,__FILE__,__LINE__); 343 return( name ); 344} 345