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


   5  * Common Development and Distribution License (the "License").
   6  * You may not use this file except in compliance with the License.
   7  *
   8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9  * or http://www.opensolaris.org/os/licensing.
  10  * See the License for the specific language governing permissions
  11  * and limitations under the License.
  12  *
  13  * When distributing Covered Code, include this CDDL HEADER in each
  14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15  * If applicable, add the following below this CDDL HEADER, with the
  16  * fields enclosed by brackets "[]" replaced with your own identifying
  17  * information: Portions Copyright [yyyy] [name of copyright owner]
  18  *
  19  * CDDL HEADER END
  20  */
  21 
  22 /*
  23  * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
  24  * Use is subject to license terms.

  25  */
  26 
  27 /*      Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T */
  28 /*        All Rights Reserved   */
  29 
  30 /*
  31  * Portions of this source code were derived from Berkeley 4.3 BSD
  32  * under license from the Regents of the University of California.
  33  */
  34 
  35 #pragma ident   "%Z%%M% %I%     %E% SMI"
  36 
  37 #include "mt.h"
  38 #include "../rpc/rpc_mt.h"              /* for MT declarations only */
  39 #include <rpc/types.h>
  40 #include <stdio.h>
  41 #include <stdlib.h>
  42 #include <string.h>
  43 #include <ctype.h>
  44 #include <netconfig.h>
  45 #include <malloc.h>
  46 #include <libintl.h>
  47 #include <syslog.h>

  48 #include "netcspace.h"
  49 
  50 #define FAILURE  (unsigned)(-1)
  51 
  52 /*
  53  *      Local routines used by the library procedures
  54  */
  55 
  56 static int blank(char *);
  57 static int comment(char *);
  58 static struct netconfig *fgetnetconfig(FILE *, char *);
  59 static void netconfig_free(struct netconfig *);
  60 static unsigned int getflag(char *);
  61 static char **getlookups(char *);
  62 static struct netconfig **getnetlist(void);
  63 static unsigned int getnlookups(char *);
  64 static char *gettoken(char *, int);
  65 static unsigned int getvalue(char *, struct nc_data nc_data[]);
  66 static void shift1left(char *);
  67 static void netlist_free(struct netconfig ***);
  68 static void free_entry(void *);
  69 static struct netconfig *netconfig_dup(struct netconfig *);
  70 
  71 extern const char __nsl_dom[];
  72 



  73 /*
  74  *      Static global variables used by the library procedures:
  75  *
  76  *      netpp - points to the beginning of the list of netconfig
  77  *              entries used by setnetconfig() and setnetpath().
  78  *              Once netpp is initialized, that memory is *never*
  79  *              released.  This was necessary to improve performance.
  80  *
  81  *      linenum - the current line number of the /etc/netconfig
  82  *                file (used for debugging and for nc_perror()).
  83  *
  84  *      fieldnum - the current field number of the current line
  85  *                 of /etc/netconfig (used for debugging and for
  86  *                 nc_perror()).
  87  *
  88  *      nc_error - the error condition encountered.
  89  */
  90 
  91 static struct netconfig **netpp = NULL;
  92 mutex_t netpp_mutex = DEFAULTMUTEX;


 238                                         return (NULL);
 239                                 }
 240                         }
 241                         return (netconfig_dup(*tpp));
 242                 }
 243         }
 244         nc_error = NC_NOTFOUND;
 245         return (NULL);
 246 }
 247 
 248 /*
 249  *      freenetconfigent frees the data allocated by getnetconfigent()
 250  */
 251 
 252 void
 253 freenetconfigent(struct netconfig *netp)
 254 {
 255         netconfig_free(netp);
 256 }
 257 








 258 /*
 259  *      getnetlist() reads the netconfig file and creates a
 260  *      NULL-terminated list of entries.
 261  *      Returns the pointer to the head of the list or a NULL
 262  *      on failure.
 263  */
 264 
 265 static struct netconfig **
 266 getnetlist(void)
 267 {
 268         char line[BUFSIZ];      /* holds each line of NETCONFIG */
 269         FILE *fp;               /* file stream for NETCONFIG */
 270         struct netconfig **listpp; /* the beginning of the netconfig list */
 271         struct netconfig **tpp; /* used to traverse the netconfig list */
 272         int count;              /* the number of entries in file */


 273 
 274         if ((fp = fopen(NETCONFIG, "rF")) == NULL) {












 275                 nc_error = NC_OPENFAIL;
 276                 return (NULL);
 277         }
 278 
 279         count = 0;
 280         while (fgets(line, BUFSIZ, fp)) {
 281                 if (!(blank(line) || comment(line))) {
 282                         ++count;
 283                 }
 284         }
 285         rewind(fp);

 286 
 287         if (count == 0) {
 288                 nc_error = NC_NOTFOUND;

 289                 (void) fclose(fp);
 290                 return (NULL);
 291         }

 292         if ((listpp = malloc((count + 1) *
 293             sizeof (struct netconfig *))) == NULL) {
 294                 nc_error = NC_NOMEM;

 295                 (void) fclose(fp);
 296                 return (NULL);
 297         }
 298 











 299         /*
 300          *      The following loop fills in the list (loops until
 301          *      fgetnetconfig() returns a NULL) and counts the
 302          *      number of entries placed in the list.  Note that
 303          *      when the loop is completed, the last entry in the
 304          *      list will contain a NULL (signifying the end of
 305          *      the list).
 306          */
 307         linenum = 0;
 308         for (tpp = listpp; *tpp = fgetnetconfig(fp, NULL); tpp++)
 309                 ;
 310         (void) fclose(fp);
 311 
 312         if (nc_error != NC_NOMOREENTRIES) /* Something is screwed up */
 313                 netlist_free(&listpp);


 314         return (listpp);
 315 }
 316 
 317 /*
 318  *      fgetnetconfig() parses a line of the netconfig file into
 319  *      a netconfig structure.  It returns a pointer to the
 320  *      structure of success and a NULL on failure or EOF.
 321  */
 322 
 323 static struct netconfig *
 324 fgetnetconfig(FILE *fp, char *netid)
 325 {
 326         char linep[BUFSIZ];     /* pointer to a line in the file */
 327         struct netconfig *netconfigp; /* holds the new netconfig structure */
 328         char  *tok1, *tok2, *tok3; /* holds a token from the line */
 329         char  *retvalp;         /* the return value of fgets() */
 330         char *entnetid;         /* netid for the current entry */
 331 
 332         /* skip past blank lines and comments. */
 333         while (retvalp = fgets(linep, BUFSIZ, fp)) {




   5  * Common Development and Distribution License (the "License").
   6  * You may not use this file except in compliance with the License.
   7  *
   8  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
   9  * or http://www.opensolaris.org/os/licensing.
  10  * See the License for the specific language governing permissions
  11  * and limitations under the License.
  12  *
  13  * When distributing Covered Code, include this CDDL HEADER in each
  14  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15  * If applicable, add the following below this CDDL HEADER, with the
  16  * fields enclosed by brackets "[]" replaced with your own identifying
  17  * information: Portions Copyright [yyyy] [name of copyright owner]
  18  *
  19  * CDDL HEADER END
  20  */
  21 
  22 /*
  23  * Copyright 2007 Sun Microsystems, Inc.  All rights reserved.
  24  * Use is subject to license terms.
  25  * Copyright 2015 Joyent, Inc.
  26  */
  27 
  28 /*      Copyright (c) 1983, 1984, 1985, 1986, 1987, 1988, 1989 AT&T */
  29 /*        All Rights Reserved   */
  30 
  31 /*
  32  * Portions of this source code were derived from Berkeley 4.3 BSD
  33  * under license from the Regents of the University of California.
  34  */
  35 


  36 #include "mt.h"
  37 #include "../rpc/rpc_mt.h"              /* for MT declarations only */
  38 #include <rpc/types.h>
  39 #include <stdio.h>
  40 #include <stdlib.h>
  41 #include <string.h>
  42 #include <ctype.h>
  43 #include <netconfig.h>
  44 #include <malloc.h>
  45 #include <libintl.h>
  46 #include <syslog.h>
  47 #include <zone.h>
  48 #include "netcspace.h"
  49 
  50 #define FAILURE  (unsigned)(-1)
  51 
  52 /*
  53  *      Local routines used by the library procedures
  54  */
  55 
  56 static int blank(char *);
  57 static int comment(char *);
  58 static struct netconfig *fgetnetconfig(FILE *, char *);
  59 static void netconfig_free(struct netconfig *);
  60 static unsigned int getflag(char *);
  61 static char **getlookups(char *);
  62 static struct netconfig **getnetlist(void);
  63 static unsigned int getnlookups(char *);
  64 static char *gettoken(char *, int);
  65 static unsigned int getvalue(char *, struct nc_data nc_data[]);
  66 static void shift1left(char *);
  67 static void netlist_free(struct netconfig ***);
  68 static void free_entry(void *);
  69 static struct netconfig *netconfig_dup(struct netconfig *);
  70 
  71 extern const char __nsl_dom[];
  72 
  73 static int (*brand_get_sz)(void) = NULL;
  74 static struct netconfig *(*brand_get_net_ent)(int) = NULL;
  75 
  76 /*
  77  *      Static global variables used by the library procedures:
  78  *
  79  *      netpp - points to the beginning of the list of netconfig
  80  *              entries used by setnetconfig() and setnetpath().
  81  *              Once netpp is initialized, that memory is *never*
  82  *              released.  This was necessary to improve performance.
  83  *
  84  *      linenum - the current line number of the /etc/netconfig
  85  *                file (used for debugging and for nc_perror()).
  86  *
  87  *      fieldnum - the current field number of the current line
  88  *                 of /etc/netconfig (used for debugging and for
  89  *                 nc_perror()).
  90  *
  91  *      nc_error - the error condition encountered.
  92  */
  93 
  94 static struct netconfig **netpp = NULL;
  95 mutex_t netpp_mutex = DEFAULTMUTEX;


 241                                         return (NULL);
 242                                 }
 243                         }
 244                         return (netconfig_dup(*tpp));
 245                 }
 246         }
 247         nc_error = NC_NOTFOUND;
 248         return (NULL);
 249 }
 250 
 251 /*
 252  *      freenetconfigent frees the data allocated by getnetconfigent()
 253  */
 254 
 255 void
 256 freenetconfigent(struct netconfig *netp)
 257 {
 258         netconfig_free(netp);
 259 }
 260 
 261 void
 262 _nsl_brand_set_hooks(int (*set_sz_func)(void),
 263     struct netconfig *(*get_ent_func)(int))
 264 {
 265         brand_get_sz = set_sz_func;
 266         brand_get_net_ent = get_ent_func;
 267 }
 268 
 269 /*
 270  *      getnetlist() reads the netconfig file and creates a
 271  *      NULL-terminated list of entries.
 272  *      Returns the pointer to the head of the list or a NULL
 273  *      on failure.
 274  */
 275 
 276 static struct netconfig **
 277 getnetlist(void)
 278 {
 279         FILE *fp = NULL;        /* file stream for NETCONFIG */

 280         struct netconfig **listpp; /* the beginning of the netconfig list */
 281         struct netconfig **tpp; /* used to traverse the netconfig list */
 282         int count;              /* the number of entries in file */
 283         char nc_path[MAXPATHLEN];
 284         const char *zroot = zone_get_nroot();
 285 
 286         /*
 287          * If we are running in a branded zone, ensure we use the "/native"
 288          * prefix when opening the netconfig file:
 289          */
 290         (void) snprintf(nc_path, sizeof (nc_path), "%s%s", zroot != NULL ?
 291             zroot : "", NETCONFIG);
 292 
 293         if (brand_get_sz != NULL) {
 294                 count = brand_get_sz();
 295         } else {
 296                 char line[BUFSIZ];      /* holds each line of NETCONFIG */
 297 
 298                 if ((fp = fopen(nc_path, "rF")) == NULL) {
 299                         nc_error = NC_OPENFAIL;
 300                         return (NULL);
 301                 }
 302 
 303                 count = 0;
 304                 while (fgets(line, BUFSIZ, fp)) {
 305                         if (!(blank(line) || comment(line))) {
 306                                 ++count;
 307                         }
 308                 }
 309                 rewind(fp);
 310         }
 311 
 312         if (count == 0) {
 313                 nc_error = NC_NOTFOUND;
 314                 if (fp != NULL)
 315                         (void) fclose(fp);
 316                 return (NULL);
 317         }
 318 
 319         if ((listpp = malloc((count + 1) *
 320             sizeof (struct netconfig *))) == NULL) {
 321                 nc_error = NC_NOMEM;
 322                 if (fp != NULL)
 323                         (void) fclose(fp);
 324                 return (NULL);
 325         }
 326 
 327         if (brand_get_net_ent != NULL) {
 328                 int i;
 329 
 330                 tpp = listpp;
 331                 for (i = 0; i < count; i++) {
 332                         *tpp = brand_get_net_ent(i);
 333                         tpp++;
 334                 }
 335                 *tpp = NULL;
 336                 nc_error = NC_NOMOREENTRIES;
 337         } else {
 338                 /*
 339                  *      The following loop fills in the list (loops until
 340                  *      fgetnetconfig() returns a NULL) and counts the
 341                  *      number of entries placed in the list.  Note that
 342                  *      when the loop is completed, the last entry in the
 343                  *      list will contain a NULL (signifying the end of
 344                  *      the list).
 345                  */
 346                 linenum = 0;
 347                 for (tpp = listpp; *tpp = fgetnetconfig(fp, NULL); tpp++)
 348                         ;
 349                 (void) fclose(fp);
 350 
 351                 if (nc_error != NC_NOMOREENTRIES) /* Something is screwed up */
 352                         netlist_free(&listpp);
 353         }
 354 
 355         return (listpp);
 356 }
 357 
 358 /*
 359  *      fgetnetconfig() parses a line of the netconfig file into
 360  *      a netconfig structure.  It returns a pointer to the
 361  *      structure of success and a NULL on failure or EOF.
 362  */
 363 
 364 static struct netconfig *
 365 fgetnetconfig(FILE *fp, char *netid)
 366 {
 367         char linep[BUFSIZ];     /* pointer to a line in the file */
 368         struct netconfig *netconfigp; /* holds the new netconfig structure */
 369         char  *tok1, *tok2, *tok3; /* holds a token from the line */
 370         char  *retvalp;         /* the return value of fgets() */
 371         char *entnetid;         /* netid for the current entry */
 372 
 373         /* skip past blank lines and comments. */
 374         while (retvalp = fgets(linep, BUFSIZ, fp)) {