Print this page
NEX-18907 File Access Auditing does not work with SMB Kerberos authentication
Review by: Gordon Ross <gordon.ross@nexenta.com>
Review by: Evan Layton <evan.layton@nexenta.com>
NEX-13644 File access audit logging
Reviewed by: Gordon Ross <gordon.ross@nexenta.com>
Reviewed by: Roman Strashkin <roman.strashkin@nexenta.com>
Reviewed by: Saso Kiselkov <saso.kiselkov@nexenta.com>
Reviewed by: Rick McNeal <rick.mcneal@nexenta.com>
Reviewed by: Yuri Pankov <yuri.pankov@nexenta.com>
NEX-15558 SMB logon fails during 1st second after service start
Reviewed by: Matt Barden <matt.barden@nexenta.com>
Reviewed by: Evan Layton <evan.layton@nexenta.com>
NEX-15558 SMB logon fails during 1st second after service start
Reviewed by: Matt Barden <matt.barden@nexenta.com>
Reviewed by: Evan Layton <evan.layton@nexenta.com>
NEX-8707 smb/server in 4.0.x does not accept username@hostname
Reviewed by: Evan Layton <evan.layton@nexenta.com>
Reviewed by: Gordon Ross <gordon.ross@nexenta.com>
NEX-4083 Upstream changes from illumos 5917 and 5995
Reviewed by: Matt Barden <matt.barden@nexenta.com>
Reviewed by: Kevin Crowe <kevin.crowe@nexenta.com>
Reviewed by: Yuri Pankov <yuri.pankov@nexenta.com>
SMB-149 mount.cifs RedHat\Centos 6 doesn't work with default security options
@@ -18,11 +18,11 @@
*
* CDDL HEADER END
*/
/*
* Copyright (c) 2007, 2010, Oracle and/or its affiliates. All rights reserved.
- * Copyright 2014 Nexenta Systems, Inc. All rights reserved.
+ * Copyright 2018 Nexenta Systems, Inc. All rights reserved.
*/
#include <sys/types.h>
#include <errno.h>
#include <synch.h>
@@ -74,51 +74,109 @@
static smb_audit_t *smbd_audit_unlink(uint32_t);
/*
* Invoked at user logon due to SmbSessionSetupX. Authenticate the
- * user, start an audit session and audit the event.
+ * user.
+ *
+ * On error, returns NULL, and status in user_info->lg_status
*/
smb_token_t *
smbd_user_auth_logon(smb_logon_t *user_info)
{
smb_token_t *token;
- smb_audit_t *entry;
- adt_session_data_t *ah;
- adt_event_data_t *event;
smb_logon_t tmp_user;
- au_tid_addr_t termid;
- char sidbuf[SMB_SID_STRSZ];
- char *username;
- char *domain;
- uid_t uid;
- gid_t gid;
- char *sid;
- int status;
- int retval;
+ char *p;
+ char *buf = NULL;
if (user_info->lg_username == NULL ||
user_info->lg_domain == NULL ||
user_info->lg_workstation == NULL) {
+ user_info->lg_status = NT_STATUS_INVALID_PARAMETER;
return (NULL);
}
+ /*
+ * Avoid modifying the caller-provided struct because it
+ * may or may not point to allocated strings etc.
+ * Copy to tmp_user, auth, then copy the (out) lg_status
+ * member back to the caller-provided struct.
+ */
tmp_user = *user_info;
if (tmp_user.lg_username[0] == '\0') {
tmp_user.lg_flags |= SMB_ATF_ANON;
tmp_user.lg_e_username = "anonymous";
} else {
tmp_user.lg_e_username = tmp_user.lg_username;
}
+
+ /* Handle user@domain format. */
+ if (tmp_user.lg_domain[0] == '\0' &&
+ (p = strchr(tmp_user.lg_e_username, '@')) != NULL) {
+ buf = strdup(tmp_user.lg_e_username);
+ p = buf + (p - tmp_user.lg_e_username);
+ *p = '\0';
+ tmp_user.lg_e_domain = p + 1;
+ tmp_user.lg_e_username = buf;
+ } else {
tmp_user.lg_e_domain = tmp_user.lg_domain;
+ }
- if ((token = smb_logon(&tmp_user)) == NULL) {
+ token = smb_logon(&tmp_user);
+ user_info->lg_status = tmp_user.lg_status;
+
+ if (token == NULL) {
+ if (user_info->lg_status == 0) /* should not happen */
+ user_info->lg_status = NT_STATUS_INTERNAL_ERROR;
+ }
+
+ if (!smbd_logon_audit(token, &user_info->lg_clnt_ipaddr,
+ tmp_user.lg_e_username, tmp_user.lg_e_domain)) {
+ user_info->lg_status = NT_STATUS_AUDIT_FAILED;
+ goto errout;
+ }
+
+ if (token) {
+ smb_autohome_add(token);
+ }
+
+ if (buf != NULL)
+ free(buf);
+
+ return (token);
+
+errout:
+ if (buf != NULL)
+ free(buf);
+ smb_token_destroy(token);
+ return (NULL);
+}
+
+/* Start an audit session and audit the event. */
+boolean_t
+smbd_logon_audit(smb_token_t *token, smb_inaddr_t *ipaddr, char *username,
+ char *domain)
+{
+ smb_audit_t *entry;
+ adt_session_data_t *ah = NULL;
+ adt_event_data_t *event;
+ au_tid_addr_t termid;
+ char sidbuf[SMB_SID_STRSZ];
+ uid_t uid;
+ gid_t gid;
+ char *sid;
+ int status;
+ int retval;
+
+ if (username == NULL)
+ username = "";
+
+ if (token == NULL) {
uid = ADT_NO_ATTRIB;
gid = ADT_NO_ATTRIB;
sid = NT_NULL_SIDSTR;
- username = tmp_user.lg_e_username;
- domain = tmp_user.lg_e_domain;
+ /* use the 'default' username and domain we were given */
status = ADT_FAILURE;
retval = ADT_FAIL_VALUE_AUTH;
} else {
uid = token->tkn_user.i_id;
gid = token->tkn_primary_grp.i_id;
@@ -130,41 +188,36 @@
retval = ADT_SUCCESS;
}
if (adt_start_session(&ah, NULL, 0)) {
syslog(LOG_AUTH | LOG_ALERT, "adt_start_session: %m");
- smb_token_destroy(token);
- return (NULL);
+ goto errout;
}
if ((event = adt_alloc_event(ah, ADT_smbd_session)) == NULL) {
syslog(LOG_AUTH | LOG_ALERT,
"adt_alloc_event(ADT_smbd_session): %m");
- (void) adt_end_session(ah);
- smb_token_destroy(token);
- return (NULL);
+ goto errout;
}
(void) memset(&termid, 0, sizeof (au_tid_addr_t));
- termid.at_port = user_info->lg_local_port;
+ termid.at_port = 445;
- if (user_info->lg_clnt_ipaddr.a_family == AF_INET) {
- termid.at_addr[0] = user_info->lg_clnt_ipaddr.a_ipv4;
+ if (ipaddr->a_family == AF_INET) {
+ termid.at_addr[0] = ipaddr->a_ipv4;
termid.at_type = AU_IPv4;
} else {
- bcopy(&user_info->lg_clnt_ipaddr.a_ip, termid.at_addr,
+ bcopy(&ipaddr->a_ip, termid.at_addr,
sizeof (in6_addr_t));
termid.at_type = AU_IPv6;
}
adt_set_termid(ah, &termid);
if (adt_set_user(ah, uid, gid, uid, gid, NULL, ADT_NEW)) {
syslog(LOG_AUTH | LOG_ALERT, "adt_set_user: %m");
adt_free_event(event);
- (void) adt_end_session(ah);
- smb_token_destroy(token);
- return (NULL);
+ goto errout;
}
event->adt_smbd_session.domain = domain;
event->adt_smbd_session.username = username;
event->adt_smbd_session.sid = sid;
@@ -175,27 +228,32 @@
adt_free_event(event);
if (token) {
if ((entry = malloc(sizeof (smb_audit_t))) == NULL) {
syslog(LOG_ERR, "smbd_user_auth_logon: %m");
- (void) adt_end_session(ah);
- smb_token_destroy(token);
- return (NULL);
+ goto errout;
}
entry->sa_handle = ah;
entry->sa_uid = uid;
entry->sa_gid = gid;
entry->sa_username = strdup(username);
entry->sa_domain = strdup(domain);
- smb_autohome_add(token);
smbd_audit_link(entry);
token->tkn_audit_sid = entry->sa_audit_sid;
+ adt_get_auid(ah, &token->tkn_auid);
+ adt_get_mask(ah, &token->tkn_amask);
+ adt_get_asid(ah, &token->tkn_asid);
}
- return (token);
+ return (B_TRUE);
+errout:
+ if (ah != NULL)
+ (void) adt_end_session(ah);
+
+ return (B_FALSE);
}
/*
* Logon due to a subsequent SmbSessionSetupX on an existing session.
* The user was authenticated during the initial session setup.