* Makefile.in (cygcheck.exe): Link against ntdll.
* bloda.cc: Use statically linked functions throughout. * cygpath.cc: Drop 9x considerations. * mkgroup.c: Revamp. Redefine -l and -d options to take optional machine and domain parameters. Redefine -c to work always, using token information. Add -L, -D, -C to create unique groupnames in domain\group syntax. Add -S option to define domain\group separator char. Ignore -u and -s options. * mkpasswd.c: Revamp. Redefine -l and -d options to take optional machine and domain parameters. Redefine -c to work always, using token information. Add -L, -D, -C to create unique usernames in domain\user syntax. Add -S option to define domain\user separator char. Ignore -g and -s options. Prefer to take homedir from $HOME over $HOMEDRIVE/$HOMEPATH. * path.cc (oopts): Add "acl", "noacl", "posix=0" and "posix=1" options. (getmntent): Accomodate throughout. * ps.cc: Fix copyright dates. * utils.sgml: Fix text for mkgroup and mkpasswd.
This commit is contained in:
		| @@ -1,3 +1,24 @@ | |||||||
|  | 2008-07-22  Corinna Vinschen  <corinna@vinschen.de> | ||||||
|  |  | ||||||
|  | 	* Makefile.in (cygcheck.exe): Link against ntdll. | ||||||
|  | 	* bloda.cc: Use statically linked functions throughout. | ||||||
|  | 	* cygpath.cc: Drop 9x considerations. | ||||||
|  | 	* mkgroup.c: Revamp.  Redefine -l and -d options to take optional | ||||||
|  | 	machine and domain parameters.  Redefine -c to work always, using | ||||||
|  | 	token information.  Add -L, -D, -C to create unique groupnames in | ||||||
|  | 	domain\group syntax.  Add -S option to define domain\group separator | ||||||
|  | 	char.  Ignore -u and -s options. | ||||||
|  | 	* mkpasswd.c: Revamp.  Redefine -l and -d options to take optional | ||||||
|  | 	machine and domain parameters.  Redefine -c to work always, using | ||||||
|  | 	token information.  Add -L, -D, -C to create unique usernames in | ||||||
|  | 	domain\user syntax.  Add -S option to define domain\user separator | ||||||
|  | 	char.  Ignore -g and -s options.  Prefer to take homedir from $HOME | ||||||
|  | 	over $HOMEDRIVE/$HOMEPATH. | ||||||
|  | 	* path.cc (oopts): Add "acl", "noacl", "posix=0" and "posix=1" options. | ||||||
|  | 	(getmntent): Accomodate throughout. | ||||||
|  | 	* ps.cc: Fix copyright dates. | ||||||
|  | 	* utils.sgml: Fix text for mkgroup and mkpasswd. | ||||||
|  |  | ||||||
| 2008-07-17  Corinna Vinschen  <corinna@vinschen.de> | 2008-07-17  Corinna Vinschen  <corinna@vinschen.de> | ||||||
|  |  | ||||||
| 	* mount.cc (do_mount): Remove MOUNT_ENC code. | 	* mount.cc (do_mount): Remove MOUNT_ENC code. | ||||||
|   | |||||||
| @@ -94,7 +94,7 @@ ifdef libz | |||||||
| zlib_h  := -include ${patsubst %/lib/mingw/libz.a,%/include/zlib.h,${patsubst %/lib/libz.a,%/include/zlib.h,$(libz)}} | zlib_h  := -include ${patsubst %/lib/mingw/libz.a,%/include/zlib.h,${patsubst %/lib/libz.a,%/include/zlib.h,$(libz)}} | ||||||
| zconf_h := ${patsubst %/zlib.h,%/zconf.h,$(zlib_h)} | zconf_h := ${patsubst %/zlib.h,%/zconf.h,$(zlib_h)} | ||||||
| dump_setup.o: MINGW_CXXFLAGS += $(zconf_h) $(zlib_h) | dump_setup.o: MINGW_CXXFLAGS += $(zconf_h) $(zlib_h) | ||||||
| cygcheck.exe: MINGW_LDFLAGS += $(libz) | cygcheck.exe: MINGW_LDFLAGS += $(libz) -lntdll | ||||||
| else | else | ||||||
| all: warn_cygcheck_zlib | all: warn_cygcheck_zlib | ||||||
| endif | endif | ||||||
|   | |||||||
| @@ -108,24 +108,13 @@ static struct bad_app_info big_list_of_dodgy_apps[] = | |||||||
|  |  | ||||||
| static const size_t num_of_dodgy_apps = sizeof (big_list_of_dodgy_apps) / sizeof (big_list_of_dodgy_apps[0]); | static const size_t num_of_dodgy_apps = sizeof (big_list_of_dodgy_apps) / sizeof (big_list_of_dodgy_apps[0]); | ||||||
|  |  | ||||||
| /* This function is not in the ntdll export lib, so it has |  | ||||||
|   to be looked up at runtime and called through a pointer.  */ |  | ||||||
| VOID NTAPI (*pRtlFreeUnicodeString)(PUNICODE_STRING) = NULL; |  | ||||||
|  |  | ||||||
| NTSTATUS NTAPI (*pNtQuerySystemInformation) (SYSTEM_INFORMATION_CLASS, |  | ||||||
|                                              PVOID, ULONG, PULONG) = NULL; |  | ||||||
|  |  | ||||||
| NTSTATUS NTAPI (*pRtlAnsiStringToUnicodeString) (PUNICODE_STRING, PANSI_STRING, |  | ||||||
|                                                BOOLEAN) = NULL; |  | ||||||
|  |  | ||||||
|  |  | ||||||
| static PSYSTEM_PROCESSES | static PSYSTEM_PROCESSES | ||||||
| get_process_list (void) | get_process_list (void) | ||||||
| { | { | ||||||
|   int n_procs = 0x100; |   int n_procs = 0x100; | ||||||
|   PSYSTEM_PROCESSES pslist = (PSYSTEM_PROCESSES) malloc (n_procs * sizeof *pslist); |   PSYSTEM_PROCESSES pslist = (PSYSTEM_PROCESSES) malloc (n_procs * sizeof *pslist); | ||||||
|  |  | ||||||
|   while (pNtQuerySystemInformation (SystemProcessesAndThreadsInformation, |   while (NtQuerySystemInformation (SystemProcessesAndThreadsInformation, | ||||||
|     pslist, n_procs * sizeof *pslist, 0) == STATUS_INFO_LENGTH_MISMATCH) |     pslist, n_procs * sizeof *pslist, 0) == STATUS_INFO_LENGTH_MISMATCH) | ||||||
|     { |     { | ||||||
|       n_procs *= 2; |       n_procs *= 2; | ||||||
| @@ -141,7 +130,7 @@ get_module_list (void) | |||||||
|   int modsize = 0x1000; |   int modsize = 0x1000; | ||||||
|   PSYSTEM_MODULE_INFORMATION modlist = (PSYSTEM_MODULE_INFORMATION) malloc (modsize); |   PSYSTEM_MODULE_INFORMATION modlist = (PSYSTEM_MODULE_INFORMATION) malloc (modsize); | ||||||
|  |  | ||||||
|   while (pNtQuerySystemInformation (SystemModuleInformation, |   while (NtQuerySystemInformation (SystemModuleInformation, | ||||||
|     modlist, modsize, NULL) == STATUS_INFO_LENGTH_MISMATCH) |     modlist, modsize, NULL) == STATUS_INFO_LENGTH_MISMATCH) | ||||||
|     { |     { | ||||||
|       modsize *= 2; |       modsize *= 2; | ||||||
| @@ -299,14 +288,14 @@ detect_dodgy_app (const struct bad_app_det *det, PSYSTEM_PROCESSES pslist, PSYST | |||||||
|       /* Equivalent of RtlInitAnsiString.  */ |       /* Equivalent of RtlInitAnsiString.  */ | ||||||
|       ansiname.Length = ansiname.MaximumLength = strlen (det->param); |       ansiname.Length = ansiname.MaximumLength = strlen (det->param); | ||||||
|       ansiname.Buffer = (CHAR *) det->param; |       ansiname.Buffer = (CHAR *) det->param; | ||||||
|       rv = pRtlAnsiStringToUnicodeString (&unicodename, &ansiname, TRUE); |       rv = RtlAnsiStringToUnicodeString (&unicodename, &ansiname, TRUE); | ||||||
|       if (rv != STATUS_SUCCESS) |       if (rv != STATUS_SUCCESS) | ||||||
|         { |         { | ||||||
|           printf ("Ansi to unicode conversion failure $%08x\n", (unsigned int) rv); |           printf ("Ansi to unicode conversion failure $%08x\n", (unsigned int) rv); | ||||||
|           break; |           break; | ||||||
|         } |         } | ||||||
|       found = find_process_in_list (pslist, &unicodename); |       found = find_process_in_list (pslist, &unicodename); | ||||||
|       pRtlFreeUnicodeString (&unicodename); |       RtlFreeUnicodeString (&unicodename); | ||||||
|       if (found) |       if (found) | ||||||
|         { |         { | ||||||
|           dbg_printf (("found!\n")); |           dbg_printf (("found!\n")); | ||||||
| @@ -347,25 +336,6 @@ dump_dodgy_apps (int verbose) | |||||||
|   size_t i, n_det = 0; |   size_t i, n_det = 0; | ||||||
|   PSYSTEM_PROCESSES pslist; |   PSYSTEM_PROCESSES pslist; | ||||||
|   PSYSTEM_MODULE_INFORMATION modlist; |   PSYSTEM_MODULE_INFORMATION modlist; | ||||||
|   HMODULE ntdll; |  | ||||||
|  |  | ||||||
|   if ((ntdll = LoadLibrary ("ntdll.dll")) == NULL) |  | ||||||
|     { |  | ||||||
|       puts ("Skipping dodgy app check on Win9x/ME."); |  | ||||||
|       return; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
| #define GPA(func,rv) \ |  | ||||||
|       if ((p##func = (rv) GetProcAddress (ntdll, #func)) == NULL) \ |  | ||||||
|         { \ |  | ||||||
|           puts ("Can't GetProcAddress() for " #func ", " \ |  | ||||||
|                 "skipping dodgy app check."); \ |  | ||||||
|           return; \ |  | ||||||
|         } |  | ||||||
|   GPA(NtQuerySystemInformation, NTSTATUS NTAPI (*) (SYSTEM_INFORMATION_CLASS,PVOID,ULONG,PULONG)); |  | ||||||
|   GPA(RtlFreeUnicodeString, VOID NTAPI (*)(PUNICODE_STRING)); |  | ||||||
|   GPA(RtlAnsiStringToUnicodeString, NTSTATUS NTAPI (*)(PUNICODE_STRING,PANSI_STRING,BOOLEAN)); |  | ||||||
| #undef GPA |  | ||||||
|  |  | ||||||
|   /* Read system info for detect testing.  */ |   /* Read system info for detect testing.  */ | ||||||
|   pslist = get_process_list (); |   pslist = get_process_list (); | ||||||
|   | |||||||
| @@ -1,6 +1,6 @@ | |||||||
| /* cygpath.cc -- convert pathnames between Windows and Unix format | /* cygpath.cc -- convert pathnames between Windows and Unix format | ||||||
|    Copyright 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, |    Copyright 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, | ||||||
|    2006, 2007 Red Hat, Inc. |    2006, 2007, 2008 Red Hat, Inc. | ||||||
|  |  | ||||||
| This file is part of Cygwin. | This file is part of Cygwin. | ||||||
|  |  | ||||||
| @@ -529,8 +529,7 @@ get_special_folder (char* path, int id) | |||||||
| static void | static void | ||||||
| get_user_folder (char* path, int id, int allid) | get_user_folder (char* path, int id, int allid) | ||||||
| { | { | ||||||
|   if (!get_special_folder (path, allusers_flag ? allid : id) && allusers_flag) |   get_special_folder (path, allusers_flag ? allid : id); | ||||||
|     get_special_folder (path, id); // Fix for Win9x without any "All Users" |  | ||||||
| } | } | ||||||
|  |  | ||||||
| static void | static void | ||||||
| @@ -740,7 +739,7 @@ print_version () | |||||||
| cygpath (cygwin) %.*s\n\ | cygpath (cygwin) %.*s\n\ | ||||||
| Path Conversion Utility\n\ | Path Conversion Utility\n\ | ||||||
| Copyright 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, \n\ | Copyright 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, \n\ | ||||||
|           2007 Red Hat, Inc.\n\ |           2007, 2008 Red Hat, Inc.\n\ | ||||||
| Compiled on %s\n\ | Compiled on %s\n\ | ||||||
| ", len, v, __DATE__); | ", len, v, __DATE__); | ||||||
| } | } | ||||||
|   | |||||||
| @@ -9,37 +9,31 @@ | |||||||
|    Cygwin license.  Please consult the file "CYGWIN_LICENSE" for |    Cygwin license.  Please consult the file "CYGWIN_LICENSE" for | ||||||
|    details. */ |    details. */ | ||||||
|  |  | ||||||
|  | #define _WIN32_WINNT 0x0600 | ||||||
| #include <ctype.h> | #include <ctype.h> | ||||||
| #include <stdlib.h> | #include <stdlib.h> | ||||||
| #include <wchar.h> | #include <wchar.h> | ||||||
| #include <stdio.h> | #include <stdio.h> | ||||||
| #include <windows.h> | #include <unistd.h> | ||||||
| #include <sys/cygwin.h> |  | ||||||
| #include <getopt.h> | #include <getopt.h> | ||||||
| #include <lmaccess.h> | #include <io.h> | ||||||
| #include <lmapibuf.h> | #include <sys/fcntl.h> | ||||||
|  | #include <sys/cygwin.h> | ||||||
|  | #include <windows.h> | ||||||
|  | #include <lm.h> | ||||||
| #include <wininet.h> | #include <wininet.h> | ||||||
| #include <iptypes.h> | #include <iptypes.h> | ||||||
| #include <ntsecapi.h> | #include <ntsecapi.h> | ||||||
|  | #include <dsgetdc.h> | ||||||
| #include <ntdef.h> | #include <ntdef.h> | ||||||
|  |  | ||||||
| #define print_win_error(x) _print_win_error(x, __LINE__) | #define print_win_error(x) _print_win_error(x, __LINE__) | ||||||
|  |  | ||||||
| static const char version[] = "$Revision$"; |  | ||||||
|  |  | ||||||
| #define MAX_SID_LEN 40 | #define MAX_SID_LEN 40 | ||||||
|  |  | ||||||
| typedef struct { | static const char version[] = "$Revision$"; | ||||||
|   LPWSTR DomainControllerName; |  | ||||||
|   LPWSTR DomainControllerAddress; | extern char *__progname; | ||||||
|   ULONG  DomainControllerAddressType; |  | ||||||
|   GUID   DomainGuid; |  | ||||||
|   LPWSTR DomainName; |  | ||||||
|   LPWSTR DnsForestName; |  | ||||||
|   ULONG  Flags; |  | ||||||
|   LPWSTR DcSiteName; |  | ||||||
|   LPWSTR ClientSiteName; |  | ||||||
| } *PDOMAIN_CONTROLLER_INFOW; |  | ||||||
|  |  | ||||||
| SID_IDENTIFIER_AUTHORITY sid_world_auth = {SECURITY_WORLD_SID_AUTHORITY}; | SID_IDENTIFIER_AUTHORITY sid_world_auth = {SECURITY_WORLD_SID_AUTHORITY}; | ||||||
| SID_IDENTIFIER_AUTHORITY sid_nt_auth = {SECURITY_NT_AUTHORITY}; | SID_IDENTIFIER_AUTHORITY sid_nt_auth = {SECURITY_NT_AUTHORITY}; | ||||||
| @@ -50,14 +44,83 @@ NET_API_STATUS WINAPI (*dsgetdcname)(LPWSTR,LPWSTR,GUID*,LPWSTR,ULONG,PDOMAIN_CO | |||||||
| #define min(a,b) (((a)<(b))?(a):(b)) | #define min(a,b) (((a)<(b))?(a):(b)) | ||||||
| #endif | #endif | ||||||
|  |  | ||||||
|  | typedef struct | ||||||
|  | { | ||||||
|  |   char *str; | ||||||
|  |   BOOL with_dom; | ||||||
|  | } domlist_t; | ||||||
|  |  | ||||||
| void | void | ||||||
| load_netapi () | _print_win_error (DWORD code, int line) | ||||||
|  | { | ||||||
|  |   char buf[4096]; | ||||||
|  |  | ||||||
|  |   if (FormatMessage (FORMAT_MESSAGE_FROM_SYSTEM | ||||||
|  |       | FORMAT_MESSAGE_IGNORE_INSERTS, | ||||||
|  |       NULL, | ||||||
|  |       code, | ||||||
|  |       MAKELANGID (LANG_NEUTRAL, SUBLANG_DEFAULT), | ||||||
|  |       (LPTSTR) buf, sizeof (buf), NULL)) | ||||||
|  |     fprintf (stderr, "mkgroup (%d): [%lu] %s", line, code, buf); | ||||||
|  |   else | ||||||
|  |     fprintf (stderr, "mkgroup (%d): error %lu", line, code); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void | ||||||
|  | load_dsgetdcname () | ||||||
| { | { | ||||||
|   HANDLE h = LoadLibrary ("netapi32.dll"); |   HANDLE h = LoadLibrary ("netapi32.dll"); | ||||||
|   if (h) |   if (h) | ||||||
|     dsgetdcname = (void *) GetProcAddress (h, "DsGetDcNameW"); |     dsgetdcname = (void *) GetProcAddress (h, "DsGetDcNameW"); | ||||||
| } | } | ||||||
|  |  | ||||||
|  | static PWCHAR | ||||||
|  | get_dcname (char *domain) | ||||||
|  | { | ||||||
|  |   static WCHAR server[INTERNET_MAX_HOST_NAME_LENGTH + 1]; | ||||||
|  |   DWORD rc; | ||||||
|  |   PWCHAR servername; | ||||||
|  |   WCHAR domain_name[MAX_DOMAIN_NAME_LEN + 1]; | ||||||
|  |   PDOMAIN_CONTROLLER_INFOW pdci = NULL; | ||||||
|  |  | ||||||
|  |   if (dsgetdcname) | ||||||
|  |     { | ||||||
|  |       if (domain) | ||||||
|  | 	{ | ||||||
|  | 	  mbstowcs (domain_name, domain, strlen (domain) + 1); | ||||||
|  | 	  rc = dsgetdcname (NULL, domain_name, NULL, NULL, 0, &pdci); | ||||||
|  | 	} | ||||||
|  |       else | ||||||
|  | 	rc = dsgetdcname (NULL, NULL, NULL, NULL, 0, &pdci); | ||||||
|  |       if (rc != ERROR_SUCCESS) | ||||||
|  | 	{ | ||||||
|  | 	  print_win_error (rc); | ||||||
|  | 	  return (PWCHAR) -1; | ||||||
|  | 	} | ||||||
|  |       wcscpy (server, pdci->DomainControllerName); | ||||||
|  |       NetApiBufferFree (pdci); | ||||||
|  |     } | ||||||
|  |   else | ||||||
|  |     { | ||||||
|  |       rc = NetGetDCName (NULL, NULL, (void *) &servername); | ||||||
|  |       if (rc == ERROR_SUCCESS && domain) | ||||||
|  | 	{ | ||||||
|  | 	  LPWSTR server = servername; | ||||||
|  | 	  mbstowcs (domain_name, domain, strlen (domain) + 1); | ||||||
|  | 	  rc = NetGetDCName (server, domain_name, (void *) &servername); | ||||||
|  | 	  NetApiBufferFree (server); | ||||||
|  | 	} | ||||||
|  |       if (rc != ERROR_SUCCESS) | ||||||
|  | 	{ | ||||||
|  | 	  print_win_error(rc); | ||||||
|  | 	  return (PWCHAR) -1; | ||||||
|  | 	} | ||||||
|  |       wcscpy (server, servername); | ||||||
|  |       NetApiBufferFree ((PVOID) servername); | ||||||
|  |     } | ||||||
|  |   return server; | ||||||
|  | } | ||||||
|  |  | ||||||
| char * | char * | ||||||
| put_sid (PSID sid) | put_sid (PSID sid) | ||||||
| { | { | ||||||
| @@ -76,48 +139,6 @@ put_sid (PSID sid) | |||||||
|   return s; |   return s; | ||||||
| } | } | ||||||
|  |  | ||||||
| void |  | ||||||
| _print_win_error(DWORD code, int line) |  | ||||||
| { |  | ||||||
|   char buf[4096]; |  | ||||||
|  |  | ||||||
|   if (FormatMessage (FORMAT_MESSAGE_FROM_SYSTEM |  | ||||||
|       | FORMAT_MESSAGE_IGNORE_INSERTS, |  | ||||||
|       NULL, |  | ||||||
|       code, |  | ||||||
|       MAKELANGID (LANG_NEUTRAL, SUBLANG_DEFAULT), |  | ||||||
|       (LPTSTR) buf, sizeof (buf), NULL)) |  | ||||||
|     fprintf (stderr, "mkgroup (%d): [%lu] %s", line, code, buf); |  | ||||||
|   else |  | ||||||
|     fprintf (stderr, "mkgroup (%d): error %lu", line, code); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| void |  | ||||||
| enum_local_users (LPWSTR servername, LPWSTR groupname) |  | ||||||
| { |  | ||||||
|   LOCALGROUP_MEMBERS_INFO_1 *buf1; |  | ||||||
|   DWORD entries = 0; |  | ||||||
|   DWORD total = 0; |  | ||||||
|   DWORD reshdl = 0; |  | ||||||
|  |  | ||||||
|   if (!NetLocalGroupGetMembers (servername, groupname, 1, (void *) &buf1, |  | ||||||
| 				MAX_PREFERRED_LENGTH, |  | ||||||
| 				&entries, &total, &reshdl)) |  | ||||||
|     { |  | ||||||
|       unsigned i, first = 1; |  | ||||||
|  |  | ||||||
|       for (i = 0; i < entries; ++i) |  | ||||||
| 	if (buf1[i].lgrmi1_sidusage == SidTypeUser) |  | ||||||
| 	  { |  | ||||||
| 	    if (!first) |  | ||||||
| 	      printf (","); |  | ||||||
| 	    first = 0; |  | ||||||
| 	    printf ("%ls", buf1[i].lgrmi1_name); |  | ||||||
| 	  } |  | ||||||
|       NetApiBufferFree (buf1); |  | ||||||
|     } |  | ||||||
| } |  | ||||||
|  |  | ||||||
| typedef struct { | typedef struct { | ||||||
|   BYTE  Revision; |   BYTE  Revision; | ||||||
|   BYTE  SubAuthorityCount; |   BYTE  SubAuthorityCount; | ||||||
| @@ -130,26 +151,48 @@ DBGSID builtin_sid_list[MAX_BUILTIN_SIDS]; | |||||||
| DWORD builtin_sid_cnt; | DWORD builtin_sid_cnt; | ||||||
|  |  | ||||||
| int | int | ||||||
| enum_local_groups (LPWSTR servername, int print_sids, int print_users, | enum_local_groups (BOOL domain, domlist_t *dom_or_machine, const char *sep, | ||||||
| 		   int id_offset, char *disp_groupname) | 		   int id_offset, char *disp_groupname) | ||||||
| { | { | ||||||
|  |   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; |   LOCALGROUP_INFO_0 *buffer; | ||||||
|   DWORD entriesread = 0; |   DWORD entriesread = 0; | ||||||
|   DWORD totalentries = 0; |   DWORD totalentries = 0; | ||||||
|   DWORD resume_handle = 0; |   DWORD resume_handle = 0; | ||||||
|   WCHAR uni_name[GNLEN + 1]; |   WCHAR gname[GNLEN + 1]; | ||||||
|   DWORD rc; |   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, 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", | ||||||
|  | 		   __progname, d_or_m); | ||||||
|  | 	  return 1; | ||||||
|  | 	} | ||||||
|  |       servername = machine; | ||||||
|  |     } | ||||||
|  |  | ||||||
|   do |   do | ||||||
|     { |     { | ||||||
|       DWORD i; |       DWORD i; | ||||||
|  |  | ||||||
|       if (disp_groupname != NULL) |       if (disp_groupname != NULL) | ||||||
| 	{ | 	{ | ||||||
| 	  mbstowcs (uni_name, disp_groupname, GNLEN + 1); | 	  mbstowcs (gname, disp_groupname, GNLEN + 1); | ||||||
| 	  rc = NetApiBufferAllocate (sizeof (LOCALGROUP_INFO_0), | 	  rc = NetApiBufferAllocate (sizeof (LOCALGROUP_INFO_0), | ||||||
| 				     (void *) &buffer); | 				     (void *) &buffer); | ||||||
| 	  buffer[0].lgrpi0_name = uni_name; | 	  buffer[0].lgrpi0_name = gname; | ||||||
| 	  entriesread = 1; | 	  entriesread = 1; | ||||||
| 	} | 	} | ||||||
|       else  |       else  | ||||||
| @@ -159,16 +202,16 @@ enum_local_groups (LPWSTR servername, int print_sids, int print_users, | |||||||
|       switch (rc) |       switch (rc) | ||||||
| 	{ | 	{ | ||||||
| 	case ERROR_ACCESS_DENIED: | 	case ERROR_ACCESS_DENIED: | ||||||
| 	  print_win_error(rc); | 	  print_win_error (rc); | ||||||
| 	  exit (1); | 	  return 1; | ||||||
|  |  | ||||||
| 	case ERROR_MORE_DATA: | 	case ERROR_MORE_DATA: | ||||||
| 	case ERROR_SUCCESS: | 	case ERROR_SUCCESS: | ||||||
| 	  break; | 	  break; | ||||||
|  |  | ||||||
| 	default: | 	default: | ||||||
| 	  print_win_error(rc); | 	  print_win_error (rc); | ||||||
| 	  exit (1); | 	  return 1; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|       for (i = 0; i < entriesread; i++) |       for (i = 0; i < entriesread; i++) | ||||||
| @@ -187,7 +230,7 @@ enum_local_groups (LPWSTR servername, int print_sids, int print_users, | |||||||
| 				   &sid_length, domain_name, &domname_len, | 				   &sid_length, domain_name, &domname_len, | ||||||
| 				   &acc_type)) | 				   &acc_type)) | ||||||
| 	    { | 	    { | ||||||
| 	      print_win_error(rc); | 	      print_win_error (rc); | ||||||
| 	      fprintf (stderr, " (%ls)\n", buffer[i].lgrpi0_name); | 	      fprintf (stderr, " (%ls)\n", buffer[i].lgrpi0_name); | ||||||
| 	      continue; | 	      continue; | ||||||
| 	    } | 	    } | ||||||
| @@ -205,7 +248,7 @@ enum_local_groups (LPWSTR servername, int print_sids, int print_users, | |||||||
|                                        domain_name, &domname_len, |                                        domain_name, &domname_len, | ||||||
|                                        &acc_type)) |                                        &acc_type)) | ||||||
|                 { |                 { | ||||||
|                   print_win_error(rc); |                   print_win_error (rc); | ||||||
| 		  fprintf(stderr, " (%ls)\n", domname); | 		  fprintf(stderr, " (%ls)\n", domname); | ||||||
|                   continue; |                   continue; | ||||||
|                 } |                 } | ||||||
| @@ -232,12 +275,12 @@ enum_local_groups (LPWSTR servername, int print_sids, int print_users, | |||||||
|  |  | ||||||
| 	  gid = *GetSidSubAuthority (psid, *GetSidSubAuthorityCount(psid) - 1); | 	  gid = *GetSidSubAuthority (psid, *GetSidSubAuthorityCount(psid) - 1); | ||||||
|  |  | ||||||
| 	  printf ("%ls:%s:%ld:", buffer[i].lgrpi0_name, | 	  printf ("%ls%s%ls:%s:%ld:\n", | ||||||
|                                 print_sids ? put_sid (psid) : "", | 		  with_dom ? domain_name : L"", | ||||||
|  | 		  with_dom ? sep : "", | ||||||
|  | 		  buffer[i].lgrpi0_name, | ||||||
|  | 		  put_sid (psid), | ||||||
| 		  gid + (is_builtin ? 0 : id_offset)); | 		  gid + (is_builtin ? 0 : id_offset)); | ||||||
| 	  if (print_users) |  | ||||||
| 	    enum_local_users (servername, buffer[i].lgrpi0_name); |  | ||||||
| 	  printf ("\n"); |  | ||||||
| skip_group: | skip_group: | ||||||
| 	  ; | 	  ; | ||||||
| 	} | 	} | ||||||
| @@ -251,48 +294,46 @@ skip_group: | |||||||
| } | } | ||||||
|  |  | ||||||
| void | void | ||||||
| enum_users (LPWSTR servername, LPWSTR groupname) | enum_groups (BOOL domain, domlist_t *dom_or_machine, const char *sep, | ||||||
| { | 	     int id_offset, char *disp_groupname) | ||||||
|   GROUP_USERS_INFO_0 *buf1; |  | ||||||
|   DWORD entries = 0; |  | ||||||
|   DWORD total = 0; |  | ||||||
|   DWORD reshdl = 0; |  | ||||||
|  |  | ||||||
|   if (!NetGroupGetUsers (servername, groupname, 0, (void *) &buf1, |  | ||||||
| 			 MAX_PREFERRED_LENGTH, &entries, &total, &reshdl)) |  | ||||||
|     { |  | ||||||
|       unsigned i, first = 1; |  | ||||||
|  |  | ||||||
|       for (i = 0; i < entries; ++i) |  | ||||||
| 	{ |  | ||||||
| 	  if (!first) |  | ||||||
| 	    printf (","); |  | ||||||
| 	  first = 0; |  | ||||||
| 	  printf ("%ls", buf1[i].grui0_name); |  | ||||||
| 	} |  | ||||||
|       NetApiBufferFree (buf1); |  | ||||||
|     } |  | ||||||
| } |  | ||||||
|  |  | ||||||
| void |  | ||||||
| enum_groups (LPWSTR servername, int print_sids, int print_users, int id_offset, |  | ||||||
| 	     char *disp_groupname) |  | ||||||
| { | { | ||||||
|  |   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; |   GROUP_INFO_2 *buffer; | ||||||
|   DWORD entriesread = 0; |   DWORD entriesread = 0; | ||||||
|   DWORD totalentries = 0; |   DWORD totalentries = 0; | ||||||
|   DWORD resume_handle = 0; |   DWORD resume_handle = 0; | ||||||
|   WCHAR uni_name[GNLEN + 1]; |   WCHAR gname[GNLEN + 1]; | ||||||
|   DWORD rc; |   DWORD rc; | ||||||
|  |  | ||||||
|  |   if (domain) | ||||||
|  |     { | ||||||
|  |       servername = get_dcname (d_or_m); | ||||||
|  |       if (servername == (PWCHAR) -1) | ||||||
|  | 	return; | ||||||
|  |     } | ||||||
|  |   else if (d_or_m) | ||||||
|  |     { | ||||||
|  |       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", | ||||||
|  | 		   __progname, d_or_m); | ||||||
|  | 	  return; | ||||||
|  | 	} | ||||||
|  |       servername = machine; | ||||||
|  |     } | ||||||
|  |  | ||||||
|   do |   do | ||||||
|     { |     { | ||||||
|       DWORD i; |       DWORD i; | ||||||
|  |  | ||||||
|       if (disp_groupname != NULL) |       if (disp_groupname != NULL) | ||||||
| 	{ | 	{ | ||||||
| 	  mbstowcs (uni_name, disp_groupname, GNLEN + 1); | 	  mbstowcs (gname, disp_groupname, GNLEN + 1); | ||||||
| 	  rc = NetGroupGetInfo (servername, (LPWSTR) & uni_name, 2, | 	  rc = NetGroupGetInfo (servername, (LPWSTR) & gname, 2, | ||||||
| 				(void *) &buffer); | 				(void *) &buffer); | ||||||
| 	  entriesread=1; | 	  entriesread=1; | ||||||
| 	} | 	} | ||||||
| @@ -303,16 +344,16 @@ enum_groups (LPWSTR servername, int print_sids, int print_users, int id_offset, | |||||||
|       switch (rc) |       switch (rc) | ||||||
| 	{ | 	{ | ||||||
| 	case ERROR_ACCESS_DENIED: | 	case ERROR_ACCESS_DENIED: | ||||||
| 	  print_win_error(rc); | 	  print_win_error (rc); | ||||||
| 	  exit (1); | 	  return; | ||||||
|  |  | ||||||
| 	case ERROR_MORE_DATA: | 	case ERROR_MORE_DATA: | ||||||
| 	case ERROR_SUCCESS: | 	case ERROR_SUCCESS: | ||||||
| 	  break; | 	  break; | ||||||
|  |  | ||||||
| 	default: | 	default: | ||||||
| 	  print_win_error(rc); | 	  print_win_error (rc); | ||||||
| 	  exit (1); | 	  return; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|       for (i = 0; i < entriesread; i++) |       for (i = 0; i < entriesread; i++) | ||||||
| @@ -325,14 +366,12 @@ enum_groups (LPWSTR servername, int print_sids, int print_users, int id_offset, | |||||||
| 	  SID_NAME_USE acc_type; | 	  SID_NAME_USE acc_type; | ||||||
|  |  | ||||||
| 	  int gid = buffer[i].grpi2_group_id; | 	  int gid = buffer[i].grpi2_group_id; | ||||||
|           if (print_sids) |  | ||||||
|             { |  | ||||||
| 	  if (!LookupAccountNameW (servername, buffer[i].grpi2_name, | 	  if (!LookupAccountNameW (servername, buffer[i].grpi2_name, | ||||||
| 				   psid, &sid_length, | 				   psid, &sid_length, | ||||||
| 				   domain_name, &domname_len, | 				   domain_name, &domname_len, | ||||||
| 				   &acc_type)) | 				   &acc_type)) | ||||||
| 	    { | 	    { | ||||||
|                   print_win_error(rc); | 	      print_win_error (rc); | ||||||
| 	      fprintf(stderr, " (%ls)\n", buffer[i].grpi2_name); | 	      fprintf(stderr, " (%ls)\n", buffer[i].grpi2_name); | ||||||
| 	      continue; | 	      continue; | ||||||
| 	    } | 	    } | ||||||
| @@ -350,18 +389,17 @@ enum_groups (LPWSTR servername, int print_sids, int print_users, int id_offset, | |||||||
| 				       domain_name, &domname_len, | 				       domain_name, &domname_len, | ||||||
| 				       &acc_type)) | 				       &acc_type)) | ||||||
| 		{ | 		{ | ||||||
|                       print_win_error(rc); | 		  print_win_error (rc); | ||||||
| 		  fprintf(stderr, " (%ls)\n", domname); | 		  fprintf(stderr, " (%ls)\n", domname); | ||||||
| 		  continue; | 		  continue; | ||||||
| 		} | 		} | ||||||
| 	    } | 	    } | ||||||
|             } | 	  printf ("%ls%s%ls:%s:%u:\n", | ||||||
| 	  printf ("%ls:%s:%u:", buffer[i].grpi2_name, | 		  with_dom ? domain_name : L"", | ||||||
|                                print_sids ? put_sid (psid) : "", | 		  with_dom ? sep : "", | ||||||
|  | 		  buffer[i].grpi2_name, | ||||||
|  | 		  put_sid (psid), | ||||||
| 		  gid + id_offset); | 		  gid + id_offset); | ||||||
| 	  if (print_users) |  | ||||||
| 	    enum_users (servername, buffer[i].grpi2_name); |  | ||||||
| 	  printf ("\n"); |  | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|       NetApiBufferFree (buffer); |       NetApiBufferFree (buffer); | ||||||
| @@ -371,8 +409,7 @@ enum_groups (LPWSTR servername, int print_sids, int print_users, int id_offset, | |||||||
| } | } | ||||||
|  |  | ||||||
| void | void | ||||||
| print_special (int print_sids, | print_special (PSID_IDENTIFIER_AUTHORITY auth, BYTE cnt, | ||||||
| 	       PSID_IDENTIFIER_AUTHORITY auth, BYTE cnt, |  | ||||||
| 	       DWORD sub1, DWORD sub2, DWORD sub3, DWORD sub4, | 	       DWORD sub1, DWORD sub2, DWORD sub3, DWORD sub4, | ||||||
| 	       DWORD sub5, DWORD sub6, DWORD sub7, DWORD sub8) | 	       DWORD sub5, DWORD sub6, DWORD sub7, DWORD sub8) | ||||||
| { | { | ||||||
| @@ -405,97 +442,96 @@ print_special (int print_sids, | |||||||
| 	    rid = sub2; | 	    rid = sub2; | ||||||
| 	  else | 	  else | ||||||
| 	    rid = sub1; | 	    rid = sub1; | ||||||
| 	  printf ("%s:%s:%lu:\n", name, | 	  printf ("%s:%s:%lu:\n", name, put_sid (sid), rid); | ||||||
| 				 print_sids ? put_sid (sid) : "", |  | ||||||
| 				 rid); |  | ||||||
|         } |         } | ||||||
|       FreeSid (sid); |       FreeSid (sid); | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  |  | ||||||
| void | void | ||||||
| current_group (int print_sids, int print_users, int id_offset) | current_group (const char *sep, int id_offset) | ||||||
| { | { | ||||||
|   char name[UNLEN + 1], *envname, *envdomain; |  | ||||||
|   DWORD len; |   DWORD len; | ||||||
|   HANDLE ptok; |   HANDLE ptok; | ||||||
|   int errpos = 0; |  | ||||||
|   struct { |   struct { | ||||||
|     PSID psid; |     PSID psid; | ||||||
|     char buffer[MAX_SID_LEN]; |     char buffer[MAX_SID_LEN]; | ||||||
|   } tg; |   } tg; | ||||||
|  |   char grp[GNLEN + 1]; | ||||||
|  |   char 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 (!OpenProcessToken (GetCurrentProcess (), TOKEN_QUERY, &ptok) | ||||||
|   if ((!GetUserName (name, (len = sizeof (name), &len)) && (errpos = __LINE__)) |       || !GetTokenInformation (ptok, TokenPrimaryGroup, &tg, sizeof tg, &len) | ||||||
|       || !name[0] |       || !CloseHandle (ptok) | ||||||
|       || !(envname = getenv("USERNAME")) |       || !LookupAccountSidA (NULL, tg.psid, grp, &glen, dom, &dlen, &acc_type)) | ||||||
|       || strcasecmp (envname, name) |  | ||||||
|       || (!GetComputerName (name, (len = sizeof (name), &len)) |  | ||||||
| 	  && (errpos = __LINE__)) |  | ||||||
|       || !(envdomain = getenv("USERDOMAIN")) |  | ||||||
|       || !envdomain[0] |  | ||||||
|       || !strcasecmp (envdomain, name) |  | ||||||
|       || (!OpenProcessToken (GetCurrentProcess (), TOKEN_QUERY, &ptok) |  | ||||||
| 	  && (errpos = __LINE__)) |  | ||||||
|       || (!GetTokenInformation (ptok, TokenPrimaryGroup, &tg, sizeof tg, &len) |  | ||||||
| 	  && (errpos = __LINE__)) |  | ||||||
|       || (!CloseHandle (ptok) && (errpos = __LINE__))) |  | ||||||
|     { |  | ||||||
|       if (errpos) |  | ||||||
|     { |     { | ||||||
|       print_win_error (GetLastError ()); |       print_win_error (GetLastError ()); | ||||||
| 	} |  | ||||||
|       return; |       return; | ||||||
|     } |     } | ||||||
|  |   gid = *GetSidSubAuthority (tg.psid, *GetSidSubAuthorityCount(tg.psid) - 1); | ||||||
|   int gid = *GetSidSubAuthority (tg.psid, *GetSidSubAuthorityCount(tg.psid) - 1); |   printf ("%s%s%s:%s:%u:\n", | ||||||
|  | 	  sep ? dom : "", | ||||||
|   printf ("mkgroup_l_d:%s:%u:", print_sids ? put_sid (tg.psid) : "", | 	  sep ?: "", | ||||||
|  | 	  grp, | ||||||
|  | 	  put_sid (tg.psid), | ||||||
| 	  gid + id_offset); | 	  gid + id_offset); | ||||||
|   if (print_users) |  | ||||||
|     printf("%s", envname); |  | ||||||
|   printf ("\n"); |  | ||||||
| } | } | ||||||
|  |  | ||||||
| int | int | ||||||
| usage (FILE * stream, int isNT) | usage (FILE * stream) | ||||||
| { | { | ||||||
|   fprintf (stream, "Usage: mkgroup [OPTION]... [domain]...\n" |   fprintf (stream, | ||||||
| 	           "Print /etc/group file to stdout\n\n" | "Usage: mkgroup [OPTION]...\n" | ||||||
| 	           "Options:\n"); | "Print /etc/group file to stdout\n" | ||||||
|   if (isNT) | "\n" | ||||||
|     fprintf (stream, "   -l,--local             print machine local group information\n" | "Options:\n" | ||||||
| 	             "   -c,--current           print current group, if a domain account\n" | "   -l,--local [machine]    print local groups (from local machine if no\n" | ||||||
| 		     "   -d,--domain            print domain group information (from current\n" | "                           machine specified)\n" | ||||||
| 	             "                          domain if no domains specified)\n" | "   -L,--Local [machine]    ditto, but generate groupname with machine prefix\n" | ||||||
| 		     "   -o,--id-offset offset  change the default offset (10000) added to gids\n" | "   -d,--domain [domain]    print domain groups (from current domain if no\n" | ||||||
| 		     "                          in domain accounts.\n" | "                           domain specified)\n" | ||||||
| 		     "   -s,--no-sids           don't print SIDs in pwd field\n" | "   -D,--Domain [domain]    ditto, but generate groupname with machine prefix\n" | ||||||
| 		     "                          (this affects ntsec)\n" | "   -c,--current            print current group\n" | ||||||
| 	             "   -u,--users             print user list in gr_mem field\n" | "   -C,--Current            ditto, but generate groupname with machine or\n" | ||||||
|                      "   -g,--group groupname   only return information for the specified group\n"); | "                           domain prefix\n" | ||||||
|   fprintf (stream, "   -h,--help              print this message\n" | "   -S,--separator char     for -L, -D, -C use character char as domain\\group\n" | ||||||
| 	           "   -v,--version           print version information and exit\n\n"); | "                           separator in groupname instead of the default '\\'\n" | ||||||
|   if (isNT) | "   -o,--id-offset offset   change the default offset (10000) added to gids\n" | ||||||
|     fprintf (stream, "One of '-l' or '-d' must be given.\n"); | "                           in domain or foreign server accounts.\n" | ||||||
|  | "   -g,--group groupname    only return information for the specified group\n" | ||||||
|  | "                           one of -l, -L, -d, -D must be specified, too\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"); | ||||||
|   return 1; |   return 1; | ||||||
| } | } | ||||||
|  |  | ||||||
| struct option longopts[] = { | struct option longopts[] = { | ||||||
|   {"local", no_argument, NULL, 'l'}, |  | ||||||
|   {"current", no_argument, NULL, 'c'}, |   {"current", no_argument, NULL, 'c'}, | ||||||
|   {"domain", no_argument, NULL, 'd'}, |   {"Current", no_argument, NULL, 'C'}, | ||||||
|   {"id-offset", required_argument, NULL, 'o'}, |   {"domain", optional_argument, NULL, 'd'}, | ||||||
|   {"no-sids", no_argument, NULL, 's'}, |   {"Domain", optional_argument, NULL, 'D'}, | ||||||
|   {"users", no_argument, NULL, 'u'}, |  | ||||||
|   {"group", required_argument, NULL, 'g'}, |   {"group", required_argument, NULL, 'g'}, | ||||||
|   {"help", no_argument, NULL, 'h'}, |   {"help", no_argument, NULL, 'h'}, | ||||||
|  |   {"local", optional_argument, NULL, 'l'}, | ||||||
|  |   {"Local", optional_argument, NULL, 'L'}, | ||||||
|  |   {"id-offset", required_argument, NULL, 'o'}, | ||||||
|  |   {"no-sids", no_argument, NULL, 's'}, | ||||||
|  |   {"separator", required_argument, NULL, 'S'}, | ||||||
|  |   {"users", no_argument, NULL, 'u'}, | ||||||
|   {"version", no_argument, NULL, 'v'}, |   {"version", no_argument, NULL, 'v'}, | ||||||
|   {0, no_argument, NULL, 0} |   {0, no_argument, NULL, 0} | ||||||
| }; | }; | ||||||
|  |  | ||||||
| char opts[] = "lcdo:sug:hv"; | char opts[] = "cCd::D::g:hl::L::o:sS:uv"; | ||||||
|  |  | ||||||
| void | void | ||||||
| print_version () | print_version () | ||||||
| @@ -520,67 +556,138 @@ Compiled on %s\n\ | |||||||
| ", len, v, __DATE__); | ", len, v, __DATE__); | ||||||
| } | } | ||||||
|  |  | ||||||
|  | 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 *) &p_dom); | ||||||
|  |       LsaClose (lsa); | ||||||
|  |       if (!NT_SUCCESS (status)) | ||||||
|  | 	return FALSE; | ||||||
|  |     } | ||||||
|  |   return !!p_dom->Sid; | ||||||
|  | } | ||||||
|  |  | ||||||
| int | int | ||||||
| main (int argc, char **argv) | main (int argc, char **argv) | ||||||
| { | { | ||||||
|   LPWSTR servername; |  | ||||||
|   DWORD rc = ERROR_SUCCESS; |  | ||||||
|   WCHAR domain_name[MAX_DOMAIN_NAME_LEN + 1]; |  | ||||||
|   int print_local = 0; |   int print_local = 0; | ||||||
|   int print_current = 0; |   domlist_t locals[16]; | ||||||
|   int print_domain = 0; |   int print_domain = 0; | ||||||
|   int print_sids = 1; |   domlist_t domains[16]; | ||||||
|   int print_users = 0; |   char *opt; | ||||||
|   int domain_specified = 0; |   int print_current = 0; | ||||||
|  |   const char *sep_char = "\\"; | ||||||
|   int id_offset = 10000; |   int id_offset = 10000; | ||||||
|  |   int c, i, off; | ||||||
|   char *disp_groupname = NULL; |   char *disp_groupname = NULL; | ||||||
|   int isRoot = 0; |   int isRoot = 0; | ||||||
|   int isNT; |   BOOL in_domain; | ||||||
|   int i; |  | ||||||
|  |  | ||||||
|   char dom[MAX_DOMAIN_NAME_LEN + 1]; |   if (!isatty (1)) | ||||||
|   DWORD len, len2; |     setmode (1, O_BINARY); | ||||||
|   PSID psid = NULL; |  | ||||||
|   SID_NAME_USE use; |  | ||||||
|  |  | ||||||
|   LSA_OBJECT_ATTRIBUTES oa = { 0, 0, 0, 0, 0, 0 }; |   load_dsgetdcname (); | ||||||
|   LSA_HANDLE lsa = INVALID_HANDLE_VALUE; |   in_domain = fetch_primary_domain (); | ||||||
|   NTSTATUS ret; |   if (argc == 1) | ||||||
|   PPOLICY_PRIMARY_DOMAIN_INFO pdi; |  | ||||||
|  |  | ||||||
|   isNT = (GetVersion () < 0x80000000); |  | ||||||
|  |  | ||||||
|   if (isNT && argc == 1) |  | ||||||
|     return usage(stderr, isNT); |  | ||||||
|   else |  | ||||||
|     { |     { | ||||||
|       while ((i = getopt_long (argc, argv, opts, longopts, NULL)) != EOF) |       print_special (&sid_nt_auth, 1, SECURITY_LOCAL_SYSTEM_RID, | ||||||
| 	switch (i) | 		     0, 0, 0, 0, 0, 0, 0); | ||||||
|  |       if (in_domain) | ||||||
|  | 	{ | ||||||
|  | 	  if (!enum_local_groups (TRUE, NULL, sep_char, id_offset, | ||||||
|  | 				  disp_groupname)) | ||||||
|  | 	    enum_groups (TRUE, NULL, sep_char, id_offset, disp_groupname); | ||||||
|  | 	} | ||||||
|  |       else if (!enum_local_groups (FALSE, NULL, sep_char, 0, disp_groupname)) | ||||||
|  | 	enum_groups (FALSE, NULL, sep_char, 0, disp_groupname); | ||||||
|  |       return 0; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |   while ((c = getopt_long (argc, argv, opts, longopts, NULL)) != EOF) | ||||||
|  |     switch (c) | ||||||
|       { |       { | ||||||
|       case 'l': |       case 'l': | ||||||
| 	  print_local = 1; |       case 'L': | ||||||
| 	  break; | 	if (print_local >= 16) | ||||||
| 	case 'c': | 	  { | ||||||
| 	  print_current = 1; | 	    fprintf (stderr, "%s: Can not enumerate from more than 16 " | ||||||
|  | 			     "servers.\n", __progname); | ||||||
|  | 	    return 1; | ||||||
|  | 	  } | ||||||
|  | 	opt = optarg ?: | ||||||
|  | 	      argv[optind] && argv[optind][0] != '-' ? argv[optind] : NULL; | ||||||
|  | 	for (i = 0; i < print_local; ++i) | ||||||
|  | 	  if ((!locals[i].str && !opt) | ||||||
|  | 	      || (locals[i].str && opt && !strcmp (locals[i].str, opt))) | ||||||
|  | 	    goto skip_local; | ||||||
|  | 	locals[print_local].str = opt; | ||||||
|  | 	locals[print_local++].with_dom = c == 'L'; | ||||||
|  |   skip_local: | ||||||
| 	break; | 	break; | ||||||
|       case 'd': |       case 'd': | ||||||
| 	  print_domain = 1; |       case 'D': | ||||||
|  | 	if (print_domain >= 16) | ||||||
|  | 	  { | ||||||
|  | 	    fprintf (stderr, "%s: Can not enumerate from more than 16 " | ||||||
|  | 			     "domains.\n", __progname); | ||||||
|  | 	    return 1; | ||||||
|  | 	  } | ||||||
|  | 	opt = optarg ?: | ||||||
|  | 	      argv[optind] && argv[optind][0] != '-' ? argv[optind] : NULL; | ||||||
|  | 	for (i = 0; i < print_domain; ++i) | ||||||
|  | 	  if ((!domains[i].str && !opt) | ||||||
|  | 	      || (domains[i].str && opt && !strcmp (domains[i].str, opt))) | ||||||
|  | 	    goto skip_domain; | ||||||
|  | 	domains[print_domain].str = opt; | ||||||
|  | 	domains[print_domain++].with_dom = c == 'D'; | ||||||
|  |   skip_domain: | ||||||
|  | 	break; | ||||||
|  |       case 'S': | ||||||
|  | 	sep_char = optarg; | ||||||
|  | 	if (strlen (sep_char) > 1) | ||||||
|  | 	  { | ||||||
|  | 	    fprintf (stderr, "%s: Only one character allowed as domain\\user " | ||||||
|  | 			     "separator character.\n", __progname); | ||||||
|  | 	    return 1; | ||||||
|  | 	  } | ||||||
|  | 	if (*sep_char == ':') | ||||||
|  | 	  { | ||||||
|  | 	    fprintf (stderr, "%s: Colon not allowed as domain\\user separator " | ||||||
|  | 			     "character.\n", __progname); | ||||||
|  | 	    return 1; | ||||||
|  | 	  } | ||||||
|  |         break; | ||||||
|  |       case 'c': | ||||||
|  |       	sep_char = NULL; | ||||||
|  | 	/*FALLTHRU*/ | ||||||
|  |       case 'C': | ||||||
|  | 	print_current = 1; | ||||||
| 	break; | 	break; | ||||||
|       case 'o': |       case 'o': | ||||||
| 	id_offset = strtol (optarg, NULL, 10); | 	id_offset = strtol (optarg, NULL, 10); | ||||||
| 	break; | 	break; | ||||||
|       case 's': |       case 's': | ||||||
| 	  print_sids = 0; |  | ||||||
| 	break; | 	break; | ||||||
|       case 'u': |       case 'u': | ||||||
| 	  print_users = 1; |  | ||||||
| 	break; | 	break; | ||||||
|       case 'g': |       case 'g': | ||||||
| 	disp_groupname = optarg; | 	disp_groupname = optarg; | ||||||
| 	isRoot = !strcmp(disp_groupname, "root"); | 	isRoot = !strcmp(disp_groupname, "root"); | ||||||
| 	break; | 	break; | ||||||
|       case 'h': |       case 'h': | ||||||
| 	  usage (stdout, isNT); | 	usage (stdout); | ||||||
| 	return 0; | 	return 0; | ||||||
|       case 'v': |       case 'v': | ||||||
| 	print_version (); | 	print_version (); | ||||||
| @@ -589,150 +696,48 @@ main (int argc, char **argv) | |||||||
| 	fprintf (stderr, "Try '%s --help' for more information.\n", argv[0]); | 	fprintf (stderr, "Try '%s --help' for more information.\n", argv[0]); | ||||||
| 	return 1; | 	return 1; | ||||||
|       } |       } | ||||||
|     } |  | ||||||
|  |  | ||||||
|   /* This takes Windows 9x/ME into account. */ |   if (optind < argc - 1) | ||||||
|   if (!isNT) |     usage (stdout); | ||||||
|     { |  | ||||||
|       printf ("all::%ld:\n", DOMAIN_ALIAS_RID_ADMINS); |  | ||||||
|       return 0; |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|   if (!print_local && !print_domain) |   /* Get 'system' group */ | ||||||
|     { |   if (!disp_groupname && (print_local > 0 || print_domain > 0)) | ||||||
|       fprintf (stderr, "%s: Specify one of '-l' or '-d'\n", argv[0]); |     print_special (&sid_nt_auth, 1, SECURITY_LOCAL_SYSTEM_RID, | ||||||
|       return 1; | 		   0, 0, 0, 0, 0, 0, 0); | ||||||
|     } |  | ||||||
|   if (optind < argc) |  | ||||||
|     { |  | ||||||
|       if (!print_domain) |  | ||||||
|         { |  | ||||||
| 	  fprintf (stderr, "%s: A domain name is only accepted " |  | ||||||
| 		   "when '-d' is given.\n", argv[0]); |  | ||||||
| 	  return 1; |  | ||||||
| 	} |  | ||||||
|       domain_specified = 1; |  | ||||||
|     } |  | ||||||
|   load_netapi (); |  | ||||||
|  |  | ||||||
|   if (print_local) |  | ||||||
|     { |  | ||||||
|       char machine[INTERNET_MAX_HOST_NAME_LENGTH + 1]; |  | ||||||
|       char sid[MAX_SID_LEN]; |  | ||||||
|  |  | ||||||
|  |   off = 1; | ||||||
|   if (isRoot) |   if (isRoot) | ||||||
|     { |     { | ||||||
| 	  /* |       /* Very special feature for the oncoming future: | ||||||
| 	   * Very special feature for the oncoming future: | 	 Create a "root" group being actually the local Administrators group. | ||||||
| 	   * Create a "root" group account, being actually the local |          Printing root disables printing any other "real" local group. */ | ||||||
| 	   * Administrators group.  Since user name, sid and gid are |  | ||||||
| 	   * fixed, there's no need to call print_special() for this. |  | ||||||
| 	   */ |  | ||||||
|       printf ("root:S-1-5-32-544:0:\n"); |       printf ("root:S-1-5-32-544:0:\n"); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|       if (disp_groupname == NULL) |  | ||||||
|         { |  | ||||||
|       /* |  | ||||||
|        * Get 'system' group |  | ||||||
|        */ |  | ||||||
|       print_special (print_sids, &sid_nt_auth, 1, SECURITY_LOCAL_SYSTEM_RID, |  | ||||||
| 		     0, 0, 0, 0, 0, 0, 0); |  | ||||||
|       /* |  | ||||||
|        * Get 'None' group |  | ||||||
|       */ |  | ||||||
|       len = INTERNET_MAX_HOST_NAME_LENGTH + 1; |  | ||||||
|       GetComputerName (machine, &len); |  | ||||||
|       len = MAX_SID_LEN; |  | ||||||
|       len2 = MAX_DOMAIN_NAME_LEN + 1; |  | ||||||
|       if (LookupAccountName (NULL, machine, (PSID) sid, &len, dom, &len2, &use)) |  | ||||||
| 	psid = (PSID) sid; |  | ||||||
|   else |   else | ||||||
|  |     for (i = 0; i < print_local; ++i) | ||||||
|       { |       { | ||||||
| 	  ret = LsaOpenPolicy (NULL, &oa, POLICY_VIEW_LOCAL_INFORMATION, &lsa); | 	if (locals[i].str) | ||||||
| 	  if (ret == STATUS_SUCCESS && lsa != INVALID_HANDLE_VALUE) |  | ||||||
| 	  { | 	  { | ||||||
| 	      ret = LsaQueryInformationPolicy (lsa, | 	    if (!enum_local_groups (FALSE, locals + i, sep_char, | ||||||
| 					       PolicyPrimaryDomainInformation, | 				    id_offset * off, disp_groupname)) | ||||||
| 					       (void *) &pdi); | 	      enum_groups (FALSE, locals + i, sep_char, id_offset * off++, | ||||||
| 	      if (ret == STATUS_SUCCESS) |  | ||||||
| 	        { |  | ||||||
| 		  if (pdi->Sid) |  | ||||||
| 		    { |  | ||||||
| 		      CopySid (MAX_SID_LEN, (PSID) sid, pdi->Sid); |  | ||||||
| 		      psid = (PSID) sid; |  | ||||||
| 		    } |  | ||||||
| 		  LsaFreeMemory (pdi); |  | ||||||
| 		} |  | ||||||
| 	      LsaClose (lsa); |  | ||||||
| 	    } |  | ||||||
| 	} |  | ||||||
|       if (!psid) |  | ||||||
|         fprintf (stderr, |  | ||||||
| 	        "WARNING: Machine local group 513 couldn't get retrieved.  Try mkgroup -d\n"); |  | ||||||
|       else |  | ||||||
| 	print_special (print_sids, GetSidIdentifierAuthority (psid), 5, |  | ||||||
| 				   *GetSidSubAuthority (psid, 0), |  | ||||||
| 				   *GetSidSubAuthority (psid, 1), |  | ||||||
| 				   *GetSidSubAuthority (psid, 2), |  | ||||||
| 				   *GetSidSubAuthority (psid, 3), |  | ||||||
| 				   513, |  | ||||||
| 				   0, |  | ||||||
| 				   0, |  | ||||||
| 				   0); |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
|       if (!isRoot) |  | ||||||
| 	enum_local_groups (NULL, print_sids, print_users, 0, disp_groupname); |  | ||||||
|     } |  | ||||||
|   i = 1; |  | ||||||
|   if (print_domain)  |  | ||||||
|     do |  | ||||||
|       { |  | ||||||
| 	PDOMAIN_CONTROLLER_INFOW pdci = NULL; |  | ||||||
|  |  | ||||||
| 	if (dsgetdcname) |  | ||||||
| 	  { |  | ||||||
| 	    if (domain_specified) |  | ||||||
| 	      { |  | ||||||
| 	        mbstowcs (domain_name, argv[optind], strlen (argv[optind]) + 1); |  | ||||||
| 		rc = dsgetdcname (NULL, domain_name, NULL, NULL, 0, &pdci); |  | ||||||
| 	      } |  | ||||||
| 	    else |  | ||||||
| 	      rc = dsgetdcname (NULL, NULL, NULL, NULL, 0, &pdci); |  | ||||||
| 	    if (rc != ERROR_SUCCESS) |  | ||||||
| 	      { |  | ||||||
| 	        print_win_error(rc); |  | ||||||
| 		return 1; |  | ||||||
| 	      } |  | ||||||
| 	    servername = pdci->DomainControllerName; |  | ||||||
| 	  } |  | ||||||
| 	else |  | ||||||
| 	  { |  | ||||||
| 	    rc = NetGetDCName (NULL, NULL, (void *) &servername); |  | ||||||
| 	    if (rc == ERROR_SUCCESS && domain_specified) |  | ||||||
| 	      { |  | ||||||
| 		LPWSTR server = servername; |  | ||||||
| 		mbstowcs (domain_name, argv[optind], strlen (argv[optind]) + 1); |  | ||||||
| 		rc = NetGetDCName (NULL, domain_name, (void *) &servername); |  | ||||||
| 		NetApiBufferFree (server); |  | ||||||
| 	      } |  | ||||||
| 	    if (rc != ERROR_SUCCESS) |  | ||||||
| 	      { |  | ||||||
| 		print_win_error(rc); |  | ||||||
| 		return 1; |  | ||||||
| 	      } |  | ||||||
| 	  } |  | ||||||
| 	enum_groups (servername, print_sids, print_users, id_offset * i, |  | ||||||
| 			   disp_groupname); | 			   disp_groupname); | ||||||
| 	enum_local_groups (servername, print_sids, print_users, id_offset * i++, |  | ||||||
| 			   disp_groupname); |  | ||||||
| 	NetApiBufferFree (pdci ? (PVOID) pdci : (PVOID) servername); |  | ||||||
| 	  } | 	  } | ||||||
|     while (++optind < argc); | 	else if (!enum_local_groups (FALSE, locals + i, sep_char, 0, | ||||||
|  | 				     disp_groupname)) | ||||||
|  | 	  enum_groups (FALSE, locals + i, sep_char, 0, disp_groupname); | ||||||
|  |       } | ||||||
|  |  | ||||||
|   if (print_current && !print_domain) |   for (i = 0; i < print_domain; ++i) | ||||||
|     current_group (print_sids, print_users, id_offset); |     { | ||||||
|  |       if (!enum_local_groups (TRUE, domains + i, sep_char, id_offset * off, | ||||||
|  | 			      disp_groupname)) | ||||||
|  | 	enum_groups (TRUE, domains + i, sep_char, id_offset * off++, | ||||||
|  | 		     disp_groupname); | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |   if (print_current) | ||||||
|  |     current_group (sep_char, id_offset); | ||||||
|  |  | ||||||
|   return 0; |   return 0; | ||||||
| } | } | ||||||
|   | |||||||
| @@ -9,21 +9,23 @@ | |||||||
|    Cygwin license.  Please consult the file "CYGWIN_LICENSE" for |    Cygwin license.  Please consult the file "CYGWIN_LICENSE" for | ||||||
|    details. */ |    details. */ | ||||||
|  |  | ||||||
|  | #define _WIN32_WINNT 0x0600 | ||||||
| #include <ctype.h> | #include <ctype.h> | ||||||
| #include <stdlib.h> | #include <stdlib.h> | ||||||
| #include <wchar.h> | #include <wchar.h> | ||||||
| #include <stdio.h> | #include <stdio.h> | ||||||
| #include <windows.h> |  | ||||||
| #include <io.h> |  | ||||||
| #include <unistd.h> | #include <unistd.h> | ||||||
| #include <sys/cygwin.h> |  | ||||||
| #include <getopt.h> | #include <getopt.h> | ||||||
| #include <lmaccess.h> | #include <io.h> | ||||||
| #include <lmapibuf.h> |  | ||||||
| #include <sys/fcntl.h> | #include <sys/fcntl.h> | ||||||
| #include <lmerr.h> | #include <sys/cygwin.h> | ||||||
| #include <lmcons.h> | #include <windows.h> | ||||||
|  | #include <lm.h> | ||||||
| #include <iptypes.h> | #include <iptypes.h> | ||||||
|  | #include <wininet.h> | ||||||
|  | #include <ntsecapi.h> | ||||||
|  | #include <dsgetdc.h> | ||||||
|  | #include <ntdef.h> | ||||||
|  |  | ||||||
| #define print_win_error(x) _print_win_error(x, __LINE__) | #define print_win_error(x) _print_win_error(x, __LINE__) | ||||||
|  |  | ||||||
| @@ -31,29 +33,41 @@ | |||||||
|  |  | ||||||
| static const char version[] = "$Revision$"; | static const char version[] = "$Revision$"; | ||||||
|  |  | ||||||
|  | extern char *__progname; | ||||||
|  |  | ||||||
| SID_IDENTIFIER_AUTHORITY sid_world_auth = {SECURITY_WORLD_SID_AUTHORITY}; | SID_IDENTIFIER_AUTHORITY sid_world_auth = {SECURITY_WORLD_SID_AUTHORITY}; | ||||||
| SID_IDENTIFIER_AUTHORITY sid_nt_auth = {SECURITY_NT_AUTHORITY}; | SID_IDENTIFIER_AUTHORITY sid_nt_auth = {SECURITY_NT_AUTHORITY}; | ||||||
|  |  | ||||||
| typedef struct { |  | ||||||
|   LPWSTR DomainControllerName; |  | ||||||
|   LPWSTR DomainControllerAddress; |  | ||||||
|   ULONG  DomainControllerAddressType; |  | ||||||
|   GUID   DomainGuid; |  | ||||||
|   LPWSTR DomainName; |  | ||||||
|   LPWSTR DnsForestName; |  | ||||||
|   ULONG  Flags; |  | ||||||
|   LPWSTR DcSiteName; |  | ||||||
|   LPWSTR ClientSiteName; |  | ||||||
| } *PDOMAIN_CONTROLLER_INFOW; |  | ||||||
|  |  | ||||||
| NET_API_STATUS WINAPI (*dsgetdcname)(LPWSTR,LPWSTR,GUID*,LPWSTR,ULONG,PDOMAIN_CONTROLLER_INFOW*); | NET_API_STATUS WINAPI (*dsgetdcname)(LPWSTR,LPWSTR,GUID*,LPWSTR,ULONG,PDOMAIN_CONTROLLER_INFOW*); | ||||||
|  |  | ||||||
| #ifndef min | #ifndef min | ||||||
| #define min(a,b) (((a)<(b))?(a):(b)) | #define min(a,b) (((a)<(b))?(a):(b)) | ||||||
| #endif | #endif | ||||||
|  |  | ||||||
|  | typedef struct  | ||||||
|  | { | ||||||
|  |   char *str; | ||||||
|  |   BOOL with_dom; | ||||||
|  | } domlist_t; | ||||||
|  |  | ||||||
| void | void | ||||||
| load_netapi () | _print_win_error(DWORD code, int line) | ||||||
|  | { | ||||||
|  |   char buf[4096]; | ||||||
|  |  | ||||||
|  |   if (FormatMessage (FORMAT_MESSAGE_FROM_SYSTEM | ||||||
|  |       | FORMAT_MESSAGE_IGNORE_INSERTS, | ||||||
|  |       NULL, | ||||||
|  |       code, | ||||||
|  |       MAKELANGID (LANG_NEUTRAL, SUBLANG_DEFAULT), | ||||||
|  |       (LPTSTR) buf, sizeof (buf), NULL)) | ||||||
|  |     fprintf (stderr, "mkpasswd (%d): [%lu] %s", line, code, buf); | ||||||
|  |   else | ||||||
|  |     fprintf (stderr, "mkpasswd (%d): error %lu", line, code); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | void | ||||||
|  | load_dsgetdcname () | ||||||
| { | { | ||||||
|   HANDLE h = LoadLibrary ("netapi32.dll"); |   HANDLE h = LoadLibrary ("netapi32.dll"); | ||||||
|  |  | ||||||
| @@ -61,6 +75,53 @@ load_netapi () | |||||||
|     dsgetdcname = (void *) GetProcAddress (h, "DsGetDcNameW"); |     dsgetdcname = (void *) GetProcAddress (h, "DsGetDcNameW"); | ||||||
| } | } | ||||||
|  |  | ||||||
|  | static PWCHAR | ||||||
|  | get_dcname (char *domain) | ||||||
|  | { | ||||||
|  |   static WCHAR server[INTERNET_MAX_HOST_NAME_LENGTH + 1]; | ||||||
|  |   DWORD rc; | ||||||
|  |   PWCHAR servername; | ||||||
|  |   WCHAR domain_name[MAX_DOMAIN_NAME_LEN + 1]; | ||||||
|  |   PDOMAIN_CONTROLLER_INFOW pdci = NULL; | ||||||
|  |  | ||||||
|  |   if (dsgetdcname) | ||||||
|  |     { | ||||||
|  |       if (domain) | ||||||
|  | 	{ | ||||||
|  | 	  mbstowcs (domain_name, domain, strlen (domain) + 1); | ||||||
|  | 	  rc = dsgetdcname (NULL, domain_name, NULL, NULL, 0, &pdci); | ||||||
|  | 	} | ||||||
|  |       else | ||||||
|  | 	rc = dsgetdcname (NULL, NULL, NULL, NULL, 0, &pdci); | ||||||
|  |       if (rc != ERROR_SUCCESS) | ||||||
|  | 	{ | ||||||
|  | 	  print_win_error(rc); | ||||||
|  | 	  return (PWCHAR) -1; | ||||||
|  | 	} | ||||||
|  |       wcscpy (server, pdci->DomainControllerName); | ||||||
|  |       NetApiBufferFree (pdci); | ||||||
|  |     } | ||||||
|  |   else | ||||||
|  |     { | ||||||
|  |       rc = NetGetDCName (NULL, NULL, (void *) &servername); | ||||||
|  |       if (rc == ERROR_SUCCESS && domain) | ||||||
|  | 	{ | ||||||
|  | 	  LPWSTR server = servername; | ||||||
|  | 	  mbstowcs (domain_name, domain, strlen (domain) + 1); | ||||||
|  | 	  rc = NetGetDCName (server, domain_name, (void *) &servername); | ||||||
|  | 	  NetApiBufferFree (server); | ||||||
|  | 	} | ||||||
|  |       if (rc != ERROR_SUCCESS) | ||||||
|  | 	{ | ||||||
|  | 	  print_win_error(rc); | ||||||
|  | 	  return (PWCHAR) -1; | ||||||
|  | 	} | ||||||
|  |       wcscpy (server, servername); | ||||||
|  |       NetApiBufferFree ((PVOID) servername); | ||||||
|  |     } | ||||||
|  |   return server; | ||||||
|  | } | ||||||
|  |  | ||||||
| char * | char * | ||||||
| put_sid (PSID sid) | put_sid (PSID sid) | ||||||
| { | { | ||||||
| @@ -112,68 +173,50 @@ uni2ansi (LPWSTR wcs, char *mbs, int size) | |||||||
| } | } | ||||||
|  |  | ||||||
| void | void | ||||||
| _print_win_error(DWORD code, int line) | current_user (int print_cygpath, const char *sep, const char *passed_home_path, | ||||||
|  | 	      int id_offset, const char *disp_username) | ||||||
| { | { | ||||||
|   char buf[4096]; |  | ||||||
|  |  | ||||||
|   if (FormatMessage (FORMAT_MESSAGE_FROM_SYSTEM |  | ||||||
|       | FORMAT_MESSAGE_IGNORE_INSERTS, |  | ||||||
|       NULL, |  | ||||||
|       code, |  | ||||||
|       MAKELANGID (LANG_NEUTRAL, SUBLANG_DEFAULT), |  | ||||||
|       (LPTSTR) buf, sizeof (buf), NULL)) |  | ||||||
|     fprintf (stderr, "mkpasswd (%d): [%lu] %s", line, code, buf); |  | ||||||
|   else |  | ||||||
|     fprintf (stderr, "mkpasswd (%d): error %lu", line, code); |  | ||||||
| } |  | ||||||
|  |  | ||||||
| void |  | ||||||
| current_user (int print_sids, int print_cygpath, |  | ||||||
| 	      const char * passed_home_path, int id_offset, const char * disp_username) |  | ||||||
| { |  | ||||||
|   char name[UNLEN + 1], *envname, *envdomain; |  | ||||||
|   DWORD len; |   DWORD len; | ||||||
|   HANDLE ptok; |   HANDLE ptok; | ||||||
|   int errpos = 0; |  | ||||||
|   struct { |   struct { | ||||||
|     PSID psid; |     PSID psid; | ||||||
|     int buffer[10]; |     int buffer[10]; | ||||||
|   } tu, tg; |   } tu, tg; | ||||||
|  |   char user[UNLEN + 1]; | ||||||
|  |   char 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}, homedir_w32[MAX_PATH] = {0}; | ||||||
|  |  | ||||||
|  |   if (!OpenProcessToken (GetCurrentProcess (), TOKEN_QUERY, &ptok) | ||||||
|   if ((!GetUserName (name, (len = sizeof (name), &len)) && (errpos = __LINE__)) |       || !GetTokenInformation (ptok, TokenUser, &tu, sizeof tu, &len) | ||||||
|       || !name[0] |       || !GetTokenInformation (ptok, TokenPrimaryGroup, &tg, sizeof tg, &len) | ||||||
|       || !(envname = getenv("USERNAME")) |       || !CloseHandle (ptok) | ||||||
|       || strcasecmp (envname, name) |       || !LookupAccountSidA (NULL, tu.psid, user, &ulen, dom, &dlen, &acc_type)) | ||||||
|       || (disp_username && strcasecmp(envname, disp_username)) |  | ||||||
|       || (!GetComputerName (name, (len = sizeof (name), &len)) |  | ||||||
| 	  && (errpos = __LINE__)) |  | ||||||
|       || !(envdomain = getenv("USERDOMAIN")) |  | ||||||
|       || !envdomain[0] |  | ||||||
|       || !strcasecmp (envdomain, name) |  | ||||||
|       || (!OpenProcessToken (GetCurrentProcess (), TOKEN_QUERY, &ptok) |  | ||||||
| 	  && (errpos = __LINE__)) |  | ||||||
|       || (!GetTokenInformation (ptok, TokenUser, &tu, sizeof tu, &len) |  | ||||||
| 	  && (errpos = __LINE__)) |  | ||||||
|       || (!GetTokenInformation (ptok, TokenPrimaryGroup, &tg, sizeof tg, &len) |  | ||||||
| 	  && (errpos = __LINE__)) |  | ||||||
|       || (!CloseHandle (ptok) && (errpos = __LINE__))) |  | ||||||
|     { |     { | ||||||
|       if (errpos) |       print_win_error (GetLastError ()); | ||||||
| 	_print_win_error (GetLastError (), errpos); |  | ||||||
|       return; |       return; | ||||||
|     } |     } | ||||||
|  |  | ||||||
|   int uid = *GetSidSubAuthority (tu.psid, *GetSidSubAuthorityCount(tu.psid) - 1); |   uid = *GetSidSubAuthority (tu.psid, *GetSidSubAuthorityCount(tu.psid) - 1); | ||||||
|   int gid = *GetSidSubAuthority (tg.psid, *GetSidSubAuthorityCount(tg.psid) - 1); |   gid = *GetSidSubAuthority (tg.psid, *GetSidSubAuthorityCount(tg.psid) - 1); | ||||||
|   char homedir_psx[MAX_PATH] = {0}, homedir_w32[MAX_PATH] = {0}; |   if (passed_home_path[0] == '\0') | ||||||
|  |     { | ||||||
|  |       char *envhome = getenv ("HOME"); | ||||||
|       char *envhomedrive = getenv ("HOMEDRIVE"); |       char *envhomedrive = getenv ("HOMEDRIVE"); | ||||||
|       char *envhomepath = getenv ("HOMEPATH"); |       char *envhomepath = getenv ("HOMEPATH"); | ||||||
|  |  | ||||||
|   if (passed_home_path[0] == '\0') |       if (envhome && envhome[0]) | ||||||
|         { |         { | ||||||
|       if (envhomepath && envhomepath[0]) | 	  if (print_cygpath) | ||||||
|  | 	    cygwin_conv_path (CCP_WIN_A_TO_POSIX | CCP_ABSOLUTE, envhome, | ||||||
|  | 			      homedir_psx, PATH_MAX); | ||||||
|  | 	  else | ||||||
|  | 	    psx_dir (envhome, homedir_psx); | ||||||
|  | 	} | ||||||
|  |       else if (envhomepath && envhomepath[0]) | ||||||
|         { |         { | ||||||
| 	  if (envhomedrive) | 	  if (envhomedrive) | ||||||
| 	    strlcpy (homedir_w32, envhomedrive, sizeof (homedir_w32)); | 	    strlcpy (homedir_w32, envhomedrive, sizeof (homedir_w32)); | ||||||
| @@ -182,41 +225,43 @@ current_user (int print_sids, int print_cygpath, | |||||||
| 	  strlcat (homedir_w32, envhomepath, sizeof (homedir_w32)); | 	  strlcat (homedir_w32, envhomepath, sizeof (homedir_w32)); | ||||||
| 	  if (print_cygpath) | 	  if (print_cygpath) | ||||||
| 	    cygwin_conv_path (CCP_WIN_A_TO_POSIX | CCP_ABSOLUTE, homedir_w32, | 	    cygwin_conv_path (CCP_WIN_A_TO_POSIX | CCP_ABSOLUTE, homedir_w32, | ||||||
| 			      homedir_psx, MAX_PATH); | 			      homedir_psx, PATH_MAX); | ||||||
| 	  else | 	  else | ||||||
| 	    psx_dir (homedir_w32, homedir_psx); | 	    psx_dir (homedir_w32, homedir_psx); | ||||||
| 	} | 	} | ||||||
|       else |       else | ||||||
|         { |         { | ||||||
| 	  strlcpy (homedir_psx, "/home/", sizeof (homedir_psx)); | 	  strlcpy (homedir_psx, "/home/", sizeof (homedir_psx)); | ||||||
| 	  strlcat (homedir_psx, envname, sizeof (homedir_psx)); | 	  strlcat (homedir_psx, user, sizeof (homedir_psx)); | ||||||
| 	} | 	} | ||||||
|     } |     } | ||||||
|   else |   else | ||||||
|     { |     { | ||||||
|       strlcpy (homedir_psx, passed_home_path, sizeof (homedir_psx)); |       strlcpy (homedir_psx, passed_home_path, sizeof (homedir_psx)); | ||||||
|       strlcat (homedir_psx, envname, sizeof (homedir_psx)); |       strlcat (homedir_psx, user, sizeof (homedir_psx)); | ||||||
|     } |     } | ||||||
|  |  | ||||||
|   printf ("%s:unused:%u:%u:%s%s%s%s%s%s%s%s:%s:/bin/bash\n", |   printf ("%s%s%s:unused:%u:%u:U-%s\\%s,%s:%s:/bin/bash\n", | ||||||
| 	  envname, | 	  sep ? dom : "", | ||||||
|  | 	  sep ?: "", | ||||||
|  | 	  user, | ||||||
| 	  uid + id_offset, | 	  uid + id_offset, | ||||||
| 	  gid + id_offset, | 	  gid + id_offset, | ||||||
| 	  envname, | 	  dom, | ||||||
| 	  print_sids ? "," : "", | 	  user, | ||||||
| 	  print_sids ? "U-" : "", | 	  put_sid (tu.psid), | ||||||
| 	  print_sids ? envdomain : "", |  | ||||||
| 	  print_sids ? "\\" : "", |  | ||||||
| 	  print_sids ? envname : "", |  | ||||||
| 	  print_sids ? "," : "", |  | ||||||
| 	  print_sids ? put_sid (tu.psid) : "", |  | ||||||
| 	  homedir_psx); | 	  homedir_psx); | ||||||
| } | } | ||||||
|  |  | ||||||
| int | int | ||||||
| enum_users (LPWSTR servername, int print_sids, int print_cygpath, | enum_users (BOOL domain, domlist_t *dom_or_machine, const char *sep, | ||||||
| 	    const char * passed_home_path, int id_offset, char *disp_username) | 	    int print_cygpath, const char *passed_home_path, int id_offset, | ||||||
|  | 	    char *disp_username) | ||||||
| { | { | ||||||
|  |   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; |   USER_INFO_3 *buffer; | ||||||
|   DWORD entriesread = 0; |   DWORD entriesread = 0; | ||||||
|   DWORD totalentries = 0; |   DWORD totalentries = 0; | ||||||
| @@ -224,6 +269,24 @@ enum_users (LPWSTR servername, int print_sids, int print_cygpath, | |||||||
|   DWORD rc; |   DWORD rc; | ||||||
|   WCHAR uni_name[UNLEN + 1]; |   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, 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", | ||||||
|  | 		   __progname, d_or_m); | ||||||
|  | 	  return 1; | ||||||
|  | 	} | ||||||
|  |       servername = machine; | ||||||
|  |     } | ||||||
|  |  | ||||||
|   do |   do | ||||||
|     { |     { | ||||||
|       DWORD i; |       DWORD i; | ||||||
| @@ -243,7 +306,7 @@ enum_users (LPWSTR servername, int print_sids, int print_cygpath, | |||||||
| 	{ | 	{ | ||||||
| 	case ERROR_ACCESS_DENIED: | 	case ERROR_ACCESS_DENIED: | ||||||
| 	  print_win_error(rc); | 	  print_win_error(rc); | ||||||
| 	  exit (1); | 	  return 1; | ||||||
|  |  | ||||||
| 	case ERROR_MORE_DATA: | 	case ERROR_MORE_DATA: | ||||||
| 	case ERROR_SUCCESS: | 	case ERROR_SUCCESS: | ||||||
| @@ -251,7 +314,7 @@ enum_users (LPWSTR servername, int print_sids, int print_cygpath, | |||||||
|  |  | ||||||
| 	default: | 	default: | ||||||
| 	  print_win_error(rc); | 	  print_win_error(rc); | ||||||
| 	  exit (1); | 	  return 1; | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
|       for (i = 0; i < entriesread; i++) |       for (i = 0; i < entriesread; i++) | ||||||
| @@ -289,8 +352,6 @@ enum_users (LPWSTR servername, int print_sids, int print_cygpath, | |||||||
| 		      stpcpy (homedir_psx, passed_home_path), | 		      stpcpy (homedir_psx, passed_home_path), | ||||||
| 		      PATH_MAX - strlen (passed_home_path)); | 		      PATH_MAX - strlen (passed_home_path)); | ||||||
|  |  | ||||||
| 	  if (print_sids) |  | ||||||
| 	    { |  | ||||||
| 	  if (!LookupAccountNameW (servername, buffer[i].usri3_name, | 	  if (!LookupAccountNameW (servername, buffer[i].usri3_name, | ||||||
| 				   psid, &sid_length, domain_name, | 				   psid, &sid_length, domain_name, | ||||||
| 				   &domname_len, &acc_type)) | 				   &domname_len, &acc_type)) | ||||||
| @@ -317,20 +378,19 @@ enum_users (LPWSTR servername, int print_sids, int print_cygpath, | |||||||
| 		  continue; | 		  continue; | ||||||
| 		} | 		} | ||||||
| 	    } | 	    } | ||||||
| 	    } |  | ||||||
| 	  printf ("%ls:unused:%u:%u:%ls%s%s%ls%s%ls%s%s:%s:/bin/bash\n", | 	  printf ("%ls%s%ls:unused:%u:%u:%ls%sU-%ls\\%ls,%s:%s:/bin/bash\n", | ||||||
|  | 		  with_dom ? domain_name : L"", | ||||||
|  | 		  with_dom ? sep : "", | ||||||
| 	  	  buffer[i].usri3_name, | 	  	  buffer[i].usri3_name, | ||||||
| 		  uid + id_offset, | 		  uid + id_offset, | ||||||
| 		  gid + id_offset, | 		  gid + id_offset, | ||||||
| 		  buffer[i].usri3_full_name ?: L"", | 		  buffer[i].usri3_full_name ?: L"", | ||||||
| 		  print_sids && buffer[i].usri3_full_name  | 		  buffer[i].usri3_full_name  | ||||||
| 		  && buffer[i].usri3_full_name[0] ? "," : "", | 		  && buffer[i].usri3_full_name[0] ? "," : "", | ||||||
| 		  print_sids ? "U-" : "", | 		  domain_name, | ||||||
| 		  print_sids ? domain_name : L"", | 		  buffer[i].usri3_name, | ||||||
| 		  print_sids && domain_name[0] ? "\\" : "", | 		  put_sid (psid), | ||||||
| 		  print_sids ? buffer[i].usri3_full_name : L"", |  | ||||||
| 		  print_sids ? "," : "", |  | ||||||
| 		  print_sids ? put_sid (psid) : "", |  | ||||||
| 		  homedir_psx); | 		  homedir_psx); | ||||||
| 	} | 	} | ||||||
|  |  | ||||||
| @@ -342,90 +402,8 @@ enum_users (LPWSTR servername, int print_sids, int print_cygpath, | |||||||
|   return 0; |   return 0; | ||||||
| } | } | ||||||
|  |  | ||||||
| int |  | ||||||
| enum_local_groups (int print_sids) |  | ||||||
| { |  | ||||||
|   LOCALGROUP_INFO_0 *buffer; |  | ||||||
|   DWORD entriesread = 0; |  | ||||||
|   DWORD totalentries = 0; |  | ||||||
|   DWORD resume_handle = 0; |  | ||||||
|   DWORD rc ; |  | ||||||
|  |  | ||||||
|   do |  | ||||||
|     { |  | ||||||
|       DWORD i; |  | ||||||
|  |  | ||||||
|       rc = NetLocalGroupEnum (NULL, 0, (void *) &buffer, 1024, |  | ||||||
| 			      &entriesread, &totalentries, &resume_handle); |  | ||||||
|       switch (rc) |  | ||||||
| 	{ |  | ||||||
| 	case ERROR_ACCESS_DENIED: |  | ||||||
| 	  print_win_error(rc); |  | ||||||
| 	  exit (1); |  | ||||||
|  |  | ||||||
| 	case ERROR_MORE_DATA: |  | ||||||
| 	case ERROR_SUCCESS: |  | ||||||
| 	  break; |  | ||||||
|  |  | ||||||
| 	default: |  | ||||||
| 	  print_win_error(rc); |  | ||||||
| 	  exit (1); |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
|       for (i = 0; i < entriesread; i++) |  | ||||||
| 	{ |  | ||||||
| 	  WCHAR domain_name[MAX_DOMAIN_NAME_LEN + 1]; |  | ||||||
| 	  DWORD domname_len = MAX_DOMAIN_NAME_LEN + 1; |  | ||||||
| 	  char psid_buffer[MAX_SID_LEN]; |  | ||||||
| 	  PSID psid = (PSID) psid_buffer; |  | ||||||
| 	  DWORD sid_length = MAX_SID_LEN; |  | ||||||
| 	  DWORD gid; |  | ||||||
| 	  SID_NAME_USE acc_type; |  | ||||||
|  |  | ||||||
| 	  if (!LookupAccountNameW (NULL, buffer[i].lgrpi0_name, psid, |  | ||||||
| 				   &sid_length, domain_name, &domname_len, |  | ||||||
| 				   &acc_type)) |  | ||||||
| 	    { |  | ||||||
| 	      print_win_error(GetLastError ()); |  | ||||||
| 	      fprintf(stderr, " (%ls)\n", buffer[i].lgrpi0_name); |  | ||||||
| 	      continue; |  | ||||||
| 	    } |  | ||||||
| 	  else if (acc_type == SidTypeDomain) |  | ||||||
| 	    { |  | ||||||
| 	      WCHAR domname[MAX_DOMAIN_NAME_LEN + GNLEN + 2]; |  | ||||||
|  |  | ||||||
| 	      wcscpy (domname, domain_name); |  | ||||||
| 	      wcscat (domname, L"\\"); |  | ||||||
| 	      wcscat (domname, buffer[i].lgrpi0_name); |  | ||||||
| 	      sid_length = MAX_SID_LEN; |  | ||||||
| 	      domname_len = MAX_DOMAIN_NAME_LEN + 1; |  | ||||||
| 	      if (!LookupAccountNameW (NULL, domname, psid, &sid_length, |  | ||||||
| 				       domain_name, &domname_len, &acc_type)) |  | ||||||
| 		{ |  | ||||||
| 		  print_win_error(GetLastError ()); |  | ||||||
| 		  fprintf(stderr, " (%ls)\n", domname); |  | ||||||
| 		  continue; |  | ||||||
| 		} |  | ||||||
| 	    } |  | ||||||
|  |  | ||||||
| 	  gid = *GetSidSubAuthority (psid, *GetSidSubAuthorityCount(psid) - 1); |  | ||||||
|  |  | ||||||
| 	  printf ("%ls:*:%ld:%ld:%s%s::\n", buffer[i].lgrpi0_name, gid, gid, |  | ||||||
| 		  print_sids ? "," : "", |  | ||||||
| 		  print_sids ? put_sid (psid) : ""); |  | ||||||
| 	} |  | ||||||
|  |  | ||||||
|       NetApiBufferFree (buffer); |  | ||||||
|  |  | ||||||
|     } |  | ||||||
|   while (rc == ERROR_MORE_DATA); |  | ||||||
|  |  | ||||||
|   return 0; |  | ||||||
| } |  | ||||||
|  |  | ||||||
| void | void | ||||||
| print_special (int print_sids, | print_special (PSID_IDENTIFIER_AUTHORITY auth, BYTE cnt, | ||||||
| 	       PSID_IDENTIFIER_AUTHORITY auth, BYTE cnt, |  | ||||||
| 	       DWORD sub1, DWORD sub2, DWORD sub3, DWORD sub4, | 	       DWORD sub1, DWORD sub2, DWORD sub3, DWORD sub4, | ||||||
| 	       DWORD sub5, DWORD sub6, DWORD sub7, DWORD sub8) | 	       DWORD sub5, DWORD sub6, DWORD sub7, DWORD sub8) | ||||||
| { | { | ||||||
| @@ -458,58 +436,70 @@ print_special (int print_sids, | |||||||
| 	    rid = sub2; | 	    rid = sub2; | ||||||
| 	  else | 	  else | ||||||
| 	    rid = sub1; | 	    rid = sub1; | ||||||
| 	  printf ("%s:*:%lu:%lu:%s%s::\n", | 	  printf ("%s:*:%lu:%lu:,%s::\n", | ||||||
| 		  name, rid, rid == 18 ? 544 : rid, /* SYSTEM hack */ | 		  name, rid, rid == 18 ? 544 : rid, /* SYSTEM hack */ | ||||||
| 		  print_sids ? "," : "", | 		  put_sid (sid)); | ||||||
| 		  print_sids ? put_sid (sid) : ""); |  | ||||||
|         } |         } | ||||||
|       FreeSid (sid); |       FreeSid (sid); | ||||||
|     } |     } | ||||||
| } | } | ||||||
|  |  | ||||||
| int | int | ||||||
| usage (FILE * stream, int isNT) | usage (FILE * stream) | ||||||
| { | { | ||||||
|   fprintf (stream, "Usage: mkpasswd [OPTION]... [domain]...\n" |   fprintf (stream, | ||||||
| 	           "Print /etc/passwd file to stdout\n\n" | "Usage: mkpasswd [OPTIONS]...\n" | ||||||
| 	           "Options:\n"); | "Print /etc/passwd file to stdout\n" | ||||||
|   if (isNT) | "\n" | ||||||
|     fprintf (stream, "   -l,--local              print local user accounts\n" | "Options:\n" | ||||||
| 	             "   -c,--current            print current account, if a domain account\n" | "   -l,--local [machine]    print local user accounts (from local machine\n" | ||||||
|                      "   -d,--domain             print domain accounts (from current domain\n" | "                           if no machine specified)\n" | ||||||
|                      "                           if no domains specified)\n" | "   -L,--Local [machine]    ditto, but generate username with machine prefix\n" | ||||||
|                      "   -o,--id-offset offset   change the default offset (10000) added to uids\n" | "   -d,--domain [domain]    print domain accounts (from current domain\n" | ||||||
|                      "                           in domain accounts.\n" | "                           if no domain specified)\n" | ||||||
|                      "   -g,--local-groups       print local group information too\n" | "   -D,--Domain [domain]    ditto, but generate username with domain prefix\n" | ||||||
|                      "                           if no domain specified\n" | "   -c,--current            print current user\n" | ||||||
|                      "   -m,--no-mount           don't use mount points for home dir\n" | "   -C,--Current            ditto, but generate username with machine or\n" | ||||||
|                      "   -s,--no-sids            don't print SIDs in GCOS field\n" | "                           domain prefix\n" | ||||||
| 	             "                           (this affects ntsec)\n"); | "   -S,--separator char     for -L, -D, -C use character char as domain\\user\n" | ||||||
|   fprintf (stream, "   -p,--path-to-home path  use specified path and not user account home dir or /home\n" | "                           separator in username instead of the default '\\'\n" | ||||||
|                    "   -u,--username username  only return information for the specified user\n" | "   -o,--id-offset offset   change the default offset (10000) added to uids\n" | ||||||
|                    "   -h,--help               displays this message\n" | "                           in domain or foreign server accounts.\n" | ||||||
| 	           "   -v,--version            version information and exit\n\n"); | "   -u,--username username  only return information for the specified user\n" | ||||||
|   if (isNT) | "                           one of -l, -L, -d, -D must be specified, too\n" | ||||||
|     fprintf (stream, "One of '-l', '-d' or '-g' must be given.\n"); | "   -p,--path-to-home path  use specified path instead of user account home dir\n" | ||||||
|  | "                           or /home prefix\n" | ||||||
|  | "   -m,--no-mount           don't use mount points for home dir\n" | ||||||
|  | "   -s,--no-sids            (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"); | ||||||
|   return 1; |   return 1; | ||||||
| } | } | ||||||
|  |  | ||||||
| struct option longopts[] = { | struct option longopts[] = { | ||||||
|   {"local", no_argument, NULL, 'l'}, |  | ||||||
|   {"current", no_argument, NULL, 'c'}, |   {"current", no_argument, NULL, 'c'}, | ||||||
|   {"domain", no_argument, NULL, 'd'}, |   {"Current", no_argument, NULL, 'C'}, | ||||||
|   {"id-offset", required_argument, NULL, 'o'}, |   {"domain", optional_argument, NULL, 'd'}, | ||||||
|  |   {"Domain", optional_argument, NULL, 'D'}, | ||||||
|   {"local-groups", no_argument, NULL, 'g'}, |   {"local-groups", no_argument, NULL, 'g'}, | ||||||
|   {"no-mount", no_argument, NULL, 'm'}, |  | ||||||
|   {"no-sids", no_argument, NULL, 's'}, |  | ||||||
|   {"path-to-home", required_argument, NULL, 'p'}, |  | ||||||
|   {"username", required_argument, NULL, 'u'}, |  | ||||||
|   {"help", no_argument, NULL, 'h'}, |   {"help", no_argument, NULL, 'h'}, | ||||||
|  |   {"local", optional_argument, NULL, 'l'}, | ||||||
|  |   {"Local", optional_argument, NULL, 'L'}, | ||||||
|  |   {"no-mount", no_argument, NULL, 'm'}, | ||||||
|  |   {"id-offset", required_argument, NULL, 'o'}, | ||||||
|  |   {"path-to-home", required_argument, NULL, 'p'}, | ||||||
|  |   {"no-sids", no_argument, NULL, 's'}, | ||||||
|  |   {"separator", required_argument, NULL, 'S'}, | ||||||
|  |   {"username", required_argument, NULL, 'u'}, | ||||||
|   {"version", no_argument, NULL, 'v'}, |   {"version", no_argument, NULL, 'v'}, | ||||||
|   {0, no_argument, NULL, 0} |   {0, no_argument, NULL, 0} | ||||||
| }; | }; | ||||||
|  |  | ||||||
| char opts[] = "lcdo:gsmhp:u:v"; | char opts[] = "cCd::D::ghl::L::mo:sS:p:u:v"; | ||||||
|  |  | ||||||
| static void | static void | ||||||
| print_version () | print_version () | ||||||
| @@ -534,55 +524,142 @@ Compiled on %s\n\ | |||||||
| ", len, v, __DATE__); | ", len, v, __DATE__); | ||||||
| } | } | ||||||
|  |  | ||||||
|  | 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 (&sid_nt_auth, 2, SECURITY_BUILTIN_DOMAIN_RID, | ||||||
|  | 		 DOMAIN_ALIAS_RID_ADMINS, 0, 0, 0, 0, 0, 0); | ||||||
|  | } | ||||||
|  |  | ||||||
|  | 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 *) &p_dom); | ||||||
|  |       LsaClose (lsa); | ||||||
|  |       if (!NT_SUCCESS (status)) | ||||||
|  | 	return FALSE; | ||||||
|  |     } | ||||||
|  |   return !!p_dom->Sid; | ||||||
|  | } | ||||||
|  |  | ||||||
| int | int | ||||||
| main (int argc, char **argv) | main (int argc, char **argv) | ||||||
| { | { | ||||||
|   LPWSTR servername = NULL; |  | ||||||
|   DWORD rc = ERROR_SUCCESS; |  | ||||||
|   WCHAR domain_name[MAX_DOMAIN_NAME_LEN + 1]; |  | ||||||
|   int print_local = 0; |   int print_local = 0; | ||||||
|   int print_current = 0; |   domlist_t locals[16]; | ||||||
|   int print_domain = 0; |   int print_domain = 0; | ||||||
|   int print_local_groups = 0; |   domlist_t domains[16]; | ||||||
|   int domain_specified = 0; |   char *opt; | ||||||
|   int print_sids = 1; |  | ||||||
|   int print_cygpath = 1; |   int print_cygpath = 1; | ||||||
|  |   int print_current = 0; | ||||||
|  |   const char *sep_char = "\\"; | ||||||
|   int id_offset = 10000; |   int id_offset = 10000; | ||||||
|   int i; |   int c, i, off; | ||||||
|   int isNT; |  | ||||||
|   char *disp_username = NULL; |   char *disp_username = NULL; | ||||||
|   char name[256], passed_home_path[MAX_PATH]; |   char passed_home_path[PATH_MAX]; | ||||||
|   DWORD len; |   BOOL in_domain; | ||||||
|  |  | ||||||
|   isNT = (GetVersion () < 0x80000000); |  | ||||||
|   passed_home_path[0] = '\0'; |   passed_home_path[0] = '\0'; | ||||||
|   if (!isatty (1)) |   if (!isatty (1)) | ||||||
|     setmode (1, O_BINARY); |     setmode (1, O_BINARY); | ||||||
|  |  | ||||||
|   if (isNT && argc == 1) |   load_dsgetdcname (); | ||||||
|     return usage (stderr, isNT); |   in_domain = fetch_primary_domain (); | ||||||
|   else |   if (argc == 1) | ||||||
|     { |     { | ||||||
|       while ((i = getopt_long (argc, argv, opts, longopts, NULL)) != EOF) |       enum_std_accounts (); | ||||||
| 	switch (i) |       if (in_domain) | ||||||
|  | 	enum_users (TRUE, NULL, sep_char, print_cygpath, passed_home_path, | ||||||
|  | 		    10000, disp_username); | ||||||
|  |       else | ||||||
|  | 	enum_users (FALSE, NULL, sep_char, print_cygpath, passed_home_path, 0, | ||||||
|  | 		    disp_username); | ||||||
|  |       return 0; | ||||||
|  |     } | ||||||
|  |  | ||||||
|  |   while ((c = getopt_long (argc, argv, opts, longopts, NULL)) != EOF) | ||||||
|  |     switch (c) | ||||||
|       { |       { | ||||||
|       case 'l': |       case 'l': | ||||||
| 	    print_local = 1; |       case 'L': | ||||||
| 	    break; | 	if (print_local >= 16) | ||||||
| 	  case 'c': | 	  { | ||||||
| 	    print_current = 1; | 	    fprintf (stderr, "%s: Can not enumerate from more than 16 " | ||||||
|  | 			     "servers.\n", __progname); | ||||||
|  | 	    return 1; | ||||||
|  | 	  } | ||||||
|  | 	opt = optarg ?: | ||||||
|  | 	      argv[optind] && argv[optind][0] != '-' ? argv[optind] : NULL; | ||||||
|  | 	for (i = 0; i < print_local; ++i) | ||||||
|  | 	  if ((!locals[i].str && !opt) | ||||||
|  | 	      || (locals[i].str && opt && !strcmp (locals[i].str, opt))) | ||||||
|  | 	    goto skip_local; | ||||||
|  | 	locals[print_local].str = opt; | ||||||
|  | 	locals[print_local++].with_dom = c == 'L'; | ||||||
|  | skip_local: | ||||||
| 	break; | 	break; | ||||||
|       case 'd': |       case 'd': | ||||||
| 	    print_domain = 1; |       case 'D': | ||||||
|  | 	if (print_domain >= 16) | ||||||
|  | 	  { | ||||||
|  | 	    fprintf (stderr, "%s: Can not enumerate from more than 16 " | ||||||
|  | 			     "domains.\n", __progname); | ||||||
|  | 	    return 1; | ||||||
|  | 	  } | ||||||
|  | 	opt = optarg ?: | ||||||
|  | 	      argv[optind] && argv[optind][0] != '-' ? argv[optind] : NULL; | ||||||
|  | 	for (i = 0; i < print_domain; ++i) | ||||||
|  | 	  if ((!domains[i].str && !opt) | ||||||
|  | 	      || (domains[i].str && opt && !strcmp (domains[i].str, opt))) | ||||||
|  | 	    goto skip_domain; | ||||||
|  | 	domains[print_domain].str = opt; | ||||||
|  | 	domains[print_domain++].with_dom = c == 'D'; | ||||||
|  | skip_domain: | ||||||
|  | 	break; | ||||||
|  |       case 'S': | ||||||
|  | 	sep_char = optarg; | ||||||
|  | 	if (strlen (sep_char) > 1) | ||||||
|  | 	  { | ||||||
|  | 	    fprintf (stderr, "%s: Only one character allowed as domain\\user " | ||||||
|  | 			     "separator character.\n", __progname); | ||||||
|  | 	    return 1; | ||||||
|  | 	  } | ||||||
|  | 	if (*sep_char == ':') | ||||||
|  | 	  { | ||||||
|  | 	    fprintf (stderr, "%s: Colon not allowed as domain\\user separator " | ||||||
|  | 			     "character.\n", __progname); | ||||||
|  | 	    return 1; | ||||||
|  | 	  } | ||||||
|  |         break; | ||||||
|  |       case 'c': | ||||||
|  | 	sep_char = NULL; | ||||||
|  | 	/*FALLTHRU*/ | ||||||
|  |       case 'C': | ||||||
|  | 	print_current = 1; | ||||||
| 	break; | 	break; | ||||||
|       case 'o': |       case 'o': | ||||||
| 	id_offset = strtol (optarg, NULL, 10); | 	id_offset = strtol (optarg, NULL, 10); | ||||||
| 	break; | 	break; | ||||||
|       case 'g': |       case 'g': | ||||||
| 	    print_local_groups = 1; |  | ||||||
| 	break; | 	break; | ||||||
|       case 's': |       case 's': | ||||||
| 	    print_sids = 0; |  | ||||||
| 	break; | 	break; | ||||||
|       case 'm': |       case 'm': | ||||||
| 	print_cygpath = 0; | 	print_cygpath = 0; | ||||||
| @@ -591,7 +668,7 @@ main (int argc, char **argv) | |||||||
| 	if (optarg[0] != '/') | 	if (optarg[0] != '/') | ||||||
| 	{ | 	{ | ||||||
| 	  fprintf (stderr, "%s: '%s' is not a fully qualified path.\n", | 	  fprintf (stderr, "%s: '%s' is not a fully qualified path.\n", | ||||||
| 		       argv[0], optarg); | 		   __progname, optarg); | ||||||
| 	  return 1; | 	  return 1; | ||||||
| 	} | 	} | ||||||
| 	strcpy (passed_home_path, optarg); | 	strcpy (passed_home_path, optarg); | ||||||
| @@ -602,134 +679,39 @@ main (int argc, char **argv) | |||||||
| 	disp_username = optarg; | 	disp_username = optarg; | ||||||
| 	break; | 	break; | ||||||
|       case 'h': |       case 'h': | ||||||
| 	    usage (stdout, isNT); | 	usage (stdout); | ||||||
| 	return 0; | 	return 0; | ||||||
|       case 'v': |       case 'v': | ||||||
| 	print_version (); | 	print_version (); | ||||||
| 	return 0; | 	return 0; | ||||||
|       default: |       default: | ||||||
| 	    fprintf (stderr, "Try '%s --help' for more information.\n", argv[0]); | 	fprintf (stderr, "Try '%s --help' for more information.\n", __progname); | ||||||
| 	return 1; | 	return 1; | ||||||
|       } |       } | ||||||
|     } |  | ||||||
|   if (!isNT) |  | ||||||
|     { |  | ||||||
|       /* This takes Windows 9x/ME into account. */ |  | ||||||
|       if (passed_home_path[0] == '\0') |  | ||||||
| 	strcpy (passed_home_path, "/home/"); |  | ||||||
|       if (!disp_username) |  | ||||||
|         { |  | ||||||
| 	  printf ("admin:use_crypt:%lu:%lu:Administrator:%sadmin:/bin/bash\n",  |  | ||||||
| 		  DOMAIN_USER_RID_ADMIN, |  | ||||||
| 		  DOMAIN_ALIAS_RID_ADMINS, |  | ||||||
| 		  passed_home_path); |  | ||||||
| 	  if (GetUserName (name, (len = 256, &len))) |  | ||||||
| 	    disp_username = name; |  | ||||||
| 	} |  | ||||||
|       if (disp_username && disp_username[0]) |  | ||||||
|         { |  | ||||||
| 	  /* Create a pseudo random uid */ |  | ||||||
| 	  unsigned long uid = 0, i; |  | ||||||
| 	  for (i = 0; disp_username[i]; i++) |  | ||||||
| 	    uid += toupper (disp_username[i]) << ((6 * i) % 25); |  | ||||||
| 	  uid = (uid % (1000 - DOMAIN_USER_RID_ADMIN - 1))  |  | ||||||
| 	    + DOMAIN_USER_RID_ADMIN + 1; |  | ||||||
|  |  | ||||||
| 	  printf ("%s:use_crypt:%lu:%lu:%s:%s%s:/bin/bash\n",  |   if (optind < argc - 1) | ||||||
| 		  disp_username, |     usage (stdout); | ||||||
| 		  uid, |  | ||||||
| 		  DOMAIN_ALIAS_RID_ADMINS, |  | ||||||
| 		  disp_username, |  | ||||||
| 		  passed_home_path, |  | ||||||
| 		  disp_username); |  | ||||||
| 	} |  | ||||||
|       return 0; |  | ||||||
|     } |  | ||||||
|   if (!print_local && !print_domain && !print_local_groups) |  | ||||||
|     { |  | ||||||
|       fprintf (stderr, "%s: Specify one of '-l', '-d' or '-g'\n", argv[0]); |  | ||||||
|       return 1; |  | ||||||
|     } |  | ||||||
|   if (optind < argc) |  | ||||||
|     { |  | ||||||
|       if (!print_domain) |  | ||||||
|         { |  | ||||||
| 	  fprintf (stderr, "%s: A domain name is only accepted " |  | ||||||
| 		   "when '-d' is given.\n", argv[0]); |  | ||||||
| 	  return 1; |  | ||||||
| 	} |  | ||||||
|       domain_specified = 1; |  | ||||||
|     } |  | ||||||
|   load_netapi (); |  | ||||||
|  |  | ||||||
|   if (disp_username == NULL) |   off = 1; | ||||||
|  |   for (i = 0; i < print_local; ++i) | ||||||
|     { |     { | ||||||
|       if (print_local) |       if (locals[i].str) | ||||||
|         { | 	enum_users (FALSE, locals + i, sep_char, print_cygpath, | ||||||
| 	  /* Generate service starter account entries. */ | 		    passed_home_path, id_offset * off++, disp_username); | ||||||
| 	  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). */ |  | ||||||
| 	  if (!print_local_groups) |  | ||||||
| 	    print_special (print_sids, &sid_nt_auth, 2, SECURITY_BUILTIN_DOMAIN_RID, |  | ||||||
| 			   DOMAIN_ALIAS_RID_ADMINS, 0, 0, 0, 0, 0, 0); |  | ||||||
| 	} |  | ||||||
|       if (print_local_groups) |  | ||||||
| 	enum_local_groups (print_sids); |  | ||||||
|     } |  | ||||||
|  |  | ||||||
|   if (print_local) |  | ||||||
|     enum_users (NULL, print_sids, print_cygpath, passed_home_path, 0, |  | ||||||
|     		disp_username); |  | ||||||
|  |  | ||||||
|   i = 1; |  | ||||||
|   if (print_domain)  |  | ||||||
|     do  |  | ||||||
|       { |  | ||||||
| 	PDOMAIN_CONTROLLER_INFOW pdci = NULL; |  | ||||||
|  |  | ||||||
| 	if (dsgetdcname) |  | ||||||
| 	  { |  | ||||||
| 	    if (domain_specified) |  | ||||||
| 	      { |  | ||||||
| 		mbstowcs (domain_name, argv[optind], strlen (argv[optind]) + 1); |  | ||||||
| 		rc = dsgetdcname (NULL, domain_name, NULL, NULL, 0, &pdci); |  | ||||||
| 	      } |  | ||||||
| 	    else |  | ||||||
| 	      rc = dsgetdcname (NULL, NULL, NULL, NULL, 0, &pdci); |  | ||||||
| 	    if (rc != ERROR_SUCCESS) |  | ||||||
| 	      { |  | ||||||
| 		print_win_error(rc); |  | ||||||
| 		return 1; |  | ||||||
| 	      } |  | ||||||
| 	    servername = pdci->DomainControllerName; |  | ||||||
| 	  } |  | ||||||
|       else |       else | ||||||
| 	{ | 	{ | ||||||
| 	    rc = NetGetDCName (NULL, NULL, (void *) &servername); | 	  enum_std_accounts (); | ||||||
| 	    if (rc == ERROR_SUCCESS && domain_specified) | 	  enum_users (FALSE, locals + i, sep_char, print_cygpath, | ||||||
| 	      { | 		      passed_home_path, 0, disp_username); | ||||||
| 		LPWSTR server = servername; |  | ||||||
| 		mbstowcs (domain_name, argv[optind], strlen (argv[optind]) + 1); |  | ||||||
| 		rc = NetGetDCName (server, domain_name, (void *) &servername); |  | ||||||
| 		NetApiBufferFree (server); |  | ||||||
| 	      } |  | ||||||
| 	    if (rc != ERROR_SUCCESS) |  | ||||||
| 	      { |  | ||||||
| 		print_win_error(rc); |  | ||||||
| 		return 1; |  | ||||||
| 	} | 	} | ||||||
|     } |     } | ||||||
| 	enum_users (servername, print_sids, print_cygpath, passed_home_path, |  | ||||||
| 		    id_offset * i++, disp_username); |  | ||||||
| 	NetApiBufferFree (pdci ? (PVOID) pdci : (PVOID) servername); |  | ||||||
|       } |  | ||||||
|     while (++optind < argc); |  | ||||||
|  |  | ||||||
|   if (print_current && !print_domain) |   for (i = 0; i < print_domain; ++i) | ||||||
|     current_user(print_sids, print_cygpath, passed_home_path, |     enum_users (TRUE, domains + i, sep_char, print_cygpath, passed_home_path, | ||||||
| 		 id_offset, disp_username); | 		id_offset * off++, disp_username); | ||||||
|  |  | ||||||
|  |   if (print_current) | ||||||
|  |     current_user (print_cygpath, sep_char, passed_home_path, id_offset, disp_username); | ||||||
|  |  | ||||||
|   return 0; |   return 0; | ||||||
| } | } | ||||||
|   | |||||||
| @@ -298,7 +298,11 @@ struct opt | |||||||
|   {"exec", MOUNT_EXEC, 0}, |   {"exec", MOUNT_EXEC, 0}, | ||||||
|   {"notexec", MOUNT_NOTEXEC, 0}, |   {"notexec", MOUNT_NOTEXEC, 0}, | ||||||
|   {"cygexec", MOUNT_CYGWIN_EXEC, 0}, |   {"cygexec", MOUNT_CYGWIN_EXEC, 0}, | ||||||
|   {"nosuid", 0, 0} |   {"nosuid", 0, 0}, | ||||||
|  |   {"acl", MOUNT_NOACL, 1}, | ||||||
|  |   {"noacl", MOUNT_NOACL, 0}, | ||||||
|  |   {"posix=1", MOUNT_NOPOSIX, 1}, | ||||||
|  |   {"posix=0", MOUNT_NOPOSIX, 0} | ||||||
| }; | }; | ||||||
|  |  | ||||||
| static bool | static bool | ||||||
| @@ -844,6 +848,10 @@ getmntent (FILE *) | |||||||
|     strcat (mnt.mnt_opts, (char *) ",noexec"); |     strcat (mnt.mnt_opts, (char *) ",noexec"); | ||||||
|   if ((m->flags & MOUNT_CYGDRIVE))	/* cygdrive */ |   if ((m->flags & MOUNT_CYGDRIVE))	/* cygdrive */ | ||||||
|     strcat (mnt.mnt_opts, (char *) ",cygdrive"); |     strcat (mnt.mnt_opts, (char *) ",cygdrive"); | ||||||
|  |   if ((m->flags & MOUNT_NOACL)) | ||||||
|  |     strcat (mnt.mnt_opts, (char *) ",noacl"); | ||||||
|  |   if ((m->flags & MOUNT_NOPOSIX)) | ||||||
|  |     strcat (mnt.mnt_opts, (char *) ",posix=0"); | ||||||
|   mnt.mnt_freq = 1; |   mnt.mnt_freq = 1; | ||||||
|   mnt.mnt_passno = 1; |   mnt.mnt_passno = 1; | ||||||
|   m++; |   m++; | ||||||
|   | |||||||
| @@ -1,6 +1,7 @@ | |||||||
| /* ps.cc | /* ps.cc | ||||||
|  |  | ||||||
|    Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004 Red Hat, Inc. |    Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, | ||||||
|  |    2008 Red Hat, Inc. | ||||||
|  |  | ||||||
| This file is part of Cygwin. | This file is part of Cygwin. | ||||||
|  |  | ||||||
|   | |||||||
| @@ -505,69 +505,75 @@ SIGUSR2     31    user defined signal 2 | |||||||
| <sect2 id="mkgroup"><title>mkgroup</title> | <sect2 id="mkgroup"><title>mkgroup</title> | ||||||
|  |  | ||||||
| <screen> | <screen> | ||||||
| Usage: mkgroup [OPTION]... [domain]... | Usage: mkgroup [OPTION]... | ||||||
| Prints /etc/group file to stdout | Print /etc/group file to stdout | ||||||
|  |  | ||||||
| Options: | Options: | ||||||
|    -l,--local             print local group information |    -l,--local [machine]    print local groups (from local machine if no | ||||||
|    -c,--current           print current group, if a domain account |                            machine specified) | ||||||
|    -d,--domain            print global group information (from current |    -L,--Local [machine]    ditto, but generate groupname with machine prefix | ||||||
|                           domain if no domains specified). |    -d,--domain [domain]    print domain groups (from current domain if no | ||||||
|  |                            domain specified) | ||||||
|  |    -D,--Domain [domain]    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 |    -o,--id-offset offset   change the default offset (10000) added to gids | ||||||
|                           in domain accounts. |                            in domain or foreign server accounts. | ||||||
|    -s,--no-sids           don't print SIDs in pwd field |    -g,--group groupname    only return information for the specified group | ||||||
|                           (this affects ntsec) |                            one of -l, -L, -d, -D must be specified, too | ||||||
|    -u,--users             print user list in gr_mem field |    -s,--no-sids            (ignored) | ||||||
|    -g,--group groupname   only return information for the specified group\n"); |    -u,--users              (ignored) | ||||||
|    -h,--help               print this message |    -h,--help               print this message | ||||||
|  |  | ||||||
|    -v,--version            print version information and exit |    -v,--version            print version information and exit | ||||||
|  |  | ||||||
| One of `-l' or `-d' must be given on NT/W2K. | Default is to print local groups on stand-alone machines, plus domain | ||||||
|  | groups on domain controllers and domain member machines. | ||||||
| </screen> | </screen> | ||||||
|  |  | ||||||
| <para>The <command>mkgroup</command> program can be used to help | <para>The <command>mkgroup</command> program can be used to help | ||||||
| configure your Windows system to be more UNIX-like by creating an | configure Cygwin by creating a <filename>/etc/group</filename> | ||||||
| initial <filename>/etc/group</filename>. | file.  Its use is essential to include Windows security information.</para> | ||||||
| Its use is essential on the NT series (Windows NT, 2000, and XP) to |  | ||||||
| include Windows security information. |  | ||||||
| It can also be used on the Win9x series (Windows 95, 98, and Me) to |  | ||||||
| create a file with the correct format. |  | ||||||
| To initially set up your machine if you are a local user, you'd do |  | ||||||
| something like this:</para> |  | ||||||
|  |  | ||||||
| <example id="utils-mkgroup-ex"><title>Setting up the groups file for local accounts</title> | <para>The command is initially called by <command>setup.exe</command> to | ||||||
| <screen> | create a default <filename>/etc/group</filename>.  This should be | ||||||
| <prompt>$</prompt> <userinput>mkdir /etc</userinput> | sufficient in most circumstances.  However, especially when working | ||||||
| <prompt>$</prompt> <userinput>mkgroup -l > /etc/group</userinput> | in a multi-domain environment, you can use <command>mkgroup</command> | ||||||
| </screen> | manually to create a more complete <filename>/etc/group</filename> file for | ||||||
| </example> | 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 | <para>Note that this information is static.  If you change the group | ||||||
| information in your system, you'll need to regenerate the group file | information in your system, you'll need to regenerate the group file | ||||||
| for it to have the new information.</para> | for it to have the new information.</para> | ||||||
|  |  | ||||||
| <para>The <literal>-d</literal> and <literal>-l</literal> options | <para>The <literal>-d/-D</literal> and <literal>-l/-L</literal> options | ||||||
| allow you to specify where the information comes from, the | allow you to specify where the information comes from, the | ||||||
| local machine or the domain (default or given), or both. | local SAM of a machine or from the domain, or both. | ||||||
| With the  <literal>-d</literal> option the program contacts the Domain | With the <literal>-d/-D</literal> options the program contacts a Domain | ||||||
| Controller, which my be unreachable or have restricted access. | Controller, which my be unreachable or have restricted access. | ||||||
| An entry for the current domain user can then be created by using the | For very simple needs, an entry for the current user's group can be | ||||||
| option <literal>-c</literal> together with <literal>-l</literal>, | created by using the option <literal>-c</literal> or <literal>-C</literal>. | ||||||
| but <literal>-c</literal> has no effect when used with <literal>-d</literal>. | If you want to use one of the <literal>-D</literal>, <literal>-L</literal> | ||||||
| The <literal>-o</literal> option allows for special cases | 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> | ||||||
|  |  | ||||||
|  | <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+ > /etc/group</userinput> | ||||||
|  | <prompt>$</prompt> <userinput>cat /etc/group</userinput> | ||||||
|  | DOMAIN+my_group:S-1-5-21-2913048732-1697188782-3448811101-1144:11144: | ||||||
|  | </screen> | ||||||
|  | </example> | ||||||
|  |  | ||||||
|  | <para>The <literal>-o</literal> option allows for special cases | ||||||
| (such as multiple domains) where the GIDs might match otherwise. | (such as multiple domains) where the GIDs might match otherwise. | ||||||
| The <literal>-s</literal> | The <literal>-g</literal> option only prints the information for one group. | ||||||
| option omits the NT Security Identifier (SID).  For more information on  |  | ||||||
| SIDs, see <xref linkend="ntsec"></xref> in the Cygwin User's Guide.  The |  | ||||||
| <literal>-u</literal> option causes <command>mkgroup</command> to  |  | ||||||
| enumerate the users for each group, placing the group members in the  |  | ||||||
| gr_mem (last) field.  Note that this can greatly increase |  | ||||||
| the time for <command>mkgroup</command> to run in a large domain. |  | ||||||
| Having gr_mem fields is helpful when a domain user logs in remotely |  | ||||||
| while the local machine is disconnected from the Domain Controller. |  | ||||||
| The <literal>-g</literal> option only prints the information for |  | ||||||
| one group. |  | ||||||
| </para> | </para> | ||||||
|  |  | ||||||
| </sect2> | </sect2> | ||||||
| @@ -575,68 +581,74 @@ one group. | |||||||
| <sect2 id="mkpasswd"><title>mkpasswd</title> | <sect2 id="mkpasswd"><title>mkpasswd</title> | ||||||
|  |  | ||||||
| <screen> | <screen> | ||||||
| Usage: mkpasswd [OPTION]... [domain]... | Usage: mkpasswd [OPTIONS]... | ||||||
| Prints /etc/passwd file to stdout | Print /etc/passwd file to stdout | ||||||
|  |  | ||||||
| Options: | Options: | ||||||
|    -l,--local              print local user accounts |    -l,--local [machine]    print local user accounts (from local machine | ||||||
|    -c,--current            print current account, if a domain account |                            if no machine specified) | ||||||
|    -d,--domain             print domain accounts (from current domain |    -L,--Local [machine]    ditto, but generate username with machine prefix | ||||||
|                            if no domains specified) |    -d,--domain [domain]    print domain accounts (from current domain | ||||||
|  |                            if no domain specified) | ||||||
|  |    -D,--Domain [domain]    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 |    -o,--id-offset offset   change the default offset (10000) added to uids | ||||||
|                            in domain accounts. |                            in domain or foreign server accounts. | ||||||
|    -g,--local-groups       print local group information too |  | ||||||
|                            if no domains specified |  | ||||||
|    -m,--no-mount           don't use mount points for home dir |  | ||||||
|    -s,--no-sids            don't print SIDs in GCOS field |  | ||||||
|                            (this affects ntsec) |  | ||||||
|    -p,--path-to-home path  use specified path and not user account home dir or /home |  | ||||||
|    -u,--username username  only return information for the specified user |    -u,--username username  only return information for the specified user | ||||||
|  |                            one of -l, -L, -d, -D must be specified, too | ||||||
|  |    -p,--path-to-home path  use specified path instead of user account home dir | ||||||
|  |                            or /home prefix | ||||||
|  |    -m,--no-mount           don't use mount points for home dir | ||||||
|  |    -s,--no-sids            (ignored) | ||||||
|  |    -g,--local-groups       (ignored) | ||||||
|    -h,--help               displays this message |    -h,--help               displays this message | ||||||
|    -v,--version            version information and exit |    -v,--version            version information and exit | ||||||
|  |  | ||||||
| One of `-l', `-d' or `-g' must be given on NT/W2K. | Default is to print local accounts on stand-alone machines, domain accounts | ||||||
|  | on domain controllers and domain member machines. | ||||||
| </screen> | </screen> | ||||||
|  |  | ||||||
| <para>The <command>mkpasswd</command> program can be used to help | <para>The <command>mkpasswd</command> program can be used to help | ||||||
| configure your Windows system to be more UNIX-like by creating an | configure Cygwin by creating a <filename>/etc/passwd</filename> from | ||||||
| initial <filename>/etc/passwd</filename> from your system information. | your system information. | ||||||
| Its use is essential on the NT series (Windows NT, 2000, and XP) to | Its use is essential to include Windows security information.  However, | ||||||
| include Windows security information, but the actual passwords are | the actual passwords are determined by Windows, not by the content of | ||||||
| determined by Windows, not by the content of <filename>/etc/passwd</filename>. | <filename>/etc/passwd</filename>.</para> | ||||||
| On the Win9x series (Windows 95, 98, and Me) the password field must be |  | ||||||
| replaced by the output of <userinput>crypt your_password</userinput> |  | ||||||
| if remote access is desired. |  | ||||||
| To initially set up your machine if you are a local user, you'd do |  | ||||||
| something like this:</para> |  | ||||||
|  |  | ||||||
| <example id="utils-mkpasswd-ex"><title>Setting up the passwd file for local accounts</title> | <para>The command is initially called by <command>setup.exe</command> to | ||||||
| <screen> | create a default <filename>/etc/passwd</filename>.  This should be | ||||||
| <prompt>$</prompt> <userinput>mkdir /etc</userinput> | sufficient in most circumstances.  However, especially when working | ||||||
| <prompt>$</prompt> <userinput>mkpasswd -l > /etc/passwd</userinput> | in a multi-domain environment, you can use <command>mkpasswd</command> | ||||||
| </screen> | manually to create a more complete <filename>/etc/passwd</filename> file for | ||||||
| </example> | 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 | <para>Note that this information is static.  If you change the user | ||||||
| information in your system, you'll need to regenerate the passwd file | information in your system, you'll need to regenerate the passwd file | ||||||
| for it to have the new information.</para> | for it to have the new information.</para> | ||||||
|  |  | ||||||
| <para>The <literal>-d</literal> and <literal>-l</literal> options | <para>The <literal>-d/-D</literal> and <literal>-l/-L</literal> options | ||||||
| allow you to specify where the information comes from, the | allow you to specify where the information comes from, the | ||||||
| local machine or the domain (default or given), or both. | local machine or the domain (default or given), or both. | ||||||
| With the  <literal>-d</literal> option the program contacts the Domain | With the  <literal>-d/-D</literal> options the program contacts the Domain | ||||||
| Controller, which my be unreachable or have restricted access. | Controller, which may be unreachable or have restricted access. | ||||||
| An entry for the current domain user can then be created by using the | An entry for the current user can be created by using the | ||||||
| option <literal>-c</literal> together with <literal>-l</literal>, | option <literal>-c</literal> or  <literal>-C</literal>. | ||||||
| but <literal>-c</literal> has no effect when used with <literal>-d</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, simialar to the <command>mkgroup</command>. | ||||||
| The <literal>-o</literal> option allows for special cases | The <literal>-o</literal> option allows for special cases | ||||||
| (such as multiple domains) where the UIDs might match otherwise. | (such as multiple domains) where the UIDs might match otherwise. | ||||||
| The <literal>-g</literal> option creates a local | The <literal>-m</literal> option bypasses the current | ||||||
| user that corresponds to each local group. This is because NT assigns groups |  | ||||||
| file ownership.  The <literal>-m</literal> option bypasses the current |  | ||||||
| mount table so that, for example, two users who have a Windows home  | mount table so that, for example, two users who have a Windows home  | ||||||
| directory of H: could mount them differently.  The <literal>-s</literal> | directory of H: could mount them differently.  For more information on | ||||||
| option omits the NT Security Identifier (SID).  For more information on |  | ||||||
| SIDs, see <xref linkend="ntsec"></xref> in the Cygwin User's Guide.  The | SIDs, see <xref linkend="ntsec"></xref> in the Cygwin User's Guide.  The | ||||||
| <literal>-p</literal> option causes <command>mkpasswd</command> to | <literal>-p</literal> option causes <command>mkpasswd</command> to | ||||||
| use the specified prefix instead of the account home dir or <literal>/home/ | use the specified prefix instead of the account home dir or <literal>/home/ | ||||||
| @@ -649,9 +661,8 @@ use the specified prefix instead of the account home dir or <literal>/home/ | |||||||
| </example> | </example> | ||||||
|  |  | ||||||
| would put local users' home directories in the Windows 'Profiles' directory.  | would put local users' home directories in the Windows 'Profiles' directory.  | ||||||
| On Win9x machines the <literal>-u</literal> option creates an entry for | The <literal>-u</literal> option creates just an entry for | ||||||
| the specified user. On the NT series it restricts the output to that user, | the specified user.</para> | ||||||
| greatly reducing the amount of time it takes in a large domain.</para> |  | ||||||
|  |  | ||||||
| </sect2> | </sect2> | ||||||
|  |  | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user