]>
Commit | Line | Data |
---|---|---|
41b2f314 | 1 | /* |
2 | * | |
3 | * Copyright (c) 2001 Gert Doering. All rights reserved. | |
4 | * | |
5 | * Redistribution and use in source and binary forms, with or without | |
6 | * modification, are permitted provided that the following conditions | |
7 | * are met: | |
8 | * 1. Redistributions of source code must retain the above copyright | |
9 | * notice, this list of conditions and the following disclaimer. | |
10 | * 2. Redistributions in binary form must reproduce the above copyright | |
11 | * notice, this list of conditions and the following disclaimer in the | |
12 | * documentation and/or other materials provided with the distribution. | |
13 | * | |
14 | * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR | |
15 | * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES | |
16 | * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. | |
17 | * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, | |
18 | * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT | |
19 | * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | |
20 | * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | |
21 | * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | |
22 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF | |
23 | * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
24 | * | |
25 | */ | |
e9a17296 | 26 | #include "includes.h" |
0fff78ff | 27 | #include "ssh.h" |
28 | #include "log.h" | |
29 | #include "servconf.h" | |
acc3d05e | 30 | #include "canohost.h" |
31 | #include "xmalloc.h" | |
12408a1b | 32 | #include "buffer.h" |
e9a17296 | 33 | |
34 | #ifdef _AIX | |
35 | ||
e9a17296 | 36 | #include <uinfo.h> |
0fff78ff | 37 | #include "port-aix.h" |
38 | ||
39 | extern ServerOptions options; | |
12408a1b | 40 | extern Buffer loginmsg; |
e9a17296 | 41 | |
e9a17296 | 42 | /* |
41b2f314 | 43 | * AIX has a "usrinfo" area where logname and other stuff is stored - |
44 | * a few applications actually use this and die if it's not set | |
45 | * | |
46 | * NOTE: TTY= should be set, but since no one uses it and it's hard to | |
47 | * acquire due to privsep code. We will just drop support. | |
e9a17296 | 48 | */ |
49 | void | |
41b2f314 | 50 | aix_usrinfo(struct passwd *pw) |
e9a17296 | 51 | { |
52 | u_int i; | |
0fff78ff | 53 | size_t len; |
41b2f314 | 54 | char *cp; |
e9a17296 | 55 | |
0fff78ff | 56 | len = sizeof("LOGNAME= NAME= ") + (2 * strlen(pw->pw_name)); |
57 | cp = xmalloc(len); | |
58 | ||
59 | i = snprintf(cp, len, "LOGNAME=%s%cNAME=%s%c", pw->pw_name, '\0', | |
60 | pw->pw_name, '\0'); | |
e9a17296 | 61 | if (usrinfo(SETUINFO, cp, i) == -1) |
62 | fatal("Couldn't set usrinfo: %s", strerror(errno)); | |
63 | debug3("AIX/UsrInfo: set len %d", i); | |
0fff78ff | 64 | |
e9a17296 | 65 | xfree(cp); |
66 | } | |
67 | ||
12408a1b | 68 | # ifdef WITH_AIXAUTHENTICATE |
0fff78ff | 69 | /* |
70 | * Remove embedded newlines in string (if any). | |
71 | * Used before logging messages returned by AIX authentication functions | |
72 | * so the message is logged on one line. | |
73 | */ | |
74 | void | |
75 | aix_remove_embedded_newlines(char *p) | |
76 | { | |
77 | if (p == NULL) | |
78 | return; | |
79 | ||
80 | for (; *p; p++) { | |
81 | if (*p == '\n') | |
82 | *p = ' '; | |
83 | } | |
84 | /* Remove trailing whitespace */ | |
85 | if (*--p == ' ') | |
86 | *p = '\0'; | |
87 | } | |
12408a1b | 88 | |
89 | /* | |
90 | * Do authentication via AIX's authenticate routine. We loop until the | |
91 | * reenter parameter is 0, but normally authenticate is called only once. | |
92 | * | |
93 | * Note: this function returns 1 on success, whereas AIX's authenticate() | |
94 | * returns 0. | |
95 | */ | |
96 | int | |
97 | aix_authenticate(const char *name, const char *password, const char *host) | |
98 | { | |
99 | char *authmsg = NULL, *msg; | |
100 | int authsuccess = 0, reenter, result; | |
101 | ||
102 | do { | |
103 | result = authenticate((char *)name, (char *)password, &reenter, | |
104 | &authmsg); | |
105 | aix_remove_embedded_newlines(authmsg); | |
106 | debug3("AIX/authenticate result %d, msg %.100s", result, | |
107 | authmsg); | |
108 | } while (reenter); | |
109 | ||
110 | if (result == 0) { | |
111 | authsuccess = 1; | |
112 | ||
113 | /* No pty yet, so just label the line as "ssh" */ | |
114 | aix_setauthdb(name); | |
115 | if (loginsuccess((char *)name, (char *)host, "ssh", &msg) == 0) { | |
116 | if (msg != NULL) { | |
117 | debug("%s: msg %s", __func__, msg); | |
118 | buffer_append(&loginmsg, msg, strlen(msg)); | |
119 | xfree(msg); | |
120 | } | |
121 | } | |
122 | } | |
123 | ||
124 | if (authmsg != NULL) | |
125 | xfree(authmsg); | |
126 | ||
127 | return authsuccess; | |
128 | } | |
0fff78ff | 129 | |
12408a1b | 130 | # ifdef CUSTOM_FAILED_LOGIN |
0fff78ff | 131 | /* |
132 | * record_failed_login: generic "login failed" interface function | |
133 | */ | |
134 | void | |
135 | record_failed_login(const char *user, const char *ttyname) | |
136 | { | |
12408a1b | 137 | char *hostname = (char *)get_canonical_hostname(options.use_dns); |
0fff78ff | 138 | |
139 | if (geteuid() != 0) | |
140 | return; | |
141 | ||
142 | aix_setauthdb(user); | |
12408a1b | 143 | # ifdef AIX_LOGINFAILED_4ARG |
0fff78ff | 144 | loginfailed((char *)user, hostname, (char *)ttyname, AUDIT_FAIL_AUTH); |
12408a1b | 145 | # else |
0fff78ff | 146 | loginfailed((char *)user, hostname, (char *)ttyname); |
12408a1b | 147 | # endif |
0fff78ff | 148 | } |
12408a1b | 149 | # endif /* CUSTOM_FAILED_LOGIN */ |
0fff78ff | 150 | |
151 | /* | |
152 | * If we have setauthdb, retrieve the password registry for the user's | |
153 | * account then feed it to setauthdb. This may load registry-specific method | |
154 | * code. If we don't have setauthdb or have already called it this is a no-op. | |
155 | */ | |
156 | void | |
157 | aix_setauthdb(const char *user) | |
158 | { | |
159 | # ifdef HAVE_SETAUTHDB | |
160 | static char *registry = NULL; | |
161 | ||
162 | if (registry != NULL) /* have already done setauthdb */ | |
163 | return; | |
164 | ||
165 | if (setuserdb(S_READ) == -1) { | |
166 | debug3("%s: Could not open userdb to read", __func__); | |
167 | return; | |
168 | } | |
169 | ||
170 | if (getuserattr((char *)user, S_REGISTRY, ®istry, SEC_CHAR) == 0) { | |
171 | if (setauthdb(registry, NULL) == 0) | |
172 | debug3("%s: AIX/setauthdb set registry %s", __func__, | |
173 | registry); | |
174 | else | |
175 | debug3("%s: AIX/setauthdb set registry %s failed: %s", | |
176 | __func__, registry, strerror(errno)); | |
177 | } else | |
178 | debug3("%s: Could not read S_REGISTRY for user: %s", __func__, | |
179 | strerror(errno)); | |
180 | enduserdb(); | |
12408a1b | 181 | # endif /* HAVE_SETAUTHDB */ |
0fff78ff | 182 | } |
e9a17296 | 183 | |
12408a1b | 184 | # endif /* WITH_AIXAUTHENTICATE */ |
185 | ||
186 | #endif /* _AIX */ |