# vim: set ft=python : import errno import os import subprocess def get_samba_paths(samba='samba'): lines = [] paths = {} cmd = [samba, '--show-build'] with open(os.devnull, 'r') as nul: p = subprocess.Popen( cmd, stdin=nul, stdout=subprocess.PIPE, stderr=subprocess.PIPE ) out, err = p.communicate() in_paths = False for line in out.splitlines(): out += line if line.startswith(b'Paths:'): in_paths = True continue if in_paths: if line.startswith(b' '): parts = line.decode().split(':', 1) if len(parts) != 2: raise ValueError( 'Unexpected output from samba: {}'.format(line) ) paths[parts[0].strip()] = parts[1].strip() else: in_paths = False if p.returncode != 0: raise subprocess.CalledProcessError(p.returncode, cmd, out, err) return paths def main(): module = AnsibleModule( argument_spec=dict( realm=dict( required=True, ), domain=dict( required=False, ), use_rfc2307=dict( required=False, type='bool', default=True, ), dns_backend=dict( required=False, choices=[ 'BIND9_DLZ', 'SAMBA_INTERNAL', ], ), username=dict( required=False, ), password=dict( required=False, no_log=True, ), state=dict( required=True, choices=[ 'provisioned', 'joined', ], ), ), supports_check_mode=True, ) realm = module.params['realm'] domain = module.params['domain'] or realm.split('.')[0] use_rfc2307 = module.params['use_rfc2307'] dns_backend = module.params['dns_backend'] state = module.params['state'] username = module.params['username'] password = module.params['password'] samba_tool = module.get_bin_path('samba-tool', required=True) samba = module.get_bin_path('samba', required=True) try: samba_paths = get_samba_paths(samba) except OSError as e: module.fail_json(msg='Error running samba: {}'.format(e)) except subprocess.CalledProcessError as e: module.fail_json( msg='Error running samba: {}'.format(e), stdout=e.stdout, stderr=e.stderr, ) changed = not os.path.isdir(os.path.join( samba_paths['STATEDIR'], 'sysvol', realm.lower(), )) if changed and not module.check_mode: try: os.unlink(samba_paths['CONFIGFILE']) except OSError as e: if e.errno != errno.ENOENT: raise cmd = [ samba_tool, 'domain', ] if state == 'provisioned': cmd += [ 'provision', '--realm={}'.format(realm), '--domain={}'.format(domain), ] if use_rfc2307: cmd.append('--use-rfc2307') else: cmd += [ 'join', realm, 'DC', ] if username and password: cmd += [ '--username', username, '--password', password, ] else: cmd += [ '--kerberos', 'true', ] if dns_backend: cmd += ('--dns-backend', dns_backend) rc, out, err = module.run_command(cmd, check_rc=True) admin_password = '' domain_sid = '' for line in err.splitlines(): if line.startswith('Admin password:'): admin_password = line.split(':', 1)[1].lstrip() if line.startswith('DOMAIN SID:'): domain_sid = line.split(':', 1)[1].lstrip() module.exit_json( changed=True, rc=rc, admin_password=admin_password, domain_sid=domain_sid, ) module.exit_json(changed=changed) from ansible.module_utils.basic import * if __name__ == '__main__': main()