Print this page
OS-4335 ipadm_door_call should work in a branded zone without chroot
OS-4336 ipmgmtd should work in a branded zone without chroot
Reviewed by: Robert Mustacchi <rm@joyent.com>
OS-2837 lx brand only works with shared IP stacks


   4  * The contents of this file are subject to the terms of the
   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 (c) 2010, Oracle and/or its affiliates. All rights reserved.

  24  * Copyright 2014 Nexenta Systems, Inc.  All rights reserved.
  25  */
  26 
  27 #include <stdio.h>
  28 #include <stdlib.h>
  29 #include <string.h>
  30 #include <errno.h>
  31 #include <fcntl.h>
  32 #include <unistd.h>
  33 #include <stropts.h>
  34 #include <sys/sockio.h>
  35 #include <sys/types.h>
  36 #include <sys/stat.h>
  37 #include <sys/socket.h>
  38 #include <net/route.h>
  39 #include <netinet/in.h>
  40 #include <inet/ip.h>
  41 #include <arpa/inet.h>
  42 #include <libintl.h>
  43 #include <libdlpi.h>


 268         if (iph->iph_sock != -1)
 269                 (void) close(iph->iph_sock);
 270         if (iph->iph_sock6 != -1)
 271                 (void) close(iph->iph_sock6);
 272         if (iph->iph_rtsock != -1)
 273                 (void) close(iph->iph_rtsock);
 274         if (iph->iph_door_fd != -1)
 275                 (void) close(iph->iph_door_fd);
 276         dladm_close(iph->iph_dlh);
 277         (void) pthread_mutex_destroy(&iph->iph_lock);
 278         free(iph);
 279 }
 280 
 281 /*
 282  * Checks if the caller has the authorization to configure network
 283  * interfaces.
 284  */
 285 boolean_t
 286 ipadm_check_auth(void)
 287 {

 288         struct passwd   pwd;
 289         char            buf[NSS_BUFLEN_PASSWD];
 290 







 291         /* get the password entry for the given user ID */
 292         if (getpwuid_r(getuid(), &pwd, buf, sizeof (buf)) == NULL)
 293                 return (B_FALSE);
 294 
 295         /* check for presence of given authorization */
 296         return (chkauthattr(NETWORK_INTERFACE_CONFIG_AUTH, pwd.pw_name) != 0);
 297 }
 298 
 299 /*
 300  * Stores the index value of the interface in `ifname' for the address
 301  * family `af' into the buffer pointed to by `index'.
 302  */
 303 static ipadm_status_t
 304 i_ipadm_get_index(ipadm_handle_t iph, const char *ifname, sa_family_t af,
 305     int *index)
 306 {
 307         struct lifreq   lifr;
 308         int             sock;
 309 
 310         bzero(&lifr, sizeof (lifr));
 311         (void) strlcpy(lifr.lifr_name, ifname, sizeof (lifr.lifr_name));
 312         if (af == AF_INET)


 880         door_arg_t      darg;
 881         int             err;
 882         ipmgmt_retval_t rval, *rvalp;
 883         boolean_t       reopen = B_FALSE;
 884 
 885         if (rbufp == NULL) {
 886                 rvalp = &rval;
 887                 rbufp = (void **)&rvalp;
 888                 rsize = sizeof (rval);
 889         }
 890 
 891         darg.data_ptr = arg;
 892         darg.data_size = asize;
 893         darg.desc_ptr = NULL;
 894         darg.desc_num = 0;
 895         darg.rbuf = *rbufp;
 896         darg.rsize = rsize;
 897 
 898 reopen:
 899         (void) pthread_mutex_lock(&iph->iph_lock);
 900         /* The door descriptor is opened if it isn't already */


 901         if (iph->iph_door_fd == -1) {
 902                 if ((iph->iph_door_fd = open(IPMGMT_DOOR, O_RDONLY)) < 0) {










 903                         err = errno;
 904                         (void) pthread_mutex_unlock(&iph->iph_lock);
 905                         return (err);
 906                 }
 907         }
 908         (void) pthread_mutex_unlock(&iph->iph_lock);
 909 
 910         if (door_call(iph->iph_door_fd, &darg) == -1) {
 911                 /*
 912                  * Stale door descriptor is possible if ipmgmtd was restarted
 913                  * since last iph_door_fd was opened, so try re-opening door
 914                  * descriptor.
 915                  */
 916                 if (!reopen && errno == EBADF) {
 917                         (void) close(iph->iph_door_fd);
 918                         iph->iph_door_fd = -1;
 919                         reopen = B_TRUE;
 920                         goto reopen;
 921                 }
 922                 return (errno);




   4  * The contents of this file are subject to the terms of the
   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 (c) 2010, Oracle and/or its affiliates. All rights reserved.
  24  * Copyright 2015 Joyent, Inc.
  25  * Copyright 2014 Nexenta Systems, Inc.  All rights reserved.
  26  */
  27 
  28 #include <stdio.h>
  29 #include <stdlib.h>
  30 #include <string.h>
  31 #include <errno.h>
  32 #include <fcntl.h>
  33 #include <unistd.h>
  34 #include <stropts.h>
  35 #include <sys/sockio.h>
  36 #include <sys/types.h>
  37 #include <sys/stat.h>
  38 #include <sys/socket.h>
  39 #include <net/route.h>
  40 #include <netinet/in.h>
  41 #include <inet/ip.h>
  42 #include <arpa/inet.h>
  43 #include <libintl.h>
  44 #include <libdlpi.h>


 269         if (iph->iph_sock != -1)
 270                 (void) close(iph->iph_sock);
 271         if (iph->iph_sock6 != -1)
 272                 (void) close(iph->iph_sock6);
 273         if (iph->iph_rtsock != -1)
 274                 (void) close(iph->iph_rtsock);
 275         if (iph->iph_door_fd != -1)
 276                 (void) close(iph->iph_door_fd);
 277         dladm_close(iph->iph_dlh);
 278         (void) pthread_mutex_destroy(&iph->iph_lock);
 279         free(iph);
 280 }
 281 
 282 /*
 283  * Checks if the caller has the authorization to configure network
 284  * interfaces.
 285  */
 286 boolean_t
 287 ipadm_check_auth(void)
 288 {
 289         int             uid;
 290         struct passwd   pwd;
 291         char            buf[NSS_BUFLEN_PASSWD];
 292 
 293         /*
 294          * Branded zones may have different kinds of auth, but root always
 295          * allowed.
 296          */
 297         if ((uid = getuid()) == 0)
 298                 return (B_TRUE);
 299 
 300         /* get the password entry for the given user ID */
 301         if (getpwuid_r(uid, &pwd, buf, sizeof (buf)) == NULL)
 302                 return (B_FALSE);
 303 
 304         /* check for presence of given authorization */
 305         return (chkauthattr(NETWORK_INTERFACE_CONFIG_AUTH, pwd.pw_name) != 0);
 306 }
 307 
 308 /*
 309  * Stores the index value of the interface in `ifname' for the address
 310  * family `af' into the buffer pointed to by `index'.
 311  */
 312 static ipadm_status_t
 313 i_ipadm_get_index(ipadm_handle_t iph, const char *ifname, sa_family_t af,
 314     int *index)
 315 {
 316         struct lifreq   lifr;
 317         int             sock;
 318 
 319         bzero(&lifr, sizeof (lifr));
 320         (void) strlcpy(lifr.lifr_name, ifname, sizeof (lifr.lifr_name));
 321         if (af == AF_INET)


 889         door_arg_t      darg;
 890         int             err;
 891         ipmgmt_retval_t rval, *rvalp;
 892         boolean_t       reopen = B_FALSE;
 893 
 894         if (rbufp == NULL) {
 895                 rvalp = &rval;
 896                 rbufp = (void **)&rvalp;
 897                 rsize = sizeof (rval);
 898         }
 899 
 900         darg.data_ptr = arg;
 901         darg.data_size = asize;
 902         darg.desc_ptr = NULL;
 903         darg.desc_num = 0;
 904         darg.rbuf = *rbufp;
 905         darg.rsize = rsize;
 906 
 907 reopen:
 908         (void) pthread_mutex_lock(&iph->iph_lock);
 909         /*
 910          * The door descriptor is opened if it isn't already.
 911          */
 912         if (iph->iph_door_fd == -1) {
 913                 char door[MAXPATHLEN];
 914                 const char *zroot = zone_get_nroot();
 915 
 916                 /*
 917                  * If this is a branded zone, make sure we use the "/native"
 918                  * prefix for the door path:
 919                  */
 920                 (void) snprintf(door, sizeof (door), "%s%s", zroot != NULL ?
 921                     zroot : "", IPMGMT_DOOR);
 922 
 923                 if ((iph->iph_door_fd = open(door, O_RDONLY)) < 0) {
 924                         err = errno;
 925                         (void) pthread_mutex_unlock(&iph->iph_lock);
 926                         return (err);
 927                 }
 928         }
 929         (void) pthread_mutex_unlock(&iph->iph_lock);
 930 
 931         if (door_call(iph->iph_door_fd, &darg) == -1) {
 932                 /*
 933                  * Stale door descriptor is possible if ipmgmtd was restarted
 934                  * since last iph_door_fd was opened, so try re-opening door
 935                  * descriptor.
 936                  */
 937                 if (!reopen && errno == EBADF) {
 938                         (void) close(iph->iph_door_fd);
 939                         iph->iph_door_fd = -1;
 940                         reopen = B_TRUE;
 941                         goto reopen;
 942                 }
 943                 return (errno);