def get(path, value=""): """ Get a value for a specific augeas path CLI Example:: salt '*' augeas.get /files/etc/hosts/1/ ipaddr """ from augeas import Augeas aug = Augeas() ret = {} path = path.rstrip("/") if value: path += "/{0}".format(value.strip("/")) try: _match = aug.match(path) except RuntimeError as err: return {"error": str(err)} if _match: ret[path] = aug.get(path) else: ret[path] = "" # node does not exist return ret
def get(path, value=''): ''' Get a value for a specific augeas path CLI Example:: salt '*' augeas.get /files/etc/hosts/1/ ipaddr ''' from augeas import Augeas aug = Augeas() ret = {} path = path.rstrip('/') if value: path += "/{0}".format(value.strip('/')) try: _match = aug.match(path) except RuntimeError as err: return {'error': str(err)} if _match: ret[path] = aug.get(path) else: ret[path] = '' # node does not exist return ret
def match(path, value=''): ''' Get matches for path expression CLI Example:: salt '*' augeas.match /files/etc/services/service-name ssh ''' from augeas import Augeas aug = Augeas() ret = {} try: matches = aug.match(path) except RuntimeError: return ret for _match in matches: if value and aug.get(_match) == value: ret[_match] = value elif not value: ret[_match] = aug.get(_match) return ret
def get(self,entryPath,param='',hierarchy='/files'): """Get a value for a config. parameter in a config. file, with the help of Augeas, a configuration API (cf http://augeas.net)""" try: from augeas import Augeas aug=Augeas() except Exception, e: return str(e) # yes, entryPath.rstrip('/')+'/' is really needed (i.e. entryPath=/) path=(hierarchy+entryPath.rstrip('/')+'/'+param).rstrip('/') try: matchtest=aug.match(path) except Exception, e: return str(e) if matchtest: try: pvalue=aug.get(path) #aug.close() except Exception, e: return str(e) else: # The node doesn't exist pvalue='(o)' if not pvalue: # The node doesn't have a value pvalue='(none)' return { 'path': entryPath, 'parameter': param, 'value': pvalue, 'hierarchy': hierarchy }
def get(path, value=''): ''' Get a value for a specific augeas path CLI Example: .. code-block:: bash salt '*' augeas.get /files/etc/hosts/1/ ipaddr ''' aug = Augeas() ret = {} path = path.rstrip('/') if value: path += '/{0}'.format(value.strip('/')) try: _match = aug.match(path) except RuntimeError as err: return {'error': str(err)} if _match: ret[path] = aug.get(path) else: ret[path] = '' # node does not exist return ret
def get_configured_ifaces(): aug = Augeas(flags=Augeas.NO_MODL_AUTOLOAD) aug.add_transform('interfaces', '/etc/network/interfaces') aug.load() base = '/files/etc/network/interfaces' for m in aug.match('%s/iface' % base): yield aug.get(m) aug.close()
def match(self,entryPath,param='',pvalue='',hierarchy='/files'): """Match a value for a config. parameter in a config. file, with the help of Augeas, a configuration API (cf http://augeas.net)""" try: from augeas import Augeas aug=Augeas() except Exception, e: return str(e) path=(hierarchy+entryPath.rstrip('/')+'/'+param).rstrip('/') childpath=(hierarchy+entryPath.rstrip('/')+'/*/'+param).rstrip('/') if pvalue: try: matchlist = [ ospath.dirname(lstripstr(item,'/files')) for item in aug.match(path) + aug.match(childpath) if ( aug.get(item) == pvalue ) ] #aug.close() except Exception, e: return str(e) else: try: matchlist = [ ospath.dirname(lstripstr(item,'/files')) for item in aug.match(path) + aug.match(childpath) ] #aug.close() except Exception, e: return str(e) return matchlist
def set_api_timeouts(self, timeout): # Determine the file to change if self.https: config_file = self.abiquo_ssl_conf else: config_file = self.abiquo_conf logging.info("Setting Proxy timeouts in %s" % config_file) # Set timeout using Augeas a = Augeas() for loc in a.match("/files%s/VirtualHost/*[arg='/api']" % config_file): proxy_pass = a.match("%s/*[self::directive='ProxyPass']" % loc) if len(proxy_pass) == 1: # Proxy timeout already exists logging.info("ProxyPass found") arg1 = a.get("%s/arg" % proxy_pass[0]) arg2 = "timeout=%s" % timeout a.set("%s/arg[1]" % proxy_pass[0], arg1) a.set("%s/arg[2]" % proxy_pass[0], arg2) a.save() a.close()
def execute(*args, **kw): if conf.timezone == None: print >> sys.stderr, utils.multiline_message( _(""" Please supply the timezone PHP should be using. You have to use a Continent or Country / City locality name like 'Europe/Berlin', but not just 'CEST'. """)) conf.timezone = utils.ask_question(_("Timezone ID"), default="UTC") if not conf.php_ini_path == None: if not os.path.isfile(conf.php_ini_path): log.error( _("Cannot configure PHP through %r (No such file or directory)" ) % (conf.php_ini_path)) return php_ini = conf.php_ini_path else: # Search and destroy php_ini = "/etc/php.ini" if not os.path.isfile(php_ini): php_ini = "/etc/php5/apache2/php.ini" if not os.path.isfile(php_ini): log.error(_("Could not find PHP configuration file php.ini")) return myaugeas = Augeas() setting_base = '/files%s/' % (php_ini) setting = os.path.join(setting_base, 'Date', 'date.timezone') current_value = myaugeas.get(setting) if current_value == None: insert_paths = myaugeas.match('/files%s/Date/*' % (php_ini)) insert_path = insert_paths[(len(insert_paths) - 1)] myaugeas.insert(insert_path, 'date.timezone', False) log.debug(_("Setting key %r to %r") % ('Date/date.timezone', conf.timezone), level=8) myaugeas.set(setting, conf.timezone) myaugeas.save()
def execute(*args, **kw): if conf.timezone == None: print >> sys.stderr, utils.multiline_message( _(""" Please supply the timezone PHP should be using. You have to use a Continent or Country / City locality name like 'Europe/Berlin', but not just 'CEST'. """) ) conf.timezone = utils.ask_question( _("Timezone ID"), default="UTC" ) if not conf.php_ini_path == None: if not os.path.isfile(conf.php_ini_path): log.error(_("Cannot configure PHP through %r (No such file or directory)") % (conf.php_ini_path)) return php_ini = conf.php_ini_path else: # Search and destroy php_ini = "/etc/php.ini" if not os.path.isfile(php_ini): php_ini = "/etc/php5/apache2/php.ini" if not os.path.isfile(php_ini): log.error(_("Could not find PHP configuration file php.ini")) return myaugeas = Augeas() setting_base = '/files%s/' % (php_ini) setting = os.path.join(setting_base, 'Date', 'date.timezone') current_value = myaugeas.get(setting) if current_value == None: insert_paths = myaugeas.match('/files%s/Date/*' % (php_ini)) insert_path = insert_paths[(len(insert_paths)-1)] myaugeas.insert(insert_path, 'date.timezone', False) log.debug(_("Setting key %r to %r") % ('Date/date.timezone', conf.timezone), level=8) myaugeas.set(setting, conf.timezone) myaugeas.save()
def get_augeas(self, entry): """ Get an augeas object for the given entry. """ if entry.get("name") not in self._augeas: aug = Augeas() if entry.get("lens"): self.logger.debug("Augeas: Adding %s to include path for %s" % (entry.get("name"), entry.get("lens"))) incl = "/augeas/load/%s/incl" % entry.get("lens") ilen = len(aug.match(incl)) if ilen == 0: self.logger.error("Augeas: Lens %s does not exist" % entry.get("lens")) else: aug.set("%s[%s]" % (incl, ilen + 1), entry.get("name")) aug.load() self._augeas[entry.get("name")] = aug return self._augeas[entry.get("name")]
def ls(self,entryPath,hierarchy='/files'): """List the direct children of an entry in a config. file, with the help of Augeas, a configuration API (cf http://augeas.net)""" try: from augeas import Augeas aug=Augeas() except Exception, e: return str(e) path=hierarchy+entryPath.rstrip('/')+'/*' # We can't use a dict here because the same key can appear many times. nodes=[] try: for match in aug.match(path): pvalue=aug.get(match) if not pvalue: pvalue='(none)' nodes.append([ospath.basename(match),pvalue]) except Exception, e: return str(e) #try: # aug.close() #except Exception, e: return str(e) return { 'path': entryPath, 'nodes': nodes, 'hierarchy': hierarchy }
class HAProxyConfManager(object): conf_path = 'etc/haproxy/haproxy.cfg' def __init__(self, root_path=None): if root_path is None: root_path = '/' self.conf_path = root_path + self.conf_path self._conf_xpath = '/files' + self.conf_path + '/' self._augeas = Augeas(root=root_path, loadpath=HAPROXY_LENS_DIR) def load(self): LOG.debug('Loading haproxy.conf') self._augeas.load() def save(self): LOG.debug('Saving haproxy.conf') self._augeas.save() def get(self, xpath): """ Returns values of label at given xpath. If label is presented but has no value, returns True xpath is relative to haproxy.cfg file """ if self._augeas.match(self._conf_xpath + xpath) == []: return None value = self._augeas.get(self._conf_xpath + xpath) return value if value is not None else True def _find_xpath_gen(self, base_xpath, sublabel, value_pattern): section_xpaths = self._augeas.match(self._conf_xpath + base_xpath) for xpath in section_xpaths: match = re.search(value_pattern, self._augeas.get(xpath + '/' + sublabel)) if match != None: yield xpath.replace(self._conf_xpath, '') def find_all_xpaths(self, base_xpath, sublabel, value_pattern): """ Returns list of all labels from given base_xpath which sublabel matches `value_pattern` `value_pattern` is regexp This metod is useful when you need to find certain section from config that contains number of such sections (listen[1], listen[2]...) ..Example: cnf.get_matched_xpaths('listen', 'name', 'test*') this will find every listen whose name begins with 'test' """ return list(self._find_xpath_gen(base_xpath, sublabel, value_pattern)) def find_one_xpath(self, base_xpath, sublabel, value_pattern): """ Returns label xpath by given value_pattern of sublabel. Returns None if no label is found. This metod is useful when you need to find certain section from config that contains number of such sections (listen[1], listen[2]...) """ try: return self._find_xpath_gen(base_xpath, sublabel, value_pattern).next() except StopIteration: return None def get_all_xpaths(self, base_xpath): return [ x.replace(self._conf_xpath, '') for x in self._augeas.match(self._conf_xpath + base_xpath) ] def set(self, xpath, value=None, save_conf=True): """ Sets label at given xpath with given value. If there is no label - creates one. If there is - updates its value. `value` can be None/True to set label without actual value or string or iterable or dict to set number of sublabels at once. `xpath` is relative to haproxy.cfg file. """ LOG.debug('Setting %s with value: %s' % (xpath, value)) if isinstance(value, dict): self._augeas.set(self._conf_xpath + xpath, None) for k, v in value.items(): self.set(xpath + '/' + k, v, save_conf=False) elif hasattr(value, '__iter__'): for v in value: self.add(xpath, v, save_conf=False) else: if value == True: value = None elif value == False: return self.remove(xpath) elif value is not None: value = str(value) self._augeas.set(self._conf_xpath + xpath, value) if save_conf: self.save() def add(self, xpath, value=None, save_conf=True): """ Adds node at given xpath. New nodes are appended xpath is relative to haproxy.cfg file Returns xpath of created node """ nodes_qty = len(self._augeas.match(self._conf_xpath + xpath)) if nodes_qty != 0: xpath += '[%s]' % (nodes_qty + 1) self.set(xpath, value, save_conf) return xpath def insert(self, xpath, label, value=None, before=True): """ Inserts label before or after given in xpath xpath is relative to haproxy.cfg file """ xpath = self._conf_xpath + xpath self._augeas.insert(xpath, label, before) if value is not None: labels = self._augeas.match(os.path.dirname(xpath)) base_label = os.path.basename(xpath) inserted_xpath = None if label == base_label: if xpath.endswith(']'): inserted_xpath = xpath if before else labels[ labels.index(xpath) + 1] else: inserted_xpath += '[1]' if before else '[2]' else: index = labels.index(xpath) + (-1 if before else 1) inserted_xpath = labels[index] self.set(inserted_xpath.replace(self._conf_xpath, ''), value) def add_conf(self, conf, append=False): """ Append raw conf to the end of haproxy.conf file or insert at the beginning before everything """ LOG.debug('Adding raw conf part to haproxy.conf:\n%s' % conf) raw = None with open(self.conf_path, 'r') as conf_file: raw = conf_file.read() if not conf.endswith('\n'): conf += '\n' raw = '\n'.join((raw, conf) if append else (conf, raw)) with open(self.conf_path, 'w') as conf_file: conf_file.write(raw) self.load() def extend_section(self, conf, section_name): """ Appends raw conf to the section with given name """ LOG.debug( 'Adding raw conf part to section of haproxy.conf with name %s :\n%s' % (section_name, conf)) raw = None with open(self.conf_path, 'r') as conf_file: raw = conf_file.read() if conf.endswith('\n'): conf = conf[:-1] # reindenting conf conf = dedent(conf) conf = ' ' + conf.replace('\n', '\n ') raw = re.sub(section_name + r'\s*\n', '%s\n%s\n' % (section_name, conf), raw) with open(self.conf_path, 'w') as conf_file: conf_file.write(raw) self.load() def remove(self, xpath): LOG.debug('Removing %s' % xpath) return self._augeas.remove(self._conf_xpath + xpath)
class AugeasWrapper(object): """python-augeas higher-level wrapper. Load single augeas lens and configuration file. Exposes configuration file as AugeasNode object with dict-like interface. AugeasWrapper can be used in with statement in the same way as file does. """ def __init__(self, confpath, lens, root=None, loadpath=None, flags=Augeas.NO_MODL_AUTOLOAD | Augeas.NO_LOAD | Augeas.ENABLE_SPAN): """Parse configuration file using given lens. Params: confpath (str): Absolute path to the configuration file lens (str): Name of module containing Augeas lens root: passed down to original Augeas flags: passed down to original Augeas loadpath: passed down to original Augeas flags: passed down to original Augeas """ log.debug('loadpath: %s', loadpath) log.debug('confpath: %s', confpath) self._aug = Augeas(root=root, loadpath=loadpath, flags=flags) # /augeas/load/{lens} aug_load_path = join(AUGEAS_LOAD_PATH, lens) # /augeas/load/{lens}/lens = {lens}.lns self._aug.set(join(aug_load_path, 'lens'), '%s.lns' % lens) # /augeas/load/{lens}/incl[0] = {confpath} self._aug.set(join(aug_load_path, 'incl[0]'), confpath) self._aug.load() errors = self._aug.match(AUGEAS_ERROR_PATH) if errors: err_msg = '\n'.join( ["{}: {}".format(e, self._aug.get(e)) for e in errors]) raise RuntimeError(err_msg) path = join(AUGEAS_FILES_PATH, confpath) paths = self._aug.match(path) if len(paths) != 1: raise ValueError('path %s did not match exactly once' % path) self.tree = AugeasNode(self._aug, path) self._loaded = True def __enter__(self): return self def __exit__(self, exc_type, exc_value, traceback): self.save() self.close() def save(self): """Save Augeas tree to its original file.""" assert self._loaded try: self._aug.save() except IOError as exc: log.exception(exc) for err_path in self._aug.match('//error'): log.error('%s: %s', err_path, self._aug.get(os.path.join(err_path, 'message'))) raise def close(self): """ close Augeas library After calling close() the object must not be used anymore. """ assert self._loaded self._aug.close() del self._aug self._loaded = False def match(self, path): """Yield AugeasNodes matching given expression.""" assert self._loaded assert path log.debug('tree match %s', path) for matched_path in self._aug.match(path): yield AugeasNode(self._aug, matched_path)
class LVMConfig(object): def __init__(self, path="/etc/lvm/lvm.conf"): self.path = path # Augeas loads by default tons of unneeded lenses and configuration # files. On my test host, it fails to load, trying to read my 500 MiB # /etc/lvm/archive/. # # These are the standard LVM lens includes: # /augeas/load/LVM/incl[1] /etc/lvm/lvm.conf # /augeas/load/LVM/incl[2] /etc/lvm/backup/* # /augeas/load/LVM/incl[3] /etc/lvm/archive/*.vg # # We need only the first entry to work with lvm.conf. Using customized # load setup, as explained in # https://github.com/hercules-team/augeas/wiki/Loading-specific-files # # Removing the archive and backup entries, we can load augeas in 0.7 # seconds on my test vm. Removing all other lenses shorten the time to # 0.04 seconds. log.debug("Loading LVM configuration from %r", path) self.aug = Augeas(flags=Augeas.NO_MODL_AUTOLOAD | Augeas.SAVE_BACKUP) self.aug.add_transform("lvm.lns", [path]) self.aug.load() # Context manager interface def __enter__(self): return self def __exit__(self, t, v, tb): try: self.close() except Exception as e: # Caller succeeded, raise the close error. if t is None: raise # Caller has failed, do not hide the original error. log.exception("Error closing %s: %s" % (self, e)) # Accessing list of strings def getlist(self, section, option): pat = "/files%s/%s/dict/%s/list/*/str" % (self.path, section, option) matches = self.aug.match(pat) if not matches: return None # Cannot store/read empty list return [self.aug.get(m) for m in matches] def setlist(self, section, option, value): log.debug("Setting %s/%s to %s", section, option, value) opt_path = "/files%s/%s/dict/%s" % (self.path, section, option) self.aug.remove(opt_path) item_path = opt_path + "/list/%d/str" for i, item in enumerate(value, 1): self.aug.set(item_path % i, item) # Accessing flat values (int, string) def getint(self, section, option): val = self._get_flat(section, option, "int") return int(val) if val is not None else None def setint(self, section, option, value): self._set_flat(section, option, "int", str(value)) def getstr(self, section, option): return self._get_flat(section, option, "str") def setstr(self, section, option, value): self._set_flat(section, option, "str", value) def _get_flat(self, section, option, opt_type): path = self._flat_path(section, option, opt_type) return self.aug.get(path) def _set_flat(self, section, option, opt_type, value): log.debug("Setting %s/%s to %r", section, option, value) path = self._flat_path(section, option, opt_type) return self.aug.set(path, value) def _flat_path(self, section, option, opt_type): return "/files%s/%s/dict/%s/%s" % ( self.path, section, option, opt_type) # Removing options def remove(self, section, option): log.debug("Removing %s/%s", section, option) path = "/files%s/%s/dict/%s" % (self.path, section, option) self.aug.remove(path) # File operations def save(self): log.info("Saving new LVM configuration to %r, previous configuration " "saved to %r", self.path, self.path + ".augsave") self.aug.save() def close(self): log.debug("Closing LVM configuration %s", self.path) self.aug.close()
def execute(*args, **kw): group_filter = conf.get('ldap', 'kolab_group_filter') if group_filter == None: group_filter = conf.get('ldap', 'group_filter') user_filter = conf.get('ldap', 'kolab_user_filter') if user_filter == None: user_filter = conf.get('ldap', 'user_filter') resource_filter = conf.get('ldap', 'resource_filter') sharedfolder_filter = conf.get('ldap', 'sharedfolder_filter') server_host = utils.parse_ldap_uri(conf.get('ldap', 'ldap_uri'))[1] files = { "/etc/postfix/ldap/local_recipient_maps.cf": """ server_host = %(server_host)s server_port = 389 version = 3 search_base = %(base_dn)s scope = sub domain = ldap:/etc/postfix/ldap/mydestination.cf bind_dn = %(service_bind_dn)s bind_pw = %(service_bind_pw)s query_filter = (&(|(mail=%%s)(alias=%%s))(|%(kolab_user_filter)s%(kolab_group_filter)s%(resource_filter)s%(sharedfolder_filter)s)) result_attribute = mail """ % { "base_dn": conf.get('ldap', 'base_dn'), "server_host": server_host, "service_bind_dn": conf.get('ldap', 'service_bind_dn'), "service_bind_pw": conf.get('ldap', 'service_bind_pw'), "kolab_user_filter": user_filter, "kolab_group_filter": group_filter, "resource_filter": resource_filter, "sharedfolder_filter": sharedfolder_filter, }, "/etc/postfix/ldap/mydestination.cf": """ server_host = %(server_host)s server_port = 389 version = 3 search_base = %(domain_base_dn)s scope = sub bind_dn = %(service_bind_dn)s bind_pw = %(service_bind_pw)s query_filter = %(domain_filter)s result_attribute = %(domain_name_attribute)s """ % { "server_host": server_host, "domain_base_dn": conf.get('ldap', 'domain_base_dn'), "domain_filter": conf.get('ldap', 'domain_filter').replace( '*', '%s'), "domain_name_attribute": conf.get('ldap', 'domain_name_attribute'), "service_bind_dn": conf.get('ldap', 'service_bind_dn'), "service_bind_pw": conf.get('ldap', 'service_bind_pw'), }, "/etc/postfix/ldap/mailenabled_distgroups.cf": """ server_host = %(server_host)s server_port = 389 version = 3 search_base = %(group_base_dn)s scope = sub domain = ldap:/etc/postfix/ldap/mydestination.cf bind_dn = %(service_bind_dn)s bind_pw = %(service_bind_pw)s # This finds the mail enabled distribution group LDAP entry query_filter = (&(|(mail=%%s)(alias=%%s))(objectClass=kolabgroupofuniquenames)(objectclass=groupofuniquenames)(!(objectclass=groupofurls))) # From this type of group, get all uniqueMember DNs special_result_attribute = uniqueMember # Only from those DNs, get the mail result_attribute = leaf_result_attribute = mail """ % { "server_host": server_host, "group_base_dn": conf.get('ldap', 'group_base_dn'), "service_bind_dn": conf.get('ldap', 'service_bind_dn'), "service_bind_pw": conf.get('ldap', 'service_bind_pw'), }, "/etc/postfix/ldap/mailenabled_dynamic_distgroups.cf": """ server_host = %(server_host)s server_port = 389 version = 3 search_base = %(group_base_dn)s scope = sub domain = ldap:/etc/postfix/ldap/mydestination.cf bind_dn = %(service_bind_dn)s bind_pw = %(service_bind_pw)s # This finds the mail enabled dynamic distribution group LDAP entry query_filter = (&(|(mail=%%s)(alias=%%s))(objectClass=kolabgroupofuniquenames)(objectClass=groupOfURLs)) # From this type of group, get all memberURL searches/references special_result_attribute = memberURL # Only from those DNs, get the mail result_attribute = leaf_result_attribute = mail """ % { "server_host": server_host, "group_base_dn": conf.get('ldap', 'group_base_dn'), "service_bind_dn": conf.get('ldap', 'service_bind_dn'), "service_bind_pw": conf.get('ldap', 'service_bind_pw'), }, "/etc/postfix/ldap/transport_maps.cf": """ server_host = %(server_host)s server_port = 389 version = 3 search_base = %(base_dn)s scope = sub domain = ldap:/etc/postfix/ldap/mydestination.cf bind_dn = %(service_bind_dn)s bind_pw = %(service_bind_pw)s query_filter = (&(|(mailAlternateAddress=%%s)(alias=%%s)(mail=%%s))(objectclass=kolabinetorgperson)) result_attribute = mail result_format = lmtp:unix:/var/lib/imap/socket/lmtp """ % { "base_dn": conf.get('ldap', 'base_dn'), "server_host": server_host, "service_bind_dn": conf.get('ldap', 'service_bind_dn'), "service_bind_pw": conf.get('ldap', 'service_bind_pw'), }, "/etc/postfix/ldap/virtual_alias_maps.cf": """ server_host = %(server_host)s server_port = 389 version = 3 search_base = %(base_dn)s scope = sub domain = ldap:/etc/postfix/ldap/mydestination.cf bind_dn = %(service_bind_dn)s bind_pw = %(service_bind_pw)s query_filter = (&(|(mail=%%s)(alias=%%s))(objectclass=kolabinetorgperson)) result_attribute = mail """ % { "base_dn": conf.get('ldap', 'base_dn'), "server_host": server_host, "service_bind_dn": conf.get('ldap', 'service_bind_dn'), "service_bind_pw": conf.get('ldap', 'service_bind_pw'), }, "/etc/postfix/ldap/virtual_alias_maps_mailforwarding.cf": """ server_host = %(server_host)s server_port = 389 version = 3 search_base = %(base_dn)s scope = sub domain = ldap:/etc/postfix/ldap/mydestination.cf bind_dn = %(service_bind_dn)s bind_pw = %(service_bind_pw)s query_filter = (&(|(mail=%%s)(alias=%%s))(objectclass=mailrecipient)(objectclass=inetorgperson)(mailforwardingaddress=*)) result_attribute = mailForwardingAddress """ % { "base_dn": conf.get('ldap', 'base_dn'), "server_host": server_host, "service_bind_dn": conf.get('ldap', 'service_bind_dn'), "service_bind_pw": conf.get('ldap', 'service_bind_pw'), }, "/etc/postfix/ldap/virtual_alias_maps_sharedfolders.cf": """ server_host = %(server_host)s server_port = 389 version = 3 search_base = %(base_dn)s scope = sub domain = ldap:/etc/postfix/ldap/mydestination.cf bind_dn = %(service_bind_dn)s bind_pw = %(service_bind_pw)s query_filter = (&(|(mail=%%s)(alias=%%s))(objectclass=kolabsharedfolder)(kolabFolderType=mail)) result_attribute = kolabtargetfolder result_format = "shared+%%s" """ % { "base_dn": conf.get('ldap', 'base_dn'), "server_host": server_host, "service_bind_dn": conf.get('ldap', 'service_bind_dn'), "service_bind_pw": conf.get('ldap', 'service_bind_pw'), }, } if not os.path.isdir('/etc/postfix/ldap'): os.mkdir('/etc/postfix/ldap/', 0770) for filename in files.keys(): fp = open(filename, 'w') fp.write(files[filename]) fp.close() fp = open('/etc/postfix/transport', 'a') fp.write( "\n# Shared Folder Delivery for %(domain)s:\nshared@%(domain)s\t\tlmtp:unix:/var/lib/imap/socket/lmtp\n" % {'domain': conf.get('kolab', 'primary_domain')}) fp.close() subprocess.call(["postmap", "/etc/postfix/transport"]) postfix_main_settings = { "inet_interfaces": "all", "recipient_delimiter": "+", "local_recipient_maps": "ldap:/etc/postfix/ldap/local_recipient_maps.cf", "mydestination": "ldap:/etc/postfix/ldap/mydestination.cf", "transport_maps": "ldap:/etc/postfix/ldap/transport_maps.cf, hash:/etc/postfix/transport", "virtual_alias_maps": "$alias_maps, ldap:/etc/postfix/ldap/virtual_alias_maps.cf, ldap:/etc/postfix/ldap/virtual_alias_maps_mailforwarding.cf, ldap:/etc/postfix/ldap/virtual_alias_maps_sharedfolders.cf, ldap:/etc/postfix/ldap/mailenabled_distgroups.cf, ldap:/etc/postfix/ldap/mailenabled_dynamic_distgroups.cf", "smtpd_tls_auth_only": "yes", "smtpd_tls_security_level": "may", "smtp_tls_security_level": "may", "smtpd_sasl_auth_enable": "yes", "smtpd_sender_login_maps": "$local_recipient_maps", "smtpd_data_restrictions": "permit_mynetworks, check_policy_service unix:private/recipient_policy_incoming", "smtpd_recipient_restrictions": "permit_mynetworks, reject_unauth_pipelining, reject_rbl_client zen.spamhaus.org, reject_non_fqdn_recipient, reject_invalid_helo_hostname, reject_unknown_recipient_domain, reject_unauth_destination, check_policy_service unix:private/recipient_policy_incoming, permit", "smtpd_sender_restrictions": "permit_mynetworks, reject_sender_login_mismatch, check_policy_service unix:private/sender_policy_incoming", "submission_recipient_restrictions": "check_policy_service unix:private/submission_policy, permit_sasl_authenticated, reject", "submission_sender_restrictions": "reject_non_fqdn_sender, check_policy_service unix:private/submission_policy, permit_sasl_authenticated, reject", "submission_data_restrictions": "check_policy_service unix:private/submission_policy", "content_filter": "smtp-amavis:[127.0.0.1]:10024" } if os.path.isfile( '/etc/pki/tls/certs/make-dummy-cert' ) and not os.path.isfile('/etc/pki/tls/private/localhost.pem'): subprocess.call([ '/etc/pki/tls/certs/make-dummy-cert', '/etc/pki/tls/private/localhost.pem' ]) if os.path.isfile('/etc/pki/tls/private/localhost.pem'): postfix_main_settings[ 'smtpd_tls_cert_file'] = "/etc/pki/tls/private/localhost.pem" postfix_main_settings[ 'smtpd_tls_key_file'] = "/etc/pki/tls/private/localhost.pem" if not os.path.isfile('/etc/postfix/main.cf'): if os.path.isfile('/usr/share/postfix/main.cf.debian'): shutil.copy('/usr/share/postfix/main.cf.debian', '/etc/postfix/main.cf') # Copy header checks files for hc_file in ['inbound', 'internal', 'submission']: if not os.path.isfile("/etc/postfix/header_checks.%s" % (hc_file)): if os.path.isfile('/etc/kolab/templates/header_checks.%s' % (hc_file)): input_file = '/etc/kolab/templates/header_checks.%s' % ( hc_file) elif os.path.isfile('/usr/share/kolab/templates/header_checks.%s' % (hc_file)): input_file = '/usr/share/kolab/templates/header_checks.%s' % ( hc_file) elif os.path.isfile( os.path.abspath( os.path.join(__file__, '..', '..', '..', 'share', 'templates', 'header_checks.%s' % (hc_file)))): input_file = os.path.abspath( os.path.join(__file__, '..', '..', '..', 'share', 'templates', 'header_checks.%s' % (hc_file))) shutil.copy(input_file, "/etc/postfix/header_checks.%s" % (hc_file)) subprocess.call( ["postmap", "/etc/postfix/header_checks.%s" % (hc_file)]) myaugeas = Augeas() setting_base = '/files/etc/postfix/main.cf/' for setting_key in postfix_main_settings.keys(): setting = os.path.join(setting_base, setting_key) current_value = myaugeas.get(setting) if current_value == None: try: myaugeas.set(setting, postfix_main_settings[setting_key]) except: insert_paths = myaugeas.match('/files/etc/postfix/main.cf/*') insert_path = insert_paths[(len(insert_paths) - 1)] myaugeas.insert(insert_path, setting_key, False) log.debug(_("Setting key %r to %r") % (setting_key, postfix_main_settings[setting_key]), level=8) myaugeas.set(setting, postfix_main_settings[setting_key]) myaugeas.save() postfix_master_settings = {} if os.path.exists('/usr/lib/postfix/kolab_smtp_access_policy'): postfix_master_settings[ 'kolab_sap_executable_path'] = '/usr/lib/postfix/kolab_smtp_access_policy' else: postfix_master_settings[ 'kolab_sap_executable_path'] = '/usr/libexec/postfix/kolab_smtp_access_policy' template_file = None if os.path.isfile('/etc/kolab/templates/master.cf.tpl'): template_file = '/etc/kolab/templates/master.cf.tpl' elif os.path.isfile('/usr/share/kolab/templates/master.cf.tpl'): template_file = '/usr/share/kolab/templates/master.cf.tpl' elif os.path.isfile( os.path.abspath( os.path.join(__file__, '..', '..', '..', 'share', 'templates', 'master.cf.tpl'))): template_file = os.path.abspath( os.path.join(__file__, '..', '..', '..', 'share', 'templates', 'master.cf.tpl')) if not template_file == None: fp = open(template_file, 'r') template_definition = fp.read() fp.close() t = Template(template_definition, searchList=[postfix_master_settings]) fp = open('/etc/postfix/master.cf', 'w') fp.write(t.__str__()) fp.close() else: log.error( _("Could not write out Postfix configuration file /etc/postfix/master.cf" )) return if os.path.isdir('/etc/postfix/sasl/'): fp = open('/etc/postfix/sasl/smtpd.conf', 'w') fp.write("pwcheck_method: saslauthd\n") fp.write("mech_list: plain login\n") fp.close() amavisd_settings = { 'ldap_server': '%(server_host)s', 'ldap_bind_dn': conf.get('ldap', 'service_bind_dn'), 'ldap_bind_pw': conf.get('ldap', 'service_bind_pw'), 'primary_domain': conf.get('kolab', 'primary_domain'), 'ldap_filter': "(|(mail=%m)(alias=%m))", 'ldap_base_dn': conf.get('ldap', 'base_dn'), 'clamdsock': '/var/spool/amavisd/clamd.sock', } template_file = None # On RPM installations, Amavis configuration is contained within a single file. amavisconf_paths = [ "/etc/amavisd.conf", "/etc/amavis/amavisd.conf", "/etc/amavisd/amavisd.conf" ] amavis_conf = '' for amavisconf_path in amavisconf_paths: if os.path.isfile(amavisconf_path): amavis_conf = amavisconf_path break if os.path.isfile(amavis_conf): if os.path.isfile('/etc/kolab/templates/amavisd.conf.tpl'): template_file = '/etc/kolab/templates/amavisd.conf.tpl' elif os.path.isfile('/usr/share/kolab/templates/amavisd.conf.tpl'): template_file = '/usr/share/kolab/templates/amavisd.conf.tpl' elif os.path.isfile( os.path.abspath( os.path.join(__file__, '..', '..', '..', 'share', 'templates', 'amavisd.conf.tpl'))): template_file = os.path.abspath( os.path.join(__file__, '..', '..', '..', 'share', 'templates', 'amavisd.conf.tpl')) if not template_file == None: fp = open(template_file, 'r') template_definition = fp.read() fp.close() if os.path.isfile('/etc/clamd.d/amavisd.conf'): amavisdconf_content = file('/etc/clamd.d/amavisd.conf') for line in amavisdconf_content: if line.startswith('LocalSocket'): amavisd_settings['clamdsock'] = line[len('LocalSocket ' ):].strip() t = Template(template_definition, searchList=[amavisd_settings]) fp = None fp = open(amavis_conf, 'w') if not fp == None: fp.write(t.__str__()) fp.close() else: log.error( _("Could not write out Amavis configuration file amavisd.conf") ) return # On APT installations, /etc/amavis/conf.d/ is a directory with many more files. # # Somebody could work on enhancement request #1080 to configure LDAP lookups, # while really it isn't required. else: log.info(_("Not writing out any configuration for Amavis.")) # On debian wheezy amavisd-new expects '/etc/mailname' - possibly remediable through # the #1080 enhancement mentioned above, but here's a quick fix. f = open('/etc/mailname', 'w') f.writelines(conf.get('kolab', 'primary_domain')) f.close() if os.path.isfile('/etc/default/spamassassin'): myaugeas = Augeas() setting = os.path.join('/files/etc/default/spamassassin', 'ENABLED') if not myaugeas.get(setting) == '1': myaugeas.set(setting, '1') myaugeas.save() myaugeas.close() if os.path.isfile('/etc/default/wallace'): myaugeas = Augeas() setting = os.path.join('/files/etc/default/wallace', 'START') if not myaugeas.get(setting) == 'yes': myaugeas.set(setting, 'yes') myaugeas.save() myaugeas.close() if os.path.isfile('/usr/lib/systemd/system/[email protected]'): from ConfigParser import SafeConfigParser unitfile = SafeConfigParser() unitfile.optionxform = str unitfile.read('/usr/lib/systemd/system/[email protected]') if not unitfile.has_section('Install'): unitfile.add_section('Install') if not unitfile.has_option('Install', 'WantedBy'): unitfile.set('Install', 'WantedBy', 'multi-user.target') with open('/etc/systemd/system/[email protected]', 'wb') as f: unitfile.write(f) log.info(_("Configuring and refreshing Anti-Virus...")) if os.path.isfile('/etc/kolab/templates/freshclam.conf.tpl'): shutil.copy('/etc/kolab/templates/freshclam.conf.tpl', '/etc/freshclam.conf') elif os.path.isfile('/usr/share/kolab/templates/freshclam.conf.tpl'): shutil.copy('/usr/share/kolab/templates/freshclam.conf.tpl', '/etc/freshclam.conf') else: log.error(_("Could not find a ClamAV update configuration file")) if os.path.isfile('/etc/freshclam.conf'): subprocess.call( ['/usr/bin/freshclam', '--quiet', '--datadir="/var/lib/clamav"']) amavisservice = 'amavisd.service' clamavservice = '*****@*****.**' if os.path.isfile('/usr/lib/systemd/system/amavis.service'): amavisservice = 'amavis.service' if os.path.isfile('/lib/systemd/system/amavis.service'): amavisservice = 'amavis.service' if os.path.isfile('/usr/lib/systemd/system/clamd.service'): clamavservice = 'clamd.service' if os.path.isfile('/lib/systemd/system/clamd.service'): clamavservice = 'clamd.service' if os.path.isfile('/lib/systemd/system/clamav-daemon.service'): clamavservice = 'clamav-daemon.service' if os.path.isfile('/bin/systemctl'): subprocess.call(['systemctl', 'restart', 'postfix.service']) subprocess.call(['systemctl', 'restart', amavisservice]) subprocess.call(['systemctl', 'restart', clamavservice]) subprocess.call(['systemctl', 'restart', 'wallace.service']) elif os.path.isfile('/sbin/service'): subprocess.call(['service', 'postfix', 'restart']) subprocess.call(['service', 'amavisd', 'restart']) subprocess.call(['service', 'clamd.amavisd', 'restart']) subprocess.call(['service', 'wallace', 'restart']) elif os.path.isfile('/usr/sbin/service'): subprocess.call(['/usr/sbin/service', 'postfix', 'restart']) subprocess.call(['/usr/sbin/service', 'amavis', 'restart']) subprocess.call(['/usr/sbin/service', 'clamav-daemon', 'restart']) subprocess.call(['/usr/sbin/service', 'wallace', 'restart']) else: log.error( _("Could not start the postfix, clamav and amavisd services services." )) if os.path.isfile('/bin/systemctl'): subprocess.call(['systemctl', 'enable', 'postfix.service']) subprocess.call(['systemctl', 'enable', amavisservice]) subprocess.call(['systemctl', 'enable', clamavservice]) subprocess.call(['systemctl', 'enable', 'wallace.service']) elif os.path.isfile('/sbin/chkconfig'): subprocess.call(['chkconfig', 'postfix', 'on']) subprocess.call(['chkconfig', 'amavisd', 'on']) subprocess.call(['chkconfig', 'clamd.amavisd', 'on']) subprocess.call(['chkconfig', 'wallace', 'on']) elif os.path.isfile('/usr/sbin/update-rc.d'): subprocess.call(['/usr/sbin/update-rc.d', 'postfix', 'defaults']) subprocess.call(['/usr/sbin/update-rc.d', 'amavis', 'defaults']) subprocess.call(['/usr/sbin/update-rc.d', 'clamav-daemon', 'defaults']) subprocess.call(['/usr/sbin/update-rc.d', 'wallace', 'defaults']) else: log.error(_("Could not configure to start on boot, the " + \ "postfix, clamav and amavisd services."))
def execute(*args, **kw): group_filter = conf.get('ldap','kolab_group_filter') if group_filter == None: group_filter = conf.get('ldap','group_filter') user_filter = conf.get('ldap','kolab_user_filter') if user_filter == None: user_filter = conf.get('ldap','user_filter') resource_filter = conf.get('ldap', 'resource_filter') sharedfolder_filter = conf.get('ldap', 'sharedfolder_filter') server_host = utils.parse_ldap_uri(conf.get('ldap', 'ldap_uri'))[1] files = { "/etc/postfix/ldap/local_recipient_maps.cf": """ server_host = %(server_host)s server_port = 389 version = 3 search_base = %(base_dn)s scope = sub domain = ldap:/etc/postfix/ldap/mydestination.cf bind_dn = %(service_bind_dn)s bind_pw = %(service_bind_pw)s query_filter = (&(|(mail=%%s)(alias=%%s))(|%(kolab_user_filter)s%(kolab_group_filter)s%(resource_filter)s%(sharedfolder_filter)s)) result_attribute = mail """ % { "base_dn": conf.get('ldap', 'base_dn'), "server_host": server_host, "service_bind_dn": conf.get('ldap', 'service_bind_dn'), "service_bind_pw": conf.get('ldap', 'service_bind_pw'), "kolab_user_filter": user_filter, "kolab_group_filter": group_filter, "resource_filter": resource_filter, "sharedfolder_filter": sharedfolder_filter, }, "/etc/postfix/ldap/mydestination.cf": """ server_host = %(server_host)s server_port = 389 version = 3 search_base = %(domain_base_dn)s scope = sub bind_dn = %(service_bind_dn)s bind_pw = %(service_bind_pw)s query_filter = %(domain_filter)s result_attribute = %(domain_name_attribute)s """ % { "server_host": server_host, "domain_base_dn": conf.get('ldap', 'domain_base_dn'), "domain_filter": conf.get('ldap', 'domain_filter').replace('*', '%s'), "domain_name_attribute": conf.get('ldap', 'domain_name_attribute'), "service_bind_dn": conf.get('ldap', 'service_bind_dn'), "service_bind_pw": conf.get('ldap', 'service_bind_pw'), }, "/etc/postfix/ldap/mailenabled_distgroups.cf": """ server_host = %(server_host)s server_port = 389 version = 3 search_base = %(group_base_dn)s scope = sub domain = ldap:/etc/postfix/ldap/mydestination.cf bind_dn = %(service_bind_dn)s bind_pw = %(service_bind_pw)s # This finds the mail enabled distribution group LDAP entry query_filter = (&(|(mail=%%s)(alias=%%s))(objectClass=kolabgroupofuniquenames)(objectclass=groupofuniquenames)(!(objectclass=groupofurls))) # From this type of group, get all uniqueMember DNs special_result_attribute = uniqueMember # Only from those DNs, get the mail result_attribute = leaf_result_attribute = mail """ % { "server_host": server_host, "group_base_dn": conf.get('ldap', 'group_base_dn'), "service_bind_dn": conf.get('ldap', 'service_bind_dn'), "service_bind_pw": conf.get('ldap', 'service_bind_pw'), }, "/etc/postfix/ldap/mailenabled_dynamic_distgroups.cf": """ server_host = %(server_host)s server_port = 389 version = 3 search_base = %(group_base_dn)s scope = sub domain = ldap:/etc/postfix/ldap/mydestination.cf bind_dn = %(service_bind_dn)s bind_pw = %(service_bind_pw)s # This finds the mail enabled dynamic distribution group LDAP entry query_filter = (&(|(mail=%%s)(alias=%%s))(objectClass=kolabgroupofuniquenames)(objectClass=groupOfURLs)) # From this type of group, get all memberURL searches/references special_result_attribute = memberURL # Only from those DNs, get the mail result_attribute = leaf_result_attribute = mail """ % { "server_host": server_host, "group_base_dn": conf.get('ldap', 'group_base_dn'), "service_bind_dn": conf.get('ldap', 'service_bind_dn'), "service_bind_pw": conf.get('ldap', 'service_bind_pw'), }, "/etc/postfix/ldap/transport_maps.cf": """ server_host = %(server_host)s server_port = 389 version = 3 search_base = %(base_dn)s scope = sub domain = ldap:/etc/postfix/ldap/mydestination.cf bind_dn = %(service_bind_dn)s bind_pw = %(service_bind_pw)s query_filter = (&(|(mailAlternateAddress=%%s)(alias=%%s)(mail=%%s))(objectclass=kolabinetorgperson)) result_attribute = mail result_format = lmtp:unix:/var/lib/imap/socket/lmtp """ % { "base_dn": conf.get('ldap', 'base_dn'), "server_host": server_host, "service_bind_dn": conf.get('ldap', 'service_bind_dn'), "service_bind_pw": conf.get('ldap', 'service_bind_pw'), }, "/etc/postfix/ldap/virtual_alias_maps.cf": """ server_host = %(server_host)s server_port = 389 version = 3 search_base = %(base_dn)s scope = sub domain = ldap:/etc/postfix/ldap/mydestination.cf bind_dn = %(service_bind_dn)s bind_pw = %(service_bind_pw)s query_filter = (&(|(mail=%%s)(alias=%%s))(objectclass=kolabinetorgperson)) result_attribute = mail """ % { "base_dn": conf.get('ldap', 'base_dn'), "server_host": server_host, "service_bind_dn": conf.get('ldap', 'service_bind_dn'), "service_bind_pw": conf.get('ldap', 'service_bind_pw'), }, "/etc/postfix/ldap/virtual_alias_maps_mailforwarding.cf": """ server_host = %(server_host)s server_port = 389 version = 3 search_base = %(base_dn)s scope = sub domain = ldap:/etc/postfix/ldap/mydestination.cf bind_dn = %(service_bind_dn)s bind_pw = %(service_bind_pw)s query_filter = (&(|(mail=%%s)(alias=%%s))(objectclass=mailrecipient)(objectclass=inetorgperson)(mailforwardingaddress=*)) result_attribute = mailForwardingAddress """ % { "base_dn": conf.get('ldap', 'base_dn'), "server_host": server_host, "service_bind_dn": conf.get('ldap', 'service_bind_dn'), "service_bind_pw": conf.get('ldap', 'service_bind_pw'), }, "/etc/postfix/ldap/virtual_alias_maps_sharedfolders.cf": """ server_host = %(server_host)s server_port = 389 version = 3 search_base = %(base_dn)s scope = sub domain = ldap:/etc/postfix/ldap/mydestination.cf bind_dn = %(service_bind_dn)s bind_pw = %(service_bind_pw)s query_filter = (&(|(mail=%%s)(alias=%%s))(objectclass=kolabsharedfolder)(kolabFolderType=mail)) result_attribute = kolabtargetfolder result_format = shared+%%s """ % { "base_dn": conf.get('ldap', 'base_dn'), "server_host": server_host, "service_bind_dn": conf.get('ldap', 'service_bind_dn'), "service_bind_pw": conf.get('ldap', 'service_bind_pw'), }, } if not os.path.isdir('/etc/postfix/ldap'): os.mkdir('/etc/postfix/ldap/', 0770) for filename in files.keys(): fp = open(filename, 'w') fp.write(files[filename]) fp.close() fp = open('/etc/postfix/transport', 'a') fp.write("\n# Shared Folder Delivery for %(domain)s:\nshared@%(domain)s\t\tlmtp:unix:/var/lib/imap/socket/lmtp\n" % {'domain': conf.get('kolab', 'primary_domain')}) fp.close() subprocess.call(["postmap", "/etc/postfix/transport"]) postfix_main_settings = { "inet_interfaces": "all", "recipient_delimiter": "+", "local_recipient_maps": "ldap:/etc/postfix/ldap/local_recipient_maps.cf", "mydestination": "ldap:/etc/postfix/ldap/mydestination.cf", "transport_maps": "ldap:/etc/postfix/ldap/transport_maps.cf, hash:/etc/postfix/transport", "virtual_alias_maps": "$alias_maps, ldap:/etc/postfix/ldap/virtual_alias_maps.cf, ldap:/etc/postfix/ldap/virtual_alias_maps_mailforwarding.cf, ldap:/etc/postfix/ldap/virtual_alias_maps_sharedfolders.cf, ldap:/etc/postfix/ldap/mailenabled_distgroups.cf, ldap:/etc/postfix/ldap/mailenabled_dynamic_distgroups.cf", "smtpd_tls_auth_only": "yes", "smtpd_tls_security_level": "may", "smtp_tls_security_level": "may", "smtpd_sasl_auth_enable": "yes", "smtpd_sender_login_maps": "$local_recipient_maps", "smtpd_sender_restrictions": "permit_mynetworks, reject_sender_login_mismatch", "smtpd_recipient_restrictions": "permit_mynetworks, reject_unauth_pipelining, reject_rbl_client zen.spamhaus.org, reject_non_fqdn_recipient, reject_invalid_helo_hostname, reject_unknown_recipient_domain, reject_unauth_destination, check_policy_service unix:private/recipient_policy_incoming, permit", "smtpd_sender_restrictions": "permit_mynetworks, check_policy_service unix:private/sender_policy_incoming", "submission_recipient_restrictions": "check_policy_service unix:private/submission_policy, permit_sasl_authenticated, reject", "submission_sender_restrictions": "reject_non_fqdn_sender, check_policy_service unix:private/submission_policy, permit_sasl_authenticated, reject", "submission_data_restrictions": "check_policy_service unix:private/submission_policy", "content_filter": "smtp-amavis:[127.0.0.1]:10024" } if os.path.isfile('/etc/pki/tls/certs/make-dummy-cert') and not os.path.isfile('/etc/pki/tls/private/localhost.pem'): subprocess.call(['/etc/pki/tls/certs/make-dummy-cert', '/etc/pki/tls/private/localhost.pem']) if os.path.isfile('/etc/pki/tls/private/localhost.pem'): postfix_main_settings['smtpd_tls_cert_file'] = "/etc/pki/tls/private/localhost.pem" postfix_main_settings['smtpd_tls_key_file'] = "/etc/pki/tls/private/localhost.pem" if not os.path.isfile('/etc/postfix/main.cf'): if os.path.isfile('/usr/share/postfix/main.cf.debian'): shutil.copy( '/usr/share/postfix/main.cf.debian', '/etc/postfix/main.cf' ) # Copy header checks files for hc_file in [ 'inbound', 'internal', 'submission' ]: if not os.path.isfile("/etc/postfix/header_checks.%s" % (hc_file)): if os.path.isfile('/etc/kolab/templates/header_checks.%s' % (hc_file)): input_file = '/etc/kolab/templates/header_checks.%s' % (hc_file) elif os.path.isfile('/usr/share/kolab/templates/header_checks.%s' % (hc_file)): input_file = '/usr/share/kolab/templates/header_checks.%s' % (hc_file) elif os.path.isfile(os.path.abspath(os.path.join(__file__, '..', '..', '..', 'share', 'templates', 'header_checks.%s' % (hc_file)))): input_file = os.path.abspath(os.path.join(__file__, '..', '..', '..', 'share', 'templates', 'header_checks.%s' % (hc_file))) shutil.copy(input_file, "/etc/postfix/header_checks.%s" % (hc_file)) subprocess.call(["postmap", "/etc/postfix/header_checks.%s" % (hc_file)]) myaugeas = Augeas() setting_base = '/files/etc/postfix/main.cf/' for setting_key in postfix_main_settings.keys(): setting = os.path.join(setting_base,setting_key) current_value = myaugeas.get(setting) if current_value == None: try: myaugeas.set(setting, postfix_main_settings[setting_key]) except: insert_paths = myaugeas.match('/files/etc/postfix/main.cf/*') insert_path = insert_paths[(len(insert_paths)-1)] myaugeas.insert(insert_path, setting_key, False) log.debug(_("Setting key %r to %r") % (setting_key, postfix_main_settings[setting_key]), level=8) myaugeas.set(setting, postfix_main_settings[setting_key]) myaugeas.save() postfix_master_settings = { } if os.path.exists('/usr/lib/postfix/kolab_smtp_access_policy'): postfix_master_settings['kolab_sap_executable_path'] = '/usr/lib/postfix/kolab_smtp_access_policy' else: postfix_master_settings['kolab_sap_executable_path'] = '/usr/libexec/postfix/kolab_smtp_access_policy' template_file = None if os.path.isfile('/etc/kolab/templates/master.cf.tpl'): template_file = '/etc/kolab/templates/master.cf.tpl' elif os.path.isfile('/usr/share/kolab/templates/master.cf.tpl'): template_file = '/usr/share/kolab/templates/master.cf.tpl' elif os.path.isfile(os.path.abspath(os.path.join(__file__, '..', '..', '..', 'share', 'templates', 'master.cf.tpl'))): template_file = os.path.abspath(os.path.join(__file__, '..', '..', '..', 'share', 'templates', 'master.cf.tpl')) if not template_file == None: fp = open(template_file, 'r') template_definition = fp.read() fp.close() t = Template(template_definition, searchList=[postfix_master_settings]) fp = open('/etc/postfix/master.cf', 'w') fp.write(t.__str__()) fp.close() else: log.error(_("Could not write out Postfix configuration file /etc/postfix/master.cf")) return if os.path.isdir('/etc/postfix/sasl/'): fp = open('/etc/postfix/sasl/smtpd.conf', 'w') fp.write("pwcheck_method: saslauthd\n") fp.write("mech_list: plain login\n") fp.close() amavisd_settings = { 'ldap_server': '%(server_host)s', 'ldap_bind_dn': conf.get('ldap', 'service_bind_dn'), 'ldap_bind_pw': conf.get('ldap', 'service_bind_pw'), 'primary_domain': conf.get('kolab', 'primary_domain'), 'ldap_filter': "(|(mail=%m)(alias=%m))", 'ldap_base_dn': conf.get('ldap', 'base_dn'), } template_file = None # On RPM installations, Amavis configuration is contained within a single file. if os.path.isfile("/etc/amavisd/amavisd.conf"): if os.path.isfile('/etc/kolab/templates/amavisd.conf.tpl'): template_file = '/etc/kolab/templates/amavisd.conf.tpl' elif os.path.isfile('/usr/share/kolab/templates/amavisd.conf.tpl'): template_file = '/usr/share/kolab/templates/amavisd.conf.tpl' elif os.path.isfile(os.path.abspath(os.path.join(__file__, '..', '..', '..', 'share', 'templates', 'amavisd.conf.tpl'))): template_file = os.path.abspath(os.path.join(__file__, '..', '..', '..', 'share', 'templates', 'amavisd.conf.tpl')) if not template_file == None: fp = open(template_file, 'r') template_definition = fp.read() fp.close() t = Template(template_definition, searchList=[amavisd_settings]) fp = None if os.path.isdir('/etc/amavisd'): fp = open('/etc/amavisd/amavisd.conf', 'w') elif os.path.isdir('/etc/amavis'): fp = open('/etc/amavis/amavisd.conf', 'w') elif os.path.isfile('/etc/amavisd.conf'): fp = open('/etc/amavisd.conf', 'w') if not fp == None: fp.write(t.__str__()) fp.close() else: log.error(_("Could not write out Amavis configuration file amavisd.conf")) return # On APT installations, /etc/amavis/conf.d/ is a directory with many more files. # # Somebody could work on enhancement request #1080 to configure LDAP lookups, # while really it isn't required. else: log.info(_("Not writing out any configuration for Amavis.")) # On debian wheezy amavisd-new expects '/etc/mailname' - possibly remediable through # the #1080 enhancement mentioned above, but here's a quick fix. f = open('/etc/mailname','w') f.writelines(conf.get('kolab', 'primary_domain')) f.close() if os.path.isfile('/etc/default/spamassassin'): myaugeas = Augeas() setting = os.path.join('/files/etc/default/spamassassin','ENABLED') if not myaugeas.get(setting) == '1': myaugeas.set(setting,'1') myaugeas.save() myaugeas.close() if os.path.isfile('/etc/default/wallace'): myaugeas = Augeas() setting = os.path.join('/files/etc/default/wallace','START') if not myaugeas.get(setting) == 'yes': myaugeas.set(setting,'yes') myaugeas.save() myaugeas.close() if os.path.isfile('/bin/systemctl'): subprocess.call(['systemctl', 'restart', 'postfix.service']) subprocess.call(['systemctl', 'restart', 'amavisd.service']) subprocess.call(['systemctl', 'restart', '*****@*****.**']) subprocess.call(['systemctl', 'restart', 'wallace.service']) elif os.path.isfile('/sbin/service'): subprocess.call(['service', 'postfix', 'restart']) subprocess.call(['service', 'amavisd', 'restart']) subprocess.call(['service', 'clamd.amavisd', 'restart']) subprocess.call(['service', 'wallace', 'restart']) elif os.path.isfile('/usr/sbin/service'): subprocess.call(['/usr/sbin/service','postfix','restart']) subprocess.call(['/usr/sbin/service','amavis','restart']) subprocess.call(['/usr/sbin/service','clamav-daemon','restart']) subprocess.call(['/usr/sbin/service','wallace','restart']) else: log.error(_("Could not start the postfix, clamav and amavisd services services.")) if os.path.isfile('/bin/systemctl'): subprocess.call(['systemctl', 'enable', 'postfix.service']) subprocess.call(['systemctl', 'enable', 'amavisd.service']) subprocess.call(['systemctl', 'enable', '*****@*****.**']) subprocess.call(['systemctl', 'enable', 'wallace.service']) elif os.path.isfile('/sbin/chkconfig'): subprocess.call(['chkconfig', 'postfix', 'on']) subprocess.call(['chkconfig', 'amavisd', 'on']) subprocess.call(['chkconfig', 'clamd.amavisd', 'on']) subprocess.call(['chkconfig', 'wallace', 'on']) elif os.path.isfile('/usr/sbin/update-rc.d'): subprocess.call(['/usr/sbin/update-rc.d', 'postfix', 'defaults']) subprocess.call(['/usr/sbin/update-rc.d', 'amavis', 'defaults']) subprocess.call(['/usr/sbin/update-rc.d', 'clamav-daemon', 'defaults']) subprocess.call(['/usr/sbin/update-rc.d', 'wallace', 'defaults']) else: log.error(_("Could not configure to start on boot, the " + \ "postfix, clamav and amavisd services."))