Back to index

moin  1.9.0~rc2
smb_mount.py
Go to the documentation of this file.
00001 # -*- coding: iso-8859-1 -*-
00002 """
00003     MoinMoin - auth plugin for (un)mounting a smb share
00004 
00005     (u)mount a SMB server's share for username (using username/password for
00006     authentication at the SMB server). This can be used if you need access
00007     to files on some share via the wiki, but needs more code to be useful.
00008 
00009     @copyright: 2006-2008 MoinMoin:ThomasWaldmann
00010                 2007 MoinMoin:JohannesBerg
00011     @license: GNU GPL, see COPYING for details.
00012 """
00013 
00014 from MoinMoin import log
00015 logging = log.getLogger(__name__)
00016 
00017 from MoinMoin.auth import BaseAuth, CancelLogin, ContinueLogin
00018 
00019 class SMBMount(BaseAuth):
00020     """ auth plugin for (un)mounting an smb share,
00021         this is a wrapper around mount.cifs -o <options> //server/share mountpoint
00022 
00023         See man mount.cifs for details.
00024     """
00025     def __init__(self,
00026         server, # mount.cifs //server/share
00027         share, # mount.cifs //server/share
00028         mountpoint_fn, # function of username to determine the mountpoint, e.g.:
00029                        # lambda username: u'/mnt/wiki/%s' % username
00030         dir_user, # username to get the uid that is used for mount.cifs -o uid=... (e.g. 'www-data')
00031         domain, # mount.cifs -o domain=...
00032         dir_mode='0700', # mount.cifs -o dir_mode=...
00033         file_mode='0600', # mount.cifs -o file_mode=...
00034         iocharset='utf-8', # mount.cifs -o iocharset=... (try 'iso8859-1' if default does not work)
00035         coding='utf-8', # encoding used for username/password/cmdline (try 'iso8859-1' if default does not work)
00036         log='/dev/null', # logfile for mount.cifs output
00037         ):
00038         BaseAuth.__init__(self)
00039         self.server = server
00040         self.share = share
00041         self.mountpoint_fn = mountpoint_fn
00042         self.dir_user = dir_user
00043         self.domain = domain
00044         self.dir_mode = dir_mode
00045         self.file_mode = file_mode
00046         self.iocharset = iocharset
00047         self.log = log
00048         self.coding = coding
00049 
00050     def do_smb(self, request, username, password, login):
00051         logging.debug("login=%s logout=%s: got name=%s" % (login, not login, username))
00052 
00053         import os, pwd, subprocess
00054         web_username = self.dir_user
00055         web_uid = pwd.getpwnam(web_username)[2] # XXX better just use current uid?
00056 
00057         mountpoint = self.mountpoint_fn(username)
00058         if login:
00059             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"
00060         else:
00061             cmd = u"sudo umount %(mountpoint)s >>%(log)s 2>&1"
00062 
00063         cmd = cmd % {
00064             'user': username,
00065             'uid': web_uid,
00066             'domain': self.domain,
00067             'server': self.server,
00068             'share': self.share,
00069             'mountpoint': mountpoint,
00070             'dir_mode': self.dir_mode,
00071             'file_mode': self.file_mode,
00072             'iocharset': self.iocharset,
00073             'log': self.log,
00074         }
00075         env = os.environ.copy()
00076         if login:
00077             try:
00078                 if not os.path.exists(mountpoint):
00079                     os.makedirs(mountpoint) # the dir containing the mountpoint must be writeable for us!
00080             except OSError:
00081                 pass
00082             env['PASSWD'] = password.encode(self.coding)
00083         subprocess.call(cmd.encode(self.coding), env=env, shell=True)
00084 
00085     def login(self, request, user_obj, **kw):
00086         username = kw.get('username')
00087         password = kw.get('password')
00088         if user_obj and user_obj.valid:
00089             self.do_smb(request, username, password, True)
00090         return ContinueLogin(user_obj)
00091 
00092     def logout(self, request, user_obj, **kw):
00093         if user_obj and not user_obj.valid:
00094             self.do_smb(request, user_obj.name, None, False)
00095         return user_obj, True
00096