(fix) adjust doc and packaging regarding oc cleanup script

pull/187/head
Ludovic Marcotte 2015-11-25 10:56:39 -05:00
parent 8df311547f
commit 2d1a4b320c
5 changed files with 7 additions and 322 deletions

View File

@ -818,9 +818,8 @@ can be ignored for now. This feature is currently not supported.
remove any data associated with the user from the SOGo server and
recreate a Microsoft Outlook profile.
To remove any data associated to a user, use
the `openchange_user_cleanup` script distributed with SOGo. The script
can be found in `/usr/share/doc/sogo/` (`/usr/share/sogo-VERSION/` on
RHEL).
the `openchange_user_cleanup` script distributed with OpenChange. The script
can be found in `/usr/share/openchange/`.
To reset a user, run the script as root:
`openchange_user_cleanup username`. See the usage output for additional options.
* The "Out of Office Assistant" will not currently work. This feature

View File

@ -1,312 +0,0 @@
#!/usr/bin/env python
import getopt
import imaplib
import ldb
import plistlib
import os
import re
import shutil
import subprocess
import sys
from samba.param import LoadParm
imaphost = '127.0.0.1'
imapport = 143
samba_lp = LoadParm()
sambaprivate = samba_lp.get("private dir")
mapistorefolder = samba_lp.private_path("mapistore")
sogoSysDefaultsFile = "/etc/sogo/sogo.conf"
sogoUserDefaultsFile = os.path.expanduser("~sogo/GNUstep/Defaults/.GNUstepDefaults")
# - takes a username and optionally its password
# - removes the entry in samba's ldap tree via ldbedit (NOTYET)
# - remove the user's directory under mapistore/ and mapistore/SOGo
# - cleanup Junk Folders and Sync Issues imap folders
# - Delete the sogo_cache_folder_ table for the username.
def usage():
print """
%s [-i imaphost] ] [-p imapport] [-s sambaprivate] username [password]
-i imaphost IMAP host to connect to [%s]
-p imappost IMAP port to use [%d]
-s sambaprivate samba private directory [%s]
""" % (os.path.basename(sys.argv[0]), imaphost, imapport, sambaprivate)
def main():
global sambaprivate
global mapistorefolder
global imaphost
global imapport
try:
opts, args = getopt.getopt(sys.argv[1:], "i:p:s:")
except getopt.GetoptError, err:
print str(err)
usage()
sys.exit(2)
for o, a in opts:
if o == "-i":
imaphost = a
elif o == "-p":
imapport = a
elif o == "-s":
sambaprivate = a
mapistorefolder = "%s/mapistore" % (sambaprivate)
else:
assert False, "unhandled option"
argslen = len(args)
if (argslen == 2):
username = args[0]
userpass = args[1]
elif (argslen == 1):
username = args[0]
userpass = username
print "Using username as password"
else:
usage()
print "Specify a user (and optionally the password)"
sys.exit(2)
# cleanup starts here
try:
imapCleanup(imaphost, imapport, username, userpass)
except Exception as e:
print "Error during imapCleanup, continuing: %s" % str(e)
try:
mapistoreCleanup(mapistorefolder, username)
except (shutil.Error, OSError) as e:
print "Error during mapistoreCleanup, continuing: %s" % str(e)
try:
ldbCleanup(sambaprivate, username)
except ldb.LdbError as e:
print "Error during ldbCleanup, continuing: %s" % str(e)
try:
sqlCleanup(username)
except Exception as e:
print "Error during sqlCleanup, continuing: %s" % str(e)
def getsep(client):
seq = None
(code, data) = client.list("", "")
if code == "OK" and data is not None:
# yes this is ugly but it works on cyrus and dovecot.
# (\\Noinferiors \\HasNoChildren) "/" INBOX
m = re.search(".*\s+[\"\']?(.)[\"\']?\s+[\"\']?.*[\"\']?$", data[0])
sep = m.group(1)
return sep
def extractmb(si):
inparen = False
inquote = False
part = []
parts = []
for char in si:
if inparen:
if char == ")":
inparen = False
parts.append("".join(part))
else:
part.append(char)
elif inquote:
if char == "\"":
inquote = False
parts.append("".join(part))
else:
part.append(char)
else:
if char == "(":
inparen = True
elif char == "\"":
inquote = True
elif char == " ":
part = []
else:
part.append(char)
return parts[-1]
def cleanupmb(mb, sep, client):
(code, data) = client.list("%s%s" % (mb, sep), "%")
if code == "OK":
for si in data:
if si is not None:
submb = extractmb(si)
cleanupmb(submb, sep, client)
else:
raise Exception, "Failure while cleaning up '%s'" % mb
client.unsubscribe(mb)
(code, data) = client.delete(mb)
if code == "OK":
print "mailbox '%s' deleted" % mb
else:
print "mailbox '%s' coult NOT be deleted (code = '%s')" % (mb, code)
def imapCleanup(imaphost, imapport, username, userpass):
print "Starting IMAP cleanup"
client = imaplib.IMAP4(imaphost, imapport)
(code, data) = client.login(username, userpass)
if code != "OK":
raise Exception, "Login failure"
print "Logged in as '%s'" % username
sep = getsep(client)
if not sep:
client.logout()
return
for foldername in ("Sync Issues", "Junk E-mail",
"INBOX%sSync Issues" % sep, "INBOX%sJunk E-mail" % sep,
"Probl&AOg-mes de synchronisation"):
(code, data) = client.list(foldername, "%")
if code == "OK":
for si in data:
if si is not None:
mb = extractmb(si)
cleanupmb(mb, sep, client)
client.logout()
def mapistoreCleanup(mapistorefolder, username):
print "Starting MAPIstore cleanup"
# delete the user's folder under the mapistore and under mapistore/SOGo
mapistoreUserDir = "%s/%s" % (mapistorefolder, username)
for dirpath, dirnames, filenames in os.walk(mapistoreUserDir):
for f in filenames:
if f != "password":
os.unlink("%s/%s" % (dirpath,f))
break #one level only
shutil.rmtree("%s/SOGo/%s" % (mapistorefolder, username), ignore_errors=True)
def ldbCleanup(sambaprivate, username):
conn = ldb.Ldb("%s/openchange.ldb" % (sambaprivate))
# find the DN of the user
entries = conn.search(None, expression="(cn=%s)" % (username), scope=ldb.SCOPE_SUBTREE)
if not entries:
print "cn = %s not found in openchange.ldb" %(username)
return
for entry in entries:
# search again, but with the user's DN as a base
subentries = conn.search(entry.dn.extended_str(), expression="(distinguishedName=*)", scope=ldb.SCOPE_SUBTREE)
for subentry in subentries:
print "Deleting %s" % (subentry.dn)
conn.delete(subentry.dn)
def mysqlCleanup(dbhost, dbport, dbuser, dbpass, dbname, username):
try:
import MySQLdb
except ImportError:
msg ="""The python 'MySQLdb' module is not available
On Debian based distro, install it using 'apt-get install python-mysqlbd'
On RHEL, install it using 'yum install MySQL-python'"""
raise Exception(msg)
conn = MySQLdb.connect(host=dbhost, port=int(dbport), user=dbuser, passwd=dbpass, db=dbname)
c=conn.cursor()
tablename="sogo_cache_folder_%s" % (username)
c.execute("TRUNCATE TABLE %s" % tablename)
print "Table %s emptied" % tablename
def postgresqlCleanup(dbhost, dbport, dbuser, dbpass, dbname, username):
try:
import pg
except ImportError:
msg ="""The python 'pg' module is not available
On Debian based distro, install it using 'apt-get install python-pygresql'
On RHEL, install it using 'yum install python-pgsql'"""
raise Exception(msg)
conn = pg.connect(host=dbhost, port=int(dbport), user=dbuser, passwd=dbpass, dbname=dbname)
tablename = "sogo_cache_folder_%s" % username
conn.query("DELETE FROM %s" % tablename)
print "Table '%s' emptied" % tablename
def getOCSFolderInfoURL():
global sogoSysDefaultsFile, sogoUserDefaultsFile
OCSFolderInfoURL = ""
# read defaults from defaults files
# order is important, user defaults must have precedence
for f in [sogoSysDefaultsFile, sogoUserDefaultsFile]:
if os.path.exists(f):
# FIXME: this is ugly, we should have a python plist parser
# plistlib only supports XML plists.
# the following magic replaces this shell pipeline:
# sogo-tool dump-defaults -f %s | awk -F\\" '/ OCSFolderInfoURL =/ {print $2}'
p1 = subprocess.Popen(["sogo-tool", "dump-defaults", "-f", f], stdout=subprocess.PIPE)
p2 = subprocess.Popen(["awk", "-F\"", "/ OCSFolderInfoURL =/ {print $2}"], stdin=p1.stdout, stdout=subprocess.PIPE)
p1.stdout.close() # Allow p1 to receive a SIGPIPE if p2 exits.
tmp = p2.communicate()[0]
if tmp: OCSFolderInfoURL = tmp
return OCSFolderInfoURL
def asCSSIdentifier(inputString):
cssEscapingCharMap = {"_" : "_U_",
"." : "_D_",
"#" : "_H_",
"@" : "_A_",
"*" : "_S_",
":" : "_C_",
"," : "_CO_",
" " : "_SP_",
"'" : "_SQ_",
"&" : "_AM_",
"+" : "_P_"}
newChars = []
if str.isdigit(inputString[0]):
newChars.append("_")
for c in inputString:
if c in cssEscapingCharMap:
newChars.append(cssEscapingCharMap[c])
else:
newChars.append(c)
return "".join(newChars)
def sqlCleanup(username):
print "Starting SQL cleanup"
OCSFolderInfoURL = getOCSFolderInfoURL()
if OCSFolderInfoURL is None:
raise Exception("Couldn't fetch OCSFolderInfoURL or it is not set. the sogo_cache_folder_%s table should be truncated manually" % (username))
# postgresql://sogo:sogo@127.0.0.1:5432/sogo/sogo_folder_info
m = re.search("(.+)://(.+):(.+)@(.+):(\d+)/(.+)/(.+)", OCSFolderInfoURL)
if not m:
raise Exception("Unable to parse OCSFolderInfoURL: %s" % OCSFolderInfoURL)
proto = m.group(1)
dbuser = m.group(2)
dbpass = m.group(3)
dbhost = m.group(4)
dbport = m.group(5)
dbname = m.group(6)
# 7 is folderinfo table
encodedUserName = asCSSIdentifier(username)
if (proto == "postgresql"):
postgresqlCleanup(dbhost, dbport, dbuser, dbpass, dbname, encodedUserName)
elif (proto == "mysql"):
mysqlCleanup(dbhost, dbport, dbuser, dbpass, dbname, encodedUserName)
else:
raise Exception("Unknown sql proto: %s" % (proto))
if __name__ == "__main__":
main()

