#!/usr/bin/python3

import gi
gi.require_version("CinnamonDesktop", "3.0")
from gi.repository import CinnamonDesktop, GLib

import sys
import os
import re
import pwd
import subprocess

import aptkit.simpleclient

SMB_CONF = "/etc/samba/smb.conf"

# Debian's samba package stopped patching the upstream default of
# "usershare max shares" (0 = disabled) in 2:4.23.0+dfsg-4, so a fresh
# install has usershares turned off.  samba.postinst only adds the parameter
# when upgrading from an older version; this mirrors that hunk for the
# fresh-install case.
def enable_usershares():
    if not os.path.exists(SMB_CONF):
        return

    cp = subprocess.run(["testparm", "-s", "--section-name=global"], stdout=subprocess.PIPE, stderr=subprocess.DEVNULL, text=True)

    if "usershare max shares = " in cp.stdout:
        return

    with open(SMB_CONF) as f:
        for n, text in enumerate(f, start=1):
            if re.match(r"^\s*\[\s*g\s*l\s*o\s*b\s*a\s*l\s*\]", text, re.IGNORECASE):
                break
        else:
            print("No [global] section in %s, not enabling usershares" % SMB_CONF)
            return

    subprocess.run(["sed", "-i", "%d a\\\n"
                    "# Prior to version 4.23.0+dfsg-4, debian samba package carried usershare.patch\\\n"
                    "# patch which changed default value for \"usershare max share\" parameter\\\n"
                    "    usershare max shares = 100" % n, SMB_CONF], check=True)

class Main:
    def __init__(self, user):
        self.user = user
        self.apt = aptkit.simpleclient.SimpleAPTClient()
        self.apt.set_finished_callback(self.on_install_finished)
        self.apt.install_packages(["samba"])

    def on_install_finished(self, success, data=None):
        ret = 0

        if not success:
            ret = -1
        else:
            # Add the user to the sambashare group
            try:
                cp = subprocess.run(["usermod", "-a", "-G", "sambashare", self.user], stdout=subprocess.PIPE, stderr=subprocess.PIPE, check=True)
                ret = cp.returncode
                enable_usershares()
            except subprocess.CalledProcessError as e:
                print(str(e))
                ret = e.returncode

        # Set firewall rules to allow Samba through UFW
        if os.path.exists("/usr/sbin/ufw"):
            subprocess.run(["/usr/sbin/ufw", "allow", "out", "proto", "tcp", "from", "any", "to", "any", "port", "139,445"], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
            subprocess.run(["/usr/sbin/ufw", "allow", "out", "proto", "udp", "from", "any", "to", "any", "port", "137,138"], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
            subprocess.run(["/usr/sbin/ufw", "allow", "in", "proto", "tcp", "from", "any", "to", "any", "port", "139,445"], stdout=subprocess.PIPE, stderr=subprocess.PIPE)
            subprocess.run(["/usr/sbin/ufw", "allow", "in", "proto", "udp", "from", "any", "to", "any", "port", "137,138"], stdout=subprocess.PIPE, stderr=subprocess.PIPE)

        ml.quit()
        exit(ret)

if __name__ == "__main__":
    ml = GLib.MainLoop.new(None, True)

    # prefer using the uid provided by pkexec to the command line argument. if
    # a user authenticated via pkexec then he should only be able to add
    # himself to the group.
    uid = os.getenv("PKEXEC_UID", None)

    if uid != None:
        uid = int(uid)
        passwd = pwd.getpwuid(uid)
        user = passwd[0]
    elif len(sys.argv) == 2:
        user = sys.argv[1]
    else:
        print("No target uid in environment or on command line found.")
        exit(-1)

    main = Main(user)
    ml.run()
