ntsec odds and ends (cygcheck augmentation?)

Pierre A. Humblet Pierre.Humblet@ieee.org
Wed Feb 5 21:27:00 GMT 2003


At 01:30 PM 2/5/2003 -0500, Christopher Faylor wrote:
>I think that initial feedback is a *great* idea but if cygcheck can
>provide some kind of information that would allow diagnosing a
>problem, that would be useful, too.
>
>Maybe it could just dump selected fields from /etc/passwd and
>/etc/group.

I found the check program I had written and attach it FYI, 
have fun testing weird cases.

Simple things, such as dumping /etc/passwd fields, can easily be done 
from a script, perhaps providing immediate feedback.

I am off till late Sunday. It would be nice if a consensus could emerge 
on how to best solve the recurring problems faced by new users. 
I am convinced that a new setup.exe, with a new passwd-grp.sh and no 
passwd-grp.bat, would solve 90% of the problems.

Meanwhile Cygwin has always made progress from experimentations and one
could give a shot at what I tried in the latest patch.

I am still interested to hear if "mkpasswd -l -c" provides a correct 
entry (the last line) for domain users, in all circumstances. 

Pierre

-------------- next part --------------
#include <stdio.h>
#include <string.h>
#include <limits.h>
#include <unistd.h>
#include <pwd.h>
#include <grp.h>
#include <windows.h>

#define DEFAULT_UID_NT 400
#define DEFAULT_GID 401

char usidstring [100], gsidstring [100];

void sidstring (char *nsidstr, PSID psid)
{
  char *t = nsidstr;
  DWORD i;
  int s;

  strcpy (t, "S-1-");
  t += sizeof ("S-1-") - 1;
  s = sprintf (t, "%u", GetSidIdentifierAuthority (psid)->Value[5]);
  for (i = 0; i < *GetSidSubAuthorityCount (psid); ++i)
    s = sprintf (t += s, "-%lu", *GetSidSubAuthority (psid, i));
}

void getsids ()
{
  HANDLE ptok;
  struct {
    PSID psid;
    char buffer[40];
  } sid;
  DWORD siz;

  if (!OpenProcessToken (GetCurrentProcess (), TOKEN_QUERY, &ptok))
    fprintf(stderr, "I cannot read my process access token.\n"
	    "Windows error %ld.\n", GetLastError ());
  else
    {
      if (!GetTokenInformation (ptok, TokenUser, &sid, sizeof sid, &siz))
	fprintf(stderr, "I cannot get my own user SID.\n"
		"Windows error %ld.\n", GetLastError ());
      else
	sidstring (usidstring, sid.psid);
      if (!GetTokenInformation (ptok, TokenPrimaryGroup, &sid, sizeof sid, &siz))
	fprintf(stderr, "I cannot get my own group SID.\n"
		"Windows error %ld.\n", GetLastError ());
      else
	sidstring (gsidstring, sid.psid);
      CloseHandle (ptok);
    }
  if (!*usidstring || !*gsidstring)
    exit (1);
}