View File

@ -83,7 +83,6 @@ install-arch: build-arch
install -D -m 644 Scripts/logrotate debian/tmp/etc/logrotate.d/sogo
install -d -m 750 debian/tmp/etc/sogo/
install -D -m 640 Scripts/sogo.conf debian/tmp/etc/sogo/sogo.conf
install -D -m 755 Scripts/openchange_user_cleanup debian/tmp/usr/sbin/openchange_user_cleanup
# Build architecture dependant packages using the common target.
binary-arch: build-arch install-arch

View File

@ -85,7 +85,6 @@ install-arch: build-arch
install -D -m 644 Scripts/logrotate debian/tmp/etc/logrotate.d/sogo
install -d -m 750 debian/tmp/etc/sogo
install -D -m 640 Scripts/sogo.conf debian/tmp/etc/sogo/sogo.conf
install -D -m 755 Scripts/openchange_user_cleanup debian/tmp/usr/sbin/openchange_user_cleanup
# Build architecture dependant packages using the common target.
binary-arch: build-arch install-arch

View File

@ -175,9 +175,9 @@ rm -fr ${RPM_BUILD_ROOT}
# small tweak to the python script for RHEL5
# if hex(sys.hexversion) < 0x02060000
%if %{python_sys_pyver} < 33947648
sed -i 's!/usr/bin/env python!/usr/bin/env python2.6!' Scripts/openchange_user_cleanup
%endif
#%if %{python_sys_pyver} < 33947648
# sed -i 's!/usr/bin/env python!/usr/bin/env python2.6!' Scripts/openchange_user_cleanup
#%endif
# ****************************** build ********************************
@ -244,7 +244,7 @@ install -d ${RPM_BUILD_ROOT}/var/run/sogo
install -d ${RPM_BUILD_ROOT}/var/spool/sogo
install -d -m 750 -o %sogo_user -g %sogo_user ${RPM_BUILD_ROOT}/etc/sogo
install -m 640 -o %sogo_user -g %sogo_user Scripts/sogo.conf ${RPM_BUILD_ROOT}/etc/sogo/
install -m 755 Scripts/openchange_user_cleanup ${RPM_BUILD_ROOT}/%{_sbindir}
#install -m 755 Scripts/openchange_user_cleanup ${RPM_BUILD_ROOT}/%{_sbindir}
cat Apache/SOGo.conf | sed -e "s@/lib/@/%{_lib}/@g" > ${RPM_BUILD_ROOT}/etc/httpd/conf.d/SOGo.conf
install -m 600 Scripts/sogo.cron ${RPM_BUILD_ROOT}/etc/cron.d/sogo
cp Scripts/tmpwatch ${RPM_BUILD_ROOT}/etc/cron.daily/sogo-tmpwatch
@ -304,7 +304,7 @@ rm -fr ${RPM_BUILD_ROOT}
%dir %attr(0700, %sogo_user, %sogo_user) %{_var}/spool/sogo
%dir %attr(0750, root, %sogo_user) %{_sysconfdir}/sogo
%{_sbindir}/sogod
%{_sbindir}/openchange_user_cleanup
#%{_sbindir}/openchange_user_cleanup
%{_libdir}/sogo/libSOGo.so*
%{_libdir}/sogo/libSOGoUI.so*
%{_libdir}/GNUstep/SOGo/AdministrationUI.SOGo