On Aug 18 08:35, Tom Rodman wrote:
> On Fri 8/18/06 8:58 +0200 cygwin@cygwin.com wrote:
> > On Aug 17 18:49, Tom Rodman wrote:
> > > 
> > > tried that.. no joy, take a look:
> > > --v-v------------------C-U-T---H-E-R-E-------------------------v-v-- 
> > >   $ $WINDIR/system32/whoami /all #we're in an ssh session before edits 
> > > made to /etc/group
> > >   
> > >   USER INFORMATION
> > >   ----------------
> > >   
> > >   User Name  SID
> > >   ========== =============================================
> > >   DOMxx1\adm_usr1 S-1-5-21-1390067357-1202660629-682003330-5774
> > 
> > Must be a password logon session, otherwise you would not see this
> > user name here, but sshd_server.
> 
> Your right, it is a *password authenticated* logon session, such sessions are
> fine w/me for system administration work. On a separate issue, rightly
> or wrongly we use an expect script w/cron to schedule cron jobs that
> access and change files on network shares.

That's bad.  The user token created by cron is the same style as the
user token created with ssh /w pubkey authentication.  The main problem
is that the token has no network credentials.  There's no way around
that, not for the time being, not ever.  The only way to access network
shares using a cron job is to access public shares, or the cron job has
access to the necessary user/password combination and calls `net use'
directly.  And even then, you can only access the shares directly
(//server/share), not with drive letters.

But, Tom, this is all not new.  This has been talked about in this list
for years, really.  You should be able to find that information eaasily
by googling.

> again - A home dir on a network share, works fine for us w/password
> authentication, so the original post/problem is for the password
> authentication case - sorry I did not make that clear :-<

The trick using /etc/group only works for password-LESS authentication,
sorry for not mentioning it, but usually the problems reported here are
with passwordless authentication so I just assumed this is the case here,
too.  The /etc/group trick can work, though.  The code is just not in
Cygwin.  I put this on my TODO list for an upcoming Cygwin version, but
don't hold your breath.

> It would be interesting to see if you or otheres can duplicate the problem,
> using password authentication.

Yes, I can duplicate this with password authentication.  However, keep
in mind that the token is generated by Windows.  The token is not
further massaged by Cygwin, so whether or not the LOCAL group is
available in the token is not under control of Cygwin.

> Yes I see the local group "S-1-2-0", but when I ssh'd in, I typed the
> password in for this session and so I expect "whoami /all" to return
> the username that goes with the password - more importantly I need the
> credentials to write to the network shares, that I normally get when
> using ssh via password authentication.

No go.  Either you use password authentication, then you get the correct
username and network credentials, or you use pubkey authentication and
Windows returns the wrong username and you don't have network credentials.
I have a solution which allows to get the right username at one point
(again, don't hold your breath), but when you don't give a password
at logon time, where should the network credentials come from?  This
will never work.

> I appreciate your help on this Corinna, *thank-you*.  Most work I do does
> not seem to require membership in "S-1-2-0", so it's not that big a deal.
> 
> > This is a long standing problem, for
> > years.  There's no workaround for the time being.  However, if you take
> > a look into the user token of the process using other means
> > (OpenProcessToken/GetTokenInformation), you'll see that the token user,
> > as well as the token owner is set to the user account you logged in to,
> > DOMxx1\adm_usr1 in this case.  
> 
> Thanks, I trust your right, I don't have the experience or time to
> write a simple tool using (OpenProcessToken/GetTokenInformation); maybe
> I can google and find such a tool..

Take the attached file and compile with g++.  It's my crude token
helper application I'm using for some years now.  It shows the
access token you're using when calling the application.  The SIDs are
not translated in user or group names because I don't need that.
Without arguments, everything but the user rights are printed,
with any argument, it also prints the user rights.


HTH,
Corinna

-- 
Corinna Vinschen                  Please, send mails regarding Cygwin to
Cygwin Project Co-Leader          cygwin AT cygwin DOT com
Red Hat
#include <stdio.h>
#include <unistd.h>
#define _WIN32_WINNT 0x0501
#include <windows.h>

int
error (const char *funcname)
{
  fprintf (stderr, "%s: %d\n", funcname, GetLastError());
  return 1;
}

char *
convert_sid_to_string_sid (const PSID psid, char *sid_str)
{
  char t[32];
  DWORD i;

  if (!psid)
    return NULL;
  strcpy (sid_str, "S-1-");
  sprintf(t, "%u", GetSidIdentifierAuthority (psid)->Value[5]);
  strcat (sid_str, t);
  for (i = 0; i < *GetSidSubAuthorityCount (psid); ++i)
    {
      sprintf(t, "-%lu", *GetSidSubAuthority (psid, i));
      strcat (sid_str, t);
    }
  return sid_str;
}

HANDLE tok;
char buf[4096];
DWORD size;

PVOID
gti (TOKEN_INFORMATION_CLASS type)
{
  if (GetTokenInformation (tok, type, buf, 4096, &size))
    return (PVOID) buf;
  return NULL;
}

PVOID
hgti (HANDLE token, TOKEN_INFORMATION_CLASS type)
{
  if (GetTokenInformation (token, type, buf, 4096, &size))
    return (PVOID) buf;
  return NULL;
}

void
print_acl (PACL acl)
{
  printf ("\n");
  if (! acl)
    printf ("empty\n");
  else for (DWORD i = 0; i < acl->AceCount; ++i)
    {
      ACCESS_ALLOWED_ACE *ace;

      if (!GetAce (acl, i, (PVOID *) &ace))
        continue;
      switch (ace->Header.AceType)
        {
        case ACCESS_ALLOWED_ACE_TYPE:
          printf ("  allow ");
          break;
        case ACCESS_DENIED_ACE_TYPE:
          printf ("  deny  ");
          break;
        default:
          printf ("  unknown\n");
          continue;
        }
      if (ace->Mask & (FILE_READ_DATA|GENERIC_READ))
        printf ("read ");
      if (ace->Mask & (FILE_WRITE_DATA|GENERIC_WRITE))
        printf ("write ");
      if (ace->Mask & (FILE_EXECUTE|GENERIC_EXECUTE))
        printf ("exec ");
      if (ace->Mask & GENERIC_ALL)
        printf ("all ");
      if (ace->Mask & MAXIMUM_ALLOWED)
        printf ("max ");
      PSID sid = (PSID) &ace->SidStart;
      char ssid[256];
      printf ("%lx %s\n", ace->Mask,
                          convert_sid_to_string_sid (sid, ssid));
    }
}

void
print_default_dacl ()
{
  TOKEN_DEFAULT_DACL *dacl = (TOKEN_DEFAULT_DACL *) gti (TokenDefaultDacl);

  printf ("DefaultDacl: ");
  if (dacl)
    print_acl (dacl->DefaultDacl);
  else
    printf ("unreadable\n");
}

void
print_groups (TOKEN_INFORMATION_CLASS what, const char *disp_what)
{
  TOKEN_GROUPS *groups = (TOKEN_GROUPS *) gti (what);

  printf ("%s: ", disp_what);
  if (groups)
    {
      printf ("\n");
      for (DWORD i = 0; i < groups->GroupCount; ++i)
        {
          char ssid[256];
          printf ("  %s ",
                  convert_sid_to_string_sid (groups->Groups[i].Sid, ssid));
          if (groups->Groups[i].Attributes & SE_GROUP_ENABLED)
            printf ("enabled ");
          if (groups->Groups[i].Attributes & SE_GROUP_ENABLED_BY_DEFAULT)
            printf ("default ");
          if (groups->Groups[i].Attributes & SE_GROUP_LOGON_ID)
            printf ("logon_id ");
          if (groups->Groups[i].Attributes & SE_GROUP_MANDATORY)
            printf ("mandatory ");
          if (groups->Groups[i].Attributes & SE_GROUP_OWNER)
            printf ("owner ");
          if (groups->Groups[i].Attributes & SE_GROUP_RESOURCE)
            printf ("resource ");
          if (groups->Groups[i].Attributes & SE_GROUP_USE_FOR_DENY_ONLY)
            printf ("deny_only ");
          printf ("\n");
        }
    }
  else
    printf ("unreadable\n");
}

void
print_impersonation_level ()
{
  SECURITY_IMPERSONATION_LEVEL *imp =
        (SECURITY_IMPERSONATION_LEVEL *) gti (TokenImpersonationLevel);

  printf ("Impersonation Level: ");
  if (imp)
    switch (*imp)
      {
      case SecurityAnonymous:
        printf ("SecurityAnonymous\n");
        break;
      case SecurityIdentification:
        printf ("SecurityIdentification\n");
        break;
      case SecurityImpersonation:
        printf ("SecurityImpersonation\n");
        break;
      case SecurityDelegation:
        printf ("SecurityDelegation\n");
      default:
        printf ("unknown: %d\n", *imp);
      }
  else
    printf ("Primary Token\n");
}

void
print_owner ()
{
  TOKEN_OWNER *owner = (TOKEN_OWNER *) gti (TokenOwner);
  char ssid[256];

  printf ("Owner: ");
  if (owner)
    printf ("%s\n", convert_sid_to_string_sid (owner->Owner, ssid));
  else
    printf ("unreadable\n");
}

void
print_primary_group ()
{
  TOKEN_PRIMARY_GROUP *primary_group =
        (TOKEN_PRIMARY_GROUP *) gti (TokenPrimaryGroup);
  char ssid[256];

  printf ("Primary Group: ");
  if (primary_group)
    printf ("%s\n",
            convert_sid_to_string_sid (primary_group->PrimaryGroup, ssid));
  else
    printf ("unreadable\n");
}

void
print_privileges ()
{
  TOKEN_PRIVILEGES *privs = (TOKEN_PRIVILEGES *) gti (TokenPrivileges);

  printf ("Privileges: ");
  if (privs)
    {
      printf ("\n");
      for (DWORD i = 0; i < privs->PrivilegeCount; ++i)
        {
          DWORD siz;
          char privbuf[256];
          if (LookupPrivilegeName (NULL, &privs->Privileges[i].Luid,
                                   privbuf, (siz = 256, &siz)))
            {
              printf ("  %s ", privbuf);
              char dispbuf[256];
              DWORD lang_id;
              if (LookupPrivilegeDisplayName (NULL, privbuf, dispbuf,
                                              (siz = 256, &siz), &lang_id))
                printf ("\"%s\" ", dispbuf);
            }
          else
            printf ("unreadable: %lu %lu ", privs->Privileges[i].Luid.HighPart,
                                            privs->Privileges[i].Luid.LowPart);
          if (privs->Privileges[i].Attributes & SE_PRIVILEGE_ENABLED)
            printf ("enabled ");
          if (privs->Privileges[i].Attributes & SE_PRIVILEGE_ENABLED_BY_DEFAULT)
            printf ("default ");
          if (privs->Privileges[i].Attributes & SE_PRIVILEGE_USED_FOR_ACCESS)
            printf ("access ");
          printf ("\n");
        }
    }
  else
    printf ("unreadable\n");
}

void
print_source ()
{
  TOKEN_SOURCE *source = (TOKEN_SOURCE *) gti (TokenSource);

  printf ("Source: ");
  if (source)
    printf ("%8.8s %ld %lu\n", source->SourceName,
                               source->SourceIdentifier.HighPart,
                               source->SourceIdentifier.LowPart);
  else
    printf ("unreadable\n");
}

void print_type ()
{
  TOKEN_TYPE *type = (TOKEN_TYPE *) gti (TokenType);

  printf ("Type: ");
  if (type)
    {
      if (*type == TokenPrimary)
        printf ("Primary\n");
      else if (*type == TokenImpersonation)
        printf ("Impersonation\n");
      else
        printf ("Unknown\n");
    }
  else
    printf ("unreadable\n");
}

void
print_user ()
{
  TOKEN_USER *user = (TOKEN_USER *) gti (TokenUser);
  char ssid[256];

  printf ("User: ");
  if (user)
    printf ("%s\n", convert_sid_to_string_sid (user->User.Sid, ssid));
  else
    printf ("unreadable\n");
}
void
print_token_statistics ()
{
  TOKEN_STATISTICS *stats = (TOKEN_STATISTICS *) gti (TokenStatistics);

  printf ("Statistics: ");
  if (stats)
    {
      printf ("TokenId: %lu %lu\n", stats->TokenId.HighPart,
                                    stats->TokenId.LowPart);
      printf ("AuthenticationId: %lu %lu\n", stats->AuthenticationId.HighPart,
                                             stats->AuthenticationId.LowPart);
      printf ("ExpirationTime: %lx%lx\n", stats->ExpirationTime.HighPart,
                                          stats->ExpirationTime.LowPart);
      printf ("TokenType: ");
      if (stats->TokenType == TokenPrimary)
        printf ("Primary\n");
      else if (stats->TokenType == TokenImpersonation)
        printf ("Impersonation\n");
      else
        printf ("Unknown: %d\n", stats->TokenType);
      printf ("ImpersonationLevel: ");
      switch (stats->ImpersonationLevel)
        {
        case SecurityAnonymous:
          printf ("SecurityAnonymous\n");
          break;
        case SecurityIdentification:
          printf ("SecurityIdentification\n");
          break;
        case SecurityImpersonation:
          printf ("SecurityImpersonation\n");
          break;
        case SecurityDelegation:
          printf ("SecurityDelegation\n");
        default:
          printf ("unknown: %d\n", stats->ImpersonationLevel);
        }
      printf ("DynamicCharged: %lu\n", stats->DynamicCharged);
      printf ("DynamicAvailable: %lu\n", stats->DynamicAvailable);
      printf ("GroupCount: %lu\n", stats->GroupCount);
      printf ("PrivilegeCount: %lu\n", stats->PrivilegeCount);
      printf ("ModifiedId: %lu %lu\n", stats->ModifiedId.HighPart,
                                    stats->ModifiedId.LowPart);
    }
  else
    printf ("unreadable\n");
}

void
print_security_descriptor (HANDLE token)
{
  char sd_buf[4096];
  DWORD lret = 0;
  PSECURITY_DESCRIPTOR sd = (PSECURITY_DESCRIPTOR) sd_buf;

  printf ("SecurityDescriptor: ");
  if (!GetKernelObjectSecurity (token,
                                OWNER_SECURITY_INFORMATION
                                | GROUP_SECURITY_INFORMATION
                                | DACL_SECURITY_INFORMATION,
                                sd, 4096, &lret))
    {
      printf ("unreadable, ");
      if (lret > 4096)
        printf ("Security descriptor should be %lu bytes\n", lret);
      else
        printf ("GetKernelObjectSecurity ging nich: %lu\n", GetLastError ());
      return;
    }

  char ssid[256];
  PSID sid;
  BOOL dummy;

  if (!GetSecurityDescriptorOwner (sd, &sid, &dummy))
    printf ("\n  GetSecurityDescriptorOwner %lu", GetLastError ());
  else
    printf ("\n  Owner: %s", convert_sid_to_string_sid (sid, ssid));

  if (!GetSecurityDescriptorGroup (sd, &sid, &dummy))
    printf ("\n  GetSecurityDescriptorGroup %lu", GetLastError ());
  else
    printf ("\n  Group: %s", convert_sid_to_string_sid (sid, ssid));

  PACL acl;
  BOOL acl_exists;
        
  if (!GetSecurityDescriptorDacl (sd, &acl_exists, &acl, &dummy))
    printf ("\n  GetSecurityDescriptorDacl %lu\n", GetLastError ());
  else
    print_acl (acl);
}

void
print_token_info (HANDLE token, BOOL with_privs)
{
  tok = token;
  print_type ();
  print_impersonation_level ();
  print_source ();
  print_owner ();
  print_user ();
  print_primary_group ();
  print_groups (TokenGroups, "Groups");
  print_default_dacl ();
  print_security_descriptor (token);
  print_token_statistics ();
  if (with_privs)
    print_privileges ();
  print_groups (TokenRestrictedSids, "RestrictedSids");
}

#ifndef NTCT

int
main (int argc, char **argv)
{
  HANDLE token;

  if (!OpenProcessToken (GetCurrentProcess (),
                         MAXIMUM_ALLOWED, //TOKEN_QUERY|TOKEN_QUERY_SOURCE,
                         &token))
    return error ("OpenProcessToken");
  print_token_info (token, argc > 1);
  return 0;
}

#endif

--
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/

Reply via email to