a
    Wa5m                     @   sX  d dl mZ d dlZd dlZd dlmZ d dlZd dlZd dlm	Z
 d dlmZ d dlmZ d dlmZmZmZmZ d dlmZ d dlmZ d d	lmZmZ d d
lmZ d dlmZmZmZ d dlZd dlZd dl m!Z!m"Z" d dl#m$Z$ d dl%m&Z& d dl'm(Z(m)Z)m*Z*m+Z+m,Z,m-Z-m.Z.m/Z/ eddde0dddeddde0dddedddddd ed!d"d#d$ed%d&g d'd(ed)d*e1e2 d(ed+d,d-d#d.d/ed0d1d2d#d.d/ed3d4d5d6d7d8g	Z3ed9d:dd;dd ed<d=dd>dd gZ4d?Z5G d@dA dAeZ6dBdC Z7dDdE Z8dFdG Z9G dHdI dIe6Z:G dJdK dKe;Z<G dLdM dMe6Z=G dNdO dOe6Z>G dPdQ dQeZ?dS )R    )print_functionN)defaultdict)dsdb)nttime2unix)CommandSuperCommandCommandErrorOption)SamDB)	dot_graph)distance_matrixCOLOUR_SETS)full_matrix)
SCOPE_BASESCOPE_SUBTREELdbError)KCCldif_import_export)KCCError)	text_type)get_partition_mapsget_partitionget_own_cursorget_utdvget_utdv_edgesget_utdv_distancesget_utdv_max_distanceget_kcc_and_dsasz-Hz--URLz%LDB URL for database or target serverZURLH)helptypemetavardestz-oz--outputzwrite here (default stdout)ZFILE)r   r    r!   defaultz
--distancez&Distance matrix graph output (default)formatdistanceZstore_const)r   r"   Zconstactionz--utf8zUse utf-8 Unicode characters
store_true)r   r&   z--colorzuse color (yes, no, auto))Zyesnoauto)r   choicesz--color-schemez,use this colour scheme (implies --color=yes)z-Sz--shorten-namesz don't print long common suffixesF)r   r&   r#   z-rz--talk-to-remotezquery other DCs' databasesz--no-keyzomit the explanatory keyZstore_falseTkey)r   r&   r#   r"   z--dotzGraphviz dot outputdotz--xdotzattempt to call Graphviz xdotxdotZ__temp__c                   @   s\   e Zd ZdZdZejejejdZ	e
e ZdZdd Zdd	d
Zdd Zdd Zdd ZdS )GraphCommandz Base class for graphing commandsz%prog [options])	sambaoptsversionoptscredopts c                 C   s(   |  }|j|dd}t|||d}|S )NTZfallback_machine)ZurlZcredentialslp)get_loadparmget_credentialsr
   )selfr   r/   r1   r4   credssamdbr2   r2   8/usr/lib/python3/dist-packages/samba/netcmd/visualize.pyget_dbb   s    zGraphCommand.get_dbN.dotc                 C   sr   |du s|dkr"t || jd dS |tu rRtjd|d\}}t|d}t| n
t|d}|| |  |S )a  Decide whether we're dealing with a filename, a tempfile, or
        stdout, and write accordingly.

        :param s: the string to write
        :param fn: a destination
        :param suffix: suffix, if destination is a tempfile

        If fn is None or "-", write to stdout.
        If fn is visualize.TEMP_FILE, write to a temporary file
        Otherwise fn should be a filename to write to.
        N-filesamba-tool-visualise)prefixsuffixw)	printoutf	TEMP_FILEtempfileZmkstempopenosclosewrite)r7   sfnrB   fdfr2   r2   r:   rK   h   s    



zGraphCommand.writec                 C   s.   |s|r|  drdS dS |dkr*dS |S )z5Heuristics to work out what output format was wanted.r<   r,   r%   r-   )lowerendswith)r7   r$   outputr2   r2   r:   calc_output_format   s    zGraphCommand.calc_output_formatc                 C   sL   |d u r|  |t}n|  ||}tjdd}t||g t| d S )NZSAMBA_TOOL_XDOT_PATHz/usr/bin/xdot)rK   rF   rI   environget
subprocessZcallremove)r7   rL   rR   rM   r-   r2   r2   r:   	call_xdot   s    zGraphCommand.call_xdotc                 C   sn   |dkrdS |dkrHt |tr*|dkr*dS t| jds:dS | j sHdS |du rjdtjddv rfd	S d
S |S )zHeuristics to work out the colour scheme for distance matrices.
        Returning None means no colour, otherwise it sould be a colour
        from graph.COLOUR_SETSr(   Nr)   r=   isattyZ256colorZTERM zxterm-256color-heatmapansi)
