From fc887d26c72348a4f494b5d43af66244c725ce67 Mon Sep 17 00:00:00 2001 From: Peter Palfrader Date: Thu, 3 May 2007 11:06:52 +0000 Subject: Implement php as cgi with cgi-fast git-svn-id: svn+ssh://asteria.noreply.org/svn/weaselutils/trunk@267 bc3d92e2-beff-0310-a7cd-cc87d7ac0ede --- bin/ldap2apache | 255 +++++++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 190 insertions(+), 65 deletions(-) (limited to 'bin') diff --git a/bin/ldap2apache b/bin/ldap2apache index fa9cfc3..51f1207 100755 --- a/bin/ldap2apache +++ b/bin/ldap2apache @@ -10,6 +10,7 @@ require "ldap" require "getoptlong" require "myldap" require "yaml" +require "etc" @config = YAML::load( File.open( '/etc/noreply/config' ) ) ldap = MyLDAP.new(@config, "ldap2apache") @@ -22,20 +23,28 @@ clients = ldap.conn.search2(@config['basedn'], LDAP::LDAP_SCOPE_SUBTREE, 'object @defaultbindhttpport = @config['module']['apache']['defaultbindhttpport'] @defaultbindhttpsport = @config['module']['apache']['defaultbindhttpsport'] @configdir = @config['module']['apache']['configdir'] +@phpinipreamble = @config['module']['apache']['phpinipreamble'] +@phpwrapperfilesdir = @config['module']['apache']['phpwrapperfilesdir'] +@phpinifilesdir = @config['module']['apache']['phpinifilesdir'] @postgres_uid = @config['module']['apache']['postgres_uid'] @www_gid = @config['module']['apache']['www_gid'] @configtest = @config['module']['apache']['configtest'] @reload = @config['module']['apache']['reload'] +@restart = @config['module']['apache']['restart'] @statsbind = @config['module']['apache']['statsbind'] @statsvhostaddto = @config['module']['apache']['statsvhostaddto'] files = {} +phpinifiles = {} +phpwrapperfiles = {} def mkdir(dir, mode, uid, gid) Dir.mkdir(dir, mode) unless File.exists?(dir) # unless file is a symlink unless FileTest.symlink?(dir) File.chown(uid, gid, dir) == 1 or throw "chown #{dir} failed" + chmodded = File.chmod(mode, dir) + throw "Could not chmod #{dir} to #{mode}" unless chmodded == 1 end end @@ -64,7 +73,7 @@ clients.each{ |c| property[key] = val } end - property['php'] = "no" unless property['php'] == "yes" + property['php'] = "no" unless %w(yes no cgi5).include?property['php'] dirindex = vhost['tnWebVHostDirectoryIndex'][0] if vhost['tnWebVHostDirectoryIndex'] @@ -78,30 +87,61 @@ clients.each{ |c| cgidiraddto = vhost['tnWebVHostCgiDirAddto'][0].gsub("\n", "\n\t") if vhost['tnWebVHostCgiDirAddto'] ssl = true if property['https'] == "only" - vhostuid = property['DirOwnerUserNumber'] ? property['DirOwnerUserNumber'].to_i : uid - vhostgid = property['DirOwnerGroupNumber'] ? property['DirOwnerGroupNumber'].to_i : gid + vhostuid = uid + vhostgid = gid + if property['vhostUser'] + u = Etc.getpwnam(property['vhostUser']) + vhostuid = u['uid'] + vhostgid = u['gid'] + end + if property['vhostGroup'] + g = Etc.getgrnam(property['vhostGroup']) + vhostgid = g['gid'] + end + vhostuidname = Etc.getpwuid(vhostuid)['name'] + vhostgidname = Etc.getgrgid(vhostgid)['name'] umask=File.umask File.umask(0000) - mkdir(home, 02755, vhostuid, vhostgid) - mkdir(home+"/htdocs", 02755, vhostuid, vhostgid) - mkdir(home+"/bin", 02755, 0, vhostgid) + if property['permissionstyle'] == "new" + mkdir(home, 00750, vhostuid, @www_gid) + else + mkdir(home, 02755, vhostuid, vhostgid) + end + if vhostgid != gid + mkdir(home+"/htdocs", 02775, vhostuid, vhostgid) + mkdir(home+"/bin", 02775, 0, vhostgid) + else + mkdir(home+"/htdocs", 02755, vhostuid, vhostgid) + mkdir(home+"/bin", 02755, 0, vhostgid) + end mkdir(home+"/cgi-bin", 02755, vhostuid, vhostgid) if property['cgi-bin'] == "yes" - mkdir(home+"/tmp", 03775, vhostuid, @www_gid) + if property['php'] == "cgi5" + mkdir(home+"/tmp", 00770, vhostuid, vhostgid) + elsif property['php']!="no" + mkdir(home+"/tmp", 03775, vhostuid, @www_gid) + else + Dir.rmdir( home+"/tmp" ) if File.exists?(home+"/tmp") + end File.umask(umask) - basedir = "#{home}" - if property['open_basedir'] - if property['open_basedir'] != "none" - basedir += ":" + property['open_basedir'] - else - basedir = nil + config = [] + basedir = nil + unless property['php'] == "cgi5" + basedir = "#{home}" + if property['open_basedir'] + if property['open_basedir'] != "none" + basedir += ":" + property['open_basedir'] + else + basedir = nil + end + end + if property['safemode_include'] + safemode_include = property['safemode_include'] end end - if property['safemode_include'] - safemode_include = property['safemode_include'] - end - config = [] + + if ssl crtfile = "/etc/ssl/certs/apache-#{server_name}.pem" keyfile = "/etc/ssl/private/apache-#{server_name}.key" @@ -130,35 +170,34 @@ clients.each{ |c| config << " RewriteRule ^/(.*) %s://#{server_name}/$1 [R]"%[ ( ssl ? 'https' : 'http' ) ] end config << "" - config << " UserDir disabled" unless property['userdir'] == "yes" - config << " SuexecUserGroup #{c['uid']} #{c['uid']}" unless property['setusergroup'] == "no" - #config << " User #{c['uid']}" unless property['setusergroup'] == "no" - #config << " Group #{c['uid']}" unless property['setusergroup'] == "no" + unless property['userdir'] == "yes" + config << " " + config << " UserDir disabled" + config << " " + end + config << " SuexecUserGroup #{vhostuidname} #{vhostgidname}" unless property['setusergroup'] == "no" config << " ErrorLog #{client_home}/logs/#{server_name}-error.log" config << " LogLevel warn" config << " CustomLog #{client_home}/logs/#{server_name}-access.log combined" config << " ServerSignature On" config << "" - # webstats - #config << " # Alias " + @webstat_location + " " + @rmagicdir + "/" + server_name + "/" - #config << ' Alias /awstats-classes/ "/usr/share/awstats/classes/"' - #config << ' Alias /awstats-css/ "/usr/share/awstats/css/"' - #config << ' Alias /awstats-icon/ "/usr/share/awstats/icon/"' - #config << " ScriptAlias /cgi-stats/awstats.pl /usr/lib/cgi-bin/awstats.pl" - #config << " Redirect permanent " + @webstat_location + " http://"+server_name+"/cgi-stats/awstats.pl" config << "" - unless property['php'] == "no" - config << " php_admin_value engine 1" + if property['php'] == "yes" + config << " " + config << " php_admin_value engine 1" unless property['safe_mode'] == "no" - config << " php_admin_value safe_mode 1" - config << " php_admin_value safe_mode_gid 1" - config << " php_admin_value safe_mode_exec_dir \"#{home}/bin\"" + config << " php_admin_value safe_mode 1" + config << " php_admin_value safe_mode_gid 1" + config << " php_admin_value safe_mode_exec_dir \"#{home}/bin\"" end - config << " php_admin_value upload_tmp_dir \"#{home}/tmp\"" - config << " php_admin_value sendmail_path \"/usr/sbin/sendmail -t -i -f #{server_admin}\"" - config << " php_admin_value allow_url_fopen 0" - else - config << " php_admin_value engine off" + config << " php_admin_value upload_tmp_dir \"#{home}/tmp\"" + config << " php_admin_value sendmail_path \"/usr/sbin/sendmail -t -i -f #{server_admin}\"" + config << " php_admin_value allow_url_fopen 0" + config << " " + elsif property['php'] == "no" + config << " " + config << " php_admin_value engine off" + config << " " config << " AddType text/plain .php3" config << " AddType text/plain .php3s" config << " AddType text/plain .php" @@ -168,15 +207,16 @@ clients.each{ |c| unless property['document_root'] == "manual" config << " DocumentRoot #{home}/htdocs" end - config << "# " config << " " - config << " AllowOverride FileInfo AuthConfig Limit Indexes Options" + config << " #AllowOverride FileInfo AuthConfig Limit Indexes Options" config << " IndexOptions FancyIndexing NameWidth=*" - unless property['php'] == "no" - config << " php_value magic_quotes_gpc 0" - config << " php_admin_value open_basedir \"#{basedir}\"" if basedir - config << " php_admin_value safe_mode_include_dir \"#{safemode_include}\"" if safemode_include - config << " php_value include_path \".:#{home}/include:/usr/share/php:/usr/share/pear\"" if basedir + if property['php'] == "yes" + config << " " + config << " php_value magic_quotes_gpc 0" + config << " php_admin_value open_basedir \"#{basedir}\"" if basedir + config << " php_admin_value safe_mode_include_dir \"#{safemode_include}\"" if safemode_include + config << " php_value include_path \".:#{home}/include:/usr/share/php:/usr/share/pear\"" + config << " " end config << " Options #{docdiroptions}" if docdiroptions != "" config << " #{docdiraddto}" if docdiraddto @@ -194,7 +234,49 @@ clients.each{ |c| config << " Allow from all" end config << " " - config << "# " + + if property['php'] == "cgi5" + throw "@config['module']['apache']['phpwrapperfilesdir'] is not defined, yet we use php-cgi" unless @phpwrapperfilesdir + if property['open_basedir'] or property['safemode_include'] + STDERR.puts "Warning: open_basedir and safemode_include not supported with php-cgi" + end + phpini = [] + phpini.concat IO.readlines(@phpinipreamble).collect{|a| a.chop} if @phpinipreamble and FileTest.exists?(@phpinipreamble) + phpini << "[PHP]" + phpini << "upload_tmp_dir = \"#{home}/tmp\"" + phpini << "sendmail_path = \"/usr/sbin/sendmail -t -i -f #{server_admin}\"" + phpini << "allow_url_fopen = 0" + phpini << "magic_quotes_gpc = 0" + phpini << "include_path = \".:#{home}/include:/usr/share/php:/usr/share/pear\"" + + inilp = c['o'][0] +"-"+ server_name + throw "Clash on #{server_name} of client#{c['o'][0]} for phpinifiles" if phpinifiles[ inilp ] + phpinifiles[ inilp ] = phpini + + + + wrap = [] + wrap << "#!/bin/bash" + wrap << "" + wrap << "exec /usr/bin/php5-cgi --php-ini #{@phpinifilesdir}/#{inilp} \"$@\"" + + wraplp1 = "#{vhostuid}=#{vhostgid}" + wraplp2 = "php-#{server_name}" + phpwrapperfiles[wraplp1] = {} unless phpwrapperfiles[wraplp1] + throw "Clash on #{server_name} of client#{c['o'][0]} for phpwrapperfiles" if phpwrapperfiles[wraplp1][wraplp2] + phpwrapperfiles[wraplp1][wraplp2] = wrap + + + phppath = "#{@phpwrapperfilesdir}/#{wraplp1}/#{wraplp2}" + config << " " + config << " AddHandler fcgid-script .php" + config << " FCGIWrapper #{phppath} .php" + config << " " + config << " Options ExecCGI" + config << " " + config << " " + end + if property['cgi-bin'] == "yes" cgihome = home.gsub(/^\/srv\/www\/vhosts/, '/var/www/vhosts') config << " ScriptAlias /cgi-bin #{cgihome}/cgi-bin" @@ -229,7 +311,9 @@ clients.each{ |c| config << " ServerName #{server_name}" config << " ServerAlias #{server_aliases}" if server_aliases != "" config << " ServerAdmin #{server_admin}" - config << " UserDir disabled" + config << " " + config << " UserDir disabled" + config << " " config << " ErrorLog #{client_home}/logs/#{server_name}-error.log" config << " LogLevel warn" config << " CustomLog #{client_home}/logs/#{server_name}-access.log combined" @@ -250,7 +334,9 @@ clients.each{ |c| config << "" config << " ServerName #{server_name}" config << " ServerAdmin #{server_admin}" - config << " UserDir disabled" + config << " " + config << " UserDir disabled" + config << " " config << "# ErrorLog #{client_home}/logs/stats.#{server_name}-error.log" config << "# LogLevel warn" config << "# CustomLog #{client_home}/logs/stats.#{server_name}-access.log combined" @@ -273,28 +359,67 @@ clients.each{ |c| } } -need_reload = false -Dir.entries( @configdir ).each{ |e| - next if ((e =~ /^\./) != nil) - next if files.has_key?( e ) - File.unlink( @configdir + '/' + e ) - need_reload = true -} -files.each_pair{ |name, config| - filename = @configdir + '/' + name - conf = config.join("\n") + "\n" - on_disk = FileTest.exists?(filename) ? File.read(filename) : nil - next if on_disk == conf +def write_files(basedir, f, mode=0644, uid=nil, gid=nil) + need_reload = false + Dir.entries( basedir ).each{ |e| + next if ((e =~ /^\./) != nil) + next if f.has_key?( e ) + File.unlink( basedir + '/' + e ) + need_reload = true + } + f.each_pair{ |name, config| + filename = basedir + '/' + name + conf = config.join("\n") + "\n" + on_disk = FileTest.exists?(filename) ? File.read(filename) : nil + next if on_disk == conf + + f = File.new( filename, "w" ) + f.chmod(mode) + f.write(conf) + f.close + File.chown(uid, gid, filename) if uid or gid + + need_reload = true + } + return need_reload +end + + + +if phpinifiles.size > 0 + throw "@config['module']['apache']['phpinifilesdir'] is not defined, yet we use php-cgi" unless @phpinifilesdir + throw "@config['module']['apache']['restart'] is not defined, yet we use php-cgi" unless @restart +end + +need_reload = write_files(@configdir, files) +need_restart = write_files(@phpinifilesdir, phpinifiles) if @phpinifilesdir +phpwrapperfilesdirectories = {} +phpwrapperfiles.each_pair do |dirname, wrappers| + m = /^(.*)=(.*)$/.match dirname + throw "Could not parse phpwrapperfilesdir dirname #{dirname}" unless m - f = File.new( filename, "w" ) - f.write(conf) - f.close + dir = @phpwrapperfilesdir + '/' + dirname + mkdir(dir, 0755, m[1].to_i, m[2].to_i) unless File.exists?(dir) + write_files(dir, wrappers, 0755, m[1].to_i, m[2].to_i) + phpwrapperfilesdirectories[dirname] = true +end +Dir.entries( @phpwrapperfilesdir ).each do |e| + next if ((e =~ /^\./) != nil) + next if phpwrapperfilesdirectories.has_key?( e ) + Dir.entries( @phpwrapperfilesdir+'/'+e ).each do |e2| + next if ((e2 =~ /^\./) != nil) and File.directory?(@phpwrapperfilesdir+'/'+e+'/'+e2) + File.unlink( @phpwrapperfilesdir+'/'+e+'/'+e2 ) + end + Dir.rmdir( @phpwrapperfilesdir+'/'+e ) need_reload = true -} +end -if need_reload +if need_restart + system(@configtest) or throw "Configtest returned errors." + system(@restart) or throw "Restart returned errors." +elsif need_reload system(@configtest) or throw "Configtest returned errors." system(@reload) or throw "Reload returned errors." end -- cgit v1.2.3