
    ?De>                        d Z ddlZddlmZ ddlZddlZddlT ddlZddl	Z	ej
        
                                Zi Z e e                                                      D ]"Z eed          reeej        <   ej        ee<   # ee          Z G d de          Z G d d	e          Z G d
 de          Z G d d          ZddZdS )zd
ldap.schema.subentry -  subschema subentry handling

See https://www.python-ldap.org/ for details.
    N)urlopen)*schema_attributec                       e Zd ZdS )SubschemaErrorN)__name__
__module____qualname__     /./ldap/schema/subentry.pyr   r      s        $r   r   c                       e Zd Zd Zd ZdS )OIDNotUniquec                     || _         d S Ndescselfr   s     r   __init__zOIDNotUnique.__init__"       DIIIr   c                     d| j         z  S )NzOID not unique for %sr   r   s    r   __str__zOIDNotUnique.__str__%   s    "di00r   Nr   r	   r
   r   r   r   r   r   r   r       s2          1 1 1 1 1r   r   c                       e Zd Zd Zd ZdS )NameNotUniquec                     || _         d S r   r   r   s     r   r   zNameNotUnique.__init__+   r   r   c                     d| j         z  S )NzNAME not unique for %sr   r   s    r   r   zNameNotUnique.__str__.   s    #ty11r   Nr   r   r   r   r   r   )   s2          2 2 2 2 2r   r   c                   j    e Zd ZdZddZd ZddZddZdd	Zd
 Z	ddZ
ddZd Zd Zd Z	 ddZdS )	SubSchemaa-  
  Arguments:

  sub_schema_sub_entry
      Dictionary usually returned by LDAP search or the LDIF parser
      containing the sub schema sub entry

  check_uniqueness
      Defines whether uniqueness of OIDs and NAME is checked.

      0
        no check
      1
        check but add schema description with work-around
      2
        check and raise exception if non-unique OID or NAME is found

  Class attributes:

  sed
    Dictionary holding the subschema information as pre-parsed
    SchemaElement objects (do not access directly!)
  name2oid
    Dictionary holding the mapping from NAMEs to OIDs
    (do not access directly!)
  non_unique_oids
    List of OIDs used at least twice in the subschema
  non_unique_names
    List of NAMEs used at least twice in the subschema for the same schema element
     c                    i | _         i | _        i | _        i | _        t                                          D ]X}t          j                                        | j         |<   i | j        |<   t          j                                        | j        |<   Yt          j                            |          }t          D ]v}t          d |
                    |g                     D ]M}t          |         } ||          }|                                }	|r|	| j        |         v rsd | j        |	<   |dk    rNd}
|	}|| j        |         v r8d                    |	t          |
          f          }|
dz  }
|| j        |         v 8|}	n|dk    rt          |          || j        |         |	<   t          |d          rzt          j                            i                     |j                            D ]B}|r.|| j         |         v rd | j        |         |	<   t%          |          |	| j         |         |<   COxt'          | j                  | _        d S )Nr"   ;   names)name2oidsednon_unique_oidsnon_unique_namesSCHEMA_CLASS_MAPPINGvaluesldapcidictSCHEMA_ATTRSfiltergetget_idjoinstrr   hasattrfromkeysr&   r   list)r   sub_schema_sub_entrycheck_uniquenessce	attr_type
attr_valuese_classse_instancese_idsuffix_counter	new_se_idnames                r   r   zSubSchema.__init__R   sf    DMDHDD!((** 6 6++--dmAdhqk!%!3!3!5!5dA 	/00A " 4 4	tAEE)B$7$788 4 4*'	2hz**""$$ 	-(); ; ;*.D '"" ni(!333HHeC,?,?%@AA	!# (!333 "!1$$ ,,, %05!;w'' 	4k(([5F)G)GHH 4 4d 4DDM(,C$C$C7;d#H-e4!*---.3dmH%d++;4@   455D
Fr   c                 $   i }| j                                         D ]s\  }}|                                D ]Y}t          |          }	 |t          |                                      |           9# t          $ r |g|t          |         <   Y Vw xY wt|S )zB
    Returns a dictionary containing the sub schema sub entry
    )r(   itemsr,   r4   SCHEMA_ATTR_MAPPINGappendKeyError)r   entryr>   elementssese_strs         r   
