Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F143396582
D17056.id.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
9 KB
Referenced Files
None
Subscribers
None
D17056.id.diff
View Options
Index: auth2.c
===================================================================
--- auth2.c
+++ auth2.c
@@ -276,7 +276,7 @@
#ifdef HAVE_LOGIN_CAP
if (authctxt->pw != NULL &&
- (lc = login_getpwclass(authctxt->pw)) != NULL) {
+ (lc = PRIVSEP(login_getpwclass(authctxt->pw))) != NULL) {
logit("user %s login class %s", authctxt->pw->pw_name,
authctxt->pw->pw_class);
from_host = auth_get_canonical_hostname(ssh, options.use_dns);
@@ -291,7 +291,7 @@
authctxt->pw->pw_name, from_host);
packet_disconnect("Logins not available right now.");
}
- login_close(lc);
+ PRIVSEP(login_close(lc));
}
#endif /* HAVE_LOGIN_CAP */
Index: buffer.h
===================================================================
--- buffer.h
+++ buffer.h
@@ -21,6 +21,7 @@
#ifndef BUFFER_H
#define BUFFER_H
+#include <pwd.h>
#include "sshbuf.h"
typedef struct sshbuf Buffer;
@@ -91,5 +92,9 @@
void buffer_get_ecpoint(Buffer *, const EC_GROUP *, EC_POINT *);
#endif
+void buffer_put_passwd(Buffer *, const struct passwd *);
+struct passwd *buffer_get_passwd(Buffer *);
+void buffer_free_passwd(struct passwd *);
+
#endif /* BUFFER_H */
Index: buffer.c
===================================================================
--- buffer.c
+++ buffer.c
@@ -115,4 +115,75 @@
fatal("%s: buffer error", __func__);
}
+void
+buffer_put_passwd(Buffer *buffer, const struct passwd *pwent)
+{
+ /* We never send pointer values of struct passwd.
+ It is safe from wild pointer even if a new pointer member is added. */
+ buffer_put_int64(buffer, sizeof(*pwent));
+ buffer_put_cstring(buffer, pwent->pw_name);
+ buffer_put_cstring(buffer, "*");
+ buffer_put_int(buffer, pwent->pw_uid);
+ buffer_put_int(buffer, pwent->pw_gid);
+ buffer_put_int64(buffer, pwent->pw_change);
+#ifdef HAVE_STRUCT_PASSWD_PW_GECOS
+ buffer_put_cstring(buffer, pwent->pw_gecos);
+#endif
+#ifdef HAVE_STRUCT_PASSWD_PW_CLASS
+ buffer_put_cstring(buffer, pwent->pw_class);
+#endif
+ buffer_put_cstring(buffer, pwent->pw_dir);
+ buffer_put_cstring(buffer, pwent->pw_shell);
+ buffer_put_int64(buffer, pwent->pw_expire);
+ buffer_put_int(buffer, pwent->pw_fields);
+}
+
+struct passwd *
+buffer_get_passwd(Buffer *buffer)
+{
+ struct passwd *pw;
+ size_t len;
+
+ /* check if size of struct passwd is as same as sender's size */
+ len = buffer_get_int64(buffer);
+ if (len != sizeof(*pw))
+ return NULL;
+
+ pw = calloc(1, sizeof(*pw));
+ if (pw == NULL)
+ return NULL;
+
+ pw->pw_name = buffer_get_string(buffer, NULL);
+ pw->pw_passwd = buffer_get_string(buffer, NULL);
+ pw->pw_uid = buffer_get_int(buffer);
+ pw->pw_gid = buffer_get_int(buffer);
+ pw->pw_change = buffer_get_int64(buffer);
+#ifdef HAVE_STRUCT_PASSWD_PW_GECOS
+ pw->pw_gecos = buffer_get_string(buffer, NULL);
+#endif
+#ifdef HAVE_STRUCT_PASSWD_PW_CLASS
+ pw->pw_class = buffer_get_string(buffer, NULL);
+#endif
+ pw->pw_dir = buffer_get_string(buffer, NULL);
+ pw->pw_shell = buffer_get_string(buffer, NULL);
+ pw->pw_expire = buffer_get_int64(buffer);
+ pw->pw_fields = buffer_get_int(buffer);
+ return pw;
+}
+
+void
+buffer_free_passwd(struct passwd *pwent)
+{
+ free(pwent->pw_shell);
+ free(pwent->pw_dir);
+#ifdef HAVE_STRUCT_PASSWD_PW_CLASS
+ free(pwent->pw_class);
+#endif
+#ifdef HAVE_STRUCT_PASSWD_PW_GECOS
+ free(pwent->pw_gecos);
+#endif
+ free(pwent->pw_passwd);
+ free(pwent->pw_name);
+ free(pwent);
+}
Index: monitor.h
===================================================================
--- monitor.h
+++ monitor.h
@@ -55,7 +55,8 @@
MONITOR_REQ_GSSSTEP = 44, MONITOR_ANS_GSSSTEP = 45,
MONITOR_REQ_GSSUSEROK = 46, MONITOR_ANS_GSSUSEROK = 47,
MONITOR_REQ_GSSCHECKMIC = 48, MONITOR_ANS_GSSCHECKMIC = 49,
- MONITOR_REQ_TERM = 50,
+ MONITOR_REQ_GETPWCLASS = 50, MONITOR_ANS_GETPWCLASS = 51,
+ MONITOR_REQ_TERM = 52,
MONITOR_REQ_PAM_START = 100,
MONITOR_REQ_PAM_ACCOUNT = 102, MONITOR_ANS_PAM_ACCOUNT = 103,
Index: monitor.c
===================================================================
--- monitor.c
+++ monitor.c
@@ -125,6 +125,7 @@
int mm_answer_moduli(int, Buffer *);
int mm_answer_sign(int, Buffer *);
+int mm_answer_login_getpwclass(int, Buffer *);
int mm_answer_pwnamallow(int, Buffer *);
int mm_answer_auth2_read_banner(int, Buffer *);
int mm_answer_authserv(int, Buffer *);
@@ -203,6 +204,7 @@
#endif
{MONITOR_REQ_SIGN, MON_ONCE, mm_answer_sign},
{MONITOR_REQ_PWNAM, MON_ONCE, mm_answer_pwnamallow},
+ {MONITOR_REQ_GETPWCLASS, MON_AUTH, mm_answer_login_getpwclass},
{MONITOR_REQ_AUTHSERV, MON_ONCE, mm_answer_authserv},
{MONITOR_REQ_AUTH2_READ_BANNER, MON_ONCE, mm_answer_auth2_read_banner},
{MONITOR_REQ_AUTHPASSWORD, MON_AUTH, mm_answer_authpassword},
@@ -707,6 +709,40 @@
return (0);
}
+int
+mm_answer_login_getpwclass(int sock, Buffer *m)
+{
+ login_cap_t *lc;
+ struct passwd *pw;
+ u_int len;
+
+ debug3("%s", __func__);
+
+ pw = buffer_get_passwd(m);
+ if (pw == NULL)
+ fatal("%s: receive get struct passwd failed", __func__);
+
+ lc = login_getpwclass(pw);
+ if (lc == NULL) {
+ buffer_put_char(m, 0);
+ goto out;
+ }
+
+ buffer_put_char(m, 1);
+ buffer_put_cstring(m, lc->lc_class);
+ buffer_put_cstring(m, lc->lc_cap);
+ buffer_put_cstring(m, lc->lc_style);
+
+ login_close(lc);
+ out:
+ debug3("%s: sending MONITOR_ANS_GETPWCLASS", __func__);
+ mm_request_send(sock, MONITOR_ANS_GETPWCLASS, m);
+
+ buffer_free_passwd(pw);
+
+ return (0);
+}
+
/* Retrieves the password entry and also checks if the user is permitted */
int
@@ -744,17 +780,7 @@
authctxt->valid = 1;
buffer_put_char(m, 1);
- buffer_put_string(m, pwent, sizeof(struct passwd));
- buffer_put_cstring(m, pwent->pw_name);
- buffer_put_cstring(m, "*");
-#ifdef HAVE_STRUCT_PASSWD_PW_GECOS
- buffer_put_cstring(m, pwent->pw_gecos);
-#endif
-#ifdef HAVE_STRUCT_PASSWD_PW_CLASS
- buffer_put_cstring(m, pwent->pw_class);
-#endif
- buffer_put_cstring(m, pwent->pw_dir);
- buffer_put_cstring(m, pwent->pw_shell);
+ buffer_put_passwd(m, pwent);
out:
ssh_packet_set_log_preamble(ssh, "%suser %s",
Index: monitor_wrap.h
===================================================================
--- monitor_wrap.h
+++ monitor_wrap.h
@@ -28,6 +28,8 @@
#ifndef _MM_WRAP_H_
#define _MM_WRAP_H_
+#include <login_cap.h>
+
extern int use_privsep;
#define PRIVSEP(x) (use_privsep ? mm_##x : x)
@@ -45,6 +47,8 @@
const char *);
void mm_inform_authserv(char *, char *);
struct passwd *mm_getpwnamallow(const char *);
+login_cap_t *mm_login_getpwclass(const struct passwd *pwd);
+void mm_login_close(login_cap_t *lc);
char *mm_auth2_read_banner(void);
int mm_auth_password(struct ssh *, char *);
int mm_key_allowed(enum mm_keytype, const char *, const char *, struct sshkey *,
Index: monitor_wrap.c
===================================================================
--- monitor_wrap.c
+++ monitor_wrap.c
@@ -238,6 +238,51 @@
return (0);
}
+login_cap_t *
+mm_login_getpwclass(const struct passwd *pwent)
+{
+ Buffer m;
+ login_cap_t *lc;
+
+ debug3("%s entering", __func__);
+
+ buffer_init(&m);
+ buffer_put_passwd(&m, pwent);
+
+ mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_GETPWCLASS, &m);
+
+ debug3("%s: waiting for MONITOR_ANS_GETPWCLASS", __func__);
+ mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_GETPWCLASS, &m);
+
+ if (buffer_get_char(&m) == 0) {
+ lc = NULL;
+ goto out;
+ }
+
+ lc = malloc(sizeof(*lc));
+ if (lc == NULL)
+ fatal("%s: fail to allocate memory", __func__);
+ lc->lc_class = buffer_get_string(&m, NULL);
+ lc->lc_cap = buffer_get_string(&m, NULL);
+ lc->lc_style = buffer_get_string(&m, NULL);
+
+ out:
+ buffer_free(&m);
+
+ return (lc);
+}
+
+void
+mm_login_close(login_cap_t *lc)
+{
+ if (lc != NULL) {
+ free(lc->lc_style);
+ free(lc->lc_class);
+ free(lc->lc_cap);
+ free(lc);
+ }
+}
+
struct passwd *
mm_getpwnamallow(const char *username)
{
@@ -261,19 +306,9 @@
pw = NULL;
goto out;
}
- pw = buffer_get_string(&m, &len);
- if (len != sizeof(struct passwd))
- fatal("%s: struct passwd size mismatch", __func__);
- pw->pw_name = buffer_get_string(&m, NULL);
- pw->pw_passwd = buffer_get_string(&m, NULL);
-#ifdef HAVE_STRUCT_PASSWD_PW_GECOS
- pw->pw_gecos = buffer_get_string(&m, NULL);
-#endif
-#ifdef HAVE_STRUCT_PASSWD_PW_CLASS
- pw->pw_class = buffer_get_string(&m, NULL);
-#endif
- pw->pw_dir = buffer_get_string(&m, NULL);
- pw->pw_shell = buffer_get_string(&m, NULL);
+ pw = buffer_get_passwd(&m);
+ if (pw == NULL)
+ fatal("%s: receive struct passwd failed", __func__);
out:
/* copy options block as a Match directive may have changed some */
Index: sandbox-capsicum.c
===================================================================
--- sandbox-capsicum.c
+++ sandbox-capsicum.c
@@ -31,6 +31,7 @@
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
+#include <capsicum_helpers.h>
#include "log.h"
#include "monitor.h"
@@ -71,6 +72,8 @@
struct rlimit rl_zero;
cap_rights_t rights;
+ caph_cache_tzdata();
+
rl_zero.rlim_cur = rl_zero.rlim_max = 0;
if (setrlimit(RLIMIT_FSIZE, &rl_zero) == -1)
Index: sshd.c
===================================================================
--- sshd.c
+++ sshd.c
@@ -2084,6 +2084,10 @@
* the socket goes away.
*/
remote_ip = ssh_remote_ipaddr(ssh);
+#ifdef HAVE_LOGIN_CAP
+ /* Also caches remote hostname for sandboxed child*/
+ auth_get_canonical_hostname(ssh, options.use_dns);
+#endif
#ifdef SSH_AUDIT_EVENTS
audit_connection_from(remote_ip, remote_port);
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Fri, Jan 30, 10:37 PM (13 h, 4 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
28104956
Default Alt Text
D17056.id.diff (9 KB)
Attached To
Mode
D17056: [sshd] add wrapper function of login_getpwclass
Attached
Detach File
Event Timeline
Log In to Comment