diff options
author | djl <none@none> | 2006-09-29 06:00:17 -0700 |
---|---|---|
committer | djl <none@none> | 2006-09-29 06:00:17 -0700 |
commit | cb5caa98562cf06753163f558cbcfe30b8f4673a (patch) | |
tree | 7a24623821583899295e29553207e69701b471ff /usr/src/lib/nsswitch/ldap/common | |
parent | 350f572a3fa518fc3690d53066c2c54fd03b5a08 (diff) | |
download | illumos-joyent-cb5caa98562cf06753163f558cbcfe30b8f4673a.tar.gz |
PSARC 2005/133 Sparks: Name Service Switch 2
4406529 artificial limit of 10 threads per backend
4516075 LDAP connections could be reused more
4696964 LDAP naming services should support Kerberos authentication
4740951 Need host based authentication options in Native LDAP
4952533 Some backends of gethostby* do not set h_errno correctly
4979596 getXbyY calls should have better buffer mechanism
5028908 /usr/bin/logins accesses free memory deep in nss_getent_u().
5046881 nscd: old-data-ok parameter is not useful, should go away
6225323 NSS/nscd Enhancements (Sparks Project)
--HG--
rename : usr/src/cmd/nscd/attrstr.c => deleted_files/usr/src/cmd/nscd/attrstr.c
rename : usr/src/cmd/nscd/hash.c => deleted_files/usr/src/cmd/nscd/hash.c
rename : usr/src/cmd/nscd/nscd_parse.c => deleted_files/usr/src/cmd/nscd/nscd_parse.c
rename : usr/src/cmd/nscd/nscd.h => usr/src/cmd/nscd/cache.h
Diffstat (limited to 'usr/src/lib/nsswitch/ldap/common')
25 files changed, 2003 insertions, 3104 deletions
diff --git a/usr/src/lib/nsswitch/ldap/common/getauthattr.c b/usr/src/lib/nsswitch/ldap/common/getauthattr.c index ea3341bf57..7b7b0c38b2 100644 --- a/usr/src/lib/nsswitch/ldap/common/getauthattr.c +++ b/usr/src/lib/nsswitch/ldap/common/getauthattr.c @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -20,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2003 Sun Microsystems, Inc. All rights reserved. + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -51,170 +50,94 @@ static const char *auth_attrs[] = { _AUTH_ATTRS, (char *)NULL }; - - +/* + * _nss_ldap_auth2str is the data marshaling method for the auth_attr + * system call getauthattr and getauthnam. + * This method is called after a successful search has been performed. + * This method will parse the search results into the file format. + * e.g. + * + * solaris.:::All Solaris Authorizations::help=AllSolAuthsHeader.html + * + */ static int -_nss_ldap_auth2ent(ldap_backend_ptr be, nss_XbyY_args_t *argp) +_nss_ldap_auth2str(ldap_backend_ptr be, nss_XbyY_args_t *argp) { - int i, nss_result; - int buflen = (int)0; + int nss_result; + int buflen = 0; unsigned long len = 0L; - char *nullstring = (char *)NULL; - char *buffer = (char *)NULL; - char *ceiling = (char *)NULL; - authstr_t *auth = (authstr_t *)NULL; - ns_ldap_attr_t *attrptr; + char *buffer = NULL; ns_ldap_result_t *result = be->result; + char **name, **res1, **res2, **sdes, **ldes, **attr; + char *res1_str, *res2_str, *sdes_str, *ldes_str; + char *attr_str; - buffer = argp->buf.buffer; - buflen = (size_t)argp->buf.buflen; - if (!argp->buf.result) { - nss_result = (int)NSS_STR_PARSE_ERANGE; - goto result_auth2ent; - } - auth = (authstr_t *)(argp->buf.result); - ceiling = buffer + buflen; - auth->name = (char *)NULL; - auth->res1 = (char *)NULL; - auth->res2 = (char *)NULL; - auth->short_desc = (char *)NULL; - auth->long_desc = (char *)NULL; - auth->attr = (char *)NULL; - nss_result = (int)NSS_STR_PARSE_SUCCESS; - (void) memset(argp->buf.buffer, 0, buflen); - - attrptr = getattr(result, 0); - if (attrptr == NULL) { - nss_result = (int)NSS_STR_PARSE_PARSE; - goto result_auth2ent; - } + if (result == NULL) + return (NSS_STR_PARSE_PARSE); - for (i = 0; i < result->entry->attr_count; i++) { - attrptr = getattr(result, i); - if (attrptr == NULL) { - nss_result = (int)NSS_STR_PARSE_PARSE; - goto result_auth2ent; - } - if (strcasecmp(attrptr->attrname, _AUTH_NAME) == 0) { - if ((attrptr->attrvalue[0] == NULL) || - (len = strlen(attrptr->attrvalue[0])) < 1) { - nss_result = (int)NSS_STR_PARSE_PARSE; - goto result_auth2ent; - } - auth->name = buffer; - buffer += len + 1; - if (buffer >= ceiling) { - nss_result = (int)NSS_STR_PARSE_ERANGE; - goto result_auth2ent; - } - (void) strcpy(auth->name, attrptr->attrvalue[0]); - continue; - } - if (strcasecmp(attrptr->attrname, _AUTH_RES1) == 0) { - if ((attrptr->attrvalue[0] == NULL) || - (len = strlen(attrptr->attrvalue[0])) < 1) { - auth->res1 = nullstring; - } else { - auth->res1 = buffer; - buffer += len + 1; - if (buffer >= ceiling) { - nss_result = (int)NSS_STR_PARSE_ERANGE; - goto result_auth2ent; - } - (void) strcpy(auth->res1, - attrptr->attrvalue[0]); - } - continue; - } - if (strcasecmp(attrptr->attrname, _AUTH_RES2) == 0) { - if ((attrptr->attrvalue[0] == NULL) || - (len = strlen(attrptr->attrvalue[0])) < 1) { - auth->res2 = nullstring; - } else { - auth->res2 = buffer; - buffer += len + 1; - if (buffer >= ceiling) { - nss_result = (int)NSS_STR_PARSE_ERANGE; - goto result_auth2ent; - } - (void) strcpy(auth->res2, - attrptr->attrvalue[0]); - } - continue; - } - if (strcasecmp(attrptr->attrname, _AUTH_SHORTDES) == 0) { - if ((attrptr->attrvalue[0] == NULL) || - (len = strlen(attrptr->attrvalue[0])) < 1) { - auth->short_desc = nullstring; - } else { - auth->short_desc = buffer; - buffer += len + 1; - if (buffer >= ceiling) { - nss_result = (int)NSS_STR_PARSE_ERANGE; - goto result_auth2ent; - } - (void) strcpy(auth->short_desc, - attrptr->attrvalue[0]); - } - continue; - } - if (strcasecmp(attrptr->attrname, _AUTH_LONGDES) == 0) { - if ((attrptr->attrvalue[0] == NULL) || - (len = strlen(attrptr->attrvalue[0])) < 1) { - auth->long_desc = nullstring; - } else { - auth->long_desc = buffer; - buffer += len + 1; - if (buffer >= ceiling) { - nss_result = (int)NSS_STR_PARSE_ERANGE; - goto result_auth2ent; - } - (void) strcpy(auth->long_desc, - attrptr->attrvalue[0]); - } - continue; - } - if (strcasecmp(attrptr->attrname, _AUTH_ATTRS) == 0) { - if ((attrptr->attrvalue[0] == NULL) || - (len = strlen(attrptr->attrvalue[0])) < 1) { - auth->attr = nullstring; - } else { - auth->attr = buffer; - buffer += len + 1; - if (buffer >= ceiling) { - nss_result = (int)NSS_STR_PARSE_ERANGE; - goto result_auth2ent; - } - (void) strcpy(auth->attr, - attrptr->attrvalue[0]); - } - continue; - } - } + buflen = argp->buf.buflen; + nss_result = NSS_STR_PARSE_SUCCESS; + (void) memset(argp->buf.buffer, 0, buflen); -#ifdef DEBUG - (void) fprintf(stdout, "\n[getauthattr.c: _nss_ldap_auth2ent]\n"); - (void) fprintf(stdout, " auth-name: [%s]\n", auth->name); - if (auth->res1 != (char *)NULL) { - (void) fprintf(stdout, " res1: [%s]\n", auth->res1); - } - if (auth->res2 != (char *)NULL) { - (void) fprintf(stdout, " res2: [%s]\n", auth->res2); - } - if (auth->short_desc != (char *)NULL) { - (void) fprintf(stdout, " short_desc: [%s]\n", - auth->short_desc); + name = __ns_ldap_getAttr(result->entry, _AUTH_NAME); + if (name == NULL || name[0] == NULL || + (strlen(name[0]) < 1)) { + nss_result = NSS_STR_PARSE_PARSE; + goto result_auth2str; } - if (auth->long_desc != (char *)NULL) { - (void) fprintf(stdout, " long_desc: [%s]\n", - auth->long_desc); + res1 = __ns_ldap_getAttr(result->entry, _AUTH_RES1); + if (res1 == NULL || res1[0] == NULL || (strlen(res1[0]) < 1)) + res1_str = _NO_VALUE; + else + res1_str = res1[0]; + + res2 = __ns_ldap_getAttr(result->entry, _AUTH_RES2); + if (res2 == NULL || res2[0] == NULL || (strlen(res2[0]) < 1)) + res2_str = _NO_VALUE; + else + res2_str = res2[0]; + + sdes = __ns_ldap_getAttr(result->entry, _AUTH_SHORTDES); + if (sdes == NULL || sdes[0] == NULL || (strlen(sdes[0]) < 1)) + sdes_str = _NO_VALUE; + else + sdes_str = sdes[0]; + + ldes = __ns_ldap_getAttr(result->entry, _AUTH_LONGDES); + if (ldes == NULL || ldes[0] == NULL || (strlen(ldes[0]) < 1)) + ldes_str = _NO_VALUE; + else + ldes_str = ldes[0]; + + attr = __ns_ldap_getAttr(result->entry, _AUTH_ATTRS); + if (attr == NULL || attr[0] == NULL || (strlen(attr[0]) < 1)) + attr_str = _NO_VALUE; + else + attr_str = attr[0]; + /* 6 = 5 ':' + 1 '\0' */ + len = strlen(name[0]) + strlen(res1_str) + strlen(res2_str) + + strlen(sdes_str) + strlen(ldes_str) + strlen(attr_str) + 6; + if (len > buflen) { + nss_result = NSS_STR_PARSE_ERANGE; + goto result_auth2str; } - if (auth->attr != (char *)NULL) { - (void) fprintf(stdout, " attr: [%s]\n", auth->attr); - } -#endif /* DEBUG */ -result_auth2ent: + if (argp->buf.result != NULL) { + if ((be->buffer = calloc(1, len)) == NULL) { + nss_result = NSS_STR_PARSE_PARSE; + goto result_auth2str; + } + buffer = be->buffer; + } else + buffer = argp->buf.buffer; + (void) snprintf(buffer, len, "%s:%s:%s:%s:%s:%s", + name[0], res1_str, res2_str, sdes_str, + ldes_str, attr_str); + /* The front end marshaller doesn't need the trailing null */ + if (argp->buf.result != NULL) + be->buflen = strlen(be->buffer); + +result_auth2str: (void) __ns_ldap_freeResult(&be->result); return ((int)nss_result); } @@ -229,10 +152,6 @@ getbyname(ldap_backend_ptr be, void *a) char name[SEARCHFILTERLEN]; int ret; -#ifdef DEBUG - (void) fprintf(stdout, "\n[getauthattr.c: getbyname]\n"); -#endif /* DEBUG */ - if (_ldap_filter_name(name, argp->key.name, sizeof (name)) != 0) return ((nss_status_t)NSS_NOTFOUND); @@ -268,11 +187,7 @@ _nss_ldap_auth_attr_constr(const char *dummy1, const char *dummy4, const char *dummy5) { -#ifdef DEBUG - (void) fprintf(stdout, - "\n[getauthattr.c: _nss_ldap_auth_attr_constr]\n"); -#endif return ((nss_backend_t *)_nss_ldap_constr(authattr_ops, sizeof (authattr_ops)/sizeof (authattr_ops[0]), _AUTHATTR, - auth_attrs, _nss_ldap_auth2ent)); + auth_attrs, _nss_ldap_auth2str)); } diff --git a/usr/src/lib/nsswitch/ldap/common/getauuser.c b/usr/src/lib/nsswitch/ldap/common/getauuser.c index 2267b22ba9..7c9d9431c5 100644 --- a/usr/src/lib/nsswitch/ldap/common/getauuser.c +++ b/usr/src/lib/nsswitch/ldap/common/getauuser.c @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -20,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2003 Sun Microsystems, Inc. All rights reserved. + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -45,109 +44,73 @@ static const char *auuser_attrs[] = { _AU_NEVER, (char *)NULL }; - - +/* + * _nss_ldap_au2str is the data marshaling method for the audit_user + * system call getauusernam, getauusernam_r, getauuserent and getauuserent_r. + * This method is called after a successful search has been performed. + * This method will parse the search results into the file format. + * e.g. + * + * root:lo:no + * + */ static int -_nss_ldap_au2ent(ldap_backend_ptr be, nss_XbyY_args_t *argp) +_nss_ldap_au2str(ldap_backend_ptr be, nss_XbyY_args_t *argp) { - int i, nss_result; - int buflen = (int)0; + int nss_result; + int buflen = 0; unsigned long len = 0L; - char *nullstring = (char *)NULL; - char *buffer = (char *)NULL; - char *ceiling = (char *)NULL; - au_user_str_t *au_user = (au_user_str_t *)NULL; - ns_ldap_attr_t *attrptr; + char *buffer = NULL; ns_ldap_result_t *result = be->result; + char **name, **al, **ne, *al_str, *ne_str; - buffer = argp->buf.buffer; - buflen = (size_t)argp->buf.buflen; - if (!argp->buf.result) { - nss_result = (int)NSS_STR_PARSE_ERANGE; - goto result_au2ent; - } - au_user = (au_user_str_t *)(argp->buf.result); - ceiling = buffer + buflen; - au_user->au_name = (char *)NULL; - au_user->au_always = (char *)NULL; - au_user->au_never = (char *)NULL; - nss_result = (int)NSS_STR_PARSE_SUCCESS; - (void) memset(argp->buf.buffer, 0, buflen); + if (result == NULL) + return (NSS_STR_PARSE_PARSE); - attrptr = getattr(result, 0); - if (attrptr == NULL) { - nss_result = (int)NSS_STR_PARSE_PARSE; - goto result_au2ent; - } - for (i = 0; i < result->entry->attr_count; i++) { - attrptr = getattr(result, i); - if (attrptr == NULL) { - nss_result = (int)NSS_STR_PARSE_PARSE; - goto result_au2ent; - } - if (strcasecmp(attrptr->attrname, _AU_NAME) == 0) { - if ((attrptr->attrvalue[0] == NULL) || - (len = strlen(attrptr->attrvalue[0])) < 1) { - nss_result = (int)NSS_STR_PARSE_PARSE; - goto result_au2ent; - } - au_user->au_name = buffer; - buffer += len + 1; - if (buffer >= ceiling) { - nss_result = (int)NSS_STR_PARSE_ERANGE; - goto result_au2ent; - } - (void) strcpy(au_user->au_name, attrptr->attrvalue[0]); - continue; - } - if (strcasecmp(attrptr->attrname, _AU_ALWAYS) == 0) { - if ((attrptr->attrvalue[0] == NULL) || - (len = strlen(attrptr->attrvalue[0])) < 1) { - au_user->au_always = nullstring; - } else { - au_user->au_always = buffer; - buffer += len + 1; - if (buffer >= ceiling) { - nss_result = (int)NSS_STR_PARSE_ERANGE; - goto result_au2ent; - } - (void) strcpy(au_user->au_always, - attrptr->attrvalue[0]); - } - continue; - } - if (strcasecmp(attrptr->attrname, _AU_NEVER) == 0) { - if ((attrptr->attrvalue[0] == NULL) || - (len = strlen(attrptr->attrvalue[0])) < 1) { - au_user->au_never = nullstring; - } else { - au_user->au_never = buffer; - buffer += len + 1; - if (buffer >= ceiling) { - nss_result = (int)NSS_STR_PARSE_ERANGE; - goto result_au2ent; - } - (void) strcpy(au_user->au_never, - attrptr->attrvalue[0]); - } - continue; - } - } + buflen = argp->buf.buflen; + nss_result = NSS_STR_PARSE_SUCCESS; + (void) memset(argp->buf.buffer, 0, buflen); -#ifdef DEBUG - (void) fprintf(stdout, "\n[getauuser.c: _nss_ldap_au2ent]\n"); - (void) fprintf(stdout, " au_name: [%s]\n", au_user->au_name); - if (au_user->au_always != (char *)NULL) { - (void) fprintf(stdout, " au_always: [%s]\n", - au_user->au_always); + name = __ns_ldap_getAttr(result->entry, _AU_NAME); + if (name == NULL || name[0] == NULL || + (strlen(name[0]) < 1)) { + nss_result = NSS_STR_PARSE_PARSE; + goto result_au2str; } - if (au_user->au_never != (char *)NULL) { - (void) fprintf(stdout, " au_never: [%s]\n", - au_user->au_never); + al = __ns_ldap_getAttr(result->entry, _AU_ALWAYS); + if (al == NULL || al[0] == NULL || (strlen(al[0]) < 1)) + al_str = _NO_VALUE; + else + al_str = al[0]; + + ne = __ns_ldap_getAttr(result->entry, _AU_NEVER); + if (ne == NULL || ne[0] == NULL || (strlen(ne[0]) < 1)) + ne_str = _NO_VALUE; + else + ne_str = ne[0]; + + /* 3 = 2 ':' + 1 '\0' */ + len = strlen(name[0]) + strlen(al_str) + strlen(ne_str) + 3; + if (len > buflen) { + nss_result = NSS_STR_PARSE_ERANGE; + goto result_au2str; } -#endif /* DEBUG */ -result_au2ent: + if (argp->buf.result != NULL) { + if ((be->buffer = calloc(1, len)) == NULL) { + nss_result = NSS_STR_PARSE_PARSE; + goto result_au2str; + } + buffer = be->buffer; + } else + buffer = argp->buf.buffer; + (void) snprintf(buffer, len, "%s:%s:%s", + name[0], al_str, ne_str); + /* The front end marshaller doesn't need the trailing null */ + if (argp->buf.result != NULL) + be->buflen = strlen(be->buffer); + +result_au2str: (void) __ns_ldap_freeResult(&be->result); return ((int)nss_result); } @@ -162,10 +125,6 @@ getbyname(ldap_backend_ptr be, void *a) nss_XbyY_args_t *argp = (nss_XbyY_args_t *)a; int ret; -#ifdef DEBUG - (void) fprintf(stdout, "\n[getauuser.c: getbyname]\n"); -#endif /* DEBUG */ - if (_ldap_filter_name(name, argp->key.name, sizeof (name)) != 0) return ((nss_status_t)NSS_NOTFOUND); @@ -203,11 +162,7 @@ _nss_ldap_audit_user_constr(const char *dummy1, const char *dummy4, const char *dummy5) { -#ifdef DEBUG - (void) fprintf(stdout, - "\n[getauuser.c: _nss_ldap_audit_user_constr]\n"); -#endif return ((nss_backend_t *)_nss_ldap_constr(auuser_ops, sizeof (auuser_ops)/sizeof (auuser_ops[0]), _AUUSER, - auuser_attrs, _nss_ldap_au2ent)); + auuser_attrs, _nss_ldap_au2str)); } diff --git a/usr/src/lib/nsswitch/ldap/common/getbootparams.c b/usr/src/lib/nsswitch/ldap/common/getbootparams.c index f1426ba4b6..6a5c05d132 100644 --- a/usr/src/lib/nsswitch/ldap/common/getbootparams.c +++ b/usr/src/lib/nsswitch/ldap/common/getbootparams.c @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -20,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2003 Sun Microsystems, Inc. All rights reserved. + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -41,85 +40,83 @@ static const char *bootparams_attrs[] = { }; /* - * _nss_ldap_bootparams2ent is the data marshaling method for the - * bootparams getXbyY (e.g., getbyname()) backend processes. This - * method is called after a successful ldap search has been performed. - * This method will parse the ldap search values into argp->buf.buffer - * Three error conditions are expected and returned to nsswitch. + * _nss_ldap_bootparams2str is the data marshaling method for the + * bootparams bootparams_getbyname backend processes. + * This method is called after a successful ldap search has been performed. + * This method will parse the ldap search values into the file format. * * A host's bootparameters are returned on one line separated by white - * space. Slapd stores each boot parameter as a separate entry. If more - * than one bootparameter is available, a white space separated buffer + * space. The LDAP server stores each boot parameter as a separate entry. + * If more than one bootparameter is available, a white space separated buffer * must be constructed and returned. + * */ static int -_nss_ldap_bootparams2ent(ldap_backend_ptr be, nss_XbyY_args_t *argp) +_nss_ldap_bootparams2str(ldap_backend_ptr be, nss_XbyY_args_t *argp) { - int i, j, nss_result; - int buflen = (int)0; - int firstime = (int)1; - unsigned long len = 0L; - char *cp = (char *)NULL; - char *buffer = (char *)NULL; + uint_t i; + int buflen = 0, len = 0; + int nss_result, firsttime; + ns_ldap_attr_t *bparams; + char *buffer, **names; ns_ldap_result_t *result = be->result; - ns_ldap_attr_t *attrptr; - - buffer = argp->buf.buffer; - buflen = (size_t)argp->buf.buflen; - nss_result = (int)NSS_STR_PARSE_SUCCESS; - (void) memset(buffer, 0, buflen); - - attrptr = getattr(result, 0); - if (attrptr == NULL) { - nss_result = (int)NSS_STR_PARSE_PARSE; - goto result_bp2ent; + if (result == NULL) + return (NSS_STR_PARSE_PARSE); + buflen = argp->buf.buflen; + if (argp->buf.result != NULL) { + if ((be->buffer = calloc(1, buflen)) == NULL) { + nss_result = NSS_STR_PARSE_PARSE; + goto result_bp2str; + } + buffer = be->buffer; + } else + buffer = argp->buf.buffer; + + nss_result = NSS_STR_PARSE_SUCCESS; + (void) memset(argp->buf.buffer, 0, buflen); + + names = __ns_ldap_getAttr(result->entry, _B_HOSTNAME); + if (names == NULL || names[0] == NULL || + (strlen(names[0]) < 1)) { + nss_result = NSS_STR_PARSE_PARSE; + goto result_bp2str; } - - for (i = 0; i < result->entry->attr_count; i++) { - attrptr = getattr(result, i); - if (attrptr == NULL) { - nss_result = (int)NSS_STR_PARSE_PARSE; - goto result_bp2ent; + bparams = __ns_ldap_getAttrStruct(result->entry, _B_PARAMETER); + if (bparams == NULL || bparams->attrvalue == NULL) { + nss_result = NSS_STR_PARSE_PARSE; + goto result_bp2str; + } + firsttime = 1; + for (i = 0; i < bparams->value_count; i++) { + if (bparams->attrvalue[i] == NULL) { + nss_result = NSS_STR_PARSE_PARSE; + goto result_bp2str; } - if (strcasecmp(attrptr->attrname, _B_PARAMETER) == 0) { - for (j = 0; j < attrptr->value_count; j++) { - if ((attrptr->attrvalue[j] == NULL) || - (len = strlen(attrptr->attrvalue[j])) < 1) { - *buffer = 0; - nss_result = (int)NSS_STR_PARSE_PARSE; - goto result_bp2ent; - } - if (len > buflen) { - nss_result = (int)NSS_STR_PARSE_ERANGE; - goto result_bp2ent; - } - if (firstime) { - (void) strcpy(buffer, - attrptr->attrvalue[j]); - firstime = (int)0; - } else { - if ((cp = strrchr(buffer, '\0')) - != NULL) - *cp = ' '; - (void) strcat(buffer, - attrptr->attrvalue[j]); - } - } + /* + * Skip client host name. The early version of ldapaddent + * adds hostname as a boot param and it should be filtered. + */ + if (strcasecmp(names[0], bparams->attrvalue[i]) != 0) { + if (firsttime) { + firsttime = 0; + len = snprintf(buffer, buflen, "%s", + bparams->attrvalue[i]); + } else + len = snprintf(buffer, buflen, " %s", + bparams->attrvalue[i]); + TEST_AND_ADJUST(len, buffer, buflen, result_bp2str); } } + /* The front end marshaller doesn't need to copy trailing nulls */ + if (argp->buf.result != NULL) + be->buflen = strlen(be->buffer); -#ifdef DEBUG - (void) fprintf(stdout, "\n[bootparams_getbyname.c: " - "_nss_ldap_bootparams2ent]\n"); - (void) fprintf(stdout, " bootparameter: [%s]\n", buffer); -#endif /* DEBUG */ - -result_bp2ent: +result_bp2str: (void) __ns_ldap_freeResult(&be->result); - return ((int)nss_result); + return (nss_result); } /* @@ -156,7 +153,6 @@ getbyname(ldap_backend_ptr be, void *a) _F_GETBOOTPARAMBYNAME_SSD, hostname); if (ret >= sizeof (userdata) || ret < 0) return ((nss_status_t)NSS_NOTFOUND); - return ((nss_status_t)_nss_ldap_lookup(be, argp, _BOOTPARAMS, searchfilter, NULL, _merge_SSD_filter, userdata)); @@ -183,5 +179,5 @@ _nss_ldap_bootparams_constr(const char *dummy1, const char *dummy2, return ((nss_backend_t *)_nss_ldap_constr(bootparams_ops, sizeof (bootparams_ops)/sizeof (bootparams_ops[0]), - _BOOTPARAMS, bootparams_attrs, _nss_ldap_bootparams2ent)); + _BOOTPARAMS, bootparams_attrs, _nss_ldap_bootparams2str)); } diff --git a/usr/src/lib/nsswitch/ldap/common/getether.c b/usr/src/lib/nsswitch/ldap/common/getether.c index 01f337dea8..9ce919853b 100644 --- a/usr/src/lib/nsswitch/ldap/common/getether.c +++ b/usr/src/lib/nsswitch/ldap/common/getether.c @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -20,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2003 Sun Microsystems, Inc. All rights reserved. + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -48,131 +47,58 @@ static const char *ethers_attrs[] = { (char *)NULL }; - /* - * _nss_ldap_ethers2ent is the data marshaling method for the ethers - * getXbyY * (e.g., getbyhost(), getbyether()) backend processes. This - * method is called after a successful ldap search has been performed. - * This method will parse the ldap search values into uchar_t *ether - * = argp->buf.buffer which the frontend process expects. Three error - * conditions are expected and returned to nsswitch. - * - * Place the resulting struct ether_addr from the ldap query into - * argp->buf.result only if argp->buf.result is initialized (not NULL). - * e.g., it happens for the call ether_hostton. + * _nss_ldap_ethers2str is the data marshaling method for the ethers + * ether_hostton/ether_ntohost backend processes. + * This method is called after a successful ldap search has been performed. + * This method will parse the ldap search values into the file format. + * e.g. * - * Place the resulting hostname into argp->buf.buffer only if - * argp->buf.buffer is initialized. I.e. it happens for the call - * ether_ntohost. + * 8:0:20:8e:eb:8a8 borealis * - * argp->buf.buflen does not make sense for ethers. It is always set - * to 0 by the frontend. The caller only passes a hostname pointer in - * case of ether_ntohost, that is assumed to be big enough. For - * ether_hostton, the struct ether_addr passed is a fixed size. + * The front end marshaller str2ether uses argp->buf.result for a different + * purpose so a flag be->db_type is set to work around this oddity. * - * The interface does not let the caller specify how long is the buffer - * pointed by host. We make a safe assumption that the callers will - * always give MAXHOSTNAMELEN. In any case, it is the only finite number - * we can lay our hands on in case of runaway strings, memory corruption etc. */ - +/*ARGSUSED0*/ static int -_nss_ldap_ethers2ent(ldap_backend_ptr be, nss_XbyY_args_t *argp) +_nss_ldap_ethers2str(ldap_backend_ptr be, nss_XbyY_args_t *argp) { - int i, ip; int nss_result; - int buflen = (int)0; - unsigned int t[ETHERADDRL]; - unsigned long len = 0L; - char *host = NULL; - struct ether_addr *ether = NULL; ns_ldap_result_t *result = be->result; - ns_ldap_attr_t *attrptr; - int etherflag = 0, hostflag = 0; + char **host, **macaddress; - if (argp->buf.buffer) { - hostflag = 1; - host = argp->buf.buffer; - } - - buflen = (size_t)argp->buf.buflen; + if (result == NULL) + return (NSS_STR_PARSE_PARSE); + nss_result = NSS_STR_PARSE_SUCCESS; - if (argp->buf.result) { - etherflag = 1; - ether = (struct ether_addr *)argp->buf.result; + host = __ns_ldap_getAttr(result->entry, _E_HOSTNAME); + if (host == NULL || host[0] == NULL || (strlen(host[0]) < 1)) { + nss_result = NSS_STR_PARSE_PARSE; + goto result_ea2str; } - - nss_result = (int)NSS_STR_PARSE_SUCCESS; - (void) memset(argp->buf.buffer, 0, buflen); - - attrptr = getattr(result, 0); - if (attrptr == NULL) { - nss_result = (int)NSS_STR_PARSE_PARSE; - goto result_ea2ent; + macaddress = __ns_ldap_getAttr(result->entry, _E_MACADDRESS); + if (macaddress == NULL || macaddress[0] == NULL || + (strlen(macaddress[0]) < 1)) { + nss_result = NSS_STR_PARSE_PARSE; + goto result_ea2str; } - - for (i = 0; i < result->entry->attr_count; i++) { - attrptr = getattr(result, i); - if (attrptr == NULL) { - nss_result = (int)NSS_STR_PARSE_PARSE; - goto result_ea2ent; - } - if (hostflag) { - if (strcasecmp(attrptr->attrname, _E_HOSTNAME) == 0) { - if ((attrptr->attrvalue[0] == NULL) || - (len = strlen(attrptr->attrvalue[0])) < 1) { - nss_result = (int)NSS_STR_PARSE_PARSE; - goto result_ea2ent; - } - if (len > MAXHOSTNAMELEN) { - nss_result = (int)NSS_STR_PARSE_ERANGE; - goto result_ea2ent; - } - (void) strcpy(host, attrptr->attrvalue[0]); - continue; - } - } - if (etherflag) { - if (strcasecmp(attrptr->attrname, _E_MACADDRESS) == 0) { - if ((attrptr->attrvalue[0] == NULL) || - (len = strlen(attrptr->attrvalue[0])) < 1) { - nss_result = (int)NSS_STR_PARSE_PARSE; - goto result_ea2ent; - } - ip = (int)sscanf(attrptr->attrvalue[0], - "%x:%x:%x:%x:%x:%x", &t[0], &t[1], - &t[2], &t[3], &t[4], &t[5]); - if (ip != ETHERADDRL) { - nss_result = (int)NSS_STR_PARSE_PARSE; - goto result_ea2ent; - } - for (ip = 0; ip < ETHERADDRL; ip++) - ether->ether_addr_octet[ip] = - (uchar_t)t[ip]; - continue; - } - } + be->buflen = strlen(host[0]) + strlen(macaddress[0]) + 1; /* ' ' */ + /* Add a trailing null for easy debug */ + be->buffer = calloc(1, be->buflen + 1); + if (be->buffer == NULL) { + nss_result = NSS_STR_PARSE_PARSE; + goto result_ea2str; } -#ifdef DEBUG - (void) fprintf(stdout, "\n[ether_addr.c: _nss_ldap_ethers2ent]\n"); - if (host != NULL) - (void) fprintf(stdout, " hostname: [%s]\n", host); - if (ether != NULL) - (void) fprintf(stdout, - " ether_addr: [%x:%x:%x:%x:%x:%x]\n", - ether->ether_addr_octet[0], - ether->ether_addr_octet[1], - ether->ether_addr_octet[2], - ether->ether_addr_octet[3], - ether->ether_addr_octet[4], - ether->ether_addr_octet[5]); -#endif /* DEBUG */ - -result_ea2ent: + (void) snprintf(be->buffer, be->buflen + 1, "%s %s", + macaddress[0], host[0]); + be->db_type = NSS_LDAP_DB_ETHERS; + +result_ea2str: (void) __ns_ldap_freeResult(&be->result); - return ((int)nss_result); + return (nss_result); } /* @@ -197,23 +123,28 @@ getbyhost(ldap_backend_ptr be, void *a) char searchfilter[SEARCHFILTERLEN]; char userdata[SEARCHFILTERLEN]; int ret; + nss_status_t rc; if (_ldap_filter_name(hostname, argp->key.name, sizeof (hostname)) != 0) return ((nss_status_t)NSS_NOTFOUND); ret = snprintf(searchfilter, sizeof (searchfilter), _F_GETETHERBYHOST, hostname); + if (ret >= sizeof (searchfilter) || ret < 0) return ((nss_status_t)NSS_NOTFOUND); ret = snprintf(userdata, sizeof (userdata), _F_GETETHERBYHOST_SSD, hostname); + if (ret >= sizeof (userdata) || ret < 0) return ((nss_status_t)NSS_NOTFOUND); - return ((nss_status_t)_nss_ldap_lookup(be, argp, + rc = (nss_status_t)_nss_ldap_lookup(be, argp, _ETHERS, searchfilter, NULL, - _merge_SSD_filter, userdata)); + _merge_SSD_filter, userdata); + + return (rc); } @@ -279,5 +210,5 @@ _nss_ldap_ethers_constr(const char *dummy1, const char *dummy2, return ((nss_backend_t *)_nss_ldap_constr(ethers_ops, sizeof (ethers_ops)/sizeof (ethers_ops[0]), _ETHERS, - ethers_attrs, _nss_ldap_ethers2ent)); + ethers_attrs, _nss_ldap_ethers2str)); } diff --git a/usr/src/lib/nsswitch/ldap/common/getexecattr.c b/usr/src/lib/nsswitch/ldap/common/getexecattr.c index 4dfedc8628..35a60e579d 100644 --- a/usr/src/lib/nsswitch/ldap/common/getexecattr.c +++ b/usr/src/lib/nsswitch/ldap/common/getexecattr.c @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -20,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2003 Sun Microsystems, Inc. All rights reserved. + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -262,29 +261,94 @@ _exec_ldap_exec2ent(ns_ldap_entry_t *entry, nss_XbyY_args_t *argp) /* - * place the results from ldap object structure into argp->buf.result + * place the results from ldap object structure into the file format * returns NSS_STR_PARSE_{SUCCESS, ERANGE, PARSE} */ static int -_nss_ldap_exec2ent(ldap_backend_ptr be, nss_XbyY_args_t *argp) +_nss_ldap_exec2str(ldap_backend_ptr be, nss_XbyY_args_t *argp) { - int status = (int)NSS_STR_PARSE_SUCCESS; - ns_ldap_entry_t *entry; + int status = NSS_STR_PARSE_SUCCESS; ns_ldap_result_t *result = be->result; - - if (!argp->buf.result) { - status = (int)NSS_STR_PARSE_ERANGE; - goto result_exec2ent; + int len; + char *buffer, **name, **policy, **type; + char **res1, **res2, **id, **attr; + char *policy_str, *type_str, *res1_str, *res2_str; + char *id_str, *attr_str; + + if (result == NULL) + return (NSS_STR_PARSE_PARSE); + + (void) memset(argp->buf.buffer, 0, argp->buf.buflen); + + name = __ns_ldap_getAttr(result->entry, _EXEC_NAME); + if (name == NULL || name[0] == NULL || + (strlen(name[0]) < 1)) { + status = NSS_STR_PARSE_PARSE; + goto result_exec2str; } - for (entry = result->entry; entry != NULL; entry = entry->next) { - status = _exec_ldap_exec2ent(entry, argp); - if (status != NSS_STR_PARSE_SUCCESS) { - goto result_exec2ent; - } + policy = __ns_ldap_getAttr(result->entry, _EXEC_POLICY); + + if (policy == NULL || policy[0] == NULL) + policy_str = _NO_VALUE; + else + policy_str = policy[0]; + + type = __ns_ldap_getAttr(result->entry, _EXEC_TYPE); + if (type == NULL || type[0] == NULL) + type_str = _NO_VALUE; + else + type_str = type[0]; + + res1 = __ns_ldap_getAttr(result->entry, _EXEC_RES1); + if (res1 == NULL || res1[0] == NULL) + res1_str = _NO_VALUE; + else + res1_str = res1[0]; + + res2 = __ns_ldap_getAttr(result->entry, _EXEC_RES2); + if (res2 == NULL || res2[0] == NULL) + res2_str = _NO_VALUE; + else + res2_str = res2[0]; + + id = __ns_ldap_getAttr(result->entry, _EXEC_ID); + if (id == NULL || id[0] == NULL) + id_str = _NO_VALUE; + else + id_str = id[0]; + + attr = __ns_ldap_getAttr(result->entry, _EXEC_ATTRS); + if (attr == NULL || attr[0] == NULL) + attr_str = _NO_VALUE; + else + attr_str = attr[0]; + + /* 7 = 6 ':' + 1 '\0' */ + len = strlen(name[0]) + strlen(policy_str) + strlen(type_str) + + strlen(res1_str) + strlen(res2_str) + strlen(id_str) + + strlen(attr_str) + 7; + + if (len > argp->buf.buflen) { + status = NSS_STR_PARSE_ERANGE; + goto result_exec2str; } - -result_exec2ent: + if (argp->buf.result != NULL) { + if ((be->buffer = calloc(1, len)) == NULL) { + status = NSS_STR_PARSE_PARSE; + goto result_exec2str; + } + buffer = be->buffer; + } else + buffer = argp->buf.buffer; + + (void) snprintf(buffer, len, "%s:%s:%s:%s:%s:%s:%s", + name[0], policy_str, type_str, res1_str, + res2_str, id_str, attr_str); + /* The front end marshaller does not need the trailing null */ + if (argp->buf.result != NULL) + be->buflen = strlen(buffer); +result_exec2str: (void) __ns_ldap_freeResult(&be->result); return (status); } @@ -300,10 +364,6 @@ _exec_process_val(ldap_backend_ptr be, nss_XbyY_args_t *argp) ns_ldap_result_t *result = be->result; _priv_execattr *_priv_exec = (_priv_execattr *)(argp->key.attrp); -#ifdef DEBUG - (void) fprintf(stdout, "\n[getexecattr.c: _exec_process_val]\n"); -#endif /* DEBUG */ - argp->returnval = NULL; attrptr = getattr(result, 0); if (attrptr == NULL) { @@ -426,6 +486,54 @@ go_out: } static nss_status_t +exec_attr_process_val(ldap_backend_ptr be, nss_XbyY_args_t *argp) { + + _priv_execattr *_priv_exec = (_priv_execattr *)(argp->key.attrp); + int stat, nss_stat = NSS_SUCCESS; + + if (_priv_exec->search_flag == GET_ONE) { + /* ns_ldap_entry_t -> file format */ + stat = (*be->ldapobj2str)(be, argp); + + if (stat == NSS_STR_PARSE_SUCCESS) { + if (argp->buf.result != NULL) { + /* file format -> execstr_t */ + stat = (*argp->str2ent)(be->buffer, + be->buflen, + argp->buf.result, + argp->buf.buffer, + argp->buf.buflen); + if (stat == NSS_STR_PARSE_SUCCESS) { + argp->returnval = argp->buf.result; + argp->returnlen = 1; /* irrelevant */ + nss_stat = NSS_SUCCESS; + } else { + argp->returnval = NULL; + argp->returnlen = 0; + nss_stat = NSS_NOTFOUND; + } + } else { + /* return file format in argp->buf.buffer */ + argp->returnval = argp->buf.buffer; + argp->returnlen = strlen(argp->buf.buffer); + nss_stat = NSS_SUCCESS; + } + } else { + argp->returnval = NULL; + argp->returnlen = 0; + nss_stat = NSS_NOTFOUND; + } + } else { + /* GET_ALL */ + nss_stat = _exec_process_val(be, argp); + _exec_cleanup(nss_stat, argp); + } + + return (nss_stat); + +} + +static nss_status_t getbynam(ldap_backend_ptr be, void *a) { char searchfilter[SEARCHFILTERLEN]; @@ -438,10 +546,6 @@ getbynam(ldap_backend_ptr be, void *a) const char *policy = _priv_exec->policy; const char *type = _priv_exec->type; -#ifdef DEBUG - (void) fprintf(stdout, "\n[getexecattr.c: getbyname]\n"); -#endif /* DEBUG */ - if (strpbrk(policy, "*()\\") != NULL || type != NULL && strpbrk(type, "*()\\") != NULL || _ldap_filter_name(name, _priv_exec->name, sizeof (name)) != 0) @@ -458,31 +562,22 @@ getbynam(ldap_backend_ptr be, void *a) nss_stat = _nss_ldap_nocb_lookup(be, argp, _EXECATTR, searchfilter, NULL, _merge_SSD_filter, userdata); - if (nss_stat == NSS_SUCCESS) - nss_stat = _exec_process_val(be, argp); - - _exec_cleanup(nss_stat, argp); + if (nss_stat == NSS_SUCCESS) + nss_stat = exec_attr_process_val(be, argp); return (nss_stat); } - static nss_status_t getbyid(ldap_backend_ptr be, void *a) { - nss_status_t nss_stat; + nss_status_t nss_stat = NSS_SUCCESS; nss_XbyY_args_t *argp = (nss_XbyY_args_t *)a; -#ifdef DEBUG - (void) fprintf(stdout, "\n[getexecattr.c: getbyid]\n"); -#endif /* DEBUG */ - nss_stat = get_wild(be, argp, NSS_DBOP_EXECATTR_BYID); - if (nss_stat == NSS_SUCCESS) - nss_stat = _exec_process_val(be, argp); - - _exec_cleanup(nss_stat, argp); + if (nss_stat == NSS_SUCCESS) + nss_stat = exec_attr_process_val(be, argp); return (nss_stat); } @@ -494,16 +589,10 @@ getbynameid(ldap_backend_ptr be, void *a) nss_status_t nss_stat; nss_XbyY_args_t *argp = (nss_XbyY_args_t *)a; -#ifdef DEBUG - (void) fprintf(stdout, "\n[getexecattr.c: getbynameid]\n"); -#endif /* DEBUG */ - nss_stat = get_wild(be, argp, NSS_DBOP_EXECATTR_BYNAMEID); - if (nss_stat == NSS_SUCCESS) - nss_stat = _exec_process_val(be, argp); - - _exec_cleanup(nss_stat, argp); + if (nss_stat == NSS_SUCCESS) + nss_stat = exec_attr_process_val(be, argp); return (nss_stat); } @@ -536,5 +625,5 @@ _nss_ldap_exec_attr_constr(const char *dummy1, #endif return ((nss_backend_t *)_nss_ldap_constr(execattr_ops, sizeof (execattr_ops)/sizeof (execattr_ops[0]), _EXECATTR, - exec_attrs, _nss_ldap_exec2ent)); + exec_attrs, _nss_ldap_exec2str)); } diff --git a/usr/src/lib/nsswitch/ldap/common/getgrent.c b/usr/src/lib/nsswitch/ldap/common/getgrent.c index 1533ad8b3b..3456b6241f 100644 --- a/usr/src/lib/nsswitch/ldap/common/getgrent.c +++ b/usr/src/lib/nsswitch/ldap/common/getgrent.c @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -20,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2003 Sun Microsystems, Inc. All rights reserved. + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -56,195 +55,106 @@ static const char *gr_attrs[] = { /* - * _nss_ldap_group2ent is the data marshaling method for the group getXbyY + * _nss_ldap_group2str is the data marshaling method for the group getXbyY * (e.g., getgrnam(), getgrgid(), getgrent()) backend processes. This method * is called after a successful ldap search has been performed. This method - * will parse the ldap search values into struct group = argp->buf.buffer - * which the frontend process expects. Three error conditions are expected - * and returned to nsswitch. + * will parse the ldap search values into the file format. + * e.g. + * + * adm::4:root,adm,daemon + * */ static int -_nss_ldap_group2ent(ldap_backend_ptr be, nss_XbyY_args_t *argp) +_nss_ldap_group2str(ldap_backend_ptr be, nss_XbyY_args_t *argp) { - int i, j; + int i; int nss_result; - int buflen = (int)0; - int firstime = (int)1; - unsigned long len = 0L; - char **mp = NULL; - char *val = (char *)NULL; - char *buffer = (char *)NULL; - char *ceiling = (char *)NULL; - struct group *grp = (struct group *)NULL; + int buflen = 0, len; + int firstime = 1; + char *buffer = NULL; ns_ldap_result_t *result = be->result; - ns_ldap_attr_t *attrptr; + char **gname, **passwd, **gid, *password; + ns_ldap_attr_t *members; - buffer = argp->buf.buffer; - buflen = (size_t)argp->buf.buflen; - if (!argp->buf.result) { - nss_result = (int)NSS_STR_PARSE_ERANGE; - goto result_grp2ent; - } - grp = (struct group *)argp->buf.result; - ceiling = buffer + buflen; - mp = grp->gr_mem = (char **)NULL; - - /* initialize no group password */ - grp->gr_passwd = (char *)NULL; - nss_result = (int)NSS_STR_PARSE_SUCCESS; - (void) memset(argp->buf.buffer, 0, buflen); - - attrptr = getattr(result, 0); - if (attrptr == NULL) { - nss_result = (int)NSS_STR_PARSE_PARSE; - goto result_grp2ent; - } - for (i = 0; i < result->entry->attr_count; i++) { - attrptr = getattr(result, i); - if (attrptr == NULL) { - nss_result = (int)NSS_STR_PARSE_PARSE; - goto result_grp2ent; - } - if (strcasecmp(attrptr->attrname, _G_NAME) == 0) { - if ((attrptr->attrvalue[0] == NULL) || - (len = strlen(attrptr->attrvalue[0])) < 1) { - nss_result = (int)NSS_STR_PARSE_PARSE; - goto result_grp2ent; - } - grp->gr_name = buffer; - buffer += len + 1; - if (buffer > ceiling) { - nss_result = (int)NSS_STR_PARSE_ERANGE; - goto result_grp2ent; - } - (void) strcpy(grp->gr_name, attrptr->attrvalue[0]); - continue; - } - if (strcasecmp(attrptr->attrname, _G_PASSWD) == 0) { - val = attrptr->attrvalue[0]; - /* - * Preen "{crypt}" if necessary. - * If the password does not include the {crypt} prefix - * then the password may be plain text. And thus - * perhaps crypt(3c) should be used to encrypt it. - * Currently the password is copied verbatim. - */ - if (strncasecmp(val, _CRYPT, - (sizeof (_CRYPT) - 1)) == 0) - val += (sizeof (_CRYPT) - 1); - len = strlen(val); - grp->gr_passwd = buffer; - buffer += len + 1; - if (buffer > ceiling) { - nss_result = (int)NSS_STR_PARSE_ERANGE; - goto result_grp2ent; - } - (void) strcpy(grp->gr_passwd, val); - continue; - } - if (strcasecmp(attrptr->attrname, _G_GID) == 0) { - if (strlen(attrptr->attrvalue[0]) == 0) { - nss_result = (int)NSS_STR_PARSE_PARSE; - goto result_grp2ent; - } - errno = 0; - grp->gr_gid = (gid_t)strtol(attrptr->attrvalue[0], - (char **)NULL, 10); - if (errno != 0) { - nss_result = (int)NSS_STR_PARSE_PARSE; - goto result_grp2ent; - } - continue; - } - if (strcasecmp(attrptr->attrname, _G_MEM) == 0) { - for (j = 0; j < attrptr->value_count; j++) { - if (firstime) { - mp = grp->gr_mem = - (char **)ROUND_UP(buffer, - sizeof (char **)); - buffer = (char *)grp->gr_mem + - sizeof (char *) * - (attrptr->value_count + 1); - buffer = (char *)ROUND_UP(buffer, - sizeof (char **)); - if (buffer > ceiling) { - nss_result = - (int)NSS_STR_PARSE_ERANGE; - goto result_grp2ent; - } - firstime = (int)0; - } - if (attrptr->attrvalue[j] == NULL) { - nss_result = (int)NSS_STR_PARSE_PARSE; - goto result_grp2ent; - } - len = strlen(attrptr->attrvalue[j]); - if (len == 0) - continue; - *mp = buffer; - buffer += len + 1; - if (buffer > ceiling) { - nss_result = (int)NSS_STR_PARSE_ERANGE; - goto result_grp2ent; - } - (void) strcpy(*mp++, attrptr->attrvalue[j]); - continue; - } + if (result == NULL) + return (NSS_STR_PARSE_PARSE); + buflen = argp->buf.buflen; + + if (argp->buf.result != NULL) { + if ((be->buffer = calloc(1, buflen)) == NULL) { + nss_result = NSS_STR_PARSE_PARSE; + goto result_grp2str; } + buffer = be->buffer; + } else + buffer = argp->buf.buffer; + + nss_result = NSS_STR_PARSE_SUCCESS; + (void) memset(buffer, 0, buflen); + + gname = __ns_ldap_getAttr(result->entry, _G_NAME); + if (gname == NULL || gname[0] == NULL || (strlen(gname[0]) < 1)) { + nss_result = NSS_STR_PARSE_PARSE; + goto result_grp2str; } - /* Don't leave password as null */ - if (grp->gr_passwd == (char *)NULL) { + passwd = __ns_ldap_getAttr(result->entry, _G_PASSWD); + if (passwd == NULL || passwd[0] == NULL || (strlen(passwd[0]) == 0)) { + /* group password could be NULL, replace it with "" */ + password = _NO_PASSWD_VAL; + } else { /* - * The password may be missing; rfc2307bis defines - * the 'posixGroup' attributes 'authPassword' and - * 'userPassword' as being optional. Or a directory - * access control may be preventing us from reading - * the password. Currently we don't know which it is. - * If it's an access problem then perhaps the password - * should be set to "*NP*". But for now a simple empty - * string is returned. + * Preen "{crypt}" if necessary. + * If the password does not include the {crypt} prefix + * then the password may be plain text. And thus + * perhaps crypt(3c) should be used to encrypt it. + * Currently the password is copied verbatim. */ - grp->gr_passwd = buffer; - buffer += sizeof (_NO_PASSWD_VAL); - if (buffer > ceiling) { - nss_result = (int)NSS_STR_PARSE_ERANGE; - goto result_grp2ent; - } - (void) strcpy(grp->gr_passwd, _NO_PASSWD_VAL); + if (strncasecmp(passwd[0], _CRYPT, strlen(_CRYPT)) == 0) + password = passwd[0] + strlen(_CRYPT); + else + password = passwd[0]; } - if (mp == NULL) { - mp = grp->gr_mem = (char **)ROUND_UP(buffer, sizeof (char **)); - buffer = (char *)grp->gr_mem + sizeof (char *); - buffer = (char *)ROUND_UP(buffer, sizeof (char **)); - if (buffer > ceiling) { - nss_result = (int)NSS_STR_PARSE_ERANGE; - goto result_grp2ent; - } + gid = __ns_ldap_getAttr(result->entry, _G_GID); + if (gid == NULL || gid[0] == NULL || (strlen(gid[0]) < 1)) { + nss_result = NSS_STR_PARSE_PARSE; + goto result_grp2str; } - *mp = NULL; - -#ifdef DEBUG - (void) fprintf(stdout, "\n[getgrent.c: _nss_ldap_group2ent]\n"); - (void) fprintf(stdout, " gr_name: [%s]\n", grp->gr_name); - if (grp->gr_passwd != (char *)NULL) - (void) fprintf(stdout, " gr_passwd: [%s]\n", - grp->gr_passwd); - (void) fprintf(stdout, " gr_gid: [%ld]\n", grp->gr_gid); - if (mp != NULL) { - for (mp = grp->gr_mem; *mp != NULL; mp++) - (void) fprintf(stdout, " gr_mem: [%s]\n", *mp); + 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) { + nss_result = NSS_STR_PARSE_PARSE; + goto result_grp2str; } -#endif /* DEBUG */ - -result_grp2ent: + for (i = 0; i < members->value_count; i++) { + if (members->attrvalue[i] == NULL) { + nss_result = NSS_STR_PARSE_PARSE; + goto result_grp2str; + } + if (firstime) { + len = snprintf(buffer, buflen, "%s", + members->attrvalue[i]); + TEST_AND_ADJUST(len, buffer, buflen, result_grp2str); + firstime = 0; + } else { + len = snprintf(buffer, buflen, ",%s", + members->attrvalue[i]); + TEST_AND_ADJUST(len, buffer, buflen, result_grp2str); + } + } + /* The front end marshaller doesn't need the trailing nulls */ + if (argp->buf.result != NULL) + be->buflen = strlen(be->buffer); +result_grp2str: (void) __ns_ldap_freeResult(&be->result); - return ((int)nss_result); + 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 @@ -262,9 +172,6 @@ getbynam(ldap_backend_ptr be, void *a) char groupname[SEARCHFILTERLEN]; int ret; -#ifdef DEBUG - (void) fprintf(stdout, "\n[getgrent.c: getbyname]\n"); -#endif /* DBEUG */ if (_ldap_filter_name(groupname, argp->key.name, sizeof (groupname)) != 0) return ((nss_status_t)NSS_NOTFOUND); @@ -300,9 +207,6 @@ getbygid(ldap_backend_ptr be, void *a) char userdata[SEARCHFILTERLEN]; int ret; -#ifdef DEBUG - (void) fprintf(stdout, "\n[getgrent.c: getbygid]\n"); -#endif /* DBEUG */ ret = snprintf(searchfilter, sizeof (searchfilter), _F_GETGRGID, (long)argp->key.uid); if (ret >= sizeof (searchfilter) || ret < 0) @@ -354,10 +258,7 @@ getbymember(ldap_backend_ptr be, void *a) gid_t gid; int ret; -#ifdef DEBUG - (void) fprintf(stdout, "\n[getgrent.c: getbymember]\n"); -#endif /* DBEUG */ - + /* LINTED E_EXPR_NULL_EFFECT */ NSS_XbyY_ALLOC(&gb, sizeof (struct group), NSS_BUFLEN_GROUP); NSS_XbyY_INIT(&argb, gb->result, gb->buffer, gb->buflen, 0); @@ -414,7 +315,7 @@ getbymember(ldap_backend_ptr be, void *a) curEntry = curEntry->next; } - __ns_ldap_freeResult((ns_ldap_result_t **)&be->result); + (void) __ns_ldap_freeResult((ns_ldap_result_t **)&be->result); NSS_XbyY_FREE(&gb); if (gcnt == argp->numgids) return ((nss_status_t)NSS_NOTFOUND); @@ -441,5 +342,5 @@ _nss_ldap_group_constr(const char *dummy1, const char *dummy2, return ((nss_backend_t *)_nss_ldap_constr(gr_ops, sizeof (gr_ops)/sizeof (gr_ops[0]), _GROUP, gr_attrs, - _nss_ldap_group2ent)); + _nss_ldap_group2str)); } diff --git a/usr/src/lib/nsswitch/ldap/common/gethostent.c b/usr/src/lib/nsswitch/ldap/common/gethostent.c index 78b84c785e..f327c232c6 100644 --- a/usr/src/lib/nsswitch/ldap/common/gethostent.c +++ b/usr/src/lib/nsswitch/ldap/common/gethostent.c @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -20,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2003 Sun Microsystems, Inc. All rights reserved. + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -52,261 +51,203 @@ static const char *hosts_attrs[] = { (char *)NULL }; - /* - * _nss_ldap_hosts2ent is the data marshaling method for the hosts getXbyY - * system call gethostbyname() and gethostbyaddr. The format of this call - * is a cononical name and alias (alias is cononical name too) and one or - * more IP addresses in support of multihomed hosts. This method is called - * after a successful synchronous search has been performed. This method - * will parse the search results into struct hostent = argp->buf.buffer - * which gets returned to the frontend process. One of three error - * conditions is also returned to nsswitch. + * _nss_ldap_hosts2str is the data marshaling method for the hosts getXbyY + * system call gethostbyname() and gethostbyaddr. + * This method is called after a successful search has been performed. + * This method will parse the search results into the file format. + * e.g. + * + * 9.9.9.9 jurassic jurassic1 jurassic2 + * 10.10.10.10 puppy + * */ - -static int -_nss_ldap_hosts2ent(ldap_backend_ptr be, nss_XbyY_args_t *argp) +int +_nss_ldap_hosts2str_int(int af, ldap_backend_ptr be, nss_XbyY_args_t *argp) { - int i, j; + uint_t i; int nss_result; - int buflen = (int)0; - int firstimename = (int)1; - int firstimedn = (int)1; - int firstimeaddr = (int)1; - unsigned long len = 0L; - char **hn, **ha, **dp; - char *cname = (char *)NULL; - char *buffer = (char *)NULL; - char *ceiling = (char *)NULL; - struct hostent *host = (struct hostent *)NULL; - in_addr_t addr; + int buflen, buflen1, buflen2, len; + int firstimedn = 1, first_entry; + int validaddress = 0, copy_cname; + char *cname = NULL, *h_name = NULL; + char *buffer = NULL; + char *name; ns_ldap_result_t *result = be->result; - ns_ldap_attr_t *attrptr; - in_addr_t inet_addr(const char *cp); - int namecount = 0; - int addrcount = 0; - int aliascount = 0; - int validaddress = 0; - int gluelen = 0; + ns_ldap_attr_t *names; ns_ldap_entry_t *entry; - ns_ldap_attr_t *attr; -#ifdef DEBUG - struct in_addr in; -#endif /* DEBUG */ - - buffer = argp->buf.buffer; - buflen = (size_t)argp->buf.buflen; - if (!argp->buf.result) { - nss_result = (int)NSS_STR_PARSE_ERANGE; - goto result_hosts2ent; + char **ips = NULL, **dns = NULL; + char *first_host = NULL, *other_hosts = NULL; + char *buf1, *buf2; + + if (result == NULL) + return (NSS_STR_PARSE_PARSE); + buflen = buflen1 = buflen2 = argp->buf.buflen; + + if (argp->buf.result != NULL) { + if ((be->buffer = calloc(1, buflen)) == NULL) { + nss_result = NSS_STR_PARSE_PARSE; + goto result_host2str; + } + buffer = be->buffer; + } else + buffer = argp->buf.buffer; + if ((first_host = calloc(1, buflen1)) == NULL) { + nss_result = NSS_STR_PARSE_PARSE; + goto result_host2str; } - - host = (struct hostent *)argp->buf.result; - ceiling = buffer + buflen; - - nss_result = (int)NSS_STR_PARSE_SUCCESS; - (void) memset(argp->buf.buffer, 0, buflen); - - attrptr = getattr(result, 0); - if (attrptr == NULL) { - nss_result = (int)NSS_STR_PARSE_PARSE; - goto result_hosts2ent; + if ((other_hosts = calloc(1, buflen2)) == NULL) { + nss_result = NSS_STR_PARSE_PARSE; + goto result_host2str; } - namecount = 0; - addrcount = 0; - for (entry = result->entry; entry != NULL; entry = entry->next) { - for (i = 0, attr = entry->attr_pair[i]; - i < entry->attr_count; i++) { - attr = entry->attr_pair[i]; - if (strcasecmp(attr->attrname, _H_NAME) == 0) - namecount += attr->value_count; - if (strcasecmp(attr->attrname, _H_ADDR) == 0) - addrcount += attr->value_count; - } - } + nss_result = NSS_STR_PARSE_SUCCESS; + (void) memset(argp->buf.buffer, 0, buflen); + /* + * Multiple lines return will be sepereated by newlines + * Single line return or last line does not have newline + * e.g. + * + * 8.8.8.8 hostname + * + * or the search for hostname h1 returns 3 entries + * + * 9.9.9.9 h1 + * 10.10.10.10 h1 xx + * 20.20.20.20 h1 yyy + * + * str2hostent expects all name/aliases in the first entry + * so the string is organized as + * + * "9.9.9.9 h1 xx yy\n10.10.10.10 \n20.20.20.20 " + * + * Use first_host to hold "9.9.9.9 h1 xx yy" and other_hosts to hold + * "\n10.10.10.10 \n20.20.20.20 " + * + */ + buf1 = first_host; + buf2 = other_hosts; + first_entry = 1; for (entry = result->entry; entry != NULL; entry = entry->next) { - for (i = 0; i < entry->attr_count; i++) { - attrptr = entry->attr_pair[i]; - if (attrptr == NULL) { - nss_result = (int)NSS_STR_PARSE_PARSE; - goto result_hosts2ent; - } - if (strcasecmp(attrptr->attrname, _H_DN) == 0) { - for (j = 0; j < attrptr->value_count; j++) { - if (firstimedn) { - /* get domain name associated with this dn */ - be->toglue = _get_domain_name( - attrptr->attrvalue[j]); - firstimedn = (int)0; - } - } - } - if (strcasecmp(attrptr->attrname, _H_NAME) == 0) { - for (j = 0; j < attrptr->value_count; j++) { - if (firstimename) { - /* canonical name */ - cname = __s_api_get_canonical_name(result->entry, - attrptr, 1); - if (cname == NULL || - (len = strlen(cname)) < 1) { - nss_result = (int)NSS_STR_PARSE_PARSE; - goto result_hosts2ent; - } - if (be->toglue != NULL && - !DOTTEDSUBDOMAIN(cname)) - gluelen = strlen(be->toglue) + 1; - else - gluelen = 0; - host->h_name = buffer; - buffer += len + gluelen + 1; - if (buffer >= ceiling) { - nss_result = (int)NSS_STR_PARSE_ERANGE; - goto result_hosts2ent; - } - (void) strcpy(host->h_name, cname); - if (gluelen > 0) { - (void) strcat(host->h_name, "."); - (void) strcat(host->h_name, be->toglue); - } - /* alias name */ - aliascount = (namecount >= 1 ? (namecount - 1) : 0); - hn = host->h_aliases = (char **)ROUND_UP(buffer, - sizeof (char **)); - buffer = (char *)host->h_aliases + - (sizeof (char *) * (aliascount + 1)); - buffer = (char *)ROUND_UP(buffer, - sizeof (char **)); - if (buffer >= ceiling) { - nss_result = (int)NSS_STR_PARSE_ERANGE; - goto result_hosts2ent; - } - firstimename = (int)0; - } - /* alias list */ - if (aliascount > 0) { - if ((attrptr->attrvalue[j] == NULL) || - (len = strlen(attrptr->attrvalue[j])) < 1) { - nss_result = (int)NSS_STR_PARSE_PARSE; - goto result_hosts2ent; - } - /* skip canonical name */ - if (strcmp(cname, attrptr->attrvalue[j]) == 0) - continue; - /* check for duplicates */ - for (dp = host->h_aliases; *dp != NULL; dp++) { - if (strcmp(*dp, attrptr->attrvalue[j]) == 0) - goto next_alias; - } - if (be->toglue != NULL && - !DOTTEDSUBDOMAIN(attrptr->attrvalue[j])) - gluelen = strlen(be->toglue) + 1; - else - gluelen = 0; - *hn = buffer; - buffer += len + gluelen + 1; - if (buffer >= ceiling) { - nss_result = (int)NSS_STR_PARSE_ERANGE; - goto result_hosts2ent; - } - (void) strcpy(*hn, attrptr->attrvalue[j]); - if (gluelen > 0) { - (void) strcat(*hn, "."); - (void) strcat(*hn, be->toglue); - } - hn++; - } -next_alias: - continue; + if (firstimedn) { + dns = __ns_ldap_getAttr(entry, _H_DN); + if (dns == NULL || dns[0] == NULL || strlen(dns[0]) < 1) { + nss_result = NSS_STR_PARSE_PARSE; + goto result_host2str; } - } + /* get domain name associated with this dn */ + be->toglue = _get_domain_name(dns[0]); + firstimedn = 0; } - } - for (entry = result->entry; entry != NULL; entry = entry->next) { - for (i = 0; i < entry->attr_count; i++) { - attrptr = entry->attr_pair[i]; - if (attrptr == NULL) { - nss_result = (int)NSS_STR_PARSE_PARSE; - goto result_hosts2ent; - } - if (strcasecmp(attrptr->attrname, _H_ADDR) == 0) { - for (j = 0; j < attrptr->value_count; j++) { - if (firstimeaddr) { - /* allocate 1 address per entry */ - ha = host->h_addr_list = - (char **)ROUND_UP(buffer, - sizeof (char **)); - buffer = (char *)host->h_addr_list + - sizeof (char *) * - (addrcount + 1); - buffer = (char *)ROUND_UP(buffer, - sizeof (char **)); - if (buffer >= ceiling) { - nss_result = (int)NSS_STR_PARSE_ERANGE; - goto result_hosts2ent; - } - firstimeaddr = (int)0; - } - /* filter out IPV6 addresses */ - addr = inet_addr(_strip_quotes(attrptr->attrvalue[j])); - if (addr == (in_addr_t)-1) { - goto next_addr; - } - validaddress++; - /* check for duplicates */ - for (dp = host->h_addr_list; *dp != NULL; dp++) { - if (memcmp(*dp, &addr, (size_t)sizeof (in_addr_t)) == 0) - goto next_addr; - } - *ha = buffer; - len = (unsigned long)sizeof (in_addr_t); - buffer += len; - if (buffer >= ceiling) { - nss_result = (int)NSS_STR_PARSE_ERANGE; - goto result_hosts2ent; - } - (void) memcpy(*ha++, (char *)&addr, (size_t)len); -next_addr: - continue; - } - } + /* Get IP */ + ips = __ns_ldap_getAttr(entry, _H_ADDR); + if (ips == NULL || ips[0] == NULL || strlen(ips[0]) < 1) { + nss_result = NSS_STR_PARSE_PARSE; + goto result_host2str; + } + /* Skip IPV6 address in AF_INET mode */ + if (af == AF_INET && + (inet_addr(_strip_quotes(ips[0])) == (in_addr_t)-1)) + continue; + + /* A valid address for either af mode */ + validaddress++; + + if (first_entry) { + len = snprintf(buf1, buflen1, "%s", ips[0]); + TEST_AND_ADJUST(len, buf1, buflen1, result_host2str); + } else { + len = snprintf(buf2, buflen2, "\n%s ", ips[0]); + TEST_AND_ADJUST(len, buf2, buflen2, result_host2str); } - } - if (validaddress == 0) { - nss_result = (int)NSS_STR_PARSE_NO_ADDR; - goto result_hosts2ent; - } + /* Get host names */ + names = __ns_ldap_getAttrStruct(entry, _H_NAME); + if (names == NULL || names->attrvalue == NULL) { + nss_result = NSS_STR_PARSE_PARSE; + goto result_host2str; + } - host->h_addrtype = AF_INET; - host->h_length = sizeof (uint_t); + /* Get canonical name of each entry */ + cname = __s_api_get_canonical_name(entry, + names, 1); + if (cname == NULL || strlen(cname) < 1) { + nss_result = NSS_STR_PARSE_PARSE; + goto result_host2str; + } -#ifdef DEBUG - (void) fprintf(stdout, "\n[gethostent.c: _nss_ldap_hosts2ent]\n"); - (void) fprintf(stdout, " h_name: [%s]\n", host->h_name); - if (host->h_aliases != NULL) { - for (hn = host->h_aliases; *hn != NULL; hn++) - (void) fprintf(stdout, " h_aliases: [%s]\n", *hn); - } - (void) fprintf(stdout, " h_addrtype: [%d]\n", host->h_addrtype); - (void) fprintf(stdout, " h_length: [%d]\n", host->h_length); - for (ha = host->h_addr_list; *ha != NULL; ha++) { - (void) memcpy(&in.s_addr, *ha, sizeof (in.s_addr)); - if (inet_ntoa(in) != NULL) - (void) fprintf(stdout, " h_addr_list: [%s]\n", - inet_ntoa(in)); + /* Filter cname that's identical to h_name */ + if (first_entry) { + h_name = cname; + first_entry = 0; + copy_cname = 1; + } else if (strcasecmp(cname, h_name) != 0) { + copy_cname = 1; + } else + copy_cname = 0; + + if (copy_cname) { + /* Use the canonical name as the host name */ + if (DOTTEDSUBDOMAIN(cname)) + len = snprintf(buf1, buflen1, " %s", cname); else - (void) fprintf(stdout, " h_addr_list: <NULL>\n"); - } -#endif /* DEBUG */ + /* append domain name */ + len = snprintf(buf1, buflen1, " %s.%s", cname, + be->toglue); -result_hosts2ent: + TEST_AND_ADJUST(len, buf1, buflen1, result_host2str); + } + + /* Append aliases */ + for (i = 0; i < names->value_count; i++) { + name = names->attrvalue[i]; + if (name == NULL) { + nss_result = NSS_STR_PARSE_PARSE; + goto result_host2str; + } + /* Skip the canonical name and h_name */ + if (strcasecmp(name, cname) != 0 && + strcasecmp(name, h_name) != 0) { + if (DOTTEDSUBDOMAIN(name)) + len = snprintf(buf1, buflen1, " %s", name); + else + /* append domain name */ + len = snprintf(buf1, buflen1, " %s.%s", + name, be->toglue); + TEST_AND_ADJUST(len, buf1, buflen1, result_host2str); + } + } + } + if (validaddress == 0) { + /* + * For AF_INET mode, it found an IPv6 address and skipped it. + */ + nss_result = NSS_STR_PARSE_NO_ADDR; + goto result_host2str; + } + /* Combine 2 strings */ + len = snprintf(buffer, buflen, "%s%s", first_host, other_hosts); + TEST_AND_ADJUST(len, buffer, buflen, result_host2str); + + /* The front end marshaller doesn't need to copy trailing nulls */ + if (argp->buf.result != NULL) + be->buflen = strlen(be->buffer); + +result_host2str: + if (first_host) + free(first_host); + if (other_hosts) + free(other_hosts); (void) __ns_ldap_freeResult(&be->result); - return ((int)nss_result); + return (nss_result); } +static int +_nss_ldap_hosts2str(ldap_backend_ptr be, nss_XbyY_args_t *argp) { + return (_nss_ldap_hosts2str_int(AF_INET, be, argp)); +} /* * getbyname gets a struct hostent by hostname. This function constructs @@ -484,10 +425,7 @@ _nss_ldap_hosts_constr(const char *dummy1, const char *dummy2, const char *dummy3) { -#ifdef DEBUG - (void) fprintf(stdout, "\n[gethostent.c: _nss_ldap_hosts_constr]\n"); -#endif /* DEBUG */ return ((nss_backend_t *)_nss_ldap_constr(hosts_ops, sizeof (hosts_ops)/sizeof (hosts_ops[0]), _HOSTS, - hosts_attrs, _nss_ldap_hosts2ent)); + hosts_attrs, _nss_ldap_hosts2str)); } diff --git a/usr/src/lib/nsswitch/ldap/common/gethostent6.c b/usr/src/lib/nsswitch/ldap/common/gethostent6.c index 8b0a453d69..1fad135afa 100644 --- a/usr/src/lib/nsswitch/ldap/common/gethostent6.c +++ b/usr/src/lib/nsswitch/ldap/common/gethostent6.c @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -20,17 +19,17 @@ * CDDL HEADER END */ /* - * Copyright 2003 Sun Microsystems, Inc. All rights reserved. + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ #pragma ident "%Z%%M% %I% %E% SMI" #include <netdb.h> -#include <netinet/in.h> +#include <sys/types.h> #include <sys/socket.h> -#include <inet/ip6.h> -#include <syslog.h> +#include <netinet/in.h> +#include <arpa/inet.h> #include <sys/systeminfo.h> #include "ns_internal.h" #include "ldap_common.h" @@ -57,254 +56,24 @@ static const char *ipnodes_attrs[] = { (char *)NULL }; -extern int inet_pton(int, const char *, void *); -const char *inet_ntop(int af, const void *src, char *dst, size_t size); +extern int +_nss_ldap_hosts2str_int(int af, ldap_backend_ptr be, nss_XbyY_args_t *argp); /* - * _nss_ldap_hosts2ent is the data marshaling method for the ipnodes getXbyY - * system call gethostbyname() and gethostbyaddr. The format of this call - * is a cononical name and alias (alias is cononical name too) and one or - * more IP addresses in support of multihomed hosts. This method is called - * after a successful synchronous search has been performed. This method - * will parse the search results into struct hostent = argp->buf.buffer - * which gets returned to the frontend process. One of three error - * conditions is also returned to nsswitch. + * _nss_ldap_hosts2str is the data marshaling method for the ipnodes getXbyY + * system call gethostbyname() and gethostbyaddr. + * This method is called after a successful search has been performed. + * This method will parse the search results into the file format. + * e.g. + * + * fe80::a00:20ff:fec4:f2b6 ipnodes_1 + * */ - static int -_nss_ldap_hosts2ent(ldap_backend_ptr be, nss_XbyY_args_t *argp) -{ - int i, j; - int nss_result; - int buflen = (int)0; - int firstimename = (int)1; - int firstimedn = (int)1; - int firstimeaddr = (int)1; - unsigned long len = 0L; - char **hn, **ha, **dp; - char *cname = (char *)NULL; - char *buffer = (char *)NULL; - char *ceiling = (char *)NULL; - struct hostent *host = (struct hostent *)NULL; - struct in6_addr addr6; - struct in_addr addr; - char *val; - ns_ldap_result_t *result = be->result; - ns_ldap_attr_t *attrptr; - int namecount = 0; - int addrcount = 0; - int aliascount = 0; - int gluelen = 0; - ns_ldap_entry_t *entry; - ns_ldap_attr_t *attr; - - buffer = argp->buf.buffer; - buflen = (size_t)argp->buf.buflen; - if (!argp->buf.result) { - nss_result = (int)NSS_STR_PARSE_ERANGE; - goto result_hosts2ent; - } - host = (struct hostent *)argp->buf.result; - ceiling = buffer + buflen; - - nss_result = (int)NSS_STR_PARSE_SUCCESS; - (void) memset(argp->buf.buffer, 0, buflen); - - attrptr = getattr(result, 0); - if (attrptr == NULL) { - nss_result = (int)NSS_STR_PARSE_PARSE; - goto result_hosts2ent; - } - - for (entry = result->entry; entry != NULL; entry = entry->next) { - for (i = 0, attr = entry->attr_pair[i]; - i < entry->attr_count; i++) { - attr = entry->attr_pair[i]; - if (strcasecmp(attr->attrname, _H_NAME) == 0) - namecount += attr->value_count; - if (strcasecmp(attr->attrname, _H_ADDR) == 0) - addrcount += attr->value_count; - } - } - - for (entry = result->entry; entry != NULL; entry = entry->next) { - for (i = 0; i < entry->attr_count; i++) { - attrptr = entry->attr_pair[i]; - if (attrptr == NULL) { - nss_result = (int)NSS_STR_PARSE_PARSE; - goto result_hosts2ent; - } - if (strcasecmp(attrptr->attrname, _H_DN) == 0) { - for (j = 0; j < attrptr->value_count; j++) { - if (firstimedn) { - /* get domain name associated with this dn */ - be->toglue = _get_domain_name( - attrptr->attrvalue[j]); - firstimedn = (int)0; - } - } - } - if (strcasecmp(attrptr->attrname, _H_NAME) == 0) { - for (j = 0; j < attrptr->value_count; j++) { - if (firstimename) { - /* canonical name */ - cname = __s_api_get_canonical_name(result->entry, - attrptr, 1); - if (cname == NULL || - (len = strlen(cname)) < 1) { - nss_result = (int)NSS_STR_PARSE_PARSE; - goto result_hosts2ent; - } - if (be->toglue != NULL && - !DOTTEDSUBDOMAIN(cname)) - gluelen = strlen(be->toglue) + 1; - else - gluelen = 0; - host->h_name = buffer; - buffer += len + gluelen + 1; - if (buffer >= ceiling) { - nss_result = (int)NSS_STR_PARSE_ERANGE; - goto result_hosts2ent; - } - (void) strcpy(host->h_name, cname); - if (gluelen > 0) { - (void) strcat(host->h_name, "."); - (void) strcat(host->h_name, be->toglue); - } - /* alias name */ - aliascount = (namecount >= 1 ? (namecount - 1) : 0); - hn = host->h_aliases = - (char **)ROUND_UP(buffer, sizeof (char **)); - buffer = (char *)host->h_aliases + - sizeof (char *) * (aliascount + 1); - buffer = (char *)ROUND_UP(buffer, sizeof (char **)); - if (buffer >= ceiling) { - nss_result = (int)NSS_STR_PARSE_ERANGE; - goto result_hosts2ent; - } - firstimename = (int)0; - } - /* alias list */ - if (aliascount > 0) { - if ((attrptr->attrvalue[j] == NULL) || - (len = strlen(attrptr->attrvalue[j])) < 1) { - nss_result = (int)NSS_STR_PARSE_PARSE; - goto result_hosts2ent; - } - /* skip canonical name */ - if (strcmp(attrptr->attrvalue[j], cname) == 0) - continue; - /* check for duplicates */ - for (dp = host->h_aliases; *dp != NULL; dp++) { - if (strcmp(*dp, attrptr->attrvalue[j]) == 0) - goto next_alias; - } - if (be->toglue != NULL && - !DOTTEDSUBDOMAIN(attrptr->attrvalue[j])) - gluelen = strlen(be->toglue) + 1; - else - gluelen = 0; - *hn = buffer; - buffer += len + gluelen + 1; - if (buffer >= ceiling) { - nss_result = (int)NSS_STR_PARSE_ERANGE; - goto result_hosts2ent; - } - (void) strcpy(*hn, attrptr->attrvalue[j]); - if (gluelen > 0) { - (void) strcat(*hn, "."); - (void) strcat(*hn, be->toglue); - } - hn++; - } -next_alias: - continue; - } - } - } - } - - for (entry = result->entry; entry != NULL; entry = entry->next) { - for (i = 0; i < entry->attr_count; i++) { - attrptr = entry->attr_pair[i]; - if (attrptr == NULL) { - nss_result = (int)NSS_STR_PARSE_PARSE; - goto result_hosts2ent; - } - - if (strcasecmp(attrptr->attrname, _H_ADDR) == 0) { - for (j = 0; j < attrptr->value_count; j++) { - if (firstimeaddr) { - /* allocate 1 address per entry */ - ha = host->h_addr_list = (char **)ROUND_UP(buffer, - sizeof (char **)); - buffer = (char *)host->h_addr_list + - sizeof (char *) * (addrcount + 1); - buffer = (char *)ROUND_UP(buffer, sizeof (char **)); - if (buffer >= ceiling) { - nss_result = (int)NSS_STR_PARSE_ERANGE; - goto result_hosts2ent; - } - firstimeaddr = (int)0; - } - val = (char *)_strip_quotes(attrptr->attrvalue[j]); - if (inet_pton(AF_INET6, val, (void *) &addr6) != 1) { - if (inet_pton(AF_INET, val, (void *) &addr) != 1) { - goto next_addr; - } else { - IN6_INADDR_TO_V4MAPPED(&addr, &addr6); - } - } - - /* check for duplicates */ - for (dp = host->h_addr_list; *dp != NULL; dp++) { - if (memcmp(*dp, &addr6, sizeof (struct in6_addr)) - == 0) - goto next_addr; - } - *ha = buffer; - len = (unsigned long)sizeof (struct in6_addr); - buffer += len; - if (buffer >= ceiling) { - nss_result = (int)NSS_STR_PARSE_ERANGE; - goto result_hosts2ent; - } - (void) memcpy(*ha++, (char *)&addr6, (size_t)len); -next_addr: - continue; - } - } - } - } - - host->h_addrtype = AF_INET6; - host->h_length = IPV6_ADDR_LEN; - -#ifdef DEBUG - (void) fprintf(stdout, "\n[gethostent.c: _nss_ldap_byname2ent]\n"); - (void) fprintf(stdout, " h_name: [%s]\n", host->h_name); - if (host->h_aliases != NULL) { - for (hn = host->h_aliases; *hn != NULL; hn++) - (void) fprintf(stdout, " h_aliases: [%s]\n", *hn); - } - (void) fprintf(stdout, " h_addrtype: [%d]\n", host->h_addrtype); - (void) fprintf(stdout, " h_length: [%d]\n", host->h_length); - - for (hn = host->h_addr_list; *hn != NULL; hn++) { - char addrbuf[INET6_ADDRSTRLEN + 1]; - (void) fprintf(stdout, " haddr_list: [%s]\n", - inet_ntop(AF_INET6, (void *)hn, (void *)addrbuf, - INET6_ADDRSTRLEN)); - } -#endif /* DEBUG */ - -result_hosts2ent: - - (void) __ns_ldap_freeResult(&be->result); - return ((int)nss_result); +_nss_ldap_hosts2str(ldap_backend_ptr be, nss_XbyY_args_t *argp) { + return (_nss_ldap_hosts2str_int(AF_INET6, be, argp)); } - /* * getbyname gets a struct hostent by hostname. This function constructs * an ldap search filter using the name invocation parameter and the @@ -325,10 +94,6 @@ getbyname(ldap_backend_ptr be, void *a) char userdata[SEARCHFILTERLEN]; int rc; -#ifdef DEBUG - (void) fprintf(stdout, "\n[gethostent6.c: getbyname]\n"); -#endif /* DEBUG */ - if (_ldap_filter_name(hostname, argp->key.ipnode.name, sizeof (hostname)) != 0) return ((nss_status_t)NSS_NOTFOUND); @@ -432,9 +197,6 @@ getbyaddr(ldap_backend_ptr be, void *a) char userdata[SEARCHFILTERLEN]; int ret; -#ifdef DEBUG - (void) fprintf(stdout, "\n[gethostent6.c: getbyaddr]\n"); -#endif /* DEBUG */ argp->h_errno = 0; if ((argp->key.hostaddr.type != AF_INET6) || (argp->key.hostaddr.len != sizeof (addr))) @@ -493,10 +255,7 @@ _nss_ldap_ipnodes_constr(const char *dummy1, const char *dummy2, const char *dummy3) { -#ifdef DEBUG - (void) fprintf(stdout, "\n[gethostent6.c: _nss_ldap_host6_constr]\n"); -#endif /* DEBUG */ return ((nss_backend_t *)_nss_ldap_constr(ipnodes_ops, sizeof (ipnodes_ops)/sizeof (ipnodes_ops[0]), _HOSTS6, - ipnodes_attrs, _nss_ldap_hosts2ent)); + ipnodes_attrs, _nss_ldap_hosts2str)); } diff --git a/usr/src/lib/nsswitch/ldap/common/getkeyent.c b/usr/src/lib/nsswitch/ldap/common/getkeyent.c index c1c9dbd381..95f27cddb9 100644 --- a/usr/src/lib/nsswitch/ldap/common/getkeyent.c +++ b/usr/src/lib/nsswitch/ldap/common/getkeyent.c @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -20,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2003 Sun Microsystems, Inc. All rights reserved. + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -49,69 +48,58 @@ static const char *keys_attrs[] = { /* - * _nss_ldap_key2ent is the data marshaling method for the publickey getXbyY + * _nss_ldap_key2str is the data marshaling method for the publickey getXbyY * (e.g., getpublickey() and getsecretkey()) backend processes. This method * is called after a successful ldap search has been performed. This method - * will parse the ldap search values into "public:secret" key string = - * argp->buf.buffer which the frontend process expects. Three error - * conditions are expected and returned to nsswitch. + * will parse the ldap search values into "public:secret" file format. + * + * c3d91f44568fbbefada50d336d9bd67b16e7016f987bb607: + * 7675cd9b8753b5db09dabf12da759c2bd1331c927bb322861fffb54be13f55e9 + * + * (All in one line) + * + * Publickey does not have a front end marshaller so db_type is set + * for special handling. */ static int -_nss_ldap_key2ent(ldap_backend_ptr be, nss_XbyY_args_t *argp) +_nss_ldap_key2str(ldap_backend_ptr be, nss_XbyY_args_t *argp) { int nss_result; char *keytype = (char *)argp->key.pkey.keytype; int keytypelen = strlen(keytype); - char *key_start = NULL; - int key_len; - int buflen = (size_t)argp->buf.buflen; - char *buffer = (char *)argp->buf.buffer; - char *ceiling = (char *)NULL; + int len; + int buflen = argp->buf.buflen; + char *buffer, *pkey, *skey; ns_ldap_result_t *result = be->result; - char **key_array; - -#ifdef DEBUG - (void) fprintf(stdout, "\n[getpublikey.c: _nss_ldap_passwd2ent]\n"); -#endif /* DEBUG */ + char **pkey_array, **skey_array; - if (!argp->buf.result) { - nss_result = (int)NSS_STR_PARSE_ERANGE; - goto result_key2ent; + if (result == NULL || keytype == NULL) { + nss_result = NSS_STR_PARSE_ERANGE; + goto result_key2str; } - ceiling = buffer + buflen; - nss_result = (int)NSS_STR_PARSE_SUCCESS; - (void) memset(buffer, 0, buflen); - + nss_result = NSS_STR_PARSE_SUCCESS; + (void) memset(argp->buf.buffer, 0, buflen); /* get the publickey */ - key_array = __ns_ldap_getAttr(result->entry, _KEY_NISPUBLICKEY); - if (key_array == NULL) { - nss_result = (int)NSS_STR_PARSE_PARSE; - goto result_key2ent; + pkey_array = __ns_ldap_getAttr(result->entry, _KEY_NISPUBLICKEY); + if (pkey_array == NULL) { + nss_result = NSS_STR_PARSE_PARSE; + goto result_key2str; } - while (*key_array) { - if (strncasecmp(*key_array, keytype, keytypelen) == NULL) + while (*pkey_array) { + if (strncasecmp(*pkey_array, keytype, keytypelen) == NULL) break; - key_array++; - } - if (*key_array == NULL) { - nss_result = (int)NSS_STR_PARSE_PARSE; - goto result_key2ent; + pkey_array++; } - - key_start = *(key_array) + keytypelen; - key_len = strlen(key_start) + 1; - if (buffer + key_len + 2 > ceiling) { - nss_result = (int)NSS_STR_PARSE_ERANGE; - goto result_key2ent; + if (*pkey_array == NULL) { + nss_result = NSS_STR_PARSE_PARSE; + goto result_key2str; } - (void) strncpy(buffer, key_start, key_len); - (void) strcat(buffer, ":"); - buffer += strlen(buffer); + pkey = *pkey_array + keytypelen; /* get the secretkey */ - key_array = __ns_ldap_getAttr(result->entry, _KEY_NISSECRETKEY); - if (key_array == NULL) { + skey_array = __ns_ldap_getAttr(result->entry, _KEY_NISSECRETKEY); + if (skey_array == NULL) { /* * if we got this far, it's possible that the secret * key is actually missing or no permission to read it. @@ -120,33 +108,37 @@ _nss_ldap_key2ent(ldap_backend_ptr be, nss_XbyY_args_t *argp) * the only possibility of reaching this here is due to * missing secret key. */ - nss_result = (int)NSS_STR_PARSE_PARSE; - goto result_key2ent; + nss_result = NSS_STR_PARSE_PARSE; + goto result_key2str; } - while (*key_array) { - if (strncasecmp(*key_array, keytype, keytypelen) == NULL) + while (*skey_array) { + if (strncasecmp(*skey_array, keytype, keytypelen) == NULL) break; - key_array++; + skey_array++; } - if (*key_array == NULL) { - nss_result = (int)NSS_STR_PARSE_PARSE; - goto result_key2ent; + if (*skey_array == NULL) { + nss_result = NSS_STR_PARSE_PARSE; + goto result_key2str; } + skey = *skey_array + keytypelen; - key_start = *(key_array) + keytypelen; - key_len = strlen(key_start); - if (buffer + key_len + 1 > ceiling) { - nss_result = (int)NSS_STR_PARSE_ERANGE; - goto result_key2ent; + /* 2 = 1 ':' + 1 '\0' */ + len = strlen(pkey) + strlen(skey) + 2; + if (len > buflen) { + nss_result = NSS_STR_PARSE_ERANGE; + goto result_key2str; } - (void) strcat(buffer, key_start); + /* + * publickey does not have a frontend marshaller. + * copy the result to buf.buffer directly + */ + buffer = argp->buf.buffer; + + (void) snprintf(buffer, len, "%s:%s", pkey, skey); -#ifdef DEBUG - (void) fprintf(stdout, "\n[getkeys.c: _nss_ldap_key2ent]\n"); - (void) fprintf(stdout, "\treturn: %s\n", buffer); -#endif /* DEBUG */ + be->db_type = NSS_LDAP_DB_PUBLICKEY; -result_key2ent: +result_key2str: (void) __ns_ldap_freeResult(&be->result); return ((int)nss_result); @@ -176,10 +168,6 @@ getkeys(ldap_backend_ptr be, void *a) nss_status_t rc; int ret; -#ifdef DEBUG - (void) fprintf(stdout, "\n[getpwnam.c: getbyname]\n"); -#endif /* DEBUG */ - /* * We need to break it down to find if this is a netname for host * or user. We'll pass the domain as is to the LDAP call. @@ -187,6 +175,7 @@ getkeys(ldap_backend_ptr be, void *a) if (_ldap_filter_name(netname, argp->key.pkey.name, sizeof (netname)) != 0) return ((nss_status_t)NSS_NOTFOUND); + domain = strchr(netname, '@'); if (!domain) return ((nss_status_t)NSS_NOTFOUND); @@ -252,11 +241,7 @@ _nss_ldap_publickey_constr(const char *dummy1, const char *dummy2, const char *dummy3) { -#ifdef DEBUG - (void) fprintf(stdout, "\n[getkeys.c: _nss_ldap_keys_constr]\n"); -#endif /* DEBUG */ - return ((nss_backend_t *)_nss_ldap_constr(keys_ops, sizeof (keys_ops)/sizeof (keys_ops[0]), - _PUBLICKEY, keys_attrs, _nss_ldap_key2ent)); + _PUBLICKEY, keys_attrs, _nss_ldap_key2str)); } diff --git a/usr/src/lib/nsswitch/ldap/common/getnetent.c b/usr/src/lib/nsswitch/ldap/common/getnetent.c index a5afb360ce..d042e0fe2b 100644 --- a/usr/src/lib/nsswitch/ldap/common/getnetent.c +++ b/usr/src/lib/nsswitch/ldap/common/getnetent.c @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -20,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2003 Sun Microsystems, Inc. All rights reserved. + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -38,8 +37,10 @@ #define _N_NETWORK "ipnetworknumber" #define _F_GETNETBYNAME "(&(objectClass=ipNetwork)(cn=%s))" #define _F_GETNETBYNAME_SSD "(&(%%s)(cn=%s))" -#define _F_GETNETBYADDR "(&(objectClass=ipNetwork)(ipNetworkNumber=%s))" -#define _F_GETNETBYADDR_SSD "(&(%%s)(ipNetworkNumber=%s))" +#define _F_GETNETBYADDR "(&(objectClass=ipNetwork)(|(ipNetworkNumber=%s)" \ + "(ipNetworkNumber=%s)))" +#define _F_GETNETBYADDR_SSD "(&(%%s)(|(ipNetworkNumber=%s)" \ + "(ipNetworkNumber=%s)))" static const char *networks_attrs[] = { _N_NAME, @@ -48,187 +49,119 @@ static const char *networks_attrs[] = { }; /* - * _nss_ldap_networks2ent is the data marshaling method for the networks + * _nss_ldap_networks2str is the data marshaling method for the networks * getXbyY * (e.g., getbyname(), getbyaddr(), getnetent() backend processes. * This method is called after a successful ldap search has been performed. - * This method will parse the ldap search values into struct netent = - * argp->buf.buffer which the frontend process expects. Three error conditions - * are expected and returned to nsswitch. + * This method will parse the ldap search values into the file format. + * e.g. + * + * SunRay-ce2 10.34.96.0 SunRay + * */ - static int -_nss_ldap_networks2ent(ldap_backend_ptr be, nss_XbyY_args_t *argp) +_nss_ldap_networks2str(ldap_backend_ptr be, nss_XbyY_args_t *argp) { - int i, j; + uint_t i; int nss_result; - int buflen = (int)0; - int firstime = (int)1; - unsigned long len = 0L; - char **mp, *cname = NULL; -#ifdef DEBUG - char addrstr[16]; -#endif /* DEBUG */ - char *buffer = (char *)NULL; - char *ceiling = (char *)NULL; - struct netent *ntk = (struct netent *)NULL; + int buflen = 0, len; + char **network, *cname = NULL; + char *buffer = NULL; ns_ldap_result_t *result = be->result; - ns_ldap_attr_t *attrptr; + ns_ldap_attr_t *names; - buffer = argp->buf.buffer; - buflen = (size_t)argp->buf.buflen; - if (!argp->buf.result) { - nss_result = (int)NSS_STR_PARSE_ERANGE; - goto result_net2ent; - } - ntk = (struct netent *)argp->buf.result; - ceiling = buffer + buflen; + if (result == NULL) + return (NSS_STR_PARSE_PARSE); + buflen = argp->buf.buflen; - nss_result = (int)NSS_STR_PARSE_SUCCESS; + if (argp->buf.result != NULL) { + if ((be->buffer = calloc(1, buflen)) == NULL) { + nss_result = NSS_STR_PARSE_PARSE; + goto result_net2str; + } + buffer = be->buffer; + } else + buffer = argp->buf.buffer; + + nss_result = NSS_STR_PARSE_SUCCESS; (void) memset(argp->buf.buffer, 0, buflen); - attrptr = getattr(result, 0); - if (attrptr == NULL) { - nss_result = (int)NSS_STR_PARSE_PARSE; - goto result_net2ent; + names = __ns_ldap_getAttrStruct(result->entry, _N_NAME); + if (names == NULL || names->attrvalue == NULL) { + nss_result = NSS_STR_PARSE_PARSE; + goto result_net2str; } - - for (i = 0; i < result->entry->attr_count; i++) { - attrptr = getattr(result, i); - if (attrptr == NULL) { - nss_result = (int)NSS_STR_PARSE_PARSE; - goto result_net2ent; - } - if (strcasecmp(attrptr->attrname, _N_NAME) == 0) { - for (j = 0; j < attrptr->value_count; j++) { - if (firstime) { - /* - * The definition of the object class - * "ipNetwork" has a descripency between - * RFC 2307 and 2307bis. - * In 2307, "cn" is a MUST attribute. - * In 2307bis, "cn" is a MAY attribute. - * If "cn" is a MAY attribute, - * it does not appear in RDN and can't - * be derived from RDN as a canonical - * "cn" name. In that case, use 1st - * "cn" value as the official name. - */ - cname = __s_api_get_canonical_name( - result->entry, attrptr, 1); - if (cname == NULL) - /* 2307bis case */ - cname = attrptr->attrvalue[j]; - - if (cname == NULL || - (len = strlen(cname)) < 1) { - nss_result = - NSS_STR_PARSE_PARSE; - goto result_net2ent; - } - ntk->n_name = buffer; - buffer += len + 1; - if (buffer >= ceiling) { - nss_result = - (int)NSS_STR_PARSE_ERANGE; - goto result_net2ent; - } - (void) strcpy(ntk->n_name, cname); - /* alias list */ - mp = ntk->n_aliases = - (char **)ROUND_UP(buffer, - sizeof (char **)); - buffer = (char *)ntk->n_aliases + - sizeof (char *) * - (attrptr->value_count + 1); - buffer = (char *)ROUND_UP(buffer, - sizeof (char **)); - if (buffer >= ceiling) { - nss_result = - (int)NSS_STR_PARSE_ERANGE; - goto result_net2ent; - } - firstime = (int)0; - } - /* alias list */ - if ((attrptr->attrvalue[j] == NULL) || - (len = strlen(attrptr->attrvalue[j])) < 1) { - nss_result = (int)NSS_STR_PARSE_PARSE; - goto result_net2ent; - } - /* skip canonical name(official name) */ - if (strcmp(attrptr->attrvalue[j], cname) == 0) - continue; - *mp = buffer; - buffer += len + 1; - if (buffer >= ceiling) { - nss_result = (int)NSS_STR_PARSE_ERANGE; - goto result_net2ent; - } - (void) strcpy(*mp++, attrptr->attrvalue[j]); - continue; - } + /* Get the canonical name */ + cname = __s_api_get_canonical_name(result->entry, names, 1); + /* + * The definition of the object class "ipNetwork" has a + * discrepency between RFC 2307 and 2307bis. + * In 2307, "cn" is a MUST attribute. In 2307bis, "cn" is a + * MAY attribute. + * If "cn" is a MAY attribute, it does not appear in RDN and can't + * be derived from RDN as a canonical "cn" name. In that case, use 1st + * "cn" value as the official name. + */ + if (cname == NULL) + /* 2307bis case */ + cname = names->attrvalue[0]; + if (cname == NULL || (len = strlen(cname)) < 1) { + nss_result = NSS_STR_PARSE_PARSE; + goto result_net2str; + } + network = __ns_ldap_getAttr(result->entry, _N_NETWORK); + if (network == NULL || network[0] == NULL || + (len = strlen(network[0])) < 1) { + nss_result = NSS_STR_PARSE_PARSE; + goto result_net2str; + } + len = snprintf(buffer, buflen, "%s %s", cname, network[0]); + TEST_AND_ADJUST(len, buffer, buflen, result_net2str); + /* Append aliases */ + for (i = 0; i < names->value_count; i++) { + if (names->attrvalue[i] == NULL) { + nss_result = NSS_STR_PARSE_PARSE; + goto result_net2str; } - if (strcasecmp(attrptr->attrname, _N_NETWORK) == 0) { - if ((attrptr->attrvalue[0] == NULL) || - (len = strlen(attrptr->attrvalue[0])) < 1) { - nss_result = (int)NSS_STR_PARSE_PARSE; - goto result_net2ent; - } - if ((ntk->n_net = (in_addr_t) - inet_network(attrptr->attrvalue[0])) == - (in_addr_t)-1) { - nss_result = (int)NSS_STR_PARSE_PARSE; - goto result_net2ent; - } -#ifdef DEBUG - strlcpy(addrstr, attrptr->attrvalue[0], - sizeof (addrstr)); -#endif /* DEBUG */ - continue; + /* Skip the canonical name */ + if (strcasecmp(names->attrvalue[i], cname) != 0) { + len = snprintf(buffer, buflen, " %s", + names->attrvalue[i]); + TEST_AND_ADJUST(len, buffer, buflen, result_net2str); } } - ntk->n_addrtype = AF_INET; - -#ifdef DEBUG - (void) fprintf(stdout, "\n[getnetent.c: _nss_ldap_networks2ent]\n"); - (void) fprintf(stdout, " n_name: [%s]\n", ntk->n_name); - if (mp != NULL) { - for (mp = ntk->n_aliases; *mp != NULL; mp++) - (void) fprintf(stdout, " n_aliases: [%s]\n", *mp); - } - if (ntk->n_addrtype == AF_INET) - (void) fprintf(stdout, " n_addrtype: [AF_INET]\n"); - else - (void) fprintf(stdout, " n_addrtype: [%d]\n", - ntk->n_addrtype); - (void) fprintf(stdout, " n_net: [%s]\n", addrstr); -#endif /* DEBUG */ -result_net2ent: + /* The front end marshaller doesn't need to copy trailing nulls */ + if (argp->buf.result != NULL) + be->buflen = strlen(be->buffer); + +result_net2str: (void) __ns_ldap_freeResult(&be->result); - return ((int)nss_result); + return (nss_result); } - /* * Takes an unsigned integer in host order, and returns a printable * string for it as a network number. To allow for the possibility of * naming subnets, only trailing dot-zeros are truncated. + * buf2 is untruncated version. */ -static int nettoa(int anet, char *buf, int buflen) +static int nettoa(int anet, char *buf, char *buf2, int buflen) { int addr; char *p; struct in_addr in; - if (buf == 0) + if (buf == NULL || buf2 == NULL) return ((int)1); in = inet_makeaddr(anet, INADDR_ANY); addr = in.s_addr; - if (strlcpy(buf, inet_ntoa(in), buflen) >= buflen) + if (inet_ntop(AF_INET, (const void *)&in, buf2, INET_ADDRSTRLEN) + == NULL) + return ((int)1); + if (strlcpy(buf, buf2, buflen) >= buflen) return ((int)1); if ((IN_CLASSA_HOST & htonl(addr)) == 0) { p = strchr(buf, '.'); @@ -304,21 +237,22 @@ static nss_status_t getbyaddr(ldap_backend_ptr be, void *a) { nss_XbyY_args_t *argp = (nss_XbyY_args_t *)a; - char addrstr[16]; + char addrstr[INET_ADDRSTRLEN], addrstr2[INET_ADDRSTRLEN]; char searchfilter[SEARCHFILTERLEN]; char userdata[SEARCHFILTERLEN]; int ret; - if (nettoa((int)argp->key.netaddr.net, addrstr, 16) != 0) + if (nettoa((int)argp->key.netaddr.net, addrstr, addrstr2, + INET_ADDRSTRLEN) != 0) return ((nss_status_t)NSS_UNAVAIL); ret = snprintf(searchfilter, sizeof (searchfilter), - _F_GETNETBYADDR, addrstr); + _F_GETNETBYADDR, addrstr, addrstr2); if (ret >= sizeof (searchfilter) || ret < 0) return ((nss_status_t)NSS_NOTFOUND); ret = snprintf(userdata, sizeof (userdata), - _F_GETNETBYADDR_SSD, addrstr); + _F_GETNETBYADDR_SSD, addrstr, addrstr2); if (ret >= sizeof (userdata) || ret < 0) return ((nss_status_t)NSS_NOTFOUND); @@ -351,5 +285,5 @@ _nss_ldap_networks_constr(const char *dummy1, const char *dummy2, return ((nss_backend_t *)_nss_ldap_constr(net_ops, sizeof (net_ops)/sizeof (net_ops[0]), _NETWORKS, - networks_attrs, _nss_ldap_networks2ent)); + networks_attrs, _nss_ldap_networks2str)); } diff --git a/usr/src/lib/nsswitch/ldap/common/getnetgrent.c b/usr/src/lib/nsswitch/ldap/common/getnetgrent.c index 01728e3420..d3072440f2 100644 --- a/usr/src/lib/nsswitch/ldap/common/getnetgrent.c +++ b/usr/src/lib/nsswitch/ldap/common/getnetgrent.c @@ -890,7 +890,7 @@ netgr_set(ldap_backend_ptr be, void *a) get_be->tablename = NULL; get_be->attrs = netgrent_attrs; get_be->result = NULL; - get_be->ldapobj2ent = NULL; + get_be->ldapobj2str = NULL; get_be->setcalled = 1; get_be->filter = NULL; get_be->toglue = NULL; diff --git a/usr/src/lib/nsswitch/ldap/common/getnetmasks.c b/usr/src/lib/nsswitch/ldap/common/getnetmasks.c index 69ef802520..2e6f28053e 100644 --- a/usr/src/lib/nsswitch/ldap/common/getnetmasks.c +++ b/usr/src/lib/nsswitch/ldap/common/getnetmasks.c @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -20,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2003 Sun Microsystems, Inc. All rights reserved. + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -47,80 +46,61 @@ static const char *netmasks_attrs[] = { /* - * _nss_ldap_netmasks2ent is the data marshaling method for the netmasks - * getXbyY * (e.g., getbynet()) backend processes. This method is called - * after a successful ldap search has been performed. This method will - * parse the ldap search values into struct in_addr *mask = argp->buf.result - * only if argp->buf.result is initialized (not NULL). Three error - * conditions are expected and returned to nsswitch. + * _nss_ldap_netmasks2str is the data marshaling method for the netmasks + * getXbyY * (e.g., getnetmaskby[net|addr]()) backend processes. + * This method is called after a successful ldap search has been performed. + * This method will parse the ldap search values into the file format. + * + * getnetmaskbykey set argp->buf.buffer to NULL and argp->buf.buflen to 0 + * and argp->buf.result to non-NULL. + * The front end marshaller str2add expects "netmask" only + * + * e.g. + * + * 255.255.255.0 + * + * */ static int -_nss_ldap_netmasks2ent(ldap_backend_ptr be, nss_XbyY_args_t *argp) +_nss_ldap_netmasks2str(ldap_backend_ptr be, nss_XbyY_args_t *argp) { - int i, j; - int nss_result; - unsigned long len = 0L; -#ifdef DEBUG - char maskstr[16]; -#endif /* DEBUG */ - struct in_addr addr; - struct in_addr *mask = (struct in_addr *)NULL; + int nss_result, len; ns_ldap_result_t *result = be->result; - ns_ldap_attr_t *attrptr; + char *buffer, **netmask; - mask = (struct in_addr *)argp->buf.result; - nss_result = (int)NSS_STR_PARSE_SUCCESS; + if (result == NULL) + return (NSS_STR_PARSE_PARSE); - attrptr = getattr(result, 0); - if (attrptr == NULL) { - nss_result = (int)NSS_STR_PARSE_PARSE; - goto result_nmks2ent; - } + nss_result = NSS_STR_PARSE_SUCCESS; - for (i = 0; i < result->entry->attr_count; i++) { - attrptr = getattr(result, i); - if (attrptr == NULL) { - nss_result = (int)NSS_STR_PARSE_PARSE; - goto result_nmks2ent; - } - if (strcasecmp(attrptr->attrname, _N_NETMASK) == 0) { - for (j = 0; j < attrptr->value_count; j++) { - if (mask == NULL) - continue; - if ((attrptr->attrvalue[j] == NULL) || - (len = strlen(attrptr->attrvalue[j])) < 1) { - nss_result = (int)NSS_STR_PARSE_PARSE; - goto result_nmks2ent; - } - /* addr a IPv4 address and 32 bits */ - addr.s_addr = inet_addr(attrptr->attrvalue[j]); - if (addr.s_addr == 0xffffffffUL) { - nss_result = (int)NSS_STR_PARSE_PARSE; - goto result_nmks2ent; - } - mask->s_addr = addr.s_addr; -#ifdef DEBUG - strlcpy(maskstr, attrptr->attrvalue[j], - sizeof (maskstr)); -#endif /* DEBUG */ - continue; - } - } + netmask = __ns_ldap_getAttr(result->entry, _N_NETMASK); + if (netmask == NULL || netmask[0] == NULL || + (strlen(netmask[0]) < 1)) { + nss_result = NSS_STR_PARSE_PARSE; + goto result_nmks2str; } + /* Add a trailing null for debugging purpose */ + len = strlen(netmask[0]) + 1; + if (argp->buf.result != NULL) { + if ((be->buffer = calloc(1, len)) == NULL) { + nss_result = NSS_STR_PARSE_PARSE; + goto result_nmks2str; + } + be->buflen = len - 1; + buffer = be->buffer; + } else + buffer = argp->buf.buffer; -#ifdef DEBUG - (void) fprintf(stdout, "\n[netmasks.c: _nss_ldap_netmasks2ent]\n"); - (void) fprintf(stdout, " netmask: [%s]\n", maskstr); -#endif /* DEBUG */ -result_nmks2ent: + (void) snprintf(buffer, len, "%s", netmask[0]); + +result_nmks2str: (void) __ns_ldap_freeResult(&be->result); return ((int)nss_result); } - /* * getbynet gets a network mask by address. This function constructs an * ldap search filter using the netmask name invocation parameter and the @@ -142,7 +122,6 @@ getbynet(ldap_backend_ptr be, void *a) if (_ldap_filter_name(netnumber, argp->key.name, sizeof (netnumber)) != 0) return ((nss_status_t)NSS_NOTFOUND); - ret = snprintf(searchfilter, sizeof (searchfilter), _F_GETMASKBYNET, netnumber); if (ret >= sizeof (searchfilter) || ret < 0) @@ -179,5 +158,5 @@ _nss_ldap_netmasks_constr(const char *dummy1, const char *dummy2, return ((nss_backend_t *)_nss_ldap_constr(netmasks_ops, sizeof (netmasks_ops)/sizeof (netmasks_ops[0]), _NETMASKS, - netmasks_attrs, _nss_ldap_netmasks2ent)); + netmasks_attrs, _nss_ldap_netmasks2str)); } diff --git a/usr/src/lib/nsswitch/ldap/common/getprinter.c b/usr/src/lib/nsswitch/ldap/common/getprinter.c index f4004be41a..aae2f326cb 100644 --- a/usr/src/lib/nsswitch/ldap/common/getprinter.c +++ b/usr/src/lib/nsswitch/ldap/common/getprinter.c @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -20,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2004 Sun Microsystems, Inc. All rights reserved. + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -36,6 +35,9 @@ static void append_attr(char *buf, char *attr); #define _F_GETPRINTERBYNAME \ "(&(objectClass=sunPrinter)(|(printer-name=%s)(printer-aliases=%s)))" +#define PRINTER_PREFIX "printer-" +#define SUNWPR_PREFIX "sunwpr-" + /* * Attributes from the following classes: * printerService @@ -50,85 +52,82 @@ static const char **printer_attrs = NULL; /* - * _nss_ldap_printers2ent is the data marshaling method for the printers + * _nss_ldap_printers2str is the data marshaling method for the printers * getXbyY backend processes. This method is called after a successful * ldap search has been performed. This method will parse the ldap search * values into argp->buf.buffer. Three error conditions are expected and * returned to nsswitch. + * In order to be compatible with old data output, the code is commented out + * with NSS_LDAP_PRINTERS. The NSS_LDAP_PRINTERS section is for future + * refrences if it's decided to fix the output format. */ static int -_nss_ldap_printers2ent(ldap_backend_ptr be, nss_XbyY_args_t *argp) +_nss_ldap_printers2str(ldap_backend_ptr be, nss_XbyY_args_t *argp) { int i, j; int nss_result; - int buflen = (int)0; - unsigned long len = 0L; - char *cp = (char *)NULL; - char *buffer = (char *)NULL; + int buflen = 0, len; + char *buffer = NULL; + char **name, *attrname; ns_ldap_attr_t *attr; ns_ldap_result_t *result = be->result; +#ifdef NSS_LDAP_PRINTERS + int slen, plen; +#endif - buffer = argp->buf.buffer; - buflen = (size_t)argp->buf.buflen; - if (!argp->buf.result) { - nss_result = (int)NSS_STR_PARSE_ERANGE; - goto result_printers2ent; + if (result == NULL) + return (NSS_STR_PARSE_PARSE); + + buflen = argp->buf.buflen; + if (argp->buf.result != NULL) { + be->buffer = calloc(1, buflen); + if (be->buffer == NULL) + return (NSS_STR_PARSE_PARSE); + be->buflen = buflen; + buffer = be->buffer; + } else { + buffer = argp->buf.buffer; + (void) memset(argp->buf.buffer, 0, buflen); } - nss_result = (int)NSS_STR_PARSE_SUCCESS; - (void) memset(argp->buf.buffer, 0, buflen); - - /* Make sure our buffer stays NULL terminated */ - buflen--; + nss_result = NSS_STR_PARSE_SUCCESS; - attr = getattr(result, 0); - if (attr == NULL) { - nss_result = (int)NSS_STR_PARSE_PARSE; - goto result_printers2ent; - } +#ifdef NSS_LDAP_PRINTERS + slen = strlen(SUNWPR_PREFIX); + plen = strlen(PRINTER_PREFIX); +#endif /* - * Pick out the printer name. + * Pick out the printer name and aliases */ - for (i = 0; i < result->entry->attr_count; i++) { - attr = getattr(result, i); - if (attr == NULL) { - nss_result = (int)NSS_STR_PARSE_PARSE; - goto result_printers2ent; - } - if (strcasecmp(attr->attrname, "printer-name") == 0) { - len = strlen(attr->attrvalue[0]); - if (len < 1 || (attr->attrvalue[0] == '\0')) { - *buffer = 0; - nss_result = (int)NSS_STR_PARSE_PARSE; - goto result_printers2ent; - } - if (len > buflen) { - nss_result = (int)NSS_STR_PARSE_ERANGE; - goto result_printers2ent; - } - (void) strcpy(buffer, attr->attrvalue[0]); - } + name = __ns_ldap_getAttr(result->entry, "printer-name"); + if (name == NULL || name[0] == NULL) { + nss_result = NSS_STR_PARSE_PARSE; + goto result_printers2str; } - - /* - * Should never happen since it is mandatory but bail if - * we don't have a printer name. - */ - if (buffer[0] == NULL) { - nss_result = (int)NSS_STR_PARSE_PARSE; - goto result_printers2ent; + len = snprintf(buffer, buflen, "%s", name[0]); + TEST_AND_ADJUST(len, buffer, buflen, result_printers2str); + +#ifdef NSS_LDAP_PRINTERS + attr = __ns_ldap_getAttrStruct(result->entry, "printer-aliases"); + if (attr != NULL && attr->attrvalue != NULL) { + for (i = 0; i < attr->value_count; i++) { + len = snprintf(buffer, buflen, "|%s", + attr->attrvalue[i]); + TEST_AND_ADJUST(len, buffer, buflen, + result_printers2str); + } } - +#endif /* * Add the rest of the attributes */ for (i = 0; i < result->entry->attr_count; i++) { attr = getattr(result, i); if (attr == NULL) { - nss_result = (int)NSS_STR_PARSE_PARSE; - goto result_printers2ent; + nss_result = NSS_STR_PARSE_PARSE; + goto result_printers2str; } /* * The attribute contains key=value @@ -140,51 +139,76 @@ _nss_ldap_printers2ent(ldap_backend_ptr be, nss_XbyY_args_t *argp) (attr->attrvalue[j] == '\0')) { *buffer = 0; nss_result = (int)NSS_STR_PARSE_PARSE; - goto result_printers2ent; - } - len += strlen(buffer) + 1; /* 1 for ':' */ - if (len > buflen) { - nss_result = (int)NSS_STR_PARSE_ERANGE; - goto result_printers2ent; - } - if ((cp = strrchr(buffer, '\0')) != NULL) { - *cp = ':'; - (void) strcat(buffer, - attr->attrvalue[j]); + goto result_printers2str; } + len = snprintf(buffer, buflen, ":%s", + attr->attrvalue[j]); + TEST_AND_ADJUST(len, buffer, buflen, + result_printers2str); } } else { /* - * Skip the printer name + * Skip some attr names */ - if (strcmp(attr->attrname, "printer-name") == 0) { +#ifdef NSS_LDAP_PRINTERS + if (strcasecmp(attr->attrname, "printer-name") == 0 || + strcasecmp(attr->attrname, "dn") == 0 || + strcasecmp(attr->attrname, + "objectclass") == 0 || + strcasecmp(attr->attrname, + "printer-uri") == 0 || + strcasecmp(attr->attrname, + "printer-aliases") == 0) +#else + if (strcasecmp(attr->attrname, "printer-name") == 0) +#endif continue; } /* - * Translate sun-printer-bsdaddr -> bsdaddr + * Translate attr name ->key name */ - if (strcmp(attr->attrname, "sun-printer-bsdaddr") == - 0) { - if (attr->attrname != NULL) { - free(attr->attrname); - } - attr->attrname = strdup("bsdaddr"); - } + if (strcmp(attr->attrname, "sun-printer-bsdaddr") + == 0) + attrname = "bsdaddr"; +#ifdef NSS_LDAP_PRINTERS + else if (strcmp(attr->attrname, "printer-info") + == 0) + attrname = "description"; + else if (strcmp(attr->attrname, "sunwpr-support") + == 0) + attrname = "itopssupported"; + else if (strncmp(attr->attrname, PRINTER_PREFIX, plen) + == 0) + attrname = attr->attrname + plen; + else if (strncmp(attr->attrname, SUNWPR_PREFIX, slen) + == 0) + attrname = attr->attrname + slen; +#endif + else + attrname = attr->attrname; /* - * The attribute name is the key. The attribute + * The attrname is the key. The attribute * data is the value. */ + len = snprintf(buffer, buflen, ":%s=", attrname); + TEST_AND_ADJUST(len, buffer, buflen, + result_printers2str); + for (j = 0; j < attr->value_count; j++) { int k; char *kp; + if (attr->attrvalue[j] == NULL) { + *buffer = 0; + nss_result = NSS_STR_PARSE_PARSE; + goto result_printers2str; + } len = strlen(attr->attrvalue[j]); - if (len < 1 || - (attr->attrvalue[j] == '\0')) { + if (len < 1) { *buffer = 0; - nss_result = (int)NSS_STR_PARSE_PARSE; - goto result_printers2ent; + nss_result = NSS_STR_PARSE_PARSE; + goto result_printers2str; } /* * Add extra for any colons which need to @@ -193,38 +217,33 @@ _nss_ldap_printers2ent(ldap_backend_ptr be, nss_XbyY_args_t *argp) k = 0; for (kp = attr->attrvalue[j]; *kp != NULL; kp++) if (*kp == ':') + /* count ':' in value */ k++; - len += strlen(buffer) + k; + if (j == 0) + /* first time */ + len += k; + else + /* add ',' */ + len += k + 1; - if (j == 0) { - len += strlen(attr->attrname) + 1; - } if (len > buflen) { - nss_result = (int)NSS_STR_PARSE_ERANGE; - goto result_printers2ent; + nss_result = NSS_STR_PARSE_ERANGE; + goto result_printers2str; } - if ((cp = strrchr(buffer, '\0')) != NULL) { - if (j == 0) { - *cp = ':'; - (void) strcat(buffer, - attr->attrname); - (void) strcat(buffer, "="); - } else { - *cp = ','; - } - (void) append_attr(buffer, + if (j > 0) + *buffer++ = ','; + + (void) append_attr(buffer, attr->attrvalue[j]); - } + buffer += strlen(attr->attrvalue[j]) + k; + buflen -= len; } - } } -#ifdef DEBUG - (void) fprintf(stdout, "\n[getprinter.c: _nss_ldap_printers2ent]\n"); - (void) fprintf(stdout, " printers: [%s]\n", buffer); -#endif + if (argp->buf.result != NULL) + be->buflen = strlen(be->buffer); -result_printers2ent: +result_printers2str: (void) __ns_ldap_freeResult(&be->result); return ((int)nss_result); } @@ -241,7 +260,7 @@ append_attr(char *buf, char *attr) (void) strcat(buf, attr); return; } - bp = buf + strlen(buf); + bp = buf; cp = attr; while (*cp != NULL) { if (*cp == ':') { @@ -257,7 +276,7 @@ append_attr(char *buf, char *attr) * parameter and the getprinterbyname search filter defined. Once the * filter is constructed, we search for matching entries and marshal * the data results into argp->buf.buffer for the frontend process. - * The function * _nss_ldap_printers2ent performs the data marshaling. + * The function _nss_ldap_printers2str performs the data marshaling. */ static nss_status_t @@ -297,12 +316,7 @@ _nss_ldap_printers_constr(const char *dummy1, const char *dummy2, const char *dummy3) { -#ifdef DEBUG - (void) fprintf(stdout, - "\n[getprinterent.c: _nss_ldap_printers_constr]\n"); -#endif - return ((nss_backend_t *)_nss_ldap_constr(printers_ops, sizeof (printers_ops)/sizeof (printers_ops[0]), _PRINTERS, - printer_attrs, _nss_ldap_printers2ent)); + printer_attrs, _nss_ldap_printers2str)); } diff --git a/usr/src/lib/nsswitch/ldap/common/getprofattr.c b/usr/src/lib/nsswitch/ldap/common/getprofattr.c index d4c4adf6d4..dc8469ce58 100644 --- a/usr/src/lib/nsswitch/ldap/common/getprofattr.c +++ b/usr/src/lib/nsswitch/ldap/common/getprofattr.c @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -20,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2003 Sun Microsystems, Inc. All rights reserved. + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -37,7 +36,9 @@ #define _PROF_RES2 "SolarisAttrReserved2" #define _PROF_DESC "SolarisAttrLongDesc" #define _PROF_ATTRS "SolarisAttrKeyValue" -#define _PROF_GETPROFNAME "(&(objectClass=SolarisProfAttr)(cn=%s))" +/* Negate an exec_attr attribute to exclude exec_attr entries */ +#define _PROF_GETPROFNAME \ +"(&(objectClass=SolarisProfAttr)(!(SolarisKernelSecurityPolicy=*))(cn=%s))" #define _PROF_GETPROFNAME_SSD "(&(%%s)(cn=%s))" static const char *prof_attrs[] = { @@ -48,150 +49,88 @@ static const char *prof_attrs[] = { _PROF_ATTRS, (char *)NULL }; - - +/* + * _nss_ldap_prof2str is the data marshaling method for the prof_attr + * system call getprofattr, getprofnam and getproflist. + * This method is called after a successful search has been performed. + * This method will parse the search results into the file format. + * e.g. + * + * All:::Execute any command as the user or role:help=RtAll.html + * + */ static int -_nss_ldap_prof2ent(ldap_backend_ptr be, nss_XbyY_args_t *argp) +_nss_ldap_prof2str(ldap_backend_ptr be, nss_XbyY_args_t *argp) { - int i, nss_result; - int buflen = (int)0; + int nss_result; + int buflen = 0; unsigned long len = 0L; - char *nullstring = (char *)NULL; - char *buffer = (char *)NULL; - char *ceiling = (char *)NULL; - profstr_t *prof = (profstr_t *)NULL; - ns_ldap_attr_t *attrptr; + char *buffer = NULL; ns_ldap_result_t *result = be->result; + char **name, **res1, **res2, **des, **attr; + char *res1_str, *res2_str, *des_str, *attr_str; - buffer = argp->buf.buffer; - buflen = (size_t)argp->buf.buflen; - if (!argp->buf.result) { - nss_result = (int)NSS_STR_PARSE_ERANGE; - goto result_prof2ent; - } - prof = (profstr_t *)(argp->buf.result); - ceiling = buffer + buflen; - prof->name = (char *)NULL; - prof->res1 = (char *)NULL; - prof->res2 = (char *)NULL; - prof->desc = (char *)NULL; - prof->attr = (char *)NULL; - nss_result = (int)NSS_STR_PARSE_SUCCESS; - (void) memset(argp->buf.buffer, 0, buflen); + if (result == NULL) + return (NSS_STR_PARSE_PARSE); - attrptr = getattr(result, 0); - if (attrptr == NULL) { - nss_result = (int)NSS_STR_PARSE_PARSE; - goto result_prof2ent; - } - - for (i = 0; i < result->entry->attr_count; i++) { - attrptr = getattr(result, i); - if (attrptr == NULL) { - nss_result = (int)NSS_STR_PARSE_PARSE; - goto result_prof2ent; - } - if (strcasecmp(attrptr->attrname, _PROF_NAME) == 0) { - if ((attrptr->attrvalue[0] == NULL) || - (len = strlen(attrptr->attrvalue[0])) < 1) { - nss_result = (int)NSS_STR_PARSE_PARSE; - goto result_prof2ent; - } - prof->name = buffer; - buffer += len + 1; - if (buffer >= ceiling) { - nss_result = (int)NSS_STR_PARSE_ERANGE; - goto result_prof2ent; - } - (void) strcpy(prof->name, attrptr->attrvalue[0]); - continue; - } - if (strcasecmp(attrptr->attrname, _PROF_RES1) == 0) { - if ((attrptr->attrvalue[0] == NULL) || - (len = strlen(attrptr->attrvalue[0])) < 1) { - prof->res1 = nullstring; - } else { - prof->res1 = buffer; - buffer += len + 1; - if (buffer >= ceiling) { - nss_result = (int)NSS_STR_PARSE_ERANGE; - goto result_prof2ent; - } - (void) strcpy(prof->res1, - attrptr->attrvalue[0]); - } - continue; - } - if (strcasecmp(attrptr->attrname, _PROF_RES2) == 0) { - if ((attrptr->attrvalue[0] == NULL) || - (len = strlen(attrptr->attrvalue[0])) < 1) { - prof->res2 = nullstring; - } else { - prof->res2 = buffer; - buffer += len + 1; - if (buffer >= ceiling) { - nss_result = (int)NSS_STR_PARSE_ERANGE; - goto result_prof2ent; - } - (void) strcpy(prof->res2, - attrptr->attrvalue[0]); - } - continue; - } - if (strcasecmp(attrptr->attrname, _PROF_DESC) == 0) { - if ((attrptr->attrvalue[0] == NULL) || - (len = strlen(attrptr->attrvalue[0])) < 1) { - prof->desc = nullstring; - } else { - prof->desc = buffer; - buffer += len + 1; - if (buffer >= ceiling) { - nss_result = (int)NSS_STR_PARSE_ERANGE; - goto result_prof2ent; - } - (void) strcpy(prof->desc, - attrptr->attrvalue[0]); - } - continue; - } - if (strcasecmp(attrptr->attrname, _PROF_ATTRS) == 0) { - if ((attrptr->attrvalue[0] == NULL) || - (len = strlen(attrptr->attrvalue[0])) < 1) { - prof->attr = nullstring; - } else { - prof->attr = buffer; - buffer += len + 1; - if (buffer >= ceiling) { - nss_result = (int)NSS_STR_PARSE_ERANGE; - goto result_prof2ent; - } - (void) strcpy(prof->attr, - attrptr->attrvalue[0]); - } - continue; - } - } + buflen = argp->buf.buflen; + nss_result = NSS_STR_PARSE_SUCCESS; + (void) memset(argp->buf.buffer, 0, buflen); -#ifdef DEBUG - (void) fprintf(stdout, "\n[getprofattr.c: _nss_ldap_prof2ent]\n"); - (void) fprintf(stdout, " prof-name: [%s]\n", prof->name); - if (prof->res1 != (char *)NULL) { - (void) fprintf(stdout, " res1: [%s]\n", prof->res1); - } - if (prof->res2 != (char *)NULL) { - (void) fprintf(stdout, " res2: [%s]\n", prof->res2); - } - if (prof->desc != (char *)NULL) { - (void) fprintf(stdout, " desc: [%s]\n", prof->desc); + name = __ns_ldap_getAttr(result->entry, _PROF_NAME); + if (name == NULL || name[0] == NULL || + (strlen(name[0]) < 1)) { + nss_result = NSS_STR_PARSE_PARSE; + goto result_prof2str; } - if (prof->attr != (char *)NULL) { - (void) fprintf(stdout, " attr: [%s]\n", prof->attr); + res1 = __ns_ldap_getAttr(result->entry, _PROF_RES1); + if (res1 == NULL || res1[0] == NULL || (strlen(res1[0]) < 1)) + res1_str = _NO_VALUE; + else + res1_str = res1[0]; + + res2 = __ns_ldap_getAttr(result->entry, _PROF_RES2); + if (res2 == NULL || res2[0] == NULL || (strlen(res2[0]) < 1)) + res2_str = _NO_VALUE; + else + res2_str = res2[0]; + + des = __ns_ldap_getAttr(result->entry, _PROF_DESC); + if (des == NULL || des[0] == NULL || (strlen(des[0]) < 1)) + des_str = _NO_VALUE; + else + des_str = des[0]; + + attr = __ns_ldap_getAttr(result->entry, _PROF_ATTRS); + if (attr == NULL || attr[0] == NULL || (strlen(attr[0]) < 1)) + attr_str = _NO_VALUE; + else + attr_str = attr[0]; + /* 5 = 4 ':' + 1 '\0' */ + len = strlen(name[0]) + strlen(res1_str) + strlen(res2_str) + + strlen(des_str) + strlen(attr_str) + 6; + if (len > buflen) { + nss_result = NSS_STR_PARSE_ERANGE; + goto result_prof2str; } -#endif /* DEBUG */ -result_prof2ent: + if (argp->buf.result != NULL) { + if ((be->buffer = calloc(1, len)) == NULL) { + nss_result = NSS_STR_PARSE_PARSE; + goto result_prof2str; + } + buffer = be->buffer; + } else + buffer = argp->buf.buffer; + (void) snprintf(buffer, len, "%s:%s:%s:%s:%s", + name[0], res1_str, res2_str, des_str, attr_str); + /* The front end marshaller doesn't need the trailing null */ + if (argp->buf.result != NULL) + be->buflen = strlen(be->buffer); + +result_prof2str: (void) __ns_ldap_freeResult(&be->result); - return ((int)nss_result); + return (nss_result); } @@ -204,10 +143,6 @@ getbyname(ldap_backend_ptr be, void *a) int ret; nss_XbyY_args_t *argp = (nss_XbyY_args_t *)a; -#ifdef DEBUG - (void) fprintf(stdout, "\n[getprofattr.c: getbyname]\n"); -#endif /* DEBUG */ - if (_ldap_filter_name(name, argp->key.name, sizeof (name)) != 0) return ((nss_status_t)NSS_NOTFOUND); @@ -243,11 +178,7 @@ _nss_ldap_prof_attr_constr(const char *dummy1, const char *dummy4, const char *dummy5) { -#ifdef DEBUG - (void) fprintf(stdout, - "\n[getprofattr.c: _nss_ldap_prof_attr_constr]\n"); -#endif return ((nss_backend_t *)_nss_ldap_constr(profattr_ops, sizeof (profattr_ops)/sizeof (profattr_ops[0]), _PROFATTR, - prof_attrs, _nss_ldap_prof2ent)); + prof_attrs, _nss_ldap_prof2str)); } diff --git a/usr/src/lib/nsswitch/ldap/common/getprojent.c b/usr/src/lib/nsswitch/ldap/common/getprojent.c index fd332209d8..f1ff6db64e 100644 --- a/usr/src/lib/nsswitch/ldap/common/getprojent.c +++ b/usr/src/lib/nsswitch/ldap/common/getprojent.c @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -20,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2004 Sun Microsystems, Inc. All rights reserved. + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -50,220 +49,96 @@ static const char *project_attrs[] = { (char *)NULL }; -static char * -gettok(char **nextpp, char sep) -{ - char *p = *nextpp; - char *q = p; - char c; - - if (p == NULL) - return (NULL); - while ((c = *q) != '\0' && c != sep) - q++; - if (c == '\0') - *nextpp = 0; - else { - *q++ = '\0'; - *nextpp = q; - } - return (p); -} - /* - * _nss_ldap_proj2ent is the data marshalling method for the project getXbyY + * _nss_ldap_proj2str is the data marshalling method for the project getXbyY * (getprojbyname, getprojbyid, getprojent) backend processes. This method * is called after a successful ldap search has been performed. This method - * will parse the ldap search values into struct project = argp->buf.buffer - * which the frontend routine expects. Three error conditions are expected - * and returned to nsswitch. + * will parse the ldap search values into the file format. + * e.g. + * + * system:0:System::: + * + * beatles:100:The Beatles:john,paul,george,ringo::task.max-lwps= + * (privileged,100,signal=SIGTERM),(privileged,110,deny) + * + * (All in one line) */ static int -_nss_ldap_proj2ent(ldap_backend_ptr be, nss_XbyY_args_t *argp) +_nss_ldap_proj2str(ldap_backend_ptr be, nss_XbyY_args_t *argp) { - int i, nss_result; + int nss_result, buflen; unsigned long len = 0; - char **uglist; - char *buffer, *ceiling; - char *users, *groups, *p; - struct project *proj; + char *buffer, *comment, *user_str, *group_str, *attr_str; ns_ldap_result_t *result = be->result; - ns_ldap_attr_t *attrptr; + char **name, **id, **descr, **users, **groups, **attr; + + if (result == NULL) + return (NSS_STR_PARSE_PARSE); + buflen = argp->buf.buflen; - buffer = argp->buf.buffer; - if (!argp->buf.result) { - nss_result = NSS_STR_PARSE_ERANGE; - goto result_proj2ent; - } - attrptr = getattr(result, 0); - if (attrptr == NULL) { - nss_result = NSS_STR_PARSE_PARSE; - goto result_proj2ent; - } nss_result = NSS_STR_PARSE_SUCCESS; - proj = argp->buf.result; - proj->pj_users = proj->pj_groups = NULL; - proj->pj_attr = proj->pj_comment = NULL; - ceiling = (char *)ROUND_DOWN(buffer + argp->buf.buflen, - sizeof (char *)); - (void) memset(argp->buf.buffer, 0, argp->buf.buflen); - for (i = 0; i < result->entry->attr_count; i++) { - attrptr = getattr(result, i); - if (attrptr == NULL) { - nss_result = NSS_STR_PARSE_PARSE; - goto result_proj2ent; - } - len = strlen(attrptr->attrvalue[0]); - if (strcasecmp(attrptr->attrname, _PROJ_NAME) == 0) { - if (len == 0) { - nss_result = NSS_STR_PARSE_PARSE; - goto result_proj2ent; - } - proj->pj_name = buffer; - buffer += len + 1; - if (buffer >= ceiling) { - nss_result = NSS_STR_PARSE_ERANGE; - goto result_proj2ent; - } - (void) strcpy(proj->pj_name, attrptr->attrvalue[0]); - continue; - } - if (strcasecmp(attrptr->attrname, _PROJ_PROJID) == 0) { - if (len == 0) { - nss_result = NSS_STR_PARSE_PARSE; - goto result_proj2ent; - } - errno = 0; - proj->pj_projid = - (projid_t)strtol(attrptr->attrvalue[0], - NULL, 10); - if (errno != 0) { - nss_result = NSS_STR_PARSE_PARSE; - goto result_proj2ent; - } - continue; - } - if (strcasecmp(attrptr->attrname, _PROJ_DESCR) == 0) { - proj->pj_comment = buffer; - buffer += len + 1; - if (buffer >= ceiling) { - nss_result = NSS_STR_PARSE_ERANGE; - goto result_proj2ent; - } - (void) strcpy(proj->pj_comment, attrptr->attrvalue[0]); - continue; - } - if (strcasecmp(attrptr->attrname, _PROJ_ATTR) == 0) { - proj->pj_attr = buffer; - buffer += len + 1; - if (buffer >= ceiling) { - nss_result = NSS_STR_PARSE_ERANGE; - goto result_proj2ent; - } - (void) strcpy(proj->pj_attr, attrptr->attrvalue[0]); - continue; - } - if (strcasecmp(attrptr->attrname, _PROJ_USERS) == 0) { - buffer = (char *)ROUND_UP(buffer, sizeof (char *)); - users = buffer; - buffer += len + 1; - if (buffer >= ceiling) { - nss_result = NSS_STR_PARSE_ERANGE; - goto result_proj2ent; - } - (void) strcpy(users, attrptr->attrvalue[0]); - buffer = (char *)ROUND_UP(buffer, sizeof (char *)); - if (buffer >= ceiling) { - nss_result = NSS_STR_PARSE_ERANGE; - goto result_proj2ent; - } - proj->pj_users = uglist = (char **)buffer; - *uglist = NULL; - while (uglist < (char **)ceiling) { - p = gettok(&users, ','); - if (p == NULL || *p == '\0') { - *uglist++ = 0; - break; - } - *uglist++ = p; - } - buffer = (char *)uglist; - if (buffer >= ceiling) - return (NSS_STR_PARSE_ERANGE); - continue; - } - if (strcasecmp(attrptr->attrname, _PROJ_GROUPS) == 0) { - buffer = (char *)ROUND_UP(buffer, sizeof (char *)); - groups = buffer; - buffer += len + 1; - if (buffer >= ceiling) { - nss_result = NSS_STR_PARSE_ERANGE; - goto result_proj2ent; - } - (void) strcpy(groups, attrptr->attrvalue[0]); - buffer = (char *)ROUND_UP(buffer, sizeof (char *)); - if (buffer >= ceiling) { - nss_result = NSS_STR_PARSE_ERANGE; - goto result_proj2ent; - } - proj->pj_groups = uglist = (char **)buffer; - *uglist = NULL; - while (uglist < (char **)ceiling) { - p = gettok(&groups, ','); - if (p == NULL || *p == '\0') { - *uglist++ = 0; - break; - } - *uglist++ = p; - } - buffer = (char *)uglist; - if (buffer >= ceiling) - return (NSS_STR_PARSE_ERANGE); - continue; - } - } - if (proj->pj_comment == NULL) { - buffer = (char *)ROUND_UP(buffer, sizeof (char *)); - if (buffer >= ceiling) { - nss_result = NSS_STR_PARSE_ERANGE; - goto result_proj2ent; - } - proj->pj_comment = buffer; - *buffer = '\0'; - buffer++; + (void) memset(argp->buf.buffer, 0, buflen); + + name = __ns_ldap_getAttr(result->entry, _PROJ_NAME); + if (name == NULL || name[0] == NULL || (strlen(name[0]) < 1)) { + nss_result = NSS_STR_PARSE_PARSE; + goto result_proj2str; } - if (proj->pj_users == NULL) { - buffer = (char *)ROUND_UP(buffer, sizeof (char *)); - if (buffer >= ceiling) { - nss_result = NSS_STR_PARSE_ERANGE; - goto result_proj2ent; - } - proj->pj_users = (char **)buffer; - *buffer = '\0'; - buffer++; + id = __ns_ldap_getAttr(result->entry, _PROJ_PROJID); + if (id == NULL || id[0] == NULL || (strlen(id[0]) < 1)) { + nss_result = NSS_STR_PARSE_PARSE; + goto result_proj2str; } - if (proj->pj_groups == NULL) { - buffer = (char *)ROUND_UP(buffer, sizeof (char *)); - if (buffer >= ceiling) { - nss_result = NSS_STR_PARSE_ERANGE; - goto result_proj2ent; - } - proj->pj_groups = (char **)buffer; - *buffer = '\0'; - buffer++; + descr = __ns_ldap_getAttr(result->entry, _PROJ_DESCR); + if (descr == NULL || descr[0] == NULL || (strlen(descr[0]) < 1)) + comment = _NO_VALUE; + + else + comment = descr[0]; + + users = __ns_ldap_getAttr(result->entry, _PROJ_USERS); + if (users == NULL || users[0] == NULL || (strlen(users[0]) < 1)) + user_str = _NO_VALUE; + + else + user_str = users[0]; + + groups = __ns_ldap_getAttr(result->entry, _PROJ_GROUPS); + if (groups == NULL || groups[0] == NULL || (strlen(groups[0]) < 1)) + group_str = _NO_VALUE; + + else + group_str = groups[0]; + + attr = __ns_ldap_getAttr(result->entry, _PROJ_ATTR); + if (attr == NULL || attr[0] == NULL || (strlen(attr[0]) < 1)) + attr_str = _NO_VALUE; + + else + attr_str = attr[0]; + + /* 6 = 5 ':' + 1 '\0' */ + len = strlen(name[0]) + strlen(id[0]) + strlen(comment) + + strlen(user_str) + strlen(group_str) + strlen(attr_str) + 6; + if (len >= buflen) { + nss_result = NSS_STR_PARSE_ERANGE; + goto result_proj2str; } - if (proj->pj_attr == NULL) { - buffer = (char *)ROUND_UP(buffer, sizeof (char *)); - if (buffer >= ceiling) { - nss_result = NSS_STR_PARSE_ERANGE; - goto result_proj2ent; + if (argp->buf.result != NULL) { + if ((be->buffer = calloc(1, len)) == NULL) { + nss_result = NSS_STR_PARSE_PARSE; + goto result_proj2str; } - proj->pj_attr = buffer; - *buffer = '\0'; - buffer++; - } + buffer = be->buffer; + /* The front end marshaller does not need trailing nulls */ + be->buflen = len - 1; + } else + buffer = argp->buf.buffer; + + (void) snprintf(buffer, len, "%s:%s:%s:%s:%s:%s", name[0], id[0], + comment, user_str, group_str, attr_str); -result_proj2ent: +result_proj2str: (void) __ns_ldap_freeResult(&be->result); return ((int)nss_result); } @@ -327,5 +202,5 @@ _nss_ldap_project_constr(const char *dummy1, const char *dummy2, { return (_nss_ldap_constr(project_ops, sizeof (project_ops) / sizeof (project_ops[0]), - _PROJECT, project_attrs, _nss_ldap_proj2ent)); + _PROJECT, project_attrs, _nss_ldap_proj2str)); } diff --git a/usr/src/lib/nsswitch/ldap/common/getprotoent.c b/usr/src/lib/nsswitch/ldap/common/getprotoent.c index 09522445e4..e9542a7543 100644 --- a/usr/src/lib/nsswitch/ldap/common/getprotoent.c +++ b/usr/src/lib/nsswitch/ldap/common/getprotoent.c @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -20,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2003 Sun Microsystems, Inc. All rights reserved. + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -47,181 +46,164 @@ static const char *protocols_attrs[] = { (char *)NULL }; +typedef struct protocol_alias { + char *protocol; + char *alias; +} protocol_alias_t; + +static const protocol_alias_t ip_aliases[10] = { + { "ip", "IP" }, + { "ipip", "IP-IP" }, + { "ipcomp", "IPComp" }, + { "ipv6", "IPv6" }, + { "ipv6-route", "IPv6-Route" }, + { "ipv6-frag", "IPv6-Frag" }, + { "ipv6-icmp", "IPv6-ICMP" }, + { "ipv6-nonxt", "IPv6-NoNxt" }, + { "ipv6-opts", "IPv6-Opts" }, + { NULL, NULL } +}; /* - * _nss_ldap_protocols2ent is the data marshaling method for the protocols + * When the data is imported by ldapaddent, it does not save the aliase in the + * "cn" that is same as the canonical name but only different in case. + * e.g. + * icmp 1 ICMP + * + * is saved as + * + * dn: cn=icmp, ... + * ... + * cn: icmp + * ... + * + * So it needs to replicate the canonical name as an alias of upper case. + * But some protocol does have different aliases. + * + * e.g. + * dn: cn=ospf, ... + * ... + * cn: ospf + * cn: OSPFIGP + * ... + * + * For many ip* protocols, the aliases are mixed cased. Maybe it's case + * insensitive. But this fucntion tries to restore the aliases to the original + * form as much as possible. If the alias can't be found in the aliases table, + * it assumes the alias is all upper case. + * + */ +static char * +get_alias(char *protocol) { + int i; + char *cp; + + if (strncmp(protocol, "ip", 2) == 0) { + for (i = 0; ip_aliases[i].protocol != NULL; i++) { + if (strcmp(protocol, ip_aliases[i].protocol) == 0) + return (ip_aliases[i].alias); + } + /* + * No aliase in the table. Return an all upper case aliase + */ + for (cp = protocol; *cp; cp++) + *cp = toupper(*cp); + + return (protocol); + } else { + /* Return an all upper case aliase */ + for (cp = protocol; *cp; cp++) + *cp = toupper(*cp); + + return (protocol); + } + +} +/* + * _nss_ldap_protocols2str is the data marshaling method for the protocols * getXbyY * (e.g., getbyname(), getbynumber(), getent()) backend processes. * This method is called after a successful ldap search has been performed. - * This method will parse the ldap search values into *proto = (struct - * protoent *)argp->buf.result which the frontend process expects. Three error - * conditions are expected and returned to nsswitch. + * This method will parse the ldap search values into a file format. + * e.g. + * idrp 45 IDRP + * or + * ospf 89 OSPFIGP */ static int -_nss_ldap_protocols2ent(ldap_backend_ptr be, nss_XbyY_args_t *argp) +_nss_ldap_protocols2str(ldap_backend_ptr be, nss_XbyY_args_t *argp) { - int i, j; + uint_t i; int nss_result; - int buflen = (int)0; - int firstime = (int)1; - unsigned long len = 0L; - char *cp, **mp, *cname = NULL; - char *buffer = (char *)NULL; - char *ceiling = (char *)NULL; - struct protoent *proto = (struct protoent *)NULL; + int buflen = 0, len; + char *cname = NULL; + char *buffer = NULL, **number, *alias; ns_ldap_result_t *result = be->result; - ns_ldap_attr_t *attrptr; + ns_ldap_attr_t *names; - buffer = (char *)argp->buf.buffer; - buflen = (size_t)argp->buf.buflen; - if (!argp->buf.result) { - nss_result = (int)NSS_STR_PARSE_ERANGE; - goto result_pls2ent; - } - proto = (struct protoent *)argp->buf.result; - ceiling = buffer + buflen; + if (result == NULL) + return (NSS_STR_PARSE_PARSE); - nss_result = (int)NSS_STR_PARSE_SUCCESS; + buflen = argp->buf.buflen; + if (argp->buf.result != NULL) { + if ((be->buffer = calloc(1, buflen)) == NULL) { + nss_result = NSS_STR_PARSE_PARSE; + goto result_pls2str; + } + buffer = be->buffer; + } else + buffer = argp->buf.buffer; + + nss_result = NSS_STR_PARSE_SUCCESS; (void) memset(argp->buf.buffer, 0, buflen); - attrptr = getattr(result, 0); - if (attrptr == NULL) { - nss_result = (int)NSS_STR_PARSE_PARSE; - goto result_pls2ent; + names = __ns_ldap_getAttrStruct(result->entry, _P_NAME); + if (names == NULL || names->attrvalue == NULL) { + nss_result = NSS_STR_PARSE_PARSE; + goto result_pls2str; } - for (i = 0; i < result->entry->attr_count; i++) { - attrptr = getattr(result, i); - if (attrptr == NULL) { - nss_result = (int)NSS_STR_PARSE_PARSE; - goto result_pls2ent; - } - if (strcasecmp(attrptr->attrname, _P_NAME) == 0) { - for (j = 0; j < attrptr->value_count; j++) { - if (firstime) { - /* protocol name */ - cname = __s_api_get_canonical_name( - result->entry, attrptr, 1); - if (cname == NULL || - (len = strlen(cname)) < 1) { - nss_result = - NSS_STR_PARSE_PARSE; - goto result_pls2ent; - } - proto->p_name = buffer; - buffer += len + 1; - if (buffer >= ceiling) { - nss_result = - (int)NSS_STR_PARSE_ERANGE; - goto result_pls2ent; - } - (void) strcpy(proto->p_name, cname); - mp = proto->p_aliases = - (char **)ROUND_UP(buffer, - sizeof (char **)); - buffer = (char *)proto->p_aliases + - sizeof (char *) * - (attrptr->value_count + 1); - buffer = (char *)ROUND_UP(buffer, - sizeof (char **)); - if (buffer >= ceiling) { - nss_result = - (int)NSS_STR_PARSE_ERANGE; - goto result_pls2ent; - } - firstime = (int)0; - } - /* alias list */ - if ((attrptr->attrvalue[j] == NULL) || - (len = strlen(attrptr->attrvalue[j])) < 1) { - nss_result = NSS_STR_PARSE_PARSE; - goto result_pls2ent; - } - /* - * When the data is imported by ldapaddent, - * it does not save the aliase in the "cn" - * that is same as the canonical name but only - * differnt in case. - * e.g. - * icmp 1 ICMP - * - * is saved as - * - * dn: cn=icmp, ... - * ... - * cn: icmp - * ... - * So it needs to replicate the canonical name - * as an aliase of upper case. - * - * But in the case of - * ospf 89 OSPFIGP - * it creates a redundant aliase. - * e.g. - * dn: cn=icmp, ... - * ... - * cn: ospf - * cn: OSPFIGP - * ... - * - * getent services ospf - * ==> ospf 89 ospf OSPFIGP - * - * Some condition check is added to handle this - * scenario. Such check also works with - * following scenario. - * dn: cn=icmp, ... - * ... - * cn: icmp - * cn: ICMP - * ... - */ - if (strcmp(proto->p_name, - attrptr->attrvalue[j]) == 0) { - if (attrptr->value_count > 1) - /* Do not replicate */ - continue; - for (cp = attrptr->attrvalue[j]; - *cp; cp++) - *cp = toupper(*cp); - } - *mp = buffer; - buffer += len + 1; - if (buffer >= ceiling) { - nss_result = (int)NSS_STR_PARSE_ERANGE; - goto result_pls2ent; - } - (void) strcpy(*mp++, attrptr->attrvalue[j]); - continue; - } - } - if (strcasecmp(attrptr->attrname, _P_PROTO) == 0) { - if ((attrptr->attrvalue[0] == NULL) || - (len = strlen(attrptr->attrvalue[0])) < 1) { - nss_result = (int)NSS_STR_PARSE_PARSE; - goto result_pls2ent; + /* Get the canonical name */ + cname = __s_api_get_canonical_name(result->entry, names, 1); + if (cname == NULL || (len = strlen(cname)) < 1) { + nss_result = NSS_STR_PARSE_PARSE; + goto result_pls2str; + } + number = __ns_ldap_getAttr(result->entry, _P_PROTO); + if (number == NULL || number[0] == NULL || + (len = strlen(number[0])) < 1) { + nss_result = NSS_STR_PARSE_PARSE; + goto result_pls2str; + } + len = snprintf(buffer, buflen, "%s %s", cname, number[0]); + TEST_AND_ADJUST(len, buffer, buflen, result_pls2str); + /* Append aliases */ + if (names->value_count == 1) { + /* create an aliase from protocol name */ + alias = get_alias(cname); + len = snprintf(buffer, buflen, " %s", alias); + TEST_AND_ADJUST(len, buffer, buflen, result_pls2str); + + } else { + for (i = 0; i < names->value_count; i++) { + if (names->attrvalue[i] == NULL) { + nss_result = NSS_STR_PARSE_PARSE; + goto result_pls2str; } - errno = 0; - proto->p_proto = (int)strtol(attrptr->attrvalue[0], - (char **)NULL, 10); - if (errno != 0) { - nss_result = (int)NSS_STR_PARSE_PARSE; - goto result_pls2ent; + /* Skip the canonical name */ + if (strcasecmp(names->attrvalue[i], cname) != 0) { + len = snprintf(buffer, buflen, " %s", + names->attrvalue[i]); + TEST_AND_ADJUST(len, buffer, buflen, + result_pls2str); } - continue; } } -#ifdef DEBUG - (void) fprintf(stdout, "\n[getprotoent.c: _nss_ldap_protocols2ent]\n"); - (void) fprintf(stdout, " p_name: [%s]\n", proto->p_name); - if (mp != NULL) { - for (mp = proto->p_aliases; *mp != NULL; mp++) - (void) fprintf(stdout, " p_aliases: [%s]\n", *mp); - } - (void) fprintf(stdout, " p_proto: [%d]\n", proto->p_proto); -#endif /* DEBUG */ + /* The front end marshaller doesn't need to copy trailing nulls */ + if (argp->buf.result != NULL) + be->buflen = strlen(be->buffer); -result_pls2ent: +result_pls2str: (void) __ns_ldap_freeResult(&be->result); return ((int)nss_result); @@ -323,5 +305,5 @@ _nss_ldap_protocols_constr(const char *dummy1, const char *dummy2, return ((nss_backend_t *)_nss_ldap_constr(proto_ops, sizeof (proto_ops)/sizeof (proto_ops[0]), _PROTOCOLS, - protocols_attrs, _nss_ldap_protocols2ent)); + protocols_attrs, _nss_ldap_protocols2str)); } diff --git a/usr/src/lib/nsswitch/ldap/common/getpwnam.c b/usr/src/lib/nsswitch/ldap/common/getpwnam.c index 205513812a..a2c9ff40c9 100644 --- a/usr/src/lib/nsswitch/ldap/common/getpwnam.c +++ b/usr/src/lib/nsswitch/ldap/common/getpwnam.c @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -20,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2003 Sun Microsystems, Inc. All rights reserved. + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -58,190 +57,106 @@ static const char *pwd_attrs[] = { (char *)NULL }; - /* - * _nss_ldap_passwd2ent is the data marshaling method for the passwd getXbyY + * _nss_ldap_passwd2str is the data marshaling method for the passwd getXbyY * (e.g., getbyuid(), getbyname(), getpwent()) backend processes. This method is * called after a successful ldap search has been performed. This method will - * parse the ldap search values into struct passwd = argp->buf.buffer which - * the frontend process expects. Three error conditions are expected and - * returned to nsswitch. + * parse the ldap search values into the file format. + * e.g. + * + * nobody:x:60001:60001:Nobody:/: + * */ - static int -_nss_ldap_passwd2ent(ldap_backend_ptr be, nss_XbyY_args_t *argp) +_nss_ldap_passwd2str(ldap_backend_ptr be, nss_XbyY_args_t *argp) { - int i = 0; int nss_result; - int buflen = (int)0; - unsigned long len = 0L; - char *buffer = (char *)NULL; - char *ptr2x; - char *ceiling = (char *)NULL; - char *nullstring = (char *)NULL; - struct passwd *pwd = (struct passwd *)NULL; + int buflen = 0; + unsigned long str_len = 0L; + char *buffer = NULL; ns_ldap_result_t *result = be->result; - ns_ldap_attr_t *attrptr; - int have_uid = 0; - int have_uidn = 0; - int have_gidn = 0; + ns_ldap_entry_t *entry; + char **uid_v, **uidn_v, **gidn_v; + char **gecos_v, **homedir_v, **shell_v; + char *NULL_STR = ""; + + if (result == NULL) + return (NSS_STR_PARSE_PARSE); -#ifdef DEBUG - (void) fprintf(stdout, "\n[getpwnam.c: _nss_ldap_passwd2ent]\n"); -#endif /* DEBUG */ + entry = result->entry; + buflen = argp->buf.buflen; buffer = argp->buf.buffer; - buflen = (size_t)argp->buf.buflen; - if (!argp->buf.result) { - nss_result = (int)NSS_STR_PARSE_ERANGE; - goto result_pwd2ent; - } - pwd = (struct passwd *)argp->buf.result; - ceiling = buffer + buflen; - nullstring = (buffer + (buflen - 1)); - nss_result = (int)NSS_STR_PARSE_SUCCESS; + nss_result = NSS_STR_PARSE_SUCCESS; (void) memset(buffer, 0, buflen); - /* - * need to always return password as "x" - * so put "x" at top of the buffer - */ - ptr2x = buffer; - *buffer++ = 'x'; - *buffer++ = '\0'; - - attrptr = getattr(result, 0); - if (attrptr == NULL) { - nss_result = (int)NSS_STR_PARSE_PARSE; - goto result_pwd2ent; - } - - pwd->pw_gecos = nullstring; - pwd->pw_dir = nullstring; - pwd->pw_shell = nullstring; + /* 8 = 6 ':' + 1 '\0' + 1 'x' */ + buflen -= 8; - for (i = 0; i < result->entry->attr_count; i++) { - attrptr = getattr(result, i); - if (attrptr == NULL) { - nss_result = (int)NSS_STR_PARSE_PARSE; - goto result_pwd2ent; - } - if (strcasecmp(attrptr->attrname, _PWD_UID) == 0) { - if ((attrptr->attrvalue[0] == NULL) || - (len = strlen(attrptr->attrvalue[0])) < 1) { - nss_result = (int)NSS_STR_PARSE_PARSE; - goto result_pwd2ent; - } - pwd->pw_name = buffer; - buffer += len + 1; - if (buffer >= ceiling) { - nss_result = (int)NSS_STR_PARSE_ERANGE; - goto result_pwd2ent; - } - (void) strcpy(pwd->pw_name, attrptr->attrvalue[0]); - have_uid = 1; - continue; - } - if (strcasecmp(attrptr->attrname, _PWD_UIDNUMBER) == 0) { - if (attrptr->attrvalue[0] == '\0') { - nss_result = (int)NSS_STR_PARSE_PARSE; - goto result_pwd2ent; - } - pwd->pw_uid = strtol(attrptr->attrvalue[0], - (char **)NULL, 10); - have_uidn = 1; - continue; - } - if (strcasecmp(attrptr->attrname, _PWD_GIDNUMBER) == 0) { - if (attrptr->attrvalue[0] == '\0') { - nss_result = (int)NSS_STR_PARSE_PARSE; - goto result_pwd2ent; - } - pwd->pw_gid = strtol(attrptr->attrvalue[0], - (char **)NULL, 10); - have_gidn = 1; - continue; - } - if ((strcasecmp(attrptr->attrname, _PWD_GECOS) == 0) && - (attrptr->value_count > 0)) { - if ((attrptr->attrvalue[0] == NULL) || - (len = strlen(attrptr->attrvalue[0])) < 1) { - pwd->pw_gecos = nullstring; - } else { - pwd->pw_gecos = buffer; - buffer += len + 1; - if (buffer >= ceiling) { - nss_result = (int)NSS_STR_PARSE_ERANGE; - goto result_pwd2ent; - } - (void) strcpy(pwd->pw_gecos, - attrptr->attrvalue[0]); - } - continue; - } - if ((strcasecmp(attrptr->attrname, _PWD_HOMEDIRECTORY) == 0) && - (attrptr->value_count > 0)) { - if ((attrptr->attrvalue[0] == NULL) || - (len = strlen(attrptr->attrvalue[0])) < 1) { - pwd->pw_dir = nullstring; - } else { - pwd->pw_dir = buffer; - buffer += len + 1; - if (buffer >= ceiling) { - nss_result = (int)NSS_STR_PARSE_ERANGE; - goto result_pwd2ent; - } - (void) strcpy(pwd->pw_dir, - attrptr->attrvalue[0]); - } - continue; - } - if ((strcasecmp(attrptr->attrname, _PWD_LOGINSHELL) == 0) && - (attrptr->value_count > 0)) { - if ((attrptr->attrvalue[0] == NULL) || - (len = strlen(attrptr->attrvalue[0])) < 1) { - pwd->pw_shell = nullstring; - } else { - pwd->pw_shell = buffer; - buffer += len + 1; - if (buffer >= ceiling) { - nss_result = (int)NSS_STR_PARSE_ERANGE; - goto result_pwd2ent; - } - (void) strcpy(pwd->pw_shell, - attrptr->attrvalue[0]); - } - continue; - } + uid_v = __ns_ldap_getAttr(entry, _PWD_UID); + uidn_v = __ns_ldap_getAttr(entry, _PWD_UIDNUMBER); + gidn_v = __ns_ldap_getAttr(entry, _PWD_GIDNUMBER); + if (uid_v == NULL || uidn_v == NULL || gidn_v == NULL || + uid_v[0] == NULL || uidn_v[0] == NULL || gidn_v[0] == NULL) { + nss_result = NSS_STR_PARSE_PARSE; + goto result_pwd2str; + } + str_len = strlen(uid_v[0]) + strlen(uidn_v[0]) + strlen(gidn_v[0]); + if (str_len > buflen) { + nss_result = NSS_STR_PARSE_ERANGE; + goto result_pwd2str; } - /* error if missing required attributes */ - if (have_uid == 0 || have_uidn == 0 || have_gidn == 0) { - nss_result = (int)NSS_STR_PARSE_PARSE; + gecos_v = __ns_ldap_getAttr(entry, _PWD_GECOS); + if (gecos_v == NULL || gecos_v[0] == NULL || *gecos_v[0] == '\0') + gecos_v = &NULL_STR; + else + str_len += strlen(gecos_v[0]); + + homedir_v = __ns_ldap_getAttr(entry, _PWD_HOMEDIRECTORY); + if (homedir_v == NULL || homedir_v[0] == NULL || *homedir_v[0] == '\0') + homedir_v = &NULL_STR; + else + str_len += strlen(homedir_v[0]); + + shell_v = __ns_ldap_getAttr(entry, _PWD_LOGINSHELL); + if (shell_v == NULL || shell_v[0] == NULL || *shell_v[0] == '\0') + shell_v = &NULL_STR; + else + str_len += strlen(shell_v[0]); + + if (str_len > buflen) { + nss_result = NSS_STR_PARSE_ERANGE; + goto result_pwd2str; } - pwd->pw_age = nullstring; - pwd->pw_comment = nullstring; - pwd->pw_passwd = ptr2x; + if (argp->buf.result != NULL) { + be->buflen = str_len + 8; + be->buffer = malloc(be->buflen); + if (be->buffer == NULL) { + nss_result = (int)NSS_STR_PARSE_ERANGE; + goto result_pwd2str; + } -#ifdef DEBUG - (void) fprintf(stdout, "\n[getpwnam.c: _nss_ldap_passwd2ent]\n"); - (void) fprintf(stdout, " pw_name: [%s]\n", pwd->pw_name); - (void) fprintf(stdout, " pw_uid: [%ld]\n", pwd->pw_uid); - (void) fprintf(stdout, " pw_gid: [%ld]\n", pwd->pw_gid); - (void) fprintf(stdout, " pw_gecos: [%s]\n", pwd->pw_gecos); - (void) fprintf(stdout, " pw_dir: [%s]\n", pwd->pw_dir); - (void) fprintf(stdout, " pw_shell: [%s]\n", pwd->pw_shell); -#endif /* DEBUG */ + (void) snprintf(be->buffer, be->buflen, + "%s:%s:%s:%s:%s:%s:%s", + uid_v[0], "x", uidn_v[0], gidn_v[0], + gecos_v[0], homedir_v[0], shell_v[0]); + } else { + (void) snprintf(argp->buf.buffer, (str_len + 8), + "%s:%s:%s:%s:%s:%s:%s", + uid_v[0], "x", uidn_v[0], gidn_v[0], + gecos_v[0], homedir_v[0], shell_v[0]); -result_pwd2ent: + } + +result_pwd2str: (void) __ns_ldap_freeResult(&be->result); return ((int)nss_result); } - /* * getbyname gets a passwd entry by uid name. This function constructs an ldap * search filter using the name invocation parameter and the getpwnam search @@ -259,10 +174,6 @@ getbyname(ldap_backend_ptr be, void *a) char name[SEARCHFILTERLEN]; int ret; -#ifdef DEBUG - (void) fprintf(stdout, "\n[getpwnam.c: getbyname]\n"); -#endif /* DEBUG */ - if (_ldap_filter_name(name, argp->key.name, sizeof (name)) != 0) return ((nss_status_t)NSS_NOTFOUND); @@ -296,10 +207,6 @@ getbyuid(ldap_backend_ptr be, void *a) char userdata[SEARCHFILTERLEN]; int ret; -#ifdef DEBUG - (void) fprintf(stdout, "\n[getpwnam.c: getbyuid]\n"); -#endif /* DEBUG */ - ret = snprintf(searchfilter, sizeof (searchfilter), _F_GETPWUID, (long)argp->key.uid); if (ret >= sizeof (searchfilter) || ret < 0) @@ -337,11 +244,7 @@ _nss_ldap_passwd_constr(const char *dummy1, const char *dummy2, const char *dummy3) { -#ifdef DEBUG - (void) fprintf(stdout, "\n[getpwnam.c: _nss_ldap_passwd_constr]\n"); -#endif /* DEBUG */ - return ((nss_backend_t *)_nss_ldap_constr(passwd_ops, sizeof (passwd_ops)/sizeof (passwd_ops[0]), - _PASSWD, pwd_attrs, _nss_ldap_passwd2ent)); + _PASSWD, pwd_attrs, _nss_ldap_passwd2str)); } diff --git a/usr/src/lib/nsswitch/ldap/common/getrpcent.c b/usr/src/lib/nsswitch/ldap/common/getrpcent.c index e8e0d51df3..3419d93fb6 100644 --- a/usr/src/lib/nsswitch/ldap/common/getrpcent.c +++ b/usr/src/lib/nsswitch/ldap/common/getrpcent.c @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -20,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2003 Sun Microsystems, Inc. All rights reserved. + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -47,144 +46,86 @@ static const char *rpc_attrs[] = { }; /* - * _nss_ldap_rpc2ent is the data marshaling method for the rpc getXbyY + * _nss_ldap_rpc2str is the data marshaling method for the rpc getXbyY * (e.g., getbyname(), getbynumber(), getrpcent()) backend processes. * This method is called after a successful ldap search has been performed. - * This method will parse the ldap search values into *rpc = (struct - * rpcent *)argp->buf.result which the frontend process expects. Three - * error conditions are expected and returned to nsswitch. + * This method will parse the ldap search values into the file format. + * e.g. + * + * nfs_acl 100227 + * snmp 100122 na.snmp snmp-cmc snmp-synoptics snmp-unisys snmp-utk */ - static int -_nss_ldap_rpc2ent(ldap_backend_ptr be, nss_XbyY_args_t *argp) +_nss_ldap_rpc2str(ldap_backend_ptr be, nss_XbyY_args_t *argp) { - int i, j; + uint_t i; int nss_result; - int buflen = (int)0; - int firstime = (int)1; - unsigned long len = 0L; - char **mp, *cname = NULL; - char *buffer = (char *)NULL; - char *ceiling = (char *)NULL; - struct rpcent *rpc = (struct rpcent *)NULL; + int buflen = 0, len; + char *cname = NULL; + char *buffer = NULL; ns_ldap_result_t *result = be->result; - ns_ldap_attr_t *attrptr; - - buffer = (char *)argp->buf.buffer; - buflen = (size_t)argp->buf.buflen; - if (!argp->buf.result) { - nss_result = (int)NSS_STR_PARSE_ERANGE; - goto result_rpc2ent; - } - rpc = (struct rpcent *)argp->buf.result; - ceiling = buffer + buflen; + ns_ldap_attr_t *names; + char **rpcnumber; - nss_result = (int)NSS_STR_PARSE_SUCCESS; + if (result == NULL) + return (NSS_STR_PARSE_PARSE); + nss_result = NSS_STR_PARSE_SUCCESS; (void) memset(argp->buf.buffer, 0, buflen); - attrptr = getattr(result, 0); - if (attrptr == NULL) { - nss_result = (int)NSS_STR_PARSE_PARSE; - goto result_rpc2ent; - } - for (i = 0; i < result->entry->attr_count; i++) { - attrptr = getattr(result, i); - if (attrptr == NULL) { - nss_result = (int)NSS_STR_PARSE_PARSE; - goto result_rpc2ent; + buflen = argp->buf.buflen; + if (argp->buf.result != NULL) { + if ((be->buffer = calloc(1, buflen)) == NULL) { + nss_result = NSS_STR_PARSE_PARSE; + goto result_rpc2str; } - if (strcasecmp(attrptr->attrname, _R_NAME) == 0) { - for (j = 0; j < attrptr->value_count; j++) { - /* traverse for all multivalued values */ - if (firstime) { - /* rpc name */ - cname = __s_api_get_canonical_name( - result->entry, attrptr, 1); - if (cname == NULL || - (len = strlen(cname)) < 1) { - nss_result = - NSS_STR_PARSE_PARSE; - goto result_rpc2ent; - } - rpc->r_name = buffer; - buffer += len + 1; - if (buffer >= ceiling) { - nss_result = - (int)NSS_STR_PARSE_ERANGE; - goto result_rpc2ent; - } - (void) strcpy(rpc->r_name, cname); - /* alias list */ - mp = rpc->r_aliases = - (char **)ROUND_UP(buffer, - sizeof (char **)); - buffer = (char *)rpc->r_aliases + - sizeof (char *) * - (attrptr->value_count + 1); - buffer = (char *)ROUND_UP(buffer, - sizeof (char **)); - if (buffer >= ceiling) { - nss_result = - (int)NSS_STR_PARSE_ERANGE; - goto result_rpc2ent; - } - firstime = (int)0; - } - /* alias list */ - if ((attrptr->attrvalue[j] == NULL) || - (len = strlen(attrptr->attrvalue[j])) < 1) { - nss_result = (int)NSS_STR_PARSE_PARSE; - goto result_rpc2ent; - } - /* skip canonical name */ - if (strcmp(attrptr->attrvalue[j], cname) == 0) - continue; - *mp = buffer; - buffer += len + 1; - if (buffer >= ceiling) { - nss_result = (int)NSS_STR_PARSE_ERANGE; - goto result_rpc2ent; - } - (void) strcpy(*mp++, attrptr->attrvalue[j]); - continue; - } + buffer = be->buffer; + } else + buffer = argp->buf.buffer; + + + names = __ns_ldap_getAttrStruct(result->entry, _R_NAME); + if (names == NULL || names->attrvalue == NULL) { + nss_result = NSS_STR_PARSE_PARSE; + goto result_rpc2str; + } + /* Get the canonical rpc name */ + cname = __s_api_get_canonical_name(result->entry, names, 1); + if (cname == NULL || (len = strlen(cname)) < 1) { + nss_result = NSS_STR_PARSE_PARSE; + goto result_rpc2str; + } + rpcnumber = __ns_ldap_getAttr(result->entry, _R_NUMBER); + if (rpcnumber == NULL || rpcnumber[0] == NULL || + (len = strlen(rpcnumber[0])) < 1) { + nss_result = NSS_STR_PARSE_PARSE; + goto result_rpc2str; + } + len = snprintf(buffer, buflen, "%s %s", cname, rpcnumber[0]); + TEST_AND_ADJUST(len, buffer, buflen, result_rpc2str); + /* Append aliases */ + for (i = 0; i < names->value_count; i++) { + if (names->attrvalue[i] == NULL) { + nss_result = NSS_STR_PARSE_PARSE; + goto result_rpc2str; } - if (strcasecmp(attrptr->attrname, _R_NUMBER) == 0) { - if ((attrptr->attrvalue[0] == NULL) || - (len = strlen(attrptr->attrvalue[0])) < 1) { - nss_result = (int)NSS_STR_PARSE_PARSE; - goto result_rpc2ent; - } - errno = 0; - rpc->r_number = (int)strtol(attrptr->attrvalue[0], - (char **)NULL, 10); - if (errno != 0) { - nss_result = (int)NSS_STR_PARSE_PARSE; - goto result_rpc2ent; - } - continue; + /* Skip the canonical name */ + if (strcasecmp(names->attrvalue[i], cname) != 0) { + len = snprintf(buffer, buflen, " %s", + names->attrvalue[i]); + TEST_AND_ADJUST(len, buffer, buflen, result_rpc2str); } } - if (mp != NULL) - *mp = NULL; - -#ifdef DEBUG - (void) fprintf(stdout, "\n[getrpcent.c: _nss_ldap_rpc2ent]\n"); - (void) fprintf(stdout, " r_name: [%s]\n", rpc->r_name); - if (mp != NULL) { - for (mp = rpc->r_aliases; *mp != NULL; mp++) - (void) fprintf(stdout, " r_aliases: [%s]\n", *mp); - } - (void) fprintf(stdout, " r_number: [%d]\n", rpc->r_number); -#endif /* DEBUG */ -result_rpc2ent: + /* The front end marshaller doesn't need to copy trailing nulls */ + if (argp->buf.result != NULL) + be->buflen = strlen(be->buffer); + +result_rpc2str: (void) __ns_ldap_freeResult(&be->result); - return ((int)nss_result); + return (nss_result); } - /* * getbyname gets struct rpcent values by rpc name. This function * constructs an ldap search filter using the rpc name invocation @@ -276,5 +217,5 @@ _nss_ldap_rpc_constr(const char *dummy1, const char *dummy2, return ((nss_backend_t *)_nss_ldap_constr(rpc_ops, sizeof (rpc_ops)/sizeof (rpc_ops[0]), - _RPC, rpc_attrs, _nss_ldap_rpc2ent)); + _RPC, rpc_attrs, _nss_ldap_rpc2str)); } diff --git a/usr/src/lib/nsswitch/ldap/common/getservent.c b/usr/src/lib/nsswitch/ldap/common/getservent.c index e266a31b42..9d83298fbc 100644 --- a/usr/src/lib/nsswitch/ldap/common/getservent.c +++ b/usr/src/lib/nsswitch/ldap/common/getservent.c @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -20,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2003 Sun Microsystems, Inc. All rights reserved. + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -91,14 +90,15 @@ _nss_services_cookie_new(ns_ldap_result_t *result, int index, char *cname) { return (cookie); } - /* - * _nss_ldap_services2ent is the data marshaling method for the services + * _nss_ldap_services2str is the data marshaling method for the services * getXbyY * (e.g., getbyname(), getbyport(), getent()) backend processes. * This method is called after a successful ldap search has been performed. - * This method will parse the ldap search values into *serv = (struct - * servent *)argp->buf.result which the frontend process expects. Three error - * conditions are expected and returned to nsswitch. + * This method will parse the ldap search values into the file format. + * e.g. + * + * nfsd 2049/udp nfs + * nfsd 2049/tcp nfs * * In section 5.5 of RFC 2307, it specifies that a "services" LDAP entry * containing multiple ipserviceprotocol values should be able to be mapped @@ -107,30 +107,18 @@ _nss_services_cookie_new(ns_ldap_result_t *result, int index, char *cname) { */ static int -_nss_ldap_services2ent(ldap_backend_ptr be, nss_XbyY_args_t *argp) +_nss_ldap_services2str(ldap_backend_ptr be, nss_XbyY_args_t *argp) { - int i, j, k; + uint_t i, k; int nss_result; - int buflen = (int)0; - int firstime = (int)1; - unsigned long len = 0L; - char **mp, *cname = NULL, *protoval = NULL; - char *buffer = (char *)NULL; - char *ceiling = (char *)NULL; - struct servent *serv = (struct servent *)NULL; + int buflen = 0, len; + char **ipport, *cname = NULL, *protoval = NULL; + char *buffer = NULL; ns_ldap_result_t *result; - ns_ldap_attr_t *attrptr, *protocol = NULL; + ns_ldap_attr_t *names = NULL, *protocol = NULL; _nss_services_cookie_t *cookie = (_nss_services_cookie_t *) be->services_cookie; - buffer = (char *)argp->buf.buffer; - buflen = (size_t)argp->buf.buflen; - serv = (struct servent *)argp->buf.result; - ceiling = buffer + buflen; -#ifdef DEBUG - (void) fprintf(stderr, "[getservent.c: _nss_ldap_services2ent]\n"); -#endif /* DEBUG */ - if (cookie) { /* * getservent_r with multiple protocol values and the entry @@ -146,160 +134,123 @@ _nss_ldap_services2ent(ldap_backend_ptr be, nss_XbyY_args_t *argp) */ result = be->result; } + if (result == NULL) { + nss_result = NSS_STR_PARSE_PARSE; + goto result_srvs2str; + } + + buflen = argp->buf.buflen; + if (argp->buf.result != NULL) { + if ((be->buffer = calloc(1, buflen)) == NULL) { + nss_result = NSS_STR_PARSE_PARSE; + goto result_srvs2str; + } + buffer = be->buffer; + } else + buffer = argp->buf.buffer; + - nss_result = (int)NSS_STR_PARSE_SUCCESS; + nss_result = NSS_STR_PARSE_SUCCESS; (void) memset(argp->buf.buffer, 0, buflen); - attrptr = getattr(result, 0); - if (attrptr == NULL) { - nss_result = (int)NSS_STR_PARSE_PARSE; - goto result_srvs2ent; + /* Get services names */ + names = __ns_ldap_getAttrStruct(result->entry, _S_NAME); + if (names == NULL || names->attrvalue == NULL) { + nss_result = NSS_STR_PARSE_PARSE; + goto result_srvs2str; + } + /* Get canonical services name */ + if (cname == NULL) { + cname = __s_api_get_canonical_name(result->entry, names, 1); + if (cname == NULL || (len = strlen(cname)) < 1) { + nss_result = NSS_STR_PARSE_PARSE; + goto result_srvs2str; + } + } + /* Get port */ + ipport = __ns_ldap_getAttr(result->entry, _S_PORT); + if (ipport == NULL || ipport[0] == NULL || + (len = strlen(cname)) < 1) { + nss_result = NSS_STR_PARSE_PARSE; + goto result_srvs2str; + } + /* Set services name and port and '/' */ + len = snprintf(buffer, buflen, "%s %s/", cname, ipport[0]); + TEST_AND_ADJUST(len, buffer, buflen, result_srvs2str); + + /* Get protocol */ + protocol = __ns_ldap_getAttrStruct(result->entry, _S_PROTOCOL); + if (protocol == NULL || protocol->attrvalue == NULL) { + nss_result = NSS_STR_PARSE_PARSE; + goto result_srvs2str; } - for (i = 0; i < result->entry->attr_count; i++) { - attrptr = getattr(result, i); - if (attrptr == NULL) { - nss_result = (int)NSS_STR_PARSE_PARSE; - goto result_srvs2ent; - } - if (strcasecmp(attrptr->attrname, _S_NAME) == 0) { - for (j = 0; j < attrptr->value_count; j++) { - if (firstime) { - /* service name */ - if (cname == NULL) { - cname = __s_api_get_canonical_name( - result->entry, attrptr, 1); - } - if (cname == NULL || - (len = strlen(cname)) < 1) { - nss_result = - NSS_STR_PARSE_PARSE; - goto result_srvs2ent; - } - serv->s_name = buffer; - buffer += len + 1; - if (buffer >= ceiling) { - nss_result = - (int)NSS_STR_PARSE_ERANGE; - goto result_srvs2ent; - } - (void) strcpy(serv->s_name, cname); - /* alias list */ - mp = serv->s_aliases = - (char **)ROUND_UP(buffer, - sizeof (char **)); - buffer = (char *)serv->s_aliases + - sizeof (char *) * - (attrptr->value_count + 1); - buffer = (char *)ROUND_UP(buffer, - sizeof (char **)); - if (buffer >= ceiling) { - nss_result = - (int)NSS_STR_PARSE_ERANGE; - goto result_srvs2ent; - } - firstime = (int)0; - } - /* alias list */ - if ((attrptr->attrvalue[j] == NULL) || - (len = strlen(attrptr->attrvalue[j])) < 1) { - nss_result = (int)NSS_STR_PARSE_PARSE; - goto result_srvs2ent; - } - /* skip canonical name */ - if (strcmp(cname, attrptr->attrvalue[j]) == 0) - continue; - - *mp = buffer; - buffer += len + 1; - if (buffer >= ceiling) { - nss_result = (int)NSS_STR_PARSE_ERANGE; - goto result_srvs2ent; - } - (void) strcpy(*mp++, attrptr->attrvalue[j]); - continue; - } - } - if (strcasecmp(attrptr->attrname, _S_PORT) == 0) { - if ((attrptr->attrvalue[0] == NULL) || - (len = strlen(attrptr->attrvalue[0])) < 1) { - nss_result = (int)NSS_STR_PARSE_PARSE; - goto result_srvs2ent; + if (cookie) { + /* + * getservent_r + * Get current value then increment index + */ + protoval = protocol->attrvalue[cookie->index++]; + } else if (protocol->value_count > 1 && be->setcalled == 0 && + argp->key.serv.proto) { + /* + * getserverbyname_r and getservbyport_r + * + * If there are more than one value and + * it needs to match protocol too, + * iterate each value to find matching one. + */ + for (k = 0; k < protocol->value_count; k++) { + if (protocol->attrvalue[k] == NULL) { + nss_result = NSS_STR_PARSE_PARSE; + goto result_srvs2str; + } + if (strcmp(protocol->attrvalue[k], + argp->key.serv.proto) == 0) { + protoval = protocol->attrvalue[k]; + break; } - serv->s_port = - htons((ushort_t)atoi(attrptr->attrvalue[0])); - continue; } + } else { + /* + * 1. getserverbyname_r and getservbyport_r + * + * It does not need to match protocol or + * ipserviceprotocol has single value, + * return the first one. + * + * 2. getservent_r with single ipserviceprotocol value + * or multiple values and the entry is + * enumerated 1st time, return the first one. + * + */ + protoval = protocol->attrvalue[0]; + } - if (strcasecmp(attrptr->attrname, _S_PROTOCOL) == 0) { - /* protocol name */ - if (attrptr->attrvalue == NULL) { - nss_result = (int)NSS_STR_PARSE_PARSE; - goto result_srvs2ent; - } - protocol = attrptr; - if (cookie) { - /* - * getservent_r - * Get current value then increment index - */ - protoval = attrptr->attrvalue[cookie->index++]; - } else if (attrptr->value_count > 1 && - argp->key.serv.proto) { - /* - * getserverbyname_r and getservbyport_r - * - * If there are more than one value and - * it needs to match protocol too, - * iterate each value to find matching one. - * getservent_r sets key.serv.proto to NULL, - * so it wouldn't run this part of code. - */ - for (k = 0; k < attrptr->value_count; k++) { - if (attrptr->attrvalue[k] == NULL) { - nss_result = - NSS_STR_PARSE_PARSE; - goto result_srvs2ent; - } - if (strcmp(attrptr->attrvalue[k], - argp->key.serv.proto) == 0) { - protoval = - attrptr->attrvalue[k]; - break; - } - } - } else { - /* - * 1. getserverbyname_r and getservbyport_r - * - * It does not need to match protocol or - * ipserviceprotocol has single value, - * return the first one - * - * 2. getservent_r with single value - * or multiple values and the entry is - * enumerated 1st time, - * return the first one - * - */ - protoval = attrptr->attrvalue[0]; - } + if (protoval == NULL || (len = strlen(protoval)) < 1) { + nss_result = NSS_STR_PARSE_PARSE; + goto result_srvs2str; + } - if (protoval == NULL || (len = strlen(protoval)) < 1) { - nss_result = (int)NSS_STR_PARSE_PARSE; - goto result_srvs2ent; - } - serv->s_proto = buffer; - buffer += len + 1; - if (buffer >= ceiling) { - nss_result = (int)NSS_STR_PARSE_ERANGE; - goto result_srvs2ent; - } - (void) strcpy(serv->s_proto, protoval); - continue; + /* Set protocol */ + len = snprintf(buffer, buflen, "%s", protoval); + TEST_AND_ADJUST(len, buffer, buflen, result_srvs2str); + + /* Append aliases */ + for (i = 0; i < names->value_count; i++) { + if (names->attrvalue[i] == NULL) { + nss_result = NSS_STR_PARSE_PARSE; + goto result_srvs2str; + } + /* Skip the canonical name */ + if (strcmp(cname, names->attrvalue[i]) != 0) { + len = snprintf(buffer, buflen, " %s", + names->attrvalue[i]); + TEST_AND_ADJUST(len, buffer, buflen, result_srvs2str); } } + if (be->enumcookie != NULL && cookie == NULL && protocol->value_count > 1) { /* @@ -314,25 +265,18 @@ _nss_ldap_services2ent(ldap_backend_ptr be, nss_XbyY_args_t *argp) (void *)_nss_services_cookie_new(be->result, 1, cname); if (be->services_cookie == NULL) { nss_result = NSS_STR_PARSE_PARSE; - goto result_srvs2ent; + goto result_srvs2str; } /* reset be->result so it won't get freed later */ be->result = NULL; } -#ifdef DEBUG - (void) fprintf(stdout, "\n[getservent.c: _nss_ldap_services2ent]\n"); - (void) fprintf(stdout, " s_name: [%s]\n", serv->s_name); - if (mp != NULL) { - for (mp = serv->s_aliases; *mp != NULL; mp++) - (void) fprintf(stdout, " s_aliases: [%s]\n", *mp); - } - (void) fprintf(stdout, " s_port: [%d]\n", serv->s_port); - (void) fprintf(stdout, " s_protocol: [%s]\n", serv->s_proto); -#endif /* DEBUG */ + /* The front end marshaller doesn't need to copy trailing nulls */ + if (argp->buf.result != NULL) + be->buflen = strlen(be->buffer); -result_srvs2ent: +result_srvs2str: if (cookie) { /* * getservent_r with multiple ipserviceprotocol values and @@ -356,10 +300,9 @@ result_srvs2ent: */ (void) __ns_ldap_freeResult(&be->result); } - return ((int)nss_result); + return (nss_result); } - /* * getbyname gets struct servent values by service name. This * function constructs an ldap search filter using the service @@ -498,5 +441,5 @@ _nss_ldap_services_constr(const char *dummy1, const char *dummy2, return ((nss_backend_t *)_nss_ldap_constr(serv_ops, sizeof (serv_ops)/sizeof (serv_ops[0]), _SERVICES, - services_attrs, _nss_ldap_services2ent)); + services_attrs, _nss_ldap_services2str)); } diff --git a/usr/src/lib/nsswitch/ldap/common/getspent.c b/usr/src/lib/nsswitch/ldap/common/getspent.c index cf5ea84652..dc93c5d9ca 100644 --- a/usr/src/lib/nsswitch/ldap/common/getspent.c +++ b/usr/src/lib/nsswitch/ldap/common/getspent.c @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -20,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2003 Sun Microsystems, Inc. All rights reserved. + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -31,7 +30,6 @@ #include "ldap_common.h" /* shadow attributes filters */ -#define _S_CN "cn" #define _S_UID "uid" #define _S_USERPASSWORD "userpassword" #define _S_FLAG "shadowflag" @@ -46,185 +44,105 @@ static const char *sp_attrs[] = { (char *)NULL }; - -extern ns_ldap_attr_t *getattr(ns_ldap_result_t *result, int i); - /* - * _nss_ldap_shadow2ent is the data marshaling method for the passwd getXbyY + * _nss_ldap_shadow2str is the data marshaling method for the shadow getXbyY * (e.g., getspnam(), getspent()) backend processes. This method is called after * a successful ldap search has been performed. This method will parse the - * ldap search values into struct spwd = argp->buf.buffer which the frontend - * process expects. Three error conditions are expected and returned to - * nsswitch. + * ldap search values into the file format. + * e.g. + * + * myname:gaBXNJuz4JDmA:6445:::::: + * */ static int -_nss_ldap_shadow2ent(ldap_backend_ptr be, nss_XbyY_args_t *argp) +_nss_ldap_shadow2str(ldap_backend_ptr be, nss_XbyY_args_t *argp) { - int i = 0; int nss_result; - int buflen = (int)0; + int buflen = 0; unsigned long len = 0L; - char *buffer = (char *)NULL; - char *ceiling = (char *)NULL; - char *pw_passwd = (char *)NULL; - char *nullstring = (char *)NULL; + char *tmp, *buffer = NULL; + char *pw_passwd = NULL; char np[] = "*NP*"; ns_ldap_result_t *result = be->result; - ns_ldap_attr_t *attrptr; - long ltmp = (long)0L; - struct spwd *spd = (struct spwd *)NULL; - -#ifdef DEBUG - (void) fprintf(stdout, "\n[getspent.c: _nss_ldap_shadow2ent]\n"); -#endif /* DEBUG */ + char **uid, **passwd, **flag, *flag_str; - buffer = argp->buf.buffer; - buflen = (size_t)argp->buf.buflen; - if (!argp->buf.result) { - nss_result = (int)NSS_STR_PARSE_ERANGE; - goto result_spd2ent; - } - spd = (struct spwd *)argp->buf.result; - ceiling = buffer + buflen; - nullstring = (buffer + (buflen - 1)); - - /* Default values */ - spd->sp_lstchg = -1; spd->sp_min = -1; - spd->sp_max = -1; spd->sp_warn = -1; - spd->sp_inact = -1; spd->sp_expire = -1; - spd->sp_flag = 0; spd->sp_pwdp = NULL; + if (result == NULL) + return (NSS_STR_PARSE_PARSE); + buflen = argp->buf.buflen; - nss_result = (int)NSS_STR_PARSE_SUCCESS; - (void) memset(buffer, 0, buflen); + nss_result = NSS_STR_PARSE_SUCCESS; + (void) memset(argp->buf.buffer, 0, buflen); - attrptr = getattr(result, 0); - if (attrptr == NULL) { - nss_result = (int)NSS_STR_PARSE_PARSE; - goto result_spd2ent; + uid = __ns_ldap_getAttr(result->entry, _S_UID); + if (uid == NULL || uid[0] == NULL || (strlen(uid[0]) < 1)) { + nss_result = NSS_STR_PARSE_PARSE; + goto result_spd2str; } - - for (i = 0; i < result->entry->attr_count; i++) { - attrptr = getattr(result, i); - if (strcasecmp(attrptr->attrname, _S_UID) == 0) { - if ((attrptr->attrvalue[0] == NULL) || - (len = strlen(attrptr->attrvalue[0])) < 1) { - nss_result = (int)NSS_STR_PARSE_PARSE; - goto result_spd2ent; - } - spd->sp_namp = buffer; - buffer += len + 1; - if (buffer >= ceiling) { - nss_result = (int)NSS_STR_PARSE_ERANGE; - goto result_spd2ent; - } - (void) strcpy(spd->sp_namp, attrptr->attrvalue[0]); - continue; - } - if (strcasecmp(attrptr->attrname, _S_USERPASSWORD) == 0) { - if (attrptr->attrvalue[0] == '\0') { - spd->sp_pwdp = nullstring; - nss_result = (int)NSS_STR_PARSE_PARSE; - goto result_spd2ent; - } - pw_passwd = attrptr->attrvalue[0]; - if (pw_passwd) { - char *tmp; - - if ((tmp = strstr(pw_passwd, "{crypt}")) - != NULL) { - if (tmp != pw_passwd) - pw_passwd = np; - else - pw_passwd += 7; - } else if ((tmp = strstr(pw_passwd, "{CRYPT}")) - != NULL) { - if (tmp != pw_passwd) - pw_passwd = np; - else - pw_passwd += 7; - } else { - pw_passwd = np; - } - } - len = (unsigned long)strlen(pw_passwd); - if (len < 1) { - spd->sp_pwdp = nullstring; - } else { - spd->sp_pwdp = buffer; - buffer += len + 1; - if (buffer >= ceiling) { - nss_result = (int)NSS_STR_PARSE_ERANGE; - goto result_spd2ent; - } - } - (void) strcpy(spd->sp_pwdp, pw_passwd); - } - - /* - * Ignore the following password aging related attributes: - * -- shadowlastchange - * -- shadowmin - * -- shadowmax - * -- shadowwarning - * -- shadowinactive - * -- shadowexpire - * This is because the LDAP naming service does not - * really support the password aging fields defined - * in the shadow structure. These fields, sp_lstchg, - * sp_min, sp_max, sp_warn, sp_inact, and sp_expire, - * have been set to -1. - */ - - if (strcasecmp(attrptr->attrname, _S_FLAG) == 0) { - if (attrptr->attrvalue[0] == '\0') { - nss_result = (int)NSS_STR_PARSE_PARSE; - goto result_spd2ent; - } - errno = 0; - ltmp = strtol(attrptr->attrvalue[0], (char **)NULL, 10); - if (errno != 0) { - nss_result = (int)NSS_STR_PARSE_PARSE; - goto result_spd2ent; - } - spd->sp_flag = (int)ltmp; - continue; + len += strlen(uid[0]); + + passwd = __ns_ldap_getAttr(result->entry, _S_USERPASSWORD); + if (passwd == NULL || passwd[0] == NULL || strlen(passwd[0]) < 1) { + pw_passwd = _NO_VALUE; + } else { + if ((tmp = strstr(passwd[0], "{crypt}")) != NULL || + (tmp = strstr(passwd[0], "{CRYPT}")) != NULL) { + if (tmp != passwd[0]) + pw_passwd = np; + else + pw_passwd = tmp + strlen("{crypt}"); + } else { + /* Replace it with *NP* */ + pw_passwd = np; } } - - /* we will not allow for an empty password to be */ - /* returned to the front end as this is not a supported */ - /* configuration. Since we got to this point without */ - /* the password being set, we assume that no password was */ - /* set on the server which is consider a misconfiguration. */ - /* We will proceed and set the password to *NP* as no password */ - /* is not supported */ - - if (spd->sp_pwdp == NULL) { - spd->sp_pwdp = buffer; - buffer += strlen(np) + 1; - if (buffer >= ceiling) { - nss_result = (int)NSS_STR_PARSE_ERANGE; - goto result_spd2ent; - } - strcpy(spd->sp_pwdp, np); + len += strlen(pw_passwd); + + /* + * Ignore the following password aging related attributes: + * -- shadowlastchange + * -- shadowmin + * -- shadowmax + * -- shadowwarning + * -- shadowinactive + * -- shadowexpire + * This is because the LDAP naming service does not + * really support the password aging fields defined + * in the shadow structure. These fields, sp_lstchg, + * sp_min, sp_max, sp_warn, sp_inact, and sp_expire, + * will be set to -1 by the front end marshaller. + */ + flag = __ns_ldap_getAttr(result->entry, _S_FLAG); + if (flag == NULL || flag[0] == NULL) + flag_str = _NO_VALUE; + else + flag_str = flag[0]; + + /* 9 = 8 ':' + 1 '\0' */ + len += strlen(flag_str) + 9; + + if (len > buflen) { + nss_result = NSS_STR_PARSE_ERANGE; + goto result_spd2str; } + if (argp->buf.result != NULL) { + be->buffer = calloc(1, len); + if (be->buffer == NULL) { + nss_result = NSS_STR_PARSE_PARSE; + goto result_spd2str; + } + buffer = be->buffer; + } else + buffer = argp->buf.buffer; -#ifdef DEBUG - (void) fprintf(stdout, "\n[getspent.c: _nss_ldap_shadow2ent]\n"); - (void) fprintf(stdout, " sp_namp: [%s]\n", spd->sp_namp); - (void) fprintf(stdout, " sp_pwdp: [%s]\n", spd->sp_pwdp); - (void) fprintf(stdout, " sp_latchg: [%d]\n", spd->sp_lstchg); - (void) fprintf(stdout, " sp_min: [%d]\n", spd->sp_min); - (void) fprintf(stdout, " sp_max: [%d]\n", spd->sp_max); - (void) fprintf(stdout, " sp_warn: [%d]\n", spd->sp_warn); - (void) fprintf(stdout, " sp_inact: [%d]\n", spd->sp_inact); - (void) fprintf(stdout, " sp_expire: [%d]\n", spd->sp_expire); - (void) fprintf(stdout, " sp_flag: [%d]\n", spd->sp_flag); -#endif /* DEBUG */ + (void) snprintf(buffer, len, "%s:%s:::::::%s", + uid[0], pw_passwd, flag_str); -result_spd2ent: + /* The front end marhsaller doesn't need the trailing null */ + if (argp->buf.result != NULL) + be->buflen = strlen(be->buffer); +result_spd2str: (void) __ns_ldap_freeResult(&be->result); return ((int)nss_result); @@ -245,13 +163,8 @@ getbynam(ldap_backend_ptr be, void *a) char searchfilter[SEARCHFILTERLEN]; char userdata[SEARCHFILTERLEN]; char name[SEARCHFILTERLEN + 1]; - int len; int ret; -#ifdef DEBUG - (void) fprintf(stdout, "\n[getspent.c: getbynam]\n"); -#endif /* DEBUG */ - if (_ldap_filter_name(name, argp->key.name, sizeof (name)) != 0) return ((nss_status_t)NSS_NOTFOUND); @@ -288,11 +201,7 @@ _nss_ldap_shadow_constr(const char *dummy1, const char *dummy2, const char *dummy3) { -#ifdef DEBUG - (void) fprintf(stdout, "\n[getspent.c: _nss_ldap_shadow_constr]\n"); -#endif /* DEBUG */ - return ((nss_backend_t *)_nss_ldap_constr(sp_ops, sizeof (sp_ops)/sizeof (sp_ops[0]), - _SHADOW, sp_attrs, _nss_ldap_shadow2ent)); + _SHADOW, sp_attrs, _nss_ldap_shadow2str)); } diff --git a/usr/src/lib/nsswitch/ldap/common/getuserattr.c b/usr/src/lib/nsswitch/ldap/common/getuserattr.c index d36194d27e..c804a92187 100644 --- a/usr/src/lib/nsswitch/ldap/common/getuserattr.c +++ b/usr/src/lib/nsswitch/ldap/common/getuserattr.c @@ -2,9 +2,8 @@ * CDDL HEADER START * * The contents of this file are subject to the terms of the - * Common Development and Distribution License, Version 1.0 only - * (the "License"). You may not use this file except in compliance - * with the License. + * Common Development and Distribution License (the "License"). + * You may not use this file except in compliance with the License. * * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE * or http://www.opensolaris.org/os/licensing. @@ -20,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 2003 Sun Microsystems, Inc. All rights reserved. + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -50,149 +49,87 @@ static const char *user_attrs[] = { _USER_ATTRS, (char *)NULL }; - - +/* + * _nss_ldap_user2str is the data marshaling method for the user_attr + * system call getuserattr, getusernam and getuseruid. + * This method is called after a successful search has been performed. + * This method will parse the search results into the file format. + * e.g. + * + * adm::::profiles=Log Management + * + */ static int -_nss_ldap_user2ent(ldap_backend_ptr be, nss_XbyY_args_t *argp) +_nss_ldap_user2str(ldap_backend_ptr be, nss_XbyY_args_t *argp) { - int i, nss_result; - int buflen = (int)0; + int nss_result; + int buflen = 0; unsigned long len = 0L; - char *nullstring = (char *)NULL; - char *buffer = (char *)NULL; - char *ceiling = (char *)NULL; - userstr_t *user = (userstr_t *)NULL; - ns_ldap_attr_t *attrptr; + char *buffer = NULL; ns_ldap_result_t *result = be->result; + char **name, **res1, **res2, **qu, **attr; + char *res1_str, *res2_str, *qu_str, *attr_str; - buffer = argp->buf.buffer; - buflen = (size_t)argp->buf.buflen; - if (!argp->buf.result) { - nss_result = (int)NSS_STR_PARSE_ERANGE; - goto result_user2ent; - } - user = (userstr_t *)(argp->buf.result); - ceiling = buffer + buflen; - user->name = (char *)NULL; - user->qualifier = (char *)NULL; - user->res1 = (char *)NULL; - user->res2 = (char *)NULL; - user->attr = (char *)NULL; - nss_result = (int)NSS_STR_PARSE_SUCCESS; + if (result == NULL) + return (NSS_STR_PARSE_PARSE); + + buflen = argp->buf.buflen; + nss_result = NSS_STR_PARSE_SUCCESS; (void) memset(argp->buf.buffer, 0, buflen); - attrptr = getattr(result, 0); - if (attrptr == NULL) { - nss_result = (int)NSS_STR_PARSE_PARSE; - goto result_user2ent; + name = __ns_ldap_getAttr(result->entry, _USER_NAME); + if (name == NULL || name[0] == NULL || + (strlen(name[0]) < 1)) { + nss_result = NSS_STR_PARSE_PARSE; + goto result_user2str; } - for (i = 0; i < result->entry->attr_count; i++) { - attrptr = getattr(result, i); - if (attrptr == NULL) { - nss_result = (int)NSS_STR_PARSE_PARSE; - goto result_user2ent; - } - if (strcasecmp(attrptr->attrname, _USER_NAME) == 0) { - if ((attrptr->attrvalue[0] == NULL) || - (len = strlen(attrptr->attrvalue[0])) < 1) { - nss_result = (int)NSS_STR_PARSE_PARSE; - goto result_user2ent; - } - user->name = buffer; - buffer += len + 1; - if (buffer >= ceiling) { - nss_result = (int)NSS_STR_PARSE_ERANGE; - goto result_user2ent; - } - (void) strcpy(user->name, attrptr->attrvalue[0]); - continue; - } - if (strcasecmp(attrptr->attrname, _USER_QUALIFIER) == 0) { - if ((attrptr->attrvalue[0] == NULL) || - (len = strlen(attrptr->attrvalue[0])) < 1) { - user->qualifier = nullstring; - } else { - user->qualifier = buffer; - buffer += len + 1; - if (buffer >= ceiling) { - nss_result = (int)NSS_STR_PARSE_ERANGE; - goto result_user2ent; - } - (void) strcpy(user->qualifier, - attrptr->attrvalue[0]); - } - continue; - } - if (strcasecmp(attrptr->attrname, _USER_RES1) == 0) { - if ((attrptr->attrvalue[0] == NULL) || - (len = strlen(attrptr->attrvalue[0])) < 1) { - user->res1 = nullstring; - } else { - user->res1 = buffer; - buffer += len + 1; - if (buffer >= ceiling) { - nss_result = (int)NSS_STR_PARSE_ERANGE; - goto result_user2ent; - } - (void) strcpy(user->res1, - attrptr->attrvalue[0]); - } - continue; - } - if (strcasecmp(attrptr->attrname, _USER_RES2) == 0) { - if ((attrptr->attrvalue[0] == NULL) || - (len = strlen(attrptr->attrvalue[0])) < 1) { - user->res2 = nullstring; - } else { - user->res2 = buffer; - buffer += len + 1; - if (buffer >= ceiling) { - nss_result = (int)NSS_STR_PARSE_ERANGE; - goto result_user2ent; - } - (void) strcpy(user->res2, - attrptr->attrvalue[0]); - } - continue; - } - if (strcasecmp(attrptr->attrname, _USER_ATTRS) == 0) { - if ((attrptr->attrvalue[0] == NULL) || - (len = strlen(attrptr->attrvalue[0])) < 1) { - user->attr = nullstring; - } else { - user->attr = buffer; - buffer += len + 1; - if (buffer >= ceiling) { - nss_result = (int)NSS_STR_PARSE_ERANGE; - goto result_user2ent; - } - (void) strcpy(user->attr, - attrptr->attrvalue[0]); - } - continue; - } - } - -#ifdef DEBUG - (void) fprintf(stdout, "\n[getuserattr.c: _nss_ldap_user2ent]\n"); - (void) fprintf(stdout, " user-name: [%s]\n", user->name); - if (user->qualifier != (char *)NULL) { - (void) fprintf(stdout, " qualifier: [%s]\n", - user->qualifier); + qu = __ns_ldap_getAttr(result->entry, _USER_QUALIFIER); + if (qu == NULL || qu[0] == NULL || (strlen(qu[0]) < 1)) + qu_str = _NO_VALUE; + else + qu_str = qu[0]; + + res1 = __ns_ldap_getAttr(result->entry, _USER_RES2); + if (res1 == NULL || res1[0] == NULL || (strlen(res1[0]) < 1)) + res1_str = _NO_VALUE; + else + res1_str = res1[0]; + + res2 = __ns_ldap_getAttr(result->entry, _USER_RES2); + if (res2 == NULL || res2[0] == NULL || (strlen(res2[0]) < 1)) + res2_str = _NO_VALUE; + else + res2_str = res2[0]; + + attr = __ns_ldap_getAttr(result->entry, _USER_ATTRS); + if (attr == NULL || attr[0] == NULL || (strlen(attr[0]) < 1)) + attr_str = _NO_VALUE; + else + attr_str = attr[0]; + /* 5 = 4 ':' + 1 '\0' */ + len = strlen(name[0]) + strlen(res1_str) + strlen(res2_str) + + strlen(qu_str) + strlen(attr_str) + 5; + if (len > buflen) { + nss_result = NSS_STR_PARSE_ERANGE; + goto result_user2str; } - if (user->res1 != (char *)NULL) { - (void) fprintf(stdout, " res1: [%s]\n", user->res1); - } - if (user->res2 != (char *)NULL) { - (void) fprintf(stdout, " res2: [%s]\n", user->res2); - } - if (user->attr != (char *)NULL) { - (void) fprintf(stdout, " attr: [%s]\n", user->attr); - } -#endif /* DEBUG */ -result_user2ent: + if (argp->buf.result != NULL) { + if ((be->buffer = calloc(1, len)) == NULL) { + nss_result = NSS_STR_PARSE_PARSE; + goto result_user2str; + } + buffer = be->buffer; + } else + buffer = argp->buf.buffer; + (void) snprintf(buffer, len, "%s:%s:%s:%s:%s", + name[0], qu_str, res1_str, res2_str, attr_str); + /* The front end marshaller doesn't need the trailing null */ + if (argp->buf.result != NULL) + be->buflen = strlen(be->buffer); + +result_user2str: (void) __ns_ldap_freeResult(&be->result); return ((int)nss_result); } @@ -207,10 +144,6 @@ getbyname(ldap_backend_ptr be, void *a) char name[SEARCHFILTERLEN]; int ret; -#ifdef DEBUG - (void) fprintf(stdout, "\n[getuserattr.c: getbyname]\n"); -#endif /* DEBUG */ - if (_ldap_filter_name(name, argp->key.name, sizeof (name)) != 0) return ((nss_status_t)NSS_NOTFOUND); @@ -246,11 +179,7 @@ _nss_ldap_user_attr_constr(const char *dummy1, const char *dummy4, const char *dummy5) { -#ifdef DEBUG - (void) fprintf(stdout, - "\n[getuserattr.c: _nss_ldap_user_attr_constr]\n"); -#endif return ((nss_backend_t *)_nss_ldap_constr(userattr_ops, sizeof (userattr_ops)/sizeof (userattr_ops[0]), _USERATTR, - user_attrs, _nss_ldap_user2ent)); + user_attrs, _nss_ldap_user2str)); } diff --git a/usr/src/lib/nsswitch/ldap/common/ldap_common.c b/usr/src/lib/nsswitch/ldap/common/ldap_common.c index 9d961d9d1d..a6537c7b41 100644 --- a/usr/src/lib/nsswitch/ldap/common/ldap_common.c +++ b/usr/src/lib/nsswitch/ldap/common/ldap_common.c @@ -45,7 +45,8 @@ #define _F_GETGRENT "(objectClass=posixGroup)" #define _F_GETHOSTENT "(objectClass=ipHost)" #define _F_GETNETENT "(objectClass=ipNetwork)" -#define _F_GETPROFNAME "(objectClass=SolarisProfAttr)" +#define _F_GETPROFNAME \ +"(&(objectClass=SolarisProfAttr)(!(SolarisKernelSecurityPolicy=*)))" #define _F_GETPROTOENT "(objectClass=ipProtocol)" #define _F_GETPWENT "(objectClass=posixAccount)" #define _F_GETPRINTERENT "(objectClass=sunPrinter)" @@ -85,7 +86,7 @@ static struct gettablefilter { }; -nss_status_t +static nss_status_t switch_err(int rc, ns_ldap_error_t *error) { switch (rc) { @@ -109,6 +110,7 @@ switch_err(int rc, ns_ldap_error_t *error) return (NSS_UNAVAIL); } } +/* ARGSUSED */ nss_status_t _nss_ldap_lookup(ldap_backend_ptr be, nss_XbyY_args_t *argp, char *database, char *searchfilter, char *domain, @@ -136,16 +138,79 @@ _nss_ldap_lookup(ldap_backend_ptr be, nss_XbyY_args_t *argp, argp->returnval = 0; rc = switch_err(rc, error); (void) __ns_ldap_freeError(&error); + return (rc); } + (void) __ns_ldap_freeError(&error); /* callback function */ if ((callbackstat = - be->ldapobj2ent(be, argp)) == NSS_STR_PARSE_SUCCESS) { - argp->returnval = argp->buf.result; - return ((nss_status_t)NSS_SUCCESS); + be->ldapobj2str(be, argp)) != NSS_STR_PARSE_SUCCESS) { + goto error_out; } - (void) __ns_ldap_freeResult(&be->result); + /* + * publickey does not have a front end marshaller and expects + * a string to be returned in NSS. + * No need to convert file format -> struct. + * + */ + if (be->db_type == NSS_LDAP_DB_PUBLICKEY) { + argp->returnval = argp->buf.buffer; + argp->returnlen = strlen(argp->buf.buffer); + be->db_type = NSS_LDAP_DB_NONE; + return (NSS_SUCCESS); + } + /* + * Assume the switch engine wants the returned data in the file + * format when argp->buf.result == NULL. + * The front-end marshaller str2ether(ethers) uses + * ent (argp->buf.result) and buffer (argp->buf.buffer) + * for different purpose so ethers has to be treated differently. + */ + if (argp->buf.result != NULL || + be->db_type == NSS_LDAP_DB_ETHERS) { + /* file format -> struct */ + if (argp->str2ent == NULL) { + callbackstat = NSS_STR_PARSE_PARSE; + goto error_out; + } + + callbackstat = (*argp->str2ent)(be->buffer, + be->buflen, + argp->buf.result, + argp->buf.buffer, + argp->buf.buflen); + if (callbackstat == NSS_STR_PARSE_SUCCESS) { + if (be->db_type == NSS_LDAP_DB_ETHERS && + argp->buf.buffer != NULL) { + argp->returnval = argp->buf.buffer; + argp->returnlen = strlen(argp->buf.buffer); + } else { + argp->returnval = argp->buf.result; + argp->returnlen = 1; /* irrelevant */ + } + if (be->buffer != NULL) { + free(be->buffer); + be->buffer = NULL; + be->buflen = 0; + be->db_type = NSS_LDAP_DB_NONE; + } + return ((nss_status_t)NSS_SUCCESS); + } + } else { + /* return file format in argp->buf.buffer */ + argp->returnval = argp->buf.buffer; + argp->returnlen = strlen(argp->buf.buffer); + return ((nss_status_t)NSS_SUCCESS); + } + +error_out: + if (be->buffer != NULL) { + free(be->buffer); + be->buffer = NULL; + be->buflen = 0; + be->db_type = NSS_LDAP_DB_NONE; + } /* error */ if (callbackstat == NSS_STR_PARSE_PARSE) { argp->returnval = 0; @@ -163,12 +228,12 @@ _nss_ldap_lookup(ldap_backend_ptr be, nss_XbyY_args_t *argp, return ((nss_status_t)NSS_UNAVAIL); } - /* * This function is similar to _nss_ldap_lookup except it does not * do a callback. It is only used by getnetgrent.c */ +/* ARGSUSED */ nss_status_t _nss_ldap_nocb_lookup(ldap_backend_ptr be, nss_XbyY_args_t *argp, char *database, char *searchfilter, char *domain, @@ -227,6 +292,10 @@ _clean_ldap_backend(ldap_backend_ptr be) free(be->toglue); be->toglue = NULL; } + if (be->buffer != NULL) { + free(be->buffer); + be->buffer = NULL; + } free(be); } @@ -280,6 +349,7 @@ _nss_ldap_setent(ldap_backend_ptr be, void *a) be->enumcookie = NULL; be->result = NULL; be->services_cookie = NULL; + be->buffer = NULL; return ((nss_status_t)NSS_SUCCESS); } @@ -311,6 +381,10 @@ _nss_ldap_endent(ldap_backend_ptr be, void *a) if (be->services_cookie != NULL) { _nss_services_cookie_free((void **)&be->services_cookie); } + if (be->buffer != NULL) { + free(be->buffer); + be->buffer = NULL; + } return ((nss_status_t)NSS_SUCCESS); } @@ -353,11 +427,47 @@ next_entry: (void) _nss_ldap_endent(be, a); return (retcode); } else { - if ((parsestat = be->ldapobj2ent(be, argp)) + /* ns_ldap_entry_t -> file format */ + if ((parsestat = be->ldapobj2str(be, argp)) == NSS_STR_PARSE_SUCCESS) { - be->result = NULL; - argp->returnval = argp->buf.result; - return ((nss_status_t)NSS_SUCCESS); + if (argp->buf.result != NULL) { + /* file format -> struct */ + if (argp->str2ent == NULL) { + parsestat = NSS_STR_PARSE_PARSE; + goto error_out; + } + parsestat = (*argp->str2ent)(be->buffer, + be->buflen, + argp->buf.result, + argp->buf.buffer, + argp->buf.buflen); + if (parsestat == NSS_STR_PARSE_SUCCESS) { + if (be->buffer != NULL) { + free(be->buffer); + be->buffer = NULL; + be->buflen = 0; + } + be->result = NULL; + argp->returnval = argp->buf.result; + argp->returnlen = 1; /* irrevelant */ + return ((nss_status_t)NSS_SUCCESS); + } + } else { + /* + * nscd is not caching the enumerated + * entries. This code path would be dormant. + * Keep this path for the future references. + */ + argp->returnval = argp->buf.buffer; + argp->returnlen = + strlen(argp->buf.buffer) + 1; + } + } +error_out: + if (be->buffer != NULL) { + free(be->buffer); + be->buffer = NULL; + be->buflen = 0; } be->result = NULL; if (parsestat == NSS_STR_PARSE_PARSE) { @@ -394,7 +504,7 @@ next_entry: nss_backend_t * _nss_ldap_constr(ldap_backend_op_t ops[], int nops, char *tablename, - const char **attrs, fnf ldapobj2ent) + const char **attrs, fnf ldapobj2str) { ldap_backend_ptr be; @@ -402,20 +512,13 @@ _nss_ldap_constr(ldap_backend_op_t ops[], int nops, char *tablename, (void) fprintf(stdout, "\n[ldap_common.c: _nss_ldap_constr]\n"); #endif /* DEBUG */ - if ((be = (ldap_backend_ptr) malloc(sizeof (*be))) == 0) + if ((be = (ldap_backend_ptr) calloc(1, sizeof (*be))) == 0) return (0); be->ops = ops; be->nops = (nss_dbop_t)nops; be->tablename = (char *)strdup(tablename); be->attrs = attrs; - be->result = NULL; - be->ldapobj2ent = ldapobj2ent; - be->setcalled = 0; - be->filter = NULL; - be->enumcookie = NULL; - be->netgroup_cookie = NULL; - be->services_cookie = NULL; - be->toglue = NULL; + be->ldapobj2str = ldapobj2str; return ((nss_backend_t *)be); } @@ -436,8 +539,8 @@ chophostdomain(char *string, char *host, char *domain) return (0); } *dot = '\0'; - strcpy(host, string); - strcpy(domain, ++dot); + (void) strcpy(host, string); + (void) strcpy(domain, ++dot); return (0); } diff --git a/usr/src/lib/nsswitch/ldap/common/ldap_common.h b/usr/src/lib/nsswitch/ldap/common/ldap_common.h index 23d5e2b1ae..deb5ffd642 100644 --- a/usr/src/lib/nsswitch/ldap/common/ldap_common.h +++ b/usr/src/lib/nsswitch/ldap/common/ldap_common.h @@ -76,6 +76,19 @@ extern "C" { ((string != NULL) && (strchr(string, '.') != NULL)) #define SEARCHFILTERLEN 256 +#define _NO_VALUE "" + +#define TEST_AND_ADJUST(len, buffer, buflen, label) \ + /* Use '>=' to ensure there is at least one byte left for '\0' */ \ + if (len >= buflen || len < 0) { \ + nss_result = NSS_STR_PARSE_ERANGE; \ + goto label; \ + } \ + /* Adjust pointer and available buffer length */ \ + buffer += len; \ + buflen -= len; + + /* * Superset the nss_backend_t abstract data type. This ADT has * been extended to include ldap associated data structures. @@ -85,6 +98,12 @@ typedef struct ldap_backend *ldap_backend_ptr; typedef nss_status_t (*ldap_backend_op_t)(ldap_backend_ptr, void *); typedef int (*fnf)(ldap_backend_ptr be, nss_XbyY_args_t *argp); +typedef enum { + NSS_LDAP_DB_NONE = 0, + NSS_LDAP_DB_PUBLICKEY = 1, + NSS_LDAP_DB_ETHERS = 2 +} nss_ldap_db_type_t; + struct ldap_backend { ldap_backend_op_t *ops; nss_dbop_t nops; @@ -94,10 +113,13 @@ struct ldap_backend { int setcalled; const char **attrs; ns_ldap_result_t *result; - fnf ldapobj2ent; + fnf ldapobj2str; void *netgroup_cookie; void *services_cookie; char *toglue; + char *buffer; + int buflen; + nss_ldap_db_type_t db_type; }; extern nss_status_t _nss_ldap_destr(ldap_backend_ptr be, void *a); @@ -105,7 +127,7 @@ extern nss_status_t _nss_ldap_endent(ldap_backend_ptr be, void *a); extern nss_status_t _nss_ldap_setent(ldap_backend_ptr be, void *a); extern nss_status_t _nss_ldap_getent(ldap_backend_ptr be, void *a); nss_backend_t *_nss_ldap_constr(ldap_backend_op_t ops[], int nops, - char *tablename, const char **attrs, fnf ldapobj2ent); + 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, @@ -132,7 +154,6 @@ extern int _merge_SSD_filter(const ns_ldap_search_desc_t *desc, char **realfilter, const void *userdata); extern int _ldap_filter_name(char *filter_name, const char *name, int filter_name_size); -extern nss_status_t switch_err(int rc, ns_ldap_error_t *error); extern void _nss_services_cookie_free(void **cookieP); diff --git a/usr/src/lib/nsswitch/ldap/common/tsol_getrhent.c b/usr/src/lib/nsswitch/ldap/common/tsol_getrhent.c index 90a21988a2..77e04f2cfe 100644 --- a/usr/src/lib/nsswitch/ldap/common/tsol_getrhent.c +++ b/usr/src/lib/nsswitch/ldap/common/tsol_getrhent.c @@ -45,82 +45,82 @@ static const char *tnrhdb_attrs[] = { NULL }; +static void +escape_colon(char *in, char *out) { + int i, j; + for (i = 0, j = 0; in[i] != '\0'; i++) { + if (in[i] == ':') { + out[j++] = '\\'; + out[j++] = in[i]; + } else + out[j++] = in[i]; + } + out[j] = '\0'; +} + +/* + * _nss_ldap_tnrhdb2str is the data marshaling method for the tnrhdb + * (tsol_getrhbyaddr()/tsol_getrhent()) backend processes. + * This method is called after a successful ldap search has been performed. + * This method will parse the ldap search values into the file format. + * + * e.g. + * + * 192.168.120.6:public + * fec0\:\:a00\:20ff\:fea0\:21f7:cipso + * + */ static int -_nss_ldap_tnrhdb2ent(ldap_backend_ptr be, nss_XbyY_args_t *argp) +_nss_ldap_tnrhdb2str(ldap_backend_ptr be, nss_XbyY_args_t *argp) { - int i, nss_result; + int nss_result = NSS_STR_PARSE_SUCCESS; int len = 0; - int buflen = 0; char *buffer = NULL; - char *ceiling = NULL; - ns_ldap_attr_t *attrptr; + char **addr, **template, *addr_out; ns_ldap_result_t *result = be->result; - tsol_rhstr_t *rhstrp; + char addr6[INET6_ADDRSTRLEN + 5]; /* 5 '\' for ':' at most */ + + if (result == NULL) + return (NSS_STR_PARSE_PARSE); - buffer = argp->buf.buffer; - buflen = argp->buf.buflen; - if (argp->buf.result == NULL) { - nss_result = NSS_STR_PARSE_ERANGE; - goto result_tnrhdb2ent; + addr = __ns_ldap_getAttr(result->entry, _TNRHDB_ADDR); + if (addr == NULL || addr[0] == NULL || (strlen(addr[0]) < 1)) { + nss_result = NSS_STR_PARSE_PARSE; + goto result_tnrhdb2str; } - rhstrp = (tsol_rhstr_t *)(argp->buf.result); - rhstrp->family = 0; - rhstrp->address = rhstrp->template = NULL; - ceiling = buffer + buflen; - (void) memset(argp->buf.buffer, 0, buflen); - attrptr = getattr(result, 0); - if (attrptr == NULL) { + + /* + * Escape ':' in IPV6. + * The value is stored in LDAP directory without escape charaters. + */ + if (strchr(addr[0], ':') != NULL) { + escape_colon(addr[0], addr6); + addr_out = addr6; + } else + addr_out = addr[0]; + + template = __ns_ldap_getAttr(result->entry, _TNRHDB_TNAME); + if (template == NULL || template[0] == NULL || + (strlen(template[0]) < 1)) { nss_result = NSS_STR_PARSE_PARSE; - goto result_tnrhdb2ent; + goto result_tnrhdb2str; } - for (i = 0; i < result->entry->attr_count; i++) { - attrptr = getattr(result, i); - if (attrptr == NULL) { + /* "addr:template" */ + len = strlen(addr_out) + strlen(template[0]) + 2; + + if (argp->buf.result != NULL) { + if ((be->buffer = calloc(1, len)) == NULL) { nss_result = NSS_STR_PARSE_PARSE; - goto result_tnrhdb2ent; - } - if (strcasecmp(attrptr->attrname, _TNRHDB_ADDR) == 0) { - len = strlen(attrptr->attrvalue[0]); - if (len < 1 || (attrptr->attrvalue[0] == '\0')) { - nss_result = NSS_STR_PARSE_PARSE; - goto result_tnrhdb2ent; - } - rhstrp->address = buffer; - buffer += len + 1; - if (buffer >= ceiling) { - nss_result = (int)NSS_STR_PARSE_ERANGE; - goto result_tnrhdb2ent; - } - (void) strcpy(rhstrp->address, attrptr->attrvalue[0]); - continue; + goto result_tnrhdb2str; } - if (strcasecmp(attrptr->attrname, _TNRHDB_TNAME) == 0) { - len = strlen(attrptr->attrvalue[0]); - if (len < 1 || (attrptr->attrvalue[0] == '\0')) { - nss_result = NSS_STR_PARSE_PARSE; - goto result_tnrhdb2ent; - } - rhstrp->template = buffer; - buffer += len + 1; - if (buffer >= ceiling) { - nss_result = (int)NSS_STR_PARSE_ERANGE; - goto result_tnrhdb2ent; - } - (void) strcpy(rhstrp->template, attrptr->attrvalue[0]); - continue; - } - } - nss_result = NSS_STR_PARSE_SUCCESS; + be->buflen = len - 1; + buffer = be->buffer; + } else + buffer = argp->buf.buffer; -#ifdef DEBUG - (void) printf("\n[tsol_getrhent.c: _nss_ldap_tnrhdb2ent]\n"); - (void) printf(" address: [%s]\n", - rhstrp->address ? rhstrp->address : "NULL"); - (void) printf("template: [%s]\n", - rhstrp->template ? rhstrp->template : "NULL"); -#endif /* DEBUG */ + (void) snprintf(buffer, len, "%s:%s", addr_out, template[0]); -result_tnrhdb2ent: +result_tnrhdb2str: (void) __ns_ldap_freeResult(&be->result); return (nss_result); } @@ -132,23 +132,31 @@ getbyaddr(ldap_backend_ptr be, void *a) char searchfilter[SEARCHFILTERLEN]; char userdata[SEARCHFILTERLEN]; nss_XbyY_args_t *argp = (nss_XbyY_args_t *)a; - struct in_addr addr; - char buf[18]; - extern char *inet_ntoa_r(); -#ifdef DEBUG - (void) fprintf(stdout, "\n[tsol_getrhent.c: getbyaddr]\n"); -#endif /* DEBUG */ - - (void) memcpy(&addr, argp->key.hostaddr.addr, sizeof (addr)); - (void) inet_ntoa_r(addr, buf); + if (argp->key.hostaddr.addr == NULL || + (argp->key.hostaddr.type != AF_INET && + argp->key.hostaddr.type != AF_INET6)) + return (NSS_NOTFOUND); + if (strchr(argp->key.hostaddr.addr, ':') != NULL) { + /* IPV6 */ + if (argp->key.hostaddr.type == AF_INET) + return (NSS_NOTFOUND); + } else { + /* IPV4 */ + if (argp->key.hostaddr.type == AF_INET6) + return (NSS_NOTFOUND); + } + /* + * The IPV6 addresses are saved in the directory without '\'s. + * So don't need to escape colons in IPV6 addresses. + */ if (snprintf(searchfilter, sizeof (searchfilter), _F_GETTNDBBYADDR, - buf) < 0) + argp->key.hostaddr.addr) < 0) return ((nss_status_t)NSS_NOTFOUND); if (snprintf(userdata, sizeof (userdata), _F_GETTNDBBYADDR_SSD, - buf) < 0) + argp->key.hostaddr.addr) < 0) return ((nss_status_t)NSS_NOTFOUND); return (_nss_ldap_lookup(be, argp, _TNRHDB, searchfilter, NULL, @@ -173,11 +181,7 @@ _nss_ldap_tnrhdb_constr(const char *dummy1, const char *dummy4, const char *dummy5) { -#ifdef DEBUG - (void) fprintf(stdout, - "\n[tsol_getrhent.c: _nss_ldap_tnrhdb_constr]\n"); -#endif return ((nss_backend_t *)_nss_ldap_constr(tnrhdb_ops, sizeof (tnrhdb_ops)/sizeof (tnrhdb_ops[0]), _TNRHDB, - tnrhdb_attrs, _nss_ldap_tnrhdb2ent)); + tnrhdb_attrs, _nss_ldap_tnrhdb2str)); } diff --git a/usr/src/lib/nsswitch/ldap/common/tsol_gettpent.c b/usr/src/lib/nsswitch/ldap/common/tsol_gettpent.c index b7f5423f6f..31c84df762 100644 --- a/usr/src/lib/nsswitch/ldap/common/tsol_gettpent.c +++ b/usr/src/lib/nsswitch/ldap/common/tsol_gettpent.c @@ -32,6 +32,7 @@ #define _TNRHTP_NAME "ipTnetTemplateName" #define _TNRHTP_ATTRS "SolarisAttrKeyValue" #define _F_GETTNTPBYNAME "(&(objectClass=ipTnetTemplate)"\ + "(!(objectClass=ipTnetHost))" \ "(ipTnetTemplateName=%s))" #define _F_GETTNTPBYNAME_SSD "(&(%%s)(ipTnetTemplateName=%s))" @@ -41,97 +42,63 @@ static const char *tnrhtp_attrs[] = { NULL }; +/* + * _nss_ldap_tnrhtp2str is the data marshaling method for the tnrhtp + * (tsol_gettpbyaddr()/tsol_gettpent()) backend processes. + * This method is called after a successful ldap search has been performed. + * This method will parse the ldap search values into the file format. + * + * e.g. + * + * admin_low:host_type=unlabeled;def_label=[0x0000000000000000000000000000000000 + * 0000000000000000000000000000000000];min_sl=0x00000000000000000000000000000000 + * 000000000000000000000000000000000000;max_sl=0x7ffffffffffffffffffffffffffffff + * fffffffffffffffffffffffffffffffffffff;doi=0; + */ static int -_nss_ldap_tnrhtp2ent(ldap_backend_ptr be, nss_XbyY_args_t *argp) +_nss_ldap_tnrhtp2str(ldap_backend_ptr be, nss_XbyY_args_t *argp) { - int i, nss_result; + int nss_result = NSS_STR_PARSE_SUCCESS; int len = 0; - int buflen = 0; char *buffer = NULL; - char *ceiling = NULL; - ns_ldap_attr_t *attrptr; + char **attrs, **template; ns_ldap_result_t *result = be->result; - tsol_tpstr_t *tpstrp; - buffer = argp->buf.buffer; - buflen = argp->buf.buflen; - if (argp->buf.result == NULL) { - nss_result = (int)NSS_STR_PARSE_ERANGE; - goto result_tnrhtp2ent; + if (result == NULL) + return (NSS_STR_PARSE_PARSE); + + template = __ns_ldap_getAttr(result->entry, _TNRHTP_NAME); + if (template == NULL || template[0] == NULL || + (strlen(template[0]) < 1)) { + nss_result = NSS_STR_PARSE_PARSE; + goto result_tnrhtp2str; } - tpstrp = (tsol_tpstr_t *)(argp->buf.result); - tpstrp->template = tpstrp->attrs = NULL; - ceiling = buffer + buflen; - (void) memset(argp->buf.buffer, 0, buflen); - attrptr = getattr(result, 0); - if (attrptr == NULL) { + attrs = __ns_ldap_getAttr(result->entry, _TNRHTP_ATTRS); + if (attrs == NULL || attrs[0] == NULL || (strlen(attrs[0]) < 1)) { nss_result = NSS_STR_PARSE_PARSE; - goto result_tnrhtp2ent; + goto result_tnrhtp2str; } - for (i = 0; i < result->entry->attr_count; i++) { - attrptr = getattr(result, i); - if (attrptr == NULL) { - nss_result = (int)NSS_STR_PARSE_PARSE; - goto result_tnrhtp2ent; - } -#ifdef DEBUG - (void) fprintf(stdout, - "\n[tsol_gettpent.c: _nss_ldap_tnrhtp2ent %d]\n", i); - (void) fprintf(stdout, " entry value count %d: %s:%s\n", - attrptr->value_count, - attrptr->attrname ? attrptr->attrname : "NULL", - attrptr->attrvalue[0] ? attrptr->attrvalue[0] : "NULL"); -#endif /* DEBUG */ - if (strcasecmp(attrptr->attrname, _TNRHTP_NAME) == 0) { - len = strlen(attrptr->attrvalue[0]); - if (len < 1 || (attrptr->attrvalue[0] == '\0')) { - nss_result = (int)NSS_STR_PARSE_PARSE; - goto result_tnrhtp2ent; - } - tpstrp->template = buffer; - buffer += len + 1; - if (buffer >= ceiling) { - nss_result = (int)NSS_STR_PARSE_ERANGE; - goto result_tnrhtp2ent; - } - (void) strcpy(tpstrp->template, attrptr->attrvalue[0]); - continue; - } - if (strcasecmp(attrptr->attrname, _TNRHTP_ATTRS) == 0) { - len = strlen(attrptr->attrvalue[0]); - if (len < 1 || (attrptr->attrvalue[0] == '\0')) { - nss_result = (int)NSS_STR_PARSE_PARSE; - goto result_tnrhtp2ent; - } - tpstrp->attrs = buffer; - buffer += len + 1; - if (buffer >= ceiling) { - nss_result = (int)NSS_STR_PARSE_PARSE; - goto result_tnrhtp2ent; - } - (void) strcpy(tpstrp->attrs, attrptr->attrvalue[0]); - continue; + + /* "template:attrs" */ + len = strlen(template[0]) + strlen(attrs[0]) + 2; + + if (argp->buf.result != NULL) { + if ((be->buffer = calloc(1, len)) == NULL) { + nss_result = NSS_STR_PARSE_PARSE; + goto result_tnrhtp2str; } - } - if (tpstrp->attrs == NULL) - nss_result = NSS_STR_PARSE_PARSE; - else - nss_result = NSS_STR_PARSE_SUCCESS; - -#ifdef DEBUG - (void) fprintf(stdout, "\n[tsol_gettpent.c: _nss_ldap_tnrhtp2ent]\n"); - (void) fprintf(stdout, " template: [%s]\n", - tpstrp->template ? tpstrp->template : "NULL"); - (void) fprintf(stdout, " attrs: [%s]\n", - tpstrp->attrs ? tpstrp->attrs : "NULL"); -#endif /* DEBUG */ - -result_tnrhtp2ent: + be->buflen = len - 1; + buffer = be->buffer; + } else + buffer = argp->buf.buffer; + + (void) snprintf(buffer, len, "%s:%s", template[0], attrs[0]); + +result_tnrhtp2str: (void) __ns_ldap_freeResult(&be->result); return (nss_result); } - static nss_status_t getbyname(ldap_backend_ptr be, void *a) { @@ -139,9 +106,8 @@ getbyname(ldap_backend_ptr be, void *a) char userdata[SEARCHFILTERLEN]; nss_XbyY_args_t *argp = (nss_XbyY_args_t *)a; -#ifdef DEBUG - (void) fprintf(stdout, "\n[tsol_gettpent.c: getbyname]\n"); -#endif /* DEBUG */ + if (argp->key.name == NULL) + return (NSS_NOTFOUND); if (snprintf(searchfilter, SEARCHFILTERLEN, _F_GETTNTPBYNAME, argp->key.name) < 0) @@ -164,7 +130,7 @@ static ldap_backend_op_t tnrhtp_ops[] = { getbyname }; - +/* ARGSUSED */ nss_backend_t * _nss_ldap_tnrhtp_constr(const char *dummy1, const char *dummy2, @@ -172,11 +138,7 @@ _nss_ldap_tnrhtp_constr(const char *dummy1, const char *dummy4, const char *dummy5) { -#ifdef DEBUG - (void) fprintf(stdout, - "\n[gettnrhtpattr.c: _nss_ldap_tnrhtp_constr]\n"); -#endif return ((nss_backend_t *)_nss_ldap_constr(tnrhtp_ops, sizeof (tnrhtp_ops)/sizeof (tnrhtp_ops[0]), _TNRHTP, - tnrhtp_attrs, _nss_ldap_tnrhtp2ent)); + tnrhtp_attrs, _nss_ldap_tnrhtp2str)); } |