diff -uNr jailkit-2.14.orig/py/jk_cp.in jailkit-2.14/py/jk_cp.in
--- jailkit-2.14.orig/py/jk_cp.in	2011-01-27 09:21:56.000000000 +0100
+++ jailkit-2.14/py/jk_cp.in	2012-04-27 14:42:08.000000000 +0200
@@ -43,7 +43,8 @@
 import jk_lib
 
 def startcopy(config, chroot, filestocopy, checklibs=1):
-	jk_lib.copy_binaries_and_libs(chroot,filestocopy,config['force'] , config['verbose'], try_hardlink=config['hardlink'], retain_owner=config['retainowner'])
+	jk_lib.copy_binaries_and_libs(chroot,filestocopy,config['force'] , config['verbose'], try_hardlink=config['hardlink'], 
+        allow_suid=config['retainsetuid'], retain_owner=config['retainowner'])
 	jk_lib.gen_library_cache(chroot)
 
 def usage():
@@ -55,6 +56,7 @@
 	print "-f, --force        : overwrite existing files"
 	print "-k, --hardlink     : use hardlinks if possible"
 	print "-o, --owner        : retain file ownership and group"
+	print "-s, --setuid       : retain file setuid/setgid bits"
 	print "\nNote: if no jail is specified, the first argument is\nconsidered to be the jail\n"
 
 def testargs(jail, args):
@@ -78,7 +80,7 @@
 		print 'cannot run without root privileges'
 		sys.exit(5)
 	try:
-		opts, args = getopt.getopt(sys.argv[1:], 'fh?vkoj:', ['help', 'verbose', 'force', 'hardlink', 'owner', 'jail'])
+		opts, args = getopt.getopt(sys.argv[1:], 'fh?vkojs:', ['help', 'verbose', 'force', 'hardlink', 'owner', 'jail', 'setuid'])
 	except getopt.GetoptError:
 		usage()
 		sys.exit(1)
@@ -87,6 +89,7 @@
 	config['force'] = 0
 	config['hardlink'] = 0
 	config['retainowner'] = 0
+	config['retainsetuid'] = 0
 	jail = None
 	for o, a in opts:
 		if o in ("-h",'?', "--help"):
@@ -102,6 +105,8 @@
 			config['hardlink'] = 1
 		if o in ("-o", "--owner"):
 			config['retainowner'] = 1
+		if o in ("-s", "--setuid"):
+			config['retainsetuid'] = 1
 	if (jail == None and len(args)>0 ):
 		jail = args[0]
 		args = args[1:]
diff -uNr jailkit-2.14.orig/py/jk_init.in jailkit-2.14/py/jk_init.in
--- jailkit-2.14.orig/py/jk_init.in	2010-09-05 22:12:58.000000000 +0200
+++ jailkit-2.14/py/jk_init.in	2012-04-27 11:41:41.000000000 +0200
@@ -110,6 +110,10 @@
 		if (len(paths_w_owner)>0):
 			self.didfiles = jk_lib.copy_binaries_and_libs(chroot, paths_w_owner, config['force'], config['verbose'], check_libs=1, try_hardlink=config['hardlink'], retain_owner=1,try_glob_matching=1, handledfiles=self.didfiles)
 		
+		paths_w_setuid = jk_lib.config_get_option_as_list(cfg,section,'paths_w_setuid')
+		if (len(paths_w_setuid)>0):
+			self.didfiles = jk_lib.copy_binaries_and_libs(chroot, paths_w_setuid, config['force'], config['verbose'], check_libs=1, try_hardlink=config['hardlink'], allow_suid=1, retain_owner=1, try_glob_matching=3, handledfiles=self.didfiles)
+		
 		emptydirs = jk_lib.config_get_option_as_list(cfg,section,'emptydirs')
 		for edir in emptydirs:
 	#		print 'DEBUG emptydir='+edir
diff -uNr jailkit-2.14.orig/py/jk_lib.py jailkit-2.14/py/jk_lib.py
--- jailkit-2.14.orig/py/jk_lib.py	2011-04-28 10:30:44.000000000 +0200
+++ jailkit-2.14/py/jk_lib.py	2012-04-27 15:19:08.000000000 +0200
@@ -315,10 +315,12 @@
 			mode = (mode & ~stat.S_ISUID) & ~stat.S_ISGID
 #			print 'setuid!!! after mode='+str(mode)
 #		print 'mode='+str(mode)
-	os.chmod(dst, mode)
 	os.utime(dst, (sbuf[stat.ST_ATIME], sbuf[stat.ST_MTIME]))
 	if (copy_ownership):
 		os.chown(dst, sbuf[stat.ST_UID], sbuf[stat.ST_GID])
