Пример #1
0
    def process(self, obj, key, valDict, maxGidValue=65500, maxUidValue=65500):

        try:
            maxUidValue = int(maxUidValue)
            maxGidValue = int(maxGidValue)
        except ValueError:
            raise PosixException(C.make_error("PARAMETER_NOT_NUMERIC", "GenerateIDs"))

        if "uidNumber" in valDict:
            if not(len(valDict['uidNumber']['value'])):
                if len(valDict["uidNumber"]['backend']) > 1:
                    raise PosixException(C.make_error("BACKEND_TOO_MANY", "GenerateIDs"))

                be = ObjectBackendRegistry.getBackend(valDict["uidNumber"]['backend'][0])
                uid = be.get_next_id("uidNumber")
                if uid > maxUidValue:
                    raise PosixException(C.make_error("POSIX_ID_POOL_EMPTY", "uidNumber", max=maxUidValue))

                valDict["uidNumber"]['value'] = [uid]

        if "gidNumber" in valDict:
            if not(len(valDict['gidNumber']['value'])):
                if len(valDict["gidNumber"]['backend']) > 1:
                    raise PosixException(C.make_error("BACKEND_TOO_MANY", "GenerateIDs"))

                be = ObjectBackendRegistry.getBackend(valDict["gidNumber"]['backend'][0])
                gid = be.get_next_id("gidNumber")
                if gid > maxGidValue:
                    raise PosixException(C.make_error("POSIX_ID_POOL_EMPTY", "gidNumber", max=maxGidValue))

                valDict["gidNumber"]['value'] = [gid]

        return key, valDict
Пример #2
0
    def getObjectProperty(self, user, ref, name):
        """
        Get a property of an existing stack object.

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

        ``Return``: mixed
        """
        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))

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

        if not self.__can_be_handled_locally(ref):
            proxy = self.__get_proxy(ref)
            return proxy.getObjectProperty(ref, name)

        return getattr(objdsc['object']['object'], name)