ldap_entryzSubSchema.ldap_entry   s    
 E #hnn.. < <(!! < <"R	<
#H-
.
5
5f
=
=
=
= 	< 	< 	<39%#H-
.
.
.	<	< Ls   &A..BBNc                     | j         |         }|r]g }|                                D ]E\  }}|D ]=\  }}	 t          ||          |v r|                    |           .# t          $ r Y :w xY wFnt          |          }|S )zf
    Returns a list of OIDs of all available schema
    elements of a given schema element class.
    )r(   rE   getattrrG   AttributeErrorr7   )	r   schema_element_classschema_element_filtersavail_seresultse_keyrK   fkfvs	            r   listallzSubSchema.listall   s    
 x,-H 
f ((  *&"+ 	 	EBrr"~~##mmF###   D		 H~~fMs   'A
A('A(c                    |t           t          fv sJ |                     ||          }d}t          j                            |g i          }|D ]}g ||<   |D ]}|                     ||d          }|j        |k    r%|j        |k    s)J d                    ||j        |j                              |j	        pdD ];}	| 
                    ||	          }
	 ||
                             |           5#  Y 9xY w|S )zm
    Returns a ldap.cidict.cidict dictionary representing the
    tree structure of the schema elements.
    _Nz>Schema element referenced by {} must be of class {} but was {})rZ   )ObjectClassAttributeTyperX   r-   r.   get_obj	__class__formatr   supgetoidrG   )r   rQ   rR   rS   top_nodetreerK   se_oidse_objssup_oids              r   rc   zSubSchema.tree   sD   
  K#>>>>>||01GHHHH;xm,,D  d2hh  ||0==f		/	/	/ 	3333HOO
%.v/?	
 	
 433 z#V  !++2155	
w-

v
&
&
&
&	
$ Ks   C//C3r   c           	      >   |                     d          d                                         }|| j        |         v r|S 	 | j        |         |         }nI# t          $ r< |r5t	          d                    |j        t          |                              |}Y nw xY w|S )z#
    Get an OID by name or OID
    r$   r   z%No registered {}-OID for nameoroid {})splitstripr(   r'   rH   r_   r   repr)r   r>   	nameoroidraise_keyerrornameoroid_stripped
result_oids         r   ra   zSubSchema.getoid   s     #--a06688TXh///*]8,-?@

 * * * 	*@GGHYZ^_qZrZrsstt
t)***	*
 s    A ABBc                     | j         |         |                     ||                   }	 t          ||          }n# t          $ r d}Y nw xY w|)|j        r"|                     ||j        d         |          }|S )z
    Get a possibly inherited attribute specified by name
    of a schema element specified by nameoroid.
    Returns None if class attribute is not set at all.

    Raises KeyError if no schema element is found by nameoroid.
    Nr   )r(   ra   rO   rP   r`   get_inheritedattr)r   r>   rl   rC   rK   rT   s         r   rq   zSubSchema.get_inheritedattr   s     
(	DKK;;	<Br$ff   fff~"&~%%hrvay>>fMs   : A	A	c           
      
   |                      ||          }	 | j        |         |         }nW# t          $ rJ |rCt          d                    |j        t          |          t          |                              |}Y nw xY w|S )z-
    Get a schema element by name or OID
    z:No ldap.schema.{} instance with nameoroid {} and se_oid {})ra   r(   rH   r_   r   rk   )r   r>   rl   defaultrm   rd   re   s          r   r]   zSubSchema.get_obj   s     [[),,Fx!&)ff   	 SZZ

DOODLL: : 
 
 	
  Ms   , AB ?B c           
         |pg }t          j         | j        |                             |                     ||                              }|r;t	          |d          r+|D ](}t          |||                     |||                     )|S )zt
    Get a schema element by name or OID with all class attributes
    set including inherited class attributes
    r`   )copyr(   r1   ra   r5   setattrrq   )r   r>   rl   	inheritedrK   class_attr_names         r   get_inheritedobjzSubSchema.get_inheritedobj  s    
 RI	48H%))$++hy*I*IJJ	K	KB	 _gb _& _ _/?4#9#9(9_#]#]^^^^Ir   c                     |                      t          |          }	 |                     t          |          }|j        S # t          $ r Y dS w xY w)zF
    Get the syntax of an attribute type specified by name or OID
    N)ra   r\   ry   syntaxrH   )r   rl   at_oidat_objs       r   
