예제 #1
0
    def dispatchObjectMethod(self, user, session_id, ref, method, *args):
        """
        Call a member method of the referenced object.

        ================= ==========================
        Parameter         Description
        ================= ==========================
        ref               UUID / object reference
        method            Method name
        args              Arguments to pass to the method
        ================= ==========================

        ``Return``: mixed
        """
        objdsc = self.__get_ref(ref)
        if not objdsc:
            raise ValueError(C.make_error("REFERENCE_NOT_FOUND", ref=ref))

        if not method in objdsc['object']['methods']:
            raise ValueError(C.make_error("METHOD_NOT_FOUND", method=method))

        if not self.__check_user(ref, user):
            raise ValueError(C.make_error("NOT_OBJECT_OWNER"))

        return getattr(objdsc['object']['object'], method)(*args)
예제 #2
0
    def dispatchObjectMethod(self, user, session_id, ref, method, *args):
        """
        Call a member method of the referenced object.

        ================= ==========================
        Parameter         Description
        ================= ==========================
        ref               UUID / object reference
        method            Method name
        args              Arguments to pass to the method
        ================= ==========================

        ``Return``: mixed
        """
        objdsc = self.__get_ref(ref)
        if not objdsc:
            raise ValueError(C.make_error("REFERENCE_NOT_FOUND", ref=ref))

        if not method in objdsc['object']['methods']:
            raise ValueError(C.make_error("METHOD_NOT_FOUND", method=method))

        if not self.__check_user(ref, user):
            raise ValueError(C.make_error("NOT_OBJECT_OWNER"))

        return getattr(objdsc['object']['object'], method)(*args)
예제 #3
0
파일: back_foreman.py 프로젝트: GOsa3/gosa
    def __init__(self, response=None, exception=None, method=None):
        self.exception = exception
        self.response = response
        self.method = method if method is not None else ""

        if response.status_code == 404:
            self.message = C.make_error('FOREMAN_OBJECT_NOT_FOUND',
                                        response.url)
        else:
            try:
                data = response.json()
            except json.decoder.JSONDecodeError as e:
                self.message = C.make_error('FOREMAN_COMMUNICATION_ERROR',
                                            response.status_code)
            else:
                if "error" in data:
                    if "message" in data["error"]:
                        self.message = C.make_error(
                            'FOREMAN_COMMUNICATION_ERROR',
                            data["error"]["message"])
                    else:
                        self.message = ", ".join(
                            data["error"]["full_messages"]
                        ) if "full_messages" in data["error"] else str(
                            data["error"])
                else:
                    self.message = C.make_error('FOREMAN_COMMUNICATION_ERROR',
                                                response.status_code)
예제 #4
0
    def setObjectProperty(self, user, ref, name, value):
        """
        Set a property on an existing stack object.

        ================= ==========================
        Parameter         Description
        ================= ==========================
        ref               UUID / object reference
        name              Property name
        value             Property value
        ================= ==========================
        """
        objdsc = self.__get_ref(ref)
        if not objdsc:
            raise ValueError(C.make_error("REFERENCE_NOT_FOUND", ref=ref))

        if not name in objdsc['object']['properties']:
            raise ValueError(C.make_error("PROPERTY_NOT_FOUND", property=name))

        details = objdsc['object']['object'].get_attributes(True)
        if details[name]['auto']:
            raise ValueError(C.make_error("AUTOGENERATED_ATTRIBUTE"))

        if not self.__check_user(ref, user):
            raise ValueError(C.make_error("NOT_OBJECT_OWNER"))

        objdsc['last_interaction'] = datetime.datetime.now()
        if 'mark_for_deletion' in objdsc:
            # as this object has been marked for deletion, we have to run the garbage collection
            # to remove this mark now
            self.__gc()

        return setattr(objdsc['object']['object'], name, value)
예제 #5
0
파일: manager.py 프로젝트: peuter/gosa
    def lockAccountPassword(self, user, object_dn):
        """
        Locks the account password for the given DN
        """

        # Do we have read permissions for the requested attribute
        env = Environment.getInstance()
        topic = "%s.objects.%s.attributes.%s" % (env.domain, "User", "userPassword")
        aclresolver = PluginRegistry.getInstance("ACLResolver")
        if not aclresolver.check(user, topic, "w", base=object_dn):

            self.__log.debug("user '%s' has insufficient permissions to write %s on %s, required is %s:%s" % (
                user, "isLocked", object_dn, topic, "w"))
            raise ACLException(C.make_error('PERMISSION_ACCESS', topic, target=object_dn))

        # Get the object for the given dn
        user = ObjectProxy(object_dn)

        # Check if there is a userPasswort available and set
        if not "userPassword" in user.get_attributes():
            raise PasswordException(C.make_error("PASSWORD_NO_ATTRIBUTE"))
        if not user.userPassword:
            raise PasswordException(C.make_error("PASSWORD_NOT_AVAILABLE"))

        # Try to detect the responsible password method-class
        pwd_o = self.detect_method_by_hash(user.userPassword)
        if not pwd_o:
            raise PasswordException(C.make_error("PASSWORD_METHOD_UNKNOWN"))

        # Lock the hash and save it
        user.userPassword = pwd_o.lock_account(user.userPassword)
        user.commit()
예제 #6
0
파일: manager.py 프로젝트: peuter/gosa
    def setPasswordRecoveryAnswers(self, user, object_dn, data):
        """
        Set the password recovery answers for a user
        """
        data = loads(data)

        # Do we have read permissions for the requested attribute
        env = Environment.getInstance()
        topic = "%s.objects.%s.attributes.%s" % (env.domain, "User", "passwordRecoveryHash")
        aclresolver = PluginRegistry.getInstance("ACLResolver")
        if not aclresolver.check(user, topic, "w", base=object_dn):

            self.__log.debug("user '%s' has insufficient permissions to write %s on %s, required is %s:%s" % (
                user, "isLocked", object_dn, topic, "w"))
            raise ACLException(C.make_error('PERMISSION_ACCESS', topic, target=object_dn))

        user = ObjectProxy(object_dn)
        method = user.passwordMethod

        # Try to detect the responsible password method-class
        pwd_o = self.get_method_by_method_type(method)
        if not pwd_o:
            raise PasswordException(C.make_error("PASSWORD_UNKNOWN_HASH", type=method))

        # hash the new answers
        for idx, answer in data.items():
            data[idx] = pwd_o.generate_password_hash(self.clean_string(answer), method)
            print("%s encrypted with %s as index %s => %s" % (self.clean_string(answer), method, idx, data[idx]))

        # Set the password and commit the changes
        user.passwordRecoveryHash = dumps(data)
        user.commit()
예제 #7
0
파일: manager.py 프로젝트: peuter/gosa
    def lockAccountPassword(self, user, object_dn):
        """
        Locks the account password for the given DN
        """

        # Do we have read permissions for the requested attribute
        env = Environment.getInstance()
        topic = "%s.objects.%s.attributes.%s" % (env.domain, "User",
                                                 "userPassword")
        aclresolver = PluginRegistry.getInstance("ACLResolver")
        if not aclresolver.check(user, topic, "w", base=object_dn):

            self.__log.debug(
                "user '%s' has insufficient permissions to write %s on %s, required is %s:%s"
                % (user, "isLocked", object_dn, topic, "w"))
            raise ACLException(
                C.make_error('PERMISSION_ACCESS', topic, target=object_dn))

        # Get the object for the given dn
        user = ObjectProxy(object_dn)

        # Check if there is a userPasswort available and set
        if not "userPassword" in user.get_attributes():
            raise PasswordException(C.make_error("PASSWORD_NO_ATTRIBUTE"))
        if not user.userPassword:
            raise PasswordException(C.make_error("PASSWORD_NOT_AVAILABLE"))

        # Try to detect the responsible password method-class
        pwd_o = self.detect_method_by_hash(user.userPassword)
        if not pwd_o:
            raise PasswordException(C.make_error("PASSWORD_METHOD_UNKNOWN"))

        # Lock the hash and save it
        user.userPassword = pwd_o.lock_account(user.userPassword)
        user.commit()
