* cyglsa.h: New header file.
* environ.cc: Disable subauth settings. * grp.cc: Accomodate cygsidlist's count now being a method. * sec_helper.cc (SECURITY_MANDATORY_INTEGRITY_AUTHORITY): Remove. (mandatory_medium_integrity_sid): Remove. (mandatory_high_integrity_sid): Remove. (mandatory_system_integrity_sid): Remove. (fake_logon_sid): Add. (cygsid::get_sid): Add well_known parameter. Set well_known_sid accordingly. (cygsid::getfromstr): Ditto. (cygsidlist::alloc_sids): Move here from security.cc. (cygsidlist::free_sids): Ditto. (cygsidlist::add): Move here from security.h. Add well_known parameter. Set well_known_sid accordingly. Don't allow duplicate SIDs. * security.cc: Include cyglsa.h and cygwin/version.h. Throughout accomodate cygsidlist's count now being a method. Throughout drop redundant "contains" tests. (get_user_local_groups): Add local groups as well known SIDs. (get_token_group_sidlist): Add well known groups as well known SIDs. (get_server_groups): Ditto. Only call get_unix_group_sidlist after get_user_local_groups to maintain "well_known_sid" attribute. (get_initgroups_sidlist): Add well known groups as well known SIDs. (get_setgroups_sidlist): Add usersid and struct passwd parameter to allow calling get_server_groups from here. (get_system_priv_list): Make static. Return size of TOKEN_PRIVILEGES structure. (get_priv_list): Ditto. (create_token): Accomodate above changes. Drop misguided attempt to add MIC SIDs to created user token. Print returned token as hex value. (subauth): Disable. (lsaauth): New function implementing client side of LSA authentication. * security.h (class cygsid): Add well_known_sid attribute. Accomodate throughout. Add *= operator to create a well known SID. (class cygsidlist): Rename count to cnt. Make count a method. (cygsidlist::add): Move to sec_helper.cc. (cygsidlist::operator *=): New method to add well known SID. (cygsidlist::non_well_known_count): New method returning number of non well known SIDs in list. (cygsidlist::next_non_well_known_sid): New method returning next non well known SID by index. (mandatory_medium_integrity_sid): Drop declaration. (mandatory_high_integrity_sid): Drop declaration. (mandatory_system_integrity_sid): Drop declaration. (fake_logon_sid): Add declaration. (subauth): Disable declaration. (lsaauth): Add declaration. * syscalls.cc (seteuid32): Disable subauthentication. Add LSA authentication. * wincap.h: Define needs_logon_sid_in_sid_list throughout. * wincap.cc: Ditto.
This commit is contained in:
parent
b6bb405954
commit
b825c587ba
|
@ -1,3 +1,57 @@
|
||||||
|
2006-11-27 Corinna Vinschen <corinna@vinschen.de>
|
||||||
|
|
||||||
|
* cyglsa.h: New header file.
|
||||||
|
* environ.cc: Disable subauth settings.
|
||||||
|
* grp.cc: Accomodate cygsidlist's count now being a method.
|
||||||
|
* sec_helper.cc (SECURITY_MANDATORY_INTEGRITY_AUTHORITY): Remove.
|
||||||
|
(mandatory_medium_integrity_sid): Remove.
|
||||||
|
(mandatory_high_integrity_sid): Remove.
|
||||||
|
(mandatory_system_integrity_sid): Remove.
|
||||||
|
(fake_logon_sid): Add.
|
||||||
|
(cygsid::get_sid): Add well_known parameter. Set well_known_sid
|
||||||
|
accordingly.
|
||||||
|
(cygsid::getfromstr): Ditto.
|
||||||
|
(cygsidlist::alloc_sids): Move here from security.cc.
|
||||||
|
(cygsidlist::free_sids): Ditto.
|
||||||
|
(cygsidlist::add): Move here from security.h. Add well_known parameter.
|
||||||
|
Set well_known_sid accordingly. Don't allow duplicate SIDs.
|
||||||
|
* security.cc: Include cyglsa.h and cygwin/version.h. Throughout
|
||||||
|
accomodate cygsidlist's count now being a method. Throughout drop
|
||||||
|
redundant "contains" tests.
|
||||||
|
(get_user_local_groups): Add local groups as well known SIDs.
|
||||||
|
(get_token_group_sidlist): Add well known groups as well known SIDs.
|
||||||
|
(get_server_groups): Ditto. Only call get_unix_group_sidlist after
|
||||||
|
get_user_local_groups to maintain "well_known_sid" attribute.
|
||||||
|
(get_initgroups_sidlist): Add well known groups as well known SIDs.
|
||||||
|
(get_setgroups_sidlist): Add usersid and struct passwd parameter to
|
||||||
|
allow calling get_server_groups from here.
|
||||||
|
(get_system_priv_list): Make static. Return size of TOKEN_PRIVILEGES
|
||||||
|
structure.
|
||||||
|
(get_priv_list): Ditto.
|
||||||
|
(create_token): Accomodate above changes. Drop misguided attempt to
|
||||||
|
add MIC SIDs to created user token. Print returned token as hex value.
|
||||||
|
(subauth): Disable.
|
||||||
|
(lsaauth): New function implementing client side of LSA authentication.
|
||||||
|
* security.h (class cygsid): Add well_known_sid attribute. Accomodate
|
||||||
|
throughout. Add *= operator to create a well known SID.
|
||||||
|
(class cygsidlist): Rename count to cnt. Make count a method.
|
||||||
|
(cygsidlist::add): Move to sec_helper.cc.
|
||||||
|
(cygsidlist::operator *=): New method to add well known SID.
|
||||||
|
(cygsidlist::non_well_known_count): New method returning number of
|
||||||
|
non well known SIDs in list.
|
||||||
|
(cygsidlist::next_non_well_known_sid): New method returning next non
|
||||||
|
well known SID by index.
|
||||||
|
(mandatory_medium_integrity_sid): Drop declaration.
|
||||||
|
(mandatory_high_integrity_sid): Drop declaration.
|
||||||
|
(mandatory_system_integrity_sid): Drop declaration.
|
||||||
|
(fake_logon_sid): Add declaration.
|
||||||
|
(subauth): Disable declaration.
|
||||||
|
(lsaauth): Add declaration.
|
||||||
|
* syscalls.cc (seteuid32): Disable subauthentication. Add LSA
|
||||||
|
authentication.
|
||||||
|
* wincap.h: Define needs_logon_sid_in_sid_list throughout.
|
||||||
|
* wincap.cc: Ditto.
|
||||||
|
|
||||||
2006-11-23 Corinna Vinschen <corinna@vinschen.de>
|
2006-11-23 Corinna Vinschen <corinna@vinschen.de>
|
||||||
|
|
||||||
* security.h (DBGSID): Define for debugging purposes.
|
* security.h (DBGSID): Define for debugging purposes.
|
||||||
|
|
|
@ -0,0 +1,149 @@
|
||||||
|
/* cyglsa.h: Header file for Cygwin LSA authentication
|
||||||
|
|
||||||
|
Copyright 2006 Red Hat, Inc.
|
||||||
|
|
||||||
|
Written by Corinna Vinschen <corinna@vinschen.de>
|
||||||
|
|
||||||
|
This file is part of Cygwin.
|
||||||
|
|
||||||
|
This software is a copyrighted work licensed under the terms of the
|
||||||
|
Cygwin license. Please consult the file "CYGWIN_LICENSE" for details. */
|
||||||
|
|
||||||
|
#ifndef _CYGLSA_H
|
||||||
|
#define _CYGLSA_H
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
extern "C" {
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#define CYG_LSA_PKGNAME "CygwinLsa"
|
||||||
|
|
||||||
|
#define CYG_LSA_MAGIC 0x0379f014LU
|
||||||
|
|
||||||
|
/* Datastructures not defined in w32api. */
|
||||||
|
typedef PVOID *PLSA_CLIENT_REQUEST;
|
||||||
|
|
||||||
|
typedef struct _SECPKG_CLIENT_INFO
|
||||||
|
{
|
||||||
|
LUID LogonId;
|
||||||
|
ULONG ProcessID;
|
||||||
|
ULONG ThreadID;
|
||||||
|
BOOLEAN HasTcbPrivilege;
|
||||||
|
BOOLEAN Impersonating;
|
||||||
|
BOOLEAN Restricted;
|
||||||
|
} SECPKG_CLIENT_INFO, *PSECPKG_CLIENT_INFO;
|
||||||
|
|
||||||
|
/* The table returned by LsaApInitializePackage is actually a
|
||||||
|
LSA_SECPKG_FUNCTION_TABLE even though that's not documented.
|
||||||
|
We need only a subset of this table, basically the LSA_DISPATCH_TABLE
|
||||||
|
plus the pointer to the GetClientInfo function. */
|
||||||
|
typedef struct _LSA_SECPKG_FUNCS
|
||||||
|
{
|
||||||
|
NTSTATUS (NTAPI *CreateLogonSession)(PLUID);
|
||||||
|
NTSTATUS (NTAPI *DeleteLogonSession)(PLUID);
|
||||||
|
NTSTATUS (NTAPI *AddCredentials)(PVOID); /* wrong prototype, unused */
|
||||||
|
NTSTATUS (NTAPI *GetCredentials)(PVOID); /* wrong prototype, unused */
|
||||||
|
NTSTATUS (NTAPI *DeleteCredentials)(PVOID); /* wrong prototype, unused */
|
||||||
|
PVOID (NTAPI *AllocateLsaHeap)(ULONG);
|
||||||
|
VOID (NTAPI *FreeLsaHeap)(PVOID);
|
||||||
|
NTSTATUS (NTAPI *AllocateClientBuffer)(PLSA_CLIENT_REQUEST, ULONG, PVOID *);
|
||||||
|
NTSTATUS (NTAPI *FreeClientBuffer)(PLSA_CLIENT_REQUEST, PVOID);
|
||||||
|
NTSTATUS (NTAPI *CopyToClientBuffer)(PLSA_CLIENT_REQUEST, ULONG,
|
||||||
|
PVOID, PVOID);
|
||||||
|
NTSTATUS (NTAPI *CopyFromClientBuffer)(PLSA_CLIENT_REQUEST, ULONG,
|
||||||
|
PVOID, PVOID);
|
||||||
|
NTSTATUS (NTAPI *ImpersonateClient)(VOID);
|
||||||
|
NTSTATUS (NTAPI *UnloadPackage)(VOID);
|
||||||
|
NTSTATUS (NTAPI *DuplicateHandle)(HANDLE,PHANDLE);
|
||||||
|
NTSTATUS (NTAPI *SaveSupplementalCredentials)(VOID);
|
||||||
|
NTSTATUS (NTAPI *CreateThread)(PVOID); /* wrong prototype, unused */
|
||||||
|
NTSTATUS (NTAPI *GetClientInfo)(PSECPKG_CLIENT_INFO);
|
||||||
|
} LSA_SECPKG_FUNCS, *PLSA_SECPKG_FUNCS;
|
||||||
|
|
||||||
|
typedef enum _LSA_TOKEN_INFORMATION_TYPE
|
||||||
|
{
|
||||||
|
LsaTokenInformationNull,
|
||||||
|
LsaTokenInformationV1,
|
||||||
|
LsaTokenInformationV2
|
||||||
|
} LSA_TOKEN_INFORMATION_TYPE, *PLSA_TOKEN_INFORMATION_TYPE;
|
||||||
|
|
||||||
|
typedef struct _LSA_TOKEN_INFORMATION_V2
|
||||||
|
{
|
||||||
|
LARGE_INTEGER ExpirationTime;
|
||||||
|
TOKEN_USER User;
|
||||||
|
PTOKEN_GROUPS Groups;
|
||||||
|
TOKEN_PRIMARY_GROUP PrimaryGroup;
|
||||||
|
PTOKEN_PRIVILEGES Privileges;
|
||||||
|
TOKEN_OWNER Owner;
|
||||||
|
TOKEN_DEFAULT_DACL DefaultDacl;
|
||||||
|
} LSA_TOKEN_INFORMATION_V2, *PLSA_TOKEN_INFORMATION_V2;
|
||||||
|
|
||||||
|
/* These structures are eqivalent to the appropriate Windows structures,
|
||||||
|
using 32 bit offsets instead of pointers. These datastructures are
|
||||||
|
used to transfer the logon information to the LSA authentication package.
|
||||||
|
We can't use the LSA_TOKEN_INFORMATION_V2 structure directly, because
|
||||||
|
its size differs between 32 bit and 64 bit Windows. */
|
||||||
|
|
||||||
|
typedef DWORD OFFSET;
|
||||||
|
|
||||||
|
typedef struct _CYG_SID_AND_ATTRIBUTES
|
||||||
|
{
|
||||||
|
OFFSET Sid;
|
||||||
|
DWORD Attributes;
|
||||||
|
} CYG_SID_AND_ATTRIBUTES, *PCYG_SID_AND_ATTRIBUTES;
|
||||||
|
|
||||||
|
typedef struct _CYG_TOKEN_USER
|
||||||
|
{
|
||||||
|
CYG_SID_AND_ATTRIBUTES User;
|
||||||
|
} CYG_TOKEN_USER, *PCYG_TOKEN_USER;
|
||||||
|
|
||||||
|
typedef struct _CYG_TOKEN_GROUPS
|
||||||
|
{
|
||||||
|
DWORD GroupCount;
|
||||||
|
CYG_SID_AND_ATTRIBUTES Groups[ANYSIZE_ARRAY];
|
||||||
|
} CYG_TOKEN_GROUPS, *PCYG_TOKEN_GROUPS;
|
||||||
|
|
||||||
|
typedef struct _CYG_TOKEN_PRIMARY_GROUP
|
||||||
|
{
|
||||||
|
OFFSET PrimaryGroup;
|
||||||
|
} CYG_TOKEN_PRIMARY_GROUP, *PCYG_TOKEN_PRIMARY_GROUP;
|
||||||
|
|
||||||
|
typedef struct _CYG_TOKEN_OWNER
|
||||||
|
{
|
||||||
|
OFFSET Owner;
|
||||||
|
} CYG_TOKEN_OWNER, *PCYG_TOKEN_OWNER;
|
||||||
|
|
||||||
|
typedef struct _CYG_TOKEN_DEFAULT_DACL
|
||||||
|
{
|
||||||
|
OFFSET DefaultDacl;
|
||||||
|
} CYG_TOKEN_DEFAULT_DACL, *PCYG_TOKEN_DEFAULT_DACL;
|
||||||
|
|
||||||
|
typedef struct _CYG_LSA_TOKEN_INFORMATION
|
||||||
|
{
|
||||||
|
LARGE_INTEGER ExpirationTime;
|
||||||
|
CYG_TOKEN_USER User;
|
||||||
|
OFFSET Groups;
|
||||||
|
CYG_TOKEN_PRIMARY_GROUP PrimaryGroup;
|
||||||
|
OFFSET Privileges;
|
||||||
|
CYG_TOKEN_OWNER Owner;
|
||||||
|
CYG_TOKEN_DEFAULT_DACL DefaultDacl;
|
||||||
|
} CYG_LSA_TOKEN_INFORMATION, *PCYG_LSA_TOKEN_INFORMATION;
|
||||||
|
|
||||||
|
/* This is the structure created by security.cc:lsaauth(), which is given to
|
||||||
|
LsaApLogonUser to create the token information returned to the LSA. */
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
DWORD magic;
|
||||||
|
DWORD checksum;
|
||||||
|
CHAR username[UNLEN + 1];
|
||||||
|
CHAR domain[INTERNET_MAX_HOST_NAME_LENGTH + 1];
|
||||||
|
ULONG inf_size;
|
||||||
|
CYG_LSA_TOKEN_INFORMATION inf;
|
||||||
|
BYTE data[1];
|
||||||
|
} cyglsa_t;
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif /* _CYGLSA_H */
|
|
@ -34,7 +34,9 @@ extern bool ignore_case_with_glob;
|
||||||
extern bool allow_winsymlinks;
|
extern bool allow_winsymlinks;
|
||||||
extern bool strip_title_path;
|
extern bool strip_title_path;
|
||||||
extern int pcheck_case;
|
extern int pcheck_case;
|
||||||
|
#if 0
|
||||||
extern int subauth_id;
|
extern int subauth_id;
|
||||||
|
#endif
|
||||||
bool reset_com = false;
|
bool reset_com = false;
|
||||||
static bool envcache = true;
|
static bool envcache = true;
|
||||||
#ifdef USE_SERVER
|
#ifdef USE_SERVER
|
||||||
|
@ -530,6 +532,7 @@ codepage_init (const char *buf)
|
||||||
debug_printf ("Wrong codepage name: %s", buf);
|
debug_printf ("Wrong codepage name: %s", buf);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if 0
|
||||||
static void
|
static void
|
||||||
subauth_id_init (const char *buf)
|
subauth_id_init (const char *buf)
|
||||||
{
|
{
|
||||||
|
@ -542,6 +545,7 @@ subauth_id_init (const char *buf)
|
||||||
if (i > 127 && i != 132 && i <= 255)
|
if (i > 127 && i != 132 && i <= 255)
|
||||||
subauth_id = i;
|
subauth_id = i;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
static void
|
static void
|
||||||
set_chunksize (const char *buf)
|
set_chunksize (const char *buf)
|
||||||
|
@ -620,7 +624,9 @@ static struct parse_thing
|
||||||
#endif
|
#endif
|
||||||
{"smbntsec", {func: set_smbntsec}, isfunc, NULL, {{0}, {s: "yes"}}},
|
{"smbntsec", {func: set_smbntsec}, isfunc, NULL, {{0}, {s: "yes"}}},
|
||||||
{"strip_title", {&strip_title_path}, justset, NULL, {{false}, {true}}},
|
{"strip_title", {&strip_title_path}, justset, NULL, {{false}, {true}}},
|
||||||
|
#if 0
|
||||||
{"subauth_id", {func: &subauth_id_init}, isfunc, NULL, {{0}, {0}}},
|
{"subauth_id", {func: &subauth_id_init}, isfunc, NULL, {{0}, {0}}},
|
||||||
|
#endif
|
||||||
{"title", {&display_title}, justset, NULL, {{false}, {true}}},
|
{"title", {&display_title}, justset, NULL, {{false}, {true}}},
|
||||||
{"traverse", {func: set_traverse}, isfunc, NULL, {{0}, {s: "yes"}}},
|
{"traverse", {func: set_traverse}, isfunc, NULL, {{0}, {s: "yes"}}},
|
||||||
{"tty", {NULL}, set_process_state, NULL, {{0}, {PID_USETTY}}},
|
{"tty", {NULL}, set_process_state, NULL, {{0}, {PID_USETTY}}},
|
||||||
|
|
|
@ -348,7 +348,7 @@ internal_getgroups (int gidsetsize, __gid32_t *grouplist, cygpsid * srchsid)
|
||||||
cygsid sid;
|
cygsid sid;
|
||||||
for (int gidx = 0; (gr = internal_getgrent (gidx)); ++gidx)
|
for (int gidx = 0; (gr = internal_getgrent (gidx)); ++gidx)
|
||||||
if (sid.getfromgr (gr))
|
if (sid.getfromgr (gr))
|
||||||
for (int pg = 0; pg < cygheap->user.groups.sgsids.count; ++pg)
|
for (int pg = 0; pg < cygheap->user.groups.sgsids.count (); ++pg)
|
||||||
if (sid == cygheap->user.groups.sgsids.sids[pg] &&
|
if (sid == cygheap->user.groups.sgsids.sids[pg] &&
|
||||||
sid != well_known_world_sid)
|
sid != well_known_world_sid)
|
||||||
{
|
{
|
||||||
|
@ -484,10 +484,10 @@ initgroups32 (const char *name, __gid32_t gid)
|
||||||
if (!get_server_groups (tmp_gsids, usersid, pw))
|
if (!get_server_groups (tmp_gsids, usersid, pw))
|
||||||
goto out;
|
goto out;
|
||||||
tmp_gsids += grpsid;
|
tmp_gsids += grpsid;
|
||||||
cygsidlist new_gsids (cygsidlist_alloc, tmp_gsids.count);
|
cygsidlist new_gsids (cygsidlist_alloc, tmp_gsids.count ());
|
||||||
for (int i = 0; i < tmp_gsids.count; i++)
|
for (int i = 0; i < tmp_gsids.count (); i++)
|
||||||
new_gsids.sids[i] = tmp_gsids.sids[i];
|
new_gsids.sids[i] = tmp_gsids.sids[i];
|
||||||
new_gsids.count = tmp_gsids.count;
|
new_gsids.count (tmp_gsids.count ());
|
||||||
cygheap->user.groups.update_supp (new_gsids);
|
cygheap->user.groups.update_supp (new_gsids);
|
||||||
}
|
}
|
||||||
ret = 0;
|
ret = 0;
|
||||||
|
|
|
@ -67,15 +67,8 @@ MKSID (well_known_system_sid, "S-1-5-18",
|
||||||
MKSID (well_known_admins_sid, "S-1-5-32-544",
|
MKSID (well_known_admins_sid, "S-1-5-32-544",
|
||||||
SECURITY_NT_AUTHORITY, 2, SECURITY_BUILTIN_DOMAIN_RID,
|
SECURITY_NT_AUTHORITY, 2, SECURITY_BUILTIN_DOMAIN_RID,
|
||||||
DOMAIN_ALIAS_RID_ADMINS);
|
DOMAIN_ALIAS_RID_ADMINS);
|
||||||
|
MKSID (fake_logon_sid, "S-1-5-5-0-0",
|
||||||
#define SECURITY_MANDATORY_INTEGRITY_AUTHORITY {0,0,0,0,0,16}
|
SECURITY_NT_AUTHORITY, 3, SECURITY_LOGON_IDS_RID, 0, 0);
|
||||||
|
|
||||||
MKSID (mandatory_medium_integrity_sid, "S-1-64-8192",
|
|
||||||
SECURITY_MANDATORY_INTEGRITY_AUTHORITY, 1, 8192);
|
|
||||||
MKSID (mandatory_high_integrity_sid, "S-1-64-12288",
|
|
||||||
SECURITY_MANDATORY_INTEGRITY_AUTHORITY, 1, 12288);
|
|
||||||
MKSID (mandatory_system_integrity_sid, "S-1-64-16384",
|
|
||||||
SECURITY_MANDATORY_INTEGRITY_AUTHORITY, 1, 16384);
|
|
||||||
|
|
||||||
bool
|
bool
|
||||||
cygpsid::operator== (const char *nsidstr) const
|
cygpsid::operator== (const char *nsidstr) const
|
||||||
|
@ -135,7 +128,7 @@ cygpsid::string (char *nsidstr) const
|
||||||
}
|
}
|
||||||
|
|
||||||
PSID
|
PSID
|
||||||
cygsid::get_sid (DWORD s, DWORD cnt, DWORD *r)
|
cygsid::get_sid (DWORD s, DWORD cnt, DWORD *r, bool well_known)
|
||||||
{
|
{
|
||||||
DWORD i;
|
DWORD i;
|
||||||
SID_IDENTIFIER_AUTHORITY sid_auth = {0,0,0,0,0,0};
|
SID_IDENTIFIER_AUTHORITY sid_auth = {0,0,0,0,0,0};
|
||||||
|
@ -150,11 +143,12 @@ cygsid::get_sid (DWORD s, DWORD cnt, DWORD *r)
|
||||||
InitializeSid (psid, &sid_auth, cnt);
|
InitializeSid (psid, &sid_auth, cnt);
|
||||||
for (i = 0; i < cnt; ++i)
|
for (i = 0; i < cnt; ++i)
|
||||||
memcpy ((char *) psid + 8 + sizeof (DWORD) * i, &r[i], sizeof (DWORD));
|
memcpy ((char *) psid + 8 + sizeof (DWORD) * i, &r[i], sizeof (DWORD));
|
||||||
|
well_known_sid = well_known;
|
||||||
return psid;
|
return psid;
|
||||||
}
|
}
|
||||||
|
|
||||||
const PSID
|
const PSID
|
||||||
cygsid::getfromstr (const char *nsidstr)
|
cygsid::getfromstr (const char *nsidstr, bool well_known)
|
||||||
{
|
{
|
||||||
char *lasts;
|
char *lasts;
|
||||||
DWORD s, cnt = 0;
|
DWORD s, cnt = 0;
|
||||||
|
@ -166,7 +160,7 @@ cygsid::getfromstr (const char *nsidstr)
|
||||||
while (cnt < 8 && *lasts == '-')
|
while (cnt < 8 && *lasts == '-')
|
||||||
r[cnt++] = strtoul (lasts + 1, &lasts, 10);
|
r[cnt++] = strtoul (lasts + 1, &lasts, 10);
|
||||||
if (!*lasts)
|
if (!*lasts)
|
||||||
return get_sid (s, cnt, r);
|
return get_sid (s, cnt, r, well_known);
|
||||||
}
|
}
|
||||||
return psid = NO_SID;
|
return psid = NO_SID;
|
||||||
}
|
}
|
||||||
|
@ -185,6 +179,48 @@ cygsid::getfromgr (const struct __group32 *gr)
|
||||||
return (*this = sp) != NULL;
|
return (*this = sp) != NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cygsid *
|
||||||
|
cygsidlist::alloc_sids (int n)
|
||||||
|
{
|
||||||
|
if (n > 0)
|
||||||
|
return (cygsid *) cmalloc (HEAP_STR, n * sizeof (cygsid));
|
||||||
|
else
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
cygsidlist::free_sids ()
|
||||||
|
{
|
||||||
|
if (sids)
|
||||||
|
cfree (sids);
|
||||||
|
sids = NULL;
|
||||||
|
cnt = maxcnt = 0;
|
||||||
|
type = cygsidlist_empty;
|
||||||
|
}
|
||||||
|
|
||||||
|
BOOL
|
||||||
|
cygsidlist::add (const PSID nsi, bool well_known)
|
||||||
|
{
|
||||||
|
if (contains (nsi))
|
||||||
|
return TRUE;
|
||||||
|
if (cnt >= maxcnt)
|
||||||
|
{
|
||||||
|
cygsid *tmp = new cygsid [2 * maxcnt];
|
||||||
|
if (!tmp)
|
||||||
|
return FALSE;
|
||||||
|
maxcnt *= 2;
|
||||||
|
for (int i = 0; i < cnt; ++i)
|
||||||
|
tmp[i] = sids[i];
|
||||||
|
delete [] sids;
|
||||||
|
sids = tmp;
|
||||||
|
}
|
||||||
|
if (well_known)
|
||||||
|
sids[cnt++] *= nsi;
|
||||||
|
else
|
||||||
|
sids[cnt++] = nsi;
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
get_sids_info (cygpsid owner_sid, cygpsid group_sid, __uid32_t * uidret, __gid32_t * gidret)
|
get_sids_info (cygpsid owner_sid, cygpsid group_sid, __uid32_t * uidret, __gid32_t * gidret)
|
||||||
{
|
{
|
||||||
|
|
|
@ -41,6 +41,8 @@ details. */
|
||||||
#include "ntdll.h"
|
#include "ntdll.h"
|
||||||
#include "lm.h"
|
#include "lm.h"
|
||||||
#include "pwdgrp.h"
|
#include "pwdgrp.h"
|
||||||
|
#include "cyglsa.h"
|
||||||
|
#include <cygwin/version.h>
|
||||||
|
|
||||||
bool allow_ntsec;
|
bool allow_ntsec;
|
||||||
/* allow_smbntsec is handled exclusively in path.cc (path_conv::check).
|
/* allow_smbntsec is handled exclusively in path.cc (path_conv::check).
|
||||||
|
@ -48,25 +50,6 @@ bool allow_ntsec;
|
||||||
bool allow_smbntsec;
|
bool allow_smbntsec;
|
||||||
bool allow_traverse;
|
bool allow_traverse;
|
||||||
|
|
||||||
cygsid *
|
|
||||||
cygsidlist::alloc_sids (int n)
|
|
||||||
{
|
|
||||||
if (n > 0)
|
|
||||||
return (cygsid *) cmalloc (HEAP_STR, n * sizeof (cygsid));
|
|
||||||
else
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
|
||||||
cygsidlist::free_sids ()
|
|
||||||
{
|
|
||||||
if (sids)
|
|
||||||
cfree (sids);
|
|
||||||
sids = NULL;
|
|
||||||
count = maxcount = 0;
|
|
||||||
type = cygsidlist_empty;
|
|
||||||
}
|
|
||||||
|
|
||||||
extern "C" void
|
extern "C" void
|
||||||
cygwin_set_impersonation_token (const HANDLE hToken)
|
cygwin_set_impersonation_token (const HANDLE hToken)
|
||||||
{
|
{
|
||||||
|
@ -346,7 +329,7 @@ is_group_member (WCHAR *wgroup, PSID pusersid, cygsidlist &grp_list)
|
||||||
Note: Allowing those groups in our group list renders external
|
Note: Allowing those groups in our group list renders external
|
||||||
tokens invalid, so that it becomes impossible to logon with
|
tokens invalid, so that it becomes impossible to logon with
|
||||||
password and valid logon token. */
|
password and valid logon token. */
|
||||||
for (int glidx = 0; glidx < grp_list.count; ++glidx)
|
for (int glidx = 0; glidx < grp_list.count (); ++glidx)
|
||||||
if ((buf[bidx].lgrmi1_sidusage == SidTypeGroup
|
if ((buf[bidx].lgrmi1_sidusage == SidTypeGroup
|
||||||
|| buf[bidx].lgrmi1_sidusage == SidTypeWellKnownGroup)
|
|| buf[bidx].lgrmi1_sidusage == SidTypeWellKnownGroup)
|
||||||
&& EqualSid (grp_list.sids[glidx], buf[bidx].lgrmi1_sid))
|
&& EqualSid (grp_list.sids[glidx], buf[bidx].lgrmi1_sid))
|
||||||
|
@ -409,8 +392,7 @@ get_user_local_groups (cygsidlist &grp_list, PSID pusersid)
|
||||||
}
|
}
|
||||||
if (!legal_sid_type (use))
|
if (!legal_sid_type (use))
|
||||||
debug_printf ("Rejecting local %s. use: %d", bgroup + blen, use);
|
debug_printf ("Rejecting local %s. use: %d", bgroup + blen, use);
|
||||||
else if (!grp_list.contains (gsid))
|
grp_list *= gsid;
|
||||||
grp_list += gsid;
|
|
||||||
}
|
}
|
||||||
NetApiBufferFree (buf);
|
NetApiBufferFree (buf);
|
||||||
return true;
|
return true;
|
||||||
|
@ -480,7 +462,7 @@ get_unix_group_sidlist (struct passwd *pw, cygsidlist &grp_list)
|
||||||
goto found;
|
goto found;
|
||||||
continue;
|
continue;
|
||||||
found:
|
found:
|
||||||
if (gsid.getfromgr (gr) && !grp_list.contains (gsid))
|
if (gsid.getfromgr (gr))
|
||||||
grp_list += gsid;
|
grp_list += gsid;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -498,26 +480,26 @@ get_token_group_sidlist (cygsidlist &grp_list, PTOKEN_GROUPS my_grps,
|
||||||
/*if (sid_in_token_groups (my_grps, well_known_local_sid))*/
|
/*if (sid_in_token_groups (my_grps, well_known_local_sid))*/
|
||||||
grp_list += well_known_local_sid;
|
grp_list += well_known_local_sid;
|
||||||
if (sid_in_token_groups (my_grps, well_known_dialup_sid))
|
if (sid_in_token_groups (my_grps, well_known_dialup_sid))
|
||||||
grp_list += well_known_dialup_sid;
|
grp_list *= well_known_dialup_sid;
|
||||||
if (sid_in_token_groups (my_grps, well_known_network_sid))
|
if (sid_in_token_groups (my_grps, well_known_network_sid))
|
||||||
grp_list += well_known_network_sid;
|
grp_list *= well_known_network_sid;
|
||||||
if (sid_in_token_groups (my_grps, well_known_batch_sid))
|
if (sid_in_token_groups (my_grps, well_known_batch_sid))
|
||||||
grp_list += well_known_batch_sid;
|
grp_list *= well_known_batch_sid;
|
||||||
/* This is a problem on 2K3 (only domain controllers?!?) which only
|
/* This is a problem on 2K3 (only domain controllers?!?) which only
|
||||||
enables tools for selected special groups. A subauth token is
|
enables tools for selected special groups. A subauth token is
|
||||||
only NETWORK, but NETWORK has no access to these tools. Therefore
|
only NETWORK, but NETWORK has no access to these tools. Therefore
|
||||||
we always add INTERACTIVE here. */
|
we always add INTERACTIVE here. */
|
||||||
/*if (sid_in_token_groups (my_grps, well_known_interactive_sid))*/
|
/*if (sid_in_token_groups (my_grps, well_known_interactive_sid))*/
|
||||||
grp_list += well_known_interactive_sid;
|
grp_list *= well_known_interactive_sid;
|
||||||
if (sid_in_token_groups (my_grps, well_known_service_sid))
|
if (sid_in_token_groups (my_grps, well_known_service_sid))
|
||||||
grp_list += well_known_service_sid;
|
grp_list *= well_known_service_sid;
|
||||||
if (sid_in_token_groups (my_grps, well_known_this_org_sid))
|
if (sid_in_token_groups (my_grps, well_known_this_org_sid))
|
||||||
grp_list += well_known_this_org_sid;
|
grp_list *= well_known_this_org_sid;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
grp_list += well_known_local_sid;
|
grp_list += well_known_local_sid;
|
||||||
grp_list += well_known_interactive_sid;
|
grp_list *= well_known_interactive_sid;
|
||||||
}
|
}
|
||||||
if (get_ll (auth_luid) != 999LL) /* != SYSTEM_LUID */
|
if (get_ll (auth_luid) != 999LL) /* != SYSTEM_LUID */
|
||||||
{
|
{
|
||||||
|
@ -525,7 +507,7 @@ get_token_group_sidlist (cygsidlist &grp_list, PTOKEN_GROUPS my_grps,
|
||||||
if (my_grps->Groups[i].Attributes & SE_GROUP_LOGON_ID)
|
if (my_grps->Groups[i].Attributes & SE_GROUP_LOGON_ID)
|
||||||
{
|
{
|
||||||
grp_list += my_grps->Groups[i].Sid;
|
grp_list += my_grps->Groups[i].Sid;
|
||||||
auth_pos = grp_list.count - 1;
|
auth_pos = grp_list.count () - 1;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -541,22 +523,24 @@ get_server_groups (cygsidlist &grp_list, PSID usersid, struct passwd *pw)
|
||||||
|
|
||||||
if (well_known_system_sid == usersid)
|
if (well_known_system_sid == usersid)
|
||||||
{
|
{
|
||||||
grp_list += well_known_admins_sid;
|
grp_list *= well_known_admins_sid;
|
||||||
get_unix_group_sidlist (pw, grp_list);
|
get_unix_group_sidlist (pw, grp_list);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!grp_list.contains (well_known_world_sid))
|
grp_list *= well_known_world_sid;
|
||||||
grp_list += well_known_world_sid;
|
grp_list *= well_known_authenticated_users_sid;
|
||||||
if (!grp_list.contains (well_known_authenticated_users_sid))
|
|
||||||
grp_list += well_known_authenticated_users_sid;
|
|
||||||
extract_nt_dom_user (pw, domain, user);
|
extract_nt_dom_user (pw, domain, user);
|
||||||
if (get_logon_server (domain, server, wserver, false)
|
if (get_logon_server (domain, server, wserver, false)
|
||||||
&& !get_user_groups (wserver, grp_list, user, domain)
|
&& !get_user_groups (wserver, grp_list, user, domain)
|
||||||
&& get_logon_server (domain, server, wserver, true))
|
&& get_logon_server (domain, server, wserver, true))
|
||||||
get_user_groups (wserver, grp_list, user, domain);
|
get_user_groups (wserver, grp_list, user, domain);
|
||||||
get_unix_group_sidlist (pw, grp_list);
|
if (get_user_local_groups (grp_list, usersid))
|
||||||
return get_user_local_groups (grp_list, usersid);
|
{
|
||||||
|
get_unix_group_sidlist (pw, grp_list);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool
|
static bool
|
||||||
|
@ -564,8 +548,8 @@ get_initgroups_sidlist (cygsidlist &grp_list,
|
||||||
PSID usersid, PSID pgrpsid, struct passwd *pw,
|
PSID usersid, PSID pgrpsid, struct passwd *pw,
|
||||||
PTOKEN_GROUPS my_grps, LUID auth_luid, int &auth_pos)
|
PTOKEN_GROUPS my_grps, LUID auth_luid, int &auth_pos)
|
||||||
{
|
{
|
||||||
grp_list += well_known_world_sid;
|
grp_list *= well_known_world_sid;
|
||||||
grp_list += well_known_authenticated_users_sid;
|
grp_list *= well_known_authenticated_users_sid;
|
||||||
if (well_known_system_sid == usersid)
|
if (well_known_system_sid == usersid)
|
||||||
auth_pos = -1;
|
auth_pos = -1;
|
||||||
else
|
else
|
||||||
|
@ -574,24 +558,22 @@ get_initgroups_sidlist (cygsidlist &grp_list,
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
/* special_pgrp true if pgrpsid is not in normal groups */
|
/* special_pgrp true if pgrpsid is not in normal groups */
|
||||||
if (!grp_list.contains (pgrpsid))
|
grp_list += pgrpsid;
|
||||||
grp_list += pgrpsid;
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
get_setgroups_sidlist (cygsidlist &tmp_list, PTOKEN_GROUPS my_grps,
|
get_setgroups_sidlist (cygsidlist &tmp_list, PSID usersid, struct passwd *pw,
|
||||||
user_groups &groups, LUID auth_luid, int &auth_pos)
|
PTOKEN_GROUPS my_grps, user_groups &groups,
|
||||||
|
LUID auth_luid, int &auth_pos)
|
||||||
{
|
{
|
||||||
PSID pgpsid = groups.pgsid;
|
tmp_list *= well_known_world_sid;
|
||||||
tmp_list += well_known_world_sid;
|
tmp_list *= well_known_authenticated_users_sid;
|
||||||
tmp_list += well_known_authenticated_users_sid;
|
|
||||||
get_token_group_sidlist (tmp_list, my_grps, auth_luid, auth_pos);
|
get_token_group_sidlist (tmp_list, my_grps, auth_luid, auth_pos);
|
||||||
for (int gidx = 0; gidx < groups.sgsids.count; gidx++)
|
get_server_groups (tmp_list, usersid, pw);
|
||||||
if (!tmp_list.contains (groups.sgsids.sids[gidx]))
|
for (int gidx = 0; gidx < groups.sgsids.count (); gidx++)
|
||||||
tmp_list += groups.sgsids.sids[gidx];
|
tmp_list += groups.sgsids.sids[gidx];
|
||||||
if (!groups.sgsids.contains (pgpsid))
|
tmp_list += groups.pgsid;
|
||||||
tmp_list += pgpsid;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static const cygpriv_idx sys_privs[] = {
|
static const cygpriv_idx sys_privs[] = {
|
||||||
|
@ -628,13 +610,13 @@ static const cygpriv_idx sys_privs[] = {
|
||||||
|
|
||||||
#define SYSTEM_PRIVILEGES_COUNT (sizeof sys_privs / sizeof *sys_privs)
|
#define SYSTEM_PRIVILEGES_COUNT (sizeof sys_privs / sizeof *sys_privs)
|
||||||
|
|
||||||
PTOKEN_PRIVILEGES
|
static PTOKEN_PRIVILEGES
|
||||||
get_system_priv_list (cygsidlist &grp_list)
|
get_system_priv_list (cygsidlist &grp_list, size_t &size)
|
||||||
{
|
{
|
||||||
const LUID *priv;
|
const LUID *priv;
|
||||||
PTOKEN_PRIVILEGES privs = (PTOKEN_PRIVILEGES)
|
size = sizeof (ULONG)
|
||||||
malloc (sizeof (ULONG)
|
+ SYSTEM_PRIVILEGES_COUNT * sizeof (LUID_AND_ATTRIBUTES);
|
||||||
+ SYSTEM_PRIVILEGES_COUNT * sizeof (LUID_AND_ATTRIBUTES));
|
PTOKEN_PRIVILEGES privs = (PTOKEN_PRIVILEGES) malloc (size);
|
||||||
if (!privs)
|
if (!privs)
|
||||||
{
|
{
|
||||||
debug_printf ("malloc (system_privs) failed.");
|
debug_printf ("malloc (system_privs) failed.");
|
||||||
|
@ -653,8 +635,9 @@ get_system_priv_list (cygsidlist &grp_list)
|
||||||
return privs;
|
return privs;
|
||||||
}
|
}
|
||||||
|
|
||||||
PTOKEN_PRIVILEGES
|
static PTOKEN_PRIVILEGES
|
||||||
get_priv_list (LSA_HANDLE lsa, cygsid &usersid, cygsidlist &grp_list)
|
get_priv_list (LSA_HANDLE lsa, cygsid &usersid, cygsidlist &grp_list,
|
||||||
|
size_t &size)
|
||||||
{
|
{
|
||||||
PLSA_UNICODE_STRING privstrs;
|
PLSA_UNICODE_STRING privstrs;
|
||||||
ULONG cnt;
|
ULONG cnt;
|
||||||
|
@ -663,9 +646,9 @@ get_priv_list (LSA_HANDLE lsa, cygsid &usersid, cygsidlist &grp_list)
|
||||||
char buf[INTERNET_MAX_HOST_NAME_LENGTH + 1];
|
char buf[INTERNET_MAX_HOST_NAME_LENGTH + 1];
|
||||||
|
|
||||||
if (usersid == well_known_system_sid)
|
if (usersid == well_known_system_sid)
|
||||||
return get_system_priv_list (grp_list);
|
return get_system_priv_list (grp_list, size);
|
||||||
|
|
||||||
for (int grp = -1; grp < grp_list.count; ++grp)
|
for (int grp = -1; grp < grp_list.count (); ++grp)
|
||||||
{
|
{
|
||||||
if (grp == -1)
|
if (grp == -1)
|
||||||
{
|
{
|
||||||
|
@ -699,9 +682,9 @@ get_priv_list (LSA_HANDLE lsa, cygsid &usersid, cygsidlist &grp_list)
|
||||||
}
|
}
|
||||||
|
|
||||||
tmp_count = privs ? privs->PrivilegeCount : 0;
|
tmp_count = privs ? privs->PrivilegeCount : 0;
|
||||||
tmp = (PTOKEN_PRIVILEGES)
|
size = sizeof (DWORD)
|
||||||
realloc (privs, sizeof (ULONG) +
|
+ (tmp_count + 1) * sizeof (LUID_AND_ATTRIBUTES);
|
||||||
(tmp_count + 1) * sizeof (LUID_AND_ATTRIBUTES));
|
tmp = (PTOKEN_PRIVILEGES) realloc (privs, size);
|
||||||
if (!tmp)
|
if (!tmp)
|
||||||
{
|
{
|
||||||
if (privs)
|
if (privs)
|
||||||
|
@ -794,7 +777,7 @@ verify_token (HANDLE token, cygsid &usersid, user_groups &groups, bool *pintern)
|
||||||
{
|
{
|
||||||
cygsid gsid;
|
cygsid gsid;
|
||||||
struct __group32 *gr;
|
struct __group32 *gr;
|
||||||
bool saw[groups.sgsids.count];
|
bool saw[groups.sgsids.count ()];
|
||||||
memset (saw, 0, sizeof(saw));
|
memset (saw, 0, sizeof(saw));
|
||||||
|
|
||||||
/* token groups found in /etc/group match the user.gsids ? */
|
/* token groups found in /etc/group match the user.gsids ? */
|
||||||
|
@ -811,7 +794,7 @@ verify_token (HANDLE token, cygsid &usersid, user_groups &groups, bool *pintern)
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
/* user.sgsids groups must be in the token */
|
/* user.sgsids groups must be in the token */
|
||||||
for (int gidx = 0; gidx < groups.sgsids.count; gidx++)
|
for (int gidx = 0; gidx < groups.sgsids.count (); gidx++)
|
||||||
if (!saw[gidx] && !sid_in_token_groups (my_grps, groups.sgsids.sids[gidx]))
|
if (!saw[gidx] && !sid_in_token_groups (my_grps, groups.sgsids.sids[gidx]))
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
@ -857,6 +840,7 @@ create_token (cygsid &usersid, user_groups &new_groups, struct passwd *pw,
|
||||||
|
|
||||||
PTOKEN_GROUPS my_tok_gsids = NULL;
|
PTOKEN_GROUPS my_tok_gsids = NULL;
|
||||||
DWORD size;
|
DWORD size;
|
||||||
|
size_t psize = 0;
|
||||||
|
|
||||||
/* SE_CREATE_TOKEN_NAME privilege needed to call NtCreateToken. */
|
/* SE_CREATE_TOKEN_NAME privilege needed to call NtCreateToken. */
|
||||||
push_self_privilege (SE_CREATE_TOKEN_PRIV, true);
|
push_self_privilege (SE_CREATE_TOKEN_PRIV, true);
|
||||||
|
@ -929,8 +913,8 @@ create_token (cygsid &usersid, user_groups &new_groups, struct passwd *pw,
|
||||||
/* Create list of groups, the user is member in. */
|
/* Create list of groups, the user is member in. */
|
||||||
int auth_pos;
|
int auth_pos;
|
||||||
if (new_groups.issetgroups ())
|
if (new_groups.issetgroups ())
|
||||||
get_setgroups_sidlist (tmp_gsids, my_tok_gsids, new_groups, auth_luid,
|
get_setgroups_sidlist (tmp_gsids, usersid, pw, my_tok_gsids, new_groups,
|
||||||
auth_pos);
|
auth_luid, auth_pos);
|
||||||
else if (!get_initgroups_sidlist (tmp_gsids, usersid, new_groups.pgsid, pw,
|
else if (!get_initgroups_sidlist (tmp_gsids, usersid, new_groups.pgsid, pw,
|
||||||
my_tok_gsids, auth_luid, auth_pos))
|
my_tok_gsids, auth_luid, auth_pos))
|
||||||
goto out;
|
goto out;
|
||||||
|
@ -940,9 +924,9 @@ create_token (cygsid &usersid, user_groups &new_groups, struct passwd *pw,
|
||||||
|
|
||||||
/* Create a TOKEN_GROUPS list from the above retrieved list of sids. */
|
/* Create a TOKEN_GROUPS list from the above retrieved list of sids. */
|
||||||
new_tok_gsids = (PTOKEN_GROUPS)
|
new_tok_gsids = (PTOKEN_GROUPS)
|
||||||
alloca (sizeof (ULONG) + (tmp_gsids.count + 1 )
|
alloca (sizeof (DWORD) + tmp_gsids.count ()
|
||||||
* sizeof (SID_AND_ATTRIBUTES));
|
* sizeof (SID_AND_ATTRIBUTES));
|
||||||
new_tok_gsids->GroupCount = tmp_gsids.count;
|
new_tok_gsids->GroupCount = tmp_gsids.count ();
|
||||||
for (DWORD i = 0; i < new_tok_gsids->GroupCount; ++i)
|
for (DWORD i = 0; i < new_tok_gsids->GroupCount; ++i)
|
||||||
{
|
{
|
||||||
new_tok_gsids->Groups[i].Sid = tmp_gsids.sids[i];
|
new_tok_gsids->Groups[i].Sid = tmp_gsids.sids[i];
|
||||||
|
@ -952,42 +936,8 @@ create_token (cygsid &usersid, user_groups &new_groups, struct passwd *pw,
|
||||||
}
|
}
|
||||||
if (auth_pos >= 0)
|
if (auth_pos >= 0)
|
||||||
new_tok_gsids->Groups[auth_pos].Attributes |= SE_GROUP_LOGON_ID;
|
new_tok_gsids->Groups[auth_pos].Attributes |= SE_GROUP_LOGON_ID;
|
||||||
|
|
||||||
/* On systems supporting Mandatory Integrity Control, add a MIC SID. */
|
|
||||||
if (wincap.has_mandatory_integrity_control ())
|
|
||||||
{
|
|
||||||
bool add_mic_sid = true;
|
|
||||||
new_tok_gsids->Groups[new_tok_gsids->GroupCount].Attributes = 0;
|
|
||||||
|
|
||||||
/* The subauth token usually contains a MIC SID. Copy it into our
|
|
||||||
group SID list. */
|
|
||||||
if (my_tok_gsids)
|
|
||||||
for (DWORD i = 0; i < my_tok_gsids->GroupCount; ++i)
|
|
||||||
if (EqualPrefixSid (mandatory_medium_integrity_sid,
|
|
||||||
my_tok_gsids->Groups[i].Sid))
|
|
||||||
{
|
|
||||||
new_tok_gsids->Groups[new_tok_gsids->GroupCount++].Sid
|
|
||||||
= my_tok_gsids->Groups[i].Sid;
|
|
||||||
add_mic_sid = false;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
/* If no MIC SID was available add a matching one for the account type. */
|
|
||||||
if (add_mic_sid)
|
|
||||||
{
|
|
||||||
if (usersid == well_known_system_sid)
|
|
||||||
new_tok_gsids->Groups[new_tok_gsids->GroupCount++].Sid
|
|
||||||
= mandatory_system_integrity_sid;
|
|
||||||
else if (tmp_gsids.contains (well_known_admins_sid))
|
|
||||||
new_tok_gsids->Groups[new_tok_gsids->GroupCount++].Sid
|
|
||||||
= mandatory_high_integrity_sid;
|
|
||||||
else
|
|
||||||
new_tok_gsids->Groups[new_tok_gsids->GroupCount++].Sid
|
|
||||||
= mandatory_medium_integrity_sid;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Retrieve list of privileges of that user. */
|
/* Retrieve list of privileges of that user. */
|
||||||
if (!privs && !(privs = get_priv_list (lsa, usersid, tmp_gsids)))
|
if (!privs && !(privs = get_priv_list (lsa, usersid, tmp_gsids, psize)))
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
/* Let's be heroic... */
|
/* Let's be heroic... */
|
||||||
|
@ -1023,10 +973,16 @@ out:
|
||||||
free (my_tok_gsids);
|
free (my_tok_gsids);
|
||||||
close_local_policy (lsa);
|
close_local_policy (lsa);
|
||||||
|
|
||||||
debug_printf ("%d = create_token ()", primary_token);
|
debug_printf ("0x%x = create_token ()", primary_token);
|
||||||
return primary_token;
|
return primary_token;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Subauthentication gets useless now that real LSA authentication is
|
||||||
|
available. The accompanying code in seteuid32 and environ.cc is
|
||||||
|
also disabled.
|
||||||
|
TODO: Deprecate and delete code entirely.
|
||||||
|
TODO: Delete from documentation. */
|
||||||
|
#if 0
|
||||||
extern "C"
|
extern "C"
|
||||||
{
|
{
|
||||||
BOOL WINAPI Wow64DisableWow64FsRedirection (PVOID *);
|
BOOL WINAPI Wow64DisableWow64FsRedirection (PVOID *);
|
||||||
|
@ -1047,7 +1003,7 @@ HANDLE
|
||||||
subauth (struct passwd *pw)
|
subauth (struct passwd *pw)
|
||||||
{
|
{
|
||||||
LSA_STRING name;
|
LSA_STRING name;
|
||||||
HANDLE lsa_hdl;
|
HANDLE lsa_hdl = NULL;
|
||||||
LSA_OPERATIONAL_MODE sec_mode;
|
LSA_OPERATIONAL_MODE sec_mode;
|
||||||
NTSTATUS ret, ret2;
|
NTSTATUS ret, ret2;
|
||||||
ULONG package_id, size;
|
ULONG package_id, size;
|
||||||
|
@ -1141,7 +1097,6 @@ subauth (struct passwd *pw)
|
||||||
{
|
{
|
||||||
debug_printf ("LsaLookupAuthenticationPackage: %d", ret);
|
debug_printf ("LsaLookupAuthenticationPackage: %d", ret);
|
||||||
__seterrno_from_win_error (LsaNtStatusToWinError (ret));
|
__seterrno_from_win_error (LsaNtStatusToWinError (ret));
|
||||||
LsaDeregisterLogonProcess (lsa_hdl);
|
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
/* Create origin. */
|
/* Create origin. */
|
||||||
|
@ -1170,7 +1125,6 @@ subauth (struct passwd *pw)
|
||||||
{
|
{
|
||||||
debug_printf ("LsaLogonUser: %d", ret);
|
debug_printf ("LsaLogonUser: %d", ret);
|
||||||
__seterrno_from_win_error (LsaNtStatusToWinError (ret));
|
__seterrno_from_win_error (LsaNtStatusToWinError (ret));
|
||||||
LsaDeregisterLogonProcess (lsa_hdl);
|
|
||||||
goto out;
|
goto out;
|
||||||
}
|
}
|
||||||
LsaFreeReturnBuffer (profile);
|
LsaFreeReturnBuffer (profile);
|
||||||
|
@ -1180,11 +1134,254 @@ subauth (struct passwd *pw)
|
||||||
__seterrno ();
|
__seterrno ();
|
||||||
|
|
||||||
out:
|
out:
|
||||||
|
if (lsa_hdl)
|
||||||
|
LsaDeregisterLogonProcess (lsa_hdl);
|
||||||
pop_self_privilege ();
|
pop_self_privilege ();
|
||||||
if (user_token)
|
if (user_token)
|
||||||
CloseHandle (user_token);
|
CloseHandle (user_token);
|
||||||
return primary_token;
|
return primary_token;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
HANDLE
|
||||||
|
lsaauth (cygsid &usersid, user_groups &new_groups, struct passwd *pw)
|
||||||
|
{
|
||||||
|
cygsidlist tmp_gsids (cygsidlist_auto, 12);
|
||||||
|
cygpsid pgrpsid;
|
||||||
|
LSA_STRING name;
|
||||||
|
HANDLE lsa_hdl = NULL, lsa;
|
||||||
|
LSA_OPERATIONAL_MODE sec_mode;
|
||||||
|
NTSTATUS ret, ret2;
|
||||||
|
ULONG package_id, size;
|
||||||
|
LUID auth_luid = SYSTEM_LUID;
|
||||||
|
struct {
|
||||||
|
LSA_STRING str;
|
||||||
|
CHAR buf[16];
|
||||||
|
} origin;
|
||||||
|
cyglsa_t *authinf = NULL;
|
||||||
|
ULONG authinf_size;
|
||||||
|
TOKEN_SOURCE ts;
|
||||||
|
PCYG_TOKEN_GROUPS gsids = NULL;
|
||||||
|
PTOKEN_PRIVILEGES privs = NULL;
|
||||||
|
PACL dacl = NULL;
|
||||||
|
PVOID profile = NULL;
|
||||||
|
LUID luid;
|
||||||
|
QUOTA_LIMITS quota;
|
||||||
|
size_t psize = 0, gsize = 0, dsize = 0;
|
||||||
|
OFFSET offset, sids_offset;
|
||||||
|
int tmpidx, non_well_known_cnt;
|
||||||
|
|
||||||
|
HANDLE user_token = NULL;
|
||||||
|
|
||||||
|
push_self_privilege (SE_TCB_PRIV, true);
|
||||||
|
|
||||||
|
/* Register as logon process. */
|
||||||
|
str2lsa (name, "Cygwin");
|
||||||
|
SetLastError (0);
|
||||||
|
ret = LsaRegisterLogonProcess (&name, &lsa_hdl, &sec_mode);
|
||||||
|
if (ret != STATUS_SUCCESS)
|
||||||
|
{
|
||||||
|
debug_printf ("LsaRegisterLogonProcess: %p", ret);
|
||||||
|
__seterrno_from_win_error (LsaNtStatusToWinError (ret));
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
else if (GetLastError () == ERROR_PROC_NOT_FOUND)
|
||||||
|
{
|
||||||
|
debug_printf ("Couldn't load Secur32.dll");
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
/* Get handle to our own LSA package. */
|
||||||
|
str2lsa (name, CYG_LSA_PKGNAME);
|
||||||
|
ret = LsaLookupAuthenticationPackage (lsa_hdl, &name, &package_id);
|
||||||
|
if (ret != STATUS_SUCCESS)
|
||||||
|
{
|
||||||
|
debug_printf ("LsaLookupAuthenticationPackage: %p", ret);
|
||||||
|
__seterrno_from_win_error (LsaNtStatusToWinError (ret));
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Open policy object. */
|
||||||
|
if ((lsa = open_local_policy ()) == INVALID_HANDLE_VALUE)
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
/* Create origin. */
|
||||||
|
str2buf2lsa (origin.str, origin.buf, "Cygwin");
|
||||||
|
/* Create token source. */
|
||||||
|
memcpy (ts.SourceName, "Cygwin.1", 8);
|
||||||
|
ts.SourceIdentifier.HighPart = 0;
|
||||||
|
ts.SourceIdentifier.LowPart = 0x0103;
|
||||||
|
|
||||||
|
/* Create list of groups, the user is member in. */
|
||||||
|
int auth_pos;
|
||||||
|
if (new_groups.issetgroups ())
|
||||||
|
get_setgroups_sidlist (tmp_gsids, usersid, pw, NULL, new_groups, auth_luid,
|
||||||
|
auth_pos);
|
||||||
|
else if (!get_initgroups_sidlist (tmp_gsids, usersid, new_groups.pgsid, pw,
|
||||||
|
NULL, auth_luid, auth_pos))
|
||||||
|
goto out;
|
||||||
|
/* The logon SID entry is not generated automatically on Windows 2000
|
||||||
|
and earlier for some reason. So add fake logon sid here, which is
|
||||||
|
filled with logon id values in the authentication package. */
|
||||||
|
if (wincap.needs_logon_sid_in_sid_list ())
|
||||||
|
tmp_gsids += fake_logon_sid;
|
||||||
|
|
||||||
|
tmp_gsids.debug_print ("tmp_gsids");
|
||||||
|
|
||||||
|
/* Evaluate size of TOKEN_GROUPS list */
|
||||||
|
non_well_known_cnt = tmp_gsids.non_well_known_count ();
|
||||||
|
gsize = sizeof (DWORD) + non_well_known_cnt * sizeof (SID_AND_ATTRIBUTES);
|
||||||
|
tmpidx = -1;
|
||||||
|
for (int i = 0; i < non_well_known_cnt; ++i)
|
||||||
|
if ((tmpidx = tmp_gsids.next_non_well_known_sid (tmpidx)) >= 0)
|
||||||
|
gsize += GetLengthSid (tmp_gsids.sids[tmpidx]);
|
||||||
|
|
||||||
|
/* Retrieve list of privileges of that user. */
|
||||||
|
if (!(privs = get_priv_list (lsa, usersid, tmp_gsids, psize)))
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
/* Create DefaultDacl. */
|
||||||
|
dsize = sizeof (ACL) + 3 * sizeof (ACCESS_ALLOWED_ACE)
|
||||||
|
+ GetLengthSid (usersid)
|
||||||
|
+ GetLengthSid (well_known_admins_sid)
|
||||||
|
+ GetLengthSid (well_known_system_sid);
|
||||||
|
dacl = (PACL) alloca (dsize);
|
||||||
|
if (!InitializeAcl (dacl, dsize, ACL_REVISION))
|
||||||
|
goto out;
|
||||||
|
if (!AddAccessAllowedAce (dacl, ACL_REVISION, GENERIC_ALL, usersid))
|
||||||
|
goto out;
|
||||||
|
if (!AddAccessAllowedAce (dacl, ACL_REVISION, GENERIC_ALL,
|
||||||
|
well_known_admins_sid))
|
||||||
|
goto out;
|
||||||
|
if (!AddAccessAllowedAce (dacl, ACL_REVISION, GENERIC_ALL,
|
||||||
|
well_known_system_sid))
|
||||||
|
goto out;
|
||||||
|
|
||||||
|
/* Evaluate authinf size and allocate authinf. */
|
||||||
|
authinf_size = (authinf->data - (PBYTE) authinf);
|
||||||
|
authinf_size += GetLengthSid (usersid); /* User SID */
|
||||||
|
authinf_size += gsize; /* Groups + Group SIDs */
|
||||||
|
/* When trying to define the admins group as primary group on Vista,
|
||||||
|
LsaLogonUser fails with error STATUS_INVALID_OWNER. As workaround
|
||||||
|
we define "Local" as primary group here. First, this adds the otherwise
|
||||||
|
missing "Local" group to the group list and second, seteuid32
|
||||||
|
sets the primary group to the group set in /etc/passwd anyway. */
|
||||||
|
pgrpsid = well_known_local_sid;
|
||||||
|
authinf_size += GetLengthSid (pgrpsid); /* Primary Group SID */
|
||||||
|
|
||||||
|
authinf_size += psize; /* Privileges */
|
||||||
|
authinf_size += 0; /* Owner SID */
|
||||||
|
authinf_size += dsize; /* Default DACL */
|
||||||
|
|
||||||
|
authinf = (cyglsa_t *) alloca (authinf_size);
|
||||||
|
authinf->inf_size = authinf_size - ((PBYTE) &authinf->inf - (PBYTE) authinf);
|
||||||
|
|
||||||
|
authinf->magic = CYG_LSA_MAGIC;
|
||||||
|
|
||||||
|
extract_nt_dom_user (pw, authinf->domain, authinf->username);
|
||||||
|
|
||||||
|
/* Store stuff in authinf with offset relative to start of "inf" member,
|
||||||
|
instead of using pointers. */
|
||||||
|
offset = authinf->data - (PBYTE) &authinf->inf;
|
||||||
|
|
||||||
|
authinf->inf.ExpirationTime.LowPart = 0xffffffffL;
|
||||||
|
authinf->inf.ExpirationTime.HighPart = 0x7fffffffL;
|
||||||
|
/* User SID */
|
||||||
|
authinf->inf.User.User.Sid = offset;
|
||||||
|
authinf->inf.User.User.Attributes = 0;
|
||||||
|
CopySid (GetLengthSid (usersid), (PSID) ((PBYTE) &authinf->inf + offset),
|
||||||
|
usersid);
|
||||||
|
offset += GetLengthSid (usersid);
|
||||||
|
/* Groups */
|
||||||
|
authinf->inf.Groups = offset;
|
||||||
|
gsids = (PCYG_TOKEN_GROUPS) ((PBYTE) &authinf->inf + offset);
|
||||||
|
sids_offset = offset + sizeof (ULONG) + non_well_known_cnt
|
||||||
|
* sizeof (SID_AND_ATTRIBUTES);
|
||||||
|
gsids->GroupCount = non_well_known_cnt;
|
||||||
|
/* Group SIDs */
|
||||||
|
tmpidx = -1;
|
||||||
|
for (int i = 0; i < non_well_known_cnt; ++i)
|
||||||
|
{
|
||||||
|
if ((tmpidx = tmp_gsids.next_non_well_known_sid (tmpidx)) < 0)
|
||||||
|
break;
|
||||||
|
gsids->Groups[i].Sid = sids_offset;
|
||||||
|
gsids->Groups[i].Attributes = SE_GROUP_MANDATORY
|
||||||
|
| SE_GROUP_ENABLED_BY_DEFAULT
|
||||||
|
| SE_GROUP_ENABLED;
|
||||||
|
/* Mark logon SID as logon SID :) */
|
||||||
|
if (wincap.needs_logon_sid_in_sid_list ()
|
||||||
|
&& tmp_gsids.sids[tmpidx] == fake_logon_sid)
|
||||||
|
gsids->Groups[i].Attributes += SE_GROUP_LOGON_ID;
|
||||||
|
CopySid (GetLengthSid (tmp_gsids.sids[tmpidx]),
|
||||||
|
(PSID) ((PBYTE) &authinf->inf + sids_offset),
|
||||||
|
tmp_gsids.sids[tmpidx]);
|
||||||
|
sids_offset += GetLengthSid (tmp_gsids.sids[tmpidx]);
|
||||||
|
}
|
||||||
|
offset += gsize;
|
||||||
|
/* Primary Group SID */
|
||||||
|
authinf->inf.PrimaryGroup.PrimaryGroup = offset;
|
||||||
|
CopySid (GetLengthSid (pgrpsid), (PSID) ((PBYTE) &authinf->inf + offset),
|
||||||
|
pgrpsid);
|
||||||
|
offset += GetLengthSid (pgrpsid);
|
||||||
|
/* Privileges */
|
||||||
|
authinf->inf.Privileges = offset;
|
||||||
|
memcpy ((PBYTE) &authinf->inf + offset, privs, psize);
|
||||||
|
offset += psize;
|
||||||
|
/* Owner */
|
||||||
|
authinf->inf.Owner.Owner = 0;
|
||||||
|
/* Default DACL */
|
||||||
|
authinf->inf.DefaultDacl.DefaultDacl = offset;
|
||||||
|
memcpy ((PBYTE) &authinf->inf + offset, dacl, dsize);
|
||||||
|
|
||||||
|
authinf->checksum = CYGWIN_VERSION_MAGIC (CYGWIN_VERSION_DLL_MAJOR,
|
||||||
|
CYGWIN_VERSION_DLL_MINOR);
|
||||||
|
PDWORD csp = (PDWORD) &authinf->username;
|
||||||
|
PDWORD csp_end = (PDWORD) ((PBYTE) authinf + authinf_size);
|
||||||
|
while (csp < csp_end)
|
||||||
|
authinf->checksum += *csp++;
|
||||||
|
|
||||||
|
/* Try to logon... */
|
||||||
|
ret = LsaLogonUser (lsa_hdl, (PLSA_STRING) &origin, Interactive, package_id,
|
||||||
|
authinf, authinf_size, NULL, &ts, &profile, &size, &luid,
|
||||||
|
&user_token, "a, &ret2);
|
||||||
|
if (ret != STATUS_SUCCESS)
|
||||||
|
{
|
||||||
|
debug_printf ("LsaLogonUser: %p", ret);
|
||||||
|
__seterrno_from_win_error (LsaNtStatusToWinError (ret));
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
if (profile)
|
||||||
|
LsaFreeReturnBuffer (profile);
|
||||||
|
|
||||||
|
if (wincap.has_mandatory_integrity_control ())
|
||||||
|
{
|
||||||
|
typedef struct _TOKEN_LINKED_TOKEN
|
||||||
|
{
|
||||||
|
HANDLE LinkedToken;
|
||||||
|
} TOKEN_LINKED_TOKEN, *PTOKEN_LINKED_TOKEN;
|
||||||
|
# define TokenLinkedToken ((TOKEN_INFORMATION_CLASS) 19)
|
||||||
|
|
||||||
|
TOKEN_LINKED_TOKEN linked;
|
||||||
|
|
||||||
|
if (GetTokenInformation (user_token, TokenLinkedToken,
|
||||||
|
(PVOID) &linked, sizeof linked, &size))
|
||||||
|
{
|
||||||
|
debug_printf ("Linked Token: %lu", linked.LinkedToken);
|
||||||
|
if (linked.LinkedToken)
|
||||||
|
user_token = linked.LinkedToken;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
out:
|
||||||
|
if (privs)
|
||||||
|
free (privs);
|
||||||
|
close_local_policy (lsa);
|
||||||
|
if (lsa_hdl)
|
||||||
|
LsaDeregisterLogonProcess (lsa_hdl);
|
||||||
|
pop_self_privilege ();
|
||||||
|
|
||||||
|
debug_printf ("0x%x = lsaauth ()", user_token);
|
||||||
|
return user_token;
|
||||||
|
}
|
||||||
|
|
||||||
/* read_sd reads a security descriptor from a file.
|
/* read_sd reads a security descriptor from a file.
|
||||||
In case of error, -1 is returned and errno is set.
|
In case of error, -1 is returned and errno is set.
|
||||||
|
|
|
@ -80,11 +80,12 @@ public:
|
||||||
|
|
||||||
class cygsid : public cygpsid {
|
class cygsid : public cygpsid {
|
||||||
char sbuf[MAX_SID_LEN];
|
char sbuf[MAX_SID_LEN];
|
||||||
|
bool well_known_sid;
|
||||||
|
|
||||||
const PSID getfromstr (const char *nsidstr);
|
const PSID getfromstr (const char *nsidstr, bool well_known);
|
||||||
PSID get_sid (DWORD s, DWORD cnt, DWORD *r);
|
PSID get_sid (DWORD s, DWORD cnt, DWORD *r, bool well_known);
|
||||||
|
|
||||||
inline const PSID assign (const PSID nsid)
|
inline const PSID assign (const PSID nsid, bool well_known)
|
||||||
{
|
{
|
||||||
if (!nsid)
|
if (!nsid)
|
||||||
psid = NO_SID;
|
psid = NO_SID;
|
||||||
|
@ -92,21 +93,32 @@ class cygsid : public cygpsid {
|
||||||
{
|
{
|
||||||
psid = (PSID) sbuf;
|
psid = (PSID) sbuf;
|
||||||
CopySid (MAX_SID_LEN, psid, nsid);
|
CopySid (MAX_SID_LEN, psid, nsid);
|
||||||
|
well_known_sid = well_known;
|
||||||
}
|
}
|
||||||
return psid;
|
return psid;
|
||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
inline operator const PSID () { return psid; }
|
inline operator const PSID () { return psid; }
|
||||||
|
inline bool is_well_known_sid () { return well_known_sid; }
|
||||||
|
|
||||||
|
/* Both, = and *= are assignment operators. = creates a "normal" SID,
|
||||||
|
*= marks the SID as being a well-known SID. This difference is
|
||||||
|
important when creating a SID list for LSA authentication. */
|
||||||
inline const PSID operator= (cygsid &nsid)
|
inline const PSID operator= (cygsid &nsid)
|
||||||
{ return assign (nsid); }
|
{ return assign (nsid, nsid.well_known_sid); }
|
||||||
inline const PSID operator= (const PSID nsid)
|
inline const PSID operator= (const PSID nsid)
|
||||||
{ return assign (nsid); }
|
{ return assign (nsid, false); }
|
||||||
inline const PSID operator= (const char *nsidstr)
|
inline const PSID operator= (const char *nsidstr)
|
||||||
{ return getfromstr (nsidstr); }
|
{ return getfromstr (nsidstr, false); }
|
||||||
|
inline const PSID operator*= (cygsid &nsid)
|
||||||
|
{ return assign (nsid, true); }
|
||||||
|
inline const PSID operator*= (const PSID nsid)
|
||||||
|
{ return assign (nsid, true); }
|
||||||
|
inline const PSID operator*= (const char *nsidstr)
|
||||||
|
{ return getfromstr (nsidstr, true); }
|
||||||
|
|
||||||
inline cygsid () : cygpsid ((PSID) sbuf) {}
|
inline cygsid () : cygpsid ((PSID) sbuf), well_known_sid (false) {}
|
||||||
inline cygsid (const PSID nsid) { *this = nsid; }
|
inline cygsid (const PSID nsid) { *this = nsid; }
|
||||||
inline cygsid (const char *nstrsid) { *this = nstrsid; }
|
inline cygsid (const char *nstrsid) { *this = nstrsid; }
|
||||||
|
|
||||||
|
@ -114,21 +126,28 @@ public:
|
||||||
|
|
||||||
BOOL getfrompw (const struct passwd *pw);
|
BOOL getfrompw (const struct passwd *pw);
|
||||||
BOOL getfromgr (const struct __group32 *gr);
|
BOOL getfromgr (const struct __group32 *gr);
|
||||||
|
|
||||||
|
void debug_print (const char *prefix = NULL) const
|
||||||
|
{
|
||||||
|
char buf[256] __attribute__ ((unused));
|
||||||
|
debug_printf ("%s %s%s", prefix ?: "", string (buf) ?: "NULL", well_known_sid ? " (*)" : " (+)");
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef enum { cygsidlist_empty, cygsidlist_alloc, cygsidlist_auto } cygsidlist_type;
|
typedef enum { cygsidlist_empty, cygsidlist_alloc, cygsidlist_auto } cygsidlist_type;
|
||||||
class cygsidlist {
|
class cygsidlist {
|
||||||
int maxcount;
|
int maxcnt;
|
||||||
|
int cnt;
|
||||||
|
|
||||||
|
BOOL add (const PSID nsi, bool well_known); /* Only with auto for now */
|
||||||
|
|
||||||
public:
|
public:
|
||||||
int count;
|
|
||||||
cygsid *sids;
|
cygsid *sids;
|
||||||
cygsidlist_type type;
|
cygsidlist_type type;
|
||||||
|
|
||||||
cygsidlist (cygsidlist_type t, int m)
|
cygsidlist (cygsidlist_type t, int m)
|
||||||
|
: maxcnt (m), cnt (0), type (t)
|
||||||
{
|
{
|
||||||
type = t;
|
|
||||||
count = 0;
|
|
||||||
maxcount = m;
|
|
||||||
if (t == cygsidlist_alloc)
|
if (t == cygsidlist_alloc)
|
||||||
sids = alloc_sids (m);
|
sids = alloc_sids (m);
|
||||||
else
|
else
|
||||||
|
@ -136,49 +155,56 @@ public:
|
||||||
}
|
}
|
||||||
~cygsidlist () { if (type == cygsidlist_auto) delete [] sids; }
|
~cygsidlist () { if (type == cygsidlist_auto) delete [] sids; }
|
||||||
|
|
||||||
BOOL add (const PSID nsi) /* Only with auto for now */
|
|
||||||
{
|
|
||||||
if (count >= maxcount)
|
|
||||||
{
|
|
||||||
cygsid *tmp = new cygsid [ 2 * maxcount];
|
|
||||||
if (!tmp)
|
|
||||||
return FALSE;
|
|
||||||
maxcount *= 2;
|
|
||||||
for (int i = 0; i < count; ++i)
|
|
||||||
tmp[i] = sids[i];
|
|
||||||
delete [] sids;
|
|
||||||
sids = tmp;
|
|
||||||
}
|
|
||||||
sids[count++] = nsi;
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
BOOL add (cygsid &nsi) { return add ((PSID) nsi); }
|
|
||||||
BOOL add (const char *sidstr)
|
|
||||||
{ cygsid nsi (sidstr); return add (nsi); }
|
|
||||||
BOOL addfromgr (struct __group32 *gr) /* Only with alloc */
|
BOOL addfromgr (struct __group32 *gr) /* Only with alloc */
|
||||||
{ return sids[count].getfromgr (gr) && ++count; }
|
{ return sids[cnt].getfromgr (gr) && ++cnt; }
|
||||||
|
|
||||||
BOOL operator+= (cygsid &si) { return add (si); }
|
/* += adds a "normal" SID, *= adds a well-known SID. See comment in class
|
||||||
BOOL operator+= (const char *sidstr) { return add (sidstr); }
|
cygsid above. */
|
||||||
BOOL operator+= (const PSID psid) { return add (psid); }
|
BOOL operator+= (cygsid &si) { return add ((PSID) si, false); }
|
||||||
|
BOOL operator+= (const char *sidstr) { cygsid nsi (sidstr);
|
||||||
|
return add ((PSID) nsi, false); }
|
||||||
|
BOOL operator+= (const PSID psid) { return add (psid, false); }
|
||||||
|
BOOL operator*= (cygsid &si) { return add ((PSID) si, true); }
|
||||||
|
BOOL operator*= (const char *sidstr) { cygsid nsi (sidstr);
|
||||||
|
return add ((PSID) nsi, true); }
|
||||||
|
BOOL operator*= (const PSID psid) { return add (psid, true); }
|
||||||
|
|
||||||
|
void count (int ncnt)
|
||||||
|
{ cnt = ncnt; }
|
||||||
|
int count () const { return cnt; }
|
||||||
|
int non_well_known_count () const
|
||||||
|
{
|
||||||
|
int wcnt = 0;
|
||||||
|
for (int i = 0; i < cnt; ++i)
|
||||||
|
if (!sids[i].is_well_known_sid ())
|
||||||
|
++wcnt;
|
||||||
|
return wcnt;
|
||||||
|
}
|
||||||
|
|
||||||
int position (const PSID sid) const
|
int position (const PSID sid) const
|
||||||
{
|
{
|
||||||
for (int i = 0; i < count; ++i)
|
for (int i = 0; i < cnt; ++i)
|
||||||
if (sids[i] == sid)
|
if (sids[i] == sid)
|
||||||
return i;
|
return i;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int next_non_well_known_sid (int idx)
|
||||||
|
{
|
||||||
|
while (++idx < cnt)
|
||||||
|
if (!sids[idx].is_well_known_sid ())
|
||||||
|
return idx;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
BOOL contains (const PSID sid) const { return position (sid) >= 0; }
|
BOOL contains (const PSID sid) const { return position (sid) >= 0; }
|
||||||
cygsid *alloc_sids (int n);
|
cygsid *alloc_sids (int n);
|
||||||
void free_sids ();
|
void free_sids ();
|
||||||
void debug_print (const char *prefix = NULL) const
|
void debug_print (const char *prefix = NULL) const
|
||||||
{
|
{
|
||||||
debug_printf ("-- begin sidlist ---");
|
debug_printf ("-- begin sidlist ---");
|
||||||
if (!count)
|
if (!cnt)
|
||||||
debug_printf ("No elements");
|
debug_printf ("No elements");
|
||||||
for (int i = 0; i < count; ++i)
|
for (int i = 0; i < cnt; ++i)
|
||||||
sids[i].debug_print (prefix);
|
sids[i].debug_print (prefix);
|
||||||
debug_printf ("-- ende sidlist ---");
|
debug_printf ("-- ende sidlist ---");
|
||||||
}
|
}
|
||||||
|
@ -256,9 +282,7 @@ extern cygpsid well_known_authenticated_users_sid;
|
||||||
extern cygpsid well_known_this_org_sid;
|
extern cygpsid well_known_this_org_sid;
|
||||||
extern cygpsid well_known_system_sid;
|
extern cygpsid well_known_system_sid;
|
||||||
extern cygpsid well_known_admins_sid;
|
extern cygpsid well_known_admins_sid;
|
||||||
extern cygpsid mandatory_medium_integrity_sid;
|
extern cygpsid fake_logon_sid;
|
||||||
extern cygpsid mandatory_high_integrity_sid;
|
|
||||||
extern cygpsid mandatory_system_integrity_sid;
|
|
||||||
|
|
||||||
/* Order must be same as cygpriv in sec_helper.cc. */
|
/* Order must be same as cygpriv in sec_helper.cc. */
|
||||||
enum cygpriv_idx {
|
enum cygpriv_idx {
|
||||||
|
@ -348,11 +372,15 @@ struct _UNICODE_STRING;
|
||||||
void __stdcall str2buf2uni (_UNICODE_STRING &, WCHAR *, const char *) __attribute__ ((regparm (3)));
|
void __stdcall str2buf2uni (_UNICODE_STRING &, WCHAR *, const char *) __attribute__ ((regparm (3)));
|
||||||
void __stdcall str2uni_cat (_UNICODE_STRING &, const char *) __attribute__ ((regparm (2)));
|
void __stdcall str2uni_cat (_UNICODE_STRING &, const char *) __attribute__ ((regparm (2)));
|
||||||
|
|
||||||
/* Try a subauthentication. */
|
/* Function creating a token by calling NtCreateToken. */
|
||||||
HANDLE subauth (struct passwd *pw);
|
|
||||||
/* Try creating a token directly. */
|
|
||||||
HANDLE create_token (cygsid &usersid, user_groups &groups, struct passwd * pw,
|
HANDLE create_token (cygsid &usersid, user_groups &groups, struct passwd * pw,
|
||||||
HANDLE subauth_token);
|
HANDLE subauth_token);
|
||||||
|
#if 0
|
||||||
|
/* Subauthentication function. */
|
||||||
|
HANDLE subauth (struct passwd *pw);
|
||||||
|
#endif
|
||||||
|
/* LSA authentication function. */
|
||||||
|
HANDLE lsaauth (cygsid &, user_groups &, struct passwd *);
|
||||||
/* Verify an existing token */
|
/* Verify an existing token */
|
||||||
bool verify_token (HANDLE token, cygsid &usersid, user_groups &groups, bool *pintern = NULL);
|
bool verify_token (HANDLE token, cygsid &usersid, user_groups &groups, bool *pintern = NULL);
|
||||||
/* Get groups of a user */
|
/* Get groups of a user */
|
||||||
|
|
|
@ -2111,30 +2111,46 @@ seteuid32 (__uid32_t uid)
|
||||||
debug_printf ("Found token %d", new_token);
|
debug_printf ("Found token %d", new_token);
|
||||||
|
|
||||||
/* If no impersonation token is available, try to
|
/* If no impersonation token is available, try to
|
||||||
authenticate using NtCreateToken () or subauthentication. */
|
authenticate using NtCreateToken () or LSA authentication. */
|
||||||
if (new_token == INVALID_HANDLE_VALUE)
|
if (new_token == INVALID_HANDLE_VALUE)
|
||||||
{
|
{
|
||||||
new_token = subauth (pw_new);
|
if (!(new_token = lsaauth (usersid, groups, pw_new)))
|
||||||
debug_printf ("subauth %s, try create_token.",
|
{
|
||||||
new_token == INVALID_HANDLE_VALUE ? "failed" : "succeeded");
|
#if 0
|
||||||
HANDLE new_token2 = create_token (usersid, groups, pw_new, new_token);
|
new_token = subauth (pw_new);
|
||||||
if (new_token2 == INVALID_HANDLE_VALUE)
|
debug_printf ("subauth %s, try create_token.",
|
||||||
{
|
new_token == INVALID_HANDLE_VALUE ? "failed" : "succeeded");
|
||||||
|
HANDLE new_token2 = create_token (usersid, groups, pw_new, new_token);
|
||||||
|
if (new_token2 == INVALID_HANDLE_VALUE)
|
||||||
|
{
|
||||||
|
if (new_token == INVALID_HANDLE_VALUE)
|
||||||
|
{
|
||||||
|
debug_printf ("create_token failed, bail out of here");
|
||||||
|
cygheap->user.reimpersonate ();
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
debug_printf ("create_token failed, use original subauth token");
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
debug_printf ("create_token succeeded");
|
||||||
|
if (new_token != INVALID_HANDLE_VALUE)
|
||||||
|
CloseHandle (new_token);
|
||||||
|
new_token = new_token2;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
debug_printf ("lsaauth failed, try create_token.");
|
||||||
|
new_token = create_token (usersid, groups, pw_new,
|
||||||
|
INVALID_HANDLE_VALUE);
|
||||||
if (new_token == INVALID_HANDLE_VALUE)
|
if (new_token == INVALID_HANDLE_VALUE)
|
||||||
{
|
{
|
||||||
debug_printf ("create_token failed, bail out of here");
|
debug_printf ("create_token failed, bail out of here");
|
||||||
cygheap->user.reimpersonate ();
|
cygheap->user.reimpersonate ();
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
debug_printf ("create_token failed, use original subauth token");
|
#endif
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
debug_printf ("create_token succeeded");
|
|
||||||
if (new_token != INVALID_HANDLE_VALUE)
|
|
||||||
CloseHandle (new_token);
|
|
||||||
new_token = new_token2;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Keep at most one internal token */
|
/* Keep at most one internal token */
|
||||||
if (cygheap->user.internal_token != NO_IMPERSONATION)
|
if (cygheap->user.internal_token != NO_IMPERSONATION)
|
||||||
CloseHandle (cygheap->user.internal_token);
|
CloseHandle (cygheap->user.internal_token);
|
||||||
|
|
|
@ -69,6 +69,7 @@ static NO_COPY wincaps wincap_unknown = {
|
||||||
has_exclusiveaddruse:false,
|
has_exclusiveaddruse:false,
|
||||||
has_buggy_restart_scan:false,
|
has_buggy_restart_scan:false,
|
||||||
has_mandatory_integrity_control:false,
|
has_mandatory_integrity_control:false,
|
||||||
|
needs_logon_sid_in_sid_list:false,
|
||||||
};
|
};
|
||||||
|
|
||||||
static NO_COPY wincaps wincap_95 = {
|
static NO_COPY wincaps wincap_95 = {
|
||||||
|
@ -129,6 +130,7 @@ static NO_COPY wincaps wincap_95 = {
|
||||||
has_exclusiveaddruse:false,
|
has_exclusiveaddruse:false,
|
||||||
has_buggy_restart_scan:false,
|
has_buggy_restart_scan:false,
|
||||||
has_mandatory_integrity_control:false,
|
has_mandatory_integrity_control:false,
|
||||||
|
needs_logon_sid_in_sid_list:false,
|
||||||
};
|
};
|
||||||
|
|
||||||
static NO_COPY wincaps wincap_95osr2 = {
|
static NO_COPY wincaps wincap_95osr2 = {
|
||||||
|
@ -189,6 +191,7 @@ static NO_COPY wincaps wincap_95osr2 = {
|
||||||
has_exclusiveaddruse:false,
|
has_exclusiveaddruse:false,
|
||||||
has_buggy_restart_scan:false,
|
has_buggy_restart_scan:false,
|
||||||
has_mandatory_integrity_control:false,
|
has_mandatory_integrity_control:false,
|
||||||
|
needs_logon_sid_in_sid_list:false,
|
||||||
};
|
};
|
||||||
|
|
||||||
static NO_COPY wincaps wincap_98 = {
|
static NO_COPY wincaps wincap_98 = {
|
||||||
|
@ -249,6 +252,7 @@ static NO_COPY wincaps wincap_98 = {
|
||||||
has_exclusiveaddruse:false,
|
has_exclusiveaddruse:false,
|
||||||
has_buggy_restart_scan:false,
|
has_buggy_restart_scan:false,
|
||||||
has_mandatory_integrity_control:false,
|
has_mandatory_integrity_control:false,
|
||||||
|
needs_logon_sid_in_sid_list:false,
|
||||||
};
|
};
|
||||||
|
|
||||||
static NO_COPY wincaps wincap_98se = {
|
static NO_COPY wincaps wincap_98se = {
|
||||||
|
@ -309,6 +313,7 @@ static NO_COPY wincaps wincap_98se = {
|
||||||
has_exclusiveaddruse:false,
|
has_exclusiveaddruse:false,
|
||||||
has_buggy_restart_scan:false,
|
has_buggy_restart_scan:false,
|
||||||
has_mandatory_integrity_control:false,
|
has_mandatory_integrity_control:false,
|
||||||
|
needs_logon_sid_in_sid_list:false,
|
||||||
};
|
};
|
||||||
|
|
||||||
static NO_COPY wincaps wincap_me = {
|
static NO_COPY wincaps wincap_me = {
|
||||||
|
@ -369,6 +374,7 @@ static NO_COPY wincaps wincap_me = {
|
||||||
has_exclusiveaddruse:false,
|
has_exclusiveaddruse:false,
|
||||||
has_buggy_restart_scan:false,
|
has_buggy_restart_scan:false,
|
||||||
has_mandatory_integrity_control:false,
|
has_mandatory_integrity_control:false,
|
||||||
|
needs_logon_sid_in_sid_list:false,
|
||||||
};
|
};
|
||||||
|
|
||||||
static NO_COPY wincaps wincap_nt3 = {
|
static NO_COPY wincaps wincap_nt3 = {
|
||||||
|
@ -429,6 +435,7 @@ static NO_COPY wincaps wincap_nt3 = {
|
||||||
has_exclusiveaddruse:false,
|
has_exclusiveaddruse:false,
|
||||||
has_buggy_restart_scan:false,
|
has_buggy_restart_scan:false,
|
||||||
has_mandatory_integrity_control:false,
|
has_mandatory_integrity_control:false,
|
||||||
|
needs_logon_sid_in_sid_list:true,
|
||||||
};
|
};
|
||||||
|
|
||||||
static NO_COPY wincaps wincap_nt4 = {
|
static NO_COPY wincaps wincap_nt4 = {
|
||||||
|
@ -489,6 +496,7 @@ static NO_COPY wincaps wincap_nt4 = {
|
||||||
has_exclusiveaddruse:false,
|
has_exclusiveaddruse:false,
|
||||||
has_buggy_restart_scan:false,
|
has_buggy_restart_scan:false,
|
||||||
has_mandatory_integrity_control:false,
|
has_mandatory_integrity_control:false,
|
||||||
|
needs_logon_sid_in_sid_list:true,
|
||||||
};
|
};
|
||||||
|
|
||||||
static NO_COPY wincaps wincap_nt4sp4 = {
|
static NO_COPY wincaps wincap_nt4sp4 = {
|
||||||
|
@ -549,6 +557,7 @@ static NO_COPY wincaps wincap_nt4sp4 = {
|
||||||
has_exclusiveaddruse:true,
|
has_exclusiveaddruse:true,
|
||||||
has_buggy_restart_scan:false,
|
has_buggy_restart_scan:false,
|
||||||
has_mandatory_integrity_control:false,
|
has_mandatory_integrity_control:false,
|
||||||
|
needs_logon_sid_in_sid_list:true,
|
||||||
};
|
};
|
||||||
|
|
||||||
static NO_COPY wincaps wincap_2000 = {
|
static NO_COPY wincaps wincap_2000 = {
|
||||||
|
@ -609,6 +618,7 @@ static NO_COPY wincaps wincap_2000 = {
|
||||||
has_exclusiveaddruse:true,
|
has_exclusiveaddruse:true,
|
||||||
has_buggy_restart_scan:true,
|
has_buggy_restart_scan:true,
|
||||||
has_mandatory_integrity_control:false,
|
has_mandatory_integrity_control:false,
|
||||||
|
needs_logon_sid_in_sid_list:true,
|
||||||
};
|
};
|
||||||
|
|
||||||
static NO_COPY wincaps wincap_xp = {
|
static NO_COPY wincaps wincap_xp = {
|
||||||
|
@ -669,6 +679,7 @@ static NO_COPY wincaps wincap_xp = {
|
||||||
has_exclusiveaddruse:true,
|
has_exclusiveaddruse:true,
|
||||||
has_buggy_restart_scan:false,
|
has_buggy_restart_scan:false,
|
||||||
has_mandatory_integrity_control:false,
|
has_mandatory_integrity_control:false,
|
||||||
|
needs_logon_sid_in_sid_list:false,
|
||||||
};
|
};
|
||||||
|
|
||||||
static NO_COPY wincaps wincap_2003 = {
|
static NO_COPY wincaps wincap_2003 = {
|
||||||
|
@ -729,6 +740,7 @@ static NO_COPY wincaps wincap_2003 = {
|
||||||
has_exclusiveaddruse:true,
|
has_exclusiveaddruse:true,
|
||||||
has_buggy_restart_scan:false,
|
has_buggy_restart_scan:false,
|
||||||
has_mandatory_integrity_control:false,
|
has_mandatory_integrity_control:false,
|
||||||
|
needs_logon_sid_in_sid_list:false,
|
||||||
};
|
};
|
||||||
|
|
||||||
static NO_COPY wincaps wincap_vista = {
|
static NO_COPY wincaps wincap_vista = {
|
||||||
|
@ -789,6 +801,7 @@ static NO_COPY wincaps wincap_vista = {
|
||||||
has_exclusiveaddruse:true,
|
has_exclusiveaddruse:true,
|
||||||
has_buggy_restart_scan:false,
|
has_buggy_restart_scan:false,
|
||||||
has_mandatory_integrity_control:true,
|
has_mandatory_integrity_control:true,
|
||||||
|
needs_logon_sid_in_sid_list:false,
|
||||||
};
|
};
|
||||||
|
|
||||||
wincapc wincap __attribute__((section (".cygwin_dll_common"), shared));
|
wincapc wincap __attribute__((section (".cygwin_dll_common"), shared));
|
||||||
|
|
|
@ -70,6 +70,7 @@ struct wincaps
|
||||||
unsigned has_exclusiveaddruse : 1;
|
unsigned has_exclusiveaddruse : 1;
|
||||||
unsigned has_buggy_restart_scan : 1;
|
unsigned has_buggy_restart_scan : 1;
|
||||||
unsigned has_mandatory_integrity_control : 1;
|
unsigned has_mandatory_integrity_control : 1;
|
||||||
|
unsigned needs_logon_sid_in_sid_list : 1;
|
||||||
};
|
};
|
||||||
|
|
||||||
class wincapc
|
class wincapc
|
||||||
|
@ -146,6 +147,7 @@ public:
|
||||||
bool IMPLEMENT (has_exclusiveaddruse)
|
bool IMPLEMENT (has_exclusiveaddruse)
|
||||||
bool IMPLEMENT (has_buggy_restart_scan)
|
bool IMPLEMENT (has_buggy_restart_scan)
|
||||||
bool IMPLEMENT (has_mandatory_integrity_control)
|
bool IMPLEMENT (has_mandatory_integrity_control)
|
||||||
|
bool IMPLEMENT (needs_logon_sid_in_sid_list)
|
||||||
|
|
||||||
#undef IMPLEMENT
|
#undef IMPLEMENT
|
||||||
};
|
};
|
||||||
|
|
Loading…
Reference in New Issue