|
#!/bin/env ruby
|
|
|
|
require 'socket'
|
|
hostname = Socket.gethostname
|
|
|
|
require 'pp'
|
|
|
|
# TODO handle #<uid>
|
|
def sudo_parse(files)
|
|
newfiles = Array.new
|
|
File.open(file).each_line do |line|
|
|
line.chomp!
|
|
# Handle include files and directories
|
|
if line =~ /^[\t ]*#(include(?:dir)?)[\t ]+([a-zA-Z0-9_.%-]+)/
|
|
type = $1
|
|
node = $2
|
|
node.gsub(/%h/, hostname) # include file param may include hostname substitution
|
|
if !File.exists?(node)
|
|
next
|
|
elsif type == 'include' and File.file?(node)
|
|
newfiles.push(node)
|
|
elsif type == 'includedir' and File.directory?(node)
|
|
newfiles.push(*Dir.entries(node))
|
|
end
|
|
# Skip comments and blank lines
|
|
elsif line =~ /^[\t ]*(#|$)/
|
|
next
|
|
# Handle Defaults
|
|
elsif line =~ /^[\t ]*Defaults(@|[\t ]*)([^\t ]+)/
|
|
puts "Defaults IFS [#{$1}] str [#{$2}]"
|
|
# Handle aliases
|
|
elsif line =~ /^[\t ]*(User|Runas|Host|Cmnd)_Alias[\t ](.+)$/
|
|
puts "type [$1] string [$2]"
|
|
# Handle definition lines
|
|
elsif cap = (line.match(/^\ *
|
|
(?<type>%)? # "%" indicates a group
|
|
(?<name>[a-zA-Z][a-zA-Z0-9_.-]*) # user or group name
|
|
[\t\ ]+
|
|
(?<host>[a-zA-Z0-9_.-]+) # hostname
|
|
[\t\ ]*=[\t\ ]* # "="
|
|
(?: # alternate user/group is optional
|
|
\([\t\ ]* # start runas list
|
|
(?<runas>[a-zA-Z0-9_.,\ -]+) # runas users - will need to split on ","
|
|
(?:: # possibly with groups
|
|
(?<runas_group>[a-zA-Z0-9_.,\ -]+) # runas groups - will need to split on ","
|
|
)?
|
|
[\t\ ]*\) # end runas list
|
|
)?
|
|
[\t\ ]*
|
|
(?<tags>[A-Z:]+:)? # optional settings - will need to split on ':' and ends with ':'
|
|
[\t\ ]*
|
|
(?<command>[a-zA-Z0-9_.,\/\ -]+) # list of commands - split on ","
|
|
/x))
|
|
puts "* #{cap['name']} command [#{cap['command']}]"
|
|
pp cap
|
|
end
|
|
end
|
|
return newfiles
|
|
end
|
|
|
|
sourced = sudo_parse('/etc/sudoers')
|
|
|
|
loop do
|
|
if !sourced.length?
|
|
break
|
|
end
|
|
new_files = Array.new
|
|
sourced.each do |file|
|
|
tmp_list = sudo_parse(file)
|
|
if tmp_list.length?
|
|
new_files.push(*tmp_list)
|
|
end
|
|
end
|
|
sourced = new_files
|
|
end
|
|
|