diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog index 7ceed3293..bcf327553 100644 --- a/winsup/cygwin/ChangeLog +++ b/winsup/cygwin/ChangeLog @@ -1,3 +1,25 @@ +2014-02-18 Corinna Vinschen + + * 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 * setlsapwd.cc (setlsapwd): Fix conditional expression after breaking diff --git a/winsup/cygwin/external.cc b/winsup/cygwin/external.cc index 4dc87bf80..eb602fbf6 100644 --- a/winsup/cygwin/external.cc +++ b/winsup/cygwin/external.cc @@ -1,7 +1,7 @@ /* external.cc: Interface to Cygwin internals from external programs. Copyright 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, - 2008, 2009, 2010, 2011, 2012 Red Hat, Inc. + 2008, 2009, 2010, 2011, 2012, 2014 Red Hat, Inc. Written by Christopher Faylor @@ -26,6 +26,7 @@ details. */ #include "child_info.h" #include "environ.h" #include "cygserver_setpwd.h" +#include "pwdgrp.h" #include #include #include @@ -553,6 +554,47 @@ 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; + default: set_errno (ENOSYS); } diff --git a/winsup/cygwin/grp.cc b/winsup/cygwin/grp.cc index 6f9b4b9bb..18e091642 100644 --- a/winsup/cygwin/grp.cc +++ b/winsup/cygwin/grp.cc @@ -429,6 +429,28 @@ endgrent (void) grent.endgrent (); } +/* *_filtered functions are called from mkgroup */ +void * +setgrent_filtered (int enums, PCWSTR enum_tdoms) +{ + gr_ent *gr = new gr_ent; + if (gr) + gr->setgrent (enums, enum_tdoms); + return (void *) gr; +} + +void * +getgrent_filtered (void *gr) +{ + return (void *) ((gr_ent *) gr)->getgrent (); +} + +void +endgrent_filtered (void *gr) +{ + ((gr_ent *) gr)->endgrent (); +} + int internal_getgroups (int gidsetsize, gid_t *grouplist, cygpsid *srchsid) { diff --git a/winsup/cygwin/include/sys/cygwin.h b/winsup/cygwin/include/sys/cygwin.h index 705aa7f64..46c3595e6 100644 --- a/winsup/cygwin/include/sys/cygwin.h +++ b/winsup/cygwin/include/sys/cygwin.h @@ -1,7 +1,7 @@ /* sys/cygwin.h Copyright 1997, 1998, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, - 2009, 2010, 2011, 2012, 2013 Red Hat, Inc. + 2009, 2010, 2011, 2012, 2013, 2014 Red Hat, Inc. This file is part of Cygwin. @@ -143,7 +143,10 @@ typedef enum CW_CVT_ENV_TO_WINENV, CW_ALLOC_DRIVE_MAP, CW_MAP_DRIVE_MAP, - CW_FREE_DRIVE_MAP + CW_FREE_DRIVE_MAP, + CW_SETENT, + CW_GETENT, + CW_ENDENT } cygwin_getinfo_types; #define CW_LOCK_PINFO CW_LOCK_PINFO @@ -194,6 +197,9 @@ typedef enum #define CW_ALLOC_DRIVE_MAP CW_ALLOC_DRIVE_MAP #define CW_MAP_DRIVE_MAP CW_MAP_DRIVE_MAP #define CW_FREE_DRIVE_MAP CW_FREE_DRIVE_MAP +#define CW_SETENT CW_SETENT +#define CW_GETENT CW_GETENT +#define CW_ENDENT CW_ENDENT /* Token type for CW_SET_EXTERNAL_TOKEN */ enum diff --git a/winsup/cygwin/passwd.cc b/winsup/cygwin/passwd.cc index 9d4eaba14..547e93235 100644 --- a/winsup/cygwin/passwd.cc +++ b/winsup/cygwin/passwd.cc @@ -317,6 +317,7 @@ pg_ent::setent (bool _group, int _enums, PCWSTR _enum_tdoms) from_files = cygheap->pg.nss_pwd_files (); from_db = cygheap->pg.nss_pwd_db (); } + state = from_cache; } void * @@ -361,6 +362,11 @@ pg_ent::getent (void) 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; @@ -640,6 +646,28 @@ endpwent (void) pwent.endpwent (); } +/* *_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) diff --git a/winsup/cygwin/pwdgrp.h b/winsup/cygwin/pwdgrp.h index e59b2173b..23931e2bc 100644 --- a/winsup/cygwin/pwdgrp.h +++ b/winsup/cygwin/pwdgrp.h @@ -22,6 +22,14 @@ extern struct group *internal_getgrgid (gid_t); extern struct group *internal_getgrnam (const char *); int internal_getgroups (int, gid_t *, cygpsid * = NULL); +/* 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); + #include "sync.h" #include "ldap.h" #include "miscfuncs.h"