/* * CDDL HEADER START * * The contents of this file are subject to the terms of the * Common Development and Distribution License, Version 1.0 only * (the "License"). You may not use this file except in compliance * with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. * See the License for the specific language governing permissions * and limitations under the License. * * When distributing Covered Code, include this CDDL HEADER in each * file and include the License file at usr/src/OPENSOLARIS.LICENSE. * If applicable, add the following below this CDDL HEADER, with the * fields enclosed by brackets "[]" replaced with your own identifying * information: Portions Copyright [yyyy] [name of copyright owner] * * CDDL HEADER END */ /* * Copyright 2004 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ #pragma ident "%Z%%M% %I% %E% SMI" #include #include #include #include "inetd_impl.h" extern char **environ; static int valid_env_var(const char *var, const char *instance, const char *method) { char *cp = strchr(var, '='); if (cp == NULL || cp == var) { if (method == NULL) return (0); error_msg(gettext("Invalid environment variable \"%s\" for " "method %s of instance %s.\n"), var, method, instance); return (0); } else if (strncmp(var, "SMF_", 4) == 0) { if (method == NULL) return (0); error_msg(gettext("Invalid environment variable \"%s\" for " "method %s of instance %s; \"SMF_\" prefix is reserved.\n"), var, method, instance); return (0); } return (1); } static char ** find_dup(const char *var, char **env, const char *instance, const char *method) { char **p; char *tmp; for (p = env; *p != NULL; p++) { tmp = strchr(*p, '='); assert(tmp != NULL); tmp++; if (strncmp(*p, var, tmp - *p) == 0) break; } if (*p == NULL) return (NULL); error_msg(gettext("Ignoring duplicate environment variable \"%s\" " "for method %s of instance %s.\n"), *p, method, instance); return (p); } /* * Create an environment which is appropriate for spawning an SMF aware * process. * * In order to preserve the correctness of the new environment, various * checks are performed: * * - All SMF_ entries are ignored. All SMF_ entries should be provided * by this function. * - Duplicates in the entry are eliminated. * - Malformed entries are eliminated. * * Detected errors are logged but not fatal, since a single bad entry * should not be enough to prevent an SMF_ functional environment from * being created. */ char ** set_smf_env(struct method_context *mthd_ctxt, instance_t *instance, const char *method) { char **nenv; char **p, **np; size_t nenv_size; /* * Max. of env, three SMF_ variables, and terminating NULL. */ nenv_size = mthd_ctxt->env_sz + 3 + 1; if (instance->config->basic->inherit_env) { for (p = environ; *p != NULL; p++) nenv_size++; } nenv = malloc(sizeof (char *) * nenv_size); if (nenv == NULL) return (NULL); (void) memset(nenv, 0, sizeof (char *) * nenv_size); np = nenv; *np = uu_msprintf("SMF_RESTARTER=%s", INETD_INSTANCE_FMRI); if (*np == NULL) goto fail; else np++; *np = uu_msprintf("SMF_FMRI=%s", instance->fmri); if (*np == NULL) goto fail; else np++; *np = uu_msprintf("SMF_METHOD=%s", method); if (*np == NULL) goto fail; else np++; if (instance->config->basic->inherit_env) { for (p = environ; *p != NULL; p++) { if (!valid_env_var(*p, NULL, NULL)) continue; *np = strdup(*p); if (*np == NULL) goto fail; else np++; } } if (mthd_ctxt->env != NULL) { for (p = mthd_ctxt->env; *p != NULL; p++) { char **dup_pos; if (!valid_env_var(*p, instance->fmri, method)) continue; if ((dup_pos = find_dup(*p, nenv, instance->fmri, method)) != NULL) { free(*dup_pos); *dup_pos = strdup(*p); if (*dup_pos == NULL) goto fail; } else { *np = strdup(*p); if (*np == NULL) goto fail; else np++; } } } *np = NULL; return (nenv); fail: p = nenv; while (nenv_size--) free(*p++); free(nenv); return (NULL); }