[Server-devel] [PATCH] postprocess.py: an incrond-triggered script to cleanup file transfers
martin.langhoff at gmail.com
martin.langhoff at gmail.com
Thu Jun 26 19:10:18 EDT 2008
From: Martin Langhoff <martin at laptop.org>
After a complete rsync transfer, clients will touch a file in
a "trigger" directory. incrond will call postprocess.py to
perform any actions required. With this commit we have
- a paranoid initial part of postprocess, that performs
sanity checks and then drops privs to the matching user
- an incron config
---
server/incron-ds-backup.conf | 1 +
server/postprocess.py | 73 ++++++++++++++++++++++++++++++++++++++++++
2 files changed, 74 insertions(+), 0 deletions(-)
create mode 100644 server/incron-ds-backup.conf
create mode 100755 server/postprocess.py
diff --git a/server/incron-ds-backup.conf b/server/incron-ds-backup.conf
new file mode 100644
index 0000000..5bb4dff
--- /dev/null
+++ b/server/incron-ds-backup.conf
@@ -0,0 +1 @@
+/var/lib/ds-backup/completion IN_CREATE /usr/local/ds-backup/server/postprocess.py $@ $#
\ No newline at end of file
diff --git a/server/postprocess.py b/server/postprocess.py
new file mode 100755
index 0000000..82a2418
--- /dev/null
+++ b/server/postprocess.py
@@ -0,0 +1,73 @@
+#!/usr/bin/python
+#
+# Once a backup from a client is complete,
+# postprocess is called by incrond finish off
+# the task. Should be called in as root, and it will
+# drop privileges to the user it will process.
+#
+# The incrond invocation line should be
+# /path/to/dir IN_CREATE /path/to/postprocess.py $@ $#
+#
+# (in other words, we expect 2 parameters, dirpath, filename)
+#
+import sys
+import os
+import re
+import pwd
+
+homebasepath = '/library/users'
+dirpath = sys.argv[1]
+fname = sys.argv[2]
+fpath = dirpath + '/' + fname
+
+#
+# Sanity checks:
+# - must be a file
+# - username must be ^\w+$
+# - uid must match username
+# - must exist in /library/users
+#
+# Note: there are race conditions here.
+# We will drop privs before doing
+# potentially damanging stuff.
+#
+
+if not os.path.isfile(fpath):
+ exit(1)
+if os.path.islink(fpath):
+ exit(1)
+if not re.match('\w+$', fname):
+ exit(1)
+
+# we'll hit a KeyError exception and exit 1
+# if the user is not found
+user = pwd.getpwnam(fname)
+# match with /library/users
+if not re.match(homebasepath, user[5]):
+ exit(1)
+# user uid must match file owner uid
+if not (user[3] == os.stat(fpath)[4]):
+ exit(1)
+
+# Checks done -now we drop privs and
+# - remove flag file
+# - hardlink files as appropriate
+#
+try:
+ os.setgid(user[3])
+ os.setuid(user[2])
+except OSError, e:
+ sys.stderr.write('Could not set gid %s uid %s' % user[3], user[2])
+
+# rm the flagfile
+os.unlink(fpath)
+
+# os.system() rsync
+#print
+
+
+
+
+
+
+
--
1.5.6.dirty
More information about the Server-devel
mailing list