+	#WARNING: chmod must be AFTER chown to preserve setuid/setgid bits
+	os.chmod(dst, mode)
+
 
 def OLDreturn_existing_base_directory(path):
 	"""This function tests if a directory exists, if not tries the parent etc. etc. until it finds a directory that exists"""
@@ -518,8 +520,8 @@
 	else:
 		print 'Not everything was copied to '+dstdir+', keeping the old directory '+srcdir
 
-def copy_with_permissions(src, dst, be_verbose=0, try_hardlink=1, retain_owner=0):
-	"""copies/links the file and the permissions, except any setuid or setgid bits"""
+def copy_with_permissions(src, dst, be_verbose=0, try_hardlink=1, allow_suid=0, retain_owner=0):
+	"""copies/links the file and the permissions (and possibly ownership and setuid/setgid bits"""
 	do_normal_copy = 1
 	if (try_hardlink==1):
 		try:
@@ -531,7 +533,7 @@
 	if (do_normal_copy == 1):
 		try:
 			shutil.copyfile(src,dst)
-			copy_time_and_permissions(src, dst, be_verbose, allow_suid=0, copy_ownership=retain_owner)
+			copy_time_and_permissions(src, dst, be_verbose, allow_suid=allow_suid, copy_ownership=retain_owner)
 		except (IOError, OSError), (errno,strerror):
 			sys.stderr.write('ERROR: copying file and permissions '+src+' to '+dst+': '+strerror+'\n')
 
@@ -575,21 +577,21 @@
 		print 'use "mknod '+chrootpath+' mode major minor" to create the device'
 		print 'use chmod and chown to set the permissions as found by ls -l'
 
-def copy_dir_recursive(chroot,dir,force_overwrite=0, be_verbose=0, check_libs=1, try_hardlink=1, retain_owner=0, handledfiles=[]):
-	"""copies a directory and the permissions recursive, except any setuid or setgid bits"""
+def copy_dir_recursive(chroot,dir,force_overwrite=0, be_verbose=0, check_libs=1, try_hardlink=1, allow_suid=0, retain_owner=0, handledfiles=[]):
+	"""copies a directory and the permissions recursively, possibly with ownership and setuid/setgid bits"""
 	files2 = ()
 	for entry in os.listdir(dir):
 		tmp = os.path.join(dir, entry)
 		try:
 			sbuf = cachedlstat(tmp)
 			if (stat.S_ISDIR(sbuf.st_mode)):
-				create_parent_path(chroot, tmp, be_verbose=be_verbose, copy_permissions=1, allow_suid=0, copy_ownership=retain_owner)			
-				handledfiles = copy_dir_recursive(chroot,tmp,force_overwrite, be_verbose, check_libs, try_hardlink, retain_owner, handledfiles)
+				create_parent_path(chroot, tmp, be_verbose=be_verbose, copy_permissions=1, allow_suid=allow_suid, copy_ownership=retain_owner)			
+				handledfiles = copy_dir_recursive(chroot,tmp,force_overwrite, be_verbose, check_libs, try_hardlink, allow_suid, retain_owner, handledfiles)
 			else:
 				files2 += os.path.join(dir, entry),
 		except OSError, e:
 			sys.stderr.write('ERROR: failed to investigate source file '+tmp+': '+e.strerror+'\n')
-	handledfiles = copy_binaries_and_libs(chroot,files2,force_overwrite, be_verbose, check_libs, try_hardlink, retain_owner, handledfiles)
+	handledfiles = copy_binaries_and_libs(chroot,files2,force_overwrite, be_verbose, check_libs, try_hardlink, allow_suid, retain_owner, handledfiles)
 	return handledfiles 
 #	for root, dirs, files in os.walk(dir):
 #		files2 = ()
@@ -608,7 +610,7 @@
 # try to lstat(/srv/jail/opt/bin/foo) and you get the result for /usr/bin/foo
 # so use resolve_realpath to find you want lstat(/srv/jail/usr/bin/foo)
 #
-def copy_binaries_and_libs(chroot, binarieslist, force_overwrite=0, be_verbose=0, check_libs=1, try_hardlink=1, retain_owner=0, try_glob_matching=0, handledfiles=[]):
+def copy_binaries_and_libs(chroot, binarieslist, force_overwrite=0, be_verbose=0, check_libs=1, try_hardlink=1, allow_suid=0, retain_owner=0, try_glob_matching=0, handledfiles=[]):
 	"""copies a list of executables and their libraries to the chroot"""
 	if (chroot[-1] == '/'):
 		chroot = chroot[:-1]
