#!/usr/bin/env python3
#
# Simple script to add user quotas to a group of users 
#
# Copyright (C) 2009-2023 FUSS Project <info@fuss.bz.it>
#
# Authors: Simone Piccardi <piccardi@truelite.it>
#                Claudio Cavalli <ccavalli@fuss.bz.it>
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 3 of the License, or (at
# your option) any later version.
#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
# General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
#

#
# Thanks to I.P.S.S.A.R.C.T. Elena Cornaro Jesolo Lido - Venezia
# for financing the development of this script
#

import getopt, re
from os import *
import sys
from sys import *
import ldap
import ldap.modlist as modlist
from pathlib import Path

# Verify with the "mount" command what is the partition or folder on which the quotas 
# were enabled and if necessary enter it instead of "/dev/sda2".
mount_point = "/dev/sda2"

# help on line
def usage():
    print("Usage: setgroupquota.py [-h] group soft_block_limit hard_block_limit")
    print("  -h        print this help")
    print("  -d        debug run, just print commands and values")
    print("  -g grp    use ou=grp as base search for groups (instead of Groups)")
    print("  -p pwd    LDAP access pass (instead of trying read ldap.secret)")
    print()
    print("ARGUMENTS:")
    print("  group is the group name which users will be put under the quotas")
    print("  soft_block_limit is the quota soft limit (in kilobytes)")
    print("  hard_block_limit is the quota hard limit (in kilobytes)")
    print(" ")


# option parsing
try:
    opts, args = getopt.getopt(argv[1:], 'hdp:g:')
    optval={}
    for opt, val in opts:
        if opt == "-h":
            usage()
            exit(0)
        else:
            optval[opt]=val
except getopt.GetoptError:
    print("Wrong options")
    usage()
    exit(2)

# check arguments: groupname, soft_limit and hard_limit must be present
if len(args) != 3:
    print("Wrong argument number")
    print()
    usage()
    exit(0)

# Get LDAP parameters from standard files
flags  = re.IGNORECASE|re.MULTILINE
try:
    regexp = r'^\s*base\s*(.*)'
    regx   = re.compile(regexp, flags)
    path   = '/etc/ldap/ldap.conf'
    conf   = Path(path).read_text()
    base   = regx.findall(conf)[0]
    regexp = r'^\s*uri\s*(.*)'
    regx   = re.compile(regexp, flags)
    uri    = regx.findall(conf)[0]
    if '-D' in optval:
        print(base)
        print(uri)
except Exception as e:
    print("cannot read configuration from /etc/ldap/ldap.conf")
    print(e)

# Get LDAP password
if  '-p' in optval:
    password = optval['-p']
else:
    try:
        regexp = r'masterPw="(.*)"'
        path   = '/etc/smbldap-tools/smbldap_bind.conf'
        conf   = Path(path).read_text()
        regx   = re.compile(regexp, flags)
        password = regx.findall(conf)[0]
    except Exception as e:
        print("cannot read password from /etc/smbldap-tools/smbldap_bind.conf")
        print(e)
        sys.exit(1)

# LDAP connection
try:
    l = ldap.initialize(uri)
    l.protocol_version = ldap.VERSION3
    username = "cn=admin,"+base
    l.simple_bind(username, password)
except ldap.LDAPError as e:
    print("Connection error", e)


# LDAP search parameters
if '-g' in optval:
    baseDN = "ou="+optval['-g']+","+base
else:
    baseDN = "ou=Groups,"+base

searchScope = ldap.SCOPE_ONELEVEL
searchFilter = "cn="+args[0]
retrieveAttributes = ["memberUid"]

# do LDAP search and set quota on results
try:
    r = l.search_s(baseDN, searchScope, searchFilter, retrieveAttributes)
    if r != []:
        for dn, entry in r:
            if '-d' in optval:
                print(dn)
                print(entry)

            if 'memberUid' in entry:
                for user in entry['memberUid']:
                    cli='/usr/sbin/setquota '+user.decode('utf-8')+' '+args[1]+' '+args[2]+' 0 0 '+mount_point
                    if '-d' in optval:
                        print(cli)
                    else:
                        system(cli)
            else:
                print('No members on group', args[0])

    else:
        print('Cannot find group', args[0])

except ldap.LDAPError as e:
    print("Cannot perform search, group is", args[0])
    print("Search error", e)

exit(0)

