Skip to content

Instantly share code, notes, and snippets.

@colinbm
Last active December 22, 2015 17:38
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save colinbm/6507094 to your computer and use it in GitHub Desktop.
Save colinbm/6507094 to your computer and use it in GitHub Desktop.
Allow any user to change the group of a file or directory within their home directory to www-data. Usage sudo chown-www-data <path>
#! /usr/bin/env ruby
require 'pathname'
require 'etc'
require 'shellwords'
path = ARGV.first
user = ENV['SUDO_USER']
SAFE_PATH_PREFIX = "/home/#{user}/"
# Resolve any symlinks in the path
path = Pathname.new(path).realpath.to_s
# Make sure the path is valid
unless path[0, SAFE_PATH_PREFIX.length] == SAFE_PATH_PREFIX
puts "path is illegal"
exit 1
end
# Make sure the path is owned by the calling user
unless Etc.getpwuid(File.stat(path).uid).name == user
puts "path is not owned by #{user}"
exit 2
end
# Make sure it's either a file or directory - i.e. not a block device or anything else dodgy
unless File.file?(path) || File.directory?(path)
puts "path is neither file or directory"
exit 3
end
# Make sure there's only one link to the inode.
if File.file?(path) && File.stat(path).nlink > 1
puts "there is more than one hard link to this file"
exit 4
end
exec "chgrp www-data #{Shellwords.escape(path)}"
@inhumantsar
Copy link

I'm not familiar with Ruby on the command line. I'd double check the File.file? and File.directory? in the docs to be sure that they definitely won't respond True to a symlink. This looks like it'd be a safe bet though.

@colinbm
Copy link
Author

colinbm commented Sep 11, 2013

@inhumantsar Thanks. The Pathname.new(path).realpath bit should take care of that, as it resolves any symlinks.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment