]> sourceware.org Git - newlib-cygwin.git/commitdiff
* mkgroup.c (domlist_t): Drop id_offset.
authorCorinna Vinschen <corinna@vinschen.de>
Mon, 24 Feb 2014 10:51:42 +0000 (10:51 +0000)
committerCorinna Vinschen <corinna@vinschen.de>
Mon, 24 Feb 2014 10:51:42 +0000 (10:51 +0000)
(get_dcname): Remove.
(current_group): Remove.
(enum_unix_groups): Simplify.  Change space to underscore in domain
name.
(enum_local_groups): Simplify to accommodate the fact that it's only
called for foreign machines.
(enum_groups): Ditto.
(print_special_by_sid): Remove.
(print_special_by_name): Remove.
(usage): Align to new code.
(fetch_primary_domain): Remove.
(main): Use cygwin_internal CW_SETENT, CW_GETENT and CW_ENDENT method.
Call enum_local_groups, enum_groups, and enum_unix_groups only for
foreign machines.
* mkpasswd.c (get_dcname): Remove.
(current_user): Remove.
(enum_unix_users): Simplify.  Change space to underscore in domain name.
(enum_users): Simplify to accommodate the fact that it's only
called for foreign machines.
(print_special_by_sid): Remove.
(usage): Align to new code.
(longopts): Add -b/--no-builtin option.
(opts): Add -b option.
(print_special_by_name): Remove.
(enum_std_accounts): Remove.
(fetch_primary_domain): Remove.
(main): Use cygwin_internal CW_SETENT, CW_GETENT and CW_ENDENT method.
Call enum_users and enum_unix_users only for foreign machines.
* utils.xml (mkgroup): Align documentation to new usage.
(mkpasswd): Ditto.

winsup/utils/ChangeLog
winsup/utils/mkgroup.c
winsup/utils/mkpasswd.c
winsup/utils/utils.xml

index 63b5e953e9d929b58893b719ffd5df8bc698c4f3..84281496951bbc7421dc57a18485315fb8a6a2ff 100644 (file)
@@ -1,3 +1,37 @@
+2013-11-24  Corinna Vinschen  <corinna@vinschen.de>
+
+       * mkgroup.c (domlist_t): Drop id_offset.
+       (get_dcname): Remove.
+       (current_group): Remove.
+       (enum_unix_groups): Simplify.  Change space to underscore in domain
+       name.
+       (enum_local_groups): Simplify to accommodate the fact that it's only
+       called for foreign machines.
+       (enum_groups): Ditto.
+       (print_special_by_sid): Remove.
+       (print_special_by_name): Remove.
+       (usage): Align to new code.
+       (fetch_primary_domain): Remove.
+       (main): Use cygwin_internal CW_SETENT, CW_GETENT and CW_ENDENT method.
+       Call enum_local_groups, enum_groups, and enum_unix_groups only for
+       foreign machines.
+       * mkpasswd.c (get_dcname): Remove.
+       (current_user): Remove.
+       (enum_unix_users): Simplify.  Change space to underscore in domain name.
+       (enum_users): Simplify to accommodate the fact that it's only
+       called for foreign machines.
+       (print_special_by_sid): Remove.
+       (usage): Align to new code.
+       (longopts): Add -b/--no-builtin option.
+       (opts): Add -b option.
+       (print_special_by_name): Remove.
+       (enum_std_accounts): Remove.
+       (fetch_primary_domain): Remove.
+       (main): Use cygwin_internal CW_SETENT, CW_GETENT and CW_ENDENT method.
+       Call enum_users and enum_unix_users only for foreign machines.
+       * utils.xml (mkgroup): Align documentation to new usage.
+       (mkpasswd): Ditto.
+
 2014-02-23  Jon TURNEY  <jon.turney@dronecode.org.uk>
 
        * minidumper.cc (minidump): Fix -t option argument handling.
