* Makefile.in (install): Add install-ldif target.

(install-ldif): New target to install cygwin.ldif.
	* cygheap.h (class cygheap_pwdgrp): Rename pfx_t to nss_pfx_t.  Add
	PFX to enum value.  Add nss_scheme_method enum and nss_scheme_t
	structure.  Add home_scheme, shell_scheme and gecos_scheme members.
	(NSS_SCHEME_MAX): Define.
	(cygheap_pwdgrp::get_home): Declare.
	(cygheap_pwdgrp::get_shell): Declare.
	(cygheap_pwdgrp::get_gecos): Declare.
	* cygwin.ldif: New file.
	* ldap.cc (std_user_attr): New array, just defining the standard
	attributes.
	(group_attr): Add cygwinUnixGid.
	(user_attr): Convert to macro pointing to cygheap->pg.ldap_user_attr.
	(cygheap_pwdgrp::init_ldap_user_attr): New method.
	(cyg_ldap::fetch_ad_account): Call cygheap_pwdgrp::init_ldap_user_attr
	if user_attr initialization is required.  Fix comment.
	(cyg_ldap::get_string_attribute): Implement taking attribute name
	as argument.
	* ldap.h: Drop unused macros.
	(cyg_ldap::get_gecos): Remove.
	(cyg_ldap::get_home): Remove.
	(cyg_ldap::get_shell): Remove.
	(cyg_ldap::get_string_attribute): Declare name argument variant public.
	* uinfo.cc (cygheap_user::ontherange): Fix indentation.
	(cygheap_pwdgrp::init): Initialize new home_scheme, shell_scheme and
	gecos_scheme members.  Align comment.
	(NSS_NCMP): Define comparison macro.
	(NSS_CMP): Ditto.
	(cygheap_pwdgrp::nss_init_line): Use aforementioned macros throughout.
	Fix comment handling.  Add db_home, db_shell and db_gecos handling.
	(fetch_from_description): New function to fetch XML-style attributes
	from (description) string.
	(fetch_from_path): New function to evaluate path string with wildcards.
	(cygheap_pwdgrp::get_home): New methods to fetch pw_dir value.
	(cygheap_pwdgrp::get_shell): Ditto for pw_shell.
	(cygheap_pwdgrp::get_gecos): Ditto for pw_gecos.
	(colon_to_semicolon): Move up.
	(pwdgrp::fetch_account_from_windows): Convert home, shell, gecos
	variables to char*.  Drop statement breaking extended group info.
	Fetch home, shell and gecos values using new methods.  Use
	fetch_from_description calls to fetch UNIX id and primary groups from
	SAM comment field.  Accommodate uxid being a char* now.  Accommodate
	the fact that extended info is malloc'ed, rather then alloca'ed.
	Create linebuf content as multibyte string.  Create line buffer by
	just calling cstrdup.
This commit is contained in:
Corinna Vinschen 2014-11-26 19:46:59 +00:00
parent 8a2ab1aea1
commit 93d15b36ef
7 changed files with 912 additions and 184 deletions

View File

@ -1,3 +1,52 @@
2014-11-26 Corinna Vinschen <corinna@vinschen.de>
* Makefile.in (install): Add install-ldif target.
(install-ldif): New target to install cygwin.ldif.
* cygheap.h (class cygheap_pwdgrp): Rename pfx_t to nss_pfx_t. Add
PFX to enum value. Add nss_scheme_method enum and nss_scheme_t
structure. Add home_scheme, shell_scheme and gecos_scheme members.
(NSS_SCHEME_MAX): Define.
(cygheap_pwdgrp::get_home): Declare.
(cygheap_pwdgrp::get_shell): Declare.
(cygheap_pwdgrp::get_gecos): Declare.
* cygwin.ldif: New file.
* ldap.cc (std_user_attr): New array, just defining the standard
attributes.
(group_attr): Add cygwinUnixGid.
(user_attr): Convert to macro pointing to cygheap->pg.ldap_user_attr.
(cygheap_pwdgrp::init_ldap_user_attr): New method.
(cyg_ldap::fetch_ad_account): Call cygheap_pwdgrp::init_ldap_user_attr
if user_attr initialization is required. Fix comment.
(cyg_ldap::get_string_attribute): Implement taking attribute name
as argument.
* ldap.h: Drop unused macros.
(cyg_ldap::get_gecos): Remove.
(cyg_ldap::get_home): Remove.
(cyg_ldap::get_shell): Remove.
(cyg_ldap::get_string_attribute): Declare name argument variant public.
* uinfo.cc (cygheap_user::ontherange): Fix indentation.
(cygheap_pwdgrp::init): Initialize new home_scheme, shell_scheme and
gecos_scheme members. Align comment.
(NSS_NCMP): Define comparison macro.
(NSS_CMP): Ditto.
(cygheap_pwdgrp::nss_init_line): Use aforementioned macros throughout.
Fix comment handling. Add db_home, db_shell and db_gecos handling.
(fetch_from_description): New function to fetch XML-style attributes
from (description) string.
(fetch_from_path): New function to evaluate path string with wildcards.
(cygheap_pwdgrp::get_home): New methods to fetch pw_dir value.
(cygheap_pwdgrp::get_shell): Ditto for pw_shell.
(cygheap_pwdgrp::get_gecos): Ditto for pw_gecos.
(colon_to_semicolon): Move up.
(pwdgrp::fetch_account_from_windows): Convert home, shell, gecos
variables to char*. Drop statement breaking extended group info.
Fetch home, shell and gecos values using new methods. Use
fetch_from_description calls to fetch UNIX id and primary groups from
SAM comment field. Accommodate uxid being a char* now. Accommodate
the fact that extended info is malloc'ed, rather then alloca'ed.
Create linebuf content as multibyte string. Create line buffer by
just calling cstrdup.
2014-11-25 Corinna Vinschen <corinna@vinschen.de>
* include/fcntl.h: Move all open flags (except O_NDELAY) to newlib's

View File