Пример #3
0
    def setUserPassword(self, user, object_dn, password):
        """
        Set a new 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", "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 usind 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()
Пример #4
0
    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()
Пример #5
0
    def dispatchObjectMethod(self, user, 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("NO_OBJECT_OWNER"))

        #TODO: need to implement dispatchObjectMethodAsUser
        #if not self.__can_be_handled_locally(ref):
        #    proxy = self.__get_proxy(ref)
        #    return proxy.dispatchObjectMethodAsUser(user, ref, method, *args)

        return getattr(objdsc['object']['object'], method)(*args)
Пример #6
0
    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))

        # Move the extension to retractions
        self.__retractions[extension] = self.__extensions[extension]
        self.__extensions[extension] = None
Пример #7
0
    def process(self, obj, key, valDict, attributeName="uidNumber", maxValue=65500):
        if len(valDict[key]['value']) and (valDict[key]['value'][0] == -1):
            maxValue = int(maxValue)

            if len(valDict[key]['backend']) > 1:
                raise PosixException(C.make_error("BACKEND_TOO_MANY", "GetNextID"))

            be = ObjectBackendRegistry.getBackend(valDict[key]['backend'][0])
            gid = be.get_next_id(attributeName)
            if gid > maxValue:
                raise PosixException(C.make_error("POSIX_ID_POOL_EMPTY", attributeName, max=maxValue))
            valDict[key]['value'] = [gid]

        return key, valDict
Пример #8
0
    def extensionExists(self, userid, dn, etype):
        index = PluginRegistry.getInstance("ObjectIndex")
        res = index.search({'_type': 'User', 'dn': dn}, {'_extensions': 1})
        if not res.count():
            raise GOsaException(C.make_error("UNKNOWN_USER", userid))

        return etype in res[0]['_extensions'] if '_extensions' in res[0] else False
Пример #9
0
    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
Пример #10
0
    def commandReceived(self, ssn, message):
        """
        Process incoming commands, coming in with session and message
        information.

        ================= ==========================
        Parameter         Description
        ================= ==========================
        ssn               AMQP session object
        message           Received AMQP message
        ================= ==========================

        Incoming messages are coming from an
        :class:`clacks.common.components.amqp_proxy.AMQPServiceProxy` which
        is providing a *reply to* queue as a return channel. The command
        result is written to that queue.
        """

        # Check for id
        if not message.user_id:
            raise ValueError(C.make_error("AMQP_MESSAGE_WITHOUT_UID"))

        id_ = ''
        name = args = err = res = None

        try:
            req = loads(message.content)
        except ServiceRequestNotTranslatable, e:
            err = str(e)
            req = {'id': id_}
Пример #11
0
    def update(self, obj):
        # Gather information
        current = obj.asJSON(True)
        saved = self.db.index.find_one({'_uuid': obj.uuid})
        if not saved:
            raise IndexException(C.make_error('OBJECT_NOT_FOUND', "base", id=obj.uuid))

        # Remove old entry and insert new
        self.remove_by_uuid(obj.uuid)
        self.db.index.save(obj.asJSON(True))

        # Has the entry been moved?
        if current['dn'] != saved['dn']:

            # Adjust all ParentDN entries of child objects
            res = self.db.index.find(
                {'_parent_dn': re.compile('^(.*,)?%s$' % re.escape(saved['dn']))},
                {'_uuid': 1, 'dn': 1, '_parent_dn': 1})

            for entry in res:
                o_uuid = entry['_uuid']
                o_dn = entry['dn']
                o_parent = entry['_parent_dn']

                n_dn = o_dn[:-len(saved['dn'])] + current['dn']
                n_parent = o_parent[:-len(saved['dn'])] + current['dn']

                self.db.index.update({'_uuid': o_uuid}, {
                        '$set': {'dn': n_dn, '_parent_dn': n_parent}})
Пример #12
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)
Пример #13
0
    def process(self, obj, key, valDict):
        if len(valDict[key]['value']) and type(valDict[key]['value'][0]) in [str, unicode]:
            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
Пример #14
0
    def process(self, req, environ):
        """
        Process an incoming JSONRPC request and dispatch it thru the
        *CommandRegistry*.

        ================= ==========================
        Parameter         Description
        ================= ==========================
        req               Incoming Request
        environ           WSGI environment
        ================= ==========================

        ``Return``: varries
        """
        # Handle OPTIONS
        if req.method == 'OPTIONS':
            return Response(
                    server=self.ident,
                    allow='POST'
                    )

        if not req.method == 'POST':
            raise exc.HTTPMethodNotAllowed(
                "Only POST allowed",
                allow='POST').exception
        try:
            json = loads(req.body)
        except ValueError, e:
            raise ValueError(C.make_error("INVALID_JSON", data=str(e)))
Пример #15
0
def get_operator(name):
    for entry in pkg_resources.iter_entry_points("object.operator"):
        module = entry.load()
        if module.__name__ == name:
            return module

    raise KeyError(C.make_error("OPERATOR_NO_INSTANCE", operator=name))
Пример #16
0
def get_filter(name):
    for entry in pkg_resources.iter_entry_points("object.filter"):
        module = entry.load()
        if module.__name__ == name:
            return module

    raise KeyError(C.make_error("FILTER_NO_INSTANCE", name))
Пример #17
0
    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": {"$size": 1}}, {"userPassword": 1})
        if res.count():
            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)
Пример #18
0
    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": re.compile("^(.*,)?" + re.escape(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 index.search({"dn": re.compile("^(.*,)" + re.escape(self.__base.dn) + "$")}, {'dn': 1}).count():
                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))
Пример #19
0
    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
Пример #20
0
    def insert(self, obj):
        self.log.debug("creating object index for %s" % obj.uuid)

        # If this is the root node, add the root document
        if self.db.index.find_one({'_uuid': obj.uuid}, {'_uuid': 1}):
            raise IndexException(C.make_error('OBJECT_EXISTS', "base", uuid=obj.uuid))

        self.db.index.save(obj.asJSON(True))
Пример #21
0
    def systemSetStatus(self, device_uuid, status):
        """
        TODO
        """

        #TODO: use object backends instead of LDAP

        # Check params
        valid = [STATUS_SYSTEM_ON, STATUS_LOCKED, STATUS_UPDATABLE,
            STATUS_UPDATING, STATUS_INVENTORY, STATUS_CONFIGURING,
            STATUS_INSTALLING, STATUS_VM_INITIALIZING, STATUS_WARNING,
            STATUS_ERROR, STATUS_OCCUPIED, STATUS_BOOTING,
            STATUS_NEEDS_INSTALL, STATUS_NEEDS_CONFIG,
            STATUS_NEEDS_INITIAL_CONFIG, STATUS_NEEDS_REMOVE_CONFIG]

        # Write to LDAP
        lh = LDAPHandler.get_instance()
        fltr = "deviceUUID=%s" % device_uuid

        with lh.get_handle() as conn:
            res = conn.search_s(lh.get_base(), ldap.SCOPE_SUBTREE,
                "(&(objectClass=device)(%s))" % fltr, ['deviceStatus'])

            if len(res) != 1:
                raise ValueError(C.make_error("CLIENT_NOT_FOUND", device_uuid))

            devstat = res[0][1]['deviceStatus'][0] if 'deviceStatus' in res[0][1] else ""
            is_new = not bool(devstat)
            devstat = list(devstat.strip("[]"))

            r = re.compile(r"([+-].)")
            for stat in r.findall(status):
                if not stat[1] in valid:
                    raise ValueError(C.make_error("CLIENT_STATUS_INVALID", device_uuid, status=stat[1]))
                if stat.startswith("+"):
                    if not stat[1] in devstat:
                        devstat.append(stat[1])
                else:
                    if stat[1] in devstat:
                        devstat.remove(stat[1])

            devstat = "[" + "".join(devstat).encode('utf8') + "]"
            if is_new:
                conn.modify(res[0][0], [(ldap.MOD_ADD, "deviceStatus", [devstat])])
            else:
                conn.modify(res[0][0], [(ldap.MOD_REPLACE, "deviceStatus", [devstat])])
Пример #22
0
    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 fullfilled
        oTypes = self.__factory.getObjectTypes()
        for r_ext in oTypes[extension]['requires']:
            if not r_ext in self.__extensions or self.__extensions[r_ext] is None:
                raise ProxyException(C.make_error('OBJECT_EXTENSION_DEPENDS', extension=extension, missing=r_ext))

        # 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:
            self.__extensions[extension] = self.__factory.getObject(extension, self.__base.uuid, mode="extend")
            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)
Пример #23
0
    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]
Пример #24
0
    def searchForObjectDetails(self, user, extension, attribute, fltr, attributes, skip_values):
        """
        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.
        of = ObjectFactory.getInstance()
        be_data = of.getObjectBackendParameters(extension, attribute)
        if not be_data:
            raise GOsaException(C.make_error("BACKEND_PARAMETER_MISSING", extension=extension, attribute=attribute))

        # Collection basic information
        otype, oattr, foreignMatchAttr, matchAttr = be_data[attribute] #@UnusedVariable

        # Create a list of attributes that will be requested
        if oattr not in attributes:
            attributes.append(oattr)
        attrs = dict([(x, 1) for x in attributes])
        if not "dn" in attrs:
            attrs.update({'dn': 1})

        # Start the query and brind the result in a usable form
        index = PluginRegistry.getInstance("ObjectIndex")
        res = index.search({
            '$or': [{'_type': otype}, {'_extensions': otype}],
            oattr: re.compile("^.*" + re.escape(fltr) + ".*$")
            }, attrs)
        result = []

        # Do we have read permissions for the requested attribute
        env = Environment.getInstance()
        topic = "%s.objects.%s" % (env.domain, otype)
        aclresolver = PluginRegistry.getInstance("ACLResolver")

        for entry in res:

            if not aclresolver.check(user, topic, "s", base=entry['dn']):
                continue

            item = {}
            for attr in attributes:
                if attr in entry and len(entry[attr]):
                    item[attr] = entry[attr] if attr == "dn" else entry[attr][0]
                else:
                    item[attr] = ""
            item['__identifier__'] = item[oattr]

            # Skip values that are in the skip list
            if skip_values and item['__identifier__'] in skip_values:
                continue

            result.append(item)

        return result
