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:
authorCorinna Vinschen <corinna@vinschen.de>2014-11-26 22:46:59 +0300
committerCorinna Vinschen <corinna@vinschen.de>2014-11-26 22:46:59 +0300
commit93d15b36efe67e26e89bcd4def82c4d73c7a6dcb (patch)
tree15661bd5ab69acf7b742e30925c631bf4abcc659 /winsup
parent8a2ab1aea1ccd84400d4f7dfd1ac87fa67485036 (diff)
* 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.
Diffstat (limited to 'winsup')
-rw-r--r--winsup/cygwin/ChangeLog49
-rw-r--r--winsup/cygwin/Makefile.in6
-rw-r--r--winsup/cygwin/cygheap.h65
-rw-r--r--winsup/cygwin/cygwin.ldif253
-rw-r--r--winsup/cygwin/ldap.cc68
-rw-r--r--winsup/cygwin/ldap.h16
-rw-r--r--winsup/cygwin/uinfo.cc641
7 files changed, 913 insertions, 185 deletions
diff --git a/winsup/cygwin/ChangeLog b/winsup/cygwin/ChangeLog
index 10ccff6da..443176095 100644
--- a/winsup/cygwin/ChangeLog
+++ b/winsup/cygwin/ChangeLog
@@ -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
diff --git a/winsup/cygwin/Makefile.in b/winsup/cygwin/Makefile.in
index 6f603d887..3d09e2133 100644
--- a/winsup/cygwin/Makefile.in
+++ b/winsup/cygwin/Makefile.in
@@ -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:
diff --git a/winsup/cygwin/cygheap.h b/winsup/cygwin/cygheap.h
index aa2a7f65a..1502e8c43 100644
--- a/winsup/cygwin/cygheap.h
+++ b/winsup/cygwin/cygheap.h
@@ -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; }
};
diff --git a/winsup/cygwin/cygwin.ldif b/winsup/cygwin/cygwin.ldif
new file mode 100644
index 000000000..166a58123
--- /dev/null
+++ b/winsup/cygwin/cygwin.ldif
@@ -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
+-
diff --git a/winsup/cygwin/ldap.cc b/winsup/cygwin/ldap.cc
index df7756809..9daf89b6d 100644
--- a/winsup/cygwin/ldap.cc
+++ b/winsup/cygwin/ldap.cc
@@ -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
};
@@ -73,6 +85,32 @@ PWCHAR rfc2307_gid_attr[] =
};
/* ================================================================= */
+/* 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;
diff --git a/winsup/cygwin/ldap.h b/winsup/cygwin/ldap.h
index 7f90a3821..d3c28fcbd 100644
--- a/winsup/cygwin/ldap.h
+++ b/winsup/cygwin/ldap.h
@@ -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);
};
diff --git a/winsup/cygwin/uinfo.cc b/winsup/cygwin/uinfo.cc
index 6b7ad550c..df2cde270 100644
--- a/winsup/cygwin/uinfo.cc
+++ b/winsup/cygwin/uinfo.cc
@@ -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;
- }
- /* 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;
- }
+ /* Fetch unix gid from comment field. */
+ uxid = fetch_from_description (gi->lgrpi1_comment,
+ L"unix=\"", 6);
}
+
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;
}