--- a/getent-2.18.90/getent.c 2014-02-20 17:31:43.000000000 +0100 +++ b/getent-2.18.90/getent.c 2014-11-18 11:26:56.195442795 +0100 @@ -18,30 +18,69 @@ /* getent: get entries from administrative database. */ -#include +//#include #include #include #include #include +#ifndef __CYGWIN__ #include #include +#endif #include +#ifndef __CYGWIN__ #include +#endif #include #include +#ifndef __CYGWIN__ #include +#endif #include #include #include #include #include #include +#ifndef __CYGWIN__ #include +#endif #include #include +#ifndef __CYGWIN__ /* Get libc version number. */ #include +#else +#include +#include +#include +#include + +#define _(string) (string) +#define N_(string) (string) +#define textdomain(string) +#define gettext(string) (string) + +#define fputc_unlocked fputc +#define fputs_unlocked fputs +#define putchar_unlocked putchar + +#define PKGVERSION "(Cygwin)" +#define VERSION "2.18.90" /* glibc version we took getent from. */ +#define REPORT_BUGS_TO "http://cygwin.com/problems.html" + +# define stackinfo_alloca_round(l) (((l) + 15) & -16) +# define extend_alloca(buf, len, newlen) \ + (__typeof (buf)) ({ size_t __newlen = stackinfo_alloca_round (newlen); \ + char *__newbuf = alloca (__newlen); \ + if (__newbuf + __newlen == (char *) buf) \ + len += __newlen; \ + else \ + len = __newlen; \ + __newbuf; }) + +#endif /* !__CYGWIN__ */ #define PACKAGE _libc_intl_domainname @@ -57,6 +96,9 @@ static const struct argp_option args_opt { { "service", 's', N_("CONFIG"), 0, N_("Service configuration to be used") }, { "no-idn", 'i', NULL, 0, N_("disable IDN encoding") }, +#ifdef __CYGWIN__ + { "windows", 'w', NULL, 0, N_("Cygwin:Windows account mapping only (with passwd and group databases)") }, +#endif { NULL, 0, NULL, 0, NULL }, }; @@ -78,6 +120,10 @@ static struct argp argp = /* Additional getaddrinfo flags for IDN encoding. */ static int idn_flags = AI_IDN | AI_CANONIDN; +#ifdef __CYGWIN__ +static int windows_only = 0; +#endif + /* Print the version information. */ static void print_version (FILE *stream, struct argp_state *state) @@ -91,6 +137,7 @@ warranty; not even for MERCHANTABILITY o fprintf (stream, gettext ("Written by %s.\n"), "Thorsten Kukuk"); } +#ifndef __CYGWIN__ /* This is for aliases */ static void print_aliases (struct aliasent *alias) @@ -179,6 +226,78 @@ ethers_keys (int number, char *key[]) return result; } +#endif /* !__CYGWIN__ */ + +#ifdef __CYGWIN__ +static PSID +get_sid_from_special_string (const char *key, PBOOL try_as_cygname) +{ + PSID sid = NULL; + + if (!strncmp (key, "U-", 2)) + { + WCHAR wnam[4096]; + + /* DNLEN is moot. Domain names can now be twice as long. */ + WCHAR dom[32]; + DWORD dlen = 32; + DWORD slen = SECURITY_MAX_SID_SIZE; + SID_NAME_USE use; + + memset (wnam, 0, sizeof wnam); + mbstowcs (wnam, key + 2, sizeof wnam / sizeof (wchar_t) - 1); + sid = (PSID) LocalAlloc (LMEM_FIXED, SECURITY_MAX_SID_SIZE); + if (sid && !LookupAccountNameW (NULL, wnam, sid, &slen, + dom, &dlen, &use)) + { + LocalFree (sid); + sid = NULL; + } + if (sid + && (use == SidTypeDomain || use == SidTypeComputer) + && wcslen (wnam) < sizeof wnam / sizeof (wchar_t) / 2 - 2) + { + wcpcpy (wnam + wcslen (wnam) + 1, wnam); + wnam[wcslen (wnam)] = L'\\'; + dlen = 32; + slen = SECURITY_MAX_SID_SIZE; + if (!LookupAccountNameW (NULL, wnam, sid, &slen, + dom, &dlen, &use)) + { + LocalFree (sid); + sid = NULL; + } + } + } + else if (!strncmp (key, "S-1-", 4)) + { + *try_as_cygname = TRUE; + ConvertStringSidToSidA (key, &sid); + } + return sid; +} + +static void +print_windows_mapping (const char *cygname, unsigned long id, + const char *sid_string) +{ + PSID sid; + WCHAR name[NAME_MAX + 1]; + DWORD nlen = NAME_MAX + 1; + /* DNLEN is moot. Domain names can now be twice as long. */ + WCHAR dom[32]; + DWORD dlen = 32; + SID_NAME_USE use; + + if (!cygname || !sid_string) + return; + if (!ConvertStringSidToSidA (sid_string, &sid)) + return; + if (LookupAccountSidW (NULL, sid, name, &nlen, dom, &dlen, &use)) + printf ("%s:%lu:%ls\\%ls:%s\n", cygname, id, dom, name, sid_string); + LocalFree (sid); +} +#endif /* This is for group */ static void @@ -186,6 +305,18 @@ print_group (struct group *grp) { unsigned int i = 0; +#ifdef __CYGWIN__ + /* Disable printing gid -1, the fallback invalid group called "????????" on + Cygwin versions prior to the introduction of direct SAM/AD access. */ + if (grp->gr_gid == (gid_t) -1) + return; + if (windows_only) + { + print_windows_mapping (grp->gr_name, (unsigned long) grp->gr_gid, + grp->gr_passwd); + return; + } +#endif printf ("%s:%s:%lu:", grp->gr_name ? grp->gr_name : "", grp->gr_passwd ? grp->gr_passwd : "", (unsigned long int) grp->gr_gid); @@ -205,7 +336,7 @@ group_keys (int number, char *key[]) { int result = 0; int i; - struct group *grp; + struct group *grp = NULL; if (number == 0) { @@ -225,8 +356,27 @@ group_keys (int number, char *key[]) if (errno != EINVAL && *key[i] != '\0' && *ep == '\0') /* Valid numeric gid. */ grp = getgrgid (arg_gid); +#ifdef __CYGWIN__ + /* Allow searching for Windows SIDs. */ + else + { + BOOL try_as_cygname = FALSE; + PSID sid = get_sid_from_special_string (key[i], &try_as_cygname); + + if (sid) + { + grp = (struct group *) cygwin_internal (CW_GETGRSID, 0, sid); + if (grp == (struct group *) -1) /* pre 1.7.29 Cygwin */ + grp = NULL; + LocalFree (sid); + } + else if (!try_as_cygname) + grp = getgrnam (key[i]); + } +#else else grp = getgrnam (key[i]); +#endif if (grp == NULL) result = 2; @@ -237,6 +387,7 @@ group_keys (int number, char *key[]) return result; } +#ifndef __CYGWIN__ /* This is for gshadow */ static void print_gshadow (struct sgrp *sg) @@ -300,6 +451,7 @@ gshadow_keys (int number, char *key[]) return result; } +#endif /* !__CYGWIN__ */ /* This is for hosts */ static void @@ -334,11 +486,16 @@ hosts_keys (int number, char *key[]) if (number == 0) { +#ifdef __CYGWIN__ + fprintf (stderr, _("Enumeration not supported on %s\n"), "hosts"); + return 3; +#else sethostent (0); while ((host = gethostent ()) != NULL) print_hosts (host); endhostent (); return result; +#endif /* !__CYGWIN__ */ } for (i = 0; i < number; ++i) @@ -372,11 +529,16 @@ ahosts_keys_int (int af, int xflags, int if (number == 0) { +#ifdef __CYGWIN__ + fprintf (stderr, _("Enumeration not supported on %s\n"), "hosts"); + return 3; +#else sethostent (0); while ((host = gethostent ()) != NULL) print_hosts (host); endhostent (); return result; +#endif /* !__CYGWIN__ */ } struct addrinfo hint; @@ -466,6 +628,7 @@ ahostsv6_keys (int number, char *key[]) return ahosts_keys_int (AF_INET6, AI_V4MAPPED, number, key); } +#ifndef __CYGWIN__ /* This is for netgroup */ static int netgroup_keys (int number, char *key[]) @@ -508,6 +671,7 @@ netgroup_keys (int number, char *key[]) return result; } +#endif /* !__CYGWIN__ */ /* This is for initgroups */ static int @@ -547,6 +711,7 @@ initgroups_keys (int number, char *key[] return 0; } +#ifndef __CYGWIN__ /* This is for networks */ static void print_networks (struct netent *net) @@ -598,11 +763,24 @@ networks_keys (int number, char *key[]) return result; } +#endif /* !__CYGWIN__ */ /* Now is all for passwd */ static void print_passwd (struct passwd *pwd) { +#ifdef __CYGWIN__ + /* Disable printing uid -1, the fallback invalid user called "????????" on + Cygwin versions prior to the introduction of direct SAM/AD access. */ + if (pwd->pw_uid == (uid_t) -1) + return; + if (windows_only) + { + char *c = strstr (pwd->pw_gecos, "S-1-"); + print_windows_mapping (pwd->pw_name, (unsigned long) pwd->pw_uid, c); + return; + } +#endif printf ("%s:%s:%lu:%lu:%s:%s:%s\n", pwd->pw_name ? pwd->pw_name : "", pwd->pw_passwd ? pwd->pw_passwd : "", @@ -618,7 +796,7 @@ passwd_keys (int number, char *key[]) { int result = 0; int i; - struct passwd *pwd; + struct passwd *pwd = NULL; if (number == 0) { @@ -638,8 +816,27 @@ passwd_keys (int number, char *key[]) if (errno != EINVAL && *key[i] != '\0' && *ep == '\0') /* Valid numeric uid. */ pwd = getpwuid (arg_uid); +#ifdef __CYGWIN__ + /* Allow searching for Windows SIDs. */ + else + { + BOOL try_as_cygname = FALSE; + PSID sid = get_sid_from_special_string (key[i], &try_as_cygname); + + if (sid) + { + pwd = (struct passwd *) cygwin_internal (CW_GETPWSID, 0, sid); + if (pwd == (struct passwd *) -1) /* pre 1.7.29 Cygwin */ + pwd = NULL; + LocalFree (sid); + } + else if (!try_as_cygname) + pwd = getpwnam (key[i]); + } +#else else pwd = getpwnam (key[i]); +#endif if (pwd == NULL) result = 2; @@ -700,6 +897,7 @@ protocols_keys (int number, char *key[]) return result; } +#ifndef __CYGWIN__ /* Now is all for rpc */ static void print_rpc (struct rpcent *rpc) @@ -745,6 +943,7 @@ rpc_keys (int number, char *key[]) return result; } +#endif /* !__CYGWIN__ */ /* for services */ static void @@ -806,6 +1005,7 @@ services_keys (int number, char *key[]) return result; } +#ifndef __CYGWIN__ /* This is for shadow */ static void print_shadow (struct spwd *sp) @@ -863,6 +1063,7 @@ shadow_keys (int number, char *key[]) return result; } +#endif /* !__CYGWIN__ */ struct { @@ -874,19 +1075,29 @@ struct D(ahosts) D(ahostsv4) D(ahostsv6) +#ifndef __CYGWIN__ D(aliases) D(ethers) +#endif /* !__CYGWIN__ */ D(group) +#ifndef __CYGWIN__ D(gshadow) +#endif /* !__CYGWIN__ */ D(hosts) D(initgroups) +#ifndef __CYGWIN__ D(netgroup) D(networks) +#endif /* !__CYGWIN__ */ D(passwd) D(protocols) +#ifndef __CYGWIN__ D(rpc) +#endif /* !__CYGWIN__ */ D(services) +#ifndef __CYGWIN__ D(shadow) +#endif /* !__CYGWIN__ */ #undef D { NULL, NULL } }; @@ -899,6 +1110,7 @@ parse_option (int key, char *arg, struct switch (key) { case 's': +#ifndef __CYGWIN__ endp = strchr (arg, ':'); if (endp == NULL) /* No specific database, change them all. */ @@ -916,12 +1128,19 @@ parse_option (int key, char *arg, struct if (databases[i].name == NULL) error (EXIT_FAILURE, 0, gettext ("Unknown database name")); } +#endif /* !__CYGWIN__ */ break; case 'i': idn_flags = 0; break; +#ifdef __CYGWIN__ + case 'w': + windows_only = 1; + break; +#endif + default: return ARGP_ERR_UNKNOWN; } @@ -986,8 +1205,10 @@ For bug reporting instructions, please s int main (int argc, char *argv[]) { +#ifndef __CYGWIN__ /* Debugging support. */ mtrace (); +#endif /* !__CYGWIN__ */ /* Set locale via LC_ALL. */ setlocale (LC_ALL, "");