Пример #25
0
    def process(self, obj, key, valDict):
        if len(valDict[key]['value']) and type(valDict[key]['value'][0]) in [str, unicode]:
            lm, nt = smbpasswd.hash(valDict[key]['value'][0])
            valDict['sambaNTPassword']['value'] = [nt]
            valDict['sambaLMPassword']['value'] = [lm]
        else:
            raise ValueError(C.make_error("TYPE_UNKNOWN", self.__class__.__name__, type=type(valDict[key]['value'])))

        return key, valDict
Пример #26
0
    def find(self, user, query, conditions=None):
        """
        Perform a raw mongodb find call.

        ========== ==================
        Parameter  Description
        ========== ==================
        query      Query hash
        conditions Conditions hash
        ========== ==================

        For more information on the query format, consult the mongodb documentation.

        ``Return``: List of dicts
        """
        res = []

        # Always return dn and _type - we need it for ACL control
        if isinstance(conditions, dict):
            conditions['dn'] = 1
            conditions['_type'] = 1

        else:
            conditions = None

        if not isinstance(query, dict):
            raise FilterException(C.make_error('INVALID_QUERY'))

        # Create result-set
        for item in self.search(query, conditions):

            # Filter out what the current use is not allowed to see
            item = self.__filter_entry(user, item)
            if item and item['dn'] is not None:
                del item['_id']

                # Convert binary (bson) to Binary
                for key in item.keys():
                    if isinstance(item[key], list):

                        n = []
                        for v in item[key]:
                            if isinstance(v, Binary):
                                v = CBinary(v)

                            n.append(v)

                        item[key] = n

                    elif isinstance(item[key], Binary):
                        item[key] = CBinary(item[key])

                res.append(item)

        return res
