1 /* |
1 /* |
2 * CDDL HEADER START |
2 * CDDL HEADER START |
3 * |
3 * |
4 * The contents of this file are subject to the terms of the |
4 * The contents of this file are subject to the terms of the |
5 * Common Development and Distribution License, Version 1.0 only |
5 * Common Development and Distribution License (the "License"). |
6 * (the "License"). You may not use this file except in compliance |
6 * You may not use this file except in compliance with the License. |
7 * with the License. |
|
8 * |
7 * |
9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE |
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE |
10 * or http://www.opensolaris.org/os/licensing. |
9 * or http://www.opensolaris.org/os/licensing. |
11 * See the License for the specific language governing permissions |
10 * See the License for the specific language governing permissions |
12 * and limitations under the License. |
11 * and limitations under the License. |
67 int rc; |
65 int rc; |
68 |
66 |
69 assert(pwd != NULL); |
67 assert(pwd != NULL); |
70 |
68 |
71 if (adt_start_session(&ah, NULL, ADT_USE_PROC_DATA)) { |
69 if (adt_start_session(&ah, NULL, ADT_USE_PROC_DATA)) { |
72 syslog(LOG_AUTH | LOG_ALERT, "audit: %m"); |
70 syslog(LOG_AUTH | LOG_ALERT, "login adt_start_session(): %m"); |
73 return; |
71 return; |
74 } |
72 } |
75 if (adt_set_user(ah, pwd->pw_uid, pwd->pw_gid, |
73 if (adt_set_user(ah, pwd->pw_uid, pwd->pw_gid, |
76 pwd->pw_uid, pwd->pw_gid, NULL, ADT_USER)) { |
74 pwd->pw_uid, pwd->pw_gid, NULL, ADT_USER)) { |
77 syslog(LOG_AUTH | LOG_ALERT, "audit: %m"); |
75 syslog(LOG_AUTH | LOG_ALERT, "login adt_set_user(): %m"); |
78 (void) adt_end_session(ah); |
76 (void) adt_end_session(ah); |
79 return; |
77 return; |
80 } |
78 } |
81 event = adt_alloc_event(ah, event_id); |
79 event = adt_alloc_event(ah, event_id); |
82 |
80 |
93 rc = adt_put_event(event, ADT_SUCCESS, ADT_SUCCESS); |
91 rc = adt_put_event(event, ADT_SUCCESS, ADT_SUCCESS); |
94 |
92 |
95 (void) adt_free_event(event); |
93 (void) adt_free_event(event); |
96 if (rc) { |
94 if (rc) { |
97 (void) adt_end_session(ah); |
95 (void) adt_end_session(ah); |
98 syslog(LOG_AUTH | LOG_ALERT, "audit: %m"); |
96 syslog(LOG_AUTH | LOG_ALERT, "login adt_put_event(): %m"); |
99 return; |
97 return; |
100 } |
98 } |
101 /* |
99 /* |
102 * The code above executes whether or not audit is enabled. |
100 * The code above executes whether or not audit is enabled. |
103 * However audit_logout must only execute if audit is |
101 * However audit_logout must only execute if audit is |
123 audit_logout(adt_session_data_t *ah) |
121 audit_logout(adt_session_data_t *ah) |
124 { |
122 { |
125 adt_event_data_t *logout; |
123 adt_event_data_t *logout; |
126 int status; /* wait status */ |
124 int status; /* wait status */ |
127 pid_t pid; |
125 pid_t pid; |
|
126 priv_set_t *priv; /* waiting process privs */ |
|
127 |
|
128 if ((logout = adt_alloc_event(ah, ADT_logout)) == NULL) { |
|
129 syslog(LOG_AUTH | LOG_ALERT, |
|
130 "adt_alloc_event(ADT_logout): %m"); |
|
131 return; |
|
132 } |
|
133 if ((priv = priv_allocset()) == NULL) { |
|
134 syslog(LOG_AUTH | LOG_ALERT, |
|
135 "login audit_logout: could not alloc privs: %m"); |
|
136 adt_free_event(logout); |
|
137 return; |
|
138 } |
|
139 |
|
140 /* |
|
141 * The child returns and continues the login processing. |
|
142 * The parent's sole job is to wait for child exit, write the |
|
143 * logout audit record, and replay the child's exit code. |
|
144 */ |
128 |
145 |
129 if ((pid = fork()) == 0) { |
146 if ((pid = fork()) == 0) { |
130 return; |
147 /* child */ |
131 } else if (pid == -1) { |
|
132 syslog(LOG_AUTH | LOG_ALERT, "login: could not fork: %m"); |
|
133 exit(1); |
|
134 } else { |
|
135 /* |
|
136 * When this routine is called, the current working |
|
137 * directory is the user's home directory. Change it |
|
138 * to root for the waiting process so that the user's |
|
139 * home directory can be unmounted if necessary. |
|
140 */ |
|
141 if (chdir("/") != 0) { |
|
142 syslog(LOG_AUTH | LOG_ALERT, |
|
143 "login: could not chdir: %m"); |
|
144 /* since we let the child finish we just bail */ |
|
145 exit(0); |
|
146 } |
|
147 while (pid != waitpid(pid, &status, 0)) |
|
148 continue; |
|
149 |
|
150 logout = adt_alloc_event(ah, ADT_logout); |
|
151 if (logout == NULL) |
|
152 exit(0); |
|
153 |
|
154 (void) adt_put_event(logout, ADT_SUCCESS, ADT_SUCCESS); |
|
155 |
148 |
156 adt_free_event(logout); |
149 adt_free_event(logout); |
157 exit(0); |
150 priv_freeset(priv); |
158 } |
151 return; |
|
152 } |
|
153 if (pid == -1) { |
|
154 /* failure */ |
|
155 |
|
156 syslog(LOG_AUTH | LOG_ALERT, |
|
157 "login audit_logout: could not fork: %m"); |
|
158 adt_free_event(logout); |
|
159 priv_freeset(priv); |
|
160 return; |
|
161 } |
|
162 |
|
163 /* parent process */ |
|
164 |
|
165 /* |
|
166 * When this routine is called, the current working |
|
167 * directory is the user's home directory and there are |
|
168 * unknown open files. For the waiting process, change the |
|
169 * current directory to root and close files so that the |
|
170 * user's home directory and anything else can be unmounted |
|
171 * if necessary. |
|
172 */ |
|
173 if (chdir("/") != 0) { |
|
174 syslog(LOG_AUTH | LOG_ALERT, |
|
175 "login audit_logut: could not chdir /: %m"); |
|
176 } |
|
177 /* |
|
178 * Reduce privileges to just those needed. |
|
179 */ |
|
180 priv_emptyset(priv); |
|
181 if ((priv_addset(priv, PRIV_PROC_AUDIT) != 0) || |
|
182 (setppriv(PRIV_SET, PRIV_PERMITTED, priv) != 0)) { |
|
183 syslog(LOG_AUTH | LOG_ALERT, |
|
184 "login audit_logout: could not reduce privs: %m"); |
|
185 } |
|
186 closefrom(0); |
|
187 priv_freeset(priv); |
|
188 while (pid != waitpid(pid, &status, 0)) |
|
189 continue; |
|
190 |
|
191 (void) adt_put_event(logout, ADT_SUCCESS, ADT_SUCCESS); |
|
192 adt_free_event(logout); |
|
193 (void) adt_end_session(ah); |
|
194 exit(WEXITSTATUS(status)); |
159 } |
195 } |
160 |
196 |
161 /* |
197 /* |
162 * errors are ignored since there is no action to take on error. |
198 * errors are ignored since there is no action to take on error. |
163 * |
199 * |