
    gM                        S SK r S SKJrJr  S SKJrJr  S SKJrJr  S SK	J
r
  S SKJrJrJrJrJr  S SKJr  S SKJr  S S	KJrJr  S S
KJrJr   " S S\S9r " S S\5      r " S S\5      r " S S\5      r " S S\5      r " S S\5      r  " S S\5      r! " S S\5      r" " S S\5      r# " S S\5      r$ " S  S!\5      r% " S" S#\5      r& " S$ S%\5      r' " S& S'\5      r(g)(    N)ABCMetaabstractmethod)datetimetimezone)IntEnumIntFlag)ElementTree)DnMessageElementbinary_encodestring_to_time
timestring)security)GUID)ndr_pack
ndr_unpack)datetime_from_nt_timent_time_from_datetimec                   L    \ rS rSrSr  S	S jr\S 5       r\S 5       rS r	Sr
g)
Field$   a5  Base class for all fields.

Each field will need to implement from_db_value and to_db_value.

A field must correctly support converting both single valued fields,
and list type fields.

The only thing many=True does is say the field "prefers" to be a list,
but really any field can be a list or single value.
Nc                 x    Xl         X l        X@l        XPl        U R                  (       a  Uc  / U l        gX0l        g)aa  Creates a new field, should be subclassed.

:param name: SamDB field name.
:param many: If true always convert field to a list when loaded.
:param default: Default value or callback method (obj is first argument)
:param hidden: If this is True, exclude the field when calling as_dict()
:param readonly: If true don't write this value when calling save.
N)namemanyhiddenreadonlydefault)selfr   r   r   r   r   s         </usr/lib/python3/dist-packages/samba/domain/models/fields.py__init__Field.__init__0   s1     		  99DL"L    c                     g)zConverts value read from the database to Python value.

:param samdb: SamDB connection
:param value: MessageElement value from the database
:returns: Parsed value as Python type
N )r   samdbvalues      r   from_db_valueField.from_db_valueF   s     	r"   c                     g)a  Converts value to database value.

This should return a MessageElement or None, where None means
the field will be unset on the next save.

