* autoload.cc (LsaLookupSids): Import.
* cygserver_pwdgrp.h: Include userinfo.h. Drop workaround defining fetch_user_arg_type_t locally. * grp.cc (internal_getgrsid_cachedonly): New function. (internal_getgrfull): Ditto. (internal_getgroups): Rearrange function. Center around fetching all cached group info first, calling LsaLookupSids on all so far non-cached groups second. Pass all available info to new internal_getgrfull call. * pwdgrp.h: Include userinfo.h. Move definitions of fetch_user_arg_type_t and fetch_user_arg_t there. (pwdgrp::add_group_from_windows): Declare with getting full group info. Called from internal_getgrfull. * uinfo.cc (pwdgrp::add_group_from_windows): Define. (pwdgrp::fetch_account_from_line): Add default case. (pwdgrp::fetch_account_from_file): Ditto. (pwdgrp::fetch_account_from_windows): Handle FULL_grp_arg. (client_request_pwdgrp::client_request_pwdgrp): Add default case. * userinfo.h: New header. (enum fetch_user_arg_type_t): Add FULL_grp_arg. (struct fetch_full_grp_t): New datatype.
This commit is contained in:
parent
9b54770bd7
commit
bef55bb5c3
@ -1,3 +1,26 @@
|
|||||||
|
2015-02-23 Corinna Vinschen <corinna@vinschen.de>
|
||||||
|
|
||||||
|
* autoload.cc (LsaLookupSids): Import.
|
||||||
|
* cygserver_pwdgrp.h: Include userinfo.h. Drop workaround defining
|
||||||
|
fetch_user_arg_type_t locally.
|
||||||
|
* grp.cc (internal_getgrsid_cachedonly): New function.
|
||||||
|
(internal_getgrfull): Ditto.
|
||||||
|
(internal_getgroups): Rearrange function. Center around fetching all
|
||||||
|
cached group info first, calling LsaLookupSids on all so far non-cached
|
||||||
|
groups second. Pass all available info to new internal_getgrfull call.
|
||||||
|
* pwdgrp.h: Include userinfo.h. Move definitions of
|
||||||
|
fetch_user_arg_type_t and fetch_user_arg_t there.
|
||||||
|
(pwdgrp::add_group_from_windows): Declare with getting full group info.
|
||||||
|
Called from internal_getgrfull.
|
||||||
|
* uinfo.cc (pwdgrp::add_group_from_windows): Define.
|
||||||
|
(pwdgrp::fetch_account_from_line): Add default case.
|
||||||
|
(pwdgrp::fetch_account_from_file): Ditto.
|
||||||
|
(pwdgrp::fetch_account_from_windows): Handle FULL_grp_arg.
|
||||||
|
(client_request_pwdgrp::client_request_pwdgrp): Add default case.
|
||||||
|
* userinfo.h: New header.
|
||||||
|
(enum fetch_user_arg_type_t): Add FULL_grp_arg.
|
||||||
|
(struct fetch_full_grp_t): New datatype.
|
||||||
|
|
||||||
2015-02-23 Corinna Vinschen <corinna@vinschen.de>
|
2015-02-23 Corinna Vinschen <corinna@vinschen.de>
|
||||||
|
|
||||||
* grp.cc (internal_getgroups): Check for group attributes and
|
* grp.cc (internal_getgroups): Check for group attributes and
|
||||||
|
@ -545,6 +545,7 @@ LoadDLLfunc (LookupAccountSidW, 28, advapi32)
|
|||||||
LoadDLLfunc (LsaClose, 4, advapi32)
|
LoadDLLfunc (LsaClose, 4, advapi32)
|
||||||
LoadDLLfunc (LsaEnumerateAccountRights, 16, advapi32)
|
LoadDLLfunc (LsaEnumerateAccountRights, 16, advapi32)
|
||||||
LoadDLLfunc (LsaFreeMemory, 4, advapi32)
|
LoadDLLfunc (LsaFreeMemory, 4, advapi32)
|
||||||
|
LoadDLLfunc (LsaLookupSids, 20, advapi32)
|
||||||
LoadDLLfunc (LsaOpenPolicy, 16, advapi32)
|
LoadDLLfunc (LsaOpenPolicy, 16, advapi32)
|
||||||
LoadDLLfunc (LsaQueryInformationPolicy, 12, advapi32)
|
LoadDLLfunc (LsaQueryInformationPolicy, 12, advapi32)
|
||||||
LoadDLLfunc (LsaRetrievePrivateData, 12, advapi32)
|
LoadDLLfunc (LsaRetrievePrivateData, 12, advapi32)
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
/* cygserver_pwdgrp.h: Request account information
|
/* cygserver_pwdgrp.h: Request account information
|
||||||
|
|
||||||
Copyright 2014 Red Hat, Inc.
|
Copyright 2014, 2015 Red Hat, Inc.
|
||||||
|
|
||||||
This file is part of Cygwin.
|
This file is part of Cygwin.
|
||||||
|
|
||||||
@ -13,21 +13,11 @@ details. */
|
|||||||
|
|
||||||
#include <sys/types.h>
|
#include <sys/types.h>
|
||||||
#include "cygserver.h"
|
#include "cygserver.h"
|
||||||
|
#include "userinfo.h"
|
||||||
|
|
||||||
class transport_layer_base;
|
class transport_layer_base;
|
||||||
class process_cache;
|
class process_cache;
|
||||||
|
|
||||||
#ifdef __INSIDE_CYGWIN__
|
|
||||||
#include "pwdgrp.h"
|
|
||||||
#else
|
|
||||||
/* Don't include pwdgrp.h, but keep this in sync. */
|
|
||||||
enum fetch_user_arg_type_t {
|
|
||||||
SID_arg,
|
|
||||||
NAME_arg,
|
|
||||||
ID_arg
|
|
||||||
};
|
|
||||||
#endif
|
|
||||||
|
|
||||||
class client_request_pwdgrp : public client_request
|
class client_request_pwdgrp : public client_request
|
||||||
{
|
{
|
||||||
friend class client_request;
|
friend class client_request;
|
||||||
|
@ -14,6 +14,7 @@ details. */
|
|||||||
|
|
||||||
#include "winsup.h"
|
#include "winsup.h"
|
||||||
#include <lm.h>
|
#include <lm.h>
|
||||||
|
#include <ntsecapi.h>
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
@ -117,6 +118,65 @@ internal_getgrsid (cygpsid &sid, cyg_ldap *pldap)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Like internal_getgrsid but return only already cached data,
|
||||||
|
NULL otherwise. */
|
||||||
|
static struct group *
|
||||||
|
internal_getgrsid_cachedonly (cygpsid &sid)
|
||||||
|
{
|
||||||
|
struct group *ret;
|
||||||
|
|
||||||
|
/* Check caches only. */
|
||||||
|
if (cygheap->pg.nss_cygserver_caching ()
|
||||||
|
&& (ret = cygheap->pg.grp_cache.cygserver.find_group (sid)))
|
||||||
|
return ret;
|
||||||
|
if (cygheap->pg.nss_grp_files ()
|
||||||
|
&& (ret = cygheap->pg.grp_cache.file.find_group (sid)))
|
||||||
|
return ret;
|
||||||
|
if (cygheap->pg.nss_grp_db ()
|
||||||
|
&& (ret = cygheap->pg.grp_cache.win.find_group (sid)))
|
||||||
|
return ret;
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Called from internal_getgroups. The full information required to create
|
||||||
|
a group account entry is already available from the LookupAccountSids
|
||||||
|
call. internal_getgrfull passes all available info into
|
||||||
|
pwdgrp::fetch_account_from_line, thus avoiding a LookupAccountSid call
|
||||||
|
for each group. This is quite a bit faster, especially in slower
|
||||||
|
environments. */
|
||||||
|
static struct group * __attribute__((used))
|
||||||
|
internal_getgrfull (fetch_full_grp_t &full_grp, cyg_ldap *pldap)
|
||||||
|
{
|
||||||
|
struct group *ret;
|
||||||
|
|
||||||
|
cygheap->pg.nss_init ();
|
||||||
|
/* Check caches first. */
|
||||||
|
if (cygheap->pg.nss_cygserver_caching ()
|
||||||
|
&& (ret = cygheap->pg.grp_cache.cygserver.find_group (full_grp.sid)))
|
||||||
|
return ret;
|
||||||
|
if (cygheap->pg.nss_grp_files ()
|
||||||
|
&& (ret = cygheap->pg.grp_cache.file.find_group (full_grp.sid)))
|
||||||
|
return ret;
|
||||||
|
if (cygheap->pg.nss_grp_db ()
|
||||||
|
&& (ret = cygheap->pg.grp_cache.win.find_group (full_grp.sid)))
|
||||||
|
return ret;
|
||||||
|
/* Ask sources afterwards. */
|
||||||
|
if (cygheap->pg.nss_cygserver_caching ()
|
||||||
|
&& (ret = cygheap->pg.grp_cache.cygserver.add_group_from_cygserver
|
||||||
|
(full_grp.sid)))
|
||||||
|
return ret;
|
||||||
|
if (cygheap->pg.nss_grp_files ())
|
||||||
|
{
|
||||||
|
cygheap->pg.grp_cache.file.check_file ();
|
||||||
|
if ((ret = cygheap->pg.grp_cache.file.add_group_from_file
|
||||||
|
(full_grp.sid)))
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
if (cygheap->pg.nss_grp_db ())
|
||||||
|
return cygheap->pg.grp_cache.win.add_group_from_windows (full_grp, pldap);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
/* This function gets only called from mkgroup via cygwin_internal. */
|
/* This function gets only called from mkgroup via cygwin_internal. */
|
||||||
struct group *
|
struct group *
|
||||||
internal_getgrsid_from_db (cygpsid &sid)
|
internal_getgrsid_from_db (cygpsid &sid)
|
||||||
@ -502,8 +562,15 @@ internal_getgroups (int gidsetsize, gid_t *grouplist, cyg_ldap *pldap,
|
|||||||
NTSTATUS status;
|
NTSTATUS status;
|
||||||
HANDLE tok;
|
HANDLE tok;
|
||||||
ULONG size;
|
ULONG size;
|
||||||
int cnt = 0;
|
PTOKEN_GROUPS groups;
|
||||||
|
PSID *sidp_buf;
|
||||||
|
ULONG scnt;
|
||||||
|
PLSA_REFERENCED_DOMAIN_LIST dlst = NULL;
|
||||||
|
PLSA_TRANSLATED_NAME nlst = NULL;
|
||||||
|
|
||||||
|
tmp_pathbuf tp;
|
||||||
struct group *grp;
|
struct group *grp;
|
||||||
|
int cnt = 0;
|
||||||
|
|
||||||
if (cygheap->user.groups.issetgroups ())
|
if (cygheap->user.groups.issetgroups ())
|
||||||
{
|
{
|
||||||
@ -515,26 +582,32 @@ internal_getgroups (int gidsetsize, gid_t *grouplist, cyg_ldap *pldap,
|
|||||||
grouplist[cnt] = grp->gr_gid;
|
grouplist[cnt] = grp->gr_gid;
|
||||||
++cnt;
|
++cnt;
|
||||||
if (gidsetsize && cnt > gidsetsize)
|
if (gidsetsize && cnt > gidsetsize)
|
||||||
goto error;
|
{
|
||||||
|
cnt = -1;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
return cnt;
|
}
|
||||||
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* If impersonated, use impersonation token. */
|
/* If impersonated, use impersonation token. */
|
||||||
tok = cygheap->user.issetuid () ? cygheap->user.primary_token () : hProcToken;
|
tok = cygheap->user.issetuid () ? cygheap->user.primary_token ()
|
||||||
|
: hProcToken;
|
||||||
|
|
||||||
status = NtQueryInformationToken (tok, TokenGroups, NULL, 0, &size);
|
/* Fetch groups from user token. */
|
||||||
if (NT_SUCCESS (status) || status == STATUS_BUFFER_TOO_SMALL)
|
groups = (PTOKEN_GROUPS) tp.w_get ();
|
||||||
|
status = NtQueryInformationToken (tok, TokenGroups, groups, 2 * NT_MAX_PATH,
|
||||||
|
&size);
|
||||||
|
if (!NT_SUCCESS (status))
|
||||||
{
|
{
|
||||||
PTOKEN_GROUPS groups = (PTOKEN_GROUPS) alloca (size);
|
system_printf ("token group list > 64K? status = %u", status);
|
||||||
|
goto out;
|
||||||
status = NtQueryInformationToken (tok, TokenGroups, groups, size, &size);
|
}
|
||||||
if (NT_SUCCESS (status))
|
/* Iterate over the group list and check which of them are already cached.
|
||||||
{
|
Those are simply copied to grouplist. The non-cached ones are collected
|
||||||
ULONGLONG t0;
|
in sidp_buf for a later call to LsaLookupSids. */
|
||||||
|
sidp_buf = (PSID *) tp.w_get ();
|
||||||
if (timeout_ns)
|
scnt = 0;
|
||||||
t0 = GetTickCount_ns ();
|
|
||||||
for (DWORD pg = 0; pg < groups->GroupCount; ++pg)
|
for (DWORD pg = 0; pg < groups->GroupCount; ++pg)
|
||||||
{
|
{
|
||||||
cygpsid sid = groups->Groups[pg].Sid;
|
cygpsid sid = groups->Groups[pg].Sid;
|
||||||
@ -542,26 +615,68 @@ internal_getgroups (int gidsetsize, gid_t *grouplist, cyg_ldap *pldap,
|
|||||||
& (SE_GROUP_ENABLED | SE_GROUP_INTEGRITY_ENABLED)) == 0
|
& (SE_GROUP_ENABLED | SE_GROUP_INTEGRITY_ENABLED)) == 0
|
||||||
|| sid == well_known_world_sid)
|
|| sid == well_known_world_sid)
|
||||||
continue;
|
continue;
|
||||||
if ((grp = internal_getgrsid (sid, pldap)))
|
if ((grp = internal_getgrsid_cachedonly (sid)))
|
||||||
{
|
{
|
||||||
if (cnt < gidsetsize)
|
if (cnt < gidsetsize)
|
||||||
grouplist[cnt] = grp->gr_gid;
|
grouplist[cnt] = grp->gr_gid;
|
||||||
++cnt;
|
++cnt;
|
||||||
if (gidsetsize && cnt > gidsetsize)
|
if (gidsetsize && cnt > gidsetsize)
|
||||||
goto error;
|
{
|
||||||
}
|
cnt = -1;
|
||||||
if (timeout_ns && GetTickCount_ns () - t0 >= timeout_ns)
|
goto out;
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
debug_printf ("%u = NtQueryInformationToken(NULL) %y", size, status);
|
sidp_buf[scnt++] = sid;
|
||||||
return cnt;
|
}
|
||||||
|
/* If there are non-cached groups left, call LsaLookupSids and call
|
||||||
|
internal_getgrfull on the returned groups. This performs a lot
|
||||||
|
better than calling internal_getgrsid on each group. */
|
||||||
|
if (scnt > 0)
|
||||||
|
{
|
||||||
|
status = STATUS_ACCESS_DENIED;
|
||||||
|
HANDLE lsa = lsa_open_policy (NULL, POLICY_LOOKUP_NAMES);
|
||||||
|
if (!lsa)
|
||||||
|
{
|
||||||
|
system_printf ("POLICY_LOOKUP_NAMES not given?");
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
status = LsaLookupSids (lsa, scnt, sidp_buf, &dlst, &nlst);
|
||||||
|
lsa_close_policy (lsa);
|
||||||
|
if (NT_SUCCESS (status))
|
||||||
|
{
|
||||||
|
for (ULONG ncnt = 0; ncnt < scnt; ++ncnt)
|
||||||
|
{
|
||||||
|
fetch_full_grp_t full_grp =
|
||||||
|
{
|
||||||
|
.sid = sidp_buf[ncnt],
|
||||||
|
.name = &nlst[ncnt].Name,
|
||||||
|
.dom = &dlst->Domains[nlst[ncnt].DomainIndex].Name,
|
||||||
|
.acc_type = nlst[ncnt].Use
|
||||||
|
};
|
||||||
|
if ((grp = internal_getgrfull (full_grp, pldap)))
|
||||||
|
{
|
||||||
|
if (cnt < gidsetsize)
|
||||||
|
grouplist[cnt] = grp->gr_gid;
|
||||||
|
++cnt;
|
||||||
|
if (gidsetsize && cnt > gidsetsize)
|
||||||
|
{
|
||||||
|
cnt = -1;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
error:
|
out:
|
||||||
|
if (dlst)
|
||||||
|
LsaFreeMemory (dlst);
|
||||||
|
if (nlst)
|
||||||
|
LsaFreeMemory (nlst);
|
||||||
|
if (cnt == -1)
|
||||||
set_errno (EINVAL);
|
set_errno (EINVAL);
|
||||||
return -1;
|
return cnt;
|
||||||
}
|
}
|
||||||
|
|
||||||
extern "C" int
|
extern "C" int
|
||||||
|
@ -15,6 +15,7 @@ details. */
|
|||||||
#include "sync.h"
|
#include "sync.h"
|
||||||
#include "ldap.h"
|
#include "ldap.h"
|
||||||
#include "miscfuncs.h"
|
#include "miscfuncs.h"
|
||||||
|
#include "userinfo.h"
|
||||||
|
|
||||||
/* These functions are needed to allow searching and walking through
|
/* These functions are needed to allow searching and walking through
|
||||||
the passwd and group lists */
|
the passwd and group lists */
|
||||||
@ -37,24 +38,6 @@ void *setgrent_filtered (int enums, PCWSTR enum_tdoms);
|
|||||||
void *getgrent_filtered (void *gr);
|
void *getgrent_filtered (void *gr);
|
||||||
void endgrent_filtered (void *gr);
|
void endgrent_filtered (void *gr);
|
||||||
|
|
||||||
enum fetch_user_arg_type_t {
|
|
||||||
SID_arg,
|
|
||||||
NAME_arg,
|
|
||||||
ID_arg
|
|
||||||
};
|
|
||||||
|
|
||||||
struct fetch_user_arg_t
|
|
||||||
{
|
|
||||||
fetch_user_arg_type_t type;
|
|
||||||
union {
|
|
||||||
cygpsid *sid;
|
|
||||||
const char *name;
|
|
||||||
uint32_t id;
|
|
||||||
};
|
|
||||||
/* Only used in fetch_account_from_file/line. */
|
|
||||||
size_t len;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct pg_pwd
|
struct pg_pwd
|
||||||
{
|
{
|
||||||
struct passwd p;
|
struct passwd p;
|
||||||
@ -176,6 +159,8 @@ public:
|
|||||||
{ return (struct group *) add_account_from_windows (name, pldap); }
|
{ return (struct group *) add_account_from_windows (name, pldap); }
|
||||||
struct group *add_group_from_windows (uint32_t id, cyg_ldap *pldap = NULL)
|
struct group *add_group_from_windows (uint32_t id, cyg_ldap *pldap = NULL)
|
||||||
{ return (struct group *) add_account_from_windows (id, pldap); }
|
{ return (struct group *) add_account_from_windows (id, pldap); }
|
||||||
|
struct group *add_group_from_windows (fetch_full_grp_t &full_grp,
|
||||||
|
cyg_ldap *pldap = NULL);
|
||||||
struct group *find_group (cygpsid &sid);
|
struct group *find_group (cygpsid &sid);
|
||||||
struct group *find_group (const char *name);
|
struct group *find_group (const char *name);
|
||||||
struct group *find_group (gid_t gid);
|
struct group *find_group (gid_t gid);
|
||||||
|
@ -1545,6 +1545,19 @@ pwdgrp::add_account_from_windows (uint32_t id, cyg_ldap *pldap)
|
|||||||
return add_account_post_fetch (line, true);
|
return add_account_post_fetch (line, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Called from internal_getgrfull, in turn called from internal_getgroups. */
|
||||||
|
struct group *
|
||||||
|
pwdgrp::add_group_from_windows (fetch_full_grp_t &full_grp, cyg_ldap *pldap)
|
||||||
|
{
|
||||||
|
fetch_user_arg_t arg;
|
||||||
|
arg.type = FULL_grp_arg;
|
||||||
|
arg.full_grp = &full_grp;
|
||||||
|
char *line = fetch_account_from_windows (arg, pldap);
|
||||||
|
if (!line)
|
||||||
|
return NULL;
|
||||||
|
return (struct group *) add_account_post_fetch (line, true);
|
||||||
|
}
|
||||||
|
|
||||||
/* Check if file exists and if it has been written to since last checked.
|
/* Check if file exists and if it has been written to since last checked.
|
||||||
If file has been changed, invalidate the current cache.
|
If file has been changed, invalidate the current cache.
|
||||||
|
|
||||||
@ -1627,6 +1640,8 @@ pwdgrp::fetch_account_from_line (fetch_user_arg_t &arg, const char *line)
|
|||||||
if (strtoul (p + 1, &e, 10) != arg.id || !e || *e != ':')
|
if (strtoul (p + 1, &e, 10) != arg.id || !e || *e != ':')
|
||||||
return NULL;
|
return NULL;
|
||||||
break;
|
break;
|
||||||
|
default:
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
return cstrdup (line);
|
return cstrdup (line);
|
||||||
}
|
}
|
||||||
@ -1653,6 +1668,8 @@ pwdgrp::fetch_account_from_file (fetch_user_arg_t &arg)
|
|||||||
break;
|
break;
|
||||||
case ID_arg:
|
case ID_arg:
|
||||||
break;
|
break;
|
||||||
|
default:
|
||||||
|
return NULL;
|
||||||
}
|
}
|
||||||
if (rl.init (&attr, buf, NT_MAX_PATH))
|
if (rl.init (&attr, buf, NT_MAX_PATH))
|
||||||
while ((buf = rl.gets ()))
|
while ((buf = rl.gets ()))
|
||||||
@ -1742,6 +1759,17 @@ pwdgrp::fetch_account_from_windows (fetch_user_arg_t &arg, cyg_ldap *pldap)
|
|||||||
|
|
||||||
switch (arg.type)
|
switch (arg.type)
|
||||||
{
|
{
|
||||||
|
case FULL_grp_arg:
|
||||||
|
{
|
||||||
|
sid = arg.full_grp->sid;
|
||||||
|
*wcpncpy (name, arg.full_grp->name->Buffer,
|
||||||
|
arg.full_grp->name->Length / sizeof (WCHAR)) = L'\0';
|
||||||
|
*wcpncpy (dom, arg.full_grp->dom->Buffer,
|
||||||
|
arg.full_grp->dom->Length / sizeof (WCHAR)) = L'\0';
|
||||||
|
acc_type = arg.full_grp->acc_type;
|
||||||
|
ret = acc_type != SidTypeUnknown;
|
||||||
|
}
|
||||||
|
break;
|
||||||
case SID_arg:
|
case SID_arg:
|
||||||
sid = *arg.sid;
|
sid = *arg.sid;
|
||||||
ret = LookupAccountSidW (NULL, sid, name, &nlen, dom, &dlen, &acc_type);
|
ret = LookupAccountSidW (NULL, sid, name, &nlen, dom, &dlen, &acc_type);
|
||||||
@ -2489,6 +2517,9 @@ client_request_pwdgrp::client_request_pwdgrp (fetch_user_arg_t &arg, bool group)
|
|||||||
case ID_arg:
|
case ID_arg:
|
||||||
_parameters.in.arg.id = arg.id;
|
_parameters.in.arg.id = arg.id;
|
||||||
len = sizeof (uint32_t);
|
len = sizeof (uint32_t);
|
||||||
|
default:
|
||||||
|
api_fatal ("Fetching account info from cygserver with wrong arg.type "
|
||||||
|
"%d", arg.type);
|
||||||
}
|
}
|
||||||
msglen (__builtin_offsetof (struct _pwdgrp_param_t::_pwdgrp_in_t, arg) + len);
|
msglen (__builtin_offsetof (struct _pwdgrp_param_t::_pwdgrp_in_t, arg) + len);
|
||||||
}
|
}
|
||||||
|
38
winsup/cygwin/userinfo.h
Normal file
38
winsup/cygwin/userinfo.h
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
/* userinfo.h
|
||||||
|
|
||||||
|
Copyright 2015 Red Hat inc.
|
||||||
|
|
||||||
|
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. */
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
enum fetch_user_arg_type_t {
|
||||||
|
SID_arg,
|
||||||
|
NAME_arg,
|
||||||
|
ID_arg,
|
||||||
|
FULL_grp_arg,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct fetch_full_grp_t {
|
||||||
|
cygpsid sid;
|
||||||
|
PUNICODE_STRING name;
|
||||||
|
PUNICODE_STRING dom;
|
||||||
|
SID_NAME_USE acc_type;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct fetch_user_arg_t
|
||||||
|
{
|
||||||
|
fetch_user_arg_type_t type;
|
||||||
|
union {
|
||||||
|
cygpsid *sid;
|
||||||
|
const char *name;
|
||||||
|
uint32_t id;
|
||||||
|
fetch_full_grp_t *full_grp;
|
||||||
|
};
|
||||||
|
/* Only used in fetch_account_from_file/line. */
|
||||||
|
size_t len;
|
||||||
|
};
|
Loading…
x
Reference in New Issue
Block a user