1 /*
2 * $Id$
3 *
4 * This file was written by Andrew G. Morgan <morgan@parc.power.net>
5 *
6 */
7
8 #include "config.h"
9
10 #include <stdlib.h>
11 #include <stdio.h>
12 #include <string.h>
13 #include <security/pam_misc.h>
14 #include "pam_inline.h"
15
16 /*
17 * This function should be used to carefully dispose of the copied
18 * environment.
19 *
20 * usage: env = pam_misc_drop_env(env);
21 */
22
23 char **pam_misc_drop_env(char **dump)
24 {
25 int i;
26
27 for (i=0; dump[i] != NULL; ++i) {
28 D(("dump[%d]=`%s'", i, dump[i]));
29 pam_overwrite_string(dump[i]);
30 _pam_drop(dump[i]);
31 }
32 _pam_drop(dump);
33
34 return NULL;
35 }
36
37 /*
38 * This function takes the supplied environment and uploads it to be
39 * the PAM one.
40 */
41
42 int pam_misc_paste_env(pam_handle_t *pamh, const char * const * user_env)
43 {
44 for (; user_env && *user_env; ++user_env) {
45 int retval;
46
47 D(("uploading: %s", *user_env));
48 retval = pam_putenv(pamh, *user_env);
49 if (retval != PAM_SUCCESS) {
50 D(("error setting %s: %s", *user_env, pam_strerror(pamh,retval)));
51 return retval;
52 }
53 }
54 D(("done."));
55 return PAM_SUCCESS;
56 }
57
58 /*
59 * This is a wrapper to make pam behave in the way that setenv() does.
60 */
61
62 int pam_misc_setenv(pam_handle_t *pamh, const char *name
63 , const char *value, int readonly)
64 {
65 char *tmp;
66 int retval;
67
68 if (readonly) {
69 const char *etmp;
70
71 /* we check if the variable is there already */
72 etmp = pam_getenv(pamh, name);
73 if (etmp != NULL) {
74 D(("failed to set readonly variable: %s", name));
75 return PAM_PERM_DENIED; /* not allowed to overwrite */
76 }
77 }
78 if (asprintf(&tmp, "%s=%s", name, value) >= 0) {
79 D(("pam_putt()ing: %s", tmp));
80 retval = pam_putenv(pamh, tmp);
81 pam_overwrite_string(tmp); /* purge */
82 _pam_drop(tmp); /* forget */
83 } else {
84 D(("malloc failure"));
85 retval = PAM_BUF_ERR;
86 }
87
88 return retval;
89 }