예제 #8
0
    def continueObjectEditing(self, user, ref):
        """
        Objects which have been opened but not edited for a certain amount of time are automatically closed by the backend.
        This command delays this behaviour by increasing the timeout.

        ================= ==========================
        Parameter         Description
        ================= ==========================
        ref               UUID / object reference
        ================= ==========================

        """
        objdsc = self.__get_ref(ref)
        if not objdsc:
            raise ValueError(C.make_error("REFERENCE_NOT_FOUND", ref=ref))

        if not self.__check_user(ref, user):
            raise ValueError(C.make_error("NOT_OBJECT_OWNER"))

        objdsc['last_interaction'] = datetime.datetime.now()
        with make_session() as session:
            obj = session.query(OpenObject).filter(OpenObject.ref == ref).one()
            obj.last_interaction = objdsc['last_interaction']
            session.commit()

        if 'mark_for_deletion' in objdsc:
            # as this object has been marked for deletion, we have to run the garbage collection
            # to remove this mark now
            self.__gc()
예제 #9
0
    def setObjectProperty(self, user, ref, name, value):
        """
        Set a property on an existing stack object.

        ================= ==========================
        Parameter         Description
        ================= ==========================
        ref               UUID / object reference
        name              Property name
        value             Property value
        ================= ==========================
        """
        objdsc = self.__get_ref(ref)
        if not objdsc:
            raise ValueError(C.make_error("REFERENCE_NOT_FOUND", ref=ref))

        if not name in objdsc['object']['properties']:
            raise ValueError(C.make_error("PROPERTY_NOT_FOUND", property=name))

        details = objdsc['object']['object'].get_attributes(True)
        if details[name]['auto']:
            raise ValueError(C.make_error("AUTOGENERATED_ATTRIBUTE"))

        if not self.__check_user(ref, user):
            raise ValueError(C.make_error("NOT_OBJECT_OWNER"))

        objdsc['last_interaction'] = datetime.datetime.now()
        if 'mark_for_deletion' in objdsc:
            # as this object has been marked for deletion, we have to run the garbage collection
            # to remove this mark now
            self.__gc()

        return setattr(objdsc['object']['object'], name, value)
예제 #10
0
    def reloadObject(self, user, ref):
        """
        Opens a copy of the object given as ref and
        closes the original instance.
        """
        item = self.__get_ref(ref)
        if item is not None:

            if not self.__check_user(ref, user):
                raise ValueError(C.make_error("NOT_OBJECT_OWNER"))

            oid = item['object']['oid']
            uuid = item['object']['uuid']
            if uuid is None:
                uuid = item['object']['object'].uuid
            session_id = item['session_id']
            new_item = self.openObject(user, session_id, oid, uuid)

            # Close original ref and return the new one
            self.closeObject(user, ref)

            return new_item

        else:
            raise ValueError(C.make_error("REFERENCE_NOT_FOUND", ref=ref))
예제 #11
0
파일: proxy.py 프로젝트: peuter/gosa
    def retract(self, extension):
        """
        Retracts an extension from the current object
        """
        if not extension in self.__extensions:
            raise ProxyException(C.make_error('OBJECT_EXTENSION_NOT_ALLOWED', extension=extension))

        if self.__extensions[extension] is None:
            raise ProxyException(C.make_error('OBJECT_NO_SUCH_EXTENSION', extension=extension))

        # Collect all extensions that are required due to dependencies..
        oTypes = self.__factory.getObjectTypes()
        for ext in self.__extensions:
            if self.__extensions[ext]:
                if extension in  oTypes[ext]['requires']:
                    raise ProxyException(C.make_error('OBJECT_EXTENSION_IN_USE', extension=extension, origin=ext))

        # Check Acls
        # Required is the 'd' (delete) right for the extension on the current object.
        if self.__current_user is not None:
            topic = "%s.objects.%s" % (self.__env.domain, extension)
            if not self.__acl_resolver.check(self.__current_user, topic, "d", base=self.__base.dn):
                self.__log.debug("user '%s' has insufficient permissions to add extension %s to %s, required is %s:%s on %s" % (
                self.__current_user, extension, self.__base.dn, topic, "d", self.__base.dn))
                raise ACLException(C.make_error('PERMISSION_RETRACT', extension=extension, target=self.__base.dn))

        # Unregister the extensions methods
        for method in list(self.__method_type_map):
            if self.__method_type_map[method] == extension:
                del(self.__method_map[method])
                del(self.__method_type_map[method])

        # Move the extension to retractions
        self.__retractions[extension] = self.__extensions[extension]
        self.__extensions[extension] = None
예제 #12
0
파일: manager.py 프로젝트: peuter/gosa
    def setUserPassword(self, user, object_dn, password):
        """
        Set a new password for a user
        """

        # Do we have write permissions for the requested attribute
        env = Environment.getInstance()
        topic = "%s.objects.%s.attributes.%s" % (env.domain, "User",
                                                 "userPassword")
        aclresolver = PluginRegistry.getInstance("ACLResolver")
        if not aclresolver.check(user, topic, "w", base=object_dn):

            self.__log.debug(
                "user '%s' has insufficient permissions to write %s on %s, required is %s:%s"
                % (user, "isLocked", object_dn, topic, "w"))
            raise ACLException(
                C.make_error('PERMISSION_ACCESS', topic, target=object_dn))

        user = ObjectProxy(object_dn)
        method = user.passwordMethod

        # Try to detect the responsible password method-class
        pwd_o = self.get_method_by_method_type(method)
        if not pwd_o:
            raise PasswordException(
                C.make_error("PASSWORD_UNKNOWN_HASH", type=method))

        # Generate the new password hash using the detected method
        pwd_str = pwd_o.generate_password_hash(password, method)

        # Set the password and commit the changes
        user.userPassword = pwd_str
        user.commit()
예제 #13
0
파일: main.py 프로젝트: peuter/gosa
    def setTwoFactorMethod(self, user_name, object_dn, factor_method, user_password=None):

        # Do we have write permissions for the requested attribute
        self.__check_acl(user_name, object_dn, "w")

        if factor_method == "None":
            factor_method = None

        if factor_method not in self.methods:
            raise UnknownTwoFAMethod(C.make_error("UNKNOWN_2FA_METHOD", method=factor_method))

        # Get the object for the given dn
        user = ObjectProxy(object_dn)
        current_method = self.get_method_from_user(user)
        if current_method == factor_method:
            # nothing to change
            return None

        if current_method is not None:
            # we need to be verified by user password in order to change the method
           if user_password is None or not check_auth(user_name, user_password):
            raise ChangingNotAllowed(C.make_error('CHANGE_2FA_METHOD_FORBIDDEN'))

        if factor_method == "otp":
            return self.__enable_otp(user)
        elif factor_method == "u2f":
            return self.__enable_u2f(user)
        elif factor_method is None:
            # disable two factor auth
            del self.__settings[user.uuid]
            self.__save_settings()
        return None
예제 #14
0
    def registerWebhook(self, user, sender_name, mime_type):
        topic = "%s.webhook.%s" % (self.env.domain, mime_type)
        aclresolver = PluginRegistry.getInstance("ACLResolver")
        if not aclresolver.check(user, topic, "e"):
            self.log.debug("user '%s' has insufficient permissions to register webhook for mime-type %s" % (user, mime_type))
            raise ACLException(C.make_error('PERMISSION_ACCESS', topic))

        # check sender_name syntax
        if not self.name_check.match(sender_name):
            raise WebhookException(C.make_error('INVALID_WEBHOOK_SENDER_NAME'))

        # check mime-type syntax
        if not self.mime_type_check.match(mime_type):
            raise WebhookException(C.make_error('INVALID_WEBHOOK_MIME_TYPE'))

        # check for duplicates
        if mime_type not in self.__handlers:
            raise WebhookException(C.make_error('NO_REGISTERED_WEBHOOK_HANDLER', mime_type))

        path = self.get_path(mime_type, sender_name)
        if self.settings.has(path):
            raise WebhookException(C.make_error('EXISTING_WEBHOOK_HANDLER', mime_type, name=sender_name))

        self.settings.set(path, str(uuid.uuid4()))

        return self.getWebhookUrl(), self.settings.get(path)