isinstancestrhasattrrE   rY   rI   rT   rU   )r7   colorcolor_schemerR   r2   r2   r:   calc_distance_color_scheme   s    
z'GraphCommand.calc_distance_color_scheme)Nr<   )__name__
__module____qualname____doc__ZsynopsisoptionsZSambaOptionsZVersionOptionsZCredentialsOptionsZtakes_optiongroupsCOMMON_OPTIONSDOT_OPTIONStakes_optionsZ
takes_argsr;   rK   rS   rX   ra   r2   r2   r2   r:   r.   V   s   
	r.   c                 C   s   t d| }|r|dS | S )zFHelper function for sorting and grouping DNs by site, if
    possible.z$CN=Servers,CN=\s*([^,]+)\s*,CN=Sites   )researchgroup)dnmr2   r2   r:   get_dnstr_site   s    
rp   c                 C   s   t | d S )z\Helper function for sorting and grouping lists of (DN, ...) tuples
    by site, if possible.r   )rp   )tr2   r2   r:   get_dnstrlist_site   s    rr   c                 C   sP   ddl m} t| }t|tr(|d}t|| dd ddd@ }d	| S )
zQGenerate a randomish but consistent darkish colour based on the
    given object.r   )md5utf8N      )basei z#%06x)Zhashlibrs   r]   r\   r   encodeintZ	hexdigest)xrs   Ztmp_strcr2   r2   r:   colour_hash   s    

 r|   c                   @   s4   e Zd ZdZee edddddg Zdd
dZdS )cmd_repszrepsFrom/repsTo from every DSA-p--partitionrestrict to this partitionNr   r#   FTr7   c           @      C   s  |  }|j|dd}t|||\}}|j}t|j|
}
tdd }i }|D ]H}t|dd}|r|jj|t	dgd}t
|d d d }td	||f tjd
 z|d| || W nF ty } z.td||f tjd
 W Y d }~qLW Y d }~n
d }~0 0 |||| n |||| |j||||d t| }||krtdtjd
 || D ]}td| tjd
 q\td| tjd
 || D ]}td| tjd
 q|D ]}|	dkr||kr̐qn|	dkr||krq|d| }|| ||t
