Import Upstream version 1.8.5
[hcoop/debian/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 <afsconfig.h>
11 #include <afs/param.h>
12
13 #include <roken.h>
14
15 #ifdef HAVE_SYS_WAIT_H
16 #include <sys/wait.h>
17 #endif
18
19 #include <limits.h>
20
21 #ifdef AFS_AIX51_ENV
22 #include <sys/cred.h>
23 #ifdef HAVE_SYS_PAG_H
24 #include <sys/pag.h>
25 #endif
26 #endif
27
28 #include <security/pam_appl.h>
29
30 #include <afs/auth.h>
31
32 #include "afs_util.h"
33
34
35 char *pam_afs_ident = "pam_afs";
36 char *pam_afs_lh = "OPENAFS_PAM_AFS_AUTH_login_handle";
37
38
39 void
40 lc_cleanup(pam_handle_t * pamh, void *data, int pam_end_status)
41 {
42 if (data) {
43 memset(data, 0, strlen(data));
44 free(data);
45 }
46 }
47
48
49 void
50 nil_cleanup(pam_handle_t * pamh, void *data, int pam_end_status)
51 {
52 return;
53 }
54
55 /* converts string to integer */
56
57 char *
58 cv2string(char *ttp, unsigned long aval)
59 {
60 char *tp = ttp;
61 int i;
62 int any = 0;
63
64 *(--tp) = 0;
65 while (aval != 0) {
66 i = aval % 10;
67 *(--tp) = '0' + i;
68 aval /= 10;
69 any = 1;
70 }
71 if (!any)
72 *(--tp) = '0';
73 return tp;
74 }
75
76 int
77 do_klog(const char *user, const char *password, const char *lifetime,
78 const char *cell_name)
79 {
80 pid_t pid;
81 int pipedes[2];
82 int status;
83 char *argv[32];
84 int argc = 0;
85 char *klog_prog;
86 int ret = 1; /* ret different than zero means failure */
87 int fd, nbytes;
88
89 #if defined(AFS_KERBEROS_ENV)
90 klog_prog = KLOGKRB;
91 #else
92 klog_prog = KLOG;
93 #endif
94 if (access(klog_prog, X_OK) != 0) {
95 syslog(LOG_ERR, "can not access klog program '%s'", KLOG);
96 goto out;
97 }
98 #if defined(AFS_KERBEROS_ENV)
99 argv[argc++] = "klog.krb";
100
101 #else
102 argv[argc++] = "klog";
103 #endif
104 argv[argc++] = (char *)user;
105 if (cell_name) {
106 argv[argc++] = "-cell";
107 argv[argc++] = (char *)cell_name;
108 }
109 argv[argc++] = "-silent";
110 argv[argc++] = "-pipe";
111 if (lifetime != NULL) {
112 argv[argc++] = "-lifetime";
113 argv[argc++] = (char *)lifetime;
114 }
115 argv[argc] = NULL;
116
117 if (pipe(pipedes) != 0) {
118 syslog(LOG_ERR, "can not open pipe: %s", strerror(errno));
119 goto out;
120 }
121 pid = fork();
122 switch (pid) {
123 case (-1): /* Error: fork failed */
124 syslog(LOG_ERR, "fork failed: %s", strerror(errno));
125 goto out;
126 case (0): /* child */
127 close(0);
128 fd = dup(pipedes[0]);
129 close(pipedes[0]);
130 if (fd == -1) {
131 syslog(LOG_ERR, "do_klog: dup failed for pipedes[0]: %s",
132 strerror(errno));
133 exit(1);
134 }
135 close(1);
136 fd = dup(pipedes[1]);
137 close(pipedes[1]);
138 if (fd == -1) {
139 close(0);
140 syslog(LOG_ERR, "do_klog: dup failed for pipedes[1]: %s",
141 strerror(errno));
142 exit(1);
143 }
144 execv(klog_prog, argv);
145 /* notreached */
146 syslog(LOG_ERR, "execv failed: %s", strerror(errno));
147 close(0);
148 close(1);
149 goto out;
150 default:
151 nbytes = write(pipedes[1], password, strlen(password));
152 if (nbytes == -1) {
153 syslog(LOG_ERR,
154 "do_klog: could not write the password into the input of the pipe: %s",
155 strerror(errno));
156 }
157 nbytes = write(pipedes[1], "\n", 1);
158 if (nbytes == -1) {
159 syslog(LOG_ERR,
160 "do_klog: could not write the end-of-line code into the input of the pipe: %s",
161 strerror(errno));
162 }
163 close(pipedes[0]);
164 close(pipedes[1]);
165 if (pid != wait(&status))
166 return (0);
167 if (WIFEXITED(status)) {
168 ret = WEXITSTATUS(status);
169 goto out;
170 }
171 syslog(LOG_NOTICE, "%s for %s failed", klog_prog, user);
172 }
173 out:
174 /* syslog(LOG_DEBUG, "do_klog returns %d", ret); */
175 return (ret);
176 }
177
178 /* Returns the AFS pag number, if any, otherwise return -1 */
179 afs_int32
180 getPAG(void)
181 {
182 afs_int32 pag;
183
184 pag = ktc_curpag();
185 if (pag == 0 || pag == -1)
186 return -1;
187
188 /* high order byte is always 'A'; actual pag value is low 24 bits */
189 return (pag & 0xFFFFFF);
190 }