예제 #15
0
파일: manager.py 프로젝트: peuter/gosa
    def setUserPassword(self, user, object_dn, password):
        """
        Set a new password for a user
        """

        # Do we have write permissions for the requested attribute
        env = Environment.getInstance()
        topic = "%s.objects.%s.attributes.%s" % (env.domain, "User", "userPassword")
        aclresolver = PluginRegistry.getInstance("ACLResolver")
        if not aclresolver.check(user, topic, "w", base=object_dn):

            self.__log.debug("user '%s' has insufficient permissions to write %s on %s, required is %s:%s" % (
                user, "isLocked", object_dn, topic, "w"))
            raise ACLException(C.make_error('PERMISSION_ACCESS', topic, target=object_dn))

        user = ObjectProxy(object_dn)
        method = user.passwordMethod

        # Try to detect the responsible password method-class
        pwd_o = self.get_method_by_method_type(method)
        if not pwd_o:
            raise PasswordException(C.make_error("PASSWORD_UNKNOWN_HASH", type=method))

        # Generate the new password hash using the detected method
        pwd_str = pwd_o.generate_password_hash(password, method)

        # Set the password and commit the changes
        user.userPassword = pwd_str
        user.commit()
예제 #16
0
    def continueObjectEditing(self, user, ref):
        """
        Objects which have been opened but not edited for a certain amount of time are automatically closed by the backend.
        This command delays this behaviour by increasing the timeout.

        ================= ==========================
        Parameter         Description
        ================= ==========================
        ref               UUID / object reference
        ================= ==========================

        """
        objdsc = self.__get_ref(ref)
        if not objdsc:
            raise ValueError(C.make_error("REFERENCE_NOT_FOUND", ref=ref))

        if not self.__check_user(ref, user):
            raise ValueError(C.make_error("NOT_OBJECT_OWNER"))

        objdsc['last_interaction'] = datetime.datetime.now()
        with make_session() as session:
            obj = session.query(OpenObject).filter(OpenObject.ref == ref).one()
            obj.last_interaction = objdsc['last_interaction']
            session.commit()

        if 'mark_for_deletion' in objdsc:
            # as this object has been marked for deletion, we have to run the garbage collection
            # to remove this mark now
            self.__gc()
예제 #17
0
파일: registry.py 프로젝트: gonicus/gosa
    def registerWebhook(self, user, sender_name, mime_type):
        topic = "%s.webhook.%s" % (self.env.domain, mime_type)
        aclresolver = PluginRegistry.getInstance("ACLResolver")
        if not aclresolver.check(user, topic, "e"):
            self.log.debug("user '%s' has insufficient permissions to register webhook for mime-type %s" % (user, mime_type))
            raise ACLException(C.make_error('PERMISSION_ACCESS', topic))

        # check sender_name syntax
        if not self.name_check.match(sender_name):
            raise WebhookException(C.make_error('INVALID_WEBHOOK_SENDER_NAME'))

        # check mime-type syntax
        if not self.mime_type_check.match(mime_type):
            raise WebhookException(C.make_error('INVALID_WEBHOOK_MIME_TYPE'))

        # check for duplicates
        if mime_type not in self.__handlers:
            raise WebhookException(C.make_error('NO_REGISTERED_WEBHOOK_HANDLER', mime_type))

        path = self.get_path(mime_type, sender_name)
        if self.settings.has(path):
            raise WebhookException(C.make_error('EXISTING_WEBHOOK_HANDLER', mime_type, name=sender_name))

        self.settings.set(path, str(uuid.uuid4()))

        return self.getWebhookUrl(), self.settings.get(path)
예제 #18
0
    def reloadObject(self, user, ref):
        """
        Opens a copy of the object given as ref and
        closes the original instance.
        """
        item = self.__get_ref(ref)
        if item is not None:

            if not self.__check_user(ref, user):
                raise ValueError(C.make_error("NOT_OBJECT_OWNER"))

            oid = item['object']['oid']
            uuid = item['object']['uuid']
            if uuid is None:
                uuid = item['object']['object'].uuid
            session_id = item['session_id']
            new_item = self.openObject(user, session_id, oid, uuid)

            # Close original ref and return the new one
            self.closeObject(user, ref)

            return new_item

        else:
            raise ValueError(C.make_error("REFERENCE_NOT_FOUND", ref=ref))
예제 #19
0
파일: domain.py 프로젝트: peuter/gosa
    def setSambaPassword(self, user, object_dn, password):
        """
        Set a new samba-password for a user
        """

        # Do we have read permissions for the requested attribute
        env = Environment.getInstance()
        topic = "%s.objects.%s.attributes.%s" % (env.domain, "User", "sambaNTPassword")
        aclresolver = PluginRegistry.getInstance("ACLResolver")
        if not aclresolver.check(user, topic, "w", base=object_dn):
            self.__log.debug("user '%s' has insufficient permissions to write %s on %s, required is %s:%s" % (
                user, "isLocked", object_dn, topic, "w"))
            raise ACLException(C.make_error('PERMISSION_ACCESS', topic, target=object_dn))

        topic = "%s.objects.%s.attributes.%s" % (env.domain, "User", "sambaLMPassword")
        aclresolver = PluginRegistry.getInstance("ACLResolver")
        if not aclresolver.check(user, topic, "w", base=object_dn):
            self.__log.debug("user '%s' has insufficient permissions to write %s on %s, required is %s:%s" % (
                user, "isLocked", object_dn, topic, "w"))
            raise ACLException(C.make_error('PERMISSION_ACCESS', topic, target=object_dn))

        # Set the password and commit the changes
        user = ObjectProxy(object_dn)
        user.sambaNTPassword = nthash.encrypt(password)
        user.sambaLMPassword = lmhash.encrypt(password)
        user.commit()
예제 #20
0
파일: workflow.py 프로젝트: GOsa3/gosa
    def _execute_embedded_script(self, script):
        log = logging.getLogger("%s.%s" % (__name__, self.uuid))
        try:
            log.info("start executing workflow script")
            env = dict(data=self._get_data())
            dispatcher = PluginRegistry.getInstance('CommandRegistry')

            def make_dispatch(method):
                def call(*args, **kwargs):
                    return dispatcher.dispatch(self.__user, self.__session_id,
                                               method, *args, **kwargs)

                return call

            # Add public calls
            for method in dispatcher.getMethods():
                env[method] = make_dispatch(method)

            # add logger
            env['log'] = log

            exec(script, env)

            log.info("finished executing workflow script")

            if self.__user is not None:
                # tell the frontend
                e = EventMaker()
                ev = e.Event(
                    e.BackendDone(e.UUID(self.uuid), e.Type("workflow"),
                                  e.State("success")))
                event_object = objectify.fromstring(
                    etree.tostring(ev, pretty_print=True).decode('utf-8'))
                SseHandler.notify(event_object,
                                  channel="user.%s" % self.__user)

        except Exception as ex:
            exc_type, exc_obj, exc_tb = sys.exc_info()
            fname = os.path.split(exc_tb.tb_frame.f_code.co_filename)[1]

            log.error("Exception while executing the embedded script:")
            log.error("%s line %s" % (fname, exc_tb.tb_lineno))
            log.error(exc_type)
            log.error(exc_obj)

            if GosaErrorHandler.get_error_id(str(ex)) is None:
                ex = ScriptError(C.make_error('WORKFLOW_SCRIPT_ERROR',
                                              str(ex)))

            e = EventMaker()
            ev = e.Event(
                e.BackendDone(e.UUID(self.uuid), e.Type("workflow"),
                              e.State("error"), e.Message(str(ex))))
            event_object = objectify.fromstring(
                etree.tostring(ev, pretty_print=True).decode('utf-8'))
            SseHandler.notify(event_object, channel="user.%s" % self.__user)
            raise ex

        return True
예제 #21
0
    def __check_res(self, uuid, res):
        if not res:
            raise EntryNotFound(C.make_error("ENTRY_UUID_NOT_FOUND",
                                             uuid=uuid))

        if len(res) != 1:
            raise EntryNotFound(
                C.make_error("ENTRY_UUID_NOT_UNIQUE", uuid=uuid))
