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

📄 syscalls.cc

📁 cygwin, 著名的在win32下模拟unix操作系统的东东
💻 CC
📖 第 1 页 / 共 4 页
字号:
  debug_printf ("uid: %d myself->gid: %d", uid, myself->gid);  if (!wincap.has_security ()      || (uid == myself->uid && !cygheap->user.groups.ischanged))    {      debug_printf ("Nothing happens");      return 0;    }  if (uid == ILLEGAL_UID)    {      set_errno (EINVAL);      return -1;    }  sigframe thisframe (mainthread);  cygsid usersid;  user_groups &groups = cygheap->user.groups;  HANDLE ptok, sav_token;  BOOL sav_impersonated, sav_token_is_internal_token;  BOOL process_ok, explicitly_created_token = FALSE;  struct passwd * pw_new;  PSID origpsid, psid2 = NO_SID;  pw_new = getpwuid32 (uid);  if (!usersid.getfrompw (pw_new))    {      set_errno (EINVAL);      return -1;    }  /* Save current information */  sav_token = cygheap->user.token;  sav_impersonated = cygheap->user.impersonated;  RevertToSelf ();  if (!OpenProcessToken (hMainProc, TOKEN_QUERY | TOKEN_ADJUST_DEFAULT, &ptok))    {      __seterrno ();      goto failed;    }  /* Verify if the process token is suitable.     Currently we do not try to differentiate between	 internal tokens and others */  process_ok = verify_token (ptok, usersid, groups);  debug_printf ("Process token %sverified", process_ok ? "" : "not ");  if (process_ok)    {      if (cygheap->user.issetuid ())	cygheap->user.impersonated = FALSE;      else	{	  CloseHandle (ptok);	  goto success; /* No change */	}    }  if (!process_ok && cygheap->user.token != INVALID_HANDLE_VALUE)    {      /* Verify if the current tokem is suitable */      BOOL token_ok = verify_token (cygheap->user.token, usersid, groups,				    &sav_token_is_internal_token);      debug_printf ("Thread token %d %sverified",		   cygheap->user.token, token_ok?"":"not ");      if (!token_ok)	cygheap->user.token = INVALID_HANDLE_VALUE;      else	{	  /* Return if current token is valid */	  if (cygheap->user.impersonated)	    {	      CloseHandle (ptok);	      if (!ImpersonateLoggedOnUser (cygheap->user.token))		system_printf ("Impersonating in seteuid failed: %E");	      goto success; /* No change */	    }	}    }  /* Set process def dacl to allow access to impersonated token */  char dacl_buf[MAX_DACL_LEN (5)];  if (usersid != (origpsid =  cygheap->user.orig_sid ())) psid2 = usersid;  if (sec_acl ((PACL) dacl_buf, FALSE, origpsid, psid2))    {      TOKEN_DEFAULT_DACL tdacl;      tdacl.DefaultDacl = (PACL) dacl_buf;      if (!SetTokenInformation (ptok, TokenDefaultDacl,				&tdacl, sizeof dacl_buf))	debug_printf ("SetTokenInformation"		      "(TokenDefaultDacl): %E");    }  CloseHandle (ptok);  if (!process_ok && cygheap->user.token == INVALID_HANDLE_VALUE)    {      /* If no impersonation token is available, try to	 authenticate using NtCreateToken () or subauthentication. */      cygheap->user.token = create_token (usersid, groups, pw_new);      if (cygheap->user.token != INVALID_HANDLE_VALUE)	explicitly_created_token = TRUE;      else	{	  /* create_token failed. Try subauthentication. */	  debug_printf ("create token failed, try subauthentication.");	  cygheap->user.token = subauth (pw_new);	  if (cygheap->user.token == INVALID_HANDLE_VALUE)	    goto failed;	}    }  /* If using the token, set info and impersonate */  if (!process_ok)    {      /* If the token was explicitly created, all information has	 already been set correctly. */      if (!explicitly_created_token)	{	  /* Try setting owner to same value as user. */	  if (!SetTokenInformation (cygheap->user.token, TokenOwner,				    &usersid, sizeof usersid))	    debug_printf ("SetTokenInformation(user.token, "			  "TokenOwner): %E");	  /* Try setting primary group in token to current group */	  if (!SetTokenInformation (cygheap->user.token,				    TokenPrimaryGroup,				    &groups.pgsid, sizeof (cygsid)))	    debug_printf ("SetTokenInformation(user.token, "			  "TokenPrimaryGroup): %E");	}      /* Now try to impersonate. */      if (!ImpersonateLoggedOnUser (cygheap->user.token))	{	  debug_printf ("ImpersonateLoggedOnUser %E");	  __seterrno ();	  goto failed;	}      cygheap->user.impersonated = TRUE;    }  /* If sav_token was internally created and is replaced, destroy it. */  if (sav_token != INVALID_HANDLE_VALUE &&      sav_token != cygheap->user.token &&      sav_token_is_internal_token)      CloseHandle (sav_token);  cygheap->user.set_name (pw_new->pw_name);  cygheap->user.set_sid (usersid);success:  myself->uid = uid;  groups.ischanged = FALSE;  return 0; failed:  cygheap->user.token = sav_token;  cygheap->user.impersonated = sav_impersonated;  if (cygheap->user.issetuid ()       && !ImpersonateLoggedOnUser (cygheap->user.token))    system_printf ("Impersonating in seteuid failed: %E");  return -1;}extern "C" intseteuid (__uid16_t uid){  return seteuid32 (uid16touid32 (uid));}/* setuid: POSIX 4.2.2.1 */extern "C" intsetuid32 (__uid32_t uid){  int ret = seteuid32 (uid);  if (!ret)    cygheap->user.real_uid = myself->uid;  debug_printf ("real: %d, effective: %d", cygheap->user.real_uid, myself->uid);  return ret;}extern "C" intsetuid (__uid16_t uid){  return setuid32 (uid16touid32 (uid));}/* setegid: from System V.  */extern "C" intsetegid32 (__gid32_t gid){  if (!wincap.has_security () || gid == myself->gid)    return 0;  if (gid == ILLEGAL_GID)    {      set_errno (EINVAL);      return -1;    }  sigframe thisframe (mainthread);  user_groups * groups = &cygheap->user.groups;  cygsid gsid;  HANDLE ptok;  struct __group32 * gr = getgrgid32 (gid);  if (!gr || gr->gr_gid != gid || !gsid.getfromgr (gr))    {      set_errno (EINVAL);      return -1;    }  myself->gid = gid;  groups->update_pgrp (gsid);  /* If impersonated, update primary group and revert */  if (cygheap->user.issetuid ())    {      if (!SetTokenInformation (cygheap->user.token,				TokenPrimaryGroup,				&gsid, sizeof gsid))	debug_printf ("SetTokenInformation(thread, "		      "TokenPrimaryGroup): %E");      RevertToSelf ();    }  if (!OpenProcessToken (hMainProc, TOKEN_ADJUST_DEFAULT, &ptok))    debug_printf ("OpenProcessToken(): %E");  else    {      if (!SetTokenInformation (ptok, TokenPrimaryGroup,				&gsid, sizeof gsid))	debug_printf ("SetTokenInformation(process, "		      "TokenPrimaryGroup): %E");      CloseHandle (ptok);    }  if (cygheap->user.issetuid ()      && !ImpersonateLoggedOnUser (cygheap->user.token))    system_printf ("Impersonating in setegid failed: %E");  return 0;}extern "C" intsetegid (__gid16_t gid){  return setegid32 (gid16togid32 (gid));}/* setgid: POSIX 4.2.2.1 */extern "C" intsetgid32 (__gid32_t gid){  int ret = setegid32 (gid);  if (!ret)    cygheap->user.real_gid = myself->gid;  return ret;}extern "C" intsetgid (__gid16_t gid){  int ret = setegid32 (gid16togid32 (gid));  if (!ret)    cygheap->user.real_gid = myself->gid;  return ret;}/* chroot: privileged Unix system call.  *//* FIXME: Not privileged here. How should this be done? */extern "C" intchroot (const char *newroot){  sigframe thisframe (mainthread);  path_conv path (newroot, PC_SYM_FOLLOW | PC_FULL | PC_POSIX);  int ret;  if (path.error)    ret = -1;  else if (!path.exists ())    {      set_errno (ENOENT);      ret = -1;    }  else if (!path.isdir ())    {      set_errno (ENOTDIR);      ret = -1;    }  else    {      cygheap->root.set (path.normalized_path, path);      ret = 0;    }  syscall_printf ("%d = chroot (%s)", ret ? get_errno () : 0,				      newroot ? newroot : "NULL");  return ret;}extern "C" intcreat (const char *path, mode_t mode){  sigframe thisframe (mainthread);  return open (path, O_WRONLY | O_CREAT | O_TRUNC, mode);}extern "C" void__assertfail (){  exit (99);}extern "C" intgetw (FILE *fp){  sigframe thisframe (mainthread);  int w, ret;  ret = fread (&w, sizeof (int), 1, fp);  return ret != 1 ? EOF : w;}extern "C" intputw (int w, FILE *fp){  sigframe thisframe (mainthread);  int ret;  ret = fwrite (&w, sizeof (int), 1, fp);  if (feof (fp) || ferror (fp))    return -1;  return 0;}extern "C" intwcscmp (const wchar_t *s1, const wchar_t *s2){  while (*s1  && *s1 == *s2)    {      s1++;      s2++;    }  return (* (unsigned short *) s1) - (* (unsigned short *) s2);}extern "C" size_twcslen (const wchar_t *s1){  int l = 0;  while (s1[l])    l++;  return l;}/* FIXME: to do this right, maybe work out the usoft va_list machine   and use wsvprintfW instead?*/extern "C" intwprintf (const char *fmt, ...){  va_list ap;  int ret;  va_start (ap, fmt);  ret = vprintf (fmt, ap);  va_end (ap);  return ret;}extern "C" intvhangup (){  set_errno (ENOSYS);  return -1;}extern "C" _PTRmemccpy (_PTR out, const _PTR in, int c, size_t len){  const char *inc = (char *) in;  char *outc = (char *) out;  while (len)    {      char x = *inc++;      *outc++ = x;      if (x == c)	return outc;      len --;    }  return 0;}extern "C" intnice (int incr){  sigframe thisframe (mainthread);  DWORD priority[] =    {      IDLE_PRIORITY_CLASS,      IDLE_PRIORITY_CLASS,      NORMAL_PRIORITY_CLASS,      HIGH_PRIORITY_CLASS,      REALTIME_PRIORITY_CLASS,      REALTIME_PRIORITY_CLASS    };  int curr = 2;  switch (GetPriorityClass (hMainProc))    {      case IDLE_PRIORITY_CLASS:	curr = 1;	break;      case NORMAL_PRIORITY_CLASS:	curr = 2;	break;      case HIGH_PRIORITY_CLASS:	curr = 3;	break;      case REALTIME_PRIORITY_CLASS:	curr = 4;	break;    }  if (incr > 0)    incr = -1;  else if (incr < 0)    incr = 1;  if (SetPriorityClass (hMainProc, priority[curr + incr]) == FALSE)    {      __seterrno ();      return -1;    }  return 0;}/* * Find the first bit set in I. */extern "C" intffs (int i){  static const unsigned char table[] =    {      0,1,2,2,3,3,3,3,4,4,4,4,4,4,4,4,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,      6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,      7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,      7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,      8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,      8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,      8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,      8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8    };  unsigned long int a;  unsigned long int x = i & -i;  a = x <= 0xffff ? (x <= 0xff ? 0 : 8) : (x <= 0xffffff ?  16 : 24);  return table[x >> a] + a;}extern "C" voidlogin (struct utmp *ut){  sigframe thisframe (mainthread);  register int fd;  pututline (ut);  if ((fd = open (_PATH_WTMP, O_WRONLY | O_APPEND | O_BINARY, 0)) >= 0)    {      (void) write (fd, (char *) ut, sizeof (struct utmp));      (void) close (fd);    }}/* It isn't possible to use unix-style I/O function in logout code becausecygwin's I/O subsystem may be inaccessible at logout () call time.FIXME (cgf): huh?*/extern "C" intlogout (char *line){  sigframe thisframe (mainthread);  int res = 0;  HANDLE ut_fd;  static const char path_utmp[] = _PATH_UTMP;  path_conv win32_path (path_utmp);  if (win32_path.error)    return 0;  ut_fd = CreateFile (win32_path.get_win32 (),		      GENERIC_READ | GENERIC_WRITE,		      FILE_SHARE_READ | FILE_SHARE_WRITE,		      &sec_none_nih, OPEN_EXISTING,		      FILE_ATTRIBUTE_NORMAL, NULL);  if (ut_fd != INVALID_HANDLE_VALUE)    {      struct utmp *ut;      struct utmp ut_buf[100];      /* FIXME: utmp file access is not 64 bit clean for now. */      __off32_t pos = 0;		/* Position in file */      DWORD rd;      while (!res && ReadFile (ut_fd, ut_buf, sizeof ut_buf, &rd, NULL)	     && rd != 0)	{	  struct utmp *ut_end = (struct utmp *) ((char *) ut_buf + rd);	  for (ut = ut_buf; ut < ut_end; ut++, pos += sizeof (*ut))	    if (ut->ut_name[0]		&& strncmp (ut->ut_line, line, sizeof (ut->ut_line)) == 0)	      /* Found the entry for LINE; mark it as logged out.  */	      {		/* Zero out entries describing who's logged in.  */		bzero (ut->ut_name, sizeof (ut->ut_name));		bzero (ut->ut_host, sizeof (ut->ut_host));		time (&ut->ut_time);		/* Now seek back to the position in utmp at which UT occured,		   and write the new version of UT there.  */		if ((SetFilePointer (ut_fd, pos, 0, FILE_BEGIN) != 0xFFFFFFFF)		    && (WriteFile (ut_fd, (char *) ut, sizeof (*ut),				   &rd, NULL)))		  {		    res = 1;		    break;		  }	      }	}      CloseHandle (ut_fd);    }  return res;}static int utmp_fd = -2;static char *utmp_file = (char *) _PATH_UTMP;static struct utmp utmp_data;extern "C" voidsetutent (){  sigframe thisframe (mainthread);  if (utmp_fd == -2)    {      utmp_fd = open (utmp_file, O_RDWR);    }  lseek (utmp_fd, 0, SEEK_SET);}extern "C" voidendutent (){  sigframe thisframe (mainthread);  if (utmp_fd != -2)    {      close (utmp_fd);      utmp_fd = -2;    }}extern "C" voidutmpname (_CONST char *file){  sigframe thisframe (mainthread);  if (check_null_empty_str (file))    {      debug_printf ("Invalid file");      return;    }  endutent ();  utmp_file = strdup (file);  debug_printf ("New UTMP file: %s", utmp_file);}extern "C" struct utmp *getutent (){  sigframe thisframe (mainthread);  if (utmp_fd == -2)    setutent ();  if (read (utmp_fd, &utmp_data, sizeof (utmp_data)) != sizeof (utmp_data))    return NULL;  return &utmp_data;}extern "C" struct utmp *getutid (struct utmp *id){  sigframe thisframe (mainthread);  if (check_null_invalid_struct_errno (id))    return NULL;  while (read (utmp_fd, &utmp_data, sizeof (utmp_data)) == sizeof (utmp_data))    {      switch (id->ut_type)	{	case RUN_LVL:	case BOOT_TIME:	case OLD_TIME:	case NEW_TIME:	  if (id->ut_type == utmp_data.ut_type)	    return &utmp_data;	  break;	case INIT_PROCESS:	case LOGIN_PROCESS:	case USER_PROCESS:	case DEAD_PROCESS:	   if (strncmp (id->ut_id, utmp_data.ut_id, UT_IDLEN) == 0)	    return &utmp_data;	  break;	default:	  return NULL;	}    }  return NULL;}extern "C" struct utmp *getutline (struct utmp *line){  sigframe thisframe (mainthread);  if (check_null_invalid_struct_errno (line))    return NULL;  while (read (utmp_fd, &utmp_data, sizeof (utmp_data)) == sizeof (utmp_data))    {      if ((utmp_data.ut_type == LOGIN_PROCESS ||	   utmp_data.ut_type == USER_PROCESS) &&	  !strncmp (utmp_data.ut_line, line->ut_line,		    sizeof (utmp_data.ut_line)))	return &utmp_data;    }  return NULL;}extern "C" voidpututline (struct utmp *ut){  sigframe thisframe (mainthread);  if (check_null_invalid_struct (ut))    return;  setutent ();  struct utmp *u;  if ((u = getutid (ut)))    lseek (utmp_fd, -sizeof(struct utmp), SEEK_CUR);  else    lseek (utmp_fd, 0, SEEK_END);  (void) write (utmp_fd, (char *) ut, sizeof (struct utmp));}

⌨️ 快捷键说明

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