index 05f5910b0200921077a2a12c4e886f37966ba7df..7b102ec994eecf474b7e592aaa46856bf384cb5b 100644 (file)
@@ -1,7 +1,7 @@
 /* mkgroup.c:
 
    Copyright 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007,
-   2008, 2009, 2010, 2011, 2012, 2013 Red Hat, Inc.
+   2008, 2009, 2010, 2011, 2012, 2013, 2014 Red Hat, Inc.
 
    This file is part of Cygwin.
 
@@ -21,6 +21,7 @@
 #include <inttypes.h>
 #include <getopt.h>
 #include <io.h>
+#include <grp.h>
 #include <sys/fcntl.h>
 #include <sys/cygwin.h>
 #include <cygwin/version.h>
@@ -29,9 +30,7 @@
 #include <wininet.h>
 #include <iptypes.h>
 #include <ntsecapi.h>
-#include <dsgetdc.h>
 #include <ntdef.h>
-#include "loadlib.h"
 
 #define print_win_error(x) _print_win_error(x, __LINE__)
 
@@ -47,7 +46,6 @@ SID_IDENTIFIER_AUTHORITY sid_nt_auth = {SECURITY_NT_AUTHORITY};
 typedef struct
 {
   char *str;
-  DWORD id_offset;
   BOOL domain;
   BOOL with_dom;
 } domlist_t;
@@ -70,31 +68,6 @@ _print_win_error (DWORD code, int line)
             line, (unsigned int) code);
 }
 
-static PWCHAR
-get_dcname (char *domain)
-{
-  static WCHAR server[INTERNET_MAX_HOST_NAME_LENGTH + 1];
-  DWORD rc;
-  WCHAR domain_name[MAX_DOMAIN_NAME_LEN + 1];
-  PDOMAIN_CONTROLLER_INFOW pdci = NULL;
-
-  if (domain)
-    {
-      mbstowcs (domain_name, domain, strlen (domain) + 1);
-      rc = DsGetDcNameW (NULL, domain_name, NULL, NULL, 0, &pdci);
-    }
-  else
-    rc = DsGetDcNameW (NULL, NULL, NULL, NULL, 0, &pdci);
-  if (rc != ERROR_SUCCESS)
-    {
-      print_win_error (rc);
-      return (PWCHAR) -1;
-    }
-  wcscpy (server, pdci->DomainControllerName);
-  NetApiBufferFree (pdci);
-  return server;
-}
-
 static char *
 put_sid (PSID psid)
 {
@@ -149,40 +122,10 @@ fetch_current_pgrp_sid ()
 }
 
 static void
-current_group (const char *sep, DWORD id_offset)
-{
-  WCHAR grp[GNLEN + 1];
-  WCHAR dom[MAX_DOMAIN_NAME_LEN + 1];
-  DWORD glen = GNLEN + 1;
-  DWORD dlen = MAX_DOMAIN_NAME_LEN + 1;
-  int gid;
-  SID_NAME_USE acc_type;
-
-  if (!curr_pgrp.psid
-      || !LookupAccountSidW (NULL, curr_pgrp.psid, grp, &glen, dom, &dlen,
-                            &acc_type))
-    {
-      print_win_error (GetLastError ());
-      return;
-    }
-  gid = *GetSidSubAuthority (curr_pgrp.psid,
-                            *GetSidSubAuthorityCount(curr_pgrp.psid) - 1);
-  printf ("%ls%s%ls:%s:%" PRIu32 ":\n",
-         sep ? dom : L"",
-         sep ?: "",
-         grp,
-         put_sid (curr_pgrp.psid),
-         (unsigned int) (id_offset + gid));
-}
-
-static void
-enum_unix_groups (domlist_t *dom_or_machine, const char *sep, DWORD id_offset,
+enum_unix_groups (domlist_t *mach, const char *sep, DWORD id_offset,
                  char *unix_grp_list)
 {
   WCHAR machine[INTERNET_MAX_HOST_NAME_LENGTH + 1];
-  PWCHAR servername = NULL;
-  char *d_or_m = dom_or_machine ? dom_or_machine->str : NULL;
-  BOOL with_dom = dom_or_machine ? dom_or_machine->with_dom : FALSE;
   SID_IDENTIFIER_AUTHORITY auth = { { 0, 0, 0, 0, 0, 22 } };
   char *gstr, *grp_list;
   WCHAR grp[GNLEN + sizeof ("Unix Group\\") + 1];
@@ -192,17 +135,13 @@ enum_unix_groups (domlist_t *dom_or_machine, const char *sep, DWORD id_offset,
   char psid_buffer[MAX_SID_LEN];
   SID_NAME_USE acc_type;
 
-  if (!d_or_m)
-    return;
-
-  int ret = mbstowcs (machine, d_or_m, INTERNET_MAX_HOST_NAME_LENGTH + 1);
+  int ret = mbstowcs (machine, mach->str, INTERNET_MAX_HOST_NAME_LENGTH + 1);
   if (ret < 1 || ret >= INTERNET_MAX_HOST_NAME_LENGTH + 1)
     {
       fprintf (stderr, "%s: Invalid machine name '%s'.  Skipping...\n",
-              program_invocation_short_name, d_or_m);
+              program_invocation_short_name, mach->str);
       return;
     }
-  servername = machine;
 
   if (!AllocateAndInitializeSid (&auth, 2, 2, 0, 0, 0, 0, 0, 0, 0, &psid))
     return;
@@ -222,15 +161,15 @@ enum_unix_groups (domlist_t *dom_or_machine, const char *sep, DWORD id_offset,
          if (ret < 1 || ret >= GNLEN + 1)
            fprintf (stderr, "%s: Invalid group name '%s'.  Skipping...\n",
                     program_invocation_short_name, gstr);
-         else if (LookupAccountNameW (servername, grp,
+         else if (LookupAccountNameW (machine, grp,
                                       psid = (PSID) psid_buffer,
                                       (sidlen = MAX_SID_LEN, &sidlen),
                                       dom,
                                       (dlen = MAX_DOMAIN_NAME_LEN + 1, &dlen),
                                       &acc_type))
            printf ("%s%s%ls:%s:%" PRIu32 ":\n",
-                   with_dom ? "Unix Group" : "",
-                   with_dom ? sep : "",
+                   mach->with_dom ? "Unix_Group" : "",
+                   mach->with_dom ? sep : "",
                    p,
                    put_sid (psid),
                    (unsigned int) (id_offset +
@@ -259,15 +198,15 @@ enum_unix_groups (domlist_t *dom_or_machine, const char *sep, DWORD id_offset,
            {
              *GetSidSubAuthority (psid, *GetSidSubAuthorityCount(psid) - 1)
              = start;
-             if (LookupAccountSidW (servername, psid,
+             if (LookupAccountSidW (machine, psid,
                                     grp, (glen = GNLEN + 1, &glen),
                                     dom,
                                     (dlen = MAX_DOMAIN_NAME_LEN + 1, &dlen),
                                     &acc_type)
                  && !iswdigit (grp[0]))
                printf ("%s%s%ls:%s:%" PRIu32 ":\n",
-                       with_dom ? "Unix Group" : "",
-                       with_dom ? sep : "",
+                       mach->with_dom ? "Unix_Group" : "",
+                       mach->with_dom ? sep : "",
                        grp,
                        put_sid (psid),
                        (unsigned int) (id_offset + start));
@@ -280,14 +219,11 @@ enum_unix_groups (domlist_t *dom_or_machine, const char *sep, DWORD id_offset,
 }
 
 static int
-enum_local_groups (BOOL domain, domlist_t *dom_or_machine, const char *sep,
+enum_local_groups (domlist_t *mach, const char *sep,
                   DWORD id_offset, char *disp_groupname, int print_builtin,
                   int print_current)
 {
   WCHAR machine[INTERNET_MAX_HOST_NAME_LENGTH + 1];
-  PWCHAR servername = NULL;
-  char *d_or_m = dom_or_machine ? dom_or_machine->str : NULL;
-  BOOL with_dom = dom_or_machine ? dom_or_machine->with_dom : FALSE;
   LOCALGROUP_INFO_0 *buffer;
   DWORD entriesread = 0;
   DWORD totalentries = 0;
@@ -295,22 +231,12 @@ enum_local_groups (BOOL domain, domlist_t *dom_or_machine, const char *sep,
   WCHAR gname[GNLEN + 1];
   DWORD rc;
 
-  if (domain)
-    {
-      servername = get_dcname (d_or_m);
-      if (servername == (PWCHAR) -1)
-       return 1;
-    }
-  else if (d_or_m)
+  int ret = mbstowcs (machine, mach->str, INTERNET_MAX_HOST_NAME_LENGTH + 1);
+  if (ret < 1 || ret >= INTERNET_MAX_HOST_NAME_LENGTH + 1)
     {
-      int ret = mbstowcs (machine, d_or_m, INTERNET_MAX_HOST_NAME_LENGTH + 1);
-      if (ret < 1 || ret >= INTERNET_MAX_HOST_NAME_LENGTH + 1)
-       {
-         fprintf (stderr, "%s: Invalid machine name '%s'.  Skipping...\n",
-                  program_invocation_short_name, d_or_m);
-         return 1;
-       }
-      servername = machine;
+      fprintf (stderr, "%s: Invalid machine name '%s'.  Skipping...\n",
+              program_invocation_short_name, mach->str);
+      return 1;
     }
 
   do
@@ -320,7 +246,7 @@ enum_local_groups (BOOL domain, domlist_t *dom_or_machine, const char *sep,
       if (disp_groupname)
        {
          mbstowcs (gname, disp_groupname, GNLEN + 1);
-         rc = NetLocalGroupGetInfo (servername, gname, 0, (void *) &buffer);
+         rc = NetLocalGroupGetInfo (machine, gname, 0, (void *) &buffer);
          if (rc == ERROR_SUCCESS)
            entriesread = 1;
          /* Allow further searching for the group and avoid annoying
@@ -330,7 +256,7 @@ enum_local_groups (BOOL domain, domlist_t *dom_or_machine, const char *sep,
            return 0;
        }
       else
-       rc = NetLocalGroupEnum (servername, 0, (void *) &buffer,
+       rc = NetLocalGroupEnum (machine, 0, (void *) &buffer,
                                MAX_PREFERRED_LENGTH, &entriesread,
                                &totalentries, &resume_handle);
       switch (rc)
@@ -360,7 +286,7 @@ enum_local_groups (BOOL domain, domlist_t *dom_or_machine, const char *sep,
          PDBGSID pdsid;
          BOOL is_builtin = FALSE;
 
-         if (!LookupAccountNameW (servername, buffer[i].lgrpi0_name, psid,
+         if (!LookupAccountNameW (machine, buffer[i].lgrpi0_name, psid,
                                   &sid_length, domain_name, &domname_len,
                                   &acc_type))
            {
@@ -377,7 +303,7 @@ enum_local_groups (BOOL domain, domlist_t *dom_or_machine, const char *sep,
              wcscat (domname, buffer[i].lgrpi0_name);
              sid_length = MAX_SID_LEN;
              domname_len = MAX_DOMAIN_NAME_LEN + 1;
-             if (!LookupAccountNameW (servername, domname,
+             if (!LookupAccountNameW (machine, domname,
                                       psid, &sid_length,
                                       domain_name, &domname_len,
                                       &acc_type))
@@ -415,8 +341,8 @@ enum_local_groups (BOOL domain, domlist_t *dom_or_machine, const char *sep,
 
          gid = *GetSidSubAuthority (psid, *GetSidSubAuthorityCount(psid) - 1);
          printf ("%ls%s%ls:%s:%" PRIu32 ":\n",
-                 with_dom && !is_builtin ? domain_name : L"",
-                 with_dom && !is_builtin ? sep : "",
+                 mach->with_dom && !is_builtin ? domain_name : L"",
+                 mach->with_dom || is_builtin ? sep : "",
                  buffer[i].lgrpi0_name,
                  put_sid (psid),
                  (unsigned int) (gid + (is_builtin ? 0 : id_offset)));
@@ -436,13 +362,10 @@ skip_group:
 }
 
 static void
-enum_groups (BOOL domain, domlist_t *dom_or_machine, const char *sep,
-            DWORD id_offset, char *disp_groupname, int print_current)
+enum_groups (domlist_t *mach, const char *sep, DWORD id_offset,
+            char *disp_groupname, int print_current)
 {
   WCHAR machine[INTERNET_MAX_HOST_NAME_LENGTH + 1];
-  PWCHAR servername = NULL;
-  char *d_or_m = dom_or_machine ? dom_or_machine->str : NULL;
-  BOOL with_dom = dom_or_machine ? dom_or_machine->with_dom : FALSE;
   GROUP_INFO_2 *buffer;
   DWORD entriesread = 0;
   DWORD totalentries = 0;
@@ -450,22 +373,12 @@ enum_groups (BOOL domain, domlist_t *dom_or_machine, const char *sep,
   WCHAR gname[GNLEN + 1];
   DWORD rc;
 
-  if (domain)
-    {
-      servername = get_dcname (d_or_m);
-      if (servername == (PWCHAR) -1)
-       return;
-    }
-  else if (d_or_m)
+  int ret = mbstowcs (machine, mach->str, INTERNET_MAX_HOST_NAME_LENGTH + 1);
+  if (ret < 1 || ret >= INTERNET_MAX_HOST_NAME_LENGTH + 1)
     {
-      int ret = mbstowcs (machine, d_or_m, INTERNET_MAX_HOST_NAME_LENGTH + 1);
-      if (ret < 1 || ret >= INTERNET_MAX_HOST_NAME_LENGTH + 1)
-       {
-         fprintf (stderr, "%s: Invalid machine name '%s'.  Skipping...\n",
-                  program_invocation_short_name, d_or_m);
-         return;
-       }
-      servername = machine;
+      fprintf (stderr, "%s: Invalid machine name '%s'.  Skipping...\n",
+              program_invocation_short_name, mach->str);
+      return;
     }
 
   do
@@ -475,8 +388,7 @@ enum_groups (BOOL domain, domlist_t *dom_or_machine, const char *sep,
       if (disp_groupname != NULL)
        {
          mbstowcs (gname, disp_groupname, GNLEN + 1);
-         rc = NetGroupGetInfo (servername, (LPWSTR) & gname, 2,
-                               (void *) &buffer);
+         rc = NetGroupGetInfo (machine, (LPWSTR) & gname, 2, (void *) &buffer);
          entriesread=1;
          /* Avoid annoying error messages just because the group hasn't been
             found. */
@@ -484,9 +396,8 @@ enum_groups (BOOL domain, domlist_t *dom_or_machine, const char *sep,
            return;
        }
       else