@ -523,7 +523,7 @@ all_host: $(TEST_LIB_NAME)
force:
install: install-libs install-headers install-man install_target \
install: install-libs install-headers install-man install-ldif install_target \
$(install_host) $(install_target)
uninstall: uninstall-libs uninstall-headers uninstall-man
@ -561,6 +561,10 @@ install-man:
$(INSTALL_DATA) $$i $(DESTDIR)$(mandir)/man7/`basename $$i` ; \
done
install-ldif:
@$(MKDIRP) $(DESTDIR)$(datarootdir)/cygwin
$(INSTALL_DATA) $(srcdir)/cygwin.ldif $(DESTDIR)$(datarootdir)/cygwin
install_target:
install_host:

View File

@ -400,19 +400,40 @@ public:
class cygheap_pwdgrp
{
enum pfx_t {
NSS_AUTO = 0,
NSS_PRIMARY,
NSS_ALWAYS
enum nss_pfx_t {
NSS_PFX_AUTO = 0,
NSS_PFX_PRIMARY,
NSS_PFX_ALWAYS
};
bool nss_inited;
int pwd_src;
int grp_src;
pfx_t prefix;
WCHAR separator[2];
bool caching;
int enums;
PWCHAR enum_tdoms;
public:
enum nss_scheme_method {
NSS_SCHEME_FALLBACK = 0,
NSS_SCHEME_WINDOWS,
NSS_SCHEME_CYGWIN,
NSS_SCHEME_UNIX,
NSS_SCHEME_DESC,
NSS_SCHEME_PATH,
NSS_SCHEME_FREEATTR
};
struct nss_scheme_t {
nss_scheme_method method;
PWCHAR attrib;
};
private:
bool nss_inited;
uint32_t pwd_src;
uint32_t grp_src;
nss_pfx_t prefix;
WCHAR separator[2];
bool caching;
#define NSS_SCHEME_MAX 4
nss_scheme_t home_scheme[NSS_SCHEME_MAX];
nss_scheme_t shell_scheme[NSS_SCHEME_MAX];
nss_scheme_t gecos_scheme[NSS_SCHEME_MAX];
uint32_t enums;
PWCHAR enum_tdoms;
void nss_init_line (const char *line);
void _nss_init ();
@ -431,6 +452,10 @@ public:
void init ();
/* Implemented in ldap.cc */
PWCHAR *ldap_user_attr;
void init_ldap_user_attr ();
inline void nss_init () { if (!nss_inited) _nss_init (); }
inline bool nss_pwd_files () const { return !!(pwd_src & NSS_SRC_FILES); }
inline bool nss_pwd_db () const { return !!(pwd_src & NSS_SRC_DB); }
@ -438,12 +463,22 @@ public:
inline bool nss_grp_files () const { return !!(grp_src & NSS_SRC_FILES); }
inline bool nss_grp_db () const { return !!(grp_src & NSS_SRC_DB); }
inline int nss_grp_src () const { return grp_src; } /* CW_GETNSS_GRP_SRC */
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 bool nss_prefix_auto () const { return prefix == NSS_PFX_AUTO; }
inline bool nss_prefix_primary () const { return prefix == NSS_PFX_PRIMARY; }
inline bool nss_prefix_always () const { return prefix == NSS_PFX_ALWAYS; }
inline PCWSTR nss_separator () const { return separator; }
inline bool nss_cygserver_caching () const { return caching; }
inline void nss_disable_cygserver_caching () { caching = false; }
char *get_home (cyg_ldap *pldap, PCWSTR dom, PCWSTR name, bool fq);
char *get_home (struct _USER_INFO_3 *ui, PCWSTR dom, PCWSTR name, bool fq);
char *get_shell (cyg_ldap *pldap, PCWSTR dom, PCWSTR name, bool fq);
char *get_shell (struct _USER_INFO_3 *ui, PCWSTR dom, PCWSTR name, bool fq);
char *get_gecos (cyg_ldap *pldap, PCWSTR dom, PCWSTR name, bool fq);
char *get_gecos (struct _USER_INFO_3 *ui, PCWSTR dom, PCWSTR name, bool fq);
inline int nss_db_enums () const { return enums; }
inline PCWSTR nss_db_enum_tdoms () const { return enum_tdoms; }
};

253
winsup/cygwin/cygwin.ldif Normal file
View File

@ -0,0 +1,253 @@
# =========================================================================
#
# Schema Extension for Cygwin User and Group auxiliary classes
#
# Extend your Active Directory using
#
# ldifde -i -f <path>\<this>.ldif -b <username> <domain> <password> \
# -k -c "CN=schema,CN=Configuration,DC=X" #schemaNamingContext
#
# Remember:
# - you have to be schema admin for your active directory
# - you have to run the above command directly from your schema master
#
# For further information read
# http://technet.microsoft.com/en-us/magazine/2008.05.schema.aspx
#
# ----------------------------------------------------------------------
#
# Explanation for the OIDs:
#
# Value Meaning Description
# 1 ISO Identifies the root authority.
# 3 IANA Group designation assigned by ISO.
# 6.1.4.1.2312 Red Hat Organization assigned by IANA.
# 15 Cygwin Assigned by Organization.
# Y Object Type Number defining the different object type
# (category) such as classSchema or
# attributeSchema. For example, 5 defines
# object class.
# Z Object Number identifying a particular object
# within the category. For example, the user
# class has the number 9 assigned to it.
#
# ----------------------------------------------------------------------
# Attribute definition for cygwinHome
dn: CN=cygwin-Home,CN=Schema,CN=Configuration,DC=X
changetype: ntdsschemaadd
objectClass: top
objectClass: attributeSchema
cn: cygwin-Home
attributeID: 1.3.6.1.4.1.2312.15.2.1
# attributeSyntax 2.5.5.12 is String(Unicode) with oMSyntax == 64
# see http://technet.microsoft.com/en-us/library/cc961740.aspx
attributeSyntax: 2.5.5.12
isSingleValued: TRUE
adminDisplayName: cygwin-Home
adminDescription: cygwin-Home
oMSyntax: 64
searchFlags: 1
lDAPDisplayName: cygwinHome
systemOnly: FALSE
dn:
changetype: modify
add: schemaUpdateNow
schemaUpdateNow: 1
-
# Attribute definition for cygwinShell
dn: CN=cygwin-Shell,CN=Schema,CN=Configuration,DC=X
changetype: ntdsschemaadd
objectClass: top
objectClass: attributeSchema
cn: cygwin-Shell
attributeID: 1.3.6.1.4.1.2312.15.2.2
attributeSyntax: 2.5.5.12
isSingleValued: TRUE
adminDisplayName: cygwin-Shell
adminDescription: cygwin-Shell
oMSyntax: 64
searchFlags: 1
lDAPDisplayName: cygwinShell
systemOnly: FALSE
dn:
changetype: modify
add: schemaUpdateNow
schemaUpdateNow: 1
-
# Attribute definition for cygwinGecos
dn: CN=cygwin-Gecos,CN=Schema,CN=Configuration,DC=X
changetype: ntdsschemaadd
objectClass: top
objectClass: attributeSchema
cn: cygwin-Gecos
attributeID: 1.3.6.1.4.1.2312.15.2.3
attributeSyntax: 2.5.5.12
isSingleValued: TRUE
adminDisplayName: cygwin-Gecos
adminDescription: cygwin-Gecos
oMSyntax: 64
searchFlags: 1
lDAPDisplayName: cygwinGecos
systemOnly: FALSE
dn:
changetype: modify
add: schemaUpdateNow
schemaUpdateNow: 1
-
# Attribute definition for cygwinFstab
dn: CN=cygwin-Fstab,CN=Schema,CN=Configuration,DC=X
changetype: ntdsschemaadd
objectClass: top
objectClass: attributeSchema
cn: cygwin-Fstab
attributeID: 1.3.6.1.4.1.2312.15.2.4
attributeSyntax: 2.5.5.12
isSingleValued: FALSE
adminDisplayName: cygwin-Fstab
adminDescription: cygwin-Fstab
oMSyntax: 64
searchFlags: 1
lDAPDisplayName: cygwinFstab
systemOnly: FALSE
dn:
changetype: modify
add: schemaUpdateNow
schemaUpdateNow: 1
-
# Attribute definition for cygwinUnixUid
dn: CN=cygwin-UnixUid,CN=Schema,CN=Configuration,DC=X
changetype: ntdsschemaadd
objectClass: top
objectClass: attributeSchema
cn: cygwin-UnixUid
attributeID: 1.3.6.1.4.1.2312.15.2.5
# attributeSyntax 2.5.5.9 is Integer with oMSyntax == 2
attributeSyntax: 2.5.5.9
isSingleValued: TRUE
adminDisplayName: cygwin-UnixUid
adminDescription: cygwin-UnixUid
oMSyntax: 2
searchFlags: 1
lDAPDisplayName: cygwinUnixUid
systemOnly: FALSE
dn:
changetype: modify
add: schemaUpdateNow
schemaUpdateNow: 1
-
# Attribute definition for cygwinUnixGid
dn: CN=cygwin-UnixGid,CN=Schema,CN=Configuration,DC=X
changetype: ntdsschemaadd
objectClass: top
objectClass: attributeSchema
cn: cygwin-UnixGid
attributeID: 1.3.6.1.4.1.2312.15.2.6
attributeSyntax: 2.5.5.9
isSingleValued: TRUE
adminDisplayName: cygwin-UnixGid
adminDescription: cygwin-UnixGid
oMSyntax: 2
searchFlags: 1
lDAPDisplayName: cygwinUnixGid
systemOnly: FALSE
dn:
changetype: modify
add: schemaUpdateNow
schemaUpdateNow: 1
-
# cygwin-User auxiliary class
dn: CN=cygwin-User,CN=Schema,CN=Configuration,DC=X
changetype: ntdsschemaadd
objectClass: top
objectClass: classSchema
cn: cygwin-User
governsID: 1.3.6.1.4.1.2312.15.1.1
mayContain: cygwinHome
mayContain: cygwinShell
mayContain: cygwinGecos
mayContain: cygwinFstab
mayContain: cygwinUnixUid
rDNAttID: cn
adminDisplayName: cygwin-User
adminDescription: cygwin-User
objectClassCategory: 3
lDAPDisplayName: cygwinUser
name: cygwin-User
systemOnly: FALSE
dn:
changetype: modify
add: schemaUpdateNow
schemaUpdateNow: 1
-
# cygwin-Group auxiliary class
dn: CN=cygwin-Group,CN=Schema,CN=Configuration,DC=X
changetype: ntdsschemaadd
objectClass: top
objectClass: classSchema
cn: cygwin-Group
governsID: 1.3.6.1.4.1.2312.15.1.2
mayContain: cygwinUnixGid
rDNAttID: cn
adminDisplayName: cygwin-Group
adminDescription: cygwin-Group
objectClassCategory: 3
lDAPDisplayName: cygwinGroup
name: cygwin-Group
systemOnly: FALSE
dn:
changetype: modify
add: schemaUpdateNow
schemaUpdateNow: 1
-
# Attach cygwin-User to User
dn: CN=User,CN=Schema,CN=Configuration,DC=X
changetype: ntdsschemamodify
add: auxiliaryClass
auxiliaryClass: cygwinUser
-
dn:
changetype: modify
add: schemaUpdateNow
schemaUpdateNow: 1
-
# Attach cygwin-Group to Group
dn: CN=Group,CN=Schema,CN=Configuration,DC=X
changetype: ntdsschemamodify
add: auxiliaryClass
auxiliaryClass: cygwinGroup
-
dn:
changetype: modify
add: schemaUpdateNow
schemaUpdateNow: 1
-

View File

@ -31,20 +31,32 @@ static PWCHAR rootdse_attr[] =
NULL
};
static PWCHAR user_attr[] =
static const PCWSTR std_user_attr[] =
{
(PWCHAR) L"primaryGroupID",
(PWCHAR) L"gecos",
(PWCHAR) L"unixHomeDirectory",
(PWCHAR) L"loginShell",
(PWCHAR) L"uidNumber",
NULL
L"primaryGroupID",
L"uidNumber",
L"cygwinUnixUid", /* TODO */
/* windows scheme */
L"displayName",
L"homeDrive",
L"homeDirectory",
/* cygwin scheme */
L"cygwinGecos",
L"cygwinHome",
L"cygwinShell",
/* unix scheme */
L"gecos",
L"unixHomeDirectory",
L"loginShell",
/* desc scheme */
L"description"
};
static PWCHAR group_attr[] =
{
(PWCHAR) L"cn",
(PWCHAR) L"gidNumber",
(PWCHAR) L"cygwinUnixGid", /* TODO */
NULL
};
@ -72,6 +84,32 @@ PWCHAR rfc2307_gid_attr[] =
NULL
};
/* ================================================================= */
/* Helper method of cygheap_pwdgrp class. It sets the user attribs */
/* from the settings in nsswitch.conf. */
/* ================================================================= */
#define user_attr (cygheap->pg.ldap_user_attr)
void
cygheap_pwdgrp::init_ldap_user_attr ()
{
ldap_user_attr = (PWCHAR *)
ccalloc_abort (HEAP_BUF, sizeof (std_user_attr) / sizeof (*std_user_attr)
+ 3 * NSS_SCHEME_MAX + 1, sizeof (PWCHAR));
memcpy (ldap_user_attr, std_user_attr, sizeof (std_user_attr));
uint16_t freeattr_idx = sizeof (std_user_attr) / sizeof (*std_user_attr);
for (uint16_t idx = 0; idx < NSS_SCHEME_MAX; ++idx)
{
if (home_scheme[idx].method == NSS_SCHEME_FREEATTR)
ldap_user_attr[freeattr_idx++] = home_scheme[idx].attrib;
if (shell_scheme[idx].method == NSS_SCHEME_FREEATTR)
ldap_user_attr[freeattr_idx++] = shell_scheme[idx].attrib;
if (gecos_scheme[idx].method == NSS_SCHEME_FREEATTR)
ldap_user_attr[freeattr_idx++] = gecos_scheme[idx].attrib;
}
}
/* ================================================================= */
/* Helper methods. */
/* ================================================================= */
@ -388,6 +426,8 @@ cyg_ldap::fetch_ad_account (PSID sid, bool group, PCWSTR domain)
r = wcpcpy (r, domain);
}
}
if (!user_attr)
cygheap->pg.init_ldap_user_attr ();
attr = group ? group_attr : user_attr;
if (search (rdse, filter, attr) != 0)
return false;
@ -421,7 +461,7 @@ cyg_ldap::enumerate_ad_accounts (PCWSTR domain, bool group)
"(objectSid=*))";
else
filter = L"(&(objectClass=Group)"
/* 1 == ACCOUNT_GROUP */
/* 1 == BUILTIN_LOCAL_GROUP */
"(!(groupType:" LDAP_MATCHING_RULE_BIT_AND ":=1))"
"(objectSid=*))";
srch_id = ldap_search_init_pageW (lh, rootdse, LDAP_SCOPE_SUBTREE,
@ -503,20 +543,26 @@ cyg_ldap::fetch_posix_offset_for_domain (PCWSTR domain)
}
PWCHAR
cyg_ldap::get_string_attribute (int idx)
cyg_ldap::get_string_attribute (PCWSTR name)
{
if (val)
ldap_value_freeW (val);
val = ldap_get_valuesW (lh, entry, attr[idx]);
val = ldap_get_valuesW (lh, entry, (PWCHAR) name);
if (val)
return val[0];
return NULL;
}
PWCHAR
cyg_ldap::get_string_attribute (int idx)
{
return get_string_attribute (attr[idx]);
}
uint32_t
cyg_ldap::get_num_attribute (int idx)
{
PWCHAR ret = get_string_attribute (idx);
PWCHAR ret = get_string_attribute (attr[idx]);
if (ret)
return (uint32_t) wcstoul (ret, NULL, 10);
return (uint32_t) -1;

View File

@ -17,14 +17,11 @@ details. */
#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_USER_PGRP_ATTR 0
#define LDAP_USER_UID_ATTR 1
#define LDAP_GROUP_NAME_ATTR 0
#define LDAP_GROUP_GID_ATTR 1
#define LDAP_GROUP_NAME_ATTR 0
#define LDAP_GROUP_GID_ATTR 1
class cyg_ldap {
PLDAP lh;
@ -68,13 +65,10 @@ public:
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); }
PWCHAR get_string_attribute (PCWSTR name);
};

