]> git.ipfire.org Git - thirdparty/bind9.git/commitdiff
3707. [bug] irs_resconf_load now returns ISC_R_FILENOTFOUND
authorMark Andrews <marka@isc.org>
Wed, 15 Jan 2014 04:22:55 +0000 (15:22 +1100)
committerMark Andrews <marka@isc.org>
Wed, 15 Jan 2014 04:22:55 +0000 (15:22 +1100)
                        on a missing resolv.conf file and initializes the
                        structure as if it had been configured with:

                                nameserver ::1
                                nameserver 127.0.0.1

                        Note: Callers will need to be updated to treat
                        ISC_R_FILENOTFOUND as a qualified success or else
                        they will leak memory. The following code fragment
                        will work with both only and new versions without
                        changing the behaviour of the existing code.

                        resconf = NULL;
                        result = irs_resconf_load(mctx, "/etc/resolv.conf",
                                                  &resconf);
                        if (result != ISC_SUCCESS) {
                                if (resconf != NULL)
                                        irs_resconf_destroy(&resconf);
                                ....
                        }

                        [RT #35194]

CHANGES
lib/irs/include/irs/resconf.h
lib/irs/resconf.c
lib/samples/resolve.c

diff --git a/CHANGES b/CHANGES
index b619125c9f2f5680f01f8b487b00817d8ca77561..d0668454396694981c4852514a4f206e77ddb4b9 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -1,3 +1,27 @@
+3707.  [bug]           irs_resconf_load now returns ISC_R_FILENOTFOUND
+                       on a missing resolv.conf file and initializes the
+                       structure as if it had been configured with:
+
+                               nameserver ::1
+                               nameserver 127.0.0.1
+
+                       Note: Callers will need to be updated to treat
+                       ISC_R_FILENOTFOUND as a qualified success or else
+                       they will leak memory. The following code fragment
+                       will work with both only and new versions without
+                       changing the behaviour of the existing code.
+
+                       resconf = NULL;
+                       result = irs_resconf_load(mctx, "/etc/resolv.conf",
+                                                 &resconf);
+                       if (result != ISC_SUCCESS) {
+                               if (resconf != NULL)
+                                       irs_resconf_destroy(&resconf);
+                               ....
+                       }
+
+                       [RT #35194]
+
 3706.  [contrib]       queryperf: Fixed a possible integer overflow when
                        printing results. [RT #35182]
 
index 78c87d51660d4909f9a1d1e96ab31a9c3dd64276..c6c6e851bc4dbd48630a6efe1ab0063e915a1710 100644 (file)
@@ -46,7 +46,12 @@ isc_result_t
 irs_resconf_load(isc_mem_t *mctx, const char *filename, irs_resconf_t **confp);
 /*%<
  * Load the resolver configuration file 'filename' in the "resolv.conf" format,
- * and create a new irs_resconf_t object from the configuration.
+ * and create a new irs_resconf_t object from the configuration.  If the file
+ * is not found ISC_R_FILENOTFOUND is returned with the structure initialized
+ * as if file contained only:
+ *
+ *     nameserver ::1
+ *     nameserver 127.0.0.1
  *
  * Notes:
  *
@@ -55,6 +60,11 @@ irs_resconf_load(isc_mem_t *mctx, const char *filename, irs_resconf_t **confp);
  *     In addition, 'sortlist' is not actually effective; it's parsed, but
  *     the application cannot use the configuration.
  *
+ * Returns:
+ * \li ISC_R_SUCCESS on success
+ * \li  ISC_R_FILENOTFOUND if the file was not found. *confp will be valid.
+ * \li  other on error.
+ *
  * Requires:
  *
  *\li  'mctx' is a valid memory context.
index 15a46baf3fbe462faa2a4798c79bc7eb5c440130..29cfb75fef6e67e65652270203feb741be45a8b7 100644 (file)
@@ -507,45 +507,50 @@ irs_resconf_load(isc_mem_t *mctx, const char *filename, irs_resconf_t **confp)
                conf->search[i] = NULL;
 
        errno = 0;
-       if ((fp = fopen(filename, "r")) == NULL) {
-               isc_mem_put(mctx, conf, sizeof(*conf));
-               return (ISC_R_INVALIDFILE);
-       }
-
-       ret = ISC_R_SUCCESS;
-       do {
-               stopchar = getword(fp, word, sizeof(word));
-               if (stopchar == EOF) {
-                       rval = ISC_R_SUCCESS;
-                       POST(rval);
-                       break;
-               }
-
-               if (strlen(word) == 0U)
-                       rval = ISC_R_SUCCESS;
-               else if (strcmp(word, "nameserver") == 0)
-                       rval = resconf_parsenameserver(conf, fp);
-               else if (strcmp(word, "domain") == 0)
-                       rval = resconf_parsedomain(conf, fp);
-               else if (strcmp(word, "search") == 0)
-                       rval = resconf_parsesearch(conf, fp);
-               else if (strcmp(word, "sortlist") == 0)
-                       rval = resconf_parsesortlist(conf, fp);
-               else if (strcmp(word, "options") == 0)
-                       rval = resconf_parseoption(conf, fp);
-               else {
-                       /* unrecognised word. Ignore entire line */
-                       rval = ISC_R_SUCCESS;
-                       stopchar = eatline(fp);
+       if ((fp = fopen(filename, "r")) != NULL) {
+               ret = ISC_R_SUCCESS;
+               do {
+                       stopchar = getword(fp, word, sizeof(word));
                        if (stopchar == EOF) {
+                               rval = ISC_R_SUCCESS;
+                               POST(rval);
                                break;
                        }
-               }
-               if (ret == ISC_R_SUCCESS && rval != ISC_R_SUCCESS)
-                       ret = rval;
-       } while (1);
 
-       fclose(fp);
+                       if (strlen(word) == 0U)
+                               rval = ISC_R_SUCCESS;
+                       else if (strcmp(word, "nameserver") == 0)
+                               rval = resconf_parsenameserver(conf, fp);
+                       else if (strcmp(word, "domain") == 0)
+                               rval = resconf_parsedomain(conf, fp);
+                       else if (strcmp(word, "search") == 0)
+                               rval = resconf_parsesearch(conf, fp);
+                       else if (strcmp(word, "sortlist") == 0)
+                               rval = resconf_parsesortlist(conf, fp);
+                       else if (strcmp(word, "options") == 0)
+                               rval = resconf_parseoption(conf, fp);
+                       else {
+                               /* unrecognised word. Ignore entire line */
+                               rval = ISC_R_SUCCESS;
+                               stopchar = eatline(fp);
+                               if (stopchar == EOF) {
+                                       break;
+                               }
+                       }
+                       if (ret == ISC_R_SUCCESS && rval != ISC_R_SUCCESS)
+                               ret = rval;
+               } while (1);
+
+               fclose(fp);
+       } else {
+               switch (errno) {
+               case ENOENT:
+                       break;
+               default:
+                       isc_mem_put(mctx, conf, sizeof(*conf));
+                       return (ISC_R_INVALIDFILE);
+               }
+       }
 
        /* If we don't find a nameserver fall back to localhost */
        if (conf->numns == 0) {
@@ -575,8 +580,11 @@ irs_resconf_load(isc_mem_t *mctx, const char *filename, irs_resconf_t **confp)
 
        if (ret != ISC_R_SUCCESS)
                irs_resconf_destroy(&conf);
-       else
+       else {
+               if (fp == NULL)
+                       ret = ISC_R_FILENOTFOUND;
                *confp = conf;
+       }
 
        return (ret);
 }
index 95475ebb2136a0f42ba9104326344c26301655b8..278e0e292df61dc6a74110629945899c263c6f9c 100644 (file)
@@ -401,7 +401,7 @@ main(int argc, char *argv[]) {
                isc_sockaddrlist_t *nameservers;
 
                result = irs_resconf_load(mctx, "/etc/resolv.conf", &resconf);
-               if (result != ISC_R_SUCCESS) {
+               if (result != ISC_R_SUCCESS && result != ISC_R_FILENOTFOUND) {
                        fprintf(stderr, "irs_resconf_load failed: %d\n",
                                result);
                        exit(1);