⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 security.cc

📁 cygwin, 著名的在win32下模拟unix操作系统的东东
💻 CC
📖 第 1 页 / 共 4 页
字号:
/* security.cc: NT security functions   Copyright 1997, 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.   Originaly written by Gunther Ebert, gunther.ebert@ixos-leipzig.de   Completely rewritten by Corinna Vinschen <corinna@vinschen.de>This file is part of Cygwin.This software is a copyrighted work licensed under the terms of theCygwin license.  Please consult the file "CYGWIN_LICENSE" fordetails. */#include "winsup.h"#include <grp.h>#include <pwd.h>#include <unistd.h>#include <stdlib.h>#include <errno.h>#include <limits.h>#include <sys/types.h>#include <sys/stat.h>#include <sys/acl.h>#include <ctype.h>#include <winnls.h>#include <wingdi.h>#include <winuser.h>#include <wininet.h>#include <ntsecapi.h>#include <subauth.h>#include <aclapi.h>#include "cygerrno.h"#include "security.h"#include "fhandler.h"#include "path.h"#include "dtable.h"#include "pinfo.h"#include "cygheap.h"#include <ntdef.h>#include "ntdll.h"#include "lm.h"extern BOOL allow_ntea;BOOL allow_ntsec;/* allow_smbntsec is handled exclusively in path.cc (path_conv::check).   It's defined here because of it's strong relationship to allow_ntsec.   The default is TRUE to reflect the old behaviour. */BOOL allow_smbntsec;cygsid *cygsidlist::alloc_sids (int n){  if (n > 0)    return (cygsid *) cmalloc (HEAP_STR, n * sizeof (cygsid));  else    return NULL;}voidcygsidlist::free_sids (){  if (sids)    cfree (sids);  sids = NULL;  count = maxcount = 0;  type = cygsidlist_empty;}extern "C" voidcygwin_set_impersonation_token (const HANDLE hToken){  debug_printf ("set_impersonation_token (%d)", hToken);  if (cygheap->user.token != hToken)    {      cygheap->user.token = hToken;      cygheap->user.impersonated = FALSE;    }}voidextract_nt_dom_user (const struct passwd *pw, char *domain, char *user){  char *d, *u, *c;  domain[0] = 0;  strlcpy (user, pw->pw_name, UNLEN + 1);  debug_printf ("pw_gecos = %x (%s)", pw->pw_gecos, pw->pw_gecos);  if ((d = strstr (pw->pw_gecos, "U-")) != NULL &&      (d == pw->pw_gecos || d[-1] == ','))    {      c = strchr (d + 2, ',');      if ((u = strchr (d + 2, '\\')) == NULL || (c != NULL && u > c))	u = d + 1;      else if (u - d <= INTERNET_MAX_HOST_NAME_LENGTH + 2)	strlcpy (domain, d + 2, u - d - 1);      if (c == NULL)	c = u + UNLEN + 1;      if (c - u <= UNLEN + 1)	strlcpy (user, u + 1, c - u);    }  if (domain[0])    return;  cygsid psid;  DWORD ulen = UNLEN + 1;  DWORD dlen = INTERNET_MAX_HOST_NAME_LENGTH + 1;  SID_NAME_USE use;  if (psid.getfrompw (pw))    LookupAccountSid (NULL, psid, user, &ulen, domain, &dlen, &use);}extern "C" HANDLEcygwin_logon_user (const struct passwd *pw, const char *password){  if (!wincap.has_security ())    {      set_errno (ENOSYS);      return INVALID_HANDLE_VALUE;    }  if (!pw)    {      set_errno (EINVAL);      return INVALID_HANDLE_VALUE;    }  char nt_domain[INTERNET_MAX_HOST_NAME_LENGTH + 1];  char nt_user[UNLEN + 1];  HANDLE hToken;  extract_nt_dom_user (pw, nt_domain, nt_user);  debug_printf ("LogonUserA (%s, %s, %s, ...)", nt_user, nt_domain, password);  if (!LogonUserA (nt_user, *nt_domain ? nt_domain : NULL, (char *) password,		   LOGON32_LOGON_INTERACTIVE,		   LOGON32_PROVIDER_DEFAULT,		   &hToken)      || !SetHandleInformation (hToken,				HANDLE_FLAG_INHERIT,				HANDLE_FLAG_INHERIT))    {      __seterrno ();      return INVALID_HANDLE_VALUE;    }  debug_printf ("%d = logon_user(%s,...)", hToken, pw->pw_name);  return hToken;}static voidstr2lsa (LSA_STRING &tgt, const char *srcstr){  tgt.Length = strlen (srcstr);  tgt.MaximumLength = tgt.Length + 1;  tgt.Buffer = (PCHAR) srcstr;}static voidstr2buf2lsa (LSA_STRING &tgt, char *buf, const char *srcstr){  tgt.Length = strlen (srcstr);  tgt.MaximumLength = tgt.Length + 1;  tgt.Buffer = (PCHAR) buf;  memcpy (buf, srcstr, tgt.MaximumLength);}voidstr2buf2uni (UNICODE_STRING &tgt, WCHAR *buf, const char *srcstr){  tgt.Length = strlen (srcstr) * sizeof (WCHAR);  tgt.MaximumLength = tgt.Length + sizeof (WCHAR);  tgt.Buffer = (PWCHAR) buf;  sys_mbstowcs (buf, srcstr, tgt.MaximumLength);}#if 0				/* unused */static voidlsa2wchar (WCHAR *tgt, LSA_UNICODE_STRING &src, int size){  size = (size - 1) * sizeof (WCHAR);  if (src.Length < size)    size = src.Length;  memcpy (tgt, src.Buffer, size);  size >>= 1;  tgt[size] = 0;}#endifstatic voidlsa2str (char *tgt, LSA_UNICODE_STRING &src, int size){  if (src.Length / 2 < size)    size = src.Length / 2;  sys_wcstombs (tgt, src.Buffer, size);  tgt[size] = 0;}static LSA_HANDLEopen_local_policy (){  LSA_OBJECT_ATTRIBUTES oa = { 0, 0, 0, 0, 0, 0 };  LSA_HANDLE lsa = INVALID_HANDLE_VALUE;  NTSTATUS ret = LsaOpenPolicy (NULL, &oa, POLICY_EXECUTE, &lsa);  if (ret != STATUS_SUCCESS)    __seterrno_from_win_error (LsaNtStatusToWinError (ret));  return lsa;}static voidclose_local_policy (LSA_HANDLE &lsa){  if (lsa != INVALID_HANDLE_VALUE)    LsaClose (lsa);  lsa = INVALID_HANDLE_VALUE;}#if 0 /* unused */static BOOLget_lsa_srv_inf (LSA_HANDLE lsa, char *logonserver, char *domain){  NET_API_STATUS ret;  WCHAR *buf;  char name[INTERNET_MAX_HOST_NAME_LENGTH + 1];  WCHAR account[INTERNET_MAX_HOST_NAME_LENGTH + 1];  WCHAR primary[INTERNET_MAX_HOST_NAME_LENGTH + 1];  PPOLICY_ACCOUNT_DOMAIN_INFO adi;  PPOLICY_PRIMARY_DOMAIN_INFO pdi;  if ((ret = LsaQueryInformationPolicy (lsa, PolicyAccountDomainInformation,					(PVOID *) &adi)) != STATUS_SUCCESS)    {      __seterrno_from_win_error (LsaNtStatusToWinError (ret));      return FALSE;    }  lsa2wchar (account, adi->DomainName, INTERNET_MAX_HOST_NAME_LENGTH + 1);  LsaFreeMemory (adi);  if ((ret = LsaQueryInformationPolicy (lsa, PolicyPrimaryDomainInformation,					(PVOID *) &pdi)) != STATUS_SUCCESS)    {      __seterrno_from_win_error (LsaNtStatusToWinError (ret));      return FALSE;    }  lsa2wchar (primary, pdi->Name, INTERNET_MAX_HOST_NAME_LENGTH + 1);  LsaFreeMemory (pdi);  /* If the SID given in the primary domain info is NULL, the machine is     not member of a domain.  The name in the primary domain info is the     name of the workgroup then. */  if (pdi->Sid &&      (ret =       NetGetDCName (NULL, primary, (LPBYTE *) &buf)) == STATUS_SUCCESS)    {      sys_wcstombs (name, buf, INTERNET_MAX_HOST_NAME_LENGTH + 1);      strcpy (logonserver, name);      if (domain)	sys_wcstombs (domain, primary, INTERNET_MAX_HOST_NAME_LENGTH + 1);    }  else    {      sys_wcstombs (name, account, INTERNET_MAX_HOST_NAME_LENGTH + 1);      strcpy (logonserver, "\\\\");      strcat (logonserver, name);      if (domain)	sys_wcstombs (domain, account, INTERNET_MAX_HOST_NAME_LENGTH + 1);    }  if (ret == STATUS_SUCCESS)    NetApiBufferFree (buf);  return TRUE;}#endifBOOLget_logon_server (const char *domain, char *server, WCHAR *wserver){  WCHAR wdomain[INTERNET_MAX_HOST_NAME_LENGTH + 1];  NET_API_STATUS ret;  WCHAR *buf;  DWORD size = INTERNET_MAX_HOST_NAME_LENGTH + 1;  /* Empty domain is interpreted as local system */  if ((GetComputerName (server + 2, &size)) &&      (strcasematch (domain, server + 2) || !domain[0]))    {      server[0] = server[1] = '\\';      if (wserver)	sys_mbstowcs (wserver, server, INTERNET_MAX_HOST_NAME_LENGTH + 1);      return TRUE;    }  /* Try to get the primary domain controller for the domain */  sys_mbstowcs (wdomain, domain, INTERNET_MAX_HOST_NAME_LENGTH + 1);  if ((ret = NetGetDCName (NULL, wdomain, (LPBYTE *) &buf)) == STATUS_SUCCESS)    {      sys_wcstombs (server, buf, INTERNET_MAX_HOST_NAME_LENGTH + 1);      if (wserver)	for (WCHAR *ptr1 = buf; (*wserver++ = *ptr1++);)	  ;      NetApiBufferFree (buf);      return TRUE;    }  __seterrno_from_win_error (ret);  return FALSE;}static BOOLget_user_groups (WCHAR *wlogonserver, cygsidlist &grp_list, char *user,		 char *domain){  char dgroup[INTERNET_MAX_HOST_NAME_LENGTH + GNLEN + 2];  WCHAR wuser[UNLEN + 1];  sys_mbstowcs (wuser, user, UNLEN + 1);  LPGROUP_USERS_INFO_0 buf;  DWORD cnt, tot, len;  NET_API_STATUS ret;  /* Look only on logonserver */  ret = NetUserGetGroups (wlogonserver, wuser, 0, (LPBYTE *) &buf,			  MAX_PREFERRED_LENGTH, &cnt, &tot);  if (ret)    {      __seterrno_from_win_error (ret);      /* It's no error when the user name can't be found. */      return ret == NERR_UserNotFound;    }  len = strlen (domain);  strcpy (dgroup, domain);  dgroup[len++] = '\\';  for (DWORD i = 0; i < cnt; ++i)    {      cygsid gsid;      DWORD glen = sizeof (gsid);      char domain[INTERNET_MAX_HOST_NAME_LENGTH + 1];      DWORD dlen = sizeof (domain);      SID_NAME_USE use = SidTypeInvalid;      sys_wcstombs (dgroup + len, buf[i].grui0_name, GNLEN + 1);      if (!LookupAccountName (NULL, dgroup, gsid, &glen, domain, &dlen, &use))	debug_printf ("LookupAccountName(%s): %E", dgroup);      else if (legal_sid_type (use))	grp_list += gsid;      else	debug_printf ("Global group %s invalid. Domain: %s Use: %d",		      dgroup, domain, use);    }  NetApiBufferFree (buf);  return TRUE;}static BOOLis_group_member (WCHAR *wgroup, PSID pusersid, cygsidlist &grp_list){  LPLOCALGROUP_MEMBERS_INFO_0 buf;  DWORD cnt, tot;  NET_API_STATUS ret;  BOOL retval = FALSE;  /* Members can be users or global groups */  ret = NetLocalGroupGetMembers (NULL, wgroup, 0, (LPBYTE *) &buf,				 MAX_PREFERRED_LENGTH, &cnt, &tot, NULL);  if (ret)    return FALSE;  for (DWORD bidx = 0; !retval && bidx < cnt; ++bidx)    if (EqualSid (pusersid, buf[bidx].lgrmi0_sid))      retval = TRUE;    else      for (int glidx = 0; !retval && glidx < grp_list.count; ++glidx)	if (EqualSid (grp_list.sids[glidx], buf[bidx].lgrmi0_sid))	  retval = TRUE;  NetApiBufferFree (buf);  return retval;}static BOOLget_user_local_groups (cygsidlist &grp_list, PSID pusersid){  LPLOCALGROUP_INFO_0 buf;  DWORD cnt, tot;  NET_API_STATUS ret;  ret = NetLocalGroupEnum (NULL, 0, (LPBYTE *) &buf,			   MAX_PREFERRED_LENGTH, &cnt, &tot, NULL);  if (ret)    {      __seterrno_from_win_error (ret);      return FALSE;    }  char bgroup[sizeof ("BUILTIN\\") + GNLEN] = "BUILTIN\\";  char lgroup[INTERNET_MAX_HOST_NAME_LENGTH + GNLEN + 2];  const DWORD blen = sizeof ("BUILTIN\\") - 1;  DWORD llen = INTERNET_MAX_HOST_NAME_LENGTH + 1;  if (!GetComputerNameA (lgroup, &llen))    {      __seterrno ();      return FALSE;    }  lgroup[llen++] = '\\';  for (DWORD i = 0; i < cnt; ++i)    if (is_group_member (buf[i].lgrpi0_name, pusersid, grp_list))      {	cygsid gsid;	DWORD glen = sizeof (gsid);	char domain[INTERNET_MAX_HOST_NAME_LENGTH + 1];	DWORD dlen = sizeof (domain);	SID_NAME_USE use = SidTypeInvalid;	sys_wcstombs (bgroup + blen, buf[i].lgrpi0_name, GNLEN + 1);	if (!LookupAccountName (NULL, bgroup, gsid, &glen, domain, &dlen, &use))	  {	    if (GetLastError () != ERROR_NONE_MAPPED)	      debug_printf ("LookupAccountName(%s): %E", bgroup);	    strcpy (lgroup + llen, bgroup + blen);	    if (!LookupAccountName (NULL, lgroup, gsid, &glen,				    domain, &dlen, &use))	      debug_printf ("LookupAccountName(%s): %E", lgroup);	  }	if (!legal_sid_type (use))	  debug_printf ("Rejecting local %s. use: %d", bgroup + blen, use);	else if (!grp_list.contains (gsid))	  grp_list += gsid;      }  NetApiBufferFree (buf);  return TRUE;}static BOOLsid_in_token_groups (PTOKEN_GROUPS grps, cygsid &sid){  if (!grps)    return FALSE;  for (DWORD i = 0; i < grps->GroupCount; ++i)    if (sid == grps->Groups[i].Sid)      return TRUE;  return FALSE;}#if 0				/* Unused */static BOOLget_user_primary_group (WCHAR *wlogonserver, const char *user,			PSID pusersid, cygsid &pgrpsid){  LPUSER_INFO_3 buf;  WCHAR wuser[UNLEN + 1];  NET_API_STATUS ret;  BOOL retval = FALSE;  UCHAR count = 0;  if (well_known_system_sid == pusersid)    {      pgrpsid = well_known_system_sid;      return TRUE;    }  sys_mbstowcs (wuser, user, UNLEN + 1);  ret = NetUserGetInfo (wlogonserver, wuser, 3, (LPBYTE *) &buf);  if (ret)    {      __seterrno_from_win_error (ret);      return FALSE;    }  pgrpsid = pusersid;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -