XcA@sdZddkZddkZddkZddklZddkZddklZl Z l Z ddkl Z l Z l Z ddklZlZlZddklZddklZlZdd klZdd klZdd klZlZdd klZlZed dededdededdededdededdededdededdededdededdeded dd!ed"ded#ed$ded%ed&dd'ed(ded)ed*ded+ed,ded-ed.ded/ed0ded1ed2dd3ed4ded5ed6ded7ed8dd9ed:dd;ed<dd=ed>dd?ed@dedAedBdedCedDdedEedFdedGedHdedIedJdedKedLdedMedNdedOedPdedQedRddSedTddUedVddWedXddYedZdd[ed\dd]ed^ded_ed`dedaedbdedcedddedeedfdedgdhdigedjdedkedldedmf/ZdnZ doZ!dpZ"dqZ#e$drZ%dsZ&e'dtZ(duZ)dvZ*edwe*dedxdhdygZ+dzZ,d{Z-d|Z.d}Z/d~e fdYZ0dZ1dZ2dZ3de fdYZ4de4e fdYZ5de5e i6fdYZ7de5e i8fdYZ9de9fdYZ:de9fdYZ;de9e i<fdYZ=de:fdYZ>de9fdYZ?de?fdYZ@de?fdYZAdZBde5e iCfdYZDde9fdYZEdeEfdYZFdeEfdYZGdS(s Base classes for LDAP plugins. iN(tdeepcopy(tapitcrudterrors(tMethodtObjecttCommand(tFlagtInttStr(t NameSpace(tto_clitfrom_cli(toutput(t_(tjson_serializetvalidate_hostname(tDNtRDNt has_passwordtlabeltPasswordtmembersFailed memberss member_user?s Member userss member_group?s Member groupssmemberof_group?sMember of groupss member_host?s Member hostssmember_hostgroup?sMember host-groupssmemberof_hostgroup?sMember of host-groupssmemberof_permission?t Permissionssmemberof_privilege?t Privilegessmemberof_role?tRolessmemberof_sudocmdgroup?sSudo Command Groupssmember_privilege?sGranted to Privileges member_role?sGranting privilege to rolessmember_netgroup?sMember netgroupssmemberof_netgroup?sMember of netgroupssmember_service?sMember servicessmember_servicegroup?sMember service groupssmemberof_servicegroup?sMember of service groupssmember_hbacsvc?sMember HBAC servicesmember_hbacsvcgroup?sMember HBAC service groupssmemberof_hbacsvcgroup?sMember of HBAC service groupssmember_sudocmd?sMember Sudo commandssmemberof_sudorule?sMember of Sudo rulesmemberof_hbacrule?sMember of HBAC rulesmemberindirect_user?sIndirect Member userssmemberindirect_group?sIndirect Member groupssmemberindirect_host?sIndirect Member hostssmemberindirect_hostgroup?sIndirect Member host-groupssmemberindirect_role?sIndirect Member of rolessmemberindirect_permission?sIndirect Member permissionssmemberindirect_hbacsvc?sIndirect Member HBAC servicesmemberindirect_hbacsvcgrp?s"Indirect Member HBAC service groupsmemberindirect_netgroup?sIndirect Member netgroupssmemberofindirect_group?sIndirect Member of groupsmemberofindirect_netgroup?sIndirect Member of netgroupsmemberofindirect_hostgroup?sIndirect Member of host-groupsmemberofindirect_role?sIndirect Member of rolesmemberofindirect_sudorule?sIndirect Member of Sudo rulesmemberofindirect_hbacrule?sIndirect Member of HBAC rulet sourcehostsFailed source hosts/hostgroupst memberhostsFailed hosts/hostgroupst memberusersFailed users/groupst memberservicesFailed service/service groupstfailedsFailed to removetflagstsuppress_emptyt ipasudorunass Failed RunAstipasudorunasgroupsFailed RunAsGroupcCst|d|dS(Ntaddattr(tvalidate_attribute(tugettexttattr((s;/usr/lib/python2.6/site-packages/ipalib/plugins/baseldap.pytvalidate_add_attributescCst|d|dS(Ntsetattr(R$(R%R&((s;/usr/lib/python2.6/site-packages/ipalib/plugins/baseldap.pytvalidate_set_attributescCst|d|dS(Ntdelattr(R$(R%R&((s;/usr/lib/python2.6/site-packages/ipalib/plugins/baseldap.pytvalidate_del_attributescCsYtid|}| pt|idjo"tid|dtdndS(Ns\s*(.*?)\s*=\s*(.*?)\s*$itnameterrors$Invalid format. Should be name=value(tretmatchtlentgroupsRtValidationErrorR(R%R,R&tm((s;/usr/lib/python2.6/site-packages/ipalib/plugins/baseldap.pyR$s! cCst|tpt|djodddg}n|i||}h}d|djoa|dd}|did}x=|D]1}|id\}}|||ii/s(RORPt get_entryR9tlistttupletmapR?(R@RAR&tvalueRVRWtvalues((s;/usr/lib/python2.6/site-packages/ipalib/plugins/baseldap.pytwait_for_values      c Cs=yt|dtdtWntj o}t|SXdS(Nt check_fqdntallow_underscore(RtFalsetTruet ValueErrortunicode(R%thostnameRK((s;/usr/lib/python2.6/site-packages/ipalib/plugins/baseldap.pytvalidate_externalhost9ss externalhost*s External hostt no_optionc Cst|tptd}|i|o|djo |}nti|i}x||D]v}y||Wqbtij o$}tid|d|i qbt j o!}tid|d|qbXqbWn|S(s Pre callback to validate external members. This should be called by a command pre callback directly. membertype is the type of member cSst|dtdtdS(NRbRc(RRdRe(Rh((s;/usr/lib/python2.6/site-packages/ipalib/plugins/baseldap.pyt validate_hostQsthostR,R-( R9RR:tgetRRt primary_keyRR2R-Rf( t membertypeR@RARHtoptionsRkt validatorR_RK((s;/usr/lib/python2.6/site-packages/ipalib/plugins/baseldap.pytadd_external_pre_callbackFs    %c Osbt|tptd} | idt} ||jo|||jo|i||g\}} t|tpt|i|g} | i|g}td|D}g}x7|||D]'}|di}ti |i |}t|tpt||joQ|| joD| o|i |n|i |d|i || d7} q||jol|| jo_t tii}|d|f}|||i|}|||||<|i |q|i |qW| oPy|i|h||6Wntij onX||||<|||vs i(R9RR:RmReR[tsetR?RRtget_dntappendtaddRgRtAlreadyGroupMembertmessagetindext update_entryt EmptyModlist(t memberattrRot externalattrR@RRRRARWRHRptcompleted_externalt normalizet entry_attrs_tmemberstexternal_entriestlc_external_entriestfailed_entriesRIt membernamet member_dntmsgtnewerrortind((s;/usr/lib/python2.6/site-packages/ipalib/plugins/baseldap.pytadd_external_post_callbackbsL      c Osqt|tpt||jo?|||jo.|i||g\}} | i|g} g} d} x|||D]}|di}|| jp|d| joFy| i|Wn$tj o| i|dnX| d7} q}| i|q}W| oPy|i |h| |6Wnt i j onX| |||<| |||s Rniitaciattrstmethods(Rtdicttjson_friendly_attributesRnR,RRtget_ipa_configRmtpossible_objectclassesRtBackendRtschematattribute_typest iteritemsRwtnamesR?tsortR( RR@t json_dictt objectclassestconfigRBtattrlisttoidR&t_[1]R3((Rs;/usr/lib/python2.6/site-packages/ipalib/plugins/baseldap.pyt__json__ys.         (N(RRR(s Member OfRR(sIndirect MemberNR(sIndirect Member OfNR(s parent_objects container_dns object_namesobject_name_plurals object_classsobject_class_configsdefault_attributesslabelslabel_singularshidden_attributessuuid_attributesattribute_memberssnameRs rdn_attributesbindables relationships(/t__name__t __module__t__doc__t backend_nameRRRet normalize_dnRRRRR;RRtlimit_object_classestdisallow_object_classestsearch_attributestsearch_attributes_configRtsearch_display_attributesRRRRRdtrdn_is_primary_keyRRRRRtcontainer_not_found_msgtparent_not_found_msgRRRvRRRRRRRRRR(((s;/usr/lib/python2.6/site-packages/ipalib/plugins/baseldap.pyRs`                 cCsxy|iD]k\}}t|ttfoIt|djo6||jo%||i otid|qxq q WdS(NiR&(RR9R\R]R0t multivalueRtOnlyOneValueAllowed(tparamsRWRRG((s;/usr/lib/python2.6/site-packages/ipalib/plugins/baseldap.pyt_check_single_value_attrss  )cCsx|iD]q\}}|djp#t|toHt|djo5||jo$||iotid|q~q q WdS(NiR,(RR;R9t basestringR0RRtRequirementError(RRWRRG((s;/usr/lib/python2.6/site-packages/ipalib/plugins/baseldap.pyt_check_empty_attrss  0c Cst|ddjot|ddjodSt|}x|diD]\}}|idi|jo[|p6tidtdtd|idin|i |idiqPqPWx|diD]\}}|idi|jo[|p6tidtdtd|idin|i |idiqqWt|djo4|o-tidtdtd|dndS(s+ If the set of objectclasses is limited enforce that only those are updated in entry_attrs (plus dn) allow_only tells us what mode to check in: If True then we enforce that the attributes must be in the list of allowed. If False then those attributes are not allowed. iiNtinfos%attribute "%(attribute)s" not allowedt attribute( R0RRRR?RtObjectclassViolationRRR(t attributesRBt allow_onlyt limitattrsRR&((s;/usr/lib/python2.6/site-packages/ipalib/plugins/baseldap.pyt_check_limit_object_classs. .   "  " tCallbackInterfacecBs8eZdZeZedZeedZRS(sCallback registration interface This class's subclasses allow different types of callbacks to be added and removed to them. Registering a callback is done either by ``register_callback``, or by defining a ``_callback`` method. Subclasses should define the `_callback_registry` attribute as a dictionary mapping allowed callback types to (initially) empty dictionaries. ccss|i|i|dg}xP|D]H}|djo0yt|d|VWqktj oqkXq#|Vq#WdS(s!Yield callbacks of the given types %s_callbackN(t_callback_registryRmR;RtAttributeError(tclst callback_typet callbackstcallback((s;/usr/lib/python2.6/site-packages/ipalib/plugins/baseldap.pyt get_callbackss  cCst|pty|i||}Wn+tj odg}|i||_s R(R#R*NR&R_Rcssx|]}|iVqWdS(N(R?(Rttn((s;/usr/lib/python2.6/site-packages/ipalib/plugins/baseldap.pys s R,R-sNo such attribute on this entryii(ssetattrsaddattrsdelattr('tallR(RR,RmRuRHR;R9RR:R\RRR]textendRRfRtAttrValueNotFoundt _exc_wrapperR[RRRR2tpopRR&Rgtbase64t b64encodeRR RR0RR-tConversionError(RRWRARHRpR@tadddicttsetdicttdeldicttsetattrstaddattrstdelattrst direct_addt direct_delt needldapattrsR&tvaltdelvalt old_entryRtdel_nonexistingt changedattrstparamR_terrR((Rps;/usr/lib/python2.6/site-packages/ipalib/plugins/baseldap.pytprocess_attr_optionsFs         %" !)!     @ 1cCs|id||dS(s*Shortcut for register_callback('pre', ...)R!N(R(RRR((s;/usr/lib/python2.6/site-packages/ipalib/plugins/baseldap.pytregister_pre_callbackscCs|id||dS(s+Shortcut for register_callback('post', ...)R"N(R(RRR((s;/usr/lib/python2.6/site-packages/ipalib/plugins/baseldap.pytregister_post_callbackscCs|id||dS(s*Shortcut for register_callback('exc', ...)R#N(R(RRR((s;/usr/lib/python2.6/site-packages/ipalib/plugins/baseldap.pytregister_exc_callbackscCs|id||dS(s9Shortcut for register_callback('interactive_prompt', ...)R$N(R(RRR((s;/usr/lib/python2.6/site-packages/ipalib/plugins/baseldap.pyt$register_interactive_prompt_callbackscsfd}|S(s=Function wrapper that automatically calls exception callbackscs}tid}xytoqy|||SWqtij oJ|pn|idfd}|}qXqWdS(NR#ics||S(N((targsR(RKRHRRt call_funcRp(s;/usr/lib/python2.6/site-packages/ipalib/plugins/baseldap.pytexc_funcs(R\RReRtExecutionErrorR2(t call_argst call_kwargstfuncRRM(RHRRLRp(RKRs;/usr/lib/python2.6/site-packages/ipalib/plugins/baseldap.pytwrappeds((RRHRpRLRR((RHRRLRps;/usr/lib/python2.6/site-packages/ipalib/plugins/baseldap.pyR1sc csx"tt|iD] }|VqW|iiobx_|iD]P}t|titi fo.t ddt ddddddgVPq<q<WndS( Nt no_membersRs-Suppress processing of membership attributes.RR RRjt no_output( tsuperRt get_optionsR(Rt has_outputR9R Rt ListOfEntriesRR(RRDto((s;/usr/lib/python2.6/site-packages/ipalib/plugins/baseldap.pyRVs     (RRRR R)Rtsetattr_optionR'taddattr_optionR+tdelattr_optionRRR,RFRRdRGRHRIRJR1RV(((s;/usr/lib/python2.6/site-packages/ipalib/plugins/baseldap.pyRs:         ! ,  t LDAPCreatecBskeZdZeieifZdZeZ dZ dZ dZ dZ dZd ZdZRS( s% Create a new entry in LDAP. ccssx|iiD] }|VqW|iio|iiidtVnx%tti|iD] }|Vq`WdS(NR ( R(RRntcloneReRURtCreatetget_args(RRtarg((s;/usr/lib/python2.6/site-packages/ipalib/plugins/baseldap.pyR`s  c OsU|ii}|i||}|i|d||t|ii|d<|iio4|id}|i |ii|d|ds t takes_options(RRR\tget_json_options(RR((Rs;/usr/lib/python2.6/site-packages/ipalib/plugins/baseldap.pyRs(Rr(RRRRRZR[RsR`tglobal_output_paramsthas_output_paramsRlRmRnRoRqRR(((s;/usr/lib/python2.6/site-packages/ipalib/plugins/baseldap.pyR]s  c    t LDAPQuerycBs&eZdZdZdZdZRS(sJ Base class for commands that need to retrieve an existing entry. ccsyx|iiD] }|VqW|iio!|iiidtdtVnx%tti|iD] }|VqfWdS(NR R( R(RRnR^ReRURtPKQueryR`(RRRa((s;/usr/lib/python2.6/site-packages/ipalib/plugins/baseldap.pyR`s  !Rrcs9tfdiD}ti|d<|S(Nc3s(x!|]}|t|fVqWdS(N(R(RtR(R(s;/usr/lib/python2.6/site-packages/ipalib/plugins/baseldap.pys s Rs(RRR\Rt(RR((Rs;/usr/lib/python2.6/site-packages/ipalib/plugins/baseldap.pyRs(s takes_args(RRRR`RR(((s;/usr/lib/python2.6/site-packages/ipalib/plugins/baseldap.pyRws tLDAPMultiQuerycBs8eZdZeddddedfZdZRS(sU Base class for commands that need to retrieve one or more existing entries. tcontinueRRs&Continuous mode: Don't stop on errors.c csx|iiD] }|VqW|iio'|iiidtdtdtVnx%tti|iD] }|VqlWdS(NR RR( R(RRnR^ReRURRxR`(RRRa((s;/usr/lib/python2.6/site-packages/ipalib/plugins/baseldap.pyR`s  (RRRRRRsR`(((s;/usr/lib/python2.6/site-packages/ipalib/plugins/baseldap.pyRys  t LDAPRetrievecBsqeZdZeiZeZedde dde dfZ dZ dZ dZ d Zd ZRS( s! Retrieve an LDAP entry. RCRtRightsRsWDisplay the access rights of this entry (requires --all). See ipa man page for details.c Osv|ii}|ii||}t|tpt|idtodg|ii}nIt |ii}|idto|i |ii nt |}xI|i dD]8}|||||||}t|tptqWyN|i|||i||d|ii\}}t|tptWn&tij o|ii|nX|idto*|idtot|||d  & cOst|tpt|S(N(R9RR:(RR@RARkRHRp((s;/usr/lib/python2.6/site-packages/ipalib/plugins/baseldap.pyRmscOst|tpt|S(N(R9RR:(RR@RARWRHRp((s;/usr/lib/python2.6/site-packages/ipalib/plugins/baseldap.pyRnscOs |dS(N((RRHRpR#RLRORP((s;/usr/lib/python2.6/site-packages/ipalib/plugins/baseldap.pyRoscCsdS(N((RRp((s;/usr/lib/python2.6/site-packages/ipalib/plugins/baseldap.pyRqs(RRRR tstandard_entryRWRuRvRRRsRlRmRnRoRq(((s;/usr/lib/python2.6/site-packages/ipalib/plugins/baseldap.pyR{s    (   t LDAPUpdatec BseZdZeieieieddeddedfZ e Z dZ dZ dZd Zd Zd Zd ZRS( s Update an LDAP entry. RCRR|RsWDisplay the access rights of this entry (requires --all). See ipa man page for details.c Csbt|ii|iii}|iddddtdtddtdtd|ii S( NtrenameRRRtRenameRs#Rename the %(ldap_obj_name)s objectR( RR(RRnR,t clone_renameRdRRR(Rtrdnparam((s;/usr/lib/python2.6/site-packages/ipalib/plugins/baseldap.pyt_get_rename_options  ccsEx"tt|iD] }|VqW|iio|iVndS(N(RUR~RVR(RR(Rtoption((s;/usr/lib/python2.6/site-packages/ipalib/plugins/baseldap.pyRVs   c Os|ii}t|djotin|ii||}t|tpt|i |}|i |||||i dt odg|ii }n\t|ii }|i|i|i dt o|i|iint|}t|i|t|ii|xL|idD];}||||||||}t|tptq8Wt|iiiii|ii|idtt|iiiii|ii |idt t }yq|ii!oOd|joB|dpti"ddd d n|d||ii#i$s   '         '  "' cOs$t|tpt|||fS(N(R9RR:(RR@tfiltersRkRRRKRp((s;/usr/lib/python2.6/site-packages/ipalib/plugins/baseldap.pyRmscOs|S(N((RR@RRRKRp((s;/usr/lib/python2.6/site-packages/ipalib/plugins/baseldap.pyRnscOs |dS(N((RRKRpR#RLRORP((s;/usr/lib/python2.6/site-packages/ipalib/plugins/baseldap.pyRoscCsdS(N((RRp((s;/usr/lib/python2.6/site-packages/ipalib/plugins/baseldap.pyRqsRrcs9tfdiD}ti|d<|S(Nc3s(x!|]}|t|fVqWdS(N(R(RtR(R(s;/usr/lib/python2.6/site-packages/ipalib/plugins/baseldap.pys s Rs(RRR\Rt(RR((Rs;/usr/lib/python2.6/site-packages/ipalib/plugins/baseldap.pyRs(s takes_args(RRRRRRRReRRRdRsR`RRVRRuRvRlRmRnRoRqRR(((s;/usr/lib/python2.6/site-packages/ipalib/plugins/baseldap.pyRs:              ]    tLDAPModReverseMembercBs8eZdZdgZedZdZeZdZ RS(s5 Base class for reverse member manipulation. Rscomma-separated list of %ss%i member processed.s%i members processed.ccsx"tt|iD] }|VqWx|iD]}xx|ii|D]f}|ii|}t|}|i |i }t d|dd|d|d|i dt dt VqFWq/WdS(Ns%s*Rs%ssRRRR(RURRVtreverse_attributesR(treverse_membersRRR treverse_param_docRR RRe(RRR&RRR,R((s;/usr/lib/python2.6/site-packages/ipalib/plugins/baseldap.pyRVs   (s%i member processed.s%i members processed.( RRRRRRtreverse_count_outRuRvRV(((s;/usr/lib/python2.6/site-packages/ipalib/plugins/baseldap.pyRs   tLDAPAddReverseMemberc BseZdZedZdZdZdZdZ dZ e i de i ddedede i d deded fZeZd Zd Zd ZdZdZRS(s Add other LDAP entries to members in reverse. The call looks like "add A to B" but in fact executes add B to A to handle reverse membership. s!comma-separated list of %s to adds%i member added.s%i members added.RMRR%RsMembers that could not be addedRRsNumber of members addedcOs|ii}|ii|i|dd}|d}t|tptxF|idD]5}||||||}t|tptq^W|i dt odg|ii }nIt |ii }|i dt o|i |iint|}|ii|i|dd}d} hhg|i6d 6} xh|i |ipgD]M} yh|dd |i6}y|i|||ii|i| |}|d d jo| d } n6| d |ii| |d d |idd fWnftij oW} t| } | idd \} } | d |ii| t| ifnXWqatij o-} | d |ii| t| fqaXqaWy"t||| |idt}Wn9tj o-} tidt ddt| nXxU|idD]D}|||| | ||||\} }t|tptq Wt|tpt||dRRXRet ExceptiontReverseMemberErrorRR(RRHRpR@RMRARRkRQRRRR&RKRRW((s;/usr/lib/python2.6/site-packages/ipalib/plugins/baseldap.pyRls` !  !+9 3-") cOst|tpt|S(N(R9RR:(RR@RARHRp((s;/usr/lib/python2.6/site-packages/ipalib/plugins/baseldap.pyRm&scOs!t|tpt||fS(N(R9RR:(RR@RRRRARWRHRp((s;/usr/lib/python2.6/site-packages/ipalib/plugins/baseldap.pyRn*scOs |dS(N((RRHRpR#RLRORP((s;/usr/lib/python2.6/site-packages/ipalib/plugins/baseldap.pyRo.scCsdS(N((RRp((s;/usr/lib/python2.6/site-packages/ipalib/plugins/baseldap.pyRq1s(s%i member added.s%i members added.N(RRRRRRR;RSRRRR RRRRRWRuRvRlRmRnRoRq(((s;/usr/lib/python2.6/site-packages/ipalib/plugins/baseldap.pyRs(      >   tLDAPRemoveReverseMemberc BseZdZedZdZdZdZdZ dZ e i de i ddedede i d deded fZeZd Zd Zd ZdZdZRS(s Remove other LDAP entries from members in reverse. The call looks like "remove A from B" but in fact executes remove B from A to handle reverse membership. s$comma-separated list of %s to removes%i member removed.s%i members removed.RMRR%Rs!Members that could not be removedRRsNumber of members removedcOs|ii}|ii|i|dd}|d}t|tptxF|idD]5}||||||}t|tptq^W|i dt odg|ii }nIt |ii }|i dt o|i |iint|}|ii|i|dd}d} hhg|i6d 6} xh|i |ipgD]M} yh|dd |i6}y|i|||ii|i| |}|d d jo| d } n6| d |ii| |d d |idd fWnftij oW} t| } | idd \} } | d |ii| t| ifnXWqatij o-} | d |ii| t| fqaXqaWy"t||| |idt }Wn9tj o-} tidtddt| nXxU|idD]D}|||| | ||||\} }t|tptq Wt|tpt||dRRXRRRR(RRHRpR@RMRARRkRQRRRR&RKRRW((s;/usr/lib/python2.6/site-packages/ipalib/plugins/baseldap.pyRlQs` !  !+9 3-") cOst|tpt|S(N(R9RR:(RR@RARHRp((s;/usr/lib/python2.6/site-packages/ipalib/plugins/baseldap.pyRmscOs!t|tpt||fS(N(R9RR:(RR@RRRRARWRHRp((s;/usr/lib/python2.6/site-packages/ipalib/plugins/baseldap.pyRnscOs |dS(N((RRHRpR#RLRORP((s;/usr/lib/python2.6/site-packages/ipalib/plugins/baseldap.pyRoscCsdS(N((RRp((s;/usr/lib/python2.6/site-packages/ipalib/plugins/baseldap.pyRqs(s%i member removed.s%i members removed.N(RRRRRRR;RSRRRR RRRRRWRuRvRlRmRnRoRq(((s;/usr/lib/python2.6/site-packages/ipalib/plugins/baseldap.pyR4s(      >   (HRR.tjsonROtcopyRR3tipalibRRRRRRRRR t ipalib.baseR t ipalib.cliR R R t ipalib.textRt ipalib.utilRRt ipapython.dnRRRuR'R)R+R$R;R<RLReRXRaRitexternal_host_paramRrRRRRRRRRRR_R]RxRwRyR{tUpdateR~RRRRRRRRRR(((s;/usr/lib/python2.6/site-packages/ipalib/plugins/baseldap.pyts"                                                                                            , #      9     %4EY+be i