diff options
-rw-r--r-- | ChangeLog | 4 | ||||
-rw-r--r-- | auth-pam.c | 113 | ||||
-rw-r--r-- | auth.c | 8 | ||||
-rw-r--r-- | fake-getaddrinfo.c | 171 | ||||
-rw-r--r-- | fake-getnameinfo.c | 76 | ||||
-rw-r--r-- | fake-getnameinfo.h | 1 | ||||
-rw-r--r-- | fake-socket.h | 10 | ||||
-rw-r--r-- | login.c | 137 |
8 files changed, 274 insertions, 246 deletions
@@ -1,3 +1,7 @@ | |||
1 | 20000531 | ||
2 | - Cleanup of auth.c, login.c and fake-* | ||
3 | - Cleanup of auth-pam.c, save and print "account expired" error messages | ||
4 | |||
1 | 20000530 | 5 | 20000530 |
2 | - Define atexit for old Solaris | 6 | - Define atexit for old Solaris |
3 | - Fix buffer overrun in login.c for systems which use syslen in utmpx. | 7 | - Fix buffer overrun in login.c for systems which use syslen in utmpx. |
diff --git a/auth-pam.c b/auth-pam.c index e3f4c4252..174d289f3 100644 --- a/auth-pam.c +++ b/auth-pam.c | |||
@@ -13,12 +13,16 @@ | |||
13 | #include "xmalloc.h" | 13 | #include "xmalloc.h" |
14 | #include "servconf.h" | 14 | #include "servconf.h" |
15 | 15 | ||
16 | RCSID("$Id: auth-pam.c,v 1.4 2000/04/29 14:47:29 damien Exp $"); | 16 | RCSID("$Id: auth-pam.c,v 1.5 2000/05/31 01:20:12 damien Exp $"); |
17 | |||
18 | #define NEW_AUTHTOK_MSG \ | ||
19 | "Warning: You password has expired, please change it now" | ||
17 | 20 | ||
18 | /* Callbacks */ | 21 | /* Callbacks */ |
19 | static int pamconv(int num_msg, const struct pam_message **msg, | 22 | static int pamconv(int num_msg, const struct pam_message **msg, |
20 | struct pam_response **resp, void *appdata_ptr); | 23 | struct pam_response **resp, void *appdata_ptr); |
21 | void pam_cleanup_proc(void *context); | 24 | void pam_cleanup_proc(void *context); |
25 | void pam_msg_cat(const char *msg); | ||
22 | 26 | ||
23 | /* module-local variables */ | 27 | /* module-local variables */ |
24 | static struct pam_conv conv = { | 28 | static struct pam_conv conv = { |
@@ -27,7 +31,7 @@ static struct pam_conv conv = { | |||
27 | }; | 31 | }; |
28 | static struct pam_handle_t *pamh = NULL; | 32 | static struct pam_handle_t *pamh = NULL; |
29 | static const char *pampasswd = NULL; | 33 | static const char *pampasswd = NULL; |
30 | static char *pamconv_msg = NULL; | 34 | static char *pam_msg = NULL; |
31 | 35 | ||
32 | /* PAM conversation function. This is really a kludge to get the password */ | 36 | /* PAM conversation function. This is really a kludge to get the password */ |
33 | /* into PAM and to pick up any messages generated by PAM into pamconv_msg */ | 37 | /* into PAM and to pick up any messages generated by PAM into pamconv_msg */ |
@@ -36,8 +40,6 @@ static int pamconv(int num_msg, const struct pam_message **msg, | |||
36 | { | 40 | { |
37 | struct pam_response *reply; | 41 | struct pam_response *reply; |
38 | int count; | 42 | int count; |
39 | size_t msg_len; | ||
40 | char *p; | ||
41 | 43 | ||
42 | /* PAM will free this later */ | 44 | /* PAM will free this later */ |
43 | reply = malloc(num_msg * sizeof(*reply)); | 45 | reply = malloc(num_msg * sizeof(*reply)); |
@@ -54,31 +56,14 @@ static int pamconv(int num_msg, const struct pam_message **msg, | |||
54 | reply[count].resp_retcode = PAM_SUCCESS; | 56 | reply[count].resp_retcode = PAM_SUCCESS; |
55 | reply[count].resp = xstrdup(pampasswd); | 57 | reply[count].resp = xstrdup(pampasswd); |
56 | break; | 58 | break; |
57 | |||
58 | case PAM_TEXT_INFO: | 59 | case PAM_TEXT_INFO: |
59 | reply[count].resp_retcode = PAM_SUCCESS; | 60 | reply[count].resp_retcode = PAM_SUCCESS; |
60 | reply[count].resp = xstrdup(""); | 61 | reply[count].resp = xstrdup(""); |
61 | 62 | ||
62 | if (msg[count]->msg == NULL) | 63 | if (msg[count]->msg != NULL) |
63 | break; | 64 | pam_msg_cat(msg[count]->msg); |
64 | 65 | ||
65 | debug("Adding PAM message: %s", msg[count]->msg); | ||
66 | |||
67 | msg_len = strlen(msg[count]->msg); | ||
68 | if (pamconv_msg) { | ||
69 | size_t n = strlen(pamconv_msg); | ||
70 | pamconv_msg = xrealloc(pamconv_msg, n + msg_len + 2); | ||
71 | p = pamconv_msg + n; | ||
72 | } else { | ||
73 | pamconv_msg = p = xmalloc(msg_len + 2); | ||
74 | } | ||
75 | memcpy(p, msg[count]->msg, msg_len); | ||
76 | p[msg_len] = '\n'; | ||
77 | p[msg_len + 1] = '\0'; | ||
78 | break; | 66 | break; |
79 | |||
80 | case PAM_PROMPT_ECHO_ON: | ||
81 | case PAM_ERROR_MSG: | ||
82 | default: | 67 | default: |
83 | free(reply); | 68 | free(reply); |
84 | return PAM_CONV_ERR; | 69 | return PAM_CONV_ERR; |
@@ -100,19 +85,19 @@ void pam_cleanup_proc(void *context) | |||
100 | pam_retval = pam_close_session((pam_handle_t *)pamh, 0); | 85 | pam_retval = pam_close_session((pam_handle_t *)pamh, 0); |
101 | if (pam_retval != PAM_SUCCESS) { | 86 | if (pam_retval != PAM_SUCCESS) { |
102 | log("Cannot close PAM session: %.200s", | 87 | log("Cannot close PAM session: %.200s", |
103 | PAM_STRERROR((pam_handle_t *)pamh, pam_retval)); | 88 | PAM_STRERROR((pam_handle_t *)pamh, pam_retval)); |
104 | } | 89 | } |
105 | 90 | ||
106 | pam_retval = pam_setcred((pam_handle_t *)pamh, PAM_DELETE_CRED); | 91 | pam_retval = pam_setcred((pam_handle_t *)pamh, PAM_DELETE_CRED); |
107 | if (pam_retval != PAM_SUCCESS) { | 92 | if (pam_retval != PAM_SUCCESS) { |
108 | log("Cannot delete credentials: %.200s", | 93 | log("Cannot delete credentials: %.200s", |
109 | PAM_STRERROR((pam_handle_t *)pamh, pam_retval)); | 94 | PAM_STRERROR((pam_handle_t *)pamh, pam_retval)); |
110 | } | 95 | } |
111 | 96 | ||
112 | pam_retval = pam_end((pam_handle_t *)pamh, pam_retval); | 97 | pam_retval = pam_end((pam_handle_t *)pamh, pam_retval); |
113 | if (pam_retval != PAM_SUCCESS) { | 98 | if (pam_retval != PAM_SUCCESS) { |
114 | log("Cannot release PAM authentication: %.200s", | 99 | log("Cannot release PAM authentication: %.200s", |
115 | PAM_STRERROR((pam_handle_t *)pamh, pam_retval)); | 100 | PAM_STRERROR((pam_handle_t *)pamh, pam_retval)); |
116 | } | 101 | } |
117 | } | 102 | } |
118 | } | 103 | } |
@@ -135,7 +120,8 @@ int auth_pam_password(struct passwd *pw, const char *password) | |||
135 | 120 | ||
136 | pam_retval = pam_authenticate((pam_handle_t *)pamh, 0); | 121 | pam_retval = pam_authenticate((pam_handle_t *)pamh, 0); |
137 | if (pam_retval == PAM_SUCCESS) { | 122 | if (pam_retval == PAM_SUCCESS) { |
138 | debug("PAM Password authentication accepted for user \"%.100s\"", pw->pw_name); | 123 | debug("PAM Password authentication accepted for user \"%.100s\"", |
124 | pw->pw_name); | ||
139 | return 1; | 125 | return 1; |
140 | } else { | 126 | } else { |
141 | debug("PAM Password authentication for \"%.100s\" failed: %s", | 127 | debug("PAM Password authentication for \"%.100s\" failed: %s", |
@@ -148,26 +134,36 @@ int auth_pam_password(struct passwd *pw, const char *password) | |||
148 | int do_pam_account(char *username, char *remote_user) | 134 | int do_pam_account(char *username, char *remote_user) |
149 | { | 135 | { |
150 | int pam_retval; | 136 | int pam_retval; |
151 | 137 | ||
152 | debug("PAM setting rhost to \"%.200s\"", get_canonical_hostname()); | 138 | debug("PAM setting rhost to \"%.200s\"", get_canonical_hostname()); |
153 | pam_retval = pam_set_item((pam_handle_t *)pamh, PAM_RHOST, | 139 | pam_retval = pam_set_item((pam_handle_t *)pamh, PAM_RHOST, |
154 | get_canonical_hostname()); | 140 | get_canonical_hostname()); |
155 | if (pam_retval != PAM_SUCCESS) { | 141 | if (pam_retval != PAM_SUCCESS) { |
156 | fatal("PAM set rhost failed: %.200s", PAM_STRERROR((pam_handle_t *)pamh, pam_retval)); | 142 | fatal("PAM set rhost failed: %.200s", |
143 | PAM_STRERROR((pam_handle_t *)pamh, pam_retval)); | ||
157 | } | 144 | } |
158 | 145 | ||
159 | if (remote_user != NULL) { | 146 | if (remote_user != NULL) { |
160 | debug("PAM setting ruser to \"%.200s\"", remote_user); | 147 | debug("PAM setting ruser to \"%.200s\"", remote_user); |
161 | pam_retval = pam_set_item((pam_handle_t *)pamh, PAM_RUSER, remote_user); | 148 | pam_retval = pam_set_item((pam_handle_t *)pamh, PAM_RUSER, remote_user); |
162 | if (pam_retval != PAM_SUCCESS) { | 149 | if (pam_retval != PAM_SUCCESS) { |
163 | fatal("PAM set ruser failed: %.200s", PAM_STRERROR((pam_handle_t *)pamh, pam_retval)); | 150 | fatal("PAM set ruser failed: %.200s", |
151 | PAM_STRERROR((pam_handle_t *)pamh, pam_retval)); | ||
164 | } | 152 | } |
165 | } | 153 | } |
166 | 154 | ||
167 | pam_retval = pam_acct_mgmt((pam_handle_t *)pamh, 0); | 155 | pam_retval = pam_acct_mgmt((pam_handle_t *)pamh, 0); |
168 | if (pam_retval != PAM_SUCCESS) { | 156 | switch (pam_retval) { |
169 | log("PAM rejected by account configuration: %.200s", PAM_STRERROR((pam_handle_t *)pamh, pam_retval)); | 157 | case PAM_SUCCESS: |
170 | return(0); | 158 | /* This is what we want */ |
159 | break; | ||
160 | case PAM_NEW_AUTHTOK_REQD: | ||
161 | pam_msg_cat(NEW_AUTHTOK_MSG); | ||
162 | break; | ||
163 | default: | ||
164 | log("PAM rejected by account configuration: %.200s", | ||
165 | PAM_STRERROR((pam_handle_t *)pamh, pam_retval)); | ||
166 | return(0); | ||
171 | } | 167 | } |
172 | 168 | ||
173 | return(1); | 169 | return(1); |
@@ -181,13 +177,17 @@ void do_pam_session(char *username, const char *ttyname) | |||
181 | if (ttyname != NULL) { | 177 | if (ttyname != NULL) { |
182 | debug("PAM setting tty to \"%.200s\"", ttyname); | 178 | debug("PAM setting tty to \"%.200s\"", ttyname); |
183 | pam_retval = pam_set_item((pam_handle_t *)pamh, PAM_TTY, ttyname); | 179 | pam_retval = pam_set_item((pam_handle_t *)pamh, PAM_TTY, ttyname); |
184 | if (pam_retval != PAM_SUCCESS) | 180 | if (pam_retval != PAM_SUCCESS) { |
185 | fatal("PAM set tty failed: %.200s", PAM_STRERROR((pam_handle_t *)pamh, pam_retval)); | 181 | fatal("PAM set tty failed: %.200s", |
182 | PAM_STRERROR((pam_handle_t *)pamh, pam_retval)); | ||
183 | } | ||
186 | } | 184 | } |
187 | 185 | ||
188 | pam_retval = pam_open_session((pam_handle_t *)pamh, 0); | 186 | pam_retval = pam_open_session((pam_handle_t *)pamh, 0); |
189 | if (pam_retval != PAM_SUCCESS) | 187 | if (pam_retval != PAM_SUCCESS) { |
190 | fatal("PAM session setup failed: %.200s", PAM_STRERROR((pam_handle_t *)pamh, pam_retval)); | 188 | fatal("PAM session setup failed: %.200s", |
189 | PAM_STRERROR((pam_handle_t *)pamh, pam_retval)); | ||
190 | } | ||
191 | } | 191 | } |
192 | 192 | ||
193 | /* Set PAM credentials */ | 193 | /* Set PAM credentials */ |
@@ -197,8 +197,10 @@ void do_pam_setcred() | |||
197 | 197 | ||
198 | debug("PAM establishing creds"); | 198 | debug("PAM establishing creds"); |
199 | pam_retval = pam_setcred((pam_handle_t *)pamh, PAM_ESTABLISH_CRED); | 199 | pam_retval = pam_setcred((pam_handle_t *)pamh, PAM_ESTABLISH_CRED); |
200 | if (pam_retval != PAM_SUCCESS) | 200 | if (pam_retval != PAM_SUCCESS) { |
201 | fatal("PAM setcred failed: %.200s", PAM_STRERROR((pam_handle_t *)pamh, pam_retval)); | 201 | fatal("PAM setcred failed: %.200s", |
202 | PAM_STRERROR((pam_handle_t *)pamh, pam_retval)); | ||
203 | } | ||
202 | } | 204 | } |
203 | 205 | ||
204 | /* Cleanly shutdown PAM */ | 206 | /* Cleanly shutdown PAM */ |
@@ -217,9 +219,12 @@ void start_pam(struct passwd *pw) | |||
217 | 219 | ||
218 | pam_retval = pam_start(SSHD_PAM_SERVICE, pw->pw_name, &conv, | 220 | pam_retval = pam_start(SSHD_PAM_SERVICE, pw->pw_name, &conv, |
219 | (pam_handle_t**)&pamh); | 221 | (pam_handle_t**)&pamh); |
220 | if (pam_retval != PAM_SUCCESS) | ||
221 | fatal("PAM initialisation failed: %.200s", PAM_STRERROR((pam_handle_t *)pamh, pam_retval)); | ||
222 | 222 | ||
223 | if (pam_retval != PAM_SUCCESS) { | ||
224 | fatal("PAM initialisation failed: %.200s", | ||
225 | PAM_STRERROR((pam_handle_t *)pamh, pam_retval)); | ||
226 | } | ||
227 | |||
223 | fatal_add_cleanup(&pam_cleanup_proc, NULL); | 228 | fatal_add_cleanup(&pam_cleanup_proc, NULL); |
224 | } | 229 | } |
225 | 230 | ||
@@ -237,8 +242,30 @@ char **fetch_pam_environment(void) | |||
237 | /* or account checking to stderr */ | 242 | /* or account checking to stderr */ |
238 | void print_pam_messages(void) | 243 | void print_pam_messages(void) |
239 | { | 244 | { |
240 | if (pamconv_msg != NULL) | 245 | if (pam_msg != NULL) |
241 | fprintf(stderr, pamconv_msg); | 246 | fprintf(stderr, pam_msg); |
247 | } | ||
248 | |||
249 | /* Append a message to the PAM message buffer */ | ||
250 | void pam_msg_cat(const char *msg) | ||
251 | { | ||
252 | char *p; | ||
253 | size_t new_msg_len; | ||
254 | size_t pam_msg_len; | ||
255 | |||
256 | new_msg_len = strlen(msg); | ||
257 | |||
258 | if (pam_msg) { | ||
259 | pam_msg_len = strlen(pam_msg); | ||
260 | pam_msg = xrealloc(pam_msg, new_msg_len + pam_msg_len + 2); | ||
261 | p = pam_msg + pam_msg_len; | ||
262 | } else { | ||
263 | pam_msg = p = xmalloc(new_msg_len + 2); | ||
264 | } | ||
265 | |||
266 | memcpy(p, msg, new_msg_len); | ||
267 | p[new_msg_len] = '\n'; | ||
268 | p[new_msg_len + 1] = '\0'; | ||
242 | } | 269 | } |
243 | 270 | ||
244 | #endif /* USE_PAM */ | 271 | #endif /* USE_PAM */ |
@@ -121,17 +121,17 @@ allowed_user(struct passwd * pw) | |||
121 | } | 121 | } |
122 | 122 | ||
123 | #ifdef WITH_AIXAUTHENTICATE | 123 | #ifdef WITH_AIXAUTHENTICATE |
124 | if (loginrestrictions(pw->pw_name,S_RLOGIN,NULL,&loginmsg) != 0) { | 124 | if (loginrestrictions(pw->pw_name, S_RLOGIN, NULL, &loginmsg) != 0) { |
125 | if (loginmsg && *loginmsg) { | 125 | if (loginmsg && *loginmsg) { |
126 | /* Remove embedded newlines (if any) */ | 126 | /* Remove embedded newlines (if any) */ |
127 | char *p; | 127 | char *p; |
128 | for (p = loginmsg; *p; p++) | 128 | for (p = loginmsg; *p; p++) { |
129 | if (*p == '\n') | 129 | if (*p == '\n') |
130 | *p = ' '; | 130 | *p = ' '; |
131 | } | ||
131 | /* Remove trailing newline */ | 132 | /* Remove trailing newline */ |
132 | *--p = '\0'; | 133 | *--p = '\0'; |
133 | log("Login restricted for %s: %.100s", | 134 | log("Login restricted for %s: %.100s", pw->pw_name, loginmsg); |
134 | pw->pw_name, loginmsg); | ||
135 | } | 135 | } |
136 | return 0; | 136 | return 0; |
137 | } | 137 | } |
diff --git a/fake-getaddrinfo.c b/fake-getaddrinfo.c index 456c41e58..b3af4aa2e 100644 --- a/fake-getaddrinfo.c +++ b/fake-getaddrinfo.c | |||
@@ -7,113 +7,112 @@ | |||
7 | * But these functions are not implemented correctly. The minimum subset | 7 | * But these functions are not implemented correctly. The minimum subset |
8 | * is implemented for ssh use only. For exapmle, this routine assumes | 8 | * is implemented for ssh use only. For exapmle, this routine assumes |
9 | * that ai_family is AF_INET. Don't use it for another purpose. | 9 | * that ai_family is AF_INET. Don't use it for another purpose. |
10 | * | ||
11 | * In the case not using 'configure --enable-ipv6', this getaddrinfo.c | ||
12 | * will be used if you have broken getaddrinfo or no getaddrinfo. | ||
13 | */ | 10 | */ |
14 | 11 | ||
15 | #include "includes.h" | 12 | #include "includes.h" |
16 | #include "ssh.h" | 13 | #include "ssh.h" |
17 | 14 | ||
18 | #ifndef HAVE_GAI_STRERROR | 15 | #ifndef HAVE_GAI_STRERROR |
19 | char * | 16 | char *gai_strerror(int ecode) |
20 | gai_strerror(ecode) | ||
21 | int ecode; | ||
22 | { | 17 | { |
23 | switch (ecode) { | 18 | switch (ecode) { |
24 | case EAI_NODATA: | 19 | case EAI_NODATA: |
25 | return "no address associated with hostname."; | 20 | return "no address associated with hostname."; |
26 | case EAI_MEMORY: | 21 | case EAI_MEMORY: |
27 | return "memory allocation failure."; | 22 | return "memory allocation failure."; |
28 | default: | 23 | default: |
29 | return "unknown error."; | 24 | return "unknown error."; |
30 | } | 25 | } |
31 | } | 26 | } |
32 | #endif /* !HAVE_GAI_STRERROR */ | 27 | #endif /* !HAVE_GAI_STRERROR */ |
33 | 28 | ||
34 | #ifndef HAVE_FREEADDRINFO | 29 | #ifndef HAVE_FREEADDRINFO |
35 | void | 30 | void freeaddrinfo(struct addrinfo *ai) |
36 | freeaddrinfo(ai) | ||
37 | struct addrinfo *ai; | ||
38 | { | 31 | { |
39 | struct addrinfo *next; | 32 | struct addrinfo *next; |
40 | 33 | ||
41 | do { | 34 | do { |
42 | next = ai->ai_next; | 35 | next = ai->ai_next; |
43 | free(ai); | 36 | free(ai); |
44 | } while (NULL != (ai = next)); | 37 | } while (NULL != (ai = next)); |
45 | } | 38 | } |
46 | #endif /* !HAVE_FREEADDRINFO */ | 39 | #endif /* !HAVE_FREEADDRINFO */ |
47 | 40 | ||
48 | #ifndef HAVE_GETADDRINFO | 41 | #ifndef HAVE_GETADDRINFO |
49 | static struct addrinfo * | 42 | static struct addrinfo *malloc_ai(int port, u_long addr) |
50 | malloc_ai(port, addr) | ||
51 | int port; | ||
52 | u_long addr; | ||
53 | { | 43 | { |
54 | struct addrinfo *ai; | 44 | struct addrinfo *ai; |
45 | |||
46 | ai = malloc(sizeof(struct addrinfo) + sizeof(struct sockaddr_in)); | ||
47 | if (ai == NULL) | ||
48 | return(NULL); | ||
49 | |||
50 | memset(ai, 0, sizeof(struct addrinfo) + sizeof(struct sockaddr_in)); | ||
51 | |||
52 | ai->ai_addr = (struct sockaddr *)(ai + 1); | ||
53 | /* XXX -- ssh doesn't use sa_len */ | ||
54 | ai->ai_addrlen = sizeof(struct sockaddr_in); | ||
55 | ai->ai_addr->sa_family = ai->ai_family = AF_INET; | ||
55 | 56 | ||
56 | if (NULL != (ai = (struct addrinfo *)malloc(sizeof(struct addrinfo) + | 57 | ((struct sockaddr_in *)(ai)->ai_addr)->sin_port = port; |
57 | sizeof(struct sockaddr_in)))) { | 58 | ((struct sockaddr_in *)(ai)->ai_addr)->sin_addr.s_addr = addr; |
58 | memset(ai, 0, sizeof(struct addrinfo) + sizeof(struct sockaddr_in)); | 59 | |
59 | ai->ai_addr = (struct sockaddr *)(ai + 1); | 60 | return(ai); |
60 | /* XXX -- ssh doesn't use sa_len */ | ||
61 | ai->ai_addrlen = sizeof(struct sockaddr_in); | ||
62 | ai->ai_addr->sa_family = ai->ai_family = AF_INET; | ||
63 | ((struct sockaddr_in *)(ai)->ai_addr)->sin_port = port; | ||
64 | ((struct sockaddr_in *)(ai)->ai_addr)->sin_addr.s_addr = addr; | ||
65 | return ai; | ||
66 | } else { | ||
67 | return NULL; | ||
68 | } | ||
69 | } | 61 | } |
70 | 62 | ||
71 | int | 63 | int getaddrinfo(const char *hostname, const char *servname, |
72 | getaddrinfo(hostname, servname, hints, res) | 64 | const struct addrinfo *hints, struct addrinfo **res) |
73 | const char *hostname, *servname; | ||
74 | const struct addrinfo *hints; | ||
75 | struct addrinfo **res; | ||
76 | { | 65 | { |
77 | struct addrinfo *cur, *prev = NULL; | 66 | struct addrinfo *cur, *prev = NULL; |
78 | struct hostent *hp; | 67 | struct hostent *hp; |
79 | int i, port; | 68 | int i, port; |
80 | 69 | ||
81 | if (servname) | 70 | if (servname) |
82 | port = htons(atoi(servname)); | 71 | port = htons(atoi(servname)); |
83 | else | ||
84 | port = 0; | ||
85 | if (hints && hints->ai_flags & AI_PASSIVE) | ||
86 | if (NULL != (*res = malloc_ai(port, htonl(0x00000000)))) | ||
87 | return 0; | ||
88 | else | ||
89 | return EAI_MEMORY; | ||
90 | if (!hostname) | ||
91 | if (NULL != (*res = malloc_ai(port, htonl(0x7f000001)))) | ||
92 | return 0; | ||
93 | else | ||
94 | return EAI_MEMORY; | ||
95 | if (inet_addr(hostname) != -1) | ||
96 | if (NULL != (*res = malloc_ai(port, inet_addr(hostname)))) | ||
97 | return 0; | ||
98 | else | ||
99 | return EAI_MEMORY; | ||
100 | if ((hp = gethostbyname(hostname)) && | ||
101 | hp->h_name && hp->h_name[0] && hp->h_addr_list[0]) { | ||
102 | for (i = 0; hp->h_addr_list[i]; i++) | ||
103 | if (NULL != (cur = malloc_ai(port, | ||
104 | ((struct in_addr *)hp->h_addr_list[i])->s_addr))) { | ||
105 | if (prev) | ||
106 | prev->ai_next = cur; | ||
107 | else | 72 | else |
108 | *res = cur; | 73 | port = 0; |
109 | prev = cur; | 74 | |
110 | } else { | 75 | if (hints && hints->ai_flags & AI_PASSIVE) { |
111 | if (*res) | 76 | if (NULL != (*res = malloc_ai(port, htonl(0x00000000)))) |
112 | freeaddrinfo(*res); | 77 | return 0; |
113 | return EAI_MEMORY; | 78 | else |
114 | } | 79 | return EAI_MEMORY; |
115 | return 0; | 80 | } |
116 | } | 81 | |
117 | return EAI_NODATA; | 82 | if (!hostname) { |
83 | if (NULL != (*res = malloc_ai(port, htonl(0x7f000001)))) | ||
84 | return 0; | ||
85 | else | ||
86 | return EAI_MEMORY; | ||
87 | } | ||
88 | |||
89 | if (inet_addr(hostname) != -1) { | ||
90 | if (NULL != (*res = malloc_ai(port, inet_addr(hostname)))) | ||
91 | return 0; | ||
92 | else | ||
93 | return EAI_MEMORY; | ||
94 | } | ||
95 | |||
96 | hp = gethostbyname(hostname); | ||
97 | if (hp && hp->h_name && hp->h_name[0] && hp->h_addr_list[0]) { | ||
98 | for (i = 0; hp->h_addr_list[i]; i++) { | ||
99 | cur = malloc_ai(port, ((struct in_addr *)hp->h_addr_list[i])->s_addr); | ||
100 | if (cur == NULL) { | ||
101 | if (*res) | ||
102 | freeaddrinfo(*res); | ||
103 | return EAI_MEMORY; | ||
104 | } | ||
105 | |||
106 | if (prev) | ||
107 | prev->ai_next = cur; | ||
108 | else | ||
109 | *res = cur; | ||
110 | |||
111 | prev = cur; | ||
112 | } | ||
113 | return 0; | ||
114 | } | ||
115 | |||
116 | return EAI_NODATA; | ||
118 | } | 117 | } |
119 | #endif /* !HAVE_GETADDRINFO */ | 118 | #endif /* !HAVE_GETADDRINFO */ |
diff --git a/fake-getnameinfo.c b/fake-getnameinfo.c index f74f3128f..867cf90b5 100644 --- a/fake-getnameinfo.c +++ b/fake-getnameinfo.c | |||
@@ -7,55 +7,47 @@ | |||
7 | * But these functions are not implemented correctly. The minimum subset | 7 | * But these functions are not implemented correctly. The minimum subset |
8 | * is implemented for ssh use only. For exapmle, this routine assumes | 8 | * is implemented for ssh use only. For exapmle, this routine assumes |
9 | * that ai_family is AF_INET. Don't use it for another purpose. | 9 | * that ai_family is AF_INET. Don't use it for another purpose. |
10 | * | ||
11 | * In the case not using 'configure --enable-ipv6', this getnameinfo.c | ||
12 | * will be used if you have broken getnameinfo or no getnameinfo. | ||
13 | */ | 10 | */ |
14 | 11 | ||
15 | #include "includes.h" | 12 | #include "includes.h" |
16 | #include "ssh.h" | 13 | #include "ssh.h" |
17 | 14 | ||
18 | #ifndef HAVE_GETNAMEINFO | 15 | #ifndef HAVE_GETNAMEINFO |
19 | int | 16 | int getnameinfo(const struct sockaddr *sa, size_t salen, char *host, |
20 | getnameinfo(sa, salen, host, hostlen, serv, servlen, flags) | 17 | size_t hostlen, char *serv, size_t servlen, int flags) |
21 | const struct sockaddr *sa; | ||
22 | size_t salen; | ||
23 | char *host; | ||
24 | size_t hostlen; | ||
25 | char *serv; | ||
26 | size_t servlen; | ||
27 | int flags; | ||
28 | { | 18 | { |
29 | struct sockaddr_in *sin = (struct sockaddr_in *)sa; | 19 | struct sockaddr_in *sin = (struct sockaddr_in *)sa; |
30 | struct hostent *hp; | 20 | struct hostent *hp; |
31 | char tmpserv[16]; | 21 | char tmpserv[16]; |
32 | 22 | ||
33 | if (serv) { | 23 | if (serv) { |
34 | sprintf(tmpserv, "%d", ntohs(sin->sin_port)); | 24 | snprintf(tmpserv, sizeof(tmpserv), "%d", ntohs(sin->sin_port)); |
35 | if (strlen(tmpserv) > servlen) | 25 | if (strlen(tmpserv) > servlen) |
36 | return EAI_MEMORY; | 26 | return EAI_MEMORY; |
37 | else | 27 | else |
38 | strcpy(serv, tmpserv); | 28 | strcpy(serv, tmpserv); |
39 | } | ||
40 | if (host) | ||
41 | if (flags & NI_NUMERICHOST) | ||
42 | if (strlen(inet_ntoa(sin->sin_addr)) > hostlen) | ||
43 | return EAI_MEMORY; | ||
44 | else { | ||
45 | strcpy(host, inet_ntoa(sin->sin_addr)); | ||
46 | return 0; | ||
47 | } | ||
48 | else | ||
49 | if (NULL != (hp = gethostbyaddr((char *)&sin->sin_addr, | ||
50 | sizeof(struct in_addr), AF_INET))) | ||
51 | if (strlen(hp->h_name) > hostlen) | ||
52 | return EAI_MEMORY; | ||
53 | else { | ||
54 | strcpy(host, hp->h_name); | ||
55 | return 0; | ||
56 | } | 29 | } |
57 | else | 30 | |
58 | return EAI_NODATA; | 31 | if (host) { |
59 | return 0; | 32 | if (flags & NI_NUMERICHOST) { |
33 | if (strlen(inet_ntoa(sin->sin_addr)) > hostlen) | ||
34 | return EAI_MEMORY; | ||
35 | |||
36 | strcpy(host, inet_ntoa(sin->sin_addr)); | ||
37 | return 0; | ||
38 | } else { | ||
39 | hp = gethostbyaddr((char *)&sin->sin_addr, | ||
40 | sizeof(struct in_addr), AF_INET); | ||
41 | if (hp == NULL) | ||
42 | return EAI_NODATA; | ||
43 | |||
44 | if (strlen(hp->h_name) > hostlen) | ||
45 | return EAI_MEMORY; | ||
46 | |||
47 | strcpy(host, hp->h_name); | ||
48 | return 0; | ||
49 | } | ||
50 | } | ||
51 | return 0; | ||
60 | } | 52 | } |
61 | #endif /* !HAVE_GETNAMEINFO */ | 53 | #endif /* !HAVE_GETNAMEINFO */ |
diff --git a/fake-getnameinfo.h b/fake-getnameinfo.h index ecf0df2cf..0d25f4270 100644 --- a/fake-getnameinfo.h +++ b/fake-getnameinfo.h | |||
@@ -2,6 +2,7 @@ | |||
2 | #define _FAKE_GETNAMEINFO_H | 2 | #define _FAKE_GETNAMEINFO_H |
3 | 3 | ||
4 | #include "config.h" | 4 | #include "config.h" |
5 | |||
5 | #ifndef HAVE_GETNAMEINFO | 6 | #ifndef HAVE_GETNAMEINFO |
6 | int getnameinfo(const struct sockaddr *sa, size_t salen, char *host, | 7 | int getnameinfo(const struct sockaddr *sa, size_t salen, char *host, |
7 | size_t hostlen, char *serv, size_t servlen, int flags); | 8 | size_t hostlen, char *serv, size_t servlen, int flags); |
diff --git a/fake-socket.h b/fake-socket.h index e11ad44e0..0e1624d11 100644 --- a/fake-socket.h +++ b/fake-socket.h | |||
@@ -5,10 +5,10 @@ | |||
5 | #include "sys/types.h" | 5 | #include "sys/types.h" |
6 | 6 | ||
7 | #ifndef HAVE_STRUCT_SOCKADDR_STORAGE | 7 | #ifndef HAVE_STRUCT_SOCKADDR_STORAGE |
8 | #define _SS_MAXSIZE 128 /* Implementation specific max size */ | 8 | # define _SS_MAXSIZE 128 /* Implementation specific max size */ |
9 | #define _SS_ALIGNSIZE (sizeof(int)) | 9 | # define _SS_ALIGNSIZE (sizeof(int)) |
10 | #define _SS_PAD1SIZE (_SS_ALIGNSIZE - sizeof(u_short)) | 10 | # define _SS_PAD1SIZE (_SS_ALIGNSIZE - sizeof(u_short)) |
11 | #define _SS_PAD2SIZE (_SS_MAXSIZE - (sizeof(u_short) + \ | 11 | # define _SS_PAD2SIZE (_SS_MAXSIZE - (sizeof(u_short) + \ |
12 | _SS_PAD1SIZE + _SS_ALIGNSIZE)) | 12 | _SS_PAD1SIZE + _SS_ALIGNSIZE)) |
13 | 13 | ||
14 | struct sockaddr_storage { | 14 | struct sockaddr_storage { |
@@ -20,7 +20,7 @@ struct sockaddr_storage { | |||
20 | #endif /* !HAVE_STRUCT_SOCKADDR_STORAGE */ | 20 | #endif /* !HAVE_STRUCT_SOCKADDR_STORAGE */ |
21 | 21 | ||
22 | #ifndef IN6_IS_ADDR_LOOPBACK | 22 | #ifndef IN6_IS_ADDR_LOOPBACK |
23 | #define IN6_IS_ADDR_LOOPBACK(a) \ | 23 | # define IN6_IS_ADDR_LOOPBACK(a) \ |
24 | (((u_int32_t *) (a))[0] == 0 && ((u_int32_t *) (a))[1] == 0 && \ | 24 | (((u_int32_t *) (a))[0] == 0 && ((u_int32_t *) (a))[1] == 0 && \ |
25 | ((u_int32_t *) (a))[2] == 0 && ((u_int32_t *) (a))[3] == htonl (1)) | 25 | ((u_int32_t *) (a))[2] == 0 && ((u_int32_t *) (a))[3] == htonl (1)) |
26 | #endif /* !IN6_IS_ADDR_LOOPBACK */ | 26 | #endif /* !IN6_IS_ADDR_LOOPBACK */ |
@@ -18,7 +18,7 @@ | |||
18 | */ | 18 | */ |
19 | 19 | ||
20 | #include "includes.h" | 20 | #include "includes.h" |
21 | RCSID("$Id: login.c,v 1.28 2000/05/30 03:12:46 damien Exp $"); | 21 | RCSID("$Id: login.c,v 1.29 2000/05/31 01:20:12 damien Exp $"); |
22 | 22 | ||
23 | #if defined(HAVE_UTMPX_H) && defined(USE_UTMPX) | 23 | #if defined(HAVE_UTMPX_H) && defined(USE_UTMPX) |
24 | # include <utmpx.h> | 24 | # include <utmpx.h> |
@@ -38,6 +38,11 @@ RCSID("$Id: login.c,v 1.28 2000/05/30 03:12:46 damien Exp $"); | |||
38 | # include <login.h> | 38 | # include <login.h> |
39 | #endif | 39 | #endif |
40 | 40 | ||
41 | #ifdef WITH_AIXAUTHENTICATE | ||
42 | /* This is done in do_authentication */ | ||
43 | # define DISABLE_LASTLOG | ||
44 | #endif /* WITH_AIXAUTHENTICATE */ | ||
45 | |||
41 | /* | 46 | /* |
42 | * Returns the time when the user last logged in. Returns 0 if the | 47 | * Returns the time when the user last logged in. Returns 0 if the |
43 | * information is not available. This must be called before record_login. | 48 | * information is not available. This must be called before record_login. |
@@ -53,58 +58,50 @@ unsigned long | |||
53 | get_last_login_time(uid_t uid, const char *logname, | 58 | get_last_login_time(uid_t uid, const char *logname, |
54 | char *buf, unsigned int bufsize) | 59 | char *buf, unsigned int bufsize) |
55 | { | 60 | { |
56 | #if defined(WITH_AIXAUTHENTICATE) | ||
57 | /* This is done in do_authentication */ | ||
58 | return (unsigned long) 0; | ||
59 | #else | ||
60 | #if defined(_PATH_LASTLOG) && !defined(DISABLE_LASTLOG) | 61 | #if defined(_PATH_LASTLOG) && !defined(DISABLE_LASTLOG) |
61 | struct lastlog ll; | 62 | struct lastlog ll; |
62 | char *lastlog; | ||
63 | int fd; | 63 | int fd; |
64 | #ifdef LASTLOG_IS_DIR | 64 | # ifdef LASTLOG_IS_DIR |
65 | char lbuf[1024]; | 65 | char lbuf[1024]; |
66 | #endif /* LASTLOG_IS_DIR */ | ||
67 | 66 | ||
68 | lastlog = _PATH_LASTLOG; | 67 | snprintf(lbuf, sizeof(buf), "%s/%s", _PATH_LASTLOG, logname); |
68 | if ((fd = open(lbuf, O_RDONLY)) < 0) | ||
69 | return 0; | ||
70 | # else /* LASTLOG_IS_DIR */ | ||
69 | buf[0] = '\0'; | 71 | buf[0] = '\0'; |
70 | 72 | ||
71 | #ifndef LASTLOG_IS_DIR | 73 | if ((fd = open(_PATH_LASTLOG, O_RDONLY)) < 0) |
72 | fd = open(lastlog, O_RDONLY); | ||
73 | if (fd < 0) | ||
74 | return 0; | 74 | return 0; |
75 | |||
75 | lseek(fd, (off_t) ((long) uid * sizeof(ll)), SEEK_SET); | 76 | lseek(fd, (off_t) ((long) uid * sizeof(ll)), SEEK_SET); |
76 | #else /* LASTLOG_IS_DIR */ | 77 | # endif /* LASTLOG_IS_DIR */ |
77 | snprintf(lbuf, sizeof(buf), "%s/%s", lastlog, logname); | ||
78 | fd = open(lbuf, O_RDONLY); | ||
79 | if (fd < 0) | ||
80 | return 0; | ||
81 | #endif /* LASTLOG_IS_DIR */ | ||
82 | if (read(fd, &ll, sizeof(ll)) != sizeof(ll)) { | 78 | if (read(fd, &ll, sizeof(ll)) != sizeof(ll)) { |
83 | close(fd); | 79 | close(fd); |
84 | return 0; | 80 | return 0; |
85 | } | 81 | } |
82 | |||
86 | close(fd); | 83 | close(fd); |
84 | |||
87 | if (bufsize > sizeof(ll.ll_host) + 1) | 85 | if (bufsize > sizeof(ll.ll_host) + 1) |
88 | bufsize = sizeof(ll.ll_host) + 1; | 86 | bufsize = sizeof(ll.ll_host) + 1; |
89 | strncpy(buf, ll.ll_host, bufsize - 1); | 87 | strncpy(buf, ll.ll_host, bufsize - 1); |
90 | buf[bufsize - 1] = 0; | 88 | buf[bufsize - 1] = 0; |
91 | return ll.ll_time; | ||
92 | 89 | ||
90 | return ll.ll_time; | ||
93 | #else /* defined(_PATH_LASTLOG) && !defined(DISABLE_LASTLOG) */ | 91 | #else /* defined(_PATH_LASTLOG) && !defined(DISABLE_LASTLOG) */ |
94 | # ifdef HAVE_TYPE_IN_UTMP | 92 | # ifdef HAVE_TYPE_IN_UTMP |
95 | /* Look in wtmp for the last login */ | 93 | /* Look in wtmp for the last login */ |
96 | struct utmp wt; | 94 | struct utmp wt; |
97 | char *wt_file = _PATH_WTMP; | 95 | int fd1; |
98 | int fd1; | ||
99 | unsigned long t = 0; | 96 | unsigned long t = 0; |
100 | 97 | ||
101 | if ( (fd1 = open(wt_file, O_RDONLY)) < 0 ) { | 98 | if ((fd1 = open(_PATH_WTMP, O_RDONLY)) < 0) { |
102 | error("Couldn't open %.100s to find last login time.", wt_file); | 99 | error("Couldn't open %.100s to find last login time.", _PATH_WTMP); |
103 | return 0; | 100 | return 0; |
104 | } | 101 | } |
105 | 102 | ||
106 | /* seek to last record of file */ | 103 | /* seek to last record of file */ |
107 | lseek(fd1, (off_t)(0-sizeof(struct utmp)), SEEK_END); | 104 | lseek(fd1, (off_t)(0 - sizeof(struct utmp)), SEEK_END); |
108 | 105 | ||
109 | /* loop through wtmp for our last user login record */ | 106 | /* loop through wtmp for our last user login record */ |
110 | do { | 107 | do { |
@@ -113,47 +110,44 @@ get_last_login_time(uid_t uid, const char *logname, | |||
113 | return 0; | 110 | return 0; |
114 | } | 111 | } |
115 | 112 | ||
116 | if ( wt.ut_type == USER_PROCESS) { | 113 | if (wt.ut_type == USER_PROCESS) { |
117 | if ( !strncmp(logname, wt.ut_user, 8) ) { | 114 | if (!strncmp(logname, wt.ut_user, 8)) { |
118 | t = (unsigned long) wt.ut_time; | 115 | t = (unsigned long)wt.ut_time; |
119 | # ifdef HAVE_HOST_IN_UTMP | 116 | # ifdef HAVE_HOST_IN_UTMP |
120 | if (bufsize > sizeof(wt.ut_host) + 1) | 117 | if (bufsize > sizeof(wt.ut_host) + 1) |
121 | bufsize = sizeof(wt.ut_host) + 1; | 118 | bufsize = sizeof(wt.ut_host) + 1; |
122 | strncpy(buf, wt.ut_host, bufsize - 1); | 119 | strncpy(buf, wt.ut_host, bufsize - 1); |
123 | buf[bufsize - 1] = 0; | 120 | buf[bufsize - 1] = 0; |
124 | # else /* HAVE_HOST_IN_UTMP */ | 121 | # else /* HAVE_HOST_IN_UTMP */ |
125 | buf[0] = 0; | 122 | buf[0] = 0; |
126 | # endif /* HAVE_HOST_IN_UTMP */ | 123 | # endif /* HAVE_HOST_IN_UTMP */ |
127 | } | 124 | } |
128 | } | 125 | } |
129 | 126 | ||
130 | if (lseek(fd1, (off_t)(0-2*sizeof(struct utmp)), SEEK_CUR) == -1) | 127 | if (lseek(fd1, (off_t)(0 - (2 * sizeof(struct utmp))), SEEK_CUR) < 0) |
131 | break; | 128 | break; |
132 | } while (t == 0); | 129 | } while (t == 0); |
133 | 130 | ||
134 | return t; | 131 | return t; |
135 | # else | 132 | # else /* HAVE_TYPE_IN_UTMP */ |
136 | return 0; | 133 | return 0; |
137 | # endif /* HAVE_TYPE_IN_UTMP */ | 134 | # endif /* HAVE_TYPE_IN_UTMP */ |
138 | #endif /* defined(_PATH_LASTLOG) && !defined(DISABLE_LASTLOG) */ | 135 | #endif /* defined(_PATH_LASTLOG) && !defined(DISABLE_LASTLOG) */ |
139 | #endif /* defined(WITH_AIXAUTHENTICATE) */ | ||
140 | } | 136 | } |
141 | 137 | ||
142 | /* | 138 | /* |
143 | * Records that the user has logged in. I these parts of operating systems | 139 | * Records that the user has logged in. I wish these parts of operating |
144 | * were more standardized. | 140 | * systems were more standardized. |
145 | */ | 141 | */ |
146 | |||
147 | void | 142 | void |
148 | record_login(pid_t pid, const char *ttyname, const char *user, uid_t uid, | 143 | record_login(pid_t pid, const char *ttyname, const char *user, uid_t uid, |
149 | const char *host, struct sockaddr * addr) | 144 | const char *host, struct sockaddr * addr) |
150 | { | 145 | { |
151 | #if defined(_PATH_LASTLOG) && !defined(DISABLE_LASTLOG) | 146 | #if defined(_PATH_LASTLOG) && !defined(DISABLE_LASTLOG) |
152 | struct lastlog ll; | 147 | struct lastlog ll; |
153 | char *lastlog; | 148 | # ifdef LASTLOG_IS_DIR |
154 | #ifdef LASTLOG_IS_DIR | ||
155 | char buf[1024]; | 149 | char buf[1024]; |
156 | #endif /* LASTLOG_IS_DIR */ | 150 | # endif /* LASTLOG_IS_DIR */ |
157 | #endif /* defined(_PATH_LASTLOG) && !defined(DISABLE_LASTLOG) */ | 151 | #endif /* defined(_PATH_LASTLOG) && !defined(DISABLE_LASTLOG) */ |
158 | struct utmp u; | 152 | struct utmp u; |
159 | #if defined(HAVE_UTMPX_H) && defined(USE_UTMPX) | 153 | #if defined(HAVE_UTMPX_H) && defined(USE_UTMPX) |
@@ -163,28 +157,35 @@ record_login(pid_t pid, const char *ttyname, const char *user, uid_t uid, | |||
163 | /* Construct an utmp/wtmp entry. */ | 157 | /* Construct an utmp/wtmp entry. */ |
164 | memset(&u, 0, sizeof(u)); | 158 | memset(&u, 0, sizeof(u)); |
165 | strncpy(u.ut_line, ttyname + 5, sizeof(u.ut_line)); | 159 | strncpy(u.ut_line, ttyname + 5, sizeof(u.ut_line)); |
160 | |||
166 | #if defined(HAVE_ID_IN_UTMP) | 161 | #if defined(HAVE_ID_IN_UTMP) |
167 | #ifdef _AIX | 162 | # ifdef _AIX |
168 | strncpy(u.ut_id, ttyname + 5, sizeof(u.ut_id)); | 163 | strncpy(u.ut_id, ttyname + 5, sizeof(u.ut_id)); |
169 | #else /* !AIX */ | 164 | # else /* !AIX */ |
170 | strncpy(u.ut_id, ttyname + 8, sizeof(u.ut_id)); | 165 | strncpy(u.ut_id, ttyname + 8, sizeof(u.ut_id)); |
171 | #endif | 166 | # endif |
172 | #endif /* defined(HAVE_ID_IN_UTMP) */ | 167 | #endif /* defined(HAVE_ID_IN_UTMP) */ |
168 | |||
173 | strncpy(u.ut_name, user, sizeof(u.ut_name)); | 169 | strncpy(u.ut_name, user, sizeof(u.ut_name)); |
170 | |||
174 | #if defined(HAVE_TV_IN_UTMP) | 171 | #if defined(HAVE_TV_IN_UTMP) |
175 | (void)gettimeofday(&u.ut_tv, NULL); | 172 | (void)gettimeofday(&u.ut_tv, NULL); |
176 | #else /* defined(HAVE_TV_IN_UTMP) */ | 173 | #else /* defined(HAVE_TV_IN_UTMP) */ |
177 | u.ut_time = time(NULL); | 174 | u.ut_time = time(NULL); |
178 | #endif /* defined(HAVE_TV_IN_UTMP) */ | 175 | #endif /* defined(HAVE_TV_IN_UTMP) */ |
176 | |||
179 | #if defined(HAVE_PID_IN_UTMP) | 177 | #if defined(HAVE_PID_IN_UTMP) |
180 | u.ut_pid = (pid_t)pid; | 178 | u.ut_pid = (pid_t)pid; |
181 | #endif /* HAVE_PID_IN_UTMP */ | 179 | #endif /* HAVE_PID_IN_UTMP */ |
180 | |||
182 | #if defined(HAVE_TYPE_IN_UTMP) | 181 | #if defined(HAVE_TYPE_IN_UTMP) |
183 | u.ut_type = (uid == -1)?DEAD_PROCESS:USER_PROCESS; | 182 | u.ut_type = (uid == -1)?DEAD_PROCESS:USER_PROCESS; |
184 | #endif /* HAVE_TYPE_IN_UTMP */ | 183 | #endif /* HAVE_TYPE_IN_UTMP */ |
184 | |||
185 | #if defined(HAVE_HOST_IN_UTMP) | 185 | #if defined(HAVE_HOST_IN_UTMP) |
186 | strncpy(u.ut_host, host, sizeof(u.ut_host)); | 186 | strncpy(u.ut_host, host, sizeof(u.ut_host)); |
187 | #endif | 187 | #endif |
188 | |||
188 | #if defined(HAVE_ADDR_IN_UTMP) | 189 | #if defined(HAVE_ADDR_IN_UTMP) |
189 | if (addr) { | 190 | if (addr) { |
190 | switch (addr->sa_family) { | 191 | switch (addr->sa_family) { |
@@ -193,26 +194,29 @@ record_login(pid_t pid, const char *ttyname, const char *user, uid_t uid, | |||
193 | memcpy(&(u.ut_addr), &(in->sin_addr), sizeof(&(in->sin_addr))); | 194 | memcpy(&(u.ut_addr), &(in->sin_addr), sizeof(&(in->sin_addr))); |
194 | break; | 195 | break; |
195 | } | 196 | } |
196 | #if defined(HAVE_ADDR_V6_IN_UTMP) | 197 | # if defined(HAVE_ADDR_V6_IN_UTMP) |
197 | case AF_INET6: { | 198 | case AF_INET6: { |
198 | struct sockaddr_in6 *in6 = (struct sockaddr_in6*)addr; | 199 | struct sockaddr_in6 *in6 = (struct sockaddr_in6*)addr; |
199 | memcpy(u.ut_addr_v6, &(in6->sin6_addr), sizeof(&(in6->sin6_addr))); | 200 | memcpy(u.ut_addr_v6, &(in6->sin6_addr), sizeof(&(in6->sin6_addr))); |
200 | break; | 201 | break; |
201 | } | 202 | } |
202 | #endif | 203 | # endif /* defined(HAVE_ADDR_V6_IN_UTMP) */ |
203 | default: | 204 | default: |
204 | break; | 205 | break; |
205 | } | 206 | } |
206 | } | 207 | } |
207 | #endif | 208 | #endif /* defined(HAVE_ADDR_IN_UTMP) */ |
208 | 209 | ||
209 | #if defined(HAVE_UTMPX_H) && defined(USE_UTMPX) | 210 | #if defined(HAVE_UTMPX_H) && defined(USE_UTMPX) |
210 | memset(&utx, 0, sizeof(utx)); | 211 | memset(&utx, 0, sizeof(utx)); |
212 | |||
211 | strncpy(utx.ut_user, user, sizeof(utx.ut_name)); | 213 | strncpy(utx.ut_user, user, sizeof(utx.ut_name)); |
212 | strncpy(utx.ut_line, ttyname + 5, sizeof(utx.ut_line)); | 214 | strncpy(utx.ut_line, ttyname + 5, sizeof(utx.ut_line)); |
213 | strncpy(utx.ut_id, ttyname + 8, sizeof(utx.ut_id)); | 215 | strncpy(utx.ut_id, ttyname + 8, sizeof(utx.ut_id)); |
216 | |||
214 | utx.ut_pid = (pid_t)pid; | 217 | utx.ut_pid = (pid_t)pid; |
215 | (void)gettimeofday(&utx.ut_tv, NULL); | 218 | (void)gettimeofday(&utx.ut_tv, NULL); |
219 | |||
216 | utx.ut_type = (uid == -1)?DEAD_PROCESS:USER_PROCESS; | 220 | utx.ut_type = (uid == -1)?DEAD_PROCESS:USER_PROCESS; |
217 | # ifdef HAVE_HOST_IN_UTMPX | 221 | # ifdef HAVE_HOST_IN_UTMPX |
218 | # ifdef HAVE_SYSLEN_IN_UTMPX | 222 | # ifdef HAVE_SYSLEN_IN_UTMPX |
@@ -225,7 +229,8 @@ record_login(pid_t pid, const char *ttyname, const char *user, uid_t uid, | |||
225 | # endif /* HAVE_SYSLEN_IN_UTMPX */ | 229 | # endif /* HAVE_SYSLEN_IN_UTMPX */ |
226 | utx.ut_host[sizeof(utx.ut_host)-1] = '\0'; | 230 | utx.ut_host[sizeof(utx.ut_host)-1] = '\0'; |
227 | # endif | 231 | # endif |
228 | #if defined(HAVE_ADDR_IN_UTMPX) | 232 | |
233 | # if defined(HAVE_ADDR_IN_UTMPX) | ||
229 | if (addr) { | 234 | if (addr) { |
230 | switch (addr->sa_family) { | 235 | switch (addr->sa_family) { |
231 | case AF_INET: { | 236 | case AF_INET: { |
@@ -233,31 +238,27 @@ record_login(pid_t pid, const char *ttyname, const char *user, uid_t uid, | |||
233 | memcpy(&(utx.ut_addr), &(in->sin_addr), sizeof(&(in->sin_addr))); | 238 | memcpy(&(utx.ut_addr), &(in->sin_addr), sizeof(&(in->sin_addr))); |
234 | break; | 239 | break; |
235 | } | 240 | } |
236 | #if defined(HAVE_ADDR_V6_IN_UTMPX) | 241 | # if defined(HAVE_ADDR_V6_IN_UTMPX) |
237 | case AF_INET6: { | 242 | case AF_INET6: { |
238 | struct sockaddr_in6 *in6 = (struct sockaddr_in6*)addr; | 243 | struct sockaddr_in6 *in6 = (struct sockaddr_in6*)addr; |
239 | memcpy(utx.ut_addr_v6, &(in6->sin6_addr), sizeof(&(in6->sin6_addr))); | 244 | memcpy(utx.ut_addr_v6, &(in6->sin6_addr), sizeof(&(in6->sin6_addr))); |
240 | break; | 245 | break; |
241 | } | 246 | } |
242 | #endif | 247 | # endif /* defined(HAVE_ADDR_V6_IN_UTMPX) */ |
243 | default: | 248 | default: |
244 | break; | 249 | break; |
245 | } | 250 | } |
246 | } | 251 | } |
247 | #endif | 252 | # endif /* defined(HAVE_ADDR_IN_UTMPX) */ |
248 | #endif /* defined(HAVE_UTMPX_H) && defined(USE_UTMPX) */ | 253 | #endif /* defined(HAVE_UTMPX_H) && defined(USE_UTMPX) */ |
249 | 254 | ||
250 | /*#if defined(HAVE_UTMPX_H) && defined(USE_UTMPX) && !defined(HAVE_LOGIN)*/ | ||
251 | #if defined(HAVE_UTMPX_H) && defined(USE_UTMPX) | 255 | #if defined(HAVE_UTMPX_H) && defined(USE_UTMPX) |
252 | login(&u, &utx); | 256 | login(&u, &utx); |
253 | #else /* defined(HAVE_UTMPX_H) && defined(USE_UTMPX) */ | 257 | #else /* defined(HAVE_UTMPX_H) && defined(USE_UTMPX) */ |
254 | login(&u); | 258 | login(&u); |
255 | #endif /* defined(HAVE_UTMPX_H) && defined(USE_UTMPX) */ | 259 | #endif /* defined(HAVE_UTMPX_H) && defined(USE_UTMPX) */ |
256 | 260 | ||
257 | #if defined(_PATH_LASTLOG) && !defined(DISABLE_LASTLOG) && !defined(WITH_AIXAUTHENTICATE) | 261 | #if defined(_PATH_LASTLOG) && !defined(DISABLE_LASTLOG) |
258 | /* AIX does this in do_authentication */ | ||
259 | lastlog = _PATH_LASTLOG; | ||
260 | |||
261 | /* Update lastlog unless actually recording a logout. */ | 262 | /* Update lastlog unless actually recording a logout. */ |
262 | if (strcmp(user, "") != 0) { | 263 | if (strcmp(user, "") != 0) { |
263 | int fd; | 264 | int fd; |
@@ -271,21 +272,25 @@ record_login(pid_t pid, const char *ttyname, const char *user, uid_t uid, | |||
271 | ll.ll_time = time(NULL); | 272 | ll.ll_time = time(NULL); |
272 | strncpy(ll.ll_line, ttyname + 5, sizeof(ll.ll_line)); | 273 | strncpy(ll.ll_line, ttyname + 5, sizeof(ll.ll_line)); |
273 | strncpy(ll.ll_host, host, sizeof(ll.ll_host)); | 274 | strncpy(ll.ll_host, host, sizeof(ll.ll_host)); |
274 | #ifdef LASTLOG_IS_DIR | 275 | # ifdef LASTLOG_IS_DIR |
275 | snprintf(buf, sizeof(buf), "%s/%s", lastlog, user); | 276 | snprintf(buf, sizeof(buf), "%s/%s", _PATH_LASTLOG, user); |
276 | fd = open(buf, O_RDWR); | 277 | if ((fd = open(buf, O_RDWR)) >= 0) { |
277 | if (fd >= 0) { | ||
278 | #else /* LASTLOG_IS_DIR */ | ||
279 | fd = open(lastlog, O_RDWR); | ||
280 | if (fd >= 0) { | ||
281 | lseek(fd, (off_t) ((long) uid * sizeof(ll)), SEEK_SET); | ||
282 | #endif /* LASTLOG_IS_DIR */ | ||
283 | if (write(fd, &ll, sizeof(ll)) != sizeof(ll)) | 278 | if (write(fd, &ll, sizeof(ll)) != sizeof(ll)) |
284 | log("Could not write %.100s: %.100s", lastlog, strerror(errno)); | 279 | log("Could not write %.100s: %.100s", buf, strerror(errno)); |
285 | close(fd); | 280 | close(fd); |
286 | } | 281 | } |
282 | # else /* LASTLOG_IS_DIR */ | ||
283 | if ((fd = open(_PATH_LASTLOG, O_RDWR)) >= 0) { | ||
284 | lseek(fd, (off_t) ((long) uid * sizeof(ll)), SEEK_SET); | ||
285 | if (write(fd, &ll, sizeof(ll)) != sizeof(ll)) { | ||
286 | log("Could not write %.100s: %.100s", _PATH_LASTLOG, | ||
287 | strerror(errno)); | ||
288 | } | ||
289 | close(fd); | ||
290 | } | ||
291 | # endif /* LASTLOG_IS_DIR */ | ||
287 | } | 292 | } |
288 | #endif /* defined(_PATH_LASTLOG) && !defined(DISABLE_LASTLOG) && !defined(WITH_AIXAUTHENTICATE) */ | 293 | #endif /* defined(_PATH_LASTLOG) && !defined(DISABLE_LASTLOG) */ |
289 | } | 294 | } |
290 | 295 | ||
291 | /* Records that the user has logged out. */ | 296 | /* Records that the user has logged out. */ |