diff options
author | Jerry Jelinek <jerry.jelinek@joyent.com> | 2019-05-31 11:41:35 +0000 |
---|---|---|
committer | Jerry Jelinek <jerry.jelinek@joyent.com> | 2019-05-31 11:41:35 +0000 |
commit | 598a26718811d9be082ffc4a87807db5d27aba2c (patch) | |
tree | c7331c318caf7805162b3d15aca54a84b02ddbdf /usr/src | |
parent | 1205f1a47f18f403254c28de55875156744b9e0a (diff) | |
parent | 02f11668f579380770bed664cc4f91bfd9a3a81b (diff) | |
download | illumos-joyent-598a26718811d9be082ffc4a87807db5d27aba2c.tar.gz |
[illumos-gate merge]
commit 02f11668f579380770bed664cc4f91bfd9a3a81b
11054 loader: malloc+memset is calloc in spa_create
commit b5b5d63449cdd6704056e02737cee60bef57229c
11053 loader: zfs_alloc and zfs_free should use panic
commit 695ef821379e863d33c30fb148f4ecf87038b246
10990 Get UNIX group info. from AD/LDAP with partial RFC2307 schema
commit dbcaafbddbc82f9a7b3310551c4bcdb862b2515a
9751 Allocation throttling misplacing ditto blocks
Diffstat (limited to 'usr/src')
-rw-r--r-- | usr/src/boot/lib/libstand/zfs/zfsimpl.c | 9 | ||||
-rw-r--r-- | usr/src/lib/libldap5/sources/ldap/common/search.c | 14 | ||||
-rw-r--r-- | usr/src/lib/libsldap/common/mapfile-vers | 2 | ||||
-rw-r--r--[-rwxr-xr-x] | usr/src/lib/libsldap/common/ns_connmgmt.c | 4 | ||||
-rw-r--r--[-rwxr-xr-x] | usr/src/lib/libsldap/common/ns_connmgmt.h | 5 | ||||
-rw-r--r-- | usr/src/lib/libsldap/common/ns_internal.h | 28 | ||||
-rw-r--r-- | usr/src/lib/libsldap/common/ns_reads.c | 83 | ||||
-rw-r--r-- | usr/src/lib/libsldap/common/ns_sldap.h | 7 | ||||
-rw-r--r-- | usr/src/lib/nsswitch/ldap/common/getgrent.c | 355 | ||||
-rw-r--r-- | usr/src/lib/nsswitch/ldap/common/ldap_common.c | 8 | ||||
-rw-r--r-- | usr/src/lib/nsswitch/ldap/common/ldap_common.h | 3 | ||||
-rw-r--r-- | usr/src/uts/common/fs/zfs/metaslab.c | 13 |
12 files changed, 367 insertions, 164 deletions
diff --git a/usr/src/boot/lib/libstand/zfs/zfsimpl.c b/usr/src/boot/lib/libstand/zfs/zfsimpl.c index 23632e98c0..9217d4363a 100644 --- a/usr/src/boot/lib/libstand/zfs/zfsimpl.c +++ b/usr/src/boot/lib/libstand/zfs/zfsimpl.c @@ -106,8 +106,7 @@ zfs_alloc(size_t size) char *ptr; if (zfs_temp_ptr + size > zfs_temp_end) { - printf("ZFS: out of temporary buffer space\n"); - for (;;) ; + panic("ZFS: out of temporary buffer space"); } ptr = zfs_temp_ptr; zfs_temp_ptr += size; @@ -121,8 +120,7 @@ zfs_free(void *ptr, size_t size) zfs_temp_ptr -= size; if (zfs_temp_ptr != ptr) { - printf("ZFS: zfs_alloc()/zfs_free() mismatch\n"); - for (;;) ; + panic("ZFS: zfs_alloc()/zfs_free() mismatch"); } } @@ -760,9 +758,8 @@ spa_create(uint64_t guid, const char *name) { spa_t *spa; - if ((spa = malloc(sizeof(spa_t))) == NULL) + if ((spa = calloc(1, sizeof (spa_t))) == NULL) return (NULL); - memset(spa, 0, sizeof(spa_t)); if ((spa->spa_name = strdup(name)) == NULL) { free(spa); return (NULL); diff --git a/usr/src/lib/libldap5/sources/ldap/common/search.c b/usr/src/lib/libldap5/sources/ldap/common/search.c index 1235234f8b..2f4cb166cd 100644 --- a/usr/src/lib/libldap5/sources/ldap/common/search.c +++ b/usr/src/lib/libldap5/sources/ldap/common/search.c @@ -1,10 +1,10 @@ /* * Copyright 2001-2002 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. + * + * Copyright 2017 Nexenta Systems, Inc. All rights reserved. */ -#pragma ident "%Z%%M% %I% %E% SMI" - /* * The contents of this file are subject to the Netscape Public @@ -805,6 +805,16 @@ unescape_filterval( char *val ) for ( s = d = val; *s; s++ ) { if ( escape ) { /* + * need to leave escaped comma as-is, i.e. + * val="CN=Last\, First,OU=..." + */ + if (*s == ',') { + *d++ = '\\'; + *d++ = *s; + escape = 0; + continue; + } + /* * first try LDAPv3 escape (hexadecimal) sequence */ if (( ival = hexchar2int( *s )) < 0 ) { diff --git a/usr/src/lib/libsldap/common/mapfile-vers b/usr/src/lib/libsldap/common/mapfile-vers index 8c88eb55bb..542afde60c 100644 --- a/usr/src/lib/libsldap/common/mapfile-vers +++ b/usr/src/lib/libsldap/common/mapfile-vers @@ -20,6 +20,7 @@ # # # Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved. +# Copyright 2017 Nexenta Systems, Inc. All rights reserved. # # @@ -48,6 +49,7 @@ SYMBOL_VERSION SUNWprivate_1.1 { __ns_ldap_check_all_preq; __ns_ldap_check_dns_preq; __ns_ldap_check_gssapi_preq; + __ns_ldap_dn2uid; __ns_ldap_getAcctMgmt; __ns_ldap_getAttrStruct; __ns_ldap_getConnectionInfoFromDUA; diff --git a/usr/src/lib/libsldap/common/ns_connmgmt.c b/usr/src/lib/libsldap/common/ns_connmgmt.c index 1bacf7fdd8..975d5ad079 100755..100644 --- a/usr/src/lib/libsldap/common/ns_connmgmt.c +++ b/usr/src/lib/libsldap/common/ns_connmgmt.c @@ -21,10 +21,10 @@ /* * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. + * + * Copyright 2017 Nexenta Systems, Inc. All rights reserved. */ -#pragma ident "%Z%%M% %I% %E% SMI" - #include <string.h> #include <errno.h> #include <syslog.h> diff --git a/usr/src/lib/libsldap/common/ns_connmgmt.h b/usr/src/lib/libsldap/common/ns_connmgmt.h index bb7849bf86..5d4040a95b 100755..100644 --- a/usr/src/lib/libsldap/common/ns_connmgmt.h +++ b/usr/src/lib/libsldap/common/ns_connmgmt.h @@ -21,14 +21,13 @@ /* * Copyright 2008 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. + * + * Copyright 2017 Nexenta Systems, Inc. All rights reserved. */ - #ifndef _NS_CONNMGMT_H #define _NS_CONNMGMT_H -#pragma ident "%Z%%M% %I% %E% SMI" - #ifdef __cplusplus extern "C" { #endif diff --git a/usr/src/lib/libsldap/common/ns_internal.h b/usr/src/lib/libsldap/common/ns_internal.h index bc46e6df6e..9a7e076c5a 100644 --- a/usr/src/lib/libsldap/common/ns_internal.h +++ b/usr/src/lib/libsldap/common/ns_internal.h @@ -21,6 +21,7 @@ /* * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright 2017 Nexenta Systems, Inc. All rights reserved. */ @@ -63,9 +64,12 @@ extern "C" { #define CREDFILE 0 #define CONFIGFILE 1 #define UIDNUMFILTER "(&(objectclass=posixAccount)(uidnumber=%s))" -#define UIDNUMFILTER_SSD "(&(%%s)(uidnumber=%s))" +#define UIDNUMFILTER_SSD "(&(%%s)(uidnumber=%s))" #define UIDFILTER "(&(objectclass=posixAccount)(uid=%s))" #define UIDFILTER_SSD "(&(%%s)(uid=%s))" +#define UIDDNFILTER "(&(objectclass=posixAccount)(distinguishedName=%s))" +#define UIDDNFILTER_SSD "(&(%%s)(distinguishedName=%s))" + #define HOSTFILTER "(&(objectclass=ipHost)(cn=%s))" #define HOSTFILTER_SSD "(&(%%s)(cn=%s))" @@ -455,7 +459,7 @@ typedef struct ns_default_config { ns_conftype_t config_type; /* CLIENT/SERVER/CREDCONFIG */ ns_datatype_t data_type; /* ppc,pi,pc,int etc... */ int single_valued; /* TRUE OR FALSE */ - ns_version_t version; /* Version # for attribute */ + ns_version_t version; /* Version # for attribute */ const char *profile_name; /* profile schema attribute name */ ns_param_t defval; /* config file parameter default */ int (*ns_verify)(ParamIndexType i, @@ -579,7 +583,7 @@ typedef struct connection { LDAP *ld; thread_t threadID; /* thread ID using it */ struct ns_ldap_cookie *cookieInfo; - char **controls; /* from server_info */ + char **controls; /* from server_info */ char **saslMechanisms; /* from server_info */ } Connection; @@ -626,7 +630,7 @@ typedef struct ns_ldap_cookie { /* search filter callback */ int use_filtercb; - int (*init_filter_cb)(const ns_ldap_search_desc_t *desc, + int (*init_filter_cb)(const ns_ldap_search_desc_t *desc, char **realfilter, const void *userdata); /* user callback */ @@ -642,7 +646,7 @@ typedef struct ns_ldap_cookie { const char * const *i_attr; const char *i_sortattr; const ns_cred_t *i_auth; - int i_flags; + int i_flags; /* OUTPUTS */ ns_ldap_result_t *result; @@ -679,12 +683,12 @@ typedef struct ns_ldap_cookie { char **dns; char *currentdn; int flag; - struct berval *ctrlCookie; + struct berval *ctrlCookie; /* REFERRALS PROCESSING */ /* referralinfo list & position */ - ns_referral_info_t *reflist; - ns_referral_info_t *refpos; + ns_referral_info_t *reflist; + ns_referral_info_t *refpos; /* search timeout value */ struct timeval search_timeout; /* response control to hold account management information */ @@ -713,7 +717,7 @@ typedef struct ns_ldap_cookie { typedef struct ns_server_info { char *server; char *serverFQDN; - char **controls; + char **controls; char **saslMechanisms; } ns_server_info_t; @@ -873,7 +877,7 @@ __ns_ldap_check_all_preq(int foreground, ns_ldap_error_t **errpp); /* internal un-exposed APIs */ -ns_cred_t *__ns_ldap_dupAuth(const ns_cred_t *authp); +ns_cred_t *__ns_ldap_dupAuth(const ns_cred_t *authp); boolean_t __s_api_is_auth_matched(const ns_cred_t *auth1, const ns_cred_t *auth2); int __s_api_get_SSD_from_SSDtoUse_service(const char *service, @@ -901,10 +905,10 @@ void __s_api_free_server_info(ns_server_info_t *sinfo); void __s_api_freeConnection(Connection *con); /* internal referrals APIs */ -int __s_api_toFollowReferrals(const int flags, +int __s_api_toFollowReferrals(const int flags, int *toFollow, ns_ldap_error_t **errorp); -int __s_api_addRefInfo(ns_referral_info_t **head, +int __s_api_addRefInfo(ns_referral_info_t **head, char *url, char *baseDN, int *scope, char *filter, LDAP *ld); void __s_api_deleteRefInfo(ns_referral_info_t *head); diff --git a/usr/src/lib/libsldap/common/ns_reads.c b/usr/src/lib/libsldap/common/ns_reads.c index 726aea2bc1..83e93cd3d0 100644 --- a/usr/src/lib/libsldap/common/ns_reads.c +++ b/usr/src/lib/libsldap/common/ns_reads.c @@ -20,6 +20,7 @@ */ /* * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright 2017 Nexenta Systems, Inc. All rights reserved. */ #include <stdio.h> @@ -227,7 +228,8 @@ _cvtDN(const char *service, const char *dn) { if ((rdns = ldap_explode_dn(dn, 0)) == NULL) return (NULL); - for (nRdn = 0; rdns[nRdn] != NULL; nRdn++); + for (nRdn = 0; rdns[nRdn] != NULL; nRdn++) + ; if ((mapped_rdns = (char **)calloc(nRdn, sizeof (char *))) == NULL) { ldap_value_free(rdns); @@ -4231,6 +4233,85 @@ __ns_ldap_uid2dn(const char *uid, return (NS_LDAP_SUCCESS); } +#define _P_UID "uid" +static const char *dn2uid_attrs[] = { + _P_CN, + _P_UID, + (char *)NULL +}; + +/*ARGSUSED*/ +int +__ns_ldap_dn2uid(const char *dn, + char **userID, + const ns_cred_t *cred, /* cred is ignored */ + ns_ldap_error_t **errorp) +{ + ns_ldap_result_t *result = NULL; + char *filter, *userdata; + char errstr[MAXERROR]; + char **value; + int rc = 0; + size_t len; + + *errorp = NULL; + *userID = NULL; + if ((dn == NULL) || (dn[0] == '\0')) + return (NS_LDAP_INVALID_PARAM); + + len = strlen(UIDDNFILTER) + strlen(dn) + 1; + filter = (char *)malloc(len); + if (filter == NULL) { + return (NS_LDAP_MEMORY); + } + (void) snprintf(filter, len, UIDDNFILTER, dn); + + len = strlen(UIDDNFILTER_SSD) + strlen(dn) + 1; + userdata = (char *)malloc(len); + if (userdata == NULL) { + return (NS_LDAP_MEMORY); + } + (void) snprintf(userdata, len, UIDDNFILTER_SSD, dn); + + /* + * Unlike uid2dn, we DO want attribute mapping, so that + * "uid" is mapped to/from samAccountName, for example. + */ + rc = __ns_ldap_list("passwd", filter, + __s_api_merge_SSD_filter, + dn2uid_attrs, cred, 0, + &result, errorp, NULL, + userdata); + free(filter); + filter = NULL; + free(userdata); + userdata = NULL; + if (rc != NS_LDAP_SUCCESS) + goto out; + + if (result->entries_count > 1) { + (void) sprintf(errstr, + gettext("Too many entries are returned for %s"), dn); + MKERROR(LOG_WARNING, *errorp, NS_LDAP_INTERNAL, strdup(errstr), + NULL); + rc = NS_LDAP_INTERNAL; + goto out; + } + + value = __ns_ldap_getAttr(result->entry, _P_UID); + if (value == NULL || value[0] == NULL) { + rc = NS_LDAP_NOTFOUND; + goto out; + } + + *userID = strdup(value[0]); + rc = NS_LDAP_SUCCESS; + +out: + (void) __ns_ldap_freeResult(&result); + result = NULL; + return (rc); +} /*ARGSUSED*/ int diff --git a/usr/src/lib/libsldap/common/ns_sldap.h b/usr/src/lib/libsldap/common/ns_sldap.h index 7d27d20371..fbee323739 100644 --- a/usr/src/lib/libsldap/common/ns_sldap.h +++ b/usr/src/lib/libsldap/common/ns_sldap.h @@ -20,6 +20,7 @@ */ /* * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright 2017 Nexenta Systems, Inc. All rights reserved. */ @@ -814,6 +815,12 @@ int __ns_ldap_uid2dn( const ns_cred_t *cred, ns_ldap_error_t ** errorp); +int __ns_ldap_dn2uid( + const char *dn, + char **userID, + const ns_cred_t *cred, + ns_ldap_error_t ** errorp); + int __ns_ldap_host2dn( const char *host, const char *domain, diff --git a/usr/src/lib/nsswitch/ldap/common/getgrent.c b/usr/src/lib/nsswitch/ldap/common/getgrent.c index 291d16dbc6..e65a741efe 100644 --- a/usr/src/lib/nsswitch/ldap/common/getgrent.c +++ b/usr/src/lib/nsswitch/ldap/common/getgrent.c @@ -37,36 +37,41 @@ #define _G_NAME "cn" #define _G_GID "gidnumber" #define _G_PASSWD "userpassword" -#define _G_MEM "memberuid" +#define _G_MEMUID "memberuid" +#define _G_MEM_DN "member" /* DN */ #define _F_GETGRNAM "(&(objectClass=posixGroup)(cn=%s))" #define _F_GETGRNAM_SSD "(&(%%s)(cn=%s))" #define _F_GETGRGID "(&(objectClass=posixGroup)(gidNumber=%u))" #define _F_GETGRGID_SSD "(&(%%s)(gidNumber=%u))" -/* - * Group membership can be defined by either username or DN, so when searching - * for groups by member we need to consider both. The first parameter in the - * filter is replaced by username, the second by DN. - */ -#define _F_GETGRMEM \ - "(&(objectClass=posixGroup)(|(memberUid=%s)(memberUid=%s)))" -#define _F_GETGRMEM_SSD "(&(%%s)(|(memberUid=%s)(memberUid=%s)))" /* - * Copied from getpwnam.c, needed to look up user DN. - * Would it be better to move to ldap_common.h rather than duplicate? + * When searching for groups in which a specified user is a member, + * there are a few different membership schema that might be in use. + * We'll use a filter that should work with an of the common ones: + * "memberUid=NAME", or "member=DN" (try uniquemember too?) + * The first parameter in the filter string is replaced by username, + * and the remaining ones by the full DN. */ -#define _F_GETPWNAM "(&(objectClass=posixAccount)(uid=%s))" -#define _F_GETPWNAM_SSD "(&(%%s)(uid=%s))" +#define _F_GETGRMEM "(&(objectClass=posixGroup)" \ + "(|(memberUid=%s)(member=%s)))" +#define _F_GETGRMEM_SSD "(&(%%s)" \ + "(|(memberUid=%s)(member=%s)))" static const char *gr_attrs[] = { _G_NAME, _G_GID, _G_PASSWD, - _G_MEM, + _G_MEMUID, + _G_MEM_DN, (char *)NULL }; +static int +getmembers_UID(char **bufpp, int *lenp, ns_ldap_attr_t *members); +static int +getmembers_DN(char **bufpp, int *lenp, ns_ldap_attr_t *members); + /* * _nss_ldap_group2str is the data marshaling method for the group getXbyY @@ -85,13 +90,11 @@ _nss_ldap_group2str(ldap_backend_ptr be, nss_XbyY_args_t *argp) int i; int nss_result; int buflen = 0, len; - int firstime = 1; char *buffer = NULL; ns_ldap_result_t *result = be->result; char **gname, **passwd, **gid, *password, *end; char gid_nobody[NOBODY_STR_LEN]; char *gid_nobody_v[1]; - char *member_str, *strtok_state; ns_ldap_attr_t *members; (void) snprintf(gid_nobody, sizeof (gid_nobody), "%u", GID_NOBODY); @@ -146,48 +149,20 @@ _nss_ldap_group2str(ldap_backend_ptr be, nss_XbyY_args_t *argp) len = snprintf(buffer, buflen, "%s:%s:%s:", gname[0], password, gid[0]); TEST_AND_ADJUST(len, buffer, buflen, result_grp2str); - members = __ns_ldap_getAttrStruct(result->entry, _G_MEM); - if (members == NULL || members->attrvalue == NULL) { - /* no member is fine, skip processing the member list */ - goto nomember; + members = __ns_ldap_getAttrStruct(result->entry, _G_MEMUID); + if (members != NULL && members->attrvalue != NULL) { + nss_result = getmembers_UID(&buffer, &buflen, members); + if (nss_result != 0) + goto result_grp2str; } - for (i = 0; i < members->value_count; i++) { - if (members->attrvalue[i] == NULL) { - nss_result = NSS_STR_PARSE_PARSE; + members = __ns_ldap_getAttrStruct(result->entry, _G_MEM_DN); + if (members != NULL && members->attrvalue != NULL) { + nss_result = getmembers_DN(&buffer, &buflen, members); + if (nss_result != 0) goto result_grp2str; - } - /* - * If we find an '=' in the member attribute value, treat it as - * a DN, otherwise as a username. - */ - if (member_str = strchr(members->attrvalue[i], '=')) { - member_str++; /* skip over the '=' */ - /* Fail if we can't pull a username out of the RDN */ - if (! (member_str = strtok_r(member_str, - ",", &strtok_state))) { - nss_result = NSS_STR_PARSE_PARSE; - goto result_grp2str; - } - } else { - member_str = members->attrvalue[i]; - } - if (*member_str != '\0') { - if (firstime) { - len = snprintf(buffer, buflen, "%s", - member_str); - TEST_AND_ADJUST(len, buffer, buflen, - result_grp2str); - firstime = 0; - } else { - len = snprintf(buffer, buflen, ",%s", - member_str); - TEST_AND_ADJUST(len, buffer, buflen, - result_grp2str); - } - } } -nomember: + /* The front end marshaller doesn't need the trailing nulls */ if (argp->buf.result != NULL) be->buflen = strlen(be->buffer); @@ -197,6 +172,128 @@ result_grp2str: } /* + * Process the list values from the "memberUid" attribute of the + * current group. Note that this list is often empty, and we + * get the real list of members via getmember_DN (see below). + */ +static int +getmembers_UID(char **bufpp, int *lenp, ns_ldap_attr_t *members) +{ + char *member_str, *strtok_state; + char *buffer; + int buflen; + int i, len; + int nss_result = 0; + int firsttime; + + buffer = *bufpp; + buflen = *lenp; + firsttime = (buffer[-1] == ':'); + + for (i = 0; i < members->value_count; i++) { + member_str = members->attrvalue[i]; + if (member_str == NULL) + goto out; + +#ifdef DEBUG + (void) fprintf(stdout, "getmembers_UID: uid=<%s>\n", + member_str); +#endif + /* + * If not a valid Unix user name, or + * not valid in ldap, just skip. + */ + if (member_str[0] == '\0' || + strpbrk(member_str, " ,:=") != NULL) + continue; + + if (firsttime) + len = snprintf(buffer, buflen, "%s", member_str); + else + len = snprintf(buffer, buflen, ",%s", member_str); + TEST_AND_ADJUST(len, buffer, buflen, out); + } + +out: + *bufpp = buffer; + *lenp = buflen; + return (nss_result); +} + +/* + * Process the list values from the "member" attribute of the + * current group. Note that this list is ONLY one that can be + * assumed to be non-empty. The problem here is that this list + * contains the list of members as "distinguished names" (DN), + * and we want the Unix names (known here as "uid"). We must + * lookup the "uid" for each DN in the member list. Example: + * CN=Doe\, John,OU=Users,DC=contoso,DC=com => john.doe + */ +static int +getmembers_DN(char **bufpp, int *lenp, ns_ldap_attr_t *members) +{ + ns_ldap_error_t *error = NULL; + char *member_dn, *member_uid; + char *buffer; + int buflen; + int i, len; + int nss_result = 0; + int firsttime; + + buffer = *bufpp; + buflen = *lenp; + firsttime = (buffer[-1] == ':'); + + for (i = 0; i < members->value_count; i++) { + member_dn = members->attrvalue[i]; + if (member_dn == NULL) + goto out; + + /* + * The attribute name was "member", so these should be + * full distinguished names (DNs). We need to loookup + * the Unix UID (name) for each. + */ +#ifdef DEBUG + (void) fprintf(stdout, "getmembers_DN: dn=%s\n", + member_dn); +#endif + if (member_dn[0] == '\0') + continue; + + nss_result = __ns_ldap_dn2uid(member_dn, + &member_uid, NULL, &error); + if (nss_result != NS_LDAP_SUCCESS) { + (void) __ns_ldap_freeError(&error); + error = NULL; + continue; + } +#ifdef DEBUG + (void) fprintf(stdout, "getmembers_DN: uid=<%s>\n", + member_uid); +#endif + /* Skip invalid names. */ + if (member_uid[0] == '\0' || + strpbrk(member_uid, " ,:=") != NULL) { + free(member_uid); + continue; + } + + if (firsttime) + len = snprintf(buffer, buflen, "%s", member_uid); + else + len = snprintf(buffer, buflen, ",%s", member_uid); + free(member_uid); + TEST_AND_ADJUST(len, buffer, buflen, out); + } + +out: + *bufpp = buffer; + *lenp = buflen; + return (nss_result); +} + +/* * getbynam gets a group entry by name. This function constructs an ldap * search filter using the name invocation parameter and the getgrnam search * filter defined. Once the filter is constructed, we searche for a matching @@ -267,6 +364,18 @@ getbygid(ldap_backend_ptr be, void *a) /* + * Use a custom attributes list for getbymember, because the LDAP + * query for this requests a list of groups, and the result can be + * very large if it includes the list of members with each group. + * We don't need or want the list of members in this case. + */ +static const char *grbymem_attrs[] = { + _G_NAME, /* cn */ + _G_GID, /* gidnumber */ + (char *)NULL +}; + +/* * getbymember returns all groups a user is defined in. This function * uses different architectural procedures than the other group backend * system calls because it's a private interface. This function constructs @@ -284,20 +393,21 @@ getbygid(ldap_backend_ptr be, void *a) static nss_status_t getbymember(ldap_backend_ptr be, void *a) { + ns_ldap_error_t *error = NULL; int i, j, k; int gcnt = (int)0; - char **groupvalue, **membervalue, *member_str; - char *strtok_state; + char **groupvalue; nss_status_t lstat; struct nss_groupsbymem *argp = (struct nss_groupsbymem *)a; char searchfilter[SEARCHFILTERLEN]; char userdata[SEARCHFILTERLEN]; char name[SEARCHFILTERLEN]; + char escdn[SEARCHFILTERLEN]; ns_ldap_result_t *result; ns_ldap_entry_t *curEntry; - char *username, **dn_attr, *dn; + char *dn; gid_t gid; - int ret; + int ret1, ret2; if (strcmp(argp->username, "") == 0 || strcmp(argp->username, "root") == 0) @@ -306,101 +416,82 @@ getbymember(ldap_backend_ptr be, void *a) if (_ldap_filter_name(name, argp->username, sizeof (name)) != 0) return ((nss_status_t)NSS_NOTFOUND); - ret = snprintf(searchfilter, sizeof (searchfilter), _F_GETPWNAM, name); - if (ret >= sizeof (searchfilter) || ret < 0) - return ((nss_status_t)NSS_NOTFOUND); - - ret = snprintf(userdata, sizeof (userdata), _F_GETPWNAM_SSD, name); - if (ret >= sizeof (userdata) || ret < 0) - return ((nss_status_t)NSS_NOTFOUND); - /* * Look up the user DN in ldap. If it's not found, search solely by * username. */ - lstat = (nss_status_t)_nss_ldap_nocb_lookup(be, NULL, - _PASSWD, searchfilter, NULL, _merge_SSD_filter, userdata); - if (lstat != (nss_status_t)NS_LDAP_SUCCESS) - return ((nss_status_t)lstat); - - if (be->result == NULL || - !(dn_attr = __ns_ldap_getAttr(be->result->entry, "dn"))) + lstat = __ns_ldap_uid2dn(name, &dn, NULL, &error); + if (lstat != (nss_status_t)NS_LDAP_SUCCESS) { + /* Can't get DN. Use bare name */ + (void) __ns_ldap_freeError(&error); dn = name; - else - dn = dn_attr[0]; + } + /* Note: must free dn if != name */ - ret = snprintf(searchfilter, sizeof (searchfilter), _F_GETGRMEM, name, - dn); - if (ret >= sizeof (searchfilter) || ret < 0) + /* + * Compose filter patterns + */ + ret1 = snprintf(searchfilter, sizeof (searchfilter), + _F_GETGRMEM, name, dn); + ret2 = snprintf(userdata, sizeof (userdata), + _F_GETGRMEM_SSD, name, dn); + if (dn != name) + free(dn); + if (ret1 >= sizeof (searchfilter) || ret1 < 0) return ((nss_status_t)NSS_NOTFOUND); - - ret = snprintf(userdata, sizeof (userdata), _F_GETGRMEM_SSD, name, - dn); - if (ret >= sizeof (userdata) || ret < 0) + if (ret2 >= sizeof (userdata) || ret2 < 0) return ((nss_status_t)NSS_NOTFOUND); /* - * Free up resources from user DN search before performing group - * search. + * Query for groups matching the filter. */ - (void) __ns_ldap_freeResult((ns_ldap_result_t **)&be->result); - - gcnt = (int)argp->numgids; lstat = (nss_status_t)_nss_ldap_nocb_lookup(be, NULL, - _GROUP, searchfilter, NULL, _merge_SSD_filter, userdata); + _GROUP, searchfilter, grbymem_attrs, + _merge_SSD_filter, userdata); if (lstat != (nss_status_t)NS_LDAP_SUCCESS) return ((nss_status_t)lstat); if (be->result == NULL) return (NSS_NOTFOUND); - username = (char *)argp->username; + + /* + * Walk the query result, collecting GIDs. + */ result = (ns_ldap_result_t *)be->result; curEntry = (ns_ldap_entry_t *)result->entry; - for (i = 0; i < result->entries_count && curEntry != NULL; i++) { - membervalue = __ns_ldap_getAttr(curEntry, "memberUid"); - if (membervalue == NULL) { - curEntry = curEntry->next; - continue; + gcnt = (int)argp->numgids; + for (i = 0; i < result->entries_count; i++) { + + /* + * Does this group have a gidNumber attr? + */ + groupvalue = __ns_ldap_getAttr(curEntry, _G_GID); + if (groupvalue == NULL || groupvalue[0] == NULL) { + /* Drop this group from the list */ + goto next_group; } - for (j = 0; membervalue[j]; j++) { - /* - * If we find an '=' in the member attribute - * value, treat it as a DN, otherwise as a - * username. - */ - if (member_str = strchr(membervalue[j], '=')) { - member_str++; /* skip over the '=' */ - member_str = strtok_r(member_str, ",", - &strtok_state); - } else { - member_str = membervalue[j]; - } - if (member_str != NULL && - strcmp(member_str, username) == 0) { - groupvalue = __ns_ldap_getAttr(curEntry, - "gidnumber"); - if (groupvalue == NULL || - groupvalue[0] == NULL) { - /* Drop this group from the list */ - break; - } - errno = 0; - gid = (gid_t)strtol(groupvalue[0], - (char **)NULL, 10); - - if (errno == 0 && - argp->numgids < argp->maxgids) { - for (k = 0; k < argp->numgids; k++) { - if (argp->gid_array[k] == gid) - /* already exists */ - break; - } - if (k == argp->numgids) - argp->gid_array[argp->numgids++] - = gid; + + /* + * Convert it to a numeric GID + */ + errno = 0; + gid = (gid_t)strtol(groupvalue[0], (char **)NULL, 10); + if (errno != 0) + goto next_group; + + /* + * If we don't already have this GID, add it. + */ + if (argp->numgids < argp->maxgids) { + for (k = 0; k < argp->numgids; k++) { + if (argp->gid_array[k] == gid) { + /* already have it */ + goto next_group; } - break; } + argp->gid_array[argp->numgids++] = gid; } + + next_group: curEntry = curEntry->next; } @@ -431,7 +522,7 @@ static ldap_backend_op_t gr_ops[] = { /*ARGSUSED0*/ nss_backend_t * _nss_ldap_group_constr(const char *dummy1, const char *dummy2, - const char *dummy3) + const char *dummy3) { return ((nss_backend_t *)_nss_ldap_constr(gr_ops, diff --git a/usr/src/lib/nsswitch/ldap/common/ldap_common.c b/usr/src/lib/nsswitch/ldap/common/ldap_common.c index c4103ef03e..f654580e56 100644 --- a/usr/src/lib/nsswitch/ldap/common/ldap_common.c +++ b/usr/src/lib/nsswitch/ldap/common/ldap_common.c @@ -20,6 +20,7 @@ */ /* * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright 2017 Nexenta Systems, Inc. All rights reserved. */ #include "ldap_common.h" @@ -246,7 +247,7 @@ error_out: /* ARGSUSED */ nss_status_t _nss_ldap_nocb_lookup(ldap_backend_ptr be, nss_XbyY_args_t *argp, - char *database, char *searchfilter, char *domain, + char *database, char *searchfilter, const char * const *attrs, int (*init_filter_cb)(const ns_ldap_search_desc_t *desc, char **realfilter, const void *userdata), const void *userdata) @@ -254,6 +255,9 @@ _nss_ldap_nocb_lookup(ldap_backend_ptr be, nss_XbyY_args_t *argp, ns_ldap_error_t *error = NULL; int rc; + if (attrs == NULL) + attrs = be->attrs; + #ifdef DEBUG (void) fprintf(stdout, "\n[ldap_common.c: _nss_ldap_nocb_lookup]\n"); (void) fprintf(stdout, "\tsearchfilter: %s\n", searchfilter); @@ -265,7 +269,7 @@ _nss_ldap_nocb_lookup(ldap_backend_ptr be, nss_XbyY_args_t *argp, (void) __ns_ldap_freeResult(&be->result); if ((rc = __ns_ldap_list(database, searchfilter, init_filter_cb, - be->attrs, NULL, 0, &be->result, &error, NULL, + attrs, NULL, 0, &be->result, &error, NULL, userdata)) != NS_LDAP_SUCCESS) { if (argp != NULL) argp->returnval = 0; diff --git a/usr/src/lib/nsswitch/ldap/common/ldap_common.h b/usr/src/lib/nsswitch/ldap/common/ldap_common.h index 690dd15adc..29f18f1160 100644 --- a/usr/src/lib/nsswitch/ldap/common/ldap_common.h +++ b/usr/src/lib/nsswitch/ldap/common/ldap_common.h @@ -20,6 +20,7 @@ */ /* * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved. + * Copyright 2017 Nexenta Systems, Inc. All rights reserved. */ #ifndef _LDAP_COMMON_H @@ -139,7 +140,7 @@ nss_backend_t *_nss_ldap_constr(ldap_backend_op_t ops[], int nops, char *tablename, const char **attrs, fnf ldapobj2str); extern nss_status_t _nss_ldap_nocb_lookup(ldap_backend_ptr be, nss_XbyY_args_t *argp, char *database, - char *searchfilter, char *domain, + char *searchfilter, const char * const *attrs, int (*init_filter_cb)( const ns_ldap_search_desc_t *desc, char **realfilter, const void *userdata), diff --git a/usr/src/uts/common/fs/zfs/metaslab.c b/usr/src/uts/common/fs/zfs/metaslab.c index 62a7825d16..4bea7c47c4 100644 --- a/usr/src/uts/common/fs/zfs/metaslab.c +++ b/usr/src/uts/common/fs/zfs/metaslab.c @@ -1066,7 +1066,7 @@ metaslab_group_fragmentation(metaslab_group_t *mg) */ static boolean_t metaslab_group_allocatable(metaslab_group_t *mg, metaslab_group_t *rotor, - uint64_t psize, int allocator) + uint64_t psize, int allocator, int d) { spa_t *spa = mg->mg_vd->vdev_spa; metaslab_class_t *mc = mg->mg_class; @@ -1110,6 +1110,13 @@ metaslab_group_allocatable(metaslab_group_t *mg, metaslab_group_t *rotor, if (mg->mg_no_free_space) return (B_FALSE); + /* + * Relax allocation throttling for ditto blocks. Due to + * random imbalances in allocation it tends to push copies + * to one vdev, that looks a bit better at the moment. + */ + qmax = qmax * (4 + d) / 4; + qdepth = zfs_refcount_count( &mg->mg_alloc_queue_depth[allocator]); @@ -1131,7 +1138,7 @@ metaslab_group_allocatable(metaslab_group_t *mg, metaslab_group_t *rotor, */ for (mgp = mg->mg_next; mgp != rotor; mgp = mgp->mg_next) { qmax = mgp->mg_cur_max_alloc_queue_depth[allocator]; - + qmax = qmax * (4 + d) / 4; qdepth = zfs_refcount_count( &mgp->mg_alloc_queue_depth[allocator]); @@ -3789,7 +3796,7 @@ top: */ if (allocatable && !GANG_ALLOCATION(flags) && !try_hard) { allocatable = metaslab_group_allocatable(mg, rotor, - psize, allocator); + psize, allocator, d); } if (!allocatable) { |