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

📄 security.cc

📁 cygwin, 著名的在win32下模拟unix操作系统的东东
💻 CC
📖 第 1 页 / 共 4 页
字号:
  if (IsValidSid (pgrpsid)      && (count = *GetSidSubAuthorityCount (pgrpsid)) > 1)    {      *GetSidSubAuthority (pgrpsid, count - 1) = buf->usri3_primary_group_id;      retval = TRUE;    }  NetApiBufferFree (buf);  return retval;}#endifstatic voidget_unix_group_sidlist (struct passwd *pw, cygsidlist &grp_list){  struct __group32 *gr;  cygsid gsid;  for (int gidx = 0; (gr = internal_getgrent (gidx)); ++gidx)    {      if (gr->gr_gid == (__gid32_t) pw->pw_gid)	goto found;      else if (gr->gr_mem)	for (int gi = 0; gr->gr_mem[gi]; ++gi)	  if (strcasematch (pw->pw_name, gr->gr_mem[gi]))	    goto found;      continue;    found:      if (gsid.getfromgr (gr) && !grp_list.contains (gsid))	grp_list += gsid;    }}static voidget_token_group_sidlist (cygsidlist &grp_list, PTOKEN_GROUPS my_grps,			 LUID auth_luid, int &auth_pos){  auth_pos = -1;  if (my_grps)    {      if (sid_in_token_groups (my_grps, well_known_local_sid))	grp_list += well_known_local_sid;      if (sid_in_token_groups (my_grps, well_known_dialup_sid))	grp_list += well_known_dialup_sid;      if (sid_in_token_groups (my_grps, well_known_network_sid))	grp_list += well_known_network_sid;      if (sid_in_token_groups (my_grps, well_known_batch_sid))	grp_list += well_known_batch_sid;      if (sid_in_token_groups (my_grps, well_known_interactive_sid))	grp_list += well_known_interactive_sid;      if (sid_in_token_groups (my_grps, well_known_service_sid))	grp_list += well_known_service_sid;    }  else    {      grp_list += well_known_local_sid;      grp_list += well_known_interactive_sid;    }  if (auth_luid.QuadPart != 999) /* != SYSTEM_LUID */    {      char buf[64];      __small_sprintf (buf, "S-1-5-5-%u-%u", auth_luid.HighPart,		       auth_luid.LowPart);      grp_list += buf;      auth_pos = grp_list.count - 1;    }}static BOOLget_initgroups_sidlist (cygsidlist &grp_list,			PSID usersid, PSID pgrpsid, struct passwd *pw,			PTOKEN_GROUPS my_grps, LUID auth_luid, int &auth_pos,			BOOL &special_pgrp){  grp_list += well_known_world_sid;  grp_list += well_known_authenticated_users_sid;  if (well_known_system_sid == usersid)    {      auth_pos = -1;      grp_list += well_known_admins_sid;      get_unix_group_sidlist (pw, grp_list);    }  else    {      char user[UNLEN + 1];      char domain[INTERNET_MAX_HOST_NAME_LENGTH + 1];      WCHAR wserver[INTERNET_MAX_HOST_NAME_LENGTH + 3];      char server[INTERNET_MAX_HOST_NAME_LENGTH + 3];      get_token_group_sidlist (grp_list, my_grps, auth_luid, auth_pos);      extract_nt_dom_user (pw, domain, user);      if (get_logon_server (domain, server, wserver))	get_user_groups (wserver, grp_list, user, domain);      get_unix_group_sidlist (pw, grp_list);      if (!get_user_local_groups (grp_list, usersid))	return FALSE;    }  /* special_pgrp true if pgrpsid is not in normal groups */  if ((special_pgrp = !grp_list.contains (pgrpsid)))    grp_list += pgrpsid;  return TRUE;}static voidget_setgroups_sidlist (cygsidlist &tmp_list, 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_authenticated_users_sid;  get_token_group_sidlist (tmp_list, my_grps, auth_luid, auth_pos);  for (int gidx = 0; gidx < groups.sgsids.count; gidx++)    tmp_list += groups.sgsids.sids[gidx];  if (!groups.sgsids.contains (pgpsid))    tmp_list += pgpsid;}static const char *sys_privs[] = {  SE_TCB_NAME,  SE_ASSIGNPRIMARYTOKEN_NAME,  SE_CREATE_TOKEN_NAME,  SE_CHANGE_NOTIFY_NAME,  SE_SECURITY_NAME,  SE_BACKUP_NAME,  SE_RESTORE_NAME,  SE_SYSTEMTIME_NAME,  SE_SHUTDOWN_NAME,  SE_REMOTE_SHUTDOWN_NAME,  SE_TAKE_OWNERSHIP_NAME,  SE_DEBUG_NAME,  SE_SYSTEM_ENVIRONMENT_NAME,  SE_SYSTEM_PROFILE_NAME,  SE_PROF_SINGLE_PROCESS_NAME,  SE_INC_BASE_PRIORITY_NAME,  SE_LOAD_DRIVER_NAME,  SE_CREATE_PAGEFILE_NAME,  SE_INCREASE_QUOTA_NAME};#define SYSTEM_PERMISSION_COUNT (sizeof sys_privs / sizeof (const char *))PTOKEN_PRIVILEGESget_system_priv_list (cygsidlist &grp_list){  LUID priv;  PTOKEN_PRIVILEGES privs = (PTOKEN_PRIVILEGES)    malloc (sizeof (ULONG) + 20 * sizeof (LUID_AND_ATTRIBUTES));  if (!privs)    {      debug_printf ("malloc (system_privs) failed.");      return NULL;    }  privs->PrivilegeCount = 0;  for (DWORD i = 0; i < SYSTEM_PERMISSION_COUNT; ++i)    if (LookupPrivilegeValue (NULL, sys_privs[i], &priv))      {	privs->Privileges[privs->PrivilegeCount].Luid = priv;	privs->Privileges[privs->PrivilegeCount].Attributes =	  SE_PRIVILEGE_ENABLED | SE_PRIVILEGE_ENABLED_BY_DEFAULT;	++privs->PrivilegeCount;      }  return privs;}PTOKEN_PRIVILEGESget_priv_list (LSA_HANDLE lsa, cygsid &usersid, cygsidlist &grp_list){  PLSA_UNICODE_STRING privstrs;  ULONG cnt;  PTOKEN_PRIVILEGES privs = NULL;  NTSTATUS ret;  char buf[INTERNET_MAX_HOST_NAME_LENGTH + 1];  if (usersid == well_known_system_sid)    return get_system_priv_list (grp_list);  for (int grp = -1; grp < grp_list.count; ++grp)    {      if (grp == -1)	{	  if ((ret = LsaEnumerateAccountRights (lsa, usersid, &privstrs,						&cnt)) != STATUS_SUCCESS)	    continue;	}      else if ((ret = LsaEnumerateAccountRights (lsa, grp_list.sids[grp],						 &privstrs, &cnt))	       != STATUS_SUCCESS)	continue;      for (ULONG i = 0; i < cnt; ++i)	{	  LUID priv;	  PTOKEN_PRIVILEGES tmp;	  DWORD tmp_count;	  lsa2str (buf, privstrs[i], sizeof (buf) - 1);	  if (!LookupPrivilegeValue (NULL, buf, &priv))	    continue;	  for (DWORD p = 0; privs && p < privs->PrivilegeCount; ++p)	    if (!memcmp (&priv, &privs->Privileges[p].Luid, sizeof (LUID)))	      goto next_account_right;	  tmp_count = privs ? privs->PrivilegeCount : 0;	  tmp = (PTOKEN_PRIVILEGES)	    realloc (privs, sizeof (ULONG) +		     (tmp_count + 1) * sizeof (LUID_AND_ATTRIBUTES));	  if (!tmp)	    {	      if (privs)		free (privs);	      LsaFreeMemory (privstrs);	      debug_printf ("realloc (privs) failed.");	      return NULL;	    }	  tmp->PrivilegeCount = tmp_count;	  privs = tmp;	  privs->Privileges[privs->PrivilegeCount].Luid = priv;	  privs->Privileges[privs->PrivilegeCount].Attributes =	    SE_PRIVILEGE_ENABLED | SE_PRIVILEGE_ENABLED_BY_DEFAULT;	  ++privs->PrivilegeCount;	next_account_right:	  ;	}      LsaFreeMemory (privstrs);    }  return privs;}/* Accept a token if   - the requested usersid matches the TokenUser and   - if setgroups has been called:	the token groups that are listed in /etc/group match the union of	the requested primary and supplementary groups in gsids.   - else the (unknown) implicitly requested supplementary groups and those	in the token are the groups associated with the usersid. We assume	they match and verify only the primary groups.	The requested primary group must appear in the token.	The primary group in the token is a group associated with the usersid,	except if the token is internal and the group is in the token SD	(see create_token). In that latter case that group must match the	requested primary group.  */BOOLverify_token (HANDLE token, cygsid &usersid, user_groups &groups, BOOL *pintern){  DWORD size;  BOOL intern = FALSE;  if (pintern)    {      TOKEN_SOURCE ts;      if (!GetTokenInformation (cygheap->user.token, TokenSource,				&ts, sizeof ts, &size))	debug_printf ("GetTokenInformation(): %E");      else	*pintern = intern = !memcmp (ts.SourceName, "Cygwin.1", 8);    }  /* Verify usersid */  cygsid tok_usersid = NO_SID;  if (!GetTokenInformation (token, TokenUser,			    &tok_usersid, sizeof tok_usersid, &size))    debug_printf ("GetTokenInformation(): %E");  if (usersid != tok_usersid)    return FALSE;  /* For an internal token, if setgroups was not called and if the sd group     is not well_known_null_sid, it must match pgrpsid */  if (intern && !groups.issetgroups ())    {      char sd_buf[MAX_SID_LEN + sizeof (SECURITY_DESCRIPTOR)];      PSID gsid = NO_SID;      if (!GetKernelObjectSecurity (token, GROUP_SECURITY_INFORMATION,				    (PSECURITY_DESCRIPTOR) sd_buf,				    sizeof sd_buf, &size))	debug_printf ("GetKernelObjectSecurity(): %E");      else if (!GetSecurityDescriptorGroup ((PSECURITY_DESCRIPTOR) sd_buf,					    &gsid, (BOOL *) &size))	debug_printf ("GetSecurityDescriptorGroup(): %E");      if (well_known_null_sid != gsid)	return gsid == groups.pgsid;    }  PTOKEN_GROUPS my_grps = NULL;  BOOL ret = FALSE;  char saw_buf[NGROUPS_MAX] = {};  char *saw = saw_buf, sawpg = FALSE;  if (!GetTokenInformation (token, TokenGroups, NULL, 0, &size) &&      GetLastError () != ERROR_INSUFFICIENT_BUFFER)    debug_printf ("GetTokenInformation(token, TokenGroups): %E");  else if (!(my_grps = (PTOKEN_GROUPS) malloc (size)))    debug_printf ("malloc (my_grps) failed.");  else if (!GetTokenInformation (token, TokenGroups, my_grps, size, &size))    debug_printf ("GetTokenInformation(my_token, TokenGroups): %E");  else if (!groups.issetgroups ()) /* setgroups was never called */    {      ret = sid_in_token_groups (my_grps, groups.pgsid);      if (ret == FALSE)	ret = (groups.pgsid == tok_usersid);    }  else /* setgroups was called */    {      struct __group32 *gr;      cygsid gsid;      if (groups.sgsids.count > (int) sizeof (saw_buf) &&	  !(saw = (char *) calloc (groups.sgsids.count, sizeof (char))))	goto done;      /* token groups found in /etc/group match the user.gsids ? */      for (int gidx = 0; (gr = internal_getgrent (gidx)); ++gidx)	if (gsid.getfromgr (gr) && sid_in_token_groups (my_grps, gsid))	  {	    int pos = groups.sgsids.position (gsid);	    if (pos >= 0)	      saw[pos] = TRUE;	    else if (groups.pgsid == gsid)	      sawpg = TRUE;	   else if (gsid != well_known_world_sid &&		    gsid != usersid)	      goto done;	  }      for (int gidx = 0; gidx < groups.sgsids.count; gidx++)	if (!saw[gidx])	  goto done;      if (sawpg ||	  groups.sgsids.contains (groups.pgsid) ||	  groups.pgsid == usersid)	ret = TRUE;    }done:  if (my_grps)    free (my_grps);  if (saw != saw_buf)    free (saw);  return ret;}HANDLEcreate_token (cygsid &usersid, user_groups &new_groups, struct passwd *pw){  NTSTATUS ret;  LSA_HANDLE lsa = INVALID_HANDLE_VALUE;  int old_priv_state;  cygsidlist tmp_gsids (cygsidlist_auto, 12);  SECURITY_QUALITY_OF_SERVICE sqos =    { sizeof sqos, SecurityImpersonation, SECURITY_STATIC_TRACKING, FALSE };  OBJECT_ATTRIBUTES oa = { sizeof oa, 0, 0, 0, 0, &sqos };  PSECURITY_ATTRIBUTES psa;  BOOL special_pgrp = FALSE;  char sa_buf[1024];  LUID auth_luid = SYSTEM_LUID;  LARGE_INTEGER exp = { QuadPart:0x7fffffffffffffffLL };  TOKEN_USER user;  PTOKEN_GROUPS new_tok_gsids = NULL;  PTOKEN_PRIVILEGES privs = NULL;  TOKEN_OWNER owner;  TOKEN_PRIMARY_GROUP pgrp;  char acl_buf[MAX_DACL_LEN (5)];  TOKEN_DEFAULT_DACL dacl;  TOKEN_SOURCE source;  TOKEN_STATISTICS stats;  memcpy (source.SourceName, "Cygwin.1", 8);  source.SourceIdentifier.HighPart = 0;  source.SourceIdentifier.LowPart = 0x0101;  HANDLE token = INVALID_HANDLE_VALUE;  HANDLE primary_token = INVALID_HANDLE_VALUE;  HANDLE my_token = INVALID_HANDLE_VALUE;  PTOKEN_GROUPS my_tok_gsids = NULL;  DWORD size;  /* SE_CREATE_TOKEN_NAME privilege needed to call NtCreateToken. */  if ((old_priv_state = set_process_privilege (SE_CREATE_TOKEN_NAME)) < 0)    goto out;  /* Open policy object. */  if ((lsa = open_local_policy ()) == INVALID_HANDLE_VALUE)    goto out;  /* User, owner, primary group. */  user.User.Sid = usersid;  user.User.Attributes = 0;  owner.Owner = usersid;  /* Retrieve authentication id and group list from own process. */  if (!OpenProcessToken (hMainProc, TOKEN_QUERY, &my_token))    debug_printf ("OpenProcessToken(my_token): %E");  else    {      /* Switching user context to SYSTEM doesn't inherit the authentication	 id of the user account running current process. */      if (usersid != well_known_system_sid)	if (!GetTokenInformation (my_token, TokenStatistics,				  &stats, sizeof stats, &size))	  debug_printf	    ("GetTokenInformation(my_token, TokenStatistics): %E");	else	  auth_luid = stats.AuthenticationId;      /* Retrieving current processes group list to be able to inherit	 some important well known group sids. */      if (!GetTokenInformation (my_token, TokenGroups, NULL, 0, &size) &&	  GetLastError () != ERROR_INSUFFICIENT_BUFFER)	debug_printf ("GetTokenInformation(my_token, TokenGroups): %E");      else if (!(my_tok_gsids = (PTOKEN_GROUPS) malloc (size)))	debug_printf ("malloc (my_tok_gsids) failed.");      else if (!GetTokenInformation (my_token, TokenGroups, my_tok_gsids,				     size, &size))	{	  debug_printf ("GetTokenInformation(my_token, TokenGroups): %E");	  free (my_tok_gsids);	  my_tok_gsids = NULL;	}      CloseHandle (my_token);    }  /* Create list of groups, the user is member in. */  int auth_pos;  if (new_groups.issetgroups ())    get_setgroups_sidlist (tmp_gsids, my_tok_gsids, new_groups, auth_luid,			   auth_pos);  else if (!get_initgroups_sidlist (tmp_gsids, usersid, new_groups.pgsid, pw,				    my_tok_gsids, auth_luid, auth_pos,				    special_pgrp))    goto out;  /* Primary group. */  pgrp.PrimaryGroup = new_groups.pgsid;  /* Create a TOKEN_GROUPS list from the above retrieved list of sids. */  char grps_buf[sizeof (ULONG) + tmp_gsids.count * sizeof (SID_AND_ATTRIBUTES)];  new_tok_gsids = (PTOKEN_GROUPS) grps_buf;  new_tok_gsids->GroupCount = tmp_gsids.count;  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].Attributes = SE_GROUP_MANDATORY |	SE_GROUP_ENABLED_BY_DEFAULT | SE_GROUP_ENABLED;    }  if (auth_pos >= 0)    new_tok_gsids->Groups[auth_pos].Attributes |= SE_GROUP_LOGON_ID;  /* Retrieve list of privileges of that user. */  if (!(privs = get_priv_list (lsa, usersid, tmp_gsids)))    goto out;  /* Create default dacl. */  if (!sec_acl ((PACL) acl_buf, FALSE,		tmp_gsids.contains (well_known_admins_sid) ?		well_known_admins_sid : usersid))    goto out;  dacl.DefaultDacl = (PACL) acl_buf;  /* Let's be heroic... */  ret = NtCreateToken (&token, TOKEN_ALL_ACCESS, &oa, TokenImpersonation,		       &auth_luid, &exp, &user, new_tok_gsids, privs, &owner,		       &pgrp, &dacl, &source);  if (ret)    __seterrno_from_win_error (RtlNtStatusToDosError (ret));  else if (GetLastError () == ERROR_PROC_NOT_FOUND)    {

⌨️ 快捷键说明

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