Query AD subnets using subprocess approach for Kerberos
(domain)
| 2276 | return {} |
| 2277 | |
| 2278 | def query_ad_subnets_subprocess(domain): |
| 2279 | """Query AD subnets using subprocess approach for Kerberos""" |
| 2280 | try: |
| 2281 | import subprocess |
| 2282 | import os |
| 2283 | import re |
| 2284 | |
| 2285 | # Set up environment |
| 2286 | env = os.environ.copy() |
| 2287 | # Use existing KRB5CCNAME from environment if set |
| 2288 | # Use existing KRB5_CONFIG from environment if set |
| 2289 | |
| 2290 | domain_dn = ','.join([f"DC={part}" for part in domain.split('.')]) |
| 2291 | search_base = f"CN=Subnets,CN=Sites,CN=Configuration,{domain_dn}" |
| 2292 | |
| 2293 | logger.info(f"🔍 Querying AD Sites and Services for subnets...") |
| 2294 | logger.info(f"🔍 Search base: {search_base}") |
| 2295 | |
| 2296 | # Try multiple approaches |
| 2297 | ad_subnets = {} |
| 2298 | |
| 2299 | # Approach 1: Use ldapsearch command directly |
| 2300 | try: |
| 2301 | # Use the DC host passed as parameter |
| 2302 | cmd = ['ldapsearch', '-Y', 'GSSAPI', '-H', f'ldap://{domain}', |
| 2303 | '-b', search_base, '(objectClass=subnet)', 'cn', 'siteObject', 'description'] |
| 2304 | |
| 2305 | result = subprocess.run(cmd, capture_output=True, text=True, timeout=30, env=env) |
| 2306 | |
| 2307 | if result.returncode == 0 and result.stdout: |
| 2308 | logger.info("✅ Successfully retrieved subnets via ldapsearch") |
| 2309 | # Parse ldapsearch output |
| 2310 | current_entry = {} |
| 2311 | for line in result.stdout.split('\\n'): |
| 2312 | line = line.strip() |
| 2313 | if line.startswith('dn: CN='): |
| 2314 | if current_entry.get('cn'): |
| 2315 | # Process previous entry |
| 2316 | subnet_str = current_entry['cn'] |
| 2317 | try: |
| 2318 | network = ipaddress.IPv4Network(subnet_str) |
| 2319 | site_name = "Default-First-Site-Name" |
| 2320 | if current_entry.get('siteObject'): |
| 2321 | site_match = re.search(r'CN=([^,]+)', current_entry['siteObject']) |
| 2322 | if site_match: |
| 2323 | site_name = site_match.group(1) |
| 2324 | |
| 2325 | ad_subnets[subnet_str] = { |
| 2326 | 'network': network, |
| 2327 | 'site': site_name, |
| 2328 | 'description': current_entry.get('description', ''), |
| 2329 | 'hosts': [] |
| 2330 | } |
| 2331 | logger.info(f"📍 Found AD subnet: {subnet_str} in site '{site_name}'") |
| 2332 | except ipaddress.AddressValueError: |
| 2333 | logger.debug(f"Invalid subnet format: {subnet_str}") |
| 2334 | current_entry = {} |
| 2335 | elif line.startswith('cn: '): |