death to trailing whitespace
[openafs.git] / src / pam / afs_util.c
1 /*
2  * Copyright 2000, International Business Machines Corporation and others.
3  * All Rights Reserved.
4  *
5  * This software has been released under the terms of the IBM Public
6  * License.  For details, see the LICENSE file in the top-level source
7  * directory or online at http://www.openafs.org/dl/license10.html
8  */
9
10 #include <stdio.h>
11 #include <assert.h>
12 #include <unistd.h>
13 #include <errno.h>
14 #include <syslog.h>
15 #include <security/pam_appl.h>
16 #include <afsconfig.h>
17 #include <afs/param.h>
18 #include <sys/wait.h>
19 #include <limits.h>
20 #include <string.h>
21 #include <stdlib.h>
22 #ifdef AFS_AIX51_ENV
23 #include <sys/cred.h>
24 #ifdef HAVE_SYS_PAG_H
25 #include <sys/pag.h>
26 #endif
27 #endif
28
29
30 #include "afs_util.h"
31
32
33 char *pam_afs_ident = "pam_afs";
34 char *pam_afs_lh = "OPENAFS_PAM_AFS_AUTH_login_handle";
35
36
37 void
38 lc_cleanup(pam_handle_t * pamh, void *data, int pam_end_status)
39 {
40     if (data) {
41         memset(data, 0, strlen(data));
42         free(data);
43     }
44 }
45
46
47 void
48 nil_cleanup(pam_handle_t * pamh, void *data, int pam_end_status)
49 {
50     return;
51 }
52
53 /* The PAM module needs to be free from libucb dependency. Otherwise,
54 dynamic linking is a problem, the AFS PAM library refuses to coexist
55 with the DCE library. The sigvec() and sigsetmask() are the only two
56 calls that neccesiate the inclusion of libucb.a.  There are used by
57 the lwp library to support premeptive threads and signalling between
58 threads. Since the lwp support used by the PAM module uses none of
59 these facilities, we can safely define these to be null functions */
60
61 #if !defined(AFS_HPUX110_ENV)
62 /* For HP 11.0, this function is in util/hputil.c */
63 int
64 sigvec(int sig, const struct sigvec *vec, struct sigvec *ovec)
65 {
66     assert(0);
67 }
68
69 int
70 sigsetmask(int mask)
71 {
72     assert(0);
73 }
74 #endif /* AFS_HPUX110_ENV */
75
76 /* converts string to integer */
77
78 char *
79 cv2string(char *ttp, unsigned long aval)
80 {
81     char *tp = ttp;
82     int i;
83     int any = 0;
84
85     *(--tp) = 0;
86     while (aval != 0) {
87         i = aval % 10;
88         *(--tp) = '0' + i;
89         aval /= 10;
90         any = 1;
91     }
92     if (!any)
93         *(--tp) = '0';
94     return tp;
95 }
96
97 int
98 do_klog(const char *user, const char *password, const char *lifetime,
99         const char *cell_name)
100 {
101     pid_t pid;
102     int pipedes[2];
103     int status;
104     char *argv[32];
105     int argc = 0;
106     char *klog_prog;
107     int ret = 1;
108
109 #if defined(AFS_KERBEROS_ENV)
110     klog_prog = KLOGKRB;
111 #else
112     klog_prog = KLOG;
113 #endif
114     if (access(klog_prog, X_OK) != 0) {
115         syslog(LOG_ERR, "can not access klog program '%s'", KLOG);
116         goto out;
117     }
118 #if defined(AFS_KERBEROS_ENV)
119     argv[argc++] = "klog.krb";
120
121 #else
122     argv[argc++] = "klog";
123 #endif
124     argv[argc++] = (char *)user;
125     if (cell_name) {
126         argv[argc++] = "-cell";
127         argv[argc++] = (char *)cell_name;
128     }
129     argv[argc++] = "-silent";
130     argv[argc++] = "-pipe";
131     if (lifetime != NULL) {
132         argv[argc++] = "-lifetime";
133         argv[argc++] = (char *)lifetime;
134     }
135     argv[argc] = NULL;
136
137     if (pipe(pipedes) != 0) {
138         syslog(LOG_ERR, "can not open pipe: %s", strerror(errno));
139         goto out;
140     }
141     pid = fork();
142     switch (pid) {
143     case (-1):                  /* Error: fork failed */
144         syslog(LOG_ERR, "fork failed: %s", strerror(errno));
145         goto out;
146     case (0):                   /* child */
147         close(0);
148         dup(pipedes[0]);
149         close(pipedes[0]);
150         close(1);
151         dup(pipedes[1]);
152         close(pipedes[1]);
153         execv(klog_prog, argv);
154         /* notreached */
155         syslog(LOG_ERR, "execv failed: %s", strerror(errno));
156         close(0);
157         close(1);
158         goto out;
159     default:
160         write(pipedes[1], password, strlen(password));
161         write(pipedes[1], "\n", 1);
162         close(pipedes[0]);
163         close(pipedes[1]);
164         if (pid != wait(&status))
165             return (0);
166         if (WIFEXITED(status)) {
167             ret = WEXITSTATUS(status);
168             goto out;
169         }
170         syslog(LOG_NOTICE, "%s for %s failed", klog_prog, user);
171     }
172   out:
173     /*   syslog(LOG_DEBUG, "do_klog returns %d", ret); */
174     return (ret);
175 }
176
177 /* Returns the AFS pag number, if any, otherwise return -1 */
178 afs_int32
179 getPAG(void)
180 {
181     afs_int32 pag;
182
183     pag = ktc_curpag();
184     if (pag == 0 || pag == -1)
185         return -1;
186
187     /* high order byte is always 'A'; actual pag value is low 24 bits */
188     return (pag & 0xFFFFFF);
189 }