]> granicus.if.org Git - linux-pam/blob - libpam/pam_start.c
Relevant BUGIDs:
[linux-pam] / libpam / pam_start.c
1 /* pam_start.c */
2
3 /* Creator Marc Ewing
4  * Maintained by AGM
5  *
6  * $Id$
7  *
8  */
9
10 #include "pam_private.h"
11
12 #include <ctype.h>
13 #include <stdlib.h>
14 #include <unistd.h>
15 #include <string.h>
16 #include <syslog.h>
17
18 int pam_start (
19     const char *service_name,
20     const char *user,
21     const struct pam_conv *pam_conversation,
22     pam_handle_t **pamh)
23 {
24     D(("called pam_start: [%s] [%s] [%p] [%p]"
25        ,service_name, user, pam_conversation, pamh));
26
27     if (pamh == NULL) {
28         _pam_system_log(LOG_CRIT, "pam_start: invalid argument: pamh == NULL");
29         return (PAM_BUF_ERR);
30     }
31
32     if ((*pamh = calloc(1, sizeof(**pamh))) == NULL) {
33         _pam_system_log(LOG_CRIT, "pam_start: calloc failed for *pamh");
34         return (PAM_BUF_ERR);
35     }
36
37     /* All service names should be files below /etc/pam.d and nothing
38        else. Forbid paths. */
39     if (strrchr(service_name, '/') != NULL)
40         service_name = strrchr(service_name, '/') + 1;
41     
42     /* Mark the caller as the application - permission to do certain
43        things is limited to a module or an application */
44
45     __PAM_TO_APP(*pamh);
46
47     if (service_name) {
48         char *tmp;
49
50         if (((*pamh)->service_name = _pam_strdup(service_name)) == NULL) {
51             _pam_system_log(LOG_CRIT,
52                             "pam_start: _pam_strdup failed for service name");
53             _pam_drop(*pamh);
54             return (PAM_BUF_ERR);
55         }
56         for (tmp=(*pamh)->service_name; *tmp; ++tmp)
57             *tmp = tolower(*tmp);                   /* require lower case */
58     } else
59         (*pamh)->service_name = NULL;
60
61     if (user) {
62         if (((*pamh)->user = _pam_strdup(user)) == NULL) {
63             _pam_system_log(LOG_CRIT,
64                             "pam_start: _pam_strdup failed for user");
65             _pam_drop((*pamh)->service_name);
66             _pam_drop(*pamh);
67             return (PAM_BUF_ERR);
68         }
69     } else
70         (*pamh)->user = NULL;
71
72     (*pamh)->tty = NULL;
73     (*pamh)->prompt = NULL;              /* prompt for pam_get_user() */
74     (*pamh)->ruser = NULL;
75     (*pamh)->rhost = NULL;
76     (*pamh)->authtok = NULL;
77     (*pamh)->oldauthtok = NULL;
78     (*pamh)->fail_delay.delay_fn_ptr = NULL;
79     (*pamh)->former.choice = PAM_NOT_STACKED;
80
81     if (pam_conversation == NULL
82         || ((*pamh)->pam_conversation = (struct pam_conv *)
83             malloc(sizeof(struct pam_conv))) == NULL) {
84         _pam_system_log(LOG_CRIT, "pam_start: malloc failed for pam_conv");
85         _pam_drop((*pamh)->service_name);
86         _pam_drop((*pamh)->user);
87         _pam_drop(*pamh);
88         return (PAM_BUF_ERR);
89     } else {
90         memcpy((*pamh)->pam_conversation, pam_conversation,
91                sizeof(struct pam_conv));
92     }
93
94     (*pamh)->data = NULL;
95     if ( _pam_make_env(*pamh) != PAM_SUCCESS ) {
96         _pam_system_log(LOG_ERR,"pam_start: failed to initialize environment");
97         _pam_drop((*pamh)->service_name);
98         _pam_drop((*pamh)->user);
99         _pam_drop(*pamh);
100         return PAM_ABORT;
101     }
102
103     _pam_reset_timer(*pamh);         /* initialize timer support */
104
105     _pam_start_handlers(*pamh);                   /* cannot fail */
106
107     /* According to the SunOS man pages, loading modules and resolving
108      * symbols happens on the first call from the application. */
109
110     if ( _pam_init_handlers(*pamh) != PAM_SUCCESS ) {
111         _pam_system_log(LOG_ERR, "pam_start: failed to initialize handlers");
112         _pam_drop_env(*pamh);                 /* purge the environment */
113         _pam_drop((*pamh)->service_name);
114         _pam_drop((*pamh)->user);
115         _pam_drop(*pamh);
116         return PAM_ABORT;
117     }
118     
119     D(("exiting pam_start successfully"));
120
121     return PAM_SUCCESS;
122 }