|j< | \} }!|  D ]4\}"}#|
d u s:|"|
kr||" d ||#f q|! D ]4\}"}#|
d u sx|"|
kr\||" d ||#f q\qqLg g dg g dd}$t|j\}%}&| D ]\}'}"|$ D ]\}(})|"|( D ]n\}}#|&|'|'}*|#jD ]$}+|)d ||t
|+j |*f q|#jD ]$}+|)d |t
|+j ||*f q*qqԐq| ||dkr(| |||}ddd},|$ D ]\}(})|) D ]\}-}.tt }/|.D ]\}0}1}"|/|" |0|1f q|/ D ]@\}"}2t!d |2||||t"d}3d|,|- |" |3f }3| #|3| qڐqqd S g }4g }5g }6t }7i }8t }9|$ D ]\}(}:|: D ]\}-}.|.D ]\}0}1}"|8$|"t%|"|-f};|(dkrd nd!}<|-dkrd"nd#}=|7&|0 |7&|1 |6|0|1f |4|; d$|<|=f }>|5|> |9&|"d%|-'  |;|>f qhq\qLg }?|rht(|9D ].\}"}-};}<|?d&d'|;|<f d(|"|-f f q$|?d) |?d* t)|7|6d|4|5||?d+}3|d,kr| *|3| n| #|3| d S )-NTr3   c                   S   s   t tS )N)r   listr2   r2   r2   r:   <lambda>       zcmd_reps.run.<locals>.<lambda>)readonlydNSHostNamescopeattrsr   z$Attempting to contact ldap://%s (%s)r>   	ldap://%s Could not contact ldap://%s (%s))Zforced_local_dsazfound extra DSAs:z   %sz(missing DSAs (known locally, not by %s):Zothersr7   CN=NTDS Settings,currentneeded)tofrom)r   r   r   r   r%   zRepsFrom objects for %szRepsTo objects for %s)r   r   )rt   colourshorten_namesgenerate_keygrouping_functionz
%s
%sZdottedZsolidrH   emptyzstyle="%s"; arrowhead=%sZrepsFzcolor="%s"; %sz%s %s)Fz style="dotted"; arrowhead="open"zrepsFromTo is needed)Fzstyle="solid"; arrowhead="open"zrepsFromTo currently exists)directededge_colorsedge_stylesr   	key_itemsr-   )+r5   r6   r   unix_nowr   r9   r   r   rl   r   r]   rD   sysstderrZ
load_samdbr   runsetZ	list_dsasZget_dsaZtranslate_ntdsconnZdsa_guidZget_rep_tablesitemsappendr   rU   Zrep_repsFromZsource_dsa_obj_guidZ
rep_repsTorS   ra   r   r   rp   rK   
setdefaultr|   addtitlesortedr   rX   )@r7   r   rR   r   r+   talk_to_remoter/   r1   r0   mode	partitionr_   r`   rt   r$   r-   r4   r8   	local_kccdsasr   Znc_repsZguid_to_dnstrdsa_dnZkccresdns_nameeZdsas_from_hereZdsaZ	remote_dnZ
remote_dsar{   npartZrepZ	all_edgesshort_partitionslong_partitionsZpartnamestateZ	edgelistsZ
short_namerZheader_strings	directionr   Z
part_edgessrcr"   edgesrL   edge_coloursr   	dot_edgesZdot_verticesZused_coloursZkey_setZedgelistr   Z	linestyleZarrowstyler   r2   r2   r:   r      s"   
"

 











zcmd_reps.run)NNFTFNNNr7   NNNNNF)	rb   rc   rd   re   rg   rh   r	   ri   r   r2   r2   r2   r:   r}      s        r}   c                   @   s    e Zd ZdZdd Zdd ZdS )NTDSConnzXCollects observation counts for NTDS connections, so we know
    whether all DSAs agree.c                 C   s"   d| _ d| _d| _|| _|| _d S )Nr   F)observationssrc_attestsdest_attestsr   r"   )r7   r   r"   r2   r2   r:   __init__  s
    zNTDSConn.__init__c                 C   s2   |  j d7  _ || jkrd| _|| jkr.d| _d S )Nrj   T)r   r   r   r"   r   )r7   attesterr2   r2   r:   attest  s
    

zNTDSConn.attestN)rb   rc   rd   re   r   r   r2   r2   r2   r:   r     s   r   c                   @   s:   e Zd ZdZee eddddg Zdd Zdd
dZ	dS )cmd_ntdsconnzDraw the NTDSConnection graphz--importldifz#graph from samba_kcc generated ldifNr   c                 C   s2   t jdd}tj|d}|| _t|||}|S )Nr@   )rA   zimported.ldb)rG   ZmkdtemprI   pathjoin_tmp_fn_to_deleter   Zldif_to_samdb)r7   Zldifr4   drM   r9   r2   r2   r:   import_ldif_db  s
    zcmd_ntdsconn.import_ldif_dbFTc           ;      C   s|  |  }|d u r |j|dd}nd }| ||}t|||\}}|jddd }t }g }|D ]T}|r|jj|t	dgd}|d d d }z| 
d| ||}W nF ty } z.td	||f tjd
 W Y d }~q`W Y d }~n