get_syntaxzSubSchema.get_syntax  s_     [[y11F$$]6::f ]    TTs   ? 
AAc                 b   |                      t          ddgfg          }i }|D ]5}|                     t          |d          }|r|j        dk    r
d||j        <   6d}t          |          }|rB|                                }||         D ]!}	|                     t          |	          |v r n"|}|B|S )ze
    Returns OID of structural object class in oc_list
    if any is present. Returns None else.
    kindr   N)rc   r[   r]   r   oidr7   popra   )
r   oc_listoc_tree
struct_ocsoc_nameoroidoc_serT   struct_oc_listr   	child_oids
             r   get_structural_oczSubSchema.get_structural_oc  s     iifaS\N33GJ % %ll;|D99e	 %5:q== $
59F*%%N
   cs|  );;{9--;;
% <    Mr   c                     |                      t          |          }|r|j        S |                     t          ddgfg          S )a  
    Return a list of the applicable AUXILIARY object classes
    for a STRUCTURAL object class specified by 'nameoroid'
    if the object class is governed by a DIT content rule.
    If there's no DIT content rule all available AUXILIARY
    object classes are returned.
    r   r%   )r]   DITContentRuleauxrX   r[   )r   rl   content_rules      r   get_applicable_aux_classesz$SubSchema.get_applicable_aux_classes8  sF     <<y99L 6 \\+s|n555r   c                     t           j        j        }t           j        j         fd|D             }i }t           j                                        t           j                                        }	}d|v r, j        |                                         D ]}
|
|	|
j        <   |rK|                    d          }||v rd||<   	  j                 |         }n# t          $ r |r Y Fw xY wt          |          sJ t          |d          sJ t          |                      t          |d          sJ t          |                      |j        D ]5}                     |||          }                     |||          ||<   6|j        D ]5}                     |||          }                     |||          |	|<   6|                     fd|j        D                        |K|s                     |          }|r	                      t(          |d	          }|j        D ]5}                     |||          }                     |||          ||<   6|j        D ]5}                     |||          }                     |||          |	|<   6|j        D ].}                     |||          }	 |	|= # t          $ r Y +w xY wn# t          $ r Y nw xY wt-          |	          D ]	}||v r|	|= 
|rt||	fD ]o}t-          |          D ]]}|D ]X\  }}	  j        |         |         }t/          ||          |vr||=  n)1# t          $ r |rt          d
|z            ||= Y  nw xY w^p||	fS )a  
    Returns a 2-tuple of all must and may attributes including
    all inherited attributes of superior object classes
    by walking up classes along the SUP attribute.

    The attributes are stored in a ldap.cidict.cidict dictionary.

    object_class_list
        list of strings specifying object class names or OIDs
    attr_type_filter
        list of 2-tuples containing lists of class attributes
        which has to be matched
    raise_keyerror
        All KeyError exceptions for non-existent schema elements
        are ignored
    ignore_dit_content_rule
        A DIT content rule governing the structural object class
        is ignored
    c                 <    g | ]}                     |          S r   ra   .0or[   r   s     r   
<listcomp>z-SubSchema.attribute_types.<locals>.<listcomp>b  s7       
 kk+a    r   z1.3.6.1.4.1.1466.101.120.111r   Nmustmay)rm   c                 <    g | ]}                     |          S r   r   r   s     r   r   z-SubSchema.attribute_types.<locals>.<listcomp>  s7           	K""     r   r"   z0No attribute type found in sub schema by name %s)r-   schemar\   r[   r.   r(   r,   r   r   rH   
