home *** CD-ROM | disk | FTP | other *** search
/ PC Active 2009 April / PCA224.ISO / Software / remotes / setupssh.exe / bin / mkpasswd.c < prev    next >
Encoding:
C/C++ Source or Header  |  2003-03-16  |  17.9 KB  |  733 lines

  1. /* mkpasswd.c:
  2.  
  3.    Copyright 1997, 1998, 1999, 2000, 2001, 2002, 2003 Red Hat, Inc.
  4.  
  5.    This file is part of Cygwin.
  6.  
  7.    This software is a copyrighted work licensed under the terms of the
  8.    Cygwin license.  Please consult the file "CYGWIN_LICENSE" for
  9.    details. */
  10.  
  11. #include <ctype.h>
  12. #include <stdlib.h>
  13. #include <wchar.h>
  14. #include <stdio.h>
  15. #include <windows.h>
  16. #include <io.h>
  17. #include <unistd.h>
  18. #include <sys/cygwin.h>
  19. #include <getopt.h>
  20. #include <lmaccess.h>
  21. #include <lmapibuf.h>
  22. #include <sys/fcntl.h>
  23. #include <lmerr.h>
  24. #include <lmcons.h>
  25.  
  26. static const char version[] = "$Revision: 1.20 $";
  27.  
  28. SID_IDENTIFIER_AUTHORITY sid_world_auth = {SECURITY_WORLD_SID_AUTHORITY};
  29. SID_IDENTIFIER_AUTHORITY sid_nt_auth = {SECURITY_NT_AUTHORITY};
  30.  
  31. NET_API_STATUS WINAPI (*netapibufferfree)(PVOID);
  32. NET_API_STATUS WINAPI (*netuserenum)(LPWSTR,DWORD,DWORD,PBYTE*,DWORD,PDWORD,PDWORD,PDWORD);
  33. NET_API_STATUS WINAPI (*netlocalgroupenum)(LPWSTR,DWORD,PBYTE*,DWORD,PDWORD,PDWORD,PDWORD);
  34. NET_API_STATUS WINAPI (*netgetdcname)(LPWSTR,LPWSTR,PBYTE*);
  35. NET_API_STATUS WINAPI (*netusergetinfo)(LPWSTR,LPWSTR,DWORD,PBYTE*);
  36.  
  37. #ifndef min
  38. #define min(a,b) (((a)<(b))?(a):(b))
  39. #endif
  40.  
  41. BOOL
  42. load_netapi ()
  43. {
  44.   HANDLE h = LoadLibrary ("netapi32.dll");
  45.  
  46.   if (!h)
  47.     return FALSE;
  48.  
  49.   if (!(netapibufferfree = (void *) GetProcAddress (h, "NetApiBufferFree")))
  50.     return FALSE;
  51.   if (!(netuserenum = (void *) GetProcAddress (h, "NetUserEnum")))
  52.     return FALSE;
  53.   if (!(netlocalgroupenum = (void *) GetProcAddress (h, "NetLocalGroupEnum")))
  54.     return FALSE;
  55.   if (!(netgetdcname = (void *) GetProcAddress (h, "NetGetDCName")))
  56.     return FALSE;
  57.   if (!(netusergetinfo = (void *) GetProcAddress (h, "NetUserGetInfo")))
  58.     return FALSE;
  59.  
  60.   return TRUE;
  61. }
  62.  
  63. char *
  64. put_sid (PSID sid)
  65. {
  66.   static char s[512];
  67.   char t[32];
  68.   DWORD i;
  69.  
  70.   strcpy (s, "S-1-");
  71.   sprintf(t, "%u", GetSidIdentifierAuthority (sid)->Value[5]);
  72.   strcat (s, t);
  73.   for (i = 0; i < *GetSidSubAuthorityCount (sid); ++i)
  74.     {
  75.       sprintf(t, "-%lu", *GetSidSubAuthority (sid, i));
  76.       strcat (s, t);
  77.     }
  78.   return s;
  79. }
  80.  
  81. void
  82. psx_dir (char *in, char *out)
  83. {
  84.   if (isalpha (in[0]) && in[1] == ':')
  85.     {
  86.       sprintf (out, "/cygdrive/%c", in[0]);
  87.       in += 2;
  88.       out += strlen (out);
  89.     }
  90.  
  91.   while (*in)
  92.     {
  93.       if (*in == '\\')
  94.     *out = '/';
  95.       else
  96.     *out = *in;
  97.       in++;
  98.       out++;
  99.     }
  100.  
  101.   *out = '\0';
  102. }
  103.  
  104. void
  105. uni2ansi (LPWSTR wcs, char *mbs, int size)
  106. {
  107.   if (wcs)
  108.     WideCharToMultiByte (CP_ACP, 0, wcs, -1, mbs, size, NULL, NULL);
  109.   else
  110.     *mbs = '\0';
  111. }
  112.  
  113. void
  114. print_win_error(DWORD code)
  115. {
  116.   char buf[4096];
  117.  
  118.   if (FormatMessage (FORMAT_MESSAGE_FROM_SYSTEM
  119.       | FORMAT_MESSAGE_IGNORE_INSERTS,
  120.       NULL,
  121.       code,
  122.       MAKELANGID (LANG_NEUTRAL, SUBLANG_DEFAULT),
  123.       (LPTSTR) buf, sizeof (buf), NULL))
  124.     fprintf (stderr, "mkpasswd: [%lu] %s", code, buf);
  125.   else
  126.     fprintf (stderr, "mkpasswd: error %lu", code);
  127. }
  128.  
  129. void
  130. current_user (int print_sids, int print_cygpath,
  131.           const char * passed_home_path, int id_offset, const char * disp_username)
  132. {
  133.   char name[UNLEN + 1], *envname, *envdomain;
  134.   DWORD len;
  135.   HANDLE ptok;
  136.   int errpos = 0;
  137.   struct {
  138.     PSID psid;
  139.     int buffer[10];
  140.   } tu, tg;
  141.  
  142.  
  143.   if ((!GetUserName (name, (len = sizeof (name), &len)) && (errpos = __LINE__))
  144.       || !name[0]
  145.       || !(envname = getenv("USERNAME"))
  146.       || strcasecmp (envname, name)
  147.       || (disp_username && strcasecmp(envname, disp_username))
  148.       || (!GetComputerName (name, (len = sizeof (name), &len))
  149.       && (errpos = __LINE__))
  150.       || !(envdomain = getenv("USERDOMAIN"))
  151.       || !envdomain[0]
  152.       || !strcasecmp (envdomain, name)
  153.       || (!OpenProcessToken (GetCurrentProcess (), TOKEN_QUERY, &ptok)
  154.       && (errpos = __LINE__))
  155.       || (!GetTokenInformation (ptok, TokenUser, &tu, sizeof tu, &len)
  156.       && (errpos = __LINE__))
  157.       || (!GetTokenInformation (ptok, TokenPrimaryGroup, &tg, sizeof tg, &len)
  158.       && (errpos = __LINE__))
  159.       || (!CloseHandle (ptok) && (errpos = __LINE__)))
  160.     {
  161.       if (errpos)
  162.     {
  163.       print_win_error (GetLastError ());
  164.       fprintf(stderr, " on line %d\n", errpos);
  165.     }
  166.       return;
  167.     }
  168.  
  169.   int uid = *GetSidSubAuthority (tu.psid, *GetSidSubAuthorityCount(tu.psid) - 1);
  170.   int gid = *GetSidSubAuthority (tg.psid, *GetSidSubAuthorityCount(tg.psid) - 1);
  171.   char homedir_psx[MAX_PATH] = {0}, homedir_w32[MAX_PATH] = {0};
  172.  
  173.   char *envhomedrive = getenv ("HOMEDRIVE");
  174.   char *envhomepath = getenv ("HOMEPATH");
  175.  
  176.   if (passed_home_path[0] == '\0')
  177.     {
  178.       if (envhomepath && envhomepath[0])
  179.         {
  180.       if (envhomedrive)
  181.         strlcpy (homedir_w32, envhomedrive, sizeof (homedir_w32));
  182.       if (envhomepath[0] != '\\')
  183.         strlcat (homedir_w32, "\\", sizeof (homedir_w32));
  184.       strlcat (homedir_w32, envhomepath, sizeof (homedir_w32));
  185.       if (print_cygpath)
  186.         cygwin_conv_to_posix_path (homedir_w32, homedir_psx);
  187.       else
  188.         psx_dir (homedir_w32, homedir_psx);
  189.     }
  190.       else
  191.         {
  192.       strlcpy (homedir_psx, "/home/", sizeof (homedir_psx));
  193.       strlcat (homedir_psx, envname, sizeof (homedir_psx));
  194.     }
  195.     }
  196.   else
  197.     {
  198.       strlcpy (homedir_psx, passed_home_path, sizeof (homedir_psx));
  199.       strlcat (homedir_psx, envname, sizeof (homedir_psx));
  200.     }
  201.  
  202.   printf ("%s:unused_by_nt/2000/xp:%d:%d:%s%s%s%s%s%s%s%s:%s:/bin/switch\n",
  203.       envname,
  204.       uid + id_offset,
  205.       gid + id_offset,
  206.       envname,
  207.       print_sids ? "," : "",
  208.       print_sids ? "U-" : "",
  209.       print_sids ? envdomain : "",
  210.       print_sids ? "\\" : "",
  211.       print_sids ? envname : "",
  212.       print_sids ? "," : "",
  213.       print_sids ? put_sid (tu.psid) : "",
  214.       homedir_psx);
  215. }
  216.  
  217. int
  218. enum_users (LPWSTR servername, int print_sids, int print_cygpath,
  219.         const char * passed_home_path, int id_offset, char *disp_username)
  220. {
  221.   USER_INFO_3 *buffer;
  222.   DWORD entriesread = 0;
  223.   DWORD totalentries = 0;
  224.   DWORD resume_handle = 0;
  225.   DWORD rc;
  226.   char ansi_srvname[256];
  227.   WCHAR uni_name[512];
  228.  
  229.   if (servername)
  230.     uni2ansi (servername, ansi_srvname, sizeof (ansi_srvname));
  231.  
  232.   do
  233.     {
  234.       DWORD i;
  235.  
  236.     if (disp_username != NULL)
  237.       {
  238.     MultiByteToWideChar (CP_ACP, 0, disp_username, -1, uni_name, 512 );
  239.     rc = netusergetinfo(servername, (LPWSTR) & uni_name, 3,
  240.                 (LPBYTE *) &buffer );
  241.     entriesread=1;
  242.       }
  243.     else 
  244.       rc = netuserenum (servername, 3, FILTER_NORMAL_ACCOUNT,
  245.             (LPBYTE *) & buffer, 1024,
  246.             &entriesread, &totalentries, &resume_handle);
  247.       switch (rc)
  248.     {
  249.     case ERROR_ACCESS_DENIED:
  250.       print_win_error(rc);
  251.       exit (1);
  252.  
  253.     case ERROR_MORE_DATA:
  254.     case ERROR_SUCCESS:
  255.       break;
  256.  
  257.     default:
  258.       print_win_error(rc);
  259.       exit (1);
  260.     }
  261.  
  262.       for (i = 0; i < entriesread; i++)
  263.     {
  264.       char username[100];
  265.       char fullname[100];
  266.       char homedir_psx[MAX_PATH];
  267.       char homedir_w32[MAX_PATH];
  268.       char domain_name[100];
  269.       DWORD domname_len = 100;
  270.       char psid_buffer[1024];
  271.       PSID psid = (PSID) psid_buffer;
  272.       DWORD sid_length = 1024;
  273.       SID_NAME_USE acc_type;
  274.  
  275.       int uid = buffer[i].usri3_user_id;
  276.       int gid = buffer[i].usri3_primary_group_id;
  277.       uni2ansi (buffer[i].usri3_name, username, sizeof (username));
  278.       uni2ansi (buffer[i].usri3_full_name, fullname, sizeof (fullname));
  279.       homedir_w32[0] = homedir_psx[0] = '\0';
  280.       if (passed_home_path[0] == '\0')
  281.         {
  282.           uni2ansi (buffer[i].usri3_home_dir, homedir_w32,
  283.             sizeof (homedir_w32));
  284.           if (homedir_w32[0] != '\0')
  285.         {
  286.           if (print_cygpath)
  287.             cygwin_conv_to_posix_path (homedir_w32, homedir_psx);
  288.           else
  289.             psx_dir (homedir_w32, homedir_psx);
  290.         }
  291.           else
  292.         {
  293.           strcpy (homedir_psx, "/home/");
  294.           strcat (homedir_psx, username);
  295.         }
  296.         }
  297.       else
  298.         {
  299.           strcpy (homedir_psx, passed_home_path);
  300.           strcat (homedir_psx, username);
  301.         }
  302.  
  303.       if (print_sids)
  304.         {
  305.           if (!LookupAccountName (servername ? ansi_srvname : NULL,
  306.                       username,
  307.                       psid, &sid_length,
  308.                       domain_name, &domname_len,
  309.                       &acc_type))
  310.         {
  311.             print_win_error(GetLastError ());
  312.           continue;
  313.         }
  314.           else if (acc_type == SidTypeDomain)
  315.         {
  316.           char domname[356];
  317.  
  318.           strcpy (domname, domain_name);
  319.           strcat (domname, "\\");
  320.           strcat (domname, username);
  321.           sid_length = 1024;
  322.           domname_len = 100;
  323.           if (!LookupAccountName (servername ? ansi_srvname : NULL,
  324.                       domname,
  325.                       psid, &sid_length,
  326.                       domain_name, &domname_len,
  327.                       &acc_type))
  328.             {
  329.               print_win_error(GetLastError ());
  330.               continue;
  331.             }
  332.         }
  333.         }
  334.       printf ("%s:unused_by_nt/2000/xp:%d:%d:%s%s%s%s%s%s%s%s:%s:/bin/switch\n",
  335.             username,
  336.           uid + id_offset,
  337.           gid + id_offset,
  338.           fullname,
  339.           print_sids && fullname[0] ? "," : "",
  340.           print_sids ? "U-" : "",
  341.           print_sids ? domain_name : "",
  342.           print_sids && domain_name[0] ? "\\" : "",
  343.           print_sids ? username : "",
  344.           print_sids ? "," : "",
  345.           print_sids ? put_sid (psid) : "",
  346.           homedir_psx);
  347.     }
  348.  
  349.       netapibufferfree (buffer);
  350.  
  351.     }
  352.   while (rc == ERROR_MORE_DATA);
  353.  
  354.   if (servername)
  355.     netapibufferfree (servername);
  356.  
  357.   return 0;
  358. }
  359.  
  360. int
  361. enum_local_groups (int print_sids)
  362. {
  363.   LOCALGROUP_INFO_0 *buffer;
  364.   DWORD entriesread = 0;
  365.   DWORD totalentries = 0;
  366.   DWORD resume_handle = 0;
  367.   DWORD rc ;
  368.  
  369.   do
  370.     {
  371.       DWORD i;
  372.  
  373.       rc = netlocalgroupenum (NULL, 0, (LPBYTE *) & buffer, 1024,
  374.                   &entriesread, &totalentries, &resume_handle);
  375.       switch (rc)
  376.     {
  377.     case ERROR_ACCESS_DENIED:
  378.       print_win_error(rc);
  379.       exit (1);
  380.  
  381.     case ERROR_MORE_DATA:
  382.     case ERROR_SUCCESS:
  383.       break;
  384.  
  385.     default:
  386.       print_win_error(rc);
  387.       exit (1);
  388.     }
  389.  
  390.       for (i = 0; i < entriesread; i++)
  391.     {
  392.       char localgroup_name[100];
  393.       char domain_name[100];
  394.       DWORD domname_len = 100;
  395.       char psid_buffer[1024];
  396.       PSID psid = (PSID) psid_buffer;
  397.       DWORD sid_length = 1024;
  398.       DWORD gid;
  399.       SID_NAME_USE acc_type;
  400.       uni2ansi (buffer[i].lgrpi0_name, localgroup_name, sizeof (localgroup_name));
  401.  
  402.       if (!LookupAccountName (NULL, localgroup_name, psid,
  403.                   &sid_length, domain_name, &domname_len,
  404.                   &acc_type))
  405.         {
  406.           print_win_error(GetLastError ());
  407.           continue;
  408.         }
  409.       else if (acc_type == SidTypeDomain)
  410.         {
  411.           char domname[356];
  412.  
  413.           strcpy (domname, domain_name);
  414.           strcat (domname, "\\");
  415.           strcat (domname, localgroup_name);
  416.           sid_length = 1024;
  417.           domname_len = 100;
  418.           if (!LookupAccountName (NULL, domname,
  419.                       psid, &sid_length,
  420.                       domain_name, &domname_len,
  421.                       &acc_type))
  422.         {
  423.           print_win_error(GetLastError ());
  424.           continue;
  425.         }
  426.         }
  427.  
  428.       gid = *GetSidSubAuthority (psid, *GetSidSubAuthorityCount(psid) - 1);
  429.  
  430.       printf ("%s:*:%ld:%ld:%s%s::\n", localgroup_name, gid, gid,
  431.           print_sids ? "," : "",
  432.           print_sids ? put_sid (psid) : "");
  433.     }
  434.  
  435.       netapibufferfree (buffer);
  436.  
  437.     }
  438.   while (rc == ERROR_MORE_DATA);
  439.  
  440.   return 0;
  441. }
  442.  
  443. void
  444. print_special (int print_sids,
  445.            PSID_IDENTIFIER_AUTHORITY auth, BYTE cnt,
  446.            DWORD sub1, DWORD sub2, DWORD sub3, DWORD sub4,
  447.            DWORD sub5, DWORD sub6, DWORD sub7, DWORD sub8)
  448. {
  449.   char name[256], dom[256];
  450.   DWORD len, len2, rid;
  451.   PSID sid;
  452.   SID_NAME_USE use;
  453.  
  454.   if (AllocateAndInitializeSid (auth, cnt, sub1, sub2, sub3, sub4,
  455.                   sub5, sub6, sub7, sub8, &sid))
  456.     {
  457.       if (LookupAccountSid (NULL, sid,
  458.                 name, (len = 256, &len),
  459.                 dom, (len2 = 256, &len),
  460.                 &use))
  461.     {
  462.       if (sub8)
  463.         rid = sub8;
  464.       else if (sub7)
  465.         rid = sub7;
  466.       else if (sub6)
  467.         rid = sub6;
  468.       else if (sub5)
  469.         rid = sub5;
  470.       else if (sub4)
  471.         rid = sub4;
  472.       else if (sub3)
  473.         rid = sub3;
  474.       else if (sub2)
  475.         rid = sub2;
  476.       else
  477.         rid = sub1;
  478.       printf ("%s:*:%lu:%lu:%s%s::\n",
  479.           name, rid, rid == 18 ? 544 : rid, /* SYSTEM hack */
  480.           print_sids ? "," : "",
  481.           print_sids ? put_sid (sid) : "");
  482.         }
  483.       FreeSid (sid);
  484.     }
  485. }
  486.  
  487. int
  488. usage (FILE * stream, int isNT)
  489. {
  490.   fprintf (stream, "Usage: mkpasswd [OPTION]... [domain]\n\n"
  491.                "This program prints a /etc/passwd file to stdout\n\n"
  492.                "Options:\n");
  493.   if (isNT)
  494.     fprintf (stream, "   -l,--local              print local user accounts\n"
  495.                  "   -c,--current            print current account, if a domain account\n"
  496.                      "   -d,--domain             print domain accounts (from current domain\n"
  497.                      "                           if no domain specified)\n"
  498.                      "   -o,--id-offset offset   change the default offset (10000) added to uids\n"
  499.                      "                           in domain accounts.\n"
  500.                      "   -g,--local-groups       print local group information too\n"
  501.                      "                           if no domain specified\n"
  502.                      "   -m,--no-mount           don't use mount points for home dir\n"
  503.                      "   -s,--no-sids            don't print SIDs in GCOS field\n"
  504.                  "                           (this affects ntsec)\n");
  505.   fprintf (stream, "   -p,--path-to-home path  use specified path instead of user account home dir\n"
  506.                    "   -u,--username username  only return information for the specified user\n"
  507.                    "   -h,--help               displays this message\n"
  508.                "   -v,--version            version information and exit\n\n");
  509.   if (isNT)
  510.     fprintf (stream, "One of `-l', `-d' or `-g' must be given.\n");
  511.   return 1;
  512. }
  513.  
  514. struct option longopts[] = {
  515.   {"local", no_argument, NULL, 'l'},
  516.   {"current", no_argument, NULL, 'c'},
  517.   {"domain", no_argument, NULL, 'd'},
  518.   {"id-offset", required_argument, NULL, 'o'},
  519.   {"local-groups", no_argument, NULL, 'g'},
  520.   {"no-mount", no_argument, NULL, 'm'},
  521.   {"no-sids", no_argument, NULL, 's'},
  522.   {"path-to-home", required_argument, NULL, 'p'},
  523.   {"username", required_argument, NULL, 'u'},
  524.   {"help", no_argument, NULL, 'h'},
  525.   {"version", no_argument, NULL, 'v'},
  526.   {0, no_argument, NULL, 0}
  527. };
  528.  
  529. char opts[] = "lcdo:gsmhp:u:v";
  530.  
  531. static void
  532. print_version ()
  533. {
  534.   const char *v = strchr (version, ':');
  535.   int len;
  536.   if (!v)
  537.     {
  538.       v = "?";
  539.       len = 1;
  540.     }
  541.   else
  542.     {
  543.       v += 2;
  544.       len = strchr (v, ' ') - v;
  545.     }
  546.   printf ("\
  547. mkpasswd (cygwin) %.*s\n\
  548. passwd File Generator\n\
  549. Copyright 1997, 1998, 1999, 2000, 2001, 2002 Red Hat, Inc.\n\
  550. Compiled on %s\n\
  551. ", len, v, __DATE__);
  552. }
  553.  
  554. int
  555. main (int argc, char **argv)
  556. {
  557.   LPWSTR servername = NULL;
  558.   DWORD rc = ERROR_SUCCESS;
  559.   WCHAR domain_name[200];
  560.   int print_local = 0;
  561.   int print_current = 0;
  562.   int print_domain = 0;
  563.   int print_local_groups = 0;
  564.   int domain_name_specified = 0;
  565.   int print_sids = 1;
  566.   int print_cygpath = 1;
  567.   int id_offset = 10000;
  568.   int i;
  569.   int isNT;
  570.   char *disp_username = NULL;
  571.   char name[256], passed_home_path[MAX_PATH];
  572.   DWORD len;
  573.  
  574.   isNT = (GetVersion () < 0x80000000);
  575.   passed_home_path[0] = '\0';
  576.   if (!isatty (1))
  577.     setmode (1, O_BINARY);
  578.  
  579.   if (isNT && argc == 1)
  580.     return usage (stderr, isNT);
  581.   else
  582.     {
  583.       while ((i = getopt_long (argc, argv, opts, longopts, NULL)) != EOF)
  584.     switch (i)
  585.       {
  586.       case 'l':
  587.         print_local = 1;
  588.         break;
  589.       case 'c':
  590.         print_current = 1;
  591.         break;
  592.       case 'd':
  593.         print_domain = 1;
  594.         break;
  595.       case 'o':
  596.         id_offset = strtol (optarg, NULL, 10);
  597.         break;
  598.       case 'g':
  599.         print_local_groups = 1;
  600.         break;
  601.       case 's':
  602.         print_sids = 0;
  603.         break;
  604.       case 'm':
  605.         print_cygpath = 0;
  606.         break;
  607.       case 'p':
  608.         if (optarg[0] != '/')
  609.         {
  610.           fprintf (stderr, "%s: `%s' is not a fully qualified path.\n",
  611.                argv[0], optarg);
  612.           return 1;
  613.         }
  614.         strcpy (passed_home_path, optarg);
  615.         if (optarg[strlen (optarg)-1] != '/')
  616.           strcat (passed_home_path, "/");
  617.         break;
  618.       case 'u':
  619.         disp_username = optarg;
  620.         break;
  621.       case 'h':
  622.         usage (stdout, isNT);
  623.         return 0;
  624.       case 'v':
  625.         print_version ();
  626.         return 0;
  627.       default:
  628.         fprintf (stderr, "Try `%s --help' for more information.\n", argv[0]);
  629.         return 1;
  630.       }
  631.     }
  632.   if (!isNT)
  633.     {
  634.       /* This takes Windows 9x/ME into account. */
  635.       if (!disp_username)
  636.         {
  637.       if (GetUserName (name, (len = 256, &len)))
  638.         disp_username = name;
  639.       else
  640.         /* Same behaviour as in cygwin/shared.cc (memory_init). */
  641.         disp_username = (char *) "unknown";
  642.     }
  643.  
  644.       if (passed_home_path[0] == '\0')
  645.     strcpy (passed_home_path, "/home/");
  646.  
  647.       printf ("%s:*:%ld:%ld:%s:%s%s:/bin/switch\n", disp_username,
  648.                             DOMAIN_USER_RID_ADMIN,
  649.                             DOMAIN_ALIAS_RID_ADMINS,
  650.                                             disp_username,
  651.                             passed_home_path,
  652.                             disp_username);
  653.       return 0;
  654.     }
  655.   if (!print_local && !print_domain && !print_local_groups)
  656.     {
  657.       fprintf (stderr, "%s: Specify one of `-l', `-d' or `-g'\n", argv[0]);
  658.       return 1;
  659.     }
  660.   if (optind < argc)
  661.     {
  662.       if (!print_domain)
  663.         {
  664.       fprintf (stderr, "%s: A domain name is only accepted "
  665.            "when `-d' is given.\n", argv[0]);
  666.       return 1;
  667.     }
  668.       mbstowcs (domain_name, argv[optind], (strlen (argv[optind]) + 1));
  669.       domain_name_specified = 1;
  670.     }
  671.   if (!load_netapi ())
  672.     {
  673.       print_win_error(GetLastError ());
  674.       return 1;
  675.     }
  676.  
  677.   if (disp_username == NULL)
  678.     {
  679. #if 0
  680.       /*
  681.        * Get `Everyone' group
  682.       */
  683.       print_special (print_sids, &sid_world_auth, 1, SECURITY_WORLD_RID,
  684.              0, 0, 0, 0, 0, 0, 0);
  685. #endif
  686.       /*
  687.        * Get `system' group
  688.       */
  689.       print_special (print_sids, &sid_nt_auth, 1, SECURITY_LOCAL_SYSTEM_RID,
  690.              0, 0, 0, 0, 0, 0, 0);
  691.       /*
  692.        * Get `administrators' group
  693.       */
  694.       if (!print_local_groups)
  695.     print_special (print_sids, &sid_nt_auth, 2, SECURITY_BUILTIN_DOMAIN_RID,
  696.                DOMAIN_ALIAS_RID_ADMINS, 0, 0, 0, 0, 0, 0);
  697.  
  698.       if (print_local_groups)
  699.     enum_local_groups (print_sids);
  700.     }
  701.  
  702.   if (print_domain)
  703.     {
  704.       if (domain_name_specified)
  705.     rc = netgetdcname (NULL, domain_name, (LPBYTE *) & servername);
  706.  
  707.       else
  708.     rc = netgetdcname (NULL, NULL, (LPBYTE *) & servername);
  709.  
  710.       if (rc != ERROR_SUCCESS)
  711.     {
  712.       print_win_error(rc);
  713.       return 1;
  714.     }
  715.  
  716.       enum_users (servername, print_sids, print_cygpath, passed_home_path,
  717.           id_offset, disp_username);
  718.     }
  719.  
  720.   if (print_local)
  721.     enum_users (NULL, print_sids, print_cygpath, passed_home_path, 0,
  722.             disp_username);
  723.  
  724.   if (print_current && !print_domain)
  725.     current_user(print_sids, print_cygpath, passed_home_path,
  726.          id_offset, disp_username);
  727.  
  728.   if (servername)
  729.     netapibufferfree (servername);
  730.  
  731.   return 0;
  732. }
  733.