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, Version 1.0 only 6 * (the "License"). You may not use this file except in compliance 7 * with the License. 8 * 9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10 * or http://www.opensolaris.org/os/licensing. 11 * See the License for the specific language governing permissions 12 * and limitations under the License. 13 * 14 * When distributing Covered Code, include this CDDL HEADER in each 15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16 * If applicable, add the following below this CDDL HEADER, with the 17 * fields enclosed by brackets "[]" replaced with your own identifying 18 * information: Portions Copyright [yyyy] [name of copyright owner] 19 * 20 * CDDL HEADER END 21 */ 22 /* 23 * Copyright 2004 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27 #pragma ident "%Z%%M% %I% %E% SMI" 28 29 #include <stdlib.h> 30 #include <strings.h> 31 #include <libintl.h> 32 33 #include "inetd_impl.h" 34 35 extern char **environ; 36 37 static int 38 valid_env_var(const char *var, const char *instance, const char *method) 39 { 40 char *cp = strchr(var, '='); 41 42 if (cp == NULL || cp == var) { 43 if (method == NULL) 44 return (0); 45 error_msg(gettext("Invalid environment variable \"%s\" for " 46 "method %s of instance %s.\n"), var, method, instance); 47 return (0); 48 } else if (strncmp(var, "SMF_", 4) == 0) { 49 if (method == NULL) 50 return (0); 51 error_msg(gettext("Invalid environment variable \"%s\" for " 52 "method %s of instance %s; \"SMF_\" prefix is reserved.\n"), 53 var, method, instance); 54 return (0); 55 } 56 57 return (1); 58 } 59 60 static char ** 61 find_dup(const char *var, char **env, const char *instance, const char *method) 62 { 63 char **p; 64 char *tmp; 65 66 for (p = env; *p != NULL; p++) { 67 tmp = strchr(*p, '='); 68 assert(tmp != NULL); 69 tmp++; 70 if (strncmp(*p, var, tmp - *p) == 0) 71 break; 72 } 73 74 if (*p == NULL) 75 return (NULL); 76 77 error_msg(gettext("Ignoring duplicate environment variable \"%s\" " 78 "for method %s of instance %s.\n"), *p, method, instance); 79 return (p); 80 } 81 82 /* 83 * Create an environment which is appropriate for spawning an SMF aware 84 * process. 85 * 86 * In order to preserve the correctness of the new environment, various 87 * checks are performed: 88 * 89 * - All SMF_ entries are ignored. All SMF_ entries should be provided 90 * by this function. 91 * - Duplicates in the entry are eliminated. 92 * - Malformed entries are eliminated. 93 * 94 * Detected errors are logged but not fatal, since a single bad entry 95 * should not be enough to prevent an SMF_ functional environment from 96 * being created. 97 */ 98 char ** 99 set_smf_env(struct method_context *mthd_ctxt, instance_t *instance, 100 const char *method) 101 { 102 char **nenv; 103 char **p, **np; 104 size_t nenv_size; 105 106 /* 107 * Max. of env, three SMF_ variables, and terminating NULL. 108 */ 109 nenv_size = mthd_ctxt->env_sz + 3 + 1; 110 111 if (instance->config->basic->inherit_env) { 112 for (p = environ; *p != NULL; p++) 113 nenv_size++; 114 } 115 116 nenv = malloc(sizeof (char *) * nenv_size); 117 if (nenv == NULL) 118 return (NULL); 119 (void) memset(nenv, 0, sizeof (char *) * nenv_size); 120 121 np = nenv; 122 123 *np = uu_msprintf("SMF_RESTARTER=%s", INETD_INSTANCE_FMRI); 124 if (*np == NULL) 125 goto fail; 126 else 127 np++; 128 *np = uu_msprintf("SMF_FMRI=%s", instance->fmri); 129 if (*np == NULL) 130 goto fail; 131 else 132 np++; 133 *np = uu_msprintf("SMF_METHOD=%s", method); 134 if (*np == NULL) 135 goto fail; 136 else 137 np++; 138 139 if (instance->config->basic->inherit_env) { 140 for (p = environ; *p != NULL; p++) { 141 if (!valid_env_var(*p, NULL, NULL)) 142 continue; 143 144 *np = strdup(*p); 145 if (*np == NULL) 146 goto fail; 147 else 148 np++; 149 } 150 } 151 152 if (mthd_ctxt->env != NULL) { 153 for (p = mthd_ctxt->env; *p != NULL; p++) { 154 char **dup_pos; 155 156 if (!valid_env_var(*p, instance->fmri, method)) 157 continue; 158 159 if ((dup_pos = find_dup(*p, nenv, instance->fmri, 160 method)) != NULL) { 161 free(*dup_pos); 162 *dup_pos = strdup(*p); 163 if (*dup_pos == NULL) 164 goto fail; 165 } else { 166 *np = strdup(*p); 167 if (*np == NULL) 168 goto fail; 169 else 170 np++; 171 } 172 } 173 } 174 *np = NULL; 175 176 return (nenv); 177 fail: 178 p = nenv; 179 while (nenv_size--) 180 free(*p++); 181 free(nenv); 182 return (NULL); 183 } 184