
    !h)                     
   S r SSKrSSKr SSKrSSKJs  J	r
  SSKJr  S rS rS rS rS	 r\\\\\\S
.rS rS rS rS rS rS rS rSS jr\S:X  a  SSKrSr\" \R>                  5      S:X  a3  \ " S\R>                  S   -  \RB                  S9  \RD                  " S5        \R>                  S   r#\" \R>                  5      S:  a  \R>                  S   r\" \#\5        gg! \ a  r\R                  S5        e SrCff = f)z(Generate LDIF from Github documentation.    Nz'Please install python3-markdown package)
get_stringc                     S S / S 4$ N description
attributessds      B/usr/lib/python3/dist-packages/samba/ms_forest_updates_markdown.pynoopr   %   s    $D!!    c                 "   U R                  S5      (       a]  U R                  S5      (       aG  U(       a@  UR                  5       S:X  a,  U(       a%  UR                  5       S:X  a  S[        U 5      SS/S 4$ SS / UR                  5       S:w  a  U4$ S 4$ )NzGranting the zto gMSA accounts.n/amodifyzadd: appliesToz/appliesTo: 7b8b558a-93a5-4af7-adca-c017e67f1057)
startswithendswithlowerextract_dn_or_noner   s      r   parse_grantr   *   s    //011	
((*e3	
e#,[9!#TU 	 dBbhhjE&9DDtDDr   c                 d    [        U 5      nSU[        X15      UR                  5       S:w  a  U4$ S 4$ )Naddr   )
extract_dnextract_attribr   )r   r	   r
   dns       r   	parse_addr   8   s6    	K	 B2~b5RXXZ5=Pr[[VZ[[r   c                 `    S[        U 5      [        U5      UR                  5       S:w  a  U4$ S 4$ )Nr   r   )r   extract_replace_attribr   r   s      r   	parse_setr   >   s<    (5":.((*%B1 1+/1 1r   c                 X    S nSU" U 5      S   SSU-  /S 4SU" U 5      S   SSU-  /S 4/$ )	Nc                      SU ;   a  gSU ;   a  gg )Nz
Sam-Domain)z${DOMAIN_DN}zCN=Sam-Domain,${SCHEMA_DN}z
Domain-DNS)z${...}zCN=Domain-DNS,${SCHEMA_DN}r   texts    r   extract_dn_ace!parse_ace.<locals>.extract_dn_aceH   s    4AT!;r   r   r   zreplace: nTSecurityDescriptorz+nTSecurityDescriptor: ${DOMAIN_SCHEMA_SD}%s   z"replace: defaultSecurityDescriptorz,defaultSecurityDescriptor: ${OLD_SAMBA_SD}%sr   )r   r	   r
   r#   s       r   	parse_acer&   F   si     ~k215-;b@BCGI ~k2152<rACDHJK Kr   )GrantingCreatedSet	Added ACEUpdatedCallc                    U R                  SS5      n U R                  SS5      n [        R                  " SU 5      R                  S5      nUS:X  a  gUR	                  S	5      (       a  UR                  S
S5      nUS-   $ U$ )zS
Extract a DN from the textual description
:param text:
:return: DN in string form
z in the Schema partition.z,${SCHEMA_DN}z  in the Configuration partition.z,${CONFIG_DN}z!([CDO][NCU]=.*?,)*([CDO][NCU]=.*)r   zQCN=ad://ext/AuthenticationSilo,CN=Claim Types,CN=Claims Configuration,CN=Servicesz^CN=ad://ext/AuthenticationSilo,CN=Claim Types,CN=Claims Configuration,CN=Services,${CONFIG_DN}z&,CN=Extended-Rights" to gMSA accounts.z" to gMSA accounts. )replaceresearchgroupr   )r"   r   s     r   r   r   i   s     <<3_ED<<:OLD	6	=	C	CA	FB 
``o 
{{;<<ZZ-r2O##Ir   c                 (     [        U 5      $ !    g= f)zU
Same as above, but returns None if it doesn't work
:param text:
:return: DN or None
N)r   r!   s    r   r   r      s    $s   
 c                    [         R                  R                  X 5      n[        US5       nU H  nUu  pgpUR	                  SU-  5        UR	                  SU-  5        [        U5      S:  a#  UR	                  SR                  U5      S-   5        U	b  UR	                  SU	-  5        UR	                  S5        M     SSS5        g! , (       d  f       g= f)	z
Save ldif to disk for each updates
:param filename: filename use ([OPERATION NUM]-{GUID}.ldif)
:param answers: array of tuples generated with earlier functions
:param out_folder: folder to prepend
wdn: %s
changetype: %s
r   
NnTSecurityDescriptor: D:%s
-

)ospathjoinopenwritelen)
filenameanswers
out_folderr<   ldifanswerchanger   attribr
   s
             r   	save_ldifrH      s     77<<
-D	dCDF%+"FJJzB'JJ)F236{Q

499V,t34~

9B>?JJw  
s   BC
Cc                     SnU HN  nUu  pVpxUSU-  -  nUSU-  -  n[        U5      S:  a  USR                  U5      S-   -  nUb  USU-  -  nUS-  nMP     X2U '   g)	z
Save ldif to an output dictionary
:param guid: GUID to store
:param answers: array of tuples generated with earlier functions
:param out_dict: output dictionary
r.   r6   r7   r   r8   Nr9   r:   )r@   r=   )	guidrB   out_dictrD   rE   rF   r   rG   r
   s	            r   
save_arrayrL      s     D!'F
R"V++v;?DIIf%,,D>2R77D  TNr   c                    UR                  S5       Vs/ s H1  o"R                  5       S:w  d  M  US:w  d  M   UR                  S5      PM3     nnU Vs/ s H,  o"R                  S5      (       a  UR	                  SS5      OUPM.     nnU Vs/ s H,  o"R                  S5      (       a  UR	                  SS5      OUPM.     nnU Vs/ s H*  o"R                  5       R                  S	5      (       a  M(  UPM,     nnU$ s  snf s  snf s  snf s  snf )
z
Extract the attributes as an array from the attributes column
:param dn: parsed from markdown
:param attributes: from markdown
:return: attribute array (ldif-type format)
-   r   r.   - z: Truez: TRUEz: Falsez: FALSEzmsds-claimpossiblevalues)splitr   lstripr   r/   r   )r   r	   xrG   s       r   r   r      s     '1&6&6v&>a&>'')uBTnYZ^`Y`nahhtn&>FaTZ[TZqzz(/C/Caii(+JTZF[W]^W]RSI1F1Faii	9-AMW]F^XAwwy';';<V'WaFXM b[^Xs'   C9C9C93C>3D'D/Dc                 J   U R                  S5       Vs/ s H1  oR                  5       S:w  d  M  US:w  d  M   UR                  S5      PM3     nnU Vs/ s H  nSUR                  S5      S   -  U4PM     nnU VVs/ s H  oD  H  o3PM     M     nnnU$ s  snf s  snf s  snnf )z
Extract the attributes as an array from the attributes column
(for replace)
:param attributes: from markdown
:return: attribute array (ldif-type format)
rN   r   r.   rO   zreplace: %s:r   )rP   r   rQ   )r	   rR   lineslinepairs        r   r   r      s     &0%5%5f%=`%=eAS^XY]_X_^QXXd^%=E`DIJEDmdjjoa00$7EEJ#5edTTeE5L aJ5s   BBB#B<Bc                     U R                   =(       d    SSR                  S U  5       5      -   U R                  =(       d    S-   $ )Nr.   c              3   8   #    U  H  n[        U5      v   M     g 7fr   )	innertext).0es     r   	<genexpr>innertext.<locals>.<genexpr>   s     *c	!cs   )r"   r=   tail)tags    r   rZ   rZ      s9    HHN
*c**+	R r   c           	         [        U 5       nUR                  5       n[        R                  " SSU5      n[        R                  " SSU5      n[        R                  " SSU5      n[        R                  " USS9nS	S	S	5        WR                  S
S5      n[        R                  " SU-   S-   5      nU GH  nUR                  (       d  M  S	nUR                  R                  S5      (       aZ  [        [        R                  " USS95      R                  5        V	s/ s H"  oS[        U	5      S-
   R                  S5      PM$     nn	OyUR                  R                  S5      (       aY  [        [        R                  " USS95      R                  5        V	s/ s H"  oS[        U	5      S-
   R                  S5      PM$     nn	U(       d  GM  USS	  GHc  n
[        R                  " SU
S   5      nU(       a9  UR!                  S5      nUR!                  S5      R#                  S5      < SU< S3nSnU
S   R                  S5      (       d  U
S   R                  S5      (       aU  U
S   R                  S5      S    U
S'   [%        U
S   U
S   U
S   5      nW(       a  Ub  ['        XU5        O[)        WX5        M  [*         H`  nU
S   R                  U5      (       d  M  S!n[*        U   " U
S   U
S   U
S   5      nW(       a  Ub  ['        X/U5        O[)        WU/U5          O   U(       a  GM[  [-        U
5      e   GM     g	! , (       d  f       GN= fs  sn	f s  sn	f )"z
Read Github documentation to produce forest wide updates
:param in_file: Forest-Wide-Updates.md
:param out_folder: output folder
:param out_dict: output dictionary
z<p>z<br />zCN=\\<forest root domainzCN=<forest root domainzCN=<forest root domain.*?>z${FOREST_ROOT_DOMAIN}xhtml)output_formatNzCN=Schema,%wsz${SCHEMA_DN}z<root>z</root>z
|Operationr"   )methodr%   |z| Operation   z | zOperation (\d+): {(.*)}r      z-{z}.ldifF   r(   r*   rT   T)r>   readr0   submarkdownr/   ET
fromstringr"   r   r   tostring
splitlinesr@   rP   matchr2   zfillr&   rH   rL   operation_map	Exception)in_filerC   rK   update_filecontenthtmltreenodeupdatesrR   updateoutputrJ   rA   foundresult	operations                    r   read_ms_markdownr      s    
g+""$&&! " &&41 " &&60 "   /68 
$ <<8D==D945Dyy99-- ""++d6"BCNNPRP 783q6A:,,S1P  RGYY!!-00 ""++d6"BCNNPRP 9:3q6A:,,U3P  R7!!"+"<fQiH!<<?D17a1F1Fq1I4PH!9''	22fQi6J6J;6W6W !'q	 4R 8F1I&vay&)VAYGFJ$:!(J?"4:!.Iay++I66 $!.y!9&)VAYPVWXPY!Z#
(>%h*E&tfXx@ "/ u#F++K & - 
8RRs   A.L;)M)M;
M
__main__r.   z4Usage: %s <Forest-Wide-Updates.md> [<output folder>])filer%   rf   )NN)$__doc__r0   r;   rl   ImportErrorr\   add_notexml.etree.ElementTreeetreeElementTreerm   samba.commonr   r   r   r   r   r&   rs   r   r   rH   rL   r   r   rZ   r   __name__sysrC   r@   argvprintstderrexitru   r   r   r   <module>r      s-  . / 	 	
 # " #"

E\1K*  ,	 (* 
P,j zJ
388}DQRT[^[e[efhhqkG
388}qXXa[
Wj) _  
JJ89	
s   C% %D+C==D