:param samdb: SamDB connection
:param value: Input value from Python field
:param flags: MessageElement flags
:returns: MessageElement or None
Nr$   )r   r%   r&   flagss       r   to_db_valueField.to_db_valueP   s     	r"   c                 :    SU R                    S[        U5       S3$ 1Returns the ldb search expression for this field.(=))r   r   r   r&   s     r   
expressionField.expression^   s!    499+Q}U34A66r"   )r   r   r   r   r   )FNFF)__name__
__module____qualname____firstlineno____doc__r    r   r'   r+   r4   __static_attributes__r$   r"   r   r   r   $   sB    	 ?D#,    7r"   r   )	metaclassc                   $    \ rS rSrSrS rS rSrg)IntegerFieldc   z5A simple integer field, can be an int or list of int.c                     Uc  g[        U5      S:  d  U R                  (       a  U Vs/ s H  n[        U5      PM     sn$ [        US   5      $ s  snf )z-Convert MessageElement to int or list of int.N   r   )lenr   intr   r%   r&   items       r   r'   IntegerField.from_db_valuef   sG    =Z!^tyy*/0%$CI%00uQx=  1   Ac                     Uc  g[        U[        5      (       a0  [        U Vs/ s H  n[        U5      PM     snX0R                  5      $ [        [        U5      X0R                  5      $ s  snf )z-Convert int or list of int to MessageElement.N
isinstancelistr   strr   r   r%   r&   r*   rE   s        r   r+   IntegerField.to_db_valueo   ^    =t$$!',-utTu-uiiA A "#e*eYY?? .   A)r$   Nr6   r7   r8   r9   r:   r'   r+   r;   r$   r"   r   r>   r>   c   s    ?!@r"   r>   c                   $    \ rS rSrSrS rS rSrg)BinaryFieldz   zSimilar to StringField but using bytes instead of str.

This tends to be quite easy because a MessageElement already uses bytes.
c                     Uc  g[        U5      S:  d  U R                  (       a  U Vs/ s H  n[        U5      PM     sn$ [        US   5      $ s  snf )zConvert MessageElement to bytes or list of bytes.

The values on the MessageElement should already be bytes so the
cast to bytes() is likely not needed in from_db_value.
NrA   r   )rB   r   bytesrD   s       r   r'   BinaryField.from_db_value   sI     =Z!^tyy,12EDE$KE22q?" 3rG   c                     Uc  g[        U[        5      (       a0  [        U Vs/ s H  n[        U5      PM     snX0R                  5      $ [        [        U5      X0R                  5      $ s  snf )z1Convert bytes or list of bytes to MessageElement.N)rJ   rK   r   rV   r   rM   s        r   r+   BinaryField.to_db_value   s^    =t$$!)./t/		C C "%,yyAA 0rP   r$   NrQ   r$   r"   r   rS   rS   z   s    
#Br"   rS   c                   $    \ rS rSrSrS rS rSrg)StringField   z6A simple string field, may contain str or list of str.c                     Uc  g[        U5      S:  d  U R                  (       a  U Vs/ s H  n[        U5      PM     sn$ [        U5      $ s  snf )z-Convert MessageElement to str or list of str.NrA   rB   r   rL   rD   s       r   r'   StringField.from_db_value   sC    =Z!^tyy*/0%$CI%00u: 1s   Ac                     Uc  g[        U[        5      (       a0  [        U Vs/ s H  n[        U5      PM     snX0R                  5      $ [        [        U5      X0R                  5      $ s  snf )z-Convert str or list of str to MessageElement.NrI   rM   s        r   r+   StringField.to_db_value   rO   rP   r$   NrQ   r$   r"   r   r[   r[      s    @@r"   r[   c                   H   ^  \ rS rSrSrS	U 4S jjrS rS rS rS r	Sr
U =r$ )
	EnumField   z(A field based around Python's Enum type.c                 2   > X l         [        TU ]	  XU5        g)z0Create a new EnumField for the given enum class.N)enumsuperr    )r   r   rf   r   r   	__class__s        r   r    EnumField.__init__   s    	W-r"   c                     [        U R                  [        [        45      (       a#  U R                  [	        [        U5      5      5      $ U R                  [        U5      5      $ )zfReturn Enum instance from value.

Has a special case for IntEnum as the constructor only accepts int.
)
issubclassrf   r   r   rC   rL   r3   s     r   enum_from_valueEnumField.enum_from_value   sD    
 dii'7!34499SU_--99SZ((r"   c                     Uc  g[        U5      S:  d  U R                  (       a!  U Vs/ s H  o0R                  U5      PM     sn$ U R                  U5      $ s  snf )z/Convert MessageElement to enum or list of enum.NrA   )rB   r   rl   rD   s       r   r'   EnumField.from_db_value   sP    =Z!^tyy;@A54((.5AA''.. Bs   Ac                    Uc  g[        U[        5      (       a:  [        U Vs/ s H  n[        UR                  5      PM     snX0R
                  5      $ [        [        UR                  5      X0R
                  5      $ s  snf )z/Convert enum or list of enum to MessageElement.N)rJ   rK   r   rL   r&   r   rM   s        r   r+   EnumField.to_db_value   sg    =t$$!-23UTTZZU3UIIG G "#ekk"2E99EE 4   A=c                 `    SU R                    S[        [        UR                  5      5       S3$ r.   )r   r   rL   r&   r3   s     r   r4   EnumField.expression   s*    499+Q}S-=>?qAAr"   )rf   FN)r6   r7   r8   r9   r:   r    rl   r'   r+   r4   r;   __classcell__rh   s   @r   rc   rc      s'    2.
)/FB Br"   rc   c                   $    \ rS rSrSrS rS rSrg)DateTimeField   z8A field for parsing ldb timestamps into Python datetime.c           
      J   Uc  g[        U5      S:  d  U R                  (       aF  U Vs/ s H8  n[        R                  " [	        [        U5      5      [        R                  S9PM:     sn$ [        R                  " [	        [        U5      5      [        R                  S9$ s  snf )7Convert MessageElement to datetime or list of datetime.NrA   )tz)rB   r   r   fromtimestampr   rL   r   utcrD   s       r   r'   DateTimeField.from_db_value   s    =Z!^tyyHMOHM **>#d)+D.6ll<HMO O )).U*D-5\\; ;Os   ?B c                 P   Uc  g[        U[        5      (       aM  [        U Vs/ s H+  n[        [	        [
        R                  " U5      5      5      PM-     snX0R                  5      $ [        [        [	        [
        R                  " U5      5      5      X0R                  5      $ s  snf z7Convert datetime or list of datetime to MessageElement.N)rJ   rK   r   r   rC   r   	timestampr   rM   s        r   r+   DateTimeField.to_db_value   s    =t$$!GLMutC 2 24 89:uMyy" " "*S1C1CE1J-K"L"'4 4 Ns   2B#r$   NrQ   r$   r"   r   ry   ry      s    B	;
4r"   ry   c                   $    \ rS rSrSrS rS rSrg)NtTimeField   z%18-digit Active Directory timestamps.c                     Uc  g[        U5      S:  d  U R                  (       a%  U Vs/ s H  n[        [        U5      5      PM     sn$ [        [        US   5      5      $ s  snf )r|   NrA   r   )rB   r   r   rC   rD   s       r   r'   NtTimeField.from_db_value   sS    =Z!^tyyAFG)#d)4GG(U1X77 Hs   A!c           
          Uc  g[        U[        5      (       a9  [        U Vs/ s H  n[        [	        U5      5      PM     snX0R
                  5      $ [        [        [	        U5      5      X0R
                  5      $ s  snf r   )rJ   rK   r   rL   r   r   rM   s        r   r+   NtTimeField.to_db_value   sq    =t$$!>CDed*401eDyy" " "#&;E&B"C"'4 4 E   A;r$   NrQ   r$   r"   r   r   r      s    /8
4r"   r   c                   <   ^  \ rS rSrSrSU 4S jjrS rS rSrU =r	$ )RelatedFieldi  zA field that automatically fetches the related objects.

Use sparingly, can be a little slow. If in doubt just use DnField instead.
c                 2   > X l         [        TU ]	  XU5        g)z.Create a new RelatedField for the given model.N)modelrg   r    )r   r   r   r   r   rh   s        r   r    RelatedField.__init__  s    
W-r"   c                 (   Uc  g[        U5      S:  d  U R                  (       a=  U Vs/ s H/  o0R                  R                  U[	        U[        U5      5      S9PM1     sn$ U R                  R                  U[	        U[        U5      5      S9$ s  snf )zConvert Message element to related object or list of objects.

Note that fetching related items is not using any sort of lazy
loading so use this field sparingly.
NrA   )dn)rB   r   r   getr
   rL   rD   s       r   r'   RelatedField.from_db_value  st     =Z!^tyyOTUutJJNN5Rs4y-ANBuUU::>>%Buc%j,A>BB Vs   6Bc                    Uc  g[        U[        5      (       a:  [        U Vs/ s H  n[        UR                  5      PM     snX0R
                  5      $ [        [        UR                  5      X0R
                  5      $ s  snf )z<Convert related object or list of objects to MessageElement.N)rJ   rK   r   rL   r   r   rM   s        r   r+   RelatedField.to_db_value%  sf    =t$$!*/0%$TWW%0%D D "#ehh-		BB 1rr   )r   ru   
r6   r7   r8   r9   r:   r    r'   r+   r;   rv   rw   s   @r   r   r     s    
.
CC Cr"   r   c                   $    \ rS rSrSrS rS rSrg)DnFieldi0  z5A Dn field parses the current field into a Dn object.c           	          Uc  g[        U[        5      (       a  U$ [        U5      S:  d  U R                  (       a&  U Vs/ s H  n[        U[	        U5      5      PM     sn$ [        U[	        U5      5      $ s  snf )z<Convert MessageElement to a Dn object or list of Dn objects.NrA   )rJ   r
   rB   r   rL   rD   s       r   r'   DnField.from_db_value3  sc    =r""LZ!^tyy5:;UTBuc$i(U;;eSZ(( <s    A7c                     Uc  g[        U[        5      (       a0  [        U Vs/ s H  n[        U5      PM     snX0R                  5      $ [        [        U5      X0R                  5      $ s  snf )z>Convert Dn object or list of Dn objects into a MessageElement.NrI   rM   s        r   r+   DnField.to_db_value>  rO   rP   r$   NrQ   r$   r"   r   r   r   0  s    ?	)@r"   r   c                   $    \ rS rSrSrS rS rSrg)	GUIDFieldiI  z4A GUID field decodes fields containing binary GUIDs.c           	          Uc  g[        U5      S:  d  U R                  (       a*  U Vs/ s H  n[        [        [        U5      5      PM     sn$ [        [        [        US   5      5      $ s  snf z=Convert MessageElement with a GUID into a str or list of str.NrA   r   )rB   r   rL   r   r   rD   s       r   r'   GUIDField.from_db_valueL  sX    =Z!^tyy<ABEDC
4./EBBz$a122 Cs   #A+c           
          Uc  g[        U[        5      (       a9  [        U Vs/ s H  n[        [	        U5      5      PM     snX0R
                  5      $ [        [        [	        U5      5      X0R
                  5      $ s  snf z*Convert str with GUID into MessageElement.N)rJ   rK   r   r   r   r   rM   s        r   r+   GUIDField.to_db_valueU  sh    =t$$!278%$$t*%%8%L L "(4;"7		JJ 9r   r$   NrQ   r$   r"   r   r   r   I  s    >3Kr"   r   c                   *    \ rS rSrSrS rS rS rSrg)SIDFieldi`  z)A SID field encodes and decodes SID data.c           	         Uc  g[        U5      S:  d  U R                  (       a4  U Vs/ s H&  n[        [        [        R
                  U5      5      PM(     sn$ [        [        [        R
                  US   5      5      $ s  snf r   )rB   r   rL   r   r   dom_sidrD   s       r   r'   SIDField.from_db_valuec  sd    =Z!^tyyHMNC
8#3#3T:;NNz("2"2E!H=>> Os   -A?c           
      ,   Uc  g[        U[        5      (       aD  [        U Vs/ s H"  n[        [        R
                  " U5      5      PM$     snX0R                  5      $ [        [        [        R
                  " U5      5      X0R                  5      $ s  snf r   )rJ   rK   r   r   r   r   r   rM   s        r   r+   SIDField.to_db_valuel  s{    =t$$!>CDed(**401eDyy" " "(8+;+;E+B"C"'4 4 Es   )Bc                 L    SU R                    S[        [        U5      5       S3$ r.   )r   r   rL   r3   s     r   r4   SIDField.expressionx  s'     499+Q}SZ89;;r"   r$   N)	r6   r7   r8   r9   r:   r'   r+   r4   r;   r$   r"   r   r   r   `  s    3?
4<r"   r   c                   F   ^  \ rS rSrSrSSSSS.U 4S jjrS rS	 rS
rU =r	$ )	SDDLFieldi~  z+A SDDL field encodes and decodes SDDL data.FNT)r   r   r   allow_device_in_sddlc                .   > XPl         [        TU ]	  XX4S9  g)zCreate a new SDDLField.)r   r   r   N)r   rg   r    )r   r   r   r   r   r   rh   s         r   r    SDDLField.__init__  s     %9!'Ir"   c                     Uc  g [        U5      S:  d  U R                  (       a+  U Vs/ s H  n[        [        R                  U5      PM     sn$ [        [        R                  US   5      $ s  snf )NrA   r   )rB   r   r   r   
descriptorrD   s       r   r'   SDDLField.from_db_value  sZ    =Z!^tyyFKLedJx22D9eLLh1158<< Ms   $A-c           
         Uc  g [        U[        5      (       a:  [        U Vs/ s H  o@R                  XU5      S   PM     snUU R                  5      $ [
        R                  " UR                  5       5      n[        U[        5      (       a)  [
        R                  R                  X%U R                  S9nOUn[        [        U5      X0R                  5      $ s  snf )Nr   r   )rJ   rK   r   r+   r   r   r   get_domain_sidrL   r   	from_sddlr   r   )r   r%   r&   r*   rE   
domain_siddescs          r   r+   SDDLField.to_db_value  s    =t$$!EJKUT!!%u5a8UK		 
 "))%*>*>*@AJ %%%**44)-)B)B 5 D !(4.%CC Ls   Cr   r   rw   s   @r   r   r   ~  s1    5
 &*	J 	J=D Dr"   r   c                   8   ^  \ rS rSrSrS rS rU 4S jrSrU =r	$ )BooleanFieldi  z6A simple boolean field, can be a bool or list of bool.c                     Uc  g[        U5      S:  d  U R                  (       a  U Vs/ s H  n[        U5      S:H  PM     sn$ [        U5      S:H  $ s  snf )z3Convert MessageElement into a bool or list of bool.NrA   TRUEr^   rD   s       r   r'   BooleanField.from_db_value  sM    =Z!^tyy49:EDCI'E::u:'' ;s   Ac           
      8   Uc  g[        U[        5      (       aG  [        U Vs/ s H%  n[        [	        U5      5      R                  5       PM'     snX0R                  5      $ [        [        [	        U5      5      R                  5       X0R                  5      $ s  snf )z3Convert bool or list of bool into a MessageElement.N)rJ   rK   r   rL   boolupperr   rM   s        r   r+   BooleanField.to_db_value  sy    =t$$!5:;UTT$Z&&(U;UIIO O "#d5k"2"8"8":E99MM <s   ,Bc                 ^   > USL a  SU R                    S3$ [        TU ]	  [        U5      5      $ )r/   Fz(!(z=TRUE)))r   rg   r4   rL   )r   r&   rh   s     r   r4   BooleanField.expression  s3     E>7++7%c%j11r"   r$   )
r6   r7   r8   r9   r:   r'   r+   r4   r;   rv   rw   s   @r   r   r     s    @(N2 2r"   r   c                   0    \ rS rSrSrSSSS.rS rS rS	rg
)PossibleClaimValuesFieldi  aA  Field for parsing possible values XML for claim types.

This field will be represented by a list of dicts as follows:

[
    {"ValueGUID": <GUID>},
    {"ValueDisplayName: "Display name"},
    {"ValueDescription: "Optional description or None for no description"},
    {"Value": <Value>},
]

Note that the GUID needs to be created client-side when adding entries,
leaving it as None then saving it doesn't generate the GUID.

The field itself just converts the XML to list and vice versa, it doesn't
automatically generate GUIDs for entries, this is entirely up to the caller.
z http://www.w3.org/2001/XMLSchemaz)http://www.w3.org/2001/XMLSchema-instancezChttp://schemas.microsoft.com/2010/08/ActiveDirectory/PossibleValues)xsdxsi c           
         UGb  [         R                  " [        U5      5      nUR                  SU R                  5      n/ nUR                  SU R                  5       H  nUR                  UR                  SU R                  5      R                  UR                  SU R                  5      R                  UR                  SU R                  5      R                  UR                  SU R                  5      R                  S.5        M     U$ g)	z/Parse MessageElement with XML to list of dicts.N
StringListItem	ValueGUIDValueDisplayNameValueDescriptionValue)r   r   r   r   )r	   
fromstringrL   find	NAMESPACEfindallappendtext)r   r%   r&   rootstring_listvaluesrE   s          r   r'   &PossibleClaimValuesField.from_db_value  s    ))#e*5D))L$..AKF#++FDNNC!%;!G!L!L(,		2D26..)BBF$(,		2D26..)BBF$!YYw?DD  D M r"   c                    Uc  g[        U[        5      (       a  UnOU/n[        U5      S:X  a  g[        R                  " S5      nU R
                  R                  5        H4  u  pgUS:X  a  UR                  SU5        M  UR                  SU 3U5        M6     [        R                  " US5      nU H  n	[        R                  " US5      n
[        R                  " U
S	5      nU	S	   Ul	        [        R                  " U
S
5      nU	S
   Ul	        [        R                  " U
S5      nU	S   Ul	        [        R                  " U
S5      nU	S   Ul	        M     [        R                  " 5       n[        R                  " U5      R                  USSSS9  [        UR                  5       R                  S5      X0R                   5      $ )z6Convert list of dicts back to XML as a MessageElement.Nr   PossibleClaimValuesr   xmlnszxmlns:r   r   r   r   r   r   zutf-16TF)encodingxml_declarationshort_empty_elements)rJ   rK   rB   r	   Elementr   itemsset
SubElementr   ioBytesIOwriter   getvaluedecoder   )r   r%   r&   r*   possible_valuesr   r   urlr   	item_dictrE   	item_guid	item_name	item_desc
item_valueouts                   r   r+   $PossibleClaimValuesField.to_db_value  s   = eT""#O$gO 1$ ""#89--/IDrz#&6$#.	 0 ",,T<@ )I))+v>D#..t[AI&{3IN#..t5GHI&'9:IN#..t5GHI&'9:IN$//g>J'0JO ) jjl%++C5=<@AF 	, 	H clln33H=uiiPPr"   r$   N)	r6   r7   r8   r9   r:   r   r'   r+   r;   r$   r"   r   r   r     s$    ( 2:QI&2Qr"   r   ))r   abcr   r   r   r   rf   r   r   	xml.etreer	   ldbr
   r   r   r   r   samba.dcerpcr   samba.dcerpc.miscr   	samba.ndrr   r   samba.nt_timer   r   r   r>   rS   r[   rc   ry   r   r   r   r   r   r   r   r   r$   r"   r   <module>r      s   . 
 ' ' ! ! M M ! " * F<7g <7~@5 @.B% B<@% @.'B 'BT4E 464% 42 C5  CF@e @2K K.<u <<)D )DX25 2>_Qu _Qr"   