shutdown Access denied (was Re: [ANNOUNCEMENT] Updated: cygwin-1.5.15-1)

Corinna Vinschen corinna-cygwin@cygwin.com
Fri Apr 22 11:49:00 GMT 2005


On Apr 22 13:17, Corinna Vinschen wrote:
> On Apr 22 10:59, Jason FU wrote:
> > Corinna Vinschen <corinna-cygwin <at> cygwin.com> writes:
> > > I know, that's why I was asking.  I just ran shutdown-1.5-1 again on
> > > 2003 Server and it works fine for me.  I tried it in local sessions,
> > > remote desktop sessions and in a sshd logon from another machine.  In
> > > all cases shutdown worked as expected.  So what shall I do?
> > 
> > I have the same problem in Windows XP SP2.
> 
> I don't.

I've created a patched version of shutdown which should give us some
hint why it doesn't work for you.  The source is attached.  Just call
`make shutdown' and run this newly created shutdown instead of the 
release version and report back.


Corinna

-- 
Corinna Vinschen                  Please, send mails regarding Cygwin to
Cygwin Project Co-Leader          mailto:cygwin@cygwin.com
Red Hat, Inc.
-------------- next part --------------
/*
 * shutdown.c: implementation of shutdown(1) as part of a Cygwin environment
 *
 * Copyright 1998, 2001, 2003, 2005  Corinna Vinschen,
 * bug reports to  cygwin@cygwin.com
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 * 
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
*/

#include <stdio.h>
#include <string.h>
#include <stdarg.h>
#include <getopt.h>
#include <time.h>

#include <windows.h>
#define is_winnt	(GetVersion() < 0x80000000L)

/* The following values must not collide with EWX_* values. */
#define HIBERNATE	 32
#define SUSPEND		 64
#define ABORT		128

static char *SCCSid = "@(#)shutdown V1.5, Corinna Vinschen, " __DATE__ "\n";

char *myname;

char errbuf[4096];

char *
error (DWORD err)
{
  sprintf (errbuf, "Error %lu ", err);
  FormatMessage (FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_IGNORE_INSERTS,
		 NULL, err, MAKELANGID (LANG_NEUTRAL, SUBLANG_DEFAULT),
		 (LPTSTR) errbuf + strlen (errbuf),
		 sizeof (errbuf) - strlen (errbuf), NULL);
  return errbuf;
}

int
usage (void)
{
  printf ("Usage: %s [OPTION]... time\n", myname);
  printf ("Bring the system down.\n\n");
  printf ("  -f, --force      Forces the execution.\n");
  printf ("  -s, --shutdown   The system will shutdown and power off (if supported)\n");
  printf ("  -r, --reboot     The system will reboot.\n");
  printf ("  -h, --hibernate  The system will suspend to disk (if supported)\n");
  printf ("  -p, --suspend    The system will suspend to RAM (if supported)\n");
  if (is_winnt)
    printf ("  -a, --abort      Aborts execution of formerly started shutdown.\n");
  printf ("      --help       Display this help and exit.\n");
  printf ("      --version    Output version information and exit.\n");
  printf ("\n`time' is either the time in seconds or `+' and the time in minutes or a\n");
  printf ("timestamp in the format `hh:mm' or the word \"now\" for an immediate action.\n");
  printf ("\nTo reboot is the default if started as `reboot', to hibernate if started\n");
  printf ("as `hibernate', to suspend if started as `suspend', to shutdown otherwise.\n");
  return 0;
}

WINBASEAPI BOOL WINAPI (*openprocesstoken) (HANDLE, DWORD, PHANDLE);
WINBASEAPI BOOL WINAPI (*adjusttokenprivileges) (HANDLE, BOOL,
						 PTOKEN_PRIVILEGES, DWORD,
						 PTOKEN_PRIVILEGES, PDWORD);
WINBASEAPI BOOL WINAPI (*lookupprivilegevalue) (LPCTSTR, LPCTSTR, PLUID);
WINBASEAPI BOOL WINAPI (*reverttoself) (VOID);
BOOL WINAPI (*initiatesystemshutdown) (LPCTSTR, LPCTSTR, DWORD, BOOL, BOOL);
BOOL WINAPI (*abortsystemshutdown) (LPCTSTR);