예제 #22
0
파일: command.py 프로젝트: peuter/gosa
    def dispatch(self, user, session_id, func, *arg, **larg):
        """
        The dispatch method will try to call the specified function and
        checks for user.

        Handlers like JSONRPC should use this function to dispatch the real calls.

        ========== ============
        Parameter  Description
        ========== ============
        user       the calling users name
        session_id the calling session id
        func       method to call
        args       ordinary argument list/dict
        ========== ============

        ``Return:`` the real methods result
        """

        # Check for user authentication (if user is 'self' this is an internal call)
        if not user and user != self:
            raise CommandNotAuthorized(C.make_error("COMMAND_NO_USERNAME", method=func))

        # Check if the command is available
        if not func in self.commands:
            raise CommandInvalid(C.make_error("COMMAND_NOT_DEFINED", method=func))

        # Check for permission (if user equals 'self' then this is an internal call)
        if user != self:
            chk_options = dict(zip(self.commands[func]['sig'], arg))
            chk_options.update(larg)
            acl = PluginRegistry.getInstance("ACLResolver")
            if not acl.check(user, "%s.%s.%s" % (self.env.domain, "command", func), "x", options=chk_options):
                raise CommandNotAuthorized(C.make_error("PERMISSION_EXEC", method=func))

        # Convert to list
        arg = list(arg)

        # Check if call is interested in calling user ID, prepend it
        if self.callNeedsUser(func):
            if user != self:
                arg.insert(0, user)
            else:
                arg.insert(0, None)

        # Check if call is interested in calling session ID, prepend it
        if self.callNeedsSession(func):
            index = 1 if self.callNeedsUser(func) else 0
            if user != self:
                arg.insert(index, session_id)
            else:
                arg.insert(index, None)

        # Handle function type (additive, first match, regular)
        (clazz, method) = self.path2method(self.commands[func]['path'])

        return PluginRegistry.modules[clazz].\
                 __getattribute__(method)(*arg, **larg)
예제 #23
0
파일: proxy.py 프로젝트: peuter/gosa
    def extend(self, extension):
        """
        Extends the base-object with the given extension
        """

        # Is this a valid extension?
        if not extension in self.__extensions:
            raise ProxyException(C.make_error('OBJECT_EXTENSION_NOT_ALLOWED', extension=extension))

        # Is this extension already active?
        # if self.__extensions[extension] is not None:
        #     raise ProxyException(C.make_error('OBJECT_EXTENSION_DEFINED', extension=extension))

        # Ensure that all precondition for this extension are fulfilled
        object_types = self.__factory.getObjectTypes()
        for required_extension in object_types[extension]['requires']:
            if not required_extension in self.__extensions or self.__extensions[required_extension] is None:
                raise ProxyException(C.make_error('OBJECT_EXTENSION_DEPENDS',
                                                  extension=extension,
                                                  missing=required_extension))

        # Check Acls
        # Required is the 'c' (create) right for the extension on the current object.
        if self.__current_user is not None:
            topic = "%s.objects.%s" % (self.__env.domain, extension)
            if not self.__acl_resolver.check(self.__current_user, topic, "c", base=self.__base.dn):
                self.__log.debug("user '%s' has insufficient permissions to add extension %s to %s, required is %s:%s on %s" % (
                self.__current_user, extension, self.__base.dn, topic, "c", self.__base.dn))
                raise ACLException(C.make_error('PERMISSION_EXTEND', extension=extension, target=self.__base.dn))

        # Create extension
        if extension in self.__retractions:
            self.__extensions[extension] = self.__retractions[extension]
            del self.__retractions[extension]
        else:
            mode = "extend"
            current_object = ObjectProxy(self.dn)
            if current_object.__extensions[extension]:
                mode = "update"

            self.__extensions[extension] = self.__factory.getObject(extension, self.__base.uuid, mode=mode)
            self.__extensions[extension].parent = self
            self.__extensions[extension]._owner = self.__current_user

        # Register the extensions methods
        object_types = self.__factory.getObjectTypes()
        for method in object_types[extension]['methods']:
            self.__method_map[method] = getattr(self.__extensions[extension], method)
            self.__method_type_map[method] = extension

        # Set initial values for foreign properties
        self.populate_to_foreign_properties(extension)
예제 #24
0
파일: back_ldap.py 프로젝트: gonicus/gosa
    def get_final_dn(self, base_dn, data, backend_params):
        # Check if obligatory information for assembling the DN are
        # provided
        if not 'RDN' in backend_params:
            raise RDNNotSpecified(C.make_error("RDN_NOT_SPECIFIED"))

        # Build unique DN using maybe optional RDN parameters
        rdns = [d.strip() for d in backend_params['RDN'].split(",")]

        FixedRDN = backend_params['FixedRDN'] if 'FixedRDN' in backend_params else None
        dn = self.get_uniq_dn(rdns, base_dn, data, FixedRDN)
        if not dn:
            raise DNGeneratorError(C.make_error("NO_UNIQUE_DN", base=base_dn, rdns=", ".join(rdns)))
        return dn
예제 #25
0
파일: sid.py 프로젝트: peuter/gosa
    def process(self, obj, key, valDict, method, number, domain, group_type=0):

        if number == "None":
            raise SambaException(
                C.make_error("ATTRIBUTE_NOT_FOUND", "uidNumber|gidNumber"))

        if domain == "None":
            raise SambaException(
                C.make_error("ATTRIBUTE_NOT_FOUND", "sambaDomainName"))

        index = PluginRegistry.getInstance("ObjectIndex")
        sid = index.search({
            '_type': 'SambaDomain',
            'sambaDomainName': domain
        }, {
            'sambaSID': 1,
            'sambaAlgorithmicRidBase': 1
        })

        if len(sid) != 1:
            raise SambaException(
                C.make_error("SAMBA_DOMAIN_WITHOUT_SID", domain))
        dsid = sid[0]['sambaSID'][0]

        if 'sambaAlgorithmicRidBase' in sid[0]:
            ridbase = int(sid[0]['sambaAlgorithmicRidBase'][0])
        else:
            ridbase = int(self.env.config.get('samba.ridbase', default=1000))

        # Generate a sid for groups or users.
        group_type = int(group_type)
        number = int(number)

        if "group" == method:
            if group_type == 0:
                sid = dsid + "-" + str(number * 2 + ridbase + 1)
            else:
                sid = dsid + "-" + str(group_type)
            valDict[key]['value'] = [sid]

        elif "user" == method:
            sid = dsid + "-" + str(number * 2 + ridbase)
            valDict[key]['value'] = [sid]

        else:
            raise SambaException(C.make_error("SAMBA_NO_SID_TYPE",
                                              type=method))

        return key, valDict
예제 #26
0
    def create(self,
               base,
               data,
               params,
               foreign_keys=None,
               needed=None,
               user=None):
        """
        Creates a new database entry
        """

        # All entries require a naming attribute, if it's not available we cannot generate a dn for the entry
        if not 'rdn' in params:
            raise RDNNotSpecified(C.make_error("RDN_NOT_SPECIFIED"))

        # Split given rdn-attributes into a list.
        rdns = [d.strip() for d in params['rdn'].split(",")]

        # Get FixedRDN attribute
        FixedRDN = params['FixedRDN'] if 'FixedRDN' in params else None

        # Get a unique dn for this entry, if there was no free dn left (None) throw an error
        object_dn = self.get_uniq_dn(rdns, base, data, FixedRDN)
        if not object_dn:
            raise DNGeneratorError(
                C.make_error("NO_UNIQUE_DN", base=base, rdns=", ".join(rdns)))

        # Build the entry that will be written to the json-database
        json = self.__load()
        str_uuid = str(uuid.uuid1())
        obj = {
            'dn': object_dn,
            'type': params['type'],
            'parentDN': base,
            'modifyTimestamp': datetime.datetime.now().isoformat(),
            'createTimestamp': datetime.datetime.now().isoformat()
        }
        for attr in data:
            obj[attr] = data[attr]['value']

        # Append the entry to the databse and save the changes
        if not str_uuid in json:
            json[str_uuid] = {}
        json[str_uuid][params['type']] = obj
        self.__save(json)

        # Return the uuid of the generated entry
        return str_uuid
예제 #27
0
파일: methods.py 프로젝트: peuter/gosa
    def getGuiDialogs(self, objectType):
        factory = ObjectFactory.getInstance()
        if objectType not in factory.getObjectTypes():
            raise GOsaException(
                C.make_error("OBJECT_UNKNOWN_TYPE", type=objectType))

        return factory.getObjectDialogs(objectType)
