pam_putenv.c revision 255369
154359Sroberto/*-
254359Sroberto * Copyright (c) 2002-2003 Networks Associates Technology, Inc.
354359Sroberto * Copyright (c) 2004-2011 Dag-Erling Sm��rgrav
454359Sroberto * All rights reserved.
554359Sroberto *
654359Sroberto * This software was developed for the FreeBSD Project by ThinkSec AS and
754359Sroberto * Network Associates Laboratories, the Security Research Division of
854359Sroberto * Network Associates, Inc.  under DARPA/SPAWAR contract N66001-01-C-8035
954359Sroberto * ("CBOSS"), as part of the DARPA CHATS research program.
1054359Sroberto *
1154359Sroberto * Redistribution and use in source and binary forms, with or without
1254359Sroberto * modification, are permitted provided that the following conditions
1354359Sroberto * are met:
1454359Sroberto * 1. Redistributions of source code must retain the above copyright
1554359Sroberto *    notice, this list of conditions and the following disclaimer.
1654359Sroberto * 2. Redistributions in binary form must reproduce the above copyright
1754359Sroberto *    notice, this list of conditions and the following disclaimer in the
1854359Sroberto *    documentation and/or other materials provided with the distribution.
1954359Sroberto * 3. The name of the author may not be used to endorse or promote
2054359Sroberto *    products derived from this software without specific prior written
2154359Sroberto *    permission.
2254359Sroberto *
2354359Sroberto * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
2454359Sroberto * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
2554359Sroberto * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2654359Sroberto * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
2754359Sroberto * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2854359Sroberto * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2954359Sroberto * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
3054359Sroberto * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
3154359Sroberto * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
3254359Sroberto * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
3354359Sroberto * SUCH DAMAGE.
3454359Sroberto *
3554359Sroberto * $Id: pam_putenv.c 539 2012-03-31 20:53:22Z des $
3654359Sroberto */
3754359Sroberto
3854359Sroberto#ifdef HAVE_CONFIG_H
3954359Sroberto# include "config.h"
4054359Sroberto#endif
4154359Sroberto
4254359Sroberto#include <stdlib.h>
4354359Sroberto#include <string.h>
4454359Sroberto
4554359Sroberto#include <security/pam_appl.h>
4654359Sroberto
4754359Sroberto#include "openpam_impl.h"
4854359Sroberto
4954359Sroberto/*
5054359Sroberto * XSSO 4.2.1
5154359Sroberto * XSSO 6 page 56
5254359Sroberto *
5354359Sroberto * Set the value of an environment variable
5454359Sroberto */
5554359Sroberto
5654359Srobertoint
5754359Srobertopam_putenv(pam_handle_t *pamh,
5854359Sroberto	const char *namevalue)
5954359Sroberto{
6054359Sroberto	char **env, *p;
6154359Sroberto	int i;
6254359Sroberto
6354359Sroberto	ENTER();
6454359Sroberto	if (pamh == NULL)
6554359Sroberto		RETURNC(PAM_SYSTEM_ERR);
6656746Sroberto
6754359Sroberto	/* sanity checks */
6854359Sroberto	if (namevalue == NULL || (p = strchr(namevalue, '=')) == NULL)
6954359Sroberto		RETURNC(PAM_SYSTEM_ERR);
7054359Sroberto
7154359Sroberto	/* see if the variable is already in the environment */
7254359Sroberto	if ((i = openpam_findenv(pamh, namevalue, p - namevalue)) >= 0) {
7354359Sroberto		if ((p = strdup(namevalue)) == NULL)
7456746Sroberto			RETURNC(PAM_BUF_ERR);
7556746Sroberto		FREE(pamh->env[i]);
7654359Sroberto		pamh->env[i] = p;
7756746Sroberto		RETURNC(PAM_SUCCESS);
7854359Sroberto	}
7954359Sroberto
8054359Sroberto	/* grow the environment list if necessary */
8154359Sroberto	if (pamh->env_count == pamh->env_size) {
8254359Sroberto		env = realloc(pamh->env,
8354359Sroberto		    sizeof(char *) * (pamh->env_size * 2 + 1));
8454359Sroberto		if (env == NULL)
8554359Sroberto			RETURNC(PAM_BUF_ERR);
8654359Sroberto		pamh->env = env;
8754359Sroberto		pamh->env_size = pamh->env_size * 2 + 1;
8854359Sroberto	}
8954359Sroberto
9054359Sroberto	/* add the variable at the end */
9154359Sroberto	if ((pamh->env[pamh->env_count] = strdup(namevalue)) == NULL)
9254359Sroberto		RETURNC(PAM_BUF_ERR);
9354359Sroberto	++pamh->env_count;
9454359Sroberto	RETURNC(PAM_SUCCESS);
9554359Sroberto}
9654359Sroberto
9754359Sroberto/*
9854359Sroberto * Error codes:
9956746Sroberto *
10054359Sroberto *	PAM_SYSTEM_ERR
10154359Sroberto *	PAM_BUF_ERR
10254359Sroberto */
10354359Sroberto
10454359Sroberto/**
10554359Sroberto * The =pam_putenv function sets an environment variable.
10654359Sroberto * Its semantics are similar to those of =putenv, but it modifies the PAM
10754359Sroberto * context's environment list instead of the application's.
10854359Sroberto *
10954359Sroberto * >pam_getenv
11054359Sroberto * >pam_getenvlist
11154359Sroberto * >pam_setenv
11254359Sroberto */
11354359Sroberto