changeset 87990:78715eba45dd

(g_b_init_get_sid_sub_authority, g_b_init_get_sid_sub_authority_count): New static variables. (GetSidSubAuthority_Proc, GetSidSubAuthorityCount_Proc): New typedefs. (get_sid_sub_authority, get_sid_sub_authority_count): New functions. (init_user_info): Use the above two new functions to retrieve uid and gid. Use 500/513, the Windows defaults, as Administrator's uid/gid.
author Eli Zaretskii <eliz@gnu.org>
date Sat, 26 Jan 2008 13:03:39 +0000
parents a0f010afb29f
children 66e6887d98d0
files src/w32.c
diffstat 1 files changed, 88 insertions(+), 23 deletions(-) [+]
line wrap: on
line diff
--- a/src/w32.c	Sat Jan 26 04:28:04 2008 +0000
+++ b/src/w32.c	Sat Jan 26 13:03:39 2008 +0000
@@ -120,6 +120,8 @@
 static BOOL g_b_init_get_token_information;
 static BOOL g_b_init_lookup_account_sid;
 static BOOL g_b_init_get_sid_identifier_authority;
+static BOOL g_b_init_get_sid_sub_authority;
+static BOOL g_b_init_get_sid_sub_authority_count;
 
 /*
   BEGIN: Wrapper functions around OpenProcessToken
@@ -161,6 +163,12 @@
     PSID_NAME_USE peUse);
 typedef PSID_IDENTIFIER_AUTHORITY (WINAPI * GetSidIdentifierAuthority_Proc) (
     PSID pSid);
+typedef PDWORD (WINAPI * GetSidSubAuthority_Proc) (
+    PSID pSid,
+    DWORD n);
+typedef PUCHAR (WINAPI * GetSidSubAuthorityCount_Proc) (
+    PSID pSid);
+
 
   /* ** A utility function ** */
 static BOOL
@@ -349,6 +357,55 @@
   return (s_pfn_Get_Sid_Identifier_Authority (pSid));
 }
 
+PDWORD WINAPI get_sid_sub_authority (
+    PSID pSid,
+    DWORD n)
+{
+  static GetSidSubAuthority_Proc s_pfn_Get_Sid_Sub_Authority = NULL;
+  HMODULE hm_advapi32 = NULL;
+  if (is_windows_9x () == TRUE)
+    {
+      return NULL;
+    }
+  if (g_b_init_get_sid_sub_authority == 0)
+    {
+      g_b_init_get_sid_sub_authority = 1;
+      hm_advapi32 = LoadLibrary ("Advapi32.dll");
+      s_pfn_Get_Sid_Sub_Authority =
+        (GetSidSubAuthority_Proc) GetProcAddress (
+            hm_advapi32, "GetSidSubAuthority");
+    }
+  if (s_pfn_Get_Sid_Sub_Authority == NULL)
+    {
+      return NULL;
+    }
+  return (s_pfn_Get_Sid_Sub_Authority (pSid, n));
+}
+
+PUCHAR WINAPI get_sid_sub_authority_count (
+    PSID pSid)
+{
+  static GetSidSubAuthorityCount_Proc s_pfn_Get_Sid_Sub_Authority_Count = NULL;
+  HMODULE hm_advapi32 = NULL;
+  if (is_windows_9x () == TRUE)
+    {
+      return NULL;
+    }
+  if (g_b_init_get_sid_sub_authority_count == 0)
+    {
+      g_b_init_get_sid_sub_authority_count = 1;
+      hm_advapi32 = LoadLibrary ("Advapi32.dll");
+      s_pfn_Get_Sid_Sub_Authority_Count =
+        (GetSidSubAuthorityCount_Proc) GetProcAddress (
+            hm_advapi32, "GetSidSubAuthorityCount");
+    }
+  if (s_pfn_Get_Sid_Sub_Authority_Count == NULL)
+    {
+      return NULL;
+    }
+  return (s_pfn_Get_Sid_Sub_Authority_Count (pSid));
+}
+
 /*
   END: Wrapper functions around OpenProcessToken
   and other functions in advapi32.dll that are only
@@ -547,39 +604,47 @@
 			     domain, &dlength, &user_type))
     {
       strcpy (the_passwd.pw_name, name);
-      /* Determine a reasonable uid value. */
+      /* Determine a reasonable uid value.  */
       if (stricmp ("administrator", name) == 0)
 	{
-	  the_passwd.pw_uid = 0;
-	  the_passwd.pw_gid = 0;
+	  the_passwd.pw_uid = 500; /* well-known Administrator uid */
+	  the_passwd.pw_gid = 513; /* well-known None gid */
 	}
       else
 	{
-	  SID_IDENTIFIER_AUTHORITY * pSIA;
-
-	  pSIA = get_sid_identifier_authority (*((PSID *) user_sid));
-	  /* I believe the relative portion is the last 4 bytes (of 6)
-	     with msb first. */
-	  the_passwd.pw_uid = ((pSIA->Value[2] << 24) +
-			       (pSIA->Value[3] << 16) +
-			       (pSIA->Value[4] << 8)  +
-			       (pSIA->Value[5] << 0));
-	  /* restrict to conventional uid range for normal users */
-	  the_passwd.pw_uid = the_passwd.pw_uid % 60001;
+	  /* Use RID, the relative portion of the SID, that is the last
+	     sub-authority value of the SID. */
+	  DWORD n_subauthorities =
+	    *get_sid_sub_authority_count (*((PSID *) user_sid));
+
+	  if (n_subauthorities < 1)
+	    the_passwd.pw_uid = 0;	/* the "World" RID */
+	  else
+	    {
+	      the_passwd.pw_uid =
+		*get_sid_sub_authority (*((PSID *) user_sid),
+					n_subauthorities - 1);
+	      /* Restrict to conventional uid range for normal users.  */
+	      the_passwd.pw_uid %= 60001;
+	    }
 
 	  /* Get group id */
 	  if (get_token_information (token, TokenPrimaryGroup,
 				     (PVOID) user_sid, sizeof (user_sid), &trash))
 	    {
-	      SID_IDENTIFIER_AUTHORITY * pSIA;
-
-	      pSIA = get_sid_identifier_authority (*((PSID *) user_sid));
-	      the_passwd.pw_gid = ((pSIA->Value[2] << 24) +
-				   (pSIA->Value[3] << 16) +
-				   (pSIA->Value[4] << 8)  +
-				   (pSIA->Value[5] << 0));
-	      /* I don't know if this is necessary, but for safety... */
-	      the_passwd.pw_gid = the_passwd.pw_gid % 60001;
+	      n_subauthorities =
+		*get_sid_sub_authority_count (*((PSID *) user_sid));
+
+	      if (n_subauthorities < 1)
+		the_passwd.pw_gid = 0;	/* the "World" RID */
+	      else
+		{
+		  the_passwd.pw_gid =
+		    *get_sid_sub_authority (*((PSID *) user_sid),
+					    n_subauthorities - 1);
+		  /* I don't know if this is necessary, but for safety...  */
+		  the_passwd.pw_gid %= 60001;
+		}
 	    }
 	  else
 	    the_passwd.pw_gid = the_passwd.pw_uid;