예제 #28
0
파일: command.py 프로젝트: peuter/gosa
    def serve(self):
        """
        Start serving the command registry to the outside world. Send
        hello and register event callbacks.
        """

        for clazz in PluginRegistry.modules.values():
            for mname, method in getmembers(clazz):
                if ismethod(method) and hasattr(method, "isCommand"):
                    func = mname

                    # Adjust documentation
                    if not method.__help__:
                        raise CommandInvalid(C.make_error("COMMAND_WITHOUT_DOCS", method=func))

                    doc = re.sub("(\s|\n)+", " ", method.__help__).strip()

                    self.log.debug("registering %s" % func)
                    info = {
                        'name': func,
                        'path': "%s.%s" % (clazz.__class__.__name__, mname),
                        'sig': [] if not getargspec(method).args else getargspec(method).args,
                        'target': clazz.get_target(),
                        'type': getattr(method, "type", NORMAL),
                        'doc': doc,
                        }

                    if 'self' in info['sig']:
                        info['sig'].remove('self')

                    self.commands[func] = info
예제 #29
0
파일: manager.py 프로젝트: peuter/gosa
    def accountUnlockable(self, user, object_dn):
        index = PluginRegistry.getInstance("ObjectIndex")

        # Do we have read permissions for the requested attribute
        env = Environment.getInstance()
        topic = "%s.objects.%s.attributes.%s" % (env.domain, "User", "isLocked")
        aclresolver = PluginRegistry.getInstance("ACLResolver")
        if not aclresolver.check(user, topic, "r", base=object_dn):

            self.__log.debug("user '%s' has insufficient permissions to read %s on %s, required is %s:%s" % (
                user, "isLocked", object_dn, topic, "r"))
            raise ACLException(C.make_error('PERMISSION_ACCESS', topic, target=object_dn))

        res = index.search({'dn': object_dn, 'userPassword': '******'}, {'userPassword': 1})
        if len(res):
            hsh = res[0]['userPassword'][0]
        else:
            # No password hash -> cannot lock/unlock account
            return False

        # Try to detect the responsible password method-class
        pwd_o = self.detect_method_by_hash(hsh)
        if not pwd_o:

            # Could not identify password method
            return False

        return pwd_o.isUnlockable(hsh)
예제 #30
0
파일: __init__.py 프로젝트: peuter/gosa
def get_filter(name):
    for entry in pkg_resources.iter_entry_points("gosa.object.filter"):
        module = entry.load()
        if module.__name__ == name:
            return module

    raise KeyError(C.make_error("FILTER_NO_INSTANCE", filter=name))
예제 #31
0
파일: dollar.py 프로젝트: gonicus/gosa
    def process(self, obj, key, valDict):
        if len(valDict[key]['value']) and type(valDict[key]['value'][0]) == str:
            valDict[key]['value'][0] = valDict[key]['value'][0].rstrip("$")
        else:
            raise ValueError(C.make_error("TYPE_UNKNOWN", self.__class__.__name__, type=type(valDict[key]['value'])))

        return key, valDict
예제 #32
0
    def process(self, topic, message):

        try:
            req = loads(message)
        except ValueError as e:
            raise ValueError(C.make_error("INVALID_JSON", data=str(e)))

        try:
            id_ = req['id']
            name = req['method']
            args = req['params']
            kwargs = req['kwparams']
            if 'user' in req:
                user = req['user']
            else:
                user = topic.split("/")[2]
            sid = req['session_id'] if 'session_id' in req else None

        except KeyError as e:
            self.log.error("KeyError: %s" % e)
            raise BadServiceRequest(message)

        self.log.debug("received call [%s, user=%s, session-id=%s] for %s: %s(%s,%s)" % (id_, user, sid, topic, name, args, kwargs))

        try:
            return id_, self.__command_registry.dispatch(user, sid, name, *args, **kwargs)
        except Exception as e:
            # Write exception to log
            exc_type, exc_value, exc_traceback = sys.exc_info()
            self.log.error("".join(traceback.format_exception(exc_type, exc_value, exc_traceback)))
            raise e
예제 #33
0
파일: index.py 프로젝트: peuter/gosa
    def insert(self, obj, skip_base_check=False):
        if not skip_base_check:
            pdn = self.__session.query(ObjectInfoIndex.dn).filter(
                ObjectInfoIndex.dn == obj.get_parent_dn()).one_or_none()

            # No parent?
            if not pdn:
                self.log.debug(
                    "ignoring object that has no base in the current index: " +
                    obj.dn)
                return

            parent = self._get_object(obj.get_parent_dn())
            if not parent.can_host(obj.get_base_type()):
                self.log.debug(
                    "ignoring object that is not relevant for the index: " +
                    obj.dn)
                return

        self.log.debug("creating object index for %s" % obj.uuid)

        uuid = self.__session.query(ObjectInfoIndex.uuid).filter(
            ObjectInfoIndex.uuid == obj.uuid).one_or_none()
        if uuid:
            raise IndexException(
                C.make_error('OBJECT_EXISTS', "base", uuid=obj.uuid))

        self.__save(obj.asJSON(True))
예제 #34
0
    def process(self, topic, message):

        try:
            req = loads(message)
        except ValueError as e:
            raise ValueError(C.make_error("INVALID_JSON", data=str(e)))

        try:
            id_ = req['id']
            name = req['method']
            args = req['params']
            user = req['user'] if 'user' in req else topic.split("/")[2]
            sid = req['session_id'] if 'session_id' in req else None

        except KeyError as e:
            self.log.error("KeyError: %s" % e)
            raise BadServiceRequest(message)

        self.log.debug("received call [%s] for %s: %s(%s)" %
                       (id_, topic, name, args))

        try:
            return id_, self.__command_registry.dispatch(
                user, sid, name, *args)
        except Exception as e:
            # Write exception to log
            exc_type, exc_value, exc_traceback = sys.exc_info()
            self.log.error("".join(
                traceback.format_exception(exc_type, exc_value,
                                           exc_traceback)))
            raise e
예제 #35
0
파일: manager.py 프로젝트: peuter/gosa
    def accountUnlockable(self, user, object_dn):
        index = PluginRegistry.getInstance("ObjectIndex")

        # Do we have read permissions for the requested attribute
        env = Environment.getInstance()
        topic = "%s.objects.%s.attributes.%s" % (env.domain, "User",
                                                 "isLocked")
        aclresolver = PluginRegistry.getInstance("ACLResolver")
        if not aclresolver.check(user, topic, "r", base=object_dn):

            self.__log.debug(
                "user '%s' has insufficient permissions to read %s on %s, required is %s:%s"
                % (user, "isLocked", object_dn, topic, "r"))
            raise ACLException(
                C.make_error('PERMISSION_ACCESS', topic, target=object_dn))

        res = index.search({
            'dn': object_dn,
            'userPassword': '******'
        }, {'userPassword': 1})
        if len(res):
            hsh = res[0]['userPassword'][0]
        else:
            # No password hash -> cannot lock/unlock account
            return False

        # Try to detect the responsible password method-class
        pwd_o = self.detect_method_by_hash(hsh)
        if not pwd_o:

            # Could not identify password method
            return False

        return pwd_o.isUnlockable(hsh)
예제 #36
0
파일: methods.py 프로젝트: GOsa3/gosa
    def searchForObjectDetails(self,
                               user,
                               extension,
                               attribute,
                               search_filter,
                               attributes,
                               skip_values,
                               options=None):
        """
        Search selectable items valid for the attribute "extension.attribute".

        This is used to add new groups to the users groupMembership attribute.
        """

        # Extract the the required information about the object
        # relation out of the BackendParameters for the given extension.
        object_factory = ObjectFactory.getInstance()
        be_data = object_factory.getObjectBackendParameters(
            extension, attribute)
        if not be_data:
            raise GOsaException(
                C.make_error("BACKEND_PARAMETER_MISSING",
                             extension=extension,
                             attribute=attribute))

        # Collection basic information
        object_type, object_attribute, _, _ = be_data[attribute]
        return self.searchObjects(user, object_type, object_attribute,
                                  search_filter, attributes, skip_values,
                                  options)
예제 #37
0
 def createAddGroupIfNotExists(self, user_dn, user_name, gid_number):
     if user_dn is None or user_name is None or gid_number is None:
         return
     index = PluginRegistry.getInstance("ObjectIndex")
     res = index.search({
         "_type": "PosixGroup",
         "gidNumber": gid_number
     }, {"dn": 1})
     if len(res) == 0:
         # create group
         user = ObjectProxy(user_dn)
         group = ObjectProxy(user.get_adjusted_parent_dn(), "PosixGroup")
         group.cn = user_name
         group.description = N_("Group of user %s" % user_name)
         group.autoGid = False
         group.gidNumber = gid_number
         group.memberUid = [user_name]
         group.commit()
     elif len(res) == 1:
         group = ObjectProxy(res[0]["dn"])
         if user_name not in group.memberUid:
             group.memberUid.append(user_name)
             group.commit()
     else:
         raise GosaException(
             C.make_error('GROUP_ID_IS_AMBIGUOUS', gid=gid_number))
