Author: mkhl Date: 2006-06-20 01:08:18 +0000 (Tue, 20 Jun 2006) New Revision: 16384
WebSVN: http://websvn.samba.org/cgi-bin/viewcvs.cgi?view=rev&root=samba&rev=16384 Log: Semi-informed doodling about a mapping module, affected by late insights into local_password and password_hash concerning the scope of mappings, the requirement for context and more asynchronism. Martin Added: branches/SOC/mkhl/map.txt Changeset: Added: branches/SOC/mkhl/map.txt =================================================================== --- branches/SOC/mkhl/map.txt 2006-06-20 01:03:04 UTC (rev 16383) +++ branches/SOC/mkhl/map.txt 2006-06-20 01:08:18 UTC (rev 16384) @@ -0,0 +1,178 @@ +* An LDB Mapping Module -*- outline -*- + +** Scenario +Usage of an instance of the map module requires tha full set of data +to be split in two "partitions", a local (fallback) and a remote +(mapped) one. The remote partition will be used to store additional +data but may differ from the local partition in the schema it uses. +The goal is to store as much data as possible on the remote partition. + +A user is required to define mappings between local and remote data +schemas to account for these differences, but also to enable usage of +the remote partition for as large a dataset as possible. + +Data not explicitly accounted for in the defined mappings is ignored +by the remote partition and stored on the local partition instead. + + +** Assumptions + +*** Mapped vs. Not Mapped +Each record exists in either of two states: + +**** Not mapped: +The record and all of its data are stored on the local partition; the +additional attribute "isMapped" is not present in the record. + +**** Mapped: +The record is split into a local and a remote part stored on the local +and remote partition respectively; an additional internal attribute +"isMapped" is added to the local part of the record. + +The local part of a mapped record is allowed to consist only of the +"isMapped" attribute, denoting the case when all "real" data is mapped +to the remote partition. + +*** Internal attribute "isMapped" +The local part of each mapped record includes an internal attribute +"isMapped", the value of which might denote the DN of the remote part. +It is not present in the local part of a record that is not +mapped. (Or maybe it is but with a distinguished/empty value). + +The attribute is not visible from the outside(?) and cannot be +modified directly. + +*** Local != Fallback +Each attribute must either be mapped or ignored; the local part should +be reserved for ignored data and not serve as fallback storage for +failed mappings. + +Failure to map an attribute indicates a problem with the specified +mappings and should be reported. + +*** No smart mapping +The map module has no knowledge of constraints present in the backend +of the remote partition, such as objectClass restrictions. + +Constraint violation results from the remote backend indicate a +problem with the specified mappings and should be reported. + +*** Uniqueness of local names +The specified mappings should be uniquely indexable by the local name +of a handled attribute. + +Generation of multiple remote attributes from a single local attribute +will be possible but should be defined in a single mapping to ease +conversions from the remote to the local format (as for search +responses). + +(This might be problematic for attributes that form a records RDN, as +only one attribute can be used for that at a time...) + +*** Stable naming contexts +Mappings must not tamper with the naming context of a record. The +naming context is (part of) what specifies the destination partition +for a datase; its modification is defined globally in a special record +of the map instance. + + +** Mappings + +*** Abstractly +A mapping represents, viewed abstractly, a function of type +Request x Context --> Request + +The structure of LDB modules performs dispatching based on request +type itself, so we can substitute the request contents for Request in +that type. Disregarding delete and rename requests, which contain +only one or two target DNs, the contents of a request are of type LDB +message, so we assume a type +Message x Context --> Request + +The ldb_map module disregards context completely, modelling only +functions +Message --> Message + +and a few restricted subforms of types +Message Element --> Message Element + +or even just +String --> String + +This is convenient for most cases and increases expressiveness of the +"mapping definition language" but limits the overall power of +mappings, as e.g. the password_hash module cannot currently be +expressed with the ldb_map module due to lacking context (the domain +data search result and the array `attrs' of the +`password_hash_mod_search_self' function. + +The only way to access that data is by making (synchronous) LDB calls +from within the attribute generation function. + +*** As Balls of Mud +The canonical way to fetch context is to prefix the "real" request +with a search request that results in the required data and is then +stuffed in the requests async context. + +This pattern could of course be factored into the map module; mappings +requiring this data would then need ways to request it, either as an +array of strings (for the simpler case where additional info about the +record itself is required) or as an array of (search) requests (for +the general case, allowing the whole database to be queried). + + +** Requests + +*** Delete +look for "isMapped" on local self +if set: + delete remote DN +delete local DN + +*** Rename +look for "isMapped" on local self +if set: + rename remote record +rename local record + +*** Add +for each attribute: + if it is local: + request it locally + if it doesn't require context: + map it + request it remotely + otherwise: + register requested query +if query registered: + get context from query result +if remote record requested: + add remote record with context + add local record with "isMapped" +otherwise: + add local record w/o "isMapped" + +*** Modify +if no requested changes are remote: + just run local request +look for "isMapped" on local self +if not set: + turn request into "add" + add remote record (with context) + modify local record with "isMapped" +otherwise: + modify remote record (with context) + modify local record + +*** Search +if no requested attribute is remote or "*": + just run local request +otherwise: + run query with local attributes and "isMapped" +if "isMapped" is not set and remote attribues were requested: + abort +otherwise: + query remote DN with remote attributes +unmap remote result +merge local and remote result +remove "isMapped" from result