]> granicus.if.org Git - linux-pam/blob - libpam/pam_start.c
Relevant BUGIDs: 612956
[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 <ctype.h>
11 #include <stdlib.h>
12 #include <unistd.h>
13 #include <string.h>
14 #include <syslog.h>
15
16 #include "pam_private.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 = calloc(1, sizeof(**pamh))) == NULL) {
28         _pam_system_log(LOG_CRIT, "pam_start: calloc failed for *pamh");
29         return (PAM_BUF_ERR);
30     }
31
32     /* Mark the caller as the application - permission to do certain
33        things is limited to a module or an application */
34
35     __PAM_TO_APP(*pamh);
36
37     if (service_name) {
38         char *tmp;
39
40         if (((*pamh)->service_name = _pam_strdup(service_name)) == NULL) {
41             _pam_system_log(LOG_CRIT,
42                             "pam_start: _pam_strdup failed for service name");
43             _pam_drop(*pamh);
44             return (PAM_BUF_ERR);
45         }
46         for (tmp=(*pamh)->service_name; *tmp; ++tmp)
47             *tmp = tolower(*tmp);                   /* require lower case */
48     } else
49         (*pamh)->service_name = NULL;
50
51     if (user) {
52         if (((*pamh)->user = _pam_strdup(user)) == NULL) {
53             _pam_system_log(LOG_CRIT,
54                             "pam_start: _pam_strdup failed for user");
55             _pam_drop((*pamh)->service_name);
56             _pam_drop(*pamh);
57             return (PAM_BUF_ERR);
58         }
59     } else
60         (*pamh)->user = NULL;
61
62     (*pamh)->tty = NULL;
63     (*pamh)->prompt = NULL;              /* prompt for pam_get_user() */
64     (*pamh)->ruser = NULL;
65     (*pamh)->rhost = NULL;
66     (*pamh)->authtok = NULL;
67     (*pamh)->oldauthtok = NULL;
68     (*pamh)->fail_delay.delay_fn_ptr = NULL;
69     (*pamh)->former.choice = PAM_NOT_STACKED;
70
71     if (pam_conversation == NULL
72         || ((*pamh)->pam_conversation = (struct pam_conv *)
73             malloc(sizeof(struct pam_conv))) == NULL) {
74         _pam_system_log(LOG_CRIT, "pam_start: malloc failed for pam_conv");
75         _pam_drop((*pamh)->service_name);
76         _pam_drop((*pamh)->user);
77         _pam_drop(*pamh);
78         return (PAM_BUF_ERR);
79     } else {
80         memcpy((*pamh)->pam_conversation, pam_conversation,
81                sizeof(struct pam_conv));
82     }
83
84     (*pamh)->data = NULL;
85     if ( _pam_make_env(*pamh) != PAM_SUCCESS ) {
86         _pam_system_log(LOG_ERR,"pam_start: failed to initialize environment");
87         _pam_drop((*pamh)->service_name);
88         _pam_drop((*pamh)->user);
89         _pam_drop(*pamh);
90         return PAM_ABORT;
91     }
92
93     _pam_reset_timer(*pamh);         /* initialize timer support */
94
95     _pam_start_handlers(*pamh);                   /* cannot fail */
96
97     /* According to the SunOS man pages, loading modules and resolving
98      * symbols happens on the first call from the application. */
99
100     if ( _pam_init_handlers(*pamh) != PAM_SUCCESS ) {
101         _pam_system_log(LOG_ERR, "pam_start: failed to initialize handlers");
102         _pam_drop_env(*pamh);                 /* purge the environment */
103         _pam_drop((*pamh)->service_name);
104         _pam_drop((*pamh)->user);
105         _pam_drop(*pamh);
106         return PAM_ABORT;
107     }
108     
109     D(("exiting pam_start successfully"));
110
111     return PAM_SUCCESS;
112 }