#include #include #include #include #include #include #include #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); }