int main()
{
  gid_t grouplist[NGROUPS_MAX];
  int n;
  struct passwd * pw = NULL;
  struct group * gr = NULL;
  char * ptr = NULL;
  int isnt;

  /* Verify /etc/passwd */
  if ((isnt = !(GetVersion () & 0x80000000)))
    {
      getsids ();
      if (getuid () == DEFAULT_UID_NT)
	fprintf(stdout, "My uid is %d. This value is a reserved default.\n"
		"  It is used when /etc/passwd does not contain my Windows name %s\n"
		"  nor my user SID %s.\n",
		getuid (), getlogin (), usidstring);
      else if (getpwuid (DEFAULT_UID_NT))
	fprintf(stdout, "uid %d is a reserved default.\n"
		"  It should not appear in /etc/passwd.\n",
		DEFAULT_UID_NT);
    }
  else if (getgid () == DEFAULT_GID)
    fprintf(stdout, "My gid is %d. This value is a reserved default.\n"
	    "  It is used when /etc/passwd does not contain my name %s\n"
	    "  nor a default entry with uid 500.\n",
	    getgid (), getlogin ());

  for (n = 0; n < 2; n++)
    {
      char msg [100];
      if (n == 0)
        {
	  sprintf (msg, "uid %d", getuid ());
	  pw = getpwuid (getuid ());
	}
      else
        {
	  sprintf (msg, "name %s", getlogin ());
	  pw = getpwnam (getlogin ());
	}
      if (!pw)
	fprintf(stdout, "My %s does not appear in /etc/passwd.\n", msg);
      else
        {
	  if (isnt)
	    {
	      if (!(ptr = strrchr (pw->pw_gecos, ',')) || strncmp (++ptr, "S-1-", 4))
		fprintf(stdout, "A passwd entry for my %s does not contain a SID.\n",
			msg);
	      else if (strcmp (ptr, usidstring))
		fprintf(stdout, "A passwd entry for my %s does not contain my SID %s.\n",
			msg, usidstring);
	    }
	  if (strcasecmp (pw->pw_name, getlogin ()))
	    fprintf(stdout, "A passwd entry for my %s contains name %s instead of my name %s.\n"
		    "  This is legitimate but unusual.\n",
		    msg, pw->pw_name, getlogin ());
	  if (pw->pw_uid != getuid ())
	    {
	      fprintf(stdout, "A passwd entry for my %s contains uid %d instead of my uid %d.\n",
		      msg, pw->pw_uid, getuid ());
	      if (sizeof (uid_t) == 2 && pw->pw_uid >= USHRT_MAX)
		fprintf(stdout, "  Currently uid's are short unsigned integers.\n");
	    }
	  if (pw->pw_gid != getgid ())
	    {
	      fprintf(stdout, "A passwd entry for my %s contains gid %d instead of my gid %d.\n",
		      msg, pw->pw_gid, getgid ());
	      if (sizeof (gid_t) == 2 && pw->pw_gid >= USHRT_MAX)
		fprintf(stdout, "  Currently gid's are short unsigned integers.\n");
	    }
	}
    }

  /* Verify /etc/group */
  if (((isnt && getuid () != DEFAULT_UID_NT)
       || (!isnt && getgid () != DEFAULT_GID))
      && getgrgid (DEFAULT_GID))
    fprintf(stdout, "gid %d is a reserved default.\n"
	    "  It should not appear in /etc/group.\n",
	    DEFAULT_GID);
  /* Use getgrent to detect possible augmented entry at end */
  setgrent ();
  while ((gr = getgrent ()))
    if (gr->gr_gid == getgid ())
      break;
  if (gr == NULL)
    fprintf(stdout, "My gid %d does not appear in /etc/group.\n",
	    getgid ());
  else
    {
      if (isnt)
	{
	  if (strncmp (gr->gr_passwd, "S-1-", 4))
	    fprintf(stdout, "A group entry for my gid %d does not contain a SID.\n",
		    getgid ());
	  else if (strcmp (gr->gr_passwd, gsidstring))
	    fprintf(stdout, "A group entry for my gid %d contains SID %s\n"
		    "  instead of my group SID %s.\n",
		    getgid (), gr->gr_passwd, gsidstring);
	  if ((ptr = getenv ("CYGWIN")) && strstr (ptr, "nontsec"))
	    fprintf(stdout, "ntsec is turned off. Groups cannot be verified.\n");
	  else if (!(n = getgroups (NGROUPS_MAX, grouplist)))
	    perror ("getgroups");
	  else
	    {
	      while (--n >= 0 && grouplist[n] != getgid ())
	      if (n < 0)
		fprintf(stdout, "My gid %d is not one of my Windows groups.\n",
			getgid ());
	    }
	}
      /* Check for possible augmented entry at end */
      if (getgid () != DEFAULT_GID
	  && ((isnt && !strcmp (gr->gr_passwd, gsidstring))
	   || (!isnt && !strcmp (gr->gr_name, "unknown") && !gr->gr_passwd[0]))
	  && gr->gr_mem[0] && !gr->gr_mem[1] && !strcmp (gr->gr_mem[0], getlogin ())
	  && getgrent () == NULL)
	{
	  if (!strcmp (gr->gr_name, "unknown"))
	    fprintf(stdout, "My group name is \"%s\".\n"
		    "  This suggests that my gid %d does not appear in /etc/group.\n",
		    gr->gr_name, getgid ());
	  else if (isnt)
	    fprintf(stdout, "Verify that my gid %d appears in /etc/group.\n",
		    getgid ());
	}
    }
  exit (0);
}


More information about the Cygwin-patches mailing list