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 #include <stdlib.h> 28 #include <strings.h> 29 #include <libintl.h> 30 31 #include "inetd_impl.h" 32 33 extern char **environ; 34 35 static int 36 valid_env_var(const char *var, const char *instance, const char *method) 37 { 38 char *cp = strchr(var, '='); 39 40 if (cp == NULL || cp == var) { 41 if (method == NULL) 42 return (0); 43 error_msg(gettext("Invalid environment variable \"%s\" for " 44 "method %s of instance %s.\n"), var, method, instance); 45 return (0); 46 } else if (strncmp(var, "SMF_", 4) == 0) { 47 if (method == NULL) 48 return (0); 49 error_msg(gettext("Invalid environment variable \"%s\" for " 50 "method %s of instance %s; \"SMF_\" prefix is reserved.\n"), 51 var, method, instance); 52 return (0); 53 } 54 55 return (1); 56 } 57 58 static char ** 59 find_dup(const char *var, char **env, const char *instance, const char *method) 60 { 61 char **p; 62 char *tmp; 63 64 for (p = env; *p != NULL; p++) { 65 tmp = strchr(*p, '='); 66 assert(tmp != NULL); 67 tmp++; 68 if (strncmp(*p, var, tmp - *p) == 0) 69 break; 70 } 71 72 if (*p == NULL) 73 return (NULL); 74 75 error_msg(gettext("Ignoring duplicate environment variable \"%s\" " 76 "for method %s of instance %s.\n"), *p, method, instance); 77 return (p); 78 } 79 80 /* 81 * Create an environment which is appropriate for spawning an SMF aware 82 * process. 83 * 84 * In order to preserve the correctness of the new environment, various 85 * checks are performed: 86 * 87 * - All SMF_ entries are ignored. All SMF_ entries should be provided 88 * by this function. 89 * - Duplicates in the entry are eliminated. 90 * - Malformed entries are eliminated. 91 * 92 * Detected errors are logged but not fatal, since a single bad entry 93 * should not be enough to prevent an SMF_ functional environment from 94 * being created. 95 */ 96 char ** 97 set_smf_env(struct method_context *mthd_ctxt, instance_t *instance, 98 const char *method) 99 { 100 char **nenv; 101 char **p, **np; 102 size_t nenv_size; 103 104 /* 105 * Max. of env, three SMF_ variables, and terminating NULL. 106 */ 107 nenv_size = mthd_ctxt->env_sz + 3 + 1; 108 109 if (instance->config->basic->inherit_env) { 110 for (p = environ; *p != NULL; p++) 111 nenv_size++; 112 } 113 114 nenv = malloc(sizeof (char *) * nenv_size); 115 if (nenv == NULL) 116 return (NULL); 117 (void) memset(nenv, 0, sizeof (char *) * nenv_size); 118 119 np = nenv; 120 121 *np = uu_msprintf("SMF_RESTARTER=%s", INETD_INSTANCE_FMRI); 122 if (*np == NULL) 123 goto fail; 124 else 125 np++; 126 *np = uu_msprintf("SMF_FMRI=%s", instance->fmri); 127 if (*np == NULL) 128 goto fail; 129 else 130 np++; 131 *np = uu_msprintf("SMF_METHOD=%s", method); 132 if (*np == NULL) 133 goto fail; 134 else 135 np++; 136 137 if (instance->config->basic->inherit_env) { 138 for (p = environ; *p != NULL; p++) { 139 if (!valid_env_var(*p, NULL, NULL)) 140 continue; 141 142 *np = strdup(*p); 143 if (*np == NULL) 144 goto fail; 145 else 146 np++; 147 } 148 } 149 150 if (mthd_ctxt->env != NULL) { 151 for (p = mthd_ctxt->env; *p != NULL; p++) { 152 char **dup_pos; 153 154 if (!valid_env_var(*p, instance->fmri, method)) 155 continue; 156 157 if ((dup_pos = find_dup(*p, nenv, instance->fmri, 158 method)) != NULL) { 159 free(*dup_pos); 160 *dup_pos = strdup(*p); 161 if (*dup_pos == NULL) 162 goto fail; 163 } else { 164 *np = strdup(*p); 165 if (*np == NULL) 166 goto fail; 167 else 168 np++; 169 } 170 } 171 } 172 *np = NULL; 173 174 return (nenv); 175 fail: 176 p = nenv; 177 while (nenv_size--) 178 free(*p++); 179 free(nenv); 180 return (NULL); 181 } 182