updated documentation
[ocamldap:paurkedals-ocamldap.git] / ldap_ooclient.mli
1 (* an object oriented interface to ldap
2
3    Copyright (C) 2004 Eric Stokes, and The California State University
4    at Northridge
5
6    This library is free software; you can redistribute it and/or               
7    modify it under the terms of the GNU Lesser General Public                  
8    License as published by the Free Software Foundation; either                
9    version 2.1 of the License, or (at your option) any later version.          
10    
11    This library is distributed in the hope that it will be useful,             
12    but WITHOUT ANY WARRANTY; without even the implied warranty of              
13    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU           
14    Lesser General Public License for more details.                             
15    
16    You should have received a copy of the GNU Lesser General Public
17    License along with this library; if not, write to the Free Software
18    Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
19    USA
20 *)
21
22 (** an object oriented ldap client interface *)
23
24 open Ldap_types
25
26 (** {2 Basic Data Types} *)
27
28 (** the type of an operation, eg. [("cn", ["foo";"bar"])] *)
29 type op = string * string list
30 type op_lst = op list
31
32 (** The policy the client should take when it encounteres a
33     referral. This is currently not used *)
34 type referral_policy = [ `FOLLOW | `RETURN ]
35
36 (** The change type of an ldapentry. This controls some aspects of
37     it's behavior *)
38 type changetype = [ `ADD | `DELETE | `MODDN | `MODIFY | `MODRDN ]
39
40 (** {2 Local Representation of LDAP Objects} *)
41
42 (** The base type of an ldap entry represented in memory. *)
43 class type ldapentry_t =
44 object
45   method add : op_lst -> unit
46   method attributes : string list
47   method changes : (Ldap_types.modify_optype * string * string list) list
48   method changetype : changetype
49   method delete : op_lst -> unit
50   method dn : string
51   method diff : ldapentry_t -> (modify_optype * string * string list) list
52   method exists : string -> bool
53   method flush_changes : unit
54   method get_value : string -> string list
55   method modify :
56     (Ldap_types.modify_optype * string * string list) list -> unit
57   method print : unit
58   method replace : op_lst -> unit
59   method set_changetype : changetype -> unit
60   method set_dn : string -> unit
61 end
62
63 (** this object represents a remote object within local memory. It
64     records all local changes made to it (if it's changetype is set to
65     `MODIFY), and can commit them to the server at a later time via
66     {!Ldap_ooclient.ldapcon.update_entry}. *)
67 class ldapentry :
68 object
69   (** add values to an attribute (or create a new attribute). Does
70       not change the server until you update *)
71     method add : op_lst -> unit
72
73     (** return a list of the type (name) of all the attributes present
74     on the object *)
75     method attributes : string list
76
77     (** return a list of changes made to the object in a the format of
78         a modify operation. For example, you can apply the changes to another
79         ldapentry object using the {!Ldap_ooclient.ldapentry.modify}
80         method *)
81     method changes : (Ldap_types.modify_optype * string * string list) list
82
83     (** return the changetype of the object *)
84     method changetype : changetype
85
86     (** delete attributes from the object, does not change the
87     directory until you update *)
88     method delete : op_lst -> unit
89
90     (** return the dn of the object *)
91     method dn : string
92
93     (** given an ldapentry, return the differences between the current
94         entry and the specified entry in the form of a modify
95         operation which would make the specified entry the same as the
96         current entry. *)
97     method diff : ldapentry_t -> (modify_optype * string * string list) list
98
99     (** query whether the attribute type (name) exists in the object *)
100     method exists : string -> bool
101
102     (** clear all accumulated changes *)
103     method flush_changes : unit
104
105     (** get the value of an attribute @raise Not_found If the
106         attribute does not exist. *)
107     method get_value : string -> string list
108
109     (** Apply modifications to object in memory, does not change the
110         database until you update using
111         {!Ldap_ooclient.ldapcon.update_entry} *)
112     method modify :
113       (Ldap_types.modify_optype * string * string list) list -> unit
114
115     (** @deprecated print an ldif like representation of the object to stdout, see
116         Ldif_oo for standards compliant ldif. Usefull for toplevel
117         sessions. *)
118     method print : unit
119
120     (** replace values in the object, does not change the database
121     until you call update *)
122     method replace : op_lst -> unit
123
124     (** set the changetype of the object *)
125     method set_changetype : changetype -> unit
126
127     (** set the dn of the object *)
128     method set_dn : string -> unit
129   end
130
131 (** {1 Miscallaneous} *)
132
133 (** toplevel formatter for ldapentry, prints the whole entry with a
134     nice structure. Each attribute is in the correct syntax to be
135     copied and pasted into a modify operation. *)
136 val format_entry :
137   < attributes : string list; dn : string;
138  get_value : string -> string list; .. > ->
139    unit
140
141 (** format lists of entries, in this case only print the dn *)
142 val format_entries :
143   < attributes : string list; dn : string;
144  get_value : string -> string list; .. > list ->
145    unit
146
147 (** The type of an ldap change record, used by extended LDIF *)
148 type changerec = 
149     [`Modification of string * ((Ldap_types.modify_optype * string * string list) list)
150     | `Addition of ldapentry
151     | `Delete of string
152     | `Modrdn of string * int * string]
153
154 (** {0 Communication With {!Ldap_funclient}} *)
155
156 (** given a search_result_entry as returned by ldap_funclient, produce an
157     ldapentry containing either the entry, or the referral object *)
158 val to_entry : 
159   [< `Entry of Ldap_types.search_result_entry | `Referral of string list ] 
160   -> ldapentry
161
162 (** given an ldapentry as returned by ldapcon, or constructed manually,
163     produce a search_result_entry suitable for ldap_funclient, or
164     ldap_funserver. *)
165 val of_entry : ldapentry -> search_result_entry
166
167 (** {2 Interacting with LDAP Servers} *)
168
169 (** This class abstracts a connection to an LDAP server (or servers),
170     an instance will be connected to the server you specify and can be
171     used to perform operations on that server. 
172
173     {0 Example} 
174
175     [new ldapcon ~connect_timeout:5 ~version:3
176     ["ldap://first.ldap.server";"ldap://second.ldap.server"]]. 
177
178     In addition to specifying multiple urls, if DNS names are given,
179     and those names are bound to multiple addresses, then all possible
180     addresses will be tried.
181
182     {0 Example}
183
184     [new ldapcon ["ldaps://rrldap.csun.edu"]] 
185
186     is equivelant to 
187     
188     [new ldapcon ["ldap://130.166.1.30";"ldap://130.166.1.31";"ldap://130.166.1.32"]]
189
190     This means that if any host in the rr fails, the ldapcon will
191     transparently move on to the next host, and you will never know
192     the difference. 
193
194     @raise LDAP_Failure All methods raise {!Ldap_types.LDAP_Failure} on error
195
196     @param connect_timeout Default [1], an integer which specifies how
197     long to wait for any given server in the list to respond before
198     trying the next one. After all the servers have been tried for
199     [connect_timeout] seconds [LDAP_Failure (`SERVER_DOWN, ...)]  will
200     be raised.
201
202     @param referral_policy In a future version of ocamldap this will
203     be used to specify what you would like to do in the event of a
204     referral. Currently it does nothing and is ignored see
205     {!Ldap_ooclient.referral_policy}.
206
207     @param version The protocol version to use, the default is [3],
208     the other recognized value is [2].
209 *)
210 class ldapcon :
211   ?connect_timeout:int ->
212   ?referral_policy:[> `RETURN ] ->
213   ?version:int ->
214   string list ->
215 object
216   (** {2 Authentication} *)
217
218   (** bind to the database using dn. 
219
220       {0 Simple Bind Example}
221
222       [ldap#bind ~cred:"password" "cn=foo,ou=people,ou=auth,o=bar"]
223
224       To bind anonymously, omit ~cred, and leave dn blank eg.
225
226       {0 Example}
227
228       [ldap#bind ""]
229
230       @param cred The credentials to provide for binding. Default [""]. 
231
232       @param meth The method to use when binding See
233       {!Ldap_funclient.authmethod} the default is [`SIMPLE]. If
234       [`SASL] is used then [dn] and [~cred] Are interperted according
235       to the chosen SASL mechanism. SASL binds have not been tested
236       extensively. *)
237   method bind :
238     ?cred:string -> ?meth:Ldap_funclient.authmethod -> string -> unit
239
240   (** Deauthenticate and close the connection to the server *)
241   method unbind : unit
242
243   (** {2 Searching} *)
244
245   (** Search the directory syncronously for an entry which matches the
246       search criteria.
247
248       {0 Example}
249
250       [ldap#search ~base:"dc=foo,dc=bar" ~attrs:["cn"] "uid=*"]
251
252       @param scope Default [`SUBTREE], defines the scope of the
253       search. see {!Ldap_types.search_scope} 
254
255       @param attrs Default [[]] (means all attributes) 
256
257       @param attrsonly Default [false] If true, asks the server to return
258       only the attribute names, not their values. 
259
260       @param base Default [""], The search base, which is the dn of the
261       object from which you want to start your search. Only that
262       object, and it's children will be included in the
263       search. Further controlled by [~scope]. *)
264   method search :
265     ?scope:Ldap_types.search_scope ->
266     ?attrs:string list ->
267     ?attrsonly:bool -> ?base:string -> string -> ldapentry list
268
269   (** Search the directory asyncronously, otherwise the same as
270       search. *)
271   method search_a :
272     ?scope:Ldap_types.search_scope ->
273     ?attrs:string list ->
274     ?attrsonly:bool -> ?base:string -> string -> (?abandon:bool -> unit -> ldapentry)
275
276   (** Fetch the raw (unparsed) schema from the directory using the
277       standard mechanism (requires protocol version 3) *)
278   method rawschema : ldapentry
279
280   (** Fetch and parse the schema from the directory via the standard
281       mechanism (requires version 3). Return a structured
282       representation of the schema indexed by canonical name, and oid. *)
283   method schema : Ldap_schemaparser.schema
284
285   (** {2 Making Modifications} *)
286
287   (** add an entry to the database *)
288   method add : ldapentry -> unit
289
290   (** Delete the object named by dn from the database *)
291   method delete : string -> unit
292
293   (** Modify the entry named by dn, applying mods 
294
295       {0 Example}
296
297       [ldap#modify "uid=foo,ou=people,dc=bar,dc=baz" [(`DELETE, "cn", ["foo";"bar"])]]
298   *)
299   method modify :
300     string ->
301     (Ldap_types.modify_optype * string * string list) list -> unit
302
303   (** Syncronize changes made locally to an ldapentry with the
304       directory. *)
305   method update_entry : ldapentry -> unit
306
307   (** Modify the rdn of the object named by dn, if the protocol
308       version is 3 you may additionally change the superior, the rdn
309       will be changed to the attribute represented (as a string) by
310       newrdn, 
311
312       {0 Example With New Superior}
313
314       [ldap#modrdn ~newsup:(Some "o=csun") "cn=bob,ou=people,o=org" "uid=bperson"]
315
316       After this example "cn=bob,ou=people,o=org" will end up as "uid=bperson,o=csun".
317
318       @param deleteoldrdn Default [true], delete
319       the old rdn value as part of the modrdn. 
320
321       @param newsup Default [None], only valid when the protocol
322       version is 3, change the object's location in the tree, making
323       its superior equal to the specified object. *)
324   method modrdn : string -> ?deleteoldrdn:bool -> ?newsup:string option -> string -> unit
325 end
326
327 (** {1 Iterators Over Streams of ldapentry Objects} *)
328
329 (** given a source of ldapentry objects (unit -> ldapentry), such as
330     the return value of ldapcon#search_a, apply f (first arg) to each entry
331     See List.iter *)
332 val iter : (ldapentry -> unit) -> (?abandon:bool -> unit -> ldapentry) -> unit
333
334 (** given a source of ldapentry objects (unit -> ldapentry), such as
335   the return value of ldapcon#search_a apply f (first arg) to each
336   entry in reverse, and return a list containing the result of each
337   application. See List.map *)
338 val rev_map : (ldapentry -> 'a) -> (?abandon:bool -> unit -> ldapentry) -> 'a list
339
340 (** same as rev_map, but does it in order *)
341 val map : (ldapentry -> 'a) -> (?abandon:bool -> unit -> ldapentry) -> 'a list
342
343 (** given a source of ldapentry objects (unit -> ldapentry), such as
344   the return value of ldapcon#search_a compute (f eN ... (f e2 (f e1
345   intial))) see List.fold_right. *)
346 val fold : (ldapentry -> 'a -> 'a) -> 'a -> (?abandon:bool -> unit -> ldapentry) -> 'a
347
348 (** {2 Schema Aware ldapentry Derivatives} *)
349
350 (** {1 General Schema Aware Entry} {!Ldap_ooclient.scldapentry}, A
351     schema aware derivative of {!Ldap_ooclient.ldapentry}. It contains
352     an rfc2252 schema checker, and given the database schema, it can
353     be used to garentee that operations performed in memory are valid
354     against a standards compliant database. It has numerious uses,
355     translation between two databases with different schemas an
356     example of where it finds natural usage. For an example
357     application @see <http://tdir.sourceforge.net> tdir *)
358
359 (** an ordered oid type, for placing oids in sets *)
360 module OrdOid :
361 sig
362   type t = Ldap_schemaparser.Oid.t
363   val compare : t -> t -> int
364 end
365
366 (** A set of Oids @deprecated the name is historical, and may be changed *)
367 module Setstr :
368 sig
369   type elt = OrdOid.t
370   type t = Set.Make(OrdOid).t
371   val empty : t
372   val is_empty : t -> bool
373   val mem : elt -> t -> bool
374   val add : elt -> t -> t
375   val singleton : elt -> t
376   val remove : elt -> t -> t
377   val union : t -> t -> t
378   val inter : t -> t -> t
379   val diff : t -> t -> t
380   val compare : t -> t -> int
381   val equal : t -> t -> bool
382   val subset : t -> t -> bool
383   val iter : (elt -> unit) -> t -> unit
384   val fold : (elt -> 'a -> 'a) -> t -> 'a -> 'a
385   val for_all : (elt -> bool) -> t -> bool
386   val exists : (elt -> bool) -> t -> bool
387   val filter : (elt -> bool) -> t -> t
388   val partition : (elt -> bool) -> t -> t * t
389   val cardinal : t -> int
390   val elements : t -> elt list
391   val min_elt : t -> elt
392   val max_elt : t -> elt
393   val choose : t -> elt
394   val split : elt -> t -> t * bool * t
395 end
396
397 (** The type of schema checking to perform in
398     {!Ldap_ooclient.scldapentry}. Normally this is picked
399     automatically, however it can be overridden in some cases. *)
400 type scflavor = 
401     Optimistic 
402       (** Add missing attributes to make the object consistant, or add
403           objectclasses in order to make illegal attribues legal *)
404   | Pessimistic
405       (** Delete objectclasses which must attributes which are
406           missing, and delete illegal attributes. *)
407
408 (** given a name of an attribute name (canonical or otherwise), return
409     its oid @raise Invalid_attribute If the attribute is not found in the schema. *)
410 val attrToOid :
411   Ldap_schemaparser.schema ->
412   Ldap_schemaparser.Lcstring.t -> Ldap_schemaparser.Oid.t
413
414 (** given the oid of an attribute, return its canonical name @raise
415     Invalid_attribute If the attribute is not found in the schema. *)
416 val oidToAttr : Ldap_schemaparser.schema -> Ldap_schemaparser.Oid.t -> string
417
418 (** given a name of an objectclass (canonical or otherwise), return
419     its oid. @raise Invalid_objectclass If the objectclass is not
420     found in the schema. *)
421 val ocToOid :
422   Ldap_schemaparser.schema ->
423   Ldap_schemaparser.Lcstring.t -> Ldap_schemaparser.Oid.t
424
425 (** given the oid of an objectclass, return its canonical name @raise
426     Invalid_objectclass If the objectclass is not found in the
427     schema. *)
428 val oidToOc : Ldap_schemaparser.schema -> Ldap_schemaparser.Oid.t -> string
429
430 (** get an objectclass structure by one of its names (canonical or
431     otherwise, however getting it by canonical name is currently much
432     faster) @raise Invalid_objectclass If the objectclass is not found
433     in the schema. *)
434 val getOc :
435   Ldap_schemaparser.schema ->
436   Ldap_schemaparser.Lcstring.t -> Ldap_schemaparser.objectclass
437
438 (** get an attr structure by one of its names (canonical or otherwise,
439     however getting it by canonical name is currently much faster)
440     @raise Invalid_attribute If the attribute is not found in the
441     schema. *)
442 val getAttr :
443   Ldap_schemaparser.schema ->
444   Ldap_schemaparser.Lcstring.t -> Ldap_schemaparser.attribute
445
446 (** equate attributes by oid. This allows non canonical names to be
447     handled correctly, for example "uid" and "userID" are actually the
448     same attribute. @raise Invalid_attribute If either attribute is
449     not found in the schema. *)
450 val equateAttrs :
451   Ldap_schemaparser.schema ->
452   Ldap_schemaparser.Lcstring.t -> Ldap_schemaparser.Lcstring.t -> bool
453  
454 exception Invalid_objectclass of string
455 exception Invalid_attribute of string
456 exception Single_value of string
457 exception Objectclass_is_required
458
459 class scldapentry :
460   Ldap_schemaparser.schema ->
461 object
462   (** {2 New Methods} *)
463
464   (** Returns true if the attributed specified is allowed by the
465       current set of objectclasses present on the entry. *)
466   method is_allowed : string -> bool
467
468   (** Returns true if the attribute specified is a must, but is not
469       currently present. *)
470   method is_missing : string -> bool
471
472   (** Return a list of all attributes allowed on the entry (by oid) *)
473   method list_allowed : Setstr.elt list
474
475   (** Return a list of all missing attributes (by oid) *)
476   method list_missing : Setstr.elt list
477
478   (** Return a list of all present attributes. In contrast to the
479       [attributes] method, this method ignores missing required
480       attributes and just returns those attributes which are actually
481       present. *)
482   method list_present : Setstr.elt list
483
484   (** Given an {!Ldap_ooclient.ldapentry} copy all of it's data into
485       the current object, and perform a schema check.
486
487       @param scflavor Default [Pessimistic] The schema checking
488       bias, see {!Ldap_ooclient.scflavor} *)
489   method of_entry : ?scflavor:scflavor -> ldapentry -> unit
490
491   (** {2 Inherited Methods} *)
492
493   (** Add values to the entry, just as
494       {!Ldap_ooclient.ldapentry.add}, However, after the add is
495       complete the schema checker is run in [Optimistic] mode. see
496       {!Ldap_ooclient.scflavor} *)
497   method add : op_lst -> unit
498
499   (** Same as {!Ldap_ooclient.ldapentry.add}, except that the schema
500       checker is run in [Pessimistic] mode after the operation is
501       complete. see {!Ldap_ooclient.scflavor} *)
502   method delete : op_lst -> unit
503
504   (** Same as {!Ldap_ooclient.ldapentry.replace} except that once
505       the replace has completed the schema checker is run again in
506       [Optimistic] mode. See {!Ldap_ooclient.scflavor} *)
507   method replace : op_lst -> unit
508
509   (** Same as {!Ldap_ooclient.ldapentry.attributes}, except that the
510       returned list contains attributes which may not yet exist on
511       the entry. For example musts which are not yet present will be
512       listed. *)
513   method attributes : string list
514
515   (** Same as {!Ldap_ooclient.ldapentry.exists} except that it
516       refrences attributes which may not yet exist. For example musts
517       which are not yet present. *)
518   method exists : string -> bool
519
520   (** Same as {!Ldap_ooclient.ldapentry.get_value}, except that
521       attributes which do not yet exists may be referenced. For example
522       a must which has not yet been satisfied will return [["required"]]
523       when [get_value] is called on it. *)
524   method get_value : string -> string list
525
526   (** Same as {!Ldap_ooclient.ldapentry.modify} except that the
527       schema checker is run in [Pessimistic] mode after the
528       modification is applied. see {!Ldap_ooclient.scflavor}. *)
529   method modify :
530     (Ldap_types.modify_optype * string * string list) list -> unit
531
532   (** Same as {!Ldap_ooclient.ldapentry.changes} except that changes
533       made by the schema checker may also be listed. *)
534   method changes : (Ldap_types.modify_optype * string * string list) list
535
536   (** Same as {!Ldap_ooclient.ldapentry.changetype} *)
537   method changetype : changetype
538
539   (** Same as {!Ldap_ooclient.ldapentry.dn} *)
540   method dn : string
541
542   (** Same as {!Ldap_ooclient.ldapentry.flush_changes} *)
543   method flush_changes : unit
544
545   (** Same as {!Ldap_ooclient.ldapentry.diff} *)
546   method diff : ldapentry_t -> (Ldap_types.modify_optype * string * string list) list
547
548   (** @deprecated Same as {!Ldap_ooclient.ldapentry.print}, except
549       that it prints attributes which may not yet be present on the
550       object. For example, if the object has unsatisfied musts, it will
551       print "attrname: required" for that attribute. *)
552   method print : unit 
553
554   (** Same as {!Ldap_ooclient.ldapentry.set_changetype} *)
555   method set_changetype : changetype -> unit
556
557   (** Same as {!Ldap_ooclient.ldapentry.set_dn} *)
558   method set_dn : string -> unit
559 end
560
561 (** {1 Schema Aware Entry for Account Managment} A derivative of
562     {!Ldap_ooclient.scldapentry} which includes abstractions for
563     managing user accounts in the directory. This class is
564     experimantal, and may be drastically changed in the next version. 
565     As with all experimental code, use with caution. A few of its features.
566
567     {ul 
568     {- Loosely dependant attributes: Many attributes are derived
569     from others via a function. ldapaccount allows you to codify
570     that relationship by providing an attribute generator
571     ({!Ldap_ooclient.generator}) for the attribute, which will
572     be used to derive it's value except in the case that it is
573     specified explicitly}
574     {- Attribute and Generator Grouping: via the service abstraction.
575     Allows you to group attributes together with generators and
576     default values in interesting ways. You can then assign the
577     whole grouping a name, and refer to it by that name. See 
578     {!Ldap_ooclient.service}}
579     {- Difference Based: Service operations are difference based,
580     all applications of service operations compute the delta between
581     the current object, and what the service requires. The minumum set
582     of changes necessary to satisfy the service are applied to the object.}
583     {- Idempotentcy: As a result of being difference based, 
584     Service operations are itempotent. For example, 
585     adding a service twice has no effect on the object. It will 
586     not queue changes for modification to the directory, and it 
587     will not change the object in memory. Deleting a service
588     twice has no effect...etc}}
589
590 *)
591
592 (** The structure of a generator *)
593 type generator = {
594   (** The name of the generator, this should also be its key in the hashtbl *)
595   gen_name : string; 
596
597   (** A list of names of attributes which are required by this
598       generator. The names need not be canonical. *)
599   required : string list;
600
601   (** A function which returns a list of values for the attribute,
602       given the entire object. *)
603   genfun : ldapentry_t -> string list;
604 }
605
606 (** The structure of a service *)
607 type service = {
608   (** The name of the service, should also be its key in the hashtbl. *)
609   svc_name : string;
610
611   (** A list of attributes and values which must be present for the
612       service to be satisfied. *)
613   static_attrs : (string * string list) list;
614
615   (** A list of attributes to generate. *)
616   generate_attrs : string list;
617
618   (** A list of services on which this service depends. *)
619   depends : string list;
620 }
621
622 (** The type of error raised by attribute generators *)
623 type generation_error =
624     Missing_required of string list
625   | Generator_error of string
626
627 (** You've asked it to generate an attribute (in a service) which
628     doesn't have a generator *)
629 exception No_generator of string
630
631 (** Generator has failed because of some kind of error *)
632 exception Generation_failed of generation_error
633
634 (** The service you're talking about doesn't exist *)
635 exception No_service of string
636
637 (** A service which the one you tried to add depends on doesn't exists *)
638 exception Service_dep_unsatisfiable of string
639
640 (** Your generator depends on an attribute which isn't in the schema *)
641 exception Generator_dep_unsatisfiable of string * string
642
643 (** You have detached cycles in your generator dependancy lists *)
644 exception Cannot_sort_dependancies of string list
645
646 class ldapaccount :
647   Ldap_schemaparser.schema ->
648     (string, generator) Hashtbl.t ->
649     (string, service) Hashtbl.t ->
650 object
651
652   (** {2 Account Manipulation Methods} *)
653
654   (** add the named service to the object, this also adds all the
655       services depended upon by the named service. *)
656   method add_service : string -> unit
657
658   (** Delete the named service. This will also delete all services
659       which depend on it, either directly or indirectly *)
660   method delete_service : string -> unit
661
662   (** Run service through the delta engine to find out what changes
663       would actually be applied to this object *)
664   method adapt_service : service -> service
665
666   (** Tests whether the named service is satisfied by the current
667       entry. A service is satisfied if no changes would result from
668       adding it to the entry. *)
669   method service_exists : string -> bool
670
671   (** Return a list of all the named services which are satisfied by
672       the current entry. *)
673   method services_present : string list
674
675   (** add the named attribute to the list of attributes to be generated *)
676   method add_generate : string -> unit
677
678   (** Delete the named attribute from the list of attributes to generate *)
679   method delete_generate : string -> unit
680
681   (** Run the generation functions on the list of attributes to be
682       generated, saving the results in the entry. You must run this
683       method in order to run any generators at all.  *)
684   method generate : unit
685
686   (** {2 Inherited Methods} Unless explicitly stated, these methods
687       do exactly the same thing as in {!Ldap_ooclient.scldapentry} *)
688
689   (** Missing attributes may be marked for generation. *)
690   method add : op_lst -> unit
691   method attributes : string list
692   method changes : (Ldap_types.modify_optype * string * string list) list
693   method changetype : changetype
694   method delete : op_lst -> unit
695   method dn : string
696   method diff : ldapentry_t -> (Ldap_types.modify_optype * string * string list) list
697   method exists : string -> bool
698   method flush_changes : unit
699
700   (** If a missing attribute is marked for generation its value will
701       be ["generate"] instead of ["required"] *)
702   method get_value : string -> string list
703   method is_allowed : string -> bool
704   method is_missing : string -> bool
705   method list_allowed : Setstr.elt list
706   method list_missing : Setstr.elt list
707   method list_present : Setstr.elt list
708   method modify :
709     (Ldap_types.modify_optype * string * string list) list -> unit
710   method of_entry : ?scflavor:scflavor -> ldapentry -> unit
711
712   (** @deprecated Missing required attributes which will be
713       generated are shown as "attrname: generate" instead of
714       "attrname: required" *)
715   method print : unit
716   method replace : op_lst -> unit
717   method set_changetype : changetype -> unit
718   method set_dn : string -> unit      
719 end