[newlib-cygwin] Add cygsid methods to create SIDs from scratch

Corinna Vinschen corinna@sourceware.org
Sat Mar 12 17:05:00 GMT 2016


https://sourceware.org/git/gitweb.cgi?p=newlib-cygwin.git;h=018fa93e2b9a78edbe58c9d6a281783aff38e527

commit 018fa93e2b9a78edbe58c9d6a281783aff38e527
Author: Corinna Vinschen <corinna@vinschen.de>
Date:   Sat Mar 12 16:39:19 2016 +0100

    Add cygsid methods to create SIDs from scratch
    
    So far creating cygsids requires to generate an "S-1-..." string
    which is then converted to a SID by cygsid::getfromstr.
    
    Add two new methods:
    
    - cygsid::create (DWORD auth, DWORD subauth_count, ...)
    
        ... is a variable length list of subauth_count DWORD values being
        the actual subauths.
    
    - cygsid::append (DWORD rid)
    
        allows to append a single RID to an alreaday constituted SID.
    
    	* security.h (cygsid::create): Declare public.
    	(cygsid::append): Ditto.
    	* sec_helper.cc (cygsid::create): Implement.
    	(cygsid::append): Implement.
    	* uinfo.cc (pwdgrp::fetch_account_from_windows): Use both new
    	methods as appropriate.  Drop setting csid from string.  Create
    	SID strings for printing SIDs only.
    
    Signed-off-by: Corinna Vinschen <corinna@vinschen.de>

Diff:
---
 winsup/cygwin/sec_helper.cc | 32 ++++++++++++++++++++++++++++++++
 winsup/cygwin/security.h    |  3 +++
 winsup/cygwin/uinfo.cc      | 42 +++++++++++++++++++-----------------------
 3 files changed, 54 insertions(+), 23 deletions(-)

diff --git a/winsup/cygwin/sec_helper.cc b/winsup/cygwin/sec_helper.cc
index 0c37ad2..e93a9a9 100644
--- a/winsup/cygwin/sec_helper.cc
+++ b/winsup/cygwin/sec_helper.cc
@@ -13,6 +13,7 @@ details. */
 
 #include "winsup.h"
 #include <stdlib.h>
+#include <stdarg.h>
 #include <cygwin/acl.h>
 #include <sys/queue.h>
 #include <authz.h>
@@ -284,6 +285,37 @@ cygsid::getfromstr (const char *nsidstr, bool well_known)
   return psid = NO_SID;
 }
 
+const PSID
+cygsid::create (DWORD auth, DWORD subauth_cnt, ...)
+{
+  va_list ap;
+  PSID sid;
+
+  if (subauth_cnt > SID_MAX_SUB_AUTHORITIES)
+    return NULL;
+
+  DWORD subauth[subauth_cnt];
+
+  va_start (ap, subauth_cnt);
+  for (DWORD i = 0; i < subauth_cnt; ++i)
+    subauth[i] = va_arg (ap, DWORD);
+  sid = get_sid (auth, subauth_cnt, subauth, false);
+  va_end (ap);
+  return sid;
+}
+
+bool
+cygsid::append (DWORD rid)
+{
+  if (psid == NO_SID)
+    return false;
+  PISID dsid = (PISID) psid;
+  if (dsid->SubAuthorityCount >= SID_MAX_SUB_AUTHORITIES)
+    return false;
+  dsid->SubAuthority[dsid->SubAuthorityCount++] = rid;
+  return true;
+}
+
 cygsid *
 cygsidlist::alloc_sids (int n)
 {
diff --git a/winsup/cygwin/security.h b/winsup/cygwin/security.h
index 0d744df..cd61ab9 100644
--- a/winsup/cygwin/security.h
+++ b/winsup/cygwin/security.h
@@ -248,6 +248,9 @@ public:
       return (*this = sp) != NO_SID;
     }
 
+  const PSID create (DWORD auth, DWORD subauth_cnt, ...);
+  bool append (DWORD rid);
+
   /* Implemented in pwdgrp.h. */
   BOOL getfrompw (const struct passwd *pw);
   BOOL getfromgr (const struct group *gr);
diff --git a/winsup/cygwin/uinfo.cc b/winsup/cygwin/uinfo.cc
index c9b3e09..9596f8f 100644
--- a/winsup/cygwin/uinfo.cc
+++ b/winsup/cygwin/uinfo.cc
@@ -1952,11 +1952,11 @@ pwdgrp::fetch_account_from_windows (fetch_user_arg_t &arg, cyg_ldap *pldap)
 	 We create uid/gid values compatible with the old values generated
 	 by mkpasswd/mkgroup. */
       if (arg.id < 0x200)
-	__small_swprintf (sidstr, L"S-1-5-%u", arg.id & 0x1ff);
+	csid.create (5, 1, arg.id & 0x1ff);
       else if (arg.id <= 0x3e7)
