This is the mail archive of the
cygwin-cvs@cygwin.com
mailing list for the Cygwin project.
[newlib-cygwin] Add cygsid methods to create SIDs from scratch
- From: Corinna Vinschen <corinna at sourceware dot org>
- To: cygwin-cvs at sourceware dot org
- Date: 12 Mar 2016 17:05:05 -0000
- Subject: [newlib-cygwin] Add cygsid methods to create SIDs from scratch
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;