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