-       rc = NetGroupEnum (servername, 2, (void *) & buffer,
-                          MAX_PREFERRED_LENGTH, &entriesread, &totalentries,
-                          &resume_handle);
+       rc = NetGroupEnum (machine, 2, (void *) & buffer, MAX_PREFERRED_LENGTH,
+                          &entriesread, &totalentries, &resume_handle);
       switch (rc)
        {
        case ERROR_ACCESS_DENIED:
@@ -512,7 +423,7 @@ enum_groups (BOOL domain, domlist_t *dom_or_machine, const char *sep,
          SID_NAME_USE acc_type;
 
          int gid = buffer[i].grpi2_group_id;
-         if (!LookupAccountNameW (servername, buffer[i].grpi2_name,
+         if (!LookupAccountNameW (machine, buffer[i].grpi2_name,
                                   psid, &sid_length,
                                   domain_name, &domname_len,
                                   &acc_type))
@@ -525,16 +436,13 @@ enum_groups (BOOL domain, domlist_t *dom_or_machine, const char *sep,
            {
              WCHAR domname[MAX_DOMAIN_NAME_LEN + GNLEN + 2];
 
-             wcscpy (domname, domain || !servername
-                              ? domain_name : servername);
+             wcscpy (domname, machine);
              wcscat (domname, L"\\");
              wcscat (domname, buffer[i].grpi2_name);
              sid_length = MAX_SID_LEN;
              domname_len = MAX_DOMAIN_NAME_LEN + 1;
-             if (!LookupAccountNameW (servername, domname,
-                                      psid, &sid_length,
-                                      domain_name, &domname_len,
-                                      &acc_type))
+             if (!LookupAccountNameW (machine, domname, psid, &sid_length,
+                                      domain_name, &domname_len, &acc_type))
                {
                  print_win_error (GetLastError ());
                  fprintf(stderr, " (%ls)\n", domname);
@@ -547,8 +455,8 @@ enum_groups (BOOL domain, domlist_t *dom_or_machine, const char *sep,
            got_curr_pgrp = TRUE;
 
          printf ("%ls%s%ls:%s:%" PRIu32 ":\n",
-                 with_dom ? domain_name : L"",
-                 with_dom ? sep : "",
+                 mach->with_dom ? domain_name : L"",
+                 mach->with_dom ? sep : "",
                  buffer[i].grpi2_name,
                  put_sid (psid),
                  (unsigned int) (id_offset + gid));
@@ -560,107 +468,42 @@ enum_groups (BOOL domain, domlist_t *dom_or_machine, const char *sep,
   while (rc == ERROR_MORE_DATA);
 }
 
-static void
-print_special_by_sid (PSID_IDENTIFIER_AUTHORITY auth, BYTE cnt,
-                     DWORD sub1, DWORD sub2, DWORD sub3, DWORD sub4,
-                     DWORD sub5, DWORD sub6, DWORD sub7, DWORD sub8)
-{
-  WCHAR grp[GNLEN + 1], dom[MAX_DOMAIN_NAME_LEN + 1];
-  DWORD glen, dlen, rid;
-  PSID psid;
-  SID_NAME_USE acc_type;
-
-  if (AllocateAndInitializeSid (auth, cnt, sub1, sub2, sub3, sub4,
-                               sub5, sub6, sub7, sub8, &psid))
-    {
-      if (LookupAccountSidW (NULL, psid,
-                           grp, (glen = GNLEN + 1, &glen),
-                           dom, (dlen = MAX_DOMAIN_NAME_LEN + 1, &dlen),
-                           &acc_type))
-       {
-         if (sub8)
-           rid = sub8;
-         else if (sub7)
-           rid = sub7;
-         else if (sub6)
-           rid = sub6;
-         else if (sub5)
-           rid = sub5;
-         else if (sub4)
-           rid = sub4;
-         else if (sub3)
-           rid = sub3;
-         else if (sub2)
-           rid = sub2;
-         else
-           rid = sub1;
-         printf ("%ls:%s:%" PRIu32 ":\n", grp, put_sid (psid),
-                 (unsigned int) rid);
-       }
-      FreeSid (psid);
-    }
-}
-
-static void
-print_special_by_name (PCWSTR name, gid_t gid)
-{
-  DWORD size = 256, dom_size = 256;
-  PSID sid = (PSID) alloca (size);
-  WCHAR dom[dom_size];
-  SID_NAME_USE use;
-
-  PWCHAR name_only = wcschr (name, L'\\');
-  if (name_only)
-    ++name_only;
-
-  if (LookupAccountNameW (NULL, name, sid, &size, dom, &dom_size, &use))
-    printf ("%ls:%s:%lu:\n",
-           name_only ?: name, put_sid (sid), (unsigned long) gid);
-}
-
 static int
 usage (FILE * stream)
 {
   fprintf (stream,
 "Usage: %s [OPTION]...\n"
 "\n"
-"Print /etc/group file to stdout\n"
+"Write /etc/group-like output to stdout\n"
 "\n"
 "Options:\n"
 "\n"
-"   -l,--local [machine[,offset]]\n"
-"                           print local groups with gid offset offset\n"
+"   -l,--local [machine]    print local groups\n"
 "                           (from local machine if no machine specified)\n"
-"   -L,--Local [machine[,offset]]\n"
-"                           ditto, but generate groupname with machine prefix\n"
-"   -d,--domain [domain[,offset]]\n"
-"                           print domain groups with gid offset offset\n"
+"   -L,--Local machine      ditto, but generate groupname with machine prefix\n"
+"   -d,--domain [domain]    print domain groups\n"
 "                           (from current domain if no domain specified)\n"
-"   -D,--Domain [domain[,offset]]\n"
-"                           ditto, but generate groupname with machine prefix\n"
 "   -c,--current            print current group\n"
-"   -C,--Current            ditto, but generate groupname with machine or\n"
-"                           domain prefix\n"
-"   -S,--separator char     for -L, -D, -C use character char as domain\\group\n"
-"                           separator in groupname instead of the default '\\'\n"
-"   -o,--id-offset offset   change the default offset (10000) added to gids\n"
-"                           in domain or foreign server accounts.\n"
+"   -S,--separator char     for -l use character char as domain\\group\n"
+"                           separator in groupname instead of default '%s'\n"
+"   -o,--id-offset offset   change the default offset (0x10000) added to\n"
+"                           gids of foreign machine accounts.\n"
 "   -g,--group groupname    only return information for the specified group\n"
-"                           one of -l, -L, -d, -D must be specified, too\n"
+"                           one of -l, -d must be specified, too\n"
 "   -b,--no-builtin         don't print BUILTIN groups\n"
-"   -U,--unix grouplist     additionally print UNIX groups when using -l or -L\n"
-"                           on a UNIX Samba server\n"
-"                           grouplist is a comma-separated list of groupnames\n"
-"                           or gid ranges (root,-25,50-100).\n"
+"   -U,--unix grouplist     print UNIX groups when using -l on a UNIX Samba\n"
+"                           server.  grouplist is a comma-separated list of\n"
+"                           groupnames or gid ranges (root,-25,50-100).\n"
 "                           (enumerating large ranges can take a long time!)\n"
-"   -s,--no-sids            (ignored)\n"
-"   -u,--users              (ignored)\n"
 "   -h,--help               print this message\n"
 "   -v,--version            print version information and exit\n"
 "\n"
 "Default is to print local groups on stand-alone machines, plus domain\n"
-"groups on domain controllers and domain member machines.\n"
-"\n", program_invocation_short_name);
+"groups on domain controllers and domain member machines.\n\n"
+"Don't use this command to generate a local /etc/group file, unless you\n"
+"really need one.  See the Cygwin User's Guide for more information.\n"
+"\n", program_invocation_short_name,
+      (const char *) cygwin_internal (CW_GETNSSSEP));
   return 1;
 }
 
@@ -699,44 +542,20 @@ print_version ()
          strrchr (__DATE__, ' ') + 1);
 }
 
-static PPOLICY_PRIMARY_DOMAIN_INFO p_dom;
-
-static BOOL
-fetch_primary_domain ()
-{
-  NTSTATUS status;
-  LSA_OBJECT_ATTRIBUTES oa = { 0, 0, 0, 0, 0, 0 };
-  LSA_HANDLE lsa;
-
-  if (!p_dom)
-    {
-      status = LsaOpenPolicy (NULL, &oa, POLICY_EXECUTE, &lsa);
-      if (!NT_SUCCESS (status))
-       return FALSE;
-      status = LsaQueryInformationPolicy (lsa, PolicyPrimaryDomainInformation,
-                                         (PVOID *) ((void *) &p_dom));
-      LsaClose (lsa);
-      if (!NT_SUCCESS (status))
-       return FALSE;
-    }
-  return !!p_dom->Sid;
-}
-
 int
 main (int argc, char **argv)
 {
   int print_domlist = 0;
   domlist_t domlist[32];
-  char *opt, *p, *ep;
+  char *opt, *p;
   int print_current = 0;
-  int print_system = 0;
   int print_builtin = 1;
   char *print_unix = NULL;
-  const char *sep_char = "\\";
-  DWORD id_offset = 10000, off;
+  const char *sep_char = (const char *) cygwin_internal (CW_GETNSSSEP);
+  DWORD id_offset = 0x10000, off;
   int c, i;
   char *disp_groupname = NULL;
-  BOOL in_domain;
+  //BOOL in_domain;
   int optional_args = 0;
 
   if (!isatty (1))
@@ -746,22 +565,21 @@ main (int argc, char **argv)
   setlocale (LC_CTYPE, "");
   if (!strcmp (setlocale (LC_CTYPE, NULL), "C"))
     setlocale (LC_CTYPE, "en_US.UTF-8");
-  in_domain = fetch_primary_domain ();
   fetch_current_pgrp_sid ();
 
   if (argc == 1)
     {
-      print_special_by_sid (&sid_nt_auth, 1, SECURITY_LOCAL_SYSTEM_RID,
-                           0, 0, 0, 0, 0, 0, 0);
-      if (in_domain)
+      int enums = ENUM_PRIMARY | ENUM_LOCAL | ENUM_BUILTIN;
+      uintptr_t ticket = cygwin_internal (CW_SETENT, TRUE, enums, NULL);
+      if (ticket)
        {
-         if (!enum_local_groups (TRUE, NULL, sep_char, id_offset,
-                                 disp_groupname, print_builtin, 0))
-           enum_groups (TRUE, NULL, sep_char, id_offset, disp_groupname, 0);
+         struct group *grp;
+
+         while ((grp = (struct group *) cygwin_internal (CW_GETENT, TRUE,
+                                                         ticket)))
+           printf ("%s:%s:%u:\n", grp->gr_name, grp->gr_passwd, grp->gr_gid);
+         cygwin_internal (CW_ENDENT, TRUE, ticket);
        }
-      else if (!enum_local_groups (FALSE, NULL, sep_char, 0, disp_groupname,
-                                  print_builtin, 0))
-       enum_groups (FALSE, NULL, sep_char, 0, disp_groupname, 0);
       return 0;
     }
 
@@ -799,15 +617,10 @@ main (int argc, char **argv)
                       domlist[i].str);
              goto skip;
            }
-       if (!(domlist[print_domlist].str = opt))
-         print_system = 1;
-       domlist[print_domlist].id_offset = UINT32_MAX;
+       domlist[print_domlist].str = opt;
        if (opt && (p = strchr (opt, ',')))
          {
-           if (p == opt
-               || !isdigit ((unsigned char) p[1])
-               || (domlist[print_domlist].id_offset = strtol (p + 1, &ep, 10)
-                   , *ep))
+           if (p == opt)
              {
                fprintf (stderr, "%s: Malformed machine,offset string '%s'.  "
                         "Skipping...\n", program_invocation_short_name, opt);
@@ -815,15 +628,15 @@ main (int argc, char **argv)
              }
            *p = '\0';
          }
-       domlist[print_domlist++].with_dom = (c == 'D' || c == 'L');
+       domlist[print_domlist++].with_dom = (c == 'L');
 skip:
        break;
       case 'S':
        sep_char = optarg;
        if (strlen (sep_char) > 1)
          {
-           fprintf (stderr, "%s: Only one character allowed as domain\\user "
-                            "separator character.\n",
+           fprintf (stderr, "%s: Only one ASCII character allowed as "
+                            "domain\\user separator character.\n",
                             program_invocation_short_name);
            return 1;
          }
@@ -838,8 +651,6 @@ skip:
        print_unix = optarg;
        break;
       case 'c':
-       sep_char = NULL;
-       /*FALLTHRU*/
       case 'C':
        print_current = 1;
        break;
@@ -876,34 +687,77 @@ skip:
       exit (1);
     }
 
-  /* Get 'system' group */
-  if (!disp_groupname && print_system && print_builtin && print_domlist)
+  struct group *pgrp = NULL;
+  if (print_current)
+    pgrp = (struct group *) cygwin_internal (CW_GETGRSID, TRUE, curr_pgrp.psid);
+
+  int enums = ENUM_NONE;
+  WCHAR tdoms[print_domlist * 258];
+  PWCHAR t = tdoms;
+  if (!disp_groupname && print_builtin && print_domlist)
+    enums |= ENUM_BUILTIN;
+  for (i = 0; i < print_domlist; ++i)
     {
-      print_special_by_sid (&sid_nt_auth, 1, SECURITY_LOCAL_SYSTEM_RID,
-                           0, 0, 0, 0, 0, 0, 0);
-      print_special_by_name (L"NT SERVICE\\TrustedInstaller", -2);
+      if (domlist[i].domain)
+       {
+         if (domlist[i].str)
+           {
+             enums |= ENUM_TDOMS;
+             t += mbstowcs (t, domlist[i].str, 257);
+             *t++ = L'\0';
+           }
+         else
+           enums |= ENUM_PRIMARY;
+       }
+      else if (!domlist[i].str)
+       enums |= ENUM_LOCAL;
     }
+  if (t > tdoms)
+    *t++ = L'\0';
+  if (enums)
+    {
+      uintptr_t ticket = cygwin_internal (CW_SETENT, TRUE, enums,
+                                         t > tdoms ? tdoms : NULL);
+      if (ticket)
+       {
+         struct group *grp;
+         const char *nss_sep = (const char *) cygwin_internal (CW_GETNSSSEP);
+
+         while ((grp = (struct group *)
+                       cygwin_internal (CW_GETENT, TRUE, ticket)))
+           {
+             if (disp_groupname
+                 && strcasecmp (disp_groupname, grp->gr_name) != 0
+                 && (!(p = strchr (grp->gr_name, nss_sep[0]))
+                     || strcasecmp (disp_groupname, p + 1) != 0))
+               continue;
+             printf ("%s:%s:%u:\n", grp->gr_name, grp->gr_passwd,
+                                    grp->gr_gid);
+             if (pgrp && !strcmp (grp->gr_passwd, pgrp->gr_passwd))
+               got_curr_pgrp = TRUE;
+           }
+         cygwin_internal (CW_ENDENT, TRUE, ticket);
+       }
+    }
+
+  if (print_current && !got_curr_pgrp)
+    printf ("%s:%s:%u:\n", pgrp->gr_name, pgrp->gr_passwd, pgrp->gr_gid);
 
-  off = id_offset;
+  off = 0xfd000000;
   for (i = 0; i < print_domlist; ++i)
     {
-      DWORD my_off = (domlist[i].domain || domlist[i].str)
-                    ? domlist[i].id_offset != UINT_MAX
-                      ? domlist[i].id_offset : off : 0;
-      if (!enum_local_groups (domlist[i].domain, domlist + i, sep_char,
-                             my_off, disp_groupname, print_builtin, print_current))
+      if (domlist[i].domain || !domlist[i].str)
+       continue;
+      if (!enum_local_groups (domlist + i, sep_char, off, disp_groupname,
+                             print_builtin, print_current))
        {
+         enum_groups (domlist + i, sep_char, off, disp_groupname,
+                      print_current);
          if (!domlist[i].domain && domlist[i].str && print_unix)
-           enum_unix_groups (domlist + i, sep_char, my_off, print_unix);
-         enum_groups (domlist[i].domain, domlist + i, sep_char, my_off,
-                      disp_groupname, print_current);
-         if (my_off)
-           off += id_offset;
+           enum_unix_groups (domlist + i, sep_char, 0xff000000, print_unix);
+         off += id_offset;
        }
     }
 
-  if (print_current && !got_curr_pgrp)
-    current_group (sep_char, off);
-
   return 0;
 }
index d080dbd709e83b4111c67c0799c93cbc484550ec..a2c664ed15e73ba7a21ca86428fc146300c88322 100644 (file)
@@ -1,7 +1,7 @@
 /* mkpasswd.c:
 
    Copyright 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2005, 2006, 2008, 2009,
-   2010, 2011, 2012, 2013 Red Hat, Inc.
+   2010, 2011, 2012, 2013, 2014 Red Hat, Inc.
 
    This file is part of Cygwin.
 
@@ -21,6 +21,7 @@
 #include <inttypes.h>
 #include <getopt.h>
 #include <io.h>
+#include <pwd.h>
 #include <sys/fcntl.h>
 #include <sys/cygwin.h>
 #include <cygwin/version.h>
@@ -31,7 +32,6 @@
 #include <ntsecapi.h>
 #include <dsgetdc.h>
 #include <ntdef.h>
-#include "loadlib.h"
 
 #define print_win_error(x) _print_win_error(x, __LINE__)
 
@@ -47,7 +47,6 @@ SID_IDENTIFIER_AUTHORITY sid_nt_auth = {SECURITY_NT_AUTHORITY};
 typedef struct
 {
   char *str;
-  DWORD id_offset;
   BOOL domain;
   BOOL with_dom;
 } domlist_t;
@@ -70,31 +69,6 @@ _print_win_error(DWORD code, int line)
             line, (unsigned int) code);
 }
 
-static PWCHAR
-get_dcname (char *domain)
-{
-  static WCHAR server[INTERNET_MAX_HOST_NAME_LENGTH + 1];
-  DWORD rc;
-  WCHAR domain_name[MAX_DOMAIN_NAME_LEN + 1];
-  PDOMAIN_CONTROLLER_INFOW pdci = NULL;
-
-  if (domain)
-    {
-      mbstowcs (domain_name, domain, strlen (domain) + 1);
-      rc = DsGetDcNameW (NULL, domain_name, NULL, NULL, 0, &pdci);
-    }
-  else
-    rc = DsGetDcNameW (NULL, NULL, NULL, NULL, 0, &pdci);
-  if (rc != ERROR_SUCCESS)
-    {
-      print_win_error (rc);
-      return (PWCHAR) -1;
-    }
-  wcscpy (server, pdci->DomainControllerName);
-  NetApiBufferFree (pdci);
-  return server;
-}
-
 static char *
 put_sid (PSID sid)
 {
@@ -150,72 +124,10 @@ fetch_current_user_sid ()
 }
 
 static void
-current_user (const char *sep, const char *passed_home_path, DWORD id_offset,
-             const char *disp_username)
-{
-  WCHAR user[UNLEN + 1];
-  WCHAR dom[MAX_DOMAIN_NAME_LEN + 1];
-  DWORD ulen = UNLEN + 1;
-  DWORD dlen = MAX_DOMAIN_NAME_LEN + 1;
-  SID_NAME_USE acc_type;
-  int uid, gid;
-  char homedir_psx[PATH_MAX] = {0};
-
-  if (!curr_user.psid || !curr_pgrp.psid
-      || !LookupAccountSidW (NULL, curr_user.psid, user, &ulen, dom, &dlen,
-                            &acc_type))
-    {
-      print_win_error (GetLastError ());
-      return;
-    }
-
-  uid = *GetSidSubAuthority (curr_user.psid,
-                            *GetSidSubAuthorityCount(curr_user.psid) - 1);
-  gid = *GetSidSubAuthority (curr_pgrp.psid,
-                            *GetSidSubAuthorityCount(curr_pgrp.psid) - 1);
-  if (passed_home_path[0] == '\0')
-    {
-      char *envhome = getenv ("HOME");
-
-      /* If $HOME exists and is non-empty, just copy it over to homedir_psx.
-        Otherwise, generate a new path of the form "/home/$USER". */
-      if (envhome && envhome[0] != '\0')
-       strncat (homedir_psx, envhome, sizeof (homedir_psx) - 1);
-      else
-       {
-         wcstombs (stpncpy (homedir_psx, "/home/", sizeof (homedir_psx)),
-                   user, sizeof (homedir_psx) - 6);
-         homedir_psx[PATH_MAX - 1] = '\0';
-       }
-    }
-  else
-    {
-      char *p = stpncpy (homedir_psx, passed_home_path, sizeof (homedir_psx));
-      wcstombs (p, user, sizeof (homedir_psx) - (p - homedir_psx));
-      homedir_psx[PATH_MAX - 1] = '\0';
-    }
-
-  printf ("%ls%s%ls:unused:%" PRIu32 ":%" PRIu32
-         ":U-%ls\\%ls,%s:%s:/bin/bash\n",
-         sep ? dom : L"",
-         sep ?: "",
-         user,
-         (unsigned int) (id_offset + uid),
-         (unsigned int) (id_offset + gid),
-         dom,
-         user,
-         put_sid (curr_user.psid),
-         homedir_psx);
-}
-
-static void
-enum_unix_users (domlist_t *dom_or_machine, const char *sep, DWORD id_offset,
+enum_unix_users (domlist_t *mach, const char *sep, DWORD id_offset,
                 char *unix_user_list)
 {
   WCHAR machine[INTERNET_MAX_HOST_NAME_LENGTH + 1];
-  PWCHAR servername = NULL;
-  char *d_or_m = dom_or_machine ? dom_or_machine->str : NULL;
-  BOOL with_dom = dom_or_machine ? dom_or_machine->with_dom : FALSE;
   SID_IDENTIFIER_AUTHORITY auth = { { 0, 0, 0, 0, 0, 22 } };
   char *ustr, *user_list;
   WCHAR user[UNLEN + sizeof ("Unix User\\") + 1];
@@ -225,17 +137,13 @@ enum_unix_users (domlist_t *dom_or_machine, const char *sep, DWORD id_offset,
   char psid_buffer[MAX_SID_LEN];
   SID_NAME_USE acc_type;
 
-  if (!d_or_m)
-    return;
-
-  int ret = mbstowcs (machine, d_or_m, INTERNET_MAX_HOST_NAME_LENGTH + 1);
+  int ret = mbstowcs (machine, mach->str, INTERNET_MAX_HOST_NAME_LENGTH + 1);
   if (ret < 1 || ret >= INTERNET_MAX_HOST_NAME_LENGTH + 1)
     {
       fprintf (stderr, "%s: Invalid machine name '%s'.  Skipping...\n",
-              program_invocation_short_name, d_or_m);
+              program_invocation_short_name, mach->str);
       return;
     }
-  servername = machine;
 
   if (!AllocateAndInitializeSid (&auth, 2, 1, 0, 0, 0, 0, 0, 0, 0, &psid))
     return;
@@ -255,15 +163,15 @@ enum_unix_users (domlist_t *dom_or_machine, const char *sep, DWORD id_offset,
          if (ret < 1 || ret >= UNLEN + 1)
            fprintf (stderr, "%s: Invalid user name '%s'.  Skipping...\n",
                     program_invocation_short_name, ustr);
-         else if (LookupAccountNameW (servername, user,
+         else if (LookupAccountNameW (machine, user,
                                       psid = (PSID) psid_buffer,
                                       (sidlen = MAX_SID_LEN, &sidlen),
                                       dom,
                                       (dlen = MAX_DOMAIN_NAME_LEN + 1, &dlen),
                                       &acc_type))
            printf ("%s%s%ls:unused:%" PRIu32 ":99999:,%s::\n",
-                   with_dom ? "Unix User" : "",
-                   with_dom ? sep : "",
+                   mach->with_dom ? "Unix_User" : "",
+                   mach->with_dom ? sep : "",
                    user + 10,
                    (unsigned int) (id_offset +
                    *GetSidSubAuthority (psid,
@@ -292,15 +200,15 @@ enum_unix_users (domlist_t *dom_or_machine, const char *sep, DWORD id_offset,
            {
              *GetSidSubAuthority (psid, *GetSidSubAuthorityCount(psid) - 1)
              = start;
-             if (LookupAccountSidW (servername, psid,
+             if (LookupAccountSidW (machine, psid,
                                     user, (ulen = GNLEN + 1, &ulen),
                                     dom,
                                     (dlen = MAX_DOMAIN_NAME_LEN + 1, &dlen),
                                     &acc_type)
                  && !iswdigit (user[0]))
                printf ("%s%s%ls:unused:%" PRIu32 ":99999:,%s::\n",
-                       with_dom ? "Unix User" : "",
-                       with_dom ? sep : "",
+                       mach->with_dom ? "Unix_User" : "",
+                       mach->with_dom ? sep : "",
                        user,
                        (unsigned int) (id_offset + start),
                        put_sid (psid));
@@ -313,36 +221,23 @@ enum_unix_users (domlist_t *dom_or_machine, const char *sep, DWORD id_offset,
 }
 
 static int
-enum_users (BOOL domain, domlist_t *dom_or_machine, const char *sep,
-           const char *passed_home_path, DWORD id_offset, char *disp_username,
-           int print_current)
+enum_users (domlist_t *mach, const char *sep, const char *passed_home_path,
+           DWORD id_offset, char *disp_username, int print_current)
 {
   WCHAR machine[INTERNET_MAX_HOST_NAME_LENGTH + 1];
-  PWCHAR servername = NULL;
-  char *d_or_m = dom_or_machine ? dom_or_machine->str : NULL;
-  BOOL with_dom = dom_or_machine ? dom_or_machine->with_dom : FALSE;
   USER_INFO_3 *buffer;
   DWORD entriesread = 0;
   DWORD totalentries = 0;
   DWORD resume_handle = 0;
   DWORD rc;
   WCHAR uni_name[UNLEN + 1];
-  if (domain)
-    {
-      servername = get_dcname (d_or_m);
-      if (servername == (PWCHAR) -1)
-       return 1;
-    }
-  else if (d_or_m)
+
+  int ret = mbstowcs (machine, mach->str, INTERNET_MAX_HOST_NAME_LENGTH + 1);
+  if (ret < 1 || ret >= INTERNET_MAX_HOST_NAME_LENGTH + 1)
     {
-      int ret = mbstowcs (machine, d_or_m, INTERNET_MAX_HOST_NAME_LENGTH + 1);
-      if (ret < 1 || ret >= INTERNET_MAX_HOST_NAME_LENGTH + 1)
-       {
-         fprintf (stderr, "%s: Invalid machine name '%s'.  Skipping...\n",
-                  program_invocation_short_name, d_or_m);
-         return 1;
-       }
-      servername = machine;
+      fprintf (stderr, "%s: Invalid machine name '%s'.  Skipping...\n",
+              program_invocation_short_name, mach->str);
+      return 1;
     }
 
   do
@@ -352,7 +247,7 @@ enum_users (BOOL domain, domlist_t *dom_or_machine, const char *sep,
       if (disp_username != NULL)
        {
          mbstowcs (uni_name, disp_username, UNLEN + 1);
-         rc = NetUserGetInfo (servername, (LPWSTR) &uni_name, 3,
+         rc = NetUserGetInfo (machine, (LPWSTR) &uni_name, 3,
                               (void *) &buffer);
          entriesread = 1;
          /* Avoid annoying error messages just because the user hasn't been
@@ -361,7 +256,7 @@ enum_users (BOOL domain, domlist_t *dom_or_machine, const char *sep,
            return 0;
        }
       else
-       rc = NetUserEnum (servername, 3, FILTER_NORMAL_ACCOUNT,
+       rc = NetUserEnum (machine, 3, FILTER_NORMAL_ACCOUNT,
                          (void *) &buffer, MAX_PREFERRED_LENGTH,
                          &entriesread, &totalentries, &resume_handle);
       switch (rc)
@@ -407,7 +302,7 @@ enum_users (BOOL domain, domlist_t *dom_or_machine, const char *sep,
                      stpcpy (homedir_psx, passed_home_path),
                      PATH_MAX - strlen (passed_home_path));
 
-         if (!LookupAccountNameW (servername, buffer[i].usri3_name,
+         if (!LookupAccountNameW (machine, buffer[i].usri3_name,
                                   psid, &sid_length, domain_name,
                                   &domname_len, &acc_type))
            {
@@ -419,13 +314,12 @@ enum_users (BOOL domain, domlist_t *dom_or_machine, const char *sep,
            {
              WCHAR domname[MAX_DOMAIN_NAME_LEN + UNLEN + 2];
 
-             wcscpy (domname, domain || !servername
-                              ? domain_name : servername);
+             wcscpy (domname, machine);
              wcscat (domname, L"\\");
              wcscat (domname, buffer[i].usri3_name);
              sid_length = MAX_SID_LEN;
              domname_len = sizeof (domname);
-             if (!LookupAccountNameW (servername, domname, psid,
+             if (!LookupAccountNameW (machine, domname, psid,
                                       &sid_length, domain_name,
                                       &domname_len, &acc_type))
                {
@@ -441,8 +335,8 @@ enum_users (BOOL domain, domlist_t *dom_or_machine, const char *sep,
 
          printf ("%ls%s%ls:unused:%" PRIu32 ":%" PRIu32
                  ":%ls%sU-%ls\\%ls,%s:%s:/bin/bash\n",
-                 with_dom ? domain_name : L"",
-                 with_dom ? sep : "",
+                 mach->with_dom ? domain_name : L"",
+                 mach->with_dom ? sep : "",
                  buffer[i].usri3_name,
                  (unsigned int) (id_offset + uid),
                  (unsigned int) (id_offset + gid),
@@ -463,98 +357,49 @@ enum_users (BOOL domain, domlist_t *dom_or_machine, const char *sep,
   return 0;
 }
 
-static void
-print_special_by_sid (PSID_IDENTIFIER_AUTHORITY auth, BYTE cnt,
-                     DWORD sub1, DWORD sub2, DWORD sub3, DWORD sub4,
-                     DWORD sub5, DWORD sub6, DWORD sub7, DWORD sub8)
-{
-  WCHAR user[UNLEN + 1], dom[MAX_DOMAIN_NAME_LEN + 1];
-  DWORD len, len2, rid;
-  PSID sid;
-  SID_NAME_USE acc_type;
-
-  if (AllocateAndInitializeSid (auth, cnt, sub1, sub2, sub3, sub4,
-                               sub5, sub6, sub7, sub8, &sid))
-    {
-      if (LookupAccountSidW (NULL, sid,
-                            user, (len = UNLEN + 1, &len),
-                            dom, (len2 = MAX_DOMAIN_NAME_LEN + 1, &len2),
-                            &acc_type))
-       {
-         if (sub8)
-           rid = sub8;
-         else if (sub7)
-           rid = sub7;
-         else if (sub6)
-           rid = sub6;
-         else if (sub5)
-           rid = sub5;
-         else if (sub4)
-           rid = sub4;
-         else if (sub3)
-           rid = sub3;
-         else if (sub2)
-           rid = sub2;
-         else
-           rid = sub1;
-         printf ("%ls:*:%" PRIu32 ":%" PRIu32 ":,%s::\n",
-                 user, (unsigned int) rid,
-                 (unsigned int) (rid == 18 ? 544 : rid), /* SYSTEM hack */
-                 put_sid (sid));
-       }
-      FreeSid (sid);
-    }
-}
-
 static int
 usage (FILE * stream)
 {
   fprintf (stream,
 "Usage: %s [OPTIONS]...\n"
 "\n"
-"Print /etc/passwd file to stdout\n"
+"Write /etc/passwd-like output to stdout\n"
 "\n"
 "Options:\n"
 "\n"
-"   -l,--local [machine[,offset]]\n"
-"                           print local user accounts with uid offset offset\n"
+"   -l,--local [machine]    print local user accounts with uid offset offset\n"
 "                           (from local machine if no machine specified)\n"
-"   -L,--Local [machine[,offset]]\n"
-"                           ditto, but generate username with machine prefix\n"
-"   -d,--domain [domain[,offset]]\n"
-"                           print domain accounts with uid offset offset\n"
+"   -L,--Local machine      ditto, but generate username with machine prefix\n"
+"   -d,--domain [domain]    print domain accounts with uid offset offset\n"
 "                           (from current domain if no domain specified)\n"
-"   -D,--Domain [domain[,offset]]\n"
-"                           ditto, but generate username with domain prefix\n"
 "   -c,--current            print current user\n"
-"   -C,--Current            ditto, but generate username with machine or\n"
-"                           domain prefix\n"
-"   -S,--separator char     for -L, -D, -C use character char as domain\\user\n"
-"                           separator in username instead of the default '\\'\n"
-"   -o,--id-offset offset   change the default offset (10000) added to uids\n"
+"   -S,--separator char     for -l use character char as domain\\user\n"
+"                           separator in username instead of the default '%s'\n"
+"   -o,--id-offset offset   change the default offset (0x10000) added to uids\n"
 "                           in domain or foreign server accounts.\n"
 "   -u,--username username  only return information for the specified user\n"
-"                           one of -l, -L, -d, -D must be specified, too\n"
+"                           one of -l, -d must be specified, too\n"
+"   -b,--no-builtin         don't print BUILTIN users\n"
 "   -p,--path-to-home path  use specified path instead of user account home dir\n"
 "                           or /home prefix\n"
-"   -U,--unix userlist      additionally print UNIX users when using -l or -L\n"
-"                           on a UNIX Samba server\n"
-"                           userlist is a comma-separated list of usernames\n"
-"                           or uid ranges (root,-25,50-100).\n"
+"   -U,--unix userlist      print UNIX users when using -l on a UNIX Samba\n"
+"                           server.  userlist is a comma-separated list of\n"
+"                           usernames or uid ranges (root,-25,50-100).\n"
 "                           (enumerating large ranges can take a long time!)\n"
-"   -s,--no-sids            (ignored)\n"
-"   -m,--no-mount           (ignored)\n"
-"   -g,--local-groups       (ignored)\n"
 "   -h,--help               displays this message\n"
 "   -V,--version            version information and exit\n"
 "\n"
 "Default is to print local accounts on stand-alone machines, domain accounts\n"
-"on domain controllers and domain member machines.\n"
-"\n", program_invocation_short_name);
+"on domain controllers and domain member machines.\n\n"
+"Don't use this command to generate a local /etc/passwd file, unless you\n"
+"really need one.  See the Cygwin User's Guide for more information.\n"
+"\n", program_invocation_short_name,
+      (const char *) cygwin_internal (CW_GETNSSSEP));
   return 1;
 }
 
 static struct option longopts[] = {
+  {"no-builtin", no_argument, NULL, 'b'},
   {"current", no_argument, NULL, 'c'},
   {"Current", no_argument, NULL, 'C'},
   {"domain", optional_argument, NULL, 'd'},
@@ -574,7 +419,7 @@ static struct option longopts[] = {
   {0, no_argument, NULL, 0}
 };
 
-static char opts[] = "cCd::D::ghl::L::mo:sS:p:u:U:V";
+static char opts[] = "bcCd::D::ghl::L::mo:sS:p:u:U:V";
 
 static void
 print_version ()
@@ -590,66 +435,6 @@ print_version ()
          strrchr (__DATE__, ' ') + 1);
 }
 
-static void
-print_special_by_name (PCWSTR name, uid_t uid, gid_t gid)
-{
-  DWORD size = 256, dom_size = 256;
-  PSID sid = (PSID) alloca (size);
-  WCHAR dom[dom_size];
-  SID_NAME_USE use;
-
-  PWCHAR name_only = wcschr (name, L'\\');
-  if (name_only)
-    ++name_only;
-
-  if (LookupAccountNameW (NULL, name, sid, &size, dom, &dom_size, &use))
-    printf ("%ls:*:%lu:%lu:U-%ls%s%ls,%s::\n",
-           name_only ?: name,
-           (unsigned long) uid,
-           (unsigned long) gid,
-           name_only ? dom : L"",
-           name_only ? "\\" : "",
-           name_only ?: name,
-           put_sid (sid));
-}
-
-static void
-enum_std_accounts ()
-{
-  /* Generate service starter account entries. */
-  printf ("SYSTEM:*:18:544:,S-1-5-18::\n");
-  printf ("LocalService:*:19:544:U-NT AUTHORITY\\LocalService,S-1-5-19::\n");
-  printf ("NetworkService:*:20:544:U-NT AUTHORITY\\NetworkService,S-1-5-20::\n");
-  /* Get 'administrators' group (has localized name). */
-  print_special_by_sid (&sid_nt_auth, 2, SECURITY_BUILTIN_DOMAIN_RID,
-                       DOMAIN_ALIAS_RID_ADMINS, 0, 0, 0, 0, 0, 0);
-  /* Fetch "TrustedInstaller" account starting with Vista. */
-  print_special_by_name (L"NT SERVICE\\TrustedInstaller", -2, -2);
-}
-
-static PPOLICY_PRIMARY_DOMAIN_INFO p_dom;
-
-static BOOL
-fetch_primary_domain ()
-{
-  NTSTATUS status;
-  LSA_OBJECT_ATTRIBUTES oa = { 0, 0, 0, 0, 0, 0 };
-  LSA_HANDLE lsa;
-
-  if (!p_dom)
-    {
-      status = LsaOpenPolicy (NULL, &oa, POLICY_VIEW_LOCAL_INFORMATION, &lsa);
-      if (!NT_SUCCESS (status))
-       return FALSE;
-      status = LsaQueryInformationPolicy (lsa, PolicyPrimaryDomainInformation,
-                                         (PVOID *) ((void *) &p_dom));
-      LsaClose (lsa);
-      if (!NT_SUCCESS (status))
-       return FALSE;
-    }
-  return !!p_dom->Sid;
-}
-
 int
 main (int argc, char **argv)
 {
@@ -657,13 +442,14 @@ main (int argc, char **argv)
   domlist_t domlist[32];
   char *opt, *p, *ep;
   int print_current = 0;
+  int print_builtin = 1;
   char *print_unix = NULL;
-  const char *sep_char = "\\";
-  DWORD id_offset = 10000, off;
+  const char *nss_sep = (const char *) cygwin_internal (CW_GETNSSSEP);
+  const char *sep_char = nss_sep;
+  DWORD id_offset = 0x10000, off;
   int c, i;
   char *disp_username = NULL;
   char passed_home_path[PATH_MAX];
-  BOOL in_domain;
   int optional_args = 0;
 
   passed_home_path[0] = '\0';
@@ -674,18 +460,23 @@ main (int argc, char **argv)
   setlocale (LC_CTYPE, "");
   if (!strcmp (setlocale (LC_CTYPE, NULL), "C"))
     setlocale (LC_CTYPE, "en_US.UTF-8");
-  in_domain = fetch_primary_domain ();
   fetch_current_user_sid ();
 
   if (argc == 1)
     {
-      enum_std_accounts ();
-      if (in_domain)
-       enum_users (TRUE, NULL, sep_char, passed_home_path, 10000,
-                   disp_username, 0);
-      else
-       enum_users (FALSE, NULL, sep_char, passed_home_path, 0,
-                   disp_username, 0);
+      int enums = ENUM_PRIMARY | ENUM_LOCAL | ENUM_BUILTIN;
+      uintptr_t ticket = cygwin_internal (CW_SETENT, FALSE, enums, NULL);
+      if (ticket)
+       {
+         struct passwd *pwd;
+
+         while ((pwd = (struct passwd *) cygwin_internal (CW_GETENT, FALSE,
+                                                          ticket)))
+           printf ("%s:%s:%u:%u:%s:%s:%s\n", pwd->pw_name, pwd->pw_passwd,
+                   pwd->pw_uid, pwd->pw_gid, pwd->pw_gecos, pwd->pw_dir,
+                   pwd->pw_shell);
+         cygwin_internal (CW_ENDENT, FALSE, ticket);
+       }
       return 0;
     }
 
@@ -724,13 +515,9 @@ main (int argc, char **argv)
              goto skip;
            }
        domlist[print_domlist].str = opt;
-       domlist[print_domlist].id_offset = UINT32_MAX;
        if (opt && (p = strchr (opt, ',')))
          {
-           if (p == opt
-               || !isdigit ((unsigned char) p[1])
-               || (domlist[print_domlist].id_offset = strtol (p + 1, &ep, 10)
-                   , *ep))
+           if (p == opt)
              {
                fprintf (stderr, "%s: Malformed domain,offset string '%s'.  "
                         "Skipping...\n", program_invocation_short_name, opt);
@@ -738,15 +525,15 @@ main (int argc, char **argv)
              }
            *p = '\0';
          }
-       domlist[print_domlist++].with_dom = (c == 'D' || c == 'L');
+       domlist[print_domlist++].with_dom = (c == 'L');
 skip:
        break;
       case 'S':
        sep_char = optarg;
        if (strlen (sep_char) > 1)
          {
-           fprintf (stderr, "%s: Only one character allowed as domain\\user "
-                            "separator character.\n",
+           fprintf (stderr, "%s: Only one ASCII character allowed as "
+                            "domain\\user separator character.\n",
                             program_invocation_short_name);
            return 1;
          }
@@ -761,19 +548,14 @@ skip:
        print_unix = optarg;
        break;
       case 'c':
-       sep_char = NULL;
-       /*FALLTHRU*/
       case 'C':
        print_current = 1;
        break;
       case 'o':
        id_offset = strtoul (optarg, &ep, 10);
-       if (*ep)
-         {
-           fprintf (stderr, "%s: Malformed offset '%s'.  "
-                    "Skipping...\n", program_invocation_short_name, optarg);
-           return 1;
-         }
+       break;
+      case 'b':
+       print_builtin = 0;
        break;
       case 'p':
        if (optarg[0] != '/')
@@ -814,24 +596,91 @@ skip:
       exit (1);
     }
 
-  off = id_offset;
+  struct passwd *ppwd = NULL;
+  const char *ppwd_sid = NULL;
+  if (print_current)
+    {
+      ppwd = (struct passwd *) cygwin_internal (CW_GETPWSID, TRUE,
+                                               curr_user.psid);
+      if (ppwd)
+       ppwd_sid = strrchr (ppwd->pw_gecos, ',');
+    }
+
+  int enums = ENUM_NONE;
+  WCHAR tdoms[print_domlist * 258];
+  PWCHAR t = tdoms;
+  if (!disp_username && print_builtin && print_domlist)
+    enums |= ENUM_BUILTIN;
   for (i = 0; i < print_domlist; ++i)
     {
-      DWORD my_off = (domlist[i].domain || domlist[i].str)
-                    ? domlist[i].id_offset != UINT_MAX
-                      ? domlist[i].id_offset : off : 0;
-      if (!domlist[i].domain && domlist[i].str && print_unix)
-       enum_unix_users (domlist + i, sep_char, my_off, print_unix);
-      if (!my_off && !disp_username)
-       enum_std_accounts ();
-      enum_users (domlist[i].domain, domlist + i, sep_char, passed_home_path,
-                 my_off, disp_username, print_current);
-      if (my_off)
-       off += id_offset;
+      if (domlist[i].domain)
+        {
+          if (domlist[i].str)
+            {
+              enums |= ENUM_TDOMS;
+              t += mbstowcs (t, domlist[i].str, 257);
+              *t++ = L'\0';
+            }
+          else
+            enums |= ENUM_PRIMARY;
+        }
+      else if (!domlist[i].str)
+        enums |= ENUM_LOCAL;
+    }
+  if (t > tdoms)
+    *t++ = L'\0';
+  if (enums)
+    {
+      uintptr_t ticket = cygwin_internal (CW_SETENT, FALSE, enums,
+                                          t > tdoms ? tdoms : NULL);
+      if (ticket)
+        {
+          struct passwd *pwd;
+
+          while ((pwd = (struct passwd *)
+                        cygwin_internal (CW_GETENT, FALSE, ticket)))
+            {
+             p = NULL;
+              if (disp_username
+                  && strcasecmp (disp_username, pwd->pw_name) != 0
+                  && (!(p = strchr (pwd->pw_name, nss_sep[0]))
+                      || strcasecmp (disp_username, p + 1) != 0))
+                continue;
+             printf ("%s:%s:%u:%u:%s:%s%s:%s\n", pwd->pw_name, pwd->pw_passwd,
+                     pwd->pw_uid, pwd->pw_gid, pwd->pw_gecos,
+                     passed_home_path[0] ? passed_home_path : "",
+                     passed_home_path[0] ? (p ? p + 1 : pwd->pw_name)
+                                         : pwd->pw_dir,
+                     pwd->pw_shell);
+             const char *pwd_sid = strrchr (pwd->pw_gecos, ',');
+              if (ppwd && ppwd_sid && pwd_sid && !strcmp (pwd_sid, ppwd_sid))
+                got_curr_user = TRUE;
+            }
+          cygwin_internal (CW_ENDENT, FALSE, ticket);
+        }
     }
 
   if (print_current && !got_curr_user)
-    current_user (sep_char, passed_home_path, off, disp_username);
+    {
+      p = strchr (ppwd->pw_name, nss_sep[0]);
+      printf ("%s:%s:%u:%u:%s:%s%s:%s\n", ppwd->pw_name, ppwd->pw_passwd,
+             ppwd->pw_uid, ppwd->pw_gid, ppwd->pw_gecos,
+             passed_home_path[0] ? passed_home_path : "",
+             passed_home_path[0] ? (p ? p + 1 : ppwd->pw_name) : ppwd->pw_dir,
+             ppwd->pw_shell);
+    }
+
+  off = 0xfd000000;
+  for (i = 0; i < print_domlist; ++i)
+    {
+      if (domlist[i].domain || !domlist[i].str)
+       continue;
+      enum_users (domlist + i, sep_char, passed_home_path, off, disp_username,
+                 print_current);
+      if (!domlist[i].domain && domlist[i].str && print_unix)
+       enum_unix_users (domlist + i, sep_char, 0xff000000, print_unix);
+      off += id_offset;
+    }
 
   return 0;
 }
index b7e8ff81df71d7b70dd2fbaf3e519461afad1785..45c2dfb4bfed3ed112534710d22eb631ae409d63 100644 (file)
@@ -875,89 +875,77 @@ Write minidump from WIN32PID to FILENAME.dmp
     <screen>
 Usage: mkgroup [OPTION]...
 
-Print /etc/group file to stdout
+Write /etc/group-like output to stdout
 
 Options:
 
-   -l,--local [machine[,offset]]
-                           print local groups with gid offset offset
+   -l,--local [machine]    print local groups
                            (from local machine if no machine specified)
-   -L,--Local [machine[,offset]]
-                           ditto, but generate groupname with machine prefix
-   -d,--domain [domain[,offset]]
-                           print domain groups with gid offset offset
+   -L,--Local machine      ditto, but generate groupname with machine prefix
+   -d,--domain [domain]    print domain groups
                            (from current domain if no domain specified)
-   -D,--Domain [domain[,offset]]
-                           ditto, but generate groupname with machine prefix
    -c,--current            print current group
-   -C,--Current            ditto, but generate groupname with machine or
-                           domain prefix
-   -S,--separator char     for -L, -D, -C use character char as domain\group
-                           separator in groupname instead of the default '\'
-   -o,--id-offset offset   change the default offset (10000) added to gids
-                           in domain or foreign server accounts.
+   -S,--separator char     for -l use character char as domain\group
+                           separator in groupname instead of default '+'
+   -o,--id-offset offset   change the default offset (0x10000) added to
+                           gids of foreign machine accounts.
    -g,--group groupname    only return information for the specified group
-                           one of -l, -L, -d, -D must be specified, too
+                           one of -l, -d must be specified, too
    -b,--no-builtin         don't print BUILTIN groups
-   -U,--unix grouplist     additionally print UNIX groups when using -l or -L
-                           on a UNIX Samba server
-                           grouplist is a comma-separated list of groupnames
-                           or gid ranges (root,-25,50-100).
-                          (enumerating large ranges can take a long time!)
-   -s,--no-sids            (ignored)
-   -u,--users              (ignored)
+   -U,--unix grouplist     print UNIX groups when using -l on a UNIX Samba
+                           server.  grouplist is a comma-separated list of
+                           groupnames or gid ranges (root,-25,50-100).
+                           (enumerating large ranges can take a long time!)
    -h,--help               print this message
-   -V,--version            print version information and exit
+   -v,--version            print version information and exit
 
 Default is to print local groups on stand-alone machines, plus domain
 groups on domain controllers and domain member machines.
+
+Don't use this command to generate a local /etc/group file, unless you
+really need one.  See the Cygwin User's Guide for more information.
 </screen>
 
-    <para>The <command>mkgroup</command> program can be used to help configure
-      Cygwin by creating a <filename>/etc/group</filename> file. Its use is
-      essential to include Windows security information.</para>
-
-    <para>The command is initially called by <command>setup.exe</command> to
-      create a default <filename>/etc/group</filename>. This should be
-      sufficient in most circumstances. However, especially when working in a
-      multi-domain environment, you can use <command>mkgroup</command> manually
-      to create a more complete <filename>/etc/group</filename> file for all
-      domains. Especially when you have the same group name used on multiple
-      machines or in multiple domains, you can use the <literal>-D</literal>,
-      <literal>-L</literal> and <literal>-C</literal> options to create unique
-      domain\group style groupnames.</para>
-
-    <para>Note that this information is static. If you change the group
-      information in your system, you'll need to regenerate the group file for
-      it to have the new information.</para>
-
-    <para>The <literal>-d/-D</literal> and <literal>-l/-L</literal> options
-      allow you to specify where the information comes from, the local SAM of a
-      machine or from the domain, or both. With the <literal>-d/-D</literal>
-      options the program contacts a Domain Controller, which my be unreachable
-      or have restricted access. Comma-separated from the machine or domain,
-      you can specify an offset which is used as base added to the group's RID
-      to compute the gid (offset + RID = gid). This allows you to create the
-      same gids every time you re-run <command>mkgroup</command>. For very
-      simple needs, an entry for the current user's group can be created by
-      using the option <literal>-c</literal> or <literal>-C</literal>. If you
-      want to use one of the <literal>-D</literal>, <literal>-L</literal> or
-      <literal>-C</literal> options, but you don't like the backslash as
-      domain/group separator, you can specify another separator using the
-      <literal>-S</literal> option, for instance:</para>
+    <para>The <command>mkgroup</command> program can be used to create a local
+      <filename>/etc/group</filename> file.  Cygwin doesn't need this file,
+      because it reads group information from the Windows account databases,
+      but you can add an <filename>/etc/group</filename> file for instance, if
+      your machine is often disconnected from its domain controller.
+      </para>
+
+    <para>Note that this information is static, in contrast to the information
+      automatically gathered by Cygwin from the Windows account databases. If
+      you change the group information on your system, you'll need to regenerate
+      the group file for it to have the new information.</para>
+
+    <para>By default, the information generated by <command>mkgroup</command>
+      is equivalent to the information generated by Cygwin itself.  The
+      <literal>-d</literal> and <literal>-l/-L</literal> options allow you to
+      specify where the information comes from, some domain, or the local SAM
+      of a machine. Note that you can only enumerate accounts from trusted
+      domains.  Any non-trusted domain will be ignored.  Access-restrictions
+      of your current account apply.  The <literal>-l/-L</literal> when used
+      with a machine name, tries to contact that machine to enumerate local
+      groups of other machines, typically outside of domains.  This scenario
+      cannot be covered by Cygwin's account automatism.  If you want to use 
+      the <literal>-L</literal> option, but you don't like the default
+      domain/group separator from <filename>/etc/nsswitch.conf</filename>,
+      you can specify another separator using the <literal>-S</literal> option,
+      for instance:</para>
 
     <example id="utils-mkgroup-ex">
       <title>Setting up group entry for current user with different
         domain/group separator</title>
       <screen>
-<prompt>$</prompt> <userinput>mkgroup -C -S+ &gt; /etc/group</userinput>
-<prompt>$</prompt> <userinput>cat /etc/group</userinput>
-DOMAIN+my_group:S-1-5-21-2913048732-1697188782-3448811101-1144:11144:
+<prompt>$</prompt> <userinput>mkgroup -L server1 -S= &gt; /etc/group</userinput>
 </screen>
     </example>
 
-    <para>The <literal>-o</literal> option allows for special cases (such as
-      multiple domains) where the GIDs might match otherwise. The
+    <para>For very simple needs, an entry for the current user's group can be
+      created by using the option <literal>-c</literal>.</para>
+
+    <para>The <literal>-o</literal> option allows for (unlikely) special cases
+      with multiple machines where the GIDs might match otherwise. The
       <literal>-g</literal> option only prints the information for one group.
       The <literal>-U</literal> option allows you to enumerate the standard
       UNIX groups on a Samba machine. It's used together with <literal>-l
@@ -973,81 +961,69 @@ DOMAIN+my_group:S-1-5-21-2913048732-1697188782-3448811101-1144:11144:
     <screen>
 Usage: mkpasswd [OPTIONS]...
 
-Print /etc/passwd file to stdout
+Write /etc/passwd-like output to stdout
 
 Options:
 
-   -l,--local [machine[,offset]]
-                           print local user accounts with uid offset offset
+   -l,--local [machine]    print local user accounts with uid offset offset
                            (from local machine if no machine specified)
-   -L,--Local [machine[,offset]]
-                           ditto, but generate username with machine prefix
-   -d,--domain [domain[,offset]]
-                           print domain accounts with uid offset offset
+   -L,--Local machine      ditto, but generate username with machine prefix
+   -d,--domain [domain]    print domain accounts with uid offset offset
                            (from current domain if no domain specified)
-   -D,--Domain [domain[,offset]]
-                           ditto, but generate username with domain prefix
    -c,--current            print current user
-   -C,--Current            ditto, but generate username with machine or
-                           domain prefix
-   -S,--separator char     for -L, -D, -C use character char as domain\user
-                           separator in username instead of the default '\'
-   -o,--id-offset offset   change the default offset (10000) added to uids
+   -S,--separator char     for -l use character char as domain\user
+                           separator in username instead of the default '+'
+   -o,--id-offset offset   change the default offset (0x10000) added to uids
                            in domain or foreign server accounts.
    -u,--username username  only return information for the specified user
-                           one of -l, -L, -d, -D must be specified, too
+                           one of -l, -d must be specified, too
+   -b,--no-builtin         don't print BUILTIN users
    -p,--path-to-home path  use specified path instead of user account home dir
                            or /home prefix
-   -U,--unix userlist      additionally print UNIX users when using -l or -L\
-                           on a UNIX Samba server
-                           userlist is a comma-separated list of usernames
-                           or uid ranges (root,-25,50-100).
+   -U,--unix userlist      print UNIX users when using -l on a UNIX Samba
+                           server.  userlist is a comma-separated list of
+                           usernames or uid ranges (root,-25,50-100).
                            (enumerating large ranges can take a long time!)
-   -s,--no-sids            (ignored)
-   -m,--no-mount           (ignored)
-   -g,--local-groups       (ignored)
    -h,--help               displays this message
    -V,--version            version information and exit
 
 Default is to print local accounts on stand-alone machines, domain accounts
 on domain controllers and domain member machines.
+
+Don't use this command to generate a local /etc/passwd file, unless you
+really need one.  See the Cygwin User's Guide for more information.
 </screen>
 
-    <para>The <command>mkpasswd</command> program can be used to help configure
-      Cygwin by creating a <filename>/etc/passwd</filename> from your system
-      information. Its use is essential to include Windows security
-      information. However, the actual passwords are determined by Windows, not
-      by the content of <filename>/etc/passwd</filename>.</para>
-
-    <para>The command is initially called by <command>setup.exe</command> to
-      create a default <filename>/etc/passwd</filename>. This should be
-      sufficient in most circumstances. However, especially when working in a
-      multi-domain environment, you can use <command>mkpasswd</command>
-      manually to create a more complete <filename>/etc/passwd</filename> file
-      for all domains. Especially when you have the same user name used on
-      multiple machines or in multiple domains, you can use the
-      <literal>-D</literal>, <literal>-L</literal> and <literal>-C</literal>
-      options to create unique domain\user style usernames.</para>
-
-    <para>Note that this information is static. If you change the user
-      information in your system, you'll need to regenerate the passwd file for
-      it to have the new information.</para>
-
-    <para>The <literal>-d/-D</literal> and <literal>-l/-L</literal> options
-      allow you to specify where the information comes from, the local machine
-      or the domain (default or given), or both. With the
-      <literal>-d/-D</literal> options the program contacts the Domain
-      Controller, which may be unreachable or have restricted access.
-      Comma-separated from the machine or domain, you can specify an offset
-      which is used as base added to the user's RID to compute the uid (offset
-      + RID = uid). This allows to create the same uids every time you re-run
-      <command>mkpasswd</command>. An entry for the current user can be created
-      by using the option <literal>-c</literal> or <literal>-C</literal>. If
-      you want to use one of the <literal>-D</literal>, <literal>-L</literal>
-      or <literal>-C</literal> options, but you don't like the backslash as
-      domain/group separator, you can specify another separator using the
-      <literal>-S</literal> option, similar to the <command>mkgroup</command>.
-      The <literal>-o</literal> option allows for special cases (such as
+    <para>The <command>mkpasswd</command> program can be used to create a
+      <filename>/etc/passwd</filename> file.  Cygwin doesn't need this file,
+      because it reads user information from the Windows account databases,
+      but you can add an <filename>/etc/group</filename> file for instance, if
+      your machine is often disconnected from its domain controller.</para>
+
+    <para>Note that this information is static, in contrast to the information
+      automatically gathered by Cygwin from the Windows account databases. If
+      you change the user information on your system, you'll need to regenerate
+      the passwd file for it to have the new information.</para>
+
+    <para>By default, the information generated by <command>mkpasswd</command>
+      is equivalent to the information generated by Cygwin itself.  The
+      <literal>-d</literal> and <literal>-l/-L</literal> options allow you to
+      specify where the information comes from, some domain, or the local SAM
+      of a machine.  Note that you can only enumerate accounts from trusted
+      domains.  Any non-trusted domain will be ignored.  Access-restrictions
+      of your current account apply.  The <literal>-l/-L</literal> when used
+      with a machine name, tries to contact that machine to enumerate local
+      groups of other machines, typically outside of domains.  This scenario
+      cannot be covered by Cygwin's account automatism.  If you want to use
+      the <literal>-L</literal> option, but you don't like the default
+      domain/group separator from <filename>/etc/nsswitch.conf</filename>,
+      you can specify another separator using the <literal>-S</literal> option,
+      analog to <command>mkgroup</command>.</para>
+
+    <para>For very simple needs, an entry for the current user can be created
+      by using the option <literal>-c</literal>.</para>
+      
+    <para>The <literal>-o</literal> option allows for special cases (such as
       multiple domains) where the UIDs might match otherwise. The
       <literal>-p</literal> option causes <command>mkpasswd</command> to use
       the specified prefix instead of the account home dir or <literal>/home/
@@ -1062,7 +1038,8 @@ on domain controllers and domain member machines.
       to enumerate the standard UNIX users on a Samba machine. It's used
       together with <literal>-l samba-server</literal> or <literal>-L
       samba-server</literal>. The normal UNIX users are usually not enumerated,
-      but they can show up as file owners in <command>ls -l</command> output. </para>
+      but they can show up as file owners in <command>ls -l</command> output.
+      </para>
 
   </sect2>
 
This page took 0.085056 seconds and 5 git commands to generate.