summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGerald Carter <jerry@samba.org>2006-07-10 12:35:27 +0000
committerGerald Carter <jerry@samba.org>2006-07-10 12:35:27 +0000
commite3b0c59151fc45a7bcc1c099ed71c9783f15acd5 (patch)
treea2d5168f2da0813814526e3206f1c027609af77e
parent8a3f5ba7a627c4cacbbc4dc81b3d5921e1c2ecbf (diff)
downloadsamba-e3b0c59151fc45a7bcc1c099ed71c9783f15acd5.tar.gz
samba-e3b0c59151fc45a7bcc1c099ed71c9783f15acd5.tar.xz
samba-e3b0c59151fc45a7bcc1c099ed71c9783f15acd5.zip
r16915: grab vl's fix for BUG 3915
-rw-r--r--WHATSNEW.txt2
-rw-r--r--source/auth/auth_util.c99
-rw-r--r--source/passdb/lookup_sid.c3
-rw-r--r--source/passdb/util_unixsids.c6
4 files changed, 64 insertions, 46 deletions
diff --git a/WHATSNEW.txt b/WHATSNEW.txt
index 453a563fd9a..0accd7829ac 100644
--- a/WHATSNEW.txt
+++ b/WHATSNEW.txt
@@ -201,6 +201,8 @@ o Volker Lendecke <vl@samba.org>
shares.
* Fix an invalid munlock() call in winbindd's credentials cache.
* Fix compile warnings when passing NULL to snprintf().
+ * BUG 3915: Fall back to a pure unix user with S-1-22 SIDs in the
+ token in case anything weird is going on with the 'force user'.
o Jason Mader <jason@ncac.gwu.edu>
diff --git a/source/auth/auth_util.c b/source/auth/auth_util.c
index c5ce55bc8c1..493d7393d07 100644
--- a/source/auth/auth_util.c
+++ b/source/auth/auth_util.c
@@ -1066,44 +1066,7 @@ NTSTATUS create_token_from_username(TALLOC_CTX *mem_ctx, const char *username,
goto done;
}
- if (sid_check_is_in_unix_users(&user_sid)) {
-
- /* This is a unix user not in passdb. We need to ask nss
- * directly, without consulting passdb */
-
- struct passwd *pass;
- size_t i;
-
- pass = getpwuid_alloc(tmp_ctx, *uid);
- if (pass == NULL) {
- DEBUG(1, ("getpwuid(%d) for user %s failed\n",
- *uid, username));
- goto done;
- }
-
- *gid = pass->pw_gid;
- gid_to_sid(&primary_group_sid, pass->pw_gid);
-
- if (!getgroups_unix_user(tmp_ctx, username, pass->pw_gid,
- &gids, &num_group_sids)) {
- DEBUG(1, ("getgroups_unix_user for user %s failed\n",
- username));
- goto done;
- }
-
- group_sids = talloc_array(tmp_ctx, DOM_SID, num_group_sids);
- if (group_sids == NULL) {
- DEBUG(1, ("talloc_array failed\n"));
- result = NT_STATUS_NO_MEMORY;
- goto done;
- }
-
- for (i=0; i<num_group_sids; i++) {
- gid_to_sid(&group_sids[i], gids[i]);
- }
- *found_username = talloc_strdup(mem_ctx, pass->pw_name);
-
- } else if (sid_check_is_in_our_domain(&user_sid)) {
+ if (sid_check_is_in_our_domain(&user_sid)) {
/* This is a passdb user, so ask passdb */
@@ -1118,14 +1081,13 @@ NTSTATUS create_token_from_username(TALLOC_CTX *mem_ctx, const char *username,
if (!pdb_getsampwsid(sam_acct, &user_sid)) {
DEBUG(1, ("pdb_getsampwsid(%s) for user %s failed\n",
sid_string_static(&user_sid), username));
- result = NT_STATUS_NO_SUCH_USER;
- goto done;
+ DEBUGADD(1, ("Fall back to unix user %s\n", username));
+ goto unix_user;
}
gr_sid = pdb_get_group_sid(sam_acct);
if (!gr_sid) {
- result = NT_STATUS_NO_MEMORY;
- goto done;
+ goto unix_user;
}
sid_copy(&primary_group_sid, gr_sid);
@@ -1133,7 +1095,8 @@ NTSTATUS create_token_from_username(TALLOC_CTX *mem_ctx, const char *username,
if (!sid_to_gid(&primary_group_sid, gid)) {
DEBUG(1, ("sid_to_gid(%s) failed\n",
sid_string_static(&primary_group_sid)));
- goto done;
+ DEBUGADD(1, ("Fall back to unix user %s\n", username));
+ goto unix_user;
}
result = pdb_enum_group_memberships(tmp_ctx, sam_acct,
@@ -1142,12 +1105,60 @@ NTSTATUS create_token_from_username(TALLOC_CTX *mem_ctx, const char *username,
if (!NT_STATUS_IS_OK(result)) {
DEBUG(10, ("enum_group_memberships failed for %s\n",
username));
- goto done;
+ DEBUGADD(1, ("Fall back to unix user %s\n", username));
+ goto unix_user;
}
*found_username = talloc_strdup(mem_ctx,
pdb_get_username(sam_acct));
+ } else if (sid_check_is_in_unix_users(&user_sid)) {
+
+ /* This is a unix user not in passdb. We need to ask nss
+ * directly, without consulting passdb */
+
+ struct passwd *pass;
+ size_t i;
+
+ /*
+ * This goto target is used as a fallback for the passdb
+ * case. The concrete bug report is when passdb gave us an
+ * unmapped gid.
+ */
+
+ unix_user:
+
+ uid_to_unix_users_sid(*uid, &user_sid);
+
+ pass = getpwuid_alloc(tmp_ctx, *uid);
+ if (pass == NULL) {
+ DEBUG(1, ("getpwuid(%d) for user %s failed\n",
+ *uid, username));
+ goto done;
+ }
+
+ *gid = pass->pw_gid;
+ gid_to_sid(&primary_group_sid, pass->pw_gid);
+
+ if (!getgroups_unix_user(tmp_ctx, username, pass->pw_gid,
+ &gids, &num_group_sids)) {
+ DEBUG(1, ("getgroups_unix_user for user %s failed\n",
+ username));
+ goto done;
+ }
+
+ group_sids = talloc_array(tmp_ctx, DOM_SID, num_group_sids);
+ if (group_sids == NULL) {
+ DEBUG(1, ("talloc_array failed\n"));
+ result = NT_STATUS_NO_MEMORY;
+ goto done;
+ }
+
+ for (i=0; i<num_group_sids; i++) {
+ gid_to_sid(&group_sids[i], gids[i]);
+ }
+ *found_username = talloc_strdup(mem_ctx, pass->pw_name);
+
} else {
/* This user is from winbind, force the primary gid to the
diff --git a/source/passdb/lookup_sid.c b/source/passdb/lookup_sid.c
index 8a28f75ec85..ea08c37dd0e 100644
--- a/source/passdb/lookup_sid.c
+++ b/source/passdb/lookup_sid.c
@@ -1074,8 +1074,7 @@ void uid_to_sid(DOM_SID *psid, uid_t uid)
sid_append_rid(psid, algorithmic_pdb_uid_to_user_rid(uid));
goto done;
} else {
- sid_copy(psid, &global_sid_Unix_Users);
- sid_append_rid(psid, uid);
+ uid_to_unix_users_sid(uid, psid);
goto done;
}
diff --git a/source/passdb/util_unixsids.c b/source/passdb/util_unixsids.c
index 2a4818e3aec..d3f0999d6ac 100644
--- a/source/passdb/util_unixsids.c
+++ b/source/passdb/util_unixsids.c
@@ -36,6 +36,12 @@ BOOL sid_check_is_in_unix_users(const DOM_SID *sid)
return sid_check_is_unix_users(&dom_sid);
}
+BOOL uid_to_unix_users_sid(uid_t uid, DOM_SID *sid)
+{
+ sid_copy(sid, &global_sid_Unix_Users);
+ return sid_append_rid(sid, uid);
+}
+
const char *unix_users_domain_name(void)
{
return "Unix User";