-	__small_swprintf (sidstr, L"S-1-5-32-%u", arg.id & 0x3ff);
+	csid.create (5, 2, 32, arg.id & 0x3ff);
       else if (arg.id == 0x3e8) /* Special case "Other Organization" */
-	wcpcpy (sidstr, L"S-1-5-1000");
+	csid.create (5, 1, 1000);
       else
 #endif
       if (arg.id == 0xffe)
@@ -1988,32 +1988,30 @@ pwdgrp::fetch_account_from_windows (fetch_user_arg_t &arg, cyg_ldap *pldap)
 	  arg.id -= 0x10000;
 	  /* SECURITY_APP_PACKAGE_AUTHORITY */
 	  if (arg.id >= 0xf20 && arg.id <= 0xf3f)
-	    __small_swprintf (sidstr, L"S-1-15-%u-%u", (arg.id >> 4) & 0xf,
-						       arg.id & 0xf);
+	    csid.create (15, 2, (arg.id >> 4) & 0xf, arg.id & 0xf);
 	  else
-	    __small_swprintf (sidstr, L"S-1-%u-%u", arg.id >> 8, arg.id & 0xff);
+	    csid.create (arg.id >> 8, 1, arg.id & 0xff);
 	}
       else if (arg.id >= 0x30000 && arg.id < 0x40000)
 	{
 	  /* Account domain user or group. */
-	  PWCHAR s = cygheap->dom.account_sid ().pstring (sidstr);
-	  __small_swprintf (s, L"-%u", arg.id & 0xffff);
+	  csid = cygheap->dom.account_sid ();
+	  csid.append (arg.id & 0xffff);
 	}
       else if (arg.id < 0x60000)
 	{
 	  /* Builtin Alias */
-	  __small_swprintf (sidstr, L"S-1-5-%u-%u",
-			    arg.id >> 12, arg.id & 0xffff);
+	  csid.create (5, 2, arg.id >> 12, arg.id & 0xffff);
 	}
       else if (arg.id < 0x70000)
 	{
 	  /* Mandatory Label. */
-	  __small_swprintf (sidstr, L"S-1-16-%u", arg.id & 0xffff);
+	  csid.create (16, 1, arg.id & 0xffff);
 	}
       else if (arg.id < 0x80000)
 	{
 	  /* Identity assertion SIDs. */
-	  __small_swprintf (sidstr, L"S-1-18-%u", arg.id & 0xffff);
+	  csid.create (18, 1, arg.id & 0xffff);
 	}
       else if (arg.id < PRIMARY_POSIX_OFFSET)
 	{
@@ -2024,16 +2022,15 @@ pwdgrp::fetch_account_from_windows (fetch_user_arg_t &arg, cyg_ldap *pldap)
       else if (arg.id == ILLEGAL_UID)
 	{
 	  /* Just some fake. */
-	  sid = csid = "S-1-99-0";
+	  sid = csid.create (99, 1, 0);
 	  break;
 	}
       else if (arg.id >= UNIX_POSIX_OFFSET)
 	{
 	  /* UNIX (unknown NFS or Samba) user account. */
-	  __small_swprintf (sidstr, L"S-1-22-%u-%u",
-			    is_group () ? 2 : 1,  arg.id & UNIX_POSIX_MASK);
+	  csid.create (22, 2, is_group () ? 2 : 1,  arg.id & UNIX_POSIX_MASK);
 	  /* LookupAccountSidW will fail. */
-	  sid = csid = sidstr;
+	  sid = csid;
 	  break;
 	}
       else
@@ -2049,23 +2046,22 @@ pwdgrp::fetch_account_from_windows (fetch_user_arg_t &arg, cyg_ldap *pldap)
 	    }
 	  if (this_td)
 	    {
-	      cygpsid tsid (this_td->DomainSid);
-	      PWCHAR s = tsid.pstring (sidstr);
-	      __small_swprintf (s, L"-%u", arg.id - posix_offset);
+	      csid = this_td->DomainSid;
+	      csid.append (arg.id - posix_offset);
 	    }
 	  else
 	    {
 	      /* Primary domain */
-	      PWCHAR s = cygheap->dom.primary_sid ().pstring (sidstr);
-	      __small_swprintf (s, L"-%u", arg.id - PRIMARY_POSIX_OFFSET);
+	      csid = cygheap->dom.primary_sid ();
+	      csid.append (arg.id - PRIMARY_POSIX_OFFSET);
 	    }
 	  posix_offset = 0;
 	}
-      sid = csid = sidstr;
+      sid = csid;
       ret = LookupAccountSidW (NULL, sid, name, &nlen, dom, &dlen, &acc_type);
       if (!ret)
 	{
-	  debug_printf ("LookupAccountSidW (%W), %E", sidstr);
+	  debug_printf ("LookupAccountSidW (%W), %E", sid.string (sidstr));
 	  return NULL;
 	}
       break;



More information about the Cygwin-cvs mailing list