isinstancer5   
ValueErrorr   ra   r]   r   extendr`   r   r   notsr7   rO   )r   object_class_listattr_type_filterrm   ignore_dit_content_ruler\   object_class_oids	oid_cacher_mustr_mayr}   object_class_oidobject_classard   structural_ocdit_content_rulea_oidlafkafvschema_attr_typer[   s   `                     @r   attribute_typeszSubSchema.attribute_typesH  s   , K-M+)K       
 I;%%''(:(:(<(<5F%):::H]+2244 # #&"fj  	*..q11 
Y	&	&$(i !x,-=>    	
	
 [11111\&))FF*5E*F*FFFF\%((EE4D)E)EEEE  Z Z!]1NKKmF.YYv Y Y!]1NKK]6XXf          !      	 	 	3  	> # ,,->??m	 	!\\.VW\XX

 $( ^ ^a[[q[OOF!\\-n\]]F6NN#' ] ]a[[q[OOF LLv^L\\E&MM#(  aKKa~KNNE,,   d	  	 	 	
$	& %[[  	
f!H  u~  !a 	 	A)  gc#!%-!8!; -c22c99aD :     YQUVWXXX A$ee		  %<sH   C C)(C)
K K
KK
K%$K%"M!M2	1M2	)r"   r   r   )Nr   )Nr"   r   )r   r	   r
   __doc__r   rM   rX   rc   ra   rq   r]   ry   r~   r   r   r   r   r   r   r!   r!   2   s        >4 4 4 4n  "   (   @   &  $   "
 
 
 

 
 
  46 6 6" [\w w w w w wr   r!   c                    |                                  } |                     d          rt          j        |           }t	          j        |                                |          }t          j        |_        |	                    |j
        pd|j        pd           |                    |j                  }|d}n-|j        t          }n|j        }|                    ||          }|                                 ~nIt%          |           }t'          j        |d          }|                                 |j        d         \  }}t          j                                        }	|pi }|                                D ]@\  }
}|
t2          v r2	 |	|
                             |           +# t6          $ r ||	|
<   Y <w xY wA|dk    r t          j                            |	          }nd}||fS )z
  Fetches a parsed schema entry by uri.

  If uri is a LDAP URL the LDAP server is queried directly.
  Otherwise uri is assumed to point to a LDIF file which
  is loaded with urllib.
  )zldap:zldaps:zldapi: N)attrsr"   )max_entriesr   )rj   
startswithldapurlLDAPUrlr-   
initializeinitializeUrlVERSION3protocol_versionsimple_bind_swhocredsearch_subschemasubentry_sdnr   r/   read_subschemasubentry_sunbind_sr   ldifLDIFRecordListparseall_recordsr.   rE   r+   r   rH   r   r!   )uritrace_levelldap_urlr   subschemasubentry_dns_tempschema_attrs	ldif_fileldif_parsersubschemasubentry_entryatavparsed_sub_schemas                r   urlfetchr     s    			#^^122 =s##H
oh,,..{;;AAOOHL&B(;<<<77DD#ff		#~))< *  f JJLLL	I%iA>>>K"-"9!"< K..00<R&||~~ ) )eb	!!!)#**2.... ) ) )&(###) " 4--.EFF	0	00s   
F&&F87F8r   )r   ru   urllib.requestr   ldap.cidictr-   ldap.schemaldap.schema.modelsr   r   r.   r+   rF   r7   varsr,   r   r5   r   r/   r   r   r   r   r!   r   r   r   r   <module>r      s     " " " " " "                   {))++  	ddffmmoo		 0 0AWQ!"" 0/0+,/t())    Z   1 1 1 1 1> 1 1 12 2 2 2 2N 2 2 2M M M M M M M M`/1 /1 /1 /1 /1 /1r   