예제 #38
0
파일: mode.py 프로젝트: gonicus/gosa
    def process(self, obj, key, valDict):
        # Create a list with all relevant attributes.
        alist = ['inVacation', 'activateSpamFilter', 'mailSizeFilter',
                 'localDelivery', 'skipOwnMailbox', 'customSieveScript']

        # Build up a list of values to encode.
        res = {}
        for entry in alist:
            if not len(valDict[entry]['value']):
                raise AttributeError(C.make_error('ATTRIBUTE_MANDATORY', entry))
            else:
                res[entry] = valDict[entry]['value'][0]

        # Encode the mail delivery mode attribute.
        result = ""
        if res['inVacation']:
            result += "V"
        if res['activateSpamFilter']:
            result += "S"
        if res['mailSizeFilter']:
            result += "R"
        if res['localDelivery']:
            result += "L"
        if res['skipOwnMailbox']:
            result += "I"
        if res['customSieveScript']:
            result += "C"

        valDict[key]['value'] = ["[" + result + "]"]

        return key, valDict
예제 #39
0
파일: methods.py 프로젝트: peuter/gosa
    def getUserDetails(self, userid):
        index = PluginRegistry.getInstance("ObjectIndex")
        res = index.search({
            '_type': 'User',
            'uid': userid
        }, {
            'sn': 1,
            'givenName': 1,
            'cn': 1,
            'dn': 1,
            '_uuid': 1,
            '_last_changed': 1
        })

        if len(res) == 0:
            raise GOsaException(C.make_error("UNKNOWN_USER", target=userid))

        cache_path = self.env.config.get('user.image-path',
                                         default="/var/lib/gosa/images")
        icon = "@Ligature/user"
        if os.path.exists(
                os.path.join(cache_path, res[0]['_uuid'], "jpegPhoto", "0",
                             "64.jpg")):
            icon = "/images/%s/jpegPhoto/0/64.jpg?c=%s" % (
                res[0]['_uuid'], res[0]["_last_changed"])

        return ({
            'sn': res[0]['sn'][0],
            'givenName': res[0]['givenName'][0],
            'dn': res[0]['dn'],
            'uuid': res[0]['_uuid'],
            'icon': icon,
            'cn': res[0]['cn'][0]
        })
예제 #40
0
파일: munged.py 프로젝트: peuter/gosa
    def process(self, obj, key, valDict):

        # Create a dictionary with all relevant samba attributes.
        alist = [
            'CtxCallback', 'CtxCallbackNumber', 'CtxCfgFlags1',
            'CtxCfgPresent', 'CtxInitialProgram', 'CtxKeyboardLayout',
            'CtxMaxConnectionTime', 'CtxMaxDisconnectionTime',
            'CtxMaxIdleTime', 'Ctx_flag_connectClientDrives',
            'CtxMinEncryptionLevel', 'oldStorageBehavior', 'CtxNWLogonServer',
            'CtxShadow', 'CtxWFHomeDir', 'CtxWFHomeDirDrive',
            'CtxWFProfilePath', 'CtxWorkDirectory', 'Ctx_flag_brokenConn',
            'Ctx_flag_connectClientPrinters', 'Ctx_flag_defaultPrinter',
            'Ctx_flag_inheritMode', 'Ctx_flag_reConn', 'Ctx_shadow',
            'Ctx_flag_tsLogin'
        ]

        # Build up a list of values to encode.
        res = {}
        for entry in alist:
            if not len(valDict[entry]['value']):
                raise AttributeError(C.make_error('ATTRIBUTE_MANDATORY',
                                                  entry))
            else:
                res[entry] = valDict[entry]['value'][0]

        # Encode the sambaMungedDial attribute.
        result = SambaMungedDial.encode(res)
        valDict[key]['value'] = [result]

        return key, valDict
예제 #41
0
파일: munged.py 프로젝트: gonicus/gosa
    def process(self, obj, key, valDict):

        # Create a dictionary with all relevant samba attributes.
        alist = ['CtxCallback', 'CtxCallbackNumber', 'CtxCfgFlags1', 'CtxCfgPresent',
                 'CtxInitialProgram', 'CtxKeyboardLayout', 'CtxMaxConnectionTime',
                 'CtxMaxDisconnectionTime', 'CtxMaxIdleTime', 'Ctx_flag_connectClientDrives',
                 'CtxMinEncryptionLevel', 'oldStorageBehavior',
                 'CtxNWLogonServer', 'CtxShadow', 'CtxWFHomeDir', 'CtxWFHomeDirDrive',
                 'CtxWFProfilePath', 'CtxWorkDirectory', 'Ctx_flag_brokenConn',
                 'Ctx_flag_connectClientPrinters', 'Ctx_flag_defaultPrinter',
                 'Ctx_flag_inheritMode', 'Ctx_flag_reConn', 'Ctx_shadow', 'Ctx_flag_tsLogin']

        # Build up a list of values to encode.
        res = {}
        for entry in alist:
            if not len(valDict[entry]['value']):
                raise AttributeError(C.make_error('ATTRIBUTE_MANDATORY', entry))
            else:
                res[entry] = valDict[entry]['value'][0]

        # Encode the sambaMungedDial attribute.
        result = SambaMungedDial.encode(res)
        valDict[key]['value'] = [result]

        return key, valDict
예제 #42
0
파일: proxy.py 프로젝트: peuter/gosa
    def asJSON(self, only_indexed=False):
        """
        Returns JSON representations for the base-object and all its extensions.
        """

        #TODO: only_indexed!?
        atypes = self.__factory.getAttributeTypes()

        # Check permissions
        topic = "%s.objects.%s" % (self.__env.domain, self.__base_type)
        if self.__current_user is not None and not self.__acl_resolver.check(self.__current_user, topic, "r", base=self.dn):
            self.__log.debug("user '%s' has insufficient permissions for asJSON on %s, required is %s:%s" % (
                self.__current_user, self.dn, topic, "r"))
            raise ACLException(C.make_error('PERMISSION_ACCESS', topic, target=self.dn))

        res = {'dn': self.__base.dn, '_type': self.__base.__class__.__name__,
               '_parent_dn': self.get_parent_dn(self.__base.dn),
               '_adjusted_parent_dn': self.get_adjusted_parent_dn(self.__base.dn),
               '_uuid': self.__base.uuid}

        # Create non object pseudo attributes
        if self.__base.modifyTimestamp:
            res['_last_changed'] = time.mktime(self.__base.modifyTimestamp.timetuple())

        res['_extensions'] = [k for k in self.__extensions.keys() if self.__extensions[k]]

        props = self.__property_map
        for propname in self.__property_map:

            # Use the object-type conversion method to get valid item string-representations.
            prop_value = props[propname]['value']
            if props[propname]['type'] != "Binary":
                res[propname] = atypes[props[propname]['type']].convert_to("UnicodeString", prop_value)

        return res
예제 #43
0
파일: interface.py 프로젝트: peuter/gosa
 def is_responsible_for_password_hash(self, password_hash):
     """
     Checks whether this class is responsible for this kind of password hashes or not.
     """
     raise NotImplementedError(
         C.make_error('NOT_IMPLEMENTED',
                      method="is_responsible_for_password_hash"))
예제 #44
0
파일: __init__.py 프로젝트: peuter/gosa
    def build_dn_list(self, rdns, base, data, FixedRDN):
        """
        Build a list of possible DNs for the given properties
        """

        fix = rdns[0]
        var = rdns[1:] if len(rdns) > 1 else []
        dns = [fix]

        # Check if we've have to use a fixed RDN.
        if FixedRDN:
            return["%s,%s" % (FixedRDN, base)]

        # Bail out if fix part is not in data
        if not fix in data:
            raise DNGeneratorError(C.make_error("GENERATOR_RDN_ATTRIBUTE_MISSING", fix))

        # Append possible variations of RDN attributes
        if var:
            for rdn in permutations(var + [None] * (len(var) - 1), len(var)):
                dns.append("%s,%s" % (fix, ",".join(filter(lambda x: x and x in data and data[x], list(rdn)))))
        dns = list(set(dns))

        # Assemble DN of RDN combinations
        dn_list = []
        for t in [tuple(d.split(",")) for d in dns]:
            ndn = []
            for k in t:
                ndn.append("%s=%s" % (k, ldap.dn.escape_dn_chars(data[k]['value'][0])))
            dn_list.append("+".join(ndn) + "," + base)

        return sorted(dn_list, key=len)
