osx-attr: Optionally replace existing DNS server instead of appending them
authorMartin Willi <martin@revosec.ch>
Tue, 24 Mar 2015 13:14:20 +0000 (14:14 +0100)
committerMartin Willi <martin@revosec.ch>
Thu, 18 Jun 2015 08:36:04 +0000 (10:36 +0200)
src/libcharon/plugins/osx_attr/osx_attr_handler.c

index d974b57..6baf76d 100644 (file)
@@ -31,6 +31,16 @@ struct private_osx_attr_handler_t {
         * Public interface
         */
        osx_attr_handler_t public;
+
+       /**
+        * Backup of original DNS servers, before we mess with it
+        */
+       CFMutableArrayRef original;
+
+       /**
+        * Append DNS servers to existing entries, instead of replacing
+        */
+       bool append;
 };
 
 /**
@@ -110,7 +120,8 @@ static CFMutableArrayRef get_array_from_dict(CFDictionaryRef dict,
 /**
  * Add/Remove a DNS server to the configuration
  */
-static bool manage_dns(int family, chunk_t data, bool add)
+static bool manage_dns(private_osx_attr_handler_t *this,
+                                          int family, chunk_t data, bool add)
 {
        SCDynamicStoreRef store;
        CFStringRef path, dns;
@@ -138,6 +149,11 @@ static bool manage_dns(int family, chunk_t data, bool add)
                dns = CFStringCreateWithCString(NULL, buf, kCFStringEncodingUTF8);
                if (add)
                {
+                       if (!this->append && !this->original)
+                       {       /* backup orignal config, start with empty set */
+                               this->original = arr;
+                               arr = CFArrayCreateMutable(NULL, 0, &kCFTypeArrayCallBacks);
+                       }
                        DBG1(DBG_CFG, "installing %s as DNS server", buf);
                        CFArrayInsertValueAtIndex(arr, 0, dns);
                }
@@ -150,6 +166,12 @@ static bool manage_dns(int family, chunk_t data, bool add)
                                DBG1(DBG_CFG, "removing %s from DNS servers (%d)", buf, i);
                                CFArrayRemoveValueAtIndex(arr, i);
                        }
+                       if (!this->append && this->original && CFArrayGetCount(arr) == 0)
+                       {       /* restore original config */
+                               CFRelease(arr);
+                               arr = this->original;
+                               this->original = NULL;
+                       }
                }
                CFRelease(dns);
                CFDictionarySetValue(dict, CFSTR("ServerAddresses"), arr);
@@ -175,7 +197,7 @@ METHOD(attribute_handler_t, handle, bool,
        switch (type)
        {
                case INTERNAL_IP4_DNS:
-                       return manage_dns(AF_INET, data, TRUE);
+                       return manage_dns(this, AF_INET, data, TRUE);
                default:
                        return FALSE;
        }
@@ -188,7 +210,7 @@ METHOD(attribute_handler_t, release, void,
        switch (type)
        {
                case INTERNAL_IP4_DNS:
-                       manage_dns(AF_INET, data, FALSE);
+                       manage_dns(this, AF_INET, data, FALSE);
                        break;
                default:
                        break;
@@ -240,6 +262,8 @@ osx_attr_handler_t *osx_attr_handler_create()
                        },
                        .destroy = _destroy,
                },
+               .append = lib->settings->get_bool(lib->settings,
+                                                               "%s.plugins.osx-attr.append", TRUE, lib->ns),
        );
 
        return &this->public;