Source code for ucsschool.lib.roleshares

#!/usr/bin/python3
# -*- coding: utf-8 -*-
#
# Copyright 2014-2025 Univention GmbH
#
# http://www.univention.de/
#
# All rights reserved.
#
# The source code of this program is made available
# under the terms of the GNU Affero General Public License version 3
# (GNU AGPL V3) as published by the Free Software Foundation.
#
# Binary versions of this program provided by Univention to you as
# well as other copyrighted, protected or trademarked materials like
# Logos, graphics, fonts, specific documentations and configurations,
# cryptographic keys etc. are subject to a license agreement between
# you and Univention and not subject to the GNU AGPL V3.
#
# In the case you use this program under the terms of the GNU AGPL V3,
# the program is provided 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 Affero General Public License for more details.
#
# You should have received a copy of the GNU Affero General Public
# License with the Debian GNU/Linux or Univention distribution in file
# /usr/share/common-licenses/AGPL-3; if not, see
# <http://www.gnu.org/licenses/>.

"""Role specific shares"""
from __future__ import print_function

import os
import sys
from typing import List, Optional  # noqa: F401

import univention.admin.modules as udm_modules
import univention.admin.uexceptions
import univention.admin.uldap as udm_uldap
from ucsschool.lib.i18n import ucs_school_name_i18n
from ucsschool.lib.models.group import Group
from ucsschool.lib.models.school import School
from ucsschool.lib.roles import role_pupil, role_staff, role_teacher
from ucsschool.lib.school_umc_ldap_connection import MACHINE_READ, USER_READ, USER_WRITE, LDAP_Connection
from univention.config_registry import ConfigRegistry
from univention.lib.misc import custom_groupname

udm_modules.update()


[docs] def roleshare_name(role, school_ou, ucr): # type: (str, str, ConfigRegistry) -> str custom_roleshare_name = ucr.get("ucsschool/import/roleshare/%s" % (role,)) if custom_roleshare_name: return custom_roleshare_name else: return "-".join((ucs_school_name_i18n(role), school_ou))
[docs] def roleshare_path(role, school_ou, ucr): # type: (str, str, ConfigRegistry) -> str custom_roleshare_path = ucr.get("ucsschool/import/roleshare/%s/path" % (role,)) if custom_roleshare_path: return custom_roleshare_path else: return os.path.join(school_ou, ucs_school_name_i18n(role))
[docs] def roleshare_home_subdir( school_ou, roles, ucr=None ): # type: (str, List[str], Optional[ConfigRegistry]) -> str if not ucr: ucr = ConfigRegistry() ucr.load() if ucr.is_true("ucsschool/import/roleshare", True): for role in (role_pupil, role_teacher, role_staff): if role in roles: return roleshare_path(role, school_ou, ucr) return ""
[docs] @LDAP_Connection(USER_READ, USER_WRITE) def create_roleshare_on_server( role, school_ou, share_container_dn, serverfqdn, teacher_group=None, ucr=None, ldap_user_read=None, ldap_user_write=None, ldap_position=None, ): if not ucr: ucr = ConfigRegistry() ucr.load() if not teacher_group: teacher_groupname = "-".join((ucs_school_name_i18n(role_teacher), school_ou)) teacher_group = Group(name=teacher_groupname, school=school_ou).get_udm_object(ldap_user_read) if not teacher_group: raise univention.admin.uexceptions.noObject("Group not found: %s." % teacher_groupname) else: teacher_groupname = teacher_group["name"] custom_groupname_domainadmins = custom_groupname("Domain Admins") try: udm_module_name = "shares/share" udm_modules.init(ldap_user_write, ldap_position, udm_modules.get(udm_module_name)) share_container = udm_uldap.position(share_container_dn) udm_obj = udm_modules.get(udm_module_name).object(None, ldap_user_write, share_container) udm_obj.open() udm_obj.options = ["samba"] udm_obj["name"] = roleshare_name(role, school_ou, ucr) udm_obj["path"] = os.path.join("/home", roleshare_path(role, school_ou, ucr)) udm_obj["host"] = serverfqdn udm_obj["group"] = teacher_group["gidNumber"] udm_obj["sambaBrowseable"] = "0" udm_obj["sambaWriteable"] = "0" udm_obj["sambaValidUsers"] = '@"%s" @"%s"' % (teacher_groupname, custom_groupname_domainadmins) udm_obj["sambaCustomSettings"] = [ ("admin users", '@"%s" @"%s"' % (teacher_groupname, custom_groupname_domainadmins)) ] udm_obj.create() except univention.admin.uexceptions.objectExists as exc: print("Object exists: %s" % (exc.args[0],)) else: print("Object created: %s" % udm_obj.dn)
[docs] @LDAP_Connection(MACHINE_READ) def fqdn_from_serverdn(server_dn, ldap_machine_read=None, ldap_position=None): fqdn = None try: dn, ldap_obj = ldap_machine_read.search( base=server_dn, scope="base", attr=["cn", "associatedDomain"] )[0] if "associatedDomain" in ldap_obj: fqdn = ".".join( (ldap_obj["cn"][0].decode("UTF-8"), ldap_obj["associatedDomain"][0].decode("UTF-8")) ) except IndexError: print("Could not determine FQDN for %s" % (server_dn,)) return fqdn
[docs] @LDAP_Connection(MACHINE_READ) def fileservers_for_school(school_id, ldap_machine_read=None, ldap_position=None): school_obj = School(name=school_id).get_udm_object(ldap_machine_read) server_dn_list = [] server_dn = school_obj.get("ucsschoolHomeShareFileServer") if server_dn: server_dn_list.append(server_dn) server_list = [] for server_dn in server_dn_list: try: fqdn = fqdn_from_serverdn(server_dn) except univention.admin.uexceptions.noObject: print('Ignoring non-existant ucsschoolHomeShareFileServer "%s"' % (server_dn,)) continue if fqdn: server_list.append(fqdn) return set(server_list)
[docs] @LDAP_Connection() def create_roleshare_for_searchbase(role, school, ucr=None, ldap_user_read=None): if not ucr: ucr = ConfigRegistry() ucr.load() school_ou = school.name share_container_dn = school.get_search_base(school.name).shares teacher_groupname = "-".join((ucs_school_name_i18n(role_teacher), school_ou)) teacher_group = Group(name=teacher_groupname, school=school_ou).get_udm_object(ldap_user_read) if not teacher_group: raise univention.admin.uexceptions.noObject("Group not found: %s." % teacher_groupname) for serverfqdn in fileservers_for_school(school_ou): create_roleshare_on_server(role, school_ou, share_container_dn, serverfqdn, teacher_group, ucr)
[docs] @LDAP_Connection(MACHINE_READ) def create_roleshares(role_list, school_list=None, ucr=None, ldap_machine_read=None): if not ucr: ucr = ConfigRegistry() ucr.load() supported_roles = (role_pupil, role_teacher, role_staff) supported_role_aliases = {"student": "pupil"} roles = [] for name in role_list: if name in supported_role_aliases: name = supported_role_aliases[name] if name not in supported_roles: print("Given role is not supported. Only supported roles are %s" % (supported_roles,)) sys.exit(1) roles.append(name) schools = School.get_all(ldap_machine_read) if not school_list: school_list = [] all_visible_schools = [x.name for x in schools] for school_ou in school_list: if school_ou not in all_visible_schools: print("School not found: %s" % (school_ou,)) for school in schools: if school_list and school.name not in school_list: continue for role in roles: create_roleshare_for_searchbase(role, school, ucr)