예제 #45
0
    def move(self, item_uuid, new_base, needed=None, user=None):
        """
        Moves an entry to another base
        """
        json = self.__load()
        if item_uuid in json:
            for obj in json[item_uuid]:
                if "dn" in json[item_uuid][obj]:

                    # Update the source entry
                    entry = json[item_uuid][obj]
                    entry['dn'] = re.sub(
                        re.escape(entry['parentDN']) + "$", new_base,
                        entry['dn'])
                    entry['parentDN'] = new_base

                    # Check if we can move the entry
                    if self.exists(entry['dn']):
                        raise BackendError(
                            C.make_error("TARGET_EXISTS", target=entry['dn']))

                    # Save the changes
                    json[item_uuid][obj] = entry
                    self.__save(json)
                    return True
        return False
예제 #46
0
    def getUserPPDs(self, user):
        index = PluginRegistry.getInstance("ObjectIndex")
        res = index.search({"_type": "User", "uid": user}, {"dn": 1})
        if len(res) == 0:
            raise EntryNotFound(C.make_error("USER_NOT_FOUND", topic=user))

        object = ObjectProxy(res[0]["dn"])
        printer_cns = []
        if object.is_extended_by("GotoEnvironment"):
            printer_cns.append(object.gotoPrinters)
        if object.is_extended_by("PosixUser"):
            for group_cn in object.groupMembership:
                group = ObjectProxy(group_cn)
                if group.is_extended_by("GotoEnvironment"):
                    printer_cns.append(group.gotoPrinters)
        # collect all PPDs
        res = index.search({
            "_type": "GotoPrinter",
            "cn": {
                "in_": printer_cns
            }
        }, {"gotoPrinterPPD": 1})
        ppds = []
        for r in res:
            ppds.append(r["gotoPrinterPPD"])
        return ppds
예제 #47
0
    def build_dn_list(self, rdns, base, data, FixedRDN):
        fix = rdns[0]
        var = rdns[1:] if len(rdns) > 1 else []
        dns = [fix]

        # Check if we've have to use a fixed RDN.
        if FixedRDN:
            return["%s,%s" % (FixedRDN, base)]

        # Bail out if fix part is not in data
        if not fix in data:
            raise DNGeneratorError(C.make_error("ATTRIBUTE_NOT_FOUND", attribute=fix))

        # Append possible variations of RDN attributes
        if var:
            for rdn in permutations(var + [None] * (len(var) - 1), len(var)):
                dns.append("%s,%s" % (fix, ",".join(filter(lambda x: x and x in data and data[x], list(rdn)))))
        dns = list(set(dns))

        # Assemble DN of RDN combinations
        dn_list = []
        for t in [tuple(d.split(",")) for d in dns]:
            ndn = []
            for k in t:
                ndn.append("%s=%s" % (k, ldap.dn.escape_dn_chars(data[k]['value'][0])))
            dn_list.append("+".join(ndn) + "," + base)

        return sorted(dn_list, key=len)
예제 #48
0
    def process(self, obj, key, valDict):
        # Create a list with all relevant attributes.
        alist = [
            'inVacation', 'activateSpamFilter', 'mailSizeFilter',
            'localDelivery', 'skipOwnMailbox', 'customSieveScript'
        ]

        # Build up a list of values to encode.
        res = {}
        for entry in alist:
            if not len(valDict[entry]['value']):
                raise AttributeError(C.make_error('ATTRIBUTE_MANDATORY',
                                                  entry))
            else:
                res[entry] = valDict[entry]['value'][0]

        # Encode the mail delivery mode attribute.
        result = ""
        if res['inVacation']:
            result += "V"
        if res['activateSpamFilter']:
            result += "S"
        if res['mailSizeFilter']:
            result += "R"
        if res['localDelivery']:
            result += "L"
        if res['skipOwnMailbox']:
            result += "I"
        if res['customSieveScript']:
            result += "C"

        valDict[key]['value'] = ["[" + result + "]"]

        return key, valDict
예제 #49
0
    def removeObject(self, user, oid, *args, **kwargs):
        """
        Open object on the agent side and calls its remove method

        ================= ==========================
        Parameter         Description
        ================= ==========================
        oid               OID of the object to create
        args/kwargs       Arguments to be used when getting an object instance
        ================= ==========================

        ``Return``: True
        """

        # In case of "object" we want to check the lock
        if oid == 'object':
            lck = self.__get_lock(args[0])
            if lck:
                raise Exception(
                    C.make_error(
                        "OBJECT_LOCKED",
                        object=args[0],
                        user=lck['user'],
                        when=lck['created'].strftime("%Y-%m-%d (%H:%M:%S)")))

        # Use oid to find the object type
        obj_type = self.__get_object_type(oid)

        # Make object instance and store it
        kwargs['user'] = user
        obj = obj_type(*args, **kwargs)
        obj.remove()
        return True
예제 #50
0
파일: __init__.py 프로젝트: peuter/gosa
def get_operator(name):
    for entry in pkg_resources.iter_entry_points("gosa.object.operator"):
        module = entry.load()
        if module.__name__ == name:
            return module

    raise KeyError(C.make_error("OPERATOR_NO_INSTANCE", operator=name))
예제 #51
0
    def removeObject(self, user, oid, *args, **kwargs):
        """
        Open object on the agent side and calls its remove method

        ================= ==========================
        Parameter         Description
        ================= ==========================
        oid               OID of the object to create
        args/kwargs       Arguments to be used when getting an object instance
        ================= ==========================

        ``Return``: True
        """

        # In case of "object" we want to check the lock
        if oid == 'object':
            lck = self.__get_lock(args[0])
            if lck:
                raise Exception(C.make_error("OBJECT_LOCKED", object=args[0],
                    user=lck['user'],
                    when=lck['created'].strftime("%Y-%m-%d (%H:%M:%S)")
                    ))

        # Use oid to find the object type
        obj_type = self.__get_object_type(oid)

        # Make object instance and store it
        kwargs['user'] = user
        obj = obj_type(*args, **kwargs)
        obj.remove()
        return True
예제 #52
0
파일: proxy.py 프로젝트: peuter/gosa
    def remove(self, recursive=False):
        """
        Removes the currently proxied object.
        """

        # Check ACLs
        # We need the 'd' right for the current base-object and all its active extensions to be able to remove it.
        if self.__current_user is not None:
            required_acl_objects = [self.__base_type] + [ext for ext, item in self.__extensions.items() if
                                                         item is not None]
            for ext_type in required_acl_objects:
                topic = "%s.objects.%s" % (self.__env.domain, ext_type)
                if not self.__acl_resolver.check(self.__current_user, topic, "d", base=self.dn):
                    self.__log.debug("user '%s' has insufficient permissions to remove %s, required is %s:%s" % (
                        self.__current_user, self.__base.dn, topic, 'd'))
                    raise ACLException(C.make_error('PERMISSION_REMOVE', target=self.__base.dn))

        zope.event.notify(ObjectChanged("pre object remove", self.__base))

        if recursive:

            # Load all children and remove them, starting from the most
            # nested ones.
            index = PluginRegistry.getInstance("ObjectIndex")
            children = index.search({"dn": ["%," + self.__base.dn]}, {'dn': 1})
            children = [c['dn'] for c in children]

            children.sort(key=len, reverse=True)

            for child in children:
                c_obj = ObjectProxy(child)
                c_obj.remove(recursive=True)

        else:
            # Test if we've children
            index = PluginRegistry.getInstance("ObjectIndex")
            if len(index.search({"dn": "%," + self.__base.dn}, {'dn': 1})):
                raise ProxyException(C.make_error('OBJECT_HAS_CHILDREN', target=self.__base.dn))

        for extension in [e for e in self.__extensions.values() if e]:
            extension.remove_refs()
            extension.retract()

        self.__base.remove_refs()
        self.__base.remove()

        zope.event.notify(ObjectChanged("post object remove", self.__base))
