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

commit 018fa93e2b9a78edbe58c9d6a281783aff38e527
Author: Corinna Vinschen <[email protected]>
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 <[email protected]>

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;

Reply via email to