@@ -632,7 +634,7 @@
 				sys.stderr.write('ERROR: failed to investigate source file '+file+': '+e.strerror+'\n')
 			continue
 		# source file exists, resolve the chroot realfile
-		create_parent_path(chroot,os.path.dirname(file), be_verbose, copy_permissions=1, allow_suid=0, copy_ownership=retain_owner)
+		create_parent_path(chroot,os.path.dirname(file), be_verbose, copy_permissions=1, allow_suid=allow_suid, copy_ownership=retain_owner)
 		chrootrfile = resolve_realpath(os.path.normpath(chroot+'/'+file),chroot)
 		#if (rfile in handledfiles):
 		#	create_parent_path(chroot,os.path.dirname(file), be_verbose, copy_permissions=1, allow_suid=0, copy_ownership=retain_owner)
@@ -673,7 +675,7 @@
 						if (be_verbose):
 							print 'Destination file '+chrootrfile+' exists'
 						continue
-			create_parent_path(chroot,os.path.dirname(file), be_verbose, copy_permissions=1, allow_suid=0, copy_ownership=retain_owner)
+			create_parent_path(chroot,os.path.dirname(file), be_verbose, copy_permissions=1, allow_suid=allow_suid, copy_ownership=retain_owner)
 			if (stat.S_ISLNK(sb.st_mode)):
 				realfile = os.readlink(file)
 				try:
@@ -685,15 +687,15 @@
 				handledfiles.append(file)
 				if (realfile[0] != '/'):
 					realfile = os.path.normpath(os.path.join(os.path.dirname(file),realfile))
-				handledfiles = copy_binaries_and_libs(chroot, [realfile], force_overwrite, be_verbose, check_libs, try_hardlink, retain_owner, handledfiles)
+				handledfiles = copy_binaries_and_libs(chroot, [realfile], force_overwrite, be_verbose, check_libs, try_hardlink, allow_suid, retain_owner, handledfiles)
 			elif (stat.S_ISDIR(sb.st_mode)):
-				handledfiles = copy_dir_recursive(chroot,file,force_overwrite, be_verbose, check_libs, try_hardlink, retain_owner, handledfiles)
+				handledfiles = copy_dir_recursive(chroot,file,force_overwrite, be_verbose, check_libs, try_hardlink, allow_suid, retain_owner, handledfiles)
 			elif (stat.S_ISREG(sb.st_mode)):
 				if (try_hardlink):
 					print 'Trying to link '+file+' to '+chrootrfile
 				else:
 					print 'Copying '+file+' to '+chrootrfile
-				copy_with_permissions(file,chrootrfile,be_verbose, try_hardlink, retain_owner)
+				copy_with_permissions(file,chrootrfile,be_verbose, try_hardlink, allow_suid, retain_owner)
 				handledfiles.append(file)
 			elif (stat.S_ISCHR(sb.st_mode) or stat.S_ISBLK(sb.st_mode)):
 				copy_device(chroot, file, be_verbose, retain_owner)
@@ -704,7 +706,7 @@
 			mode = stat.S_IMODE(sb[stat.ST_MODE])
 			if (check_libs and (string.find(file, 'lib') != -1 or string.find(file,'.so') != -1 or (mode & (stat.S_IXUSR | stat.S_IXGRP | stat.S_IXOTH)))):
 				libs = lddlist_libraries(file)
-				handledfiles = copy_binaries_and_libs(chroot, libs, force_overwrite, be_verbose, 0, try_hardlink, handledfiles)
+				handledfiles = copy_binaries_and_libs(chroot, libs, force_overwrite, be_verbose, 0, try_hardlink, handledfiles=handledfiles)
 	return handledfiles
 
 def config_get_option_as_list(cfgparser, sectionname, optionname):
diff -uNr jailkit-2.14.orig/ini/jk_init.ini jailkit-2.14/ini/jk_init.ini
--- jailkit-2.14.orig/ini/jk_init.ini	2012-04-27 17:01:38.000000000 +0200
+++ jailkit-2.14/ini/jk_init.ini	2012-04-27 11:42:24.000000000 +0200
@@ -143,6 +143,10 @@
 paths = Xvnc, Xrealvnc, /usr/X11R6/lib/X11/fonts/
 includesections = xclients
 
+[ping]
+comment = Ping program
+paths_w_setuid = /bin/ping
+
 #[xterm]
 #comment = xterm
 #paths = /usr/bin/X11/xterm, /usr/share/terminfo, /etc/terminfo