int
load_funcs (void)
{
  HMODULE adv;

  if (!is_winnt)
    return 0;

  if (!(adv = LoadLibrary ("advapi32.dll")))
    {
      fprintf (stderr, "%s: can't load advapi32.dll: %s\n",
	       myname, error (GetLastError ()));
      return 1;
    }
  if (!(lookupprivilegevalue = (WINBASEAPI BOOL WINAPI (*)
	    (LPCTSTR, LPCTSTR, PLUID))
	    GetProcAddress (adv, "LookupPrivilegeValueA")))
    goto err;
  if (!(openprocesstoken = (WINBASEAPI BOOL WINAPI (*)
	    (HANDLE, DWORD, PHANDLE))
	    GetProcAddress (adv, "OpenProcessToken")))
    goto err;
  if (!(adjusttokenprivileges = (WINBASEAPI BOOL WINAPI (*)
	    (HANDLE, BOOL, PTOKEN_PRIVILEGES, DWORD, PTOKEN_PRIVILEGES, PDWORD))
	    GetProcAddress (adv, "AdjustTokenPrivileges")))
    goto err;
  if (!(initiatesystemshutdown = (BOOL WINAPI (*)
	    (LPCTSTR, LPCTSTR, DWORD, BOOL, BOOL))
	    GetProcAddress (adv, "InitiateSystemShutdownA")))
    goto err;
  if (!(abortsystemshutdown = (BOOL WINAPI (*)
  	    (LPCTSTR))
	    GetProcAddress (adv, "AbortSystemShutdownA")))
    goto err;
  if (!(reverttoself = (WINBASEAPI BOOL WINAPI (*)
	    (VOID))
	    GetProcAddress (adv, "RevertToSelf")))
    goto err;

  return 0;

err:
  fprintf (stderr, "%s: can't load symbol from advapi32.dll: %s\n",
  	   myname, error (GetLastError ()));
  return 1;
}


int
setprivs (void)
{
  HANDLE token;
  TOKEN_PRIVILEGES privs;

  /* Privileges are not supported on 9x/ME. */
  if (!is_winnt)
    return 0;

  if (!lookupprivilegevalue (NULL, SE_SHUTDOWN_NAME,
			     &privs.Privileges[0].Luid))
    /* If the privilege have been found, we're trying to shutdown anyway. */
    return 0;

  privs.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
  privs.PrivilegeCount = 1;

  if (!openprocesstoken (GetCurrentProcess (), TOKEN_ADJUST_PRIVILEGES,
			 &token))
    {
      fprintf (stderr, "%s: can't open process token: %s\n",
	       myname, error (GetLastError ()));
      return 1;
    }
  if (!adjusttokenprivileges (token, FALSE, &privs, 0, NULL, NULL))
    {
      fprintf (stderr, "%s: can't set required privilege: %s\n",
	       myname, error (GetLastError ()));
      return 1;
    }
  if (GetLastError () == ERROR_NOT_ALL_ASSIGNED)
    {
      fprintf (stderr, "%s: required privilege not held: %s\n",
	       myname, error (GetLastError ()));
      return 1;
    }
  if (!reverttoself ())
    {
      fprintf (stderr, "%s: can't activate required privilege: %s\n",
	       myname, error (GetLastError ()));
      return 1;
    }
  return 0;
}

struct option longopts[] = {
  {"abort", no_argument, NULL, 'a'},
  {"force", no_argument, NULL, 'f'},
  {"shutdown", no_argument, NULL, 's'},
  {"reboot", no_argument, NULL, 'r'},
  {"hibernate", no_argument, NULL, 'h'},
  {"suspend", no_argument, NULL, 'p'},
  {"help", no_argument, NULL, 'H'},
  {"version", no_argument, NULL, 'v'},
  {0, no_argument, NULL, 0}
};

char opts[] = "afsrhp";

