|
|
167d4b |
From 051a27256323da350eb8a64007231e72cbc53d0b Mon Sep 17 00:00:00 2001
|
|
|
167d4b |
From: Jeremy Allison <jra@samba.org>
|
|
|
167d4b |
Date: Tue, 13 Jan 2015 13:35:56 -0800
|
|
|
167d4b |
Subject: [PATCH 1/5] s3: auth: Add a utility function - SamInfo3_handle_sids()
|
|
|
167d4b |
that factors out the code to handle "Unix Users" and "Unix Groups".
|
|
|
167d4b |
|
|
|
167d4b |
Based on code from Michael Zeis <mzeis.quantum@gmail.com>
|
|
|
167d4b |
|
|
|
167d4b |
https://bugzilla.samba.org/show_bug.cgi?id=11044
|
|
|
167d4b |
|
|
|
167d4b |
Signed-off-by: Jeremy Allison <jra@samba.org>
|
|
|
167d4b |
Reviewed-by: Volker Lendecke <vl@samba.org>
|
|
|
167d4b |
(cherry picked from commit 9395243890aff5bb2166e18e33492afb28850097)
|
|
|
167d4b |
---
|
|
|
167d4b |
source3/auth/server_info.c | 70 ++++++++++++++++++++++++++++++++++++++++++++++
|
|
|
167d4b |
1 file changed, 70 insertions(+)
|
|
|
167d4b |
|
|
|
167d4b |
Index: samba-4.1.12/source3/auth/server_info.c
|
|
|
167d4b |
===================================================================
|
|
|
167d4b |
--- samba-4.1.12.orig/source3/auth/server_info.c
|
|
|
167d4b |
+++ samba-4.1.12/source3/auth/server_info.c
|
|
|
167d4b |
@@ -330,6 +330,76 @@ NTSTATUS create_info3_from_pac_logon_inf
|
|
|
167d4b |
return NT_STATUS_OK;
|
|
|
167d4b |
}
|
|
|
167d4b |
|
|
|
167d4b |
+/*
|
|
|
167d4b |
+ * Check if this is a "Unix Users" domain user, or a
|
|
|
167d4b |
+ * "Unix Groups" domain group, we need to handle it
|
|
|
167d4b |
+ * in a special way if that's the case.
|
|
|
167d4b |
+ */
|
|
|
167d4b |
+
|
|
|
167d4b |
+static NTSTATUS SamInfo3_handle_sids(const char *username,
|
|
|
167d4b |
+ const struct dom_sid *user_sid,
|
|
|
167d4b |
+ const struct dom_sid *group_sid,
|
|
|
167d4b |
+ struct netr_SamInfo3 *info3,
|
|
|
167d4b |
+ struct dom_sid *domain_sid,
|
|
|
167d4b |
+ struct extra_auth_info *extra)
|
|
|
167d4b |
+{
|
|
|
167d4b |
+ if (sid_check_is_in_unix_users(user_sid)) {
|
|
|
167d4b |
+ /* in info3 you can only set rids for the user and the
|
|
|
167d4b |
+ * primary group, and the domain sid must be that of
|
|
|
167d4b |
+ * the sam domain.
|
|
|
167d4b |
+ *
|
|
|
167d4b |
+ * Store a completely bogus value here.
|
|
|
167d4b |
+ * The real SID is stored in the extra sids.
|
|
|
167d4b |
+ * Other code will know to look there if (-1) is found
|
|
|
167d4b |
+ */
|
|
|
167d4b |
+ info3->base.rid = (uint32_t)(-1);
|
|
|
167d4b |
+ sid_copy(&extra->user_sid, user_sid);
|
|
|
167d4b |
+
|
|
|
167d4b |
+ DEBUG(10, ("Unix User found. Rid marked as "
|
|
|
167d4b |
+ "special and sid (%s) saved as extra sid\n",
|
|
|
167d4b |
+ sid_string_dbg(user_sid)));
|
|
|
167d4b |
+ } else {
|
|
|
167d4b |
+ sid_copy(domain_sid, user_sid);
|
|
|
167d4b |
+ sid_split_rid(domain_sid, &info3->base.rid);
|
|
|
167d4b |
+ }
|
|
|
167d4b |
+
|
|
|
167d4b |
+ if (is_null_sid(domain_sid)) {
|
|
|
167d4b |
+ sid_copy(domain_sid, get_global_sam_sid());
|
|
|
167d4b |
+ }
|
|
|
167d4b |
+
|
|
|
167d4b |
+ /* check if this is a "Unix Groups" domain group,
|
|
|
167d4b |
+ * if so we need special handling */
|
|
|
167d4b |
+ if (sid_check_is_in_unix_groups(group_sid)) {
|
|
|
167d4b |
+ /* in info3 you can only set rids for the user and the
|
|
|
167d4b |
+ * primary group, and the domain sid must be that of
|
|
|
167d4b |
+ * the sam domain.
|
|
|
167d4b |
+ *
|
|
|
167d4b |
+ * Store a completely bogus value here.
|
|
|
167d4b |
+ * The real SID is stored in the extra sids.
|
|
|
167d4b |
+ * Other code will know to look there if (-1) is found
|
|
|
167d4b |
+ */
|
|
|
167d4b |
+ info3->base.primary_gid = (uint32_t)(-1);
|
|
|
167d4b |
+ sid_copy(&extra->pgid_sid, group_sid);
|
|
|
167d4b |
+
|
|
|
167d4b |
+ DEBUG(10, ("Unix Group found. Rid marked as "
|
|
|
167d4b |
+ "special and sid (%s) saved as extra sid\n",
|
|
|
167d4b |
+ sid_string_dbg(group_sid)));
|
|
|
167d4b |
+ } else {
|
|
|
167d4b |
+ bool ok = sid_peek_check_rid(domain_sid, group_sid,
|
|
|
167d4b |
+ &info3->base.primary_gid);
|
|
|
167d4b |
+ if (!ok) {
|
|
|
167d4b |
+ DEBUG(1, ("The primary group domain sid(%s) does not "
|
|
|
167d4b |
+ "match the domain sid(%s) for %s(%s)\n",
|
|
|
167d4b |
+ sid_string_dbg(group_sid),
|
|
|
167d4b |
+ sid_string_dbg(domain_sid),
|
|
|
167d4b |
+ username,
|
|
|
167d4b |
+ sid_string_dbg(user_sid)));
|
|
|
167d4b |
+ return NT_STATUS_INVALID_SID;
|
|
|
167d4b |
+ }
|
|
|
167d4b |
+ }
|
|
|
167d4b |
+ return NT_STATUS_OK;
|
|
|
167d4b |
+}
|
|
|
167d4b |
+
|
|
|
167d4b |
#define RET_NOMEM(ptr) do { \
|
|
|
167d4b |
if (!ptr) { \
|
|
|
167d4b |
TALLOC_FREE(info3); \
|
|
|
167d4b |
@@ -351,7 +421,6 @@ NTSTATUS samu_to_SamInfo3(TALLOC_CTX *me
|
|
|
167d4b |
const char *tmp;
|
|
|
167d4b |
gid_t *gids;
|
|
|
167d4b |
NTSTATUS status;
|
|
|
167d4b |
- bool ok;
|
|
|
167d4b |
|
|
|
167d4b |
user_sid = pdb_get_user_sid(samu);
|
|
|
167d4b |
group_sid = pdb_get_group_sid(samu);
|
|
|
167d4b |
@@ -368,63 +437,16 @@ NTSTATUS samu_to_SamInfo3(TALLOC_CTX *me
|
|
|
167d4b |
|
|
|
167d4b |
ZERO_STRUCT(domain_sid);
|
|
|
167d4b |
|
|
|
167d4b |
- /* check if this is a "Unix Users" domain user,
|
|
|
167d4b |
- * we need to handle it in a special way if that's the case */
|
|
|
167d4b |
- if (sid_check_is_in_unix_users(user_sid)) {
|
|
|
167d4b |
- /* in info3 you can only set rids for the user and the
|
|
|
167d4b |
- * primary group, and the domain sid must be that of
|
|
|
167d4b |
- * the sam domain.
|
|
|
167d4b |
- *
|
|
|
167d4b |
- * Store a completely bogus value here.
|
|
|
167d4b |
- * The real SID is stored in the extra sids.
|
|
|
167d4b |
- * Other code will know to look there if (-1) is found
|
|
|
167d4b |
- */
|
|
|
167d4b |
- info3->base.rid = (uint32_t)(-1);
|
|
|
167d4b |
- sid_copy(&extra->user_sid, user_sid);
|
|
|
167d4b |
-
|
|
|
167d4b |
- DEBUG(10, ("Unix User found in struct samu. Rid marked as "
|
|
|
167d4b |
- "special and sid (%s) saved as extra sid\n",
|
|
|
167d4b |
- sid_string_dbg(user_sid)));
|
|
|
167d4b |
- } else {
|
|
|
167d4b |
- sid_copy(&domain_sid, user_sid);
|
|
|
167d4b |
- sid_split_rid(&domain_sid, &info3->base.rid);
|
|
|
167d4b |
- }
|
|
|
167d4b |
+ status = SamInfo3_handle_sids(pdb_get_username(samu),
|
|
|
167d4b |
+ user_sid,
|
|
|
167d4b |
+ group_sid,
|
|
|
167d4b |
+ info3,
|
|
|
167d4b |
+ &domain_sid,
|
|
|
167d4b |
+ extra);
|
|
|
167d4b |
|
|
|
167d4b |
- if (is_null_sid(&domain_sid)) {
|
|
|
167d4b |
- sid_copy(&domain_sid, get_global_sam_sid());
|
|
|
167d4b |
- }
|
|
|
167d4b |
-
|
|
|
167d4b |
- /* check if this is a "Unix Groups" domain group,
|
|
|
167d4b |
- * if so we need special handling */
|
|
|
167d4b |
- if (sid_check_is_in_unix_groups(group_sid)) {
|
|
|
167d4b |
- /* in info3 you can only set rids for the user and the
|
|
|
167d4b |
- * primary group, and the domain sid must be that of
|
|
|
167d4b |
- * the sam domain.
|
|
|
167d4b |
- *
|
|
|
167d4b |
- * Store a completely bogus value here.
|
|
|
167d4b |
- * The real SID is stored in the extra sids.
|
|
|
167d4b |
- * Other code will know to look there if (-1) is found
|
|
|
167d4b |
- */
|
|
|
167d4b |
- info3->base.primary_gid = (uint32_t)(-1);
|
|
|
167d4b |
- sid_copy(&extra->pgid_sid, group_sid);
|
|
|
167d4b |
-
|
|
|
167d4b |
- DEBUG(10, ("Unix Group found in struct samu. Rid marked as "
|
|
|
167d4b |
- "special and sid (%s) saved as extra sid\n",
|
|
|
167d4b |
- sid_string_dbg(group_sid)));
|
|
|
167d4b |
-
|
|
|
167d4b |
- } else {
|
|
|
167d4b |
- ok = sid_peek_check_rid(&domain_sid, group_sid,
|
|
|
167d4b |
- &info3->base.primary_gid);
|
|
|
167d4b |
- if (!ok) {
|
|
|
167d4b |
- DEBUG(1, ("The primary group domain sid(%s) does not "
|
|
|
167d4b |
- "match the domain sid(%s) for %s(%s)\n",
|
|
|
167d4b |
- sid_string_dbg(group_sid),
|
|
|
167d4b |
- sid_string_dbg(&domain_sid),
|
|
|
167d4b |
- pdb_get_username(samu),
|
|
|
167d4b |
- sid_string_dbg(user_sid)));
|
|
|
167d4b |
- TALLOC_FREE(info3);
|
|
|
167d4b |
- return NT_STATUS_UNSUCCESSFUL;
|
|
|
167d4b |
- }
|
|
|
167d4b |
+ if (!NT_STATUS_IS_OK(status)) {
|
|
|
167d4b |
+ TALLOC_FREE(info3);
|
|
|
167d4b |
+ return status;
|
|
|
167d4b |
}
|
|
|
167d4b |
|
|
|
167d4b |
unix_to_nt_time(&info3->base.logon_time, pdb_get_logon_time(samu));
|
|
|
167d4b |
@@ -517,7 +539,8 @@ NTSTATUS samu_to_SamInfo3(TALLOC_CTX *me
|
|
|
167d4b |
NTSTATUS passwd_to_SamInfo3(TALLOC_CTX *mem_ctx,
|
|
|
167d4b |
const char *unix_username,
|
|
|
167d4b |
const struct passwd *pwd,
|
|
|
167d4b |
- struct netr_SamInfo3 **pinfo3)
|
|
|
167d4b |
+ struct netr_SamInfo3 **pinfo3,
|
|
|
167d4b |
+ struct extra_auth_info *extra)
|
|
|
167d4b |
{
|
|
|
167d4b |
struct netr_SamInfo3 *info3;
|
|
|
167d4b |
NTSTATUS status;
|
|
|
167d4b |
@@ -612,9 +635,22 @@ NTSTATUS passwd_to_SamInfo3(TALLOC_CTX *
|
|
|
167d4b |
|
|
|
167d4b |
ZERO_STRUCT(domain_sid);
|
|
|
167d4b |
|
|
|
167d4b |
- sid_copy(&domain_sid, &user_sid);
|
|
|
167d4b |
- sid_split_rid(&domain_sid, &info3->base.rid);
|
|
|
167d4b |
+ status = SamInfo3_handle_sids(unix_username,
|
|
|
167d4b |
+ &user_sid,
|
|
|
167d4b |
+ &group_sid,
|
|
|
167d4b |
+ info3,
|
|
|
167d4b |
+ &domain_sid,
|
|
|
167d4b |
+ extra);
|
|
|
167d4b |
+
|
|
|
167d4b |
+ if (!NT_STATUS_IS_OK(status)) {
|
|
|
167d4b |
+ goto done;
|
|
|
167d4b |
+ }
|
|
|
167d4b |
+
|
|
|
167d4b |
info3->base.domain_sid = dom_sid_dup(info3, &domain_sid);
|
|
|
167d4b |
+ if (info3->base.domain_sid == NULL) {
|
|
|
167d4b |
+ status = NT_STATUS_NO_MEMORY;
|
|
|
167d4b |
+ goto done;
|
|
|
167d4b |
+ }
|
|
|
167d4b |
|
|
|
167d4b |
ok = sid_peek_check_rid(&domain_sid, &group_sid,
|
|
|
167d4b |
&info3->base.primary_gid);
|
|
|
167d4b |
Index: samba-4.1.12/source3/auth/auth_util.c
|
|
|
167d4b |
===================================================================
|
|
|
167d4b |
--- samba-4.1.12.orig/source3/auth/auth_util.c
|
|
|
167d4b |
+++ samba-4.1.12/source3/auth/auth_util.c
|
|
|
167d4b |
@@ -662,7 +662,8 @@ NTSTATUS make_server_info_pw(TALLOC_CTX
|
|
|
167d4b |
status = passwd_to_SamInfo3(result,
|
|
|
167d4b |
unix_username,
|
|
|
167d4b |
pwd,
|
|
|
167d4b |
- &result->info3);
|
|
|
167d4b |
+ &result->info3,
|
|
|
167d4b |
+ &result->extra);
|
|
|
167d4b |
if (!NT_STATUS_IS_OK(status)) {
|
|
|
167d4b |
goto done;
|
|
|
167d4b |
}
|
|
|
167d4b |
Index: samba-4.1.12/source3/auth/proto.h
|
|
|
167d4b |
===================================================================
|
|
|
167d4b |
--- samba-4.1.12.orig/source3/auth/proto.h
|
|
|
167d4b |
+++ samba-4.1.12/source3/auth/proto.h
|
|
|
167d4b |
@@ -298,7 +298,8 @@ NTSTATUS samu_to_SamInfo3(TALLOC_CTX *me
|
|
|
167d4b |
NTSTATUS passwd_to_SamInfo3(TALLOC_CTX *mem_ctx,
|
|
|
167d4b |
const char *unix_username,
|
|
|
167d4b |
const struct passwd *pwd,
|
|
|
167d4b |
- struct netr_SamInfo3 **pinfo3);
|
|
|
167d4b |
+ struct netr_SamInfo3 **pinfo3,
|
|
|
167d4b |
+ struct extra_auth_info *extra);
|
|
|
167d4b |
struct netr_SamInfo3 *copy_netr_SamInfo3(TALLOC_CTX *mem_ctx,
|
|
|
167d4b |
const struct netr_SamInfo3 *orig);
|
|
|
167d4b |
struct netr_SamInfo3 *wbcAuthUserInfo_to_netr_SamInfo3(TALLOC_CTX *mem_ctx,
|
|
|
167d4b |
Index: samba-4.1.12/selftest/target/Samba3.pm
|
|
|
167d4b |
===================================================================
|
|
|
167d4b |
--- samba-4.1.12.orig/selftest/target/Samba3.pm
|
|
|
167d4b |
+++ samba-4.1.12/selftest/target/Samba3.pm
|
|
|
167d4b |
@@ -1045,6 +1045,10 @@ sub provision($$$$$$)
|
|
|
167d4b |
path = $shrdir
|
|
|
167d4b |
force user = $unix_name
|
|
|
167d4b |
guest ok = yes
|
|
|
167d4b |
+[forceuser_unixonly]
|
|
|
167d4b |
+ path = $shrdir
|
|
|
167d4b |
+ force user = pdbtest
|
|
|
167d4b |
+ guest ok = yes
|
|
|
167d4b |
[forcegroup]
|
|
|
167d4b |
path = $shrdir
|
|
|
167d4b |
force group = nogroup
|
|
|
167d4b |
Index: samba-4.1.12/source3/script/tests/test_smbclient_auth.sh
|
|
|
167d4b |
===================================================================
|
|
|
167d4b |
--- samba-4.1.12.orig/source3/script/tests/test_smbclient_auth.sh
|
|
|
167d4b |
+++ samba-4.1.12/source3/script/tests/test_smbclient_auth.sh
|
|
|
167d4b |
@@ -27,5 +27,6 @@ testit "smbclient //$SERVER/tmpguest" $S
|
|
|
167d4b |
testit "smbclient //$SERVER/tmpguest as anon" $SMBCLIENT //$SERVER/tmpguest $CONFIGURATION -U% -I $SERVER_IP -p 139 -c quit $ADDARGS
|
|
|
167d4b |
testit "smbclient //$SERVER/forceuser" $SMBCLIENT //$SERVER/forceuser $CONFIGURATION -U$USERNAME%$PASSWORD -I $SERVER_IP -p 139 -c quit $ADDARGS
|
|
|
167d4b |
testit "smbclient //$SERVER/forceuser as anon" $SMBCLIENT //$SERVER/forceuser $CONFIGURATION -U% -I $SERVER_IP -p 139 -c quit $ADDARGS
|
|
|
167d4b |
+testit "smbclient //$SERVER/forceuser_unixonly" $SMBCLIENT //$SERVER/forceuser_unixonly $CONFIGURATION -U$USERNAME%$PASSWORD -I $SERVER_IP -p 139 -c quit $ADDARGS
|
|
|
167d4b |
testit "smbclient //$SERVER/forcegroup" $SMBCLIENT //$SERVER/forcegroup $CONFIGURATION -U$USERNAME%$PASSWORD -I $SERVER_IP -p 139 -c quit $ADDARGS
|
|
|
167d4b |
testit "smbclient //$SERVER/forcegroup as anon" $SMBCLIENT //$SERVER/forcegroup $CONFIGURATION -U% -I $SERVER_IP -p 139 -c quit $ADDARGS
|