Initial import from FreeBSD RELENG_4:
[dragonfly.git] / contrib / libpam / libpam / pam_start.c
1 /* pam_start.c */
2
3 /* Creator Marc Ewing
4  * Maintained by AGM
5  *
6  * $Id: pam_start.c,v 1.10 1997/04/05 06:58:11 morgan Exp $
7  * $FreeBSD: src/contrib/libpam/libpam/pam_start.c,v 1.1.1.1.6.2 2001/06/11 15:28:12 markm Exp $
8  *
9  * $Log: pam_start.c,v $
10  */
11
12 #include <ctype.h>
13 #include <stdlib.h>
14 #include <unistd.h>
15 #include <string.h>
16 #include <syslog.h>
17
18 #include "pam_private.h"
19
20 int pam_start (
21     const char *service_name,
22     const char *user,
23     const struct pam_conv *pam_conversation,
24     pam_handle_t **pamh)
25 {
26     D(("called pam_start: [%s] [%s] [%p] [%p]"
27        ,service_name, user, pam_conversation, pamh));
28
29     if ((*pamh = calloc(1, sizeof(**pamh))) == NULL) {
30         pam_system_log(NULL, NULL, LOG_CRIT,
31                        "pam_start: calloc failed for *pamh");
32         return (PAM_BUF_ERR);
33     }
34
35     if (service_name) {
36         char *tmp;
37
38         if (((*pamh)->service_name = _pam_strdup(service_name)) == NULL) {
39             pam_system_log(NULL, NULL, LOG_CRIT,
40                            "pam_start: _pam_strdup failed for service name");
41             _pam_drop(*pamh);
42             return (PAM_BUF_ERR);
43         }
44         for (tmp=(*pamh)->service_name; *tmp; ++tmp)
45             *tmp = tolower(*tmp);                   /* require lower case */
46     } else
47         (*pamh)->service_name = NULL;
48
49     if (user) {
50         if (((*pamh)->user = _pam_strdup(user)) == NULL) {
51             pam_system_log(NULL, NULL, LOG_CRIT,
52                            "pam_start: _pam_strdup failed for user");
53             _pam_drop((*pamh)->service_name);
54             _pam_drop(*pamh);
55             return (PAM_BUF_ERR);
56         }
57     } else
58         (*pamh)->user = NULL;
59
60     (*pamh)->tty = NULL;
61     (*pamh)->prompt = NULL;              /* prompt for pam_get_user() */
62     (*pamh)->ruser = NULL;
63     (*pamh)->rhost = NULL;
64     (*pamh)->authtok = NULL;
65     (*pamh)->oldauthtok = NULL;
66     (*pamh)->fail_delay.delay_fn_ptr = NULL;
67     (*pamh)->former.choice = PAM_NOT_STACKED;
68
69     if (pam_conversation == NULL
70         || ((*pamh)->pam_conversation = (struct pam_conv *)
71             malloc(sizeof(struct pam_conv))) == NULL) {
72         pam_system_log(NULL, NULL, LOG_CRIT,
73                        "pam_start: malloc failed for pam_conv");
74         _pam_drop((*pamh)->service_name);
75         _pam_drop((*pamh)->user);
76         _pam_drop(*pamh);
77         return (PAM_BUF_ERR);
78     } else {
79         memcpy((*pamh)->pam_conversation, pam_conversation,
80                sizeof(struct pam_conv));
81     }
82
83     (*pamh)->data = NULL;
84     if ( _pam_make_env(*pamh) != PAM_SUCCESS ) {
85         pam_system_log(NULL, NULL, LOG_ERR,
86                        "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     /*
101      * XXX - should we call _pam_init_handlers() here ? The following
102      * is new as of Linux-PAM 0.55
103      */
104
105     if ( _pam_init_handlers(*pamh) != PAM_SUCCESS ) {
106         pam_system_log(NULL, NULL, LOG_ERR,
107                        "pam_start: failed to initialize handlers");
108         _pam_drop_env(*pamh);                 /* purge the environment */
109         _pam_drop((*pamh)->service_name);
110         _pam_drop((*pamh)->user);
111         _pam_drop(*pamh);
112         return PAM_ABORT;
113     }
114
115     D(("exiting pam_start successfully"));
116
117     return PAM_SUCCESS;
118 }