int
main (int argc, char **argv)
{
  int c;
  long secs = -1;
  int action = is_winnt? EWX_POWEROFF : EWX_SHUTDOWN;
  int force = 0;
  char buf[4096], *arg, *endptr;
  DWORD err;

  if ((myname = strrchr (argv[0], '/')) || (myname = strrchr (argv[0], '\\')))
    ++myname;
  else
    myname = argv[0];
  if (strrchr (myname, '.'))
    *strrchr (myname, '.') = '\0';
  if (!strcasecmp (myname, "reboot"))
    action = EWX_REBOOT;
  else if (!strcasecmp (myname, "hibernate"))
    action = HIBERNATE;
  else if (!strcasecmp (myname, "suspend"))
    action = SUSPEND;
  while ((c = getopt_long (argc, argv, opts, longopts, NULL)) != EOF)
    switch (c)
      {
      case 'f':
	/* EWX_FORCE doesn't work correctly on 9x/ME. */
	if (is_winnt)
	  force = EWX_FORCE;
	break;
      case 's':
        action = is_winnt ? EWX_POWEROFF : EWX_SHUTDOWN;
	break;
      case 'r':
	action = EWX_REBOOT;
	break;
      case 'h':
        action = HIBERNATE;
	break;
      case 'p':
        action = SUSPEND;
	break;
      case 'a':
	if (!is_winnt)
	  {
	    fprintf (stderr, "Try `%s --help' for more information.\n", myname);
	    return 1;
	  }
	action = ABORT;
	break;
      case 'v':
	printf ("%s\n", SCCSid + 4);
	printf ("Copyright (C) 2005 Corinna Vinschen\n");
	printf ("This is free software; see the source for copying conditions.\n");
	printf ("There is NO warranty; not even for MERCHANTABILITY or FITNESS\n");
	printf ("FOR A PARTICULAR PURPOSE.\n");
        return 0;
      case 'H':
	return usage ();
      default:
        fprintf (stderr, "Try `%s --help' for more information.\n", myname);
	return 1;
      }
  if (action != ABORT)
    {
      if (optind >= argc)
	{
	  fprintf (stderr, "%s: missing arguments\n", myname);
	  fprintf (stderr, "Try `%s --help' for more information.\n", myname);
	  return 1;
	}
      arg = argv[optind];
      if (!strcasecmp (arg, "now"))
	{
	  secs = 0;
	  strcpy (buf, "NOW");
	}
      else if (arg[0] == '+' && isdigit (arg[1]))
	{
	  /* Leading `+' means time in minutes. */
	  secs = strtol (arg, &endptr, 10) * 60;
	  if (*endptr)
	    secs = -1;
	  else
	    sprintf (buf, "in %d minute", secs / 60);
	}
      else if (isdigit (arg[0]) && strchr (arg + 1, ':'))
	{
	  /* HH:MM, timestamp when to shutdown. */
	  long hour, minute;
	  time_t now, then;
	  struct tm *loc;

	  hour = strtol (arg, &endptr, 10);
	  if (*endptr == ':' && hour >= 0 && hour <= 23)
	    {
	      minute = strtol (endptr + 1, &endptr, 10);
	      if (!*endptr && minute >= 0 && minute <= 59)
		{
		  then = now = time (NULL);
		  loc = localtime (&now);
		  if (loc->tm_hour > hour
		      || (loc->tm_hour == hour && loc->tm_min >= minute))
		    {
		      then += 24 * 60 * 60; /* Next day */
		      loc = localtime (&then);
		    }
		  loc->tm_hour = hour;
		  loc->tm_min = minute;
		  loc->tm_sec = 0;
		  then = mktime (loc);
		  secs = then - now;
		  sprintf (buf, "at %02d:%02d", hour, minute);
		}
	    }
	}
      else if (isdigit (arg[0]))
	{
	  /* otherwise time in seconds. */
	  secs = strtol (arg, &endptr, 10);
	  if (*endptr)
	    secs = -1;
	  else
	    sprintf (buf, "in %d seconds", secs);
	}
      if (secs < 0)
	{
	  fprintf (stderr, "%s: Invalid time format.\n", myname);
	  fprintf (stderr, "Try `%s --help' for more information.\n", myname);
	  return 2;
	}
    }
  if (load_funcs ())
    return 4;

  if (setprivs ())
    return 3;

  if (action != ABORT)
    printf ("WARNING!!! System is going down %s\n", buf);

  if (action == EWX_POWEROFF || action == EWX_SHUTDOWN || action == EWX_REBOOT)
    {
      if (is_winnt)
        {
	  if (initiatesystemshutdown (NULL,
				      "WARNING!!! System is going down",
				      secs,
				      force == EWX_FORCE,
				      action == EWX_REBOOT))
	    return 0;
	}
      else if (ExitWindowsEx (action | force, 0))
        return 0;
    }
  else if (action == ABORT)
    {
      if (abortsystemshutdown (NULL))
        return 0;
    }
  else
    {
      while (secs)
	secs = sleep (secs);
      if (SetSystemPowerState (action == SUSPEND, force == EWX_FORCE))
	return 0;
    }
  
  err = GetLastError ();
  fprintf (stderr, "%s: Couldn't ", myname);
  switch (action)
    {
    case EWX_POWEROFF:
    case EWX_SHUTDOWN:
      fprintf (stderr, "shutdown");
      break;
    case EWX_REBOOT:
      fprintf (stderr, "reboot");
      break;
    case HIBERNATE:
      fprintf (stderr, "hibernate");
      break;
    case SUSPEND:
      fprintf (stderr, "suspend");
      break;
    case ABORT:
      fprintf (stderr, "abort");
      break;
    }
  fprintf (stderr, ": %s\n", error (err));
  return 3;
}

-------------- next part --------------
--
Unsubscribe info:      http://cygwin.com/ml/#unsubscribe-simple
Problem reports:       http://cygwin.com/problems.html
Documentation:         http://cygwin.com/docs.html
FAQ:                   http://cygwin.com/faq/


More information about the Cygwin mailing list