Пример #27
0
    def getChecksumByHardwareUUID(self, huuid):
        """
        Returns the checksum of a specific entry.
        """
        results = self.db.find({'HardwareUUID': huuid}, {'Checksum': 1})

        # Walk through results and return the found checksum
        if results.count() == 1:
            return results[0]['Checksum']
        else:
            raise InventoryException(C.make_error("INVENTORY_CHECKSUM_MISMATCH", huuid))
Пример #28
0
    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})
        if not res.count():
            raise GOsaException(C.make_error("UNKNOWN_USER", userid))

        return({'sn': res[0]['sn'][0],
                'givenName': res[0]['givenName'][0],
                'dn': res[0]['dn'],
                'uuid': res[0]['_uuid'],
                'cn': res[0]['cn'][0]})
Пример #29
0
    def getObjectDetails(self, extension, attribute, names, attributes):
        """
        This method is used to complete object information shown in the gui.
        e.g. The groupMembership table just knows the groups cn attribute.
             To be able to show the description too, it uses this method.

        #TODO: @fabian - this function is about 95% the same than the one
        #                above.
        """

        # Extract the the required information about the object
        # relation out of the BackendParameters for the given extension.
        of = ObjectFactory.getInstance()
        be_data = of.getObjectBackendParameters(extension, attribute)

        if not be_data:
            raise GOsaException(C.make_error("BACKEND_PARAMETER_MISSING", extension=extension, attribute=attribute))

        # Collection basic information
        otype, oattr, foreignMatchAttr, matchAttr = be_data[attribute] #@UnusedVariable

        # Create a list of attributes that will be requested
        if oattr not in attributes:
            attributes.append(oattr)
        attrs = dict([(x, 1) for x in attributes])

        # Start the query and brind the result in a usable form
        index = PluginRegistry.getInstance("ObjectIndex")

        res = index.search({
            '$or': [{'_type': otype}, {'_extensions': otype}],
            oattr: {'$in': names}
            }, attrs)

        result = {}
        mapping = {}

        for entry in names:
            _id = len(result)
            mapping[entry] = _id
            result[_id] = None

        for entry in res:
            item = {}
            for attr in attributes:
                if attr in entry and len(entry[attr]):
                    item[attr] = entry[attr] if attr == 'dn' else entry[attr][0]
                else:
                    item[attr] = ""

            _id = mapping[item[oattr]]
            result[_id] = item

        return {"result": result, "map": mapping}
Пример #30
0
    def process(self, obj, key, valDict, *sizes):

        # Sanity check
        if len(sizes) == 0:
            raise ElementFilterException(C.make_error("USER_IMAGE_SIZE_MISSING"))

        # Do we have an attribute to process?
        if key in valDict and valDict[key]['value']:

            # Check if a cache entry exists...
            entry = self.db.cache.find_one({'uuid': obj.uuid, 'attribute': key}, {'modified': 1})
            if entry:

                # Nothing to do if it's unmodified
                if obj.modifyTimestamp == entry['modified']:
                    return key, valDict

            # Create new cache entry
            else:
                c_entry = {
                    'uuid': obj.uuid,
                    'attribute': key
                    }
                self.db.cache.save(c_entry)

            # Convert all images to all requested sizes
            data = {
                    'uuid': obj.uuid,
                    'attribute': key,
                    'modified': obj.modifyTimestamp
                    }
            for idx in range(0, len(valDict[key]['value'])):
                image = StringIO(valDict[key]['value'][idx].get())
                try:
                    im = Image.open(image) #@UndefinedVariable
                except IOError:
                    continue

                for size in sizes:
                    s = int(size)
                    tmp = ImageOps.fit(im, (s, s), Image.ANTIALIAS) #@UndefinedVariable
                    tgt = StringIO()
                    tmp.save(tgt, "JPEG")

                    # Collect all images in [size][] lists
                    if not size in data:
                        data[size] = []

                    data[size].append(Binary(tgt.getvalue()))

            # Update cache
            self.db.cache.update({'uuid': obj.uuid, 'attribute': key}, data)

        return key, valDict