Initial import from FreeBSD RELENG_4:
[dragonfly.git] / contrib / libpam / libpam / pam_data.c
1 /* pam_data.c */
2
3 /*
4  * $Id: pam_data.c,v 1.5 1996/12/01 03:14:13 morgan Exp $
5  * $FreeBSD: src/contrib/libpam/libpam/pam_data.c,v 1.1.1.1.6.2 2001/06/11 15:28:12 markm Exp $
6  *
7  * $Log: pam_data.c,v $
8  * Revision 1.5  1996/12/01 03:14:13  morgan
9  * use _pam_macros.h
10  *
11  * Revision 1.4  1996/11/10 19:59:56  morgan
12  * internalized strdup for malloc debugging
13  *
14  * Revision 1.3  1996/09/05 06:10:31  morgan
15  * changed type of cleanup(), added PAM_DATA_REPLACE to replacement
16  * cleanup() call.
17  *
18  * Revision 1.2  1996/03/16 21:33:05  morgan
19  * removed const from cleanup argument, also deleted comment about SUN stuff
20  *
21  *
22  */
23
24 #include <stdlib.h>
25 #include <string.h>
26
27 #include "pam_private.h"
28
29 struct pam_data *_pam_locate_data(const pam_handle_t *pamh, const char *name);
30
31 int pam_set_data(
32     pam_handle_t *pamh,
33     const char *module_data_name,
34     void *data,
35     void (*cleanup)(pam_handle_t *pamh, void *data, int error_status))
36 {
37     struct pam_data *data_entry;
38     
39     IF_NO_PAMH("pam_set_data",pamh,PAM_SYSTEM_ERR);
40
41     /* first check if there is some data already. If so clean it up */
42
43     if ((data_entry = _pam_locate_data(pamh, module_data_name))) {
44         if (data_entry->cleanup) {
45             data_entry->cleanup(pamh, data_entry->data
46                                 , PAM_DATA_REPLACE | PAM_SUCCESS );
47         }
48     } else if ((data_entry = malloc(sizeof(*data_entry)))) {
49         char *tname;
50
51         if ((tname = _pam_strdup(module_data_name)) == NULL) {
52             pam_system_log(pamh, NULL, LOG_CRIT,
53                            "pam_set_data: no memory for data name");
54             _pam_drop(data_entry);
55             return PAM_BUF_ERR;
56         }
57         data_entry->next = pamh->data;
58         pamh->data = data_entry;
59         data_entry->name = tname;
60     } else {
61         pam_system_log(pamh, NULL, LOG_CRIT,
62                        "pam_set_data: cannot allocate data entry");
63         return PAM_BUF_ERR;
64     }
65
66     data_entry->data = data;           /* note this could be NULL */
67     data_entry->cleanup = cleanup;
68
69     return PAM_SUCCESS;
70 }
71
72 int pam_get_data(
73     const pam_handle_t *pamh,
74     const char *module_data_name,
75     const void **datap)
76 {
77     struct pam_data *data;
78
79     IF_NO_PAMH("pam_get_data",pamh,PAM_SYSTEM_ERR);
80
81     data = _pam_locate_data(pamh, module_data_name);
82     if (data) {
83         *datap = data->data;
84         return PAM_SUCCESS;
85     }
86
87     return PAM_NO_MODULE_DATA;
88 }
89
90 struct pam_data *_pam_locate_data(const pam_handle_t *pamh, const char *name)
91 {
92     struct pam_data *data;
93
94     IF_NO_PAMH("_pam_locate_data",pamh,NULL);
95     data = pamh->data;
96     
97     while (data) {
98         if (!strcmp(data->name, name)) {
99             return data;
100         }
101         data = data->next;
102     }
103
104     return NULL;
105 }
106
107 void _pam_free_data(pam_handle_t *pamh, int status)
108 {
109     struct pam_data *last;
110     struct pam_data *data;
111
112     IF_NO_PAMH("_pam_free_data",pamh,/* no return value for void fn */);
113     data = pamh->data;
114
115     while (data) {
116         last = data;
117         data = data->next;
118         if (last->cleanup) {
119             last->cleanup(pamh, last->data, status);
120         }
121         _pam_drop(last->name);
122         _pam_drop(last);
123     }
124 }