d }~0 0 | }| }n| 
|||}d| }|}|j|t	dgd}|d d d dk}|||rNdndf |j|tddgdgd}|D ]B}t|j}||dd d  } |t|d d | |f qrq`|r|| jkrt| ttj| i }!|D ]B\}"}#}$|"|#f}%|%|!v r|!|% }nt|% }||!|%< ||$ qtt | \}}&| !||dkr| "|	|
|}
t#|
 }'|'$dd}(|'$dd})g }*d|&v r|*d |s|!% }+d| },ng }+g }-g }.g }/|!& D ]N\}}0|0j'r|+| |0j(s|-| n|0j(r|.| n
|/| qd},|/rH|*d |/D ]}|*d|  q2|.rr|*d |.D ]}|*d|  q\|-r|*d |-D ]}|*d|  qt)||+||
||t*|&d}1d+|*}*|*rd|(|)|*f }*| ,d |,|1|*f | d S g }2g }3g }4g }5t-|}6t |!& D ]\}%}|2|% |j.|6ks4|sJ|3d! |4d nd|j'r||4d |j(rp|3d" n
|3d# n2|j(r|3d$ |4d% n|3d$ |4d& qg }7|r"|7d' d(D ](\}8}9|8|3v r|7d)d*|8 |9f qd+D ](\}:}9|:|4v r|7d)d,|: |9f q|r.d-},nd| },t/t ||2d|,|3|5|4||7d.	}1|d/krl| 0|1| n| ,|1| d S )0NTr3   ,rj   r   r   r   r   r   r>   r   zmsDS-isRODCZTRUEZRODCrZ   z(objectClass=nTDSConnection)Z
fromServerzsearch_options:0:2)r   Z
expressionr   Zcontrolsr%   headerresetz/No outbound connections are expected from RODCszNTDS Connections known to %sz-NTDS Connections known to each destination DCzTThe following connections are alleged by DCs other than the source and destination:
z  %s -> %s
zbThe following connections are alleged by DCs other than the destination but including the source:
zRThe following connections (included in the chart) are not known to the source DC:
)rt   r   r   r   r   Zrow_commentsz
%sNOTES%s
%sz

%s

%s
%sz#000000#0000ff#cc00ffz#ff0000style=dashedstyle=dotted)Fzcolor="#000000"zNTDS Connection))r   zmissing from some DCs)r   zmissing from source DCFz
color="%s"))r   zunknown to destination)r   z!unknown to source and destinationzcolor="#ff0000; %s"zNTDS Connections)r   r   r   edge_labelsr   r   r   r-   )1r5   r6   r   r   Zmy_dsa_dnstrsplitr   r9   rl   r   r;   r   rD   r   r   Zget_dsServiceNameZ	domain_dnr   r   r]   rn   indexr   r   rI   rW   rmdirr   dirnamer   r   zipr   rS   ra   r   rU   keysr   r   r   r   rr   r   rK   lenr   r   rX   );r7   r   rR   r   r+   r   r/   r1   r0   r_   r`   rt   r$   
importldifr-   r4   r8   r   r   Zlocal_dsa_dnZverticesZattested_edgesr   r   r   r9   r   Zntds_dnrn   Zis_rodcmsgZmsgdnZdest_dnr   r   r"   r   kZrodc_statusZcoloursZc_headerZc_resetZepilogZgraph_edgesr   Zsource_deniesZdest_deniesZ	both_denyZconnrL   r   r   r   r   Z	n_serversr   r   Zdescr   r2   r2   r:   r     sN   
"
	





















	
zcmd_ntdsconn.run)NNFTFNNNNNNNNF)
rb   rc   rd   re   rg   rh   r	   ri   r   r   r2   r2   r2   r:   r     s         r   c                   @   s>   e Zd ZdZeedddddedded	d
g ZdddZdS )cmd_uptodatenesszvisualize uptodateness vectorsr~   r   r   Nr   z--max-digits   z,display this many digits of out-of-date-ness)r#   r    r   FTc                 C   s  |st d| jd d S | }|j|dd}t|||\}}|j| _t| j|}t| j\}}| |	|
|}
|	 D ]\}}||d fvrqtt
|||||}t||}t|}t|tt|}|dk rd}d| }t|||
||t||ddd	
}| d
||f | qtd S )Nz>this won't work without talking to the remote servers (use -r)r>   Tr3   rj   
   ZDCzout-of-date-ness)	rt   r   r   r   r   Zcolour_scaledigitsZylabelZxlabelz
%s

%s)rD   rE   r5   r6   r   r9   r   r   ra   r   r   r   r   minr   r]   r   rp   rK   )r7   r   rR   r   r+   r   r/   r1   r0   r_   r`   rt   r$   r   r-   r   Z
max_digitsr4   r8   r   r   r   r   Z	part_nameZpart_dnZ
utdv_edgesZ	distancesZmax_distancer   Zc_scalerL   r2   r2   r:   r     sJ    
zcmd_uptodateness.run)NNFTFNNNNNFNNFNr   )	rb   rc   rd   re   rg   r	   ry   ri   r   r2   r2   r2   r:   r     s          r   c                   @   sD   e Zd ZdZi Ze  D ]$\ZZe	dre eedd < qdS )cmd_visualizez:Produces graphical representations of Samba network state.Zcmd_   N)
rb   rc   rd   re   Zsubcommandsglobalsr   r   v
startswithr2   r2   r2   r:   r     s
   
r   )@Z
__future__r   rI   r   collectionsr   rV   rG   Zsamba.getoptZgetoptrf   Zsambar   r   Zsamba.netcmdr   r   r   r	   Zsamba.samdbr
   Zsamba.graphr   r   r   r   Zldbr   r   r   timerk   Z	samba.kccr   r   Zsamba.kcc.kcc_utilsr   Zsamba.compatr   Zsamba.uptodatenessr   r   r   r   r   r   r   r   r]   r   r   rg   rh   rF   r.   rp   rr   r|   r}   objectr   r   r   r   r2   r2   r2   r:   <module>   s   (
^
 5 p?