a „oeÈJã@s€dZddlZddlZddlZddlZddlZddlZddlZddl Z ddl m Z ddl Tddl mZdadagZdaddlZeZd0d d „Zd1d d „Zd2dd„Zdd„Zdd„Zdd„ZGdd„dƒZefdd„Zdd„Zdd„Zdd„Zd d!„Z d"d#„Z!d$d%„Z"d&d'„Z#d efd efd(e fde!fd)e"fde#ffZ$Gd*d+„d+ej%ƒZ&d,d-„Z'e(d.k�r|z e'ƒWne)�yze*d/ƒYn0dS)3aÃA re-implementation of the MS DirectoryService samples related to services. * Adds and removes an ActiveDirectory "Service Connection Point", including managing the security on the object. * Creates and registers Service Principal Names. * Changes the username for a domain user. Some of these functions are likely to become move to a module - but there is also a little command-line-interface to try these functions out. For example: scp.py --account-name=domain\user --service-class=PythonScpTest \ --keyword=foo --keyword=bar --binding-string=bind_info \ ScpCreate SpnCreate SpnRegister would: * Attempt to delete a Service Connection Point for the service class 'PythonScpTest' * Attempt to create a Service Connection Point for that class, with 2 keywords and a binding string of 'bind_info' * Create a Service Principal Name for the service and register it to undo those changes, you could execute: scp.py --account-name=domain\user --service-class=PythonScpTest \ SpnCreate SpnUnregister ScpDelete which will: * Create a SPN * Unregister that SPN from the Active Directory. * Delete the Service Connection Point Executing with --test will create and remove one of everything. éN)Úadsi)Ú*)ÚDispatchéÚserviceConnectionPointÚAc CsÎ|p|}|st tj¡}|dur,t tj¡}t d|tj¡} |pDg}dt t |ffdt t |ffdt t |fdt t |ffdt t |ffdt t |ffdt t |ffg} |   d || ¡} t   d |¡t| ƒ} t|| ƒ| S) NúLDAP://ZcnZ objectClassÚkeywordsZserviceDnsNameZserviceDnsNameTypeZserviceClassNameZserviceBindingInformationúcn=zNew connection point is at %s)Úwin32apiZGetComputerNameExÚwin32conZComputerNameDnsFullyQualifiedÚGetComputerObjectNameÚNameFullyQualifiedDNrÚ ADsGetObjectÚIID_IDirectoryObjectZADS_ATTR_UPDATEZADSTYPE_CASE_IGNORE_STRINGZCreateDSObjectÚloggerÚinforÚAllowAccessToScpProperties) Zservice_binding_infoZservice_class_nameÚ account_nameÚcontainer_namer Z object_classZ dns_name_typeÚdnZdns_nameÚcompÚattrsÚnew©rú;C:\Program Files\Certbot\pkgs\win32comext\adsi\demos\scp.pyÚ ScpCreate?s@       üüüï  rcCsR|durt tj¡}t d||¡t d|tj¡}|  d|¡t  d|¡dS)Nz&Removing connection point '%s' from %srr z%Deleted service connection point '%s') r r r rrÚdebugrrrZDeleteDSObjectr)rrrrrrÚ ScpDeleteys  r©z&{28630eb8-41d5-11d1-a9c1-0000f80367c1}z&{b7b1311c-b82e-11d0-afee-0000f80367c1}c Csž|r |}n t tj¡}d}t||ƒ}|j}|D]@}ttjƒ}t t B|_ ||_ t |_d|_t|_||_| |¡q.||_t|||ƒ| ¡t d|f¡dS)NZnTSecurityDescriptorrz'Set security on object for account '%s')r r r ÚNameSamCompatibleÚgetattrZDiscretionaryAclrrZCLSID_AccessControlEntryZADS_RIGHT_DS_READ_PROPZADS_RIGHT_DS_WRITE_PROPZ AccessMaskZTrusteeZ!ADS_ACETYPE_ACCESS_ALLOWED_OBJECTZAceTypeZAceFlagsZADS_FLAG_OBJECT_TYPE_PRESENTZFlagsZ ObjectTypeZAddAceÚsetattrZSetInforr) Z accountSAMZ scpObjectZ schemaIDGUIDsZtrusteeZ attributeÚsdZaclZsguidZacerrrr•s&       rcCs®t|ƒttfvrt|dƒs&Jd|ƒ‚t tj¡}| dd¡d}|sRt tj ¡}t   d|¡t j |tjtjBtjBd�}t  |d¡}t   d ¡t  ||||¡| ¡dS) NÚ__iter__z+spns must be a sequence of strings (got %r)ú\rrzSpnRegister using DN '%s')Z domainNameÚflagsZDomainControllerNamezDsWriteAccountSpn with spns %s)ÚtypeÚstrÚhasattrr Z GetUserNameExr Úsplitr r rrrÚ win32securityZ DsGetDcNameÚdsconZDS_IS_FLAT_NAMEZDS_RETURN_DNS_NAMEZDS_DIRECTORY_SERVICE_REQUIREDZDsBindZDsWriteAccountSpnÚClose)Z serviceAcctDNÚspnsZ operationZsamNamerÚhandlerrrÚ SpnRegisterÙs2ÿ   ÿþþ ür0cCs$d|}t |tj¡}| |¡dS)Nr)rrZ IID_IADsUserZ SetPassword)Z username_dnZ new_passwordZ accountPathÚuserrrrÚUserChangePasswordsr2cGst|krt||ƒdS©N)ÚverboseÚprint)ÚlevelÚmsgÚargsrrrÚlog sr9c@s eZdZdS)Ú _NoDefaultN)Ú__name__Ú __module__Ú __qualname__rrrrr:sr:cCs:|\}}t|||ƒ}|s.|tur.| d|¡|s6|}|S)Nz4The '%s' option must be specified for this operation)r!r:Úerror)ÚpoZopt_nameÚdefaultÚparserÚoptionsÚretrrrÚ _get_options  rDcCs|d}| |¡dS)Nr)r>)r?ÚwhyrArrrÚ _option_error srFcCs6tt|dƒt|dƒt|ddƒt|ddƒd�}|a|jS)z!Create a Service Connection PointÚbinding_stringÚ service_classÚaccount_name_samNr )r )rrDÚ g_createdSCPÚdistinguishedName)r?ZscprrrÚ do_ScpCreate%s  ürLc Cs^t|dƒ}z t|ƒWnBtjyX}z(|dtjkr8‚tdd|ƒWYd}~n d}~00|S)z!Delete a Service Connection PointrHréz@ScpDelete ignoring ERROR_DS_OBJ_NOT_FOUND for service-class '%s'N)rDrrr>ÚwinerrorZERROR_DS_OBJ_NOT_FOUNDr9)r?ZscZdetailsrrrÚ do_ScpDelete2s  "rOc Cs^tdurt|dƒt tjt|dƒtjt|ddƒdd¡}|d}tdd|ƒ|a t   |¡|S)zCreate a Service Principal NameNz3ScpCreate must have been specified before SpnCreaterHÚportrrMzCreated SPN: %s) rJrFr+ZDsGetSpnr,ZDS_SPN_SERVICErDrKr9Úg_createdSPNLastÚ g_createdSPNsÚappend)r?r.ZspnrrrÚ do_SpnCreate>s  ú  rTcCs*tst|dƒtt|ddƒtftjƒtS)z4Register a previously created Service Principal Namez(SpnCreate must appear before SpnRegisterÚaccount_name_dnN)rQrFr0rDr,ZDS_SPN_ADD_SPN_OP©r?rrrÚdo_SpnRegisterUs  ýrWcCs*tst|dƒtt|ddƒtftjƒtS)z6Unregister a previously created Service Principal Namez*SpnCreate must appear before SpnUnregisterrUN)rQrFr0rDr,ZDS_SPN_DELETE_SPN_OPrVrrrÚdo_SpnUnregisterbs  ýrXcCstt|dƒt|dƒƒdS)z(Change the password for a specified userrUÚpasswordzPassword changed OK)r2rDrVrrrÚdo_UserChangePasswordnsrZZ SpnCreateZ SpnUnregisterc@seZdZdd„ZdS)Ú HelpFormattercCs|Sr3r)ÚselfÚ descriptionrrrÚformat_descriptionsz HelpFormatter.format_descriptionN)r;r<r=r^rrrrr[~sr[c Cs¨i}g}tD]<\}}d tj|jdd�¡}| d||f¡||| ¡<q tdd |¡d}tjd|t ƒd�}|j dd d d d d �|j ddddd�|j ddddd�f|j ddddd�|j dddd�|j ddddd�|j dd d!d�|j dd"d#d�|j dd$d%d�|j dd&d'd(d)d*�|j dd+d,t t j ƒd-�| ¡\}}||f} zt|jƒ|_Wn"ttf�y‚| d.¡Yn0zt|jƒ} WnVttf�yèzttt |j ¡ƒƒ} Wn$tttf�yâ| d/¡Yn0Yn0z tj} Wnt�yt  ¡j} Yn0| | ƒ|j�r6|j�r6| d0¡|j�rL|jd 8_|ja|j�rÚ|�rj| d1¡d2}td d3|ƒ| ¡}|j �sžd4|_ td5d6|j ƒ|j!�s¾d7 ¡|_!td5d8|j!ƒ|j"�sÚd9|_"td5d:|j"ƒ|�sê| d;¡|D]"}| ¡|v�rî| d<|¡�qî|j#�rptd5d=|j#ƒt$ %|j#t&j't&j(¡|_)td5d>|j)ƒt$ %|j#t&j't&j*¡|_+td5d?|j+ƒ|D�],}|| ¡} | du�rž| d@|¡d} zRz&td5dA|ƒ| | ƒ}td dB||ƒWn&|j,�rêt-dCƒt. /¡‚Yn0Wn–t0j�yT}zD|j1\}}}}|�r&|d5}nd}|} |�r@| dD|7} WYd}~n@d}~0t&j�yŠ}z|j1\}}}|} WYd}~n d}~00| �rttd dE|| ƒ�qtdS)FNÚ z )Úsubsequent_indentz %s: %sz commands: z%prog [options] command ...)Úusager]Ú formatterz-vÚcountr4rz)increase the verbosity of status messages)ÚactionÚdestr@Úhelpz-qz--quietÚ store_truezDon't print any status messages)rdrfz-tz--testzGExecute a mini-test suite, providing defaults for most options and argsÚz--show-tracebacksz&Show the tracebacks for any exceptionsz--service-classzThe service class name to use)rfz--portrz)The port number to associate with the SPN)r@rfz--binding-stringz*The binding string to use for SCP creationz--account-namez0The account name to use (default is LocalSystem)z --passwordzThe password to set.z --keywordrSr z[A keyword to add to the SCP. May be specified multiple times)rdrerfz --log-levelz`The log-level to use - may be a number or a logging module constant)rfr@z--port must be numericzInvalid --log-level valuez#Can't specify --quiet and --verbosezCan't specify args with --testzAScpDelete ScpCreate SpnCreate SpnRegister SpnUnregister ScpDeletez!--test - pretending args are: %sZ PythonScpTestrMz--test: --service-class=%szPython Poweredz--test: --keyword=%sztest binding stringz--test: --binding-string=%sz4No command specified (use --help for valid commands)z4Invalid command '%s' (use --help for valid commands)zTranslating account name '%s'zNameSamCompatible is '%s'zNameFullyQualifiedDNis '%s'zInvalid command '%s'zExecuting '%s'...z%s: %sz/--show-tracebacks specified - dumping exceptionz zCommand '%s' failed: %s)2ÚhandlersÚjoinÚtextwrapÚwrapÚ__doc__rSÚlowerÚoptparseZ OptionParserr[Z add_optionr(ÚloggingZWARNINGÚ parse_argsÚintrPÚ TypeErrorÚ ValueErrorr>Ú log_levelr!ÚupperÚAttributeErrorrZsetLevelZ getLoggerÚquietr4Útestr9r*rHr rGrr+Z TranslateNamer Z NameUnknownr rIrrUZshow_tracebacksr5Ú tracebackÚ print_excrr8)Z_handlers_dictZ arg_descsÚargÚfuncZ this_descr]rArBr8r?ruÚslZhandlerÚerr_msgÚresultZxxx_todo_changemeÚhrZdescÚexcZargerrZ extra_descZxxx_todo_changeme1r7rrrÚmainƒs ýûÿüüÿÿÿû û        ÿ ÿ        rƒÚ__main__z*** Interrupted)NNNrrNN)N)r)+rmrorkrzZ ntsecurityconr,r r r+rNZ win32com.adsirZwin32com.adsi.adsiconZwin32com.clientrr4rJrRrQrprrrrr0r2r9r:rDrFrLrOrTrWrXrZriZIndentedHelpFormatterr[rƒr;ÚKeyboardInterruptr5rrrrÚsn$   ÷ : ý D)      ú /