1616# You should have received a copy of the GNU General Public License
1717# along with this program. If not, see <http://www.gnu.org/licenses/>.
1818
19- import configparser
2019import os
2120import operator
2221import requests
2726from vendor_samba .gp .gpclass import get_dc_hostname
2827import base64
2928from shutil import which
30- from subprocess import Popen , PIPE , TimeoutExpired
29+ from subprocess import Popen , PIPE
3130import re
3231import json
3332from vendor_samba .gp .util .logging import log
@@ -55,8 +54,6 @@ def load_der_pkcs7_certificates(x): return []
5554 '/etc/pki/ca-trust/source/anchors' , # RHEL/Fedora
5655 '/usr/local/share/ca-certificates' ] # Debian/Ubuntu
5756
58- CEPCES_CONFIG_PATH = '/etc/cepces/cepces.conf'
59-
6057def octet_string_to_objectGUID (data ):
6158 """Convert an octet string to an objectGUID."""
6259 return '%s-%s-%s-%s-%s' % ('%02x' % struct .unpack ('<L' , data [0 :4 ])[0 ],
@@ -151,11 +148,10 @@ def fetch_certification_authorities(ldb):
151148 [MS-CAESO] 4.4.5.3.1.2
152149 """
153150 result = []
154- configdn = ldb .get_config_basedn ()
151+ basedn = ldb .get_default_basedn ()
155152 # Autoenrollment MUST do an LDAP search for the CA information
156153 # (pKIEnrollmentService) objects under the following container:
157- dn = 'CN=Enrollment Services,CN=Public Key Services,CN=Services,%s' % configdn
158-
154+ dn = 'CN=Enrollment Services,CN=Public Key Services,CN=Services,CN=Configuration,%s' % basedn
159155 attrs = ['cACertificate' , 'cn' , 'dNSHostName' ]
160156 expr = '(objectClass=pKIEnrollmentService)'
161157 res = ldb .search (dn , SCOPE_SUBTREE , expr , attrs )
@@ -172,8 +168,8 @@ def fetch_certification_authorities(ldb):
172168def fetch_template_attrs (ldb , name , attrs = None ):
173169 if attrs is None :
174170 attrs = ['msPKI-Minimal-Key-Size' ]
175- configdn = ldb .get_config_basedn ()
176- dn = 'CN=Certificate Templates,CN=Public Key Services,CN=Services,%s' % configdn
171+ basedn = ldb .get_default_basedn ()
172+ dn = 'CN=Certificate Templates,CN=Public Key Services,CN=Services,CN=Configuration, %s' % basedn
177173 expr = '(cn=%s)' % name
178174 res = ldb .search (dn , SCOPE_SUBTREE , expr , attrs )
179175 if len (res ) == 1 and 'msPKI-Minimal-Key-Size' in res [0 ]:
@@ -195,33 +191,14 @@ def get_supported_templates(server):
195191 log .error ('Failed to find cepces-submit' )
196192 return []
197193
198- cepces_config = configparser .ConfigParser ()
199- cepces_config .read (CEPCES_CONFIG_PATH )
200- # If the config file was overriden, then we let cepces-submit use the values defined there.
201- cepces_args = [cepces_submit , '--server=%s' % server , '--auth=Kerberos' ]
202- if cepces_config ['global' ] and cepces_config ['global' ]['server' ] != 'ca' :
203- log .debug (f'Changes detected in "{ CEPCES_CONFIG_PATH } ". Using the values defined there.' )
204- cepces_args = [cepces_submit ]
205-
206194 env = os .environ
207195 env ['CERTMONGER_OPERATION' ] = 'GET-SUPPORTED-TEMPLATES'
208- p = Popen (cepces_args , env = env , stdout = PIPE , stderr = PIPE )
209- out , err = bytes (), bytes ()
210- try :
211- # Server calls could hang if the provider is slow or too busy.
212- # A timeout is set to avoid this.
213- out , err = p .communicate (timeout = 3 )
214- except TimeoutExpired as te :
215- log .warn (f'GET-SUPPORTED-TEMPLATES expired. { server } is probably not a CEPCES server: { te } ' )
216- p .kill ()
217- except Exception as e :
218- log .error (f'Failed to fetch supported templates with command "{ cepces_args } ": { e } ' )
219- p .kill ()
220-
196+ p = Popen ([cepces_submit , '--server=%s' % server , '--auth=Kerberos' ],
197+ env = env , stdout = PIPE , stderr = PIPE )
198+ out , err = p .communicate ()
221199 if p .returncode != 0 :
222200 data = {'Error' : err .decode ()}
223201 log .error ('Failed to fetch the list of supported templates.' , data )
224- raise Exception (f'Failed to fetch the list of supported templates: { data } ' )
225202 return out .strip ().split ()
226203
227204
@@ -296,11 +273,11 @@ def changed(new_data, old_data):
296273def cert_enroll (ca , ldb , trust_dir , private_dir , auth = 'Kerberos' ):
297274 """Install the root certificate chain."""
298275 data = dict ({'files' : [], 'templates' : []}, ** ca )
276+ url = 'http://%s/CertSrv/mscep/mscep.dll/pkiclient.exe?' % ca ['hostname' ]
299277
300278 log .info ("Try to get root or server certificates" )
301- url = 'https://%s/CertSrv/mscep/mscep.dll/pkiclient.exe?' % ca ['hostname' ]
302- root_certs = getca (ca , url , trust_dir )
303279
280+ root_certs = getca (ca , url , trust_dir )
304281 data ['files' ].extend (root_certs )
305282 global_trust_dir = find_global_trust_dir ()
306283 for src in root_certs :
@@ -348,7 +325,6 @@ def cert_enroll(ca, ldb, trust_dir, private_dir, auth='Kerberos'):
348325 log .error ('Failed to add Certificate Authority' , data )
349326
350327 supported_templates = get_supported_templates (ca ['hostname' ])
351- log .debug (f"Supported templates for CA \" { ca ['name' ]} \" : { supported_templates } " )
352328 for template in supported_templates :
353329 attrs = fetch_template_attrs (ldb , template )
354330 nickname = '%s.%s' % (ca ['name' ], template .decode ())
@@ -368,11 +344,8 @@ def cert_enroll(ca, ldb, trust_dir, private_dir, auth='Kerberos'):
368344 data = {'Error' : err .decode (), 'Certificate' : nickname }
369345 log .error ('Failed to request certificate' , data )
370346
371- if data .get ('files' ) is not None :
372- data ['files' ].extend ([keyfile , certfile ])
373-
374- if data .get ('templates' ) is not None :
375- data ['templates' ].append (nickname )
347+ data ['files' ].extend ([keyfile , certfile ])
348+ data ['templates' ].append (nickname )
376349 if update is not None :
377350 ret = Popen ([update ]).wait ()
378351 if ret != 0 :
@@ -405,19 +378,8 @@ def apply(self, guid, ca, applier_func, *args, **kwargs):
405378 # If the policy has changed, unapply, then apply new policy
406379 old_val = self .cache_get_attribute_value (guid , attribute )
407380 old_data = json .loads (old_val ) if old_val is not None else {}
408-
409- templates = []
410- if old_val is not None :
411- supported_templates = []
412- try :
413- supported_templates = get_supported_templates (ca ['hostname' ])
414- except Exception as e :
415- raise e
416- log .debug (f"Supported templates for CA \" { ca ['name' ]} \" : { supported_templates } " )
417- for template in supported_templates :
418- formatted = '%s.%s' % (ca ['name' ], template .decode ())
419- templates .append (formatted )
420-
381+ templates = ['%s.%s' % (ca ['name' ], t .decode ()) for t in get_supported_templates (ca ['hostname' ])] \
382+ if old_val is not None else []
421383 new_data = { 'templates' : templates , ** ca }
422384 if changed (new_data , old_data ) or self .cache_get_apply_state () == GPOSTATE .ENFORCE :
423385 self .unapply (guid , attribute , old_val )
@@ -501,17 +463,15 @@ def __read_cep_data(self, guid, ldb, end_point_information,
501463 # If the current group contains a
502464 # CertificateEnrollmentPolicyEndPoint instance with EndPoint.URI
503465 # equal to "LDAP":
504- for e in end_point_group :
505- if e ['URL' ] != 'LDAP:' :
506- continue
466+ if any ([e ['URL' ] == 'LDAP:' for e in end_point_group ]):
507467 # Perform an LDAP search to read the value of the objectGuid
508468 # attribute of the root object of the forest root domain NC. If
509469 # any errors are encountered, continue with the next group.
510470 res = ldb .search ('' , SCOPE_BASE , '(objectClass=*)' ,
511- ['defaultNamingContext ' ])
471+ ['rootDomainNamingContext ' ])
512472 if len (res ) != 1 :
513473 continue
514- res2 = ldb .search (res [0 ]['defaultNamingContext ' ][0 ],
474+ res2 = ldb .search (res [0 ]['rootDomainNamingContext ' ][0 ],
515475 SCOPE_BASE , '(objectClass=*)' ,
516476 ['objectGUID' ])
517477 if len (res2 ) != 1 :
@@ -534,13 +494,9 @@ def __read_cep_data(self, guid, ldb, end_point_information,
534494 if ca ['URL' ] == 'LDAP:' :
535495 # This is a basic configuration.
536496 cas = fetch_certification_authorities (ldb )
537- log .debug (f'Fetched the following CAs: { cas } ' )
538497 for _ca in cas :
539- try :
540- self .apply (guid , _ca , cert_enroll , _ca , ldb , trust_dir , private_dir )
541- except Exception as e :
542- log .warn (f"Could not enroll to CA { _ca ['name' ]} : { e } " )
543- continue
498+ self .apply (guid , _ca , cert_enroll , _ca , ldb , trust_dir ,
499+ private_dir )
544500 ca_names .append (_ca ['name' ])
545501 # If EndPoint.URI starts with "HTTPS//":
546502 elif ca ['URL' ].lower ().startswith ('https://' ):
@@ -560,19 +516,15 @@ def __enroll(self, guid, entries, trust_dir, private_dir):
560516 ca_names = []
561517 end_point_information = obtain_end_point_information (entries )
562518 if len (end_point_information ) > 0 :
563- cep_data = self .__read_cep_data (guid , ldb , end_point_information , trust_dir , private_dir )
564- if cep_data :
565- ca_names . extend ( cep_data )
519+ ca_names . extend ( self .__read_cep_data (guid , ldb ,
520+ end_point_information ,
521+ trust_dir , private_dir ) )
566522 else :
567523 cas = fetch_certification_authorities (ldb )
568524 for ca in cas :
569- try :
570- self .apply (guid , ca , cert_enroll , ca , ldb , trust_dir , private_dir )
571- except Exception as e :
572- log .warn (f"Could not enroll to CA { ca ['name' ]} : { e } " )
573- continue
525+ self .apply (guid , ca , cert_enroll , ca , ldb , trust_dir ,
526+ private_dir )
574527 ca_names .append (ca ['name' ])
575- log .debug (f'Enrolled to the following CAs: { ca_names } ' )
576528 return ca_names
577529
578530 def rsop (self , gpo ):
0 commit comments