Welcome to mirror list, hosted at ThFree Co, Russian Federation.

cygwin.com/git/newlib-cygwin.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/winsup
diff options
context:
space:
mode:
Diffstat (limited to 'winsup')
-rw-r--r--winsup/cygserver/ChangeLog12
-rw-r--r--winsup/cygserver/Makefile.in4
-rw-r--r--winsup/cygserver/client.cc4
-rw-r--r--winsup/cygserver/pwdgrp.cc161
-rw-r--r--winsup/cygwin/ChangeLog880
-rw-r--r--winsup/cygwin/Makefile.in4
-rw-r--r--winsup/cygwin/autoload.cc34
-rw-r--r--winsup/cygwin/cygheap.h132
-rw-r--r--winsup/cygwin/cygserver.h1
-rw-r--r--winsup/cygwin/cygserver_pwdgrp.h73
-rw-r--r--winsup/cygwin/cygtls.h11
-rw-r--r--winsup/cygwin/dcrt0.cc6
-rw-r--r--winsup/cygwin/errno.cc8
-rw-r--r--winsup/cygwin/external.cc131
-rw-r--r--winsup/cygwin/fhandler_disk_file.cc52
-rw-r--r--winsup/cygwin/fhandler_process.cc1
-rw-r--r--winsup/cygwin/fhandler_registry.cc4
-rw-r--r--winsup/cygwin/fhandler_socket.cc8
-rw-r--r--winsup/cygwin/grp.cc530
-rw-r--r--winsup/cygwin/import/rexec.c391
-rw-r--r--winsup/cygwin/include/cygwin/version.h5
-rw-r--r--winsup/cygwin/include/sys/cygwin.h22
-rw-r--r--winsup/cygwin/ldap.cc627
-rw-r--r--winsup/cygwin/ldap.h80
-rw-r--r--winsup/cygwin/miscfuncs.cc76
-rw-r--r--winsup/cygwin/miscfuncs.h21
-rw-r--r--winsup/cygwin/mount.cc82
-rw-r--r--winsup/cygwin/passwd.cc674
-rw-r--r--winsup/cygwin/path.cc136
-rw-r--r--winsup/cygwin/path.h17
-rw-r--r--winsup/cygwin/pinfo.cc4
-rw-r--r--winsup/cygwin/pwdgrp.h256
-rw-r--r--winsup/cygwin/release/1.7.312
-rw-r--r--winsup/cygwin/release/1.7.3215
-rw-r--r--winsup/cygwin/sec_acl.cc20
-rw-r--r--winsup/cygwin/sec_auth.cc112
-rw-r--r--winsup/cygwin/sec_helper.cc148
-rw-r--r--winsup/cygwin/security.cc99
-rw-r--r--winsup/cygwin/security.h70
-rw-r--r--winsup/cygwin/setlsapwd.cc5
-rw-r--r--winsup/cygwin/shared.cc2
-rw-r--r--winsup/cygwin/syscalls.cc1
-rw-r--r--winsup/cygwin/thread.cc4
-rw-r--r--winsup/cygwin/tlsoffsets.h216
-rw-r--r--winsup/cygwin/tlsoffsets64.h216
-rw-r--r--winsup/cygwin/uinfo.cc1579
-rw-r--r--winsup/cygwin/wincap.cc7
-rw-r--r--winsup/cygwin/wincap.h4
-rw-r--r--winsup/cygwin/winlean.h14
-rw-r--r--winsup/cygwin/winsup.h25
-rw-r--r--winsup/doc/ChangeLog4
-rw-r--r--winsup/doc/new-features.xml27
-rw-r--r--winsup/utils/ChangeLog34
-rw-r--r--winsup/utils/mkgroup.c418
-rw-r--r--winsup/utils/mkpasswd.c449
-rw-r--r--winsup/utils/utils.xml215
56 files changed, 1867 insertions, 6266 deletions
diff --git a/winsup/cygserver/ChangeLog b/winsup/cygserver/ChangeLog
index 1104918c3..653f531fb 100644
--- a/winsup/cygserver/ChangeLog
+++ b/winsup/cygserver/ChangeLog
@@ -21,11 +21,6 @@
2014-04-16 Corinna Vinschen <corinna@vinschen.de>
- * pwdgrp.cc (client_request_pwdgrp::pwd_serve): Add 1 to the message
- length to account for the trailing NUL.
-
-2014-04-16 Corinna Vinschen <corinna@vinschen.de>
-
* cygserver-config: Use numeric id 18 instead of "system" in chown.
2014-04-07 Corinna Vinschen <corinna@vinschen.de>
@@ -35,13 +30,6 @@
2014-03-12 Corinna Vinschen <corinna@vinschen.de>
- * Makefile.in (OBJS): Add pwdgrp.o.
- * client.cc (client_request::handle_request): Handle
- CYGSERVER_REQUEST_PWDGRP message.
- * pwdgrp.cc: New file implementing CYGSERVER_REQUEST_PWDGRP.
-
-2014-03-12 Corinna Vinschen <corinna@vinschen.de>
-
* Throughout, fix format specifiers in debug statements to accommodate
x86_64.
diff --git a/winsup/cygserver/Makefile.in b/winsup/cygserver/Makefile.in
index 816f5b3db..e2fe30992 100644
--- a/winsup/cygserver/Makefile.in
+++ b/winsup/cygserver/Makefile.in
@@ -1,5 +1,5 @@
# Makefile for Cygwin server
-# Copyright 2003, 2006, 2007, 2008, 2009, 2014 Red Hat, Inc.
+# Copyright 2003, 2006, 2007, 2008, 2009 Red Hat, Inc.
# This file is part of Cygwin.
@@ -46,7 +46,7 @@ AR:=@AR@
OBJS:= cygserver.o client.o process.o msg.o sem.o shm.o threaded_queue.o \
transport.o transport_pipes.o \
bsd_helper.o bsd_log.o bsd_mutex.o \
- sysv_msg.o sysv_sem.o sysv_shm.o setpwd.o pwdgrp.o
+ sysv_msg.o sysv_sem.o sysv_shm.o setpwd.o
LIBOBJS:=${patsubst %.o,lib%.o,$(OBJS)}
CYGWIN_OBJS:=$(cygwin_build)/version.o
diff --git a/winsup/cygserver/client.cc b/winsup/cygserver/client.cc
index 0c6c24ba9..9c890f7a8 100644
--- a/winsup/cygserver/client.cc
+++ b/winsup/cygserver/client.cc
@@ -26,7 +26,6 @@ details. */
#include "cygserver_sem.h"
#include "cygserver_shm.h"
#include "cygserver_setpwd.h"
-#include "cygserver_pwdgrp.h"
#include "cygserver.h"
#include "transport.h"
@@ -286,9 +285,6 @@ client_request::handle_request (transport_layer_base *const conn,
case CYGSERVER_REQUEST_SETPWD:
req = new client_request_setpwd;
break;
- case CYGSERVER_REQUEST_PWDGRP:
- req = new client_request_pwdgrp;
- break;
default:
syscall_printf ("unknown request code %d received: request ignored",
header.request_code);
diff --git a/winsup/cygserver/pwdgrp.cc b/winsup/cygserver/pwdgrp.cc
deleted file mode 100644
index cc12deadd..000000000
--- a/winsup/cygserver/pwdgrp.cc
+++ /dev/null
@@ -1,161 +0,0 @@
-/* pwdgrp.cc: Request account information
-
- Copyright 2014 Red Hat, Inc.
-
-This file is part of Cygwin.
-
-This software is a copyrighted work licensed under the terms of the
-Cygwin license. Please consult the file "CYGWIN_LICENSE" for
-details. */
-
-#ifdef __OUTSIDE_CYGWIN__
-#include "woutsup.h"
-
-#include <stdio.h>
-#include <errno.h>
-#include <pwd.h>
-#include <grp.h>
-#include <sys/cygwin.h>
-
-#include "cygserver.h"
-#include "process.h"
-#include "transport.h"
-
-#include "cygserver_pwdgrp.h"
-
-#include <sddl.h>
-
-client_request_pwdgrp::client_request_pwdgrp ()
- : client_request (CYGSERVER_REQUEST_PWDGRP,
- &_parameters, sizeof (_parameters))
-{
-}
-
-void
-client_request_pwdgrp::pwd_serve ()
-{
- struct passwd *pwd = NULL;
-
- switch (_parameters.in.type)
- {
- case SID_arg:
- pwd = (struct passwd *) cygwin_internal (CW_GETPWSID, 0,
- &_parameters.in.arg.sid);
- break;
- case NAME_arg:
- pwd = getpwnam (_parameters.in.arg.name);
- break;
- case ID_arg:
- pwd = getpwuid (_parameters.in.arg.id);
- break;
- }
- if (pwd)
- msglen (snprintf (_parameters.out.line, sizeof _parameters.out.line,
- "%s:%s:%u:%u:%s:%s:%s",
- pwd->pw_name ?: "",
- pwd->pw_passwd ?: "",
- (uint32_t) pwd->pw_uid,
- (uint32_t) pwd->pw_gid,
- pwd->pw_gecos ?: "",
- pwd->pw_dir ?: "",
- pwd->pw_shell ?: "") + 1);
- else
- {
- switch (_parameters.in.type)
- {
- case SID_arg:
- {
- char *str;
- if (ConvertSidToStringSid (&_parameters.in.arg.sid, &str))
- {
- debug_printf ("User <%s> failed", str);
- LocalFree (str);
- }
- }
- break;
- case NAME_arg:
- debug_printf ("User <%s> failed", _parameters.in.arg.name);
- break;
- case ID_arg:
- debug_printf ("User <%u> failed", _parameters.in.arg.id);
- break;
- }
- _parameters.out.line[0] = '\0';
- msglen (0);
- error_code (ENOENT);
- }
-}
-
-void
-client_request_pwdgrp::grp_serve ()
-{
- struct group *grp = NULL;
-
- switch (_parameters.in.type)
- {
- case SID_arg:
- grp = (struct group *) cygwin_internal (CW_GETGRSID, 0,
- &_parameters.in.arg.sid);
- break;
- case NAME_arg:
- grp = getgrnam (_parameters.in.arg.name);
- break;
- case ID_arg:
- grp = getgrgid (_parameters.in.arg.id);
- break;
- }
- if (grp)
- msglen (snprintf (_parameters.out.line, sizeof _parameters.out.line,
- "%s:%s:%u:",
- grp->gr_name ?: "",
- grp->gr_passwd ?: "",
- (uint32_t) grp->gr_gid) + 1);
- else
- {
- switch (_parameters.in.type)
- {
- case SID_arg:
- {
- char *str;
- if (ConvertSidToStringSid (&_parameters.in.arg.sid, &str))
- {
- debug_printf ("Group <%s> failed", str);
- LocalFree (str);
- }
- }
- break;
- case NAME_arg:
- debug_printf ("Group <%s> failed", _parameters.in.arg.name);
- break;
- case ID_arg:
- debug_printf ("Group <%u> failed", _parameters.in.arg.id);
- break;
- }
- _parameters.out.line[0] = '\0';
- msglen (0);
- error_code (ENOENT);
- }
-}
-
-void
-client_request_pwdgrp::serve (transport_layer_base *const conn,
- process_cache *const cache)
-{
- debug_printf ("Request account information");
- if (msglen () < __builtin_offsetof (struct _pwdgrp_param_t::_pwdgrp_in_t, arg)
- + sizeof (uint32_t)
- || msglen () > sizeof (_parameters.in))
- {
- syscall_printf ("bad request body length: got %lu", msglen ());
- error_code (EINVAL);
- msglen (0);
- return;
- }
- error_code (0);
- if (_parameters.in.group)
- grp_serve ();
- else
- pwd_serve ();
- debug_printf ("Request account information returns <%s> error %d", _parameters.out.line, error_code ());
-}
-#endif /* __OUTSIDE_CYGWIN__ */
diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog
index bc71d7a79..17dcd06ef 100644
--- a/winsup/cygwin/ChangeLog
+++ b/winsup/cygwin/ChangeLog
@@ -1,3 +1,14 @@
+2014-07-24 Corinna Vinschen <corinna@vinschen.de>
+
+ * fhandler_socket.cc (fhandler_socket::send_internal): Fix value of
+ out_len when tweaking the last buffer so out_len is correct in a
+ subsequent if expression.
+
+2014-07-21 Corinna Vinschen <corinna@vinschen.de>
+
+ * thread.cc (pthread::init_mainthread): Initialize thread mutex to
+ type PTHREAD_MUTEX_RECURSIVE, just as for any other thread.
+
2014-07-16 Corinna Vinschen <corinna@vinschen.de>
* thread.cc (pthread::create): Handle stackaddr as upper bound address.
@@ -31,13 +42,6 @@
* sigproc.cc (send_sig): Fix bad format in diagnostic output.
-2014-07-14 Corinna Vinschen <corinna@vinschen.de>
-
- * uinfo.cc (cygheap_domain_info::init): Correctly set
- lowest_tdo_posix_offset to UNIX_POSIX_OFFSET.
- (fetch_posix_offset): Redesign to fake a POSIX offset in all cases
- where we can't fetch a non-0 POSIX offset from our primary domain.
-
2014-07-14 Yaakov Selkowitz <yselkowitz@cygwin.com>
* thread.cc (pthread_mutex::pthread_mutex): Change default type
@@ -85,12 +89,6 @@
2014-07-07 Corinna Vinschen <corinna@vinschen.de>
- * passwd.cc (pg_ent::enumerate_ad): Revert to simply skipping a domain
- if opening the connection to the domain fails.
-
-2014-07-07 Pierre Humblet <Pierre.Humblet@ieee.org>
- Corinna Vinschen <corinna@vinschen.de>
-
* libc/minires.c (minires_dprintf): Change "Minires" to "Resolv" to
differ from external minres lib.
(res_nquerydomain): Fix off-by-one in domain concatenation. Add debug
@@ -101,73 +99,6 @@
* fhandler_disk_file.cc (fhandler_disk_file::fstatvfs): Add debug
output.
-2014-06-25 Corinna Vinschen <corinna@vinschen.de>
-
- * errno.cc (errmap): Fix order of SERVICE_REQUEST_TIMEOUT.
-
-2014-06-25 Corinna Vinschen <corinna@vinschen.de>
-
- * errno.cc (errmap): Handle Windows error codes ERROR_CANCELLED,
- ERROR_CONNECTION_REFUSED, ERROR_DEV_NOT_EXIST, ERROR_DS_GENERIC_ERROR,
- ERROR_NOT_ENOUGH_QUOTA, ERROR_SERVICE_REQUEST_TIMEOUT, ERROR_TIMEOUT,
- ERROR_UNEXP_NET_ERR.
- * ldap.cc (cyg_ldap::map_ldaperr_to_errno): Drop explicit LDAP_TIMEOUT
- handling.
-
-2014-06-25 Corinna Vinschen <corinna@vinschen.de>
-
- * ldap.cc (cyg_ldap::map_ldaperr_to_errno): Explicitely map LDAP_TIMEOUT
- to EIO.
-
-2014-06-25 Corinna Vinschen <corinna@vinschen.de>
-
- * autoload.cc (ldap_search_sW): Replace ldap_search_stW.
- (LdapMapErrorToWin32): Import.
- * fhandler_disk_file.cc (fhandler_base::fstat_by_nfs_ea): Accommodate
- change to cyg_ldap::open.
- * ldap.cc (CYG_LDAP_TIMEOUT): Remove.
- (CYG_LDAP_ENUM_TIMEOUT): Remove.
- (def_tv): Remove.
- (enum_tv): Remove.
- (cyg_ldap::map_ldaperr_to_errno): New method to map LDAP error codes to
- POSIX errno codes. Explicitly map LDAP_NO_RESULTS_RETURNED to ENMFILE.
- (cyg_ldap::wait): Ditto.
- (struct cyg_ldap_init): New struct.
- (cyg_ldap::connect_ssl): Return ULONG. Drop setting LDAP_OPT_TIMELIMIT.
- Add call to ldap_search_sW to fetch root DSE.
- (cyg_ldap::connect_non_ssl): Ditto.
- (ldap_init_thr): New static thread function.
- (cyg_ldap::connect): New method to call connect_ssl/connect_non_ssl in
- an interruptible cygthread.
- (struct cyg_ldap_search): New struct.
- (cyg_ldap::search_s): New method to perform generic synchronous search.
- (ldap_search_thr): New static thread function.
- (cyg_ldap::search): New method to call search_s in an interruptible
- cygthread.
- (struct cyg_ldap_next_page): New struct.
- (cyg_ldap::next_page_s): New method to perform generic synchronous
- paged search.
- (ldap_next_page_thr): New static thread function.
- (cyg_ldap::next_page): New method to call next_page_s in an
- interruptible cygthread.
- (cyg_ldap::open): Return POSIX errno. Call connect method.
- (cyg_ldap::fetch_ad_account): Call search method rather than
- ldap_search_stW.
- (cyg_ldap::enumerate_ad_accounts): Return POSIX errno. Use infinite
- timeout in call to ldap_search_init_pageW.
- (cyg_ldap::next_account): Return POSIX errno. Call next_page method
- rather than ldap_get_next_page_s.
- (cyg_ldap::fetch_posix_offset_for_domain): Call search method rather
- than ldap_search_stW.
- (cyg_ldap::fetch_unix_sid_from_ad): Ditto.
- (cyg_ldap::fetch_unix_name_from_rfc2307): Ditto.
- * ldap.h (class cyg_ldap): Accommodate aforementioned changes.
- * passwd.cc (pg_ent::enumerate_ad): Ditto. Break search if one of
- cyg_ldap::enumerate_ad_accounts or cldap.next_account returns with
- an error code other than ENMFILE.
- * sec_helper.cc (cygpsid::get_id): Accommodate change to cyg_ldap::open.
- * uinfo.cc (fetch_posix_offset): Ditto.
-
2014-06-23 Corinna Vinschen <corinna@vinschen.de>
* spawn.cc (find_exec): Initialize err (CID 60111).
@@ -225,24 +156,6 @@
* dcrt0.cc (insert_file): Fix resource leaks (CIDs 59987, 59988).
-2014-06-23 Corinna Vinschen <corinna@vinschen.de>
-
- * ldap.cc (CYG_LDAP_TIMEOUT): Set to 5 secs.
- (CYG_LDAP_ENUM_TIMEOUT): New timeout value for enumeration only. Set
- to 60 secs.
- (CYG_LDAP_ENUM_PAGESIZE): Define as number of entries per single
- search page. Set to 100. Use throughout.
- (def_tv): Rename from tv. Use throughout.
- (enum_tv): New variable. Use in call to ldap_get_next_page_s.
-
-2014-06-17 Corinna Vinschen <corinna@vinschen.de>
-
- * ldap.cc (CYG_LDAP_TIMEOUT): Define as timeout value. Set to 30 secs
- for now. Use throughout.
- * uinfo.cc (colon_to_semicolon): New local function.
- (pwdgrp::fetch_account_from_windows): Convert all colons in AD gecos
- entry to semicolons.
-
2014-06-17 David Stacey <drstacey@tiscali.co.uk>
* libc/rexec.cc (cygwin_rexec): Make ahostbuf static to avoid returning
@@ -263,62 +176,12 @@
* timer.cc (timer_tracker::cancel): Demote api_fatal to system_printf,
printing more details about odd failure condition.
-2014-05-23 Corinna Vinschen <corinna@vinschen.de>
-
- * autoload.cc (ldap_memfreeW): Remove.
- (ldap_msgfree): Import.
- * ldap.cc: Throughout, use ldap_msgfree to free LDAPMessage memory,
- rather than ldap_memfreeW.
- (cyg_ldap::next_account): Immediately abandon search when quiting from
- search.
-
-2014-05-22 Corinna Vinschen <corinna@vinschen.de>
-
- * autoload.cc (ldap_abandon): Remove.
- (ldap_count_entries): Import.
- (ldap_get_next_page_s): Import.
- (ldap_result): Remove.
- (ldap_searchW): Remove.
- (ldap_search_abandon_page): Import.
- (ldap_search_init_pageW): Import.
- * ldap.cc (cyg_ldap::close): Use ldap_search_abandon_page to abandon
- search. Reset srch_id, srch_msg and srch_entry.
- (cyg_ldap::enumerate_ad_accounts): Use paged search to overcome server
- side search result set restriction.
- (cyg_ldap::next_account): Ditto.
- * ldap.h (class cyg_ldap): Add members srch_id, srch_msg and srch_entry.
- Remove member msg_id.
- (cyg_ldap::cyg_ldap): Change initialization accordingly.
-
-2014-05-22 Corinna Vinschen <corinna@vinschen.de>
-
- * sec_auth.cc (get_server_groups): Call get_user_local_groups only if
- get_logon_server succeeded.
-
-2014-05-22 Corinna Vinschen <corinna@vinschen.de>
-
- * ldap.cc (cyg_ldap::fetch_ad_account): Take additional domain string
- parameter. Convert into likely rootDSE string if not NULL, and use in
- subsequent call to ldap_search_stW. Add comment to explain that this
- is not the exactly correct solution.
- * ldap.h (cyg_ldap::fetch_ad_account): Change prototype accordingly.
- * uinfo.cc (pwdgrp::fetch_account_from_windows): Always use loc_ldap
- in call to fetch_posix_offset to make sure we're fetchoinmg the posix
- offsets from *our* domain controller. Only set domain variable to
- non-NULL if the account is from a trusted domain. Use domain in call
- to cyg_ldap::fetch_ad_account.
-
2014-05-22 Corinna Vinschen <corinna@vinschen.de>
* gmon.h: Pull in profile.h. Explain why.
2014-05-22 Corinna Vinschen <corinna@vinschen.de>
- * uinfo.cc (pwdgrp::fetch_account_from_windows): Fix potential SEGV
- referencing NULL pointer.
-
-2014-05-22 Corinna Vinschen <corinna@vinschen.de>
-
* libc/bsdlib.cc (forkpty): Close master and slave if fork fails to
avoid resource leak (CID 59997).
* libc/fts.c: Update to FreeBSD version 1.39 (CID 59947).
@@ -354,7 +217,7 @@
2014-05-20 Corinna Vinschen <corinna@vinschen.de>
* fhandler_floppy.cc (fhandler_dev_floppy::get_drive_info): Fix floppy
- drive handling broken with 1.7.19.
+ drive handling broken with 1.7.19.
2014-05-20 Corinna Vinschen <corinna@vinschen.de>
@@ -402,30 +265,6 @@
* syscalls.cc (getusershell): Fix buffer overrun (Coverity ID 59932).
-2014-05-15 Corinna Vinschen <corinna@vinschen.de>
-
- * external.cc (cygwin_internal): Use local name buffer instead of
- allocated one in CW_CYGNAME_FROM_WINNAME.
-
-2014-05-15 Corinna Vinschen <corinna@vinschen.de>
-
- * include/cygwin/version.h (CYGWIN_VERSION_API_MINOR): Bump to 273.
-
-2014-05-15 Corinna Vinschen <corinna@vinschen.de>
-
- * external.cc (cygwin_internal): Implement CW_CYGNAME_FROM_WINNAME.
- Add lengthy comment to explain what we do and why.
- * include/sys/cygwin.h (cygwin_getinfo_types): Add
- CW_CYGNAME_FROM_WINNAME.
-
-2014-05-14 Corinna Vinschen <corinna@vinschen.de>
-
- * sec_auth.cc (get_server_groups): Call get_logon_server only for
- non-builtin accounts.
- * uinfo.cc (pwdgrp::fetch_account_from_windows): Check incoming
- account name for validity in terms of the current name prefixing rules
- and refuse invalid names.
-
2014-05-13 Corinna Vinschen <corinna@vinschen.de>
* fhandler_socket.cc (fhandler_socket::ioctl): Handle the different
@@ -439,76 +278,6 @@
* fhandler_console.cc (dev_console::save_restore): Only save current
dwEnd line rather than the one after that.
-2014-05-08 Corinna Vinschen <corinna@vinschen.de>
-
- * uinfo.cc (cygheap_user::init): Fix formatting in debug output.
- (struct cyg_USER_INFO_24): Define temporarily. Explain why.
- (pwdgrp::fetch_account_from_windows): Handle sane primary group
- setting for Microsoft Accounts. Explain why.
- * wincap.h (wincaps::has_microsoft_accounts): New element.
- * wincap.cc: Implement above element throughout.
-
-2014-05-08 Corinna Vinschen <corinna@vinschen.de>
-
- * grp.cc (gr_ent::enumerate_caches): Fix copy/paste bug introducing
- an endless loop.
-
-2014-05-07 Corinna Vinschen <corinna@vinschen.de>
-
- * passwd.cc (pwdgrp::parse_passwd): Fix an off by one computing the
- buffer len. Add comment.
- * uinfo.cc (internal_getlogin): Fix typo in comment.
-
-2014-05-07 Corinna Vinschen <corinna@vinschen.de>
-
- * uinfo.cc (pwdgrp::fetch_account_from_windows): Tweak SID<->uid
- conversion to cover S-1-5-113, S-1-5-114, and S-1-5-1000 groups.
-
-2014-05-07 Corinna Vinschen <corinna@vinschen.de>
-
- * grp.cc (pwdgrp::parse_group): Set grp.len. Drop generating any
- gr_mem entries.
- (getgrgid_r): Don't try to copy gr_mem entries. Always set gr_mem
- to an empty list.
- (getgrnam_r): Ditto.
- (app_gr): New static struct to store group data propagated to the
- calling application via getgrgid/getgrnam.
- (getgr_cp): Fill app_gr and return pointer to app_gr.g.
- (getgrgid32): Call getgr_cp.
- (getgrnam32): Ditto.
- * passwd.cc (pwdgrp::parse_passwd): Set res.len.
- (app_pw): New static struct to store passwd data propagated to the
- calling application via getpwuid/getpwnam.
- (getpw_cp): Fill app_pw and return pointer to app_pw.p.
- (getpwuid32): Cal getpw_cp.
- (getpwnam): Ditto.
- * pwdgrp.h (struct pg_pwd): Add len member.
- (struct pg_grp): Ditto.
-
-2014-05-06 Corinna Vinschen <corinna@vinschen.de>
-
- * security.h (MAX_SUBAUTH_CNT): Drop. Use SID_MAX_SUB_AUTHORITIES
- instead throughout.
- (MAX_SID_LEN): Drop. Use SECURITY_MAX_SID_SIZE instead throughout.
-
-2014-05-06 Corinna Vinschen <corinna@vinschen.de>
-
- * grp.cc (internal_getgroups): Drop unused cygsid variable.
- * sec_helper.cc (cygpsid::pstring): Use sid_sub_auth_count macro.
- (cygsid::get_sid): Use MAX_SUBAUTH_CNT rather than wrong constant 8.
- Don't call memcpy to copy subauthorities into SID, use assignment.
- (cygsid::getfromstr): Use MAX_SUBAUTH_CNT rather than wrong constant 8.
- * security.h (MAX_SUBAUTH_CNT): New definition. Set to 11 to cover
- Microsoft Accounts.
- (MAX_SID_LEN): Define in terms of SID member sizes and MAX_SUBAUTH_CNT.
- (DBGSID): Use MAX_SUBAUTH_CNT to define size of SubAuthority array.
- * uinfo.cc (pwdgrp::fetch_account_from_windows): Handle Micosoft
- Accounts. Handle them as well known group. Compare domain names
- case-insensitive.
- * winlean.h (PIPE_REJECT_REMOTE_CLIENTS): Drop temporary definition
- since Mingw64 catched up.
- (DNLEN): Redefine as 16. Explain why.
-
2014-05-05 Corinna Vinschen <corinna@vinschen.de>
* net.cc (cygwin_getsockopt): Rearrange code slightly and handle
@@ -552,16 +321,6 @@
* miscfuncs.cc (check_iovec): Allow 0 as valid iovcnt value.
-2014-04-22 Corinna Vinschen <corinna@vinschen.de>
-
- * ldap.cc (user_attr): Remove "uid" attribute.
- * ldap.h (LDAP_USER_NAME_ATTR): Remove. Change other attribute index
- values as required.
- (cyg_ldap::get_user_name): Remove inline function.
- * uinfo.cc (pwdgrp::fetch_account_from_windows): Remove code to handle
- Cygwin username different from Windows username.
- (pwdgrp::add_account_from_cygserver): Remove unnecessary cast.
-
2014-04-18 Corinna Vinschen <corinna@vinschen.de>
* winf.cc (linebuf::fromargv): Temporarily revert patch from 2014-01-24.
@@ -582,7 +341,7 @@
(tmp_pathbuf::w_get): Ditto.
* tls_pbuf.h (class tmp_pathbuf): Change type of c_buf_old and w_buf_old
to unsigned.
- (tmp_pathbuf::check_usage): New inline method to check if we have
+ (tmp_pathbuf::check_usage): New inline method to check if we have
enough tmp_pathbuf buffers left to call a function using tmp_pathbuf
buffers.
* tlsoffsets.h: Regenerate.
@@ -592,30 +351,25 @@
* net.cc (cygwin_setsockopt): Ignore IPV6_TCLASS the same way as IP_TOS.
-2014-04-12 Corinna Vinschen <corinna@vinschen.de>
-
- * uinfo.cc (pwdgrp::fetch_account_from_windows): Fix gid evaluation
- for local accounts.
-
2014-04-10 Corinna Vinschen <corinna@vinschen.de>
* include/cygwin/version.h (CYGWIN_VERSION_DLL_MINOR): Bump to 30.
-2014-04-09 Corinna Vinschen <corinna@vinschen.de>
-
- * exceptions.cc (exception::myfault_handle): Only handle the minimum
- amount of exceptions the myfault handler was designed for.
-
2014-04-08 Corinna Vinschen <corinna@vinschen.de>
* cygwin.sc.in: (Temporarily?) workaround serious ld bug which
truncates symbols in certain computations to 32 bit. See
https://sourceware.org/bugzilla/show_bug.cgi?id=16821
+2014-04-09 Corinna Vinschen <corinna@vinschen.de>
+
+ * exceptions.cc (exception::myfault_handle): Only handle the minimum
+ amount of exceptions the myfault handler was designed for.
+
2014-04-07 Corinna Vinschen <corinna@vinschen.de>
* cygserver_ipc.h (ipc_set_proc_info): Add bool parameter to specify
- whether or not to send signal_arrived.
+ whether or not to send signal_arrived.
* shm.cc (client_request_shm::client_request_shm): Call
ipc_set_proc_info with bool parameter set to true to not send
signal_arrived.
@@ -707,12 +461,6 @@
(exception::exception): Install unhandled exception filter.
* exceptions.cc (exception::handle_while_being_debugged): New method.
-2014-03-19 Corinna Vinschen <corinna@vinschen.de>
-
- * passwd.cc (pg_ent::enumerate_ad): Ignore primary domain in list of
- trusted domains only if all trusted domains are enumerated anyway.
- Explain why.
-
2014-03-18 Christopher Faylor <me.cygwin2014@cgf.cx>
* fhandler_dsp.cc (fhandler_dev_dsp::fixup_after_fork): Actually call
@@ -759,58 +507,6 @@
2014-03-12 Corinna Vinschen <corinna@vinschen.de>
- * cygheap.h (enum cygheap_pwdgrp::cache_t): Remove.
- (cygheap_pwdgrp::caching): Convert to bool.
- (cygheap_pwdgrp::pwd_cache): Add cygserver member.
- (cygheap_pwdgrp::grp_cache): Ditto.
- (cygheap_pwdgrp::nss_db_caching): Drop.
- (cygheap_pwdgrp::nss_db_full_caching): Drop.
- (cygheap_pwdgrp::nss_cygserver_caching): New method.
- (cygheap_pwdgrp::nss_disable_cygserver_caching): New method.
- * cygserver.h (client_request::request_code_t): Add
- CYGSERVER_REQUEST_PWDGRP.
- * cygserver_pwdgrp.h: New file.
- * cygtls.h (struct _local_storage): Remove pwbuf and grbuf members.
- * grp.cc (pwdgrp::prep_tls_grbuf): Drop.
- (internal_getgrsid): Handle cygserver caching and rearrange to check
- the caches first.
- (internal_getgrnam): Ditto.
- (internal_getgrgid): Ditto.
- (gr_ent::enumerate_caches): Handle cygserver cache.
- * passwd.cc (pwdgrp::prep_tls_pwbuf): Drop.
- (internal_getpwsid): Handle cygserver caching and rearrange to check
- the caches first.
- (internal_getpwnam): Ditto.
- (internal_getpwuid): Ditto.
- (pw_ent::enumerate_caches): Handle cygserver cache.
- * pwdgrp.h (pwdgrp::add_account_from_cygserver): New method declaration.
- (pwdgrp::fetch_account_from_cygserver): New method declaration.
- (pwdgrp::prep_tls_pwbuf): Drop declaration.
- (pwdgrp::prep_tls_grbuf): Drop declaration.
- (pwdgrp::add_user_from_cygserver): New inline methods.
- (pwdgrp::add_group_from_cygserver): New inline methods.
- * tlsoffsets.h: Regenerate.
- * tlsoffsets64.h: Regenerate.
- * uinfo.cc (internal_getlogin): Call internal_getgroups if cygserver
- caching is not available.
- (cygheap_pwdgrp::init): Initialize pwd_cache.cygserver and
- grp_cache.cygserver. Set caching to true.
- (cygheap_pwdgrp::nss_init_line): Drop db_cache handling entirely.
- (pwdgrp::add_account_from_windows): Drop no caching handling.
- (client_request_pwdgrp::client_request_pwdgrp): New method.
- (pwdgrp::fetch_account_from_cygserver): New method.
- (pwdgrp::add_account_from_cygserver): New method.
-
- * fhandler_disk_file.cc (fhandler_base::fstat_helper): Fix formatting.
- * include/sys/cygwin.h: Ditto.
-
-2014-03-12 Corinna Vinschen <corinna@vinschen.de>
-
- * uinfo.cc (pwdgrp::fetch_account_from_windows): Avoid crash on
- non-domain member machines if an unknown SID comes in.
-
-2014-03-12 Corinna Vinschen <corinna@vinschen.de>
-
* include/cygwin/socket.h (IPV6_JOIN_GROUP): Revert.
(IPV6_LEAVE_GROUP): Ditto.
@@ -870,55 +566,6 @@
* dir.cc (opendir): Propagate any errno from build_fh_name.
-2014-03-07 Corinna Vinschen <corinna@vinschen.de>
-
- * pwdgrp.h (pwdgrp::is_passwd): New inline method.
- (pwdgrp::is_group): New inline method.
- (add_account_from_windows): Drop group argument from declaration.
- (fetch_account_from_windows): Ditto.
- (check_file): Ditto.
- (add_user_from_windows): Call add_account_from_windows accordingly.
- (add_group_from_windows): Ditto.
- * uinfo.cc (pwdgrp::add_account_from_windows): Drop group argument.
- Use is_group method instead.
- (pwdgrp::check_file): Ditto.
- (pwdgrp::fetch_account_from_windows): Ditto.
- * grp.cc: Accommodate aforementioned changes.
- * passwd.cc: Ditto.
-
-2014-03-06 Corinna Vinschen <corinna@vinschen.de>
-
- * passwd.cc (pg_ent::enumerate_builtin): Convert pwd_builtins and
- grp_builtins to array of cygpsid pointers. Replace SID strings with
- pointers to well known SIDs.
- * sec_helper.cc (well_known_local_service_sid): Define.
- (well_known_network_service_sid): Define.
- (trusted_installer_sid): Define.
- * security.h (well_known_local_service_sid): Declare.
- (well_known_network_service_sid): Declare.
- (trusted_installer_sid): Declare.
- * uinfo.cc (pwdgrp::fetch_account_from_windows): Throughout set acc_type
- to SidTypeUnknown if LookupAccountXXX function failed. Create
- simplified passwd entry for non-user accounts, except for LocalSystem.
- Add comment.
-
-2014-03-06 Corinna Vinschen <corinna@vinschen.de>
-
- * setlsapwd.cc (setlsapwd): Use RtlSecureZeroMemory to delete password
- from memory.
-
-2014-03-05 Corinna Vinschen <corinna@vinschen.de>
-
- * ldap.cc (rediscover_thread): Remove.
- (cyg_ldap::open): Remove code to rediscover DC. It just won't do the
- right thing.
- (cyg_ldap::enumerate_ad_accounts): Change to be self-sufficient (no
- explicit open call required). Enumerate on a DC of the domain itself
- instead of relying on delegation. Remove ill-advised code trying to
- generate rootdse from domain name.
- * passwd.cc (pg_ent::enumerate_ad): Drop explicit call to
- cyg_ldap::open.
-
2014-03-05 Corinna Vinschen <corinna@vinschen.de>
* include/cygwin/config.h (__TM_GMTOFF): Define.
@@ -947,115 +594,6 @@
* exception.h (exception::exception): Install vectored exception
handler rather than vectored continue handler.
-2014-03-03 Corinna Vinschen <corinna@vinschen.de>
-
- * sec_helper.cc (cygpsid::get_id): Move Samba SID->uid/gid mapping
- from get_sids_info here.
- (get_sids_info): Vice versa.
- * security.cc (convert_samba_sd): New static function to map a Samba
- security descriptor to a security descriptor with UNIX users and groups
- converted to Windows SIDs per RFC 2307 mapping.
- (check_file_access): Call convert_samba_sd on Samba security
- descriptors.
-
-2014-02-28 Corinna Vinschen <corinna@vinschen.de>
-
- * uinfo.cc (pwdgrp::fetch_account_from_windows): Only fetch extended
- user info if we're creating a passwd entry. Add comment.
-
-2014-02-28 Corinna Vinschen <corinna@vinschen.de>
-
- * cygheap.h (cygheap_user::sid): Return reference to cygpsid rather
- than PSID.
- (cygheap_user::saved_sid): Ditto.
- (cygheap_pwdgrp::cache_t): New type.
- (cygheap_pwdgrp::caching): Convert to cache_t.
- (cygheap_pwdgrp::nss_db_caching): Change accordingly.
- (cygheap_pwdgrp::nss_db_full_caching): New inline method.
- * grp.cc (internal_getgroups): Reinvent. Take cyg_ldap pointer as
- third parameter and use throughout.
- (getgroups32): Call internal_getgroups.
- * pwdgrp.h (internal_getgroups): Declare.
- * uinfo.cc (internal_getlogin): Partial rewrite to accommodate having
- no connection to the DC. Give primary group from user token more
- weight. Generate group entries for all groups in the user token if
- caching is set to NSS_FULL_CACHING.
- (cygheap_pwdgrp::init): Initialize caching to NSS_FULL_CACHING.
- (cygheap_pwdgrp::nss_init_line): Handle "db_cache: full".
- (pwdgrp::add_account_from_windows): Fix group handling in non-caching
- mode.
- (pwdgrp::fetch_account_from_windows): Default primary group for the
- current user to primary group from user token. Check for primary
- domain first after LookupAccountSid failed.
-
-2014-02-27 Corinna Vinschen <corinna@vinschen.de>
-
- * autoload.cc (CheckTokenMembership): Import.
- * external.cc (cygwin_internal): Call get_uid/get_gid instead of get_id.
- * grp.cc (internal_getgrsid): Take additional cyg_ldap pointer.
- Forward to pwdgrp::add_group_from_windows.
- (internal_getgrnam): Ditto.
- (internal_getgrgid): Ditto.
- (gr_ent::enumerate_local): Drop ugid_caching bool from call to
- pwdgrp::fetch_account_from_windows.
- (getgroups32): Rename from internal_getgroups and drop getgroups32 stub.
- Drop srchsid parameter and code handling it. Add local cyg_ldap
- instance and forward to internal_getgrXXX.
- (getgroups): Call getgroups32.
- (get_groups): Add local cyg_ldap instance and forward to
- internal_getgrXXX.
- (getgrouplist): Ditto.
- (setgroups32): Ditto.
- * ldap.cc (cyg_ldap::open): Don't call close. Return true if connection
- is already open.
- (cyg_ldap::remap_uid): Forward this to internal_getpwsid.
- (cyg_ldap::remap_gid): Forward this to internal_getgrsid.
- * passwd.cc (internal_getpwsid): Take additional cyg_ldap pointer.
- Forward to pwdgrp::add_user_from_windows.
- (internal_getpwnam): Ditto.
- (internal_getpwuid): Ditto.
- (pg_ent::enumerate_builtin): Drop ugid_caching bool from call to
- pwdgrp::fetch_account_from_windows.
- (pg_ent::enumerate_sam): Ditto.
- (pg_ent::enumerate_ad): Ditto. Forward local cldap instead.
- * pwdgrp.h (internal_getpwsid): Align declaration to above change.
- (internal_getpwnam): Ditto.
- (internal_getpwuid): Ditto.
- (internal_getgrsid): Ditto.
- (internal_getgrgid): Ditto.
- (internal_getgrnam): Ditto.
- (internal_getgroups): Drop declaration.
- (pwdgrp::add_account_from_windows): Align declaration to below change.
- (pwdgrp::add_user_from_windows): Ditto.
- (pwdgrp::add_group_from_windows): Ditto.
- * sec_acl.cc (setacl): Add local cyg_ldap instance and forward to
- internal_getpwuid and internal_getgrgid.
- (getacl): Add local cyg_ldap instance and forward to cygpsid::get_id.
- (aclfromtext32): Add local cyg_ldap instance and forward to
- internal_getpwnam and internal_getgrnam.
- * sec_helper.cc (cygpsid::get_id): Take additional cyg_ldap pointer.
- Forward to internal_getgrsid and internal_getpwsid.
- (get_sids_info): Drop ldap_open. Forward local cldap to
- internal_getpwsid and internal_getgrXXX. Call CheckTokenMembership
- rather than internal_getgroups.
- * security.h (cygpsid::get_id): Add cyg_ldap pointer, drop default
- parameter.
- (cygpsid::get_uid): Add cyg_ldap pointer. Call get_id accordingly.
- (cygpsid::get_gid): Ditto.
- * uinfo.cc (internal_getlogin): Add local cyg_ldap instance and forward
- to internal_getpwXXX and internal_getgrXXX calls.
- (pwdgrp::add_account_from_windows): Take additional cyg_ldap pointer.
- Forward to pwdgrp::fetch_account_from_windows.
- (fetch_posix_offset): Drop ldap_open argument and handling. Get
- cyg_ldap instance as pointer.
- (pwdgrp::fetch_account_from_windows): Take additional cyg_ldap pointer.
- Use it if it's not NULL, local instance otherwise. Drop ldap_open.
- Drop fetching extended group arguments from AD for speed.
-
-2014-02-27 Corinna Vinschen <corinna@vinschen.de>
-
- * path.cc (find_fast_cwd_pointer): Fix preceeding comment.
-
2014-02-25 Christopher Faylor <me.cygwin2014@cgf.cx>
* fhandler.h (fhandler_console::scroll_buffer_screen): New function.
@@ -1063,6 +601,13 @@
(fhandler_console::char_command): Use scroll_buffer_screen as appropriate.
(dev_console::scroll_buffer): Remove if 0'ed block.
+2014-02-22 Corinna Vinschen <corinna@vinschen.de>
+
+ * external.cc (cygwin_internal): Add cases for CW_GETPWSID and
+ CW_GETGRSID.
+ * include/sys/cygwin.h (cygwin_getinfo_types): Add CW_SETENT, CW_GETENT,
+ CW_ENDENT, CW_GETNSSSEP, CW_GETPWSID and CW_GETGRSID.
+
2014-02-22 Christopher Faylor <me.cygwin2014@cgf.cx>
* dev_console::scroll_buffer): Reinstate clipping region.
@@ -1092,35 +637,6 @@
(fhandler_console::cursor_get): Ditto.
(fhandler_console::write): Fix "reverse index".
-2014-02-22 Corinna Vinschen <corinna@vinschen.de>
-
- * external.cc (cygwin_internal): Add cases for CW_GETNSSSEP,
- CW_GETPWSID and CW_GETGRSID.
- * grp.cc (internal_getgrsid_from_db): New function.
- * passwd.cc (internal_getpwsid_from_db): New function.
- (pg_ent::setent): Add special case for call from mkpasswd/mkgroup.
- * pwdgrp.h (internal_getpwsid_from_db): Declare.
- (internal_getgrsid_from_db): Declare.
- (enum nss_enum_t): Move to include/sys/cygwin.h.
- (class pg_ent): Add comment.
- * uinfo.cc (pwdgrp::fetch_account_from_windows): Fix typo in comment.
- Change "UNIX" to "Unix" in domain name.
- * include/sys/cygwin.h (cygwin_getinfo_types): Add CW_GETNSSSEP,
- CW_GETPWSID and CW_GETGRSID.
- (enum nss_enum_t): Define here.
-
-2014-02-21 Corinna Vinschen <corinna@vinschen.de>
-
- * pwdgrp.h (pwdgrp::fetch_account_from_windows): Add bool parameter
- to declaration, set to true by default.
- * uinfo.cc (pwdgrp::fetch_account_from_windows): Add bool parameter
- "ugid_caching". Only add account to ugid_cache if set to true.
- * grp.cc (gr_ent::enumerate_local): Call fetch_account_from_windows
- with ugid_caching parameter set to false.
- * passwd.cc (pg_ent::enumerate_builtin): Ditto.
- (pg_ent::enumerate_sam): Ditto.
- (pg_ent::enumerate_ad): Ditto.
-
2014-02-20 Corinna Vinschen <corinna@vinschen.de>
* grp.cc (getgrouplist): Fix previous fix so ret is only set to ngroups
@@ -1131,120 +647,6 @@
* grp.cc (get_groups): Don't add gid to list if it's ILLEGAL_GID.
(getgrouplist): Return number of groups, just like glibc.
-2014-02-19 Corinna Vinschen <corinna@vinschen.de>
-
- * passwd.cc (pg_ent::setent): Initialize cygheap domain info.
- * sec_auth.cc (get_logon_server): Ditto.
-
-2014-02-18 Corinna Vinschen <corinna@vinschen.de>
-
- * external.cc (cygwin_internal): Handle new CW_SETENT, CW_GETENT and
- CW_ENDENT info types.
- * grp.cc (setgrent_filtered): New function, called from cygwin_internal.
- (getgrent_filtered): Ditto.
- (endgrent_filtered): Ditto.
- * passwd.cc (pg_ent::setent): Set state explicitely to from_cache.
- (pg_ent::getent): Handle the fact that a DC has no SAM and enumerating
- local accounts is equivalent to enumerating domain accounts.
- (setpwent_filtered): New function, called from cygwin_internal.
- (getpwent_filtered): Ditto.
- (endpwent_filtered): Ditto.
- * pwdgrp.h (setpwent_filtered): Declare.
- (getgrent_filtered): Ditto.
- (endgrent_filtered): Ditto.
- (setpwent_filtered): Ditto.
- (getpwent_filtered): Ditto.
- (endpwent_filtered): Ditto.
- * include/sys/cygwin.h (cygwin_getinfo_types): Add CW_SETENT, CW_GETENT,
- and CW_ENDENT.
-
-2014-02-18 Corinna Vinschen <corinna@vinschen.de>
-
- * setlsapwd.cc (setlsapwd): Fix conditional expression after breaking
- it on 2014-01-23.
-
-2014-02-17 Corinna Vinschen <corinna@vinschen.de>
-
- * autoload.cc (ldap_abandon): Import.
- (ldap_result): Import.
- (ldap_searchW): Import.
- (NetGroupEnum): Import.
- (NetLocalGroupEnum): Import.
- (NetUserEnum): Import.
- * cygheap.h (class cygheap_pwdgrp): Add members enums and enum_tdoms.
- (cygheap_pwdgrp::nss_db_enums): New inline method.
- (cygheap_pwdgrp::nss_db_enum_tdoms): Ditto.
- * cygtls.h (struct _local_storage): Drop unused members pw_pos and
- grp_pos.
- * grp.cc (grent): New static variable of class gr_ent.
- (gr_ent::enumerate_caches): New method.
- (gr_ent::enumerate_local): New method.
- (gr_ent::getgrent): New method.
- (setgrent): Call gr_ent method.
- (getgrent32): Ditto.
- (endgrent): Ditto.
- * ldap.cc (sid_attr): Rename from nfs_attr.
- (cyg_ldap::close): Abandon still running asynchronous search.
- (cyg_ldap::fetch_ad_account): Reduce filter buffer size.
- (cyg_ldap::enumerate_ad_accounts): New method.
- (cyg_ldap::next_account): New method.
- (cyg_ldap::fetch_posix_offset_for_domain): Reduce filter buffer size.
- (cyg_ldap::fetch_unix_sid_from_ad): Ditto. Fix return value in case
- no value has been read.
- (cyg_ldap::fetch_unix_name_from_rfc2307): Reduce filter buffer size.
- * ldap.h (class cyg_ldap): Add msg_id member.
- (cyg_ldap::enumerate_ad_accounts): Declare.
- (cyg_ldap::next_account): Declare:
- * passwd.cc (pwent): New static variable of class pw_ent.
- (pg_ent::clear_cache): New method.
- (pg_ent::setent): New method.
- (pg_ent::getent): New method.
- (pg_ent::endent): New method.
- (pg_ent::enumerate_file): New method.
- (pg_ent::enumerate_builtin): New method.
- (pg_ent::enumerate_sam): New method.
- (pg_ent::enumerate_ad): New method.
- (pw_ent::enumerate_caches): New method.
- (pw_ent::enumerate_local): New method.
- (pw_ent::getpwent): New method.
- (setpwent): Call pw_ent method.
- (getpwent): Ditto.
- (endpwent): Ditto.
- * pwdgrp.h (class pwdgrp): Define pg_ent, pw_ent and gr_ent as friend
- classes.
- (pwdgrp::add_account_post_fetch): Declare with extra bool parameter.
- (pwdgrp::file_attr): New inline method.
- (enum nss_enum_t): Define.
- (class pg_ent): Define.
- (class pw_ent): Define.
- (class gr_ent): Define.
- * tlsoffsets.h: Regenerate.
- * tlsoffsets64.h: Ditto.
- * uinfo.cc (cygheap_pwdgrp::init): Initialize enums and enum_tdoms.
- (cygheap_pwdgrp::nss_init_line): Fix typo in preceeding comment.
- Handle new "db_enum" keyword.
- (pwdgrp::add_account_post_fetch): Take additional `bool lock' parameter
- and acquire pglock before adding element to array if lock is true.
- (pwdgrp::add_account_from_file): Call add_account_post_fetch with lock
- set to true.
- (pwdgrp::add_account_from_windows): Ditto in case of caching.
- (pwdgrp::fetch_account_from_windows): Handle builtin aliases only
- known to the domain controller. Only call NetLocalGroupGetInfo for
- aliases.
-
-2014-02-16 Corinna Vinschen <corinna@vinschen.de>
-
- * miscfuncs.h (NT_readline::close): New function to close handle.
- (NT_readline::~NT_readline): Call close.
- * sec_auth.cc (verify_token): Use constructor to initialize tok_usersid.
- * security.h (cygsid::cygsid): Add copy constructor taking cygsid as
- source.
-
-2014-02-16 Corinna Vinschen <corinna@vinschen.de>
-
- * dcrt0.cc (dll_crt0_1): Call initial_setlocale before fetching
- current user information.
-
2014-02-15 Christopher Faylor <me.cygwin2014@cgf.cx>
* DevNotes: Add entry cgf-000024.
@@ -1280,95 +682,18 @@
when !winpid. Simplify logic. Don't do duplicate detection for
winpid.
-2014-02-14 Corinna Vinschen <corinna@vinschen.de>
-
- * uinfo.cc (pwdgrp::fetch_account_from_windows): Default to /bin/bash
- as login shell.
-
-2014-02-13 Corinna Vinschen <corinna@vinschen.de>
-
- * ldap.cc (cyg_ldap::fetch_posix_offset_for_domain): If domain name
- has no dot, it's a Netbios name. Change the search filter expression
- accordingly and filter by flatName. Add comment.
- * uinfo.cc (cygheap_domain_info::init): Gracefully handle NULL
- DnsDomainName and DomainSid members in DS_DOMAIN_TRUSTSW structure.
- Add comment. Fix comment preceeding fetching the mapping server
- from registry.
- (pwdgrp::fetch_account_from_file): Convert str to a local array.
- (fetch_posix_offset): New static function.
- (pwdgrp::fetch_account_from_windows): Add debug output in case
- LookupAccountSidW fails. Simplify code by calling fetch_posix_offset
- where appropriate. If LookupAccountSidW fails, check if the SID is
- one of the known trusted domains. If so, create a more informative
- account entry.
-
-2014-02-12 Corinna Vinschen <corinna@vinschen.de>
-
- * uinfo.cc (cygheap_pwdgrp::nss_init_line): Explicitely ignore a colon
- as separator char.
-
2014-02-11 Christopher Faylor <me.cygwin2014@cgf.cx>
- * winsup.h: Turn off previous workaround but leave a comment.
-
-2014-02-11 Corinna Vinschen <corinna@vinschen.de>
-
- * ldap.cc (rediscover_thread): Give argument a useful name.
- * miscfuncs.cc (NT_readline::init): It's a really bad idea trying to
- print a pointer to a PUNICODE_STRING as PUNICODE_STRING. Fix it.
- * uinfo.cc (cygheap_domain_info::init): Print status codes as hex
- values in debug output.
-
-2014-02-11 Corinna Vinschen <corinna@vinschen.de>
-
- * autoload.cc (NetLocalGroupGetInfo): Replace NetGroupGetInfo.
- * cygheap.h (class cygheap_ugid_cache): Move ugid_cache_t type here
- and rename.
- (struct init_cygheap): Add cygheap_ugid_cache member "ugid_cache".
- * pwdgrp.h (class ugid_cache_t): Remove here.
- * fhandler_disk_file.cc (fhandler_base::fstat_by_nfs_ea): Accommodate
- move of ugid_cache to cygheap.
- * sec_helper.cc (get_sids_info): Ditto.
- * uinfo.cc (ugid_cache): Remove.
- (pwdgrp::fetch_account_from_windows): Define id_val globally.
- Move SidTypeAlias handling into SidTypeUser/SidTypeGroup branch since
- aliases are handled like groups in SAM. Accommodate move of ugid_cache
- to cygheap. Consolidate code reading SAM comments into a single branch
- for both, SidTypeUser and SidTypeAlias. For SidTypeAlias, fix thinko
- and call NetLocalGroupGetInfo rather than NetGroupGetInfo. Simplify
- code setting Cygwin primary group for SAM accounts. Add code to handle
- UNIX uid/gid from SAM comment.
-
-2014-02-11 Christopher Faylor <me.cygwin2014@cgf.cx>
-
- * winsup.h (Interlocked*): Use intrinsic versions of Interlocked
- functions.
-
* cygwin.sc.in: More closely emulate default pe/i386 linker script.
2014-02-10 Corinna Vinschen <corinna@vinschen.de>
- * uinfo.cc (cygheap_domain_info::init): Drop accidentally leftover if
- statement.
-
-2014-02-10 Corinna Vinschen <corinna@vinschen.de>
-
- * uinfo.cc (cygheap_domain_info::init): Fix handling of account domain
- on donmain controllers. Explain why.
-
-2014-02-10 Corinna Vinschen <corinna@vinschen.de>
-
* cygheap.cc (cwcsdup): Change parameter to correct PWCSTR.
(cwcsdup1): Ditto.
* cygheap_malloc.h: Change declarations accordingly.
2014-02-10 Corinna Vinschen <corinna@vinschen.de>
- * uinfo.cc (pwdgrp::fetch_account_from_windows): Add code to allow
- setting the primary group from the SAM comment field.
-
-2014-02-10 Corinna Vinschen <corinna@vinschen.de>
-
* dcrt0.cc (child_info_spawn::handle_spawn): Call fixup_lockf_after_exec
with additional argument to specify if the process has been execed
or spawned.
@@ -1386,161 +711,11 @@
* environ.cc (strbrk): New function.
(parse_options): Use strbrk to parse CYGWIN environment variable.
-2014-02-09 Corinna Vinschen <corinna@vinschen.de>
-
- Introduce reading passwd/group entries from SAM/AD. Introduce
- /etc/nsswitch.conf file to configure it.
- * Makefile.in (DLL_OFILES): Add ldap.o.
- * autoload.cc: Import ldap functions from wldap32.dll.
- (DsEnumerateDomainTrustsW): Import.
- (NetGroupGetInfo): Import.
- * cygheap.h (class cygheap_domain_info): New class to keep global
- domain info.
- (class cygheap_pwdgrp): New class to keep passwd/group caches and
- configuration info from /etc/nssswitch.conf.
- (struct init_cygheap): Add cygheap_domain_info member "dom" and
- cygheap_pwdgrp member "pg".
- * cygtls.h (struct _local_storage): Remove unused member "res".
- Rearrange slightly, Add members pwbuf and grbuf to implement non-caching
- passwd/group fetching from SAM/AD. Make pw_pos and pw_pos unsigned.
- * fhandler_disk_file.cc (fhandler_base::fstat_by_nfs_ea): Add RFC 2307
- uid/gid mapping.
- * fhandler_process.cc: Drop including pwdgrp.h.
- * fhandler_procsysvipc.cc: Ditto.
- * fhandler_registry.cc (fhandler_registry::fstat): Set key uid/gid
- to ILLEGAL_UID/ILLEGAL_GID rather than UNKNOWN_UID/UNKNOWN_GID.
- * grp.cc (group_buf): Drop.
- (gr): Drop.
- (pwdgrp::parse_group): Fill pg_grp.
- (pwdgrp::read_group): Remove.
- (pwdgrp::init_grp): New method.
- (pwdgrp::prep_tls_grbuf): New method.
- (pwdgrp::find_group): New methods.
- (internal_getgrsid): Convert to call new pwdgrp methods.
- (internal_getgrnam): Ditto.
- (internal_getgrgid): Ditto.
- (getgrgid_r): Drop 2nd parameter from internal_getgrgid call.
- (getgrgid32): Ditto.
- (getgrnam_r): Ditto for internal_getgrnam.
- (getgrnam32): Ditto.
- (getgrent32): Convert to call new pwdgrp methods.
- (internal_getgrent): Remove.
- (internal_getgroups): Simplify, especially drop calls to
- internal_getgrent.
- * ldap.cc: New file implementing cyg_ldap class for LDAP access to AD
- and RFC 2307 server.
- * ldap.h: New header, declaring cyg_ldap class.
- * passwd.cc (passwd_buf): Drop.
- (pr): Drop.
- (pwdgrp::parse_passwd): Fill pg_pwd.
- (pwdgrp::read_passwd): Remove.
- (pwdgrp::init_pwd): New method.
- (pwdgrp::prep_tls_pwbuf): New method.
- (find_user): New methods.
- (internal_getpwsid): Convert to call new pwdgrp methods.
- (internal_getpwnam): Ditto.
- (internal_getpwuid): Ditto.
- (getpwuid32): Drop 2nd parameter from internal_getpwuid call.
- (getpwuid_r): Ditto.
- (getpwnam): Ditto for internal_getpwnam.
- (getpwnam_r): Ditto.
- (getpwent): Convert to call new pwdgrp methods.
- * path.cc (class etc): Remove all methods.
- * path.h (class etc): Drop.
- * pinfo.cc (pinfo_basic::pinfo_basic): Set gid to ILLEGAL_GID rather
- than UNKNOWN_GID.
- (pinfo_init): Ditto.
- * pwdgrp.h (internal_getpwnam): Drop 2nd parameter from declaration.
- (internal_getpwuid): Ditto.
- (internal_getgrgid): Ditto.
- (internal_getgrnam): Ditto.
- (internal_getgrent): Drop declaration.
- (enum fetch_user_arg_type_t): New type.
- (struct fetch_user_arg_t): New type.
- (struct pg_pwd): New type.
- (struct pg_grp): New type.
- (class pwdgrp): Rework to provide functions for file and db requests
- and caching.
- (class ugid_cache_t): New class to provide RFC 2307 uid map caching.
- (ugid_cache): Declare.
- * sec_acl.cc: Drop including pwdgrp.h.
- * sec_auth.cc: Drop including dsgetdc.h and pwdgrp.h.
- (get_logon_server): Convert third parameter to ULONG flags argument
- to allow arbitrary flags values in DsGetDcNameW call and change calls
- to this function throughout. Use cached account domain name rather
- than calling GetComputerNameW.
- (get_unix_group_sidlist): Remove.
- (get_server_groups): Drop call to get_unix_group_sidlist.
- (verify_token): Rework token group check without calling
- internal_getgrent.
- * sec_helper.cc (cygpsid::pstring): New methods, like string() but
- return pointer to end of string.
- (cygsid::getfromstr): Add wide character implementation.
- (get_sids_info): Add RFC 2307 uid/gid mapping for Samba shares.
- * security.cc: Drop including pwdgrp.h.
- * security.h (DEFAULT_UID): Remove.
- (UNKNOWN_UID): Remove.
- (UNKNOWN_GID): Remove.
- (uinfo_init): Move here from winsup.h.
- (ILLEGAL_UID): Ditto.
- (ILLEGAL_GID): Ditto.
- (UNIX_POSIX_OFFSET): Define. Add lengthy comment.
- (UNIX_POSIX_MASK): Ditto.
- (MAP_UNIX_TO_CYGWIN_ID): Ditto.
- (ILLEGAL_UID16): Move here from winsup.h.
- (ILLEGAL_GID16): Ditto.
- (uid16touid32): Ditto.
- (gid16togid32): Ditto.
- (sid_id_auth): New convenience macro for SID component access.
- (sid_sub_auth_count): Ditto.
- (sid_sub_auth): Ditto.
- (sid_sub_auth_rid): Ditto.
- (cygpsid::pstring): Declare.
- (cygsid::getfromstr): Declare wide character variant.
- (cygsid::operator=): Ditto.
- (cygsid::operator*=): Ditto.
- (get_logon_server): Change declaration according to source code.
- * setlsapwd.cc (setlsapwd): Drop 2nd parameter from internal_getpwnam
- call.
- * shared.cc (memory_init): Call cygheap->pg.init in first process.
- * syscalls.cc: Drop including pwdgrp.h.
- * tlsoffsets.h: Regenerate.
- * tlsoffsets64.h: Ditto.
- * uinfo.cc (internal_getlogin): Drop gratuitious internal_getpwuid
- call. Fix debug output. Overwrite user gid in border case of a
- missing passwd file while a group file exists.
- (pwdgrp::add_line): Allocate memory on cygheap.
- (pwdgrp::load): Remove.
- (ugid_cache): Define.
- (cygheap_pwdgrp::init): New method.
- (cygheap_pwdgrp::nss_init_line): New method.
- (cygheap_pwdgrp::_nss_init): New method.
- (cygheap_domain_info::init): New method.
- (logon_sid): Define.
- (get_logon_sid): New function.
- (pwdgrp::add_account_post_fetch): New method.
- (pwdgrp::add_account_from_file): New methods.
- (pwdgrp::add_account_from_windows): New methods.
- (pwdgrp::check_file): New method.
- (pwdgrp::fetch_account_from_line): New method.
- (pwdgrp::fetch_account_from_file): New method.
- (pwdgrp::fetch_account_from_windows): New method.
- * winsup.h: Move aforementioned macros and declarations to security.h.
-
2014-02-09 Christopher Faylor <me.cygwin2014@cgf.cx>
* sigproc.cc (sig_send): Don't bother with an error message if we are
exiting.
-2014-02-08 Corinna Vinschen <corinna@vinschen.de>
-
- * miscfuncs.h (class NT_readline): New class to implement line-wise
- reading from file using native NT functions.
- * miscfuncs.cc (NT_readline::init): New method.
- (NT_readline::fgets): New method.
- * mount.cc (mount_info::from_fstab): Utilize NT_readline to read
- fstab files.
-
2014-02-06 Corinna Vinschen <corinna@vinschen.de>
* fhandler_disk_file.cc (fhandler_disk_file::fchown): Fix typo in
@@ -1550,9 +725,6 @@
* net.cc (cygwin_gethostname): Call GetComputerNameExA rather than
GetComputerNameA if gethostname failed.
* shared.cc (user_info::initialize): Fix formatting.
-
-2014-02-06 Corinna Vinschen <corinna@vinschen.de>
-
* include/sys/file.h: Define flock and accompanying macros if not
already defined in sys/_default_fcntl.h.
diff --git a/winsup/cygwin/Makefile.in b/winsup/cygwin/Makefile.in
index 6065d120c..b47330379 100644
--- a/winsup/cygwin/Makefile.in
+++ b/winsup/cygwin/Makefile.in
@@ -1,6 +1,6 @@
# Makefile.in for Cygwin.
# Copyright 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
-# 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014 Red Hat, Inc.
+# 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013 Red Hat, Inc.
#
# This file is part of Cygwin.
#
@@ -166,7 +166,7 @@ DLL_OFILES:=advapi32.o arc4random.o assert.o autoload.o base64.o bsdlib.o ctype.
fhandler_termios.o fhandler_tty.o fhandler_virtual.o fhandler_windows.o \
fhandler_zero.o flock.o fnmatch.o fork.o fts.o ftw.o getopt.o glob.o \
glob_pattern_p.o globals.o grp.o heap.o hookapi.o inet_addr.o \
- inet_network.o init.o ioctl.o ipc.o kernel32.o ldap.o libstdcxx_wrapper.o \
+ inet_network.o init.o ioctl.o ipc.o kernel32.o libstdcxx_wrapper.o \
localtime.o lsearch.o malloc_wrapper.o minires-os-if.o minires.o \
miscfuncs.o mktemp.o mmap.o msg.o mount.o net.o netdb.o nfs.o nftw.o \
nlsfuncs.o ntea.o passwd.o path.o pinfo.o pipe.o poll.o posix_ipc.o \
diff --git a/winsup/cygwin/autoload.cc b/winsup/cygwin/autoload.cc
index 8e3733e5c..0199cc553 100644
--- a/winsup/cygwin/autoload.cc
+++ b/winsup/cygwin/autoload.cc
@@ -1,7 +1,7 @@
/* autoload.cc: all dynamic load stuff.
Copyright 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
- 2011, 2012, 2013, 2014 Red Hat, Inc.
+ 2011, 2012, 2013 Red Hat, Inc.
This file is part of Cygwin.
@@ -536,7 +536,6 @@ wsock_init ()
LoadDLLprime (ws2_32, _wsock_init, 0)
-LoadDLLfunc (CheckTokenMembership, 12, advapi32)
LoadDLLfunc (CreateProcessAsUserW, 44, advapi32)
LoadDLLfunc (DeregisterEventSource, 4, advapi32)
LoadDLLfunc (LogonUserW, 24, advapi32)
@@ -581,46 +580,15 @@ LoadDLLfuncEx2 (IdnToAscii, 20, kernel32, 1, 0)
LoadDLLfuncEx2 (IdnToUnicode, 20, kernel32, 1, 0)
LoadDLLfunc (LocaleNameToLCID, 8, kernel32)
-/* ldap functions are cdecl! */
-#pragma push_macro ("mangle")
-#undef mangle
-#define mangle(name, n) #name
-LoadDLLfunc (ldap_bind_s, 0, wldap32)
-LoadDLLfunc (ldap_count_entries, 0, wldap32)
-LoadDLLfunc (ldap_count_valuesW, 0, wldap32)
-LoadDLLfunc (ldap_first_entry, 0, wldap32)
-LoadDLLfunc (ldap_get_next_page_s, 0, wldap32)
-LoadDLLfunc (ldap_get_valuesW, 0, wldap32)
-LoadDLLfunc (ldap_get_values_lenW, 0, wldap32)
-LoadDLLfunc (ldap_initW, 0, wldap32)
-LoadDLLfunc (ldap_msgfree, 0, wldap32)
-LoadDLLfunc (ldap_next_entry, 0, wldap32)
-LoadDLLfunc (ldap_search_abandon_page, 0, wldap32)
-LoadDLLfunc (ldap_search_init_pageW, 0, wldap32)
-LoadDLLfunc (ldap_search_sW, 0, wldap32)
-LoadDLLfunc (ldap_set_option, 0, wldap32)
-LoadDLLfunc (ldap_sslinitW, 0, wldap32)
-LoadDLLfunc (ldap_unbind, 0, wldap32)
-LoadDLLfunc (ldap_value_freeW, 0, wldap32)
-LoadDLLfunc (ldap_value_free_len, 0, wldap32)
-LoadDLLfunc (LdapGetLastError, 0, wldap32)
-LoadDLLfunc (LdapMapErrorToWin32, 0, wldap32)
-#pragma pop_macro ("mangle")
-
LoadDLLfunc (WNetCloseEnum, 4, mpr)
LoadDLLfunc (WNetEnumResourceA, 16, mpr)
LoadDLLfunc (WNetGetProviderNameA, 12, mpr)
LoadDLLfunc (WNetGetResourceInformationA, 16, mpr)
LoadDLLfunc (WNetOpenEnumA, 20, mpr)
-LoadDLLfunc (DsEnumerateDomainTrustsW, 16, netapi32)
LoadDLLfunc (DsGetDcNameW, 24, netapi32)
LoadDLLfunc (NetApiBufferFree, 4, netapi32)
-LoadDLLfunc (NetGroupEnum, 28, netapi32)
-LoadDLLfunc (NetLocalGroupEnum, 28, netapi32)
-LoadDLLfunc (NetLocalGroupGetInfo, 16, netapi32)
LoadDLLfunc (NetUseGetInfo, 16, netapi32)
-LoadDLLfunc (NetUserEnum, 32, netapi32)
LoadDLLfunc (NetUserGetGroups, 28, netapi32)
LoadDLLfunc (NetUserGetInfo, 16, netapi32)
LoadDLLfunc (NetUserGetLocalGroups, 32, netapi32)
diff --git a/winsup/cygwin/cygheap.h b/winsup/cygwin/cygheap.h
index c4b2ed9ad..164a87090 100644
--- a/winsup/cygwin/cygheap.h
+++ b/winsup/cygwin/cygheap.h
@@ -1,7 +1,7 @@
/* cygheap.h: Cygwin heap manager.
Copyright 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
- 2011, 2012, 2013, 2014 Red Hat, Inc.
+ 2011, 2012, 2013 Red Hat, Inc.
This file is part of Cygwin.
@@ -11,7 +11,6 @@ details. */
#include "hires.h"
#include "cygheap_malloc.h"
-#include "pwdgrp.h"
#define incygheap(s) (cygheap && ((char *) (s) >= (char *) cygheap) && ((char *) (s) <= ((char *) cygheap_max)))
@@ -156,8 +155,8 @@ public:
}
void set_sid (PSID new_sid) { effec_cygsid = new_sid;}
void set_saved_sid () { saved_cygsid = effec_cygsid; }
- cygpsid &sid () { return effec_cygsid; }
- cygpsid &saved_sid () { return saved_cygsid; }
+ PSID sid () { return effec_cygsid; }
+ PSID saved_sid () { return saved_cygsid; }
const char *ontherange (homebodies what, struct passwd * = NULL);
#define NO_IMPERSONATION NULL
bool issetuid () const { return curr_imp_token != NO_IMPERSONATION; }
@@ -356,128 +355,6 @@ struct user_heap_info
void __reg1 init ();
};
-class cygheap_domain_info
-{
- PWCHAR pdom_name;
- PWCHAR pdom_dns_name;
- cygsid pdom_sid;
-
- PWCHAR adom_name;
- cygsid adom_sid;
-
- PDS_DOMAIN_TRUSTSW tdom;
- ULONG tdom_count;
-
- PWCHAR rfc2307_domain_buf;
-
-public:
- ULONG lowest_tdo_posix_offset;
-
- bool init ();
-
- inline PCWSTR primary_flat_name () const { return pdom_name; }
- inline PCWSTR primary_dns_name () const { return pdom_dns_name; }
- inline cygsid &primary_sid () { return pdom_sid; }
-
- inline bool member_machine () const { return pdom_sid != NO_SID; }
-
- inline PCWSTR account_flat_name () const { return adom_name; }
- inline cygsid &account_sid () { return adom_sid; }
-
- inline PDS_DOMAIN_TRUSTSW trusted_domain (ULONG idx) const
- { return (idx < tdom_count) ? tdom + idx : NULL; }
-
- inline PWCHAR get_rfc2307_domain () const
- { return rfc2307_domain_buf ?: NULL; }
-};
-
-class cygheap_pwdgrp
-{
- static const int NSS_FILES = 1;
- static const int NSS_DB = 2;
- enum pfx_t {
- NSS_AUTO = 0,
- NSS_PRIMARY,
- NSS_ALWAYS
- };
- bool nss_inited;
- int pwd_src;
- int grp_src;
- pfx_t prefix;
- WCHAR separator[2];
- bool caching;
- int enums;
- PWCHAR enum_tdoms;
-
- void nss_init_line (const char *line);
- void _nss_init ();
-
-public:
- struct {
- pwdgrp cygserver;
- pwdgrp file;
- pwdgrp win;
- } pwd_cache;
- struct {
- pwdgrp cygserver;
- pwdgrp file;
- pwdgrp win;
- } grp_cache;
-
- void init ();
-
- inline void nss_init () { if (!nss_inited) _nss_init (); }
- inline bool nss_pwd_files () const { return !!(pwd_src & NSS_FILES); }
- inline bool nss_pwd_db () const { return !!(pwd_src & NSS_DB); }
- inline bool nss_grp_files () const { return !!(grp_src & NSS_FILES); }
- inline bool nss_grp_db () const { return !!(grp_src & NSS_DB); }
- inline bool nss_prefix_auto () const { return prefix == NSS_AUTO; }
- inline bool nss_prefix_primary () const { return prefix == NSS_PRIMARY; }
- inline bool nss_prefix_always () const { return prefix == NSS_ALWAYS; }
- inline PCWSTR nss_separator () const { return separator; }
- inline bool nss_cygserver_caching () const { return caching; }
- inline void nss_disable_cygserver_caching () { caching = false; }
- inline int nss_db_enums () const { return enums; }
- inline PCWSTR nss_db_enum_tdoms () const { return enum_tdoms; }
-};
-
-class cygheap_ugid_cache
-{
- struct idmap {
- uint32_t nfs_id;
- uint32_t cyg_id;
- };
- class idmaps {
- uint32_t _cnt;
- uint32_t _max;
- idmap *_map;
- public:
- uint32_t get (uint32_t id) const
- {
- for (uint32_t i = 0; i < _cnt; ++i)
- if (_map[i].nfs_id == id)
- return _map[i].cyg_id;
- return (uint32_t) -1;
- }
- void add (uint32_t nfs_id, uint32_t cyg_id)
- {
- if (_cnt >= _max)
- _map = (idmap *) crealloc (_map, (_max += 10) * sizeof (*_map));
- _map[_cnt].nfs_id = nfs_id;
- _map[_cnt].cyg_id = cyg_id;
- ++_cnt;
- }
- };
- idmaps uids;
- idmaps gids;
-
-public:
- uid_t get_uid (uid_t uid) const { return uids.get (uid); }
- gid_t get_gid (gid_t gid) const { return gids.get (gid); }
- void add_uid (uid_t nfs_uid, uid_t cyg_uid) { uids.add (nfs_uid, cyg_uid); }
- void add_gid (gid_t nfs_gid, gid_t cyg_gid) { gids.add (nfs_gid, cyg_gid); }
-};
-
struct hook_chain
{
void **loc;
@@ -501,9 +378,6 @@ struct init_cygheap: public mini_cygheap
UNICODE_STRING installation_key;
WCHAR installation_key_buf[18];
cygheap_root root;
- cygheap_domain_info dom;
- cygheap_pwdgrp pg;
- cygheap_ugid_cache ugid_cache;
cygheap_user user;
user_heap_info user_heap;
mode_t umask;
diff --git a/winsup/cygwin/cygserver.h b/winsup/cygwin/cygserver.h
index 1313d3c1e..8bcc271f3 100644
--- a/winsup/cygwin/cygserver.h
+++ b/winsup/cygwin/cygserver.h
@@ -52,7 +52,6 @@ protected:
CYGSERVER_REQUEST_SEM,
CYGSERVER_REQUEST_SHM,
CYGSERVER_REQUEST_SETPWD,
- CYGSERVER_REQUEST_PWDGRP,
CYGSERVER_REQUEST_LAST
} request_code_t;
diff --git a/winsup/cygwin/cygserver_pwdgrp.h b/winsup/cygwin/cygserver_pwdgrp.h
deleted file mode 100644
index 52b9b42ba..000000000
--- a/winsup/cygwin/cygserver_pwdgrp.h
+++ /dev/null
@@ -1,73 +0,0 @@
-/* cygserver_pwdgrp.h: Request account information
-
- Copyright 2014 Red Hat, Inc.
-
-This file is part of Cygwin.
-
-This software is a copyrighted work licensed under the terms of the
-Cygwin license. Please consult the file "CYGWIN_LICENSE" for
-details. */
-
-#ifndef __CYGSERVER_PWDGRP_H__
-#define __CYGSERVER_PWDGRP_H__
-
-#include <sys/types.h>
-#include "cygserver.h"
-
-class transport_layer_base;
-class process_cache;
-
-#ifdef __INSIDE_CYGWIN__
-#include "pwdgrp.h"
-#else
-/* Don't include pwdgrp.h, but keep this in sync. */
-enum fetch_user_arg_type_t {
- SID_arg,
- NAME_arg,
- ID_arg
-};
-#endif
-
-class client_request_pwdgrp : public client_request
-{
- friend class client_request;
-
-private:
- union _pwdgrp_param_t
- {
- struct _pwdgrp_in_t
- {
- bool group;
- fetch_user_arg_type_t type;
- union
- {
- BYTE sid[40];
- char name[UNLEN + 1];
- uint32_t id;
- } arg;
- } in;
-
- struct
- {
- char line[1024];
- } out;
- } _parameters;
-
-#ifndef __INSIDE_CYGWIN__
- client_request_pwdgrp ();
- virtual void serve (transport_layer_base *, process_cache *);
- void pwd_serve ();
- void grp_serve ();
-#endif
-
-public:
-
-#ifdef __INSIDE_CYGWIN__
- client_request_pwdgrp (fetch_user_arg_t &arg, bool group);
-#endif
-
- const char *line () const { return (msglen () > 0) ? _parameters.out.line
- : NULL; }
-};
-
-#endif /* __CYGSERVER_PWDGRP_H__ */
diff --git a/winsup/cygwin/cygtls.h b/winsup/cygwin/cygtls.h
index 32838744d..0d6aa713b 100644
--- a/winsup/cygwin/cygtls.h
+++ b/winsup/cygwin/cygtls.h
@@ -79,13 +79,20 @@ public:
struct _local_storage
{
- /* passwd.cc */
- char pass[_PASSWORD_LEN];
+ /*
+ Needed for the group functions
+ */
+ int grp_pos;
/* dlfcn.cc */
int dl_error;
char dl_buffer[256];
+ /* passwd.cc */
+ struct passwd res;
+ char pass[_PASSWORD_LEN];
+ int pw_pos;
+
/* path.cc */
struct mntent mntbuf;
int iteration;
diff --git a/winsup/cygwin/dcrt0.cc b/winsup/cygwin/dcrt0.cc
index 6e75ccee4..5c6004c91 100644
--- a/winsup/cygwin/dcrt0.cc
+++ b/winsup/cygwin/dcrt0.cc
@@ -936,14 +936,14 @@ dll_crt0_1 (void *)
/* Allocate cygheap->fdtab */
dtable_init ();
- /* Set internal locale to the environment settings. */
- initial_setlocale ();
-
uinfo_init (); /* initialize user info */
/* Connect to tty. */
tty::init_session ();
+ /* Set internal locale to the environment settings. */
+ initial_setlocale ();
+
if (!__argc)
{
PWCHAR wline = GetCommandLineW ();
diff --git a/winsup/cygwin/errno.cc b/winsup/cygwin/errno.cc
index a87a11564..2a5f711bd 100644
--- a/winsup/cygwin/errno.cc
+++ b/winsup/cygwin/errno.cc
@@ -59,21 +59,17 @@ static const struct
X (BUSY, EBUSY),
X (BUS_RESET, EIO),
X (CALL_NOT_IMPLEMENTED, ENOSYS),
- X (CANCELLED, EINTR),
X (CANNOT_MAKE, EPERM),
X (CHILD_NOT_COMPLETE, EBUSY),
X (COMMITMENT_LIMIT, EAGAIN),
- X (CONNECTION_REFUSED, ECONNREFUSED),
X (CRC, EIO),
X (DEVICE_DOOR_OPEN, EIO),
X (DEVICE_IN_USE, EAGAIN),
X (DEVICE_REQUIRES_CLEANING, EIO),
- X (DEV_NOT_EXIST, ENOENT),
X (DIRECTORY, ENOTDIR),
X (DIR_NOT_EMPTY, ENOTEMPTY),
X (DISK_CORRUPT, EIO),
X (DISK_FULL, ENOSPC),
- X (DS_GENERIC_ERROR, EIO),
X (DUP_NAME, ENOTUNIQ),
X (EAS_DIDNT_FIT, ENOSPC),
X (EAS_NOT_SUPPORTED, ENOTSUP),
@@ -119,7 +115,6 @@ static const struct
X (NONPAGED_SYSTEM_RESOURCES, EAGAIN),
X (NOT_CONNECTED, ENOLINK),
X (NOT_ENOUGH_MEMORY, ENOMEM),
- X (NOT_ENOUGH_QUOTA, EIO),
X (NOT_OWNER, EPERM),
X (NOT_READY, ENOMEDIUM),
X (NOT_SAME_DEVICE, EXDEV),
@@ -151,7 +146,6 @@ static const struct
X (REM_NOT_LIST, ENONET),
X (SECTOR_NOT_FOUND, EINVAL),
X (SEEK, EINVAL),
- X (SERVICE_REQUEST_TIMEOUT, EBUSY),
X (SETMARK_DETECTED, EIO),
X (SHARING_BUFFER_EXCEEDED, ENOLCK),
X (SHARING_VIOLATION, EBUSY),
@@ -159,10 +153,8 @@ static const struct
X (SIGNAL_REFUSED, EIO),
X (SXS_CANT_GEN_ACTCTX, ELIBBAD),
X (THREAD_1_INACTIVE, EINVAL),
- X (TIMEOUT, EBUSY),
X (TOO_MANY_LINKS, EMLINK),
X (TOO_MANY_OPEN_FILES, EMFILE),
- X (UNEXP_NET_ERR, EIO),
X (WAIT_NO_CHILDREN, ECHILD),
X (WORKING_SET_QUOTA, EAGAIN),
X (WRITE_PROTECT, EROFS),
diff --git a/winsup/cygwin/external.cc b/winsup/cygwin/external.cc
index edc9d5d29..47b18809c 100644
--- a/winsup/cygwin/external.cc
+++ b/winsup/cygwin/external.cc
@@ -380,13 +380,13 @@ cygwin_internal (cygwin_getinfo_types t, ...)
case CW_GET_UID_FROM_SID:
{
cygpsid psid = va_arg (arg, PSID);
- res = psid.get_uid (NULL);
+ res = psid.get_id (false, NULL);
}
break;
case CW_GET_GID_FROM_SID:
{
cygpsid psid = va_arg (arg, PSID);
- res = psid.get_gid (NULL);
+ res = psid.get_id (true, NULL);
}
break;
case CW_GET_BINMODE:
@@ -554,123 +554,22 @@ cygwin_internal (cygwin_getinfo_types t, ...)
}
break;
- case CW_SETENT:
- {
- int group = va_arg (arg, int);
- int enums = va_arg (arg, int);
- PCWSTR enum_tdoms = va_arg (arg, PCWSTR);
- if (group)
- res = (uintptr_t) setgrent_filtered (enums, enum_tdoms);
- else
- res = (uintptr_t) setpwent_filtered (enums, enum_tdoms);
- }
- break;
-
- case CW_GETENT:
- {
- int group = va_arg (arg, int);
- void *obj = va_arg (arg, void *);
- if (obj)
- {
- if (group)
- res = (uintptr_t) getgrent_filtered (obj);
- else
- res = (uintptr_t) getpwent_filtered (obj);
- }
- }
- break;
-
- case CW_ENDENT:
- {
- int group = va_arg (arg, int);
- void *obj = va_arg (arg, void *);
- if (obj)
- {
- if (group)
- endgrent_filtered (obj);
- else
- endpwent_filtered (obj);
- res = 0;
- }
- }
- break;
-
- case CW_GETNSSSEP:
- res = (uintptr_t) cygheap->pg.nss_separator ();
- break;
-
case CW_GETPWSID:
- {
- int db_only = va_arg (arg, int);
- PSID psid = va_arg (arg, PSID);
- cygpsid sid (psid);
- res = (uintptr_t) (db_only ? internal_getpwsid_from_db (sid)
- : internal_getpwsid (sid));
- }
- break;
+ {
+ va_arg (arg, int);
+ PSID psid = va_arg (arg, PSID);
+ cygpsid sid (psid);
+ res = (uintptr_t) internal_getpwsid (sid);
+ }
+ break;
case CW_GETGRSID:
- {
- int db_only = va_arg (arg, int);
- PSID psid = va_arg (arg, PSID);
- cygpsid sid (psid);
- res = (uintptr_t) (db_only ? internal_getgrsid_from_db (sid)
- : internal_getgrsid (sid));
- }
- break;
-
- case CW_CYGNAME_FROM_WINNAME:
- {
- /* This functionality has been added mainly for sshd. Sshd
- calls getpwnam() with the username of the non-privileged
- user used for privilege separation. This is usually a
- fixed string "sshd". However, when using usernames from
- the Windows DBs, it's no safe bet anymore if the username
- is "sshd", it could also be "DOMAIN+sshd". So what we do
- here is this:
-
- Sshd calls cygwin_internal (CW_CYGNAME_FROM_WINNAME,
- "sshd",
- username_buffer,
- sizeof username_buffer);
-
- If this call succeeds, sshd expects the correct Cygwin
- username of the unprivileged sshd account in username_buffer.
-
- The below code checks for a Windows username matching the
- incoming username, and then fetches the Cygwin username with
- the matching SID. This is our username used for privsep then.
-
- Of course, other applications with similar needs can use the
- same method. */
- const char *winname = va_arg (arg, const char *);
- char *buffer = va_arg (arg, char *);
- size_t buflen = va_arg (arg, size_t);
-
- if (!winname || !buffer || !buflen)
- break;
-
- WCHAR name[UNLEN + 1];
- sys_mbstowcs (name, sizeof name, winname);
-
- cygsid sid;
- DWORD slen = SECURITY_MAX_SID_SIZE;
- WCHAR dom[DNLEN + 1];
- DWORD dlen = DNLEN + 1;
- SID_NAME_USE acc_type;
-
- if (!LookupAccountNameW (NULL, name, sid, &slen, dom, &dlen,
- &acc_type))
- break;
-
- struct passwd *pw = internal_getpwsid (sid);
- if (!pw)
- break;
-
- buffer[0] = '\0';
- strncat (buffer, pw->pw_name, buflen - 1);
- res = 0;
- }
+ {
+ va_arg (arg, int);
+ PSID psid = va_arg (arg, PSID);
+ cygpsid sid (psid);
+ res = (uintptr_t) internal_getgrsid (sid);
+ }
break;
default:
diff --git a/winsup/cygwin/fhandler_disk_file.cc b/winsup/cygwin/fhandler_disk_file.cc
index 428d04c45..b5415c9ce 100644
--- a/winsup/cygwin/fhandler_disk_file.cc
+++ b/winsup/cygwin/fhandler_disk_file.cc
@@ -10,8 +10,6 @@ Cygwin license. Please consult the file "CYGWIN_LICENSE" for
details. */
#include "winsup.h"
-#include <winioctl.h>
-#include <lm.h>
#include <stdlib.h>
#include <sys/acl.h>
#include <sys/statvfs.h>
@@ -25,8 +23,10 @@ details. */
#include "pinfo.h"
#include "ntdll.h"
#include "tls_pbuf.h"
+#include "pwdgrp.h"
+#include <winioctl.h>
+#include <lm.h>
#include "devices.h"
-#include "ldap.h"
#define _COMPILING_NEWLIB
#include <dirent.h>
@@ -323,9 +323,6 @@ int __reg2
fhandler_base::fstat_by_nfs_ea (struct stat *buf)
{
fattr3 *nfs_attr = pc.nfsattr ();
- PWCHAR domain;
- cyg_ldap cldap;
- bool ldap_open = false;
if (get_io_handle ())
{
@@ -343,36 +340,14 @@ fhandler_base::fstat_by_nfs_ea (struct stat *buf)
buf->st_mode = (nfs_attr->mode & 0xfff)
| nfs_type_mapping[nfs_attr->type & 7];
buf->st_nlink = nfs_attr->nlink;
- /* Try to map UNIX uid/gid to Cygwin uid/gid. If there's no mapping in
- the cache, try to fetch it from the configured RFC 2307 domain (see
- last comment in cygheap_domain_info::init() for more information) and
- add it to the mapping cache. */
- buf->st_uid = cygheap->ugid_cache.get_uid (nfs_attr->uid);
- buf->st_gid = cygheap->ugid_cache.get_gid (nfs_attr->gid);
- if (buf->st_uid == ILLEGAL_UID)
- {
- uid_t map_uid = ILLEGAL_UID;
-
- domain = cygheap->dom.get_rfc2307_domain ();
- if ((ldap_open = (cldap.open (domain) == NO_ERROR)))
- map_uid = cldap.remap_uid (nfs_attr->uid);
- if (map_uid == ILLEGAL_UID)
- map_uid = MAP_UNIX_TO_CYGWIN_ID (nfs_attr->uid);
- cygheap->ugid_cache.add_uid (nfs_attr->uid, map_uid);
- buf->st_uid = map_uid;
- }
- if (buf->st_gid == ILLEGAL_GID)
- {
- gid_t map_gid = ILLEGAL_GID;
-
- domain = cygheap->dom.get_rfc2307_domain ();
- if ((ldap_open || cldap.open (domain) == NO_ERROR))
- map_gid = cldap.remap_gid (nfs_attr->gid);
- if (map_gid == ILLEGAL_GID)
- map_gid = MAP_UNIX_TO_CYGWIN_ID (nfs_attr->gid);
- cygheap->ugid_cache.add_gid (nfs_attr->gid, map_gid);
- buf->st_gid = map_gid;
- }
+ /* FIXME: How to convert UNIX uid/gid to Windows SIDs? */
+#if 0
+ buf->st_uid = nfs_attr->uid;
+ buf->st_gid = nfs_attr->gid;
+#else
+ buf->st_uid = myself->uid;
+ buf->st_gid = myself->gid;
+#endif
buf->st_rdev = makedev (nfs_attr->rdev.specdata1,
nfs_attr->rdev.specdata2);
buf->st_size = nfs_attr->size;
@@ -534,7 +509,8 @@ fhandler_base::fstat_fs (struct stat *buf)
}
int __reg3
-fhandler_base::fstat_helper (struct stat *buf, DWORD nNumberOfLinks)
+fhandler_base::fstat_helper (struct stat *buf,
+ DWORD nNumberOfLinks)
{
IO_STATUS_BLOCK st;
FILE_COMPRESSION_INFORMATION fci;
@@ -802,7 +778,7 @@ fhandler_disk_file::fstatvfs (struct statvfs *sfs)
}
else
debug_printf ("%y = NtQueryVolumeInformationFile"
- "(%S, FileFsFullSizeInformation)",
+ "(%S, FileFsFullSizeInformation)",
status, pc.get_nt_native_path ());
out:
if (opened)
diff --git a/winsup/cygwin/fhandler_process.cc b/winsup/cygwin/fhandler_process.cc
index a6e326cd3..1e5a02806 100644
--- a/winsup/cygwin/fhandler_process.cc
+++ b/winsup/cygwin/fhandler_process.cc
@@ -24,6 +24,7 @@ details. */
#include "cygheap.h"
#include "ntdll.h"
#include "cygtls.h"
+#include "pwdgrp.h"
#include "mount.h"
#include "tls_pbuf.h"
#include <sys/sysmacros.h>
diff --git a/winsup/cygwin/fhandler_registry.cc b/winsup/cygwin/fhandler_registry.cc
index fd3b76824..d4b6706c7 100644
--- a/winsup/cygwin/fhandler_registry.cc
+++ b/winsup/cygwin/fhandler_registry.cc
@@ -586,8 +586,8 @@ fhandler_registry::fstat (struct stat *buf)
and it's also rather unlikely that the user is the owner.
Therefore it's probably most safe to assume unknown ownership
and no permissions for nobody. */
- buf->st_uid = ILLEGAL_UID;
- buf->st_gid = ILLEGAL_GID;
+ buf->st_uid = UNKNOWN_UID;
+ buf->st_gid = UNKNOWN_GID;
buf->st_mode &= ~0777;
}
}
diff --git a/winsup/cygwin/fhandler_socket.cc b/winsup/cygwin/fhandler_socket.cc
index dbcd2619c..793578f39 100644
--- a/winsup/cygwin/fhandler_socket.cc
+++ b/winsup/cygwin/fhandler_socket.cc
@@ -1701,9 +1701,13 @@ fhandler_socket::send_internal (struct _WSAMSG *wsamsg, int flags)
while (out_len < (unsigned) wmem ()
&& (in_off = 0, ++in_idx < wsamsg->dwBufferCount));
/* Tweak len of the last out_buf buffer so the entire number of bytes
- is less than wmem (). */
+ is (less than or) equal to wmem (). Fix out_len as well since it's
+ used in a subsequent test expression. */
if (out_len > (unsigned) wmem ())
- out_buf[out_idx - 1].len -= out_len - (unsigned) wmem ();
+ {
+ out_buf[out_idx - 1].len -= out_len - (unsigned) wmem ();
+ out_len = (unsigned) wmem ();
+ }
/* Add the bytes written from the current last buffer to in_off,
so in_off points to the next byte to be written from that buffer,
or beyond which lets the outper loop skip to the next buffer. */
diff --git a/winsup/cygwin/grp.cc b/winsup/cygwin/grp.cc
index f7ce61b08..d4d1b653f 100644
--- a/winsup/cygwin/grp.cc
+++ b/winsup/cygwin/grp.cc
@@ -1,7 +1,7 @@
/* grp.cc
Copyright 1996, 1997, 1998, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007,
- 2008, 2009, 2011, 2012, 2013, 2014 Red Hat, Inc.
+ 2008, 2009, 2011, 2012, 2013 Red Hat, Inc.
Original stubs by Jason Molenda of Cygnus Support, crash@cygnus.com
First implementation by Gunther Ebert, gunther.ebert@ixos-leipzig.de
@@ -13,7 +13,6 @@ Cygwin license. Please consult the file "CYGWIN_LICENSE" for
details. */
#include "winsup.h"
-#include <lm.h>
#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
@@ -24,166 +23,134 @@ details. */
#include "dtable.h"
#include "cygheap.h"
#include "ntdll.h"
-#include "miscfuncs.h"
-#include "ldap.h"
-#include "tls_pbuf.h"
+#include "pwdgrp.h"
+static group *group_buf;
+static pwdgrp gr (group_buf);
static char * NO_COPY_RO null_ptr;
bool
pwdgrp::parse_group ()
{
- pg_grp &grp = group ()[curr_lines];
- grp.g.gr_name = next_str (':');
- if (!*grp.g.gr_name)
+ group &grp = (*group_buf)[curr_lines];
+ grp.gr_name = next_str (':');
+ if (!*grp.gr_name)
return false;
- grp.g.gr_passwd = next_str (':');
- /* Note that lptr points to the first byte of the gr_gid field.
- We deliberately ignore the gr_gid and gr_mem entries when copying
- the buffer content since they are not referenced anymore. */
- grp.len = lptr - grp.g.gr_name;
- if (!next_num (grp.g.gr_gid))
+
+ grp.gr_passwd = next_str (':');
+
+ if (!next_num (grp.gr_gid))
return false;
- /* Don't generate gr_mem entries. */
- grp.g.gr_mem = &null_ptr;
- grp.sid.getfromgr (&grp.g);
+
+ int n;
+ char *dp = raw_ptr ();
+ for (n = 0; *next_str (','); n++)
+ continue;
+
+ grp.gr_mem = &null_ptr;
+ if (n)
+ {
+ char **namearray = (char **) calloc (n + 1, sizeof (char *));
+ if (namearray)
+ {
+ for (int i = 0; i < n; i++, dp = strchr (dp, '\0') + 1)
+ namearray[i] = dp;
+ grp.gr_mem = namearray;
+ }
+ }
+
return true;
}
-muto NO_COPY pwdgrp::pglock;
-
+/* Cygwin internal */
+/* Read in /etc/group and save contents in the group cache */
+/* This sets group_in_memory_p to 1 so functions in this file can
+ tell that /etc/group has been read in */
void
-pwdgrp::init_grp ()
+pwdgrp::read_group ()
{
- pwdgrp_buf_elem_size = sizeof (pg_grp);
- parse = &pwdgrp::parse_group;
-}
+ for (int i = 0; i < gr.curr_lines; i++)
+ if ((*group_buf)[i].gr_mem != &null_ptr)
+ free ((*group_buf)[i].gr_mem);
-struct group *
-pwdgrp::find_group (cygpsid &sid)
-{
- for (ULONG i = 0; i < curr_lines; i++)
- if (sid == group ()[i].sid)
- return &group ()[i].g;
- return NULL;
+ load (L"\\etc\\group");
+
+ /* Complete /etc/group in memory if needed */
+ if (!internal_getgrgid (myself->gid))
+ {
+ static char linebuf [200];
+ char group_name [UNLEN + 1] = "mkgroup";
+ char strbuf[128] = "";
+ struct group *gr;
+
+ cygheap->user.groups.pgsid.string (strbuf);
+ if ((gr = internal_getgrsid (cygheap->user.groups.pgsid)))
+ snprintf (group_name, sizeof (group_name),
+ "passwd/group_GID_clash(%u/%u)", myself->gid, gr->gr_gid);
+ if (myself->uid == UNKNOWN_UID)
+ strcpy (group_name, "mkpasswd"); /* Feedback... */
+ snprintf (linebuf, sizeof (linebuf), "%s:%s:%u:%s",
+ group_name, strbuf, myself->gid, cygheap->user.name ());
+ debug_printf ("Completing /etc/group: %s", linebuf);
+ add_line (linebuf);
+ }
+ static char NO_COPY pretty_ls[] = "????????::-1:";
+ add_line (pretty_ls);
}
-struct group *
-pwdgrp::find_group (const char *name)
+muto NO_COPY pwdgrp::pglock;
+
+pwdgrp::pwdgrp (passwd *&pbuf) :
+ pwdgrp_buf_elem_size (sizeof (*pbuf)), passwd_buf (&pbuf)
{
- for (ULONG i = 0; i < curr_lines; i++)
- if (strcasematch (group ()[i].g.gr_name, name))
- return &group ()[i].g;
- return NULL;
+ read = &pwdgrp::read_passwd;
+ parse = &pwdgrp::parse_passwd;
+ pglock.init ("pglock");
}
-struct group *
-pwdgrp::find_group (gid_t gid)
+pwdgrp::pwdgrp (group *&gbuf) :
+ pwdgrp_buf_elem_size (sizeof (*gbuf)), group_buf (&gbuf)
{
- for (ULONG i = 0; i < curr_lines; i++)
- if (gid == group ()[i].g.gr_gid)
- return &group ()[i].g;
- return NULL;
+ read = &pwdgrp::read_group;
+ parse = &pwdgrp::parse_group;
+ pglock.init ("pglock");
}
struct group *
-internal_getgrsid (cygpsid &sid, cyg_ldap *pldap)
+internal_getgrsid (cygpsid &sid)
{
- struct group *ret;
-
- cygheap->pg.nss_init ();
- /* Check caches first. */
- if (cygheap->pg.nss_cygserver_caching ()
- && (ret = cygheap->pg.grp_cache.cygserver.find_group (sid)))
- return ret;
- if (cygheap->pg.nss_grp_files ()
- && (ret = cygheap->pg.grp_cache.file.find_group (sid)))
- return ret;
- if (cygheap->pg.nss_grp_db ()
- && (ret = cygheap->pg.grp_cache.win.find_group (sid)))
- return ret;
- /* Ask sources afterwards. */
- if (cygheap->pg.nss_cygserver_caching ()
- && (ret = cygheap->pg.grp_cache.cygserver.add_group_from_cygserver (sid)))
- return ret;
- if (cygheap->pg.nss_grp_files ())
- {
- cygheap->pg.grp_cache.file.check_file ();
- if ((ret = cygheap->pg.grp_cache.file.add_group_from_file (sid)))
- return ret;
- }
- if (cygheap->pg.nss_grp_db ())
- return cygheap->pg.grp_cache.win.add_group_from_windows (sid, pldap);
+ char sid_string[128];
+
+ gr.refresh (false);
+
+ if (sid.string (sid_string))
+ for (int i = 0; i < gr.curr_lines; i++)
+ if (!strcmp (sid_string, group_buf[i].gr_passwd))
+ return group_buf + i;
return NULL;
}
-/* This function gets only called from mkgroup via cygwin_internal. */
struct group *
-internal_getgrsid_from_db (cygpsid &sid)
+internal_getgrgid (gid_t gid, bool check)
{
- cygheap->pg.nss_init ();
- return cygheap->pg.grp_cache.win.add_group_from_windows (sid);
-}
+ gr.refresh (check);
-struct group *
-internal_getgrnam (const char *name, cyg_ldap *pldap)
-{
- struct group *ret;
-
- cygheap->pg.nss_init ();
- /* Check caches first. */
- if (cygheap->pg.nss_cygserver_caching ()
- && (ret = cygheap->pg.grp_cache.cygserver.find_group (name)))
- return ret;
- if (cygheap->pg.nss_grp_files ()
- && (ret = cygheap->pg.grp_cache.file.find_group (name)))
- return ret;
- if (cygheap->pg.nss_grp_db ()
- && (ret = cygheap->pg.grp_cache.win.find_group (name)))
- return ret;
- /* Ask sources afterwards. */
- if (cygheap->pg.nss_cygserver_caching ()
- && (ret = cygheap->pg.grp_cache.cygserver.add_group_from_cygserver (name)))
- return ret;
- if (cygheap->pg.nss_grp_files ())
- {
- cygheap->pg.grp_cache.file.check_file ();
- if ((ret = cygheap->pg.grp_cache.file.add_group_from_file (name)))
- return ret;
- }
- if (cygheap->pg.nss_grp_db ())
- return cygheap->pg.grp_cache.win.add_group_from_windows (name, pldap);
+ for (int i = 0; i < gr.curr_lines; i++)
+ if (group_buf[i].gr_gid == gid)
+ return group_buf + i;
return NULL;
}
struct group *
-internal_getgrgid (gid_t gid, cyg_ldap *pldap)
+internal_getgrnam (const char *name, bool check)
{
- struct group *ret;
-
- cygheap->pg.nss_init ();
- /* Check caches first. */
- if (cygheap->pg.nss_cygserver_caching ()
- && (ret = cygheap->pg.grp_cache.cygserver.find_group (gid)))
- return ret;
- if (cygheap->pg.nss_grp_files ()
- && (ret = cygheap->pg.grp_cache.file.find_group (gid)))
- return ret;
- if (cygheap->pg.nss_grp_db ()
- && (ret = cygheap->pg.grp_cache.win.find_group (gid)))
- return ret;
- /* Ask sources afterwards. */
- if (cygheap->pg.nss_cygserver_caching ()
- && (ret = cygheap->pg.grp_cache.cygserver.add_group_from_cygserver (gid)))
- return ret;
- if (cygheap->pg.nss_grp_files ())
- {
- cygheap->pg.grp_cache.file.check_file ();
- if ((ret = cygheap->pg.grp_cache.file.add_group_from_file (gid)))
- return ret;
- }
- if (cygheap->pg.nss_grp_db () || gid == ILLEGAL_GID)
- return cygheap->pg.grp_cache.win.add_group_from_windows (gid, pldap);
+ gr.refresh (check);
+
+ for (int i = 0; i < gr.curr_lines; i++)
+ if (strcasematch (group_buf[i].gr_name, name))
+ return group_buf + i;
+
+ /* Didn't find requested group */
return NULL;
}
@@ -214,65 +181,37 @@ getgrgid_r (gid_t gid, struct group *grp, char *buffer, size_t bufsize,
if (!grp || !buffer)
return ERANGE;
- struct group *tempgr = internal_getgrgid (gid);
+ struct group *tempgr = internal_getgrgid (gid, true);
pthread_testcancel ();
if (!tempgr)
return 0;
- /* Check needed buffer size. Deliberately ignore gr_mem. */
+ /* check needed buffer size. */
+ int i;
size_t needsize = strlen (tempgr->gr_name) + strlen (tempgr->gr_passwd)
+ 2 + sizeof (char *);
+ for (i = 0; tempgr->gr_mem[i]; ++i)
+ needsize += strlen (tempgr->gr_mem[i]) + 1 + sizeof (char *);
if (needsize > bufsize)
return ERANGE;
- /* Make a copy of tempgr. Deliberately ignore gr_mem. */
+ /* make a copy of tempgr */
*result = grp;
grp->gr_gid = tempgr->gr_gid;
buffer = stpcpy (grp->gr_name = buffer, tempgr->gr_name);
buffer = stpcpy (grp->gr_passwd = buffer + 1, tempgr->gr_passwd);
grp->gr_mem = (char **) (buffer + 1);
- grp->gr_mem[0] = NULL;
+ buffer = (char *) grp->gr_mem + (i + 1) * sizeof (char *);
+ for (i = 0; tempgr->gr_mem[i]; ++i)
+ buffer = stpcpy (grp->gr_mem[i] = buffer, tempgr->gr_mem[i]) + 1;
+ grp->gr_mem[i] = NULL;
return 0;
}
-/* getgrgid/getgrnam are not reentrant. */
-static struct {
- struct group g;
- char *buf;
- size_t bufsiz;
-} app_gr;
-
-static struct group *
-getgr_cp (struct group *tempgr)
-{
- if (!tempgr)
- return NULL;
- pg_grp *gr = (pg_grp *) tempgr;
- if (app_gr.bufsiz < gr->len)
- {
- char *newbuf = (char *) realloc (app_gr.buf, gr->len);
- if (!newbuf)
- {
- set_errno (ENOMEM);
- return NULL;
- }
- app_gr.buf = newbuf;
- app_gr.bufsiz = gr->len;
- }
- memcpy (app_gr.buf, gr->g.gr_name, gr->len);
- memcpy (&app_gr.g, &gr->g, sizeof gr->g);
- ptrdiff_t diff = app_gr.buf - gr->g.gr_name;
- app_gr.g.gr_name += diff;
- app_gr.g.gr_passwd += diff;
- return &app_gr.g;
-}
-
extern "C" struct group *
getgrgid32 (gid_t gid)
{
- struct group *tempgr = internal_getgrgid (gid);
- pthread_testcancel ();
- return getgr_cp (tempgr);
+ return internal_getgrgid (gid, true);
}
#ifdef __x86_64__
@@ -296,33 +235,37 @@ getgrnam_r (const char *nam, struct group *grp, char *buffer,
if (!grp || !buffer)
return ERANGE;
- struct group *tempgr = internal_getgrnam (nam);
+ struct group *tempgr = internal_getgrnam (nam, true);
pthread_testcancel ();
if (!tempgr)
return 0;
- /* Check needed buffer size. Deliberately ignore gr_mem. */
+ /* check needed buffer size. */
+ int i;
size_t needsize = strlen (tempgr->gr_name) + strlen (tempgr->gr_passwd)
+ 2 + sizeof (char *);
+ for (i = 0; tempgr->gr_mem[i]; ++i)
+ needsize += strlen (tempgr->gr_mem[i]) + 1 + sizeof (char *);
if (needsize > bufsize)
return ERANGE;
- /* Make a copy of tempgr. Deliberately ignore gr_mem. */
+ /* make a copy of tempgr */
*result = grp;
grp->gr_gid = tempgr->gr_gid;
buffer = stpcpy (grp->gr_name = buffer, tempgr->gr_name);
buffer = stpcpy (grp->gr_passwd = buffer + 1, tempgr->gr_passwd);
grp->gr_mem = (char **) (buffer + 1);
- grp->gr_mem[0] = NULL;
+ buffer = (char *) grp->gr_mem + (i + 1) * sizeof (char *);
+ for (i = 0; tempgr->gr_mem[i]; ++i)
+ buffer = stpcpy (grp->gr_mem[i] = buffer, tempgr->gr_mem[i]) + 1;
+ grp->gr_mem[i] = NULL;
return 0;
}
extern "C" struct group *
getgrnam32 (const char *name)
{
- struct group *tempgr = internal_getgrnam (name);
- pthread_testcancel ();
- return getgr_cp (tempgr);
+ return internal_getgrnam (name, true);
}
#ifdef __x86_64__
@@ -337,119 +280,21 @@ getgrnam (const char *name)
}
#endif
-/* getgrent functions are not reentrant. */
-static gr_ent grent;
-
-void *
-gr_ent::enumerate_caches ()
-{
- switch (max)
- {
- case 0:
- if (cygheap->pg.nss_cygserver_caching ())
- {
- pwdgrp &grc = cygheap->pg.grp_cache.cygserver;
- if (cnt < grc.cached_groups ())
- return &grc.group ()[cnt++].g;
- }
- cnt = 0;
- max = 1;
- /*FALLTHRU*/
- case 1:
- if (from_files)
- {
- pwdgrp &grf = cygheap->pg.grp_cache.file;
- grf.check_file ();
- if (cnt < grf.cached_groups ())
- return &grf.group ()[cnt++].g;
- }
- cnt = 0;
- max = 2;
- /*FALLTHRU*/
- case 2:
- if (from_db)
- {
- pwdgrp &grw = cygheap->pg.grp_cache.win;
- if (cnt < grw.cached_groups ())
- return &grw.group ()[cnt++].g;
- }
- break;
- }
- cnt = max = 0;
- return NULL;
-}
-
-void *
-gr_ent::enumerate_local ()
-{
- while (true)
- {
- if (!cnt)
- {
- DWORD total;
- NET_API_STATUS ret;
-
- if (buf)
- {
- NetApiBufferFree (buf);
- buf = NULL;
- }
- if (resume == ULONG_MAX)
- ret = ERROR_NO_MORE_ITEMS;
- else
- ret = NetLocalGroupEnum (NULL, 0, (PBYTE *) &buf,
- MAX_PREFERRED_LENGTH,
- &max, &total, &resume);
- if (ret == NERR_Success)
- resume = ULONG_MAX;
- else if (ret != ERROR_MORE_DATA)
- {
- cnt = max = resume = 0;
- return NULL;
- }
- }
- while (cnt < max)
- {
- cygsid sid;
- DWORD slen = SECURITY_MAX_SID_SIZE;
- WCHAR dom[DNLEN + 1];
- DWORD dlen = DNLEN + 1;
- SID_NAME_USE acc_type;
-
- LookupAccountNameW (NULL,
- ((PLOCALGROUP_INFO_0) buf)[cnt++].lgrpi0_name,
- sid, &slen, dom, &dlen, &acc_type);
- fetch_user_arg_t arg;
- arg.type = SID_arg;
- arg.sid = &sid;
- char *line = pg.fetch_account_from_windows (arg);
- if (line)
- return pg.add_account_post_fetch (line, false);
- }
- cnt = 0;
- }
-}
-
-struct group *
-gr_ent::getgrent (void)
-{
- if (state == rewound)
- setent (true);
- else
- clear_cache ();
- return (struct group *) getent ();
-}
-
extern "C" void
-setgrent ()
+endgrent ()
{
- grent.setgrent ();
+ _my_tls.locals.grp_pos = 0;
}
extern "C" struct group *
-getgrent32 (void)
+getgrent32 ()
{
- return grent.getgrent ();
+ if (_my_tls.locals.grp_pos == 0)
+ gr.refresh (true);
+ if (_my_tls.locals.grp_pos < gr.curr_lines)
+ return group_buf + _my_tls.locals.grp_pos++;
+
+ return NULL;
}
#ifdef __x86_64__
@@ -465,85 +310,90 @@ getgrent ()
#endif
extern "C" void
-endgrent (void)
-{
- grent.endgrent ();
-}
-
-/* *_filtered functions are called from mkgroup */
-void *
-setgrent_filtered (int enums, PCWSTR enum_tdoms)
+setgrent ()
{
- gr_ent *gr = new gr_ent;
- if (gr)
- gr->setgrent (enums, enum_tdoms);
- return (void *) gr;
+ _my_tls.locals.grp_pos = 0;
}
-void *
-getgrent_filtered (void *gr)
+/* Internal function. ONLY USE THIS INTERNALLY, NEVER `getgrent'!!! */
+struct group *
+internal_getgrent (int pos)
{
- return (void *) ((gr_ent *) gr)->getgrent ();
-}
+ gr.refresh (false);
-void
-endgrent_filtered (void *gr)
-{
- ((gr_ent *) gr)->endgrent ();
+ if (pos < gr.curr_lines)
+ return group_buf + pos;
+ return NULL;
}
int
-internal_getgroups (int gidsetsize, gid_t *grouplist, cyg_ldap *pldap)
+internal_getgroups (int gidsetsize, gid_t *grouplist, cygpsid * srchsid)
{
NTSTATUS status;
- HANDLE tok;
+ HANDLE hToken = NULL;
ULONG size;
int cnt = 0;
- struct group *grp;
+ struct group *gr;
- if (cygheap->user.groups.issetgroups ())
+ if (!srchsid && cygheap->user.groups.issetgroups ())
{
- for (int pg = 0; pg < cygheap->user.groups.sgsids.count (); ++pg)
- if ((grp = internal_getgrsid (cygheap->user.groups.sgsids.sids[pg],
- pldap)))
- {
- if (cnt < gidsetsize)
- grouplist[cnt] = grp->gr_gid;
- ++cnt;
- if (gidsetsize && cnt > gidsetsize)
- goto error;
- }
+ cygsid sid;
+ for (int gidx = 0; (gr = internal_getgrent (gidx)); ++gidx)
+ if (sid.getfromgr (gr))
+ for (int pg = 0; pg < cygheap->user.groups.sgsids.count (); ++pg)
+ if (sid == cygheap->user.groups.sgsids.sids[pg]
+ && sid != well_known_world_sid)
+ {
+ if (cnt < gidsetsize)
+ grouplist[cnt] = gr->gr_gid;
+ ++cnt;
+ if (gidsetsize && cnt > gidsetsize)
+ goto error;
+ break;
+ }
return cnt;
}
+
/* If impersonated, use impersonation token. */
- tok = cygheap->user.issetuid () ? cygheap->user.primary_token () : hProcToken;
+ if (cygheap->user.issetuid ())
+ hToken = cygheap->user.primary_token ();
+ else
+ hToken = hProcToken;
- status = NtQueryInformationToken (tok, TokenGroups, NULL, 0, &size);
+ status = NtQueryInformationToken (hToken, TokenGroups, NULL, 0, &size);
if (NT_SUCCESS (status) || status == STATUS_BUFFER_TOO_SMALL)
{
PTOKEN_GROUPS groups = (PTOKEN_GROUPS) alloca (size);
- status = NtQueryInformationToken (tok, TokenGroups, groups, size, &size);
+ status = NtQueryInformationToken (hToken, TokenGroups, groups,
+ size, &size);
if (NT_SUCCESS (status))
{
- for (DWORD pg = 0; pg < groups->GroupCount; ++pg)
+ cygsid sid;
+
+ if (srchsid)
{
- cygpsid sid = groups->Groups[pg].Sid;
- if ((grp = internal_getgrsid (sid, pldap)))
- {
- if ((groups->Groups[pg].Attributes
- & (SE_GROUP_ENABLED | SE_GROUP_INTEGRITY_ENABLED))
+ for (DWORD pg = 0; pg < groups->GroupCount; ++pg)
+ if ((cnt = (*srchsid == groups->Groups[pg].Sid)))
+ break;
+ }
+ else
+ for (int gidx = 0; (gr = internal_getgrent (gidx)); ++gidx)
+ if (sid.getfromgr (gr))
+ for (DWORD pg = 0; pg < groups->GroupCount; ++pg)
+ if (sid == groups->Groups[pg].Sid
+ && (groups->Groups[pg].Attributes
+ & (SE_GROUP_ENABLED | SE_GROUP_INTEGRITY_ENABLED))
&& sid != well_known_world_sid)
{
if (cnt < gidsetsize)
- grouplist[cnt] = grp->gr_gid;
+ grouplist[cnt] = gr->gr_gid;
++cnt;
if (gidsetsize && cnt > gidsetsize)
goto error;
+ break;
}
- }
- }
}
}
else
@@ -558,9 +408,7 @@ error:
extern "C" int
getgroups32 (int gidsetsize, gid_t *grouplist)
{
- cyg_ldap cldap;
-
- return internal_getgroups (gidsetsize, grouplist, &cldap);
+ return internal_getgroups (gidsetsize, grouplist);
}
#ifdef __x86_64__
@@ -579,7 +427,7 @@ getgroups (int gidsetsize, __gid16_t *grouplist)
if (gidsetsize > 0 && grouplist)
grouplist32 = (gid_t *) alloca (gidsetsize * sizeof (gid_t));
- int ret = getgroups32 (gidsetsize, grouplist32);
+ int ret = internal_getgroups (gidsetsize, grouplist32);
if (gidsetsize > 0 && grouplist)
for (int i = 0; i < ret; ++ i)
@@ -593,15 +441,13 @@ getgroups (int gidsetsize, __gid16_t *grouplist)
static void
get_groups (const char *user, gid_t gid, cygsidlist &gsids)
{
- cyg_ldap cldap;
-
cygheap->user.deimpersonate ();
- struct passwd *pw = internal_getpwnam (user, &cldap);
- struct group *grp = internal_getgrgid (gid, &cldap);
+ struct passwd *pw = internal_getpwnam (user);
+ struct group *gr = internal_getgrgid (gid);
cygsid usersid, grpsid;
if (usersid.getfrompw (pw))
get_server_groups (gsids, usersid, pw);
- if (gid != ILLEGAL_GID && grpsid.getfromgr (grp))
+ if (gid != ILLEGAL_GID && grpsid.getfromgr (gr))
gsids += grpsid;
cygheap->user.reimpersonate ();
}
@@ -636,8 +482,7 @@ getgrouplist (const char *user, gid_t gid, gid_t *groups, int *ngroups)
{
int ret = 0;
int cnt = 0;
- struct group *grp;
- cyg_ldap cldap;
+ struct group *gr;
/* Note that it's not defined if groups or ngroups may be NULL!
GLibc does not check the pointers on entry and just uses them.
@@ -650,10 +495,10 @@ getgrouplist (const char *user, gid_t gid, gid_t *groups, int *ngroups)
cygsidlist tmp_gsids (cygsidlist_auto, 12);
get_groups (user, gid, tmp_gsids);
for (int i = 0; i < tmp_gsids.count (); i++)
- if ((grp = internal_getgrsid (tmp_gsids.sids[i], &cldap)) != NULL)
+ if ((gr = internal_getgrsid (tmp_gsids.sids[i])) != NULL)
{
if (groups && cnt < *ngroups)
- groups[cnt] = grp->gr_gid;
+ groups[cnt] = gr->gr_gid;
++cnt;
}
if (cnt > *ngroups)
@@ -679,16 +524,15 @@ setgroups32 (int ngroups, const gid_t *grouplist)
}
cygsidlist gsids (cygsidlist_alloc, ngroups);
- struct group *grp;
- cyg_ldap cldap;
+ struct group *gr;
if (ngroups && !gsids.sids)
return -1;
for (int gidx = 0; gidx < ngroups; ++gidx)
{
- if ((grp = internal_getgrgid (grouplist[gidx], &cldap))
- && gsids.addfromgr (grp))
+ if ((gr = internal_getgrgid (grouplist[gidx]))
+ && gsids.addfromgr (gr))
continue;
debug_printf ("No sid found for gid %u", grouplist[gidx]);
gsids.free_sids ();
diff --git a/winsup/cygwin/import/rexec.c b/winsup/cygwin/import/rexec.c
deleted file mode 100644
index 4e01eb659..000000000
--- a/winsup/cygwin/import/rexec.c
+++ /dev/null
@@ -1,391 +0,0 @@
-/*
- * Copyright (c) 1980, 1993
- * The Regents of the University of California. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- * 1. Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- * 2. Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- * 4. Neither the name of the University nor the names of its contributors
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
- * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
- * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
- * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
- * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
- * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
- * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
- * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
- * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
- *
- * $FreeBSD$
- */
-
-#if defined(LIBC_SCCS) && !defined(lint)
-static char sccsid[] = "@(#)rexec.c 8.1 (Berkeley) 6/4/93";
-#endif /* LIBC_SCCS and not lint */
-
-#include <sys/types.h>
-#include <sys/uio.h>
-#include <sys/socket.h>
-#include <sys/param.h>
-#include <sys/stat.h>
-
-#include <netinet/in.h>
-
-#include <stdio.h>
-#include <unistd.h>
-#include <string.h>
-#include <netdb.h>
-#include <errno.h>
-#include <ctype.h>
-#include <err.h>
-#include <stdlib.h>
-#include <unistd.h>
-
-int rexecoptions;
-char *getpass(), *getlogin();
-
-/*
- * Options and other state info.
- */
-struct macel {
- char mac_name[9]; /* macro name */
- char *mac_start; /* start of macro in macbuf */
- char *mac_end; /* end of macro in macbuf */
-};
-
-int macnum; /* number of defined macros */
-struct macel macros[16];
-char macbuf[4096];
-
-static FILE *cfile;
-
-#define DEFAULT 1
-#define LOGIN 2
-#define PASSWD 3
-#define ACCOUNT 4
-#define MACDEF 5
-#define ID 10
-#define MACH 11
-
-static char tokval[100];
-
-static struct toktab {
- char *tokstr;
- int tval;
-} toktab[]= {
- { "default", DEFAULT },
- { "login", LOGIN },
- { "password", PASSWD },
- { "passwd", PASSWD },
- { "account", ACCOUNT },
- { "machine", MACH },
- { "macdef", MACDEF },
- { NULL, 0 }
-};
-
-static int
-token()
-{
- char *cp;
- int c;
- struct toktab *t;
-
- if (feof(cfile) || ferror(cfile))
- return (0);
- while ((c = getc(cfile)) != EOF &&
- (c == '\n' || c == '\t' || c == ' ' || c == ','))
- continue;
- if (c == EOF)
- return (0);
- cp = tokval;
- if (c == '"') {
- while ((c = getc(cfile)) != EOF && c != '"') {
- if (c == '\\')
- c = getc(cfile);
- *cp++ = c;
- }
- } else {
- *cp++ = c;
- while ((c = getc(cfile)) != EOF
- && c != '\n' && c != '\t' && c != ' ' && c != ',') {
- if (c == '\\')
- c = getc(cfile);
- *cp++ = c;
- }
- }
- *cp = 0;
- if (tokval[0] == 0)
- return (0);
- for (t = toktab; t->tokstr; t++)
- if (!strcmp(t->tokstr, tokval))
- return (t->tval);
- return (ID);
-}
-
-static int
-ruserpass(host, aname, apass, aacct)
- char *host, **aname, **apass, **aacct;
-{
- char *hdir, buf[BUFSIZ], *tmp;
- char myname[MAXHOSTNAMELEN], *mydomain;
- int t, i, c, usedefault = 0;
- struct stat stb;
-
- hdir = getenv("HOME");
- if (hdir == NULL)
- hdir = ".";
- if (strlen(hdir) + 8 > sizeof(buf))
- return (0);
- (void) sprintf(buf, "%s/.netrc", hdir);
- cfile = fopen(buf, "r");
- if (cfile == NULL) {
- if (errno != ENOENT)
- warn("%s", buf);
- return (0);
- }
- if (gethostname(myname, sizeof(myname)) < 0)
- myname[0] = '\0';
- if ((mydomain = strchr(myname, '.')) == NULL)
- mydomain = "";
-next:
- while ((t = token())) switch(t) {
-
- case DEFAULT:
- usedefault = 1;
- /* FALL THROUGH */
-
- case MACH:
- if (!usedefault) {
- if (token() != ID)
- continue;
- /*
- * Allow match either for user's input host name
- * or official hostname. Also allow match of
- * incompletely-specified host in local domain.
- */
- if (strcasecmp(host, tokval) == 0)
- goto match;
- if ((tmp = strchr(host, '.')) != NULL &&
- strcasecmp(tmp, mydomain) == 0 &&
- strncasecmp(host, tokval, tmp - host) == 0 &&
- tokval[tmp - host] == '\0')
- goto match;
- continue;
- }
- match:
- while ((t = token()) && t != MACH && t != DEFAULT) switch(t) {
-
- case LOGIN:
- if (token())
- if (*aname == 0) {
- *aname = malloc((unsigned) strlen(tokval) + 1);
- (void) strcpy(*aname, tokval);
- } else {
- if (strcmp(*aname, tokval))
- goto next;
- }
- break;
- case PASSWD:
- if ((*aname == 0 || strcmp(*aname, "anonymous")) &&
- fstat(fileno(cfile), &stb) >= 0 &&
- (stb.st_mode & 077) != 0) {
- warnx("Error: .netrc file is readable by others.");
- warnx("Remove password or make file unreadable by others.");
- goto bad;
- }
- if (token() && *apass == 0) {
- *apass = malloc((unsigned) strlen(tokval) + 1);
- (void) strcpy(*apass, tokval);
- }
- break;
- case ACCOUNT:
- if (fstat(fileno(cfile), &stb) >= 0
- && (stb.st_mode & 077) != 0) {
- warnx("Error: .netrc file is readable by others.");
- warnx("Remove account or make file unreadable by others.");
- goto bad;
- }
- if (token() && *aacct == 0) {
- *aacct = malloc((unsigned) strlen(tokval) + 1);
- (void) strcpy(*aacct, tokval);
- }
- break;
- case MACDEF:
- while ((c=getc(cfile)) != EOF &&
- (c == ' ' || c == '\t'))
- ;
- if (c == EOF || c == '\n') {
- printf("Missing macdef name argument.\n");
- goto bad;
- }
- if (macnum == 16) {
- printf("Limit of 16 macros have already been defined\n");
- goto bad;
- }
- tmp = macros[macnum].mac_name;
- *tmp++ = c;
- for (i=0; i < 8 && (c=getc(cfile)) != EOF &&
- !isspace(c); ++i) {
- *tmp++ = c;
- }
- if (c == EOF) {
- printf("Macro definition missing null line terminator.\n");
- goto bad;
- }
- *tmp = '\0';
- if (c != '\n') {
- while ((c=getc(cfile)) != EOF && c != '\n');
- }
- if (c == EOF) {
- printf("Macro definition missing null line terminator.\n");
- goto bad;
- }
- if (macnum == 0) {
- macros[macnum].mac_start = macbuf;
- }
- else {
- macros[macnum].mac_start = macros[macnum-1].mac_end + 1;
- }
- tmp = macros[macnum].mac_start;
- while (tmp != macbuf + 4096) {
- if ((c=getc(cfile)) == EOF) {
- printf("Macro definition missing null line terminator.\n");
- goto bad;
- }
- *tmp = c;
- if (*tmp == '\n') {
- if (*(tmp-1) == '\0') {
- macros[macnum++].mac_end = tmp - 1;
- break;
- }
- *tmp = '\0';
- }
- tmp++;
- }
- if (tmp == macbuf + 4096) {
- printf("4K macro buffer exceeded\n");
- goto bad;
- }
- break;
- default:
- warnx("Unknown .netrc keyword %s", tokval);
- break;
- }
- goto done;
- }
-done:
- (void) fclose(cfile);
- return (0);
-bad:
- (void) fclose(cfile);
- return (-1);
-}
-
-int
-rexec(ahost, rport, name, pass, cmd, fd2p)
- char **ahost;
- int rport;
- char *name, *pass, *cmd;
- int *fd2p;
-{
- struct sockaddr_in sin, sin2, from;
- struct hostent *hp;
- u_short port;
- int s, timo = 1, s3;
- char c, *acct;
-
- hp = gethostbyname(*ahost);
- if (hp == 0) {
- herror(*ahost);
- return (-1);
- }
- *ahost = hp->h_name;
- acct = NULL;
- ruserpass(hp->h_name, &name, &pass, &acct);
- free(acct);
-retry:
- s = socket(AF_INET, SOCK_STREAM, 0);
- if (s < 0) {
- perror("rexec: socket");
- return (-1);
- }
- sin.sin_family = hp->h_addrtype;
- sin.sin_port = rport;
- bcopy(hp->h_addr, (caddr_t)&sin.sin_addr, hp->h_length);
- if (connect(s, (struct sockaddr *)&sin, sizeof(sin)) < 0) {
- if (errno == ECONNREFUSED && timo <= 16) {
- (void) close(s);
- sleep(timo);
- timo *= 2;
- goto retry;
- }
- perror(hp->h_name);
- return (-1);
- }
- if (fd2p == 0) {
- (void) write(s, "", 1);
- port = 0;
- } else {
- char num[8];
- int s2, sin2len;
-
- s2 = socket(AF_INET, SOCK_STREAM, 0);
- if (s2 < 0) {
- (void) close(s);
- return (-1);
- }
- listen(s2, 1);
- sin2len = sizeof (sin2);
- if (getsockname(s2, (struct sockaddr *)&sin2, &sin2len) < 0 ||
- sin2len != sizeof (sin2)) {
- perror("getsockname");
- (void) close(s2);
- goto bad;
- }
- port = ntohs((u_short)sin2.sin_port);
- (void) sprintf(num, "%u", port);
- (void) write(s, num, strlen(num)+1);
- { int len = sizeof (from);
- s3 = accept(s2, (struct sockaddr *)&from, &len);
- close(s2);
- if (s3 < 0) {
- perror("accept");
- port = 0;
- goto bad;
- }
- }
- *fd2p = s3;
- }
- (void) write(s, name, strlen(name) + 1);
- /* should public key encypt the password here */
- (void) write(s, pass, strlen(pass) + 1);
- (void) write(s, cmd, strlen(cmd) + 1);
- if (read(s, &c, 1) != 1) {
- perror(*ahost);
- goto bad;
- }
- if (c != 0) {
- while (read(s, &c, 1) == 1) {
- (void) write(2, &c, 1);
- if (c == '\n')
- break;
- }
- goto bad;
- }
- return (s);
-bad:
- if (port)
- (void) close(*fd2p);
- (void) close(s);
- return (-1);
-}
diff --git a/winsup/cygwin/include/cygwin/version.h b/winsup/cygwin/include/cygwin/version.h
index 97a53cb30..4412161c8 100644
--- a/winsup/cygwin/include/cygwin/version.h
+++ b/winsup/cygwin/include/cygwin/version.h
@@ -446,15 +446,12 @@ details. */
as number of partitions on tape.
271: Export posix_spawn, posix_spawnp, and helper functions.
272: Export tm_gmtoff and tm_zone members.
- 273: Introduce account mapping from Windows account DBs. Add CW_SETENT,
- CW_GETENT, CW_ENDENT, CW_GETNSSSEP, CW_GETPWSID, CW_GETGRSID,
- CW_CYGNAME_FROM_WINNAME.
*/
/* Note that we forgot to bump the api for ualarm, strtoll, strtoull */
#define CYGWIN_VERSION_API_MAJOR 0
-#define CYGWIN_VERSION_API_MINOR 273
+#define CYGWIN_VERSION_API_MINOR 272
/* There is also a compatibity version number associated with the
shared memory regions. It is incremented when incompatible
diff --git a/winsup/cygwin/include/sys/cygwin.h b/winsup/cygwin/include/sys/cygwin.h
index 7e344ecab..24026cf57 100644
--- a/winsup/cygwin/include/sys/cygwin.h
+++ b/winsup/cygwin/include/sys/cygwin.h
@@ -149,8 +149,7 @@ typedef enum
CW_ENDENT,
CW_GETNSSSEP,
CW_GETPWSID,
- CW_GETGRSID,
- CW_CYGNAME_FROM_WINNAME
+ CW_GETGRSID
} cygwin_getinfo_types;
#define CW_LOCK_PINFO CW_LOCK_PINFO
@@ -207,27 +206,12 @@ typedef enum
#define CW_GETNSSSEP CW_GETNSSSEP
#define CW_GETPWSID CW_GETPWSID
#define CW_GETGRSID CW_GETGRSID
-#define CW_CYGNAME_FROM_WINNAME CW_CYGNAME_FROM_WINNAME
/* Token type for CW_SET_EXTERNAL_TOKEN */
enum
{
- CW_TOKEN_IMPERSONATION = 0,
- CW_TOKEN_RESTRICTED = 1
-};
-
-/* Enumeration source constants for CW_SETENT called from mkpasswd/mkgroup. */
-enum nss_enum_t
-{
- ENUM_NONE = 0x00,
- ENUM_CACHE = 0x01,
- ENUM_FILES = 0x02,
- ENUM_BUILTIN = 0x04,
- ENUM_LOCAL = 0x08,
- ENUM_PRIMARY = 0x10,
- ENUM_TDOMS = 0x20,
- ENUM_TDOMS_ALL = 0x40,
- ENUM_ALL = 0x7f
+CW_TOKEN_IMPERSONATION = 0,
+CW_TOKEN_RESTRICTED = 1
};
#define CW_NEXTPID 0x80000000 /* or with pid to get next one */
diff --git a/winsup/cygwin/ldap.cc b/winsup/cygwin/ldap.cc
deleted file mode 100644
index fa19c307e..000000000
--- a/winsup/cygwin/ldap.cc
+++ /dev/null
@@ -1,627 +0,0 @@
-/* ldap.cc: Helper functions for ldap access to Active Directory.
-
- Copyright 2014 Red Hat, Inc.
-
-This file is part of Cygwin.
-
-This software is a copyrighted work licensed under the terms of the
-Cygwin license. Please consult the file "CYGWIN_LICENSE" for
-details. */
-
-#include "winsup.h"
-#include "ldap.h"
-#include "cygerrno.h"
-#include "security.h"
-#include "path.h"
-#include "fhandler.h"
-#include "dtable.h"
-#include "cygheap.h"
-#include "registry.h"
-#include "pinfo.h"
-#include "lm.h"
-#include "dsgetdc.h"
-#include "tls_pbuf.h"
-
-#define CYG_LDAP_ENUM_PAGESIZE 100 /* entries per page */
-
-static PWCHAR rootdse_attr[] =
-{
- (PWCHAR) L"defaultNamingContext",
- (PWCHAR) L"supportedCapabilities",
- NULL
-};
-
-static PWCHAR user_attr[] =
-{
- (PWCHAR) L"primaryGroupID",
- (PWCHAR) L"gecos",
- (PWCHAR) L"unixHomeDirectory",
- (PWCHAR) L"loginShell",
- (PWCHAR) L"uidNumber",
- NULL
-};
-
-static PWCHAR group_attr[] =
-{
- (PWCHAR) L"cn",
- (PWCHAR) L"gidNumber",
- NULL
-};
-
-PWCHAR tdom_attr[] =
-{
- (PWCHAR) L"trustPosixOffset",
- NULL
-};
-
-PWCHAR sid_attr[] =
-{
- (PWCHAR) L"objectSid",
- NULL
-};
-
-PWCHAR rfc2307_uid_attr[] =
-{
- (PWCHAR) L"uid",
- NULL
-};
-
-PWCHAR rfc2307_gid_attr[] =
-{
- (PWCHAR) L"cn",
- NULL
-};
-
-/* ================================================================= */
-/* Helper methods. */
-/* ================================================================= */
-
-inline int
-cyg_ldap::map_ldaperr_to_errno (ULONG lerr)
-{
- switch (lerr)
- {
- case LDAP_SUCCESS:
- return NO_ERROR;
- case LDAP_NO_RESULTS_RETURNED:
- /* LdapMapErrorToWin32 maps LDAP_NO_RESULTS_RETURNED to ERROR_MORE_DATA,
- which in turn is mapped to EMSGSIZE by geterrno_from_win_error. This
- is SO wrong, especially considering that LDAP_MORE_RESULTS_TO_RETURN
- is mapped to ERROR_MORE_DATA as well :-P */
- return ENMFILE;
- default:
- break;
- }
- return geterrno_from_win_error (LdapMapErrorToWin32 (lerr));
-}
-
-inline int
-cyg_ldap::wait (cygthread *thr)
-{
- if (!thr)
- return EIO;
- if (cygwait (*thr, INFINITE, cw_sig | cw_sig_eintr) != WAIT_OBJECT_0)
- {
- thr->terminate_thread ();
- _my_tls.call_signal_handler ();
- return EINTR;
- }
- thr->detach ();
- return 0;
-}
-
-/* ================================================================= */
-/* Helper struct and functions for interruptible LDAP initalization. */
-/* ================================================================= */
-
-struct cyg_ldap_init {
- cyg_ldap *that;
- PCWSTR domain;
- bool ssl;
- ULONG ret;
-};
-
-ULONG
-cyg_ldap::connect_ssl (PCWSTR domain)
-{
- ULONG ret;
-
- if (!(lh = ldap_sslinitW ((PWCHAR) domain, LDAP_SSL_PORT, 1)))
- {
- debug_printf ("ldap_init(%W) error 0x%02x", domain, LdapGetLastError ());
- return LdapGetLastError ();
- }
- if ((ret = ldap_bind_s (lh, NULL, NULL, LDAP_AUTH_NEGOTIATE)) != LDAP_SUCCESS)
- debug_printf ("ldap_bind(%W) 0x%02x", domain, ret);
- else if ((ret = ldap_search_sW (lh, NULL, LDAP_SCOPE_BASE,
- (PWCHAR) L"(objectclass=*)", rootdse_attr,
- 0, &msg))
- != LDAP_SUCCESS)
- debug_printf ("ldap_search(%W, ROOTDSE) error 0x%02x", domain, ret);
- return ret;
-}
-
-ULONG
-cyg_ldap::connect_non_ssl (PCWSTR domain)
-{
- ULONG ret;
-
- if (!(lh = ldap_initW ((PWCHAR) domain, LDAP_PORT)))
- {
- debug_printf ("ldap_init(%W) error 0x%02x", domain, LdapGetLastError ());
- return LdapGetLastError ();
- }
- if ((ret = ldap_set_option (lh, LDAP_OPT_SIGN, LDAP_OPT_ON))
- != LDAP_SUCCESS)
- debug_printf ("ldap_set_option(LDAP_OPT_SIGN) error 0x%02x", ret);
- if ((ret = ldap_set_option (lh, LDAP_OPT_ENCRYPT, LDAP_OPT_ON))
- != LDAP_SUCCESS)
- debug_printf ("ldap_set_option(LDAP_OPT_ENCRYPT) error 0x%02x", ret);
- if ((ret = ldap_bind_s (lh, NULL, NULL, LDAP_AUTH_NEGOTIATE)) != LDAP_SUCCESS)
- debug_printf ("ldap_bind(%W) 0x%02x", domain, ret);
- else if ((ret = ldap_search_sW (lh, NULL, LDAP_SCOPE_BASE,
- (PWCHAR) L"(objectclass=*)", rootdse_attr,
- 0, &msg))
- != LDAP_SUCCESS)
- debug_printf ("ldap_search(%W, ROOTDSE) error 0x%02x", domain, ret);
- return ret;
-}
-
-static DWORD WINAPI
-ldap_init_thr (LPVOID param)
-{
- cyg_ldap_init *cl = (cyg_ldap_init *) param;
- cl->ret = cl->ssl ? cl->that->connect_ssl (cl->domain)
- : cl->that->connect_non_ssl (cl->domain);
- return 0;
-}
-
-inline int
-cyg_ldap::connect (PCWSTR domain)
-{
- /* FIXME? connect_ssl can take ages even when failing, so we're trying to
- do everything the non-SSL (but still encrypted) way. */
- cyg_ldap_init cl = { this, domain, false, NO_ERROR };
- cygthread *thr = new cygthread (ldap_init_thr, &cl, "ldap_init");
- return wait (thr) ?: map_ldaperr_to_errno (cl.ret);
-}
-
-/* ================================================================= */
-/* Helper struct and functions for interruptible LDAP search. */
-/* ================================================================= */
-
-struct cyg_ldap_search {
- cyg_ldap *that;
- PWCHAR base;
- PWCHAR filter;
- PWCHAR *attrs;
- ULONG ret;
-};
-
-ULONG
-cyg_ldap::search_s (PWCHAR base, PWCHAR filter, PWCHAR *attrs)
-{
- ULONG ret;
-
- if ((ret = ldap_search_sW (lh, base, LDAP_SCOPE_SUBTREE, filter,
- attrs, 0, &msg)) != LDAP_SUCCESS)
- debug_printf ("ldap_search_sW(%W,%W) error 0x%02x", base, filter, ret);
- return ret;
-}
-
-static DWORD WINAPI
-ldap_search_thr (LPVOID param)
-{
- cyg_ldap_search *cl = (cyg_ldap_search *) param;
- cl->ret = cl->that->search_s (cl->base, cl->filter, cl->attrs);
- return 0;
-}
-
-inline int
-cyg_ldap::search (PWCHAR base, PWCHAR filter, PWCHAR *attrs)
-{
- cyg_ldap_search cl = { this, base, filter, attrs, NO_ERROR };
- cygthread *thr = new cygthread (ldap_search_thr, &cl, "ldap_search");
- return wait (thr) ?: map_ldaperr_to_errno (cl.ret);
-}
-
-/* ================================================================= */
-/* Helper struct and functions for interruptible LDAP page search. */
-/* ================================================================= */
-
-struct cyg_ldap_next_page {
- cyg_ldap *that;
- ULONG ret;
-};
-
-ULONG
-cyg_ldap::next_page_s ()
-{
- ULONG total;
- ULONG ret;
-
- do
- {
- ret = ldap_get_next_page_s (lh, srch_id, NULL, CYG_LDAP_ENUM_PAGESIZE,
- &total, &srch_msg);
- }
- while (ret == LDAP_SUCCESS && ldap_count_entries (lh, srch_msg) == 0);
- if (ret && ret != LDAP_NO_RESULTS_RETURNED)
- debug_printf ("ldap_result() error 0x%02x", ret);
- return ret;
-}
-
-static DWORD WINAPI
-ldap_next_page_thr (LPVOID param)
-{
- cyg_ldap_next_page *cl = (cyg_ldap_next_page *) param;
- cl->ret = cl->that->next_page_s ();
- return 0;
-}
-
-inline int
-cyg_ldap::next_page ()
-{
- cyg_ldap_next_page cl = { this, NO_ERROR };
- cygthread *thr = new cygthread (ldap_next_page_thr, &cl, "ldap_next_page");
- return wait (thr) ?: map_ldaperr_to_errno (cl.ret);
-}
-
-/* ================================================================= */
-/* Public methods. */
-/* ================================================================= */
-
-int
-cyg_ldap::open (PCWSTR domain)
-{
- int ret = 0;
-
- /* Already open? */
- if (lh)
- return 0;
-
- if ((ret = connect (domain)) != NO_ERROR)
- goto err;
- /* Prime `ret' and fetch ROOTDSE search result. */
- ret = EIO;
- if (!(entry = ldap_first_entry (lh, msg)))
- {
- debug_printf ("No ROOTDSE entry for %W", domain);
- goto err;
- }
- if (!(val = ldap_get_valuesW (lh, entry, rootdse_attr[0])))
- {
- debug_printf ("No ROOTDSE value for %W", domain);
- goto err;
- }
- if (!(rootdse = wcsdup (val[0])))
- {
- debug_printf ("wcsdup(%W, ROOTDSE) %d", domain, get_errno ());
- goto err;
- }
- ldap_value_freeW (val);
- if ((val = ldap_get_valuesW (lh, entry, rootdse_attr[1])))
- {
- for (ULONG idx = 0; idx < ldap_count_valuesW (val); ++idx)
- if (!wcscmp (val[idx], LDAP_CAP_ACTIVE_DIRECTORY_OID_W))
- {
- isAD = true;
- break;
- }
- }
- ldap_value_freeW (val);
- val = NULL;
- ldap_msgfree (msg);
- msg = entry = NULL;
- return 0;
-err:
- close ();
- return ret;
-}
-
-void
-cyg_ldap::close ()
-{
- if (srch_id != NULL)
- ldap_search_abandon_page (lh, srch_id);
- if (lh)
- ldap_unbind (lh);
- if (srch_msg)
- ldap_msgfree (srch_msg);
- if (msg)
- ldap_msgfree (msg);
- if (val)
- ldap_value_freeW (val);
- if (rootdse)
- free (rootdse);
- lh = NULL;
- msg = entry = NULL;
- val = NULL;
- rootdse = NULL;
- srch_id = NULL;
- srch_msg = srch_entry = NULL;
-}
-
-bool
-cyg_ldap::fetch_ad_account (PSID sid, bool group, PCWSTR domain)
-{
- WCHAR filter[140], *f, *rdse = rootdse;
- LONG len = (LONG) RtlLengthSid (sid);
- PBYTE s = (PBYTE) sid;
- static WCHAR hex_wchars[] = L"0123456789abcdef";
- tmp_pathbuf tp;
-
- if (msg)
- {
- ldap_msgfree (msg);
- msg = entry = NULL;
- }
- if (val)
- {
- ldap_value_freeW (val);
- val = NULL;
- }
- f = wcpcpy (filter, L"(objectSid=");
- while (len-- > 0)
- {
- *f++ = L'\\';
- *f++ = hex_wchars[*s >> 4];
- *f++ = hex_wchars[*s++ & 0xf];
- }
- wcpcpy (f, L")");
- if (domain)
- {
- /* FIXME: This is a hack. The most correct solution is probably to
- open a connection to the DC of the trusted domain. But this always
- takes extra time, so we're trying to avoid it. If this results in
- problems, we know what to do. */
- rdse = tp.w_get ();
- PWCHAR r = rdse;
- for (PWCHAR dotp = (PWCHAR) domain; dotp && *dotp; domain = dotp)
- {
- dotp = wcschr (domain, L'.');
- if (dotp)
- *dotp++ = L'\0';
- if (r > rdse)
- *r++ = L',';
- r = wcpcpy (r, L"DC=");
- r = wcpcpy (r, domain);
- }
- }
- attr = group ? group_attr : user_attr;
- if (search (rdse, filter, attr) != 0)
- return false;
- if (!(entry = ldap_first_entry (lh, msg)))
- {
- debug_printf ("No entry for %W in rootdse %W", filter, rdse);
- return false;
- }
- return true;
-}
-
-int
-cyg_ldap::enumerate_ad_accounts (PCWSTR domain, bool group)
-{
- int ret;
- tmp_pathbuf tp;
- PCWSTR filter;
-
- close ();
- if ((ret = open (domain)) != NO_ERROR)
- return ret;
-
- if (!group)
- filter = L"(&(objectClass=User)"
- "(objectCategory=Person)"
- /* 512 == ADS_UF_NORMAL_ACCOUNT */
- "(userAccountControl:" LDAP_MATCHING_RULE_BIT_AND ":=512)"
- "(objectSid=*))";
- else if (!domain)
- filter = L"(&(objectClass=Group)"
- "(objectSid=*))";
- else
- filter = L"(&(objectClass=Group)"
- /* 1 == ACCOUNT_GROUP */
- "(!(groupType:" LDAP_MATCHING_RULE_BIT_AND ":=1))"
- "(objectSid=*))";
- srch_id = ldap_search_init_pageW (lh, rootdse, LDAP_SCOPE_SUBTREE,
- (PWCHAR) filter, sid_attr, 0, NULL, NULL,
- INFINITE, CYG_LDAP_ENUM_PAGESIZE, NULL);
- if (srch_id == NULL)
- {
- debug_printf ("ldap_search_init_pageW(%W,%W) error 0x%02x",
- rootdse, filter, LdapGetLastError ());
- return map_ldaperr_to_errno (LdapGetLastError ());
- }
- return NO_ERROR;
-}
-
-int
-cyg_ldap::next_account (cygsid &sid)
-{
- ULONG ret;
- PLDAP_BERVAL *bval;
-
- if (srch_entry)
- {
- if ((srch_entry = ldap_next_entry (lh, srch_entry))
- && (bval = ldap_get_values_lenW (lh, srch_entry, sid_attr[0])))
- {
- sid = (PSID) bval[0]->bv_val;
- ldap_value_free_len (bval);
- return NO_ERROR;
- }
- ldap_msgfree (srch_msg);
- srch_msg = srch_entry = NULL;
- }
- ret = next_page ();
- if (ret == NO_ERROR)
- {
- if ((srch_entry = ldap_first_entry (lh, srch_msg))
- && (bval = ldap_get_values_lenW (lh, srch_entry, sid_attr[0])))
- {
- sid = (PSID) bval[0]->bv_val;
- ldap_value_free_len (bval);
- return NO_ERROR;
- }
- ret = EIO;
- }
- ldap_search_abandon_page (lh, srch_id);
- srch_id = NULL;
- return ret;
-}
-
-uint32_t
-cyg_ldap::fetch_posix_offset_for_domain (PCWSTR domain)
-{
- WCHAR filter[300];
-
- if (msg)
- {
- ldap_msgfree (msg);
- msg = entry = NULL;
- }
- if (val)
- {
- ldap_value_freeW (val);
- val = NULL;
- }
- /* If domain name has no dot, it's a Netbios name. In that case, filter
- by flatName rather than by name. */
- __small_swprintf (filter, L"(&(objectClass=trustedDomain)(%W=%W))",
- wcschr (domain, L'.') ? L"name" : L"flatName", domain);
- if (search (rootdse, filter, attr = tdom_attr) != 0)
- return 0;
- if (!(entry = ldap_first_entry (lh, msg)))
- {
- debug_printf ("No entry for %W in rootdse %W", filter, rootdse);
- return 0;
- }
- return get_num_attribute (0);
-}
-
-PWCHAR
-cyg_ldap::get_string_attribute (int idx)
-{
- if (val)
- ldap_value_freeW (val);
- val = ldap_get_valuesW (lh, entry, attr[idx]);
- if (val)
- return val[0];
- return NULL;
-}
-
-uint32_t
-cyg_ldap::get_num_attribute (int idx)
-{
- PWCHAR ret = get_string_attribute (idx);
- if (ret)
- return (uint32_t) wcstoul (ret, NULL, 10);
- return (uint32_t) -1;
-}
-
-bool
-cyg_ldap::fetch_unix_sid_from_ad (uint32_t id, cygsid &sid, bool group)
-{
- WCHAR filter[48];
- PLDAP_BERVAL *bval;
-
- if (msg)
- {
- ldap_msgfree (msg);
- msg = entry = NULL;
- }
- if (group)
- __small_swprintf (filter, L"(&(objectClass=Group)(gidNumber=%u))", id);
- else
- __small_swprintf (filter, L"(&(objectClass=User)(uidNumber=%u))", id);
- if (search (rootdse, filter, sid_attr) != 0)
- return false;
- if ((entry = ldap_first_entry (lh, msg))
- && (bval = ldap_get_values_lenW (lh, entry, sid_attr[0])))
- {
- sid = (PSID) bval[0]->bv_val;
- ldap_value_free_len (bval);
- return true;
- }
- return false;
-}
-
-PWCHAR
-cyg_ldap::fetch_unix_name_from_rfc2307 (uint32_t id, bool group)
-{
- WCHAR filter[52];
-
- if (msg)
- {
- ldap_msgfree (msg);
- msg = entry = NULL;
- }
- if (val)
- {
- ldap_value_freeW (val);
- val = NULL;
- }
- attr = group ? rfc2307_gid_attr : rfc2307_uid_attr;
- if (group)
- __small_swprintf (filter, L"(&(objectClass=posixGroup)(gidNumber=%u))", id);
- else
- __small_swprintf (filter, L"(&(objectClass=posixAccount)(uidNumber=%u))",
- id);
- if (search (rootdse, filter, attr) != 0)
- return NULL;
- if (!(entry = ldap_first_entry (lh, msg)))
- {
- debug_printf ("No entry for %W in rootdse %W", filter, rootdse);
- return NULL;
- }
- return get_string_attribute (0);
-}
-
-uid_t
-cyg_ldap::remap_uid (uid_t uid)
-{
- cygsid user (NO_SID);
- PWCHAR name;
- struct passwd *pw;
-
- if (isAD)
- {
- if (fetch_unix_sid_from_ad (uid, user, false)
- && user != NO_SID
- && (pw = internal_getpwsid (user, this)))
- return pw->pw_uid;
- }
- else if ((name = fetch_unix_name_from_rfc2307 (uid, false)))
- {
- char *mbname = NULL;
- sys_wcstombs_alloc (&mbname, HEAP_NOTHEAP, name);
- if ((pw = internal_getpwnam (mbname)))
- return pw->pw_uid;
- }
- return ILLEGAL_UID;
-}
-
-gid_t
-cyg_ldap::remap_gid (gid_t gid)
-{
- cygsid group (NO_SID);
- PWCHAR name;
- struct group *gr;
-
- if (isAD)
- {
- if (fetch_unix_sid_from_ad (gid, group, true)
- && group != NO_SID
- && (gr = internal_getgrsid (group, this)))
- return gr->gr_gid;
- }
- else if ((name = fetch_unix_name_from_rfc2307 (gid, true)))
- {
- char *mbname = NULL;
- sys_wcstombs_alloc (&mbname, HEAP_NOTHEAP, name);
- if ((gr = internal_getgrnam (mbname)))
- return gr->gr_gid;
- }
- return ILLEGAL_GID;
-}
diff --git a/winsup/cygwin/ldap.h b/winsup/cygwin/ldap.h
deleted file mode 100644
index 7f90a3821..000000000
--- a/winsup/cygwin/ldap.h
+++ /dev/null
@@ -1,80 +0,0 @@
-/* ldap.h.
-
- Copyright 2014 Red Hat, Inc.
-
-This file is part of Cygwin.
-
-This software is a copyrighted work licensed under the terms of the
-Cygwin license. Please consult the file "CYGWIN_LICENSE" for
-details. */
-
-#pragma once
-
-#pragma push_macro ("DECLSPEC_IMPORT")
-#undef DECLSPEC_IMPORT
-#define DECLSPEC_IMPORT
-#include <winldap.h>
-#include <ntldap.h>
-#pragma pop_macro ("DECLSPEC_IMPORT")
-
-#define LDAP_USER_PGRP_ATTR 0
-#define LDAP_USER_GECOS_ATTR 1
-#define LDAP_USER_HOME_ATTR 2
-#define LDAP_USER_SHELL_ATTR 3
-#define LDAP_USER_UID_ATTR 4
-
-#define LDAP_GROUP_NAME_ATTR 0
-#define LDAP_GROUP_GID_ATTR 1
-
-class cyg_ldap {
- PLDAP lh;
- PWCHAR rootdse;
- PLDAPMessage msg, entry;
- PWCHAR *val;
- PWCHAR *attr;
- bool isAD;
- PLDAPSearch srch_id;
- PLDAPMessage srch_msg, srch_entry;
-
- inline int map_ldaperr_to_errno (ULONG lerr);
- inline int wait (cygthread *thr);
- inline int connect (PCWSTR domain);
- inline int search (PWCHAR base, PWCHAR filter, PWCHAR *attrs);
- inline int next_page ();
- bool fetch_unix_sid_from_ad (uint32_t id, cygsid &sid, bool group);
- PWCHAR fetch_unix_name_from_rfc2307 (uint32_t id, bool group);
- PWCHAR get_string_attribute (int idx);
- uint32_t get_num_attribute (int idx);
-
-public:
- cyg_ldap () : lh (NULL), rootdse (NULL), msg (NULL), entry (NULL), val (NULL),
- isAD (false), srch_id (NULL), srch_msg (NULL), srch_entry (NULL)
- {}
- ~cyg_ldap () { close (); }
-
- ULONG connect_ssl (PCWSTR domain);
- ULONG connect_non_ssl (PCWSTR domain);
- ULONG search_s (PWCHAR base, PWCHAR filter, PWCHAR *attrs);
- ULONG next_page_s ();
-
- operator PLDAP () const { return lh; }
- int open (PCWSTR in_domain);
- void close ();
- bool fetch_ad_account (PSID sid, bool group, PCWSTR domain = NULL);
- int enumerate_ad_accounts (PCWSTR domain, bool group);
- int next_account (cygsid &sid);
- uint32_t fetch_posix_offset_for_domain (PCWSTR domain);
- uid_t remap_uid (uid_t uid);
- gid_t remap_gid (gid_t gid);
- /* User only */
- gid_t get_primary_gid () { return get_num_attribute (LDAP_USER_PGRP_ATTR); }
- PWCHAR get_gecos () { return get_string_attribute (LDAP_USER_GECOS_ATTR); }
- PWCHAR get_home ()
- { return get_string_attribute (LDAP_USER_HOME_ATTR); }
- PWCHAR get_shell () { return get_string_attribute (LDAP_USER_SHELL_ATTR); }
- gid_t get_unix_uid () { return get_num_attribute (LDAP_USER_UID_ATTR); }
- /* group only */
- PWCHAR get_group_name ()
- { return get_string_attribute (LDAP_GROUP_NAME_ATTR); }
- gid_t get_unix_gid () { return get_num_attribute (LDAP_GROUP_GID_ATTR); }
-};
diff --git a/winsup/cygwin/miscfuncs.cc b/winsup/cygwin/miscfuncs.cc
index 7397bea47..0a3651cb1 100644
--- a/winsup/cygwin/miscfuncs.cc
+++ b/winsup/cygwin/miscfuncs.cc
@@ -384,82 +384,6 @@ WritePipeOverlapped (HANDLE h, LPCVOID buf, DWORD len, LPDWORD ret_len,
return ret;
}
-bool
-NT_readline::init (POBJECT_ATTRIBUTES attr, PCHAR in_buf, ULONG in_buflen)
-{
- NTSTATUS status;
- IO_STATUS_BLOCK io;
-
- status = NtOpenFile (&fh, SYNCHRONIZE | FILE_READ_DATA, attr, &io,
- FILE_SHARE_VALID_FLAGS,
- FILE_SYNCHRONOUS_IO_NONALERT
- | FILE_OPEN_FOR_BACKUP_INTENT);
- if (!NT_SUCCESS (status))
- {
- paranoid_printf ("NtOpenFile(%S) failed, status %y",
- attr->ObjectName, status);
- return false;
- }
- buf = in_buf;
- buflen = in_buflen;
- got = end = buf;
- len = 0;
- line = 1;
- return true;
-}
-
-PCHAR
-NT_readline::gets ()
-{
- IO_STATUS_BLOCK io;
-
- while (true)
- {
- /* len == 0 indicates we have to read from the file. */
- if (!len)
- {
- if (!NT_SUCCESS (NtReadFile (fh, NULL, NULL, NULL, &io, got,
- (buflen - 2) - (got - buf), NULL, NULL)))
- return NULL;
- len = io.Information;
- /* Set end marker. */
- got[len] = got[len + 1] = '\0';
- /* Set len to the absolute len of bytes in buf. */
- len += got - buf;
- /* Reset got to start reading at the start of the buffer again. */
- got = end = buf;
- }
- else
- {
- got = end + 1;
- ++line;
- }
- /* Still some valid full line? */
- if (got < buf + len)
- {
- if ((end = strchr (got, '\n')))
- {
- end[end[-1] == '\r' ? -1 : 0] = '\0';
- return got;
- }
- /* Last line missing a \n at EOF? */
- if (len < buflen - 2)
- {
- len = 0;
- return got;
- }
- }
- /* We have to read once more. Move remaining bytes to the start of
- the buffer and reposition got so that it points to the end of
- the remaining bytes. */
- len = buf + len - got;
- memmove (buf, got, len);
- got = buf + len;
- buf[len] = buf[len + 1] = '\0';
- len = 0;
- }
-}
-
/* backslashify: Convert all forward slashes in src path to back slashes
in dst path. Add a trailing slash to dst when trailing_slash_p arg
is set to 1. */
diff --git a/winsup/cygwin/miscfuncs.h b/winsup/cygwin/miscfuncs.h
index e42940c1a..bc36a1987 100644
--- a/winsup/cygwin/miscfuncs.h
+++ b/winsup/cygwin/miscfuncs.h
@@ -1,7 +1,7 @@
/* miscfuncs.h: main Cygwin header file.
Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006,
- 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014 Red Hat, Inc.
+ 2007, 2008, 2009, 2010, 2011, 2012, 2013 Red Hat, Inc.
This file is part of Cygwin.
@@ -23,25 +23,6 @@ BOOL WINAPI ReadPipeOverlapped (HANDLE h, PVOID buf, DWORD len,
BOOL WINAPI WritePipeOverlapped (HANDLE h, LPCVOID buf, DWORD len,
LPDWORD ret_len, DWORD timeout);
-/* class for per-line reading using native functions. The caller provides
- the file as an POBJECT_ATTRIBUTES, and the buffer space. */
-class NT_readline
-{
- HANDLE fh;
- PCHAR buf;
- PCHAR got;
- PCHAR end;
- ULONG buflen;
- ULONG len;
- ULONG line;
-public:
- NT_readline () : fh (NULL) {}
- bool init (POBJECT_ATTRIBUTES attr, char *buf, ULONG buflen);
- PCHAR gets ();
- void close () { if (fh) NtClose (fh); fh = NULL; }
- ~NT_readline () { close (); }
-};
-
extern "C" void yield ();
#define import_address(x) __import_address ((void *)(x))
diff --git a/winsup/cygwin/mount.cc b/winsup/cygwin/mount.cc
index eecd72692..43f462686 100644
--- a/winsup/cygwin/mount.cc
+++ b/winsup/cygwin/mount.cc
@@ -1177,9 +1177,10 @@ mount_info::from_fstab (bool user, WCHAR fstab[], PWCHAR fstab_end)
{
UNICODE_STRING upath;
OBJECT_ATTRIBUTES attr;
- NT_readline rl;
+ IO_STATUS_BLOCK io;
+ NTSTATUS status;
+ HANDLE fh;
tmp_pathbuf tp;
- char *buf = tp.c_get ();
if (user)
{
@@ -1194,10 +1195,81 @@ mount_info::from_fstab (bool user, WCHAR fstab[], PWCHAR fstab_end)
RtlInitUnicodeString (&upath, fstab);
InitializeObjectAttributes (&attr, &upath, OBJ_CASE_INSENSITIVE, NULL, NULL);
debug_printf ("Try to read mounts from %W", fstab);
- if (rl.init (&attr, buf, NT_MAX_PATH))
- while ((buf = rl.gets ()))
- if (!from_fstab_line (buf, user))
+ status = NtOpenFile (&fh, SYNCHRONIZE | FILE_READ_DATA, &attr, &io,
+ FILE_SHARE_VALID_FLAGS,
+ FILE_SYNCHRONOUS_IO_NONALERT
+ | FILE_OPEN_FOR_BACKUP_INTENT);
+ if (!NT_SUCCESS (status))
+ {
+ debug_printf ("NtOpenFile(%S) failed, %y", &upath, status);
+ return false;
+ }
+
+ char *buf = tp.c_get ();
+ char *got = buf;
+ DWORD len = 0;
+ unsigned line = 1;
+ /* Using buffer size - 2 leaves space to append two \0. */
+ while (NT_SUCCESS (NtReadFile (fh, NULL, NULL, NULL, &io, got,
+ (NT_MAX_PATH - 2) - (got - buf), NULL, NULL)))
+ {
+ char *end;
+
+ len = io.Information;
+ /* Set end marker. */
+ got[len] = got[len + 1] = '\0';
+ /* Set len to the absolute len of bytes in buf. */
+ len += got - buf;
+ /* Reset got to start reading at the start of the buffer again. */
+ got = buf;
+retry:
+ bool got_nl = false;
+ while (got < buf + len && (end = strchr (got, '\n')))
+ {
+ got_nl = true;
+ end[end[-1] == '\r' ? -1 : 0] = '\0';
+ if (!from_fstab_line (got, user))
+ goto done;
+ got = end + 1;
+ ++line;
+ }
+ if (len < (NT_MAX_PATH - 2))
break;
+ /* Check if the buffer contained at least one \n. If not, the
+ line length is > 32K. We don't take such long lines. Print
+ a debug message and skip this line entirely. */
+ if (!got_nl)
+ {
+ system_printf ("%W: Line %d too long, skipping...", fstab, line);
+ while (NT_SUCCESS (NtReadFile (fh, NULL, NULL, NULL, &io, buf,
+ (NT_MAX_PATH - 2), NULL, NULL)))
+ {
+ len = io.Information;
+ buf[len] = buf[len + 1] = '\0';
+ got = strchr (buf, '\n');
+ if (got)
+ {
+ ++got;
+ ++line;
+ goto retry;
+ }
+ }
+ got = buf;
+ break;
+ }
+ /* We have to read once more. Move remaining bytes to the start of
+ the buffer and reposition got so that it points to the end of
+ the remaining bytes. */
+ len = buf + len - got;
+ memmove (buf, got, len);
+ got = buf + len;
+ buf[len] = buf[len + 1] = '\0';
+ }
+ /* Catch a last line without trailing \n. */
+ if (got > buf)
+ from_fstab_line (got, user);
+done:
+ NtClose (fh);
return true;
}
diff --git a/winsup/cygwin/passwd.cc b/winsup/cygwin/passwd.cc
index b8ed09466..88690e379 100644
--- a/winsup/cygwin/passwd.cc
+++ b/winsup/cygwin/passwd.cc
@@ -10,7 +10,6 @@ Cygwin license. Please consult the file "CYGWIN_LICENSE" for
details. */
#include "winsup.h"
-#include <lm.h>
#include <stdlib.h>
#include <stdio.h>
#include "cygerrno.h"
@@ -20,210 +19,127 @@ details. */
#include "dtable.h"
#include "pinfo.h"
#include "cygheap.h"
+#include "pwdgrp.h"
#include "shared_info.h"
-#include "miscfuncs.h"
-#include "ldap.h"
-#include "tls_pbuf.h"
+
+/* Read /etc/passwd only once for better performance. This is done
+ on the first call that needs information from it. */
+
+passwd *passwd_buf;
+static pwdgrp pr (passwd_buf);
/* Parse /etc/passwd line into passwd structure. */
bool
pwdgrp::parse_passwd ()
{
- pg_pwd &res = passwd ()[curr_lines];
- res.p.pw_name = next_str (':');
- res.p.pw_passwd = next_str (':');
- if (!next_num (res.p.pw_uid))
+ passwd &res = (*passwd_buf)[curr_lines];
+ res.pw_name = next_str (':');
+ res.pw_passwd = next_str (':');
+ if (!next_num (res.pw_uid))
return false;
- if (!next_num (res.p.pw_gid))
+ if (!next_num (res.pw_gid))
return false;
- res.p.pw_comment = NULL;
- res.p.pw_gecos = next_str (':');
- res.p.pw_dir = next_str (':');
- res.p.pw_shell = next_str (':');
- res.sid.getfrompw (&res.p);
- /* lptr points to the \0 after pw_shell. Increment by one to get the correct
- required buffer len in getpw_cp. */
- res.len = lptr - res.p.pw_name + 1;
+ res.pw_comment = NULL;
+ res.pw_gecos = next_str (':');
+ res.pw_dir = next_str (':');
+ res.pw_shell = next_str (':');
return true;
}
+/* Read in /etc/passwd and save contents in the password cache.
+ This sets pr to loaded or emulated so functions in this file can
+ tell that /etc/passwd has been read in or will be emulated. */
void
-pwdgrp::init_pwd ()
-{
- pwdgrp_buf_elem_size = sizeof (pg_pwd);
- parse = &pwdgrp::parse_passwd;
+pwdgrp::read_passwd ()
+{
+ load (L"\\etc\\passwd");
+
+ char strbuf[128] = "";
+ bool searchentry = true;
+ struct passwd *pw;
+ /* must be static */
+ static char NO_COPY pretty_ls[] = "????????:*:-1:-1:::";
+
+ add_line (pretty_ls);
+ cygsid tu = cygheap->user.sid ();
+ tu.string (strbuf);
+ if (!user_shared->cb || myself->uid == ILLEGAL_UID)
+ searchentry = !internal_getpwsid (tu);
+ if (searchentry
+ && (!(pw = internal_getpwnam (cygheap->user.name ()))
+ || !user_shared->cb
+ || (myself->uid != ILLEGAL_UID
+ && myself->uid != pw->pw_uid
+ && !internal_getpwuid (myself->uid))))
+ {
+ static char linebuf[1024]; // must be static and
+ // should not be NO_COPY
+ snprintf (linebuf, sizeof (linebuf), "%s:*:%u:%u:,%s:%s:/bin/sh",
+ cygheap->user.name (),
+ (!user_shared->cb || myself->uid == ILLEGAL_UID)
+ ? UNKNOWN_UID : myself->uid,
+ !user_shared->cb ? UNKNOWN_GID : myself->gid,
+ strbuf, getenv ("HOME") ?: "");
+ debug_printf ("Completing /etc/passwd: %s", linebuf);
+ add_line (linebuf);
+ }
}
struct passwd *
-pwdgrp::find_user (cygpsid &sid)
+internal_getpwsid (cygpsid &sid)
{
- for (ULONG i = 0; i < curr_lines; i++)
- if (sid == passwd ()[i].sid)
- return &passwd ()[i].p;
- return NULL;
-}
+ struct passwd *pw;
+ char *ptr1, *ptr2, *endptr;
+ char sid_string[128] = {0,','};
-struct passwd *
-pwdgrp::find_user (const char *name)
-{
- for (ULONG i = 0; i < curr_lines; i++)
- /* on Windows NT user names are case-insensitive */
- if (strcasematch (name, passwd ()[i].p.pw_name))
- return &passwd ()[i].p;
- return NULL;
-}
+ pr.refresh (false);
-struct passwd *
-pwdgrp::find_user (uid_t uid)
-{
- for (ULONG i = 0; i < curr_lines; i++)
- if (uid == passwd ()[i].p.pw_uid)
- return &passwd ()[i].p;
- return NULL;
-}
-
-struct passwd *
-internal_getpwsid (cygpsid &sid, cyg_ldap *pldap)
-{
- struct passwd *ret;
-
- cygheap->pg.nss_init ();
- /* Check caches first. */
- if (cygheap->pg.nss_cygserver_caching ()
- && (ret = cygheap->pg.pwd_cache.cygserver.find_user (sid)))
- return ret;
- if (cygheap->pg.nss_pwd_files ()
- && (ret = cygheap->pg.pwd_cache.file.find_user (sid)))
- return ret;
- if (cygheap->pg.nss_pwd_db ()
- && (ret = cygheap->pg.pwd_cache.win.find_user (sid)))
- return ret;
- /* Ask sources afterwards. */
- if (cygheap->pg.nss_cygserver_caching ()
- && (ret = cygheap->pg.pwd_cache.cygserver.add_user_from_cygserver (sid)))
- return ret;
- if (cygheap->pg.nss_pwd_files ())
+ if (sid.string (sid_string + 2))
{
- cygheap->pg.pwd_cache.file.check_file ();
- if ((ret = cygheap->pg.pwd_cache.file.add_user_from_file (sid)))
- return ret;
+ endptr = strchr (sid_string + 2, 0) - 1;
+ for (int i = 0; i < pr.curr_lines; i++)
+ {
+ pw = passwd_buf + i;
+ if (pw->pw_dir > pw->pw_gecos + 8)
+ for (ptr1 = endptr, ptr2 = pw->pw_dir - 2;
+ *ptr1 == *ptr2; ptr2--)
+ if (!*--ptr1)
+ return pw;
+ }
}
- if (cygheap->pg.nss_pwd_db ())
- return cygheap->pg.pwd_cache.win.add_user_from_windows (sid, pldap);
return NULL;
}
-/* This function gets only called from mkpasswd via cygwin_internal. */
struct passwd *
-internal_getpwsid_from_db (cygpsid &sid)
+internal_getpwuid (uid_t uid, bool check)
{
- cygheap->pg.nss_init ();
- return cygheap->pg.pwd_cache.win.add_user_from_windows (sid);
-}
+ pr.refresh (check);
-struct passwd *
-internal_getpwnam (const char *name, cyg_ldap *pldap)
-{
- struct passwd *ret;
-
- cygheap->pg.nss_init ();
- /* Check caches first. */
- if (cygheap->pg.nss_cygserver_caching ()
- && (ret = cygheap->pg.pwd_cache.cygserver.find_user (name)))
- return ret;
- if (cygheap->pg.nss_pwd_files ()
- && (ret = cygheap->pg.pwd_cache.file.find_user (name)))
- return ret;
- if (cygheap->pg.nss_pwd_db ()
- && (ret = cygheap->pg.pwd_cache.win.find_user (name)))
- return ret;
- /* Ask sources afterwards. */
- if (cygheap->pg.nss_cygserver_caching ()
- && (ret = cygheap->pg.pwd_cache.cygserver.add_user_from_cygserver (name)))
- return ret;
- if (cygheap->pg.nss_pwd_files ())
- {
- cygheap->pg.pwd_cache.file.check_file ();
- if ((ret = cygheap->pg.pwd_cache.file.add_user_from_file (name)))
- return ret;
- }
- if (cygheap->pg.nss_pwd_db ())
- return cygheap->pg.pwd_cache.win.add_user_from_windows (name, pldap);
+ for (int i = 0; i < pr.curr_lines; i++)
+ if (uid == passwd_buf[i].pw_uid)
+ return passwd_buf + i;
return NULL;
}
struct passwd *
-internal_getpwuid (uid_t uid, cyg_ldap *pldap)
+internal_getpwnam (const char *name, bool check)
{
- struct passwd *ret;
-
- cygheap->pg.nss_init ();
- /* Check caches first. */
- if (cygheap->pg.nss_cygserver_caching ()
- && (ret = cygheap->pg.pwd_cache.cygserver.find_user (uid)))
- return ret;
- if (cygheap->pg.nss_pwd_files ()
- && (ret = cygheap->pg.pwd_cache.file.find_user (uid)))
- return ret;
- if (cygheap->pg.nss_pwd_db ()
- && (ret = cygheap->pg.pwd_cache.win.find_user (uid)))
- return ret;
- /* Ask sources afterwards. */
- if (cygheap->pg.nss_cygserver_caching ()
- && (ret = cygheap->pg.pwd_cache.cygserver.add_user_from_cygserver (uid)))
- return ret;
- if (cygheap->pg.nss_pwd_files ())
- {
- cygheap->pg.pwd_cache.file.check_file ();
- if ((ret = cygheap->pg.pwd_cache.file.add_user_from_file (uid)))
- return ret;
- }
- if (cygheap->pg.nss_pwd_db () || uid == ILLEGAL_UID)
- return cygheap->pg.pwd_cache.win.add_user_from_windows (uid, pldap);
+ pr.refresh (check);
+
+ for (int i = 0; i < pr.curr_lines; i++)
+ /* on Windows NT user names are case-insensitive */
+ if (strcasematch (name, passwd_buf[i].pw_name))
+ return passwd_buf + i;
return NULL;
}
-/* getpwuid/getpwnam are not reentrant. */
-static struct {
- struct passwd p;
- char *buf;
- size_t bufsiz;
-} app_pw;
-
-static struct passwd *
-getpw_cp (struct passwd *temppw)
-{
- if (!temppw)
- return NULL;
- pg_pwd *pw = (pg_pwd *) temppw;
- if (app_pw.bufsiz < pw->len)
- {
- char *newbuf = (char *) realloc (app_pw.buf, pw->len);
- if (!newbuf)
- {
- set_errno (ENOMEM);
- return NULL;
- }
- app_pw.buf = newbuf;
- app_pw.bufsiz = pw->len;
- }
- memcpy (app_pw.buf, pw->p.pw_name, pw->len);
- memcpy (&app_pw.p, &pw->p, sizeof pw->p);
- ptrdiff_t diff = app_pw.buf - pw->p.pw_name;
- app_pw.p.pw_name += diff;
- app_pw.p.pw_passwd += diff;
- app_pw.p.pw_gecos += diff;
- app_pw.p.pw_dir += diff;
- app_pw.p.pw_shell += diff;
- return &app_pw.p;
-}
extern "C" struct passwd *
getpwuid32 (uid_t uid)
{
- struct passwd *temppw = internal_getpwuid (uid);
+ struct passwd *temppw = internal_getpwuid (uid, true);
pthread_testcancel ();
- return getpw_cp (temppw);
+ return temppw;
}
#ifdef __x86_64__
@@ -244,7 +160,7 @@ getpwuid_r32 (uid_t uid, struct passwd *pwd, char *buffer, size_t bufsize, struc
if (!pwd || !buffer)
return ERANGE;
- struct passwd *temppw = internal_getpwuid (uid);
+ struct passwd *temppw = internal_getpwuid (uid, true);
pthread_testcancel ();
if (!temppw)
return 0;
@@ -282,9 +198,9 @@ getpwuid_r (__uid16_t uid, struct passwd *pwd, char *buffer, size_t bufsize, str
extern "C" struct passwd *
getpwnam (const char *name)
{
- struct passwd *temppw = internal_getpwnam (name);
+ struct passwd *temppw = internal_getpwnam (name, true);
pthread_testcancel ();
- return getpw_cp (temppw);
+ return temppw;
}
@@ -300,7 +216,7 @@ getpwnam_r (const char *nam, struct passwd *pwd, char *buffer, size_t bufsize, s
if (!pwd || !buffer || !nam)
return ERANGE;
- struct passwd *temppw = internal_getpwnam (nam);
+ struct passwd *temppw = internal_getpwnam (nam, true);
pthread_testcancel ();
if (!temppw)
@@ -326,429 +242,37 @@ getpwnam_r (const char *nam, struct passwd *pwd, char *buffer, size_t bufsize, s
return 0;
}
-/* getpwent functions are not reentrant. */
-static pw_ent pwent;
-
-void
-pg_ent::clear_cache ()
-{
- if (pg.curr_lines)
- {
- if (state > from_file)
- cfree (group ? grp.g.gr_name : pwd.p.pw_name);
- pg.curr_lines = 0;
- }
-}
-
-void
-pg_ent::setent (bool _group, int _enums, PCWSTR _enum_tdoms)
-{
- cygheap->dom.init ();
- endent (_group);
- if (!_enums && !_enum_tdoms)
- {
- /* This is the default, when called from the usual setpwent/setgrent
- functions. */
- enums = cygheap->pg.nss_db_enums ();
- enum_tdoms = cygheap->pg.nss_db_enum_tdoms ();
- if (_group)
- {
- from_files = cygheap->pg.nss_grp_files ();
- from_db = cygheap->pg.nss_grp_db ();
- }
- else
- {
- from_files = cygheap->pg.nss_pwd_files ();
- from_db = cygheap->pg.nss_pwd_db ();
- }
- }
- else
- {
- /* This case is when called from mkpasswd/mkgroup via cygwin_internal. */
- enums = _enums;
- enum_tdoms = _enum_tdoms;
- from_files = false;
- from_db = true;
- }
- state = from_cache;
-}
-
-void *
-pg_ent::getent (void)
-{
- void *entry;
-
- switch (state)
- {
- case rewound:
- state = from_cache;
- /*FALLTHRU*/
- case from_cache:
- if (nss_db_enum_caches ()
- && (entry = enumerate_caches ()))
- return entry;
- state = from_file;
- /*FALLTHRU*/
- case from_file:
- if (from_files
- && nss_db_enum_files ()
- && (entry = enumerate_file ()))
- return entry;
- state = from_builtin;
- /*FALLTHRU*/
- case from_builtin:
- if (from_db
- && nss_db_enum_builtin ()
- && (entry = enumerate_builtin ()))
- return entry;
- state = from_local;
- /*FALLTHRU*/
- case from_local:
- if (from_db
- && nss_db_enum_local ()
- && (!cygheap->dom.member_machine ()
- || !nss_db_enum_primary ())
- && (entry = enumerate_local ()))
- return entry;
- state = from_sam;
- /*FALLTHRU*/
- case from_sam:
- if (from_db
- && nss_db_enum_local ()
- /* Domain controller? If so, sam and ad are one and the same
- and "local ad" would list all domain accounts twice without
- this test. */
- && (cygheap->dom.account_flat_name ()[0] != L'@'
- || !nss_db_enum_primary ())
- && (entry = enumerate_sam ()))
- return entry;
- state = from_ad;
- /*FALLTHRU*/
- case from_ad:
- if (cygheap->dom.member_machine ()
- && from_db
- && (entry = enumerate_ad ()))
- return entry;
- state = finished;
- /*FALLTHRU*/
- case finished:
- break;
- }
- return NULL;
-}
-
-void
-pg_ent::endent (bool _group)
-{
- if (buf)
- {
- if (state == from_file)
- free (buf);
- else if (state == from_local || state == from_sam)
- NetApiBufferFree (buf);
- buf = NULL;
- }
- if (!pg.curr_lines)
- {
- if ((group = _group))
- {
- pg.init_grp ();
- pg.pwdgrp_buf = (void *) &grp;
- }
- else
- {
- pg.init_pwd ();
- pg.pwdgrp_buf = (void *) &pwd;
- }
- pg.max_lines = 1;
- }
- else
- clear_cache ();
- cldap.close ();
- rl.close ();
- cnt = max = resume = 0;
- enums = 0;
- enum_tdoms = NULL;
- state = rewound;
-}
-
-void *
-pg_ent::enumerate_file ()
-{
- void *entry;
-
- if (!cnt)
- {
- pwdgrp &prf = group ? cygheap->pg.grp_cache.file
- : cygheap->pg.pwd_cache.file;
- if (prf.check_file ())
- {
- if (!buf)
- buf = (char *) malloc (NT_MAX_PATH);
- if (buf
- && !rl.init (prf.file_attr (), buf, NT_MAX_PATH))
- {
- free (buf);
- buf = NULL;
- }
- }
- }
- ++cnt;
- if ((entry = pg.add_account_post_fetch (rl.gets (), false)))
- return entry;
- rl.close ();
- free (buf);
- buf = NULL;
- cnt = max = resume = 0;
- return NULL;
-}
-
-void *
-pg_ent::enumerate_builtin ()
-{
- static cygpsid *pwd_builtins[] = {
- &well_known_system_sid,
- &well_known_local_service_sid,
- &well_known_network_service_sid,
- &well_known_admins_sid,
- &trusted_installer_sid,
- NULL
- };
- static cygpsid *grp_builtins[] = {
- &well_known_system_sid,
- &trusted_installer_sid,
- NULL
- };
-
- cygpsid **builtins = group ? grp_builtins : pwd_builtins;
- if (!builtins[cnt])
- {
- cnt = max = resume = 0;
- return NULL;
- }
- cygsid sid (*builtins[cnt++]);
- fetch_user_arg_t arg;
- arg.type = SID_arg;
- arg.sid = &sid;
- char *line = pg.fetch_account_from_windows (arg);
- return pg.add_account_post_fetch (line, false);
-}
-
-void *
-pg_ent::enumerate_sam ()
-{
- while (true)
- {
- if (!cnt)
- {
- DWORD total;
- NET_API_STATUS ret;
-
- if (buf)
- {
- NetApiBufferFree (buf);
- buf = NULL;
- }
- if (resume == ULONG_MAX)
- ret = ERROR_NO_MORE_ITEMS;
- else if (group)
- ret = NetGroupEnum (NULL, 2, (PBYTE *) &buf, MAX_PREFERRED_LENGTH,
- &max, &total, &resume);
- else
- ret = NetUserEnum (NULL, 20, FILTER_NORMAL_ACCOUNT, (PBYTE *) &buf,
- MAX_PREFERRED_LENGTH, &max, &total,
- (PDWORD) &resume);
- if (ret == NERR_Success)
- resume = ULONG_MAX;
- else if (ret != ERROR_MORE_DATA)
- {
- cnt = max = resume = 0;
- return NULL;
- }
- }
- while (cnt < max)
- {
- cygsid sid (cygheap->dom.account_sid ());
- sid_sub_auth (sid, sid_sub_auth_count (sid)) =
- group ? ((PGROUP_INFO_2) buf)[cnt].grpi2_group_id
- : ((PUSER_INFO_20) buf)[cnt].usri20_user_id;
- ++cnt;
- ++sid_sub_auth_count (sid);
- fetch_user_arg_t arg;
- arg.type = SID_arg;
- arg.sid = &sid;
- char *line = pg.fetch_account_from_windows (arg);
- if (line)
- return pg.add_account_post_fetch (line, false);
- }
- cnt = 0;
- }
-}
-
-void *
-pg_ent::enumerate_ad ()
+extern "C" struct passwd *
+getpwent (void)
{
- while (true)
- {
- if (!cnt)
- {
- PDS_DOMAIN_TRUSTSW td;
-
- if (!resume)
- {
- ++resume;
- if (!nss_db_enum_primary ()
- || cldap.enumerate_ad_accounts (NULL, group) != NO_ERROR)
- continue;
- }
- else if ((td = cygheap->dom.trusted_domain (resume - 1)))
- {
- ++resume;
- /* Ignore primary domain in list of trusted domains only if all
- trusted domains are enumerated anyway. This handles an
- annoying backward compatibility problem in mkpasswd/mkgroup.
- Without this test, `mkpasswd -d PRIMARY_DOMAIN' wouldn't
- work as expected. */
- if (((enums & ENUM_TDOMS_ALL) && td->Flags & DS_DOMAIN_PRIMARY)
- || !td->DomainSid
- || (!nss_db_enum_tdom (td->NetbiosDomainName)
- && !nss_db_enum_tdom (td->DnsDomainName))
- || cldap.enumerate_ad_accounts (td->DnsDomainName, group)
- != NO_ERROR)
- continue;
- }
- else
- {
- cldap.close ();
- return NULL;
- }
- }
- ++cnt;
- cygsid sid;
- int ret = cldap.next_account (sid);
- if (ret == NO_ERROR)
- {
- fetch_user_arg_t arg;
- arg.type = SID_arg;
- arg.sid = &sid;
- char *line = pg.fetch_account_from_windows (arg, &cldap);
- if (line)
- return pg.add_account_post_fetch (line, false);
- ret = EIO;
- }
- if (ret != ENMFILE)
- {
- cldap.close ();
- set_errno (ret);
- return NULL;
- }
- cnt = 0;
- }
-}
+ if (_my_tls.locals.pw_pos == 0)
+ pr.refresh (true);
+ if (_my_tls.locals.pw_pos < pr.curr_lines)
+ return passwd_buf + _my_tls.locals.pw_pos++;
-void *
-pw_ent::enumerate_caches ()
-{
- switch (max)
- {
- case 0:
- if (cygheap->pg.nss_cygserver_caching ())
- {
- pwdgrp &prc = cygheap->pg.pwd_cache.cygserver;
- if (cnt < prc.cached_users ())
- return &prc.passwd ()[cnt++].p;
- }
- cnt = 0;
- max = 1;
- /*FALLTHRU*/
- case 1:
- if (from_files)
- {
- pwdgrp &prf = cygheap->pg.pwd_cache.file;
- prf.check_file ();
- if (cnt < prf.cached_users ())
- return &prf.passwd ()[cnt++].p;
- }
- cnt = 0;
- max = 2;
- /*FALLTHRU*/
- default:
- if (from_db)
- {
- pwdgrp &prw = cygheap->pg.pwd_cache.win;
- if (cnt < prw.cached_users ())
- return &prw.passwd ()[cnt++].p;
- }
- break;
- }
- cnt = max = 0;
return NULL;
}
-void *
-pw_ent::enumerate_local ()
+#ifndef __x86_64__
+extern "C" struct passwd *
+getpwduid (__uid16_t)
{
return NULL;
}
-
-struct passwd *
-pw_ent::getpwent (void)
-{
- if (state == rewound)
- setent (false);
- else
- clear_cache ();
- return (struct passwd *) getent ();
-}
+#endif
extern "C" void
-setpwent ()
-{
- pwent.setpwent ();
-}
-
-extern "C" struct passwd *
-getpwent (void)
+setpwent (void)
{
- return pwent.getpwent ();
+ _my_tls.locals.pw_pos = 0;
}
extern "C" void
endpwent (void)
{
- pwent.endpwent ();
+ _my_tls.locals.pw_pos = 0;
}
-/* *_filtered functions are called from mkpasswd */
-void *
-setpwent_filtered (int enums, PCWSTR enum_tdoms)
-{
- pw_ent *pw = new pw_ent;
- if (pw)
- pw->setpwent (enums, enum_tdoms);
- return (void *) pw;
-}
-
-void *
-getpwent_filtered (void *pw)
-{
- return (void *) ((pw_ent *) pw)->getpwent ();
-}
-
-void
-endpwent_filtered (void *pw)
-{
- ((pw_ent *) pw)->endpwent ();
-}
-
-#ifndef __x86_64__
-extern "C" struct passwd *
-getpwduid (__uid16_t)
-{
- return NULL;
-}
-#endif
-
extern "C" int
setpassent (int)
{
diff --git a/winsup/cygwin/path.cc b/winsup/cygwin/path.cc
index 631b169a0..065456251 100644
--- a/winsup/cygwin/path.cc
+++ b/winsup/cygwin/path.cc
@@ -4633,6 +4633,142 @@ out:
return buf;
}
+int etc::curr_ix = 0;
+/* Note that the first elements of the below arrays are unused */
+bool etc::change_possible[MAX_ETC_FILES + 1];
+OBJECT_ATTRIBUTES etc::fn[MAX_ETC_FILES + 1];
+LARGE_INTEGER etc::last_modified[MAX_ETC_FILES + 1];
+
+int
+etc::init (int n, POBJECT_ATTRIBUTES attr)
+{
+ if (n > 0)
+ /* ok */;
+ else if (++curr_ix <= MAX_ETC_FILES)
+ n = curr_ix;
+ else
+ api_fatal ("internal error");
+
+ fn[n] = *attr;
+ change_possible[n] = false;
+ test_file_change (n);
+ paranoid_printf ("fn[%d] %S, curr_ix %d", n, fn[n].ObjectName, curr_ix);
+ return n;
+}
+
+bool
+etc::test_file_change (int n)
+{
+ NTSTATUS status;
+ FILE_NETWORK_OPEN_INFORMATION fnoi;
+ bool res;
+
+ status = NtQueryFullAttributesFile (&fn[n], &fnoi);
+ if (!NT_SUCCESS (status))
+ {
+ res = status != STATUS_OBJECT_NAME_NOT_FOUND;
+ memset (last_modified + n, 0, sizeof (last_modified[n]));
+ debug_printf ("NtQueryFullAttributesFile (%S) failed, %y",
+ fn[n].ObjectName, status);
+ }
+ else
+ {
+ res = CompareFileTime ((FILETIME *) &fnoi.LastWriteTime,
+ (FILETIME *) last_modified + n) > 0;
+ last_modified[n].QuadPart = fnoi.LastWriteTime.QuadPart;
+ }
+
+ paranoid_printf ("fn[%d] %S res %d", n, fn[n].ObjectName, res);
+ return res;
+}
+
+bool
+etc::dir_changed (int n)
+{
+ /* io MUST be static because NtNotifyChangeDirectoryFile works asynchronously.
+ It may write into io after the function has left, which may result in all
+ sorts of stack corruption. */
+ static IO_STATUS_BLOCK io NO_COPY;
+ static HANDLE changed_h NO_COPY;
+
+ if (!change_possible[n])
+ {
+ NTSTATUS status;
+
+ if (!changed_h)
+ {
+ OBJECT_ATTRIBUTES attr;
+
+ path_conv dir ("/etc");
+ status = NtOpenFile (&changed_h, SYNCHRONIZE | FILE_LIST_DIRECTORY,
+ dir.get_object_attr (attr, sec_none_nih), &io,
+ FILE_SHARE_VALID_FLAGS, FILE_DIRECTORY_FILE);
+ if (!NT_SUCCESS (status))
+ {
+#ifdef DEBUGGING
+ system_printf ("NtOpenFile (%S) failed, %y",
+ dir.get_nt_native_path (), status);
+#endif
+ changed_h = INVALID_HANDLE_VALUE;
+ }
+ else
+ {
+ status = NtNotifyChangeDirectoryFile (changed_h, NULL, NULL,
+ NULL, &io, NULL, 0,
+ FILE_NOTIFY_CHANGE_LAST_WRITE
+ | FILE_NOTIFY_CHANGE_FILE_NAME,
+ FALSE);
+ if (!NT_SUCCESS (status))
+ {
+#ifdef DEBUGGING
+ system_printf ("NtNotifyChangeDirectoryFile (1) failed, %y",
+ status);
+#endif
+ NtClose (changed_h);
+ changed_h = INVALID_HANDLE_VALUE;
+ }
+ }
+ memset (change_possible, true, sizeof (change_possible));
+ }
+
+ if (changed_h == INVALID_HANDLE_VALUE)
+ change_possible[n] = true;
+ else if (WaitForSingleObject (changed_h, 0) == WAIT_OBJECT_0)
+ {
+ status = NtNotifyChangeDirectoryFile (changed_h, NULL, NULL,
+ NULL, &io, NULL, 0,
+ FILE_NOTIFY_CHANGE_LAST_WRITE
+ | FILE_NOTIFY_CHANGE_FILE_NAME,
+ FALSE);
+ if (!NT_SUCCESS (status))
+ {
+#ifdef DEBUGGING
+ system_printf ("NtNotifyChangeDirectoryFile (2) failed, %y",
+ status);
+#endif
+ NtClose (changed_h);
+ changed_h = INVALID_HANDLE_VALUE;
+ }
+ memset (change_possible, true, sizeof change_possible);
+ }
+ }
+
+ paranoid_printf ("fn[%d] %S change_possible %d",
+ n, fn[n].ObjectName, change_possible[n]);
+ return change_possible[n];
+}
+
+bool
+etc::file_changed (int n)
+{
+ bool res = false;
+ if (dir_changed (n) && test_file_change (n))
+ res = true;
+ change_possible[n] = false; /* Change is no longer possible */
+ paranoid_printf ("fn[%d] %S res %d", n, fn[n].ObjectName, res);
+ return res;
+}
+
/* No need to be reentrant or thread-safe according to SUSv3.
/ and \\ are treated equally. Leading drive specifiers are
kept intact as far as it makes sense. Everything else is
diff --git a/winsup/cygwin/path.h b/winsup/cygwin/path.h
index dfd8f0241..d6c386075 100644
--- a/winsup/cygwin/path.h
+++ b/winsup/cygwin/path.h
@@ -447,4 +447,21 @@ int normalize_win32_path (const char *, char *, char *&);
int normalize_posix_path (const char *, char *, char *&);
PUNICODE_STRING __reg3 get_nt_native_path (const char *, UNICODE_STRING&, bool);
+/* FIXME: Move to own include file eventually */
+
+#define MAX_ETC_FILES 2
+class etc
+{
+ friend class dtable;
+ static int curr_ix;
+ static bool change_possible[MAX_ETC_FILES + 1];
+ static OBJECT_ATTRIBUTES fn[MAX_ETC_FILES + 1];
+ static LARGE_INTEGER last_modified[MAX_ETC_FILES + 1];
+ static bool dir_changed (int);
+ static int init (int, POBJECT_ATTRIBUTES);
+ static bool file_changed (int);
+ static bool test_file_change (int);
+ friend class pwdgrp;
+};
+
int __reg3 symlink_worker (const char *, const char *, bool);
diff --git a/winsup/cygwin/pinfo.cc b/winsup/cygwin/pinfo.cc
index 4518d6d51..5d9e74895 100644
--- a/winsup/cygwin/pinfo.cc
+++ b/winsup/cygwin/pinfo.cc
@@ -41,7 +41,7 @@ pinfo_basic::pinfo_basic ()
GetModuleFileNameW (NULL, progname, sizeof (progname) / sizeof (WCHAR));
/* Default uid/gid are needed very early to initialize shared user info. */
uid = ILLEGAL_UID;
- gid = ILLEGAL_GID;
+ gid = UNKNOWN_GID;
}
pinfo_basic myself_initial NO_COPY;
@@ -100,7 +100,7 @@ pinfo_init (char **envp, int envc)
myself->pgid = myself->sid = myself->pid;
myself->ctty = -1;
myself->uid = ILLEGAL_UID;
- myself->gid = ILLEGAL_GID;
+ myself->gid = UNKNOWN_GID;
environ_init (NULL, 0); /* call after myself has been set up */
myself->nice = winprio_to_nice (GetPriorityClass (GetCurrentProcess ()));
myself->ppid = 1; /* always set last */
diff --git a/winsup/cygwin/pwdgrp.h b/winsup/cygwin/pwdgrp.h
index dfeef5680..fe3c3f2a1 100644
--- a/winsup/cygwin/pwdgrp.h
+++ b/winsup/cygwin/pwdgrp.h
@@ -1,6 +1,6 @@
/* pwdgrp.h
- Copyright 2001, 2002, 2003, 2014 Red Hat inc.
+ Copyright 2001, 2002, 2003 Red Hat inc.
Stuff common to pwd and grp handling.
@@ -10,84 +10,42 @@ This software is a copyrighted work licensed under the terms of the
Cygwin license. Please consult the file "CYGWIN_LICENSE" for
details. */
-#pragma once
-
-#include "sync.h"
-#include "ldap.h"
-#include "miscfuncs.h"
-
/* These functions are needed to allow searching and walking through
the passwd and group lists */
-extern struct passwd *internal_getpwsid (cygpsid &, cyg_ldap * = NULL);
-extern struct passwd *internal_getpwsid_from_db (cygpsid &sid);
-extern struct passwd *internal_getpwnam (const char *, cyg_ldap * = NULL);
-extern struct passwd *internal_getpwuid (uid_t, cyg_ldap * = NULL);
-extern struct group *internal_getgrsid (cygpsid &, cyg_ldap * = NULL);
-extern struct group *internal_getgrsid_from_db (cygpsid &sid);
-extern struct group *internal_getgrgid (gid_t, cyg_ldap * = NULL);
-extern struct group *internal_getgrnam (const char *, cyg_ldap * = NULL);
-
-extern int internal_getgroups (int, gid_t *, cyg_ldap *);
-
-/* These functions are called from mkpasswd/mkgroup via cygwin_internal. */
-void *setpwent_filtered (int enums, PCWSTR enum_tdoms);
-void *getpwent_filtered (void *gr);
-void endpwent_filtered (void *gr);
-void *setgrent_filtered (int enums, PCWSTR enum_tdoms);
-void *getgrent_filtered (void *gr);
-void endgrent_filtered (void *gr);
-
-enum fetch_user_arg_type_t {
- SID_arg,
- NAME_arg,
- ID_arg
-};
-
-struct fetch_user_arg_t
-{
- fetch_user_arg_type_t type;
- union {
- cygpsid *sid;
- const char *name;
- uint32_t id;
- };
- /* Only used in fetch_account_from_file/line. */
- size_t len;
-};
-
-struct pg_pwd
-{
- struct passwd p;
- cygsid sid;
- size_t len;
-};
-
-struct pg_grp
-{
- struct group g;
- cygsid sid;
- size_t len;
-};
+extern struct passwd *internal_getpwsid (cygpsid &);
+extern struct passwd *internal_getpwnam (const char *, bool = FALSE);
+extern struct passwd *internal_getpwuid (uid_t, bool = FALSE);
+extern struct group *internal_getgrsid (cygpsid &);
+extern struct group *internal_getgrgid (gid_t gid, bool = FALSE);
+extern struct group *internal_getgrnam (const char *, bool = FALSE);
+extern struct group *internal_getgrent (int);
+int internal_getgroups (int, gid_t *, cygpsid * = NULL);
+#include "sync.h"
+#include "cygtls.h"
class pwdgrp
{
- friend class pg_ent;
- friend class pw_ent;
- friend class gr_ent;
-
unsigned pwdgrp_buf_elem_size;
- void *pwdgrp_buf;
+ union
+ {
+ passwd **passwd_buf;
+ group **group_buf;
+ void **pwdgrp_buf;
+ };
+ void (pwdgrp::*read) ();
bool (pwdgrp::*parse) ();
- UNICODE_STRING path;
- OBJECT_ATTRIBUTES attr;
- LARGE_INTEGER last_modified;
- char *lptr;
- ULONG curr_lines;
- ULONG max_lines;
+ int etc_ix;
+ UNICODE_STRING upath;
+ PWCHAR path;
+ char *buf, *lptr;
+ int max_lines;
+ bool initialized;
static muto pglock;
bool parse_passwd ();
bool parse_group ();
+ void read_passwd ();
+ void read_group ();
char *add_line (char *);
char *raw_ptr () const {return lptr;}
char *next_str (char);
@@ -106,157 +64,21 @@ class pwdgrp
i = (int) x;
return res;
}
- void *add_account_post_fetch (char *line, bool lock);
- void *add_account_from_file (cygpsid &sid);
- void *add_account_from_file (const char *name);
- void *add_account_from_file (uint32_t id);
- void *add_account_from_windows (cygpsid &sid, cyg_ldap *pldap = NULL);
- void *add_account_from_windows (const char *name, cyg_ldap *pldap = NULL);
- void *add_account_from_windows (uint32_t id, cyg_ldap *pldap = NULL);
- void *add_account_from_cygserver (cygpsid &sid);
- void *add_account_from_cygserver (const char *name);
- void *add_account_from_cygserver (uint32_t id);
- char *fetch_account_from_line (fetch_user_arg_t &arg, const char *line);
- char *fetch_account_from_file (fetch_user_arg_t &arg);
- char *fetch_account_from_windows (fetch_user_arg_t &arg,
- cyg_ldap *pldap = NULL);
- char *fetch_account_from_cygserver (fetch_user_arg_t &arg);
-
-public:
- ULONG cached_users () const { return curr_lines; }
- ULONG cached_groups () const { return curr_lines; }
- POBJECT_ATTRIBUTES file_attr () { return &attr; }
- bool check_file ();
-
- void init_pwd ();
- bool is_passwd () const { return pwdgrp_buf_elem_size == sizeof (pg_pwd); }
- pg_pwd *passwd () const { return (pg_pwd *) pwdgrp_buf; };
- struct passwd *add_user_from_cygserver (cygpsid &sid)
- { return (struct passwd *) add_account_from_cygserver (sid); }
- struct passwd *add_user_from_cygserver (const char *name)
- { return (struct passwd *) add_account_from_cygserver (name); }
- struct passwd *add_user_from_cygserver (uint32_t id)
- { return (struct passwd *) add_account_from_cygserver (id); }
- struct passwd *add_user_from_file (cygpsid &sid)
- { return (struct passwd *) add_account_from_file (sid); }
- struct passwd *add_user_from_file (const char *name)
- { return (struct passwd *) add_account_from_file (name); }
- struct passwd *add_user_from_file (uint32_t id)
- { return (struct passwd *) add_account_from_file (id); }
- struct passwd *add_user_from_windows (cygpsid &sid, cyg_ldap *pldap = NULL)
- { return (struct passwd *) add_account_from_windows (sid, pldap); }
- struct passwd *add_user_from_windows (const char *name,
- cyg_ldap* pldap = NULL)
- { return (struct passwd *) add_account_from_windows (name, pldap); }
- struct passwd *add_user_from_windows (uint32_t id, cyg_ldap *pldap = NULL)
- { return (struct passwd *) add_account_from_windows (id, pldap); }
- struct passwd *find_user (cygpsid &sid);
- struct passwd *find_user (const char *name);
- struct passwd *find_user (uid_t uid);
-
- void init_grp ();
- bool is_group () const { return pwdgrp_buf_elem_size == sizeof (pg_grp); }
- pg_grp *group () const { return (pg_grp *) pwdgrp_buf; };
- struct group *add_group_from_cygserver (cygpsid &sid)
- { return (struct group *) add_account_from_cygserver (sid); }
- struct group *add_group_from_cygserver (const char *name)
- { return (struct group *) add_account_from_cygserver (name); }
- struct group *add_group_from_cygserver (uint32_t id)
- { return (struct group *) add_account_from_cygserver (id); }
- struct group *add_group_from_file (cygpsid &sid)
- { return (struct group *) add_account_from_file (sid); }
- struct group *add_group_from_file (const char *name)
- { return (struct group *) add_account_from_file (name); }
- struct group *add_group_from_file (uint32_t id)
- { return (struct group *) add_account_from_file (id); }
- struct group *add_group_from_windows (cygpsid &sid, cyg_ldap *pldap = NULL)
- { return (struct group *) add_account_from_windows (sid, pldap); }
- struct group *add_group_from_windows (const char *name,
- cyg_ldap *pldap = NULL)
- { return (struct group *) add_account_from_windows (name, pldap); }
- struct group *add_group_from_windows (uint32_t id, cyg_ldap *pldap = NULL)
- { return (struct group *) add_account_from_windows (id, pldap); }
- struct group *find_group (cygpsid &sid);
- struct group *find_group (const char *name);
- struct group *find_group (gid_t gid);
-};
-
-class pg_ent
-{
-protected:
- pwdgrp pg;
- bool group;
- pg_pwd pwd;
- pg_grp grp;
- NT_readline rl;
- cyg_ldap cldap;
- PCHAR buf;
- ULONG cnt;
- ULONG max;
- ULONG_PTR resume;
- int enums; /* ENUM_xxx values defined in sys/cygwin.h. */
- PCWSTR enum_tdoms;
- bool from_files;
- bool from_db;
- enum {
- rewound = 0,
- from_cache,
- from_file,
- from_builtin,
- from_local,
- from_sam,
- from_ad,
- finished
- } state;
-
- void clear_cache ();
- inline bool nss_db_enum_caches () const { return !!(enums & ENUM_CACHE); }
- inline bool nss_db_enum_files () const { return !!(enums & ENUM_FILES); }
- inline bool nss_db_enum_builtin () const { return !!(enums & ENUM_BUILTIN); }
- inline bool nss_db_enum_local () const { return !!(enums & ENUM_LOCAL); }
- inline bool nss_db_enum_primary () const { return !!(enums & ENUM_PRIMARY); }
- inline bool nss_db_enum_tdom (PWCHAR domain)
- {
- if (enums & ENUM_TDOMS_ALL)
- return true;
- if (!(enums & ENUM_TDOMS) || !enum_tdoms || !domain)
- return false;
- for (PCWSTR td = enum_tdoms; td && *td; td = wcschr (td, L'\0'))
- if (!wcscasecmp (td, domain))
- return true;
- return false;
- }
- virtual void *enumerate_caches () = 0;
- virtual void *enumerate_file ();
- virtual void *enumerate_builtin ();
- virtual void *enumerate_local () = 0;
- virtual void *enumerate_sam ();
- virtual void *enumerate_ad ();
public:
- void setent (bool _group, int _enums = 0, PCWSTR _enum_tdoms = NULL);
- void *getent ();
- void endent (bool _group);
-};
+ int curr_lines;
-class pw_ent : public pg_ent
-{
- void *enumerate_caches ();
- void *enumerate_local ();
-public:
- inline void setpwent (int _enums = 0, PCWSTR _enum_tdoms = NULL)
- { setent (false, _enums, _enum_tdoms); }
- struct passwd *getpwent ();
- inline void endpwent () { endent (false); }
-};
+ void load (const wchar_t *);
+ inline void refresh (bool check)
+ {
+ if (!check && initialized)
+ return;
+ if (pglock.acquire () == 1 &&
+ (!initialized || (check && etc::file_changed (etc_ix))))
+ (this->*read) ();
+ pglock.release ();
+ }
-class gr_ent : public pg_ent
-{
- void *enumerate_caches ();
- void *enumerate_local ();
-public:
- inline void setgrent (int _enums = 0, PCWSTR _enum_tdoms = NULL)
- { setent (true, _enums, _enum_tdoms); }
- struct group *getgrent ();
- inline void endgrent () { endent (true); }
+ pwdgrp (passwd *&pbuf);
+ pwdgrp (group *&gbuf);
};
diff --git a/winsup/cygwin/release/1.7.31 b/winsup/cygwin/release/1.7.31
index f056a3cce..c54d96814 100644
--- a/winsup/cygwin/release/1.7.31
+++ b/winsup/cygwin/release/1.7.31
@@ -18,7 +18,7 @@ Bug Fixes
---------
- Fix various assorted bugs (potential buffer overruns, resource leaks, you
- name it) catched by Coverity.
+ name it) caught by Coverity.
- Fix return value of getgrouplist if the number of groups is bigger than the
application-provided buffer can hold.
diff --git a/winsup/cygwin/release/1.7.32 b/winsup/cygwin/release/1.7.32
deleted file mode 100644
index 400216469..000000000
--- a/winsup/cygwin/release/1.7.32
+++ /dev/null
@@ -1,15 +0,0 @@
-What's new:
------------
-
-- Introduce reading passwd/group entries directly from SAM/AD, thus allowing
- to do without /etc/passwd and /etc/group files. Introduce /etc/nsswitch.conf
- file to configure passwd/group handling.
-
-
-What changed:
--------------
-
-
-Bug Fixes
----------
-
diff --git a/winsup/cygwin/sec_acl.cc b/winsup/cygwin/sec_acl.cc
index ec5876099..2f7ac278d 100644
--- a/winsup/cygwin/sec_acl.cc
+++ b/winsup/cygwin/sec_acl.cc
@@ -1,7 +1,7 @@
/* sec_acl.cc: Sun compatible ACL functions.
Copyright 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
- 2011, 2012, 2014 Red Hat, Inc.
+ 2011, 2012 Red Hat, Inc.
Written by Corinna Vinschen <corinna@vinschen.de>
@@ -22,6 +22,7 @@ details. */
#include "dtable.h"
#include "cygheap.h"
#include "ntdll.h"
+#include "pwdgrp.h"
#include "tls_pbuf.h"
static int
@@ -94,7 +95,6 @@ setacl (HANDLE handle, path_conv &pc, int nentries, aclent_t *aclbufp,
struct passwd *pw;
struct group *gr;
int pos;
- cyg_ldap cldap;
RtlCreateAcl (acl, ACL_MAXIMUM_SIZE, ACL_REVISION);
@@ -158,7 +158,7 @@ setacl (HANDLE handle, path_conv &pc, int nentries, aclent_t *aclbufp,
break;
case USER:
case DEF_USER:
- if (!(pw = internal_getpwuid (aclbufp[i].a_id, &cldap))
+ if (!(pw = internal_getpwuid (aclbufp[i].a_id))
|| !sid.getfrompw (pw))
{
set_errno (EINVAL);
@@ -180,7 +180,7 @@ setacl (HANDLE handle, path_conv &pc, int nentries, aclent_t *aclbufp,
break;
case GROUP:
case DEF_GROUP:
- if (!(gr = internal_getgrgid (aclbufp[i].a_id, &cldap))
+ if (!(gr = internal_getgrgid (aclbufp[i].a_id))
|| !sid.getfromgr (gr))
{
set_errno (EINVAL);
@@ -283,7 +283,6 @@ getacl (HANDLE handle, path_conv &pc, int nentries, aclent_t *aclbufp)
BOOLEAN dummy;
uid_t uid;
gid_t gid;
- cyg_ldap cldap;
status = RtlGetOwnerSecurityDescriptor (sd, (PSID *) &owner_sid, &dummy);
if (!NT_SUCCESS (status))
@@ -291,7 +290,7 @@ getacl (HANDLE handle, path_conv &pc, int nentries, aclent_t *aclbufp)
__seterrno_from_nt_status (status);
return -1;
}
- uid = owner_sid.get_uid (&cldap);
+ uid = owner_sid.get_uid ();
status = RtlGetGroupSecurityDescriptor (sd, (PSID *) &group_sid, &dummy);
if (!NT_SUCCESS (status))
@@ -299,7 +298,7 @@ getacl (HANDLE handle, path_conv &pc, int nentries, aclent_t *aclbufp)
__seterrno_from_nt_status (status);
return -1;
}
- gid = group_sid.get_gid (&cldap);
+ gid = group_sid.get_gid ();
aclent_t lacl[MAX_ACL_ENTRIES];
memset (&lacl, 0, MAX_ACL_ENTRIES * sizeof (aclent_t));
@@ -369,7 +368,7 @@ getacl (HANDLE handle, path_conv &pc, int nentries, aclent_t *aclbufp)
id = ILLEGAL_GID;
}
else
- id = ace_sid.get_id (TRUE, &type, &cldap);
+ id = ace_sid.get_id (true, &type);
if (!type)
continue;
@@ -838,7 +837,6 @@ aclfromtext32 (char *acltextp, int *)
int pos = 0;
strcpy (buf, acltextp);
char *lasts;
- cyg_ldap cldap;
for (char *c = strtok_r (buf, ",", &lasts);
c;
c = strtok_r (NULL, ",", &lasts))
@@ -858,7 +856,7 @@ aclfromtext32 (char *acltextp, int *)
c += 5;
if (isalpha (*c))
{
- struct passwd *pw = internal_getpwnam (c, &cldap);
+ struct passwd *pw = internal_getpwnam (c);
if (!pw)
{
set_errno (EINVAL);
@@ -886,7 +884,7 @@ aclfromtext32 (char *acltextp, int *)
c += 5;
if (isalpha (*c))
{
- struct group *gr = internal_getgrnam (c, &cldap);
+ struct group *gr = internal_getgrnam (c);
if (!gr)
{
set_errno (EINVAL);
diff --git a/winsup/cygwin/sec_auth.cc b/winsup/cygwin/sec_auth.cc
index 3615588ef..2cdce8bd4 100644
--- a/winsup/cygwin/sec_auth.cc
+++ b/winsup/cygwin/sec_auth.cc
@@ -14,6 +14,7 @@ details. */
#include <wchar.h>
#include <wininet.h>
#include <ntsecapi.h>
+#include <dsgetdc.h>
#include "cygerrno.h"
#include "security.h"
#include "path.h"
@@ -24,6 +25,7 @@ details. */
#include "tls_pbuf.h"
#include <lm.h>
#include <iptypes.h>
+#include "pwdgrp.h"
#include "cyglsa.h"
#include "cygserver_setpwd.h"
#include <cygwin/version.h>
@@ -219,27 +221,28 @@ lsa_close_policy (HANDLE lsa)
}
bool
-get_logon_server (PWCHAR domain, WCHAR *server, ULONG flags)
+get_logon_server (PWCHAR domain, WCHAR *server, bool rediscovery)
{
DWORD ret;
PDOMAIN_CONTROLLER_INFOW pci;
+ DWORD size = MAX_COMPUTERNAME_LENGTH + 1;
/* Empty domain is interpreted as local system */
- if (cygheap->dom.init ()
- && (!domain[0]
- || !wcscasecmp (domain, cygheap->dom.account_flat_name ())))
+ if ((GetComputerNameW (server + 2, &size)) &&
+ (!wcscasecmp (domain, server + 2) || !domain[0]))
{
- wcpcpy (wcpcpy (server, L"\\\\"), cygheap->dom.account_flat_name ());
+ server[0] = server[1] = L'\\';
return true;
}
/* Try to get any available domain controller for this domain */
- ret = DsGetDcNameW (NULL, domain, NULL, NULL, flags, &pci);
+ ret = DsGetDcNameW (NULL, domain, NULL, NULL,
+ rediscovery ? DS_FORCE_REDISCOVERY : 0, &pci);
if (ret == ERROR_SUCCESS)
{
wcscpy (server, pci->DomainControllerName);
NetApiBufferFree (pci);
- debug_printf ("DC: server: %W", server);
+ debug_printf ("DC: rediscovery: %d, server: %W", rediscovery, server);
return true;
}
__seterrno_from_win_error (ret);
@@ -278,7 +281,7 @@ get_user_groups (WCHAR *logonserver, cygsidlist &grp_list,
for (DWORD i = 0; i < cnt; ++i)
{
cygsid gsid;
- DWORD glen = SECURITY_MAX_SID_SIZE;
+ DWORD glen = MAX_SID_LEN;
WCHAR dom[MAX_DOMAIN_NAME_LEN + 1];
DWORD dlen = sizeof (dom);
SID_NAME_USE use = SidTypeInvalid;
@@ -326,7 +329,7 @@ get_user_local_groups (PWCHAR logonserver, PWCHAR domain,
for (DWORD i = 0; i < cnt; ++i)
{
cygsid gsid;
- DWORD glen = SECURITY_MAX_SID_SIZE;
+ DWORD glen = MAX_SID_LEN;
WCHAR dom[MAX_DOMAIN_NAME_LEN + 1];
DWORD domlen = MAX_DOMAIN_NAME_LEN + 1;
@@ -362,7 +365,7 @@ get_user_local_groups (PWCHAR logonserver, PWCHAR domain,
if (bg_ptr)
{
wcscpy (bg_ptr, dg_ptr);
- glen = SECURITY_MAX_SID_SIZE;
+ glen = MAX_SID_LEN;
domlen = MAX_DOMAIN_NAME_LEN + 1;
if (LookupAccountNameW (NULL, builtin_grp, gsid, &glen,
dom, &domlen, &use))
@@ -395,6 +398,28 @@ sid_in_token_groups (PTOKEN_GROUPS grps, cygpsid sid)
}
static void
+get_unix_group_sidlist (struct passwd *pw, cygsidlist &grp_list)
+{
+ struct group *gr;
+ cygsid gsid;
+
+ for (int gidx = 0; (gr = internal_getgrent (gidx)); ++gidx)
+ {
+ if (gr->gr_gid == pw->pw_gid)
+ goto found;
+ else if (gr->gr_mem)
+ for (int gi = 0; gr->gr_mem[gi]; ++gi)
+ if (strcasematch (pw->pw_name, gr->gr_mem[gi]))
+ goto found;
+ continue;
+ found:
+ if (gsid.getfromgr (gr))
+ grp_list += gsid;
+
+ }
+}
+
+static void
get_token_group_sidlist (cygsidlist &grp_list, PTOKEN_GROUPS my_grps,
LUID auth_luid, int &auth_pos)
{
@@ -455,6 +480,7 @@ get_server_groups (cygsidlist &grp_list, PSID usersid, struct passwd *pw)
if (well_known_system_sid == usersid)
{
grp_list *= well_known_admins_sid;
+ get_unix_group_sidlist (pw, grp_list);
return true;
}
@@ -466,16 +492,12 @@ get_server_groups (cygsidlist &grp_list, PSID usersid, struct passwd *pw)
__seterrno ();
return false;
}
- /* If the SID does NOT start with S-1-5-21, the domain is some builtin
- domain. The search for a logon server and fetching group accounts
- is moot. */
- if (sid_id_auth (usersid) == 5 /* SECURITY_NT_AUTHORITY */
- && sid_sub_auth (usersid, 0) == SECURITY_NT_NON_UNIQUE
- && get_logon_server (domain, server, DS_IS_FLAT_NAME))
- {
- get_user_groups (server, grp_list, user, domain);
- get_user_local_groups (server, domain, grp_list, user);
- }
+ if (get_logon_server (domain, server, false)
+ && !get_user_groups (server, grp_list, user, domain)
+ && get_logon_server (domain, server, true))
+ get_user_groups (server, grp_list, user, domain);
+ get_user_local_groups (server, domain, grp_list, user);
+ get_unix_group_sidlist (pw, grp_list);
return true;
}
@@ -683,7 +705,7 @@ verify_token (HANDLE token, cygsid &usersid, user_groups &groups, bool *pintern)
*pintern = intern = !memcmp (ts.SourceName, "Cygwin.1", 8);
}
/* Verify usersid */
- cygsid tok_usersid (NO_SID);
+ cygsid tok_usersid = NO_SID;
status = NtQueryInformationToken (token, TokenUser, &tok_usersid,
sizeof tok_usersid, &size);
if (!NT_SUCCESS (status))
@@ -695,8 +717,7 @@ verify_token (HANDLE token, cygsid &usersid, user_groups &groups, bool *pintern)
is not well_known_null_sid, it must match pgrpsid */
if (intern && !groups.issetgroups ())
{
- const DWORD sd_buf_siz = SECURITY_MAX_SID_SIZE
- + sizeof (SECURITY_DESCRIPTOR);
+ const DWORD sd_buf_siz = MAX_SID_LEN + sizeof (SECURITY_DESCRIPTOR);
PSECURITY_DESCRIPTOR sd_buf = (PSECURITY_DESCRIPTOR) alloca (sd_buf_siz);
cygpsid gsid (NO_SID);
NTSTATUS status;
@@ -737,26 +758,35 @@ verify_token (HANDLE token, cygsid &usersid, user_groups &groups, bool *pintern)
if (groups.issetgroups ()) /* setgroups was called */
{
- cygpsid gsid;
+ cygsid gsid;
+ struct group *gr;
bool saw[groups.sgsids.count ()];
-
- /* Check that all groups in the setgroups () list are in the token.
- A token created through ADVAPI should be allowed to contain more
- groups than requested through setgroups(), especially since Vista
- and the addition of integrity groups. */
memset (saw, 0, sizeof(saw));
- for (int gidx = 0; gidx < groups.sgsids.count (); gidx++)
- {
- gsid = groups.sgsids.sids[gidx];
- if (sid_in_token_groups (my_grps, gsid))
- {
- int pos = groups.sgsids.position (gsid);
- if (pos >= 0)
- saw[pos] = true;
- else if (groups.pgsid == gsid)
- sawpg = true;
- }
- }
+
+ /* token groups found in /etc/group match the user.gsids ? */
+ for (int gidx = 0; (gr = internal_getgrent (gidx)); ++gidx)
+ if (gsid.getfromgr (gr) && sid_in_token_groups (my_grps, gsid))
+ {
+ int pos = groups.sgsids.position (gsid);
+ if (pos >= 0)
+ saw[pos] = true;
+ else if (groups.pgsid == gsid)
+ sawpg = true;
+#if 0
+ /* With this `else', verify_token returns false if we find
+ groups in the token, which are not in the group list set
+ with setgroups(). That's rather dangerous. What we're
+ really interested in is that all groups in the setgroups()
+ list are in the token. A token created through ADVAPI
+ should be allowed to contain more groups than requested
+ through setgroups(), esecially since Vista and the
+ addition of integrity groups. So we disable this statement
+ for now. */
+ else if (gsid != well_known_world_sid
+ && gsid != usersid)
+ goto done;
+#endif
+ }
/* user.sgsids groups must be in the token, except for builtin groups.
These can be different on domain member machines compared to
domain controllers, so these builtin groups may be validly missing
diff --git a/winsup/cygwin/sec_helper.cc b/winsup/cygwin/sec_helper.cc
index 946e78a8e..2d81cbd38 100644
--- a/winsup/cygwin/sec_helper.cc
+++ b/winsup/cygwin/sec_helper.cc
@@ -1,7 +1,7 @@
/* sec_helper.cc: NT security helper functions
Copyright 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010,
- 2011, 2012, 2013, 2014 Red Hat, Inc.
+ 2011, 2012, 2013 Red Hat, Inc.
Written by Corinna Vinschen <corinna@vinschen.de>
@@ -22,8 +22,8 @@ details. */
#include "dtable.h"
#include "pinfo.h"
#include "cygheap.h"
+#include "pwdgrp.h"
#include "ntdll.h"
-#include "ldap.h"
/* General purpose security attribute objects for global use. */
static NO_COPY_RO SECURITY_DESCRIPTOR null_sdp =
@@ -66,10 +66,6 @@ MKSID (well_known_this_org_sid, "S-1-5-15",
SECURITY_NT_AUTHORITY, 1, 15);
MKSID (well_known_system_sid, "S-1-5-18",
SECURITY_NT_AUTHORITY, 1, SECURITY_LOCAL_SYSTEM_RID);
-MKSID (well_known_local_service_sid, "S-1-5-19",
- SECURITY_NT_AUTHORITY, 1, SECURITY_LOCAL_SERVICE_RID);
-MKSID (well_known_network_service_sid, "S-1-5-20",
- SECURITY_NT_AUTHORITY, 1, SECURITY_NETWORK_SERVICE_RID);
MKSID (well_known_builtin_sid, "S-1-5-32",
SECURITY_NT_AUTHORITY, 1, SECURITY_BUILTIN_DOMAIN_RID);
MKSID (well_known_admins_sid, "S-1-5-32-544",
@@ -78,11 +74,6 @@ MKSID (well_known_admins_sid, "S-1-5-32-544",
MKSID (well_known_users_sid, "S-1-5-32-545",
SECURITY_NT_AUTHORITY, 2, SECURITY_BUILTIN_DOMAIN_RID,
DOMAIN_ALIAS_RID_USERS);
-MKSID (trusted_installer_sid,
- "S-1-5-80-956008885-3418522649-1831038044-1853292631-2271478464",
- SECURITY_NT_AUTHORITY, SECURITY_SERVICE_ID_RID_COUNT,
- SECURITY_SERVICE_ID_BASE_RID, 956008885U, 3418522649U, 1831038044U,
- 1853292631U, 2271478464U);
MKSID (mandatory_medium_integrity_sid, "S-1-16-8192",
SECURITY_MANDATORY_LABEL_AUTHORITY, 1, SECURITY_MANDATORY_MEDIUM_RID);
MKSID (mandatory_high_integrity_sid, "S-1-16-12288",
@@ -102,7 +93,7 @@ cygpsid::operator== (const char *nsidstr) const
}
uid_t
-cygpsid::get_id (BOOL search_grp, int *type, cyg_ldap *pldap)
+cygpsid::get_id (BOOL search_grp, int *type)
{
/* First try to get SID from group, then passwd */
uid_t id = ILLEGAL_UID;
@@ -112,27 +103,9 @@ cygpsid::get_id (BOOL search_grp, int *type, cyg_ldap *pldap)
struct group *gr;
if (cygheap->user.groups.pgsid == psid)
id = myself->gid;
- else if (sid_id_auth (psid) == 22)
- {
- /* Samba UNIX group. Try to map to Cygwin gid. If there's no
- mapping in the cache, try to fetch it from the configured
- RFC 2307 domain (see last comment in cygheap_domain_info::init()
- for more information) and add it to the mapping cache. */
- gid_t gid = sid_sub_auth_rid (psid);
- gid_t map_gid = cygheap->ugid_cache.get_gid (gid);
- if (map_gid == ILLEGAL_GID)
- {
- if (pldap->open (cygheap->dom.get_rfc2307_domain ()) == NO_ERROR)
- map_gid = pldap->remap_gid (gid);
- if (map_gid == ILLEGAL_GID)
- map_gid = MAP_UNIX_TO_CYGWIN_ID (gid);
- cygheap->ugid_cache.add_gid (gid, map_gid);
- }
- id = (uid_t) map_gid;
- }
- else if ((gr = internal_getgrsid (*this, pldap)))
+ else if ((gr = internal_getgrsid (*this)))
id = gr->gr_gid;
- if ((gid_t) id != ILLEGAL_GID)
+ if (id != ILLEGAL_UID)
{
if (type)
*type = GROUP;
@@ -144,22 +117,7 @@ cygpsid::get_id (BOOL search_grp, int *type, cyg_ldap *pldap)
struct passwd *pw;
if (*this == cygheap->user.sid ())
id = myself->uid;
- else if (sid_id_auth (psid) == 22)
- {
- /* Samba UNIX user. See comment above. */
- uid_t uid = sid_sub_auth_rid (psid);
- uid_t map_uid = cygheap->ugid_cache.get_uid (uid);
- if (map_uid == ILLEGAL_UID)
- {
- if (pldap->open (cygheap->dom.get_rfc2307_domain ()) == NO_ERROR)
- map_uid = pldap->remap_uid (uid);
- if (map_uid == ILLEGAL_UID)
- map_uid = MAP_UNIX_TO_CYGWIN_ID (uid);
- cygheap->ugid_cache.add_uid (uid, map_uid);
- }
- id = map_uid;
- }
- else if ((pw = internal_getpwsid (*this, pldap)))
+ else if ((pw = internal_getpwsid (*this)))
id = pw->pw_uid;
if (id != ILLEGAL_UID && type)
*type = USER;
@@ -168,7 +126,7 @@ cygpsid::get_id (BOOL search_grp, int *type, cyg_ldap *pldap)
}
PWCHAR
-cygpsid::pstring (PWCHAR nsidstr) const
+cygpsid::string (PWCHAR nsidstr) const
{
UNICODE_STRING sid;
@@ -176,19 +134,11 @@ cygpsid::pstring (PWCHAR nsidstr) const
return NULL;
RtlInitEmptyUnicodeString (&sid, nsidstr, 256);
RtlConvertSidToUnicodeString (&sid, psid, FALSE);
- return nsidstr + sid.Length / sizeof (WCHAR);
-}
-
-PWCHAR
-cygpsid::string (PWCHAR nsidstr) const
-{
- if (pstring (nsidstr))
- return nsidstr;
- return NULL;
+ return nsidstr;
}
char *
-cygpsid::pstring (char *nsidstr) const
+cygpsid::string (char *nsidstr) const
{
char *t;
DWORD i;
@@ -197,18 +147,10 @@ cygpsid::pstring (char *nsidstr) const
return NULL;
strcpy (nsidstr, "S-1-");
t = nsidstr + sizeof ("S-1-") - 1;
- t += __small_sprintf (t, "%u", sid_id_auth (psid));
- for (i = 0; i < sid_sub_auth_count (psid); ++i)
- t += __small_sprintf (t, "-%lu", sid_sub_auth (psid, i));
- return t;
-}
-
-char *
-cygpsid::string (char *nsidstr) const
-{
- if (pstring (nsidstr))
- return nsidstr;
- return NULL;
+ t += __small_sprintf (t, "%u", RtlIdentifierAuthoritySid (psid)->Value[5]);
+ for (i = 0; i < *RtlSubAuthorityCountSid (psid); ++i)
+ t += __small_sprintf (t, "-%lu", *RtlSubAuthoritySid (psid, i));
+ return nsidstr;
}
PSID
@@ -218,7 +160,7 @@ cygsid::get_sid (DWORD s, DWORD cnt, DWORD *r, bool well_known)
SID_IDENTIFIER_AUTHORITY sid_auth = { SECURITY_NULL_SID_AUTHORITY };
# define SECURITY_NT_AUTH 5
- if (s > 255 || cnt < 1 || cnt > SID_MAX_SUB_AUTHORITIES)
+ if (s > 255 || cnt < 1 || cnt > 8)
{
psid = NO_SID;
return NULL;
@@ -226,9 +168,8 @@ cygsid::get_sid (DWORD s, DWORD cnt, DWORD *r, bool well_known)
sid_auth.Value[5] = s;
set ();
RtlInitializeSid (psid, &sid_auth, cnt);
- PISID dsid = (PISID) psid;
for (i = 0; i < cnt; ++i)
- dsid->SubAuthority[i] = r[i];
+ memcpy ((char *) psid + 8 + sizeof (DWORD) * i, &r[i], sizeof (DWORD));
/* If the well_known flag isn't set explicitely, we check the SID
for being a well-known SID ourselves. That's necessary because this
cygsid is created from a SID string, usually from /etc/passwd or
@@ -244,34 +185,16 @@ cygsid::get_sid (DWORD s, DWORD cnt, DWORD *r, bool well_known)
}
const PSID
-cygsid::getfromstr (PCWSTR nsidstr, bool well_known)
-{
- PWCHAR lasts;
- DWORD s, cnt = 0;
- DWORD r[SID_MAX_SUB_AUTHORITIES];
-
- if (nsidstr && !wcsncmp (nsidstr, L"S-1-", 4))
- {
- s = wcstoul (nsidstr + 4, &lasts, 10);
- while (cnt < SID_MAX_SUB_AUTHORITIES && *lasts == '-')
- r[cnt++] = wcstoul (lasts + 1, &lasts, 10);
- if (!*lasts)
- return get_sid (s, cnt, r, well_known);
- }
- return psid = NO_SID;
-}
-
-const PSID
cygsid::getfromstr (const char *nsidstr, bool well_known)
{
char *lasts;
DWORD s, cnt = 0;
- DWORD r[SID_MAX_SUB_AUTHORITIES];
+ DWORD r[8];
if (nsidstr && !strncmp (nsidstr, "S-1-", 4))
{
s = strtoul (nsidstr + 4, &lasts, 10);
- while (cnt < SID_MAX_SUB_AUTHORITIES && *lasts == '-')
+ while (cnt < 8 && *lasts == '-')
r[cnt++] = strtoul (lasts + 1, &lasts, 10);
if (!*lasts)
return get_sid (s, cnt, r, well_known);
@@ -338,24 +261,41 @@ cygsidlist::add (const PSID nsi, bool well_known)
bool
get_sids_info (cygpsid owner_sid, cygpsid group_sid, uid_t * uidret, gid_t * gidret)
{
- BOOL ret = false;
- cyg_ldap cldap;
+ struct passwd *pw;
+ struct group *gr = NULL;
+ bool ret = false;
owner_sid.debug_print ("get_sids_info: owner SID =");
group_sid.debug_print ("get_sids_info: group SID =");
- *uidret = owner_sid.get_uid (&cldap);
- *gidret = group_sid.get_gid (&cldap);
- if (*uidret == myself->uid)
+ if (group_sid == cygheap->user.groups.pgsid)
+ *gidret = myself->gid;
+ else if ((gr = internal_getgrsid (group_sid)))
+ *gidret = gr->gr_gid;
+ else
+ *gidret = ILLEGAL_GID;
+
+ if (owner_sid == cygheap->user.sid ())
{
+ *uidret = myself->uid;
if (*gidret == myself->gid)
- ret = TRUE;
+ ret = true;
else
- CheckTokenMembership (cygheap->user.issetuid ()
- ? cygheap->user.imp_token () : NULL,
- group_sid, &ret);
+ ret = (internal_getgroups (0, NULL, &group_sid) > 0);
+ }
+ else if ((pw = internal_getpwsid (owner_sid)))
+ {
+ *uidret = pw->pw_uid;
+ if (gr || (*gidret != ILLEGAL_GID
+ && (gr = internal_getgrgid (*gidret))))
+ for (int idx = 0; gr->gr_mem[idx]; ++idx)
+ if ((ret = strcasematch (pw->pw_name, gr->gr_mem[idx])))
+ break;
}
- return (bool) ret;
+ else
+ *uidret = ILLEGAL_UID;
+
+ return ret;
}
PSECURITY_DESCRIPTOR
diff --git a/winsup/cygwin/security.cc b/winsup/cygwin/security.cc
index 07b3fa00d..251e9609e 100644
--- a/winsup/cygwin/security.cc
+++ b/winsup/cygwin/security.cc
@@ -1,7 +1,7 @@
/* security.cc: NT file access control functions
Copyright 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007,
- 2008, 2009, 2010, 2011, 2012, 2013, 2014 Red Hat, Inc.
+ 2008, 2009, 2010, 2011, 2012, 2013 Red Hat, Inc.
Originaly written by Gunther Ebert, gunther.ebert@ixos-leipzig.de
Completely rewritten by Corinna Vinschen <corinna@vinschen.de>
@@ -23,6 +23,7 @@ details. */
#include "pinfo.h"
#include "cygheap.h"
#include "ntdll.h"
+#include "pwdgrp.h"
#include "tls_pbuf.h"
#include <aclapi.h>
@@ -1046,95 +1047,6 @@ check_access (security_descriptor &sd, GENERIC_MAPPING &mapping,
return ret;
}
-/* Samba override. Check security descriptor for Samba UNIX user and group
- accounts and check if we have an RFC 2307 mapping to a Windows account.
- Create a new security descriptor with all of the UNIX acocunts with
- valid mapping replaced with their WIndows counterpart. */
-static void
-convert_samba_sd (security_descriptor &sd_ret)
-{
- NTSTATUS status;
- BOOLEAN dummy;
- PSID sid;
- cygsid owner;
- cygsid group;
- SECURITY_DESCRIPTOR sd;
- cyg_ldap cldap;
- tmp_pathbuf tp;
- PACL acl, oacl;
- size_t acl_len;
- PACCESS_ALLOWED_ACE ace;
-
- if (!NT_SUCCESS (RtlGetOwnerSecurityDescriptor (sd_ret, &sid, &dummy)))
- return;
- owner = sid;
- if (!NT_SUCCESS (RtlGetGroupSecurityDescriptor (sd_ret, &sid, &dummy)))
- return;
- group = sid;
-
- if (sid_id_auth (owner) == 22)
- {
- struct passwd *pwd;
- uid_t uid = owner.get_uid (&cldap);
- if (uid < UNIX_POSIX_OFFSET && (pwd = internal_getpwuid (uid)))
- owner.getfrompw (pwd);
- }
- if (sid_id_auth (group) == 22)
- {
- struct group *grp;
- gid_t gid = group.get_gid (&cldap);
- if (gid < UNIX_POSIX_OFFSET && (grp = internal_getgrgid (gid)))
- group.getfromgr (grp);
- }
-
- if (!NT_SUCCESS (RtlGetDaclSecurityDescriptor (sd_ret, &dummy,
- &oacl, &dummy)))
- return;
- acl = (PACL) tp.w_get ();
- RtlCreateAcl (acl, ACL_MAXIMUM_SIZE, ACL_REVISION);
- acl_len = sizeof (ACL);
-
- for (DWORD i = 0; i < oacl->AceCount; ++i)
- if (NT_SUCCESS (RtlGetAce (oacl, i, (PVOID *) &ace)))
- {
- cygsid ace_sid ((PSID) &ace->SidStart);
- if (sid_id_auth (ace_sid) == 22)
- {
- if (sid_sub_auth (ace_sid, 0) == 1) /* user */
- {
- struct passwd *pwd;
- uid_t uid = ace_sid.get_uid (&cldap);
- if (uid < UNIX_POSIX_OFFSET && (pwd = internal_getpwuid (uid)))
- ace_sid.getfrompw (pwd);
- }
- else /* group */
- {
- struct group *grp;
- gid_t gid = ace_sid.get_gid (&cldap);
- if (gid < UNIX_POSIX_OFFSET && (grp = internal_getgrgid (gid)))
- ace_sid.getfromgr (grp);
- }
- if (!add_access_allowed_ace (acl, i, ace->Mask, ace_sid, acl_len,
- ace->Header.AceFlags))
- return;
- }
- }
- acl->AclSize = acl_len;
-
- RtlCreateSecurityDescriptor (&sd, SECURITY_DESCRIPTOR_REVISION);
- RtlSetControlSecurityDescriptor (&sd, SE_DACL_PROTECTED, SE_DACL_PROTECTED);
- RtlSetOwnerSecurityDescriptor (&sd, owner, FALSE);
- RtlSetGroupSecurityDescriptor (&sd, group, FALSE);
-
- status = RtlSetDaclSecurityDescriptor (&sd, TRUE, acl, FALSE);
- if (!NT_SUCCESS (status))
- return;
- DWORD sd_size = 0;
- status = RtlAbsoluteToSelfRelativeSD (&sd, sd_ret, &sd_size);
- if (sd_size > 0 && sd_ret.malloc (sd_size))
- RtlAbsoluteToSelfRelativeSD (&sd, sd_ret, &sd_size);
-}
-
int
check_file_access (path_conv &pc, int flags, bool effective)
{
@@ -1148,12 +1060,7 @@ check_file_access (path_conv &pc, int flags, bool effective)
if (flags & X_OK)
desired |= FILE_EXECUTE;
if (!get_file_sd (pc.handle (), pc, sd, false))
- {
- /* Tweak Samba security descriptor as necessary. */
- if (pc.fs_is_samba ())
- convert_samba_sd (sd);
- ret = check_access (sd, file_mapping, desired, flags, effective);
- }
+ ret = check_access (sd, file_mapping, desired, flags, effective);
debug_printf ("flags %y, ret %d", flags, ret);
return ret;
}
diff --git a/winsup/cygwin/security.h b/winsup/cygwin/security.h
index 6b6c33955..940afc5d7 100644
--- a/winsup/cygwin/security.h
+++ b/winsup/cygwin/security.h
@@ -12,41 +12,18 @@ details. */
#pragma once
#include <accctrl.h>
-#include <dsgetdc.h>
/* Special file attribute set, for instance, in open() and mkdir() to
flag that a file has just been created. Used in alloc_sd, see there. */
#define S_JUSTCREATED 0x80000000
-/* UID/GID */
-void uinfo_init ();
-
-#define ILLEGAL_UID ((uid_t)-1)
-#define ILLEGAL_GID ((gid_t)-1)
-
-/* For UNIX accounts not mapped to Windows accounts via winbind, Samba returns
- SIDs of the form S-1-22-x-y, with x == 1 for users and x == 2 for groups,
- and y == UNIX uid/gid. NFS returns no SIDs at all, but the plain UNIX
- uid/gid values.
-
- UNIX uid/gid values are mapped to Cygwin uid/gid values 0xff000000 +
- unix uid/gid. This *might* collide with a posix_offset of some trusted
- domain, but it's *very* unlikely. Define the mapping as macro. */
-#define UNIX_POSIX_OFFSET (0xff000000)
-#define UNIX_POSIX_MASK (0x00ffffff)
-#define MAP_UNIX_TO_CYGWIN_ID(id) (UNIX_POSIX_OFFSET \
- | ((id) & UNIX_POSIX_MASK))
-
-#ifndef __x86_64__
-#define ILLEGAL_UID16 ((__uid16_t)-1)
-#define ILLEGAL_GID16 ((__gid16_t)-1)
-#define uid16touid32(u16) ((u16)==ILLEGAL_UID16?ILLEGAL_UID:(uid_t)(u16))
-#define gid16togid32(g16) ((g16)==ILLEGAL_GID16?ILLEGAL_GID:(gid_t)(g16))
-#endif
+#define DEFAULT_UID DOMAIN_USER_RID_ADMIN
+#define UNKNOWN_UID 400 /* Non conflicting number */
+#define UNKNOWN_GID 401
+#define MAX_SID_LEN 40
#define MAX_DACL_LEN(n) (sizeof (ACL) \
- + (n) * (sizeof (ACCESS_ALLOWED_ACE) - sizeof (DWORD) \
- + SECURITY_MAX_SID_SIZE))
+ + (n) * (sizeof (ACCESS_ALLOWED_ACE) - sizeof (DWORD) + MAX_SID_LEN))
#define SD_MIN_SIZE (sizeof (SECURITY_DESCRIPTOR) + MAX_DACL_LEN (1))
#define ACL_MAXIMUM_SIZE 65532 /* Yeah, right. 64K - sizeof (DWORD). */
#define SD_MAXIMUM_SIZE 65536
@@ -98,7 +75,7 @@ typedef struct {
BYTE Revision;
BYTE SubAuthorityCount;
SID_IDENTIFIER_AUTHORITY IdentifierAuthority;
- DWORD SubAuthority[SID_MAX_SUB_AUTHORITIES];
+ DWORD SubAuthority[8];
} DBGSID, *PDBGSID;
/* Macro to define variable length SID structures */
@@ -115,16 +92,6 @@ cygpsid NO_COPY name = (PSID) &name##_struct;
#define FILE_WRITE_BITS (FILE_WRITE_DATA | GENERIC_WRITE | GENERIC_ALL)
#define FILE_EXEC_BITS (FILE_EXECUTE | GENERIC_EXECUTE | GENERIC_ALL)
-/* Convenience macros. The Windows SID access functions are crude. */
-#define sid_id_auth(s) \
- (RtlIdentifierAuthoritySid (s)->Value[5])
-#define sid_sub_auth_count(s) \
- (*RtlSubAuthorityCountSid ((s)))
-#define sid_sub_auth(s,i) \
- (*RtlSubAuthoritySid ((s),(i)))
-#define sid_sub_auth_rid(s) \
- (*RtlSubAuthoritySid ((s), (*RtlSubAuthorityCountSid ((s)) - 1)))
-
#ifdef __cplusplus
extern "C"
{
@@ -137,8 +104,6 @@ extern "C"
}
#endif
-class cyg_ldap;
-
class cygpsid {
protected:
PSID psid;
@@ -147,13 +112,11 @@ public:
cygpsid (PSID nsid) { psid = nsid; }
operator PSID () const { return psid; }
const PSID operator= (PSID nsid) { return psid = nsid;}
- uid_t get_id (BOOL search_grp, int *type, cyg_ldap *pldap);
- int get_uid (cyg_ldap *pldap) { return get_id (FALSE, NULL, pldap); }
- int get_gid (cyg_ldap *pldap) { return get_id (TRUE, NULL, pldap); }
+ uid_t get_id (BOOL search_grp, int *type = NULL);
+ int get_uid () { return get_id (FALSE); }
+ int get_gid () { return get_id (TRUE); }
- PWCHAR pstring (PWCHAR nsidstr) const;
PWCHAR string (PWCHAR nsidstr) const;
- char *pstring (char *nsidstr) const;
char *string (char *nsidstr) const;
bool operator== (const PSID nsid) const
@@ -176,10 +139,9 @@ public:
};
class cygsid : public cygpsid {
- char sbuf[SECURITY_MAX_SID_SIZE];
+ char sbuf[MAX_SID_LEN];
bool well_known_sid;
- const PSID getfromstr (PCWSTR nsidstr, bool well_known);
const PSID getfromstr (const char *nsidstr, bool well_known);
PSID get_sid (DWORD s, DWORD cnt, DWORD *r, bool well_known);
@@ -190,7 +152,7 @@ class cygsid : public cygpsid {
else
{
psid = (PSID) sbuf;
- RtlCopySid (SECURITY_MAX_SID_SIZE, psid, nsid);
+ RtlCopySid (MAX_SID_LEN, psid, nsid);
well_known_sid = well_known;
}
return psid;
@@ -207,23 +169,18 @@ public:
{ return assign (nsid, nsid.well_known_sid); }
inline const PSID operator= (const PSID nsid)
{ return assign (nsid, false); }
- inline const PSID operator= (PCWSTR nsidstr)
- { return getfromstr (nsidstr, false); }
inline const PSID operator= (const char *nsidstr)
{ return getfromstr (nsidstr, false); }
inline const PSID operator*= (cygsid &nsid)
{ return assign (nsid, true); }
inline const PSID operator*= (const PSID nsid)
{ return assign (nsid, true); }
- inline const PSID operator*= (PCWSTR nsidstr)
- { return getfromstr (nsidstr, true); }
inline const PSID operator*= (const char *nsidstr)
{ return getfromstr (nsidstr, true); }
inline cygsid () : cygpsid ((PSID) sbuf), well_known_sid (false) {}
inline cygsid (const PSID nsid) { *this = nsid; }
inline cygsid (const char *nstrsid) { *this = nstrsid; }
- inline cygsid (cygsid &nsid) { *this = nsid; }
inline PSID set () { return psid = (PSID) sbuf; }
@@ -384,12 +341,9 @@ extern cygpsid well_known_service_sid;
extern cygpsid well_known_authenticated_users_sid;
extern cygpsid well_known_this_org_sid;
extern cygpsid well_known_system_sid;
-extern cygpsid well_known_local_service_sid;
-extern cygpsid well_known_network_service_sid;
extern cygpsid well_known_builtin_sid;
extern cygpsid well_known_admins_sid;
extern cygpsid well_known_users_sid;
-extern cygpsid trusted_installer_sid;
extern cygpsid mandatory_medium_integrity_sid;
extern cygpsid mandatory_high_integrity_sid;
extern cygpsid mandatory_system_integrity_sid;
@@ -460,7 +414,7 @@ bool get_server_groups (cygsidlist &grp_list, PSID usersid, struct passwd *pw);
/* Extract U-domain\user field from passwd entry. */
void extract_nt_dom_user (const struct passwd *pw, PWCHAR domain, PWCHAR user);
/* Get default logonserver for a domain. */
-bool get_logon_server (PWCHAR domain, PWCHAR wserver, ULONG flags);
+bool get_logon_server (PWCHAR domain, PWCHAR wserver, bool rediscovery);
HANDLE lsa_open_policy (PWCHAR server, ACCESS_MASK access);
void lsa_close_policy (HANDLE lsa);
diff --git a/winsup/cygwin/setlsapwd.cc b/winsup/cygwin/setlsapwd.cc
index eb3b9e6bf..5bc5c5e25 100644
--- a/winsup/cygwin/setlsapwd.cc
+++ b/winsup/cygwin/setlsapwd.cc
@@ -17,6 +17,7 @@ details. */
#include "cygheap.h"
#include "security.h"
#include "cygserver_setpwd.h"
+#include "pwdgrp.h"
#include "ntdll.h"
#include <ntsecapi.h>
#include <stdlib.h>
@@ -50,7 +51,7 @@ setlsapwd (const char *passwd, const char *username)
if (username)
{
cygsid psid;
- struct passwd *pw = internal_getpwnam (username);
+ struct passwd *pw = internal_getpwnam (username, false);
if (!pw || !psid.getfrompw (pw))
{
@@ -93,7 +94,7 @@ setlsapwd (const char *passwd, const char *username)
}
if (data_buf)
{
- RtlSecureZeroMemory (data.Buffer, data.Length);
+ memset (data.Buffer, 0, data.Length);
free (data_buf);
}
}
diff --git a/winsup/cygwin/shared.cc b/winsup/cygwin/shared.cc
index 9f1f27cd9..2f5a45376 100644
--- a/winsup/cygwin/shared.cc
+++ b/winsup/cygwin/shared.cc
@@ -22,6 +22,7 @@ details. */
#include "shared_info_magic.h"
#include "registry.h"
#include "cygwin_version.h"
+#include "pwdgrp.h"
#include "spinlock.h"
#include <alloca.h>
#include <wchar.h>
@@ -351,7 +352,6 @@ memory_init (bool init_cygheap)
cygheap_init ();
cygheap->user.init ();
cygheap->init_installation_root (); /* Requires user.init! */
- cygheap->pg.init ();
}
shared_info::create (); /* Initialize global shared memory */
diff --git a/winsup/cygwin/syscalls.cc b/winsup/cygwin/syscalls.cc
index 9edacd520..2de58205b 100644
--- a/winsup/cygwin/syscalls.cc
+++ b/winsup/cygwin/syscalls.cc
@@ -58,6 +58,7 @@ details. */
#include "pinfo.h"
#include "shared_info.h"
#include "cygheap.h"
+#include "pwdgrp.h"
#include "cpuid.h"
#include "registry.h"
#include "environ.h"
diff --git a/winsup/cygwin/thread.cc b/winsup/cygwin/thread.cc
index fc70c3752..dc4faac7c 100644
--- a/winsup/cygwin/thread.cc
+++ b/winsup/cygwin/thread.cc
@@ -358,6 +358,10 @@ pthread::init_mainthread ()
if (!thread->create_cancel_event ())
api_fatal ("couldn't create cancel event for main thread");
VerifyHandle (thread->win32_obj_id);
+ /* Make sure the pthread mutex is recursive. See comment in
+ pthread::precreate (called only for subsequent pthreads)
+ for a description. */
+ thread->mutex.set_type (PTHREAD_MUTEX_RECURSIVE);
thread->postcreate ();
}
diff --git a/winsup/cygwin/tlsoffsets.h b/winsup/cygwin/tlsoffsets.h
index 572dfb7b7..402638e59 100644
--- a/winsup/cygwin/tlsoffsets.h
+++ b/winsup/cygwin/tlsoffsets.h
@@ -3,115 +3,115 @@
//; $tls::start_offset = -12700;
//; $tls::locals = -12700;
//; $tls::plocals = 0;
-//; $tls::local_clib = -10980;
-//; $tls::plocal_clib = 1720;
-//; $tls::__dontuse = -10980;
-//; $tls::p__dontuse = 1720;
-//; $tls::func = -9892;
-//; $tls::pfunc = 2808;
-//; $tls::saved_errno = -9888;
-//; $tls::psaved_errno = 2812;
-//; $tls::sa_flags = -9884;
-//; $tls::psa_flags = 2816;
-//; $tls::oldmask = -9880;
-//; $tls::poldmask = 2820;
-//; $tls::deltamask = -9876;
-//; $tls::pdeltamask = 2824;
-//; $tls::errno_addr = -9872;
-//; $tls::perrno_addr = 2828;
-//; $tls::sigmask = -9868;
-//; $tls::psigmask = 2832;
-//; $tls::sigwait_mask = -9864;
-//; $tls::psigwait_mask = 2836;
-//; $tls::sigwait_info = -9860;
-//; $tls::psigwait_info = 2840;
-//; $tls::signal_arrived = -9856;
-//; $tls::psignal_arrived = 2844;
-//; $tls::will_wait_for_signal = -9852;
-//; $tls::pwill_wait_for_signal = 2848;
-//; $tls::thread_context = -9848;
-//; $tls::pthread_context = 2852;
-//; $tls::thread_id = -9636;
-//; $tls::pthread_id = 3064;
-//; $tls::infodata = -9632;
-//; $tls::pinfodata = 3068;
-//; $tls::tid = -9484;
-//; $tls::ptid = 3216;
-//; $tls::_ctinfo = -9480;
-//; $tls::p_ctinfo = 3220;
-//; $tls::andreas = -9476;
-//; $tls::pandreas = 3224;
-//; $tls::wq = -9472;
-//; $tls::pwq = 3228;
-//; $tls::sig = -9444;
-//; $tls::psig = 3256;
-//; $tls::incyg = -9440;
-//; $tls::pincyg = 3260;
-//; $tls::spinning = -9436;
-//; $tls::pspinning = 3264;
-//; $tls::stacklock = -9432;
-//; $tls::pstacklock = 3268;
-//; $tls::stackptr = -9428;
-//; $tls::pstackptr = 3272;
-//; $tls::stack = -9424;
-//; $tls::pstack = 3276;
-//; $tls::initialized = -8400;
-//; $tls::pinitialized = 4300;
+//; $tls::local_clib = -10940;
+//; $tls::plocal_clib = 1760;
+//; $tls::__dontuse = -10940;
+//; $tls::p__dontuse = 1760;
+//; $tls::func = -9852;
+//; $tls::pfunc = 2848;
+//; $tls::saved_errno = -9848;
+//; $tls::psaved_errno = 2852;
+//; $tls::sa_flags = -9844;
+//; $tls::psa_flags = 2856;
+//; $tls::oldmask = -9840;
+//; $tls::poldmask = 2860;
+//; $tls::deltamask = -9836;
+//; $tls::pdeltamask = 2864;
+//; $tls::errno_addr = -9832;
+//; $tls::perrno_addr = 2868;
+//; $tls::sigmask = -9828;
+//; $tls::psigmask = 2872;
+//; $tls::sigwait_mask = -9824;
+//; $tls::psigwait_mask = 2876;
+//; $tls::sigwait_info = -9820;
+//; $tls::psigwait_info = 2880;
+//; $tls::signal_arrived = -9816;
+//; $tls::psignal_arrived = 2884;
+//; $tls::will_wait_for_signal = -9812;
+//; $tls::pwill_wait_for_signal = 2888;
+//; $tls::thread_context = -9808;
+//; $tls::pthread_context = 2892;
+//; $tls::thread_id = -9596;
+//; $tls::pthread_id = 3104;
+//; $tls::infodata = -9592;
+//; $tls::pinfodata = 3108;
+//; $tls::tid = -9444;
+//; $tls::ptid = 3256;
+//; $tls::_ctinfo = -9440;
+//; $tls::p_ctinfo = 3260;
+//; $tls::andreas = -9436;
+//; $tls::pandreas = 3264;
+//; $tls::wq = -9432;
+//; $tls::pwq = 3268;
+//; $tls::sig = -9404;
+//; $tls::psig = 3296;
+//; $tls::incyg = -9400;
+//; $tls::pincyg = 3300;
+//; $tls::spinning = -9396;
+//; $tls::pspinning = 3304;
+//; $tls::stacklock = -9392;
+//; $tls::pstacklock = 3308;
+//; $tls::stackptr = -9388;
+//; $tls::pstackptr = 3312;
+//; $tls::stack = -9384;
+//; $tls::pstack = 3316;
+//; $tls::initialized = -8360;
+//; $tls::pinitialized = 4340;
//; __DATA__
#define tls_locals (-12700)
#define tls_plocals (0)
-#define tls_local_clib (-10980)
-#define tls_plocal_clib (1720)
-#define tls___dontuse (-10980)
-#define tls_p__dontuse (1720)
-#define tls_func (-9892)
-#define tls_pfunc (2808)
-#define tls_saved_errno (-9888)
-#define tls_psaved_errno (2812)
-#define tls_sa_flags (-9884)
-#define tls_psa_flags (2816)
-#define tls_oldmask (-9880)
-#define tls_poldmask (2820)
-#define tls_deltamask (-9876)
-#define tls_pdeltamask (2824)
-#define tls_errno_addr (-9872)
-#define tls_perrno_addr (2828)
-#define tls_sigmask (-9868)
-#define tls_psigmask (2832)
-#define tls_sigwait_mask (-9864)
-#define tls_psigwait_mask (2836)
-#define tls_sigwait_info (-9860)
-#define tls_psigwait_info (2840)
-#define tls_signal_arrived (-9856)
-#define tls_psignal_arrived (2844)
-#define tls_will_wait_for_signal (-9852)
-#define tls_pwill_wait_for_signal (2848)
-#define tls_thread_context (-9848)
-#define tls_pthread_context (2852)
-#define tls_thread_id (-9636)
-#define tls_pthread_id (3064)
-#define tls_infodata (-9632)
-#define tls_pinfodata (3068)
-#define tls_tid (-9484)
-#define tls_ptid (3216)
-#define tls__ctinfo (-9480)
-#define tls_p_ctinfo (3220)
-#define tls_andreas (-9476)
-#define tls_pandreas (3224)
-#define tls_wq (-9472)
-#define tls_pwq (3228)
-#define tls_sig (-9444)
-#define tls_psig (3256)
-#define tls_incyg (-9440)
-#define tls_pincyg (3260)
-#define tls_spinning (-9436)
-#define tls_pspinning (3264)
-#define tls_stacklock (-9432)
-#define tls_pstacklock (3268)
-#define tls_stackptr (-9428)
-#define tls_pstackptr (3272)
-#define tls_stack (-9424)
-#define tls_pstack (3276)
-#define tls_initialized (-8400)
-#define tls_pinitialized (4300)
+#define tls_local_clib (-10940)
+#define tls_plocal_clib (1760)
+#define tls___dontuse (-10940)
+#define tls_p__dontuse (1760)
+#define tls_func (-9852)
+#define tls_pfunc (2848)
+#define tls_saved_errno (-9848)
+#define tls_psaved_errno (2852)
+#define tls_sa_flags (-9844)
+#define tls_psa_flags (2856)
+#define tls_oldmask (-9840)
+#define tls_poldmask (2860)
+#define tls_deltamask (-9836)
+#define tls_pdeltamask (2864)
+#define tls_errno_addr (-9832)
+#define tls_perrno_addr (2868)
+#define tls_sigmask (-9828)
+#define tls_psigmask (2872)
+#define tls_sigwait_mask (-9824)
+#define tls_psigwait_mask (2876)
+#define tls_sigwait_info (-9820)
+#define tls_psigwait_info (2880)
+#define tls_signal_arrived (-9816)
+#define tls_psignal_arrived (2884)
+#define tls_will_wait_for_signal (-9812)
+#define tls_pwill_wait_for_signal (2888)
+#define tls_thread_context (-9808)
+#define tls_pthread_context (2892)
+#define tls_thread_id (-9596)
+#define tls_pthread_id (3104)
+#define tls_infodata (-9592)
+#define tls_pinfodata (3108)
+#define tls_tid (-9444)
+#define tls_ptid (3256)
+#define tls__ctinfo (-9440)
+#define tls_p_ctinfo (3260)
+#define tls_andreas (-9436)
+#define tls_pandreas (3264)
+#define tls_wq (-9432)
+#define tls_pwq (3268)
+#define tls_sig (-9404)
+#define tls_psig (3296)
+#define tls_incyg (-9400)
+#define tls_pincyg (3300)
+#define tls_spinning (-9396)
+#define tls_pspinning (3304)
+#define tls_stacklock (-9392)
+#define tls_pstacklock (3308)
+#define tls_stackptr (-9388)
+#define tls_pstackptr (3312)
+#define tls_stack (-9384)
+#define tls_pstack (3316)
+#define tls_initialized (-8360)
+#define tls_pinitialized (4340)
diff --git a/winsup/cygwin/tlsoffsets64.h b/winsup/cygwin/tlsoffsets64.h
index 991280663..7df2c988b 100644
--- a/winsup/cygwin/tlsoffsets64.h
+++ b/winsup/cygwin/tlsoffsets64.h
@@ -3,115 +3,115 @@
//; $tls::start_offset = -12800;
//; $tls::locals = -12800;
//; $tls::plocals = 0;
-//; $tls::local_clib = -10624;
-//; $tls::plocal_clib = 2176;
-//; $tls::__dontuse = -10624;
-//; $tls::p__dontuse = 2176;
-//; $tls::func = -8736;
-//; $tls::pfunc = 4064;
-//; $tls::saved_errno = -8728;
-//; $tls::psaved_errno = 4072;
-//; $tls::sa_flags = -8724;
-//; $tls::psa_flags = 4076;
-//; $tls::oldmask = -8720;
-//; $tls::poldmask = 4080;
-//; $tls::deltamask = -8712;
-//; $tls::pdeltamask = 4088;
-//; $tls::errno_addr = -8704;
-//; $tls::perrno_addr = 4096;
-//; $tls::sigmask = -8696;
-//; $tls::psigmask = 4104;
-//; $tls::sigwait_mask = -8688;
-//; $tls::psigwait_mask = 4112;
-//; $tls::sigwait_info = -8680;
-//; $tls::psigwait_info = 4120;
-//; $tls::signal_arrived = -8672;
-//; $tls::psignal_arrived = 4128;
-//; $tls::will_wait_for_signal = -8664;
-//; $tls::pwill_wait_for_signal = 4136;
-//; $tls::thread_context = -8656;
-//; $tls::pthread_context = 4144;
-//; $tls::thread_id = -7824;
-//; $tls::pthread_id = 4976;
-//; $tls::infodata = -7820;
-//; $tls::pinfodata = 4980;
-//; $tls::tid = -7672;
-//; $tls::ptid = 5128;
-//; $tls::_ctinfo = -7664;
-//; $tls::p_ctinfo = 5136;
-//; $tls::andreas = -7656;
-//; $tls::pandreas = 5144;
-//; $tls::wq = -7648;
-//; $tls::pwq = 5152;
-//; $tls::sig = -7600;
-//; $tls::psig = 5200;
-//; $tls::incyg = -7596;
-//; $tls::pincyg = 5204;
-//; $tls::spinning = -7592;
-//; $tls::pspinning = 5208;
-//; $tls::stacklock = -7588;
-//; $tls::pstacklock = 5212;
-//; $tls::stackptr = -7584;
-//; $tls::pstackptr = 5216;
-//; $tls::stack = -7576;
-//; $tls::pstack = 5224;
-//; $tls::initialized = -5528;
-//; $tls::pinitialized = 7272;
+//; $tls::local_clib = -10560;
+//; $tls::plocal_clib = 2240;
+//; $tls::__dontuse = -10560;
+//; $tls::p__dontuse = 2240;
+//; $tls::func = -8672;
+//; $tls::pfunc = 4128;
+//; $tls::saved_errno = -8664;
+//; $tls::psaved_errno = 4136;
+//; $tls::sa_flags = -8660;
+//; $tls::psa_flags = 4140;
+//; $tls::oldmask = -8656;
+//; $tls::poldmask = 4144;
+//; $tls::deltamask = -8648;
+//; $tls::pdeltamask = 4152;
+//; $tls::errno_addr = -8640;
+//; $tls::perrno_addr = 4160;
+//; $tls::sigmask = -8632;
+//; $tls::psigmask = 4168;
+//; $tls::sigwait_mask = -8624;
+//; $tls::psigwait_mask = 4176;
+//; $tls::sigwait_info = -8616;
+//; $tls::psigwait_info = 4184;
+//; $tls::signal_arrived = -8608;
+//; $tls::psignal_arrived = 4192;
+//; $tls::will_wait_for_signal = -8600;
+//; $tls::pwill_wait_for_signal = 4200;
+//; $tls::thread_context = -8592;
+//; $tls::pthread_context = 4208;
+//; $tls::thread_id = -7760;
+//; $tls::pthread_id = 5040;
+//; $tls::infodata = -7756;
+//; $tls::pinfodata = 5044;
+//; $tls::tid = -7608;
+//; $tls::ptid = 5192;
+//; $tls::_ctinfo = -7600;
+//; $tls::p_ctinfo = 5200;
+//; $tls::andreas = -7592;
+//; $tls::pandreas = 5208;
+//; $tls::wq = -7584;
+//; $tls::pwq = 5216;
+//; $tls::sig = -7536;
+//; $tls::psig = 5264;
+//; $tls::incyg = -7532;
+//; $tls::pincyg = 5268;
+//; $tls::spinning = -7528;
+//; $tls::pspinning = 5272;
+//; $tls::stacklock = -7524;
+//; $tls::pstacklock = 5276;
+//; $tls::stackptr = -7520;
+//; $tls::pstackptr = 5280;
+//; $tls::stack = -7512;
+//; $tls::pstack = 5288;
+//; $tls::initialized = -5464;
+//; $tls::pinitialized = 7336;
//; __DATA__
#define tls_locals (-12800)
#define tls_plocals (0)
-#define tls_local_clib (-10624)
-#define tls_plocal_clib (2176)
-#define tls___dontuse (-10624)
-#define tls_p__dontuse (2176)
-#define tls_func (-8736)
-#define tls_pfunc (4064)
-#define tls_saved_errno (-8728)
-#define tls_psaved_errno (4072)
-#define tls_sa_flags (-8724)
-#define tls_psa_flags (4076)
-#define tls_oldmask (-8720)
-#define tls_poldmask (4080)
-#define tls_deltamask (-8712)
-#define tls_pdeltamask (4088)
-#define tls_errno_addr (-8704)
-#define tls_perrno_addr (4096)
-#define tls_sigmask (-8696)
-#define tls_psigmask (4104)
-#define tls_sigwait_mask (-8688)
-#define tls_psigwait_mask (4112)
-#define tls_sigwait_info (-8680)
-#define tls_psigwait_info (4120)
-#define tls_signal_arrived (-8672)
-#define tls_psignal_arrived (4128)
-#define tls_will_wait_for_signal (-8664)
-#define tls_pwill_wait_for_signal (4136)
-#define tls_thread_context (-8656)
-#define tls_pthread_context (4144)
-#define tls_thread_id (-7824)
-#define tls_pthread_id (4976)
-#define tls_infodata (-7820)
-#define tls_pinfodata (4980)
-#define tls_tid (-7672)
-#define tls_ptid (5128)
-#define tls__ctinfo (-7664)
-#define tls_p_ctinfo (5136)
-#define tls_andreas (-7656)
-#define tls_pandreas (5144)
-#define tls_wq (-7648)
-#define tls_pwq (5152)
-#define tls_sig (-7600)
-#define tls_psig (5200)
-#define tls_incyg (-7596)
-#define tls_pincyg (5204)
-#define tls_spinning (-7592)
-#define tls_pspinning (5208)
-#define tls_stacklock (-7588)
-#define tls_pstacklock (5212)
-#define tls_stackptr (-7584)
-#define tls_pstackptr (5216)
-#define tls_stack (-7576)
-#define tls_pstack (5224)
-#define tls_initialized (-5528)
-#define tls_pinitialized (7272)
+#define tls_local_clib (-10560)
+#define tls_plocal_clib (2240)
+#define tls___dontuse (-10560)
+#define tls_p__dontuse (2240)
+#define tls_func (-8672)
+#define tls_pfunc (4128)
+#define tls_saved_errno (-8664)
+#define tls_psaved_errno (4136)
+#define tls_sa_flags (-8660)
+#define tls_psa_flags (4140)
+#define tls_oldmask (-8656)
+#define tls_poldmask (4144)
+#define tls_deltamask (-8648)
+#define tls_pdeltamask (4152)
+#define tls_errno_addr (-8640)
+#define tls_perrno_addr (4160)
+#define tls_sigmask (-8632)
+#define tls_psigmask (4168)
+#define tls_sigwait_mask (-8624)
+#define tls_psigwait_mask (4176)
+#define tls_sigwait_info (-8616)
+#define tls_psigwait_info (4184)
+#define tls_signal_arrived (-8608)
+#define tls_psignal_arrived (4192)
+#define tls_will_wait_for_signal (-8600)
+#define tls_pwill_wait_for_signal (4200)
+#define tls_thread_context (-8592)
+#define tls_pthread_context (4208)
+#define tls_thread_id (-7760)
+#define tls_pthread_id (5040)
+#define tls_infodata (-7756)
+#define tls_pinfodata (5044)
+#define tls_tid (-7608)
+#define tls_ptid (5192)
+#define tls__ctinfo (-7600)
+#define tls_p_ctinfo (5200)
+#define tls_andreas (-7592)
+#define tls_pandreas (5208)
+#define tls_wq (-7584)
+#define tls_pwq (5216)
+#define tls_sig (-7536)
+#define tls_psig (5264)
+#define tls_incyg (-7532)
+#define tls_pincyg (5268)
+#define tls_spinning (-7528)
+#define tls_pspinning (5272)
+#define tls_stacklock (-7524)
+#define tls_pstacklock (5276)
+#define tls_stackptr (-7520)
+#define tls_pstackptr (5280)
+#define tls_stack (-7512)
+#define tls_pstack (5288)
+#define tls_initialized (-5464)
+#define tls_pinitialized (7336)
diff --git a/winsup/cygwin/uinfo.cc b/winsup/cygwin/uinfo.cc
index b9d893794..4ca901f35 100644
--- a/winsup/cygwin/uinfo.cc
+++ b/winsup/cygwin/uinfo.cc
@@ -1,7 +1,7 @@
/* uinfo.cc: user info (uid, gid, etc...)
Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006,
- 2007, 2008, 2009, 2010, 2011, 2012, 2014 Red Hat, Inc.
+ 2007, 2008, 2009, 2010, 2011, 2012 Red Hat, Inc.
This file is part of Cygwin.
@@ -10,14 +10,12 @@ Cygwin license. Please consult the file "CYGWIN_LICENSE" for
details. */
#include "winsup.h"
-#include <iptypes.h>
-#include <lm.h>
-#include <ntsecapi.h>
-#include <wininet.h>
#include <unistd.h>
+#include <wininet.h>
#include <stdlib.h>
-#include <stdio.h>
#include <wchar.h>
+#include <lm.h>
+#include <iptypes.h>
#include <sys/cygwin.h>
#include "cygerrno.h"
#include "pinfo.h"
@@ -29,11 +27,9 @@ details. */
#include "registry.h"
#include "child_info.h"
#include "environ.h"
+#include "pwdgrp.h"
#include "tls_pbuf.h"
-#include "miscfuncs.h"
#include "ntdll.h"
-#include "ldap.h"
-#include "cygserver_pwdgrp.h"
/* Initialize the part of cygheap_user that does not depend on files.
The information is used in shared.cc for the user shared.
@@ -85,7 +81,7 @@ cygheap_user::init ()
status = NtSetInformationToken (hProcToken, TokenOwner, &effec_cygsid,
sizeof (cygsid));
if (!NT_SUCCESS (status))
- debug_printf ("NtSetInformationToken (TokenOwner), %y", status);
+ debug_printf ("NtSetInformationToken(TokenOwner), %y", status);
/* Standard way to build a security descriptor with the usual DACL */
PSECURITY_ATTRIBUTES sa_buf = (PSECURITY_ATTRIBUTES) alloca (1024);
@@ -116,63 +112,41 @@ cygheap_user::init ()
void
internal_getlogin (cygheap_user &user)
{
- struct passwd *pwd;
- struct group *pgrp, *grp, *grp2;
- cyg_ldap cldap;
-
- /* Fetch (and potentially generate) passwd and group entries for the user
- and the primary group in the token. */
- pwd = internal_getpwsid (user.sid (), &cldap);
- pgrp = internal_getgrsid (user.groups.pgsid, &cldap);
- if (!cygheap->pg.nss_cygserver_caching ())
- internal_getgroups (0, NULL, &cldap);
- if (!pwd)
- debug_printf ("user not found in passwd DB");
+ struct passwd *pw = NULL;
+
+ cygpsid psid = user.sid ();
+ pw = internal_getpwsid (psid);
+
+ if (!pw && !(pw = internal_getpwnam (user.name ()))
+ && !(pw = internal_getpwuid (DEFAULT_UID)))
+ debug_printf ("user not found in augmented /etc/passwd");
else
{
cygsid gsid;
- user.set_name (pwd->pw_name);
- myself->uid = pwd->pw_uid;
- myself->gid = pwd->pw_gid;
- /* If the primary group in the passwd DB is different from the primary
- group in the user token, we have to find the SID of that group and
- try to override the token primary group. */
- if (!pgrp || myself->gid != pgrp->gr_gid)
+ myself->uid = pw->pw_uid;
+ myself->gid = pw->pw_gid;
+ user.set_name (pw->pw_name);
+ if (gsid.getfromgr (internal_getgrgid (pw->pw_gid)))
{
- if (gsid.getfromgr (grp = internal_getgrgid (pwd->pw_gid, &cldap)))
+ if (gsid != user.groups.pgsid)
{
- /* We might have a group file with a group entry for the current
- user's primary group, but the current user has no entry in
- passwd. If so, pw_gid is taken from windows and might
- disagree with gr_gid from the group file. Overwrite it. */
- if ((grp2 = internal_getgrsid (gsid, &cldap)) && grp2 != grp)
- myself->gid = pwd->pw_gid = grp2->gr_gid;
/* Set primary group to the group in /etc/passwd. */
- if (gsid != user.groups.pgsid)
- {
- NTSTATUS status = NtSetInformationToken (hProcToken,
- TokenPrimaryGroup,
- &gsid, sizeof gsid);
- if (!NT_SUCCESS (status))
- {
- debug_printf ("NtSetInformationToken (TokenPrimaryGroup),"
- " %y", status);
- /* Revert the primary group setting and override the
- setting in the passwd entry. */
- if (pgrp)
- myself->gid = pwd->pw_gid = pgrp->gr_gid;
- }
- else
- user.groups.pgsid = gsid;
- clear_procimptoken ();
- }
+ NTSTATUS status = NtSetInformationToken (hProcToken,
+ TokenPrimaryGroup,
+ &gsid, sizeof gsid);
+ if (!NT_SUCCESS (status))
+ debug_printf ("NtSetInformationToken (TokenPrimaryGroup), %y",
+ status);
+ else
+ user.groups.pgsid = gsid;
+ clear_procimptoken ();
}
- else
- debug_printf ("group not found in group DB");
}
+ else
+ debug_printf ("gsid not found in augmented /etc/group");
}
- cygheap->user.ontherange (CH_HOME, pwd);
+ cygheap->user.ontherange (CH_HOME, pw);
}
void
@@ -441,7 +415,7 @@ cygheap_user::env_logsrv (const char *name, size_t namelen)
WCHAR wlogsrv[INTERNET_MAX_HOST_NAME_LENGTH + 3];
sys_mbstowcs (wdomain, MAX_DOMAIN_NAME_LEN + 1, mydomain);
cfree_and_set (plogsrv, almost_null);
- if (get_logon_server (wdomain, wlogsrv, DS_IS_FLAT_NAME))
+ if (get_logon_server (wdomain, wlogsrv, false))
sys_wcstombs_alloc (&plogsrv, HEAP_STR, wlogsrv);
return plogsrv;
}
@@ -551,13 +525,21 @@ pwdgrp::add_line (char *eptr)
{
if (eptr)
{
+ lptr = eptr;
+ eptr = strchr (lptr, '\n');
+ if (eptr)
+ {
+ if (eptr > lptr && eptr[-1] == '\r')
+ eptr[-1] = '\0';
+ else
+ *eptr = '\0';
+ eptr++;
+ }
if (curr_lines >= max_lines)
{
max_lines += 10;
- pwdgrp_buf = crealloc_abort (pwdgrp_buf,
- max_lines * pwdgrp_buf_elem_size);
+ *pwdgrp_buf = realloc (*pwdgrp_buf, max_lines * pwdgrp_buf_elem_size);
}
- lptr = eptr;
if ((this->*parse) ())
curr_lines++;
}
@@ -565,1437 +547,82 @@ pwdgrp::add_line (char *eptr)
}
void
-cygheap_pwdgrp::init ()
-{
- pwd_cache.cygserver.init_pwd ();
- pwd_cache.file.init_pwd ();
- pwd_cache.win.init_pwd ();
- grp_cache.cygserver.init_grp ();
- grp_cache.file.init_grp ();
- grp_cache.win.init_grp ();
- /* Default settings:
-
- passwd: files db
- group: files db
- db_prefix: auto
- db_cache: yes
- db_separator: +
- db_enum: cache builtin
- */
- pwd_src = (NSS_FILES | NSS_DB);
- grp_src = (NSS_FILES | NSS_DB);
- prefix = NSS_AUTO;
- separator[0] = L'+';
- caching = true;
- enums = (ENUM_CACHE | ENUM_BUILTIN);
- enum_tdoms = NULL;
-}
-
-/* The /etc/nsswitch.conf file is read exactly once by the root process of a
- process tree. We can't afford methodical changes during the lifetime of a
- process tree. */
-void
-cygheap_pwdgrp::nss_init_line (const char *line)
-{
- const char *c = line + strspn (line, " \t");
- switch (*c)
- {
- case 'p':
- case 'g':
- {
- int *src = NULL;
- if (!strncmp (c, "passwd:", 7))
- {
- src = &pwd_src;
- c += 7;
- }
- else if (!strncmp (c, "group:", 6))
- {
- src = &grp_src;
- c += 6;
- }
- if (src)
- {
- *src = 0;
- while (*c)
- {
- c += strspn (c, " \t");
- if (!*c || *c == '#')
- break;
- if (!strncmp (c, "files", 5) && strchr (" \t", c[5]))
- {
- *src |= NSS_FILES;
- c += 5;
- }
- else if (!strncmp (c, "db", 2) && strchr (" \t", c[2]))
- {
- *src |= NSS_DB;
- c += 2;
- }
- else
- {
- c += strcspn (c, " \t");
- debug_printf ("Invalid nsswitch.conf content: %s", line);
- }
- }
- if (*src == 0)
- *src = (NSS_FILES | NSS_DB);
- }
- }
- break;
- case 'd':
- if (strncmp (c, "db_", 3))
- {
- debug_printf ("Invalid nsswitch.conf content: %s", line);
- break;
- }
- c += 3;
- if (!strncmp (c, "prefix:", 7))
- {
- c += 7;
- c += strspn (c, " \t");
- if (!strncmp (c, "auto", 4) && strchr (" \t", c[4]))
- prefix = NSS_AUTO;
- else if (!strncmp (c, "primary", 7) && strchr (" \t", c[7]))
- prefix = NSS_PRIMARY;
- else if (!strncmp (c, "always", 6) && strchr (" \t", c[6]))
- prefix = NSS_ALWAYS;
- else
- debug_printf ("Invalid nsswitch.conf content: %s", line);
- }
- else if (!strncmp (c, "separator:", 10))
- {
- c += 10;
- c += strspn (c, " \t");
- if ((unsigned char) *c <= 0x7f && *c != ':' && strchr (" \t", c[1]))
- separator[0] = (unsigned char) *c;
- else
- debug_printf ("Invalid nsswitch.conf content: %s", line);
- }
- else if (!strncmp (c, "enum:", 5))
- {
- tmp_pathbuf tp;
- char *tdoms = tp.c_get ();
- char *td = tdoms;
- int new_enums = ENUM_NONE;
-
- td[0] = '\0';
- c += 5;
- c += strspn (c, " \t");
- while (!strchr (" \t", *c))
- {
- const char *e = c + strcspn (c, " \t");
- if (!strncmp (c, "none", 4) && strchr (" \t", c[4]))
- new_enums = ENUM_NONE;
- else if (!strncmp (c, "builtin", 7) && strchr (" \t", c[7]))
- new_enums |= ENUM_BUILTIN;
- else if (!strncmp (c, "cache", 5) && strchr (" \t", c[5]))
- new_enums |= ENUM_CACHE;
- else if (!strncmp (c, "files", 5) && strchr (" \t", c[5]))
- new_enums |= ENUM_FILES;
- else if (!strncmp (c, "local", 5) && strchr (" \t", c[5]))
- new_enums |= ENUM_LOCAL;
- else if (!strncmp (c, "primary", 7) && strchr (" \t", c[7]))
- new_enums |= ENUM_PRIMARY;
- else if (!strncmp (c, "alltrusted", 10) && strchr (" \t", c[10]))
- new_enums |= ENUM_TDOMS | ENUM_TDOMS_ALL;
- else if (!strncmp (c, "all", 3) && strchr (" \t", c[3]))
- new_enums |= ENUM_ALL;
- else
- {
- td = stpcpy (stpncpy (td, c, e - c), " ");
- new_enums |= ENUM_TDOMS;
- }
- c = e;
- c += strspn (c, " \t");
- }
- if ((new_enums & (ENUM_TDOMS | ENUM_TDOMS_ALL)) == ENUM_TDOMS)
- {
- if (td > tdoms)
- {
- PWCHAR spc;
- sys_mbstowcs_alloc (&enum_tdoms, HEAP_BUF, tdoms);
- /* Convert string to REG_MULTI_SZ-style. */
- while ((spc = wcsrchr (enum_tdoms, L' ')))
- *spc = L'\0';
- }
- else
- new_enums &= ~(ENUM_TDOMS | ENUM_TDOMS_ALL);
- }
- enums = new_enums;
- }
- break;
- case '\0':
- case '#':
- break;
- default:
- debug_printf ("Invalid nsswitch.conf content: %s", line);
- break;
- }
-}
-
-void
-cygheap_pwdgrp::_nss_init ()
+pwdgrp::load (const wchar_t *rel_path)
{
- UNICODE_STRING path;
- OBJECT_ATTRIBUTES attr;
- NT_readline rl;
- tmp_pathbuf tp;
- char *buf = tp.c_get ();
-
- PCWSTR rel_path = L"\\etc\\nsswitch.conf";
- path.Buffer = (PWCHAR) alloca ((wcslen (cygheap->installation_root)
- + wcslen (rel_path) + 1) * sizeof (WCHAR));
- wcpcpy (wcpcpy (path.Buffer, cygheap->installation_root), rel_path);
- RtlInitUnicodeString (&path, path.Buffer);
- InitializeObjectAttributes (&attr, &path, OBJ_CASE_INSENSITIVE,
- NULL, NULL);
- if (rl.init (&attr, buf, NT_MAX_PATH))
- while ((buf = rl.gets ()))
- nss_init_line (buf);
- nss_inited = true;
-}
-
-/* Override the ParentIndex value of the PDS_DOMAIN_TRUSTSW entry with the
- PosixOffset. */
-#define PosixOffset ParentIndex
+ static const char failed[] = "failed";
+ static const char succeeded[] = "succeeded";
+ const char *res = failed;
+ HANDLE fh = NULL;
-bool
-cygheap_domain_info::init ()
-{
- HANDLE lsa;
NTSTATUS status;
- ULONG ret;
- /* We *have* to copy the information. Apart from our wish to have the
- stuff in the cygheap, even when not calling LsaFreeMemory on the result,
- the data will be overwritten later. From what I gather, the information
- is, in fact, stored on the stack. */
- PPOLICY_DNS_DOMAIN_INFO pdom;
- PPOLICY_ACCOUNT_DOMAIN_INFO adom;
- PDS_DOMAIN_TRUSTSW td;
- ULONG tdom_cnt;
-
- if (adom_name)
- return true;
- lsa = lsa_open_policy (NULL, POLICY_VIEW_LOCAL_INFORMATION);
- if (!lsa)
- {
- system_printf ("lsa_open_policy(NULL) failed");
- return false;
- }
- /* Fetch primary domain information from local LSA. */
- status = LsaQueryInformationPolicy (lsa, PolicyDnsDomainInformation,
- (PVOID *) &pdom);
- if (status != STATUS_SUCCESS)
- {
- system_printf ("LsaQueryInformationPolicy(Primary) %y", status);
- return false;
- }
- /* Copy primary domain info to cygheap. */
- pdom_name = cwcsdup (pdom->Name.Buffer);
- pdom_dns_name = pdom->DnsDomainName.Length
- ? cwcsdup (pdom->DnsDomainName.Buffer) : NULL;
- pdom_sid = pdom->Sid;
- LsaFreeMemory (pdom);
- /* Fetch account domain information from local LSA. */
- status = LsaQueryInformationPolicy (lsa, PolicyAccountDomainInformation,
- (PVOID *) &adom);
- if (status != STATUS_SUCCESS)
- {
- system_printf ("LsaQueryInformationPolicy(Account) %y", status);
- return false;
- }
- /* Copy account domain info to cygheap. If we're running on a DC the account
- domain is identical to the primary domain. This leads to confusion when
- trying to compute the uid/gid values. Therefore we invalidate the account
- domain name if we're running on a DC. */
- adom_sid = adom->DomainSid;
- adom_name = cwcsdup (pdom_sid == adom_sid ? L"@" : adom->DomainName.Buffer);
- LsaFreeMemory (adom);
- lsa_close_policy (lsa);
- if (cygheap->dom.member_machine ())
- {
- /* For a domain member machine fetch all trusted domain info.
- Start out with UNIX_POSIX_OFFSET. */
- lowest_tdo_posix_offset = UNIX_POSIX_OFFSET;
- ret = DsEnumerateDomainTrustsW (NULL, DS_DOMAIN_DIRECT_INBOUND
- | DS_DOMAIN_DIRECT_OUTBOUND
- | DS_DOMAIN_IN_FOREST,
- &td, &tdom_cnt);
- if (ret != ERROR_SUCCESS)
- {
- SetLastError (ret);
- debug_printf ("DsEnumerateDomainTrusts: %E");
- return true;
- }
- if (tdom_cnt == 0)
- {
- return true;
- }
- /* Copy trusted domain info to cygheap, setting PosixOffset on the fly. */
- tdom = (PDS_DOMAIN_TRUSTSW)
- cmalloc_abort (HEAP_BUF, tdom_cnt * sizeof (DS_DOMAIN_TRUSTSW));
- memcpy (tdom, td, tdom_cnt * sizeof (DS_DOMAIN_TRUSTSW));
- for (ULONG idx = 0; idx < tdom_cnt; ++idx)
- {
- /* Copy... */
- tdom[idx].NetbiosDomainName = cwcsdup (td[idx].NetbiosDomainName);
- /* DnsDomainName as well as DomainSid can be NULL. The reason is
- usually a domain of type TRUST_TYPE_DOWNLEVEL. This can be an
- old pre-AD domain, or a Netware domain, etc. If DnsDomainName
- is NULL, just set it to NetbiosDomainName. This simplifies
- subsequent code which doesn't have to check for a NULL pointer. */
- tdom[idx].DnsDomainName = td[idx].DnsDomainName
- ? cwcsdup (td[idx].DnsDomainName)
- : tdom[idx].NetbiosDomainName;
- if (td[idx].DomainSid)
- {
- ULONG len = RtlLengthSid (td[idx].DomainSid);
- tdom[idx].DomainSid = cmalloc_abort(HEAP_BUF, len);
- RtlCopySid (len, tdom[idx].DomainSid, td[idx].DomainSid);
- }
- /* ...and set PosixOffset to 0. This */
- tdom[idx].PosixOffset = 0;
- }
- NetApiBufferFree (td);
- tdom_count = tdom_cnt;
- }
- /* If we have Microsoft Client for NFS installed, we make use of a name
- mapping server. This can be either Active Directory to map uids/gids
- directly to Windows SIDs, or an AD LDS or other RFC 2307 compatible
- identity store. The name of the mapping domain can be fetched from the
- registry key created by the NFS client installation and entered by the
- user via nfsadmin or the "Services For NFS" MMC snap-in.
-
- Reference:
- http://blogs.technet.com/b/filecab/archive/2012/10/09/nfs-identity-mapping-in-windows-server-2012.aspx
- Note that we neither support UNMP nor local passwd/group file mapping,
- nor UUUA.
-
- This function returns the mapping server from the aforementioned registry
- key, or, if none is configured, NULL, which will be resolved to the
- primary domain of the machine by the ldap_init function.
-
- The latter is useful to get an RFC 2307 mapping for Samba UNIX accounts,
- even if no NFS name mapping is configured on the machine. Fortunately,
- the posixAccount and posixGroup schemas are already available in the
- Active Directory default setup since Windows Server 2003 R2. */
- reg_key reg (HKEY_LOCAL_MACHINE, KEY_READ | KEY_WOW64_64KEY,
- L"SOFTWARE", L"Microsoft", L"ServicesForNFS", NULL);
- if (!reg.error ())
- {
- DWORD rfc2307 = reg.get_dword (L"Rfc2307", 0);
- if (rfc2307)
- {
- rfc2307_domain_buf = (PWCHAR) ccalloc_abort (HEAP_STR, 257,
- sizeof (WCHAR));
- reg.get_string (L"Rfc2307Domain", rfc2307_domain_buf, 257, L"");
- if (!rfc2307_domain_buf[0])
- {
- cfree (rfc2307_domain_buf);
- rfc2307_domain_buf = NULL;
- }
- }
- }
- return true;
-}
+ OBJECT_ATTRIBUTES attr;
+ IO_STATUS_BLOCK io;
+ FILE_STANDARD_INFORMATION fsi;
-/* Per session, so it changes potentially when switching the user context. */
-static cygsid logon_sid ("");
+ if (buf)
+ free (buf);
+ buf = NULL;
+ curr_lines = 0;
-static void
-get_logon_sid ()
-{
- if (PSID (logon_sid) == NO_SID)
+ if (!path &&
+ !(path = (PWCHAR) malloc ((wcslen (cygheap->installation_root)
+ + wcslen (rel_path) + 1) * sizeof (WCHAR))))
{
- NTSTATUS status;
- ULONG size;
- tmp_pathbuf tp;
- PTOKEN_GROUPS groups = (PTOKEN_GROUPS) tp.c_get ();
-
- status = NtQueryInformationToken (hProcToken, TokenGroups, groups,
- NT_MAX_PATH, &size);
- if (!NT_SUCCESS (status))
- debug_printf ("NtQueryInformationToken() %y", status);
- else
- {
- for (DWORD pg = 0; pg < groups->GroupCount; ++pg)
- if (groups->Groups[pg].Attributes & SE_GROUP_LOGON_ID)
- {
- logon_sid = groups->Groups[pg].Sid;
- break;
- }
- }
+ paranoid_printf ("malloc (%W) failed", rel_path);
+ goto out;
}
-}
+ wcpcpy (wcpcpy (path, cygheap->installation_root), rel_path);
+ RtlInitUnicodeString (&upath, path);
-void *
-pwdgrp::add_account_post_fetch (char *line, bool lock)
-{
- if (line)
- {
- void *ret;
- if (lock)
- pglock.init ("pglock")->acquire ();
- add_line (line);
- ret = ((char *) pwdgrp_buf) + (curr_lines - 1) * pwdgrp_buf_elem_size;
- if (lock)
- pglock.release ();
- return ret;
- }
- return NULL;
-}
+ InitializeObjectAttributes (&attr, &upath, OBJ_CASE_INSENSITIVE, NULL, NULL);
+ etc_ix = etc::init (etc_ix, &attr);
-void *
-pwdgrp::add_account_from_file (cygpsid &sid)
-{
- if (!path.MaximumLength)
- return NULL;
- fetch_user_arg_t arg;
- arg.type = SID_arg;
- arg.sid = &sid;
- char *line = fetch_account_from_file (arg);
- return (struct passwd *) add_account_post_fetch (line, true);
-}
+ paranoid_printf ("%S", &upath);
-void *
-pwdgrp::add_account_from_file (const char *name)
-{
- if (!path.MaximumLength)
- return NULL;
- fetch_user_arg_t arg;
- arg.type = NAME_arg;
- arg.name = name;
- char *line = fetch_account_from_file (arg);
- return (struct passwd *) add_account_post_fetch (line, true);
-}
-
-void *
-pwdgrp::add_account_from_file (uint32_t id)
-{
- if (!path.MaximumLength)
- return NULL;
- fetch_user_arg_t arg;
- arg.type = ID_arg;
- arg.id = id;
- char *line = fetch_account_from_file (arg);
- return (struct passwd *) add_account_post_fetch (line, true);
-}
-
-void *
-pwdgrp::add_account_from_windows (cygpsid &sid, cyg_ldap *pldap)
-{
- fetch_user_arg_t arg;
- arg.type = SID_arg;
- arg.sid = &sid;
- char *line = fetch_account_from_windows (arg, pldap);
- if (!line)
- return NULL;
- return add_account_post_fetch (line, true);
-}
-
-void *
-pwdgrp::add_account_from_windows (const char *name, cyg_ldap *pldap)
-{
- fetch_user_arg_t arg;
- arg.type = NAME_arg;
- arg.name = name;
- char *line = fetch_account_from_windows (arg, pldap);
- if (!line)
- return NULL;
- return add_account_post_fetch (line, true);
-}
-
-void *
-pwdgrp::add_account_from_windows (uint32_t id, cyg_ldap *pldap)
-{
- fetch_user_arg_t arg;
- arg.type = ID_arg;
- arg.id = id;
- char *line = fetch_account_from_windows (arg, pldap);
- if (!line)
- return NULL;
- return add_account_post_fetch (line, true);
-}
-
-/* Check if file exists and if it has been written to since last checked.
- If file has been changed, invalidate the current cache.
-
- If the file doesn't exist when this function is called the first time,
- by the first Cygwin process in a process tree, the file will never be
- visited again by any process in this process tree. This is important,
- because we cannot allow a change of UID/GID values for the lifetime
- of a process tree.
-
- If the file gets deleted or unreadable, the file cache will stay in
- place, but we won't try to read new accounts from the file.
-
- The return code indicates to the calling function if the file exists. */
-bool
-pwdgrp::check_file ()
-{
- FILE_BASIC_INFORMATION fbi;
- NTSTATUS status;
-
- if (!path.Buffer)
- {
- PCWSTR rel_path = is_group () ? L"\\etc\\group" : L"\\etc\\passwd";
- path.Buffer = (PWCHAR) cmalloc_abort (HEAP_BUF,
- (wcslen (cygheap->installation_root)
- + wcslen (rel_path) + 1)
- * sizeof (WCHAR));
- wcpcpy (wcpcpy (path.Buffer, cygheap->installation_root), rel_path);
- RtlInitUnicodeString (&path, path.Buffer);
- InitializeObjectAttributes (&attr, &path, OBJ_CASE_INSENSITIVE,
- NULL, NULL);
- }
- else if (path.MaximumLength == 0) /* Indicates that the file doesn't exist. */
- return false;
- status = NtQueryAttributesFile (&attr, &fbi);
+ status = NtOpenFile (&fh, SYNCHRONIZE | FILE_READ_DATA, &attr, &io,
+ FILE_SHARE_VALID_FLAGS,
+ FILE_SYNCHRONOUS_IO_NONALERT
+ | FILE_OPEN_FOR_BACKUP_INTENT);
if (!NT_SUCCESS (status))
{
- if (last_modified.QuadPart)
- last_modified.QuadPart = 0LL;
- else
- path.MaximumLength = 0;
- return false;
- }
- if (fbi.LastWriteTime.QuadPart > last_modified.QuadPart)
- {
- last_modified.QuadPart = fbi.LastWriteTime.QuadPart;
- if (curr_lines > 0)
- {
- pglock.init ("pglock")->acquire ();
- int curr = curr_lines;
- curr_lines = 0;
- for (int i = 0; i < curr; ++i)
- cfree (is_group () ? this->group ()[i].g.gr_name
- : this->passwd ()[i].p.pw_name);
- pglock.release ();
- }
- }
- return true;
-}
-
-char *
-pwdgrp::fetch_account_from_line (fetch_user_arg_t &arg, const char *line)
-{
- char *p, *e;
-
- switch (arg.type)
- {
- case SID_arg:
- /* Ignore fields, just scan for SID string. */
- if (!(p = strstr (line, arg.name)) || p[arg.len] != ':')
- return NULL;
- break;
- case NAME_arg:
- /* First field is always name. */
- if (!strncasematch (line, arg.name, arg.len) || line[arg.len] != ':')
- return NULL;
- break;
- case ID_arg:
- /* Skip to third field. */
- if (!(p = strchr (line, ':')) || !(p = strchr (p + 1, ':')))
- return NULL;
- if (strtoul (p + 1, &e, 10) != arg.id || !e || *e != ':')
- return NULL;
- break;
- }
- return cstrdup (line);
-}
-
-char *
-pwdgrp::fetch_account_from_file (fetch_user_arg_t &arg)
-{
- NT_readline rl;
- tmp_pathbuf tp;
- char *buf = tp.c_get ();
- char str[128];
- char *ret = NULL;
-
- /* Create search string. */
- switch (arg.type)
- {
- case SID_arg:
- /* Override SID with SID string. */
- arg.sid->string (str);
- arg.name = str;
- /*FALLTHRU*/
- case NAME_arg:
- arg.len = strlen (arg.name);
- break;
- case ID_arg:
- break;
- }
- if (rl.init (&attr, buf, NT_MAX_PATH))
- while ((buf = rl.gets ()))
- if ((ret = fetch_account_from_line (arg, buf)))
- return ret;
- return NULL;
-}
-
-static ULONG
-fetch_posix_offset (PDS_DOMAIN_TRUSTSW td, cyg_ldap *cldap)
-{
- uint32_t id_val = 0;
-
- if (!td->PosixOffset && !(td->Flags & DS_DOMAIN_PRIMARY) && td->DomainSid)
- {
- if (cldap->open (NULL) == NO_ERROR)
- id_val = cldap->fetch_posix_offset_for_domain (td->DnsDomainName);
- if (!id_val)
- {
- /* We're probably running under a local account, so we're not allowed
- to fetch any information from AD beyond the most obvious.
- Alternatively we're suffering IT madness and some admin has
- actually set the POSIX offset to 0. Either way, fake a reasonable
- posix offset and hope for the best. */
- id_val = cygheap->dom.lowest_tdo_posix_offset - 0x00800000;
- }
- td->PosixOffset = id_val;
- if (id_val < cygheap->dom.lowest_tdo_posix_offset)
- cygheap->dom.lowest_tdo_posix_offset = id_val;
- }
- return td->PosixOffset;
-}
-
-/* Helper function to replace colons with commas in pw_gecos field. */
-static PWCHAR
-colon_to_semicolon (PWCHAR str)
-{
- PWCHAR cp = str;
- while ((cp = wcschr (cp, L':')) != NULL)
- *cp++ = L';';
- return str;
-}
-
-/* CV 2014-05-08: USER_INFO_24 is not yet defined in Mingw64, but will be in
- the next release. For the time being, define the structure here with
- another name which won't collide with the upcoming correct definition
- in lmaccess.h. */
-struct cyg_USER_INFO_24
-{
- BOOL usri24_internet_identity;
- DWORD usri24_flags;
- LPWSTR usri24_internet_provider_name;
- LPWSTR usri24_internet_principal_name;
- PSID usri24_user_sid;
-};
-
-char *
-pwdgrp::fetch_account_from_windows (fetch_user_arg_t &arg, cyg_ldap *pldap)
-{
- /* Used in LookupAccount calls. */
- WCHAR namebuf[UNLEN + 1], *name = namebuf;
- WCHAR dom[DNLEN + 1] = L"";
- cygsid csid;
- DWORD nlen = UNLEN + 1;
- DWORD dlen = DNLEN + 1;
- DWORD slen = SECURITY_MAX_SID_SIZE;
- cygpsid sid (NO_SID);
- SID_NAME_USE acc_type;
- BOOL ret = false;
- /* Cygwin user name style. */
- enum name_style_t {
- name_only,
- plus_prepended,
- fully_qualified
- } name_style = name_only;
- /* Computed stuff. */
- uid_t uid = ILLEGAL_UID;
- gid_t gid = ILLEGAL_GID;
- bool is_domain_account = true;
- PCWSTR domain = NULL;
- PWCHAR shell = NULL;
- PWCHAR home = NULL;
- PWCHAR gecos = NULL;
- /* Temporary stuff. */
- PWCHAR p;
- WCHAR sidstr[128];
- ULONG posix_offset = 0;
- uint32_t id_val;
- cyg_ldap loc_ldap;
- cyg_ldap *cldap = pldap ?: &loc_ldap;
-
- /* Initialize */
- if (!cygheap->dom.init ())
- return NULL;
-
- switch (arg.type)
- {
- case SID_arg:
- sid = *arg.sid;
- ret = LookupAccountSidW (NULL, sid, name, &nlen, dom, &dlen, &acc_type);
- if (!ret
- && cygheap->dom.member_machine ()
- && sid_id_auth (sid) == 5 /* SECURITY_NT_AUTHORITY */
- && sid_sub_auth (sid, 0) == SECURITY_BUILTIN_DOMAIN_RID)
- {
- /* LookupAccountSid called on a non-DC cannot resolve aliases which
- are not defined in the local SAM. If we encounter an alias which
- can't be resolved, and if we're a domain member machine, ask a DC.
- Do *not* use LookupAccountSidW. It can take ages when called on a
- DC for some weird reason. Use LDAP instead. */
- PWCHAR val;
-
- if (cldap->open (NULL) == NO_ERROR
- && cldap->fetch_ad_account (sid, is_group ())
- && (val = cldap->get_group_name ()))
- {
- wcpcpy (name, val);
- wcpcpy (dom, L"BUILTIN");
- acc_type = SidTypeAlias;
- ret = true;
- }
- }
- if (!ret)
- debug_printf ("LookupAccountSid(%W), %E", sid.string (sidstr));
- break;
- case NAME_arg:
- /* Skip leading domain separator. This denotes an alias or well-known
- group, which will be found first by LookupAccountNameW anyway.
- Otherwise, if the name has no leading domain name, it's either a
- standalone machine, or the username must be from the primary domain.
- In the latter case, prepend the primary domain name so as not to
- collide with an account from the account domain with the same name. */
- name_style_t nstyle;
-
- nstyle = name_only;
- p = name;
- if (*arg.name == cygheap->pg.nss_separator ()[0])
- nstyle = plus_prepended;
- else if (strchr (arg.name, cygheap->pg.nss_separator ()[0]))
- nstyle = fully_qualified;
- else if (cygheap->dom.member_machine ())
- p = wcpcpy (wcpcpy (p, cygheap->dom.primary_flat_name ()),
- cygheap->pg.nss_separator ());
- /* Now fill up with name to search. */
- sys_mbstowcs (p, UNLEN + 1,
- arg.name + (nstyle == plus_prepended ? 1 : 0));
- /* Replace domain separator char with backslash and make sure p is NULL
- or points to the backslash, so... */
- if ((p = wcschr (name, cygheap->pg.nss_separator ()[0])))
- *p = L'\\';
- sid = csid;
- ret = LookupAccountNameW (NULL, name, sid, &slen, dom, &dlen, &acc_type);
- if (!ret)
- {
- debug_printf ("LookupAccountNameW (%W), %E", name);
- return NULL;
- }
- /* ... we can skip the backslash in the rest of this function. */
- if (p)
- name = p + 1;
- /* Last but not least, some validity checks on the name style. */
- switch (nstyle)
- {
- case name_only:
- /* name_only account must start with S-1-5-21 */
- if (sid_id_auth (sid) != 5 /* SECURITY_NT_AUTHORITY */
- || sid_sub_auth (sid, 0) != SECURITY_NT_NON_UNIQUE)
- {
- debug_printf ("Invalid account name <%s> (name only/"
- "not NON_UNIQUE)", arg.name);
- return NULL;
- }
- /* name_only only if db_prefix is auto. */
- if (!cygheap->pg.nss_prefix_auto ())
- {
- debug_printf ("Invalid account name <%s> (name only/"
- "db_prefix not auto)", arg.name);
- return NULL;
- }
- break;
- case plus_prepended:
- /* plus_prepended account must not start with S-1-5-21. */
- if (sid_id_auth (sid) == 5 /* SECURITY_NT_AUTHORITY */
- && sid_sub_auth (sid, 0) == SECURITY_NT_NON_UNIQUE)
- {
- debug_printf ("Invalid account name <%s> (plus prependend/"
- "NON_UNIQUE)", arg.name);
- return NULL;
- }
- /* plus_prepended only if db_prefix is not always. */
- if (cygheap->pg.nss_prefix_always ())
- {
- debug_printf ("Invalid account name <%s> (plus prependend/"
- "db_prefix not always)", arg.name);
- return NULL;
- }
- break;
- case fully_qualified:
- /* All is well if db_prefix is always. */
- if (cygheap->pg.nss_prefix_always ())
- break;
- /* Otherwise, no fully_qualified for builtin accounts. */
- if (sid_id_auth (sid) != 5 /* SECURITY_NT_AUTHORITY */
- || sid_sub_auth (sid, 0) != SECURITY_NT_NON_UNIQUE)
- {
- debug_printf ("Invalid account name <%s> (fully qualified/"
- "not NON_UNIQUE)", arg.name);
- return NULL;
- }
- /* All is well if db_prefix is primary. */
- if (cygheap->pg.nss_prefix_primary ())
- break;
- /* Domain member and domain == primary domain? */
- if (cygheap->dom.member_machine ())
- {
- if (!wcscasecmp (dom, cygheap->dom.primary_flat_name ()))
- {
- debug_printf ("Invalid account name <%s> (fully qualified/"
- "primary domain account)", arg.name);
- return NULL;
- }
- }
- /* Not domain member and domain == account domain? */
- else if (!wcscasecmp (dom, cygheap->dom.account_flat_name ()))
- {
- debug_printf ("Invalid account name <%s> (fully qualified/"
- "local account)", arg.name);
- return NULL;
- }
- break;
- }
- break;
- case ID_arg:
- /* Construct SID from ID using the SFU rules, just like the code below
- goes the opposite route. */
-#ifndef INTERIX_COMPATIBLE
- /* Except for Builtin and Alias groups in the SECURITY_NT_AUTHORITY.
- We create uid/gid values compatible with the old values generated
- by mkpasswd/mkgroup. */
- if (arg.id < 0x200)
- __small_swprintf (sidstr, L"S-1-5-%u", arg.id & 0x1ff);
- else if (arg.id == 0x3e8) /* Special case "Other Organization" */
- wcpcpy (sidstr, L"S-1-5-1000");
- else if (arg.id <= 0x7ff)
- __small_swprintf (sidstr, L"S-1-5-32-%u", arg.id & 0x7ff);
- else
-#endif
- if (arg.id == 0xffe)
- {
- /* OtherSession != Logon SID. */
- get_logon_sid ();
- /* LookupAccountSidW will fail. */
- sid = csid = logon_sid;
- sid_sub_auth_rid (sid) = 0;
- break;
- }
- else if (arg.id == 0xfff)
- {
- /* CurrentSession == Logon SID. */
- get_logon_sid ();
- /* LookupAccountSidW will fail. */
- sid = logon_sid;
- break;
- }
- else if (arg.id < 0x10000)
- {
- /* Nothing. */
- debug_printf ("Invalid POSIX id %u", arg.id);
- return NULL;
- }
- else if (arg.id < 0x20000)
- {
- /* Well-Known Group */
- arg.id -= 0x10000;
- __small_swprintf (sidstr, L"S-1-%u-%u", arg.id >> 8, arg.id & 0xff);
- }
- else if (arg.id >= 0x30000 && arg.id < 0x40000)
- {
- /* Account domain user or group. */
- PWCHAR s = cygheap->dom.account_sid ().pstring (sidstr);
- __small_swprintf (s, L"-%u", arg.id & 0xffff);
- }
- else if (arg.id < 0x60000)
- {
- /* Builtin Alias */
- __small_swprintf (sidstr, L"S-1-5-%u-%u",
- arg.id >> 12, arg.id & 0xffff);
- }
- else if (arg.id < 0x70000)
- {
- /* Mandatory Label. */
- __small_swprintf (sidstr, L"S-1-16-%u", arg.id & 0xffff);
- }
- else if (arg.id < 0x80000)
- {
- /* Identity assertion SIDs. */
- __small_swprintf (sidstr, L"S-1-18-%u", arg.id & 0xffff);
- }
- else if (arg.id < 0x100000)
- {
- /* Nothing. */
- debug_printf ("Invalid POSIX id %u", arg.id);
- return NULL;
- }
- else if (arg.id == ILLEGAL_UID)
- {
- /* Just some fake. */
- sid = csid = "S-1-99-0";
- break;
- }
- else if (arg.id >= UNIX_POSIX_OFFSET)
- {
- /* UNIX (unknown NFS or Samba) user account. */
- __small_swprintf (sidstr, L"S-1-22-%u-%u",
- is_group () ? 2 : 1, arg.id & UNIX_POSIX_MASK);
- /* LookupAccountSidW will fail. */
- sid = csid = sidstr;
- break;
- }
- else
- {
- /* Some trusted domain? */
- PDS_DOMAIN_TRUSTSW td = NULL, this_td = NULL;
-
- for (ULONG idx = 0; (td = cygheap->dom.trusted_domain (idx)); ++idx)
- {
- fetch_posix_offset (td, &loc_ldap);
- if (td->PosixOffset > posix_offset && td->PosixOffset <= arg.id)
- posix_offset = (this_td = td)->PosixOffset;
- }
- if (this_td)
- {
- cygpsid tsid (this_td->DomainSid);
- PWCHAR s = tsid.pstring (sidstr);
- __small_swprintf (s, L"-%u", arg.id - posix_offset);
- }
- else
- {
- /* Primary domain */
- PWCHAR s = cygheap->dom.primary_sid ().pstring (sidstr);
- __small_swprintf (s, L"-%u", arg.id - 0x100000);
- }
- posix_offset = 0;
- }
- sid = csid = sidstr;
- ret = LookupAccountSidW (NULL, sid, name, &nlen, dom, &dlen, &acc_type);
- if (!ret)
- {
- debug_printf ("LookupAccountSidW (%W), %E", sidstr);
- return NULL;
- }
- break;
- }
- if (ret)
- {
- /* Builtin account? SYSTEM, for instance, is returned as SidTypeUser,
- if a process is running as LocalSystem service.
- Microsoft Account? These show up in the user's group list, using the
- undocumented security authority 11. Even though this is officially a
- user account, it only matters as part of the group list, so we convert
- it to a well-known group here. */
- if (acc_type == SidTypeUser
- && (sid_sub_auth_count (sid) <= 3 || sid_id_auth (sid) == 11))
- acc_type = SidTypeWellKnownGroup;
- switch (acc_type)
- {
- case SidTypeUser:
- case SidTypeGroup:
- case SidTypeAlias:
- /* Predefined alias? */
- if (acc_type == SidTypeAlias
- && sid_sub_auth (sid, 0) != SECURITY_NT_NON_UNIQUE)
- {
-#ifdef INTERIX_COMPATIBLE
- posix_offset = 0x30000;
- uid = 0x1000 * sid_sub_auth (sid, 0)
- + (sid_sub_auth_rid (sid) & 0xffff);
-#else
- posix_offset = 0;
-#endif
- name_style = (cygheap->pg.nss_prefix_always ()) ? fully_qualified
- : plus_prepended;
- is_domain_account = false;
- }
- /* Account domain account? */
- else if (!wcscasecmp (dom, cygheap->dom.account_flat_name ()))
- {
- posix_offset = 0x30000;
- if (cygheap->dom.member_machine ()
- || !cygheap->pg.nss_prefix_auto ())
- name_style = fully_qualified;
- is_domain_account = false;
- }
- /* Domain member machine? */
- else if (cygheap->dom.member_machine ())
- {
- /* Primary domain account? */
- if (!wcscasecmp (dom, cygheap->dom.primary_flat_name ()))
- {
- posix_offset = 0x100000;
- /* In theory domain should have been set to
- cygheap->dom.primary_dns_name (), but it turns out
- that not setting the domain here has advantages.
- We open the ldap connection to NULL (== some domain
- control of our primary domain) anyway. So the domain
- is only used
- later on. So, don't set domain here to non-NULL, unless
- you're sure you have also changed subsequent assumptions
- that domain is NULL if it's a primary domain account. */
- if (!cygheap->pg.nss_prefix_auto ())
- name_style = fully_qualified;
- }
- else
- {
- /* No, fetch POSIX offset. */
- PDS_DOMAIN_TRUSTSW td = NULL;
-
- name_style = fully_qualified;
- for (ULONG idx = 0;
- (td = cygheap->dom.trusted_domain (idx));
- ++idx)
- if (!wcscasecmp (dom, td->NetbiosDomainName))
- {
- domain = td->DnsDomainName;
- posix_offset =
- fetch_posix_offset (td, &loc_ldap);
- break;
- }
-
- if (!domain)
- {
- debug_printf ("Unknown domain %W", dom);
- return NULL;
- }
- }
- }
- /* If the domain returned by LookupAccountSid is not our machine
- name, and if our machine is no domain member, we lose. We have
- nobody to ask for the POSIX offset. */
- else
- {
- debug_printf ("Unknown domain %W", dom);
- return NULL;
- }
- /* Generate values. */
- if (uid == ILLEGAL_UID)
- uid = posix_offset + sid_sub_auth_rid (sid);
-
- /* We only care for extended user information if we're creating a
- passwd entry and the account is a user or alias. */
- if (is_group () || acc_type == SidTypeGroup)
- break;
-
- if (acc_type == SidTypeUser)
- {
- /* Default primary group. If the sid is the current user, fetch
- the default group from the current user token, otherwise make
- the educated guess that the user is in group "Domain Users"
- or "None". */
- if (sid == cygheap->user.sid ())
- gid = posix_offset
- + sid_sub_auth_rid (cygheap->user.groups.pgsid);
- else
- gid = posix_offset + DOMAIN_GROUP_RID_USERS;
- }
-
- if (is_domain_account)
- {
- /* Use LDAP to fetch domain account infos. */
- if (cldap->open (NULL) != NO_ERROR)
- break;
- if (cldap->fetch_ad_account (sid, is_group (), domain))
- {
- PWCHAR val;
-
- if ((id_val = cldap->get_primary_gid ()) != ILLEGAL_GID)
- gid = posix_offset + id_val;
- if ((val = cldap->get_gecos ()))
- gecos = colon_to_semicolon (
- wcscpy ((PWCHAR) alloca ((wcslen (val) + 1)
- * sizeof (WCHAR)), val));
- if ((val = cldap->get_home ()))
- home = wcscpy ((PWCHAR) alloca ((wcslen (val) + 1)
- * sizeof (WCHAR)), val);
- if ((val = cldap->get_shell ()))
- shell = wcscpy ((PWCHAR) alloca ((wcslen (val) + 1)
- * sizeof (WCHAR)), val);
- /* Check and, if necessary, add unix<->windows id mapping on
- the fly, unless we're called from getpwent. */
- if (!pldap)
- {
- id_val = cldap->get_unix_uid ();
- if (id_val != ILLEGAL_UID
- && cygheap->ugid_cache.get_uid (id_val)
- == ILLEGAL_UID)
- cygheap->ugid_cache.add_uid (id_val, uid);
- }
- }
- }
- /* Otherwise check account domain (local SAM).*/
- else
- {
- NET_API_STATUS nas;
- PUSER_INFO_4 ui;
- PLOCALGROUP_INFO_1 gi;
- PCWSTR comment;
- PWCHAR pgrp = NULL;
- PWCHAR uxid = NULL;
- struct {
- PCWSTR str;
- size_t len;
- PWCHAR *tgt;
- bool group;
- } search[] = {
- { L"unix=\"", 6, &uxid, true },
- { L"home=\"", 6, &home, false },
- { L"shell=\"", 7, &shell, false },
- { L"group=\"", 7, &pgrp, false },
- { NULL, 0, NULL }
- };
- PWCHAR s, e;
-
- if (acc_type == SidTypeUser)
- {
- nas = NetUserGetInfo (NULL, name, 4, (PBYTE *) &ui);
- if (nas != NERR_Success)
- {
- debug_printf ("NetUserGetInfo(%W) %u", name, nas);
- break;
- }
- /* Set comment variable for below attribute loop. */
- comment = ui->usri4_comment;
- /* Logging in with a Microsoft Account, the user's primary
- group SID is the user's SID. Security sensitive tools
- expecting tight file permissions choke on that. We need
- an explicit primary group which is not identical to the
- user account. Unfortunately, while the default primary
- group of the account in SAM is still "None", "None" is not
- in the user token group list. So, what we do here is to
- use "Users" as a sane default primary group instead. */
- if (wincap.has_microsoft_accounts ())
- {
- struct cyg_USER_INFO_24 *ui24;
- nas = NetUserGetInfo (NULL, name, 24, (PBYTE *) &ui24);
- if (nas == NERR_Success)
- {
- if (ui24->usri24_internet_identity)
- gid = DOMAIN_ALIAS_RID_USERS;
- NetApiBufferFree (ui24);
- }
- }
- }
- else /* acc_type == SidTypeAlias */
- {
- nas = NetLocalGroupGetInfo (NULL, name, 1, (PBYTE *) &gi);
- if (nas != NERR_Success)
- {
- debug_printf ("NetLocalGroupGetInfo(%W) %u", name, nas);
- break;
- }
- /* Set comment variable for below attribute loop. */
- comment = gi->lgrpi1_comment;
- }
- /* Local SAM accounts have only a handful attributes
- available to home users. Therefore, fetch additional
- passwd/group attributes from the "Description" field
- in XML short style. */
- if ((s = wcsstr (comment, L"<cygwin "))
- && (e = wcsstr (s + 8, L"/>")))
- {
- s += 8;
- *e = L'\0';
- while (*s)
- {
- bool found = false;
-
- while (*s == L' ')
- ++s;
- for (size_t i = 0; search[i].str; ++i)
- if ((acc_type == SidTypeUser || search[i].group)
- && !wcsncmp (s, search[i].str, search[i].len))
- {
- s += search[i].len;
- if ((e = wcschr (s, L'"'))
- && (i > 0 || wcsncmp (name, s, e - s)))
- {
- *search[i].tgt =
- (PWCHAR) alloca ((e - s + 1)
- * sizeof (WCHAR));
- *wcpncpy (*search[i].tgt, s, e - s) = L'\0';
- s = e + 1;
- found = true;
- }
- else
- break;
- }
- if (!found)
- break;
- }
- }
- if (acc_type == SidTypeUser)
- NetApiBufferFree (ui);
- else
- NetApiBufferFree (gi);
- if (pgrp)
- {
- /* For setting the primary group, we have to test
- with and without prepended separator. */
- char gname[2 * UNLEN + 2];
- struct group *gr;
-
- *gname = cygheap->pg.nss_separator ()[0];
- sys_wcstombs (gname + 1, 2 * UNLEN + 1, pgrp);
- if ((gr = internal_getgrnam (gname, cldap))
- || (gr = internal_getgrnam (gname + 1, cldap)))
- gid = gr->gr_gid;
- }
- if (!pldap && uxid && ((id_val = wcstoul (uxid, &e, 10)), !*e))
- {
- if (acc_type == SidTypeUser)
- {
- if (cygheap->ugid_cache.get_uid (id_val) == ILLEGAL_UID)
- cygheap->ugid_cache.add_uid (id_val, uid);
- }
- else if (cygheap->ugid_cache.get_gid (id_val) == ILLEGAL_GID)
- cygheap->ugid_cache.add_gid (id_val, uid);
- }
- }
- break;
- case SidTypeWellKnownGroup:
- name_style = (cygheap->pg.nss_prefix_always ()
- || sid_id_auth (sid) == 11) /* Microsoft Account */
- ? fully_qualified : plus_prepended;
-#ifdef INTERIX_COMPATIBLE
- if (sid_id_auth (sid) == 5 /* SECURITY_NT_AUTHORITY */
- && sid_sub_auth_count (sid) > 1)
- {
- uid = 0x1000 * sid_sub_auth (sid, 0)
- + (sid_sub_auth_rid (sid) & 0xffff);
- name_style = fully_qualified;
- }
- else
- uid = 0x10000 + 0x100 * sid_id_auth (sid)
- + (sid_sub_auth_rid (sid) & 0xff);
-#else
- if (sid_id_auth (sid) != 5 /* SECURITY_NT_AUTHORITY */)
- uid = 0x10000 + 0x100 * sid_id_auth (sid)
- + (sid_sub_auth_rid (sid) & 0xff);
- else if (sid_sub_auth (sid, 0) < SECURITY_PACKAGE_BASE_RID
- || sid_sub_auth (sid, 0) > SECURITY_MAX_BASE_RID)
- uid = sid_sub_auth_rid (sid) & 0x7ff;
- else
- {
- uid = 0x1000 * sid_sub_auth (sid, 0)
- + (sid_sub_auth_rid (sid) & 0xffff);
- }
-#endif
- /* Special case for "Everyone". We don't want to return Everyone
- as user or group. Ever. */
- if (uid == 0x10100) /* Computed from S-1-1-0. */
- return NULL;
- break;
- case SidTypeLabel:
- uid = 0x60000 + sid_sub_auth_rid (sid);
- name_style = (cygheap->pg.nss_prefix_always ()) ? fully_qualified
- : plus_prepended;
- break;
- default:
- return NULL;
- }
- }
- else if (sid_id_auth (sid) == 5 /* SECURITY_NT_AUTHORITY */
- && sid_sub_auth (sid, 0) == SECURITY_LOGON_IDS_RID)
- {
- /* Logon ID. Mine or other? */
- get_logon_sid ();
- if (PSID (logon_sid) == NO_SID)
- return NULL;
- if (RtlEqualSid (sid, logon_sid))
- {
- uid = 0xfff;
- wcpcpy (name = namebuf, L"CurrentSession");
- }
- else
- {
- uid = 0xffe;
- wcpcpy (name = namebuf, L"OtherSession");
- }
- acc_type = SidTypeUnknown;
- }
- else if (sid_id_auth (sid) == 18)
- {
- /* Authentication assertion SIDs.
-
- Available when using a 2012R2 DC, but not supported by
- LookupAccountXXX on pre Windows 8/2012 machines */
- uid = 0x11200 + sid_sub_auth_rid (sid);
- wcpcpy (name = namebuf, sid_sub_auth_rid (sid) == 1
- ? (PWCHAR) L"Authentication authority asserted identity"
- : (PWCHAR) L"Service asserted identity");
- name_style = plus_prepended;
- acc_type = SidTypeUnknown;
+ paranoid_printf ("NtOpenFile(%S) failed, status %y", &upath, status);
+ goto out;
}
- else if (sid_id_auth (sid) == 22)
+ status = NtQueryInformationFile (fh, &io, &fsi, sizeof fsi,
+ FileStandardInformation);
+ if (!NT_SUCCESS (status))
{
- /* Samba UNIX Users/Groups
-
- This *might* collide with a posix_offset of some trusted domain.
- It's just very unlikely. */
- uid = MAP_UNIX_TO_CYGWIN_ID (sid_sub_auth_rid (sid));
- /* Unfortunately we have no access to the file server from here,
- so we can't generate correct user names. */
- p = wcpcpy (dom, L"Unix_");
- wcpcpy (p, sid_sub_auth (sid, 0) == 1 ? L"User" : L"Group");
- __small_swprintf (name = namebuf, L"%d", uid & UNIX_POSIX_MASK);
- name_style = fully_qualified;
- acc_type = SidTypeUnknown;
+ paranoid_printf ("NtQueryInformationFile(%S) failed, status %y",
+ &upath, status);
+ goto out;
}
- else
+ /* FIXME: Should we test for HighPart set? If so, the
+ passwd or group file is way beyond what we can handle. */
+ /* FIXME 2: It's still ugly that we keep the file in memory.
+ Big organizations have naturally large passwd files. */
+ buf = (char *) malloc (fsi.EndOfFile.LowPart + 1);
+ if (!buf)
{
- if (cygheap->dom.member_machine ()
- && sid_id_auth (sid) == 5 /* SECURITY_NT_AUTHORITY */
- && sid_sub_auth (sid, 0) == SECURITY_NT_NON_UNIQUE)
- {
- /* Check if we know the domain. If so, create a passwd/group
- entry with domain prefix and RID as username. */
- PDS_DOMAIN_TRUSTSW td = NULL;
-
- sid_sub_auth_count (sid) = sid_sub_auth_count (sid) - 1;
- if (RtlEqualSid (sid, cygheap->dom.primary_sid ()))
- {
- domain = cygheap->dom.primary_flat_name ();
- posix_offset = 0x100000;
- }
- else
- for (ULONG idx = 0; (td = cygheap->dom.trusted_domain (idx)); ++idx)
- if (td->DomainSid && RtlEqualSid (sid, td->DomainSid))
- {
- domain = td->NetbiosDomainName;
- posix_offset = fetch_posix_offset (td, &loc_ldap);
- break;
- }
- }
- if (domain)
- {
- sid_sub_auth_count (sid) = sid_sub_auth_count (sid) + 1;
- wcscpy (dom, domain);
- __small_swprintf (name = namebuf, L"%W(%u)",
- is_group () ? L"Group" : L"User",
- sid_sub_auth_rid (sid));
- uid = posix_offset + sid_sub_auth_rid (sid);
- }
- else
- {
- wcpcpy (dom, L"Unknown");
- wcpcpy (name = namebuf, is_group () ? L"Group" : L"User");
- }
- name_style = fully_qualified;
- acc_type = SidTypeUnknown;
+ paranoid_printf ("malloc (%u) failed", fsi.EndOfFile.LowPart);
+ goto out;
}
-
- tmp_pathbuf tp;
- PWCHAR linebuf = tp.w_get ();
- char *line = NULL;
-
- WCHAR posix_name[UNLEN + 1 + DNLEN + 1];
- p = posix_name;
- if (gid == ILLEGAL_GID)
- gid = uid;
- if (name_style >= fully_qualified)
- p = wcpcpy (p, dom);
- if (name_style >= plus_prepended)
- p = wcpcpy (p, cygheap->pg.nss_separator ());
- wcpcpy (p, name);
-
- if (is_group ())
- __small_swprintf (linebuf, L"%W:%W:%u:",
- posix_name, sid.string (sidstr), uid);
- /* For non-users, create a passwd entry which doesn't allow interactive
- logon. Unless it's the SYSTEM account. This conveniently allows to
- logon interactively as SYSTEM for debugging purposes. */
- else if (acc_type != SidTypeUser && sid != well_known_system_sid)
- __small_swprintf (linebuf, L"%W:*:%u:%u:,%W:/:/sbin/nologin",
- posix_name, uid, gid, sid.string (sidstr));
- else
- __small_swprintf (linebuf, L"%W:*:%u:%u:%W%WU-%W\\%W,%W:%W%W:%W",
- posix_name, uid, gid,
- gecos ?: L"", gecos ? L"," : L"",
- dom, name,
- sid.string (sidstr),
- home ? L"" : L"/home/", home ?: name,
- shell ?: L"/bin/bash");
- sys_wcstombs_alloc (&line, HEAP_BUF, linebuf);
- debug_printf ("line: <%s>", line);
- return line;
-}
-
-client_request_pwdgrp::client_request_pwdgrp (fetch_user_arg_t &arg, bool group)
- : client_request (CYGSERVER_REQUEST_PWDGRP, &_parameters, sizeof (_parameters))
-{
- size_t len = 0;
- char *p;
-
- _parameters.in.group = group;
- _parameters.in.type = arg.type;
- switch (arg.type)
- {
- case SID_arg:
- RtlCopySid (sizeof (DBGSID), (PSID) &_parameters.in.arg.sid, *arg.sid);
- len = RtlLengthSid (*arg.sid);
- break;
- case NAME_arg:
- p = stpcpy (_parameters.in.arg.name, arg.name);
- len = p - _parameters.in.arg.name;
- break;
- case ID_arg:
- _parameters.in.arg.id = arg.id;
- len = sizeof (uint32_t);
- }
- msglen (__builtin_offsetof (struct _pwdgrp_param_t::_pwdgrp_in_t, arg) + len);
-}
-
-char *
-pwdgrp::fetch_account_from_cygserver (fetch_user_arg_t &arg)
-{
- client_request_pwdgrp request (arg, is_group ());
- if (request.make_request () == -1 || request.error_code ())
+ status = NtReadFile (fh, NULL, NULL, NULL, &io, buf, fsi.EndOfFile.LowPart,
+ NULL, NULL);
+ if (!NT_SUCCESS (status))
{
- /* Cygserver not running? Don't try again. This will automatically
- avoid an endless loop in cygserver itself. */
- if (request.error_code () == ENOSYS)
- cygheap->pg.nss_disable_cygserver_caching ();
- return NULL;
- }
- if (!request.line ())
- return NULL;
- return cstrdup (request.line ());
-}
-
-void *
-pwdgrp::add_account_from_cygserver (cygpsid &sid)
-{
- /* No, Everyone is no group in terms of POSIX. */
- if (sid_id_auth (sid) == 1 /* SECURITY_WORLD_SID_AUTHORITY */
- && sid_sub_auth (sid, 0) == SECURITY_WORLD_RID)
- return NULL;
- fetch_user_arg_t arg;
- arg.type = SID_arg;
- arg.sid = &sid;
- char *line = fetch_account_from_cygserver (arg);
- return add_account_post_fetch (line, true);
-}
-
-void *
-pwdgrp::add_account_from_cygserver (const char *name)
-{
- fetch_user_arg_t arg;
- arg.type = NAME_arg;
- arg.name = name;
- char *line = fetch_account_from_cygserver (arg);
- return add_account_post_fetch (line, true);
-}
-
-void *
-pwdgrp::add_account_from_cygserver (uint32_t id)
-{
- fetch_user_arg_t arg;
- arg.type = ID_arg;
- arg.id = id;
- char *line = fetch_account_from_cygserver (arg);
- return add_account_post_fetch (line, true);
+ paranoid_printf ("NtReadFile(%S) failed, status %y", &upath, status);
+ free (buf);
+ goto out;
+ }
+ buf[fsi.EndOfFile.LowPart] = '\0';
+ for (char *eptr = buf; (eptr = add_line (eptr)); )
+ continue;
+ debug_printf ("%W curr_lines %d", rel_path, curr_lines);
+ res = succeeded;
+
+out:
+ if (fh)
+ NtClose (fh);
+ debug_printf ("%W load %s", rel_path, res);
+ initialized = true;
}
diff --git a/winsup/cygwin/wincap.cc b/winsup/cygwin/wincap.cc
index f6faa03b6..cdbb1c37e 100644
--- a/winsup/cygwin/wincap.cc
+++ b/winsup/cygwin/wincap.cc
@@ -2,7 +2,7 @@
capability class to the appropriate values.
Copyright 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011,
- 2012, 2013, 2014 Red Hat, Inc.
+ 2012, 2013 Red Hat, Inc.
This file is part of Cygwin.
@@ -49,7 +49,6 @@ wincaps wincap_xpsp2 __attribute__((section (".cygwin_dll_common"), shared)) = {
has_pipe_reject_remote_clients:false,
terminate_thread_frees_stack:false,
has_precise_system_time:false,
- has_microsoft_accounts:false,
};
wincaps wincap_2003 __attribute__((section (".cygwin_dll_common"), shared)) = {
@@ -78,7 +77,6 @@ wincaps wincap_2003 __attribute__((section (".cygwin_dll_common"), shared)) = {
has_pipe_reject_remote_clients:false,
terminate_thread_frees_stack:false,
has_precise_system_time:false,
- has_microsoft_accounts:false,
};
wincaps wincap_vista __attribute__((section (".cygwin_dll_common"), shared)) = {
@@ -107,7 +105,6 @@ wincaps wincap_vista __attribute__((section (".cygwin_dll_common"), shared)) = {
has_pipe_reject_remote_clients:true,
terminate_thread_frees_stack:true,
has_precise_system_time:false,
- has_microsoft_accounts:false,
};
wincaps wincap_7 __attribute__((section (".cygwin_dll_common"), shared)) = {
@@ -136,7 +133,6 @@ wincaps wincap_7 __attribute__((section (".cygwin_dll_common"), shared)) = {
has_pipe_reject_remote_clients:true,
terminate_thread_frees_stack:true,
has_precise_system_time:false,
- has_microsoft_accounts:false,
};
wincaps wincap_8 __attribute__((section (".cygwin_dll_common"), shared)) = {
@@ -165,7 +161,6 @@ wincaps wincap_8 __attribute__((section (".cygwin_dll_common"), shared)) = {
has_pipe_reject_remote_clients:true,
terminate_thread_frees_stack:true,
has_precise_system_time:true,
- has_microsoft_accounts:true,
};
wincapc wincap __attribute__((section (".cygwin_dll_common"), shared));
diff --git a/winsup/cygwin/wincap.h b/winsup/cygwin/wincap.h
index 43c72b648..98fef2656 100644
--- a/winsup/cygwin/wincap.h
+++ b/winsup/cygwin/wincap.h
@@ -1,7 +1,7 @@
/* wincap.h: Header for OS capability class.
Copyright 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009, 2010, 2011,
- 2012, 2013, 2014 Red Hat, Inc.
+ 2012, 2013 Red Hat, Inc.
This file is part of Cygwin.
@@ -39,7 +39,6 @@ struct wincaps
unsigned has_pipe_reject_remote_clients : 1;
unsigned terminate_thread_frees_stack : 1;
unsigned has_precise_system_time : 1;
- unsigned has_microsoft_accounts : 1;
};
class wincapc
@@ -90,7 +89,6 @@ public:
bool IMPLEMENT (has_pipe_reject_remote_clients)
bool IMPLEMENT (terminate_thread_frees_stack)
bool IMPLEMENT (has_precise_system_time)
- bool IMPLEMENT (has_microsoft_accounts)
#undef IMPLEMENT
};
diff --git a/winsup/cygwin/winlean.h b/winsup/cygwin/winlean.h
index 162994854..c50cf747a 100644
--- a/winsup/cygwin/winlean.h
+++ b/winsup/cygwin/winlean.h
@@ -1,6 +1,6 @@
/* winlean.h - Standard "lean" windows include
- Copyright 2010, 2011, 2012, 2013, 2014 Red Hat, Inc.
+ Copyright 2010, 2011, 2012, 2013 Red Hat, Inc.
This file is part of Cygwin.
@@ -58,6 +58,11 @@ details. */
#include <lmcons.h>
#include <ntdef.h>
+/* Temporary kludge for missing flag in Mingw64's w32api. */
+#ifndef PIPE_REJECT_REMOTE_CLIENTS
+#define PIPE_REJECT_REMOTE_CLIENTS 8
+#endif
+
#ifdef __undef_IN
#undef IN
#endif
@@ -74,13 +79,6 @@ details. */
#undef CRITICAL
#endif
-/* So-called "Microsoft Account" SIDs have a netbios domain name
- "MicrosoftAccounts". The problem is, while DNLEN is 15, that domain
- name is 16 chars :-P So we override DNLEN here to be 16, so that calls
- to LookupAccountSid/Name don't fail if the buffer is based on DNLEN. */
-#undef DNLEN
-#define DNLEN 16
-
/* When Terminal Services are installed, the GetWindowsDirectory function
does not return the system installation dir, but a user specific directory
instead. That's not what we have in mind when calling GetWindowsDirectory
diff --git a/winsup/cygwin/winsup.h b/winsup/cygwin/winsup.h
index 770d4bb1c..eb7a423dd 100644
--- a/winsup/cygwin/winsup.h
+++ b/winsup/cygwin/winsup.h
@@ -1,7 +1,7 @@
/* winsup.h: main Cygwin header file.
Copyright 1996, 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006,
- 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014 Red Hat, Inc.
+ 2007, 2008, 2009, 2010, 2011, 2012, 2013 Red Hat, Inc.
This file is part of Cygwin.
@@ -172,8 +172,20 @@ void __reg1 do_exit (int) __attribute__ ((noreturn));
/* libstdc++ malloc operator wrapper support. */
extern struct per_process_cxx_malloc default_cygwin_cxx_malloc;
+/* UID/GID */
+void uinfo_init ();
+
+#define ILLEGAL_UID ((uid_t)-1)
+#define ILLEGAL_GID ((gid_t)-1)
#define ILLEGAL_SEEK ((off_t)-1)
+#ifndef __x86_64__
+#define ILLEGAL_UID16 ((__uid16_t)-1)
+#define ILLEGAL_GID16 ((__gid16_t)-1)
+#define uid16touid32(u16) ((u16)==ILLEGAL_UID16?ILLEGAL_UID:(uid_t)(u16))
+#define gid16togid32(g16) ((g16)==ILLEGAL_GID16?ILLEGAL_GID:(gid_t)(g16))
+#endif
+
/* Convert LARGE_INTEGER into long long */
#define get_ll(pl) (((long long) (pl).HighPart << 32) | (pl).LowPart)
@@ -285,17 +297,6 @@ extern "C" char _data_start__, _data_end__, _bss_start__, _bss_end__;
extern "C" void (*__CTOR_LIST__) (void);
extern "C" void (*__DTOR_LIST__) (void);
-#ifdef NEEDED
-/* This was inexplicably needed after updating a toolchain.
- The need disappeared when updating further but I'm keeping
- it around temporarily in case the issue crops up again.
- This manifests as SEGVs in one of the Interlocked functions below
- in kernel32.dll. */
-#define InterlockedDecrement _InterlockedDecrement
-#define InterlockedExchange _InterlockedExchange
-#define InterlockedIncrement _InterlockedIncrement
-#endif /*NEEDED*/
-
#ifndef NO_GLOBALS_H
#define _RDATA /* See globals.h */
#include "globals.h"
diff --git a/winsup/doc/ChangeLog b/winsup/doc/ChangeLog
index 287fdb751..7518a9767 100644
--- a/winsup/doc/ChangeLog
+++ b/winsup/doc/ChangeLog
@@ -1,3 +1,7 @@
+2014-07-21 Corinna Vinschen <corinna@vinschen.de>
+
+ * new-features.xml: (ov-new1.7.31): Add new section.
+
2014-06-26 Corinna Vinschen <corinna@vinschen.de>
* legal.xml: Fix copyright.
diff --git a/winsup/doc/new-features.xml b/winsup/doc/new-features.xml
index ff7ed232d..0c24c2650 100644
--- a/winsup/doc/new-features.xml
+++ b/winsup/doc/new-features.xml
@@ -4,6 +4,33 @@
<sect1 id="ov-new1.7"><title>What's new and what changed in Cygwin 1.7</title>
+<sect2 id="ov-new1.7.31"><title>What's new and what changed from 1.7.30 to 1.7.31</title>
+
+<itemizedlist mark="bullet">
+
+<listitem><para>
+Improve performance of send(2), sendto(2), sendmsg(2) when using small
+input buffers.
+</para></listitem>
+
+<listitem><para>
+The default pthread_mutex type is now PTHREAD_MUTEX_NORMAL, rather than
+PTHREAD_MUTEX_ERRORCHECK, just as on Linux.
+</para></listitem>
+
+<listitem><para>
+Align pthread_attr stack functions more closely to Linux.
+</para></listitem>
+
+<listitem><para>
+Mark pthread_attr_getstackaddr and pthread_attr_setstackaddr as deprecated,
+as on Linux.
+</para></listitem>
+
+</itemizedlist>
+
+</sect2>
+
<sect2 id="ov-new1.7.29"><title>What's new and what changed from 1.7.28 to 1.7.29</title>
<itemizedlist mark="bullet">
diff --git a/winsup/utils/ChangeLog b/winsup/utils/ChangeLog
index b01600fb8..f61161c17 100644
--- a/winsup/utils/ChangeLog
+++ b/winsup/utils/ChangeLog
@@ -20,40 +20,6 @@
* minidumper.cc (minidump): Fix copy and paste error in checking
result of OpenProcess().
-2014-02-24 Corinna Vinschen <corinna@vinschen.de>
-
- * mkgroup.c (domlist_t): Drop id_offset.
- (get_dcname): Remove.
- (current_group): Remove.
- (enum_unix_groups): Simplify. Change space to underscore in domain
- name.
- (enum_local_groups): Simplify to accommodate the fact that it's only
- called for foreign machines.
- (enum_groups): Ditto.
- (print_special_by_sid): Remove.
- (print_special_by_name): Remove.
- (usage): Align to new code.
- (fetch_primary_domain): Remove.
- (main): Use cygwin_internal CW_SETENT, CW_GETENT and CW_ENDENT method.
- Call enum_local_groups, enum_groups, and enum_unix_groups only for
- foreign machines.
- * mkpasswd.c (get_dcname): Remove.
- (current_user): Remove.
- (enum_unix_users): Simplify. Change space to underscore in domain name.
- (enum_users): Simplify to accommodate the fact that it's only
- called for foreign machines.
- (print_special_by_sid): Remove.
- (usage): Align to new code.
- (longopts): Add -b/--no-builtin option.
- (opts): Add -b option.
- (print_special_by_name): Remove.
- (enum_std_accounts): Remove.
- (fetch_primary_domain): Remove.
- (main): Use cygwin_internal CW_SETENT, CW_GETENT and CW_ENDENT method.
- Call enum_users and enum_unix_users only for foreign machines.
- * utils.xml (mkgroup): Align documentation to new usage.
- (mkpasswd): Ditto.
-
2014-02-23 Jon TURNEY <jon.turney@dronecode.org.uk>
* minidumper.cc (minidump): Fix -t option argument handling.
diff --git a/winsup/utils/mkgroup.c b/winsup/utils/mkgroup.c
index 7b102ec99..05f5910b0 100644
--- a/winsup/utils/mkgroup.c
+++ b/winsup/utils/mkgroup.c
@@ -1,7 +1,7 @@
/* mkgroup.c:
Copyright 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007,
- 2008, 2009, 2010, 2011, 2012, 2013, 2014 Red Hat, Inc.
+ 2008, 2009, 2010, 2011, 2012, 2013 Red Hat, Inc.
This file is part of Cygwin.
@@ -21,7 +21,6 @@
#include <inttypes.h>
#include <getopt.h>
#include <io.h>
-#include <grp.h>
#include <sys/fcntl.h>
#include <sys/cygwin.h>
#include <cygwin/version.h>
@@ -30,7 +29,9 @@
#include <wininet.h>
#include <iptypes.h>
#include <ntsecapi.h>
+#include <dsgetdc.h>
#include <ntdef.h>
+#include "loadlib.h"
#define print_win_error(x) _print_win_error(x, __LINE__)
@@ -46,6 +47,7 @@ SID_IDENTIFIER_AUTHORITY sid_nt_auth = {SECURITY_NT_AUTHORITY};
typedef struct
{
char *str;
+ DWORD id_offset;
BOOL domain;
BOOL with_dom;
} domlist_t;
@@ -68,6 +70,31 @@ _print_win_error (DWORD code, int line)
line, (unsigned int) code);
}
+static PWCHAR
+get_dcname (char *domain)
+{
+ static WCHAR server[INTERNET_MAX_HOST_NAME_LENGTH + 1];
+ DWORD rc;
+ WCHAR domain_name[MAX_DOMAIN_NAME_LEN + 1];
+ PDOMAIN_CONTROLLER_INFOW pdci = NULL;
+
+ if (domain)
+ {
+ mbstowcs (domain_name, domain, strlen (domain) + 1);
+ rc = DsGetDcNameW (NULL, domain_name, NULL, NULL, 0, &pdci);
+ }
+ else
+ rc = DsGetDcNameW (NULL, NULL, NULL, NULL, 0, &pdci);
+ if (rc != ERROR_SUCCESS)
+ {
+ print_win_error (rc);
+ return (PWCHAR) -1;
+ }
+ wcscpy (server, pdci->DomainControllerName);
+ NetApiBufferFree (pdci);
+ return server;
+}
+
static char *
put_sid (PSID psid)
{
@@ -122,10 +149,40 @@ fetch_current_pgrp_sid ()
}
static void
-enum_unix_groups (domlist_t *mach, const char *sep, DWORD id_offset,
+current_group (const char *sep, DWORD id_offset)
+{
+ WCHAR grp[GNLEN + 1];
+ WCHAR dom[MAX_DOMAIN_NAME_LEN + 1];
+ DWORD glen = GNLEN + 1;
+ DWORD dlen = MAX_DOMAIN_NAME_LEN + 1;
+ int gid;
+ SID_NAME_USE acc_type;
+
+ if (!curr_pgrp.psid
+ || !LookupAccountSidW (NULL, curr_pgrp.psid, grp, &glen, dom, &dlen,
+ &acc_type))
+ {
+ print_win_error (GetLastError ());
+ return;
+ }
+ gid = *GetSidSubAuthority (curr_pgrp.psid,
+ *GetSidSubAuthorityCount(curr_pgrp.psid) - 1);
+ printf ("%ls%s%ls:%s:%" PRIu32 ":\n",
+ sep ? dom : L"",
+ sep ?: "",
+ grp,
+ put_sid (curr_pgrp.psid),
+ (unsigned int) (id_offset + gid));
+}
+
+static void
+enum_unix_groups (domlist_t *dom_or_machine, const char *sep, DWORD id_offset,
char *unix_grp_list)
{
WCHAR machine[INTERNET_MAX_HOST_NAME_LENGTH + 1];
+ PWCHAR servername = NULL;
+ char *d_or_m = dom_or_machine ? dom_or_machine->str : NULL;
+ BOOL with_dom = dom_or_machine ? dom_or_machine->with_dom : FALSE;
SID_IDENTIFIER_AUTHORITY auth = { { 0, 0, 0, 0, 0, 22 } };
char *gstr, *grp_list;
WCHAR grp[GNLEN + sizeof ("Unix Group\\") + 1];
@@ -135,13 +192,17 @@ enum_unix_groups (domlist_t *mach, const char *sep, DWORD id_offset,
char psid_buffer[MAX_SID_LEN];
SID_NAME_USE acc_type;
- int ret = mbstowcs (machine, mach->str, INTERNET_MAX_HOST_NAME_LENGTH + 1);
+ if (!d_or_m)
+ return;
+
+ int ret = mbstowcs (machine, d_or_m, INTERNET_MAX_HOST_NAME_LENGTH + 1);
if (ret < 1 || ret >= INTERNET_MAX_HOST_NAME_LENGTH + 1)
{
fprintf (stderr, "%s: Invalid machine name '%s'. Skipping...\n",
- program_invocation_short_name, mach->str);
+ program_invocation_short_name, d_or_m);
return;
}
+ servername = machine;
if (!AllocateAndInitializeSid (&auth, 2, 2, 0, 0, 0, 0, 0, 0, 0, &psid))
return;
@@ -161,15 +222,15 @@ enum_unix_groups (domlist_t *mach, const char *sep, DWORD id_offset,
if (ret < 1 || ret >= GNLEN + 1)
fprintf (stderr, "%s: Invalid group name '%s'. Skipping...\n",
program_invocation_short_name, gstr);
- else if (LookupAccountNameW (machine, grp,
+ else if (LookupAccountNameW (servername, grp,
psid = (PSID) psid_buffer,
(sidlen = MAX_SID_LEN, &sidlen),
dom,
(dlen = MAX_DOMAIN_NAME_LEN + 1, &dlen),
&acc_type))
printf ("%s%s%ls:%s:%" PRIu32 ":\n",
- mach->with_dom ? "Unix_Group" : "",
- mach->with_dom ? sep : "",
+ with_dom ? "Unix Group" : "",
+ with_dom ? sep : "",
p,
put_sid (psid),
(unsigned int) (id_offset +
@@ -198,15 +259,15 @@ enum_unix_groups (domlist_t *mach, const char *sep, DWORD id_offset,
{
*GetSidSubAuthority (psid, *GetSidSubAuthorityCount(psid) - 1)
= start;
- if (LookupAccountSidW (machine, psid,
+ if (LookupAccountSidW (servername, psid,
grp, (glen = GNLEN + 1, &glen),
dom,
(dlen = MAX_DOMAIN_NAME_LEN + 1, &dlen),
&acc_type)
&& !iswdigit (grp[0]))
printf ("%s%s%ls:%s:%" PRIu32 ":\n",
- mach->with_dom ? "Unix_Group" : "",
- mach->with_dom ? sep : "",
+ with_dom ? "Unix Group" : "",
+ with_dom ? sep : "",
grp,
put_sid (psid),
(unsigned int) (id_offset + start));
@@ -219,11 +280,14 @@ enum_unix_groups (domlist_t *mach, const char *sep, DWORD id_offset,
}
static int
-enum_local_groups (domlist_t *mach, const char *sep,
+enum_local_groups (BOOL domain, domlist_t *dom_or_machine, const char *sep,
DWORD id_offset, char *disp_groupname, int print_builtin,
int print_current)
{
WCHAR machine[INTERNET_MAX_HOST_NAME_LENGTH + 1];
+ PWCHAR servername = NULL;
+ char *d_or_m = dom_or_machine ? dom_or_machine->str : NULL;
+ BOOL with_dom = dom_or_machine ? dom_or_machine->with_dom : FALSE;
LOCALGROUP_INFO_0 *buffer;
DWORD entriesread = 0;
DWORD totalentries = 0;
@@ -231,12 +295,22 @@ enum_local_groups (domlist_t *mach, const char *sep,
WCHAR gname[GNLEN + 1];
DWORD rc;
- int ret = mbstowcs (machine, mach->str, INTERNET_MAX_HOST_NAME_LENGTH + 1);
- if (ret < 1 || ret >= INTERNET_MAX_HOST_NAME_LENGTH + 1)
+ if (domain)
{
- fprintf (stderr, "%s: Invalid machine name '%s'. Skipping...\n",
- program_invocation_short_name, mach->str);
- return 1;
+ 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",
+ program_invocation_short_name, d_or_m);
+ return 1;
+ }
+ servername = machine;
}
do
@@ -246,7 +320,7 @@ enum_local_groups (domlist_t *mach, const char *sep,
if (disp_groupname)
{
mbstowcs (gname, disp_groupname, GNLEN + 1);
- rc = NetLocalGroupGetInfo (machine, gname, 0, (void *) &buffer);
+ rc = NetLocalGroupGetInfo (servername, gname, 0, (void *) &buffer);
if (rc == ERROR_SUCCESS)
entriesread = 1;
/* Allow further searching for the group and avoid annoying
@@ -256,7 +330,7 @@ enum_local_groups (domlist_t *mach, const char *sep,
return 0;
}
else
- rc = NetLocalGroupEnum (machine, 0, (void *) &buffer,
+ rc = NetLocalGroupEnum (servername, 0, (void *) &buffer,
MAX_PREFERRED_LENGTH, &entriesread,
&totalentries, &resume_handle);
switch (rc)
@@ -286,7 +360,7 @@ enum_local_groups (domlist_t *mach, const char *sep,
PDBGSID pdsid;
BOOL is_builtin = FALSE;
- if (!LookupAccountNameW (machine, buffer[i].lgrpi0_name, psid,
+ if (!LookupAccountNameW (servername, buffer[i].lgrpi0_name, psid,
&sid_length, domain_name, &domname_len,
&acc_type))
{
@@ -303,7 +377,7 @@ enum_local_groups (domlist_t *mach, const char *sep,
wcscat (domname, buffer[i].lgrpi0_name);
sid_length = MAX_SID_LEN;
domname_len = MAX_DOMAIN_NAME_LEN + 1;
- if (!LookupAccountNameW (machine, domname,
+ if (!LookupAccountNameW (servername, domname,
psid, &sid_length,
domain_name, &domname_len,
&acc_type))
@@ -341,8 +415,8 @@ enum_local_groups (domlist_t *mach, const char *sep,
gid = *GetSidSubAuthority (psid, *GetSidSubAuthorityCount(psid) - 1);
printf ("%ls%s%ls:%s:%" PRIu32 ":\n",
- mach->with_dom && !is_builtin ? domain_name : L"",
- mach->with_dom || is_builtin ? sep : "",
+ with_dom && !is_builtin ? domain_name : L"",
+ with_dom && !is_builtin ? sep : "",
buffer[i].lgrpi0_name,
put_sid (psid),
(unsigned int) (gid + (is_builtin ? 0 : id_offset)));
@@ -362,10 +436,13 @@ skip_group:
}
static void
-enum_groups (domlist_t *mach, const char *sep, DWORD id_offset,
- char *disp_groupname, int print_current)
+enum_groups (BOOL domain, domlist_t *dom_or_machine, const char *sep,
+ DWORD id_offset, char *disp_groupname, int print_current)
{
WCHAR machine[INTERNET_MAX_HOST_NAME_LENGTH + 1];
+ PWCHAR servername = NULL;
+ char *d_or_m = dom_or_machine ? dom_or_machine->str : NULL;
+ BOOL with_dom = dom_or_machine ? dom_or_machine->with_dom : FALSE;
GROUP_INFO_2 *buffer;
DWORD entriesread = 0;
DWORD totalentries = 0;
@@ -373,12 +450,22 @@ enum_groups (domlist_t *mach, const char *sep, DWORD id_offset,
WCHAR gname[GNLEN + 1];
DWORD rc;
- int ret = mbstowcs (machine, mach->str, INTERNET_MAX_HOST_NAME_LENGTH + 1);
- if (ret < 1 || ret >= INTERNET_MAX_HOST_NAME_LENGTH + 1)
+ if (domain)
{
- fprintf (stderr, "%s: Invalid machine name '%s'. Skipping...\n",
- program_invocation_short_name, mach->str);
- return;
+ 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",
+ program_invocation_short_name, d_or_m);
+ return;
+ }
+ servername = machine;
}
do
@@ -388,7 +475,8 @@ enum_groups (domlist_t *mach, const char *sep, DWORD id_offset,
if (disp_groupname != NULL)
{
mbstowcs (gname, disp_groupname, GNLEN + 1);
- rc = NetGroupGetInfo (machine, (LPWSTR) & gname, 2, (void *) &buffer);
+ rc = NetGroupGetInfo (servername, (LPWSTR) & gname, 2,
+ (void *) &buffer);
entriesread=1;
/* Avoid annoying error messages just because the group hasn't been
found. */
@@ -396,8 +484,9 @@ enum_groups (domlist_t *mach, const char *sep, DWORD id_offset,
return;
}
else
- rc = NetGroupEnum (machine, 2, (void *) & buffer, MAX_PREFERRED_LENGTH,
- &entriesread, &totalentries, &resume_handle);
+ rc = NetGroupEnum (servername, 2, (void *) & buffer,
+ MAX_PREFERRED_LENGTH, &entriesread, &totalentries,
+ &resume_handle);
switch (rc)
{
case ERROR_ACCESS_DENIED:
@@ -423,7 +512,7 @@ enum_groups (domlist_t *mach, const char *sep, DWORD id_offset,
SID_NAME_USE acc_type;
int gid = buffer[i].grpi2_group_id;
- if (!LookupAccountNameW (machine, buffer[i].grpi2_name,
+ if (!LookupAccountNameW (servername, buffer[i].grpi2_name,
psid, &sid_length,
domain_name, &domname_len,
&acc_type))
@@ -436,13 +525,16 @@ enum_groups (domlist_t *mach, const char *sep, DWORD id_offset,
{
WCHAR domname[MAX_DOMAIN_NAME_LEN + GNLEN + 2];
- wcscpy (domname, machine);
+ wcscpy (domname, domain || !servername
+ ? domain_name : servername);
wcscat (domname, L"\\");
wcscat (domname, buffer[i].grpi2_name);
sid_length = MAX_SID_LEN;
domname_len = MAX_DOMAIN_NAME_LEN + 1;
- if (!LookupAccountNameW (machine, domname, psid, &sid_length,
- domain_name, &domname_len, &acc_type))
+ if (!LookupAccountNameW (servername, domname,
+ psid, &sid_length,
+ domain_name, &domname_len,
+ &acc_type))
{
print_win_error (GetLastError ());
fprintf(stderr, " (%ls)\n", domname);
@@ -455,8 +547,8 @@ enum_groups (domlist_t *mach, const char *sep, DWORD id_offset,
got_curr_pgrp = TRUE;
printf ("%ls%s%ls:%s:%" PRIu32 ":\n",
- mach->with_dom ? domain_name : L"",
- mach->with_dom ? sep : "",
+ with_dom ? domain_name : L"",
+ with_dom ? sep : "",
buffer[i].grpi2_name,
put_sid (psid),
(unsigned int) (id_offset + gid));
@@ -468,42 +560,107 @@ enum_groups (domlist_t *mach, const char *sep, DWORD id_offset,
while (rc == ERROR_MORE_DATA);
}
+static void
+print_special_by_sid (PSID_IDENTIFIER_AUTHORITY auth, BYTE cnt,
+ DWORD sub1, DWORD sub2, DWORD sub3, DWORD sub4,
+ DWORD sub5, DWORD sub6, DWORD sub7, DWORD sub8)
+{
+ WCHAR grp[GNLEN + 1], dom[MAX_DOMAIN_NAME_LEN + 1];
+ DWORD glen, dlen, rid;
+ PSID psid;
+ SID_NAME_USE acc_type;
+
+ if (AllocateAndInitializeSid (auth, cnt, sub1, sub2, sub3, sub4,
+ sub5, sub6, sub7, sub8, &psid))
+ {
+ if (LookupAccountSidW (NULL, psid,
+ grp, (glen = GNLEN + 1, &glen),
+ dom, (dlen = MAX_DOMAIN_NAME_LEN + 1, &dlen),
+ &acc_type))
+ {
+ if (sub8)
+ rid = sub8;
+ else if (sub7)
+ rid = sub7;
+ else if (sub6)
+ rid = sub6;
+ else if (sub5)
+ rid = sub5;
+ else if (sub4)
+ rid = sub4;
+ else if (sub3)
+ rid = sub3;
+ else if (sub2)
+ rid = sub2;
+ else
+ rid = sub1;
+ printf ("%ls:%s:%" PRIu32 ":\n", grp, put_sid (psid),
+ (unsigned int) rid);
+ }
+ FreeSid (psid);
+ }
+}
+
+static void
+print_special_by_name (PCWSTR name, gid_t gid)
+{
+ DWORD size = 256, dom_size = 256;
+ PSID sid = (PSID) alloca (size);
+ WCHAR dom[dom_size];
+ SID_NAME_USE use;
+
+ PWCHAR name_only = wcschr (name, L'\\');
+ if (name_only)
+ ++name_only;
+
+ if (LookupAccountNameW (NULL, name, sid, &size, dom, &dom_size, &use))
+ printf ("%ls:%s:%lu:\n",
+ name_only ?: name, put_sid (sid), (unsigned long) gid);
+}
+
static int
usage (FILE * stream)
{
fprintf (stream,
"Usage: %s [OPTION]...\n"
"\n"
-"Write /etc/group-like output to stdout\n"
+"Print /etc/group file to stdout\n"
"\n"
"Options:\n"
"\n"
-" -l,--local [machine] print local groups\n"
+" -l,--local [machine[,offset]]\n"
+" print local groups with gid offset offset\n"
" (from local machine if no machine specified)\n"
-" -L,--Local machine ditto, but generate groupname with machine prefix\n"
-" -d,--domain [domain] print domain groups\n"
+" -L,--Local [machine[,offset]]\n"
+" ditto, but generate groupname with machine prefix\n"
+" -d,--domain [domain[,offset]]\n"
+" print domain groups with gid offset offset\n"
" (from current domain if no domain specified)\n"
+" -D,--Domain [domain[,offset]]\n"
+" ditto, but generate groupname with machine prefix\n"
" -c,--current print current group\n"
-" -S,--separator char for -l use character char as domain\\group\n"
-" separator in groupname instead of default '%s'\n"
-" -o,--id-offset offset change the default offset (0x10000) added to\n"
-" gids of foreign machine accounts.\n"
+" -C,--Current ditto, but generate groupname with machine or\n"
+" domain prefix\n"
+" -S,--separator char for -L, -D, -C use character char as domain\\group\n"
+" separator in groupname instead of the default '\\'\n"
+" -o,--id-offset offset change the default offset (10000) added to gids\n"
+" in domain or foreign server accounts.\n"
" -g,--group groupname only return information for the specified group\n"
-" one of -l, -d must be specified, too\n"
+" one of -l, -L, -d, -D must be specified, too\n"
" -b,--no-builtin don't print BUILTIN groups\n"
-" -U,--unix grouplist print UNIX groups when using -l on a UNIX Samba\n"
-" server. grouplist is a comma-separated list of\n"
-" groupnames or gid ranges (root,-25,50-100).\n"
+" -U,--unix grouplist additionally print UNIX groups when using -l or -L\n"
+" on a UNIX Samba server\n"
+" grouplist is a comma-separated list of groupnames\n"
+" or gid ranges (root,-25,50-100).\n"
" (enumerating large ranges can take a long time!)\n"
+" -s,--no-sids (ignored)\n"
+" -u,--users (ignored)\n"
" -h,--help print this message\n"
" -v,--version print version information and exit\n"
"\n"
"Default is to print local groups on stand-alone machines, plus domain\n"
-"groups on domain controllers and domain member machines.\n\n"
-"Don't use this command to generate a local /etc/group file, unless you\n"
-"really need one. See the Cygwin User's Guide for more information.\n"
-"\n", program_invocation_short_name,
- (const char *) cygwin_internal (CW_GETNSSSEP));
+"groups on domain controllers and domain member machines.\n"
+"\n", program_invocation_short_name);
return 1;
}
@@ -542,20 +699,44 @@ print_version ()
strrchr (__DATE__, ' ') + 1);
}
+static PPOLICY_PRIMARY_DOMAIN_INFO p_dom;
+
+static BOOL
+fetch_primary_domain ()
+{
+ NTSTATUS status;
+ LSA_OBJECT_ATTRIBUTES oa = { 0, 0, 0, 0, 0, 0 };
+ LSA_HANDLE lsa;
+
+ if (!p_dom)
+ {
+ status = LsaOpenPolicy (NULL, &oa, POLICY_EXECUTE, &lsa);
+ if (!NT_SUCCESS (status))
+ return FALSE;
+ status = LsaQueryInformationPolicy (lsa, PolicyPrimaryDomainInformation,
+ (PVOID *) ((void *) &p_dom));
+ LsaClose (lsa);
+ if (!NT_SUCCESS (status))
+ return FALSE;
+ }
+ return !!p_dom->Sid;
+}
+
int
main (int argc, char **argv)
{
int print_domlist = 0;
domlist_t domlist[32];
- char *opt, *p;
+ char *opt, *p, *ep;
int print_current = 0;
+ int print_system = 0;
int print_builtin = 1;
char *print_unix = NULL;
- const char *sep_char = (const char *) cygwin_internal (CW_GETNSSSEP);
- DWORD id_offset = 0x10000, off;
+ const char *sep_char = "\\";
+ DWORD id_offset = 10000, off;
int c, i;
char *disp_groupname = NULL;
- //BOOL in_domain;
+ BOOL in_domain;
int optional_args = 0;
if (!isatty (1))
@@ -565,21 +746,22 @@ main (int argc, char **argv)
setlocale (LC_CTYPE, "");
if (!strcmp (setlocale (LC_CTYPE, NULL), "C"))
setlocale (LC_CTYPE, "en_US.UTF-8");
+ in_domain = fetch_primary_domain ();
fetch_current_pgrp_sid ();
if (argc == 1)
{
- int enums = ENUM_PRIMARY | ENUM_LOCAL | ENUM_BUILTIN;
- uintptr_t ticket = cygwin_internal (CW_SETENT, TRUE, enums, NULL);
- if (ticket)
+ print_special_by_sid (&sid_nt_auth, 1, SECURITY_LOCAL_SYSTEM_RID,
+ 0, 0, 0, 0, 0, 0, 0);
+ if (in_domain)
{
- struct group *grp;
-
- while ((grp = (struct group *) cygwin_internal (CW_GETENT, TRUE,
- ticket)))
- printf ("%s:%s:%u:\n", grp->gr_name, grp->gr_passwd, grp->gr_gid);
- cygwin_internal (CW_ENDENT, TRUE, ticket);
+ if (!enum_local_groups (TRUE, NULL, sep_char, id_offset,
+ disp_groupname, print_builtin, 0))
+ enum_groups (TRUE, NULL, sep_char, id_offset, disp_groupname, 0);
}
+ else if (!enum_local_groups (FALSE, NULL, sep_char, 0, disp_groupname,
+ print_builtin, 0))
+ enum_groups (FALSE, NULL, sep_char, 0, disp_groupname, 0);
return 0;
}
@@ -617,10 +799,15 @@ main (int argc, char **argv)
domlist[i].str);
goto skip;
}
- domlist[print_domlist].str = opt;
+ if (!(domlist[print_domlist].str = opt))
+ print_system = 1;
+ domlist[print_domlist].id_offset = UINT32_MAX;
if (opt && (p = strchr (opt, ',')))
{
- if (p == opt)
+ if (p == opt
+ || !isdigit ((unsigned char) p[1])
+ || (domlist[print_domlist].id_offset = strtol (p + 1, &ep, 10)
+ , *ep))
{
fprintf (stderr, "%s: Malformed machine,offset string '%s'. "
"Skipping...\n", program_invocation_short_name, opt);
@@ -628,15 +815,15 @@ main (int argc, char **argv)
}
*p = '\0';
}
- domlist[print_domlist++].with_dom = (c == 'L');
+ domlist[print_domlist++].with_dom = (c == 'D' || c == 'L');
skip:
break;
case 'S':
sep_char = optarg;
if (strlen (sep_char) > 1)
{
- fprintf (stderr, "%s: Only one ASCII character allowed as "
- "domain\\user separator character.\n",
+ fprintf (stderr, "%s: Only one character allowed as domain\\user "
+ "separator character.\n",
program_invocation_short_name);
return 1;
}
@@ -651,6 +838,8 @@ skip:
print_unix = optarg;
break;
case 'c':
+ sep_char = NULL;
+ /*FALLTHRU*/
case 'C':
print_current = 1;
break;
@@ -687,77 +876,34 @@ skip:
exit (1);
}
- struct group *pgrp = NULL;
- if (print_current)
- pgrp = (struct group *) cygwin_internal (CW_GETGRSID, TRUE, curr_pgrp.psid);
-
- int enums = ENUM_NONE;
- WCHAR tdoms[print_domlist * 258];
- PWCHAR t = tdoms;
- if (!disp_groupname && print_builtin && print_domlist)
- enums |= ENUM_BUILTIN;
- for (i = 0; i < print_domlist; ++i)
+ /* Get 'system' group */
+ if (!disp_groupname && print_system && print_builtin && print_domlist)
{
- if (domlist[i].domain)
- {
- if (domlist[i].str)
- {
- enums |= ENUM_TDOMS;
- t += mbstowcs (t, domlist[i].str, 257);
- *t++ = L'\0';
- }
- else
- enums |= ENUM_PRIMARY;
- }
- else if (!domlist[i].str)
- enums |= ENUM_LOCAL;
+ print_special_by_sid (&sid_nt_auth, 1, SECURITY_LOCAL_SYSTEM_RID,
+ 0, 0, 0, 0, 0, 0, 0);
+ print_special_by_name (L"NT SERVICE\\TrustedInstaller", -2);
}
- if (t > tdoms)
- *t++ = L'\0';
- if (enums)
- {
- uintptr_t ticket = cygwin_internal (CW_SETENT, TRUE, enums,
- t > tdoms ? tdoms : NULL);
- if (ticket)
- {
- struct group *grp;
- const char *nss_sep = (const char *) cygwin_internal (CW_GETNSSSEP);
-
- while ((grp = (struct group *)
- cygwin_internal (CW_GETENT, TRUE, ticket)))
- {
- if (disp_groupname
- && strcasecmp (disp_groupname, grp->gr_name) != 0
- && (!(p = strchr (grp->gr_name, nss_sep[0]))
- || strcasecmp (disp_groupname, p + 1) != 0))
- continue;
- printf ("%s:%s:%u:\n", grp->gr_name, grp->gr_passwd,
- grp->gr_gid);
- if (pgrp && !strcmp (grp->gr_passwd, pgrp->gr_passwd))
- got_curr_pgrp = TRUE;
- }
- cygwin_internal (CW_ENDENT, TRUE, ticket);
- }
- }
-
- if (print_current && !got_curr_pgrp)
- printf ("%s:%s:%u:\n", pgrp->gr_name, pgrp->gr_passwd, pgrp->gr_gid);
- off = 0xfd000000;
+ off = id_offset;
for (i = 0; i < print_domlist; ++i)
{
- if (domlist[i].domain || !domlist[i].str)
- continue;
- if (!enum_local_groups (domlist + i, sep_char, off, disp_groupname,
- print_builtin, print_current))
+ DWORD my_off = (domlist[i].domain || domlist[i].str)
+ ? domlist[i].id_offset != UINT_MAX
+ ? domlist[i].id_offset : off : 0;
+ if (!enum_local_groups (domlist[i].domain, domlist + i, sep_char,
+ my_off, disp_groupname, print_builtin, print_current))
{
- enum_groups (domlist + i, sep_char, off, disp_groupname,
- print_current);
if (!domlist[i].domain && domlist[i].str && print_unix)
- enum_unix_groups (domlist + i, sep_char, 0xff000000, print_unix);
- off += id_offset;
+ enum_unix_groups (domlist + i, sep_char, my_off, print_unix);
+ enum_groups (domlist[i].domain, domlist + i, sep_char, my_off,
+ disp_groupname, print_current);
+ if (my_off)
+ off += id_offset;
}
}
+ if (print_current && !got_curr_pgrp)
+ current_group (sep_char, off);
+
return 0;
}
diff --git a/winsup/utils/mkpasswd.c b/winsup/utils/mkpasswd.c
index a2c664ed1..d080dbd70 100644
--- a/winsup/utils/mkpasswd.c
+++ b/winsup/utils/mkpasswd.c
@@ -1,7 +1,7 @@
/* mkpasswd.c:
Copyright 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2005, 2006, 2008, 2009,
- 2010, 2011, 2012, 2013, 2014 Red Hat, Inc.
+ 2010, 2011, 2012, 2013 Red Hat, Inc.
This file is part of Cygwin.
@@ -21,7 +21,6 @@
#include <inttypes.h>
#include <getopt.h>
#include <io.h>
-#include <pwd.h>
#include <sys/fcntl.h>
#include <sys/cygwin.h>
#include <cygwin/version.h>
@@ -32,6 +31,7 @@
#include <ntsecapi.h>
#include <dsgetdc.h>
#include <ntdef.h>
+#include "loadlib.h"
#define print_win_error(x) _print_win_error(x, __LINE__)
@@ -47,6 +47,7 @@ SID_IDENTIFIER_AUTHORITY sid_nt_auth = {SECURITY_NT_AUTHORITY};
typedef struct
{
char *str;
+ DWORD id_offset;
BOOL domain;
BOOL with_dom;
} domlist_t;
@@ -69,6 +70,31 @@ _print_win_error(DWORD code, int line)
line, (unsigned int) code);
}
+static PWCHAR
+get_dcname (char *domain)
+{
+ static WCHAR server[INTERNET_MAX_HOST_NAME_LENGTH + 1];
+ DWORD rc;
+ WCHAR domain_name[MAX_DOMAIN_NAME_LEN + 1];
+ PDOMAIN_CONTROLLER_INFOW pdci = NULL;
+
+ if (domain)
+ {
+ mbstowcs (domain_name, domain, strlen (domain) + 1);
+ rc = DsGetDcNameW (NULL, domain_name, NULL, NULL, 0, &pdci);
+ }
+ else
+ rc = DsGetDcNameW (NULL, NULL, NULL, NULL, 0, &pdci);
+ if (rc != ERROR_SUCCESS)
+ {
+ print_win_error (rc);
+ return (PWCHAR) -1;
+ }
+ wcscpy (server, pdci->DomainControllerName);
+ NetApiBufferFree (pdci);
+ return server;
+}
+
static char *
put_sid (PSID sid)
{
@@ -124,10 +150,72 @@ fetch_current_user_sid ()
}
static void
-enum_unix_users (domlist_t *mach, const char *sep, DWORD id_offset,
+current_user (const char *sep, const char *passed_home_path, DWORD id_offset,
+ const char *disp_username)
+{
+ WCHAR user[UNLEN + 1];
+ WCHAR dom[MAX_DOMAIN_NAME_LEN + 1];
+ DWORD ulen = UNLEN + 1;
+ DWORD dlen = MAX_DOMAIN_NAME_LEN + 1;
+ SID_NAME_USE acc_type;
+ int uid, gid;
+ char homedir_psx[PATH_MAX] = {0};
+
+ if (!curr_user.psid || !curr_pgrp.psid
+ || !LookupAccountSidW (NULL, curr_user.psid, user, &ulen, dom, &dlen,
+ &acc_type))
+ {
+ print_win_error (GetLastError ());
+ return;
+ }
+
+ uid = *GetSidSubAuthority (curr_user.psid,
+ *GetSidSubAuthorityCount(curr_user.psid) - 1);
+ gid = *GetSidSubAuthority (curr_pgrp.psid,
+ *GetSidSubAuthorityCount(curr_pgrp.psid) - 1);
+ if (passed_home_path[0] == '\0')
+ {
+ char *envhome = getenv ("HOME");
+
+ /* If $HOME exists and is non-empty, just copy it over to homedir_psx.
+ Otherwise, generate a new path of the form "/home/$USER". */
+ if (envhome && envhome[0] != '\0')
+ strncat (homedir_psx, envhome, sizeof (homedir_psx) - 1);
+ else
+ {
+ wcstombs (stpncpy (homedir_psx, "/home/", sizeof (homedir_psx)),
+ user, sizeof (homedir_psx) - 6);
+ homedir_psx[PATH_MAX - 1] = '\0';
+ }
+ }
+ else
+ {
+ char *p = stpncpy (homedir_psx, passed_home_path, sizeof (homedir_psx));
+ wcstombs (p, user, sizeof (homedir_psx) - (p - homedir_psx));
+ homedir_psx[PATH_MAX - 1] = '\0';
+ }
+
+ printf ("%ls%s%ls:unused:%" PRIu32 ":%" PRIu32
+ ":U-%ls\\%ls,%s:%s:/bin/bash\n",
+ sep ? dom : L"",
+ sep ?: "",
+ user,
+ (unsigned int) (id_offset + uid),
+ (unsigned int) (id_offset + gid),
+ dom,
+ user,
+ put_sid (curr_user.psid),
+ homedir_psx);
+}
+
+static void
+enum_unix_users (domlist_t *dom_or_machine, const char *sep, DWORD id_offset,
char *unix_user_list)
{
WCHAR machine[INTERNET_MAX_HOST_NAME_LENGTH + 1];
+ PWCHAR servername = NULL;
+ char *d_or_m = dom_or_machine ? dom_or_machine->str : NULL;
+ BOOL with_dom = dom_or_machine ? dom_or_machine->with_dom : FALSE;
SID_IDENTIFIER_AUTHORITY auth = { { 0, 0, 0, 0, 0, 22 } };
char *ustr, *user_list;
WCHAR user[UNLEN + sizeof ("Unix User\\") + 1];
@@ -137,13 +225,17 @@ enum_unix_users (domlist_t *mach, const char *sep, DWORD id_offset,
char psid_buffer[MAX_SID_LEN];
SID_NAME_USE acc_type;
- int ret = mbstowcs (machine, mach->str, INTERNET_MAX_HOST_NAME_LENGTH + 1);
+ if (!d_or_m)
+ return;
+
+ int ret = mbstowcs (machine, d_or_m, INTERNET_MAX_HOST_NAME_LENGTH + 1);
if (ret < 1 || ret >= INTERNET_MAX_HOST_NAME_LENGTH + 1)
{
fprintf (stderr, "%s: Invalid machine name '%s'. Skipping...\n",
- program_invocation_short_name, mach->str);
+ program_invocation_short_name, d_or_m);
return;
}
+ servername = machine;
if (!AllocateAndInitializeSid (&auth, 2, 1, 0, 0, 0, 0, 0, 0, 0, &psid))
return;
@@ -163,15 +255,15 @@ enum_unix_users (domlist_t *mach, const char *sep, DWORD id_offset,
if (ret < 1 || ret >= UNLEN + 1)
fprintf (stderr, "%s: Invalid user name '%s'. Skipping...\n",
program_invocation_short_name, ustr);
- else if (LookupAccountNameW (machine, user,
+ else if (LookupAccountNameW (servername, user,
psid = (PSID) psid_buffer,
(sidlen = MAX_SID_LEN, &sidlen),
dom,
(dlen = MAX_DOMAIN_NAME_LEN + 1, &dlen),
&acc_type))
printf ("%s%s%ls:unused:%" PRIu32 ":99999:,%s::\n",
- mach->with_dom ? "Unix_User" : "",
- mach->with_dom ? sep : "",
+ with_dom ? "Unix User" : "",
+ with_dom ? sep : "",
user + 10,
(unsigned int) (id_offset +
*GetSidSubAuthority (psid,
@@ -200,15 +292,15 @@ enum_unix_users (domlist_t *mach, const char *sep, DWORD id_offset,
{
*GetSidSubAuthority (psid, *GetSidSubAuthorityCount(psid) - 1)
= start;
- if (LookupAccountSidW (machine, psid,
+ if (LookupAccountSidW (servername, psid,
user, (ulen = GNLEN + 1, &ulen),
dom,
(dlen = MAX_DOMAIN_NAME_LEN + 1, &dlen),
&acc_type)
&& !iswdigit (user[0]))
printf ("%s%s%ls:unused:%" PRIu32 ":99999:,%s::\n",
- mach->with_dom ? "Unix_User" : "",
- mach->with_dom ? sep : "",
+ with_dom ? "Unix User" : "",
+ with_dom ? sep : "",
user,
(unsigned int) (id_offset + start),
put_sid (psid));
@@ -221,23 +313,36 @@ enum_unix_users (domlist_t *mach, const char *sep, DWORD id_offset,
}
static int
-enum_users (domlist_t *mach, const char *sep, const char *passed_home_path,
- DWORD id_offset, char *disp_username, int print_current)
+enum_users (BOOL domain, domlist_t *dom_or_machine, const char *sep,
+ const char *passed_home_path, DWORD id_offset, char *disp_username,
+ int print_current)
{
WCHAR machine[INTERNET_MAX_HOST_NAME_LENGTH + 1];
+ PWCHAR servername = NULL;
+ char *d_or_m = dom_or_machine ? dom_or_machine->str : NULL;
+ BOOL with_dom = dom_or_machine ? dom_or_machine->with_dom : FALSE;
USER_INFO_3 *buffer;
DWORD entriesread = 0;
DWORD totalentries = 0;
DWORD resume_handle = 0;
DWORD rc;
WCHAR uni_name[UNLEN + 1];
-
- int ret = mbstowcs (machine, mach->str, INTERNET_MAX_HOST_NAME_LENGTH + 1);
- if (ret < 1 || ret >= INTERNET_MAX_HOST_NAME_LENGTH + 1)
+ if (domain)
{
- fprintf (stderr, "%s: Invalid machine name '%s'. Skipping...\n",
- program_invocation_short_name, mach->str);
- return 1;
+ 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",
+ program_invocation_short_name, d_or_m);
+ return 1;
+ }
+ servername = machine;
}
do
@@ -247,7 +352,7 @@ enum_users (domlist_t *mach, const char *sep, const char *passed_home_path,
if (disp_username != NULL)
{
mbstowcs (uni_name, disp_username, UNLEN + 1);
- rc = NetUserGetInfo (machine, (LPWSTR) &uni_name, 3,
+ rc = NetUserGetInfo (servername, (LPWSTR) &uni_name, 3,
(void *) &buffer);
entriesread = 1;
/* Avoid annoying error messages just because the user hasn't been
@@ -256,7 +361,7 @@ enum_users (domlist_t *mach, const char *sep, const char *passed_home_path,
return 0;
}
else
- rc = NetUserEnum (machine, 3, FILTER_NORMAL_ACCOUNT,
+ rc = NetUserEnum (servername, 3, FILTER_NORMAL_ACCOUNT,
(void *) &buffer, MAX_PREFERRED_LENGTH,
&entriesread, &totalentries, &resume_handle);
switch (rc)
@@ -302,7 +407,7 @@ enum_users (domlist_t *mach, const char *sep, const char *passed_home_path,
stpcpy (homedir_psx, passed_home_path),
PATH_MAX - strlen (passed_home_path));
- if (!LookupAccountNameW (machine, buffer[i].usri3_name,
+ if (!LookupAccountNameW (servername, buffer[i].usri3_name,
psid, &sid_length, domain_name,
&domname_len, &acc_type))
{
@@ -314,12 +419,13 @@ enum_users (domlist_t *mach, const char *sep, const char *passed_home_path,
{
WCHAR domname[MAX_DOMAIN_NAME_LEN + UNLEN + 2];
- wcscpy (domname, machine);
+ wcscpy (domname, domain || !servername
+ ? domain_name : servername);
wcscat (domname, L"\\");
wcscat (domname, buffer[i].usri3_name);
sid_length = MAX_SID_LEN;
domname_len = sizeof (domname);
- if (!LookupAccountNameW (machine, domname, psid,
+ if (!LookupAccountNameW (servername, domname, psid,
&sid_length, domain_name,
&domname_len, &acc_type))
{
@@ -335,8 +441,8 @@ enum_users (domlist_t *mach, const char *sep, const char *passed_home_path,
printf ("%ls%s%ls:unused:%" PRIu32 ":%" PRIu32
":%ls%sU-%ls\\%ls,%s:%s:/bin/bash\n",
- mach->with_dom ? domain_name : L"",
- mach->with_dom ? sep : "",
+ with_dom ? domain_name : L"",
+ with_dom ? sep : "",
buffer[i].usri3_name,
(unsigned int) (id_offset + uid),
(unsigned int) (id_offset + gid),
@@ -357,49 +463,98 @@ enum_users (domlist_t *mach, const char *sep, const char *passed_home_path,
return 0;
}
+static void
+print_special_by_sid (PSID_IDENTIFIER_AUTHORITY auth, BYTE cnt,
+ DWORD sub1, DWORD sub2, DWORD sub3, DWORD sub4,
+ DWORD sub5, DWORD sub6, DWORD sub7, DWORD sub8)
+{
+ WCHAR user[UNLEN + 1], dom[MAX_DOMAIN_NAME_LEN + 1];
+ DWORD len, len2, rid;
+ PSID sid;
+ SID_NAME_USE acc_type;
+
+ if (AllocateAndInitializeSid (auth, cnt, sub1, sub2, sub3, sub4,
+ sub5, sub6, sub7, sub8, &sid))
+ {
+ if (LookupAccountSidW (NULL, sid,
+ user, (len = UNLEN + 1, &len),
+ dom, (len2 = MAX_DOMAIN_NAME_LEN + 1, &len2),
+ &acc_type))
+ {
+ if (sub8)
+ rid = sub8;
+ else if (sub7)
+ rid = sub7;
+ else if (sub6)
+ rid = sub6;
+ else if (sub5)
+ rid = sub5;
+ else if (sub4)
+ rid = sub4;
+ else if (sub3)
+ rid = sub3;
+ else if (sub2)
+ rid = sub2;
+ else
+ rid = sub1;
+ printf ("%ls:*:%" PRIu32 ":%" PRIu32 ":,%s::\n",
+ user, (unsigned int) rid,
+ (unsigned int) (rid == 18 ? 544 : rid), /* SYSTEM hack */
+ put_sid (sid));
+ }
+ FreeSid (sid);
+ }
+}
+
static int
usage (FILE * stream)
{
fprintf (stream,
"Usage: %s [OPTIONS]...\n"
"\n"
-"Write /etc/passwd-like output to stdout\n"
+"Print /etc/passwd file to stdout\n"
"\n"
"Options:\n"
"\n"
-" -l,--local [machine] print local user accounts with uid offset offset\n"
+" -l,--local [machine[,offset]]\n"
+" print local user accounts with uid offset offset\n"
" (from local machine if no machine specified)\n"
-" -L,--Local machine ditto, but generate username with machine prefix\n"
-" -d,--domain [domain] print domain accounts with uid offset offset\n"
+" -L,--Local [machine[,offset]]\n"
+" ditto, but generate username with machine prefix\n"
+" -d,--domain [domain[,offset]]\n"
+" print domain accounts with uid offset offset\n"
" (from current domain if no domain specified)\n"
+" -D,--Domain [domain[,offset]]\n"
+" ditto, but generate username with domain prefix\n"
" -c,--current print current user\n"
-" -S,--separator char for -l use character char as domain\\user\n"
-" separator in username instead of the default '%s'\n"
-" -o,--id-offset offset change the default offset (0x10000) added to uids\n"
+" -C,--Current ditto, but generate username with machine or\n"
+" domain prefix\n"
+" -S,--separator char for -L, -D, -C use character char as domain\\user\n"
+" separator in username instead of the default '\\'\n"
+" -o,--id-offset offset change the default offset (10000) added to uids\n"
" in domain or foreign server accounts.\n"
" -u,--username username only return information for the specified user\n"
-" one of -l, -d must be specified, too\n"
-" -b,--no-builtin don't print BUILTIN users\n"
+" one of -l, -L, -d, -D must be specified, too\n"
" -p,--path-to-home path use specified path instead of user account home dir\n"
" or /home prefix\n"
-" -U,--unix userlist print UNIX users when using -l on a UNIX Samba\n"
-" server. userlist is a comma-separated list of\n"
-" usernames or uid ranges (root,-25,50-100).\n"
+" -U,--unix userlist additionally print UNIX users when using -l or -L\n"
+" on a UNIX Samba server\n"
+" userlist is a comma-separated list of usernames\n"
+" or uid ranges (root,-25,50-100).\n"
" (enumerating large ranges can take a long time!)\n"
+" -s,--no-sids (ignored)\n"
+" -m,--no-mount (ignored)\n"
+" -g,--local-groups (ignored)\n"
" -h,--help displays this message\n"
" -V,--version version information and exit\n"
"\n"
"Default is to print local accounts on stand-alone machines, domain accounts\n"
-"on domain controllers and domain member machines.\n\n"
-"Don't use this command to generate a local /etc/passwd file, unless you\n"
-"really need one. See the Cygwin User's Guide for more information.\n"
-"\n", program_invocation_short_name,
- (const char *) cygwin_internal (CW_GETNSSSEP));
+"on domain controllers and domain member machines.\n"
+"\n", program_invocation_short_name);
return 1;
}
static struct option longopts[] = {
- {"no-builtin", no_argument, NULL, 'b'},
{"current", no_argument, NULL, 'c'},
{"Current", no_argument, NULL, 'C'},
{"domain", optional_argument, NULL, 'd'},
@@ -419,7 +574,7 @@ static struct option longopts[] = {
{0, no_argument, NULL, 0}
};
-static char opts[] = "bcCd::D::ghl::L::mo:sS:p:u:U:V";
+static char opts[] = "cCd::D::ghl::L::mo:sS:p:u:U:V";
static void
print_version ()
@@ -435,6 +590,66 @@ print_version ()
strrchr (__DATE__, ' ') + 1);
}
+static void
+print_special_by_name (PCWSTR name, uid_t uid, gid_t gid)
+{
+ DWORD size = 256, dom_size = 256;
+ PSID sid = (PSID) alloca (size);
+ WCHAR dom[dom_size];
+ SID_NAME_USE use;
+
+ PWCHAR name_only = wcschr (name, L'\\');
+ if (name_only)
+ ++name_only;
+
+ if (LookupAccountNameW (NULL, name, sid, &size, dom, &dom_size, &use))
+ printf ("%ls:*:%lu:%lu:U-%ls%s%ls,%s::\n",
+ name_only ?: name,
+ (unsigned long) uid,
+ (unsigned long) gid,
+ name_only ? dom : L"",
+ name_only ? "\\" : "",
+ name_only ?: name,
+ put_sid (sid));
+}
+
+static void
+enum_std_accounts ()
+{
+ /* Generate service starter account entries. */
+ printf ("SYSTEM:*:18:544:,S-1-5-18::\n");
+ printf ("LocalService:*:19:544:U-NT AUTHORITY\\LocalService,S-1-5-19::\n");
+ printf ("NetworkService:*:20:544:U-NT AUTHORITY\\NetworkService,S-1-5-20::\n");
+ /* Get 'administrators' group (has localized name). */
+ print_special_by_sid (&sid_nt_auth, 2, SECURITY_BUILTIN_DOMAIN_RID,
+ DOMAIN_ALIAS_RID_ADMINS, 0, 0, 0, 0, 0, 0);
+ /* Fetch "TrustedInstaller" account starting with Vista. */
+ print_special_by_name (L"NT SERVICE\\TrustedInstaller", -2, -2);
+}
+
+static PPOLICY_PRIMARY_DOMAIN_INFO p_dom;
+
+static BOOL
+fetch_primary_domain ()
+{
+ NTSTATUS status;
+ LSA_OBJECT_ATTRIBUTES oa = { 0, 0, 0, 0, 0, 0 };
+ LSA_HANDLE lsa;
+
+ if (!p_dom)
+ {
+ status = LsaOpenPolicy (NULL, &oa, POLICY_VIEW_LOCAL_INFORMATION, &lsa);
+ if (!NT_SUCCESS (status))
+ return FALSE;
+ status = LsaQueryInformationPolicy (lsa, PolicyPrimaryDomainInformation,
+ (PVOID *) ((void *) &p_dom));
+ LsaClose (lsa);
+ if (!NT_SUCCESS (status))
+ return FALSE;
+ }
+ return !!p_dom->Sid;
+}
+
int
main (int argc, char **argv)
{
@@ -442,14 +657,13 @@ main (int argc, char **argv)
domlist_t domlist[32];
char *opt, *p, *ep;
int print_current = 0;
- int print_builtin = 1;
char *print_unix = NULL;
- const char *nss_sep = (const char *) cygwin_internal (CW_GETNSSSEP);
- const char *sep_char = nss_sep;
- DWORD id_offset = 0x10000, off;
+ const char *sep_char = "\\";
+ DWORD id_offset = 10000, off;
int c, i;
char *disp_username = NULL;
char passed_home_path[PATH_MAX];
+ BOOL in_domain;
int optional_args = 0;
passed_home_path[0] = '\0';
@@ -460,23 +674,18 @@ main (int argc, char **argv)
setlocale (LC_CTYPE, "");
if (!strcmp (setlocale (LC_CTYPE, NULL), "C"))
setlocale (LC_CTYPE, "en_US.UTF-8");
+ in_domain = fetch_primary_domain ();
fetch_current_user_sid ();
if (argc == 1)
{
- int enums = ENUM_PRIMARY | ENUM_LOCAL | ENUM_BUILTIN;
- uintptr_t ticket = cygwin_internal (CW_SETENT, FALSE, enums, NULL);
- if (ticket)
- {
- struct passwd *pwd;
-
- while ((pwd = (struct passwd *) cygwin_internal (CW_GETENT, FALSE,
- ticket)))
- printf ("%s:%s:%u:%u:%s:%s:%s\n", pwd->pw_name, pwd->pw_passwd,
- pwd->pw_uid, pwd->pw_gid, pwd->pw_gecos, pwd->pw_dir,
- pwd->pw_shell);
- cygwin_internal (CW_ENDENT, FALSE, ticket);
- }
+ enum_std_accounts ();
+ if (in_domain)
+ enum_users (TRUE, NULL, sep_char, passed_home_path, 10000,
+ disp_username, 0);
+ else
+ enum_users (FALSE, NULL, sep_char, passed_home_path, 0,
+ disp_username, 0);
return 0;
}
@@ -515,9 +724,13 @@ main (int argc, char **argv)
goto skip;
}
domlist[print_domlist].str = opt;
+ domlist[print_domlist].id_offset = UINT32_MAX;
if (opt && (p = strchr (opt, ',')))
{
- if (p == opt)
+ if (p == opt
+ || !isdigit ((unsigned char) p[1])
+ || (domlist[print_domlist].id_offset = strtol (p + 1, &ep, 10)
+ , *ep))
{
fprintf (stderr, "%s: Malformed domain,offset string '%s'. "
"Skipping...\n", program_invocation_short_name, opt);
@@ -525,15 +738,15 @@ main (int argc, char **argv)
}
*p = '\0';
}
- domlist[print_domlist++].with_dom = (c == 'L');
+ domlist[print_domlist++].with_dom = (c == 'D' || c == 'L');
skip:
break;
case 'S':
sep_char = optarg;
if (strlen (sep_char) > 1)
{
- fprintf (stderr, "%s: Only one ASCII character allowed as "
- "domain\\user separator character.\n",
+ fprintf (stderr, "%s: Only one character allowed as domain\\user "
+ "separator character.\n",
program_invocation_short_name);
return 1;
}
@@ -548,14 +761,19 @@ skip:
print_unix = optarg;
break;
case 'c':
+ sep_char = NULL;
+ /*FALLTHRU*/
case 'C':
print_current = 1;
break;
case 'o':
id_offset = strtoul (optarg, &ep, 10);
- break;
- case 'b':
- print_builtin = 0;
+ if (*ep)
+ {
+ fprintf (stderr, "%s: Malformed offset '%s'. "
+ "Skipping...\n", program_invocation_short_name, optarg);
+ return 1;
+ }
break;
case 'p':
if (optarg[0] != '/')
@@ -596,91 +814,24 @@ skip:
exit (1);
}
- struct passwd *ppwd = NULL;
- const char *ppwd_sid = NULL;
- if (print_current)
- {
- ppwd = (struct passwd *) cygwin_internal (CW_GETPWSID, TRUE,
- curr_user.psid);
- if (ppwd)
- ppwd_sid = strrchr (ppwd->pw_gecos, ',');
- }
-
- int enums = ENUM_NONE;
- WCHAR tdoms[print_domlist * 258];
- PWCHAR t = tdoms;
- if (!disp_username && print_builtin && print_domlist)
- enums |= ENUM_BUILTIN;
+ off = id_offset;
for (i = 0; i < print_domlist; ++i)
{
- if (domlist[i].domain)
- {
- if (domlist[i].str)
- {
- enums |= ENUM_TDOMS;
- t += mbstowcs (t, domlist[i].str, 257);
- *t++ = L'\0';
- }
- else
- enums |= ENUM_PRIMARY;
- }
- else if (!domlist[i].str)
- enums |= ENUM_LOCAL;
- }
- if (t > tdoms)
- *t++ = L'\0';
- if (enums)
- {
- uintptr_t ticket = cygwin_internal (CW_SETENT, FALSE, enums,
- t > tdoms ? tdoms : NULL);
- if (ticket)
- {
- struct passwd *pwd;
-
- while ((pwd = (struct passwd *)
- cygwin_internal (CW_GETENT, FALSE, ticket)))
- {
- p = NULL;
- if (disp_username
- && strcasecmp (disp_username, pwd->pw_name) != 0
- && (!(p = strchr (pwd->pw_name, nss_sep[0]))
- || strcasecmp (disp_username, p + 1) != 0))
- continue;
- printf ("%s:%s:%u:%u:%s:%s%s:%s\n", pwd->pw_name, pwd->pw_passwd,
- pwd->pw_uid, pwd->pw_gid, pwd->pw_gecos,
- passed_home_path[0] ? passed_home_path : "",
- passed_home_path[0] ? (p ? p + 1 : pwd->pw_name)
- : pwd->pw_dir,
- pwd->pw_shell);
- const char *pwd_sid = strrchr (pwd->pw_gecos, ',');
- if (ppwd && ppwd_sid && pwd_sid && !strcmp (pwd_sid, ppwd_sid))
- got_curr_user = TRUE;
- }
- cygwin_internal (CW_ENDENT, FALSE, ticket);
- }
+ DWORD my_off = (domlist[i].domain || domlist[i].str)
+ ? domlist[i].id_offset != UINT_MAX
+ ? domlist[i].id_offset : off : 0;
+ if (!domlist[i].domain && domlist[i].str && print_unix)
+ enum_unix_users (domlist + i, sep_char, my_off, print_unix);
+ if (!my_off && !disp_username)
+ enum_std_accounts ();
+ enum_users (domlist[i].domain, domlist + i, sep_char, passed_home_path,
+ my_off, disp_username, print_current);
+ if (my_off)
+ off += id_offset;
}
if (print_current && !got_curr_user)
- {
- p = strchr (ppwd->pw_name, nss_sep[0]);
- printf ("%s:%s:%u:%u:%s:%s%s:%s\n", ppwd->pw_name, ppwd->pw_passwd,
- ppwd->pw_uid, ppwd->pw_gid, ppwd->pw_gecos,
- passed_home_path[0] ? passed_home_path : "",
- passed_home_path[0] ? (p ? p + 1 : ppwd->pw_name) : ppwd->pw_dir,
- ppwd->pw_shell);
- }
-
- off = 0xfd000000;
- for (i = 0; i < print_domlist; ++i)
- {
- if (domlist[i].domain || !domlist[i].str)
- continue;
- enum_users (domlist + i, sep_char, passed_home_path, off, disp_username,
- print_current);
- if (!domlist[i].domain && domlist[i].str && print_unix)
- enum_unix_users (domlist + i, sep_char, 0xff000000, print_unix);
- off += id_offset;
- }
+ current_user (sep_char, passed_home_path, off, disp_username);
return 0;
}
diff --git a/winsup/utils/utils.xml b/winsup/utils/utils.xml
index 45c2dfb4b..b7e8ff81d 100644
--- a/winsup/utils/utils.xml
+++ b/winsup/utils/utils.xml
@@ -875,77 +875,89 @@ Write minidump from WIN32PID to FILENAME.dmp
<screen>
Usage: mkgroup [OPTION]...
-Write /etc/group-like output to stdout
+Print /etc/group file to stdout
Options:
- -l,--local [machine] print local groups
+ -l,--local [machine[,offset]]
+ print local groups with gid offset offset
(from local machine if no machine specified)
- -L,--Local machine ditto, but generate groupname with machine prefix
- -d,--domain [domain] print domain groups
+ -L,--Local [machine[,offset]]
+ ditto, but generate groupname with machine prefix
+ -d,--domain [domain[,offset]]
+ print domain groups with gid offset offset
(from current domain if no domain specified)
+ -D,--Domain [domain[,offset]]
+ ditto, but generate groupname with machine prefix
-c,--current print current group
- -S,--separator char for -l use character char as domain\group
- separator in groupname instead of default '+'
- -o,--id-offset offset change the default offset (0x10000) added to
- gids of foreign machine accounts.
+ -C,--Current ditto, but generate groupname with machine or
+ domain prefix
+ -S,--separator char for -L, -D, -C use character char as domain\group
+ separator in groupname instead of the default '\'
+ -o,--id-offset offset change the default offset (10000) added to gids
+ in domain or foreign server accounts.
-g,--group groupname only return information for the specified group
- one of -l, -d must be specified, too
+ one of -l, -L, -d, -D must be specified, too
-b,--no-builtin don't print BUILTIN groups
- -U,--unix grouplist print UNIX groups when using -l on a UNIX Samba
- server. grouplist is a comma-separated list of
- groupnames or gid ranges (root,-25,50-100).
- (enumerating large ranges can take a long time!)
+ -U,--unix grouplist additionally print UNIX groups when using -l or -L
+ on a UNIX Samba server
+ grouplist is a comma-separated list of groupnames
+ or gid ranges (root,-25,50-100).
+ (enumerating large ranges can take a long time!)
+ -s,--no-sids (ignored)
+ -u,--users (ignored)
-h,--help print this message
- -v,--version print version information and exit
+ -V,--version print version information and exit
Default is to print local groups on stand-alone machines, plus domain
groups on domain controllers and domain member machines.
-
-Don't use this command to generate a local /etc/group file, unless you
-really need one. See the Cygwin User's Guide for more information.
</screen>
- <para>The <command>mkgroup</command> program can be used to create a local
- <filename>/etc/group</filename> file. Cygwin doesn't need this file,
- because it reads group information from the Windows account databases,
- but you can add an <filename>/etc/group</filename> file for instance, if
- your machine is often disconnected from its domain controller.
- </para>
-
- <para>Note that this information is static, in contrast to the information
- automatically gathered by Cygwin from the Windows account databases. If
- you change the group information on your system, you'll need to regenerate
- the group file for it to have the new information.</para>
-
- <para>By default, the information generated by <command>mkgroup</command>
- is equivalent to the information generated by Cygwin itself. The
- <literal>-d</literal> and <literal>-l/-L</literal> options allow you to
- specify where the information comes from, some domain, or the local SAM
- of a machine. Note that you can only enumerate accounts from trusted
- domains. Any non-trusted domain will be ignored. Access-restrictions
- of your current account apply. The <literal>-l/-L</literal> when used
- with a machine name, tries to contact that machine to enumerate local
- groups of other machines, typically outside of domains. This scenario
- cannot be covered by Cygwin's account automatism. If you want to use
- the <literal>-L</literal> option, but you don't like the default
- domain/group separator from <filename>/etc/nsswitch.conf</filename>,
- you can specify another separator using the <literal>-S</literal> option,
- for instance:</para>
+ <para>The <command>mkgroup</command> program can be used to help configure
+ Cygwin by creating a <filename>/etc/group</filename> file. Its use is
+ essential to include Windows security information.</para>
+
+ <para>The command is initially called by <command>setup.exe</command> to
+ create a default <filename>/etc/group</filename>. This should be
+ sufficient in most circumstances. However, especially when working in a
+ multi-domain environment, you can use <command>mkgroup</command> manually
+ to create a more complete <filename>/etc/group</filename> file for all
+ domains. Especially when you have the same group name used on multiple
+ machines or in multiple domains, you can use the <literal>-D</literal>,
+ <literal>-L</literal> and <literal>-C</literal> options to create unique
+ domain\group style groupnames.</para>
+
+ <para>Note that this information is static. If you change the group
+ information in your system, you'll need to regenerate the group file for
+ it to have the new information.</para>
+
+ <para>The <literal>-d/-D</literal> and <literal>-l/-L</literal> options
+ allow you to specify where the information comes from, the local SAM of a
+ machine or from the domain, or both. With the <literal>-d/-D</literal>
+ options the program contacts a Domain Controller, which my be unreachable
+ or have restricted access. Comma-separated from the machine or domain,
+ you can specify an offset which is used as base added to the group's RID
+ to compute the gid (offset + RID = gid). This allows you to create the
+ same gids every time you re-run <command>mkgroup</command>. For very
+ simple needs, an entry for the current user's group can be created by
+ using the option <literal>-c</literal> or <literal>-C</literal>. If you
+ want to use one of the <literal>-D</literal>, <literal>-L</literal> or
+ <literal>-C</literal> options, but you don't like the backslash as
+ domain/group separator, you can specify another separator using the
+ <literal>-S</literal> option, for instance:</para>
<example id="utils-mkgroup-ex">
<title>Setting up group entry for current user with different
domain/group separator</title>
<screen>
-<prompt>$</prompt> <userinput>mkgroup -L server1 -S= &gt; /etc/group</userinput>
+<prompt>$</prompt> <userinput>mkgroup -C -S+ &gt; /etc/group</userinput>
+<prompt>$</prompt> <userinput>cat /etc/group</userinput>
+DOMAIN+my_group:S-1-5-21-2913048732-1697188782-3448811101-1144:11144:
</screen>
</example>
- <para>For very simple needs, an entry for the current user's group can be
- created by using the option <literal>-c</literal>.</para>
-
- <para>The <literal>-o</literal> option allows for (unlikely) special cases
- with multiple machines where the GIDs might match otherwise. The
+ <para>The <literal>-o</literal> option allows for special cases (such as
+ multiple domains) where the GIDs might match otherwise. The
<literal>-g</literal> option only prints the information for one group.
The <literal>-U</literal> option allows you to enumerate the standard
UNIX groups on a Samba machine. It's used together with <literal>-l
@@ -961,69 +973,81 @@ really need one. See the Cygwin User's Guide for more information.
<screen>
Usage: mkpasswd [OPTIONS]...
-Write /etc/passwd-like output to stdout
+Print /etc/passwd file to stdout
Options:
- -l,--local [machine] print local user accounts with uid offset offset
+ -l,--local [machine[,offset]]
+ print local user accounts with uid offset offset
(from local machine if no machine specified)
- -L,--Local machine ditto, but generate username with machine prefix
- -d,--domain [domain] print domain accounts with uid offset offset
+ -L,--Local [machine[,offset]]
+ ditto, but generate username with machine prefix
+ -d,--domain [domain[,offset]]
+ print domain accounts with uid offset offset
(from current domain if no domain specified)
+ -D,--Domain [domain[,offset]]
+ ditto, but generate username with domain prefix
-c,--current print current user
- -S,--separator char for -l use character char as domain\user
- separator in username instead of the default '+'
- -o,--id-offset offset change the default offset (0x10000) added to uids
+ -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
in domain or foreign server accounts.
-u,--username username only return information for the specified user
- one of -l, -d must be specified, too
- -b,--no-builtin don't print BUILTIN users
+ 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
- -U,--unix userlist print UNIX users when using -l on a UNIX Samba
- server. userlist is a comma-separated list of
- usernames or uid ranges (root,-25,50-100).
+ -U,--unix userlist additionally print UNIX users when using -l or -L\
+ on a UNIX Samba server
+ userlist is a comma-separated list of usernames
+ or uid ranges (root,-25,50-100).
(enumerating large ranges can take a long time!)
+ -s,--no-sids (ignored)
+ -m,--no-mount (ignored)
+ -g,--local-groups (ignored)
-h,--help displays this message
-V,--version version information and exit
Default is to print local accounts on stand-alone machines, domain accounts
on domain controllers and domain member machines.
-
-Don't use this command to generate a local /etc/passwd file, unless you
-really need one. See the Cygwin User's Guide for more information.
</screen>
- <para>The <command>mkpasswd</command> program can be used to create a
- <filename>/etc/passwd</filename> file. Cygwin doesn't need this file,
- because it reads user information from the Windows account databases,
- but you can add an <filename>/etc/group</filename> file for instance, if
- your machine is often disconnected from its domain controller.</para>
-
- <para>Note that this information is static, in contrast to the information
- automatically gathered by Cygwin from the Windows account databases. If
- you change the user information on your system, you'll need to regenerate
- the passwd file for it to have the new information.</para>
-
- <para>By default, the information generated by <command>mkpasswd</command>
- is equivalent to the information generated by Cygwin itself. The
- <literal>-d</literal> and <literal>-l/-L</literal> options allow you to
- specify where the information comes from, some domain, or the local SAM
- of a machine. Note that you can only enumerate accounts from trusted
- domains. Any non-trusted domain will be ignored. Access-restrictions
- of your current account apply. The <literal>-l/-L</literal> when used
- with a machine name, tries to contact that machine to enumerate local
- groups of other machines, typically outside of domains. This scenario
- cannot be covered by Cygwin's account automatism. If you want to use
- the <literal>-L</literal> option, but you don't like the default
- domain/group separator from <filename>/etc/nsswitch.conf</filename>,
- you can specify another separator using the <literal>-S</literal> option,
- analog to <command>mkgroup</command>.</para>
-
- <para>For very simple needs, an entry for the current user can be created
- by using the option <literal>-c</literal>.</para>
-
- <para>The <literal>-o</literal> option allows for special cases (such as
+ <para>The <command>mkpasswd</command> program can be used to help configure
+ Cygwin by creating a <filename>/etc/passwd</filename> from your system
+ information. Its use is essential to include Windows security
+ information. However, the actual passwords are determined by Windows, not
+ by the content of <filename>/etc/passwd</filename>.</para>
+
+ <para>The command is initially called by <command>setup.exe</command> to
+ create a default <filename>/etc/passwd</filename>. This should be
+ sufficient in most circumstances. However, especially when working in a
+ multi-domain environment, you can use <command>mkpasswd</command>
+ manually to create a more complete <filename>/etc/passwd</filename> file
+ for all domains. Especially when you have the same user name used on
+ multiple machines or in multiple domains, you can use the
+ <literal>-D</literal>, <literal>-L</literal> and <literal>-C</literal>
+ options to create unique domain\user style usernames.</para>
+
+ <para>Note that this information is static. If you change the user
+ information in your system, you'll need to regenerate the passwd file for
+ it to have the new information.</para>
+
+ <para>The <literal>-d/-D</literal> and <literal>-l/-L</literal> options
+ allow you to specify where the information comes from, the local machine
+ or the domain (default or given), or both. With the
+ <literal>-d/-D</literal> options the program contacts the Domain
+ Controller, which may be unreachable or have restricted access.
+ Comma-separated from the machine or domain, you can specify an offset
+ which is used as base added to the user's RID to compute the uid (offset
+ + RID = uid). This allows to create the same uids every time you re-run
+ <command>mkpasswd</command>. An entry for the current user can be created
+ by using the option <literal>-c</literal> or <literal>-C</literal>. If
+ you want to use one of the <literal>-D</literal>, <literal>-L</literal>
+ or <literal>-C</literal> options, but you don't like the backslash as
+ domain/group separator, you can specify another separator using the
+ <literal>-S</literal> option, similar to the <command>mkgroup</command>.
+ The <literal>-o</literal> option allows for special cases (such as
multiple domains) where the UIDs might match otherwise. The
<literal>-p</literal> option causes <command>mkpasswd</command> to use
the specified prefix instead of the account home dir or <literal>/home/
@@ -1038,8 +1062,7 @@ really need one. See the Cygwin User's Guide for more information.
to enumerate the standard UNIX users on a Samba machine. It's used
together with <literal>-l samba-server</literal> or <literal>-L
samba-server</literal>. The normal UNIX users are usually not enumerated,
- but they can show up as file owners in <command>ls -l</command> output.
- </para>
+ but they can show up as file owners in <command>ls -l</command> output. </para>
</sect2>