diff options
Diffstat (limited to 'usr/src/lib/nsswitch')
109 files changed, 6199 insertions, 6006 deletions
diff --git a/usr/src/lib/nsswitch/compat/common/compat_common.c b/usr/src/lib/nsswitch/compat/common/compat_common.c index fe21797abf..330a4b7707 100644 --- a/usr/src/lib/nsswitch/compat/common/compat_common.c +++ b/usr/src/lib/nsswitch/compat/common/compat_common.c @@ -36,6 +36,11 @@ #include <ctype.h> #include <bsm/libbsm.h> #include <user_attr.h> +#include <pwd.h> +#include <shadow.h> +#include <grp.h> +#include <unistd.h> /* for GF_PATH */ +#include <dlfcn.h> #include "compat_common.h" /* @@ -44,6 +49,62 @@ extern int yp_get_default_domain(char **domain); +/* from libc */ +extern int str2passwd(const char *instr, int lenstr, void *ent, + char *buffer, int buflen); +extern int str2spwd(const char *instr, int lenstr, void *ent, + char *buffer, int buflen); +extern int str2group(const char *instr, int lenstr, void *ent, + char *buffer, int buflen); + +/* from libnsl */ +extern char *_strtok_escape(char *, char *, char **); + +/* + * str2auuser_s and str2userattr_s are very simple version + * of the str2auuser() and str2userattr() that can be found in + * libnsl. They only copy the user name into the userstr_t + * or au_user_str_t structure (so check on user name can be + * performed). + */ +static int +str2auuser_s( + const char *instr, + int lenstr, + void *ent, + char *buffer, + int buflen) +{ + char *last = NULL; + char *sep = KV_TOKEN_DELIMIT; + au_user_str_t *au_user = (au_user_str_t *)ent; + + if (lenstr >= buflen) + return (NSS_STR_PARSE_ERANGE); + (void) strncpy(buffer, instr, buflen); + au_user->au_name = _strtok_escape(buffer, sep, &last); + return (0); +} + +static int +str2userattr_s( + const char *instr, + int lenstr, + void *ent, + char *buffer, + int buflen) +{ + char *last = NULL; + char *sep = KV_TOKEN_DELIMIT; + userstr_t *user = (userstr_t *)ent; + + if (lenstr >= buflen) + return (NSS_STR_PARSE_ERANGE); + (void) strncpy(buffer, instr, buflen); + user->name = _strtok_escape(buffer, sep, &last); + return (0); +} + /* * Routines to manage list of "-" users for get{pw, sp, gr}ent(). Current * implementation is completely moronic; we use a linked list. But then @@ -58,7 +119,6 @@ struct setofstrings { * object rather than two. */ }; -typedef struct setofstrings *strset_t; static void strset_free(ssp) @@ -88,7 +148,7 @@ strset_add(ssp, nam) free(new); return (B_FALSE); } - strcpy(new->name, nam); + (void) strcpy(new->name, nam); new->next = *ssp; *ssp = new; return (B_TRUE); @@ -109,41 +169,6 @@ strset_in(ssp, nam) return (B_FALSE); } - -struct compat_backend { - compat_backend_op_t *ops; - int n_ops; - const char *filename; - FILE *f; - int minbuf; - char *buf; - int linelen; /* <== Explain use, lifetime */ - - nss_db_initf_t db_initf; - nss_db_root_t *db_rootp; /* Shared between instances */ - nss_getent_t db_context; /* Per-instance enumeration */ - - compat_get_name getnamef; - compat_merge_func mergef; - - /* We wouldn't need all this hokey state stuff if we */ - /* used another thread to implement a coroutine... */ - enum { - GETENT_FILE, - GETENT_NETGROUP, - GETENT_ATTRDB, - GETENT_ALL, - GETENT_DONE - } state; - strset_t minuses; - - int permit_netgroups; - const char *yp_domain; - nss_backend_t *getnetgrent_backend; - char *netgr_buffer; -}; - - /* * Lookup and enumeration routines for +@group and -@group. * @@ -171,15 +196,6 @@ netgr_in(compat_backend_ptr_t be, const char *group, const char *user) return (innetgr(group, 0, user, be->yp_domain)); } -static boolean_t -netgr_all_in(compat_backend_ptr_t be, const char *group) -{ - /* - * 4.x does this; ours not to reason why... - */ - return (netgr_in(be, group, "*")); -} - static void netgr_set(be, netgroup) compat_backend_ptr_t be; @@ -202,7 +218,7 @@ netgr_set(be, netgroup) args.netgroup = netgroup; args.iterator = 0; - nss_search(&netgr_db_root, _nss_initf_netgroup, + (void) nss_search(&netgr_db_root, _nss_initf_netgroup, NSS_DBOP_NETGROUP_SET, &args); be->getnetgrent_backend = args.iterator; } @@ -270,7 +286,7 @@ do_merge(be, args, instr, linelen) int overrides; const char *p; const char *end = instr + linelen; - nss_status_t res; + nss_status_t res = NSS_NOTFOUND; /* * Potential optimization: only perform the field-splitting nonsense @@ -292,7 +308,7 @@ do_merge(be, args, instr, linelen) overrides = -1; /* Indicates "you lose" */ break; } - memcpy(s, p, len); + (void) memcpy(s, p, len); s[len] = '\0'; fields[i] = s; overrides++; @@ -306,16 +322,29 @@ do_merge(be, args, instr, linelen) } } if (overrides == 1) { - /* No real overrides, return (*args) intact */ - res = NSS_SUCCESS; - } else if (overrides > 1) { + /* + * return result here if /etc file format is requested + */ + if (be->return_string_data != 1) { + /* No real overrides, return (*args) intact */ + res = NSS_SUCCESS; + } else { + free(fields[0]); + fields[0] = NULL; + } + } + + if (overrides > 1 || be->return_string_data == 1) { /* * The zero'th field is always nonempty (+/-...), but at least * one other field was also nonempty, i.e. wants to override */ switch ((*be->mergef)(be, args, (const char **)fields)) { case NSS_STR_PARSE_SUCCESS: - args->returnval = args->buf.result; + if (be->return_string_data != 1) + args->returnval = args->buf.result; + else + args->returnval = args->buf.buffer; args->erange = 0; res = NSS_SUCCESS; break; @@ -331,7 +360,7 @@ do_merge(be, args, instr, linelen) res = NSS_NOTFOUND; break; } - } else { + } else if (res != NSS_SUCCESS) { args->returnval = 0; args->erange = 0; res = NSS_UNAVAIL; /* ==> Right? */ @@ -383,7 +412,7 @@ _nss_compat_endent(be, dummy) void *dummy; { if (be->f != 0) { - fclose(be->f); + (void) fclose(be->f); be->f = 0; } if (be->buf != 0) { @@ -412,7 +441,7 @@ _nss_compat_destr(be, dummy) { if (be != 0) { if (be->f != 0) { - _nss_compat_endent(be, 0); + (void) _nss_compat_endent(be, 0); } nss_delete(be->db_rootp); nss_delete(&netgr_db_root); @@ -459,6 +488,7 @@ read_line(f, buffer, buflen) ; } } + /*NOTREACHED*/ } static int @@ -493,6 +523,10 @@ _attrdb_compat_XY_all(be, argp, netdb, check, op_num) int (*func)(); const char *filter = argp->key.name; nss_status_t res; + union { + au_user_str_t au; + userstr_t user; + } workarea; #ifdef DEBUG (void) fprintf(stdout, "\n[compat_common.c: _attrdb_compat_XY_all]\n"); @@ -502,11 +536,33 @@ _attrdb_compat_XY_all(be, argp, netdb, check, op_num) (be->buf = malloc(be->minbuf)) == 0) { return (NSS_UNAVAIL); } - if ((res = _nss_compat_setent(be, 0)) != NSS_SUCCESS) { - return (res); - } + if (check != NULL) + if ((res = _nss_compat_setent(be, 0)) != NSS_SUCCESS) + return (res); + res = NSS_NOTFOUND; + /* + * assume a NULL buf.result pointer is an indication + * that the lookup result should be returned in /etc + * file format + */ + if (argp->buf.result == NULL) { + be->return_string_data = 1; + + /* + * the code executed later needs the result struct + * as working area + */ + argp->buf.result = &workarea; + + if (strcmp(be->filename, USERATTR_FILENAME) == 0) + func = str2userattr_s; + else + func = str2auuser_s; + } else + func = argp->str2ent; + /*CONSTCOND*/ while (1) { int linelen; @@ -560,16 +616,36 @@ _attrdb_compat_XY_all(be, argp, netdb, check, op_num) } } argp->returnval = 0; - func = argp->str2ent; parsestat = (*func)(instr, linelen, argp->buf.result, argp->buf.buffer, argp->buf.buflen); if (parsestat == NSS_STR_PARSE_SUCCESS) { - argp->returnval = argp->buf.result; + argp->returnval = argp->buf.result; if (check == 0 || (*check)(argp)) { + int len; + + if (be->return_string_data != 1) { + res = NSS_SUCCESS; + break; + } + + /* copy string data to result buffer */ + argp->buf.result = NULL; + argp->returnval = argp->buf.buffer; + if ((len = strlcpy(argp->buf.buffer, instr, + argp->buf.buflen)) >= + argp->buf.buflen) { + argp->returnval = NULL; + res = NSS_NOTFOUND; + argp->erange = 1; + break; + } + + argp->returnlen = len; res = NSS_SUCCESS; break; } } else if (parsestat == NSS_STR_PARSE_ERANGE) { + res = NSS_NOTFOUND; argp->erange = 1; break; } @@ -583,6 +659,14 @@ _attrdb_compat_XY_all(be, argp, netdb, check, op_num) } if (res != NSS_SUCCESS) { + /* + * tell the nss_search() and nss_getent() below + * if the result should be returned in the /etc + * file format + */ + if (be->return_string_data == 1) + argp->buf.result = NULL; + if ((op_num == NSS_DBOP_USERATTR_BYNAME) || (op_num == NSS_DBOP_AUDITUSER_BYNAME)) { res = nss_search(be->db_rootp, @@ -611,6 +695,13 @@ _nss_compat_XY_all(be, args, check, op_num) { nss_status_t res; int parsestat; + union { + struct passwd pwd; + struct spwd shdw; + struct group grp; + } workarea; + int (*str2ent_save)(); + if (be->buf == 0 && (be->buf = malloc(be->minbuf)) == 0) { @@ -623,6 +714,30 @@ _nss_compat_XY_all(be, args, check, op_num) res = NSS_NOTFOUND; + /* + * assume a NULL buf.result pointer is an indication + * that the lookup result should be returned in /etc + * file format + */ + if (args->buf.result == NULL) { + + be->return_string_data = 1; + + /* + * the code executed later needs the result struct + * as working area + */ + args->buf.result = &workarea; + + str2ent_save = args->str2ent; + if (strcmp(be->filename, PASSWD) == 0) + args->str2ent = str2passwd; + else if (strcmp(be->filename, SHADOW) == 0) + args->str2ent = str2spwd; + else + args->str2ent = str2group; + } + /*CONSTCOND*/ while (1) { int linelen; @@ -648,13 +763,37 @@ _nss_compat_XY_all(be, args, check, op_num) if (parsestat == NSS_STR_PARSE_SUCCESS) { args->returnval = args->buf.result; if ((*check)(args) != 0) { - res = NSS_SUCCESS; - break; - } + int len; + if (be->return_string_data != 1) { + res = NSS_SUCCESS; + break; + } + + /* + * copy string data to + * result buffer + */ + args->buf.result = NULL; + args->str2ent = str2ent_save; + if ((len = strlcpy(args->buf.buffer, + instr, args->buf.buflen)) >= + args->buf.buflen) + parsestat = + NSS_STR_PARSE_ERANGE; + else { + args->returnval = + args->buf.buffer; + args->returnlen = len; + res = NSS_SUCCESS; + break; + } + } else + continue; + } /* ===> Check the Dani logic here... */ - } else if (parsestat == NSS_STR_PARSE_ERANGE) { + if (parsestat == NSS_STR_PARSE_ERANGE) { args->erange = 1; res = NSS_NOTFOUND; break; @@ -665,6 +804,7 @@ _nss_compat_XY_all(be, args, check, op_num) /* ==> ?? */ continue; } + /* * Process "+", "+name", "+@netgroup", "-name" or "-@netgroup" * @@ -701,15 +841,15 @@ _nss_compat_XY_all(be, args, check, op_num) continue; if (instr[0] == '+') { /* need to search for "+" entry */ - nss_search(be->db_rootp, be->db_initf, - op_num, args); + (void) nss_search(be->db_rootp, + be->db_initf, op_num, args); if (args->returnval == 0) continue; } } else { /* search then compare */ - nss_search(be->db_rootp, be->db_initf, op_num, - args); + (void) nss_search(be->db_rootp, + be->db_initf, op_num, args); if (args->returnval == 0) continue; if (!be->permit_netgroups || @@ -727,7 +867,8 @@ _nss_compat_XY_all(be, args, check, op_num) if (instr[0] == '-') continue; /* need to search for "+" entry */ - nss_search(be->db_rootp, be->db_initf, op_num, args); + (void) nss_search(be->db_rootp, be->db_initf, + op_num, args); if (args->returnval == 0) continue; } else { @@ -746,15 +887,15 @@ _nss_compat_XY_all(be, args, check, op_num) continue; if (instr[0] == '+') { /* need to search for "+" entry */ - nss_search(be->db_rootp, be->db_initf, - op_num, args); + (void) nss_search(be->db_rootp, + be->db_initf, op_num, args); if (args->returnval == 0) continue; } } else { /* search then compare */ - nss_search(be->db_rootp, be->db_initf, op_num, - args); + (void) nss_search(be->db_rootp, + be->db_initf, op_num, args); if (args->returnval == 0) continue; if (strcmp(instr + 1, (*be->getnamef)(args)) @@ -783,6 +924,10 @@ _nss_compat_XY_all(be, args, check, op_num) (void) _nss_compat_endent(be, 0); } + if (be->return_string_data == 1) { + args->str2ent = str2ent_save; + } + return (res); } @@ -794,6 +939,12 @@ _nss_compat_getent(be, a) nss_XbyY_args_t *args = (nss_XbyY_args_t *)a; nss_status_t res; char *colon = 0; /* <=== need comment re lifetime */ + union { + struct passwd pwd; + struct spwd shdw; + struct group grp; + } workarea; + if (be->f == 0) { if ((res = _nss_compat_setent(be, 0)) != NSS_SUCCESS) { @@ -806,6 +957,21 @@ _nss_compat_getent(be, a) return (NSS_UNAVAIL); /* really panic, malloc failed */ } + /* + * assume a NULL buf.result pointer is an indication + * that the lookup result should be returned in /etc + * file format + */ + if (args->buf.result == NULL) { + be->return_string_data = 1; + + /* + * the code executed later needs the result struct + * as working area + */ + args->buf.result = &workarea; + } + /*CONSTCOND*/ while (1) { char *instr = be->buf; @@ -829,6 +995,7 @@ _nss_compat_getent(be, a) return (NSS_NOTFOUND); case GETENT_ATTRDB: + args->key.name = NULL; res = _attrdb_compat_XY_all(be, args, 1, (compat_XY_check_func)NULL, 0); return (res); @@ -845,11 +1012,12 @@ _nss_compat_getent(be, a) } if (instr[0] == '-') { if (instr[1] != '@') { - strset_add(&be->minuses, instr + 1); + (void) strset_add(&be->minuses, + instr + 1); } else if (be->permit_netgroups) { netgr_set(be, instr + 2); while (netgr_next_u(be, &name)) { - strset_add(&be->minuses, + (void) strset_add(&be->minuses, name); } netgr_end(be); @@ -869,8 +1037,30 @@ _nss_compat_getent(be, a) args->buf.buffer, args->buf.buflen); if (parsestat == NSS_STR_PARSE_SUCCESS) { - args->returnval = args->buf.result; - return (NSS_SUCCESS); + int len; + + if (be->return_string_data != 1) { + args->returnval = + args->buf.result; + return (NSS_SUCCESS); + } + + /* + * copy string data to + * result buffer + */ + args->buf.result = NULL; + args->returnval = + args->buf.buffer; + if ((len = strlcpy(args->buf.buffer, + instr, args->buf.buflen)) >= + args->buf.buflen) + parsestat = + NSS_STR_PARSE_ERANGE; + else { + args->returnlen = len; + return (NSS_SUCCESS); + } } /* ==> ?? Treat ERANGE differently ?? */ if (parsestat == NSS_STR_PARSE_ERANGE) { @@ -903,7 +1093,7 @@ _nss_compat_getent(be, a) case GETENT_ALL: linelen = be->linelen; args->returnval = 0; - nss_getent(be->db_rootp, be->db_initf, + (void) nss_getent(be->db_rootp, be->db_initf, &be->db_context, args); if (args->returnval == 0) { /* ==> ?? Treat ERANGE differently ?? */ @@ -947,7 +1137,7 @@ _nss_compat_getent(be, a) savename = args->key.name; args->key.name = name; args->returnval = 0; - nss_search(be->db_rootp, be->db_initf, + (void) nss_search(be->db_rootp, be->db_initf, NSS_DBOP_next_iter, args); args->key.name = savename; /* In case anyone cares */ } @@ -966,6 +1156,7 @@ _nss_compat_getent(be, a) } return (do_merge(be, args, instr, linelen)); } + /*NOTREACHED*/ } /* We don't use this directly; we just copy the bits when we want to */ @@ -1016,6 +1207,7 @@ _nss_compat_constr(ops, n_ops, filename, min_bufsize, rootp, initf, netgroups, be->yp_domain = 0; be->getnetgrent_backend = 0; be->netgr_buffer = 0; + be->return_string_data = 0; return ((nss_backend_t *)be); } diff --git a/usr/src/lib/nsswitch/compat/common/compat_common.h b/usr/src/lib/nsswitch/compat/common/compat_common.h index cfd4f37e5c..08b30a3c82 100644 --- a/usr/src/lib/nsswitch/compat/common/compat_common.h +++ b/usr/src/lib/nsswitch/compat/common/compat_common.h @@ -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,8 +19,10 @@ * CDDL HEADER END */ /* - * Copyright (c) 1992, by Sun Microsystems, Inc. - * + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ +/* * Common code and structures used by name-service-switch "compat" backends. */ @@ -58,6 +59,42 @@ typedef int (*compat_merge_func)(compat_backend_ptr_t, nss_XbyY_args_t *, const char **fields); +typedef struct setofstrings *strset_t; + +struct compat_backend { + compat_backend_op_t *ops; + int n_ops; + const char *filename; + FILE *f; + int minbuf; + char *buf; + int linelen; /* <== Explain use, lifetime */ + + nss_db_initf_t db_initf; + nss_db_root_t *db_rootp; /* Shared between instances */ + nss_getent_t db_context; /* Per-instance enumeration */ + + compat_get_name getnamef; + compat_merge_func mergef; + + /* We wouldn't need all this hokey state stuff if we */ + /* used another thread to implement a coroutine... */ + enum { + GETENT_FILE, + GETENT_NETGROUP, + GETENT_ATTRDB, + GETENT_ALL, + GETENT_DONE + } state; + strset_t minuses; + + int permit_netgroups; + const char *yp_domain; + nss_backend_t *getnetgrent_backend; + char *netgr_buffer; + int return_string_data; +}; + #if defined(__STDC__) extern nss_backend_t *_nss_compat_constr(compat_backend_op_t *ops, int n_ops, diff --git a/usr/src/lib/nsswitch/compat/common/getauuser.c b/usr/src/lib/nsswitch/compat/common/getauuser.c index 8bf983c7dc..55b700bbb4 100644 --- a/usr/src/lib/nsswitch/compat/common/getauuser.c +++ b/usr/src/lib/nsswitch/compat/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,8 +19,8 @@ * CDDL HEADER END */ /* - * Copyright (c) 1999-2000 by 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" @@ -34,7 +33,7 @@ static DEFINE_NSS_DB_ROOT(db_root); -void +static void _nss_initf_auuser_compat(nss_db_params_t *p) { p->name = NSS_DBNAM_AUDITUSER; @@ -91,6 +90,7 @@ static compat_backend_op_t auuser_ops[] = { getbynam }; +/*ARGSUSED*/ nss_backend_t * _nss_compat_audit_user_constr(const char *dummy1, const char *dummy2, diff --git a/usr/src/lib/nsswitch/compat/common/getgrent.c b/usr/src/lib/nsswitch/compat/common/getgrent.c index b34c594de2..0457392e59 100644 --- a/usr/src/lib/nsswitch/compat/common/getgrent.c +++ b/usr/src/lib/nsswitch/compat/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. @@ -22,7 +21,7 @@ /* * getgrent.c * - * Copyright 2004 Sun Microsystems, Inc. All rights reserved. + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. * * lib/nsswitch/compat/getgrent.c -- name-service-switch backend for getgrnam() @@ -192,6 +191,7 @@ merge_grents(be, argp, fields) char *buf; char *s; int parsestat; + int dlen; /* * We're allowed to override the passwd (has anyone ever actually used @@ -201,7 +201,8 @@ merge_grents(be, argp, fields) * * Efficiency is heartlessly abandoned in the quest for simplicity. */ - if (fields[1] == 0 && fields[3] == 0) { + if (fields[1] == 0 && fields[3] == 0 && + be->return_string_data != 1) { /* No legal overrides, leave *argp unscathed */ return (NSS_STR_PARSE_SUCCESS); } @@ -216,7 +217,7 @@ merge_grents(be, argp, fields) g->gr_gid); s += strlen(s); if (fields[3] != 0) { - strcpy(s, fields[3]); + (void) strcpy(s, fields[3]); s += strlen(s); } else { char **memp; @@ -235,10 +236,31 @@ merge_grents(be, argp, fields) } } } - parsestat = (*argp->str2ent)(buf, s - buf, + + dlen = s - buf; + + /* + * if asked, return the data in /etc file format + */ + if (be->return_string_data == 1) { + /* reset the result ptr to the original value */ + argp->buf.result = NULL; + + if (dlen > argp->buf.buflen) { + parsestat = NSS_STR_PARSE_ERANGE; + } else { + (void) strncpy(argp->buf.buffer, buf, dlen); + argp->returnval = argp->buf.buffer; + argp->returnlen = dlen; + parsestat = NSS_SUCCESS; + } + } else { + parsestat = (*argp->str2ent)(buf, dlen, argp->buf.result, argp->buf.buffer, argp->buf.buflen); + } + free(buf); return (parsestat); } diff --git a/usr/src/lib/nsswitch/compat/common/getpwent.c b/usr/src/lib/nsswitch/compat/common/getpwent.c index e31462443f..1219dab7fa 100644 --- a/usr/src/lib/nsswitch/compat/common/getpwent.c +++ b/usr/src/lib/nsswitch/compat/common/getpwent.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,10 +19,10 @@ * CDDL HEADER END */ /* - * getpwent.c + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. * - * Copyright (c) 1988-1992 Sun Microsystems Inc - * All Rights Reserved. + * getpwent.c * * lib/nsswitch/compat/getpwent.c -- name-service-switch backend for getpwnam() * et al that does 4.x compatibility. It looks in /etc/passwd; if it finds @@ -60,7 +59,7 @@ static DEFINE_NSS_DB_ROOT(db_root); -void +static void _nss_initf_passwd_compat(p) nss_db_params_t *p; { @@ -92,7 +91,7 @@ getbyname(be, a) compat_backend_ptr_t be; void *a; { - nss_XbyY_args_t *argp = (nss_XbyY_args_t *) a; + nss_XbyY_args_t *argp = (nss_XbyY_args_t *)a; return (_nss_compat_XY_all(be, argp, check_pwname, NSS_DBOP_PASSWD_BYNAME)); @@ -112,7 +111,7 @@ getbyuid(be, a) compat_backend_ptr_t be; void *a; { - nss_XbyY_args_t *argp = (nss_XbyY_args_t *) a; + nss_XbyY_args_t *argp = (nss_XbyY_args_t *)a; return (_nss_compat_XY_all(be, argp, check_pwuid, NSS_DBOP_PASSWD_BYUID)); @@ -129,6 +128,8 @@ merge_pwents(be, argp, fields) char *buf = malloc(NSS_LINELEN_PASSWD); char *s; int parsestat; + int len; + int buflen; if (buf == 0) { return (NSS_STR_PARSE_PARSE); @@ -142,30 +143,60 @@ merge_pwents(be, argp, fields) * That's what the SunOS 4.x code did; who are we to question it... */ s = buf; - sprintf(s, "%s:", pw->pw_name); - s += strlen(s); - if (fields[1] != 0) { - strcpy(s, fields[1]); - } else { - strcpy(s, pw->pw_passwd); - if (pw->pw_age != 0) { - s += strlen(s); + buflen = argp->buf.buflen; + + if (fields[1] != 0) + len = snprintf(s, buflen, "%s:%s", + pw->pw_name, fields[1]); + else { /* ====> Does this do the right thing? */ - sprintf(s, ",%s", pw->pw_age); - } + if (pw->pw_age != 0 && *pw->pw_age != '\0') + len = snprintf(s, buflen, "%s:%s,%s", + pw->pw_name, pw->pw_passwd, pw->pw_age); + else + len = snprintf(s, buflen, "%s:%s", + pw->pw_name, pw->pw_passwd); } - s += strlen(s); - sprintf(s, ":%d:%d:%s:%s:%s", + + if (len > buflen) + return (NSS_STR_PARSE_ERANGE); + + s += len; + buflen -= len; + len = snprintf(s, buflen, ":%ld:%ld:%s:%s:%s", pw->pw_uid, pw->pw_gid, fields[4] != 0 ? fields[4] : pw->pw_gecos, fields[5] != 0 ? fields[5] : pw->pw_dir, fields[6] != 0 ? fields[6] : pw->pw_shell); - s += strlen(s); - parsestat = (*argp->str2ent)(buf, s - buf, + + if (len > buflen) + return (NSS_STR_PARSE_ERANGE); + + s += len; + len = s - buf; + + /* + * if asked, return the data in /etc file format + */ + if (be->return_string_data == 1) { + /* reset the result ptr to the original value */ + argp->buf.result = NULL; + + if (len > argp->buf.buflen) { + parsestat = NSS_STR_PARSE_ERANGE; + } else { + (void) strncpy(argp->buf.buffer, buf, len); + argp->returnval = argp->buf.buffer; + argp->returnlen = len; + parsestat = NSS_SUCCESS; + } + } else { + parsestat = (*argp->str2ent)(buf, len, argp->buf.result, argp->buf.buffer, argp->buf.buflen); + } free(buf); return (parsestat); } diff --git a/usr/src/lib/nsswitch/compat/common/getspent.c b/usr/src/lib/nsswitch/compat/common/getspent.c index c5671dcdef..96aba4f6e1 100644 --- a/usr/src/lib/nsswitch/compat/common/getspent.c +++ b/usr/src/lib/nsswitch/compat/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,11 +19,12 @@ * CDDL HEADER END */ /* + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ +/* * getspent.c * - * Copyright (c) 1988-1992 Sun Microsystems Inc - * All Rights Reserved. - * * lib/nsswitch/compat/getspent.c -- name-service-switch backend for getspnam() * It looks in /etc/shadow; if it finds shadow entries there that begin * with "+" or "-", it consults other services. By default it uses NIS (YP), @@ -55,7 +55,7 @@ static DEFINE_NSS_DB_ROOT(db_root); -void +static void _nss_initf_shadow_compat(p) nss_db_params_t *p; { @@ -87,7 +87,7 @@ getbyname(be, a) compat_backend_ptr_t be; void *a; { - nss_XbyY_args_t *argp = (nss_XbyY_args_t *) a; + nss_XbyY_args_t *argp = (nss_XbyY_args_t *)a; return (_nss_compat_XY_all(be, argp, check_spnamp, NSS_DBOP_SHADOW_BYNAME)); @@ -116,10 +116,12 @@ merge_spents(be, argp, fields) return (NSS_STR_PARSE_ERANGE); } if (sp->sp_namp != argp->buf.buffer) { - memmove(argp->buf.buffer, sp->sp_namp, namelen); + (void) memmove(argp->buf.buffer, + sp->sp_namp, namelen); sp->sp_namp = argp->buf.buffer; } - memcpy(argp->buf.buffer + namelen, fields[1], passlen); + (void) memcpy(argp->buf.buffer + namelen, + fields[1], passlen); } #define override(field, longp) \ @@ -142,7 +144,39 @@ merge_spents(be, argp, fields) override(fields[6], &sp->sp_inact); override(fields[7], &sp->sp_expire); override(fields[8], &sp->sp_flag); - return (NSS_STR_PARSE_SUCCESS); + + /* + * if asked, return the data in /etc file format + */ + if (be->return_string_data == 1) { + int n; + char b[16]; + + /* reset the result ptr to the original value */ + argp->buf.result = NULL; + +#define printnum(num) sprintf(b, "%d", num)) ? b : "" + + n = snprintf(argp->buf.buffer, argp->buf.buflen, + "%s:%s:%s:%s:%s:%s:%s:%s:%s", sp->sp_namp, + (sp->sp_pwdp ? sp->sp_pwdp : ""), + (sp->sp_lstchg >= 0 && printnum(sp->sp_lstchg), + (sp->sp_min >= 0 && printnum(sp->sp_min), + (sp->sp_max >= 0 && printnum(sp->sp_max), + (sp->sp_warn > 0 && printnum(sp->sp_warn), + (sp->sp_inact > 0 && printnum(sp->sp_inact), + (sp->sp_expire > 0 && printnum(sp->sp_expire), + (sp->sp_flag != 0 && printnum(sp->sp_flag)); + + if (n > argp->buf.buflen) + return (NSS_STR_PARSE_ERANGE); + else { + argp->returnlen = n - 1; + return (NSS_SUCCESS); + } + + } else + return (NSS_STR_PARSE_SUCCESS); } static compat_backend_op_t shadow_ops[] = { diff --git a/usr/src/lib/nsswitch/compat/common/getuserattr.c b/usr/src/lib/nsswitch/compat/common/getuserattr.c index 00572fa644..653101eca1 100644 --- a/usr/src/lib/nsswitch/compat/common/getuserattr.c +++ b/usr/src/lib/nsswitch/compat/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,8 +19,8 @@ * CDDL HEADER END */ /* - * Copyright (c) 1999-2000 by 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" @@ -34,7 +33,7 @@ static DEFINE_NSS_DB_ROOT(db_root); -void +static void _nss_initf_userattr_compat(nss_db_params_t *p) { p->name = NSS_DBNAM_USERATTR; @@ -91,6 +90,7 @@ static compat_backend_op_t userattr_ops[] = { getbynam }; +/*ARGSUSED*/ nss_backend_t * _nss_compat_user_attr_constr(const char *dummy1, const char *dummy2, diff --git a/usr/src/lib/nsswitch/dns/Makefile.com b/usr/src/lib/nsswitch/dns/Makefile.com index f4aa3f433c..23c89c32f8 100644 --- a/usr/src/lib/nsswitch/dns/Makefile.com +++ b/usr/src/lib/nsswitch/dns/Makefile.com @@ -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. # # ident "%Z%%M% %I% %E% SMI" @@ -45,5 +44,7 @@ include ../../../Makefile.rootfs # if no libresolv was provided by the application. CPPFLAGS += -DNSS_DNS_LIBRESOLV=\"libresolv.so.2\" +LINTFLAGS += -erroff=E_GLOBAL_COULD_BE_STATIC2 + LDLIBS += -lnsl DYNLIB1 = nss_dns.so$(VERS) diff --git a/usr/src/lib/nsswitch/dns/common/dns_common.c b/usr/src/lib/nsswitch/dns/common/dns_common.c index da766c4d12..0ed02f1d23 100644 --- a/usr/src/lib/nsswitch/dns/common/dns_common.c +++ b/usr/src/lib/nsswitch/dns/common/dns_common.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,16 +19,27 @@ * CDDL HEADER END */ /* - * dns_common.c - * - * Copyright (c) 1993,1998 by 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" +#pragma ident "%Z%%M% %I% %E% SMI" + +/* + * dns_common.c + */ #include "dns_common.h" +#pragma weak dn_expand +#pragma weak res_ninit +#pragma weak res_nsearch +#pragma weak res_nclose +#pragma weak ns_get16 +#pragma weak ns_get32 +#pragma weak __ns_get16 +#pragma weak __ns_get32 + #define DNS_ALIASES 0 #define DNS_ADDRLIST 1 #define DNS_MAPDLIST 2 @@ -58,7 +68,8 @@ dns_netdb_aliases(from_list, to_list, aliaspp, type, count, af_type) if (*aliaspp <= (char *)&to_list[cnt+1]) return (NSS_STR_PARSE_ERANGE); if (type == DNS_MAPDLIST) { - struct in6_addr *addr6p = (struct in6_addr *) *aliaspp; + /* LINTED: E_BAD_PTR_CAST_ALIGN */ + struct in6_addr *addr6p = (struct in6_addr *)*aliaspp; (void) memset(addr6p, '\0', sizeof (struct in6_addr)); (void) memcpy(&addr6p->s6_addr[12], fstr, @@ -96,7 +107,7 @@ ent2result(he, argp, af_type) struct in6_addr *addrp6; limit = argp->buf.buffer + buflen; - host = (struct hostent *) argp->buf.result; + host = (struct hostent *)argp->buf.result; buffer = argp->buf.buffer; /* h_addrtype and h_length */ @@ -114,7 +125,7 @@ ent2result(he, argp, af_type) /* h_addr_list */ if (af_type == AF_INET) { - addrp = (struct in_addr *) ROUND_DOWN(limit, sizeof (*addrp)); + addrp = (struct in_addr *)ROUND_DOWN(limit, sizeof (*addrp)); host->h_addr_list = (char **) ROUND_UP(buffer, sizeof (char **)); ret = dns_netdb_aliases(he->h_addr_list, host->h_addr_list, @@ -152,16 +163,368 @@ ent2result(he, argp, af_type) return (ret); } +/* + * Convert the hostent structure into string in the following + * format: + * + * IP-address official-host-name nicknames ... + * + * If more than one IP-addresses matches the official-host-name, + * the above line will be followed by: + * IP-address-1 official-host-name + * IP-address-2 official-host-name + * ... + * + * This is so that the str2hostent function in libnsl + * can convert the string back to the original hostent + * data. + */ +int +ent2str( + struct hostent *hp, + nss_XbyY_args_t *ap, + int af_type) +{ + char **p; + char obuf[INET6_ADDRSTRLEN]; + void *addr; + struct in_addr in4; + int af; + int n; + const char *res; + char **q; + int l = ap->buf.buflen; + char *s = ap->buf.buffer; + + /* + * for "hosts" lookup, we only want address type of + * AF_INET. For "ipnodes", we can have both AF_INET + * and AF_INET6. + */ + if (af_type == AF_INET && hp->h_addrtype != AF_INET) + return (NSS_STR_PARSE_PARSE); + + for (p = hp->h_addr_list; *p != 0; p++) { + + if (p != hp->h_addr_list) { + *s = '\n'; + s++; + l--; + } + + if (hp->h_addrtype == AF_INET6) { + /* LINTED: E_BAD_PTR_CAST_ALIGN */ + if (IN6_IS_ADDR_V4MAPPED((struct in6_addr *)*p)) { + /* LINTED: E_BAD_PTR_CAST_ALIGN */ + IN6_V4MAPPED_TO_INADDR((struct in6_addr *)*p, + &in4); + af = AF_INET; + addr = &in4; + } else { + af = AF_INET6; + addr = *p; + } + } else { + af = AF_INET; + addr = *p; + } + res = inet_ntop(af, addr, obuf, sizeof (obuf)); + if (res == NULL) + return (NSS_STR_PARSE_PARSE); + + if ((n = snprintf(s, l, "%s %s", res, hp->h_name)) >= l) + return (NSS_STR_PARSE_ERANGE); + l -= n; + s += n; + if (p == hp->h_addr_list) { + for (q = hp->h_aliases; q && *q; q++) { + if ((n = snprintf(s, l, " %s", *q)) >= l) + return (NSS_STR_PARSE_ERANGE); + l -= n; + s += n; + } + } + } + + ap->returnlen = s - ap->buf.buffer; + return (NSS_STR_PARSE_SUCCESS); +} nss_backend_t * _nss_dns_constr(dns_backend_op_t ops[], int n_ops) { dns_backend_ptr_t be; - if ((be = (dns_backend_ptr_t) malloc(sizeof (*be))) == 0) + if ((be = (dns_backend_ptr_t)malloc(sizeof (*be))) == 0) return (0); be->ops = ops; be->n_ops = n_ops; - return ((nss_backend_t *) be); + return ((nss_backend_t *)be); +} + + +/* + * nss_dns_gethost_withttl(void *buffer, size_t bufsize, int ipnode) + * nss2 get hosts/ipnodes with ttl backend DNS search engine. + * + * This API is given a pointer to a packed buffer, and the buffer size + * It's job is to perform the appropriate res_nsearch, extract the + * results and build a unmarshalled hosts/ipnodes result buffer. + * Additionally in the extended results a nssuint_t ttl is placed. + * This ttl is the lessor of the ttl's extracted from the result. + * + * ***Currently the first version of this API only performs simple + * single res_nsearch lookups for with T_A or T_AAAA results. + * Other searches are deferred to the generic API w/t ttls. + * + * This function is not a generic res_* operation. It only performs + * a single T_A or T_AAAA lookups*** + * + * RETURNS: NSS_SUCCESS or NSS_ERROR + * If an NSS_ERROR result is returned, nscd is expected + * to resubmit the gethosts request using the old style + * nsswitch lookup format. + */ + +struct tsd_priv { + struct __res_state *statp; /* dns state block */ + union msg { + uchar_t buf[NS_MAXMSG]; /* max legal DNS answer size */ + HEADER h; + } resbuf; + char aliases[NS_MAXMSG]; /* set of aliases */ +}; + +static void ghttlcleanup(void *ptr) +{ + struct tsd_priv *priv = (struct tsd_priv *)ptr; + + if (priv) { + if (priv->statp != NULL) { + res_nclose(priv->statp); + free((void *)priv->statp); + } + free(ptr); + } +} + +nss_status_t +_nss_dns_gethost_withttl(void *buffer, size_t bufsize, int ipnode) +{ + /* nss buffer variables */ + nss_pheader_t *pbuf = (nss_pheader_t *)buffer; + nss_XbyY_args_t arg; + char *dbname; + int dbop; + nss_status_t sret; + size_t bsize, blen; + char *bptr; + /* resolver query variables */ + static mutex_t keylock; + static thread_key_t key; + static int once_per_keyname = 0; + struct tsd_priv *tsd = NULL; + const char *name; + int qtype; + /* answer parsing variables */ + HEADER *hp; + uchar_t *cp; /* current location in message */ + uchar_t *bom; /* start of message */ + uchar_t *eom; /* end of message */ + uchar_t *eor; /* end of record */ + int ancount, qdcount; + int type, class; + nssuint_t nttl, ttl, *pttl; /* The purpose of this API */ + int n, ret; + const char *np; + /* temporary buffers */ + char nbuf[INET6_ADDRSTRLEN]; /* address parser */ + char host[MAXHOSTNAMELEN]; /* result host name */ + char ans[MAXHOSTNAMELEN]; /* record name */ + char aname[MAXHOSTNAMELEN]; /* alias result (C_NAME) */ + /* misc variables */ + int af; + char *ap, *apc; + int hlen, alen, iplen, len; + + if (!once_per_keyname) { + (void) mutex_lock(&keylock); + if (!once_per_keyname) { + (void) thr_keycreate(&key, ghttlcleanup); + once_per_keyname++; + } + (void) mutex_unlock(&keylock); + } + (void) thr_getspecific(key, (void **)&tsd); + if (tsd == NULL) { + tsd = (struct tsd_priv *)calloc(1, sizeof (struct tsd_priv)); + (void) thr_setspecific(key, (void *)tsd); + (void) thr_getspecific(key, (void **)&tsd); + tsd->statp = (struct __res_state *) + calloc(1, sizeof (struct __res_state)); + if (tsd->statp == NULL) + return (NSS_ERROR); + if (res_ninit(tsd->statp) == -1) { + free(tsd->statp); + return (NSS_ERROR); + } + } + ap = apc = (char *)tsd->aliases; + alen = 0; + ttl = (nssuint_t)0xFFFFFFF; /* start w/max, find smaller */ + + /* save space for ttl otherwise, why bother... */ + bsize = pbuf->data_len - sizeof (nssuint_t); + bptr = (char *)buffer + pbuf->data_off; + blen = 0; + sret = nss_packed_getkey(buffer, bufsize, &dbname, &dbop, &arg); + if (sret != NSS_SUCCESS) { + return (NSS_ERROR); + } + + if (ipnode) { + /* initially only handle the simple cases */ + if (arg.key.ipnode.flags != 0) + return (NSS_ERROR); + name = arg.key.ipnode.name; + if (arg.key.ipnode.af_family == AF_INET6) + qtype = T_AAAA; + else + qtype = T_A; + } else { + name = arg.key.name; + qtype = T_A; + } + ret = res_nsearch(tsd->statp, name, C_IN, qtype, + tsd->resbuf.buf, NS_MAXMSG); + if (ret == -1) { + if (tsd->statp->res_h_errno == HOST_NOT_FOUND) { + pbuf->p_herrno = HOST_NOT_FOUND; + pbuf->p_status = NSS_NOTFOUND; + pbuf->data_len = 0; + return (NSS_NOTFOUND); + } + /* else lookup error - handle in general code */ + return (NSS_ERROR); + } + + cp = tsd->resbuf.buf; + hp = (HEADER *)&tsd->resbuf.h; + bom = cp; + eom = cp + ret; + + ancount = ntohs(hp->ancount); + qdcount = ntohs(hp->qdcount); + cp += HFIXEDSZ; + if (qdcount != 1) + return (NSS_ERROR); + n = dn_expand(bom, eom, cp, host, MAXHOSTNAMELEN); + if (n < 0) { + return (NSS_ERROR); + } else + hlen = strlen(host); + cp += n + QFIXEDSZ; + if (cp > eom) + return (NSS_ERROR); + while (ancount-- > 0 && cp < eom && blen < bsize) { + n = dn_expand(bom, eom, cp, ans, MAXHOSTNAMELEN); + if (n > 0) { + if (strncasecmp(host, ans, hlen) != 0) + return (NSS_ERROR); /* spoof? */ + } + cp += n; + /* bounds check */ + type = ns_get16(cp); /* type */ + cp += INT16SZ; + class = ns_get16(cp); /* class */ + cp += INT16SZ; + nttl = (nssuint_t)ns_get32(cp); /* ttl in sec */ + if (nttl < ttl) + ttl = nttl; + cp += INT32SZ; + n = ns_get16(cp); /* len */ + cp += INT16SZ; + if (class != C_IN) { + cp += n; + continue; + } + eor = cp + n; + if (type == T_CNAME) { + /* add an alias to the alias list */ + n = dn_expand(bom, eor, cp, aname, MAXHOSTNAMELEN); + if (n > 0) { + len = strlen(aname); + if (len > 0) { + /* + * Just error out if there is an + * attempted buffer overflow exploit + * generic code will do a syslog + */ + if (alen + len + 2 > NS_MAXMSG) + return (NSS_ERROR); + *apc++ = ' '; + alen++; + (void) strlcpy(apc, aname, len + 1); + alen += len; + apc += len; + } + } + cp += n; + continue; + } + if (type != qtype) { + cp += n; + continue; + } + /* check data size */ + if ((type == T_A && n != INADDRSZ) || + (type == T_AAAA && n != IN6ADDRSZ)) { + cp += n; + continue; + } + af = (type == T_A ? AF_INET : AF_INET6); + np = inet_ntop(af, (void *)cp, nbuf, INET6_ADDRSTRLEN); + if (np == NULL) + return (NSS_ERROR); + cp += n; + /* append IP host aliases to results */ + iplen = strlen(np); + /* ip <SP> hostname [<SP>][aliases] */ + len = iplen + 2 + hlen + alen; + if (alen > 0) + len++; + if (blen + len > bsize) + return (NSS_ERROR); + (void) strlcpy(bptr, np, bsize - blen); + blen += iplen; + bptr += iplen; + *bptr++ = ' '; + blen++; + (void) strlcpy(bptr, host, bsize - blen); + blen += hlen; + bptr += hlen; + if (alen > 0) { + *bptr++ = ' '; + blen++; + (void) strlcpy(bptr, ap, bsize - blen); + blen += alen; + bptr += alen; + } + *bptr++ = '\n'; + blen++; + } + /* Presumably the buffer is now filled. */ + len = ROUND_UP(blen, sizeof (nssuint_t)); + /* still room? */ + if (len + sizeof (nssuint_t) > pbuf->data_len) { + /* sigh, no, what happened? */ + return (NSS_ERROR); + } + pbuf->ext_off = pbuf->data_off + len; + pbuf->ext_len = sizeof (nssuint_t); + pbuf->data_len = blen; + pttl = (nssuint_t *)((void *)((char *)pbuf + pbuf->ext_off)); + *pttl = ttl; + return (NSS_SUCCESS); } diff --git a/usr/src/lib/nsswitch/dns/common/dns_common.h b/usr/src/lib/nsswitch/dns/common/dns_common.h index 7861cbb683..f60a37e436 100644 --- a/usr/src/lib/nsswitch/dns/common/dns_common.h +++ b/usr/src/lib/nsswitch/dns/common/dns_common.h @@ -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,9 +19,10 @@ * CDDL HEADER END */ /* - * Copyright (c) 1993, 1998-1999 by Sun Microsystems, Inc. - * All rights reserved. - * + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ +/* * Common code and structures used by name-service-switch "dns" backends. */ @@ -39,10 +39,12 @@ #include <netdb.h> #include <strings.h> #include <thread.h> +#include <arpa/inet.h> #include <arpa/nameser.h> #include <resolv.h> #include <syslog.h> #include <nsswitch.h> +#include <nss_common.h> #include <nss_dbdefs.h> #include <stdlib.h> #include <signal.h> @@ -74,13 +76,17 @@ extern mutex_t one_lane; extern int _thr_sigsetmask(int, const sigset_t *, sigset_t *); extern int _mutex_lock(mutex_t *); extern int _mutex_unlock(mutex_t *); -extern const char *inet_ntop(int, const void *, char *, size_t); extern int ent2result(struct hostent *, nss_XbyY_args_t *, int); +extern int ent2str(struct hostent *, nss_XbyY_args_t *, int); nss_backend_t *_nss_dns_constr(dns_backend_op_t *, int); extern nss_status_t _herrno2nss(int); +nss_status_t _nss_dns_gethost_withttl(void *buf, size_t bufsize, int ipnode); +nss_status_t _nss_get_dns_hosts_name(dns_backend_ptr_t *, void **, size_t *); +nss_status_t _nss_get_dns_ipnodes_name(dns_backend_ptr_t *, void **, size_t *); + #ifdef __cplusplus } #endif diff --git a/usr/src/lib/nsswitch/dns/common/dns_mt.c b/usr/src/lib/nsswitch/dns/common/dns_mt.c index 7e236c40eb..bf6ac565c4 100644 --- a/usr/src/lib/nsswitch/dns/common/dns_mt.c +++ b/usr/src/lib/nsswitch/dns/common/dns_mt.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,8 +19,8 @@ * CDDL HEADER END */ /* - * Copyright (c) 1993, 1998-2001 by 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" @@ -109,11 +108,10 @@ mutex_t one_lane = DEFAULTMUTEX; void _nss_dns_init(void) { - struct hostent *(*f_hostent_ptr)(); void *reslib, (*f_void_ptr)(); /* If no libresolv library, then load one */ - if ((f_hostent_ptr = res_gethostbyname) == 0) { + if (res_gethostbyname == 0) { if ((reslib = dlopen(NSS_DNS_LIBRESOLV, RTLD_LAZY|RTLD_GLOBAL)) != 0) { /* Turn off /etc/hosts fall back in libresolv */ diff --git a/usr/src/lib/nsswitch/dns/common/gethostent.c b/usr/src/lib/nsswitch/dns/common/gethostent.c index 38c8a44a3a..af365f4f2a 100644 --- a/usr/src/lib/nsswitch/dns/common/gethostent.c +++ b/usr/src/lib/nsswitch/dns/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,8 +19,8 @@ * CDDL HEADER END */ /* - * Copyright (c) 1993, 1998-2000 by 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" @@ -144,10 +143,22 @@ getbyname(be, a) he = _gethostbyname(&argp->h_errno, argp->key.name); if (he != NULL) { - ret = ent2result(he, a, AF_INET); - if (ret == NSS_STR_PARSE_SUCCESS) { - argp->returnval = argp->buf.result; + if (argp->buf.result == NULL) { + /* + * if asked to return data in string, + * convert the hostent structure into + * string data + */ + ret = ent2str(he, a, AF_INET); + if (ret == NSS_STR_PARSE_SUCCESS) + argp->returnval = argp->buf.buffer; } else { + ret = ent2result(he, a, AF_INET); + if (ret == NSS_STR_PARSE_SUCCESS) + argp->returnval = argp->buf.result; + } + + if (ret != NSS_STR_PARSE_SUCCESS) { argp->h_errno = HOST_NOT_FOUND; if (ret == NSS_STR_PARSE_ERANGE) { argp->erange = 1; @@ -176,6 +187,7 @@ getbyaddr(be, a) * Exposing a DNS backend specific interface so that it doesn't conflict * with other getbyaddr() routines from other switch backends. */ +/*ARGSUSED*/ nss_status_t __nss_dns_getbyaddr(be, a) dns_backend_ptr_t be; @@ -195,11 +207,12 @@ __nss_dns_getbyaddr(be, a) switch_resolver_setup(&mt_disabled, &oldmask, &old_retry); + /* LINTED: E_BAD_PTR_CAST_ALIGN */ if (IN6_IS_ADDR_V4MAPPED((struct in6_addr *)argp->key.hostaddr.addr)) { addrp = &unmapv4; addrlen = sizeof (unmapv4); af = AF_INET; - memcpy(addrp, &argp->key.hostaddr.addr[12], addrlen); + (void) memcpy(addrp, &argp->key.hostaddr.addr[12], addrlen); } else { addrp = (void *)argp->key.hostaddr.addr; addrlen = argp->key.hostaddr.len; @@ -217,7 +230,18 @@ __nss_dns_getbyaddr(be, a) if (n < MAXHOSTNAMELEN-1 && hbuf[n-1] != '.') { (void) strcat(hbuf, "."); } - ret = ent2result(he, a, argp->key.hostaddr.type); + + /* + * if asked to return data in string, + * convert the hostent structure into + * string data + */ + if (argp->buf.result == NULL) + ret = ent2str(he, a, argp->key.hostaddr.type); + else + ret = ent2result(he, a, + argp->key.hostaddr.type); + save_h_errno = argp->h_errno; } if (ret == NSS_STR_PARSE_SUCCESS) { @@ -242,7 +266,12 @@ __nss_dns_getbyaddr(be, a) if (memcmp(*ans, addrp, addrlen) == 0) { argp->h_errno = save_h_errno; - argp->returnval = argp->buf.result; + if (argp->buf.result == NULL) + argp->returnval = + argp->buf.buffer; + else + argp->returnval = + argp->buf.result; break; } } else { @@ -259,12 +288,16 @@ __nss_dns_getbyaddr(be, a) * this go. And return the name from byaddr. */ argp->h_errno = save_h_errno; - argp->returnval = argp->buf.result; + if (argp->buf.result == NULL) + argp->returnval = argp->buf.buffer; + else + argp->returnval = argp->buf.result; } /* we've been spoofed, make sure to log it. */ if (argp->h_errno == HOST_NOT_FOUND) { if (argp->key.hostaddr.type == AF_INET) syslog(LOG_NOTICE, "gethostbyaddr: %s != %s", + /* LINTED: E_BAD_PTR_CAST_ALIGN */ hbuf, inet_ntoa(*(struct in_addr *)argp->key.hostaddr.addr)); else syslog(LOG_NOTICE, "gethostbyaddr: %s != %s", @@ -414,3 +447,22 @@ _nss_dns_hosts_constr(dummy1, dummy2, dummy3) return (_nss_dns_constr(host_ops, sizeof (host_ops) / sizeof (host_ops[0]))); } + +/* + * optional NSS2 packed backend gethostsbyname with ttl + * entry point. + * + * Returns: + * NSS_SUCCESS - successful + * NSS_NOTFOUND - successful but nothing found + * NSS_ERROR - fallback to NSS backend lookup mode + * If successful, buffer will be filled with valid data + * + */ + +/*ARGSUSED*/ +nss_status_t +_nss_get_dns_hosts_name(dns_backend_ptr_t *be, void **bufp, size_t *sizep) +{ + return (_nss_dns_gethost_withttl(*bufp, *sizep, 0)); +} diff --git a/usr/src/lib/nsswitch/dns/common/gethostent6.c b/usr/src/lib/nsswitch/dns/common/gethostent6.c index e92ce6a356..b2d71d6b24 100644 --- a/usr/src/lib/nsswitch/dns/common/gethostent6.c +++ b/usr/src/lib/nsswitch/dns/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,9 +19,10 @@ * CDDL HEADER END */ /* - * Copyright 1993-2000, 2003 Sun Microsystems, Inc. All rights reserved. + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. - * + */ +/* * gethostent6.c */ @@ -115,7 +115,7 @@ cloneName(struct hostent *h, int *outerr) { return (0); } - memcpy(name, h->h_name, len+1); + (void) memcpy(name, h->h_name, len+1); *errp = 0; return (name); @@ -130,7 +130,7 @@ cloneName(struct hostent *h, int *outerr) { * Note: The pointers to the addresses in the moreAddrs[] array are copied, * but not the IP addresses themselves. */ -struct in6_addr ** +static struct in6_addr ** cloneAddrList(struct hostent *h, struct in6_addr **moreAddrs, int *outerr) { struct in6_addr **addrArray, *addrList; @@ -176,10 +176,12 @@ cloneAddrList(struct hostent *h, struct in6_addr **moreAddrs, int *outerr) { for (i = 0; i < addrCount; i++) { addrArray[i] = addrList; if (domap) { + /* LINTED: E_BAD_PTR_CAST_ALIGN */ IN6_INADDR_TO_V4MAPPED( (struct in_addr *)h->h_addr_list[i], addrArray[i]); } else { - memcpy(addrArray[i], h->h_addr_list[i], addrlen); + (void) memcpy(addrArray[i], h->h_addr_list[i], + addrlen); } addrList = PTROFF(addrList, addrlen); } @@ -211,7 +213,7 @@ static char ** cloneAliasList(struct hostent *h, char **mergeAliases, int *outerr) { char **aliasArray, *aliasList; - int i, j, k, aliasCount, mergeAliasCount = 0, realMac = 0; + int i, j, aliasCount, mergeAliasCount = 0, realMac = 0; int stringSize = 0; int error, *errp; @@ -259,7 +261,7 @@ cloneAliasList(struct hostent *h, char **mergeAliases, int *outerr) { for (i = 0; i < aliasCount; i++) { int len = strlen(h->h_aliases[i]); aliasArray[i] = aliasList; - memcpy(aliasArray[i], h->h_aliases[i], len+1); + (void) memcpy(aliasArray[i], h->h_aliases[i], len+1); aliasList = PTROFF(aliasList, RNDUP(len+1)); } @@ -275,7 +277,7 @@ cloneAliasList(struct hostent *h, char **mergeAliases, int *outerr) { return (aliasArray); } - +/*ARGSUSED*/ static nss_status_t getbyname(be, a) dns_backend_ptr_t be; @@ -407,11 +409,23 @@ getbyname(be, a) argp->h_errno = v6_h_errno; } - if (he != 0) { - ret = ent2result(he, a, AF_INET6); - if (ret == NSS_STR_PARSE_SUCCESS) { - argp->returnval = argp->buf.result; + if (he != NULL) { + /* + * if asked to return data in string, + * convert the hostent structure into + * string data + */ + if (argp->buf.result == NULL) { + ret = ent2str(he, a, AF_INET6); + if (ret == NSS_STR_PARSE_SUCCESS) + argp->returnval = argp->buf.buffer; } else { + ret = ent2result(he, a, AF_INET6); + if (ret == NSS_STR_PARSE_SUCCESS) + argp->returnval = argp->buf.result; + } + + if (ret != NSS_STR_PARSE_SUCCESS) { argp->h_errno = HOST_NOT_FOUND; if (ret == NSS_STR_PARSE_ERANGE) { argp->erange = 1; @@ -532,3 +546,22 @@ _nss_dns_ipnodes_constr(dummy1, dummy2, dummy3) return (_nss_dns_constr(ipnodes_ops, sizeof (ipnodes_ops) / sizeof (ipnodes_ops[0]))); } + +/* + * optional NSS2 packed backend gethostsbyipnode with ttl + * entry point. + * + * Returns: + * NSS_SUCCESS - successful + * NSS_NOTFOUND - successful but nothing found + * NSS_ERROR - fallback to NSS backend lookup mode + * If successful, buffer will be filled with valid data + * + */ + +/*ARGSUSED*/ +nss_status_t +_nss_get_dns_ipnodes_name(dns_backend_ptr_t *be, void **bufp, size_t *sizep) +{ + return (_nss_dns_gethost_withttl(*bufp, *sizep, 1)); +} diff --git a/usr/src/lib/nsswitch/dns/common/mapfile-vers b/usr/src/lib/nsswitch/dns/common/mapfile-vers index 6e44ffe568..9aa3d5ff1a 100644 --- a/usr/src/lib/nsswitch/dns/common/mapfile-vers +++ b/usr/src/lib/nsswitch/dns/common/mapfile-vers @@ -1,15 +1,14 @@ # #ident "%Z%%M% %I% %E% SMI" # -# Copyright 2005 Sun Microsystems, Inc. All rights reserved. +# Copyright 2006 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # # 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. @@ -41,6 +40,8 @@ SUNWprivate_1.1 { global: _nss_dns_hosts_constr; _nss_dns_ipnodes_constr; + _nss_get_dns_hosts_name; + _nss_get_dns_ipnodes_name; local: *; }; diff --git a/usr/src/lib/nsswitch/files/Makefile.com b/usr/src/lib/nsswitch/files/Makefile.com index f6105144d7..0f5ff82629 100644 --- a/usr/src/lib/nsswitch/files/Makefile.com +++ b/usr/src/lib/nsswitch/files/Makefile.com @@ -61,8 +61,10 @@ include ../../Makefile.com include ../../../Makefile.rootfs CPPFLAGS += -I../../../common/inc +LINTFLAGS += -erroff=E_GLOBAL_COULD_BE_STATIC2 +LINTFLAGS64 += -erroff=E_GLOBAL_COULD_BE_STATIC2 -LDLIBS += -lnsl +LDLIBS += -lsocket -lnsl DYNLIB1 = nss_files.so$(VERS) all: $(DYNLIB1) fnamecheck diff --git a/usr/src/lib/nsswitch/files/common/bootparams_getbyname.c b/usr/src/lib/nsswitch/files/common/bootparams_getbyname.c index ef51910acb..e1e88b1ced 100644 --- a/usr/src/lib/nsswitch/files/common/bootparams_getbyname.c +++ b/usr/src/lib/nsswitch/files/common/bootparams_getbyname.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,11 +19,11 @@ * CDDL HEADER END */ /* + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + * * files/bootparams_getbyname.c -- "files" backend for * nsswitch "bootparams" database. - * - * Copyright (c) 1988-1995 Sun Microsystems Inc - * All Rights Reserved. */ #pragma ident "%Z%%M% %I% %E% SMI" @@ -44,7 +43,7 @@ getbyname(be, a) files_backend_ptr_t be; void *a; { - nss_XbyY_args_t *argp = (nss_XbyY_args_t *) a; + nss_XbyY_args_t *argp = (nss_XbyY_args_t *)a; nss_status_t res; /* bootparams_getbyname() has not set/endent; rewind on each call */ @@ -108,14 +107,14 @@ _nss_files_XY_bootparams(be, args, filter) * _nss_files_read_line does process the '\' that are used * in /etc/bootparams for continuation and gives one long * buffer. - * + * * linelen counts the characters up to but excluding the '\n' */ if ((linelen = _nss_files_read_line(be->f, instr, be->minbuf)) < 0) { /* End of file */ args->returnval = 0; - args->erange = 0; + args->returnlen = 0; break; } @@ -158,6 +157,7 @@ _nss_files_XY_bootparams(be, args, filter) (void) memcpy(args->buf.buffer, p, linelen); args->buf.buffer[linelen] = '\0'; args->returnval = args->buf.result; + args->returnlen = linelen; res = NSS_SUCCESS; break; } diff --git a/usr/src/lib/nsswitch/files/common/ether_addr.c b/usr/src/lib/nsswitch/files/common/ether_addr.c index 4731e0c354..b8900cf043 100644 --- a/usr/src/lib/nsswitch/files/common/ether_addr.c +++ b/usr/src/lib/nsswitch/files/common/ether_addr.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,9 +19,9 @@ * CDDL HEADER END */ /* - * files/ether_addr.c -- "files" backend for nsswitch "ethers" database + * files/ether_addr.c -- "files" backend for nsswitch "ethers" database * - * Copyright 1988-1995,2002 Sun Microsystems, Inc. All rights reserved. + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -44,14 +43,38 @@ #include <nss_dbdefs.h> #include "files_common.h" #include <strings.h> +#include <ctype.h> #define _PATH_ETHERS "/etc/ethers" +#define DIGIT(x) \ + (isdigit(x) ? (x) - '0' : islower(x) ? (x) + 10 - 'a' : (x) + 10 - 'A') static int -check_host(args) - nss_XbyY_args_t *args; +check_host(nss_XbyY_args_t *argp, const char *line, int linelen) { - return (strcmp(args->buf.buffer, args->key.name) == 0); + const char *limit, *linep, *keyp; + linep = line; + limit = line + linelen; + + /* skip leading spaces */ + while (linep < limit && isspace(*linep)) + linep++; + /* skip mac address */ + while (linep < limit && !isspace(*linep)) + linep++; + /* skip the delimiting spaces */ + while (linep < limit && isspace(*linep)) + linep++; + if (linep == limit) + return (0); + + /* compare the host name */ + keyp = argp->key.name; + while (*keyp != '\0' && linep < limit && *keyp == *linep) { + keyp++; + linep++; + } + return (*keyp == '\0' && linep == limit); } static nss_status_t @@ -63,21 +86,57 @@ getbyhost(be, a) char hostname[MAXHOSTNAMELEN]; nss_status_t res; - argp->buf.buffer = hostname; - argp->buf.buflen = MAXHOSTNAMELEN; + /* + * use the buffer passed in if result is to be returned + * in /etc file format + */ + if (argp->buf.result != NULL) { + argp->buf.buffer = hostname; + argp->buf.buflen = MAXHOSTNAMELEN; + } res = _nss_files_XY_all(be, argp, 0, argp->key.name, check_host); - argp->buf.buffer = NULL; - argp->buf.buflen = 0; + if (argp->buf.result != NULL) { + argp->buf.buffer = NULL; + argp->buf.buflen = 0; + } + return (res); } static int -check_ether(args) - nss_XbyY_args_t *args; +check_ether(nss_XbyY_args_t *argp, const char *line, int linelen) { - return (ether_cmp(args->buf.result, args->key.ether) == 0); + + const char *limit, *linep; + uchar_t ether[6]; + ptrdiff_t i; + int n; + + linep = line; + limit = line + linelen; + + /* skip leading spaces */ + while (linep < limit && isspace(*linep)) + linep++; + + for (i = 0; i < 6; i++) { + n = 0; + while (linep < limit && isxdigit(*linep)) { + n = 16 * n + DIGIT(*linep); + linep++; + } + if (*linep != ':' && i < 5) { + return (0); + } else if (*linep == ':' && i == 5) { + return (0); + } else { + linep++; + ether[i] = (uchar_t)n; + } + } + return (ether_cmp((void *)ether, (void *)argp->key.ether) == 0); } static nss_status_t diff --git a/usr/src/lib/nsswitch/files/common/files_common.c b/usr/src/lib/nsswitch/files/common/files_common.c index bdf03a3ca9..0f89f25d0b 100644 --- a/usr/src/lib/nsswitch/files/common/files_common.c +++ b/usr/src/lib/nsswitch/files/common/files_common.c @@ -41,6 +41,7 @@ #include <poll.h> #include <unistd.h> #include <sys/stat.h> +#include <sys/mman.h> /*ARGSUSED*/ nss_status_t @@ -69,7 +70,7 @@ _nss_files_endent(be, dummy) void *dummy; { if (be->f != 0) { - fclose(be->f); + (void) fclose(be->f); be->f = 0; } if (be->buf != 0) { @@ -186,7 +187,7 @@ _nss_files_do_all(be, args, filter, func) } while (res == NSS_NOTFOUND); - _nss_files_endent(be, 0); + (void) _nss_files_endent(be, 0); return (res); } @@ -208,6 +209,8 @@ _nss_files_XY_all(be, args, netdb, filter, check) int parsestat; int (*func)(); + if (filter != NULL && *filter == '\0') + return (NSS_NOTFOUND); if (be->buf == 0 && (be->buf = malloc(be->minbuf)) == 0) { return (NSS_UNAVAIL); /* really panic, malloc failed */ @@ -230,7 +233,7 @@ _nss_files_XY_all(be, args, netdb, filter, check) be->minbuf)) < 0) { /* End of file */ args->returnval = 0; - args->erange = 0; + args->returnlen = 0; break; } if (filter != 0 && strstr(instr, filter) == 0) { @@ -277,17 +280,21 @@ _nss_files_XY_all(be, args, netdb, filter, check) } args->returnval = 0; + args->returnlen = 0; + + if (check != NULL && (*check)(args, instr, linelen) == 0) + continue; func = args->str2ent; parsestat = (*func)(instr, linelen, args->buf.result, args->buf.buffer, args->buf.buflen); if (parsestat == NSS_STR_PARSE_SUCCESS) { - args->returnval = args->buf.result; - if (check == 0 || (*check)(args)) { - res = NSS_SUCCESS; - break; - } + args->returnval = (args->buf.result != NULL)? + args->buf.result : args->buf.buffer; + args->returnlen = linelen; + res = NSS_SUCCESS; + break; } else if (parsestat == NSS_STR_PARSE_ERANGE) { args->erange = 1; break; @@ -339,15 +346,22 @@ _nss_files_hash_destroy(files_hash_t *fhp) extern void __nss_use_files_hash(void); #endif /* pic */ +/*ARGSUSED*/ nss_status_t _nss_files_XY_hash(files_backend_ptr_t be, nss_XbyY_args_t *args, int netdb, files_hash_t *fhp, int hashop, files_XY_check_func check) { + /* LINTED E_FUNC_VAR_UNUSED */ int fd, retries, ht; + /* LINTED E_FUNC_VAR_UNUSED */ uint_t hash, line, f; + /* LINTED E_FUNC_VAR_UNUSED */ files_hashent_t *hp, *htab; + /* LINTED E_FUNC_VAR_UNUSED */ char *cp, *first, *last; + /* LINTED E_FUNC_VAR_UNUSED */ nss_XbyY_args_t xargs; + /* LINTED E_FUNC_VAR_UNUSED */ struct stat64 st; #ifndef PIC @@ -375,26 +389,30 @@ retry: st.st_mtim.tv_nsec == fhp->fh_mtime.tv_nsec && fhp->fh_table != NULL) { htab = &fhp->fh_table[hashop * fhp->fh_size]; - hash = fhp->fh_hash_func[hashop](args, 1); + hash = fhp->fh_hash_func[hashop](args, 1, NULL, 0); for (hp = htab[hash % fhp->fh_size].h_first; hp != NULL; hp = hp->h_next) { if (hp->h_hash != hash) continue; line = hp - htab; + if ((*check)(args, fhp->fh_line[line].l_start, + fhp->fh_line[line].l_len) == 0) + continue; if ((*args->str2ent)(fhp->fh_line[line].l_start, fhp->fh_line[line].l_len, args->buf.result, args->buf.buffer, args->buf.buflen) == NSS_STR_PARSE_SUCCESS) { - args->returnval = args->buf.result; - if ((*check)(args)) { - mutex_unlock(&fhp->fh_lock); - return (NSS_SUCCESS); - } + args->returnval = (args->buf.result)? + args->buf.result:args->buf.buffer; + args->returnlen = fhp->fh_line[line].l_len; + mutex_unlock(&fhp->fh_lock); + return (NSS_SUCCESS); } else { args->erange = 1; } } args->returnval = 0; + args->returnlen = 0; mutex_unlock(&fhp->fh_lock); return (NSS_NOTFOUND); } @@ -461,14 +479,6 @@ retry: if (fhp->fh_line == NULL || fhp->fh_table == NULL) goto unavail; - xargs = *args; - xargs.buf.result = malloc(fhp->fh_resultsize + fhp->fh_bufsize); - if (xargs.buf.result == NULL) - goto unavail; - xargs.buf.buffer = (char *)xargs.buf.result + fhp->fh_resultsize; - xargs.buf.buflen = fhp->fh_bufsize; - xargs.returnval = xargs.buf.result; - line = 0; cp = fhp->fh_file_start; while (cp < fhp->fh_file_end) { @@ -494,18 +504,14 @@ retry: --last; *++last = '\0'; } - if ((*xargs.str2ent)(first, last - first, - xargs.buf.result, xargs.buf.buffer, xargs.buf.buflen) != - NSS_STR_PARSE_SUCCESS) - continue; for (ht = 0; ht < fhp->fh_nhtab; ht++) { hp = &fhp->fh_table[ht * fhp->fh_size + line]; - hp->h_hash = fhp->fh_hash_func[ht](&xargs, 0); + hp->h_hash = fhp->fh_hash_func[ht](&xargs, 0, first, + last - first); } fhp->fh_line[line].l_start = first; fhp->fh_line[line++].l_len = last - first; } - free(xargs.buf.result); /* * Populate the hash tables in reverse order so that the hash chains @@ -561,13 +567,13 @@ _nss_files_destr(be, dummy) { if (be != 0) { if (be->f != 0) { - _nss_files_endent(be, 0); + (void) _nss_files_endent(be, 0); } if (be->hashinfo != NULL) { - mutex_lock(&be->hashinfo->fh_lock); + (void) mutex_lock(&be->hashinfo->fh_lock); if (--be->hashinfo->fh_refcnt == 0) _nss_files_hash_destroy(be->hashinfo); - mutex_unlock(&be->hashinfo->fh_lock); + (void) mutex_unlock(&be->hashinfo->fh_lock); } free(be); } @@ -596,10 +602,80 @@ _nss_files_constr(ops, n_ops, filename, min_bufsize, fhp) be->hashinfo = fhp; if (fhp != NULL) { - mutex_lock(&fhp->fh_lock); + (void) mutex_lock(&fhp->fh_lock); fhp->fh_refcnt++; - mutex_unlock(&fhp->fh_lock); + (void) mutex_unlock(&fhp->fh_lock); } return ((nss_backend_t *)be); } + +int +_nss_files_check_name_colon(nss_XbyY_args_t *argp, const char *line, + int linelen) +{ + const char *linep, *limit; + const char *keyp = argp->key.name; + + linep = line; + limit = line + linelen; + while (*keyp && linep < limit && *keyp == *linep) { + keyp++; + linep++; + } + return (linep < limit && *keyp == '\0' && *linep == ':'); +} + +/* + * This routine is used to parse lines of the form: + * name number aliases + * It returns 1 if the key in argp matches any one of the + * names in the line, otherwise 0 + * Used by rpc, networks, protocols + */ +int +_nss_files_check_name_aliases(nss_XbyY_args_t *argp, const char *line, + int linelen) +{ + const char *limit, *linep, *keyp; + + linep = line; + limit = line + linelen; + keyp = argp->key.name; + + /* compare name */ + while (*keyp && linep < limit && !isspace(*linep) && *keyp == *linep) { + keyp++; + linep++; + } + if (*keyp == '\0' && linep < limit && isspace(*linep)) + return (1); + /* skip remainder of the name, if any */ + while (linep < limit && !isspace(*linep)) + linep++; + /* skip the delimiting spaces */ + while (linep < limit && isspace(*linep)) + linep++; + /* compare with the aliases */ + while (linep < limit) { + /* + * 1st pass: skip number + * Other passes: skip remainder of the alias name, if any + */ + while (linep < limit && !isspace(*linep)) + linep++; + /* skip the delimiting spaces */ + while (linep < limit && isspace(*linep)) + linep++; + /* compare with the alias name */ + keyp = argp->key.name; + while (*keyp && linep < limit && !isspace(*linep) && + *keyp == *linep) { + keyp++; + linep++; + } + if (*keyp == '\0' && (linep == limit || isspace(*linep))) + return (1); + } + return (0); +} diff --git a/usr/src/lib/nsswitch/files/common/files_common.h b/usr/src/lib/nsswitch/files/common/files_common.h index 87980f8310..9f7457a033 100644 --- a/usr/src/lib/nsswitch/files/common/files_common.h +++ b/usr/src/lib/nsswitch/files/common/files_common.h @@ -45,12 +45,12 @@ extern "C" { typedef struct files_backend *files_backend_ptr_t; typedef nss_status_t (*files_backend_op_t)(files_backend_ptr_t, void *); -typedef u_int (*files_hash_func)(nss_XbyY_args_t *, int); +typedef uint_t (*files_hash_func)(nss_XbyY_args_t *, int, const char *, int); typedef struct files_hashent { struct files_hashent *h_first; struct files_hashent *h_next; - u_int h_hash; + uint_t h_hash; } files_hashent_t; typedef struct { @@ -92,7 +92,8 @@ struct files_backend { * generic work for nss_XbyY_args_t backends (calls cstr2ent etc). */ typedef nss_status_t (*files_do_all_func_t)(const char *, int, void *args); -typedef int (*files_XY_check_func)(nss_XbyY_args_t *); +typedef int (*files_XY_check_func)(nss_XbyY_args_t *, + const char *, int); #if defined(__STDC__) extern nss_backend_t *_nss_files_constr(files_backend_op_t *ops, @@ -133,6 +134,9 @@ extern nss_status_t _nss_files_XY_all(); extern nss_status_t _nss_files_XY_hash(); #endif +int _nss_files_check_name_aliases(nss_XbyY_args_t *, const char *, int); +int _nss_files_check_name_colon(nss_XbyY_args_t *, const char *, int); + #ifdef __cplusplus } #endif diff --git a/usr/src/lib/nsswitch/files/common/getauthattr.c b/usr/src/lib/nsswitch/files/common/getauthattr.c index df236111ec..bf02ce214c 100644 --- a/usr/src/lib/nsswitch/files/common/getauthattr.c +++ b/usr/src/lib/nsswitch/files/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,8 +19,8 @@ * CDDL HEADER END */ /* - * Copyright (c) 1999-2001 by 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" @@ -35,24 +34,14 @@ * files/getauthattr.c -- * "files" backend for nsswitch "auth_attr" database */ -static int -check_name(nss_XbyY_args_t *args) -{ - authstr_t *auth = (authstr_t *)args->returnval; - const char *name = args->key.name; - - if (strcmp(auth->name, name) == 0) { - return (1); - } - return (0); -} static nss_status_t getbyname(files_backend_ptr_t be, void *a) { nss_XbyY_args_t *argp = (nss_XbyY_args_t *)a; - return (_nss_files_XY_all(be, argp, 1, argp->key.name, check_name)); + return (_nss_files_XY_all(be, argp, 1, argp->key.name, + _nss_files_check_name_colon)); } static files_backend_op_t authattr_ops[] = { @@ -63,6 +52,7 @@ static files_backend_op_t authattr_ops[] = { getbyname }; +/*ARGSUSED*/ nss_backend_t * _nss_files_auth_attr_constr(const char *dummy1, const char *dummy2, diff --git a/usr/src/lib/nsswitch/files/common/getauuser.c b/usr/src/lib/nsswitch/files/common/getauuser.c index b47525e416..08a79e271f 100644 --- a/usr/src/lib/nsswitch/files/common/getauuser.c +++ b/usr/src/lib/nsswitch/files/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,8 +19,8 @@ * CDDL HEADER END */ /* - * Copyright (c) 1999-2001 by 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" @@ -35,24 +34,14 @@ * files/getauuser.c -- * "files" backend for nsswitch "audit_user" database */ -static int -check_name(nss_XbyY_args_t *args) -{ - au_user_str_t *au_user = (au_user_str_t *)args->returnval; - const char *name = args->key.name; - - if (strcmp(au_user->au_name, name) == 0) { - return (1); - } - return (0); -} static nss_status_t getbyname(files_backend_ptr_t be, void *a) { nss_XbyY_args_t *argp = (nss_XbyY_args_t *)a; - return (_nss_files_XY_all(be, argp, 1, argp->key.name, check_name)); + return (_nss_files_XY_all(be, argp, 1, argp->key.name, + _nss_files_check_name_colon)); } static files_backend_op_t auuser_ops[] = { @@ -63,6 +52,7 @@ static files_backend_op_t auuser_ops[] = { getbyname }; +/*ARGSUSED*/ nss_backend_t * _nss_files_audit_user_constr(const char *dummy1, const char *dummy2, const char *dummy3) diff --git a/usr/src/lib/nsswitch/files/common/getexecattr.c b/usr/src/lib/nsswitch/files/common/getexecattr.c index 502c0112b9..ac9e50ad3a 100644 --- a/usr/src/lib/nsswitch/files/common/getexecattr.c +++ b/usr/src/lib/nsswitch/files/common/getexecattr.c @@ -52,29 +52,47 @@ extern int _readbufline(char *, int, char *, int, int *); extern char *_exec_wild_id(char *, const char *); extern void _exec_cleanup(nss_status_t, nss_XbyY_args_t *); -typedef int (*_exec_XY_check_func) (nss_XbyY_args_t *); - /* * check_match: returns 1 if matching entry found, else returns 0. */ static int -check_match(nss_XbyY_args_t *argp) +check_match(nss_XbyY_args_t *argp, const char *line, int linelen) { + const char *limit, *linep, *keyp; _priv_execattr *_priv_exec = (_priv_execattr *)(argp->key.attrp); - const char *name = _priv_exec->name; - const char *type = _priv_exec->type; - const char *id = _priv_exec->id; - const char *policy = _priv_exec->policy; - execstr_t *exec = (execstr_t *)argp->returnval; - - if ((policy && exec->policy && (strcmp(policy, exec->policy) != 0)) || - (name && exec->name && (strcmp(name, exec->name) != 0)) || - (type && exec->type && (strcmp(type, exec->type) != 0)) || - (id && exec->id && (strcmp(id, exec->id) != 0))) { - return (0); + const char *exec_field[6]; + int i; + + exec_field[0] = _priv_exec->name; /* name */ + exec_field[1] = _priv_exec->policy; /* policy */ + exec_field[2] = _priv_exec->type; /* type */ + exec_field[3] = NULL; /* res1 */ + exec_field[4] = NULL; /* res2 */ + exec_field[5] = _priv_exec->id; /* id */ + /* No need to check attr field */ + + linep = line; + limit = line + linelen; + + for (i = 0; i < 6; i++) { + keyp = exec_field[i]; + if (keyp) { + /* compare field */ + while (*keyp && linep < limit && + *linep != ':' && *keyp == *linep) { + keyp++; + linep++; + } + if (*keyp || linep == limit || *linep != ':') + return (0); + } else { + /* skip field */ + while (linep < limit && *linep != ':') + linep++; + } + linep++; } - return (1); } @@ -90,7 +108,6 @@ _exec_files_XY_all(files_backend_ptr_t be, int f_size = 0; time_t f_time = 0; static time_t read_time = 0; - char *key = NULL; char *first; char *last; static char *f_buf = NULL; @@ -169,16 +186,15 @@ _exec_files_XY_all(files_backend_ptr_t be, } res = NSS_NOTFOUND; + /*CONSTCOND*/ while (1) { int linelen = 0; - int check_stat = 0; char *instr = be->buf; linelen = _readbufline(f_buf, f_size, instr, be->minbuf, &lastlen); if (linelen < 0) { /* End of file */ - argp->erange = 0; break; } @@ -235,26 +251,25 @@ _exec_files_XY_all(files_backend_ptr_t be, if (first != instr) instr = first; - /* - * Parse the entry. - */ + /* Check the entry */ argp->returnval = NULL; + argp->returnlen = 0; + if (check_match(argp, instr, linelen) == 0) + continue; + + /* Marshall the data */ parse_stat = (*argp->str2ent)(instr, linelen, argp->buf.result, argp->buf.buffer, argp->buf.buflen); if (parse_stat == NSS_STR_PARSE_SUCCESS) { - argp->returnval = argp->buf.result; - if (check_match(argp)) { - res = NSS_SUCCESS; - if (_priv_exec->search_flag == GET_ONE) { - break; - } else if (_doexeclist(argp) == 0) { - res = NSS_UNAVAIL; - break; - } - } else { - argp->returnval = NULL; - memset(argp->buf.buffer, NULL, - argp->buf.buflen); + argp->returnval = (argp->buf.result != NULL)? + argp->buf.result : argp->buf.buffer; + argp->returnlen = linelen; + res = NSS_SUCCESS; + if (_priv_exec->search_flag == GET_ONE) { + break; + } else if (_doexeclist(argp) == 0) { + res = NSS_UNAVAIL; + break; } } else if (parse_stat == NSS_STR_PARSE_ERANGE) { argp->erange = 1; @@ -276,13 +291,13 @@ _exec_files_XY_all(files_backend_ptr_t be, static nss_status_t get_wild(files_backend_ptr_t be, nss_XbyY_args_t *argp, int getby_flag) { - char *orig_id = NULL; + const char *orig_id = NULL; char *old_id = NULL; char *wild_id = NULL; nss_status_t res = NSS_NOTFOUND; _priv_execattr *_priv_exec = (_priv_execattr *)(argp->key.attrp); - orig_id = strdup(_priv_exec->id); + orig_id = _priv_exec->id; old_id = strdup(_priv_exec->id); wild_id = old_id; while ((wild_id = _exec_wild_id(wild_id, _priv_exec->type)) != NULL) { @@ -318,6 +333,7 @@ getbyid(files_backend_ptr_t be, void *a) { nss_status_t res; nss_XbyY_args_t *argp = (nss_XbyY_args_t *)a; + /*LINTED*/ _priv_execattr *_priv_exec = (_priv_execattr *)(argp->key.attrp); res = _exec_files_XY_all(be, argp, NSS_DBOP_EXECATTR_BYID); @@ -336,6 +352,7 @@ getbynameid(files_backend_ptr_t be, void *a) { nss_status_t res; nss_XbyY_args_t *argp = (nss_XbyY_args_t *)a; + /*LINTED*/ _priv_execattr *_priv_exec = (_priv_execattr *)(argp->key.attrp); res = _exec_files_XY_all(be, argp, NSS_DBOP_EXECATTR_BYNAMEID); @@ -359,6 +376,7 @@ static files_backend_op_t execattr_ops[] = { getbynameid }; +/*ARGSUSED*/ nss_backend_t * _nss_files_exec_attr_constr(const char *dummy1, const char *dummy2, diff --git a/usr/src/lib/nsswitch/files/common/getgrent.c b/usr/src/lib/nsswitch/files/common/getgrent.c index 82bc1989df..6f45136f16 100644 --- a/usr/src/lib/nsswitch/files/common/getgrent.c +++ b/usr/src/lib/nsswitch/files/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,37 +19,71 @@ * CDDL HEADER END */ /* - * Copyright (c) 1988-1995 Sun Microsystems Inc - * All Rights Reserved. + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. * - * files/getgrent.c -- "files" backend for nsswitch "group" database + * files/getgrent.c -- "files" backend for nsswitch "group" database */ #pragma ident "%Z%%M% %I% %E% SMI" #include <grp.h> #include <unistd.h> /* for GF_PATH */ +#include <stdlib.h> /* for GF_PATH */ #include "files_common.h" #include <strings.h> -static u_int -hash_grname(nss_XbyY_args_t *argp, int keyhash) +static uint_t +hash_grname(nss_XbyY_args_t *argp, int keyhash, const char *line, + int linelen) { - struct group *g = argp->returnval; - const char *name = keyhash ? argp->key.name : g->gr_name; - u_int hash = 0; - - while (*name != 0) - hash = hash * 15 + *name++; - + const char *name; + int namelen, i; + uint_t hash = 0; + + if (keyhash) { + name = argp->key.name; + namelen = strlen(name); + } else { + name = line; + namelen = 0; + while (linelen-- && *line++ != ':') + namelen++; + } + + for (i = 0; i < namelen; i++) + hash = hash * 15 + name[i]; return (hash); } -static u_int -hash_grgid(nss_XbyY_args_t *argp, int keyhash) +static uint_t +hash_grgid(nss_XbyY_args_t *argp, int keyhash, const char *line, + int linelen) { - struct group *g = argp->returnval; - return (keyhash ? (u_int)argp->key.gid : (u_int)g->gr_gid); + uint_t id; + const char *linep, *limit, *end; + + linep = line; + limit = line + linelen; + + if (keyhash) + return ((uint_t)argp->key.gid); + + /* skip groupname */ + while (linep < limit && *linep++ != ':'); + /* skip password */ + while (linep < limit && *linep++ != ':'); + if (linep == limit) + return (GID_NOBODY); + + /* gid */ + end = linep; + id = (uint_t)strtol(linep, (char **)&end, 10); + /* empty gid */ + if (linep == end) + return (GID_NOBODY); + + return (id); } static files_hash_func hash_gr[2] = { hash_grname, hash_grgid }; @@ -64,15 +97,22 @@ static files_hash_t hashinfo = { }; static int -check_grname(argp) - nss_XbyY_args_t *argp; +check_grname(nss_XbyY_args_t *argp, const char *line, int linelen) { - struct group *g = (struct group *)argp->returnval; + const char *linep, *limit; + const char *keyp = argp->key.name; + + linep = line; + limit = line + linelen; - /* +/- entries only valid in compat source */ - if (g->gr_name != 0 && (g->gr_name[0] == '+' || g->gr_name[0] == '-')) + /* +/- entries valid for compat source only */ + if (linelen == 0 || *line == '+' || *line == '-') return (0); - return (strcmp(g->gr_name, argp->key.name) == 0); + while (*keyp && linep < limit && *keyp == *linep) { + keyp++; + linep++; + } + return (linep < limit && *keyp == '\0' && *linep == ':'); } static nss_status_t @@ -84,15 +124,34 @@ getbyname(be, a) } static int -check_grgid(argp) - nss_XbyY_args_t *argp; +check_grgid(nss_XbyY_args_t *argp, const char *line, int linelen) { - struct group *g = (struct group *)argp->returnval; + const char *linep, *limit, *end; + gid_t gr_gid; + + linep = line; + limit = line + linelen; + + /* +/- entries valid for compat source only */ + if (linelen == 0 || *line == '+' || *line == '-') + return (0); - /* +/- entries only valid in compat source */ - if (g->gr_name != 0 && (g->gr_name[0] == '+' || g->gr_name[0] == '-')) + /* skip username */ + while (linep < limit && *linep++ != ':'); + /* skip password */ + while (linep < limit && *linep++ != ':'); + if (linep == limit) return (0); - return (g->gr_gid == argp->key.gid); + + /* uid */ + end = linep; + gr_gid = (gid_t)strtol(linep, (char **)&end, 10); + + /* empty gid is not valid */ + if (linep == end) + return (0); + + return (gr_gid == argp->key.gid); } static nss_status_t @@ -108,7 +167,7 @@ getbymember(be, a) files_backend_ptr_t be; void *a; { - struct nss_groupsbymem *argp = (struct nss_groupsbymem *) a; + struct nss_groupsbymem *argp = (struct nss_groupsbymem *)a; return (_nss_files_do_all(be, argp, argp->username, (files_do_all_func_t)argp->process_cstr)); diff --git a/usr/src/lib/nsswitch/files/common/gethostent.c b/usr/src/lib/nsswitch/files/common/gethostent.c index 24dd4550c1..7012cbc856 100644 --- a/usr/src/lib/nsswitch/files/common/gethostent.c +++ b/usr/src/lib/nsswitch/files/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 2004 Sun Microsystems, Inc. All rights reserved. + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. * * files/gethostent.c -- "files" backend for nsswitch "hosts" database @@ -38,33 +37,84 @@ #include <sys/socket.h> #include <netinet/in.h> #include <arpa/nameser.h> +#include <arpa/inet.h> #include <ctype.h> -static int check_name(); +static int check_name(nss_XbyY_args_t *, const char *, int, + int, const char **, int *, void *, int *); static char *do_aliases(); -static char *strcasestr(); +static char *strcasestr(const char *as1, const char *as2); nss_status_t __nss_files_XY_hostbyname(); int __nss_files_2herrno(); +static int __nss_files_get_addr(int, const char *, int, + void *, int, int *); static int -check_name(host, args) - struct hostent *host; - nss_XbyY_args_t *args; +check_name(nss_XbyY_args_t *argp, const char *line, int linelen, + int type, const char **namep, int *namelen, + void *addrp, int *addrsize) { - const char *name = args->key.name; - char **aliasp; - - if (!host->h_name) - return (0); - if (strcasecmp(host->h_name, name) == 0) { - return (1); + const char *limit, *linep, *keyp, *addrstart; + int v6flag = 0, addrlen; + + linep = line; + limit = line + linelen; + + /* Address */ + addrstart = linep; + while (linep < limit && !isspace(*linep)) { + if (*linep == ':') + v6flag++; + linep++; } - for (aliasp = host->h_aliases; *aliasp != 0; aliasp++) { - if (strcasecmp(*aliasp, name) == 0) { + addrlen = linep - addrstart; + + /* skip the delimiting spaces */ + while (linep < limit && isspace(*linep)) + linep++; + + /* Canonical name */ + keyp = argp->key.name; + *namep = linep; + while (*keyp && linep < limit && !isspace(*linep) && + tolower(*keyp) == tolower(*linep)) { + keyp++; + linep++; + } + if (*keyp == '\0' && (linep == limit || isspace(*linep))) { + if (__nss_files_get_addr(type, addrstart, addrlen, + addrp, v6flag, addrsize)) { + *namelen = linep - *namep; return (1); } } + while (linep < limit && !isspace(*linep)) + linep++; + *namelen = linep - *namep; + + /* Aliases */ + while (linep < limit) { + /* skip the delimiting spaces */ + while (linep < limit && isspace(*linep)) + linep++; + + /* compare name (case insensitive) */ + keyp = argp->key.name; + while (*keyp && linep < limit && !isspace(*linep) && + tolower(*keyp) == tolower(*linep)) { + keyp++; + linep++; + } + if (*keyp == '\0' && (linep == limit || isspace(*linep))) + return (__nss_files_get_addr(type, addrstart, addrlen, + addrp, v6flag, addrsize)); + + /* skip remainder of alias, if any */ + while (linep < limit && !isspace(*linep)) + linep++; + } return (0); + } static nss_status_t @@ -81,22 +131,87 @@ getbyname(be, a) return (res); } +static int +__nss_files_get_addr(int af, const char *addrstart, int addrlen, + void *addrp, int v6flag, int *h_length) +{ + struct in_addr addr_ipv4; + struct in6_addr *addrpv6; + in_addr_t *addrpv4; + char addrbuf[INET6_ADDRSTRLEN + 1]; + + if (addrlen >= sizeof (addrbuf)) + return (0); + (void) memcpy(addrbuf, addrstart, addrlen); + addrbuf[addrlen] = '\0'; + + if (af == AF_INET) { + addrpv4 = (in_addr_t *)addrp; + if ((*addrpv4 = inet_addr(addrbuf)) == 0xffffffffU) + return (0); + *h_length = sizeof (in_addr_t); + } else if (af == AF_INET6) { + addrpv6 = (struct in6_addr *)addrp; + if (v6flag) { + if (inet_pton(af, addrbuf, addrpv6) != 1) + return (0); + } else { + if ((addr_ipv4.s_addr = inet_addr(addrbuf)) == + 0xffffffffU) + return (0); + IN6_INADDR_TO_V4MAPPED(&addr_ipv4, addrpv6); + } + *h_length = sizeof (struct in6_addr); + } else { + return (0); + } + return (1); +} + int -__nss_files_check_addr(argp) - nss_XbyY_args_t *argp; +__nss_files_check_addr(int af, nss_XbyY_args_t *argp, const char *line, + int linelen) { - struct hostent *host = (struct hostent *)argp->returnval; + const char *limit, *linep, *addrstart; + int v6flag = 0, addrlen, h_length; + in_addr_t addr_ipv4; + struct in6_addr addr_ipv6; + char *h_addrp; + + /* Compare the address type */ + if (argp->key.hostaddr.type != af) + return (0); - /* - * We know that /etc/hosts can only store one address per host, so... - */ - return (host->h_length == argp->key.hostaddr.len && - host->h_addrtype == argp->key.hostaddr.type && - memcmp(host->h_addr_list[0], argp->key.hostaddr.addr, + /* Retrieve the address */ + if (af == AF_INET) + h_addrp = (char *)&addr_ipv4; + else + h_addrp = (char *)&addr_ipv6; + linep = line; + limit = line + linelen; + addrstart = linep; + while (linep < limit && !isspace(*linep)) { + if (*linep == ':') + v6flag++; + linep++; + } + addrlen = linep - addrstart; + if (__nss_files_get_addr(af, addrstart, addrlen, h_addrp, + v6flag, &h_length) == 0) + return (0); + + /* Compare the address */ + return (h_length == argp->key.hostaddr.len && + memcmp(h_addrp, argp->key.hostaddr.addr, argp->key.hostaddr.len) == 0); } +static int +check_addr(nss_XbyY_args_t *argp, const char *line, int linelen) +{ + return (__nss_files_check_addr(AF_INET, argp, line, linelen)); +} static nss_status_t getbyaddr(be, a) @@ -106,7 +221,7 @@ getbyaddr(be, a) nss_XbyY_args_t *argp = (nss_XbyY_args_t *)a; nss_status_t res; - res = _nss_files_XY_all(be, argp, 1, 0, __nss_files_check_addr); + res = _nss_files_XY_all(be, argp, 1, 0, check_addr); if (res != NSS_SUCCESS) argp->h_errno = __nss_files_2herrno(res); return (res); @@ -146,20 +261,21 @@ __nss_files_XY_hostbyname(be, args, filter, type) const char *filter; /* hint for name string */ int type; { - nss_status_t res; - int parsestat; - char *first; - char *last; - int i, nhosts = 0; - struct hostent he, *hp, *thp; - in_addr_t taddr[MAXADDRS]; - struct in6_addr taddr6[MAXADDRS]; - char *abuf = 0; /* alias buffer */ - char *abuf_start = 0, *abuf_end; - int (*func)(); - - if (be->buf == 0 && - (be->buf = malloc(be->minbuf)) == 0) { + nss_status_t res; + char *abuf = NULL, *abuf_start = NULL, *abuf_end; + char *first, *last, *buffer; + int parsestat, i, nhosts = 0, buflen; + const char *namep; + char *h_name; + int h_namelen, namelen; + struct hostent *hp; + in_addr_t *taddr = NULL; + struct in6_addr *taddr6 = NULL; + size_t ntaddr; + void *addrp; + char *alias_end = NULL; + + if (be->buf == 0 && (be->buf = malloc(be->minbuf)) == 0) { return (NSS_UNAVAIL); } @@ -168,10 +284,25 @@ __nss_files_XY_hostbyname(be, args, filter, type) return (res); } + ntaddr = MAXADDRS; + if (type == AF_INET) { + taddr = (in_addr_t *)calloc(ntaddr, sizeof (*taddr)); + if (taddr == NULL) + return (NSS_UNAVAIL); + } else { + taddr6 = (struct in6_addr *)calloc(ntaddr, sizeof (*taddr6)); + if (taddr6 == NULL) + return (NSS_UNAVAIL); + } + res = NSS_NOTFOUND; - args->erange = 0; args->returnval = (char *)0; - hp = thp = (struct hostent *)args->buf.result; + args->returnlen = 0; + hp = (struct hostent *)args->buf.result; + buffer = args->buf.buffer; + buflen = args->buf.buflen; + h_namelen = 0; + h_name = NULL; for (;;) { char *instr = be->buf; @@ -207,83 +338,189 @@ __nss_files_XY_hostbyname(be, args, filter, type) if (first != instr) instr = first; - if (nhosts && strcasestr(instr, hp->h_name) == 0) { - break; - } - /* - * If we've already matched once and have a possible match - * on this line, copy the aliases where they're safe from - * being overwritten when we look at the next entry. They're - * saved as a string of blank separated names for the alias - * parser. On errors, we return failure whether or not we - * have already obtained a valid address. - */ - if (nhosts == 1 && !abuf) { - abuf = malloc(args->buf.buflen); - if (abuf == NULL) { - res = NSS_UNAVAIL; - break; - } - abuf_start = &abuf[0]; - abuf_end = abuf_start + args->buf.buflen; - if (abuf + strlen(hp->h_name) + 1 > abuf_end) { - free(abuf_start); - abuf = NULL; - args->erange = 1; - res = NSS_NOTFOUND; - break; - } - (void) strcpy(abuf, hp->h_name); - abuf += strlen(hp->h_name); - *abuf++ = ' '; - abuf = do_aliases(hp, abuf, abuf_start, abuf_end); - if (abuf == NULL) { - args->erange = 1; - res = NSS_NOTFOUND; - break; - } - } - func = args->str2ent; - parsestat = (*func)(instr, linelen, thp, - args->buf.buffer, args->buf.buflen); - - if (parsestat != NSS_STR_PARSE_SUCCESS) { - if (parsestat == NSS_STR_PARSE_ERANGE) - args->erange = 1; + /* Bail out if the canonical name does not match */ + if (nhosts && strcasestr(instr, h_name) == 0) { continue; } /* * Still need to check, strcasestr() above is just a hint. */ + addrp = (type == AF_INET)? + (void *)&taddr[nhosts]: + (void *)&taddr6[nhosts]; + + if (check_name(args, instr, linelen, + type, &namep, &namelen, + addrp, &i)) { - if (type == thp->h_addrtype) - if (check_name(thp, args)) { - if (type == AF_INET) - taddr[nhosts++] = - (*(in_addr_t *)thp->h_addr_list[0]); - else { - memcpy(&taddr6[nhosts++], thp->h_addr_list[0], - sizeof (struct in6_addr)); + /* + * If we've already matched once and have a possible + * match on this line, copy the aliases where they're + * safe from being overwritten when we look at the + * next entry. They're saved as a string of blank + * separated names for the alias parser. On errors, + * we return failure whether or not we have already + * obtained a valid address. + */ + if (nhosts == 1 && hp) { + if (h_namelen + 1 > args->buf.buflen) { + args->erange = 1; + res = NSS_NOTFOUND; + break; + } + abuf = (char *)malloc(args->buf.buflen); + if (abuf == NULL) { + res = NSS_UNAVAIL; + break; + } + abuf_start = abuf; + abuf_end = abuf_start + args->buf.buflen; + (void) memcpy(abuf, h_name, h_namelen); + abuf += h_namelen; + *abuf = '\0'; + abuf = do_aliases(hp, abuf, abuf_end); + if (abuf == NULL) { + args->erange = 1; + res = NSS_NOTFOUND; + break; + } } + if (hp != NULL) { + /* inside the application */ + parsestat = (*args->str2ent)(instr, linelen, + hp, buffer, buflen); + if (parsestat != NSS_STR_PARSE_SUCCESS) { + if (parsestat == NSS_STR_PARSE_ERANGE) + args->erange = 1; + (void) memset(buffer, 0, buflen); + continue; + } + } else { + /* inside nscd */ + int alen, cplen, erange = 0; + char *ap; + + /* Add alias to the first line if any */ + if (nhosts > 0) { + + /* get to the start of alias */ + ap = (char *)namep + namelen; + /* see if there's any alias */ + if (ap == instr + linelen) + alen = 0; + else + alen = linelen - (ap - instr); + if (alen + 1 >= buflen) + erange = 1; + if (erange == 0 && alen != 0) { + /* make room for the alias */ + if (alias_end != NULL) + (void) memmove(alias_end + + alen, alias_end, buffer - + alias_end); + /* copy in the alias */ + (void) memmove(alias_end, + ap, alen); + buffer += alen; + buflen -= alen; + alias_end += alen; + } + + /* Add delimiter to the buffer */ + *buffer++ = '\n'; + buflen--; + args->returnlen++; + } + + /* copy just the addr if not first one */ + if (alias_end == NULL) + cplen = linelen; + else + cplen = namep - instr; + + if (cplen >= buflen || erange == 1) { + args->erange = 1; + if (nhosts > 0) { + *(--buffer) = '\0'; + buflen++; + args->returnlen--; + } + continue; + } + + (void) memcpy(buffer, instr, cplen); + /* Adjust buffer */ + buffer += cplen; + *buffer = '\0'; + buflen -= cplen; + if (alias_end == NULL) + alias_end = buffer; + } + + args->returnlen += linelen; - if (nhosts == 1) { + /* + * If this is the first one, save the canonical + * name for future matches and continue. + */ + if (++nhosts == 1) { + h_name = malloc(namelen + 1); + if (h_name == NULL) { + res = NSS_UNAVAIL; + break; + } res = NSS_SUCCESS; - args->returnval = args->buf.result; - thp = &he; /* switch to tmp hostent */ + (void) memcpy(h_name, namep, namelen); + h_name[namelen] = '\0'; + h_namelen = namelen; + if (hp) + args->returnval = hp; + else + args->returnval = args->buf.buffer; continue; } - if (nhosts >= MAXADDRS) - break; - abuf = do_aliases(thp, abuf, abuf_start, abuf_end); - if (abuf == NULL) { - args->erange = 1; - res = NSS_NOTFOUND; - break; + + + /* Extend the array */ + if (nhosts >= ntaddr) { + ntaddr *= 2; + if (type == AF_INET) { + addrp = realloc(taddr, + sizeof (*taddr) * ntaddr); + if (addrp == NULL) { + res = NSS_UNAVAIL; + break; + } + taddr = (in_addr_t *)addrp; + } else { + addrp = realloc(taddr6, + sizeof (*taddr6) * ntaddr); + if (addrp == NULL) { + res = NSS_UNAVAIL; + break; + } + taddr6 = (struct in6_addr *)addrp; + } + } + + /* + * For non-nscd, save aliases in a temporary buffer + * Don't have to do this for nscd as 'buffer' already + * contains the required data in the appropriate + * format + */ + if (hp) { + abuf = do_aliases(hp, abuf, abuf_end); + if (abuf == NULL) { + args->erange = 1; + res = NSS_NOTFOUND; + break; + } } - } else if (abuf && - strcasecmp(hp->h_name, thp->h_name) == 0) { + } else if (namep && h_namelen == namelen && + strncasecmp(h_name, namep, namelen) == 0) { /* * This line didn't have the requested name but * is part of the same multihomed host (i.e. it @@ -296,7 +533,10 @@ __nss_files_XY_hostbyname(be, args, filter, type) } } - if (abuf) { + if (abuf && res == NSS_SUCCESS) { + + /* abuf != NULL implies hp and abuf_start != NULL */ + struct in_addr *addrp; struct in6_addr *addrp6; @@ -318,8 +558,8 @@ __nss_files_XY_hostbyname(be, args, filter, type) ((nhosts + 1) * sizeof (char *) + (nhosts * sizeof (*addrp6))), sizeof (char *))); for (i = 0, --addrp6; i < nhosts; i++, --addrp6) { - memcpy(addrp6, &taddr6[i], - sizeof (struct in6_addr)); + (void) memcpy(addrp6, &taddr6[i], + sizeof (struct in6_addr)); hp->h_addr_list[i] = (char *)addrp6; } } @@ -330,12 +570,11 @@ __nss_files_XY_hostbyname(be, args, filter, type) (char *)hp->h_addr_list - args->buf.buffer); if (hp->h_aliases == 0) { args->erange = 1; - res = NSS_STR_PARSE_ERANGE; + res = NSS_NOTFOUND; } else { hp->h_name = hp->h_aliases[0]; hp->h_aliases++; } - free(abuf_start); } /* @@ -345,6 +584,15 @@ __nss_files_XY_hostbyname(be, args, filter, type) if (!args->stayopen) (void) _nss_files_endent(be, 0); + if (taddr) + free(taddr); + if (taddr6) + free(taddr6); + if (h_name) + free(h_name); + if (abuf_start) + free(abuf_start); + return (res); } @@ -352,13 +600,11 @@ __nss_files_XY_hostbyname(be, args, filter, type) * A case-insensitive version of strstr(). */ static char * -strcasestr(as1, as2) - char *as1; - char *as2; +strcasestr(const char *as1, const char *as2) { int c2; - register char *tptr; - register char *s1, *s2; + register const char *tptr; + register const char *s1, *s2; s1 = as1; s2 = as2; @@ -383,25 +629,22 @@ strcasestr(as1, as2) static char * -do_aliases(hp, abuf, start, end) - struct hostent *hp; - char *abuf; - char *start; - char *end; +do_aliases(struct hostent *hp, char *abuf, char *end) { - char **cp; + char **cp; + size_t len; - for (cp = hp->h_aliases; cp && *cp && **cp; cp++) { - size_t len; + if ((cp = hp->h_aliases) == NULL) + return (abuf); + for (; *cp; cp++) { len = strlen(*cp); if (abuf+len+1 >= end) { - free(start); - return ((char *)0); + return (NULL); } - (void) strcpy(abuf, *cp); - abuf += len; *abuf++ = ' '; + (void) memcpy(abuf, *cp, len); + abuf += len; } *abuf = '\0'; diff --git a/usr/src/lib/nsswitch/files/common/gethostent6.c b/usr/src/lib/nsswitch/files/common/gethostent6.c index 22d8703848..a47f1b5f45 100644 --- a/usr/src/lib/nsswitch/files/common/gethostent6.c +++ b/usr/src/lib/nsswitch/files/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,10 +19,10 @@ * CDDL HEADER END */ /* - * Copyright 1988-1995, 2003 Sun Microsystems, Inc. All rights reserved. + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. * - * files/gethostent6.c -- "files" backend for nsswitch "hosts" database + * files/gethostent6.c -- "files" backend for nsswitch "hosts" database */ #pragma ident "%Z%%M% %I% %E% SMI" @@ -42,8 +41,7 @@ extern nss_status_t __nss_files_XY_hostbyname(); extern int __nss_files_2herrno(); -extern int __nss_files_check_addr(nss_XbyY_args_t *); - +extern int __nss_files_check_addr(int, nss_XbyY_args_t *, const char *, int); static nss_status_t getbyname(be, a) @@ -60,7 +58,11 @@ getbyname(be, a) return (res); } - +static int +check_addr(nss_XbyY_args_t *argp, const char *line, int linelen) +{ + return (__nss_files_check_addr(AF_INET6, argp, line, linelen)); +} static nss_status_t getbyaddr(be, a) @@ -71,13 +73,12 @@ getbyaddr(be, a) nss_status_t res; - res = _nss_files_XY_all(be, argp, 1, 0, __nss_files_check_addr); + res = _nss_files_XY_all(be, argp, 1, 0, check_addr); if (res != NSS_SUCCESS) argp->h_errno = __nss_files_2herrno(res); return (res); } - static files_backend_op_t ipnodes_ops[] = { _nss_files_destr, _nss_files_endent, diff --git a/usr/src/lib/nsswitch/files/common/getnetent.c b/usr/src/lib/nsswitch/files/common/getnetent.c index 992f19326c..d47b78d324 100644 --- a/usr/src/lib/nsswitch/files/common/getnetent.c +++ b/usr/src/lib/nsswitch/files/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,55 +19,70 @@ * CDDL HEADER END */ /* + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. * - * Copyright (c) 1988-1995 Sun Microsystems Inc - * All Rights Reserved. - * - * files/getnetent.c -- "files" backend for nsswitch "networks" database + * files/getnetent.c -- "files" backend for nsswitch "networks" database */ #pragma ident "%Z%%M% %I% %E% SMI" +#include <sys/types.h> +#include <sys/socket.h> +#include <netinet/in.h> +#include <arpa/inet.h> #include <netdb.h> #include "files_common.h" #include <strings.h> - -static int -check_name(args) - nss_XbyY_args_t *args; -{ - struct netent *net = (struct netent *)args->returnval; - const char *name = args->key.name; - char **aliasp; - - if (strcmp(net->n_name, name) == 0) - return (1); - for (aliasp = net->n_aliases; *aliasp != 0; aliasp++) { - if (strcmp(*aliasp, name) == 0) - return (1); - } - return (0); -} +#include <ctype.h> static nss_status_t getbyname(be, a) files_backend_ptr_t be; void *a; { - nss_XbyY_args_t *argp = (nss_XbyY_args_t *) a; + nss_XbyY_args_t *argp = (nss_XbyY_args_t *)a; - return (_nss_files_XY_all(be, argp, 1, argp->key.name, check_name)); + return (_nss_files_XY_all(be, argp, 1, argp->key.name, + _nss_files_check_name_aliases)); } static int -check_addr(args) - nss_XbyY_args_t *args; +check_addr(nss_XbyY_args_t *argp, const char *line, int linelen) { - struct netent *net = (struct netent *)args->returnval; - return ((net->n_addrtype == args->key.netaddr.type) && - (net->n_net == args->key.netaddr.net)); + const char *limit, *linep, *addrstart; + int addrlen; + char addrbuf[NSS_LINELEN_NETWORKS]; + in_addr_t linenet; + + linep = line; + limit = line + linelen; + + /* skip network name */ + while (linep < limit && !isspace(*linep)) + linep++; + /* skip the delimiting spaces */ + while (linep < limit && isspace(*linep)) + linep++; + if (linep == limit) + return (0); + + addrstart = linep; + while (linep < limit && !isspace(*linep)) + linep++; + addrlen = linep - addrstart; + if (addrlen < sizeof (addrbuf)) { + (void) memcpy(addrbuf, addrstart, addrlen); + addrbuf[addrlen] = '\0'; + if ((linenet = inet_network(addrbuf)) == + (in_addr_t)0xffffffffU) + return (0); + return (AF_INET == argp->key.netaddr.type && + linenet == argp->key.netaddr.net); + } + return (0); } static nss_status_t @@ -76,7 +90,7 @@ getbyaddr(be, a) files_backend_ptr_t be; void *a; { - nss_XbyY_args_t *argp = (nss_XbyY_args_t *) a; + nss_XbyY_args_t *argp = (nss_XbyY_args_t *)a; return (_nss_files_XY_all(be, argp, 1, 0, check_addr)); } diff --git a/usr/src/lib/nsswitch/files/common/getprinter.c b/usr/src/lib/nsswitch/files/common/getprinter.c index c41771f8d2..8f5fab855b 100644 --- a/usr/src/lib/nsswitch/files/common/getprinter.c +++ b/usr/src/lib/nsswitch/files/common/getprinter.c @@ -36,140 +36,63 @@ static const char *printers = "/etc/printers.conf"; #include <stdlib.h> #include <strings.h> -static nss_status_t _nss_files_XY_printers(files_backend_ptr_t, - nss_XbyY_args_t *, const char *); - - -static nss_status_t -getent(be, a) - files_backend_ptr_t be; - void *a; +static int +check_name(nss_XbyY_args_t *argp, const char *line, int linelen) { - nss_XbyY_args_t *args = (nss_XbyY_args_t *)a; - return (_nss_files_XY_all(be, args, 0, 0, 0)); + const char *limit, *linep; + const char *keyp = argp->key.name; + int klen = strlen(keyp); + + linep = line; + limit = line + linelen; + + /* + * find the name in the namelist a|b|c...: + */ + while (linep+klen < limit && *linep != '|' && *linep != ':') { + if ((strncmp(linep, keyp, klen) == 0) && + ((*(linep + klen) == '|') || (*(linep + klen) == ':'))) { + return (1); + } else { + while (linep < limit && *linep != '|' && *linep != ':') + linep++; + if (linep >= limit || *linep == ':') + return (0); + if (*linep == '|') + linep++; + } + } + return (0); } - static nss_status_t getbyname(be, a) files_backend_ptr_t be; void *a; { nss_XbyY_args_t *argp = (nss_XbyY_args_t *)a; - nss_status_t res; - /* printers_getbyname() has not set/endent; rewind on each call */ - if ((res = _nss_files_setent(be, 0)) != NSS_SUCCESS) { - return (res); - } - return (_nss_files_XY_printers(be, argp, argp->key.name)); + return (_nss_files_XY_all(be, argp, 1, argp->key.name, + check_name)); } static files_backend_op_t printers_ops[] = { _nss_files_destr, _nss_files_endent, _nss_files_setent, - getent, + _nss_files_getent_rigid, getbyname }; +/*ARGSUSED*/ nss_backend_t * _nss_files_printers_constr(dummy1, dummy2, dummy3) const char *dummy1, *dummy2, *dummy3; { return (_nss_files_constr(printers_ops, - sizeof (printers_ops) / sizeof (printers_ops[0]), - printers, - NSS_LINELEN_PRINTERS, - NULL)); -} - -/* - * printers has the hostname as part of the data in the file, but the other - * backends don't include it in the data passed to the backend. For this - * reason, we process everything here and don't bother calling the backend. - */ -static nss_status_t -_nss_files_XY_printers(be, args, filter) - files_backend_ptr_t be; - nss_XbyY_args_t *args; - const char *filter; - /* - * filter not useful here since the key - * we are looking for is the first "word" - * on the line and we can be fast enough. - */ -{ - nss_status_t res; - int parsestat; - int namelen; - - if (be->buf == 0 && - (be->buf = (char *)malloc(be->minbuf)) == 0) { - (void) _nss_files_endent(be, 0); - return (NSS_UNAVAIL); /* really panic, malloc failed */ - } - - res = NSS_NOTFOUND; - namelen = strlen(args->key.name); - - while (1) { - char *instr = be->buf; - char *p, *limit; - int linelen; - int found = 0; - - /* - * _nss_files_read_line does process the '\' that are used - * in /etc/printers.conf for continuation and gives one long - * buffer. - * - * linelen counts the characters up to but excluding the '\n' - */ - if ((linelen = _nss_files_read_line(be->f, instr, - be->minbuf)) < 0) { - /* End of file */ - args->returnval = 0; - args->erange = 0; - break; - } - p = instr; - - if (*p == '#') /* comment */ - continue; - - /* - * find the name in the namelist a|b|c...: - */ - if ((limit = strchr(instr, ':')) == NULL) /* bad line */ - continue; - while ((p < limit) && (found == 0)) { - if ((strncmp(p, args->key.name, namelen) == 0) && - ((*(p+namelen) == '|') || (*(p+namelen) == ':'))) - found++; - else { - if ((p = strchr(p, '|')) == NULL) - p = limit; - else /* skip the '|' */ - p++; - } - } - if (found == 0) - continue; - - p = instr; - - if (args->buf.buflen <= linelen) { /* not enough buffer */ - args->erange = 1; - break; - } - (void) memcpy(args->buf.buffer, p, linelen); - args->buf.buffer[linelen] = '\0'; - args->returnval = args->buf.result; - res = NSS_SUCCESS; - break; - } - (void) _nss_files_endent(be, 0); - return (res); + sizeof (printers_ops) / sizeof (printers_ops[0]), + printers, + NSS_LINELEN_PRINTERS, + NULL)); } diff --git a/usr/src/lib/nsswitch/files/common/getprofattr.c b/usr/src/lib/nsswitch/files/common/getprofattr.c index 67c49369b0..83d4369eaa 100644 --- a/usr/src/lib/nsswitch/files/common/getprofattr.c +++ b/usr/src/lib/nsswitch/files/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,8 +19,8 @@ * CDDL HEADER END */ /* - * Copyright (c) 1999-2001 by 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" @@ -35,24 +34,14 @@ * files/getprofattr.c -- * "files" backend for nsswitch "prof_attr" database */ -static int -check_name(nss_XbyY_args_t *args) -{ - profstr_t *prof = (profstr_t *)args->returnval; - const char *name = args->key.name; - - if (strcmp(prof->name, name) == 0) { - return (1); - } - return (0); -} static nss_status_t getbyname(files_backend_ptr_t be, void *a) { nss_XbyY_args_t *argp = (nss_XbyY_args_t *)a; - return (_nss_files_XY_all(be, argp, 1, argp->key.name, check_name)); + return (_nss_files_XY_all(be, argp, 1, argp->key.name, + _nss_files_check_name_colon)); } static files_backend_op_t profattr_ops[] = { @@ -63,6 +52,7 @@ static files_backend_op_t profattr_ops[] = { getbyname }; +/*ARGSUSED*/ nss_backend_t * _nss_files_prof_attr_constr(const char *dummy1, const char *dummy2, diff --git a/usr/src/lib/nsswitch/files/common/getprojent.c b/usr/src/lib/nsswitch/files/common/getprojent.c index cad512746c..e534760093 100644 --- a/usr/src/lib/nsswitch/files/common/getprojent.c +++ b/usr/src/lib/nsswitch/files/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,8 +19,8 @@ * CDDL HEADER END */ /* - * Copyright (c) 1999-2000 by 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" @@ -29,24 +28,57 @@ #include <sys/types.h> #include <project.h> #include <string.h> +#include <stdlib.h> #include "files_common.h" static uint_t -hash_projname(nss_XbyY_args_t *argp, int keyhash) { - struct project *p = argp->returnval; - const char *name = keyhash ? argp->key.name : p->pj_name; - uint_t hash = 0; - - while (*name != 0) - hash = hash * 15 + *name++; - +hash_projname(nss_XbyY_args_t *argp, int keyhash, const char *line, + int linelen) { + + const char *name; + int namelen, i; + uint_t hash = 0; + + if (keyhash) { + name = argp->key.name; + namelen = strlen(name); + } else { + name = line; + namelen = 0; + while (linelen-- && *line++ != ':') + namelen++; + } + + for (i = 0; i < namelen; i++) + hash = hash * 15 + name[i]; return (hash); } static uint_t -hash_projid(nss_XbyY_args_t *argp, int keyhash) { - struct project *p = argp->returnval; - return (keyhash ? (uint_t)argp->key.projid : (uint_t)p->pj_projid); +hash_projid(nss_XbyY_args_t *argp, int keyhash, const char *line, + int linelen) { + + uint_t id; + const char *linep, *limit, *end; + + linep = line; + limit = line + linelen; + + if (keyhash) + return ((uint_t)argp->key.projid); + + /* skip projname */ + while (linep < limit && *linep++ != ':'); + if (linep == limit) + return (0); + + /* projid */ + end = linep; + id = (uint_t)strtol(linep, (char **)&end, 10); + if (linep == end) + return (0); + + return (id); } static files_hash_func hash_proj[2] = { @@ -63,26 +95,35 @@ static files_hash_t hashinfo = { }; static int -check_projname(nss_XbyY_args_t *argp) { - struct project *p = argp->returnval; +check_projid(nss_XbyY_args_t *argp, const char *line, int linelen) { + projid_t projid; + const char *linep, *limit, *end; + + linep = line; + limit = line + linelen; + + /* skip projname */ + while (linep < limit && *linep++ != ':'); - if (p->pj_name == 0) + /* empty projname not allowed */ + if (linep == limit || linep == line + 1) return (0); - return (strcmp(p->pj_name, argp->key.name) == 0); -} -static int -check_projid(nss_XbyY_args_t *argp) { - struct project *p = argp->returnval; + /* projid */ + end = linep; + projid = (projid_t)strtol(linep, (char **)&end, 10); - if (p->pj_name == 0) + /* empty projid is not valid */ + if (linep == end) return (0); - return (p->pj_projid == argp->key.projid); + + return (projid == argp->key.projid); } static nss_status_t getbyname(files_backend_ptr_t be, void *a) { - return (_nss_files_XY_hash(be, a, 0, &hashinfo, 0, check_projname)); + return (_nss_files_XY_hash(be, a, 0, &hashinfo, 0, + _nss_files_check_name_colon)); } static nss_status_t diff --git a/usr/src/lib/nsswitch/files/common/getprotoent.c b/usr/src/lib/nsswitch/files/common/getprotoent.c index 25659b2e92..2f3578d13b 100644 --- a/usr/src/lib/nsswitch/files/common/getprotoent.c +++ b/usr/src/lib/nsswitch/files/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,10 +19,10 @@ * CDDL HEADER END */ /* - * Copyright (c) 1988-1995 Sun Microsystems Inc - * All Rights Reserved. + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. * - * files/getprotoent.c -- "files" backend for nsswitch "protocols" database + * files/getprotoent.c -- "files" backend for nsswitch "protocols" database */ #pragma ident "%Z%%M% %I% %E% SMI" @@ -31,41 +30,39 @@ #include <netdb.h> #include "files_common.h" #include <strings.h> - -static int -check_name(args) - nss_XbyY_args_t *args; -{ - struct protoent *proto = (struct protoent *)args->returnval; - const char *name = args->key.name; - char **aliasp; - - if (strcmp(proto->p_name, name) == 0) - return (1); - for (aliasp = proto->p_aliases; *aliasp != 0; aliasp++) { - if (strcmp(*aliasp, name) == 0) - return (1); - } - return (0); -} +#include <ctype.h> +#include <stdlib.h> static nss_status_t getbyname(be, a) files_backend_ptr_t be; void *a; { - nss_XbyY_args_t *argp = (nss_XbyY_args_t *) a; + nss_XbyY_args_t *argp = (nss_XbyY_args_t *)a; - return (_nss_files_XY_all(be, argp, 1, argp->key.name, check_name)); + return (_nss_files_XY_all(be, argp, 1, argp->key.name, + _nss_files_check_name_aliases)); } static int -check_addr(args) - nss_XbyY_args_t *args; +check_addr(nss_XbyY_args_t *argp, const char *line, int linelen) { - struct protoent *proto = (struct protoent *)args->returnval; + int proto; + const char *limit, *linep; + + linep = line; + limit = line + linelen; - return (proto->p_proto == args->key.number); + /* skip name */ + while (linep < limit && !isspace(*linep)) + linep++; + /* skip the delimiting spaces */ + while (linep < limit && isspace(*linep)) + linep++; + if (linep == limit) + return (0); + proto = (int)strtol(linep, NULL, 10); + return (proto == argp->key.number); } static nss_status_t @@ -73,10 +70,10 @@ getbynumber(be, a) files_backend_ptr_t be; void *a; { - nss_XbyY_args_t *argp = (nss_XbyY_args_t *) a; + nss_XbyY_args_t *argp = (nss_XbyY_args_t *)a; char numstr[12]; - sprintf(numstr, "%d", argp->key.number); + (void) snprintf(numstr, 12, "%d", argp->key.number); return (_nss_files_XY_all(be, argp, 1, 0, check_addr)); } diff --git a/usr/src/lib/nsswitch/files/common/getpwnam.c b/usr/src/lib/nsswitch/files/common/getpwnam.c index 303b8323c6..8faa2014eb 100644 --- a/usr/src/lib/nsswitch/files/common/getpwnam.c +++ b/usr/src/lib/nsswitch/files/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,10 +19,10 @@ * CDDL HEADER END */ /* - * Copyright (c) 1988-1995 Sun Microsystems Inc - * All Rights Reserved. + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. * - * files/getpwnam.c -- "files" backend for nsswitch "passwd" database + * files/getpwnam.c -- "files" backend for nsswitch "passwd" database */ #pragma ident "%Z%%M% %I% %E% SMI" @@ -33,25 +32,60 @@ #include <unistd.h> /* for PF_PATH */ #include "files_common.h" #include <strings.h> +#include <stdlib.h> -static u_int -hash_pwname(nss_XbyY_args_t *argp, int keyhash) +static uint_t +hash_pwname(nss_XbyY_args_t *argp, int keyhash, const char *line, + int linelen) { - struct passwd *p = argp->returnval; - const char *name = keyhash ? argp->key.name : p->pw_name; - u_int hash = 0; - - while (*name != 0) - hash = hash * 15 + *name++; - + const char *name; + int namelen, i; + uint_t hash = 0; + + if (keyhash) { + name = argp->key.name; + namelen = strlen(name); + } else { + name = line; + namelen = 0; + while (linelen-- && *line++ != ':') + namelen++; + } + + for (i = 0; i < namelen; i++) + hash = hash * 15 + name[i]; return (hash); } -static u_int -hash_pwuid(nss_XbyY_args_t *argp, int keyhash) +static uint_t +hash_pwuid(nss_XbyY_args_t *argp, int keyhash, const char *line, + int linelen) { - struct passwd *p = argp->returnval; - return (keyhash ? (u_int)argp->key.uid : (u_int)p->pw_uid); + uint_t id; + const char *linep, *limit, *end; + + linep = line; + limit = line + linelen; + + if (keyhash) + return ((uint_t)argp->key.uid); + + /* skip username */ + while (linep < limit && *linep++ != ':'); + /* skip password */ + while (linep < limit && *linep++ != ':'); + if (linep == limit) + return (UID_NOBODY); + + /* uid */ + end = linep; + id = (uint_t)strtol(linep, (char **)&end, 10); + + /* empty uid */ + if (linep == end) + return (UID_NOBODY); + + return (id); } static files_hash_func hash_pw[2] = { hash_pwname, hash_pwuid }; @@ -65,15 +99,22 @@ static files_hash_t hashinfo = { }; static int -check_pwname(argp) - nss_XbyY_args_t *argp; +check_pwname(nss_XbyY_args_t *argp, const char *line, int linelen) { - struct passwd *p = (struct passwd *)argp->returnval; + const char *linep, *limit; + const char *keyp = argp->key.name; + + linep = line; + limit = line + linelen; /* +/- entries valid for compat source only */ - if (p->pw_name != 0 && (p->pw_name[0] == '+' || p->pw_name[0] == '-')) + if (linelen == 0 || *line == '+' || *line == '-') return (0); - return (strcmp(p->pw_name, argp->key.name) == 0); + while (*keyp && linep < limit && *keyp == *linep) { + keyp++; + linep++; + } + return (linep < limit && *keyp == '\0' && *linep == ':'); } static nss_status_t @@ -85,15 +126,34 @@ getbyname(be, a) } static int -check_pwuid(argp) - nss_XbyY_args_t *argp; +check_pwuid(nss_XbyY_args_t *argp, const char *line, int linelen) { - struct passwd *p = (struct passwd *)argp->returnval; + const char *linep, *limit, *end; + uid_t pw_uid; + + linep = line; + limit = line + linelen; /* +/- entries valid for compat source only */ - if (p->pw_name != 0 && (p->pw_name[0] == '+' || p->pw_name[0] == '-')) + if (linelen == 0 || *line == '+' || *line == '-') + return (0); + + /* skip username */ + while (linep < limit && *linep++ != ':'); + /* skip password */ + while (linep < limit && *linep++ != ':'); + if (linep == limit) return (0); - return (p->pw_uid == argp->key.uid); + + /* uid */ + end = linep; + pw_uid = (uid_t)strtol(linep, (char **)&end, 10); + + /* empty uid is not valid */ + if (linep == end) + return (0); + + return (pw_uid == argp->key.uid); } static nss_status_t diff --git a/usr/src/lib/nsswitch/files/common/getrpcent.c b/usr/src/lib/nsswitch/files/common/getrpcent.c index 789822c63c..3732c368dd 100644 --- a/usr/src/lib/nsswitch/files/common/getrpcent.c +++ b/usr/src/lib/nsswitch/files/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,10 +19,10 @@ * CDDL HEADER END */ /* - * Copyright (c) 1988-1995 Sun Microsystems Inc - * All Rights Reserved. + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. * - * files/getrpcent.c -- "files" backend for nsswitch "rpc" database + * files/getrpcent.c -- "files" backend for nsswitch "rpc" database */ #pragma ident "%Z%%M% %I% %E% SMI" @@ -31,43 +30,39 @@ #include <rpc/rpcent.h> #include "files_common.h" #include <strings.h> - -static int -check_name(args) - nss_XbyY_args_t *args; -{ - struct rpcent *rpc = (struct rpcent *) args->returnval; - const char *name = args->key.name; - char **aliasp; - - if (strcmp(rpc->r_name, name) == 0) { - return (1); - } - for (aliasp = rpc->r_aliases; *aliasp != 0; aliasp++) { - if (strcmp(*aliasp, name) == 0) { - return (1); - } - } - return (0); -} +#include <ctype.h> +#include <stdlib.h> static nss_status_t getbyname(be, a) files_backend_ptr_t be; void *a; { - nss_XbyY_args_t *argp = (nss_XbyY_args_t *) a; + nss_XbyY_args_t *argp = (nss_XbyY_args_t *)a; - return (_nss_files_XY_all(be, argp, 1, argp->key.name, check_name)); + return (_nss_files_XY_all(be, argp, 1, argp->key.name, + _nss_files_check_name_aliases)); } static int -check_rpcnum(argp) - nss_XbyY_args_t *argp; +check_rpcnum(nss_XbyY_args_t *argp, const char *line, int linelen) { - struct rpcent *rpc = (struct rpcent *) argp->returnval; + int r_number; + const char *limit, *linep; + + linep = line; + limit = line + linelen; - return (rpc->r_number == argp->key.number); + /* skip name */ + while (linep < limit && !isspace(*linep)) + linep++; + /* skip the delimiting spaces */ + while (linep < limit && isspace(*linep)) + linep++; + if (linep == limit) + return (0); + r_number = (int)strtol(linep, NULL, 10); + return (r_number == argp->key.number); } @@ -76,10 +71,10 @@ getbynumber(be, a) files_backend_ptr_t be; void *a; { - nss_XbyY_args_t *argp = (nss_XbyY_args_t *) a; + nss_XbyY_args_t *argp = (nss_XbyY_args_t *)a; char numstr[12]; - sprintf(numstr, "%d", argp->key.number); + (void) snprintf(numstr, 12, "%d", argp->key.number); return (_nss_files_XY_all(be, argp, 1, numstr, check_rpcnum)); } diff --git a/usr/src/lib/nsswitch/files/common/getservent.c b/usr/src/lib/nsswitch/files/common/getservent.c index 855b543d55..32e73ea3f6 100644 --- a/usr/src/lib/nsswitch/files/common/getservent.c +++ b/usr/src/lib/nsswitch/files/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,10 +19,10 @@ * CDDL HEADER END */ /* - * Copyright (c) 1988-1995 Sun Microsystems Inc - * All Rights Reserved. + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. * - * files/getservent.c -- "files" backend for nsswitch "services" database + * files/getservent.c -- "files" backend for nsswitch "services" database */ #pragma ident "%Z%%M% %I% %E% SMI" @@ -32,27 +31,85 @@ #include "files_common.h" #include <sys/types.h> #include <netinet/in.h> +#include <inttypes.h> #include <strings.h> +#include <ctype.h> +#include <stdlib.h> static int -check_name(args) - nss_XbyY_args_t *args; +check_name(nss_XbyY_args_t *argp, const char *line, int linelen) { - struct servent *serv = (struct servent *) args->returnval; - const char *name = args->key.serv.serv.name; - const char *proto = args->key.serv.proto; - char **aliasp; + const char *limit, *linep, *keyp; + int name_match = 0; - if (proto != 0 && strcmp(serv->s_proto, proto) != 0) { - return (0); + linep = line; + limit = line + linelen; + keyp = argp->key.serv.serv.name; + + /* compare name */ + while (*keyp && linep < limit && !isspace(*linep) && *keyp == *linep) { + keyp++; + linep++; } - if (strcmp(serv->s_name, name) == 0) { - return (1); + if (*keyp == '\0' && linep < limit && isspace(*linep)) { + if (argp->key.serv.proto == NULL) + return (1); + else + name_match = 1; } - for (aliasp = serv->s_aliases; *aliasp != 0; aliasp++) { - if (strcmp(*aliasp, name) == 0) { + + /* skip remainder of the name, if any */ + while (linep < limit && !isspace(*linep)) + linep++; + /* skip the delimiting spaces */ + while (linep < limit && isspace(*linep)) + linep++; + /* skip port number */ + while (linep < limit && !isspace(*linep) && *linep != '/') + linep++; + if (linep == limit || *linep != '/') + return (0); + + linep++; + if ((keyp = argp->key.serv.proto) == NULL) { + /* skip protocol */ + while (linep < limit && !isspace(*linep)) + linep++; + } else { + /* compare protocol */ + while (*keyp && linep < limit && !isspace(*linep) && + *keyp == *linep) { + keyp++; + linep++; + } + /* no protocol match */ + if (*keyp || (linep < limit && !isspace(*linep))) + return (0); + /* protocol and name match, return */ + if (name_match) return (1); + /* protocol match but name yet to be matched, so continue */ + } + + /* compare with the aliases */ + while (linep < limit) { + /* skip the delimiting spaces */ + while (linep < limit && isspace(*linep)) + linep++; + + /* compare with the alias name */ + keyp = argp->key.serv.serv.name; + while (*keyp && linep < limit && !isspace(*linep) && + *keyp == *linep) { + keyp++; + linep++; } + if (*keyp == '\0' && (linep == limit || isspace(*linep))) + return (1); + + /* skip remainder of the alias name, if any */ + while (linep < limit && !isspace(*linep)) + linep++; } return (0); } @@ -62,21 +119,56 @@ getbyname(be, a) files_backend_ptr_t be; void *a; { - nss_XbyY_args_t *argp = (nss_XbyY_args_t *) a; + nss_XbyY_args_t *argp = (nss_XbyY_args_t *)a; return (_nss_files_XY_all(be, argp, 1, argp->key.serv.serv.name, check_name)); } static int -check_port(args) - nss_XbyY_args_t *args; +check_port(nss_XbyY_args_t *argp, const char *line, int linelen) { - struct servent *serv = (struct servent *) args->returnval; - const char *proto = args->key.serv.proto; + const char *limit, *linep, *keyp, *numstart; + int numlen, s_port; + char numbuf[12], *numend; + + linep = line; + limit = line + linelen; + + /* skip name */ + while (linep < limit && !isspace(*linep)) + linep++; + /* skip the delimiting spaces */ + while (linep < limit && isspace(*linep)) + linep++; + + /* compare port num */ + numstart = linep; + while (linep < limit && !isspace(*linep) && *linep != '/') + linep++; + if (linep == limit || *linep != '/') + return (0); + numlen = linep - numstart; + if (numlen == 0 || numlen >= sizeof (numbuf)) + return (0); + (void) memcpy(numbuf, numstart, numlen); + numbuf[numlen] = '\0'; + s_port = htons((int)strtol(numbuf, &numend, 10)); + if (*numend != '\0') + return (0); + if (s_port == argp->key.serv.serv.port) { + if ((keyp = argp->key.serv.proto) == NULL) + return (1); + } else + return (0); - return (serv->s_port == args->key.serv.serv.port && - (proto == 0 || strcmp(serv->s_proto, proto) == 0)); + /* compare protocol */ + linep++; + while (*keyp && linep < limit && !isspace(*linep) && *keyp == *linep) { + keyp++; + linep++; + } + return (*keyp == '\0' && (linep == limit || isspace(*linep))); } static nss_status_t @@ -84,10 +176,10 @@ getbyport(be, a) files_backend_ptr_t be; void *a; { - nss_XbyY_args_t *argp = (nss_XbyY_args_t *) a; + nss_XbyY_args_t *argp = (nss_XbyY_args_t *)a; char portstr[12]; - sprintf(portstr, "%d", ntohs(argp->key.serv.serv.port)); + (void) snprintf(portstr, 12, "%d", ntohs(argp->key.serv.serv.port)); return (_nss_files_XY_all(be, argp, 1, portstr, check_port)); } diff --git a/usr/src/lib/nsswitch/files/common/getspent.c b/usr/src/lib/nsswitch/files/common/getspent.c index 7287f024d2..af280b6d74 100644 --- a/usr/src/lib/nsswitch/files/common/getspent.c +++ b/usr/src/lib/nsswitch/files/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,10 +19,10 @@ * CDDL HEADER END */ /* - * Copyright (c) 1988-1995 Sun Microsystems Inc - * All Rights Reserved. + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. * - * files/getspent.c -- "files" backend for nsswitch "shadow" database + * files/getspent.c -- "files" backend for nsswitch "shadow" database */ #pragma ident "%Z%%M% %I% %E% SMI" @@ -33,15 +32,19 @@ #include <strings.h> static int -check_spnamp(argp) - nss_XbyY_args_t *argp; +check_spnamp(nss_XbyY_args_t *argp, const char *line, int linelen) { - struct spwd *s = (struct spwd *)argp->returnval; + const char *linep = line; + const char *keyp = argp->key.name; - /* +/- entries valid in compat source only */ - if (s->sp_namp != 0 && (s->sp_namp[0] == '+' || s->sp_namp[0] == '-')) + /* +/- entries valid for compat source only */ + if (linelen == 0 || *line == '+' || *line == '-') return (0); - return (strcmp(s->sp_namp, argp->key.name) == 0); + while (*keyp && linelen-- && *keyp == *linep) { + keyp++; + linep++; + } + return (linelen && *keyp == '\0' && *linep == ':'); } static nss_status_t @@ -49,7 +52,7 @@ getbyname(be, a) files_backend_ptr_t be; void *a; { - nss_XbyY_args_t *argp = (nss_XbyY_args_t *) a; + nss_XbyY_args_t *argp = (nss_XbyY_args_t *)a; return (_nss_files_XY_all(be, argp, 0, argp->key.name, check_spnamp)); } diff --git a/usr/src/lib/nsswitch/files/common/getuserattr.c b/usr/src/lib/nsswitch/files/common/getuserattr.c index 82f377c5da..3ada2a420f 100644 --- a/usr/src/lib/nsswitch/files/common/getuserattr.c +++ b/usr/src/lib/nsswitch/files/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,8 +19,8 @@ * CDDL HEADER END */ /* - * Copyright (c) 1999-2001 by 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" @@ -35,24 +34,14 @@ * files/getuserattr.c -- * "files" backend for nsswitch "user_attr" database */ -static int -check_name(nss_XbyY_args_t *args) -{ - userstr_t *user = (userstr_t *)args->returnval; - const char *name = args->key.name; - - if (strcmp(user->name, name) == 0) { - return (1); - } - return (0); -} static nss_status_t getbyname(files_backend_ptr_t be, void *a) { nss_XbyY_args_t *argp = (nss_XbyY_args_t *)a; - return (_nss_files_XY_all(be, argp, 1, argp->key.name, check_name)); + return (_nss_files_XY_all(be, argp, 1, argp->key.name, + _nss_files_check_name_colon)); } static files_backend_op_t userattr_ops[] = { @@ -63,6 +52,7 @@ static files_backend_op_t userattr_ops[] = { getbyname }; +/*ARGSUSED*/ nss_backend_t * _nss_files_user_attr_constr(const char *dummy1, const char *dummy2, diff --git a/usr/src/lib/nsswitch/files/common/netmasks.c b/usr/src/lib/nsswitch/files/common/netmasks.c index 876fcf66a6..2fe4a2fe1b 100644 --- a/usr/src/lib/nsswitch/files/common/netmasks.c +++ b/usr/src/lib/nsswitch/files/common/netmasks.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,10 +19,10 @@ * CDDL HEADER END */ /* - * files/netmasks.c -- "files" backend for nsswitch "netmasks" database + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. * - * Copyright (c) 1996 Sun Microsystems Inc - * All Rights Reserved. + * files/netmasks.c -- "files" backend for nsswitch "netmasks" database */ #pragma ident "%Z%%M% %I% %E% SMI" @@ -43,20 +42,45 @@ #include <netinet/in.h> #include <arpa/inet.h> #include <nss_dbdefs.h> +#include <ctype.h> /* * Validate 'files' netmasks entry. The comparison objects are in IPv4 * internet address format. */ static int -check_addr(args) - nss_XbyY_args_t *args; +check_addr(nss_XbyY_args_t *argp, const char *line, int linelen) { - struct in_addr tmp; + const char *limit, *linep, *addrstart; + int addrlen; + char addrbuf[NSS_LINELEN_NETMASKS]; + struct in_addr lineaddr, argsaddr; - tmp.s_addr = inet_addr(args->key.name); - return (memcmp(args->buf.buffer, (char *)&tmp, - sizeof (struct in_addr)) == 0); + linep = line; + limit = line + linelen; + + /* skip leading spaces */ + while (linep < limit && isspace(*linep)) + linep++; + + addrstart = linep; + while (linep < limit && !isspace(*linep)) + linep++; + if (linep == limit) + return (0); + addrlen = linep - addrstart; + if (addrlen < sizeof (addrbuf)) { + (void) memcpy(addrbuf, addrstart, addrlen); + addrbuf[addrlen] = '\0'; + if ((lineaddr.s_addr = inet_addr(addrbuf)) == + (in_addr_t)0xffffffffU) + return (0); + if ((argsaddr.s_addr = inet_addr(argp->key.name)) + == (in_addr_t)0xffffffffU) + return (0); + return (lineaddr.s_addr == argsaddr.s_addr); + } + return (0); } static nss_status_t @@ -64,15 +88,46 @@ getbynet(be, a) files_backend_ptr_t be; void *a; { - nss_XbyY_args_t *argp = (nss_XbyY_args_t *) a; + nss_XbyY_args_t *argp = (nss_XbyY_args_t *)a; nss_status_t res; char tmpbuf[NSS_LINELEN_NETMASKS]; - argp->buf.buffer = tmpbuf; - argp->buf.buflen = NSS_LINELEN_NETMASKS; + /* + * use the buffer passed in if result is to be returned + * in /etc file format + */ + if (argp->buf.result != NULL) { + argp->buf.buffer = tmpbuf; + argp->buf.buflen = NSS_LINELEN_NETMASKS; + } res = _nss_files_XY_all(be, argp, 0, argp->key.name, check_addr); - argp->buf.buffer = NULL; - argp->buf.buflen = 0; + if (argp->buf.result != NULL) { + argp->buf.buffer = NULL; + argp->buf.buflen = 0; + } else { + /* the frontend expects the netmask data only */ + if (res == NSS_SUCCESS) { + char *m; + char *s = (char *)argp->returnval; + int l = 0; + + m = s + argp->returnlen - 1; + + /* skip trailing spaces */ + while (s < m && isspace(*m)) + m--; + + for (; s <= m; m--) { + if (isspace(*m)) + break; + l++; + } + m++; + (void) memmove(argp->returnval, m, l); + argp->returnlen = l; + *(s + l) = '\0'; + } + } return (res); } diff --git a/usr/src/lib/nsswitch/files/common/tsol_getrhent.c b/usr/src/lib/nsswitch/files/common/tsol_getrhent.c index f41f606034..180a660189 100644 --- a/usr/src/lib/nsswitch/files/common/tsol_getrhent.c +++ b/usr/src/lib/nsswitch/files/common/tsol_getrhent.c @@ -28,30 +28,102 @@ #include "files_common.h" #include <string.h> #include <libtsnet.h> +#include <netinet/in.h> /* * files/tsol_getrhent.c -- * "files" backend for nsswitch "tnrhdb" database */ static int -check_addr(nss_XbyY_args_t *args) +check_addr(nss_XbyY_args_t *args, const char *line, int linelen) { - tsol_rhstr_t *rhstrp = (tsol_rhstr_t *)args->returnval; + const char *limit, *linep, *keyp; + char prev; + int ipv6; - if ((args->key.hostaddr.type == rhstrp->family) && - (strcmp(args->key.hostaddr.addr, rhstrp->address) == 0)) + linep = line; + limit = line + linelen; + keyp = args->key.hostaddr.addr; + prev = '\0'; + + if (strstr(linep, "\\:") != NULL) + ipv6 = 1; + else + ipv6 = 0; + + /* + * compare addr in + * + * 192.168.120.6:public + * fec0\:\:a00\:20ff\:fea0\:21f7:cipso + * + * ':' is the seperator. + */ + + while (*keyp && linep < limit && *keyp == *linep) { + if ((ipv6 == 0 && *linep == ':') || + (ipv6 == 1 && prev != '\\' && *linep == ':')) + break; + + prev = *linep; + keyp++; + linep++; + } + if (*keyp == '\0' && linep < limit && ((ipv6 == 0 && *linep == ':') || + (ipv6 == 1 && prev != '\\' && *linep == ':'))) return (1); return (0); } +static void +escape_colon(const 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'; +} + static nss_status_t getbyaddr(files_backend_ptr_t be, void *a) { nss_XbyY_args_t *argp = a; + char addr6[INET6_ADDRSTRLEN + 5]; /* 5 '\' for ':' */ + const char *addr = NULL; + nss_status_t rc; + + 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); + escape_colon(argp->key.hostaddr.addr, addr6); + /* save the key in original format */ + addr = argp->key.hostaddr.addr; + /* Replace the key with escaped format */ + argp->key.hostaddr.addr = addr6; + } else { + /* IPV4 */ + if (argp->key.hostaddr.type == AF_INET6) + return (NSS_NOTFOUND); + } + + rc = _nss_files_XY_all(be, argp, 1, + argp->key.hostaddr.addr, check_addr); + + /* restore argp->key.hostaddr.addr */ + if (addr) + argp->key.hostaddr.addr = addr; - return (_nss_files_XY_all(be, argp, 1, - argp->key.hostaddr.addr, check_addr)); + return (rc); } static files_backend_op_t tsol_rh_ops[] = { @@ -62,9 +134,10 @@ static files_backend_op_t tsol_rh_ops[] = { getbyaddr }; -/* ARGSUSED */ nss_backend_t * +/* LINTED E_FUNC_ARG_UNUSED */ _nss_files_tnrhdb_constr(const char *dummy1, const char *dummy2, +/* LINTED E_FUNC_ARG_UNUSED */ const char *dummy3) { return (_nss_files_constr(tsol_rh_ops, diff --git a/usr/src/lib/nsswitch/files/common/tsol_gettpent.c b/usr/src/lib/nsswitch/files/common/tsol_gettpent.c index ae5e9ca2be..dd604a5ee9 100644 --- a/usr/src/lib/nsswitch/files/common/tsol_gettpent.c +++ b/usr/src/lib/nsswitch/files/common/tsol_gettpent.c @@ -34,12 +34,20 @@ * "files" backend for nsswitch "tnrhtp" database */ static int -check_name(nss_XbyY_args_t *args) +check_name(nss_XbyY_args_t *args, const char *line, int linelen) { - tsol_tpstr_t *tpstrp = (tsol_tpstr_t *)args->returnval; - const char *name = args->key.name; + const char *limit, *linep, *keyp; - if (strcmp(tpstrp->template, name) == 0) + linep = line; + limit = line + linelen; + keyp = args->key.name; + + /* compare template name, ':' is the seperator */ + while (*keyp && linep < limit && *linep != ':' && *keyp == *linep) { + keyp++; + linep++; + } + if (*keyp == '\0' && linep < limit && *linep == ':') return (1); return (0); @@ -52,6 +60,9 @@ getbyname(be, a) { nss_XbyY_args_t *argp = (nss_XbyY_args_t *)a; + if (argp->key.name == NULL) + return (NSS_NOTFOUND); + return (_nss_files_XY_all(be, argp, 1, argp->key.name, check_name)); } @@ -62,8 +73,8 @@ static files_backend_op_t tsol_tp_ops[] = { _nss_files_getent_netdb, getbyname }; - nss_backend_t * +/* LINTED E_FUNC_ARG_UNUSED */ _nss_files_tnrhtp_constr(dummy1, dummy2, dummy3) const char *dummy1, *dummy2, *dummy3; { diff --git a/usr/src/lib/nsswitch/ldap/Makefile.com b/usr/src/lib/nsswitch/ldap/Makefile.com index 031dd04f46..43779514fc 100644 --- a/usr/src/lib/nsswitch/ldap/Makefile.com +++ b/usr/src/lib/nsswitch/ldap/Makefile.com @@ -62,4 +62,6 @@ include ../../Makefile.com CPPFLAGS += -I../../../libsldap/common LDLIBS += -lsldap -lnsl -lsocket -lldap +LINTFLAGS += -erroff=E_GLOBAL_COULD_BE_STATIC2 +LINTFLAGS64 += -erroff=E_GLOBAL_COULD_BE_STATIC2 DYNLIB1 = nss_ldap.so$(VERS) 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)); } diff --git a/usr/src/lib/nsswitch/nis/Makefile.com b/usr/src/lib/nsswitch/nis/Makefile.com index 63bd6a6936..2b0180d0d2 100644 --- a/usr/src/lib/nsswitch/nis/Makefile.com +++ b/usr/src/lib/nsswitch/nis/Makefile.com @@ -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 1993,2001-2003 Sun Microsystems, Inc. All rights reserved. +# Copyright 2006 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # # ident "%Z%%M% %I% %E% SMI" @@ -58,5 +57,8 @@ include ../../Makefile.com # install this library in the root filesystem include ../../../Makefile.rootfs +LINTFLAGS += -erroff=E_GLOBAL_COULD_BE_STATIC2 +LINTFLAGS64 += -erroff=E_GLOBAL_COULD_BE_STATIC2 + LDLIBS += -lnsl -lsocket DYNLIB1 = nss_nis.so$(VERS) diff --git a/usr/src/lib/nsswitch/nis/common/ether_addr.c b/usr/src/lib/nsswitch/nis/common/ether_addr.c index 83d65a4bbb..fbd233a7c0 100644 --- a/usr/src/lib/nsswitch/nis/common/ether_addr.c +++ b/usr/src/lib/nsswitch/nis/common/ether_addr.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,10 +19,10 @@ * CDDL HEADER END */ /* - * nis/ether_addr.c -- "nis" backend for nsswitch "ethers" database + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. * - * Copyright (c) 1988-1992 Sun Microsystems Inc - * All Rights Reserved. + * nis/ether_addr.c -- "nis" backend for nsswitch "ethers" database */ #pragma ident "%Z%%M% %I% %E% SMI" @@ -51,7 +50,7 @@ getbyhost(be, a) nis_backend_ptr_t be; void *a; { - nss_XbyY_args_t *argp = (nss_XbyY_args_t *) a; + nss_XbyY_args_t *argp = (nss_XbyY_args_t *)a; return (_nss_nis_lookup(be, argp, 0, "ethers.byname", argp->key.name, 0)); @@ -62,11 +61,11 @@ getbyether(be, a) nis_backend_ptr_t be; void *a; { - nss_XbyY_args_t *argp = (nss_XbyY_args_t *) a; + nss_XbyY_args_t *argp = (nss_XbyY_args_t *)a; char etherstr[18]; - u_char *e = argp->key.ether; + uchar_t *e = argp->key.ether; - sprintf(etherstr, "%x:%x:%x:%x:%x:%x", + (void) snprintf(etherstr, 18, "%x:%x:%x:%x:%x:%x", *e, *(e + 1), *(e + 2), *(e + 3), *(e + 4), *(e + 5)); return (_nss_nis_lookup(be, argp, 0, "ethers.byaddr", etherstr, 0)); } diff --git a/usr/src/lib/nsswitch/nis/common/getauthattr.c b/usr/src/lib/nsswitch/nis/common/getauthattr.c index c4040131f7..a37dcf00cd 100644 --- a/usr/src/lib/nsswitch/nis/common/getauthattr.c +++ b/usr/src/lib/nsswitch/nis/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,8 +19,8 @@ * CDDL HEADER END */ /* - * Copyright (c) 1999 by 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" @@ -49,6 +48,7 @@ static nis_backend_op_t authattr_ops[] = { getbynam }; +/*ARGSUSED*/ nss_backend_t * _nss_nis_auth_attr_constr(const char *dummy1, const char *dummy2, diff --git a/usr/src/lib/nsswitch/nis/common/getauuser.c b/usr/src/lib/nsswitch/nis/common/getauuser.c index 8abf038c7b..a86ba4112d 100644 --- a/usr/src/lib/nsswitch/nis/common/getauuser.c +++ b/usr/src/lib/nsswitch/nis/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,8 +19,8 @@ * CDDL HEADER END */ /* - * Copyright (c) 1999 by 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" @@ -50,6 +49,7 @@ static nis_backend_op_t auuser_ops[] = { getbynam }; +/*ARGSUSED*/ nss_backend_t * _nss_nis_audit_user_constr(const char *dummy1, const char *dummy2, diff --git a/usr/src/lib/nsswitch/nis/common/getexecattr.c b/usr/src/lib/nsswitch/nis/common/getexecattr.c index bc912602bc..07f8640f0b 100644 --- a/usr/src/lib/nsswitch/nis/common/getexecattr.c +++ b/usr/src/lib/nsswitch/nis/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 1999-2002 Sun Microsystems, Inc. All rights reserved. + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -41,7 +40,7 @@ extern void massage_netdb(const char **, int *); extern int _doexeclist(nss_XbyY_args_t *); extern char *_exec_wild_id(char *, const char *); extern void _exec_cleanup(nss_status_t, nss_XbyY_args_t *); - +extern char *_strtok_escape(char *, char *, char **); typedef struct __exec_nis_args { int *yp_status; @@ -88,6 +87,43 @@ check_match(nss_XbyY_args_t *argp, int check_policy) return (1); } +/* + * check_match_strbuf: set up the data needed by check_match() + * and call it to match exec_attr data in strbuf and argp->key.attrp + */ +static int +check_match_strbuf(nss_XbyY_args_t *argp, char *strbuf, int check_policy) +{ + char *last = NULL; + char *sep = KV_TOKEN_DELIMIT; + execstr_t exec; + execstr_t *execp = &exec; + void *sp; + int rc; + + /* + * Remove newline that yp_match puts at the + * end of the entry it retrieves from the map. + */ + if (strbuf[argp->returnlen] == '\n') { + strbuf[argp->returnlen] = '\0'; + } + + execp->name = _strtok_escape(strbuf, sep, &last); + execp->policy = _strtok_escape(NULL, sep, &last); + execp->type = _strtok_escape(NULL, sep, &last); + execp->res1 = _strtok_escape(NULL, sep, &last); + execp->res2 = _strtok_escape(NULL, sep, &last); + execp->id = _strtok_escape(NULL, sep, &last); + + sp = argp->returnval; + argp->returnval = execp; + rc = check_match(argp, check_policy); + argp->returnval = sp; + free(strbuf); + + return (rc); +} static nss_status_t _exec_nis_parse(const char *instr, @@ -98,13 +134,28 @@ _exec_nis_parse(const char *instr, int parse_stat; nss_status_t res; _priv_execattr *_priv_exec = (_priv_execattr *)(argp->key.attrp); + char *strbuf; + int check_matched; + argp->returnval = NULL; + argp->returnlen = 0; parse_stat = (*argp->str2ent)(instr, instr_len, argp->buf.result, argp->buf.buffer, argp->buf.buflen); switch (parse_stat) { case NSS_STR_PARSE_SUCCESS: - argp->returnval = argp->buf.result; - if (check_match(argp, check_policy)) { + argp->returnlen = instr_len; + /* if exec_attr file format requested */ + if (argp->buf.result == NULL) { + argp->returnval = argp->buf.buffer; + if ((strbuf = strdup(instr)) == NULL) + res = NSS_UNAVAIL; + check_matched = check_match_strbuf(argp, + strbuf, check_policy); + } else { + argp->returnval = argp->buf.result; + check_matched = check_match(argp, check_policy); + } + if (check_matched) { res = NSS_SUCCESS; if (_priv_exec->search_flag == GET_ALL) { if (_doexeclist(argp) == 0) { @@ -133,6 +184,7 @@ _exec_nis_parse(const char *instr, * flow of key-value pairs. If it returns a non-zero value, it is not called * again. The functional value of yp_all is then 0. */ +/*ARGSUSED*/ static int _exec_nis_cb(int instatus, char *inkey, @@ -144,7 +196,6 @@ _exec_nis_cb(int instatus, int check_policy = 1; /* always check policy for yp_all */ int stop_cb; const char *filter; - char *key = NULL; nss_status_t res; _exec_nis_args *eargp = (_exec_nis_args *)indata; nss_XbyY_args_t *argp = eargp->argp; @@ -206,7 +257,6 @@ _exec_nis_lookup(nis_backend_ptr_t be, nss_XbyY_args_t *argp, int getby_flag) if (getby_flag == NSS_DBOP_EXECATTR_BYNAMEID) { int check_policy = 0; int vallen; - int parse_stat; char *val; char key[MAX_INPUT]; @@ -330,6 +380,7 @@ getbyid(nis_backend_ptr_t be, void *a) { nss_status_t res; nss_XbyY_args_t *argp = (nss_XbyY_args_t *)a; + /*LINTED*/ _priv_execattr *_priv_exec = (_priv_execattr *)(argp->key.attrp); res = _exec_nis_lookup(be, argp, NSS_DBOP_EXECATTR_BYID); @@ -348,6 +399,7 @@ getbynameid(nis_backend_ptr_t be, void *a) { nss_status_t res; nss_XbyY_args_t *argp = (nss_XbyY_args_t *)a; + /*LINTED*/ _priv_execattr *_priv_exec = (_priv_execattr *)(argp->key.attrp); res = _exec_nis_lookup(be, argp, NSS_DBOP_EXECATTR_BYNAMEID); @@ -371,6 +423,7 @@ static nis_backend_op_t execattr_ops[] = { getbynameid }; +/*ARGSUSED*/ nss_backend_t * _nss_nis_exec_attr_constr(const char *dummy1, const char *dummy2, diff --git a/usr/src/lib/nsswitch/nis/common/getgrent.c b/usr/src/lib/nsswitch/nis/common/getgrent.c index c1f529e70b..f6447a9d4c 100644 --- a/usr/src/lib/nsswitch/nis/common/getgrent.c +++ b/usr/src/lib/nsswitch/nis/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 2004 Sun Microsystems, Inc. All rights reserved. + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -59,7 +58,7 @@ getbygid(be, a) nss_XbyY_args_t *argp = (nss_XbyY_args_t *)a; char gidstr[12]; /* More than enough */ - sprintf(gidstr, "%d", argp->key.gid); + (void) snprintf(gidstr, 12, "%d", argp->key.gid); return (_nss_nis_lookup(be, argp, 0, "group.bygid", gidstr, 0)); } @@ -154,7 +153,6 @@ parse_netid(const char *buf, gid_t gid_array[], int maxgids, int *numgids_ptr) { int numgids = *numgids_ptr; char *buf_next; - int buflen = strlen(buf); gid_t gid; long value; @@ -207,7 +205,6 @@ netid_lookup(struct nss_groupsbymem *argp) nss_status_t res; char *val; int vallen; - char *comment; int parse_res; char *lasts; @@ -232,7 +229,7 @@ netid_lookup(struct nss_groupsbymem *argp) return (res); } - strtok_r(val, "#", &lasts); + (void) strtok_r(val, "#", &lasts); parse_res = parse_netid(val, argp->gid_array, argp->maxgids, &argp->numgids); diff --git a/usr/src/lib/nsswitch/nis/common/gethostent.c b/usr/src/lib/nsswitch/nis/common/gethostent.c index 8636e5ef93..dd3f310336 100644 --- a/usr/src/lib/nsswitch/nis/common/gethostent.c +++ b/usr/src/lib/nsswitch/nis/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,8 +19,8 @@ * CDDL HEADER END */ /* - * Copyright (c) 1988-1992 Sun Microsystems Inc - * All Rights Reserved. + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. * * nis/gethostent.c -- "nis" backend for nsswitch "hosts" database */ @@ -43,7 +42,7 @@ getbyname(be, a) nis_backend_ptr_t be; void *a; { - nss_XbyY_args_t *argp = (nss_XbyY_args_t *) a; + nss_XbyY_args_t *argp = (nss_XbyY_args_t *)a; nss_status_t res; const char *s; @@ -82,7 +81,7 @@ getbyaddr(be, a) nis_backend_ptr_t be; void *a; { - nss_XbyY_args_t *argp = (nss_XbyY_args_t *) a; + nss_XbyY_args_t *argp = (nss_XbyY_args_t *)a; struct in_addr addr; char buf[18]; nss_status_t res; @@ -95,7 +94,7 @@ getbyaddr(be, a) argp->key.hostaddr.len != sizeof (addr)) { return (NSS_NOTFOUND); } - memcpy(&addr, argp->key.hostaddr.addr, sizeof (addr)); + (void) memcpy(&addr, argp->key.hostaddr.addr, sizeof (addr)); res = _nss_nis_lookup(be, argp, 1, "hosts.byaddr", inet_ntoa_r(addr, buf), 0); if (res != NSS_SUCCESS) diff --git a/usr/src/lib/nsswitch/nis/common/gethostent6.c b/usr/src/lib/nsswitch/nis/common/gethostent6.c index 4f1da89d04..48fb1f6377 100644 --- a/usr/src/lib/nsswitch/nis/common/gethostent6.c +++ b/usr/src/lib/nsswitch/nis/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,7 +19,7 @@ * CDDL HEADER END */ /* - * Copyright 1988-1992, 2003 Sun Microsystems, Inc. All rights reserved. + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. * * nis/gethostent.c -- "nis" backend for nsswitch "ipnodes" database @@ -94,7 +93,7 @@ getbyaddr(be, a) argp->key.hostaddr.len != sizeof (addr)) { return (NSS_NOTFOUND); } - memcpy(&addr, argp->key.hostaddr.addr, sizeof (addr)); + (void) memcpy(&addr, argp->key.hostaddr.addr, sizeof (addr)); if (IN6_IS_ADDR_V4MAPPED(&addr)) { if (inet_ntop(AF_INET, (void *) &addr.s6_addr[12], (void *)buf, INET_ADDRSTRLEN) == NULL) { diff --git a/usr/src/lib/nsswitch/nis/common/getnetgrent.c b/usr/src/lib/nsswitch/nis/common/getnetgrent.c index 4863f8fdff..92a631421f 100644 --- a/usr/src/lib/nsswitch/nis/common/getnetgrent.c +++ b/usr/src/lib/nsswitch/nis/common/getnetgrent.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. */ @@ -100,7 +99,7 @@ getnetgr_get(be, a) struct nis_getnetgr_be *be; void *a; { - struct nss_getnetgrent_args *args = (struct nss_getnetgrent_args *) a; + struct nss_getnetgrent_args *args = (struct nss_getnetgrent_args *)a; struct grouplist *mem; if ((mem = be->next_member) == 0) { @@ -120,7 +119,7 @@ getnetgr_get(be, a) args->retp[i] = 0; } else if ((len = strlen(str) + 1) <= buflen) { args->retp[i] = buffer; - memcpy(buffer, str, len); + (void) memcpy(buffer, str, len); buffer += len; buflen -= len; } else { @@ -170,7 +169,7 @@ getnetgr_destr(be, dummy) void *dummy; { if (be != 0) { - getnetgr_end(be, (void *)0); + (void) getnetgr_end(be, (void *)0); free(be); } return (NSS_SUCCESS); @@ -248,7 +247,7 @@ static void ngt_init(ngt) struct netgrtab *ngt; { - memset((void *)ngt, 0, sizeof (*ngt)); + (void) memset((void *)ngt, 0, sizeof (*ngt)); ngt->expand_lastp = &ngt->expand_first; } @@ -285,7 +284,7 @@ ngt_insert(ngt, name, namelen) if (cur == 0) { return; /* Out of memory, too bad */ } - memcpy(cur->name, name, namelen); + (void) memcpy(cur->name, name, namelen); cur->name[namelen] = 0; /* Insert in hash table */ @@ -349,7 +348,7 @@ top_down(struct nis_netgr_be *be, const char **groups, int ngroups, int done; nss_status_t result; - if ((ngt = (struct netgrtab *) malloc(sizeof (*ngt))) == 0) { + if ((ngt = (struct netgrtab *)malloc(sizeof (*ngt))) == 0) { return (NSS_UNAVAIL); } ngt_init(ngt); @@ -373,7 +372,9 @@ top_down(struct nis_netgr_be *be, const char **groups, int ngroups, result = _nss_nis_ypmatch(be->domain, "netgroup", group, &val, &vallen, &yperr); if (result != NSS_SUCCESS) { + /*LINTED E_NOP_IF_STMT*/ if (result == NSS_NOTFOUND) { + ; #ifdef DEBUG syslog(LOG_WARNING, "NIS netgroup lookup: %s doesn't exist", @@ -550,11 +551,11 @@ netgr_set(be, a) struct nis_netgr_be *be; void *a; { - struct nss_setnetgrent_args *args = (struct nss_setnetgrent_args *) a; + struct nss_setnetgrent_args *args = (struct nss_setnetgrent_args *)a; struct nis_getnetgr_be *get_be; nss_status_t res; - get_be = (struct nis_getnetgr_be *) malloc(sizeof (*get_be)); + get_be = (struct nis_getnetgr_be *)malloc(sizeof (*get_be)); if (get_be == 0) { return (NSS_UNAVAIL); } @@ -570,7 +571,7 @@ netgr_set(be, a) get_be->netgroup = strdup(args->netgroup); get_be->next_member = get_be->all_members; - args->iterator = (nss_backend_t *) get_be; + args->iterator = (nss_backend_t *)get_be; } else { args->iterator = 0; free(get_be); @@ -815,7 +816,7 @@ netgr_in(be, a) struct nis_netgr_be *be; void *a; { - struct nss_innetgr_args *ia = (struct nss_innetgr_args *) a; + struct nss_innetgr_args *ia = (struct nss_innetgr_args *)a; nss_status_t res; ia->status = NSS_NETGR_NO; @@ -852,7 +853,7 @@ netgr_in(be, a) */ /*ARGSUSED*/ -nss_status_t +static nss_status_t netgr_destr(be, dummy) struct nis_netgr_be *be; void *dummy; @@ -882,12 +883,12 @@ _nss_nis_netgroup_constr(dummy1, dummy2, dummy3) struct nis_netgr_be *be; if ((domain = _nss_nis_domain()) == 0 || - (be = (struct nis_netgr_be *) malloc(sizeof (*be))) == 0) { + (be = (struct nis_netgr_be *)malloc(sizeof (*be))) == 0) { return (0); } be->ops = netgroup_ops; be->n_ops = sizeof (netgroup_ops) / sizeof (netgroup_ops[0]); be->domain = domain; - return ((nss_backend_t *) be); + return ((nss_backend_t *)be); } diff --git a/usr/src/lib/nsswitch/nis/common/getprinter.c b/usr/src/lib/nsswitch/nis/common/getprinter.c index 0ccb484541..2983a00078 100644 --- a/usr/src/lib/nsswitch/nis/common/getprinter.c +++ b/usr/src/lib/nsswitch/nis/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. */ @@ -37,7 +36,6 @@ getbyname(be, a) void *a; { nss_XbyY_args_t *argp = (nss_XbyY_args_t *)a; - nss_status_t res; return (_nss_nis_lookup(be, argp, 0, "printers.conf.byname", argp->key.name, 0)); @@ -51,6 +49,7 @@ static nis_backend_op_t printers_ops[] = { getbyname }; +/*ARGSUSED*/ nss_backend_t * _nss_nis_printers_constr(dummy1, dummy2, dummy3) const char *dummy1, *dummy2, *dummy3; diff --git a/usr/src/lib/nsswitch/nis/common/getprofattr.c b/usr/src/lib/nsswitch/nis/common/getprofattr.c index 9813f70054..cdf4793e4c 100644 --- a/usr/src/lib/nsswitch/nis/common/getprofattr.c +++ b/usr/src/lib/nsswitch/nis/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,8 +19,8 @@ * CDDL HEADER END */ /* - * Copyright (c) 1999 by 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" @@ -49,6 +48,7 @@ static nis_backend_op_t profattr_ops[] = { getbynam }; +/*ARGSUSED*/ nss_backend_t * _nss_nis_prof_attr_constr(const char *dummy1, const char *dummy2, diff --git a/usr/src/lib/nsswitch/nis/common/getprojent.c b/usr/src/lib/nsswitch/nis/common/getprojent.c index 10b43d243f..c388f65749 100644 --- a/usr/src/lib/nsswitch/nis/common/getprojent.c +++ b/usr/src/lib/nsswitch/nis/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,8 +19,8 @@ * CDDL HEADER END */ /* - * Copyright (c) 1999-2000 by 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" @@ -42,7 +41,7 @@ static nss_status_t getbyid(nis_backend_ptr_t be, void *a) { char projstr[PROJNAME_MAX]; nss_XbyY_args_t *argp = (nss_XbyY_args_t *)a; - (void) sprintf(projstr, "%d", argp->key.projid); + (void) snprintf(projstr, PROJNAME_MAX, "%ld", argp->key.projid); return (_nss_nis_lookup(be, argp, 0, "project.byprojid", projstr, 0)); } diff --git a/usr/src/lib/nsswitch/nis/common/getpwnam.c b/usr/src/lib/nsswitch/nis/common/getpwnam.c index d623ebcbbd..a23ee8af5c 100644 --- a/usr/src/lib/nsswitch/nis/common/getpwnam.c +++ b/usr/src/lib/nsswitch/nis/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,8 +19,8 @@ * CDDL HEADER END */ /* - * Copyright (c) 1988-1992 Sun Microsystems Inc - * All Rights Reserved. + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. * * nis/getpwnam.c -- "nis" backend for nsswitch "passwd" database */ @@ -36,7 +35,7 @@ getbyname(be, a) nis_backend_ptr_t be; void *a; { - nss_XbyY_args_t *argp = (nss_XbyY_args_t *) a; + nss_XbyY_args_t *argp = (nss_XbyY_args_t *)a; return (_nss_nis_lookup(be, argp, 0, "passwd.byname", argp->key.name, 0)); @@ -47,10 +46,10 @@ getbyuid(be, a) nis_backend_ptr_t be; void *a; { - nss_XbyY_args_t *argp = (nss_XbyY_args_t *) a; + nss_XbyY_args_t *argp = (nss_XbyY_args_t *)a; char uidstr[12]; /* More than enough */ - sprintf(uidstr, "%d", argp->key.uid); + (void) snprintf(uidstr, 12, "%ld", argp->key.uid); return (_nss_nis_lookup(be, argp, 0, "passwd.byuid", uidstr, 0)); } diff --git a/usr/src/lib/nsswitch/nis/common/getrpcent.c b/usr/src/lib/nsswitch/nis/common/getrpcent.c index 88794e19a6..a2ead8d1e9 100644 --- a/usr/src/lib/nsswitch/nis/common/getrpcent.c +++ b/usr/src/lib/nsswitch/nis/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,8 +19,8 @@ * CDDL HEADER END */ /* - * Copyright (c) 1988-1992 Sun Microsystems Inc - * All Rights Reserved. + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. * * nis/getrpcent.c -- "nis" backend for nsswitch "rpc" database */ @@ -41,19 +40,29 @@ static int check_name(args) nss_XbyY_args_t *args; { - struct rpcent *rpc = (struct rpcent *) args->returnval; + struct rpcent *rpc = (struct rpcent *)args->returnval; const char *name = args->key.name; char **aliasp; - if (strcmp(rpc->r_name, name) == 0) { - return (1); - } - for (aliasp = rpc->r_aliases; *aliasp != 0; aliasp++) { - if (strcmp(*aliasp, name) == 0) { + if (rpc) { + if (strcmp(rpc->r_name, name) == 0) { return (1); } + for (aliasp = rpc->r_aliases; *aliasp != 0; aliasp++) { + if (strcmp(*aliasp, name) == 0) { + return (1); + } + } + return (0); + } else { + /* + * NSS2: nscd is running. + */ + return (_nss_nis_check_name_aliases(args, + (const char *)args->buf.buffer, + strlen(args->buf.buffer))); + } - return (0); } static mutex_t no_byname_lock = DEFAULTMUTEX; @@ -64,30 +73,31 @@ getbyname(be, a) nis_backend_ptr_t be; void *a; { - nss_XbyY_args_t *argp = (nss_XbyY_args_t *) a; + nss_XbyY_args_t *argp = (nss_XbyY_args_t *)a; int no_map; sigset_t oldmask, newmask; - sigfillset(&newmask); + (void) sigfillset(&newmask); (void) _thr_sigsetmask(SIG_SETMASK, &newmask, &oldmask); (void) _mutex_lock(&no_byname_lock); no_map = no_byname_map; (void) _mutex_unlock(&no_byname_lock); - (void) _thr_sigsetmask(SIG_SETMASK, &oldmask, (sigset_t*)NULL); + (void) _thr_sigsetmask(SIG_SETMASK, &oldmask, (sigset_t *)NULL); if (no_map == 0) { int yp_status; nss_status_t res; res = _nss_nis_lookup(be, argp, 1, "rpc.byname", - argp->key.name, &yp_status); + argp->key.name, &yp_status); if (yp_status == YPERR_MAP) { - sigfillset(&newmask); + (void) sigfillset(&newmask); _thr_sigsetmask(SIG_SETMASK, &newmask, &oldmask); _mutex_lock(&no_byname_lock); no_byname_map = 1; _mutex_unlock(&no_byname_lock); - _thr_sigsetmask(SIG_SETMASK, &oldmask, (sigset_t*)NULL); + _thr_sigsetmask(SIG_SETMASK, &oldmask, + (sigset_t *)NULL); } else /* if (res == NSS_SUCCESS) <==== */ { return (res); } @@ -101,10 +111,10 @@ getbynumber(be, a) nis_backend_ptr_t be; void *a; { - nss_XbyY_args_t *argp = (nss_XbyY_args_t *) a; + nss_XbyY_args_t *argp = (nss_XbyY_args_t *)a; char numstr[12]; - sprintf(numstr, "%d", argp->key.number); + (void) sprintf(numstr, "%d", argp->key.number); return (_nss_nis_lookup(be, argp, 1, "rpc.bynumber", numstr, 0)); } diff --git a/usr/src/lib/nsswitch/nis/common/getservent.c b/usr/src/lib/nsswitch/nis/common/getservent.c index 373ca89391..13b0ea17ea 100644 --- a/usr/src/lib/nsswitch/nis/common/getservent.c +++ b/usr/src/lib/nsswitch/nis/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,8 +19,8 @@ * CDDL HEADER END */ /* - * Copyright (c) 1988-1992 Sun Microsystems Inc - * All Rights Reserved. + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. * * nis/getservent.c -- "nis" backend for nsswitch "services" database */ @@ -30,11 +29,13 @@ #include "nis_common.h" #include <stdio.h> +#include <stdlib.h> #include <string.h> #include <signal.h> #include <malloc.h> #include <netdb.h> #include <synch.h> +#include <ctype.h> #include <rpcsvc/ypclnt.h> #include <thread.h> #include <sys/types.h> @@ -44,7 +45,7 @@ static int check_name(args) nss_XbyY_args_t *args; { - struct servent *serv = (struct servent *) args->returnval; + struct servent *serv = (struct servent *)args->returnval; const char *name = args->key.serv.serv.name; const char *proto = args->key.serv.proto; char **aliasp; @@ -63,6 +64,84 @@ check_name(args) return (0); } +static int +check_name2(nss_XbyY_args_t *argp) +{ + const char *limit, *linep, *keyp; + int name_match = 0; + + linep = (const char *)argp->buf.buffer; + limit = linep + strlen(argp->buf.buffer); + keyp = argp->key.serv.serv.name; + + /* compare name */ + while (*keyp && linep < limit && !isspace(*linep) && *keyp == *linep) { + keyp++; + linep++; + } + if (*keyp == '\0' && linep < limit && isspace(*linep)) { + if (argp->key.serv.proto == NULL) + return (1); + else + name_match = 1; + } + + /* skip remainder of the name, if any */ + while (linep < limit && !isspace(*linep)) + linep++; + /* skip the delimiting spaces */ + while (linep < limit && isspace(*linep)) + linep++; + /* skip port number */ + while (linep < limit && !isspace(*linep) && *linep != '/') + linep++; + if (linep == limit || *linep != '/') + return (0); + + linep++; + if ((keyp = argp->key.serv.proto) == NULL) { + /* skip protocol */ + while (linep < limit && !isspace(*linep)) + linep++; + } else { + /* compare protocol */ + while (*keyp && linep < limit && !isspace(*linep) && + *keyp == *linep) { + keyp++; + linep++; + } + /* no protocol match */ + if (*keyp || (linep < limit && !isspace(*linep))) + return (0); + /* protocol and name match, return */ + if (name_match) + return (1); + /* protocol match but name yet to be matched, so continue */ + } + + /* compare with the aliases */ + while (linep < limit) { + /* skip the delimiting spaces */ + while (linep < limit && isspace(*linep)) + linep++; + + /* compare with the alias name */ + keyp = argp->key.serv.serv.name; + while (*keyp && linep < limit && !isspace(*linep) && + *keyp == *linep) { + keyp++; + linep++; + } + if (*keyp == '\0' && (linep == limit || isspace(*linep))) + return (1); + + /* skip remainder of the alias name, if any */ + while (linep < limit && !isspace(*linep)) + linep++; + } + return (0); +} + static mutex_t no_byname_lock = DEFAULTMUTEX; static int no_byname_map = 0; @@ -71,13 +150,13 @@ getbyname(be, a) nis_backend_ptr_t be; void *a; { - nss_XbyY_args_t *argp = (nss_XbyY_args_t *) a; + nss_XbyY_args_t *argp = (nss_XbyY_args_t *)a; const char *name = argp->key.serv.serv.name; const char *proto = argp->key.serv.proto; int no_map; sigset_t oldmask, newmask; - sigfillset(&newmask); + (void) sigfillset(&newmask); (void) _thr_sigsetmask(SIG_SETMASK, &newmask, &oldmask); (void) _mutex_lock(&no_byname_lock); no_map = no_byname_map; @@ -92,37 +171,46 @@ getbyname(be, a) res = _nss_nis_lookup(be, argp, 1, "services.byservicename", name, &yp_status); } else { - char *key = malloc(strlen(name) + strlen(proto) + 3); + int len = strlen(name) + strlen(proto) + 3; + char *key = malloc(len); - if (key == 0) { + if (key == NULL) { return (NSS_UNAVAIL); } - sprintf(key, "%s/%s", name, proto); + (void) snprintf(key, len, "%s/%s", name, proto); res = _nss_nis_lookup(be, argp, 1, "services.byservicename", key, &yp_status); free(key); } if (yp_status == YPERR_MAP) { - sigfillset(&newmask); + (void) sigfillset(&newmask); _thr_sigsetmask(SIG_SETMASK, &newmask, &oldmask); _mutex_lock(&no_byname_lock); no_byname_map = 1; _mutex_unlock(&no_byname_lock); - _thr_sigsetmask(SIG_SETMASK, &oldmask, (sigset_t*)NULL); + _thr_sigsetmask(SIG_SETMASK, &oldmask, + (sigset_t *)NULL); } else /* if (res == NSS_SUCCESS) <==== */ { return (res); } } - return (_nss_nis_XY_all(be, argp, 1, name, check_name)); + /* + * use check_anme to compare service name if nss1 or nss2 and + * request is not from nscd; otherwise use check_name2 + */ + if (argp->buf.result != NULL) + return (_nss_nis_XY_all(be, argp, 1, name, check_name)); + else + return (_nss_nis_XY_all(be, argp, 1, name, check_name2)); } static int check_port(args) nss_XbyY_args_t *args; { - struct servent *serv = (struct servent *) args->returnval; + struct servent *serv = (struct servent *)args->returnval; /* * We only resorted to _nss_nis_XY_all because proto == 0, so just... @@ -130,28 +218,87 @@ check_port(args) return (serv->s_port == args->key.serv.serv.port); } +static int +check_port2(nss_XbyY_args_t *argp) +{ + const char *limit, *linep, *keyp, *numstart; + int numlen, s_port; + char numbuf[12], *numend; + + linep = (const char *)argp->buf.buffer; + limit = linep + strlen(argp->buf.buffer); + + /* skip name */ + while (linep < limit && !isspace(*linep)) + linep++; + /* skip the delimiting spaces */ + while (linep < limit && isspace(*linep)) + linep++; + + /* compare port num */ + numstart = linep; + while (linep < limit && !isspace(*linep) && *linep != '/') + linep++; + if (linep == limit || *linep != '/') + return (0); + numlen = linep - numstart; + if (numlen == 0 || numlen >= sizeof (numbuf)) + return (0); + (void) memcpy(numbuf, numstart, numlen); + numbuf[numlen] = '\0'; + s_port = htons((int)strtol(numbuf, &numend, 10)); + if (*numend != '\0') + return (0); + if (s_port == argp->key.serv.serv.port) { + if ((keyp = argp->key.serv.proto) == NULL) + return (1); + } else + return (0); + + /* compare protocol */ + linep++; + while (*keyp && linep < limit && !isspace(*linep) && *keyp == *linep) { + keyp++; + linep++; + } + return (*keyp == '\0' && (linep == limit || isspace(*linep))); +} + + static nss_status_t getbyport(be, a) nis_backend_ptr_t be; void *a; { - nss_XbyY_args_t *argp = (nss_XbyY_args_t *) a; + nss_XbyY_args_t *argp = (nss_XbyY_args_t *)a; int port = ntohs(argp->key.serv.serv.port); const char *proto = argp->key.serv.proto; char *key; nss_status_t res; + int len; if (proto == 0) { char portstr[12]; - sprintf(portstr, "%d", port); - return (_nss_nis_XY_all(be, argp, 1, portstr, check_port)); + (void) snprintf(portstr, 12, "%d", port); + /* + * use check_port to compare service port if nss1 or + * nss2 and request is not from nscd; otherwise use + * check_port2 + */ + if (argp->buf.result != NULL) + return (_nss_nis_XY_all(be, argp, 1, portstr, + check_port)); + else + return (_nss_nis_XY_all(be, argp, 1, portstr, + check_port2)); } - if ((key = malloc(strlen(proto) + 14)) == 0) { + len = strlen(proto) + 14; + if ((key = malloc(len)) == 0) { return (NSS_UNAVAIL); } - sprintf(key, "%d/%s", port, proto); + (void) snprintf(key, len, "%d/%s", port, proto); res = _nss_nis_lookup(be, argp, 1, "services.byname", key, 0); diff --git a/usr/src/lib/nsswitch/nis/common/getspent.c b/usr/src/lib/nsswitch/nis/common/getspent.c index 060083f0b9..55aff0b42f 100644 --- a/usr/src/lib/nsswitch/nis/common/getspent.c +++ b/usr/src/lib/nsswitch/nis/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. @@ -19,9 +18,10 @@ * * CDDL HEADER END */ + /* - * Copyright (c) 1988-1992 Sun Microsystems Inc - * All Rights Reserved. + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. * * nis/getspent.c -- "nis" backend for nsswitch "shadow" database */ @@ -54,7 +54,7 @@ nis_str2spent(instr, lenstr, ent, buffer, buflen) int buflen; { struct spwd *spwd = (struct spwd *)ent; - char *p, *q; + char *p, *q, *r; /* * We know that instr != 0 because we're in 'nis', not 'files' @@ -70,19 +70,34 @@ nis_str2spent(instr, lenstr, ent, buffer, buflen) if (q + 1 - instr > buflen) { return (NSS_STR_PARSE_ERANGE); } - memcpy(buffer, instr, q - instr); - buffer[p - instr] = '\0'; - buffer[q - instr] = '\0'; - - spwd->sp_namp = buffer; - spwd->sp_pwdp = buffer + (p + 1 - instr); - spwd->sp_lstchg = -1; - spwd->sp_min = -1; - spwd->sp_max = -1; - spwd->sp_warn = -1; - spwd->sp_inact = -1; - spwd->sp_expire = -1; - spwd->sp_flag = 0; + /* + * "name:password" is copied + */ + (void) memcpy(buffer, instr, q - instr); + if (spwd) { + buffer[p - instr] = '\0'; + buffer[q - instr] = '\0'; + + spwd->sp_namp = buffer; + spwd->sp_pwdp = buffer + (p + 1 - instr); + spwd->sp_lstchg = -1; + spwd->sp_min = -1; + spwd->sp_max = -1; + spwd->sp_warn = -1; + spwd->sp_inact = -1; + spwd->sp_expire = -1; + spwd->sp_flag = 0; + } else { + /* + * NSS2: nscd is running. Return files format. + * + * name:password::::::: + */ + r = buffer + (q - instr); + *r = '\0'; + if (strlcat(buffer, ":::::::", buflen) >= buflen) + return (NSS_STR_PARSE_ERANGE); + } return (NSS_STR_PARSE_SUCCESS); } @@ -93,10 +108,11 @@ getbyname(be, a) nis_backend_ptr_t be; void *a; { - nss_XbyY_args_t *argp = (nss_XbyY_args_t *) a; + nss_XbyY_args_t *argp = (nss_XbyY_args_t *)a; cstr2ent_t save_c2e; nss_status_t res; struct spwd *spwd; + char *p; save_c2e = argp->str2ent; argp->str2ent = nis_str2spent; @@ -110,12 +126,32 @@ getbyname(be, a) * succeed if the caller's uid is 0 because only root user * can use privilege port. */ - if ((res == NSS_SUCCESS) && (spwd->sp_pwdp) && - (*(spwd->sp_pwdp) == '#') && (*(spwd->sp_pwdp + 1) == '#')) { - /* get password from passwd.adjunct.byname */ - res = _nss_nis_lookup_rsvdport(be, argp, 0, + if (res == NSS_SUCCESS) { + if (spwd) { + if ((spwd->sp_pwdp) && (*(spwd->sp_pwdp) == '#') && + (*(spwd->sp_pwdp + 1) == '#')) { + /* get password from passwd.adjunct.byname */ + res = _nss_nis_lookup_rsvdport(be, argp, 0, "passwd.adjunct.byname", argp->key.name, 0); + } + } else { + /* + * getent request from nscd + */ + if ((p = memchr(argp->buf.buffer, ':', + argp->buf.buflen)) == NULL) + return (NSS_STR_PARSE_PARSE); + if (strncmp(p + 1, "##", 2) == 0) + /* get password from passwd.adjunct.byname */ + res = _nss_nis_lookup_rsvdport(be, argp, 0, + "passwd.adjunct.byname", + argp->key.name, 0); + if (res == NSS_SUCCESS) { + argp->returnval = argp->buf.buffer; + argp->returnlen = strlen(argp->buf.buffer); + } + } } argp->str2ent = save_c2e; @@ -131,10 +167,11 @@ getent(be, a) nis_backend_ptr_t be; void *a; { - nss_XbyY_args_t *argp = (nss_XbyY_args_t *) a; + nss_XbyY_args_t *argp = (nss_XbyY_args_t *)a; cstr2ent_t save_c2e; nss_status_t res; struct spwd *spwd; + char *p; save_c2e = argp->str2ent; argp->str2ent = nis_str2spent; @@ -148,13 +185,36 @@ getent(be, a) * succeed if the caller's uid is 0 because only root user * can use privilege port. */ - if ((res == NSS_SUCCESS) && (spwd->sp_pwdp) && - (*(spwd->sp_pwdp) == '#') && (*(spwd->sp_pwdp + 1) == '#')) { - /* get password from passwd.adjunct.byname */ - res = _nss_nis_lookup_rsvdport(be, argp, 0, + if (res == NSS_SUCCESS) { + if (spwd) { + if ((spwd->sp_pwdp) && (*(spwd->sp_pwdp) == '#') && + (*(spwd->sp_pwdp + 1) == '#')) { + /* get password from passwd.adjunct.byname */ + res = _nss_nis_lookup_rsvdport(be, argp, 0, "passwd.adjunct.byname", spwd->sp_namp, 0); + } + } else { + /* + * getent request from nscd + */ + if ((p = memchr(argp->buf.buffer, ':', + argp->buf.buflen)) == NULL) + return (NSS_STR_PARSE_PARSE); + if (strncmp(p + 1, "##", 2) == 0) { + /* need the name for the next search */ + *p = '\0'; + /* get password from passwd.adjunct.byname */ + res = _nss_nis_lookup_rsvdport(be, argp, 0, + "passwd.adjunct.byname", p, 0); + } + if (res == NSS_SUCCESS) { + argp->returnval = argp->buf.buffer; + argp->returnlen = strlen(argp->buf.buffer); + } + } } + argp->str2ent = save_c2e; return (res); } @@ -173,6 +233,7 @@ static nis_backend_op_t shadow_ops[] = { getbyname }; +/*ARGSUSED*/ nss_backend_t * _nss_nis_shadow_constr(dummy1, dummy2, dummy3) const char *dummy1, *dummy2, *dummy3; diff --git a/usr/src/lib/nsswitch/nis/common/getuserattr.c b/usr/src/lib/nsswitch/nis/common/getuserattr.c index c3550c51ba..48e961550b 100644 --- a/usr/src/lib/nsswitch/nis/common/getuserattr.c +++ b/usr/src/lib/nsswitch/nis/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,8 +19,8 @@ * CDDL HEADER END */ /* - * Copyright (c) 1999 by 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" @@ -49,6 +48,7 @@ static nis_backend_op_t userattr_ops[] = { getbynam }; +/*ARGSUSED*/ nss_backend_t * _nss_nis_user_attr_constr(const char *dummy1, const char *dummy2, diff --git a/usr/src/lib/nsswitch/nis/common/nis_common.c b/usr/src/lib/nsswitch/nis/common/nis_common.c index e7e90db51f..e90d82eb13 100644 --- a/usr/src/lib/nsswitch/nis/common/nis_common.c +++ b/usr/src/lib/nsswitch/nis/common/nis_common.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 1998-2002 Sun Microsystems, Inc. All rights reserved. + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -71,10 +70,12 @@ switch_err(ypstatus, ismatch) { switch (ypstatus) { case 0: + errno = 0; return (NSS_SUCCESS); case YPERR_BADARGS: case YPERR_KEY: + errno = 0; return (NSS_NOTFOUND); /* @@ -161,7 +162,7 @@ _nss_nis_ypmatch(domain, map, key, valp, vallenp, ypstatusp) #if MT_UNSAFE_YP sigset_t oldmask, newmask; - sigfillset(&newmask); + (void) sigfillset(&newmask); _thr_sigsetmask(SIG_SETMASK, &newmask, &oldmask); _mutex_lock(&one_lane); #endif @@ -182,7 +183,8 @@ _nss_nis_ypmatch(domain, map, key, valp, vallenp, ypstatusp) * XXX special version of _nss_nis_ypmatch() for handling C2 (passwd.adjunct) * lookups when we need a reserved port. */ -nss_status_t + +static nss_status_t _nss_nis_ypmatch_rsvdport(domain, map, key, valp, vallenp, ypstatusp) const char *domain; const char *map; @@ -192,12 +194,11 @@ _nss_nis_ypmatch_rsvdport(domain, map, key, valp, vallenp, ypstatusp) int *ypstatusp; { int ypstatus; - extern int yp_match_rsvdport(); #if MT_UNSAFE_YP sigset_t oldmask, newmask; - sigfillset(&newmask); + (void) sigfillset(&newmask); _thr_sigsetmask(SIG_SETMASK, &newmask, &oldmask); _mutex_lock(&one_lane); #endif @@ -240,10 +241,13 @@ _nss_nis_lookup(be, args, netdb, map, key, ypstatusp) massage_netdb((const char **)&val, &vallen); } + args->returnval = NULL; + args->returnlen = 0; parsestat = (*args->str2ent)(val, vallen, args->buf.result, args->buf.buffer, args->buf.buflen); if (parsestat == NSS_STR_PARSE_SUCCESS) { args->returnval = args->buf.result; + args->returnlen = vallen; res = NSS_SUCCESS; } else if (parsestat == NSS_STR_PARSE_ERANGE) { args->erange = 1; @@ -282,10 +286,13 @@ _nss_nis_lookup_rsvdport(be, args, netdb, map, key, ypstatusp) massage_netdb((const char **)&val, &vallen); } + args->returnval = NULL; + args->returnlen = 0; parsestat = (*args->str2ent)(val, vallen, args->buf.result, args->buf.buffer, args->buf.buflen); if (parsestat == NSS_STR_PARSE_SUCCESS) { args->returnval = args->buf.result; + args->returnlen = vallen; res = NSS_SUCCESS; } else if (parsestat == NSS_STR_PARSE_ERANGE) { args->erange = 1; @@ -314,7 +321,7 @@ do_getent(be, args, netdb) #if MT_UNSAFE_YP sigset_t oldmask, newmask; - sigfillset(&newmask); + (void) sigfillset(&newmask); _thr_sigsetmask(SIG_SETMASK, &newmask, &oldmask); _mutex_lock(&one_lane); #endif @@ -345,10 +352,13 @@ do_getent(be, args, netdb) massage_netdb((const char **)&outval, &outvallen); } + args->returnval = NULL; + args->returnlen = 0; parsestat = (*args->str2ent)(outval, outvallen, args->buf.result, args->buf.buffer, args->buf.buflen); if (parsestat == NSS_STR_PARSE_SUCCESS) { args->returnval = args->buf.result; + args->returnlen = outvallen; res = NSS_SUCCESS; } else if (parsestat == NSS_STR_PARSE_ERANGE) { args->erange = 1; @@ -450,7 +460,7 @@ _nss_nis_do_all(be, args, filter, func) #if MT_UNSAFE_YP sigset_t oldmask, newmask; - sigfillset(&newmask); + (void) sigfillset(&newmask); _thr_sigsetmask(SIG_SETMASK, &newmask, &oldmask); _mutex_lock(&one_lane); #endif @@ -494,12 +504,15 @@ XbyY_iterator(instr, instr_len, a) massage_netdb(&instr, &instr_len); } + args->returnval = NULL; + args->returnlen = 0; parsestat = (*args->str2ent)(instr, instr_len, args->buf.result, args->buf.buffer, args->buf.buflen); if (parsestat == NSS_STR_PARSE_SUCCESS) { args->returnval = args->buf.result; if ((*xydata->func)(args)) { res = NSS_SUCCESS; + args->returnlen = instr_len; } else { res = NSS_NOTFOUND; args->returnval = 0; @@ -545,7 +558,7 @@ _nss_nis_destr(be, dummy) { if (be != 0) { /* === Should change to invoke ops[ENDENT] ? */ - _nss_nis_endent(be, 0); + (void) _nss_nis_endent(be, 0); free(be); } return (NSS_SUCCESS); /* In case anyone is dumb enough to check */ @@ -565,7 +578,7 @@ _nss_nis_domain() */ sigset_t oldmask, newmask; - sigfillset(&newmask); + (void) sigfillset(&newmask); (void) _thr_sigsetmask(SIG_SETMASK, &newmask, &oldmask); (void) _mutex_lock(&yp_domain_lock); @@ -609,3 +622,57 @@ _nss_nis_constr(ops, n_ops, enum_map) return ((nss_backend_t *)be); } + +/* + * This routine is used to parse lines of the form: + * name number aliases + * It returns 1 if the key in argp matches any one of the + * names in the line, otherwise 0 + * Used by rpc + */ +int +_nss_nis_check_name_aliases(nss_XbyY_args_t *argp, const char *line, + int linelen) +{ + const char *limit, *linep, *keyp; + + linep = line; + limit = line + linelen; + keyp = argp->key.name; + + /* compare name */ + while (*keyp && linep < limit && !isspace(*linep) && *keyp == *linep) { + keyp++; + linep++; + } + if (*keyp == '\0' && linep < limit && isspace(*linep)) + return (1); + /* skip remainder of the name, if any */ + while (linep < limit && !isspace(*linep)) + linep++; + /* skip the delimiting spaces */ + while (linep < limit && isspace(*linep)) + linep++; + /* compare with the aliases */ + while (linep < limit) { + /* + * 1st pass: skip number + * Other passes: skip remainder of the alias name, if any + */ + while (linep < limit && !isspace(*linep)) + linep++; + /* skip the delimiting spaces */ + while (linep < limit && isspace(*linep)) + linep++; + /* compare with the alias name */ + keyp = argp->key.name; + while (*keyp && linep < limit && !isspace(*linep) && + *keyp == *linep) { + keyp++; + linep++; + } + if (*keyp == '\0' && (linep == limit || isspace(*linep))) + return (1); + } + return (0); +} diff --git a/usr/src/lib/nsswitch/nis/common/nis_common.h b/usr/src/lib/nsswitch/nis/common/nis_common.h index 281f80cb91..ad5407700e 100644 --- a/usr/src/lib/nsswitch/nis/common/nis_common.h +++ b/usr/src/lib/nsswitch/nis/common/nis_common.h @@ -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 1998-2002 Sun Microsystems, Inc. All rights reserved. + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -116,6 +115,9 @@ extern int __nss2herrno(nss_status_t nsstat); extern int _thr_sigsetmask(int how, const sigset_t *set, sigset_t *oset); extern int _mutex_lock(mutex_t *mp); extern int _mutex_unlock(mutex_t *mp); +extern int _nss_nis_check_name_aliases(nss_XbyY_args_t *argp, + const char *line, + int linelen); /* private yp "configurable lookup persistence" interface in libnsl */ extern int __yp_match_cflookup(char *, char *, char *, int, char **, diff --git a/usr/src/lib/nsswitch/nisplus/Makefile.com b/usr/src/lib/nsswitch/nisplus/Makefile.com index b060f52c50..c7481d2fe3 100644 --- a/usr/src/lib/nsswitch/nisplus/Makefile.com +++ b/usr/src/lib/nsswitch/nisplus/Makefile.com @@ -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 1993,2001-2003 Sun Microsystems, Inc. All rights reserved. +# Copyright 2006 Sun Microsystems, Inc. All rights reserved. # Use is subject to license terms. # # ident "%Z%%M% %I% %E% SMI" @@ -57,5 +56,8 @@ include ../../Makefile.com # install this library in the root filesystem include ../../../Makefile.rootfs +LINTFLAGS += -erroff=E_GLOBAL_COULD_BE_STATIC2 +LINTFLAGS64 += -erroff=E_GLOBAL_COULD_BE_STATIC2 + LDLIBS += -lnsl -lsocket DYNLIB1 = nss_nisplus.so$(VERS) diff --git a/usr/src/lib/nsswitch/nisplus/common/bootparams_getbyname.c b/usr/src/lib/nsswitch/nisplus/common/bootparams_getbyname.c index f43ffc0fc4..5cb2b8c591 100644 --- a/usr/src/lib/nsswitch/nisplus/common/bootparams_getbyname.c +++ b/usr/src/lib/nsswitch/nisplus/common/bootparams_getbyname.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,21 @@ * CDDL HEADER END */ /* - * nisplus/bootparams_getbyname.c -- "nisplus" backend for nsswitch - * "bootparams" database. + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +/* + * nisplus/bootparams_getbyname.c * - * Copyright (c) 1988-1992 Sun Microsystems Inc - * All Rights Reserved. + * nisplus backend for nsswitch bootparams database. */ #pragma ident "%Z%%M% %I% %E% SMI" #include <nss_dbdefs.h> #include <strings.h> +#include <stdlib.h> #include "nisplus_common.h" #include "nisplus_tables.h" @@ -39,7 +42,7 @@ getbyname(be, a) nisplus_backend_ptr_t be; void *a; { - nss_XbyY_args_t *argp = (nss_XbyY_args_t *) a; + nss_XbyY_args_t *argp = (nss_XbyY_args_t *)a; return (_nss_nisplus_lookup(be, argp, BOOTPARAM_TAG_KEY, argp->key.name)); @@ -47,22 +50,20 @@ getbyname(be, a) /* * place the results from the nis_object structure into argp->buf.buffer - * (hid argp->buf.buflen) that was supplied by the caller. + * that was supplied by the caller. * Returns NSS_STR_PARSE_{SUCCESS, ERANGE, PARSE} */ /*ARGSUSED*/ static int -nis_object2ent(nobj, obj, argp) - int nobj; - nis_object *obj; - nss_XbyY_args_t *argp; +nis_object2str(nobj, obj, be, argp) + int nobj; + nis_object *obj; + nisplus_backend_ptr_t be; + nss_XbyY_args_t *argp; { - char *buffer, *val; - int buflen = argp->buf.buflen; - struct entry_col *ecol; - int len; - - buffer = argp->buf.buffer; + char *buffer, *val; + int buflen, vallen; + struct entry_col *ecol; /* * If we got more than one nis_object, we just ignore it. @@ -79,18 +80,28 @@ nis_object2ent(nobj, obj, argp) } ecol = obj->EN_data.en_cols.en_cols_val; - /* - * datum - */ - EC_SET(ecol, BOOTPARAM_NDX_DATUM, len, val); - if (len < 2) { - *buffer = 0; - return (NSS_STR_PARSE_SUCCESS); - } - if (len > buflen) - return (NSS_STR_PARSE_ERANGE); - strncpy(buffer, val, len); + /* datum */ + __NISPLUS_GETCOL_OR_EMPTY(ecol, BOOTPARAM_NDX_DATUM, vallen, val); + buflen = vallen + 1; + if (argp->buf.result != NULL) { + if ((be->buffer = calloc(1, buflen)) == NULL) + return (NSS_STR_PARSE_PARSE); + /* include trailing null in length */ + be->buflen = buflen; + buffer = be->buffer; + } else { + if (buflen > argp->buf.buflen) + return (NSS_STR_PARSE_ERANGE); + buflen = argp->buf.buflen; + buffer = argp->buf.buffer; + (void) memset(buffer, 0, buflen); + } + (void) snprintf(buffer, buflen, "%s", val); +#ifdef DEBUG + (void) fprintf(stdout, "bootparams [%s]\n", buffer); + (void) fflush(stdout); +#endif /* DEBUG */ return (NSS_STR_PARSE_SUCCESS); } @@ -106,5 +117,5 @@ _nss_nisplus_bootparams_constr(dummy1, dummy2, dummy3) { return (_nss_nisplus_constr(bootparams_ops, sizeof (bootparams_ops) / sizeof (bootparams_ops[0]), - BOOTPARAM_TBLNAME, nis_object2ent)); + BOOTPARAM_TBLNAME, nis_object2str)); } diff --git a/usr/src/lib/nsswitch/nisplus/common/ether_addr.c b/usr/src/lib/nsswitch/nisplus/common/ether_addr.c index 3d0fbb25e1..346188c4b4 100644 --- a/usr/src/lib/nsswitch/nisplus/common/ether_addr.c +++ b/usr/src/lib/nsswitch/nisplus/common/ether_addr.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,12 +19,16 @@ * CDDL HEADER END */ /* - * nisplus/ether_addr.c -- "nisplus" backend for nsswitch "ethers" database - * - * Copyright 1988-1992,2002 Sun Microsystems, Inc. All rights reserved. + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ +/* + * nisplus/ether_addr.c + * + * nisplus backend for nsswitch "ethers" database + */ + #pragma ident "%Z%%M% %I% %E% SMI" /* @@ -36,6 +39,7 @@ * bytes are always in network order. */ +#include <stdlib.h> #include <sys/types.h> #include <sys/socket.h> #include <net/if.h> @@ -67,43 +71,30 @@ getbyether(be, a) char etherstr[18]; uchar_t *e = argp->key.ether; - (void) sprintf(etherstr, "%x:%x:%x:%x:%x:%x", + (void) snprintf(etherstr, 18, "%x:%x:%x:%x:%x:%x", *e, *(e + 1), *(e + 2), *(e + 3), *(e + 4), *(e + 5)); return (_nss_nisplus_lookup(be, argp, ETHER_TAG_ADDR, etherstr)); } /* - * Place the resulting struct ether_addr from the nis_object structure into - * argp->buf.result only if argp->buf.result is initialized (not NULL). - * I.e. it happens for the call ether_hostton. - * - * Place the resulting hostname into argp->buf.buffer only if - * argp->buf.buffer is initialized. I.e. it happens for the call - * ether_ntohost. + * Convert the ethers nisplus object into files format * * Returns NSS_STR_PARSE_{SUCCESS, ERANGE, PARSE} */ /*ARGSUSED*/ static int -nis_object2ent(nobj, obj, argp) - int nobj; - nis_object *obj; - nss_XbyY_args_t *argp; +nis_object2str(nobj, obj, be, argp) + int nobj; + nis_object *obj; + nisplus_backend_ptr_t be; + nss_XbyY_args_t *argp; { - uchar_t *ether = (uchar_t *)argp->buf.result; - char *host = argp->buf.buffer; - char *val; - struct entry_col *ecol; - int len; + char *addr, *name; + int addrlen, namelen; + struct entry_col *ecol; /* - * 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. - * * If we got more than one nis_object, we just ignore it. * Although it should never have happened. * @@ -118,46 +109,29 @@ nis_object2ent(nobj, obj, argp) } ecol = obj->EN_data.en_cols.en_cols_val; - /* - * get ether addr - * - * ether_hostton - */ - if (ether) { - int i; - unsigned int t[6]; - - EC_SET(ecol, ETHER_NDX_ADDR, len, val); - if (len < 2) - return (NSS_STR_PARSE_PARSE); - i = sscanf(val, "%x:%x:%x:%x:%x:%x", - &t[0], &t[1], &t[2], &t[3], &t[4], &t[5]); - if (i != ETHERADDRL) - return (NSS_STR_PARSE_PARSE); - for (i = 0; i < ETHERADDRL; i++) - *(ether + i) = (uchar_t)t[i]; + /* addr */ + __NISPLUS_GETCOL_OR_RETURN(ecol, ETHER_NDX_ADDR, addrlen, addr); + + /* name */ + __NISPLUS_GETCOL_OR_RETURN(ecol, ETHER_NDX_NAME, namelen, name); + + /* skip comment */ /* - * get hostname + * can't use argp->buf.result == NULL test to determine if + * the caller is nscd or not. * - * ether_ntohost + * exclude trailing null from length */ - } else if (host) { - EC_SET(ecol, ETHER_NDX_NAME, len, val); - if (len < 2) - return (NSS_STR_PARSE_PARSE); - /* - * 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. - */ - if (len > MAXHOSTNAMELEN) - return (NSS_STR_PARSE_ERANGE); - strcpy(host, val); - } + be->buflen = addrlen + namelen + 1; + if ((be->buffer = calloc(1, be->buflen + 1)) == NULL) + return (NSS_STR_PARSE_PARSE); + (void) snprintf(be->buffer, be->buflen + 1, "%s %s", addr, name); +#ifdef DEBUG + (void) fprintf(stdout, "ethers [%s]\n", be->buffer); + (void) fflush(stdout); +#endif /* DEBUG */ return (NSS_STR_PARSE_SUCCESS); } @@ -174,5 +148,5 @@ _nss_nisplus_ethers_constr(dummy1, dummy2, dummy3) { return (_nss_nisplus_constr(ethers_ops, sizeof (ethers_ops) / sizeof (ethers_ops[0]), - ETHER_TBLNAME, nis_object2ent)); + ETHER_TBLNAME, nis_object2str)); } diff --git a/usr/src/lib/nsswitch/nisplus/common/getauthattr.c b/usr/src/lib/nsswitch/nisplus/common/getauthattr.c index 5c9d63545a..cb3d76efd7 100644 --- a/usr/src/lib/nsswitch/nisplus/common/getauthattr.c +++ b/usr/src/lib/nsswitch/nisplus/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,8 +19,8 @@ * CDDL HEADER END */ /* - * Copyright (c) 1999 by 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" @@ -44,23 +43,20 @@ getbynam(nisplus_backend_ptr_t be, void *a) } /* - * place the results from the nis_object structure into argp->buf.result * Returns NSS_STR_PARSE_{SUCCESS, ERANGE, PARSE} */ +/*ARGSUSED*/ static int -nis_object2authstr(int nobj, nis_object *obj, nss_XbyY_args_t *argp) +nis_object2authstr(int nobj, nis_object *obj, + nisplus_backend_ptr_t be, + nss_XbyY_args_t *argp) { - int len; - int buflen = argp->buf.buflen; - char *buffer, *limit, *val, *endnum, *nullstring; - char *empty = ""; - authstr_t *auth; + char *buffer, *name, *res1, *res2; + char *shortdesc, *longdesc, *attr; + int buflen, namelen, res1len, res2len; + int shortdesclen, longdesclen, attrlen; struct entry_col *ecol; - limit = argp->buf.buffer + buflen; - auth = (authstr_t *)argp->buf.result; - buffer = argp->buf.buffer; - /* * If we got more than one nis_object, we just ignore object(s) * except the first. Although it should never have happened. @@ -76,96 +72,48 @@ nis_object2authstr(int nobj, nis_object *obj, nss_XbyY_args_t *argp) } ecol = obj->EN_data.en_cols.en_cols_val; - /* - * authstr->name: authorization name - */ - EC_SET(ecol, AUTHATTR_NDX_NAME, len, val); - if (len < 1 || (*val == '\0')) { - val = empty; - } - auth->name = buffer; - buffer += len; - if (buffer >= limit) { - return (NSS_STR_PARSE_ERANGE); - } - strcpy(auth->name, val); - nullstring = (buffer - 1); - - /* - * authstr->res1: reserved field 1 - */ - EC_SET(ecol, AUTHATTR_NDX_RES1, len, val); - if (len < 1 || (*val == '\0')) { - val = empty; - } - auth->res1 = buffer; - buffer += len; - if (buffer >= limit) { - return (NSS_STR_PARSE_ERANGE); - } - strcpy(auth->res1, val); - nullstring = (buffer - 1); - - /* - * authstr->res2: reserved field 2 - */ - EC_SET(ecol, AUTHATTR_NDX_RES2, len, val); - if (len < 1 || (*val == '\0')) { - val = empty; - } - auth->res2 = buffer; - buffer += len; - if (buffer >= limit) { - return (NSS_STR_PARSE_ERANGE); - } - strcpy(auth->res2, val); - nullstring = (buffer - 1); - - /* - * authstr->short_desc: short description - */ - EC_SET(ecol, AUTHATTR_NDX_SHORTDESC, len, val); - if (len < 1 || (*val == '\0')) { - val = empty; - } - auth->short_desc = buffer; - buffer += len; - if (buffer >= limit) { - return (NSS_STR_PARSE_ERANGE); - } - strcpy(auth->short_desc, val); - nullstring = (buffer - 1); - - /* - * authstr->long_desc: long description - */ - EC_SET(ecol, AUTHATTR_NDX_LONGDESC, len, val); - if (len < 1 || (*val == '\0')) { - val = empty; + /* authorization name */ + __NISPLUS_GETCOL_OR_RETURN(ecol, AUTHATTR_NDX_NAME, namelen, name); + + /* reserved field 1 */ + __NISPLUS_GETCOL_OR_EMPTY(ecol, AUTHATTR_NDX_RES1, res1len, res1); + + /* reserved field 2 */ + __NISPLUS_GETCOL_OR_EMPTY(ecol, AUTHATTR_NDX_RES2, res2len, res2); + + /* short description */ + __NISPLUS_GETCOL_OR_EMPTY(ecol, AUTHATTR_NDX_SHORTDESC, + shortdesclen, shortdesc); + + /* long description */ + __NISPLUS_GETCOL_OR_EMPTY(ecol, AUTHATTR_NDX_LONGDESC, + longdesclen, longdesc); + + /* key-value pairs of attributes */ + __NISPLUS_GETCOL_OR_EMPTY(ecol, AUTHATTR_NDX_ATTR, + attrlen, attr); + + buflen = namelen + res1len + res2len + shortdesclen + + longdesclen + attrlen + 6; + if (argp->buf.result != NULL) { + if ((be->buffer = calloc(1, buflen)) == NULL) + return (NSS_STR_PARSE_PARSE); + /* exclude trailing null from length */ + be->buflen = buflen - 1; + buffer = be->buffer; + } else { + if (buflen > argp->buf.buflen) + return (NSS_STR_PARSE_ERANGE); + buflen = argp->buf.buflen; + buffer = argp->buf.buffer; + (void) memset(buffer, 0, buflen); } - auth->long_desc = buffer; - buffer += len; - if (buffer >= limit) { - return (NSS_STR_PARSE_ERANGE); - } - strcpy(auth->long_desc, val); - nullstring = (buffer - 1); - - /* - * authstr->attrs: key-value pairs of attributes - */ - EC_SET(ecol, AUTHATTR_NDX_ATTR, len, val); - if (len < 1 || (*val == '\0')) { - val = empty; - } - auth->attr = buffer; - buffer += len; - if (buffer >= limit) { - return (NSS_STR_PARSE_ERANGE); - } - strcpy(auth->attr, val); - nullstring = (buffer - 1); - + (void) snprintf(buffer, buflen, "%s:%s:%s:%s:%s:%s", + name, res1, res2, shortdesc, longdesc, attr); +#ifdef DEBUG + (void) fprintf(stdout, "authattr [%s]\n", buffer); + (void) fflush(stdout); +#endif /* DEBUG */ return (NSS_STR_PARSE_SUCCESS); } @@ -177,6 +125,7 @@ static nisplus_backend_op_t authattr_ops[] = { getbynam }; +/*ARGSUSED*/ nss_backend_t * _nss_nisplus_auth_attr_constr(const char *dummy1, const char *dummy2, diff --git a/usr/src/lib/nsswitch/nisplus/common/getauuser.c b/usr/src/lib/nsswitch/nisplus/common/getauuser.c index b7ab478db4..23429494cf 100644 --- a/usr/src/lib/nsswitch/nisplus/common/getauuser.c +++ b/usr/src/lib/nsswitch/nisplus/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,8 +19,8 @@ * CDDL HEADER END */ /* - * Copyright (c) 1999-2001 by 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" @@ -42,7 +41,6 @@ #include <secdb.h> #include "nisplus_tables.h" - static nss_status_t getbynam(nisplus_backend_ptr_t be, void *a) { @@ -53,22 +51,18 @@ getbynam(nisplus_backend_ptr_t be, void *a) } /* - * place the results from the nis_object structure into argp->buf.result * Returns NSS_STR_PARSE_{SUCCESS, ERANGE, PARSE} */ +/*ARGSUSED*/ static int -nis_object2auuser(int nobj, nis_object *obj, nss_XbyY_args_t *argp) +nis_object2auuser(int nobj, nis_object *obj, + nisplus_backend_ptr_t be, + nss_XbyY_args_t *argp) { - int len; - int buflen = argp->buf.buflen; - char *p, *buffer, *limit, *val, *endnum, *nullstring; - char *empty = ""; - au_user_str_t *au_user; + char *buffer, *name, *always, *never; + int buflen, namelen, alwayslen, neverlen; struct entry_col *ecol; - limit = argp->buf.buffer + buflen; - au_user = (au_user_str_t *)argp->buf.result; - buffer = argp->buf.buffer; /* * If we got more than one nis_object, we just ignore object(s) except * the first. Although it should never have happened. @@ -82,51 +76,38 @@ nis_object2auuser(int nobj, nis_object *obj, nss_XbyY_args_t *argp) } ecol = obj->EN_data.en_cols.en_cols_val; - /* - * au_user->name: user name - */ - EC_SET(ecol, AUDITUSER_NDX_NAME, len, val); - if (len < 1 || (*val == '\0')) { - val = empty; - } - au_user->au_name = buffer; - buffer += len; - if (buffer >= limit) { - return (NSS_STR_PARSE_ERANGE); - } - strcpy(au_user->au_name, val); - nullstring = (buffer - 1); + /* user name */ + __NISPLUS_GETCOL_OR_RETURN(ecol, AUDITUSER_NDX_NAME, + namelen, name); - /* - * au_user->au_always: always audited events - */ - EC_SET(ecol, AUDITUSER_NDX_ALWAYS, len, val); - if (len < 1 || (*val == '\0')) { - val = empty; - } - au_user->au_always = buffer; - buffer += len; - if (buffer >= limit) { - return (NSS_STR_PARSE_ERANGE); - } - strcpy(au_user->au_always, val); - nullstring = (buffer - 1); + /* always audited events */ + __NISPLUS_GETCOL_OR_EMPTY(ecol, AUDITUSER_NDX_ALWAYS, + alwayslen, always); - /* - * au_user->au_never: never audited events - */ - EC_SET(ecol, AUDITUSER_NDX_NEVER, len, val); - if (len < 1 || (*val == '\0')) { - val = empty; - } - au_user->au_never = buffer; - buffer += len; - if (buffer >= limit) { - return (NSS_STR_PARSE_ERANGE); - } - strcpy(au_user->au_never, val); - nullstring = (buffer - 1); + /* never audited events */ + __NISPLUS_GETCOL_OR_EMPTY(ecol, AUDITUSER_NDX_NEVER, + neverlen, never); + buflen = namelen + alwayslen + neverlen + 3; + if (argp->buf.result != NULL) { + if ((be->buffer = calloc(1, buflen)) == NULL) + return (NSS_STR_PARSE_PARSE); + /* exclude trailing null from length */ + be->buflen = buflen - 1; + buffer = be->buffer; + } else { + if (buflen > argp->buf.buflen) + return (NSS_STR_PARSE_ERANGE); + buflen = argp->buf.buflen; + buffer = argp->buf.buffer; + (void) memset(buffer, 0, buflen); + } + (void) snprintf(buffer, buflen, "%s:%s:%s", + name, always, never); +#ifdef DEBUG + (void) fprintf(stdout, "audituser [%s]\n", buffer); + (void) fflush(stdout); +#endif /* DEBUG */ return (NSS_STR_PARSE_SUCCESS); } @@ -138,6 +119,7 @@ static nisplus_backend_op_t auuser_ops[] = { getbynam }; +/*ARGSUSED*/ nss_backend_t * _nss_nisplus_audit_user_constr(const char *dummy1, const char *dummy2, diff --git a/usr/src/lib/nsswitch/nisplus/common/getexecattr.c b/usr/src/lib/nsswitch/nisplus/common/getexecattr.c index a0f3fb65cc..8a60c77e75 100644 --- a/usr/src/lib/nsswitch/nisplus/common/getexecattr.c +++ b/usr/src/lib/nsswitch/nisplus/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 1999-2002 Sun Microsystems, Inc. All rights reserved. + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -88,8 +87,7 @@ _print_execstr(execstr_t *exec) static nss_status_t _exec_process_val(_exec_nisplus_args * eargp, nis_object * obj) { - int parse_stat; - nss_status_t res; + int parsestat; nss_XbyY_args_t *argp = eargp->argp; nisplus_backend_t *be = eargp->be; _priv_execattr *_priv_exec = (_priv_execattr *)(argp->key.attrp); @@ -98,30 +96,70 @@ _exec_process_val(_exec_nisplus_args * eargp, nis_object * obj) (void) fprintf(stdout, "\n[getexecattr.c: _exec_process_val]\n"); #endif /* DEBUG */ - parse_stat = (be->obj2ent) (1, obj, argp); /* passing one obj */ - switch (parse_stat) { - case NSS_STR_PARSE_SUCCESS: + /* passing one obj */ + parsestat = (be->obj2str) (1, obj, be, argp); + if (parsestat != NSS_STR_PARSE_SUCCESS) + goto fail; + + /* + * If caller is nscd's switch engine, the data + * will be in argp->buf.buffer. nscd does not + * support GET_ALL at this time so return + * success from here. + */ + if (argp->buf.result == NULL && be->buffer == NULL) { + argp->returnval = argp->buf.buffer; + if (argp->buf.buffer != NULL) + argp->returnlen = strlen(argp->buf.buffer); + return (NSS_SUCCESS); + } + + /* + * If the data is in be->buffer it needs + * to be marshalled. + */ + if (argp->str2ent == NULL) { + parsestat = NSS_STR_PARSE_PARSE; + goto fail; + } + 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; + } argp->returnval = argp->buf.result; - res = NSS_SUCCESS; - if (_priv_exec->search_flag == GET_ALL) { - if (_doexeclist(argp) == 0) { - res = NSS_UNAVAIL; - } + if (argp->buf.result != NULL) + argp->returnlen = 1; + else if (argp->buf.buffer != NULL) { + argp->returnval = argp->buf.buffer; + argp->returnlen = strlen(argp->buf.buffer); } - break; - case NSS_STR_PARSE_ERANGE: - argp->erange = 1; - res = NSS_NOTFOUND; /* We won't find this otherwise, anyway */ - break; - case NSS_STR_PARSE_PARSE: - res = NSS_NOTFOUND; - break; - default: - res = NSS_UNAVAIL; - break; + if (_priv_exec->search_flag == GET_ALL) + if (_doexeclist(argp) == 0) + return (NSS_UNAVAIL); + return (NSS_SUCCESS); } - return (res); +fail: + if (be->buffer != NULL) { + free(be->buffer); + be->buffer = NULL; + be->buflen = 0; + } + if (parsestat == NSS_STR_PARSE_ERANGE) { + argp->erange = 1; + /* We won't find this otherwise, anyway */ + return (NSS_NOTFOUND); + } else if (parsestat == NSS_STR_PARSE_PARSE) { + return (NSS_NOTFOUND); + } + return (NSS_UNAVAIL); } @@ -131,17 +169,16 @@ _exec_process_val(_exec_nisplus_args * eargp, nis_object * obj) * returns 0 if - no matching entry found, * matching entry found and next match needed. */ +/*ARGSUSED*/ static int check_match(nis_name table, nis_object * obj, void *eargs) { - int len; - int status = 0; - char *p, *val; + int len, status = 0; + char *val; struct entry_col *ecol; nss_status_t res; _exec_nisplus_args *eargp = (_exec_nisplus_args *)eargs; nss_XbyY_args_t *argp = eargp->argp; - nisplus_backend_t *be = eargp->be; _priv_execattr *_priv_exec = (_priv_execattr *)(argp->key.attrp); const char *type = _priv_exec->type; const char *policy = _priv_exec->policy; @@ -171,7 +208,7 @@ check_match(nis_name table, nis_object * obj, void *eargs) * check policy; it was not a searchable column in old servers. */ EC_SET(ecol, EXECATTR_NDX_POLICY, len, val); - if ((len == NULL) || (strcmp(val, policy) != 0)) { + if ((len == 0) || (strcmp(val, policy) != 0)) { return (0); } } @@ -181,7 +218,7 @@ check_match(nis_name table, nis_object * obj, void *eargs) * check type */ EC_SET(ecol, EXECATTR_NDX_TYPE, len, val); - if ((len == NULL) || (strcmp(val, type) != 0)) { + if ((len == 0) || (strcmp(val, type) != 0)) { return (0); } } @@ -210,11 +247,9 @@ _exec_nisplus_lookup(nisplus_backend_t *be, nss_XbyY_args_t *argp, int getby_flag) { - int status; char key[MAX_INPUT]; char policy_key[POLICY_LEN]; const char *column1, *key1, *column2, *key2; - nis_object *obj; nis_result *r = NULL; nss_status_t res = NSS_NOTFOUND; _exec_nisplus_args eargs; @@ -347,7 +382,6 @@ getbyid(nisplus_backend_ptr_t be, void *a) { nss_status_t res; nss_XbyY_args_t *argp = (nss_XbyY_args_t *)a; - _priv_execattr *_priv_exec = (_priv_execattr *)(argp->key.attrp); #ifdef DEBUG (void) fprintf(stdout, "\n[getexecattr.c: getbyid]\n"); @@ -369,7 +403,6 @@ getbynameid(nisplus_backend_ptr_t be, void *a) { nss_status_t res; nss_XbyY_args_t *argp = (nss_XbyY_args_t *)a; - _priv_execattr *_priv_exec = (_priv_execattr *)(argp->key.attrp); #ifdef DEBUG (void) fprintf(stdout, "\n[getexecattr.c: getbynameid]\n"); @@ -387,28 +420,20 @@ getbynameid(nisplus_backend_ptr_t be, void *a) /* - * place the results from the nis_object structure into argp->buf.result * Returns NSS_STR_PARSE_{SUCCESS, ERANGE, PARSE} */ +/*ARGSUSED*/ static int -nis_object2execstr(int nobj, nis_object *obj, nss_XbyY_args_t *argp) +nis_object2execstr(int nobj, nis_object *obj, + nisplus_backend_ptr_t be, + nss_XbyY_args_t *argp) { - int len; - int buflen = argp->buf.buflen; - char *limit, *val, *endnum, *nullstring; - char *buffer = NULL; - char *empty = ""; - execstr_t *exec = NULL; + char *buffer, *name, *type, *policy; + char *res1, *res2, *id, *attr; + int buflen, namelen, typelen, policylen; + int res1len, res2len, idlen, attrlen; struct entry_col *ecol; - limit = argp->buf.buffer + buflen; - exec = (execstr_t *)argp->buf.result; - buffer = argp->buf.buffer; - - if ((buffer == NULL) || (exec == NULL)) { - return (NSS_STR_PARSE_PARSE); - } - /* * If we got more than one nis_object, we just ignore object(s) except * the first. Although it should never have happened. @@ -422,113 +447,49 @@ nis_object2execstr(int nobj, nis_object *obj, nss_XbyY_args_t *argp) } ecol = obj->EN_data.en_cols.en_cols_val; - /* - * execstr->name: profile name - */ - EC_SET(ecol, EXECATTR_NDX_NAME, len, val); - if (len < 1 || (*val == '\0')) { - val = empty; - } - exec->name = buffer; - buffer += len; - if (buffer >= limit) { - return (NSS_STR_PARSE_ERANGE); - } - strcpy(exec->name, val); - nullstring = (buffer - 1); - - /* - * execstr->type: exec type - */ - EC_SET(ecol, EXECATTR_NDX_TYPE, len, val); - if (len < 1 || (*val == '\0')) { - val = empty; - } - exec->type = buffer; - buffer += len; - if (buffer >= limit) { - return (NSS_STR_PARSE_ERANGE); - } - strcpy(exec->type, val); - nullstring = (buffer - 1); - - /* - * execstr->policy - */ - EC_SET(ecol, EXECATTR_NDX_POLICY, len, val); - if (len < 1 || (*val == '\0')) { - val = empty; - } - exec->policy = buffer; - buffer += len; - if (buffer >= limit) { - return (NSS_STR_PARSE_ERANGE); - } - strcpy(exec->policy, val); - nullstring = (buffer - 1); - - /* - * execstr->res1: reserved field 1 - */ - EC_SET(ecol, EXECATTR_NDX_RES1, len, val); - if (len < 1 || (*val == '\0')) { - val = empty; - } - exec->res1 = buffer; - buffer += len; - if (buffer >= limit) { - return (NSS_STR_PARSE_ERANGE); - } - strcpy(exec->res1, val); - nullstring = (buffer - 1); - - /* - * execstr->res2: reserved field 2 - */ - EC_SET(ecol, EXECATTR_NDX_RES2, len, val); - if (len < 1 || (*val == '\0')) { - val = empty; - } - exec->res2 = buffer; - buffer += len; - if (buffer >= limit) { - return (NSS_STR_PARSE_ERANGE); - } - strcpy(exec->res2, val); - nullstring = (buffer - 1); - - /* - * execstr->id: unique id - */ - EC_SET(ecol, EXECATTR_NDX_ID, len, val); - if (len < 1 || (*val == '\0')) { - val = empty; - } - exec->id = buffer; - buffer += len; - if (buffer >= limit) { - return (NSS_STR_PARSE_ERANGE); - } - strcpy(exec->id, val); - nullstring = (buffer - 1); - - /* - * execstr->attrs: key-value pairs of attributes - */ - EC_SET(ecol, EXECATTR_NDX_ATTR, len, val); - if (len < 1 || (*val == '\0')) { - val = empty; - } - exec->attr = buffer; - buffer += len; - if (buffer >= limit) { - return (NSS_STR_PARSE_ERANGE); + /* profile name */ + __NISPLUS_GETCOL_OR_RETURN(ecol, EXECATTR_NDX_NAME, namelen, name); + + /* exec type */ + __NISPLUS_GETCOL_OR_EMPTY(ecol, EXECATTR_NDX_TYPE, typelen, type); + + /* policy */ + __NISPLUS_GETCOL_OR_EMPTY(ecol, EXECATTR_NDX_POLICY, + policylen, policy); + + /* reserved field 1 */ + __NISPLUS_GETCOL_OR_EMPTY(ecol, EXECATTR_NDX_RES1, res1len, res1); + + /* reserved field 2 */ + __NISPLUS_GETCOL_OR_EMPTY(ecol, EXECATTR_NDX_RES2, res2len, res2); + + /* unique id */ + __NISPLUS_GETCOL_OR_EMPTY(ecol, EXECATTR_NDX_ID, idlen, id); + + /* key-value pairs of attributes */ + __NISPLUS_GETCOL_OR_EMPTY(ecol, EXECATTR_NDX_ATTR, attrlen, attr); + + buflen = namelen + policylen + typelen + res1len + res2len + + idlen + attrlen + 7; + if (argp->buf.result != NULL) { + if ((be->buffer = calloc(1, buflen)) == NULL) + return (NSS_STR_PARSE_PARSE); + /* exclude trailing null from length */ + be->buflen = buflen - 1; + buffer = be->buffer; + } else { + if (buflen > argp->buf.buflen) + return (NSS_STR_PARSE_ERANGE); + buflen = argp->buf.buflen; + buffer = argp->buf.buffer; + (void) memset(buffer, 0, buflen); } - strcpy(exec->attr, val); - nullstring = (buffer - 1); - - exec->next = (execstr_t *)NULL; - + (void) snprintf(buffer, buflen, "%s:%s:%s:%s:%s:%s:%s", + name, policy, type, res1, res2, id, attr); +#ifdef DEBUG + (void) fprintf(stdout, "execattr [%s]\n", buffer); + (void) fflush(stdout); +#endif /* DEBUG */ return (NSS_STR_PARSE_SUCCESS); } @@ -542,6 +503,7 @@ static nisplus_backend_op_t execattr_ops[] = { getbynameid }; +/*ARGSUSED*/ nss_backend_t * _nss_nisplus_exec_attr_constr(const char *dummy1, const char *dummy2, diff --git a/usr/src/lib/nsswitch/nisplus/common/getgrent.c b/usr/src/lib/nsswitch/nisplus/common/getgrent.c index 1b51eb5d23..5d1a5234ff 100644 --- a/usr/src/lib/nsswitch/nisplus/common/getgrent.c +++ b/usr/src/lib/nsswitch/nisplus/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 2004 Sun Microsystems, Inc. All rights reserved. + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. */ @@ -72,7 +71,7 @@ getbygid(be, a) nss_XbyY_args_t *argp = (nss_XbyY_args_t *)a; char gidstr[12]; /* More than enough */ - sprintf(gidstr, "%d", argp->key.gid); + (void) snprintf(gidstr, 12, "%ld", argp->key.gid); return (_nss_nisplus_lookup(be, argp, GR_TAG_GID, gidstr)); } @@ -144,7 +143,8 @@ getbymember(be, a) * dumping all of the group entries and searching from the member * name on our own. */ - sprintf(buf, "[members=%s],%s", argp->username, be->table_name); + (void) snprintf(buf, NIS_MAXNAMELEN, "[members=%s],%s", + argp->username, be->table_name); r = __nis_list_localcb(buf, NIS_LIST_COMMON | ALL_RESULTS | __nis_force_hard_lookups, gr_cback, &grdata); if (r && r->status != NIS_BADATTRIBUTE) { @@ -165,7 +165,7 @@ getbymember(be, a) /* - * place the results from the nis_object structure into argp->buf.result + * convert the nisplus object into files format * Returns NSS_STR_PARSE_{SUCCESS, ERANGE, PARSE} * * This routine does not tolerate non-numeric gr_gid. It @@ -173,21 +173,16 @@ getbymember(be, a) */ /*ARGSUSED*/ static int -nis_object2ent(nobj, obj, argp) - int nobj; - nis_object *obj; - nss_XbyY_args_t *argp; +nis_object2str(nobj, obj, be, argp) + int nobj; + nis_object *obj; + nisplus_backend_ptr_t be; + nss_XbyY_args_t *argp; { - char *buffer, *limit, *val, *endnum, *grstart; - int buflen = argp->buf.buflen; - struct group *gr; - struct entry_col *ecol; - int len; - char **memlist; - - limit = argp->buf.buffer + buflen; - gr = (struct group *)argp->buf.result; - buffer = argp->buf.buffer; + char *buffer, *name, *passwd, *gid, *members; + int buflen, namelen, passwdlen, gidlen, memberslen; + char *endnum; + struct entry_col *ecol; /* * If we got more than one nis_object, we just ignore it. @@ -204,92 +199,44 @@ nis_object2ent(nobj, obj, argp) } ecol = obj->EN_data.en_cols.en_cols_val; - /* - * gr_name: group name - */ - EC_SET(ecol, GR_NDX_NAME, len, val); - if (len < 2) - return (NSS_STR_PARSE_PARSE); - gr->gr_name = buffer; - buffer += len; - if (buffer >= limit) - return (NSS_STR_PARSE_ERANGE); - strcpy(gr->gr_name, val); + /* name: group name */ + __NISPLUS_GETCOL_OR_RETURN(ecol, GR_NDX_NAME, namelen, name); /* - * gr_passwd: group passwd - * - * POLICY: The empty password ("") is gladly accepted. + * passwd: group passwd + * empty password ("") is gladly accepted. */ - EC_SET(ecol, GR_NDX_PASSWD, len, val); - if (len == 0) { - len = 1; - val = ""; - } - gr->gr_passwd = buffer; - buffer += len; - if (buffer >= limit) - return (NSS_STR_PARSE_ERANGE); - strcpy(gr->gr_passwd, val); + __NISPLUS_GETCOL_OR_EMPTY(ecol, GR_NDX_PASSWD, passwdlen, passwd); - /* - * gr_gid: group id - */ - EC_SET(ecol, GR_NDX_GID, len, val); - if (len == 0) { + /* gid: group id */ + __NISPLUS_GETCOL_OR_RETURN(ecol, GR_NDX_GID, gidlen, gid); + (void) strtol(gid, &endnum, 10); + if (*endnum != 0 || gid == endnum) return (NSS_STR_PARSE_PARSE); - } else { - gr->gr_gid = strtol(val, &endnum, 10); - if (*endnum != 0) { - return (NSS_STR_PARSE_PARSE); - } - } - /* - * gr_mem: gid list - * - * We first copy the field that looks like "grp1,grp2,..,grpn\0" - * into the buffer and advance the buffer in order to allocate - * for the gr_mem vector. We work on the group members in place - * in the buffer by replacing the "commas" with \0 and simulataneously - * advance the vector and point to a member. - * - * POLICY: We happily accept a null gid list. NIS+ tables store - * that as a single null character. - */ - EC_SET(ecol, GR_NDX_MEM, len, val); - if (len == 0) { - len = 1; - val = ""; - } - grstart = buffer; - buffer += len; - if (buffer >= limit) - return (NSS_STR_PARSE_ERANGE); - strcpy(grstart, val); - - gr->gr_mem = memlist = (char **)ROUND_UP(buffer, sizeof (char **)); - limit = (char *)ROUND_DOWN(limit, sizeof (char **)); - - while ((char *)memlist < limit) { - char c; - char *p = grstart; - - if (*p != '\0') /* avoid empty string */ - *memlist++ = p; - while ((c = *p) != '\0' && c != ',') { - p++; - } - if (*p == '\0') { /* all done */ - *memlist = 0; - break; - } - *p++ = '\0'; - grstart = p; - } - if ((char *)memlist >= limit) - return (NSS_STR_PARSE_ERANGE); + /* members: gid list */ + __NISPLUS_GETCOL_OR_EMPTY(ecol, GR_NDX_MEM, memberslen, members); + buflen = namelen + passwdlen + gidlen + memberslen + 4; + if (argp->buf.result != NULL) { + if ((be->buffer = calloc(1, buflen)) == NULL) + return (NSS_STR_PARSE_PARSE); + /* exclude the trailing null from length */ + be->buflen = buflen - 1; + buffer = be->buffer; + } else { + if (buflen > argp->buf.buflen) + return (NSS_STR_PARSE_ERANGE); + buflen = argp->buf.buflen; + buffer = argp->buf.buffer; + (void) memset(buffer, 0, buflen); + } + (void) snprintf(buffer, buflen, "%s:%s:%s:%s", + name, passwd, gid, members); +#ifdef DEBUG + (void) fprintf(stdout, "group [%s]\n", buffer); + (void) fflush(stdout); +#endif /* DEBUG */ return (NSS_STR_PARSE_SUCCESS); } @@ -310,7 +257,7 @@ _nss_nisplus_group_constr(dummy1, dummy2, dummy3) { return (_nss_nisplus_constr(gr_ops, sizeof (gr_ops) / sizeof (gr_ops[0]), - GR_TBLNAME, nis_object2ent)); + GR_TBLNAME, nis_object2str)); } #define NEXT 0 @@ -404,7 +351,7 @@ netid_lookup(struct memdata *grdata, nisplus_backend_ptr_t be) return (NSS_NOTFOUND); } - snprintf(buf, NIS_MAXNAMELEN, + (void) snprintf(buf, NIS_MAXNAMELEN, "[auth_name=%d,auth_type=LOCAL],cred.%s", pw.pw_uid, nis_domain_of(be->table_name)); @@ -436,6 +383,7 @@ netid_lookup(struct memdata *grdata, nisplus_backend_ptr_t be) } } +/*ARGSUSED*/ static int netid_cback(nis_name objname, nis_object *obj, struct memdata *g) { diff --git a/usr/src/lib/nsswitch/nisplus/common/gethostent.c b/usr/src/lib/nsswitch/nisplus/common/gethostent.c index 4070316799..ed413ffe0b 100644 --- a/usr/src/lib/nsswitch/nisplus/common/gethostent.c +++ b/usr/src/lib/nsswitch/nisplus/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,9 +19,11 @@ * CDDL HEADER END */ /* - * Copyright (c) 1988-1992 Sun Microsystems Inc - * All Rights Reserved. - * + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +/* * nisplus/gethostent.c -- NIS+ backend for nsswitch "hosts" database */ @@ -30,6 +31,8 @@ #include <string.h> #include <netdb.h> +#include <sys/types.h> +#include <arpa/inet.h> #include <netinet/in.h> #include <sys/socket.h> #include "nisplus_common.h" @@ -40,7 +43,7 @@ getbyname(be, a) nisplus_backend_ptr_t be; void *a; { - nss_XbyY_args_t *argp = (nss_XbyY_args_t *) a; + nss_XbyY_args_t *argp = (nss_XbyY_args_t *)a; nss_status_t res; /* @@ -59,13 +62,13 @@ getbyaddr(be, a) nisplus_backend_ptr_t be; void *a; { - nss_XbyY_args_t *argp = (nss_XbyY_args_t *) a; + nss_XbyY_args_t *argp = (nss_XbyY_args_t *)a; struct in_addr addr; char addrbuf[18]; nss_status_t res; - memcpy(&addr, argp->key.hostaddr.addr, sizeof (addr)); - inet_ntoa_r(addr, addrbuf); + (void) memcpy(&addr, argp->key.hostaddr.addr, sizeof (addr)); + (void) inet_ntoa_r(addr, addrbuf); res = _nss_nisplus_expand_lookup(be, argp, HOST_TAG_ADDR, addrbuf, HOST_TBLNAME); if (res != NSS_SUCCESS) @@ -75,75 +78,121 @@ getbyaddr(be, a) /* - * place the results from the nis_object structure into argp->buf.result * Returns NSS_STR_PARSE_{SUCCESS, ERANGE, PARSE} */ static int -nis_object2ent(nobj, obj, argp) - int nobj; - nis_object *obj; - nss_XbyY_args_t *argp; +nis_object2str(nobj, obj, be, argp) + int nobj; + nis_object *obj; + nisplus_backend_ptr_t be; + nss_XbyY_args_t *argp; { - char *buffer, *limit; - int buflen = argp->buf.buflen; - struct hostent *host; - struct in_addr *addrp; - int count, ret; - - limit = argp->buf.buffer + buflen; - host = (struct hostent *)argp->buf.result; - buffer = argp->buf.buffer; + return (nis_hosts_object2str(nobj, obj, be, argp, AF_INET)); +} + /* - * <--------------- buffer + buflen --------------------------------------> - * |-----------------|-----------------|----------------|----------------| - * | pointers vector | pointers vector | aliases grow | addresses grow | - * | for addresses | for aliases | | | - * | this way -> | this way -> | <- this way |<- this way | - * |-----------------|-----------------|----------------|----------------| - * | grows in PASS 1 | grows in PASS2 | grows in PASS2 | grows in PASS 1| - * - * - * ASSUME: the name and aliases columns in NIS+ tables ARE - * null terminated. - * - * - * PASS 1: get addresses + * Returns NSS_STR_PARSE_{SUCCESS, ERANGE, PARSE} */ - - addrp = (struct in_addr *) ROUND_DOWN(limit, sizeof (*addrp)); - host->h_addr_list = (char **) ROUND_UP(buffer, sizeof (char **)); - if ((char *)host->h_addr_list >= limit || - (char *)addrp <= (char *)host->h_addr_list) { - return (NSS_STR_PARSE_ERANGE); +int +nis_hosts_object2str(nobj, obj, be, argp, af) + int nobj; + nis_object *obj; + nisplus_backend_ptr_t be; + nss_XbyY_args_t *argp; + int af; +{ + char *buffer; + char *cname, *name, *addr; + int buflen, cnamelen, namelen, addrlen; + int first; + struct in_addr addr4; + struct entry_col *ecol; + + buflen = argp->buf.buflen; + buffer = argp->buf.buffer; + (void) memset(buffer, 0, buflen); + + for (first = 1; nobj > 0; nobj--, obj++) { + if (obj == NULL) + return (NSS_STR_PARSE_PARSE); + if (obj->zo_data.zo_type != NIS_ENTRY_OBJ || + obj->EN_data.en_cols.en_cols_len < HOST_COL) { + /* namespace/table/object is curdled */ + return (NSS_STR_PARSE_PARSE); + } + ecol = obj->EN_data.en_cols.en_cols_val; + + /* cname */ + __NISPLUS_GETCOL_OR_RETURN(ecol, HOST_NDX_CNAME, + cnamelen, cname); + + /* addr */ + __NISPLUS_GETCOL_OR_RETURN(ecol, HOST_NDX_ADDR, + addrlen, addr); + if (af == AF_INET) { + addr4.s_addr = inet_addr(addr); + if (addr4.s_addr == INADDR_NONE) + return (NSS_STR_PARSE_PARSE); + } + + /* name */ + __NISPLUS_GETCOL_OR_EMPTY(ecol, HOST_NDX_NAME, + namelen, name); + + /* + * newline is used to separate multiple + * entries. There is no newline before + * the first entry and after the last + * entry + */ + if (first) { + first = 0; + } else if (buflen > 1) { + *buffer = '\n'; + buffer++; + buflen--; + } else { + return (NSS_STR_PARSE_ERANGE); + } + + if (namelen > 1) { + if ((addrlen + cnamelen + namelen + 3) + > buflen) + return (NSS_STR_PARSE_ERANGE); + (void) snprintf(buffer, buflen, "%s %s %s", + addr, cname, name); + buffer += addrlen + cnamelen + namelen + 2; + buflen -= (addrlen + cnamelen + namelen + 2); + } else { + if ((addrlen + cnamelen + 2) > buflen) + return (NSS_STR_PARSE_ERANGE); + (void) snprintf(buffer, buflen, "%s %s", + addr, cname); + buffer += addrlen + cnamelen + 1; + buflen -= (addrlen + cnamelen + 1); + } } - ret = __netdb_aliases_from_nisobj(obj, nobj, NULL, - host->h_addr_list, (char **)&addrp, 0, &count, AF_INET); - if (ret != NSS_STR_PARSE_SUCCESS) - return (ret); - - /* - * PASS 2: get cname and aliases - */ - - host->h_aliases = host->h_addr_list + count + 1; - host->h_name = NULL; - - /* - * Assume that CNAME is the first column and NAME the second. - */ - ret = __netdb_aliases_from_nisobj(obj, nobj, NULL, host->h_aliases, - (char **)&addrp, &(host->h_name), &count, AF_INET); - if (ret != NSS_STR_PARSE_SUCCESS) - return (ret); - - host->h_addrtype = AF_INET; - host->h_length = sizeof (u_int); - + if (argp->buf.result != NULL) { + /* + * Some front end marshallers may require the + * files formatted data in a distinct buffer + */ + if ((be->buffer = strdup(argp->buf.buffer)) == NULL) + return (NSS_STR_PARSE_PARSE); + be->buflen = strlen(be->buffer); + } +#ifdef DEBUG + (void) fprintf(stdout, "%s [%s]\n", + (af == AF_INET)?"hosts":"ipnodes", + argp->buf.buffer); + (void) fflush(stdout); +#endif /* DEBUG */ return (NSS_STR_PARSE_SUCCESS); } + static nisplus_backend_op_t host_ops[] = { _nss_nisplus_destr, _nss_nisplus_endent, @@ -160,5 +209,5 @@ _nss_nisplus_hosts_constr(dummy1, dummy2, dummy3) { return (_nss_nisplus_constr(host_ops, sizeof (host_ops) / sizeof (host_ops[0]), - HOST_TBLNAME, nis_object2ent)); + HOST_TBLNAME, nis_object2str)); } diff --git a/usr/src/lib/nsswitch/nisplus/common/gethostent6.c b/usr/src/lib/nsswitch/nisplus/common/gethostent6.c index e9633d58a0..55ca8bc5a5 100644 --- a/usr/src/lib/nsswitch/nisplus/common/gethostent6.c +++ b/usr/src/lib/nsswitch/nisplus/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,9 +19,11 @@ * CDDL HEADER END */ /* - * Copyright 1988-1992, 2003 Sun Microsystems, Inc. All rights reserved. + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. * Use is subject to license terms. - * + */ + +/* * nisplus/gethostent6.c -- NIS+ backend for nsswitch "ipnodes" database */ @@ -34,10 +35,9 @@ #include <sys/socket.h> #include "nisplus_common.h" #include "nisplus_tables.h" +#include <arpa/inet.h> #include <inet/ip6.h> -const char *inet_ntop(int af, const void *src, char *dst, size_t size); - static nss_status_t getbyname(be, a) nisplus_backend_ptr_t be; @@ -72,7 +72,7 @@ getbyaddr(be, a) return (NSS_NOTFOUND); } - memcpy(&addr, argp->key.hostaddr.addr, sizeof (addr)); + (void) memcpy(&addr, argp->key.hostaddr.addr, sizeof (addr)); if (IN6_IS_ADDR_V4MAPPED(&addr)) { if (inet_ntop(AF_INET, (void *) &addr.s6_addr[12], (void *)addrbuf, INET_ADDRSTRLEN) == NULL) { @@ -93,76 +93,19 @@ getbyaddr(be, a) /* - * place the results from the nis_object structure into argp->buf.result * Returns NSS_STR_PARSE_{SUCCESS, ERANGE, PARSE} */ static int -nis_object2ent(nobj, obj, argp) - int nobj; - nis_object *obj; - nss_XbyY_args_t *argp; +nis_object2str(nobj, obj, be, argp) + int nobj; + nis_object *obj; + nisplus_backend_ptr_t be; + nss_XbyY_args_t *argp; { - char *buffer, *limit; - int buflen = argp->buf.buflen; - struct hostent *host; - struct in6_addr *addrp; - int count, ret; - - limit = argp->buf.buffer + buflen; - host = (struct hostent *)argp->buf.result; - buffer = argp->buf.buffer; - -/* - * <--------------- buffer + buflen --------------------------------------> - * |-----------------|-----------------|----------------|----------------| - * | pointers vector | pointers vector | aliases grow | addresses grow | - * | for addresses | for aliases | | | - * | this way -> | this way -> | <- this way |<- this way | - * |-----------------|-----------------|----------------|----------------| - * | grows in PASS 1 | grows in PASS2 | grows in PASS2 | grows in PASS 1| - * - * - * ASSUME: the name and aliases columns in NIS+ tables ARE - * null terminated. - * - * - * PASS 1: get addresses - */ - - addrp = (struct in6_addr *)ROUND_DOWN(limit, sizeof (*addrp)); - host->h_addr_list = (char **)ROUND_UP(buffer, sizeof (char **)); - if ((char *)host->h_addr_list >= limit || - (char *)addrp <= (char *)host->h_addr_list) { - return (NSS_STR_PARSE_ERANGE); - } - - ret = __netdb_aliases_from_nisobj(obj, nobj, NULL, - host->h_addr_list, (char **)&addrp, 0, &count, AF_INET6); - if (ret != NSS_STR_PARSE_SUCCESS) - return (ret); - - /* - * PASS 2: get cname and aliases - */ - - host->h_aliases = host->h_addr_list + count + 1; - host->h_name = NULL; - - /* - * Assume that CNAME is the first column and NAME the second. - */ - ret = __netdb_aliases_from_nisobj(obj, nobj, NULL, - host->h_aliases, (char **)&addrp, &(host->h_name), &count, - AF_INET6); - if (ret != NSS_STR_PARSE_SUCCESS) - return (ret); - - host->h_addrtype = AF_INET6; - host->h_length = IPV6_ADDR_LEN; - - return (NSS_STR_PARSE_SUCCESS); + return (nis_hosts_object2str(nobj, obj, be, argp, AF_INET6)); } + static nisplus_backend_op_t ipnodes_ops[] = { _nss_nisplus_destr, _nss_nisplus_endent, @@ -179,5 +122,5 @@ _nss_nisplus_ipnodes_constr(dummy1, dummy2, dummy3) { return (_nss_nisplus_constr(ipnodes_ops, sizeof (ipnodes_ops) / sizeof (ipnodes_ops[0]), - IPNODES_TBLNAME, nis_object2ent)); + IPNODES_TBLNAME, nis_object2str)); } diff --git a/usr/src/lib/nsswitch/nisplus/common/getnetent.c b/usr/src/lib/nsswitch/nisplus/common/getnetent.c index b6efa5f950..3a0a08cb7b 100644 --- a/usr/src/lib/nsswitch/nisplus/common/getnetent.c +++ b/usr/src/lib/nsswitch/nisplus/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,11 +19,11 @@ * CDDL HEADER END */ /* - * getnetent.c - * - * Copyright (c) 1988-1992 Sun Microsystems Inc - * All Rights Reserved. - * + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +/* * nisplus/getnetent.c -- NIS+ backend for nsswitch "net" database */ @@ -44,7 +43,7 @@ getbyname(be, a) nisplus_backend_ptr_t be; void *a; { - nss_XbyY_args_t *argp = (nss_XbyY_args_t *) a; + nss_XbyY_args_t *argp = (nss_XbyY_args_t *)a; /* * Don't have to do anything for case-insensitivity; the NIS+ table @@ -58,10 +57,10 @@ getbyaddr(be, a) nisplus_backend_ptr_t be; void *a; { - nss_XbyY_args_t *argp = (nss_XbyY_args_t *) a; + nss_XbyY_args_t *argp = (nss_XbyY_args_t *)a; char addrstr[16]; - if (nettoa((int) argp->key.netaddr.net, addrstr, 16) != 0) + if (nettoa((int)argp->key.netaddr.net, addrstr, 16) != 0) return (NSS_UNAVAIL); /* it's really ENOMEM */ return (_nss_nisplus_lookup(be, argp, NET_TAG_ADDR, addrstr)); @@ -69,66 +68,68 @@ getbyaddr(be, a) /* - * place the results from the nis_object structure into argp->buf.result + * Convert nisplus object into files format * Returns NSS_STR_PARSE_{SUCCESS, ERANGE, PARSE} */ static int -nis_object2ent(nobj, obj, argp) - int nobj; - nis_object *obj; - nss_XbyY_args_t *argp; +nis_object2str(nobj, obj, be, argp) + int nobj; + nis_object *obj; + nisplus_backend_ptr_t be; + nss_XbyY_args_t *argp; { - char *buffer, *limit, *val; - int buflen = argp->buf.buflen; - struct netent *net; - int len, ret; - struct entry_col *ecol; - - limit = argp->buf.buffer + buflen; - net = (struct netent *)argp->buf.result; - buffer = argp->buf.buffer; - - /* - * <-----buffer + buflen --------------> - * |-----------------|----------------| - * | pointers vector | aliases grow | - * | for aliases | | - * | this way -> | <- this way | - * |-----------------|----------------| - * - * - * ASSUME: name, aliases and number columns in NIS+ tables ARE - * null terminated. - * - * get cname and aliases - */ - - net->n_aliases = (char **) ROUND_UP(buffer, sizeof (char **)); - if ((char *)net->n_aliases >= limit) { - return (NSS_STR_PARSE_ERANGE); + char *buffer, *linep, *limit; + char *cname, *addr; + int buflen, cnamelen, addrlen; + int stat; + struct entry_col *ecol; + + if (obj->zo_data.zo_type != NIS_ENTRY_OBJ || + obj->EN_data.en_cols.en_cols_len < NET_COL) { + /* namespace/table/object is curdled */ + return (NSS_STR_PARSE_PARSE); } + ecol = obj->EN_data.en_cols.en_cols_val; - net->n_name = NULL; + buflen = argp->buf.buflen; + buffer = argp->buf.buffer; + (void) memset(buffer, 0, buflen); - /* - * Assume that CNAME is the first column and NAME the second. - */ - ret = netdb_aliases_from_nisobj(obj, nobj, NULL, - net->n_aliases, &limit, &(net->n_name), &len); - if (ret != NSS_STR_PARSE_SUCCESS) - return (ret); + /* cname */ + __NISPLUS_GETCOL_OR_RETURN(ecol, NET_NDX_CNAME, + cnamelen, cname); - /* - * get network number from the first object - * - */ - ecol = obj->EN_data.en_cols.en_cols_val; - EC_SET(ecol, NET_NDX_ADDR, len, val); - if (len <= 0 || ((net->n_net = inet_network(val)) == (in_addr_t)-1)) + /* addr */ + __NISPLUS_GETCOL_OR_RETURN(ecol, NET_NDX_ADDR, + addrlen, addr); + if (inet_network(addr) == (in_addr_t)-1) return (NSS_STR_PARSE_PARSE); - net->n_addrtype = AF_INET; - + if (cnamelen + addrlen + 2 > buflen) + return (NSS_STR_PARSE_ERANGE); + (void) snprintf(buffer, buflen, "%s %s", cname, addr); + + linep = buffer + cnamelen + addrlen + 1; + limit = buffer + buflen; + + stat = nis_aliases_object2str(obj, nobj, cname, NULL, linep, limit); + if (stat != NSS_STR_PARSE_SUCCESS) + return (stat); + + if (argp->buf.result != NULL) { + /* + * Some front end marshallers may require the + * files formatted data in a distinct buffer + */ + if ((be->buffer = strdup(buffer)) == NULL) + return (NSS_STR_PARSE_PARSE); + be->buflen = strlen(buffer); + buffer = be->buffer; + } +#ifdef DEBUG + (void) fprintf(stdout, "networks [%s]\n", buffer); + (void) fflush(stdout); +#endif /* DEBUG */ return (NSS_STR_PARSE_SUCCESS); } @@ -148,7 +149,7 @@ _nss_nisplus_networks_constr(dummy1, dummy2, dummy3) { return (_nss_nisplus_constr(net_ops, sizeof (net_ops) / sizeof (net_ops[0]), - NET_TBLNAME, nis_object2ent)); + NET_TBLNAME, nis_object2str)); } /* @@ -159,18 +160,18 @@ _nss_nisplus_networks_constr(dummy1, dummy2, dummy3) static int nettoa(anet, buf, buflen) int anet; - char *buf; + char *buf; int buflen; { - char *p; - struct in_addr in; - int addr; + char *p; + struct in_addr in; + int addr; if (buf == 0) return (1); in = inet_makeaddr(anet, INADDR_ANY); addr = in.s_addr; - (void) strncpy(buf, inet_ntoa(in), buflen); + (void) strlcpy(buf, inet_ntoa(in), buflen); if ((IN_CLASSA_HOST & htonl(addr)) == 0) { p = strchr(buf, '.'); if (p == NULL) diff --git a/usr/src/lib/nsswitch/nisplus/common/getnetgrent.c b/usr/src/lib/nsswitch/nisplus/common/getnetgrent.c index ba4c0ce14f..36ef196801 100644 --- a/usr/src/lib/nsswitch/nisplus/common/getnetgrent.c +++ b/usr/src/lib/nsswitch/nisplus/common/getnetgrent.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. */ @@ -147,7 +146,7 @@ getnetgr_get(be, a) args->retp[i] = 0; } else if ((len = strlen(str) + 1) <= buflen) { args->retp[i] = buffer; - memcpy(buffer, str, len); + (void) memcpy(buffer, str, len); buffer += len; buflen -= len; } else { @@ -196,7 +195,7 @@ getnetgr_destr(be, dummy) void *dummy; { if (be != 0) { - getnetgr_end(be, 0); + (void) getnetgr_end(be, 0); free(be); } return (NSS_SUCCESS); @@ -273,7 +272,7 @@ static void ngt_init(ngt) struct netgrtab *ngt; { - memset((void *)ngt, 0, sizeof (*ngt)); + (void) memset((void *)ngt, 0, sizeof (*ngt)); ngt->expand_lastp = &ngt->expand_first; } @@ -339,7 +338,7 @@ ngt_insert(ngt, name, namelen, breadth_first) if (cur == 0) { return; /* Out of memory, too bad */ } - memcpy(cur->name, name, namelen); + (void) memcpy(cur->name, name, namelen); cur->name[namelen] = 0; /* Insert in hash table */ @@ -497,26 +496,25 @@ top_down(be, groups, ngroups, func, iter_args) int i; /* %%% was NETGR_NDX_NAME */ - sprintf(search_crit, "[%s=%s]%s", + (void) snprintf(search_crit, NIS_MAXNAMELEN, "[%s=%s]%s", NETGR_TAG_NAME, group, be->table_name); result = _nss_nisplus_list(search_crit, 0, &r); if (result != NSS_SUCCESS) { - if (result == NSS_NOTFOUND) { #ifdef DEBUG + if (result == NSS_NOTFOUND) { syslog(LOG_WARNING, "innetgr: no such NIS+ netgroup as %s", group); -#endif /* DEBUG */ } else { -#ifdef DEBUG syslog(LOG_WARNING, "innetgr: nis_list returned [%s]", (r == 0) ? "A null pointer !?" : nis_sperrno(NIS_RES_STATUS(r))); + } #endif /* DEBUG */ + if (result != NSS_NOTFOUND) done = 1; /* Give up, return result */ - } if (r != 0) { nis_freeresult(r); } @@ -750,7 +748,7 @@ every_which_way(be, args) enum { BAD, BAD_NSS_TRYAGAIN, NO, YES } verdict; /* Copy NIS+ search value; ==== Should really do NIS+ quoting */ -#define catquoted(to, from) strcat(to, from) +#define catquoted(to, from) (void) strcat(to, from) /* * ====> @@ -813,7 +811,7 @@ every_which_way(be, args) pusers = nusers ? args->arg[NSS_NETGR_USER].argv : 0; do { if (pusers != 0) { - strcpy(users, ",user="); + (void) strcpy(users, ",user="); if (nusers != 0) { catquoted(users, *pusers); pusers++; @@ -825,7 +823,7 @@ every_which_way(be, args) phosts = nhosts ? args->arg[NSS_NETGR_MACHINE].argv : 0; do { if (phosts != 0) { - strcpy(hosts, ",host="); + (void) strcpy(hosts, ",host="); if (nhosts != 0) { catquoted(hosts, *phosts); phosts++; @@ -833,8 +831,8 @@ every_which_way(be, args) } search_crit[0] = '['; /* Was temporarily a comma */ - strcat(search_crit, "]"); - strcat(search_crit, be->table_name); + (void) strcat(search_crit, "]"); + (void) strcat(search_crit, be->table_name); switch (_nss_nisplus_list(search_crit, 0, &r)) { case NSS_SUCCESS: break; @@ -913,7 +911,8 @@ every_which_way(be, args) #ifdef SEARCH_DOWN_TOO if (top->n_total < bottom->n_total /* and a fudge factor? */) { group = ngt_next(top); - sprintf(search_crit, "[%s=%s]%s", + (void) snprintf(search_crit, NIS_MAXNAMELEN, + "[%s=%s]%s", NETGR_NDX_NAME, group, be->table_name); switch (_nss_nisplus_list(search_crit, 0, &r)) { case NSS_SUCCESS: @@ -962,7 +961,8 @@ every_which_way(be, args) #endif /* SEARCH_DOWN_TOO */ group = ngt_next(bottom); /* %%% was NETGR_NDX_GROUP */ - sprintf(search_crit, "[%s=%s],%s", + (void) snprintf(search_crit, NIS_MAXNAMELEN, + "[%s=%s],%s", NETGR_TAG_GROUP, group, be->table_name); switch (_nss_nisplus_list(search_crit, 0, &r)) { case NSS_SUCCESS: @@ -1067,10 +1067,11 @@ netgr_in(be, a) /*ARGSUSED*/ static int -bogus_object2ent(nobj, obj, argp) - int nobj; - nis_object *obj; - nss_XbyY_args_t *argp; +bogus_object2str(nobj, obj, be, argp) + int nobj; + nis_object *obj; + nisplus_backend_ptr_t be; + nss_XbyY_args_t *argp; { /* * This should never get used in the netgroup backend; @@ -1098,5 +1099,5 @@ _nss_nisplus_netgroup_constr(dummy1, dummy2, dummy3) { return (_nss_nisplus_constr(netgroup_ops, sizeof (netgroup_ops) / sizeof (netgroup_ops[0]), - NETGR_TBLNAME, bogus_object2ent)); + NETGR_TBLNAME, bogus_object2str)); } diff --git a/usr/src/lib/nsswitch/nisplus/common/getprinter.c b/usr/src/lib/nsswitch/nisplus/common/getprinter.c index 86566727c2..26037c0f96 100644 --- a/usr/src/lib/nsswitch/nisplus/common/getprinter.c +++ b/usr/src/lib/nsswitch/nisplus/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,18 +19,19 @@ * CDDL HEADER END */ /* - * Copyright (c) 1988-1995 Sun Microsystems Inc - * All Rights Reserved. - * - * nisplus/getspent.c: implementations of getspnam(), getspent(), setspent(), - * endspent() for NIS+. We keep the shadow information in a column - * ("shadow") of the same table that stores vanilla passwd information. + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +/* + * nisplus/getprinter.c */ #pragma ident "%Z%%M% %I% %E% SMI" #pragma weak _nss_nisplus__printers_constr = _nss_nisplus_printers_constr +#include <stdlib.h> #include <nss_dbdefs.h> #include "nisplus_common.h" #include "nisplus_tables.h" @@ -42,29 +42,26 @@ getbyname(be, a) nisplus_backend_ptr_t be; void *a; { - nss_XbyY_args_t *argp = (nss_XbyY_args_t *) a; + nss_XbyY_args_t *argp = (nss_XbyY_args_t *)a; return (_nss_nisplus_lookup(be, argp, PRINTERS_TAG_KEY, argp->key.name)); } /* - * place the results from the nis_object structure into argp->buf.buffer - * (hid argp->buf.buflen) that was supplied by the caller. * Returns NSS_STR_PARSE_{SUCCESS, ERANGE, PARSE} */ +/*ARGSUSED*/ static int -nis_object2ent(nobj, obj, argp) - int nobj; - nis_object *obj; - nss_XbyY_args_t *argp; +nis_object2str(nobj, obj, be, argp) + int nobj; + nis_object *obj; + nisplus_backend_ptr_t be; + nss_XbyY_args_t *argp; { - char *buffer, *val; - int buflen = argp->buf.buflen; - struct entry_col *ecol; - int len; - - buffer = argp->buf.buffer; + char *buffer, *key, *val; + int buflen, keylen, vallen; + struct entry_col *ecol; /* * If we got more than one nis_object, we just ignore it. @@ -81,30 +78,30 @@ nis_object2ent(nobj, obj, argp) } ecol = obj->EN_data.en_cols.en_cols_val; - /* - * key - */ - EC_SET(ecol, PRINTERS_NDX_KEY, len, val); - if (len < 2) { - *buffer = 0; - return (NSS_STR_PARSE_SUCCESS); - } - if (len > buflen) - return (NSS_STR_PARSE_ERANGE); - strncpy(buffer, val, len); + /* key */ + __NISPLUS_GETCOL_OR_RETURN(ecol, PRINTERS_NDX_KEY, keylen, key); - /* - * datum - */ - EC_SET(ecol, PRINTERS_NDX_DATUM, len, val); - if (len < 2) { - *buffer = 0; - return (NSS_STR_PARSE_SUCCESS); - } - if (len > buflen) - return (NSS_STR_PARSE_ERANGE); - strncat(buffer, val, buflen); + /* datum */ + __NISPLUS_GETCOL_OR_EMPTY(ecol, PRINTERS_NDX_DATUM, vallen, val); + buflen = vallen + keylen + 1; + if (argp->buf.result != NULL) { + if ((be->buffer = calloc(1, buflen)) == NULL) + return (NSS_STR_PARSE_PARSE); + be->buflen = buflen; + buffer = be->buffer; + } else { + if (buflen > argp->buf.buflen) + return (NSS_STR_PARSE_ERANGE); + buflen = argp->buf.buflen; + buffer = argp->buf.buffer; + (void) memset(buffer, 0, buflen); + } + (void) snprintf(buffer, buflen, "%s%s", key, val); +#ifdef DEBUG + (void) fprintf(stdout, "printers [%s]\n", buffer); + (void) fflush(stdout); +#endif /* DEBUG */ return (NSS_STR_PARSE_SUCCESS); } @@ -116,11 +113,12 @@ static nisplus_backend_op_t printers_ops[] = { getbyname }; +/*ARGSUSED*/ nss_backend_t * _nss_nisplus_printers_constr(dummy1, dummy2, dummy3) const char *dummy1, *dummy2, *dummy3; { return (_nss_nisplus_constr(printers_ops, sizeof (printers_ops) / sizeof (printers_ops[0]), - PRINTERS_TBLNAME, nis_object2ent)); + PRINTERS_TBLNAME, nis_object2str)); } diff --git a/usr/src/lib/nsswitch/nisplus/common/getprofattr.c b/usr/src/lib/nsswitch/nisplus/common/getprofattr.c index 7e6dfcb04c..c1a7111f41 100644 --- a/usr/src/lib/nsswitch/nisplus/common/getprofattr.c +++ b/usr/src/lib/nsswitch/nisplus/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,8 +19,8 @@ * CDDL HEADER END */ /* - * Copyright (c) 1999-2001 by 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" @@ -47,19 +46,18 @@ getbynam(nisplus_backend_ptr_t be, void *a) * place the results from the nis_object structure into argp->buf.result * Returns NSS_STR_PARSE_{SUCCESS, ERANGE, PARSE} */ +/*ARGSUSED*/ static int -nis_object2profstr(int nobj, nis_object *obj, nss_XbyY_args_t *argp) +nis_object2profstr(int nobj, nis_object *obj, + nisplus_backend_ptr_t be, + nss_XbyY_args_t *argp) { - int len; - int buflen = argp->buf.buflen; - char *buffer, *limit, *val, *endnum, *nullstring; - char *empty = ""; - profstr_t *prof; + char *buffer, *name, *res1, *res2, *desc; + char *attr; + int buflen, namelen, res1len, res2len; + int desclen, attrlen; struct entry_col *ecol; - limit = argp->buf.buffer + buflen; - prof = (profstr_t *)argp->buf.result; - buffer = argp->buf.buffer; /* * If we got more than one nis_object, we just ignore object(s) except * the first. Although it should never have happened. @@ -74,81 +72,41 @@ nis_object2profstr(int nobj, nis_object *obj, nss_XbyY_args_t *argp) } ecol = obj->EN_data.en_cols.en_cols_val; - /* - * profstr->name: profile name - */ - EC_SET(ecol, PROFATTR_NDX_NAME, len, val); - if (len < 1 || (*val == '\0')) { - val = empty; - } - prof->name = buffer; - buffer += len; - if (buffer >= limit) { - return (NSS_STR_PARSE_ERANGE); - } - strcpy(prof->name, val); - nullstring = (buffer - 1); - - /* - * profstr->res1: reserved field 1 - */ - EC_SET(ecol, PROFATTR_NDX_RES1, len, val); - if (len < 1 || (*val == '\0')) { - val = empty; - } - prof->res1 = buffer; - buffer += len; - if (buffer >= limit) { - return (NSS_STR_PARSE_ERANGE); - } - strcpy(prof->res1, val); - nullstring = (buffer - 1); - - /* - * profstr->res2: reserved field 2 - */ - EC_SET(ecol, PROFATTR_NDX_RES2, len, val); - if (len < 1 || (*val == '\0')) { - val = empty; + /* name: profile name */ + __NISPLUS_GETCOL_OR_RETURN(ecol, PROFATTR_NDX_NAME, namelen, name); + + /* res1: reserved field 1 */ + __NISPLUS_GETCOL_OR_EMPTY(ecol, PROFATTR_NDX_RES1, res1len, res1); + + /* res2: reserved field 2 */ + __NISPLUS_GETCOL_OR_EMPTY(ecol, PROFATTR_NDX_RES2, res2len, res2); + + /* desc: description */ + __NISPLUS_GETCOL_OR_EMPTY(ecol, PROFATTR_NDX_DESC, desclen, desc); + + /* attrs: key-value pairs of attributes */ + __NISPLUS_GETCOL_OR_EMPTY(ecol, PROFATTR_NDX_ATTR, attrlen, attr); + + buflen = namelen + res1len + res2len + desclen + attrlen + 5; + if (argp->buf.result != NULL) { + if ((be->buffer = calloc(1, buflen)) == NULL) + return (NSS_STR_PARSE_PARSE); + /* exclude trailing null from length */ + be->buflen = buflen - 1; + buffer = be->buffer; + } else { + if (buflen > argp->buf.buflen) + return (NSS_STR_PARSE_ERANGE); + buflen = argp->buf.buflen; + buffer = argp->buf.buffer; + (void) memset(buffer, 0, buflen); } - prof->res2 = buffer; - buffer += len; - if (buffer >= limit) { - return (NSS_STR_PARSE_ERANGE); - } - strcpy(prof->res2, val); - nullstring = (buffer - 1); - - /* - * profstr->desc: description - */ - EC_SET(ecol, PROFATTR_NDX_DESC, len, val); - if (len < 1 || (*val == '\0')) { - val = empty; - } - prof->desc = buffer; - buffer += len; - if (buffer >= limit) { - return (NSS_STR_PARSE_ERANGE); - } - strcpy(prof->desc, val); - nullstring = (buffer - 1); - - /* - * profstr->attrs: key-value pairs of attributes - */ - EC_SET(ecol, PROFATTR_NDX_ATTR, len, val); - if (len < 1 || (*val == '\0')) { - val = empty; - } - prof->attr = buffer; - buffer += len; - if (buffer >= limit) { - return (NSS_STR_PARSE_ERANGE); - } - strcpy(prof->attr, val); - nullstring = (buffer - 1); - + (void) snprintf(buffer, buflen, "%s:%s:%s:%s:%s", + name, res1, res2, desc, attr); +#ifdef DEBUG + (void) fprintf(stdout, "profattr [%s]\n", buffer); + (void) fflush(stdout); +#endif /* DEBUG */ return (NSS_STR_PARSE_SUCCESS); } @@ -160,6 +118,7 @@ static nisplus_backend_op_t profattr_ops[] = { getbynam }; +/*ARGSUSED*/ nss_backend_t * _nss_nisplus_prof_attr_constr(const char *dummy1, const char *dummy2, diff --git a/usr/src/lib/nsswitch/nisplus/common/getprotoent.c b/usr/src/lib/nsswitch/nisplus/common/getprotoent.c index aa40a34fc1..356236d2f2 100644 --- a/usr/src/lib/nsswitch/nisplus/common/getprotoent.c +++ b/usr/src/lib/nsswitch/nisplus/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,11 +19,11 @@ * CDDL HEADER END */ /* - * getprotoent.c - * - * Copyright (c) 1988-1992 Sun Microsystems Inc - * All Rights Reserved. - * + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +/* * nisplus/getprotoent.c -- NIS+ backend for nsswitch "proto" database */ @@ -41,7 +40,7 @@ getbyname(be, a) nisplus_backend_ptr_t be; void *a; { - nss_XbyY_args_t *argp = (nss_XbyY_args_t *) a; + nss_XbyY_args_t *argp = (nss_XbyY_args_t *)a; /* * Don't have to do anything for case-insensitivity; the NIS+ table @@ -55,74 +54,78 @@ getbynumber(be, a) nisplus_backend_ptr_t be; void *a; { - nss_XbyY_args_t *argp = (nss_XbyY_args_t *) a; + nss_XbyY_args_t *argp = (nss_XbyY_args_t *)a; char numstr[12]; - sprintf(numstr, "%d", argp->key.number); + (void) snprintf(numstr, 12, "%d", argp->key.number); return (_nss_nisplus_lookup(be, argp, PROTO_TAG_NUMBER, numstr)); } /* - * place the results from the nis_object structure into argp->buf.result + * Convert nisplus object into files format * Returns NSS_STR_PARSE_{SUCCESS, ERANGE, PARSE} */ static int -nis_object2ent(nobj, obj, argp) - int nobj; - nis_object *obj; - nss_XbyY_args_t *argp; +nis_object2str(nobj, obj, be, argp) + int nobj; + nis_object *obj; + nisplus_backend_ptr_t be; + nss_XbyY_args_t *argp; { - char *buffer, *limit, *val; - int buflen = argp->buf.buflen; - struct protoent *proto; - int len, ret; - struct entry_col *ecol; - - limit = argp->buf.buffer + buflen; - proto = (struct protoent *)argp->buf.result; - buffer = argp->buf.buffer; - - /* - * <-----buffer + buflen --------------> - * |-----------------|----------------| - * | pointers vector | aliases grow | - * | for aliases | | - * | this way -> | <- this way | - * |-----------------|----------------| - * - * - * ASSUME: name, aliases and number columns in NIS+ tables ARE - * null terminated. - * - * get cname and aliases - */ - - proto->p_aliases = (char **) ROUND_UP(buffer, sizeof (char **)); - if ((char *)proto->p_aliases >= limit) { - return (NSS_STR_PARSE_ERANGE); + char *buffer, *linep, *limit; + char *cname, *number, *endnum; + int buflen, cnamelen, numberlen; + int stat; + struct entry_col *ecol; + + if (obj->zo_data.zo_type != NIS_ENTRY_OBJ || + obj->EN_data.en_cols.en_cols_len < PROTO_COL) { + /* namespace/table/object is curdled */ + return (NSS_STR_PARSE_PARSE); } + ecol = obj->EN_data.en_cols.en_cols_val; - proto->p_name = NULL; + buflen = argp->buf.buflen; + buffer = argp->buf.buffer; + (void) memset(buffer, 0, buflen); - /* - * Assume that CNAME is the first column and NAME the second. - */ - ret = netdb_aliases_from_nisobj(obj, nobj, NULL, - proto->p_aliases, &limit, &(proto->p_name), &len); - if (ret != NSS_STR_PARSE_SUCCESS) - return (ret); + /* cname */ + __NISPLUS_GETCOL_OR_RETURN(ecol, PROTO_NDX_CNAME, + cnamelen, cname); - /* - * get protocol number from the first object - * - */ - ecol = obj->EN_data.en_cols.en_cols_val; - EC_SET(ecol, PROTO_NDX_NUMBER, len, val); - if (len <= 0) + /* number */ + __NISPLUS_GETCOL_OR_RETURN(ecol, PROTO_NDX_NUMBER, + numberlen, number); + (void) strtol(number, &endnum, 10); + if (*endnum != 0 || endnum == number) return (NSS_STR_PARSE_PARSE); - proto->p_proto = atoi(val); + if (cnamelen + numberlen + 2 > buflen) + return (NSS_STR_PARSE_ERANGE); + (void) snprintf(buffer, buflen, "%s %s", cname, number); + + linep = buffer + cnamelen + numberlen + 1; + limit = buffer + buflen; + + stat = nis_aliases_object2str(obj, nobj, cname, NULL, linep, limit); + if (stat != NSS_STR_PARSE_SUCCESS) + return (stat); + + if (argp->buf.result != NULL) { + /* + * Some front end marshallers may require the + * files formatted data in a distinct buffer + */ + if ((be->buffer = strdup(buffer)) == NULL) + return (NSS_STR_PARSE_PARSE); + be->buflen = strlen(buffer); + buffer = be->buffer; + } +#ifdef DEBUG + (void) fprintf(stdout, "protocols [%s]\n", buffer); + (void) fflush(stdout); +#endif /* DEBUG */ return (NSS_STR_PARSE_SUCCESS); } @@ -142,5 +145,5 @@ _nss_nisplus_protocols_constr(dummy1, dummy2, dummy3) { return (_nss_nisplus_constr(proto_ops, sizeof (proto_ops) / sizeof (proto_ops[0]), - PROTO_TBLNAME, nis_object2ent)); + PROTO_TBLNAME, nis_object2str)); } diff --git a/usr/src/lib/nsswitch/nisplus/common/getpwnam.c b/usr/src/lib/nsswitch/nisplus/common/getpwnam.c index 5336e05a82..19807456e5 100644 --- a/usr/src/lib/nsswitch/nisplus/common/getpwnam.c +++ b/usr/src/lib/nsswitch/nisplus/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,12 +19,12 @@ * CDDL HEADER END */ /* - * getpwnam.c - * - * Copyright (c) 1988-1992 Sun Microsystems Inc - * All Rights Reserved. - * - * nisplus/getpwnam.c -- NIS+ backend for nsswitch "passwd" database + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +/* + * nisplus/getpwnam.c -- NIS+ backend for nsswitch "passwd" database */ #pragma ident "%Z%%M% %I% %E% SMI" @@ -42,7 +41,7 @@ getbynam(be, a) nisplus_backend_ptr_t be; void *a; { - nss_XbyY_args_t *argp = (nss_XbyY_args_t *) a; + nss_XbyY_args_t *argp = (nss_XbyY_args_t *)a; return (_nss_nisplus_lookup(be, argp, PW_TAG_NAME, argp->key.name)); } @@ -52,39 +51,32 @@ getbyuid(be, a) nisplus_backend_ptr_t be; void *a; { - nss_XbyY_args_t *argp = (nss_XbyY_args_t *) a; + nss_XbyY_args_t *argp = (nss_XbyY_args_t *)a; char uidstr[12]; /* More than enough */ - sprintf(uidstr, "%d", argp->key.uid); + (void) snprintf(uidstr, 12, "%ld", argp->key.uid); return (_nss_nisplus_lookup(be, argp, PW_TAG_UID, uidstr)); } /* + * convert nisplus object into files format * place the results from the nis_object structure into argp->buf.result * Returns NSS_STR_PARSE_{SUCCESS, ERANGE, PARSE} - * - * This routine does not tolerate non-numeric or empty pw_uid or pw_gid. - * Nor empty name field. - * It will immediately flag a PARSE error and return. Returns a - * pointer-to-a-null in case of empty gecos, home_dir, or shell fields. */ /*ARGSUSED*/ static int -nis_object2ent(nobj, obj, argp) - int nobj; - nis_object *obj; - nss_XbyY_args_t *argp; +nis_object2str(nobj, obj, be, argp) + int nobj; + nis_object *obj; + nisplus_backend_ptr_t be; + nss_XbyY_args_t *argp; { - char *buffer, *limit, *val, *endnum, *nullstring; - int buflen = argp->buf.buflen; - struct passwd *pw; - struct entry_col *ecol; - int len; - - limit = argp->buf.buffer + buflen; - pw = (struct passwd *)argp->buf.result; - buffer = argp->buf.buffer; + char *buffer, *name, *uid, *gid, *gecos; + char *dir, *shell, *endnum; + int buflen, namelen, uidlen, gidlen, gecoslen; + int dirlen, shelllen; + struct entry_col *ecol; /* * If we got more than one nis_object, we just ignore object(s) @@ -101,126 +93,53 @@ nis_object2ent(nobj, obj, argp) } ecol = obj->EN_data.en_cols.en_cols_val; - /* - * pw_name: user name - */ - EC_SET(ecol, PW_NDX_NAME, len, val); - if (len < 2 || (*val == '\0')) - return (NSS_STR_PARSE_PARSE); - pw->pw_name = buffer; - buffer += len; - if (buffer >= limit) - return (NSS_STR_PARSE_ERANGE); - strcpy(pw->pw_name, val); - nullstring = (buffer - 1); + /* name: user name */ + __NISPLUS_GETCOL_OR_RETURN(ecol, PW_NDX_NAME, namelen, name); - /* - * pw_uid: user id - */ - EC_SET(ecol, PW_NDX_UID, len, val); - if (len < 2) { - return (NSS_STR_PARSE_PARSE); - } else { - pw->pw_uid = strtol(val, &endnum, 10); - if (*endnum != 0 || val == endnum) { - return (NSS_STR_PARSE_PARSE); - } - } + /* password field is 'x' */ - /* - * pw_passwd: user passwd. Do not HAVE to get this here - * because the caller would do a getspnam() anyway. - */ - EC_SET(ecol, PW_NDX_PASSWD, len, val); - if (len < 2) { - /* - * don't return NULL pointer, lot of stupid programs - * out there. - */ - pw->pw_passwd = nullstring; - } else { - pw->pw_passwd = buffer; - buffer += len; - if (buffer >= limit) - return (NSS_STR_PARSE_ERANGE); - strcpy(pw->pw_passwd, val); - } + /* uid: user id. Must be numeric */ + __NISPLUS_GETCOL_OR_RETURN(ecol, PW_NDX_UID, uidlen, uid); + (void) strtol(uid, &endnum, 10); + if (*endnum != 0 || uid == endnum) + return (NSS_STR_PARSE_PARSE); - /* - * pw_gid: user's primary group id. - */ - EC_SET(ecol, PW_NDX_GID, len, val); - if (len < 2) { + /* gid: primary group id. Must be numeric */ + __NISPLUS_GETCOL_OR_RETURN(ecol, PW_NDX_GID, gidlen, gid); + (void) strtol(gid, &endnum, 10); + if (*endnum != 0 || gid == endnum) return (NSS_STR_PARSE_PARSE); - } else { - pw->pw_gid = strtol(val, &endnum, 10); - if (*endnum != 0 || val == endnum) { - return (NSS_STR_PARSE_PARSE); - } - } - /* - * pw_gecos: user's real name. - */ - EC_SET(ecol, PW_NDX_GCOS, len, val); - if (len < 2) { - /* - * don't return NULL pointer, lot of stupid programs - * out there. - */ - pw->pw_gecos = nullstring; - } else { - pw->pw_gecos = buffer; - buffer += len; - if (buffer >= limit) - return (NSS_STR_PARSE_ERANGE); - strcpy(pw->pw_gecos, val); - } + /* gecos: user's real name */ + __NISPLUS_GETCOL_OR_EMPTY(ecol, PW_NDX_GCOS, gecoslen, gecos); - /* - * pw_dir: user's home directory - */ - EC_SET(ecol, PW_NDX_HOME, len, val); - if (len < 2) { - /* - * don't return NULL pointer, lot of stupid programs - * out there. - */ - pw->pw_dir = nullstring; - } else { - pw->pw_dir = buffer; - buffer += len; - if (buffer >= limit) - return (NSS_STR_PARSE_ERANGE); - strcpy(pw->pw_dir, val); - } + /* dir: user's home directory */ + __NISPLUS_GETCOL_OR_EMPTY(ecol, PW_NDX_HOME, dirlen, dir); - /* - * pw_shell: user's login shell - */ - EC_SET(ecol, PW_NDX_SHELL, len, val); - if (len < 2) { - /* - * don't return NULL pointer, lot of stupid programs - * out there. - */ - pw->pw_shell = nullstring; + /* shell: user's login shell */ + __NISPLUS_GETCOL_OR_EMPTY(ecol, PW_NDX_SHELL, shelllen, shell); + + buflen = namelen + uidlen + gidlen + gecoslen + + dirlen + shelllen + 8; + if (argp->buf.result != NULL) { + if ((be->buffer = calloc(1, buflen)) == NULL) + return (NSS_STR_PARSE_PARSE); + /* include trailing null in length */ + be->buflen = buflen; + buffer = be->buffer; } else { - pw->pw_shell = buffer; - buffer += len; - if (buffer >= limit) + if (buflen > argp->buf.buflen) return (NSS_STR_PARSE_ERANGE); - strcpy(pw->pw_shell, val); + buflen = argp->buf.buflen; + buffer = argp->buf.buffer; + (void) memset(buffer, 0, buflen); } - - /* - * pw_age and pw_comment shouldn't be used anymore, but various things - * (allegedly in.ftpd) merrily do strlen() on them anyway, so we - * keep the peace by returning a zero-length string instead of a - * null pointer. - */ - pw->pw_age = pw->pw_comment = nullstring; - + (void) snprintf(buffer, buflen, "%s:x:%s:%s:%s:%s:%s", + name, uid, gid, gecos, dir, shell); +#ifdef DEBUG + (void) fprintf(stdout, "passwd [%s]\n", buffer); + (void) fflush(stdout); +#endif /* DEBUG */ return (NSS_STR_PARSE_SUCCESS); } @@ -240,5 +159,5 @@ _nss_nisplus_passwd_constr(dummy1, dummy2, dummy3) { return (_nss_nisplus_constr(pw_ops, sizeof (pw_ops) / sizeof (pw_ops[0]), - PW_TBLNAME, nis_object2ent)); + PW_TBLNAME, nis_object2str)); } diff --git a/usr/src/lib/nsswitch/nisplus/common/getrpcent.c b/usr/src/lib/nsswitch/nisplus/common/getrpcent.c index aea3a5865d..0075a90fd9 100644 --- a/usr/src/lib/nsswitch/nisplus/common/getrpcent.c +++ b/usr/src/lib/nsswitch/nisplus/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,11 +19,11 @@ * CDDL HEADER END */ /* - * getrpcent.c - * - * Copyright (c) 1988-1992 Sun Microsystems Inc - * All Rights Reserved. - * + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +/* * nisplus/getrpcent.c -- NIS+ backend for nsswitch "rpc" database */ @@ -42,7 +41,7 @@ getbyname(be, a) nisplus_backend_ptr_t be; void *a; { - nss_XbyY_args_t *argp = (nss_XbyY_args_t *) a; + nss_XbyY_args_t *argp = (nss_XbyY_args_t *)a; /* * Don't have to do anything for case-insensitivity; the NIS+ table @@ -56,74 +55,78 @@ getbynumber(be, a) nisplus_backend_ptr_t be; void *a; { - nss_XbyY_args_t *argp = (nss_XbyY_args_t *) a; + nss_XbyY_args_t *argp = (nss_XbyY_args_t *)a; char numstr[12]; - sprintf(numstr, "%d", argp->key.number); + (void) snprintf(numstr, 12, "%d", argp->key.number); return (_nss_nisplus_lookup(be, argp, RPC_TAG_NUMBER, numstr)); } /* - * place the results from the nis_object structure into argp->buf.result + * Convert nisplus object into files format * Returns NSS_STR_PARSE_{SUCCESS, ERANGE, PARSE} */ static int -nis_object2ent(nobj, obj, argp) - int nobj; - nis_object *obj; - nss_XbyY_args_t *argp; +nis_object2str(nobj, obj, be, argp) + int nobj; + nis_object *obj; + nisplus_backend_ptr_t be; + nss_XbyY_args_t *argp; { - char *buffer, *limit, *val; - int buflen = argp->buf.buflen; - struct rpcent *rpc; - int len, ret; - struct entry_col *ecol; - - limit = argp->buf.buffer + buflen; - rpc = (struct rpcent *)argp->buf.result; - buffer = argp->buf.buffer; - - /* - * <-----buffer + buflen --------------> - * |-----------------|----------------| - * | pointers vector | aliases grow | - * | for aliases | | - * | this way -> | <- this way | - * |-----------------|----------------| - * - * - * ASSUME: name, aliases and number columns in NIS+ tables ARE - * null terminated. - * - * get cname and aliases - */ - - rpc->r_aliases = (char **) ROUND_UP(buffer, (sizeof (char **))); - if ((char *)rpc->r_aliases >= limit) { - return (NSS_STR_PARSE_ERANGE); + char *buffer, *linep, *limit; + char *cname, *number, *endnum; + int buflen, cnamelen, numberlen; + int stat; + struct entry_col *ecol; + + if (obj->zo_data.zo_type != NIS_ENTRY_OBJ || + obj->EN_data.en_cols.en_cols_len < RPC_COL) { + /* namespace/table/object is curdled */ + return (NSS_STR_PARSE_PARSE); } + ecol = obj->EN_data.en_cols.en_cols_val; - rpc->r_name = NULL; + buflen = argp->buf.buflen; + buffer = argp->buf.buffer; + (void) memset(buffer, 0, buflen); - /* - * Assume that CNAME is the first column and NAME the second. - */ - ret = netdb_aliases_from_nisobj(obj, nobj, NULL, - rpc->r_aliases, &limit, &(rpc->r_name), &len); - if (ret != NSS_STR_PARSE_SUCCESS) - return (ret); + /* cname */ + __NISPLUS_GETCOL_OR_RETURN(ecol, RPC_NDX_CNAME, + cnamelen, cname); - /* - * get program number from the first object - * - */ - ecol = obj->EN_data.en_cols.en_cols_val; - EC_SET(ecol, RPC_NDX_NUMBER, len, val); - if (len <= 0) + /* number */ + __NISPLUS_GETCOL_OR_RETURN(ecol, RPC_NDX_NUMBER, + numberlen, number); + (void) strtol(number, &endnum, 10); + if (*endnum != 0 || endnum == number) return (NSS_STR_PARSE_PARSE); - rpc->r_number = atoi(val); + if (cnamelen + numberlen + 2 > buflen) + return (NSS_STR_PARSE_ERANGE); + (void) snprintf(buffer, buflen, "%s %s", cname, number); + + linep = buffer + cnamelen + numberlen + 1; + limit = buffer + buflen; + + stat = nis_aliases_object2str(obj, nobj, cname, NULL, linep, limit); + if (stat != NSS_STR_PARSE_SUCCESS) + return (stat); + + if (argp->buf.result != NULL) { + /* + * Some front end marshallers may require the + * files formatted data in a distinct buffer + */ + if ((be->buffer = strdup(buffer)) == NULL) + return (NSS_STR_PARSE_PARSE); + be->buflen = strlen(buffer); + buffer = be->buffer; + } +#ifdef DEBUG + (void) fprintf(stdout, "rpc [%s]\n", buffer); + (void) fflush(stdout); +#endif /* DEBUG */ return (NSS_STR_PARSE_SUCCESS); } @@ -143,5 +146,5 @@ _nss_nisplus_rpc_constr(dummy1, dummy2, dummy3) { return (_nss_nisplus_constr(rpc_ops, sizeof (rpc_ops) / sizeof (rpc_ops[0]), - RPC_TBLNAME, nis_object2ent)); + RPC_TBLNAME, nis_object2str)); } diff --git a/usr/src/lib/nsswitch/nisplus/common/getservent.c b/usr/src/lib/nsswitch/nisplus/common/getservent.c index fc932dfdb6..b3138f8c1a 100644 --- a/usr/src/lib/nsswitch/nisplus/common/getservent.c +++ b/usr/src/lib/nsswitch/nisplus/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,11 +19,11 @@ * CDDL HEADER END */ /* - * getservent.c - * - * Copyright (c) 1988-1992 Sun Microsystems Inc - * All Rights Reserved. - * + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +/* * nisplus/getservent.c -- NIS+ backend for nsswitch "serv" database */ @@ -41,13 +40,13 @@ getbyname(be, a) nisplus_backend_ptr_t be; void *a; { - nss_XbyY_args_t *argp = (nss_XbyY_args_t *) a; + nss_XbyY_args_t *argp = (nss_XbyY_args_t *)a; /* * Don't have to do anything for case-insensitivity; the NIS+ table * has the right flags enabled in the 'cname' and 'name' columns. * - * Make sure that nis_object2ent would cull out only those entries + * Make sure that nis_object2str would cull out only those entries * with the given protocol if it is non-NULL, or the first one it * finds in the nis_object if user supplied proto is NULL. */ @@ -60,124 +59,109 @@ getbyport(be, a) nisplus_backend_ptr_t be; void *a; { - nss_XbyY_args_t *argp = (nss_XbyY_args_t *) a; + nss_XbyY_args_t *argp = (nss_XbyY_args_t *)a; char portstr[12]; /* - * Make sure that nis_object2ent would cull out only those entries + * Make sure that nis_object2str would cull out only those entries * with the given protocol if it is non-NULL, or the first one it * finds in the nis_object if user supplied proto is NULL. */ - sprintf(portstr, "%d", ntohs((u_short)argp->key.serv.serv.port)); + (void) snprintf(portstr, 12, "%d", + ntohs((ushort_t)argp->key.serv.serv.port)); return (_nss_nisplus_lookup(be, argp, SERV_TAG_PORT, portstr)); } /* - * place the results from the nis_object structure into argp->buf.result + * Convert nisplus object into files format * Returns NSS_STR_PARSE_{SUCCESS, ERANGE, PARSE} */ static int -nis_object2ent(nobj, obj, argp) - int nobj; - nis_object *obj; - nss_XbyY_args_t *argp; +nis_object2str(nobj, obj, be, argp) + int nobj; + nis_object *obj; + nisplus_backend_ptr_t be; + nss_XbyY_args_t *argp; { - char *buffer, *limit, *val; - int buflen = argp->buf.buflen; - struct servent *serv; - int len, ret; - struct entry_col *ecol; - const char *proto = argp->key.serv.proto; - int i; - - limit = argp->buf.buffer + buflen; - serv = (struct servent *)argp->buf.result; - buffer = argp->buf.buffer; + char *buffer, *linep, *limit; + char *cname, *port, *proto, *endnum; + int buflen, cnamelen, portlen, protolen; + const char *protokey; + int protokeylen, stat; + struct entry_col *ecol; - /* - * If the caller does not care about a specific protocol - * (udp or tcp usually), pick the one from the first nis_object - * and parse all the entries associated with only this protocol. - * NULL proto is also specified by getservent() functions. We - * end up doing extraneous work in the case. - */ - if (proto == NULL) { + protokey = argp->key.serv.proto; + protokeylen = (protokey) ? strlen(protokey) : 0; + for (; nobj > 0; obj++, nobj--) { if (obj->zo_data.zo_type != NIS_ENTRY_OBJ || obj->EN_data.en_cols.en_cols_len < SERV_COL) { + /* namespace/table/object is curdled */ return (NSS_STR_PARSE_PARSE); } ecol = obj->EN_data.en_cols.en_cols_val; - EC_SET(ecol, SERV_NDX_PROTO, len, proto); - if (len < 2) - return (NSS_STR_PARSE_PARSE); - } else { - len = strlen(proto) + 1; - } - /* - * Return (a copy of) proto in serv->s_proto - */ - if (buffer + len > limit) { - return (NSS_STR_PARSE_ERANGE); + + /* protocol */ + __NISPLUS_GETCOL_OR_RETURN(ecol, SERV_NDX_PROTO, + protolen, proto); + if (protokey != NULL) { + if (protolen != protokeylen || + strncasecmp(proto, protokey, protolen) != 0) + continue; + } + + /* + * If the caller does not care about a specific protocol + * (udp or tcp usually), pick the one from the first nis_object + * and parse all the entries associated with only this protocol. + * NULL proto is also specified by getservent() functions. We + * end up doing extraneous work in the case. + */ + break; } - memcpy(buffer, proto, len); - serv->s_proto = buffer; - buffer += len; - buflen -= len; - /* - * <-----buffer + buflen --------------> - * |-----------------|----------------| - * | pointers vector | aliases grow | - * | for aliases | | - * | this way -> | <- this way | - * |-----------------|----------------| - * - * - * ASSUME: name, aliases, proto and port columns in NIS+ tables ARE - * null terminated. - * - * get cname and aliases - */ + if (nobj <= 0) + return (NSS_STR_PARSE_PARSE); + + buflen = argp->buf.buflen; + buffer = argp->buf.buffer; + (void) memset(buffer, 0, buflen); + + /* cname */ + __NISPLUS_GETCOL_OR_RETURN(ecol, SERV_NDX_CNAME, cnamelen, cname); - serv->s_aliases = (char **) ROUND_UP(buffer, sizeof (char **)); - if ((char *)serv->s_aliases >= limit) { + /* port */ + __NISPLUS_GETCOL_OR_RETURN(ecol, SERV_NDX_PORT, portlen, port); + (void) strtol(port, &endnum, 10); + if (*endnum != 0 || endnum == port) + return (NSS_STR_PARSE_PARSE); + + if (cnamelen + portlen + protolen + 3 > buflen) return (NSS_STR_PARSE_ERANGE); - } + (void) snprintf(buffer, buflen, "%s %s/%s", cname, port, proto); - serv->s_name = NULL; + linep = buffer + cnamelen + portlen + protolen + 2; + limit = buffer + buflen; - /* - * Assume that CNAME is the first column and NAME the second. - */ - ret = netdb_aliases_from_nisobj(obj, nobj, proto, - serv->s_aliases, &limit, &(serv->s_name), &len); - if (ret != NSS_STR_PARSE_SUCCESS) - return (ret); + stat = nis_aliases_object2str(obj, nobj, cname, proto, linep, limit); + if (stat != NSS_STR_PARSE_SUCCESS) + return (stat); - /* - * Read port from the first object having the desired protocol. - * There is guaranteed to be at least one such object, or - * netdb_aliases_from_nisobj() wouldn't have returned SUCCESS. - */ - for (i = 0; i < nobj; i++) { - ecol = obj[i].EN_data.en_cols.en_cols_val; - EC_SET(ecol, SERV_NDX_PROTO, len, val); - if (len < 2) + if (argp->buf.result != NULL) { + /* + * Some front end marshallers may require the + * files formatted data in a distinct buffer + */ + if ((be->buffer = strdup(buffer)) == NULL) return (NSS_STR_PARSE_PARSE); - if (strcmp(proto, val) == 0) - break; + be->buflen = strlen(buffer); + buffer = be->buffer; } - if (i == nobj) { /* none found... can't happen, but what the heck */ - return (NSS_STR_PARSE_PARSE); - } - EC_SET(ecol, SERV_NDX_PORT, len, val); - if (len < 2) { - return (NSS_STR_PARSE_PARSE); - } - serv->s_port = htons((u_short)atoi(val)); - +#ifdef DEBUG + (void) fprintf(stdout, "services [%s]\n", buffer); + (void) fflush(stdout); +#endif /* DEBUG */ return (NSS_STR_PARSE_SUCCESS); } @@ -197,5 +181,5 @@ _nss_nisplus_services_constr(dummy1, dummy2, dummy3) { return (_nss_nisplus_constr(serv_ops, sizeof (serv_ops) / sizeof (serv_ops[0]), - SERV_TBLNAME, nis_object2ent)); + SERV_TBLNAME, nis_object2str)); } diff --git a/usr/src/lib/nsswitch/nisplus/common/getspent.c b/usr/src/lib/nsswitch/nisplus/common/getspent.c index 028a37ad98..dd246e3b76 100644 --- a/usr/src/lib/nsswitch/nisplus/common/getspent.c +++ b/usr/src/lib/nsswitch/nisplus/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,9 +19,11 @@ * CDDL HEADER END */ /* - * Copyright (c) 1988-1995 Sun Microsystems Inc - * All Rights Reserved. - * + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +/* * nisplus/getspent.c: implementations of getspnam(), getspent(), setspent(), * endspent() for NIS+. We keep the shadow information in a column * ("shadow") of the same table that stores vanilla passwd information. @@ -62,8 +63,8 @@ getbynam(be, a) nisplus_backend_ptr_t be; void *a; { - nss_XbyY_args_t *argp = (nss_XbyY_args_t *) a; - struct spwd *sp = (struct spwd *) argp->buf.result; + nss_XbyY_args_t *argp = (nss_XbyY_args_t *)a; + struct spwd *sp = (struct spwd *)argp->buf.result; int buflen = argp->buf.buflen; nss_status_t status; const char *username; @@ -76,12 +77,17 @@ getbynam(be, a) _mutex_lock(&one_lane); /* - * There is a dirty little private protocol with the nis_object2ent() + * There is a dirty little private protocol with the nis_object2str() * routine below: it gives us back a uid in the argp->key.uid * field. Since "key" is a union, and we're using key.name, * we save/restore it in case anyone cares. + * + * NSS2: be->flag is used to indicate *NP* case since we + * may not have the shadow passwd available at this point + * if called by nscd's switch. */ username = argp->key.name; + be->flag = 0; status = _nss_nisplus_lookup(be, argp, PW_TAG_NAME, username); @@ -95,13 +101,13 @@ getbynam(be, a) /* fix for bugid 4301477 DELETED if (_thr_main() != -1) goto out; */ - if (!(status == NSS_SUCCESS && argp->returnval != 0 && - sp->sp_pwdp != 0 && strcmp(sp->sp_pwdp, "*NP*") == 0)) + if (status != NSS_SUCCESS || argp->returnval == 0 || be->flag == 0) goto out; /* Get our current euid and that of the entry */ orig_uid = geteuid(); entry_uid = argp->key.uid; + be->flag = 0; /* * If the entry uid differs from our own euid, set our euid to @@ -116,10 +122,10 @@ getbynam(be, a) * results. */ if (key_secretkey_is_set_g(0, 0) && - ((save_buf = (char *) malloc(buflen)) != 0)) { + ((save_buf = (char *)malloc(buflen)) != 0)) { /* Save the old results in case the new lookup fails */ - memcpy(save_buf, argp->buf.buffer, buflen); + (void) memcpy(save_buf, argp->buf.buffer, buflen); save_sp = *sp; /* Do the lookup (this time as the user). */ @@ -128,7 +134,8 @@ getbynam(be, a) /* If it failed, restore the old results */ if (status != NSS_SUCCESS) { - memcpy(argp->buf.buffer, save_buf, buflen); + (void) memcpy(argp->buf.buffer, save_buf, + buflen); *sp = save_sp; status = NSS_SUCCESS; } @@ -137,7 +144,7 @@ getbynam(be, a) } /* Set uid back */ - seteuid(orig_uid); + (void) seteuid(orig_uid); } out: @@ -154,24 +161,17 @@ out: */ /*ARGSUSED*/ static int -nis_object2ent(nobj, obj, argp) - int nobj; - nis_object *obj; - nss_XbyY_args_t *argp; +nis_object2str(nobj, obj, be, argp) + int nobj; + nis_object *obj; + nisplus_backend_ptr_t be; + nss_XbyY_args_t *argp; { - struct spwd *sp = (struct spwd *) argp->buf.result; - char *buffer = argp->buf.buffer; - int buflen = argp->buf.buflen; - char *limit = buffer + buflen; - - struct entry_col *ecol; - char *val; - int len; - - char *endnum; - uid_t uid; - char *p; - long x; + char *buffer, *name, *passwd, *shadow; + int buflen, namelen, passwdlen, shadowlen; + char *endnum, *uidstr; + int uidlen; + struct entry_col *ecol; /* * If we got more than one nis_object, we just ignore it. @@ -188,47 +188,16 @@ nis_object2ent(nobj, obj, argp) } ecol = obj->EN_data.en_cols.en_cols_val; - /* - * sp_namp: user name - */ - EC_SET(ecol, PW_NDX_NAME, len, val); - if (len < 2) - return (NSS_STR_PARSE_PARSE); - sp->sp_namp = buffer; - buffer += len; - if (buffer >= limit) - return (NSS_STR_PARSE_ERANGE); - strcpy(sp->sp_namp, val); + /* name: user name */ + __NISPLUS_GETCOL_OR_RETURN(ecol, PW_NDX_NAME, namelen, name); - /* - * sp_pwdp: password - */ - EC_SET(ecol, PW_NDX_PASSWD, len, val); - if (len < 2) { - /* - * don't return NULL pointer, lot of stupid programs - * out there. - */ - *buffer = '\0'; - sp->sp_pwdp = buffer++; - if (buffer >= limit) - return (NSS_STR_PARSE_ERANGE); - } else { - sp->sp_pwdp = buffer; - buffer += len; - if (buffer >= limit) - return (NSS_STR_PARSE_ERANGE); - strcpy(sp->sp_pwdp, val); - } + /* passwd */ + __NISPLUS_GETCOL_OR_EMPTY(ecol, PW_NDX_PASSWD, passwdlen, passwd); - /* - * get uid - */ - EC_SET(ecol, PW_NDX_UID, len, val); - if (len < 2) - return (NSS_STR_PARSE_PARSE); - uid = strtol(val, &endnum, 10); - if (*endnum != 0) + /* uid */ + __NISPLUS_GETCOL_OR_RETURN(ecol, PW_NDX_UID, uidlen, uidstr); + (void) strtol(uidstr, &endnum, 10); + if (*endnum != 0 || endnum == uidstr) return (NSS_STR_PARSE_PARSE); /* * See discussion of private protocol in getbynam() above. @@ -236,18 +205,8 @@ nis_object2ent(nobj, obj, argp) * _nss_nisplus_getent(), but that's OK -- when we're doing * enumerations we don't care what's in the argp->key union. */ - argp->key.uid = uid; - - /* - * Default values - */ - sp->sp_lstchg = -1; - sp->sp_min = -1; - sp->sp_max = -1; - sp->sp_warn = -1; - sp->sp_inact = -1; - sp->sp_expire = -1; - sp->sp_flag = 0; + if (strncmp(passwd, "*NP*", passwdlen) == 0) + be->flag = 1; /* * shadow information @@ -256,67 +215,28 @@ nis_object2ent(nobj, obj, argp) * with less than the desired number of ":" separated longs. * XXX - should we be more strict ? */ - EC_SET(ecol, PW_NDX_SHADOW, len, val); - - if (len < 2) - return (NSS_STR_PARSE_SUCCESS); - - /* - * Parse val for the aging fields (quickly, they might die) - */ - - limit = val + len; - p = val; - - x = strtol(p, &endnum, 10); - if (*endnum != ':' || endnum >= limit) - return (NSS_STR_PARSE_SUCCESS); - if (endnum != p) - sp->sp_lstchg = (int) x; - p = endnum + 1; - - x = strtol(p, &endnum, 10); - if (*endnum != ':' || endnum >= limit) - return (NSS_STR_PARSE_SUCCESS); - if (endnum != p) - sp->sp_min = (int) x; - p = endnum + 1; - - x = strtol(p, &endnum, 10); - if (*endnum != ':' || endnum >= limit) - return (NSS_STR_PARSE_SUCCESS); - if (endnum != p) - sp->sp_max = (int) x; - p = endnum + 1; - - x = strtol(p, &endnum, 10); - if (*endnum != ':' || endnum >= limit) - return (NSS_STR_PARSE_SUCCESS); - if (endnum != p) - sp->sp_warn = (int) x; - p = endnum + 1; - - x = strtol(p, &endnum, 10); - if (*endnum != ':' || endnum >= limit) - return (NSS_STR_PARSE_SUCCESS); - if (endnum != p) { - sp->sp_inact = (int) x; + __NISPLUS_GETCOL_OR_EMPTY(ecol, PW_NDX_SHADOW, shadowlen, shadow); + + buflen = namelen + passwdlen + shadowlen + 3; + if (argp->buf.result != NULL) { + if ((be->buffer = calloc(1, buflen)) == NULL) + return (NSS_STR_PARSE_PARSE); + /* exclude trailing null from length */ + be->buflen = buflen - 1; + buffer = be->buffer; + } else { + if (buflen > argp->buf.buflen) + return (NSS_STR_PARSE_ERANGE); + buflen = argp->buf.buflen; + buffer = argp->buf.buffer; + (void) memset(buffer, 0, buflen); } - p = endnum + 1; - - x = strtol(p, &endnum, 10); - if (*endnum != ':' || endnum >= limit) - return (NSS_STR_PARSE_SUCCESS); - if (endnum != p) - sp->sp_expire = (int) x; - p = endnum + 1; - - x = strtol(p, &endnum, 10); - if (*endnum != '\0' && *endnum != ':') - return (NSS_STR_PARSE_SUCCESS); - if (endnum != p) - sp->sp_flag = (int) x; - + (void) snprintf(buffer, buflen, "%s:%s:%s", + name, passwd, shadow); +#ifdef DEBUG + (void) fprintf(stdout, "shadow [%s]\n", buffer); + (void) fflush(stdout); +#endif /* DEBUG */ return (NSS_STR_PARSE_SUCCESS); } @@ -335,5 +255,5 @@ _nss_nisplus_shadow_constr(dummy1, dummy2, dummy3) { return (_nss_nisplus_constr(sp_ops, sizeof (sp_ops) / sizeof (sp_ops[0]), - PW_TBLNAME, nis_object2ent)); + PW_TBLNAME, nis_object2str)); } diff --git a/usr/src/lib/nsswitch/nisplus/common/getuserattr.c b/usr/src/lib/nsswitch/nisplus/common/getuserattr.c index 70b8a05e76..c6337373c7 100644 --- a/usr/src/lib/nsswitch/nisplus/common/getuserattr.c +++ b/usr/src/lib/nsswitch/nisplus/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,8 +19,8 @@ * CDDL HEADER END */ /* - * Copyright (c) 1999 by 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" @@ -45,23 +44,20 @@ getbynam(nisplus_backend_ptr_t be, void *a) /* - * place the results from the nis_object structure into argp->buf.result * Returns NSS_STR_PARSE_{SUCCESS, ERANGE, PARSE} */ +/*ARGSUSED*/ static int -nis_object2userstr(int nobj, nis_object *obj, nss_XbyY_args_t *argp) +nis_object2userstr(int nobj, nis_object *obj, + nisplus_backend_ptr_t be, + nss_XbyY_args_t *argp) { - int len; - int buflen = argp->buf.buflen; - char *buffer, *limit, *val, *endnum, *nullstring; - char *empty = ""; - userstr_t *user; + char *buffer, *name, *qual, *res1, *res2; + char *attr; + int buflen, namelen, quallen, res1len; + int res2len, attrlen; struct entry_col *ecol; - limit = argp->buf.buffer + buflen; - user = (userstr_t *)argp->buf.result; - buffer = argp->buf.buffer; - /* * If we got more than one nis_object, we just ignore object(s) * except the first. Although it should never have happened. @@ -77,81 +73,42 @@ nis_object2userstr(int nobj, nis_object *obj, nss_XbyY_args_t *argp) } ecol = obj->EN_data.en_cols.en_cols_val; - /* - * userstr->name: user name - */ - EC_SET(ecol, USERATTR_NDX_NAME, len, val); - if (len < 1 || (*val == '\0')) { - val = empty; - } - user->name = buffer; - buffer += len; - if (buffer >= limit) { - return (NSS_STR_PARSE_ERANGE); - } - strcpy(user->name, val); - nullstring = (buffer - 1); - - /* - * userstr->qualifier: reserved for future use - */ - EC_SET(ecol, USERATTR_NDX_QUALIFIER, len, val); - if (len < 1 || (*val == '\0')) { - val = empty; - } - user->qualifier = buffer; - buffer += len; - if (buffer >= limit) { - return (NSS_STR_PARSE_ERANGE); - } - strcpy(user->qualifier, val); - nullstring = (buffer - 1); - - /* - * userstr->res1: reserved field 1 - */ - EC_SET(ecol, USERATTR_NDX_RES1, len, val); - if (len < 1 || (*val == '\0')) { - val = empty; + /* user name */ + __NISPLUS_GETCOL_OR_RETURN(ecol, USERATTR_NDX_NAME, namelen, name); + + /* qualifier: reserved for future use */ + __NISPLUS_GETCOL_OR_EMPTY(ecol, USERATTR_NDX_QUALIFIER, + quallen, qual); + + /* res1: reserved field 1 */ + __NISPLUS_GETCOL_OR_EMPTY(ecol, USERATTR_NDX_RES1, res1len, res1); + + /* userstr->res2: reserved field 2 */ + __NISPLUS_GETCOL_OR_EMPTY(ecol, USERATTR_NDX_RES2, res2len, res2); + + /* attrs: key-value pairs of attributes */ + __NISPLUS_GETCOL_OR_EMPTY(ecol, USERATTR_NDX_ATTR, attrlen, attr); + + buflen = namelen + quallen + res1len + res2len + attrlen + 5; + if (argp->buf.result != NULL) { + if ((be->buffer = calloc(1, buflen)) == NULL) + return (NSS_STR_PARSE_PARSE); + /* exclude trailing null from length */ + be->buflen = buflen - 1; + buffer = be->buffer; + } else { + if (buflen > argp->buf.buflen) + return (NSS_STR_PARSE_ERANGE); + buflen = argp->buf.buflen; + buffer = argp->buf.buffer; + (void) memset(buffer, 0, buflen); } - user->res1 = buffer; - buffer += len; - if (buffer >= limit) { - return (NSS_STR_PARSE_ERANGE); - } - strcpy(user->res1, val); - nullstring = (buffer - 1); - - /* - * userstr->res2: reserved field 2 - */ - EC_SET(ecol, USERATTR_NDX_RES2, len, val); - if (len < 1 || (*val == '\0')) { - val = empty; - } - user->res2 = buffer; - buffer += len; - if (buffer >= limit) { - return (NSS_STR_PARSE_ERANGE); - } - strcpy(user->res2, val); - nullstring = (buffer - 1); - - /* - * userstr->attrs: key-value pairs of attributes - */ - EC_SET(ecol, USERATTR_NDX_ATTR, len, val); - if (len < 1 || (*val == '\0')) { - val = empty; - } - user->attr = buffer; - buffer += len; - if (buffer >= limit) { - return (NSS_STR_PARSE_ERANGE); - } - strcpy(user->attr, val); - nullstring = (buffer - 1); - + (void) snprintf(buffer, buflen, "%s:%s:%s:%s:%s", + name, qual, res1, res2, attr); +#ifdef DEBUG + (void) fprintf(stdout, "userattr [%s]\n", buffer); + (void) fflush(stdout); +#endif /* DEBUG */ return (NSS_STR_PARSE_SUCCESS); } @@ -163,6 +120,7 @@ static nisplus_backend_op_t userattr_ops[] = { getbynam }; +/*ARGSUSED*/ nss_backend_t * _nss_nisplus_user_attr_constr(const char *dummy1, const char *dummy2, diff --git a/usr/src/lib/nsswitch/nisplus/common/netmasks.c b/usr/src/lib/nsswitch/nisplus/common/netmasks.c index 8e6ae5000c..308033514e 100644 --- a/usr/src/lib/nsswitch/nisplus/common/netmasks.c +++ b/usr/src/lib/nsswitch/nisplus/common/netmasks.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,10 +19,12 @@ * CDDL HEADER END */ /* + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +/* * nisplus/netmasks.c -- "nisplus" backend for nsswitch "netmasks" database - * - * Copyright (c) 1996 Sun Microsystems Inc - * All Rights Reserved. */ #pragma ident "%Z%%M% %I% %E% SMI" @@ -35,6 +36,8 @@ * dotted internet notation. */ +#include <stdlib.h> +#include <strings.h> #include <sys/types.h> #include <sys/socket.h> #include <net/if.h> @@ -49,29 +52,27 @@ getbynet(be, a) nisplus_backend_ptr_t be; void *a; { - nss_XbyY_args_t *argp = (nss_XbyY_args_t *) a; + nss_XbyY_args_t *argp = (nss_XbyY_args_t *)a; return (_nss_nisplus_lookup(be, argp, NETMASK_TAG_ADDR, argp->key.name)); } /* - * Place the resulting struct inaddr from the nis_object structure into - * argp->buf.result only if argp->buf.result is initialized (not NULL). - * + * Convert nisplus object to files format * Returns NSS_STR_PARSE_{SUCCESS, ERANGE, PARSE} */ /*ARGSUSED*/ static int -nis_object2ent(nobj, obj, argp) - int nobj; - nis_object *obj; - nss_XbyY_args_t *argp; +nis_object2str(nobj, obj, be, argp) + int nobj; + nis_object *obj; + nisplus_backend_ptr_t be; + nss_XbyY_args_t *argp; { - struct in_addr *mask = (struct in_addr *)argp->buf.result; - char *val; - struct in_addr addr; - struct entry_col *ecol; - int len; + char *mask; + int masklen; + struct in_addr addr; + struct entry_col *ecol; /* * If we got more than one nis_object, we just ignore it. @@ -89,17 +90,22 @@ nis_object2ent(nobj, obj, argp) ecol = obj->EN_data.en_cols.en_cols_val; /* getnetmaskbynet */ - if (mask) { - EC_SET(ecol, NETMASK_NDX_MASK, len, val); - if (len < 2) - return (NSS_STR_PARSE_PARSE); - /* addr is an IPv4 address, therefore will always be 32bits */ - addr.s_addr = inet_addr(val); - if (addr.s_addr == 0xffffffffL) - return (NSS_STR_PARSE_PARSE); - mask->s_addr = addr.s_addr; - } + __NISPLUS_GETCOL_OR_RETURN(ecol, NETMASK_NDX_MASK, masklen, mask); + /* addr is an IPv4 address, therefore will always be 32bits */ + addr.s_addr = inet_addr(mask); + if (addr.s_addr == INADDR_NONE) + return (NSS_STR_PARSE_PARSE); + + /* exclude trailing null from length */ + be->buflen = masklen; + if ((be->buffer = calloc(1, be->buflen + 1)) == NULL) + return (NSS_STR_PARSE_PARSE); + (void) strlcpy(be->buffer, mask, be->buflen + 1); +#ifdef DEBUG + (void) fprintf(stdout, "netmasks [%s]\n", be->buffer); + (void) fflush(stdout); +#endif /* DEBUG */ return (NSS_STR_PARSE_SUCCESS); } @@ -115,5 +121,5 @@ _nss_nisplus_netmasks_constr(dummy1, dummy2, dummy3) { return (_nss_nisplus_constr(netmasks_ops, sizeof (netmasks_ops) / sizeof (netmasks_ops[0]), NETMASK_TBLNAME, - nis_object2ent)); + nis_object2str)); } diff --git a/usr/src/lib/nsswitch/nisplus/common/nisplus_common.c b/usr/src/lib/nsswitch/nisplus/common/nisplus_common.c index 51ad628f68..eec3fa9ada 100644 --- a/usr/src/lib/nsswitch/nisplus/common/nisplus_common.c +++ b/usr/src/lib/nsswitch/nisplus/common/nisplus_common.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,8 +19,8 @@ * CDDL HEADER END */ /* - * Copyright (c) 1991-1999 by Sun Microsystems, Inc. - * All rights reserved. + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. */ /* @@ -35,6 +34,7 @@ #include "nisplus_common.h" #include "nisplus_tables.h" #include <string.h> +#include <strings.h> #include <stdlib.h> #include <arpa/inet.h> #include <rpcsvc/nislib.h> @@ -43,7 +43,7 @@ #define ORGDIR2 ".org_dir." #define ORGDIRLEN 7 -extern u_int __nis_force_hard_lookups; +extern uint_t __nis_force_hard_lookups; extern int inet_pton(int, const char *, void *); static nss_status_t @@ -58,11 +58,13 @@ switch_err(nis_res) case NIS_SUCCESS: case NIS_S_SUCCESS: case NIS_CBRESULTS: + errno = 0; return (NSS_SUCCESS); case NIS_NOTFOUND: case NIS_PARTIAL: case NIS_NOSUCHNAME: + errno = 0; return (NSS_NOTFOUND); case NIS_NAMEUNREACHABLE: @@ -82,18 +84,21 @@ _nss_nisplus_list(name, extra_flags, res_p) nis_result **res_p; { *res_p = nis_list((char *)name, NIS_LIST_COMMON | extra_flags | - __nis_force_hard_lookups, 0, 0); + __nis_force_hard_lookups, 0, 0); return (switch_err(*res_p)); } -nss_status_t +static nss_status_t process_val(args, be, result) - nss_XbyY_args_t *args; + nss_XbyY_args_t *args; nisplus_backend_t *be; - nis_result *result; + nis_result *result; { nss_status_t res; - int parsestat; + int parsestat; + + args->returnval = NULL; + args->returnlen = 0; if ((res = switch_err(result)) != NSS_SUCCESS) { return (res); @@ -101,21 +106,71 @@ process_val(args, be, result) if (NIS_RES_OBJECT(result) == 0) { return (NSS_NOTFOUND); } - parsestat = (be->obj2ent)(NIS_RES_NUMOBJ(result), - NIS_RES_OBJECT(result), args); + parsestat = (be->obj2str)(NIS_RES_NUMOBJ(result), + NIS_RES_OBJECT(result), be, args); + if (parsestat != NSS_STR_PARSE_SUCCESS) + goto fail; + + /* + * If called by nscd's switch engine, the data + * is available in args->buf.buffer and there is + * no need to marshall it. + * + * Note for some dbs like ethers, the obj2str() + * routine will always put the NFF data in + * be->buffer because we cannot determine if + * we are inside nscd or inside the application. + */ + if (args->buf.result == NULL && be->buffer == NULL) { + args->returnval = args->buf.buffer; + if (args->buf.buffer != NULL) + args->returnlen = strlen(args->buf.buffer); + return (NSS_SUCCESS); + } + + /* + * If the data is in be->buffer it needs + * to be marshalled. + */ + if (args->str2ent == NULL) { + parsestat = NSS_STR_PARSE_PARSE; + goto fail; + } + parsestat = (*args->str2ent)(be->buffer, + be->buflen, + args->buf.result, + args->buf.buffer, + args->buf.buflen); if (parsestat == NSS_STR_PARSE_SUCCESS) { + if (be->buffer != NULL) { + free(be->buffer); + be->buffer = NULL; + be->buflen = 0; + } args->returnval = args->buf.result; - res = NSS_SUCCESS; - } else if (parsestat == NSS_STR_PARSE_ERANGE) { - args->returnval = 0; + if (args->buf.result != NULL) + args->returnlen = 1; + else if (args->buf.buffer != NULL) { + args->returnval = args->buf.buffer; + args->returnlen = strlen(args->buf.buffer); + } + return (NSS_SUCCESS); + } + +fail: + if (be->buffer != NULL) { + free(be->buffer); + be->buffer = NULL; + be->buflen = 0; + } + if (parsestat == NSS_STR_PARSE_ERANGE) { args->erange = 1; /* We won't find this otherwise, anyway */ - res = NSS_NOTFOUND; + return (NSS_NOTFOUND); } else if (parsestat == NSS_STR_PARSE_PARSE) { - args->returnval = 0; - res = NSS_NOTFOUND; + return (NSS_NOTFOUND); } - return (res); + return (NSS_UNAVAIL); } nss_status_t @@ -141,7 +196,7 @@ _nss_nisplus_lookup(be, argp, column_name, keyname) /* * Assumes that "keyname" is a null-terminated string. */ - sprintf(namebuf, "[%s=%s]%s", column_name, keyname, + (void) snprintf(namebuf, BUFSIZ, "[%s=%s]%s", column_name, keyname, be->table_name); r = nis_list(namebuf, NIS_LIST_COMMON | USE_DGRAM | __nis_force_hard_lookups, 0, 0); @@ -194,23 +249,23 @@ _nss_nisplus_expand_lookup(be, argp, column_name, keyname, table) (directory[0] == '.' && directory[1] == '\0')) { return (0); } - sprintf(namebuf, "[%s=", column_name); + (void) snprintf(namebuf, sizeof (namebuf), "[%s=", column_name); if (strcmp(column_name, HOST_TAG_NAME) == 0) { p = strchr(keyname, '.'); if (p == 0) { - strcat(namebuf, keyname); + (void) strlcat(namebuf, keyname, sizeof (namebuf)); } else { - strncat(namebuf, keyname, p - keyname); + (void) strncat(namebuf, keyname, p - keyname); } } else { - strcat(namebuf, keyname); + (void) strlcat(namebuf, keyname, sizeof (namebuf)); p = 0; } - strcat(namebuf, "]"); - strcat(namebuf, table); - strcat(namebuf, ORGDIR1); + (void) strlcat(namebuf, "]", sizeof (namebuf)); + (void) strlcat(namebuf, table, sizeof (namebuf)); + (void) strlcat(namebuf, ORGDIR1, sizeof (namebuf)); if (p != 0) { - strcat(namebuf, p); + (void) strlcat(namebuf, p, sizeof (namebuf)); } r = nis_list(namebuf, EXPAND_NAME | USE_DGRAM | NIS_LIST_COMMON | __nis_force_hard_lookups, 0, 0); @@ -222,45 +277,36 @@ _nss_nisplus_expand_lookup(be, argp, column_name, keyname, table) } nss_backend_t * -_nss_nisplus_constr(ops, n_ops, tblname, obj2ent) +_nss_nisplus_constr(ops, n_ops, tblname, obj2str) nisplus_backend_op_t ops[]; int n_ops; - const char *tblname; /* (Unqualified) name of */ - /* NIS+ table */ - nisplus_obj2ent_func obj2ent; + const char *tblname; /* (Unqualified) name of NIS+ table */ + nisplus_obj2str_func obj2str; { const char *directory = nis_local_directory(); nisplus_backend_t *be; #ifdef DEBUG -fprintf(stderr, "Constructor called\n"); + (void) fprintf(stdout, "Constructor called\n"); #endif /* DEBUG */ if (directory == 0 || (directory[0] == '.' && directory[1] == '\0') || - (be = (nisplus_backend_t *)malloc(sizeof (*be))) == 0) { - return (0); + (be = (nisplus_backend_t *)calloc(1, sizeof (*be))) == 0) { + return (0); } - be->ops = ops; - be->n_ops = n_ops; - - be->directory = directory; - if ((be->table_name = (char *)malloc - (strlen(tblname) + ORGDIRLEN + strlen(directory) + 3)) == 0) + be->ops = ops; + be->n_ops = n_ops; + be->directory = directory; + if ((be->table_name = (char *)malloc + (strlen(tblname) + ORGDIRLEN + strlen(directory) + 3)) == 0) { + free(be); return (0); - strcpy(be->table_name, tblname); - strcat(be->table_name, ORGDIR2); - strcat(be->table_name, directory); - - be->obj2ent = obj2ent; - be->cursor.no.n_bytes = 0; - be->cursor.no.n_len = 0; - be->cursor.max_len = 0; - - /* this indicates that the path_list stuff is not initialized */ - be->path_list = 0; - be->table_path = 0; - be->path_index = 0; + } + (void) strcpy(be->table_name, tblname); + (void) strcat(be->table_name, ORGDIR2); + (void) strcat(be->table_name, directory); + be->obj2str = obj2str; be->path_count = -1; return ((nss_backend_t *)be); @@ -274,10 +320,13 @@ _nss_nisplus_destr(be, dummy) { if (be != 0) { /* === Should change to invoke ops[ENDENT] ? */ - _nss_nisplus_endent(be, 0); + (void) _nss_nisplus_endent(be, 0); if (be->table_name != 0) { free(be->table_name); } + if (be->buffer != NULL) { + free(be->buffer); + } free(be); } return (NSS_SUCCESS); /* In case anyone is dumb enough to check */ @@ -310,7 +359,8 @@ nis_cursor_set_next(be, from) be->cursor.no.n_bytes = (char *)malloc(be->cursor.max_len); } - memcpy(be->cursor.no.n_bytes, from->n_bytes, from->n_len); + (void) memcpy(be->cursor.no.n_bytes, from->n_bytes, + from->n_len); } be->cursor.no.n_len = from->n_len; } @@ -367,6 +417,9 @@ _nss_nisplus_setent(be, dummy) nis_result *res; nis_object *tobj; + be->buffer = NULL; + be->buflen = 0; + be->flag = 0; if (be->path_list == 0) { res = nis_lookup(be->table_name, NIS_LIST_COMMON | __nis_force_hard_lookups); @@ -393,9 +446,9 @@ _nss_nisplus_setent(be, dummy) nis_freeresult(res); return (NSS_UNAVAIL); } - strcpy(table_name, tobj->zo_name); - strcat(table_name, "."); - strcat(table_name, tobj->zo_domain); + (void) strcpy(table_name, tobj->zo_name); + (void) strcat(table_name, "."); + (void) strcat(table_name, tobj->zo_domain); /* save table path */ table_path = res->objects.objects_val[0].TA_data.ta_path; @@ -423,7 +476,7 @@ _nss_nisplus_setent(be, dummy) be->path_list[0] = table_name; be->path_count = __nis_parse_path(be->table_path, - &be->path_list[1], n - 1); + &be->path_list[1], (int)(n - 1)); be->path_count++; /* for entry at index 0 */ } be->path_index = 0; @@ -452,232 +505,73 @@ _nss_nisplus_endent(be, dummy) free(be->path_list[0]); free(be->path_list); } + if (be->buffer != NULL) { + free(be->buffer); + be->buffer = NULL; + be->buflen = 0; + } + be->flag = 0; be->table_path = 0; be->path_list = 0; be->path_index = 0; be->path_count = -1; - be->cursor.no.n_len = 0; - be->cursor.max_len = 0; + be->cursor.no.n_len = 0; + be->cursor.max_len = 0; return (NSS_SUCCESS); } - -/* - * returns NSS_STR_PARSE_PARSE if no aliases found. - * - * Overly loaded interface. Trying to do to many things using one common - * code. Main purpose is to extract cname and aliases from NIS+ entry object(s) - * for netdb databases: hosts, networks, protocols, rpc and services. - * - * hosts have always been special. We have special case code to deal with - * multiple addresses. cnamep is overloaded to indicate this special case, - * when NULL, otherwise it is set to point to the cname field in the caller's - * structure to be populated. - * - * services are weird since they sometimes use 1-1/2 keys, e.g. name and proto - * or port and proto. The NIS+ services table also has an extra column. The - * special argument, proto, when non-NULL, serves the purpose of indicating - * that we are parsing a services entry, and have specified the protocol which - * must be used for screening. It is also non-NULL, and set to the proto field - * of the first NIS+ entry by nis_obj2ent(), in case of enumeration on - * services, and getservbyname/port calls where caller used a null proto, - * which implies the caller can accept "any" protocol with the matching - * name/port. The proto argument is NULL for all non-services searches. - */ int -netdb_aliases_from_nisobj(obj, nobj, proto, alias_list, aliaspp, cnamep, count) - /* IN */ - nis_object *obj; - int nobj; - const char *proto; - /* IN-OUT */ - char **alias_list; /* beginning of the buffer and alias vector */ - char **aliaspp; /* end of the buffer + 1 */ - char **cnamep; - /* OUT */ - int *count; /* number of distinct aliases/address found */ -{ - return (__netdb_aliases_from_nisobj(obj, nobj, proto, alias_list, - aliaspp, cnamep, count, 0)); -} +nis_aliases_object2str(nis_object *obj, int nobj, + const char *cname, const char *protokey, + char *linep, char *limit) { + char *p, *name, *proto; + int cnamelen, namelen, protolen, protokeylen; + struct entry_col *ecol; -int -__netdb_aliases_from_nisobj(obj, nobj, proto, alias_list, aliaspp, cnamep, - count, af_type) - /* IN */ - nis_object *obj; - int nobj; - const char *proto; - int af_type; /* address family for host mapping only */ - /* IN-OUT */ - char **alias_list; /* beginning of the buffer and alias vector */ - char **aliaspp; /* end of the buffer + 1 */ - char **cnamep; - /* OUT */ - int *count; /* number of distinct aliases/address found */ -{ - int isaddr = (cnamep == 0); + cnamelen = strlen(cname); + protokeylen = (protokey) ? strlen(protokey) : 0; - *count = 0; - if ((char *)alias_list >= *aliaspp) { - /* - * Input condition not met. We must get a contiguous - * area (alias_list, *aliaspp - 1). - */ - return (NSS_STR_PARSE_PARSE); - } - for (/* */; nobj > 0; obj++, nobj--) { - /* - * in every iteration, pull the - * address/alias/cname, copy it, set and update - * the pointers vector if it is not a duplicate. - */ - struct entry_col *ecol; - char *val; - int len; + /* + * process remaining entries + */ + for (; nobj > 0; --nobj, obj++) { + /* object should be non-null */ + if (obj == NULL) + return (NSS_STR_PARSE_PARSE); if (obj->zo_data.zo_type != NIS_ENTRY_OBJ || - (obj->EN_data.en_cols.en_cols_len < NETDB_COL)) { + obj->EN_data.en_cols.en_cols_len < NETDB_COL) { /* namespace/table/object is curdled */ return (NSS_STR_PARSE_PARSE); } ecol = obj->EN_data.en_cols.en_cols_val; - /* - * ASSUMPTION: cname and name field in NIS+ tables are - * null terminated and the len includes the null char. - */ - if (isaddr) { - EC_SET(ecol, HOST_NDX_ADDR, len, val); - } else { + if (protokey != NULL) { + /* skip if protocols doesn't match for services */ + __NISPLUS_GETCOL_OR_RETURN(ecol, SERV_NDX_PROTO, + protolen, proto); + if (protolen != protokeylen || + strncasecmp(proto, protokey, protolen) != 0) + continue; + } - if (proto) { - /* - * indicates we screen for a desired proto - * in the case of getservbyname/port() - * with a non-null proto arg - */ - EC_SET(ecol, SERV_NDX_PROTO, len, val); - if (len < 2) - return (NSS_STR_PARSE_PARSE); - if (strcmp(proto, val) != 0) - continue; /* ignore this entry */ - } + __NISPLUS_GETCOL_OR_CONTINUE(ecol, NETDB_NDX_NAME, + namelen, name); - if (*cnamep == 0) { - /* canonical name, hasn't been set so far */ - EC_SET(ecol, NETDB_NDX_CNAME, len, val); - if (len < 2) - return (NSS_STR_PARSE_PARSE); - *aliaspp -= len; - if (*aliaspp <= - (char *)&(alias_list[*count + 1])) { - /* - * Has to be room for the pointer to - * the name we're about to add, as - * well as the final NULL ptr. - */ - return (NSS_STR_PARSE_ERANGE); - } - memcpy(*aliaspp, val, len); - *cnamep = *aliaspp; - } - EC_SET(ecol, NETDB_NDX_NAME, len, val); - } - if (len > 0) { - int i; - struct in6_addr addr6; - struct in_addr addr; - - if (isaddr) { /* special case for host addresses */ - - if (af_type == AF_INET) { - if (inet_pton(AF_INET, val, - (void *) &addr) != 1) - continue; /* skip entry */ - } else { - /* - * We now allow IPv4 and IPv6 addrs in the - * ipnodes table. If found, convert it to a - * v4 mapped IPv6 address. - */ - if (inet_pton(AF_INET6, val, - (void *) &addr6) != 1) { - if (inet_pton(AF_INET, val, - (void *) &addr) != 1) { - continue; - /* skip entry */ - } else { - IN6_INADDR_TO_V4MAPPED( - &addr, - &addr6); - } - } - } - - /* Check for duplicate address */ - for (i = 0; i < *count; i++) { - if (af_type == AF_INET) { - if (memcmp(alias_list[i], &addr, - sizeof (struct in_addr)) - == 0) { - goto next_obj; - } - } else { - if (memcmp(alias_list[i], - &addr6, - sizeof (struct in6_addr)) - == 0) { - goto next_obj; - } - } - } - /* - * Hope nobody treats an h_addr_list[i] as a - * null terminated string. We are not storing - * that here. - */ - if (af_type == AF_INET) - *aliaspp -= sizeof (struct in_addr); - else - *aliaspp -= sizeof (struct in6_addr); - } else { - /* Check for duplicate alias */ - for (i = 0; i < *count; i++) { - if (strcmp(alias_list[i], val) == 0) { - goto next_obj; - } - } - *aliaspp -= len; - } - alias_list[i] = *aliaspp; - if (*aliaspp <= (char *)&(alias_list[i + 1])) { - /* - * Has to be room for the pointer to - * the address we're about to add, as - * well as the final NULL ptr. - */ + /* + * add the "name" to the list if it doesn't + * match the "cname" + */ + if (cnamelen != namelen || + strncmp(name, cname, namelen) != 0) { + p = linep + 1 + namelen; + if (p >= limit) return (NSS_STR_PARSE_ERANGE); - } - if (isaddr) { - if (af_type == AF_INET) - memcpy(alias_list[i], (char *)&addr, - sizeof (struct in_addr)); - else - memcpy(alias_list[i], (char *)&addr6, - sizeof (struct in6_addr)); - } else { - memcpy(*aliaspp, val, len); - } - ++(*count); + (void) snprintf(linep, (size_t)(limit - linep), + " %s", name); + linep = p; } - next_obj: - ; } - alias_list[*count] = NULL; - if (*count == 0) - return (NSS_STR_PARSE_PARSE); - else - return (NSS_STR_PARSE_SUCCESS); + return (NSS_STR_PARSE_SUCCESS); } diff --git a/usr/src/lib/nsswitch/nisplus/common/nisplus_common.h b/usr/src/lib/nsswitch/nisplus/common/nisplus_common.h index 6e8bfac6ff..5c6ae11c8c 100644 --- a/usr/src/lib/nsswitch/nisplus/common/nisplus_common.h +++ b/usr/src/lib/nsswitch/nisplus/common/nisplus_common.h @@ -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. */ @@ -38,97 +37,101 @@ /* * We want these flags turned on in all nis_list() requests that we perform; - * other flags (USE_DGRAM, EXPAND_NAME) are only wanted for some requests. + * other flags (USE_DGRAM, EXPAND_NAME) are only wanted for some requests. */ #define NIS_LIST_COMMON (FOLLOW_LINKS | FOLLOW_PATH) typedef struct nisplus_backend *nisplus_backend_ptr_t; typedef nss_status_t (*nisplus_backend_op_t)(nisplus_backend_ptr_t, void *); -typedef int (*nisplus_obj2ent_func)(int nobjs, - nis_object *obj, - nss_XbyY_args_t *arg); +typedef int (*nisplus_obj2str_func)(int nobjs, nis_object *obj, + nisplus_backend_ptr_t be, + nss_XbyY_args_t *arg); struct nisplus_backend { nisplus_backend_op_t *ops; nss_dbop_t n_ops; - const char *directory; /* fully qualified directory */ - /* name */ - char *table_name; + const char *directory; /* fully qualified directory */ + /* * table_name is fully qualified (includes org_dir and * directory name) and cached here using one time malloc. */ - nisplus_obj2ent_func obj2ent; + char *table_name; + + nisplus_obj2str_func obj2str; struct { - struct netobj no; - u_int max_len; - } cursor; + struct netobj no; + uint_t max_len; + } cursor; - /* + /* * Fields for handling table paths during enumeration. * The path_list field is allocated dynamically because * it is kind of big and most applications don't do * enumeration. */ - char *table_path; - int path_index; - int path_count; - nis_name *path_list; + char *table_path; + int path_index; + int path_count; + nis_name *path_list; + + /* + * Internal fields to support NSS2 format + */ + char *buffer; + int buflen; + uint8_t flag; }; typedef struct nisplus_backend nisplus_backend_t; #if defined(__STDC__) -extern nss_backend_t *_nss_nisplus_constr (nisplus_backend_op_t *ops, - int n_ops, - const char *rdn, - nisplus_obj2ent_func func); -extern nss_status_t _nss_nisplus_destr (nisplus_backend_ptr_t, +extern nss_backend_t *_nss_nisplus_constr(nisplus_backend_op_t *ops, + int n_ops, + const char *rdn, + nisplus_obj2str_func func); +extern nss_status_t _nss_nisplus_destr(nisplus_backend_ptr_t, void *dummy); -extern nss_status_t _nss_nisplus_setent (nisplus_backend_ptr_t, +extern nss_status_t _nss_nisplus_setent(nisplus_backend_ptr_t, void *dummy); -extern nss_status_t _nss_nisplus_endent (nisplus_backend_ptr_t, +extern nss_status_t _nss_nisplus_endent(nisplus_backend_ptr_t, void *dummy); -extern nss_status_t _nss_nisplus_getent (nisplus_backend_ptr_t, - void *arg); -extern nss_status_t _nss_nisplus_lookup (nisplus_backend_ptr_t, +extern nss_status_t _nss_nisplus_getent(nisplus_backend_ptr_t, + void *arg); +extern nss_status_t _nss_nisplus_lookup(nisplus_backend_ptr_t, nss_XbyY_args_t *arg, - const char *key, - const char *val); -extern nss_status_t _nss_nisplus_expand_lookup (nisplus_backend_ptr_t, + const char *key, + const char *val); +extern nss_status_t _nss_nisplus_expand_lookup(nisplus_backend_ptr_t, nss_XbyY_args_t *arg, - const char *key, - const char *val, - const char *table); -extern int netdb_aliases_from_nisobj(nis_object *obj, - int nobj, - const char *proto, - char **alias_list, - char **aliaspp, - char **cnamep, - int *count); -extern int __netdb_aliases_from_nisobj(nis_object *obj, + const char *key, + const char *val, + const char *table); +extern int nis_aliases_object2str(nis_object *obj, int nobj, + const char *cname, const char *proto, - char **alias_list, - char **aliaspp, - char **cnamep, - int *count, - int af_type); + char *linep, + char *limit); +extern int nis_hosts_object2str(int nobj, + nis_object *obj, + nisplus_backend_ptr_t be, + nss_XbyY_args_t *argp, + int af); #else /* __STDC__ */ extern nss_backend_t *_nss_nisplus_constr(); -extern nss_status_t _nss_nisplus_destr (); +extern nss_status_t _nss_nisplus_destr(); extern nss_status_t _nss_nisplus_setent(); extern nss_status_t _nss_nisplus_endent(); extern nss_status_t _nss_nisplus_getent(); -extern nss_status_t _nss_nisplus_lookup (); +extern nss_status_t _nss_nisplus_lookup(); extern nss_status_t _nss_nisplus__expand_lookup(); extern int build_aliases_from_nisobj(); #endif /* __STDC__ */ /* Lower-level interface */ -extern nss_status_t _nss_nisplus_list(const char *name, - int extra_flags, - nis_result **r); +extern nss_status_t _nss_nisplus_list(const char *name, + int extra_flags, + nis_result **r); extern int __nis_parse_path(); extern int _thr_main(void); extern int __nss2herrno(); diff --git a/usr/src/lib/nsswitch/nisplus/common/nisplus_tables.h b/usr/src/lib/nsswitch/nisplus/common/nisplus_tables.h index 7f3823e985..a9f53fd00c 100644 --- a/usr/src/lib/nsswitch/nisplus/common/nisplus_tables.h +++ b/usr/src/lib/nsswitch/nisplus/common/nisplus_tables.h @@ -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,10 +19,12 @@ * CDDL HEADER END */ /* + * Copyright 2006 Sun Microsystems, Inc. All rights reserved. + * Use is subject to license terms. + */ + +/* * nisplus_tables.h - * - * Copyright (c) 1988-2000 by Sun Microsystems, Inc. - * All rights reserved. */ #ifndef _NISPLUS_TABLES_H @@ -302,6 +303,30 @@ extern "C" { #define EC_SET(ecp, ndx, l, v) \ ((l) = EC_LEN(ecp, ndx), (v) = EC_VAL(ecp, ndx)) +#define __NISPLUS_GETCOL_OR_EMPTY(ecp, ndx, l, v) \ + EC_SET(ecp, ndx, l, v);\ + if (l < 2) {\ + (v) = "";\ + (l) = 1;\ + } else {\ + l--;\ + } + +#define __NISPLUS_GETCOL_OR_RETURN(ecp, ndx, l, v) \ + EC_SET(ecp, ndx, l, v);\ + if (l < 2) {\ + return (NSS_STR_PARSE_PARSE);\ + } else {\ + l--;\ + } + +#define __NISPLUS_GETCOL_OR_CONTINUE(ecp, ndx, l, v) \ + EC_SET(ecp, ndx, l, v);\ + if (l < 2) {\ + continue;\ + } else {\ + l--;\ + } #ifdef __cplusplus } #endif diff --git a/usr/src/lib/nsswitch/user/Makefile.com b/usr/src/lib/nsswitch/user/Makefile.com index c51cc34604..df1c209dfc 100644 --- a/usr/src/lib/nsswitch/user/Makefile.com +++ b/usr/src/lib/nsswitch/user/Makefile.com @@ -39,6 +39,8 @@ include ../../Makefile.com include ../../../Makefile.rootfs CPPFLAGS += -I../../../common/inc +LINTFLAGS += -erroff=E_GLOBAL_COULD_BE_STATIC2 -erroff=E_FUNC_SET_NOT_USED +LINTFLAGS64 += -erroff=E_GLOBAL_COULD_BE_STATIC2 -erroff=E_FUNC_SET_NOT_USED DYNLIB1 = nss_user.so$(VERS) diff --git a/usr/src/lib/nsswitch/user/common/getprinter.c b/usr/src/lib/nsswitch/user/common/getprinter.c index 25bc1ac49d..7e62b69724 100644 --- a/usr/src/lib/nsswitch/user/common/getprinter.c +++ b/usr/src/lib/nsswitch/user/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. * * "user" backend for nsswitch "printers" database. This module implements @@ -95,6 +94,7 @@ _nss_user_printers_convert(char *entry, nss_XbyY_args_t *args) * backends don't include it in the data passed to the backend. For this * reason, we process everything here and don't bother calling the backend. */ +/*ARGSUSED*/ static nss_status_t _nss_user_XY_printers(be, args, filter) user_backend_ptr_t be; @@ -107,7 +107,6 @@ _nss_user_XY_printers(be, args, filter) */ { nss_status_t res; - int parsestat; int namelen; if (be->buf == 0 && @@ -119,12 +118,12 @@ _nss_user_XY_printers(be, args, filter) res = NSS_NOTFOUND; namelen = strlen(args->key.name); + /*CONSTCOND*/ while (1) { char *instr = be->buf; char *p, *limit; int linelen; int found = 0; - char *key, *value; /* * _nss_user_read_line does process the '\' that are used @@ -194,6 +193,7 @@ getent(be, a) res = NSS_NOTFOUND; + /*CONSTCOND*/ while (1) { char *instr = be->buf; int linelen; @@ -240,6 +240,7 @@ static user_backend_op_t printers_ops[] = { getbyname }; +/*ARGSUSED*/ nss_backend_t * _nss_user_printers_constr(dummy1, dummy2, dummy3) const char *dummy1, *dummy2, *dummy3; @@ -248,7 +249,7 @@ _nss_user_printers_constr(dummy1, dummy2, dummy3) if ((home = getenv("HOME")) == NULL) home = ""; - snprintf(path, sizeof (path), "%s/.printers", home); + (void) snprintf(path, sizeof (path), "%s/.printers", home); return (_nss_user_constr(printers_ops, sizeof (printers_ops) / sizeof (printers_ops[0]), diff --git a/usr/src/lib/nsswitch/user/common/user_common.c b/usr/src/lib/nsswitch/user/common/user_common.c index 1a52140be3..76a7aa9872 100644 --- a/usr/src/lib/nsswitch/user/common/user_common.c +++ b/usr/src/lib/nsswitch/user/common/user_common.c @@ -43,6 +43,7 @@ #include <sys/stat.h> #include <string.h> +/*ARGSUSED*/ nss_status_t _nss_user_setent(be, dummy) user_backend_ptr_t be; @@ -62,13 +63,14 @@ _nss_user_setent(be, dummy) return (NSS_SUCCESS); } +/*ARGSUSED*/ nss_status_t _nss_user_endent(be, dummy) user_backend_ptr_t be; void *dummy; { if (be->f != 0) { - fclose(be->f); + (void) fclose(be->f); be->f = 0; } if (be->buf != 0) { @@ -98,6 +100,7 @@ _nss_user_read_line(f, buffer, buflen) int linelen; /* 1st unused slot in buffer */ int c; + /*CONSTCOND*/ while (1) { linelen = 0; while (linelen < buflen - 1) { /* "- 1" saves room for \n\0 */ @@ -168,6 +171,7 @@ _nss_user_XY_all(be, args, netdb, filter, check) res = NSS_NOTFOUND; + /*CONSTCOND*/ while (1) { char *instr = be->buf; int linelen; @@ -250,6 +254,7 @@ _nss_user_XY_all(be, args, netdb, filter, check) } +/*ARGSUSED*/ nss_status_t _nss_user_destr(be, dummy) user_backend_ptr_t be; @@ -257,7 +262,7 @@ _nss_user_destr(be, dummy) { if (be != 0) { if (be->f != 0) { - _nss_user_endent(be, 0); + (void) _nss_user_endent(be, 0); } free((char *)be->filename); free(be); |
