usr/src/lib/libtsol/common/setflabel.c
changeset 1676 37f4a3e2bd99
equal deleted inserted replaced
1675:5791e75682d0 1676:37f4a3e2bd99
       
     1 /*
       
     2  * CDDL HEADER START
       
     3  *
       
     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  * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
       
    23  * Use is subject to license terms.
       
    24  */
       
    25 
       
    26 #pragma ident	"%Z%%M%	%I%	%E% SMI"
       
    27 
       
    28 /*
       
    29  *	Change the label of a file
       
    30  */
       
    31 
       
    32 #include <ctype.h>
       
    33 #include <locale.h>
       
    34 #include <stdio.h>
       
    35 #include <stdlib.h>
       
    36 #include <strings.h>
       
    37 #include <errno.h>
       
    38 
       
    39 #include <tsol/label.h>
       
    40 
       
    41 #include "labeld.h"
       
    42 #include <sys/tsol/label_macro.h>
       
    43 
       
    44 #include <sys/types.h>
       
    45 
       
    46 #include <zone.h>
       
    47 #include <sys/zone.h>
       
    48 #include <sys/param.h>
       
    49 #include <string.h>
       
    50 
       
    51 static int abspath(char *, const char *, char *);
       
    52 
       
    53 /*
       
    54  * setflabel(3TSOL) - set file label
       
    55  *
       
    56  * This is the library interface to the door call.
       
    57  */
       
    58 
       
    59 #define	clcall callp->param.acall.cargs.setfbcl_arg
       
    60 #define	clret callp->param.aret.rvals.setfbcl_ret
       
    61 /*
       
    62  *
       
    63  *	Exit	error = If error reported, the error indicator,
       
    64  *				-1, Unable to access label encodings file;
       
    65  *				 0, Invalid binary label passed;
       
    66  *				>0, Position after the first character in
       
    67  *				    string of error, 1 indicates entire string.
       
    68  *			Otherwise, unchanged.
       
    69  *
       
    70  *	Returns	0, If error.
       
    71  *		1, If successful.
       
    72  *
       
    73  *	Calls	__call_labeld(SETFLABEL)
       
    74  *
       
    75  */
       
    76 
       
    77 int
       
    78 setflabel(const char *path, m_label_t *label)
       
    79 {
       
    80 	labeld_data_t	call;
       
    81 	labeld_data_t	*callp = &call;
       
    82 	size_t	bufsize = sizeof (labeld_data_t);
       
    83 	size_t	datasize;
       
    84 	size_t	path_len;
       
    85 	static char	cwd[MAXPATHLEN];
       
    86 	char		canon[MAXPATHLEN];
       
    87 
       
    88 
       
    89 	/*
       
    90 	 * If path is relative and we haven't already determined the current
       
    91 	 * working directory, do so now.  Calculating the working directory
       
    92 	 * here lets us do the work once, instead of (potentially) repeatedly
       
    93 	 * in realpath().
       
    94 	 */
       
    95 	if (*path != '/' && cwd[0] == '\0') {
       
    96 		if (getcwd(cwd, MAXPATHLEN) == NULL) {
       
    97 			cwd[0] = '\0';
       
    98 			return (-1);
       
    99 		}
       
   100 	}
       
   101 	/*
       
   102 	 * Find an absolute pathname in the native file system name space that
       
   103 	 * corresponds to path, stuffing it into canon.
       
   104 	 */
       
   105 	if (abspath(cwd, path, canon) < 0)
       
   106 		return (-1);
       
   107 
       
   108 	path_len = strlen(canon) + 1;
       
   109 
       
   110 	datasize = CALL_SIZE(setfbcl_call_t, path_len - BUFSIZE);
       
   111 	datasize += 2; /* PAD */
       
   112 
       
   113 	if (datasize > bufsize) {
       
   114 		if ((callp = (labeld_data_t *)malloc(datasize)) == NULL) {
       
   115 			return (-1);
       
   116 		}
       
   117 		bufsize = datasize;
       
   118 	}
       
   119 
       
   120 	callp->callop = SETFLABEL;
       
   121 
       
   122 	clcall.sl = *label;
       
   123 	(void) strcpy(clcall.pathname, canon);
       
   124 
       
   125 	if (__call_labeld(&callp, &bufsize, &datasize) == SUCCESS) {
       
   126 		int err = callp->reterr;
       
   127 
       
   128 		if (callp != &call) {
       
   129 			/* free allocated buffer */
       
   130 			free(callp);
       
   131 		}
       
   132 		/*
       
   133 		 * reterr == 0, OK,
       
   134 		 * reterr < 0, invalid binary label,
       
   135 		 */
       
   136 		if (err == 0) {
       
   137 			if (clret.status > 0) {
       
   138 				errno = clret.status;
       
   139 				return (-1);
       
   140 			} else {
       
   141 				return (0);
       
   142 			}
       
   143 		} else if (err < 0) {
       
   144 			err = 0;
       
   145 		}
       
   146 		errno = ECONNREFUSED;
       
   147 		return (-1);
       
   148 	} else {
       
   149 		if (callp != &call) {
       
   150 			/* free allocated buffer */
       
   151 			free(callp);
       
   152 		}
       
   153 		/* server not present */
       
   154 		errno = ECONNREFUSED;
       
   155 		return (-1);
       
   156 	}
       
   157 }  /* setflabel */
       
   158 
       
   159 #undef	clcall
       
   160 #undef	clret
       
   161 
       
   162 #define	clcall callp->param.acall.cargs.zcopy_arg
       
   163 #define	clret callp->param.aret.rvals.zcopy_ret
       
   164 /*
       
   165  *
       
   166  *	Exit	status = result of zone copy request
       
   167  *				-1, Copy not confirmed
       
   168  *			Otherwise, unchanged.
       
   169  *
       
   170  *	Returns	0, If error.
       
   171  *		1, If successful.
       
   172  *
       
   173  *	Calls	__call_labeld(ZCOPY)
       
   174  *
       
   175  */
       
   176 int
       
   177 zonecopy(m_label_t *src_win_sl, char *remote_dir, char *filename,
       
   178     char *local_dir, int  transfer_mode)
       
   179 {
       
   180 	labeld_data_t	call;
       
   181 	labeld_data_t	*callp = &call;
       
   182 	size_t		bufsize = sizeof (labeld_data_t);
       
   183 	size_t		datasize;
       
   184 	size_t		strings;
       
   185 	size_t		remote_dir_len;
       
   186 	size_t		filename_len;
       
   187 	size_t		local_dir_len;
       
   188 	size_t		display_len;
       
   189 	char		*display;
       
   190 
       
   191 	remote_dir_len = strlen(remote_dir) + 1;
       
   192 	filename_len = strlen(filename) + 1;
       
   193 	local_dir_len = strlen(local_dir) + 1;
       
   194 
       
   195 	if ((display = getenv("DISPLAY")) == NULL)
       
   196 		display = "";
       
   197 	display_len = strlen(display) + 1;
       
   198 
       
   199 	strings = remote_dir_len + filename_len + local_dir_len + display_len;
       
   200 
       
   201 	datasize = CALL_SIZE(zcopy_call_t, strings - BUFSIZE);
       
   202 
       
   203 	datasize += 4; /* PAD */
       
   204 
       
   205 	if (datasize > bufsize) {
       
   206 		if ((callp = (labeld_data_t *)malloc(datasize)) == NULL) {
       
   207 			return (NULL);
       
   208 		}
       
   209 		bufsize = datasize;
       
   210 	}
       
   211 
       
   212 	strings = 0;
       
   213 	callp->callop = ZCOPY;
       
   214 
       
   215 	clcall.src_win_sl = *src_win_sl;
       
   216 	clcall.transfer_mode = transfer_mode;
       
   217 	clcall.remote_dir = strings;
       
   218 	strings += remote_dir_len;
       
   219 	clcall.filename = strings;
       
   220 	strings += filename_len;
       
   221 	clcall.local_dir = strings;
       
   222 	strings += local_dir_len;
       
   223 	clcall.display = strings;
       
   224 
       
   225 	(void) strcpy(&clcall.buf[clcall.remote_dir], remote_dir);
       
   226 	(void) strcpy(&clcall.buf[clcall.filename], filename);
       
   227 	(void) strcpy(&clcall.buf[clcall.local_dir], local_dir);
       
   228 	(void) strcpy(&clcall.buf[clcall.display], display);
       
   229 
       
   230 	if (__call_labeld(&callp, &bufsize, &datasize) == SUCCESS) {
       
   231 		int err = callp->reterr;
       
   232 
       
   233 		if (callp != &call) {
       
   234 			/* free allocated buffer */
       
   235 			free(callp);
       
   236 		}
       
   237 		/*
       
   238 		 * reterr == 0, OK,
       
   239 		 * reterr < 0, transer not confirmed
       
   240 		 */
       
   241 		if (err == 0) {
       
   242 			return (clret.status);
       
   243 		} else if (err < 0) {
       
   244 			err = 0;
       
   245 		}
       
   246 		return (PIPEMSG_CANCEL);
       
   247 	} else {
       
   248 		if (callp != &call) {
       
   249 			/* free allocated buffer */
       
   250 			free(callp);
       
   251 		}
       
   252 		/* server not present */
       
   253 		return (PIPEMSG_CANCEL);
       
   254 	}
       
   255 }
       
   256 
       
   257 /*
       
   258  * Convert the path given in raw to canonical, absolute, symlink-free
       
   259  * form, storing the result in the buffer named by canon, which must be
       
   260  * at least MAXPATHLEN bytes long.  If wd is non-NULL, assume that it
       
   261  * points to a path for the current working directory and use it instead
       
   262  * of invoking getcwd; accepting this value as an argument lets our caller
       
   263  * cache the value, so that realpath (called from this routine) doesn't have
       
   264  * to recalculate it each time it's given a relative pathname.
       
   265  *
       
   266  * Return 0 on success, -1 on failure.
       
   267  */
       
   268 int
       
   269 abspath(char *wd, const char *raw, char *canon)
       
   270 {
       
   271 	char		absbuf[MAXPATHLEN];
       
   272 
       
   273 	/*
       
   274 	 * Preliminary sanity check.
       
   275 	 */
       
   276 	if (raw == NULL || canon == NULL)
       
   277 		return (-1);
       
   278 
       
   279 	/*
       
   280 	 * If the path is relative, convert it to absolute form,
       
   281 	 * using wd if it's been supplied.
       
   282 	 */
       
   283 	if (raw[0] != '/') {
       
   284 		char	*limit = absbuf + sizeof (absbuf);
       
   285 		char	*d;
       
   286 
       
   287 		/* Fill in working directory. */
       
   288 		if (wd != NULL)
       
   289 			(void) strncpy(absbuf, wd, sizeof (absbuf));
       
   290 		else if (getcwd(absbuf, strlen(absbuf)) == NULL)
       
   291 			return (-1);
       
   292 
       
   293 		/* Add separating slash. */
       
   294 		d = absbuf + strlen(absbuf);
       
   295 		if (d < limit)
       
   296 			*d++ = '/';
       
   297 
       
   298 		/* Glue on the relative part of the path. */
       
   299 		while (d < limit && (*d++ = *raw++))
       
   300 			continue;
       
   301 
       
   302 		raw = absbuf;
       
   303 	}
       
   304 
       
   305 	/*
       
   306 	 * Call realpath to canonicalize and resolve symlinks.
       
   307 	 */
       
   308 	return (realpath(raw, canon) == NULL ? -1 : 0);
       
   309 }