예제 #53
0
파일: ldap.py 프로젝트: peuter/gosa
    def get_connection(self):
        """
        Get a new connection from the pool.

        ``Return``: LDAP connection
        """
        # Are there free connections in the pool?
        try:
            next_free = LDAPHandler.connection_usage.index(False)
        except ValueError:
            raise LDAPException(C.make_error("LDAP_NO_CONNECTIONS"))

        # Need to initialize?
        if not LDAPHandler.connection_handle[next_free]:
            get = self.env.config.get
            self.log.debug("initializing LDAP connection to %s" %
                           str(self.__url))
            conn = ldap.ldapobject.ReconnectLDAPObject(
                "%s://%s" % (self.__url.urlscheme, self.__url.hostport),
                retry_max=int(get("ldap.retry-max", default=3)),
                retry_delay=int(get("ldap.retry-delay", default=5)))

            # We only want v3
            conn.protocol_version = ldap.VERSION3

            # If no SSL scheme used, try TLS
            if get("ldap.tls", default="True").lower(
            ) == "true" and ldap.TLS_AVAIL and self.__url.urlscheme != "ldaps":
                try:
                    conn.start_tls_s()
                except ldap.PROTOCOL_ERROR as detail:
                    self.log.debug(
                        "cannot use TLS, falling back to unencrypted session")

            try:
                # Simple bind?
                if self.__bind_dn:
                    self.log.debug("starting simple bind using '%s'" %
                                   self.__bind_dn)
                    conn.simple_bind_s(self.__bind_dn, self.__bind_secret)
                elif self.__bind_user:
                    self.log.debug("starting SASL bind using '%s'" %
                                   self.__bind_user)
                    auth_tokens = ldap.sasl.digest_md5(self.__bind_user,
                                                       self.__bind_secret)
                    conn.sasl_interactive_bind_s("", auth_tokens)
                else:
                    self.log.debug("starting anonymous bind")
                    conn.simple_bind_s()

            except ldap.INVALID_CREDENTIALS as detail:
                self.log.error("LDAP authentication failed: %s" % str(detail))

            LDAPHandler.connection_handle[next_free] = conn

        # Lock entry
        LDAPHandler.connection_usage[next_free] = True

        return LDAPHandler.connection_handle[next_free]
예제 #54
0
    def diffObject(self, user, ref):
        """
        Opens a copy of the object given as ref and
        returns a diff - if any.
        """
        if not ref in self.__stack:
            return None

        if not self.__check_user(ref, user):
            raise ValueError(C.make_error("NOT_OBJECT_OWNER"))

        # Load current object
        item = self.__stack[ref]
        current_obj = ObjectProxy(item['object']['dn'])

        # Load cache object
        cache_obj = item['object']['object']

        ##
        ## Generate delta
        ##
        delta = {'attributes': {'added': {}, 'removed': [], 'changed': {}, 'blocked_by': {}}, 'extensions': {'added': [], 'removed': []}}

        # Compare extension list
        crnt_extensions = set(current_obj.get_object_info()['extensions'].items())
        cche_extensions = set(cache_obj.get_object_info()['extensions'].items())
        for _e, _s in crnt_extensions - cche_extensions:
            if _s:
                delta['extensions']['added'].append(_e)
            else:
                delta['extensions']['removed'].append(_e)

        # Compare attribute contents
        crnt_attributes = dict(filter(lambda x: x[1] is not None, current_obj.get_attribute_values()['value'].items()))
        cche_attributes = dict(filter(lambda x: x[1] is not None, cache_obj.get_attribute_values()['value'].items()))
        all_attributes = []
        for _k, _v in crnt_attributes.items():
            if _k in cche_attributes:
                if _v != cche_attributes[_k]:
                    delta['attributes']['changed'][_k] = _v
                    all_attributes.append(_k)
            else:
                delta['attributes']['added'][_k] = _v
                all_attributes.append(_k)

        for _k, _v in cche_attributes.items():
            # Don't add the individual attributes of extensions that are removed anyway
            if current_obj.get_extension_off_attribute(_k) in delta['extensions']['removed']:
                continue
            if not _k in crnt_attributes:
                delta['attributes']['removed'].append(_k)
                all_attributes.append(_k)

        # Find blocking dependencies between attributes
        details = current_obj.get_attributes(detail=True)
        for attribute_name in all_attributes:
            delta['attributes']['blocked_by'][attribute_name] = list(map(lambda x: x['name'], details[attribute_name]['blocked_by']))

        return delta
예제 #55
0
파일: hash.py 프로젝트: gonicus/gosa
    def process(self, obj, key, valDict):
        if len(valDict[key]['value']) and type(valDict[key]['value'][0]) == str:
            valDict['sambaNTPassword']['value'] = [nthash.encrypt(valDict[key]['value'][0])]
            valDict['sambaLMPassword']['value'] = [lmhash.encrypt(valDict[key]['value'][0])]
        else:
            raise ValueError(C.make_error("TYPE_UNKNOWN", self.__class__.__name__, type=type(valDict[key]['value'])))

        return key, valDict
예제 #56
0
파일: command.py 프로젝트: gonicus/gosa
    def __call_needs(self, func, name):
        if not func in self.commands:
            raise CommandInvalid(C.make_error("COMMAND_NOT_DEFINED", method=func))

        (clazz, method) = self.path2method(self.commands[func]['path'])

        method = PluginRegistry.modules[clazz].__getattribute__(method)
        return getattr(method, name, False)
예제 #57
0
파일: proxy.py 프로젝트: peuter/gosa
    def __getattr__(self, name):

        # Valid method? and enough permissions?
        if name in self.__method_map:

            # Check permissions
            # To execute a method the 'x' permission is required.
            attr_type = self.__method_type_map[name]
            topic = "%s.objects.%s.methods.%s" % (self.__env.domain, attr_type, name)
            if self.__current_user is not None and not self.__acl_resolver.check(self.__current_user, topic, "x", base=self.dn):
                self.__log.debug("user '%s' has insufficient permissions to execute %s on %s, required is %s:%s" % (
                    self.__current_user, name, self.dn, topic, "x"))
                raise ACLException(C.make_error('PERMISSION_ACCESS', topic, target=self.dn))
            return self.__method_map[name]

        if name == 'modifyTimestamp':
            timestamp = self.__base.modifyTimestamp
            for obj in self.__extensions.values():
                if obj and obj.modifyTimestamp and timestamp < obj.modifyTimestamp:
                    timestamp = obj.modifyTimestamp

            return timestamp

        # Valid attribute?
        if not name in self.__attribute_map:
            raise AttributeError(C.make_error('ATTRIBUTE_NOT_FOUND', name))

        # Do we have read permissions for the requested attribute
        attr_type = self.__attribute_type_map[name]
        topic = "%s.objects.%s.attributes.%s" % (self.__env.domain, attr_type, name)
        if self.__current_user is not None and not self.__acl_resolver.check(self.__current_user, topic, "r", base=self.dn):
            self.__log.debug("user '%s' has insufficient permissions to read %s on %s, required is %s:%s" % (
                self.__current_user, name, self.dn, topic, "r"))
            raise ACLException(C.make_error('PERMISSION_ACCESS', topic, target=self.dn))

        # Load from primary object
        base_object = self.__attribute_map[name]['base']
        if self.__base_type == base_object:
            return getattr(self.__base, name)

        # Check for extensions
        if base_object in self.__extensions and self.__extensions[base_object]:
            return getattr(self.__extensions[base_object], name)

        # Not set
        return None
예제 #58
0
파일: registry.py 프로젝트: peuter/gosa
    def registerWebhook(self, user, sender_name, content_type):
        topic = "%s.webhook.%s" % (self.env.domain, content_type)
        aclresolver = PluginRegistry.getInstance("ACLResolver")
        if not aclresolver.check(user, topic, "e"):
            self.__log.debug("user '%s' has insufficient permissions to register webhook for content type %s" % (user, content_type))
            raise ACLException(C.make_error('PERMISSION_ACCESS', topic))

        if content_type not in self.__handlers:
            raise WebhookException(C.make_error('NO_REGISTERED_WEBHOOK_HANDLER', content_type))

        if content_type not in self.__hooks:
            self.__hooks[content_type] = {}

        if sender_name not in self.__hooks[content_type]:
            self.__hooks[content_type] = bytes(uuid.uuid4(), 'ascii')

        return self.get_webhook_url(), self.__hooks[content_type][sender_name]