View File

@ -320,7 +320,7 @@ cuserid (char *src)
const char *
cygheap_user::ontherange (homebodies what, struct passwd *pw)
{
LPUSER_INFO_3 ui = NULL;
PUSER_INFO_3 ui = NULL;
WCHAR wuser[UNLEN + 1];
NET_API_STATUS ret;
char homedrive_env_buf[3];
@ -369,7 +369,7 @@ cygheap_user::ontherange (homebodies what, struct passwd *pw)
WCHAR wlogsrv[INTERNET_MAX_HOST_NAME_LENGTH + 3];
sys_mbstowcs (wlogsrv, sizeof (wlogsrv) / sizeof (*wlogsrv),
logsrv ());
sys_mbstowcs (wuser, sizeof (wuser) / sizeof (*wuser), winname ());
sys_mbstowcs (wuser, sizeof wuser / sizeof *wuser, winname ());
if (!(ret = NetUserGetInfo (wlogsrv, wuser, 3, (LPBYTE *) &ui)))
{
sys_wcstombs (homepath_env_buf, NT_MAX_PATH,
@ -584,17 +584,30 @@ cygheap_pwdgrp::init ()
group: files db
db_prefix: auto DISABLED
db_separator: + DISABLED
db_home: cygwin desc
db_shell: cygwin desc
db_gecos: cygwin desc
db_enum: cache builtin
*/
pwd_src = (NSS_SRC_FILES | NSS_SRC_DB);
grp_src = (NSS_SRC_FILES | NSS_SRC_DB);
prefix = NSS_AUTO;
prefix = NSS_PFX_AUTO;
separator[0] = L'+';
home_scheme[0].method = NSS_SCHEME_CYGWIN;
home_scheme[1].method = NSS_SCHEME_DESC;
shell_scheme[0].method = NSS_SCHEME_CYGWIN;
shell_scheme[1].method = NSS_SCHEME_DESC;
gecos_scheme[0].method = NSS_SCHEME_CYGWIN;
gecos_scheme[1].method = NSS_SCHEME_DESC;
enums = (ENUM_CACHE | ENUM_BUILTIN);
enum_tdoms = NULL;
caching = true; /* INTERNAL ONLY */
}
#define NSS_NCMP(s) (!strncmp(c, (s), sizeof(s)-1))
#define NSS_CMP(s) (!strncmp(c, (s), sizeof(s)-1) \
&& strchr (" \t", c[sizeof(s)-1]))
/* 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. */
@ -602,36 +615,31 @@ void
cygheap_pwdgrp::nss_init_line (const char *line)
{
const char *c = line + strspn (line, " \t");
char *comment = strchr (c, '#');
if (comment)
*comment = '\0';
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;
}
uint32_t *src = NULL;
if (NSS_NCMP ("passwd:"))
src = &pwd_src;
else if (NSS_NCMP ("group:"))
src = &grp_src;
c = strchr (c, ':') + 1;
if (src)
{
*src = 0;
while (*c)
while (*(c += strspn (c, " \t")))
{
c += strspn (c, " \t");
if (!*c || *c == '#')
break;
if (!strncmp (c, "files", 5) && strchr (" \t", c[5]))
if (NSS_CMP ("files"))
{
*src |= NSS_SRC_FILES;
c += 5;
}
else if (!strncmp (c, "db", 2) && strchr (" \t", c[2]))
else if (NSS_CMP ("db"))
{
*src |= NSS_SRC_DB;
c += 2;
@ -648,7 +656,7 @@ cygheap_pwdgrp::nss_init_line (const char *line)
}
break;
case 'd':
if (strncmp (c, "db_", 3))
if (!NSS_NCMP ("db_"))
{
debug_printf ("Invalid nsswitch.conf content: %s", line);
break;
@ -656,22 +664,22 @@ cygheap_pwdgrp::nss_init_line (const char *line)
c += 3;
#if 0 /* Disable setting prefix and separator from nsswitch.conf for now.
Remove if nobody complains too loudly. */
if (!strncmp (c, "prefix:", 7))
if (NSS_NCMP ("prefix:"))
{
c += 7;
c = strchr (c, ':') + 1;
c += strspn (c, " \t");
if (!strncmp (c, "auto", 4) && strchr (" \t", c[4]))
if (NSS_CMP ("auto"))
prefix = NSS_AUTO;
else if (!strncmp (c, "primary", 7) && strchr (" \t", c[7]))
else if (NSS_CMP ("primary"))
prefix = NSS_PRIMARY;
else if (!strncmp (c, "always", 6) && strchr (" \t", c[6]))
else if (NSS_CMP ("always"))
prefix = NSS_ALWAYS;
else
debug_printf ("Invalid nsswitch.conf content: %s", line);
}
else if (!strncmp (c, "separator:", 10))
else if (NSS_NCMP ("separator:"))
{
c += 10;
c = strchr (c, ':') + 1;
c += strspn (c, " \t");
if ((unsigned char) *c <= 0x7f && *c != ':' && strchr (" \t", c[1]))
separator[0] = (unsigned char) *c;
@ -680,7 +688,7 @@ cygheap_pwdgrp::nss_init_line (const char *line)
}
else
#endif
if (!strncmp (c, "enum:", 5))
if (NSS_NCMP ("enum:"))
{
tmp_pathbuf tp;
char *tdoms = tp.c_get ();
@ -688,26 +696,26 @@ cygheap_pwdgrp::nss_init_line (const char *line)
int new_enums = ENUM_NONE;
td[0] = '\0';
c += 5;
c = strchr (c, ':') + 1;
c += strspn (c, " \t");
while (!strchr (" \t", *c))
{
const char *e = c + strcspn (c, " \t");
if (!strncmp (c, "none", 4) && strchr (" \t", c[4]))
if (NSS_CMP ("none"))
new_enums = ENUM_NONE;
else if (!strncmp (c, "builtin", 7) && strchr (" \t", c[7]))
else if (NSS_CMP ("builtin"))
new_enums |= ENUM_BUILTIN;
else if (!strncmp (c, "cache", 5) && strchr (" \t", c[5]))
else if (NSS_CMP ("cache"))
new_enums |= ENUM_CACHE;
else if (!strncmp (c, "files", 5) && strchr (" \t", c[5]))
else if (NSS_CMP ("files"))
new_enums |= ENUM_FILES;
else if (!strncmp (c, "local", 5) && strchr (" \t", c[5]))
else if (NSS_CMP ("local"))
new_enums |= ENUM_LOCAL;
else if (!strncmp (c, "primary", 7) && strchr (" \t", c[7]))
else if (NSS_CMP ("primary"))
new_enums |= ENUM_PRIMARY;
else if (!strncmp (c, "alltrusted", 10) && strchr (" \t", c[10]))
else if (NSS_CMP ("alltrusted"))
new_enums |= ENUM_TDOMS | ENUM_TDOMS_ALL;
else if (!strncmp (c, "all", 3) && strchr (" \t", c[3]))
else if (NSS_CMP ("all"))
new_enums |= ENUM_ALL;
else
{
@ -732,9 +740,62 @@ cygheap_pwdgrp::nss_init_line (const char *line)
}
enums = new_enums;
}
else
{
nss_scheme_t *scheme = NULL;
if (NSS_NCMP ("home:"))
scheme = home_scheme;
else if (NSS_NCMP ("shell:"))
scheme = shell_scheme;
else if (NSS_NCMP ("gecos:"))
scheme = gecos_scheme;
if (scheme)
{
uint16_t idx = 0;
scheme[0].method = scheme[1].method = NSS_SCHEME_FALLBACK;
c = strchr (c, ':') + 1;
c += strspn (c, " \t");
while (*c && idx < NSS_SCHEME_MAX)
{
if (NSS_CMP ("windows"))
scheme[idx].method = NSS_SCHEME_WINDOWS;
else if (NSS_CMP ("cygwin"))
scheme[idx].method = NSS_SCHEME_CYGWIN;
else if (NSS_CMP ("unix"))
scheme[idx].method = NSS_SCHEME_UNIX;
else if (NSS_CMP ("desc"))
scheme[idx].method = NSS_SCHEME_DESC;
else if (NSS_NCMP ("/"))
{
const char *e = c + strcspn (c, " \t");
scheme[idx].method = NSS_SCHEME_PATH;
sys_mbstowcs_alloc (&scheme[idx].attrib, HEAP_STR,
c, e - c);
}
else if (NSS_NCMP ("@") && isalnum ((unsigned) *++c))
{
const char *e = c + strcspn (c, " \t");
scheme[idx].method = NSS_SCHEME_FREEATTR;
sys_mbstowcs_alloc (&scheme[idx].attrib, HEAP_STR,
c, e - c);
}
else
debug_printf ("Invalid nsswitch.conf content: %s", line);
c += strcspn (c, " \t");
c += strspn (c, " \t");
++idx;
}
/* If nothing has been set, revert to default. */
if (scheme[0].method == NSS_SCHEME_FALLBACK)
{
scheme[0].method = NSS_SCHEME_CYGWIN;
scheme[1].method = NSS_SCHEME_DESC;
}
}
}
break;
case '\0':
case '#':
break;
default:
debug_printf ("Invalid nsswitch.conf content: %s", line);
@ -742,6 +803,338 @@ cygheap_pwdgrp::nss_init_line (const char *line)
}
}
/* Local SAM accounts have only a handful attributes available to home users.
Therefore, allow to fetch additional passwd/group attributes from the
"Comment" field in XML short style. For symmetry, this is also allowed
from the equivalent "description" AD attribute. */
char *
fetch_from_description (PCWSTR desc, PCWSTR search, size_t len)
{
PWCHAR s, e;
char *ret = NULL;
if ((s = wcsstr (desc, L"<cygwin ")) && (e = wcsstr (s + 8, L"/>")))
{
s += 8;
while (s && s < e)
{
while (*s == L' ')
++s;
if (!wcsncmp (s, search, len)) /* Found what we're searching? */
{
s += len;
if ((e = wcschr (s, L'"')))
{
sys_wcstombs_alloc (&ret, HEAP_NOTHEAP, s, e - s);
s = e + 1;
}
break;
}
else /* Skip the current foo="bar" string. */
if ((s = wcschr (s, L'"')) && (s = wcschr (s + 1, L'"')))
++s;
}
}
return ret;
}
char *
fetch_from_path (PCWSTR str, PCWSTR dom, PCWSTR name, bool full_qualified)
{
tmp_pathbuf tp;
PWCHAR wpath = tp.w_get ();
PWCHAR w = wpath;
PWCHAR we = wpath + NT_MAX_PATH - 1;
char *ret = NULL;
while (*str && w < we)
{
if (*str != L'%')
*w++ = *str++;
else
{
switch (*++str)
{
case L'u':
if (full_qualified)
{
w = wcpncpy (w, dom, we - w);
if (w < we)
*w++ = cygheap->pg.nss_separator ()[0];
}
w = wcpncpy (w, name, we - w);
break;
case L'U':
w = wcpncpy (w, name, we - w);
break;
case L'D':
w = wcpncpy (w, dom, we - w);
break;
case L'_':
*w++ = L' ';
break;
default:
*w++ = *str;
break;
}
++str;
}
}
*w = L'\0';
sys_wcstombs_alloc (&ret, HEAP_NOTHEAP, wpath);
return ret;
}
char *
cygheap_pwdgrp::get_home (cyg_ldap *pldap, PCWSTR dom, PCWSTR name,
bool full_qualified)
{
PWCHAR val;
char *home = NULL;
for (uint16_t idx = 0; !home && idx < NSS_SCHEME_MAX; ++idx)
{
switch (home_scheme[idx].method)
{
case NSS_SCHEME_FALLBACK:
return NULL;
case NSS_SCHEME_WINDOWS:
val = pldap->get_string_attribute (L"homeDrive");
if (!val || !*val)
val = pldap->get_string_attribute (L"homeDirectory");
if (val && *val)
home = (char *) cygwin_create_path (CCP_WIN_W_TO_POSIX, val);
break;
case NSS_SCHEME_CYGWIN:
val = pldap->get_string_attribute (L"cygwinHome");
if (val && *val)
sys_wcstombs_alloc (&home, HEAP_NOTHEAP, val);
break;
case NSS_SCHEME_UNIX:
val = pldap->get_string_attribute (L"unixHomeDirectory");
if (val && *val)
sys_wcstombs_alloc (&home, HEAP_NOTHEAP, val);
break;
case NSS_SCHEME_DESC:
val = pldap->get_string_attribute (L"description");
if (val && *val)
home = fetch_from_description (val, L"home=\"", 6);
break;
case NSS_SCHEME_PATH:
home = fetch_from_path (home_scheme[idx].attrib, dom, name,
full_qualified);
break;
case NSS_SCHEME_FREEATTR:
val = pldap->get_string_attribute (home_scheme[idx].attrib);
if (val && *val)
sys_wcstombs_alloc (&home, HEAP_NOTHEAP, val);
break;
}
}
return home;
}
char *
cygheap_pwdgrp::get_home (PUSER_INFO_3 ui, PCWSTR dom, PCWSTR name,
bool full_qualified)
{
char *home = NULL;
for (uint16_t idx = 0; !home && idx < NSS_SCHEME_MAX; ++idx)
{
switch (home_scheme[idx].method)
{
case NSS_SCHEME_FALLBACK:
return NULL;
case NSS_SCHEME_WINDOWS:
if (ui->usri3_home_dir_drive && *ui->usri3_home_dir_drive)
home = (char *) cygwin_create_path (CCP_WIN_W_TO_POSIX,
ui->usri3_home_dir_drive);
else if (ui->usri3_home_dir && *ui->usri3_home_dir)
home = (char *) cygwin_create_path (CCP_WIN_W_TO_POSIX,
ui->usri3_home_dir);
break;
case NSS_SCHEME_CYGWIN:
case NSS_SCHEME_UNIX:
case NSS_SCHEME_FREEATTR:
break;
case NSS_SCHEME_DESC:
home = fetch_from_description (ui->usri3_comment, L"home=\"", 6);
break;
case NSS_SCHEME_PATH:
home = fetch_from_path (home_scheme[idx].attrib, dom, name,
full_qualified);
break;
}
}
return home;
}
char *
cygheap_pwdgrp::get_shell (cyg_ldap *pldap, PCWSTR dom, PCWSTR name,
bool full_qualified)
{
PWCHAR val;
char *shell = NULL;
for (uint16_t idx = 0; !shell && idx < NSS_SCHEME_MAX; ++idx)
{
switch (shell_scheme[idx].method)
{
case NSS_SCHEME_FALLBACK:
return NULL;
case NSS_SCHEME_WINDOWS:
break;
case NSS_SCHEME_CYGWIN:
val = pldap->get_string_attribute (L"cygwinShell");
if (val && *val)
sys_wcstombs_alloc (&shell, HEAP_NOTHEAP, val);
break;
case NSS_SCHEME_UNIX:
val = pldap->get_string_attribute (L"loginShell");
if (val && *val)
sys_wcstombs_alloc (&shell, HEAP_NOTHEAP, val);
break;
case NSS_SCHEME_DESC:
val = pldap->get_string_attribute (L"description");
if (val && *val)
shell = fetch_from_description (val, L"shell=\"", 7);
break;
case NSS_SCHEME_PATH:
shell = fetch_from_path (shell_scheme[idx].attrib, dom, name,
full_qualified);
break;
case NSS_SCHEME_FREEATTR:
val = pldap->get_string_attribute (shell_scheme[idx].attrib);
if (val && *val)
sys_wcstombs_alloc (&shell, HEAP_NOTHEAP, val);
break;
}
}
return shell;
}
char *
cygheap_pwdgrp::get_shell (PUSER_INFO_3 ui, PCWSTR dom, PCWSTR name,
bool full_qualified)
{
char *shell = NULL;
for (uint16_t idx = 0; !shell && idx < NSS_SCHEME_MAX; ++idx)
{
switch (shell_scheme[idx].method)
{
case NSS_SCHEME_FALLBACK:
return NULL;
case NSS_SCHEME_WINDOWS:
case NSS_SCHEME_CYGWIN:
case NSS_SCHEME_UNIX:
case NSS_SCHEME_FREEATTR:
break;
case NSS_SCHEME_DESC:
shell = fetch_from_description (ui->usri3_comment, L"shell=\"", 7);
break;
case NSS_SCHEME_PATH:
shell = fetch_from_path (shell_scheme[idx].attrib, dom, name,
full_qualified);
break;
}
}
return shell;
}
/* Helper function to replace colons with semicolons in pw_gecos field. */
static inline void
colon_to_semicolon (char *str)
{
char *cp = str;
while ((cp = strchr (cp, L':')) != NULL)
*cp++ = L';';
}
char *
cygheap_pwdgrp::get_gecos (cyg_ldap *pldap, PCWSTR dom, PCWSTR name,
bool full_qualified)
{
PWCHAR val;
char *gecos = NULL;
for (uint16_t idx = 0; !gecos && idx < NSS_SCHEME_MAX; ++idx)
{
switch (gecos_scheme[idx].method)
{
case NSS_SCHEME_FALLBACK:
return NULL;
case NSS_SCHEME_WINDOWS:
val = pldap->get_string_attribute (L"displayName");
if (val && *val)
sys_wcstombs_alloc (&gecos, HEAP_NOTHEAP, val);
break;
case NSS_SCHEME_CYGWIN:
val = pldap->get_string_attribute (L"cygwinGecos");
if (val && *val)
sys_wcstombs_alloc (&gecos, HEAP_NOTHEAP, val);
break;
case NSS_SCHEME_UNIX:
val = pldap->get_string_attribute (L"gecos");
if (val && *val)
sys_wcstombs_alloc (&gecos, HEAP_NOTHEAP, val);
break;
case NSS_SCHEME_DESC:
val = pldap->get_string_attribute (L"description");
if (val && *val)
gecos = fetch_from_description (val, L"gecos=\"", 7);
break;
case NSS_SCHEME_PATH:
gecos = fetch_from_path (gecos_scheme[idx].attrib + 1, dom, name,
full_qualified);
break;
case NSS_SCHEME_FREEATTR:
val = pldap->get_string_attribute (gecos_scheme[idx].attrib);
if (val && *val)
sys_wcstombs_alloc (&gecos, HEAP_NOTHEAP, val);
break;
}
}
if (gecos)
colon_to_semicolon (gecos);
return gecos;
}
char *
cygheap_pwdgrp::get_gecos (PUSER_INFO_3 ui, PCWSTR dom, PCWSTR name,
bool full_qualified)
{
char *gecos = NULL;
for (uint16_t idx = 0; !gecos && idx < NSS_SCHEME_MAX; ++idx)
{
switch (gecos_scheme[idx].method)
{
case NSS_SCHEME_FALLBACK:
return NULL;
case NSS_SCHEME_WINDOWS:
if (ui->usri3_full_name && *ui->usri3_full_name)
sys_wcstombs_alloc (&gecos, HEAP_NOTHEAP, ui->usri3_full_name);
break;
case NSS_SCHEME_CYGWIN:
case NSS_SCHEME_UNIX:
case NSS_SCHEME_FREEATTR:
break;
case NSS_SCHEME_DESC:
gecos = fetch_from_description (ui->usri3_comment, L"gecos=\"", 7);
break;
case NSS_SCHEME_PATH:
gecos = fetch_from_path (gecos_scheme[idx].attrib + 1, dom, name,
full_qualified);
break;
}
}
if (gecos)
colon_to_semicolon (gecos);
return gecos;
}
void
cygheap_pwdgrp::_nss_init ()
{
@ -1170,16 +1563,6 @@ fetch_posix_offset (PDS_DOMAIN_TRUSTSW td, cyg_ldap *cldap)
return td->PosixOffset;
}
/* Helper function to replace colons with semicolons 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
@ -1213,9 +1596,9 @@ pwdgrp::fetch_account_from_windows (fetch_user_arg_t &arg, cyg_ldap *pldap)
gid_t gid = ILLEGAL_GID;
bool is_domain_account = true;
PCWSTR domain = NULL;
PWCHAR shell = NULL;
PWCHAR home = NULL;
PWCHAR gecos = NULL;
char *shell = NULL;
char *home = NULL;
char *gecos = NULL;
/* Temporary stuff. */
PWCHAR p;
WCHAR sidstr[128];
@ -1604,16 +1987,10 @@ pwdgrp::fetch_account_from_windows (fetch_user_arg_t &arg, cyg_ldap *pldap)
debug_printf ("Unknown domain %W", dom);
return NULL;
}
/* Generate values. */
/* Generate uid/gid 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)
if (!is_group () && acc_type == SidTypeUser)
{
/* Default primary group. If the sid is the current user, fetch
the default group from the current user token, otherwise make
@ -1633,20 +2010,17 @@ pwdgrp::fetch_account_from_windows (fetch_user_arg_t &arg, cyg_ldap *pldap)
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);
if (!is_group ())
{
home = cygheap->pg.get_home (cldap, dom, name,
fully_qualified_name);
shell = cygheap->pg.get_shell (cldap, dom, name,
fully_qualified_name);
gecos = cygheap->pg.get_gecos (cldap, dom, name,
fully_qualified_name);
}
/* Check and, if necessary, add unix<->windows id mapping on
the fly, unless we're called from getpwent. */
if (!pldap)
@ -1663,35 +2037,19 @@ pwdgrp::fetch_account_from_windows (fetch_user_arg_t &arg, cyg_ldap *pldap)
else
{
NET_API_STATUS nas;
PUSER_INFO_4 ui;
PUSER_INFO_3 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;
char *pgrp = NULL;
char *uxid = NULL;
if (acc_type == SidTypeUser)
{
nas = NetUserGetInfo (NULL, name, 4, (PBYTE *) &ui);
nas = NetUserGetInfo (NULL, name, 3, (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
@ -1711,6 +2069,17 @@ pwdgrp::fetch_account_from_windows (fetch_user_arg_t &arg, cyg_ldap *pldap)
NetApiBufferFree (ui24);
}
}
/* Fetch user attributes. */
home = cygheap->pg.get_home (ui, dom, name,
fully_qualified_name);
shell = cygheap->pg.get_shell (ui, dom, name,
fully_qualified_name);
gecos = cygheap->pg.get_gecos (ui, dom, name,
fully_qualified_name);
uxid = fetch_from_description (ui->usri3_comment,
L"unix=\"", 6);
pgrp = fetch_from_description (ui->usri3_comment,
L"group=\"", 7);
}
else /* acc_type == SidTypeAlias */
{
@ -1720,46 +2089,11 @@ pwdgrp::fetch_account_from_windows (fetch_user_arg_t &arg, cyg_ldap *pldap)
debug_printf ("NetLocalGroupGetInfo(%W) %u", name, nas);
break;
}
/* Set comment variable for below attribute loop. */
comment = gi->lgrpi1_comment;
/* Fetch unix gid from comment field. */
uxid = fetch_from_description (gi->lgrpi1_comment,
L"unix=\"", 6);
}
/* 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
@ -1769,7 +2103,7 @@ pwdgrp::fetch_account_from_windows (fetch_user_arg_t &arg, cyg_ldap *pldap)
/* Set primary group from the "Description" field. Prepend
account domain if this is a domain member machine or the
db_prefix setting requires it. */
char gname[2 * (DNLEN + UNLEN) + 2], *gp = gname;
char gname[2 * DNLEN + strlen (pgrp) + 1], *gp = gname;
struct group *gr;
if (cygheap->dom.member_machine ()
@ -1780,11 +2114,12 @@ pwdgrp::fetch_account_from_windows (fetch_user_arg_t &arg, cyg_ldap *pldap)
cygheap->dom.account_flat_name ());
*gp++ = cygheap->pg.nss_separator ()[0];
}
sys_wcstombs (gp, sizeof gname - (gp - gname), pgrp);
stpcpy (gp, pgrp);
if ((gr = internal_getgrnam (gname, cldap)))
gid = gr->gr_gid;
}
if (!pldap && uxid && ((id_val = wcstoul (uxid, &e, 10)), !*e))
char *e;
if (!pldap && uxid && ((id_val = strtoul (uxid, &e, 10)), !*e))
{
if (acc_type == SidTypeUser)
{
@ -1794,6 +2129,10 @@ pwdgrp::fetch_account_from_windows (fetch_user_arg_t &arg, cyg_ldap *pldap)
else if (cygheap->ugid_cache.get_gid (id_val) == ILLEGAL_GID)
cygheap->ugid_cache.add_gid (id_val, uid);
}
if (pgrp)
free (pgrp);
if (uxid)
free (uxid);
}
break;
case SidTypeWellKnownGroup:
@ -1935,7 +2274,7 @@ pwdgrp::fetch_account_from_windows (fetch_user_arg_t &arg, cyg_ldap *pldap)
}
tmp_pathbuf tp;
PWCHAR linebuf = tp.w_get ();
char *linebuf = tp.c_get ();
char *line = NULL;
WCHAR posix_name[UNLEN + 1 + DNLEN + 1];
@ -1947,23 +2286,31 @@ pwdgrp::fetch_account_from_windows (fetch_user_arg_t &arg, cyg_ldap *pldap)
wcpcpy (p, name);
if (is_group ())
__small_swprintf (linebuf, L"%W:%W:%u:",
posix_name, sid.string (sidstr), uid);
__small_sprintf (linebuf, "%W:%s:%u:",
posix_name, sid.string ((char *) 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:U-%W\\%W,%W:/:/sbin/nologin",
posix_name, uid, gid, dom, name, sid.string (sidstr));
__small_sprintf (linebuf, "%W:*:%u:%u:U-%W\\%W,%s:/:/sbin/nologin",
posix_name, uid, gid,
dom, name,
sid.string ((char *) 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);
__small_sprintf (linebuf, "%W:*:%u:%u:%s%sU-%W\\%W,%s:%s%W:%s",
posix_name, uid, gid,
gecos ?: "", gecos ? "," : "",
dom, name,
sid.string ((char *) sidstr),
home ?: "/home/", home ? L"" : name,
shell ?: "/bin/bash");
if (gecos)
free (gecos);
if (home)
free (home);
if (shell)
free (shell);
line = cstrdup (linebuf);
debug_printf ("line: <%s>", line);
return line;
}