OwlCyberSecurity - MANAGER
Edit File: changeip_calendar.py
#!/usr/bin/env python # # changeip script for calendar server # # Copyright (c) 2005-2017 Apple Inc. All Rights Reserved. # # IMPORTANT NOTE: This file is licensed only for use on Apple-labeled # computers and is subject to the terms and conditions of the Apple # Software License Agreement accompanying the package this file is a # part of. You may not port this file to another platform without # Apple's written consent. from __future__ import print_function from __future__ import with_statement import datetime from getopt import getopt, GetoptError import os import plistlib import subprocess import sys SERVER_APP_ROOT = "/Applications/Server.app/Contents/ServerRoot" CALENDARSERVER_CONFIG = "%s/usr/sbin/calendarserver_config" % (SERVER_APP_ROOT,) def serverRootLocation(): """ Return the ServerRoot value from the servermgr_calendar.plist. If not present, return the default. """ plist = "/Library/Server/Preferences/Calendar.plist" serverRoot = u"/Library/Server/Calendar and Contacts" if os.path.exists(plist): serverRoot = plistlib.readPlist(plist).get("ServerRoot", serverRoot) return serverRoot def usage(): name = os.path.basename(sys.argv[0]) print("Usage: %s [-hv] old-ip new-ip [old-hostname new-hostname]" % (name,)) print(" Options:") print(" -h - print this message and exit") print(" -f <file> - path to config file") print(" Arguments:") print(" old-ip - current IPv4 address of the server") print(" new-ip - new IPv4 address of the server") print(" old-hostname - current FQDN for the server") print(" new-hostname - new FQDN for the server") def log(msg): serverRoot = serverRootLocation() logDir = os.path.join(serverRoot, "Logs") logFile = os.path.join(logDir, "changeip.log") try: timestamp = datetime.datetime.now().strftime("%b %d %H:%M:%S") msg = "changeip_calendar: %s %s" % (timestamp, msg) with open(logFile, 'a') as output: output.write("%s\n" % (msg,)) except IOError: # Could not write to log pass def main(): name = os.path.basename(sys.argv[0]) # Since the serveradmin command must be run as root, so must this script if os.getuid() != 0: print("%s must be run as root" % (name,)) sys.exit(1) try: (optargs, args) = getopt( sys.argv[1:], "hf:", [ "help", "config=", ] ) except GetoptError: usage() sys.exit(1) configFile = None for opt, arg in optargs: if opt in ("-h", "--help"): usage() sys.exit(1) elif opt in ("-f", "--config"): configFile = arg oldIP, newIP = args[0:2] try: oldHostname, newHostname = args[2:4] except ValueError: oldHostname = newHostname = None log("args: {}".format(args)) config = readConfig(configFile=configFile) updateConfig( config, oldIP, newIP, oldHostname, newHostname ) writeConfig(config) def sendCommand(commandDict, configFile=None): args = [CALENDARSERVER_CONFIG] if configFile is not None: args.append("-f {}".format(configFile)) child = subprocess.Popen( args=args, stdin=subprocess.PIPE, stdout=subprocess.PIPE, stderr=subprocess.PIPE, ) commandString = plistlib.writePlistToString(commandDict) log("Sending to calendarserver_config: {}".format(commandString)) output, error = child.communicate(input=commandString) log("Output from calendarserver_config: {}".format(output)) if child.returncode: log( "Error from calendarserver_config: {}, {}".format( child.returncode, error ) ) return None else: return plistlib.readPlistFromString(output)["result"] def readConfig(configFile=None): """ Ask calendarserver_config for the current configuration """ command = { "command": "readConfig" } return sendCommand(command) def writeConfig(valuesDict, configFile=None): """ Ask calendarserver_config to update the configuration """ command = { "command": "writeConfig", "Values": valuesDict, } return sendCommand(command) def updateConfig( config, oldIP, newIP, oldHostname, newHostname, configFile=None ): keys = ( ("Scheduling", "iMIP", "Receiving", "Server"), ("Scheduling", "iMIP", "Sending", "Server"), ("Scheduling", "iMIP", "Sending", "Address"), ("ServerHostName",), ) def _replace(value, oldIP, newIP, oldHostname, newHostname): newValue = value.replace(oldIP, newIP) if oldHostname and newHostname: newValue = newValue.replace(oldHostname, newHostname) if value != newValue: log("Changed %s -> %s" % (value, newValue)) return newValue for keyPath in keys: parent = config path = keyPath[:-1] key = keyPath[-1] for step in path: if step not in parent: parent = None break parent = parent[step] if parent: if key in parent: value = parent[key] if isinstance(value, list): newValue = [] for item in value: item = _replace( item, oldIP, newIP, oldHostname, newHostname ) newValue.append(item) else: newValue = _replace( value, oldIP, newIP, oldHostname, newHostname ) parent[key] = newValue if __name__ == '__main__': main()