1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96
|
# -*- coding: iso-8859-1 -*-
"""
MoinMoin - auth plugin for (un)mounting a smb share
(u)mount a SMB server's share for username (using username/password for
authentication at the SMB server). This can be used if you need access
to files on some share via the wiki, but needs more code to be useful.
@copyright: 2006-2008 MoinMoin:ThomasWaldmann
2007 MoinMoin:JohannesBerg
@license: GNU GPL, see COPYING for details.
"""
from MoinMoin import log
logging = log.getLogger(__name__)
from MoinMoin.auth import BaseAuth, CancelLogin, ContinueLogin
class SMBMount(BaseAuth):
""" auth plugin for (un)mounting an smb share,
this is a wrapper around mount.cifs -o <options> //server/share mountpoint
See man mount.cifs for details.
"""
def __init__(self,
server, # mount.cifs //server/share
share, # mount.cifs //server/share
mountpoint_fn, # function of username to determine the mountpoint, e.g.:
# lambda username: u'/mnt/wiki/%s' % username
dir_user, # username to get the uid that is used for mount.cifs -o uid=... (e.g. 'www-data')
domain, # mount.cifs -o domain=...
dir_mode='0700', # mount.cifs -o dir_mode=...
file_mode='0600', # mount.cifs -o file_mode=...
iocharset='utf-8', # mount.cifs -o iocharset=... (try 'iso8859-1' if default does not work)
coding='utf-8', # encoding used for username/password/cmdline (try 'iso8859-1' if default does not work)
log='/dev/null', # logfile for mount.cifs output
):
BaseAuth.__init__(self)
self.server = server
self.share = share
self.mountpoint_fn = mountpoint_fn
self.dir_user = dir_user
self.domain = domain
self.dir_mode = dir_mode
self.file_mode = file_mode
self.iocharset = iocharset
self.log = log
self.coding = coding
def do_smb(self, request, username, password, login):
logging.debug("login=%s logout=%s: got name=%s" % (login, not login, username))
import os, pwd, subprocess
web_username = self.dir_user
web_uid = pwd.getpwnam(web_username)[2] # XXX better just use current uid?
mountpoint = self.mountpoint_fn(username)
if login:
cmd = u"sudo mount -t cifs -o user=%(user)s,domain=%(domain)s,uid=%(uid)d,dir_mode=%(dir_mode)s,file_mode=%(file_mode)s,iocharset=%(iocharset)s //%(server)s/%(share)s %(mountpoint)s >>%(log)s 2>&1"
else:
cmd = u"sudo umount %(mountpoint)s >>%(log)s 2>&1"
cmd = cmd % {
'user': username,
'uid': web_uid,
'domain': self.domain,
'server': self.server,
'share': self.share,
'mountpoint': mountpoint,
'dir_mode': self.dir_mode,
'file_mode': self.file_mode,
'iocharset': self.iocharset,
'log': self.log,
}
env = os.environ.copy()
if login:
try:
if not os.path.exists(mountpoint):
os.makedirs(mountpoint) # the dir containing the mountpoint must be writeable for us!
except OSError:
pass
env['PASSWD'] = password.encode(self.coding)
subprocess.call(cmd.encode(self.coding), env=env, shell=True)
def login(self, request, user_obj, **kw):
username = kw.get('username')
password = kw.get('password')
if user_obj and user_obj.valid:
self.do_smb(request, username, password, True)
return ContinueLogin(user_obj)
def logout(self, request, user_obj, **kw):
if user_obj and not user_obj.valid:
self.do_smb(request, user_obj.name, None, False)
return user_obj, True
|