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