mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
* [RFC PATCH 5/6] ksmbd: show classic users as S-1-22-1-<uid> on every server
@ 2026-11-10  9:02 Jan Koester
  0 siblings, 0 replies; 2+ messages in thread
From: Jan Koester @ 2026-11-10  9:02 UTC (permalink / raw)
  To: linkinjeon, smfrench
  Cc: senozhatsky, tom, chenxiaosong, brauner, linux-cifs,
	linux-fsdevel, samba-technical, linux-kernel

A classic uid appeared in security descriptors as the server's own
domain SID + uid. That domain SID comes from user space and differs from
server to server (ksmbd-tools and sharedd derive it per machine), so
the same owner had a different SID on every file server, and the RID
looked like a domain account's.

Show them as S-1-22-1-<uid>, the SID ksmbd already used for root and
that S-1-22-2-<gid> pairs with for groups. Keep taking the old form when
a client sets it, and keep it in the session's SIDs, so descriptors
stored before still match.

Assisted-by: Claude:claude-opus-5-5
Signed-off-by: Jan Koester <jan.koester@tuxist.de>
---
 fs/smb/server/smbacl.c | 29 +++++++++++++++++++++--------
 1 file changed, 21 insertions(+), 8 deletions(-)

diff --git a/fs/smb/server/smbacl.c b/fs/smb/server/smbacl.c
index d6be65e3a9..769864d64e 100644
--- a/fs/smb/server/smbacl.c
+++ b/fs/smb/server/smbacl.c
@@ -300,14 +300,16 @@ static u32 sid_to_id_r(const struct smb_sid *psid, u8 *id)
 }
 
 /*
- * The SID ksmbd itself gives an id: a classic one the usual SIDs, a UUID
- * or GUID S-1-22-<kind>-w0-w1-w2-w3.
+ * The SID ksmbd itself gives an id: a classic uid S-1-22-1-<uid>, the same
+ * on every server (it used to be the server's own domain SID + uid), a
+ * classic gid S-1-22-2-<gid>, a UUID or GUID S-1-22-<kind>-w0-w1-w2-w3.
  */
 static void native_uid_sid(kuid_t uid, uint sidtype, struct smb_sid *ssid)
 {
-	if (uid_is_legacy(uid) || sidtype == SIDCREATOR_OWNER ||
-	    sidtype == SIDCREATOR_GROUP)
+	if (sidtype == SIDCREATOR_OWNER || sidtype == SIDCREATOR_GROUP)
 		id_to_sid(from_kuid_munged(&init_user_ns, uid), sidtype, ssid);
+	else if (uid_is_legacy(uid))
+		id_to_sid(from_kuid_munged(&init_user_ns, uid), SIDUNIX_USER, ssid);
 	else if (uid.type == KID_UUID)
 		id_r_to_sid(SID_UNIX_UUID_USER, uid.uuid.b, ssid);
 	else
@@ -373,13 +375,14 @@ static bool sid_equal(const struct smb_sid *a, const struct smb_sid *b)
 /*
  * The SIDs a user's ACL entries may name, like a Windows access token: the
  * user's and its groups', each the account's own SID (if user space maps
- * one) and ksmbd's. Built at login; a
+ * one) and ksmbd's -- for a classic uid also the server's domain SID + uid
+ * of older ksmbd, which stored descriptors may hold. Built at login; a
  * mapping user space couldn't give then is missing for the session (its
  * ACL entries don't match: access is denied, not granted).
  */
 void ksmbd_user_set_token(struct ksmbd_user *user)
 {
-	int i, n = 0, max = 2 + 2 * (user->ngroups + 1);
+	int i, n = 0, max = 3 + 2 * (user->ngroups + 1);
 	struct smb_sid *sids;
 
 	sids = kcalloc(max, sizeof(*sids), KSMBD_DEFAULT_GFP);
@@ -388,6 +391,9 @@ void ksmbd_user_set_token(struct ksmbd_user *user)
 	if (!mapped_uid_sid(user->kuid, &sids[n]))
 		n++;
 	native_uid_sid(user->kuid, SIDOWNER, &sids[n++]);
+	if (uid_is_legacy(user->kuid) && !uid_eq(user->kuid, GLOBAL_ROOT_UID))
+		id_to_sid(from_kuid_munged(&init_user_ns, user->kuid), SIDOWNER,
+			  &sids[n++]);
 	for (i = -1; i < user->ngroups; i++) {
 		kgid_t gid = i < 0 ? user->kgid : user->sgid[i];
 
@@ -519,8 +525,15 @@ static int sid_to_id(struct mnt_idmap *idmap,
 		kuid_t uid;
 		uid_t id;
 
-		/* Only the server domain RID has a local uid representation. */
-		sid_prefix = &server_conf.domain_sid;
+		/*
+		 * A local uid: S-1-22-1-<uid>, or the server's domain SID +
+		 * uid that ksmbd used to show (stored descriptors have it).
+		 */
+		if (psid->num_subauth == sid_unix_users.num_subauth + 1 &&
+		    !compare_sids(psid, &sid_unix_users))
+			sid_prefix = &sid_unix_users;
+		else
+			sid_prefix = &server_conf.domain_sid;
 		if (psid->num_subauth != sid_prefix->num_subauth + 1 ||
 		    compare_sids(psid, sid_prefix))
 			return -EINVAL;
-- 
2.56.0

^ permalink raw reply	[flat|nested] 2+ messages in thread

* [RFC PATCH 5/6] ksmbd: show classic users as S-1-22-1-<uid> on every server
  2026-10-28  6:19 [RFC PATCH 0/6] ksmbd: Windows SIDs for user and group ids Jan Koester
@ 2026-10-28  6:20 ` Jan Koester
  0 siblings, 0 replies; 2+ messages in thread
From: Jan Koester @ 2026-10-28  6:20 UTC (permalink / raw)
  To: Namjae Jeon, Steve French
  Cc: Sergey Senozhatsky, Tom Talpey, ChenXiaoSong, Christian Brauner,
	linux-cifs, linux-fsdevel, samba-technical, linux-kernel

A classic uid appeared in security descriptors as the server's own
domain SID + uid. That domain SID comes from user space and differs from
server to server (ksmbd-tools and sharedd derive it per machine), so
the same owner had a different SID on every file server, and the RID
looked like a domain account's.

Show them as S-1-22-1-<uid>, the SID ksmbd already used for root and
that S-1-22-2-<gid> pairs with for groups. Keep taking the old form when
a client sets it, and keep it in the session's SIDs, so descriptors
stored before still match.

Assisted-by: Claude:claude-opus-5-5
Signed-off-by: Jan Koester <jan.koester@tuxist.de>
---
 fs/smb/server/smbacl.c | 29 +++++++++++++++++++++--------
 1 file changed, 21 insertions(+), 8 deletions(-)

diff --git a/fs/smb/server/smbacl.c b/fs/smb/server/smbacl.c
index d6be65e3a9..769864d64e 100644
--- a/fs/smb/server/smbacl.c
+++ b/fs/smb/server/smbacl.c
@@ -300,14 +300,16 @@ static u32 sid_to_id_r(const struct smb_sid *psid, u8 *id)
 }
 
 /*
- * The SID ksmbd itself gives an id: a classic one the usual SIDs, a UUID
- * or GUID S-1-22-<kind>-w0-w1-w2-w3.
+ * The SID ksmbd itself gives an id: a classic uid S-1-22-1-<uid>, the same
+ * on every server (it used to be the server's own domain SID + uid), a
+ * classic gid S-1-22-2-<gid>, a UUID or GUID S-1-22-<kind>-w0-w1-w2-w3.
  */
 static void native_uid_sid(kuid_t uid, uint sidtype, struct smb_sid *ssid)
 {
-	if (uid_is_legacy(uid) || sidtype == SIDCREATOR_OWNER ||
-	    sidtype == SIDCREATOR_GROUP)
+	if (sidtype == SIDCREATOR_OWNER || sidtype == SIDCREATOR_GROUP)
 		id_to_sid(from_kuid_munged(&init_user_ns, uid), sidtype, ssid);
+	else if (uid_is_legacy(uid))
+		id_to_sid(from_kuid_munged(&init_user_ns, uid), SIDUNIX_USER, ssid);
 	else if (uid.type == KID_UUID)
 		id_r_to_sid(SID_UNIX_UUID_USER, uid.uuid.b, ssid);
 	else
@@ -373,13 +375,14 @@ static bool sid_equal(const struct smb_sid *a, const struct smb_sid *b)
 /*
  * The SIDs a user's ACL entries may name, like a Windows access token: the
  * user's and its groups', each the account's own SID (if user space maps
- * one) and ksmbd's. Built at login; a
+ * one) and ksmbd's -- for a classic uid also the server's domain SID + uid
+ * of older ksmbd, which stored descriptors may hold. Built at login; a
  * mapping user space couldn't give then is missing for the session (its
  * ACL entries don't match: access is denied, not granted).
  */
 void ksmbd_user_set_token(struct ksmbd_user *user)
 {
-	int i, n = 0, max = 2 + 2 * (user->ngroups + 1);
+	int i, n = 0, max = 3 + 2 * (user->ngroups + 1);
 	struct smb_sid *sids;
 
 	sids = kcalloc(max, sizeof(*sids), KSMBD_DEFAULT_GFP);
@@ -388,6 +391,9 @@ void ksmbd_user_set_token(struct ksmbd_user *user)
 	if (!mapped_uid_sid(user->kuid, &sids[n]))
 		n++;
 	native_uid_sid(user->kuid, SIDOWNER, &sids[n++]);
+	if (uid_is_legacy(user->kuid) && !uid_eq(user->kuid, GLOBAL_ROOT_UID))
+		id_to_sid(from_kuid_munged(&init_user_ns, user->kuid), SIDOWNER,
+			  &sids[n++]);
 	for (i = -1; i < user->ngroups; i++) {
 		kgid_t gid = i < 0 ? user->kgid : user->sgid[i];
 
@@ -519,8 +525,15 @@ static int sid_to_id(struct mnt_idmap *idmap,
 		kuid_t uid;
 		uid_t id;
 
-		/* Only the server domain RID has a local uid representation. */
-		sid_prefix = &server_conf.domain_sid;
+		/*
+		 * A local uid: S-1-22-1-<uid>, or the server's domain SID +
+		 * uid that ksmbd used to show (stored descriptors have it).
+		 */
+		if (psid->num_subauth == sid_unix_users.num_subauth + 1 &&
+		    !compare_sids(psid, &sid_unix_users))
+			sid_prefix = &sid_unix_users;
+		else
+			sid_prefix = &server_conf.domain_sid;
 		if (psid->num_subauth != sid_prefix->num_subauth + 1 ||
 		    compare_sids(psid, sid_prefix))
 			return -EINVAL;
-- 
2.56.0


^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2026-11-10  9:01 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-11-10  9:02 [RFC PATCH 5/6] ksmbd: show classic users as S-1-22-1-<uid> on every server Jan Koester
  -- strict thread matches above, loose matches on Subject: below --
2026-10-28  6:19 [RFC PATCH 0/6] ksmbd: Windows SIDs for user and group ids Jan Koester
2026-10-28  6:20 ` [RFC PATCH 5/6] ksmbd: show classic users as S-1-22-1-<uid> on every server Jan Koester

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox

all inboxes | Powered by JetHome®