Print this page
OS-4348 libnsl should seek netconfig file in native root
Reviewed by: Robert Mustacchi <rm@joyent.com>
OS-3812 lxbrand nfs mounting fails

@@ -20,10 +20,11 @@
  */
 
 /*
  * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
  * Use is subject to license terms.
+ * Copyright 2015 Joyent, Inc.
  */
 
 /*      Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T     */
 /*        All Rights Reserved   */
 

@@ -30,12 +31,10 @@
 /*
  * Portions of this source code were derived from Berkeley 4.3 BSD
  * under license from the Regents of the University of California.
  */
 
-#pragma ident   "%Z%%M% %I%     %E% SMI"
-
 #include "mt.h"
 #include "../rpc/rpc_mt.h"              /* for MT declarations only */
 #include <rpc/types.h>
 #include <stdio.h>
 #include <stdlib.h>

@@ -43,10 +42,11 @@
 #include <ctype.h>
 #include <netconfig.h>
 #include <malloc.h>
 #include <libintl.h>
 #include <syslog.h>
+#include <zone.h>
 #include "netcspace.h"
 
 #define FAILURE  (unsigned)(-1)
 
 /*

@@ -68,10 +68,13 @@
 static void free_entry(void *);
 static struct netconfig *netconfig_dup(struct netconfig *);
 
 extern const char __nsl_dom[];
 
+static int (*brand_get_sz)(void) = NULL;
+static struct netconfig *(*brand_get_net_ent)(int) = NULL;
+
 /*
  *      Static global variables used by the library procedures:
  *
  *      netpp - points to the beginning of the list of netconfig
  *              entries used by setnetconfig() and setnetpath().

@@ -253,10 +256,18 @@
 freenetconfigent(struct netconfig *netp)
 {
         netconfig_free(netp);
 }
 
+void
+_nsl_brand_set_hooks(int (*set_sz_func)(void),
+    struct netconfig *(*get_ent_func)(int))
+{
+        brand_get_sz = set_sz_func;
+        brand_get_net_ent = get_ent_func;
+}
+
 /*
  *      getnetlist() reads the netconfig file and creates a
  *      NULL-terminated list of entries.
  *      Returns the pointer to the head of the list or a NULL
  *      on failure.

@@ -263,17 +274,30 @@
  */
 
 static struct netconfig **
 getnetlist(void)
 {
-        char line[BUFSIZ];      /* holds each line of NETCONFIG */
-        FILE *fp;               /* file stream for NETCONFIG */
+        FILE *fp = NULL;        /* file stream for NETCONFIG */
         struct netconfig **listpp; /* the beginning of the netconfig list */
         struct netconfig **tpp; /* used to traverse the netconfig list */
         int count;              /* the number of entries in file */
+        char nc_path[MAXPATHLEN];
+        const char *zroot = zone_get_nroot();
 
-        if ((fp = fopen(NETCONFIG, "rF")) == NULL) {
+        /*
+         * If we are running in a branded zone, ensure we use the "/native"
+         * prefix when opening the netconfig file:
+         */
+        (void) snprintf(nc_path, sizeof (nc_path), "%s%s", zroot != NULL ?
+            zroot : "", NETCONFIG);
+
+        if (brand_get_sz != NULL) {
+                count = brand_get_sz();
+        } else {
+                char line[BUFSIZ];      /* holds each line of NETCONFIG */
+
+                if ((fp = fopen(nc_path, "rF")) == NULL) {
                 nc_error = NC_OPENFAIL;
                 return (NULL);
         }
 
         count = 0;

@@ -281,23 +305,38 @@
                 if (!(blank(line) || comment(line))) {
                         ++count;
                 }
         }
         rewind(fp);
+        }
 
         if (count == 0) {
                 nc_error = NC_NOTFOUND;
+                if (fp != NULL)
                 (void) fclose(fp);
                 return (NULL);
         }
+
         if ((listpp = malloc((count + 1) *
             sizeof (struct netconfig *))) == NULL) {
                 nc_error = NC_NOMEM;
+                if (fp != NULL)
                 (void) fclose(fp);
                 return (NULL);
         }
 
+        if (brand_get_net_ent != NULL) {
+                int i;
+
+                tpp = listpp;
+                for (i = 0; i < count; i++) {
+                        *tpp = brand_get_net_ent(i);
+                        tpp++;
+                }
+                *tpp = NULL;
+                nc_error = NC_NOMOREENTRIES;
+        } else {
         /*
          *      The following loop fills in the list (loops until
          *      fgetnetconfig() returns a NULL) and counts the
          *      number of entries placed in the list.  Note that
          *      when the loop is completed, the last entry in the

@@ -309,10 +348,12 @@
                 ;
         (void) fclose(fp);
 
         if (nc_error != NC_NOMOREENTRIES) /* Something is screwed up */
                 netlist_free(&listpp);
+        }
+
         return (listpp);
 }
 
 /*
  *      fgetnetconfig() parses a line of the netconfig file into