1*7c478bd9Sstevel@tonic-gate /* 2*7c478bd9Sstevel@tonic-gate * CDDL HEADER START 3*7c478bd9Sstevel@tonic-gate * 4*7c478bd9Sstevel@tonic-gate * The contents of this file are subject to the terms of the 5*7c478bd9Sstevel@tonic-gate * Common Development and Distribution License, Version 1.0 only 6*7c478bd9Sstevel@tonic-gate * (the "License"). You may not use this file except in compliance 7*7c478bd9Sstevel@tonic-gate * with the License. 8*7c478bd9Sstevel@tonic-gate * 9*7c478bd9Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10*7c478bd9Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 11*7c478bd9Sstevel@tonic-gate * See the License for the specific language governing permissions 12*7c478bd9Sstevel@tonic-gate * and limitations under the License. 13*7c478bd9Sstevel@tonic-gate * 14*7c478bd9Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 15*7c478bd9Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16*7c478bd9Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 17*7c478bd9Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 18*7c478bd9Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 19*7c478bd9Sstevel@tonic-gate * 20*7c478bd9Sstevel@tonic-gate * CDDL HEADER END 21*7c478bd9Sstevel@tonic-gate */ 22*7c478bd9Sstevel@tonic-gate /* 23*7c478bd9Sstevel@tonic-gate * Copyright 2005 Sun Microsystems, Inc. All rights reserved. 24*7c478bd9Sstevel@tonic-gate * Use is subject to license terms. 25*7c478bd9Sstevel@tonic-gate * 26*7c478bd9Sstevel@tonic-gate * Common code and structures used by name-service-switch "compat" backends. 27*7c478bd9Sstevel@tonic-gate * 28*7c478bd9Sstevel@tonic-gate * Most of the code in the "compat" backend is a perverted form of code from 29*7c478bd9Sstevel@tonic-gate * the "files" backend; this file is no exception. 30*7c478bd9Sstevel@tonic-gate */ 31*7c478bd9Sstevel@tonic-gate 32*7c478bd9Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 33*7c478bd9Sstevel@tonic-gate 34*7c478bd9Sstevel@tonic-gate #include <stdio.h> 35*7c478bd9Sstevel@tonic-gate #include <stdlib.h> 36*7c478bd9Sstevel@tonic-gate #include <string.h> 37*7c478bd9Sstevel@tonic-gate #include <ctype.h> 38*7c478bd9Sstevel@tonic-gate #include <bsm/libbsm.h> 39*7c478bd9Sstevel@tonic-gate #include <user_attr.h> 40*7c478bd9Sstevel@tonic-gate #include "compat_common.h" 41*7c478bd9Sstevel@tonic-gate #include "../../../libnsl/include/nsl_stdio_prv.h" 42*7c478bd9Sstevel@tonic-gate 43*7c478bd9Sstevel@tonic-gate /* 44*7c478bd9Sstevel@tonic-gate * This should be in a header. 45*7c478bd9Sstevel@tonic-gate */ 46*7c478bd9Sstevel@tonic-gate 47*7c478bd9Sstevel@tonic-gate extern int yp_get_default_domain(char **domain); 48*7c478bd9Sstevel@tonic-gate 49*7c478bd9Sstevel@tonic-gate /* 50*7c478bd9Sstevel@tonic-gate * Routines to manage list of "-" users for get{pw, sp, gr}ent(). Current 51*7c478bd9Sstevel@tonic-gate * implementation is completely moronic; we use a linked list. But then 52*7c478bd9Sstevel@tonic-gate * that's what it's always done in 4.x... 53*7c478bd9Sstevel@tonic-gate */ 54*7c478bd9Sstevel@tonic-gate 55*7c478bd9Sstevel@tonic-gate struct setofstrings { 56*7c478bd9Sstevel@tonic-gate char *name; 57*7c478bd9Sstevel@tonic-gate struct setofstrings *next; 58*7c478bd9Sstevel@tonic-gate /* 59*7c478bd9Sstevel@tonic-gate * === Should get smart and malloc the string and pointer as one 60*7c478bd9Sstevel@tonic-gate * object rather than two. 61*7c478bd9Sstevel@tonic-gate */ 62*7c478bd9Sstevel@tonic-gate }; 63*7c478bd9Sstevel@tonic-gate typedef struct setofstrings *strset_t; 64*7c478bd9Sstevel@tonic-gate 65*7c478bd9Sstevel@tonic-gate static void 66*7c478bd9Sstevel@tonic-gate strset_free(ssp) 67*7c478bd9Sstevel@tonic-gate strset_t *ssp; 68*7c478bd9Sstevel@tonic-gate { 69*7c478bd9Sstevel@tonic-gate strset_t cur, nxt; 70*7c478bd9Sstevel@tonic-gate 71*7c478bd9Sstevel@tonic-gate for (cur = *ssp; cur != 0; cur = nxt) { 72*7c478bd9Sstevel@tonic-gate nxt = cur->next; 73*7c478bd9Sstevel@tonic-gate free(cur->name); 74*7c478bd9Sstevel@tonic-gate free(cur); 75*7c478bd9Sstevel@tonic-gate } 76*7c478bd9Sstevel@tonic-gate *ssp = 0; 77*7c478bd9Sstevel@tonic-gate } 78*7c478bd9Sstevel@tonic-gate 79*7c478bd9Sstevel@tonic-gate static boolean_t 80*7c478bd9Sstevel@tonic-gate strset_add(ssp, nam) 81*7c478bd9Sstevel@tonic-gate strset_t *ssp; 82*7c478bd9Sstevel@tonic-gate const char *nam; 83*7c478bd9Sstevel@tonic-gate { 84*7c478bd9Sstevel@tonic-gate strset_t new; 85*7c478bd9Sstevel@tonic-gate 86*7c478bd9Sstevel@tonic-gate if (0 == (new = (strset_t)malloc(sizeof (*new)))) { 87*7c478bd9Sstevel@tonic-gate return (B_FALSE); 88*7c478bd9Sstevel@tonic-gate } 89*7c478bd9Sstevel@tonic-gate if (0 == (new->name = malloc(strlen(nam) + 1))) { 90*7c478bd9Sstevel@tonic-gate free(new); 91*7c478bd9Sstevel@tonic-gate return (B_FALSE); 92*7c478bd9Sstevel@tonic-gate } 93*7c478bd9Sstevel@tonic-gate strcpy(new->name, nam); 94*7c478bd9Sstevel@tonic-gate new->next = *ssp; 95*7c478bd9Sstevel@tonic-gate *ssp = new; 96*7c478bd9Sstevel@tonic-gate return (B_TRUE); 97*7c478bd9Sstevel@tonic-gate } 98*7c478bd9Sstevel@tonic-gate 99*7c478bd9Sstevel@tonic-gate static boolean_t 100*7c478bd9Sstevel@tonic-gate strset_in(ssp, nam) 101*7c478bd9Sstevel@tonic-gate const strset_t *ssp; 102*7c478bd9Sstevel@tonic-gate const char *nam; 103*7c478bd9Sstevel@tonic-gate { 104*7c478bd9Sstevel@tonic-gate strset_t cur; 105*7c478bd9Sstevel@tonic-gate 106*7c478bd9Sstevel@tonic-gate for (cur = *ssp; cur != 0; cur = cur->next) { 107*7c478bd9Sstevel@tonic-gate if (strcmp(cur->name, nam) == 0) { 108*7c478bd9Sstevel@tonic-gate return (B_TRUE); 109*7c478bd9Sstevel@tonic-gate } 110*7c478bd9Sstevel@tonic-gate } 111*7c478bd9Sstevel@tonic-gate return (B_FALSE); 112*7c478bd9Sstevel@tonic-gate } 113*7c478bd9Sstevel@tonic-gate 114*7c478bd9Sstevel@tonic-gate 115*7c478bd9Sstevel@tonic-gate struct compat_backend { 116*7c478bd9Sstevel@tonic-gate compat_backend_op_t *ops; 117*7c478bd9Sstevel@tonic-gate int n_ops; 118*7c478bd9Sstevel@tonic-gate const char *filename; 119*7c478bd9Sstevel@tonic-gate __NSL_FILE *f; 120*7c478bd9Sstevel@tonic-gate int minbuf; 121*7c478bd9Sstevel@tonic-gate char *buf; 122*7c478bd9Sstevel@tonic-gate int linelen; /* <== Explain use, lifetime */ 123*7c478bd9Sstevel@tonic-gate 124*7c478bd9Sstevel@tonic-gate nss_db_initf_t db_initf; 125*7c478bd9Sstevel@tonic-gate nss_db_root_t *db_rootp; /* Shared between instances */ 126*7c478bd9Sstevel@tonic-gate nss_getent_t db_context; /* Per-instance enumeration */ 127*7c478bd9Sstevel@tonic-gate 128*7c478bd9Sstevel@tonic-gate compat_get_name getnamef; 129*7c478bd9Sstevel@tonic-gate compat_merge_func mergef; 130*7c478bd9Sstevel@tonic-gate 131*7c478bd9Sstevel@tonic-gate /* We wouldn't need all this hokey state stuff if we */ 132*7c478bd9Sstevel@tonic-gate /* used another thread to implement a coroutine... */ 133*7c478bd9Sstevel@tonic-gate enum { 134*7c478bd9Sstevel@tonic-gate GETENT_FILE, 135*7c478bd9Sstevel@tonic-gate GETENT_NETGROUP, 136*7c478bd9Sstevel@tonic-gate GETENT_ATTRDB, 137*7c478bd9Sstevel@tonic-gate GETENT_ALL, 138*7c478bd9Sstevel@tonic-gate GETENT_DONE 139*7c478bd9Sstevel@tonic-gate } state; 140*7c478bd9Sstevel@tonic-gate strset_t minuses; 141*7c478bd9Sstevel@tonic-gate 142*7c478bd9Sstevel@tonic-gate int permit_netgroups; 143*7c478bd9Sstevel@tonic-gate const char *yp_domain; 144*7c478bd9Sstevel@tonic-gate nss_backend_t *getnetgrent_backend; 145*7c478bd9Sstevel@tonic-gate char *netgr_buffer; 146*7c478bd9Sstevel@tonic-gate }; 147*7c478bd9Sstevel@tonic-gate 148*7c478bd9Sstevel@tonic-gate 149*7c478bd9Sstevel@tonic-gate /* 150*7c478bd9Sstevel@tonic-gate * Lookup and enumeration routines for +@group and -@group. 151*7c478bd9Sstevel@tonic-gate * 152*7c478bd9Sstevel@tonic-gate * This code knows a lot more about lib/libc/port/gen/getnetgrent.c than 153*7c478bd9Sstevel@tonic-gate * is really healthy. The set/get/end routines below duplicate code 154*7c478bd9Sstevel@tonic-gate * from that file, but keep the state information per-backend-instance 155*7c478bd9Sstevel@tonic-gate * instead of just per-process. 156*7c478bd9Sstevel@tonic-gate */ 157*7c478bd9Sstevel@tonic-gate 158*7c478bd9Sstevel@tonic-gate extern void _nss_initf_netgroup(nss_db_params_t *); 159*7c478bd9Sstevel@tonic-gate /* 160*7c478bd9Sstevel@tonic-gate * Should really share the db_root in getnetgrent.c in order to get the 161*7c478bd9Sstevel@tonic-gate * resource-management quotas right, but this will have to do. 162*7c478bd9Sstevel@tonic-gate */ 163*7c478bd9Sstevel@tonic-gate static DEFINE_NSS_DB_ROOT(netgr_db_root); 164*7c478bd9Sstevel@tonic-gate 165*7c478bd9Sstevel@tonic-gate static boolean_t 166*7c478bd9Sstevel@tonic-gate netgr_in(compat_backend_ptr_t be, const char *group, const char *user) 167*7c478bd9Sstevel@tonic-gate { 168*7c478bd9Sstevel@tonic-gate if (be->yp_domain == 0) { 169*7c478bd9Sstevel@tonic-gate if (yp_get_default_domain((char **)&be->yp_domain) != 0) { 170*7c478bd9Sstevel@tonic-gate return (B_FALSE); 171*7c478bd9Sstevel@tonic-gate } 172*7c478bd9Sstevel@tonic-gate } 173*7c478bd9Sstevel@tonic-gate return (innetgr(group, 0, user, be->yp_domain)); 174*7c478bd9Sstevel@tonic-gate } 175*7c478bd9Sstevel@tonic-gate 176*7c478bd9Sstevel@tonic-gate static boolean_t 177*7c478bd9Sstevel@tonic-gate netgr_all_in(compat_backend_ptr_t be, const char *group) 178*7c478bd9Sstevel@tonic-gate { 179*7c478bd9Sstevel@tonic-gate /* 180*7c478bd9Sstevel@tonic-gate * 4.x does this; ours not to reason why... 181*7c478bd9Sstevel@tonic-gate */ 182*7c478bd9Sstevel@tonic-gate return (netgr_in(be, group, "*")); 183*7c478bd9Sstevel@tonic-gate } 184*7c478bd9Sstevel@tonic-gate 185*7c478bd9Sstevel@tonic-gate static void 186*7c478bd9Sstevel@tonic-gate netgr_set(be, netgroup) 187*7c478bd9Sstevel@tonic-gate compat_backend_ptr_t be; 188*7c478bd9Sstevel@tonic-gate const char *netgroup; 189*7c478bd9Sstevel@tonic-gate { 190*7c478bd9Sstevel@tonic-gate /* 191*7c478bd9Sstevel@tonic-gate * ===> Need comment to explain that this first "if" is optimizing 192*7c478bd9Sstevel@tonic-gate * for the same-netgroup-as-last-time case 193*7c478bd9Sstevel@tonic-gate */ 194*7c478bd9Sstevel@tonic-gate if (be->getnetgrent_backend != 0 && 195*7c478bd9Sstevel@tonic-gate NSS_INVOKE_DBOP(be->getnetgrent_backend, 196*7c478bd9Sstevel@tonic-gate NSS_DBOP_SETENT, 197*7c478bd9Sstevel@tonic-gate (void *) netgroup) != NSS_SUCCESS) { 198*7c478bd9Sstevel@tonic-gate NSS_INVOKE_DBOP(be->getnetgrent_backend, NSS_DBOP_DESTRUCTOR, 199*7c478bd9Sstevel@tonic-gate 0); 200*7c478bd9Sstevel@tonic-gate be->getnetgrent_backend = 0; 201*7c478bd9Sstevel@tonic-gate } 202*7c478bd9Sstevel@tonic-gate if (be->getnetgrent_backend == 0) { 203*7c478bd9Sstevel@tonic-gate struct nss_setnetgrent_args args; 204*7c478bd9Sstevel@tonic-gate 205*7c478bd9Sstevel@tonic-gate args.netgroup = netgroup; 206*7c478bd9Sstevel@tonic-gate args.iterator = 0; 207*7c478bd9Sstevel@tonic-gate nss_search(&netgr_db_root, _nss_initf_netgroup, 208*7c478bd9Sstevel@tonic-gate NSS_DBOP_NETGROUP_SET, &args); 209*7c478bd9Sstevel@tonic-gate be->getnetgrent_backend = args.iterator; 210*7c478bd9Sstevel@tonic-gate } 211*7c478bd9Sstevel@tonic-gate } 212*7c478bd9Sstevel@tonic-gate 213*7c478bd9Sstevel@tonic-gate static boolean_t 214*7c478bd9Sstevel@tonic-gate netgr_next_u(be, up) 215*7c478bd9Sstevel@tonic-gate compat_backend_ptr_t be; 216*7c478bd9Sstevel@tonic-gate char **up; 217*7c478bd9Sstevel@tonic-gate { 218*7c478bd9Sstevel@tonic-gate if (be->netgr_buffer == 0 && 219*7c478bd9Sstevel@tonic-gate (be->netgr_buffer = malloc(NSS_BUFLEN_NETGROUP)) == 0) { 220*7c478bd9Sstevel@tonic-gate /* Out of memory */ 221*7c478bd9Sstevel@tonic-gate return (B_FALSE); 222*7c478bd9Sstevel@tonic-gate } 223*7c478bd9Sstevel@tonic-gate 224*7c478bd9Sstevel@tonic-gate do { 225*7c478bd9Sstevel@tonic-gate struct nss_getnetgrent_args args; 226*7c478bd9Sstevel@tonic-gate 227*7c478bd9Sstevel@tonic-gate args.buffer = be->netgr_buffer; 228*7c478bd9Sstevel@tonic-gate args.buflen = NSS_BUFLEN_NETGROUP; 229*7c478bd9Sstevel@tonic-gate args.status = NSS_NETGR_NO; 230*7c478bd9Sstevel@tonic-gate 231*7c478bd9Sstevel@tonic-gate if (be->getnetgrent_backend != 0) { 232*7c478bd9Sstevel@tonic-gate NSS_INVOKE_DBOP(be->getnetgrent_backend, 233*7c478bd9Sstevel@tonic-gate NSS_DBOP_GETENT, &args); 234*7c478bd9Sstevel@tonic-gate } 235*7c478bd9Sstevel@tonic-gate 236*7c478bd9Sstevel@tonic-gate if (args.status == NSS_NETGR_FOUND) { 237*7c478bd9Sstevel@tonic-gate *up = args.retp[NSS_NETGR_USER]; 238*7c478bd9Sstevel@tonic-gate } else { 239*7c478bd9Sstevel@tonic-gate return (B_FALSE); 240*7c478bd9Sstevel@tonic-gate } 241*7c478bd9Sstevel@tonic-gate } while (*up == 0); 242*7c478bd9Sstevel@tonic-gate return (B_TRUE); 243*7c478bd9Sstevel@tonic-gate } 244*7c478bd9Sstevel@tonic-gate 245*7c478bd9Sstevel@tonic-gate static void 246*7c478bd9Sstevel@tonic-gate netgr_end(be) 247*7c478bd9Sstevel@tonic-gate compat_backend_ptr_t be; 248*7c478bd9Sstevel@tonic-gate { 249*7c478bd9Sstevel@tonic-gate if (be->getnetgrent_backend != 0) { 250*7c478bd9Sstevel@tonic-gate NSS_INVOKE_DBOP(be->getnetgrent_backend, 251*7c478bd9Sstevel@tonic-gate NSS_DBOP_DESTRUCTOR, 0); 252*7c478bd9Sstevel@tonic-gate be->getnetgrent_backend = 0; 253*7c478bd9Sstevel@tonic-gate } 254*7c478bd9Sstevel@tonic-gate if (be->netgr_buffer != 0) { 255*7c478bd9Sstevel@tonic-gate free(be->netgr_buffer); 256*7c478bd9Sstevel@tonic-gate be->netgr_buffer = 0; 257*7c478bd9Sstevel@tonic-gate } 258*7c478bd9Sstevel@tonic-gate } 259*7c478bd9Sstevel@tonic-gate 260*7c478bd9Sstevel@tonic-gate 261*7c478bd9Sstevel@tonic-gate #define MAXFIELDS 9 /* Sufficient for passwd (7), shadow (9), group (4) */ 262*7c478bd9Sstevel@tonic-gate 263*7c478bd9Sstevel@tonic-gate static nss_status_t 264*7c478bd9Sstevel@tonic-gate do_merge(be, args, instr, linelen) 265*7c478bd9Sstevel@tonic-gate compat_backend_ptr_t be; 266*7c478bd9Sstevel@tonic-gate nss_XbyY_args_t *args; 267*7c478bd9Sstevel@tonic-gate const char *instr; 268*7c478bd9Sstevel@tonic-gate int linelen; 269*7c478bd9Sstevel@tonic-gate { 270*7c478bd9Sstevel@tonic-gate char *fields[MAXFIELDS]; 271*7c478bd9Sstevel@tonic-gate int i; 272*7c478bd9Sstevel@tonic-gate int overrides; 273*7c478bd9Sstevel@tonic-gate const char *p; 274*7c478bd9Sstevel@tonic-gate const char *end = instr + linelen; 275*7c478bd9Sstevel@tonic-gate nss_status_t res; 276*7c478bd9Sstevel@tonic-gate 277*7c478bd9Sstevel@tonic-gate /* 278*7c478bd9Sstevel@tonic-gate * Potential optimization: only perform the field-splitting nonsense 279*7c478bd9Sstevel@tonic-gate * once per input line (at present, "+" and "+@netgroup" entries 280*7c478bd9Sstevel@tonic-gate * will cause us to do this multiple times in getent() requests). 281*7c478bd9Sstevel@tonic-gate */ 282*7c478bd9Sstevel@tonic-gate 283*7c478bd9Sstevel@tonic-gate for (i = 0; i < MAXFIELDS; i++) { 284*7c478bd9Sstevel@tonic-gate fields[i] = 0; 285*7c478bd9Sstevel@tonic-gate } 286*7c478bd9Sstevel@tonic-gate for (p = instr, overrides = 0, i = 0; /* no test */; i++) { 287*7c478bd9Sstevel@tonic-gate const char *q = memchr(p, ':', end - p); 288*7c478bd9Sstevel@tonic-gate const char *r = (q == 0) ? end : q; 289*7c478bd9Sstevel@tonic-gate ssize_t len = r - p; 290*7c478bd9Sstevel@tonic-gate 291*7c478bd9Sstevel@tonic-gate if (len > 0) { 292*7c478bd9Sstevel@tonic-gate char *s = malloc(len + 1); 293*7c478bd9Sstevel@tonic-gate if (s == 0) { 294*7c478bd9Sstevel@tonic-gate overrides = -1; /* Indicates "you lose" */ 295*7c478bd9Sstevel@tonic-gate break; 296*7c478bd9Sstevel@tonic-gate } 297*7c478bd9Sstevel@tonic-gate memcpy(s, p, len); 298*7c478bd9Sstevel@tonic-gate s[len] = '\0'; 299*7c478bd9Sstevel@tonic-gate fields[i] = s; 300*7c478bd9Sstevel@tonic-gate overrides++; 301*7c478bd9Sstevel@tonic-gate } 302*7c478bd9Sstevel@tonic-gate if (q == 0) { 303*7c478bd9Sstevel@tonic-gate /* End of line */ 304*7c478bd9Sstevel@tonic-gate break; 305*7c478bd9Sstevel@tonic-gate } else { 306*7c478bd9Sstevel@tonic-gate /* Skip the colon at (*q) */ 307*7c478bd9Sstevel@tonic-gate p = q + 1; 308*7c478bd9Sstevel@tonic-gate } 309*7c478bd9Sstevel@tonic-gate } 310*7c478bd9Sstevel@tonic-gate if (overrides == 1) { 311*7c478bd9Sstevel@tonic-gate /* No real overrides, return (*args) intact */ 312*7c478bd9Sstevel@tonic-gate res = NSS_SUCCESS; 313*7c478bd9Sstevel@tonic-gate } else if (overrides > 1) { 314*7c478bd9Sstevel@tonic-gate /* 315*7c478bd9Sstevel@tonic-gate * The zero'th field is always nonempty (+/-...), but at least 316*7c478bd9Sstevel@tonic-gate * one other field was also nonempty, i.e. wants to override 317*7c478bd9Sstevel@tonic-gate */ 318*7c478bd9Sstevel@tonic-gate switch ((*be->mergef)(be, args, (const char **)fields)) { 319*7c478bd9Sstevel@tonic-gate case NSS_STR_PARSE_SUCCESS: 320*7c478bd9Sstevel@tonic-gate args->returnval = args->buf.result; 321*7c478bd9Sstevel@tonic-gate args->erange = 0; 322*7c478bd9Sstevel@tonic-gate res = NSS_SUCCESS; 323*7c478bd9Sstevel@tonic-gate break; 324*7c478bd9Sstevel@tonic-gate case NSS_STR_PARSE_ERANGE: 325*7c478bd9Sstevel@tonic-gate args->returnval = 0; 326*7c478bd9Sstevel@tonic-gate args->erange = 1; 327*7c478bd9Sstevel@tonic-gate res = NSS_NOTFOUND; 328*7c478bd9Sstevel@tonic-gate break; 329*7c478bd9Sstevel@tonic-gate case NSS_STR_PARSE_PARSE: 330*7c478bd9Sstevel@tonic-gate args->returnval = 0; 331*7c478bd9Sstevel@tonic-gate args->erange = 0; 332*7c478bd9Sstevel@tonic-gate /* ===> Very likely the wrong thing to do... */ 333*7c478bd9Sstevel@tonic-gate res = NSS_NOTFOUND; 334*7c478bd9Sstevel@tonic-gate break; 335*7c478bd9Sstevel@tonic-gate } 336*7c478bd9Sstevel@tonic-gate } else { 337*7c478bd9Sstevel@tonic-gate args->returnval = 0; 338*7c478bd9Sstevel@tonic-gate args->erange = 0; 339*7c478bd9Sstevel@tonic-gate res = NSS_UNAVAIL; /* ==> Right? */ 340*7c478bd9Sstevel@tonic-gate } 341*7c478bd9Sstevel@tonic-gate 342*7c478bd9Sstevel@tonic-gate for (i = 0; i < MAXFIELDS; i++) { 343*7c478bd9Sstevel@tonic-gate if (fields[i] != 0) { 344*7c478bd9Sstevel@tonic-gate free(fields[i]); 345*7c478bd9Sstevel@tonic-gate } 346*7c478bd9Sstevel@tonic-gate } 347*7c478bd9Sstevel@tonic-gate 348*7c478bd9Sstevel@tonic-gate return (res); 349*7c478bd9Sstevel@tonic-gate } 350*7c478bd9Sstevel@tonic-gate 351*7c478bd9Sstevel@tonic-gate /*ARGSUSED*/ 352*7c478bd9Sstevel@tonic-gate nss_status_t 353*7c478bd9Sstevel@tonic-gate _nss_compat_setent(be, dummy) 354*7c478bd9Sstevel@tonic-gate compat_backend_ptr_t be; 355*7c478bd9Sstevel@tonic-gate void *dummy; 356*7c478bd9Sstevel@tonic-gate { 357*7c478bd9Sstevel@tonic-gate if (be->f == 0) { 358*7c478bd9Sstevel@tonic-gate if (be->filename == 0) { 359*7c478bd9Sstevel@tonic-gate /* Backend isn't initialized properly? */ 360*7c478bd9Sstevel@tonic-gate return (NSS_UNAVAIL); 361*7c478bd9Sstevel@tonic-gate } 362*7c478bd9Sstevel@tonic-gate if ((be->f = __nsl_fopen(be->filename, "r")) == 0) { 363*7c478bd9Sstevel@tonic-gate return (NSS_UNAVAIL); 364*7c478bd9Sstevel@tonic-gate } 365*7c478bd9Sstevel@tonic-gate } else { 366*7c478bd9Sstevel@tonic-gate __nsl_rewind(be->f); 367*7c478bd9Sstevel@tonic-gate } 368*7c478bd9Sstevel@tonic-gate strset_free(&be->minuses); 369*7c478bd9Sstevel@tonic-gate /* ===> ??? nss_endent(be->db_rootp, be->db_initf, &be->db_context); */ 370*7c478bd9Sstevel@tonic-gate 371*7c478bd9Sstevel@tonic-gate if ((strcmp(be->filename, USERATTR_FILENAME) == 0) || 372*7c478bd9Sstevel@tonic-gate (strcmp(be->filename, AUDITUSER_FILENAME) == 0)) 373*7c478bd9Sstevel@tonic-gate be->state = GETENT_ATTRDB; 374*7c478bd9Sstevel@tonic-gate else 375*7c478bd9Sstevel@tonic-gate be->state = GETENT_FILE; 376*7c478bd9Sstevel@tonic-gate 377*7c478bd9Sstevel@tonic-gate /* ===> ?? netgroup stuff? */ 378*7c478bd9Sstevel@tonic-gate return (NSS_SUCCESS); 379*7c478bd9Sstevel@tonic-gate } 380*7c478bd9Sstevel@tonic-gate 381*7c478bd9Sstevel@tonic-gate /*ARGSUSED*/ 382*7c478bd9Sstevel@tonic-gate nss_status_t 383*7c478bd9Sstevel@tonic-gate _nss_compat_endent(be, dummy) 384*7c478bd9Sstevel@tonic-gate compat_backend_ptr_t be; 385*7c478bd9Sstevel@tonic-gate void *dummy; 386*7c478bd9Sstevel@tonic-gate { 387*7c478bd9Sstevel@tonic-gate if (be->f != 0) { 388*7c478bd9Sstevel@tonic-gate __nsl_fclose(be->f); 389*7c478bd9Sstevel@tonic-gate be->f = 0; 390*7c478bd9Sstevel@tonic-gate } 391*7c478bd9Sstevel@tonic-gate if (be->buf != 0) { 392*7c478bd9Sstevel@tonic-gate free(be->buf); 393*7c478bd9Sstevel@tonic-gate be->buf = 0; 394*7c478bd9Sstevel@tonic-gate } 395*7c478bd9Sstevel@tonic-gate nss_endent(be->db_rootp, be->db_initf, &be->db_context); 396*7c478bd9Sstevel@tonic-gate 397*7c478bd9Sstevel@tonic-gate be->state = GETENT_FILE; /* Probably superfluous but comforting */ 398*7c478bd9Sstevel@tonic-gate strset_free(&be->minuses); 399*7c478bd9Sstevel@tonic-gate netgr_end(be); 400*7c478bd9Sstevel@tonic-gate 401*7c478bd9Sstevel@tonic-gate /* 402*7c478bd9Sstevel@tonic-gate * Question: from the point of view of resource-freeing vs. time to 403*7c478bd9Sstevel@tonic-gate * start up again, how much should we do in endent() and how much 404*7c478bd9Sstevel@tonic-gate * in the destructor? 405*7c478bd9Sstevel@tonic-gate */ 406*7c478bd9Sstevel@tonic-gate return (NSS_SUCCESS); 407*7c478bd9Sstevel@tonic-gate } 408*7c478bd9Sstevel@tonic-gate 409*7c478bd9Sstevel@tonic-gate /*ARGSUSED*/ 410*7c478bd9Sstevel@tonic-gate nss_status_t 411*7c478bd9Sstevel@tonic-gate _nss_compat_destr(be, dummy) 412*7c478bd9Sstevel@tonic-gate compat_backend_ptr_t be; 413*7c478bd9Sstevel@tonic-gate void *dummy; 414*7c478bd9Sstevel@tonic-gate { 415*7c478bd9Sstevel@tonic-gate if (be != 0) { 416*7c478bd9Sstevel@tonic-gate if (be->f != 0) { 417*7c478bd9Sstevel@tonic-gate _nss_compat_endent(be, 0); 418*7c478bd9Sstevel@tonic-gate } 419*7c478bd9Sstevel@tonic-gate nss_delete(be->db_rootp); 420*7c478bd9Sstevel@tonic-gate nss_delete(&netgr_db_root); 421*7c478bd9Sstevel@tonic-gate free(be); 422*7c478bd9Sstevel@tonic-gate } 423*7c478bd9Sstevel@tonic-gate return (NSS_SUCCESS); /* In case anyone is dumb enough to check */ 424*7c478bd9Sstevel@tonic-gate } 425*7c478bd9Sstevel@tonic-gate 426*7c478bd9Sstevel@tonic-gate static int 427*7c478bd9Sstevel@tonic-gate read_line(f, buffer, buflen) 428*7c478bd9Sstevel@tonic-gate __NSL_FILE *f; 429*7c478bd9Sstevel@tonic-gate char *buffer; 430*7c478bd9Sstevel@tonic-gate int buflen; 431*7c478bd9Sstevel@tonic-gate { 432*7c478bd9Sstevel@tonic-gate /*CONSTCOND*/ 433*7c478bd9Sstevel@tonic-gate while (1) { 434*7c478bd9Sstevel@tonic-gate int linelen; 435*7c478bd9Sstevel@tonic-gate 436*7c478bd9Sstevel@tonic-gate if (__nsl_fgets(buffer, buflen, f) == 0) { 437*7c478bd9Sstevel@tonic-gate /* End of file */ 438*7c478bd9Sstevel@tonic-gate return (-1); 439*7c478bd9Sstevel@tonic-gate } 440*7c478bd9Sstevel@tonic-gate linelen = strlen(buffer); 441*7c478bd9Sstevel@tonic-gate /* linelen >= 1 (since fgets didn't return 0) */ 442*7c478bd9Sstevel@tonic-gate 443*7c478bd9Sstevel@tonic-gate if (buffer[linelen - 1] == '\n') { 444*7c478bd9Sstevel@tonic-gate /* 445*7c478bd9Sstevel@tonic-gate * ===> The code below that calls read_line() doesn't 446*7c478bd9Sstevel@tonic-gate * play by the rules; it assumes in places that 447*7c478bd9Sstevel@tonic-gate * the line is null-terminated. For now we'll 448*7c478bd9Sstevel@tonic-gate * humour it. 449*7c478bd9Sstevel@tonic-gate */ 450*7c478bd9Sstevel@tonic-gate buffer[--linelen] = '\0'; 451*7c478bd9Sstevel@tonic-gate return (linelen); 452*7c478bd9Sstevel@tonic-gate } 453*7c478bd9Sstevel@tonic-gate if (__nsl_feof(f)) { 454*7c478bd9Sstevel@tonic-gate /* Line is last line in file, and has no newline */ 455*7c478bd9Sstevel@tonic-gate return (linelen); 456*7c478bd9Sstevel@tonic-gate } 457*7c478bd9Sstevel@tonic-gate /* Line too long for buffer; toss it and loop for next line */ 458*7c478bd9Sstevel@tonic-gate /* ===== should syslog() in cases where previous code did */ 459*7c478bd9Sstevel@tonic-gate while (__nsl_fgets(buffer, buflen, f) != 0 && 460*7c478bd9Sstevel@tonic-gate buffer[strlen(buffer) - 1] != '\n') { 461*7c478bd9Sstevel@tonic-gate ; 462*7c478bd9Sstevel@tonic-gate } 463*7c478bd9Sstevel@tonic-gate } 464*7c478bd9Sstevel@tonic-gate } 465*7c478bd9Sstevel@tonic-gate 466*7c478bd9Sstevel@tonic-gate static int _is_nss_lookup_by_name(int attrdb, nss_dbop_t op) { 467*7c478bd9Sstevel@tonic-gate int result = 0; 468*7c478bd9Sstevel@tonic-gate 469*7c478bd9Sstevel@tonic-gate if ((attrdb != 0) && 470*7c478bd9Sstevel@tonic-gate ((op == NSS_DBOP_AUDITUSER_BYNAME) || 471*7c478bd9Sstevel@tonic-gate (op == NSS_DBOP_USERATTR_BYNAME))) { 472*7c478bd9Sstevel@tonic-gate result = 1; 473*7c478bd9Sstevel@tonic-gate } else if ((attrdb == 0) && 474*7c478bd9Sstevel@tonic-gate ((op == NSS_DBOP_GROUP_BYNAME) || 475*7c478bd9Sstevel@tonic-gate (op == NSS_DBOP_PASSWD_BYNAME) || 476*7c478bd9Sstevel@tonic-gate (op == NSS_DBOP_SHADOW_BYNAME))) { 477*7c478bd9Sstevel@tonic-gate result = 1; 478*7c478bd9Sstevel@tonic-gate } 479*7c478bd9Sstevel@tonic-gate 480*7c478bd9Sstevel@tonic-gate return (result); 481*7c478bd9Sstevel@tonic-gate } 482*7c478bd9Sstevel@tonic-gate 483*7c478bd9Sstevel@tonic-gate /*ARGSUSED*/ 484*7c478bd9Sstevel@tonic-gate nss_status_t 485*7c478bd9Sstevel@tonic-gate _attrdb_compat_XY_all(be, argp, netdb, check, op_num) 486*7c478bd9Sstevel@tonic-gate compat_backend_ptr_t be; 487*7c478bd9Sstevel@tonic-gate nss_XbyY_args_t *argp; 488*7c478bd9Sstevel@tonic-gate int netdb; 489*7c478bd9Sstevel@tonic-gate compat_XY_check_func check; 490*7c478bd9Sstevel@tonic-gate nss_dbop_t op_num; 491*7c478bd9Sstevel@tonic-gate { 492*7c478bd9Sstevel@tonic-gate int parsestat; 493*7c478bd9Sstevel@tonic-gate int (*func)(); 494*7c478bd9Sstevel@tonic-gate const char *filter = argp->key.name; 495*7c478bd9Sstevel@tonic-gate nss_status_t res; 496*7c478bd9Sstevel@tonic-gate 497*7c478bd9Sstevel@tonic-gate #ifdef DEBUG 498*7c478bd9Sstevel@tonic-gate (void) fprintf(stdout, "\n[compat_common.c: _attrdb_compat_XY_all]\n"); 499*7c478bd9Sstevel@tonic-gate #endif /* DEBUG */ 500*7c478bd9Sstevel@tonic-gate 501*7c478bd9Sstevel@tonic-gate if (be->buf == 0 && 502*7c478bd9Sstevel@tonic-gate (be->buf = malloc(be->minbuf)) == 0) { 503*7c478bd9Sstevel@tonic-gate return (NSS_UNAVAIL); 504*7c478bd9Sstevel@tonic-gate } 505*7c478bd9Sstevel@tonic-gate if ((res = _nss_compat_setent(be, 0)) != NSS_SUCCESS) { 506*7c478bd9Sstevel@tonic-gate return (res); 507*7c478bd9Sstevel@tonic-gate } 508*7c478bd9Sstevel@tonic-gate res = NSS_NOTFOUND; 509*7c478bd9Sstevel@tonic-gate 510*7c478bd9Sstevel@tonic-gate /*CONSTCOND*/ 511*7c478bd9Sstevel@tonic-gate while (1) { 512*7c478bd9Sstevel@tonic-gate int linelen; 513*7c478bd9Sstevel@tonic-gate char *instr = be->buf; 514*7c478bd9Sstevel@tonic-gate 515*7c478bd9Sstevel@tonic-gate if ((linelen = read_line(be->f, instr, be->minbuf)) < 0) { 516*7c478bd9Sstevel@tonic-gate /* End of file */ 517*7c478bd9Sstevel@tonic-gate argp->returnval = 0; 518*7c478bd9Sstevel@tonic-gate argp->erange = 0; 519*7c478bd9Sstevel@tonic-gate break; 520*7c478bd9Sstevel@tonic-gate } 521*7c478bd9Sstevel@tonic-gate if (filter != 0 && strstr(instr, filter) == 0) { 522*7c478bd9Sstevel@tonic-gate /* 523*7c478bd9Sstevel@tonic-gate * Optimization: if the entry doesn't contain the 524*7c478bd9Sstevel@tonic-gate * filter string then it can't be the entry we want, 525*7c478bd9Sstevel@tonic-gate * so don't bother looking more closely at it. 526*7c478bd9Sstevel@tonic-gate */ 527*7c478bd9Sstevel@tonic-gate continue; 528*7c478bd9Sstevel@tonic-gate } 529*7c478bd9Sstevel@tonic-gate if (netdb) { 530*7c478bd9Sstevel@tonic-gate char *first; 531*7c478bd9Sstevel@tonic-gate char *last; 532*7c478bd9Sstevel@tonic-gate 533*7c478bd9Sstevel@tonic-gate if ((last = strchr(instr, '#')) == 0) { 534*7c478bd9Sstevel@tonic-gate last = instr + linelen; 535*7c478bd9Sstevel@tonic-gate } 536*7c478bd9Sstevel@tonic-gate *last-- = '\0'; /* Nuke '\n' or #comment */ 537*7c478bd9Sstevel@tonic-gate 538*7c478bd9Sstevel@tonic-gate /* 539*7c478bd9Sstevel@tonic-gate * Skip leading whitespace. Normally there isn't 540*7c478bd9Sstevel@tonic-gate * any, so it's not worth calling strspn(). 541*7c478bd9Sstevel@tonic-gate */ 542*7c478bd9Sstevel@tonic-gate for (first = instr; isspace(*first); first++) { 543*7c478bd9Sstevel@tonic-gate ; 544*7c478bd9Sstevel@tonic-gate } 545*7c478bd9Sstevel@tonic-gate if (*first == '\0') { 546*7c478bd9Sstevel@tonic-gate continue; 547*7c478bd9Sstevel@tonic-gate } 548*7c478bd9Sstevel@tonic-gate /* 549*7c478bd9Sstevel@tonic-gate * Found something non-blank on the line. Skip back 550*7c478bd9Sstevel@tonic-gate * over any trailing whitespace; since we know 551*7c478bd9Sstevel@tonic-gate * there's non-whitespace earlier in the line, 552*7c478bd9Sstevel@tonic-gate * checking for termination is easy. 553*7c478bd9Sstevel@tonic-gate */ 554*7c478bd9Sstevel@tonic-gate while (isspace(*last)) { 555*7c478bd9Sstevel@tonic-gate --last; 556*7c478bd9Sstevel@tonic-gate } 557*7c478bd9Sstevel@tonic-gate linelen = last - first + 1; 558*7c478bd9Sstevel@tonic-gate if (first != instr) { 559*7c478bd9Sstevel@tonic-gate instr = first; 560*7c478bd9Sstevel@tonic-gate } 561*7c478bd9Sstevel@tonic-gate } 562*7c478bd9Sstevel@tonic-gate argp->returnval = 0; 563*7c478bd9Sstevel@tonic-gate func = argp->str2ent; 564*7c478bd9Sstevel@tonic-gate parsestat = (*func)(instr, linelen, argp->buf.result, 565*7c478bd9Sstevel@tonic-gate argp->buf.buffer, argp->buf.buflen); 566*7c478bd9Sstevel@tonic-gate if (parsestat == NSS_STR_PARSE_SUCCESS) { 567*7c478bd9Sstevel@tonic-gate argp->returnval = argp->buf.result; 568*7c478bd9Sstevel@tonic-gate if (check == 0 || (*check)(argp)) { 569*7c478bd9Sstevel@tonic-gate res = NSS_SUCCESS; 570*7c478bd9Sstevel@tonic-gate break; 571*7c478bd9Sstevel@tonic-gate } 572*7c478bd9Sstevel@tonic-gate } else if (parsestat == NSS_STR_PARSE_ERANGE) { 573*7c478bd9Sstevel@tonic-gate argp->erange = 1; 574*7c478bd9Sstevel@tonic-gate break; 575*7c478bd9Sstevel@tonic-gate } 576*7c478bd9Sstevel@tonic-gate } 577*7c478bd9Sstevel@tonic-gate /* 578*7c478bd9Sstevel@tonic-gate * stayopen is set to 0 by default in order to close the opened 579*7c478bd9Sstevel@tonic-gate * file. Some applications may break if it is set to 1. 580*7c478bd9Sstevel@tonic-gate */ 581*7c478bd9Sstevel@tonic-gate if (check != 0 && !argp->stayopen) { 582*7c478bd9Sstevel@tonic-gate (void) _nss_compat_endent(be, 0); 583*7c478bd9Sstevel@tonic-gate } 584*7c478bd9Sstevel@tonic-gate 585*7c478bd9Sstevel@tonic-gate if (res != NSS_SUCCESS) { 586*7c478bd9Sstevel@tonic-gate if ((op_num == NSS_DBOP_USERATTR_BYNAME) || 587*7c478bd9Sstevel@tonic-gate (op_num == NSS_DBOP_AUDITUSER_BYNAME)) { 588*7c478bd9Sstevel@tonic-gate res = nss_search(be->db_rootp, 589*7c478bd9Sstevel@tonic-gate be->db_initf, 590*7c478bd9Sstevel@tonic-gate op_num, 591*7c478bd9Sstevel@tonic-gate argp); 592*7c478bd9Sstevel@tonic-gate } else { 593*7c478bd9Sstevel@tonic-gate res = nss_getent(be->db_rootp, 594*7c478bd9Sstevel@tonic-gate be->db_initf, &be->db_context, argp); 595*7c478bd9Sstevel@tonic-gate } 596*7c478bd9Sstevel@tonic-gate if (res != NSS_SUCCESS) { 597*7c478bd9Sstevel@tonic-gate argp->returnval = 0; 598*7c478bd9Sstevel@tonic-gate argp->erange = 0; 599*7c478bd9Sstevel@tonic-gate } 600*7c478bd9Sstevel@tonic-gate } 601*7c478bd9Sstevel@tonic-gate 602*7c478bd9Sstevel@tonic-gate return (res); 603*7c478bd9Sstevel@tonic-gate } 604*7c478bd9Sstevel@tonic-gate 605*7c478bd9Sstevel@tonic-gate nss_status_t 606*7c478bd9Sstevel@tonic-gate _nss_compat_XY_all(be, args, check, op_num) 607*7c478bd9Sstevel@tonic-gate compat_backend_ptr_t be; 608*7c478bd9Sstevel@tonic-gate nss_XbyY_args_t *args; 609*7c478bd9Sstevel@tonic-gate compat_XY_check_func check; 610*7c478bd9Sstevel@tonic-gate nss_dbop_t op_num; 611*7c478bd9Sstevel@tonic-gate { 612*7c478bd9Sstevel@tonic-gate nss_status_t res; 613*7c478bd9Sstevel@tonic-gate int parsestat; 614*7c478bd9Sstevel@tonic-gate 615*7c478bd9Sstevel@tonic-gate if (be->buf == 0 && 616*7c478bd9Sstevel@tonic-gate (be->buf = malloc(be->minbuf)) == 0) { 617*7c478bd9Sstevel@tonic-gate return (NSS_UNAVAIL); /* really panic, malloc failed */ 618*7c478bd9Sstevel@tonic-gate } 619*7c478bd9Sstevel@tonic-gate 620*7c478bd9Sstevel@tonic-gate if ((res = _nss_compat_setent(be, 0)) != NSS_SUCCESS) { 621*7c478bd9Sstevel@tonic-gate return (res); 622*7c478bd9Sstevel@tonic-gate } 623*7c478bd9Sstevel@tonic-gate 624*7c478bd9Sstevel@tonic-gate res = NSS_NOTFOUND; 625*7c478bd9Sstevel@tonic-gate 626*7c478bd9Sstevel@tonic-gate /*CONSTCOND*/ 627*7c478bd9Sstevel@tonic-gate while (1) { 628*7c478bd9Sstevel@tonic-gate int linelen; 629*7c478bd9Sstevel@tonic-gate char *instr = be->buf; 630*7c478bd9Sstevel@tonic-gate char *colon; 631*7c478bd9Sstevel@tonic-gate 632*7c478bd9Sstevel@tonic-gate linelen = read_line(be->f, instr, be->minbuf); 633*7c478bd9Sstevel@tonic-gate if (linelen < 0) { 634*7c478bd9Sstevel@tonic-gate /* End of file */ 635*7c478bd9Sstevel@tonic-gate args->returnval = 0; 636*7c478bd9Sstevel@tonic-gate args->erange = 0; 637*7c478bd9Sstevel@tonic-gate break; 638*7c478bd9Sstevel@tonic-gate } 639*7c478bd9Sstevel@tonic-gate 640*7c478bd9Sstevel@tonic-gate args->returnval = 0; /* reset for both types of entries */ 641*7c478bd9Sstevel@tonic-gate 642*7c478bd9Sstevel@tonic-gate if (instr[0] != '+' && instr[0] != '-') { 643*7c478bd9Sstevel@tonic-gate /* Simple, wholesome, God-fearing entry */ 644*7c478bd9Sstevel@tonic-gate parsestat = (*args->str2ent)(instr, linelen, 645*7c478bd9Sstevel@tonic-gate args->buf.result, 646*7c478bd9Sstevel@tonic-gate args->buf.buffer, 647*7c478bd9Sstevel@tonic-gate args->buf.buflen); 648*7c478bd9Sstevel@tonic-gate if (parsestat == NSS_STR_PARSE_SUCCESS) { 649*7c478bd9Sstevel@tonic-gate args->returnval = args->buf.result; 650*7c478bd9Sstevel@tonic-gate if ((*check)(args) != 0) { 651*7c478bd9Sstevel@tonic-gate res = NSS_SUCCESS; 652*7c478bd9Sstevel@tonic-gate break; 653*7c478bd9Sstevel@tonic-gate } 654*7c478bd9Sstevel@tonic-gate 655*7c478bd9Sstevel@tonic-gate /* ===> Check the Dani logic here... */ 656*7c478bd9Sstevel@tonic-gate 657*7c478bd9Sstevel@tonic-gate } else if (parsestat == NSS_STR_PARSE_ERANGE) { 658*7c478bd9Sstevel@tonic-gate args->erange = 1; 659*7c478bd9Sstevel@tonic-gate res = NSS_NOTFOUND; 660*7c478bd9Sstevel@tonic-gate break; 661*7c478bd9Sstevel@tonic-gate /* should we just skip this one long line ? */ 662*7c478bd9Sstevel@tonic-gate } /* else if (parsestat == NSS_STR_PARSE_PARSE) */ 663*7c478bd9Sstevel@tonic-gate /* don't care ! */ 664*7c478bd9Sstevel@tonic-gate 665*7c478bd9Sstevel@tonic-gate /* ==> ?? */ continue; 666*7c478bd9Sstevel@tonic-gate } 667*7c478bd9Sstevel@tonic-gate 668*7c478bd9Sstevel@tonic-gate /* 669*7c478bd9Sstevel@tonic-gate * Process "+", "+name", "+@netgroup", "-name" or "-@netgroup" 670*7c478bd9Sstevel@tonic-gate * 671*7c478bd9Sstevel@tonic-gate * This code is optimized for lookups by name. 672*7c478bd9Sstevel@tonic-gate * 673*7c478bd9Sstevel@tonic-gate * For lookups by identifier search key cannot be matched with 674*7c478bd9Sstevel@tonic-gate * the name of the "+" or "-" entry. So nss_search() is to be 675*7c478bd9Sstevel@tonic-gate * called before extracting the name i.e. via (*be->getnamef)(). 676*7c478bd9Sstevel@tonic-gate * 677*7c478bd9Sstevel@tonic-gate * But for lookups by name, search key is compared with the name 678*7c478bd9Sstevel@tonic-gate * of the "+" or "-" entry to acquire a match and thus 679*7c478bd9Sstevel@tonic-gate * unnesessary calls to nss_search() is eliminated. Also for 680*7c478bd9Sstevel@tonic-gate * matching "-" entries, calls to nss_search() is eliminated. 681*7c478bd9Sstevel@tonic-gate */ 682*7c478bd9Sstevel@tonic-gate 683*7c478bd9Sstevel@tonic-gate if ((colon = strchr(instr, ':')) != 0) { 684*7c478bd9Sstevel@tonic-gate *colon = '\0'; /* terminate field to extract name */ 685*7c478bd9Sstevel@tonic-gate } 686*7c478bd9Sstevel@tonic-gate 687*7c478bd9Sstevel@tonic-gate if (instr[1] == '@') { 688*7c478bd9Sstevel@tonic-gate /* 689*7c478bd9Sstevel@tonic-gate * Case 1: 690*7c478bd9Sstevel@tonic-gate * The entry is of the form "+@netgroup" or 691*7c478bd9Sstevel@tonic-gate * "-@netgroup". If we're performing a lookup by name, 692*7c478bd9Sstevel@tonic-gate * we can simply extract the name from the search key 693*7c478bd9Sstevel@tonic-gate * (i.e. args->key.name). If not, then we must call 694*7c478bd9Sstevel@tonic-gate * nss_search() before extracting the name via the 695*7c478bd9Sstevel@tonic-gate * get_XXname() function. i.e. (*be->getnamef)(args). 696*7c478bd9Sstevel@tonic-gate */ 697*7c478bd9Sstevel@tonic-gate if (_is_nss_lookup_by_name(0, op_num) != 0) { 698*7c478bd9Sstevel@tonic-gate /* compare then search */ 699*7c478bd9Sstevel@tonic-gate if (!be->permit_netgroups || 700*7c478bd9Sstevel@tonic-gate !netgr_in(be, instr + 2, args->key.name)) 701*7c478bd9Sstevel@tonic-gate continue; 702*7c478bd9Sstevel@tonic-gate if (instr[0] == '+') { 703*7c478bd9Sstevel@tonic-gate /* need to search for "+" entry */ 704*7c478bd9Sstevel@tonic-gate nss_search(be->db_rootp, be->db_initf, op_num, 705*7c478bd9Sstevel@tonic-gate args); 706*7c478bd9Sstevel@tonic-gate if (args->returnval == 0) 707*7c478bd9Sstevel@tonic-gate continue; 708*7c478bd9Sstevel@tonic-gate } 709*7c478bd9Sstevel@tonic-gate } else { 710*7c478bd9Sstevel@tonic-gate /* search then compare */ 711*7c478bd9Sstevel@tonic-gate nss_search(be->db_rootp, be->db_initf, op_num, args); 712*7c478bd9Sstevel@tonic-gate if (args->returnval == 0) 713*7c478bd9Sstevel@tonic-gate continue; 714*7c478bd9Sstevel@tonic-gate if (!be->permit_netgroups || 715*7c478bd9Sstevel@tonic-gate !netgr_in(be, instr + 2, (*be->getnamef)(args))) 716*7c478bd9Sstevel@tonic-gate continue; 717*7c478bd9Sstevel@tonic-gate } 718*7c478bd9Sstevel@tonic-gate } /* end of case 1 */ 719*7c478bd9Sstevel@tonic-gate else if (instr[1] == '\0') { 720*7c478bd9Sstevel@tonic-gate /* 721*7c478bd9Sstevel@tonic-gate * Case 2: 722*7c478bd9Sstevel@tonic-gate * The entry is of the form "+" or "-". The former 723*7c478bd9Sstevel@tonic-gate * allows all entries from name services. The latter 724*7c478bd9Sstevel@tonic-gate * is illegal and ought to be ignored. 725*7c478bd9Sstevel@tonic-gate */ 726*7c478bd9Sstevel@tonic-gate if (instr[0] == '-') 727*7c478bd9Sstevel@tonic-gate continue; 728*7c478bd9Sstevel@tonic-gate /* need to search for "+" entry */ 729*7c478bd9Sstevel@tonic-gate nss_search(be->db_rootp, be->db_initf, op_num, args); 730*7c478bd9Sstevel@tonic-gate if (args->returnval == 0) 731*7c478bd9Sstevel@tonic-gate continue; 732*7c478bd9Sstevel@tonic-gate } /* end of case 2 */ 733*7c478bd9Sstevel@tonic-gate else { 734*7c478bd9Sstevel@tonic-gate /* 735*7c478bd9Sstevel@tonic-gate * Case 3: 736*7c478bd9Sstevel@tonic-gate * The entry is of the form "+name" or "-name". 737*7c478bd9Sstevel@tonic-gate * If we're performing a lookup by name, we can simply 738*7c478bd9Sstevel@tonic-gate * extract the name from the search key 739*7c478bd9Sstevel@tonic-gate * (i.e. args->key.name). If not, then we must call 740*7c478bd9Sstevel@tonic-gate * nss_search() before extracting the name via the 741*7c478bd9Sstevel@tonic-gate * get_XXname() function. i.e. (*be->getnamef)(args). 742*7c478bd9Sstevel@tonic-gate */ 743*7c478bd9Sstevel@tonic-gate if (_is_nss_lookup_by_name(0, op_num) != 0) { 744*7c478bd9Sstevel@tonic-gate /* compare then search */ 745*7c478bd9Sstevel@tonic-gate if (strcmp(instr + 1, args->key.name) != 0) 746*7c478bd9Sstevel@tonic-gate continue; 747*7c478bd9Sstevel@tonic-gate if (instr[0] == '+') { 748*7c478bd9Sstevel@tonic-gate /* need to search for "+" entry */ 749*7c478bd9Sstevel@tonic-gate nss_search(be->db_rootp, be->db_initf, 750*7c478bd9Sstevel@tonic-gate op_num, args); 751*7c478bd9Sstevel@tonic-gate if (args->returnval == 0) 752*7c478bd9Sstevel@tonic-gate continue; 753*7c478bd9Sstevel@tonic-gate } 754*7c478bd9Sstevel@tonic-gate } else { 755*7c478bd9Sstevel@tonic-gate /* search then compare */ 756*7c478bd9Sstevel@tonic-gate nss_search(be->db_rootp, be->db_initf, op_num, 757*7c478bd9Sstevel@tonic-gate args); 758*7c478bd9Sstevel@tonic-gate if (args->returnval == 0) 759*7c478bd9Sstevel@tonic-gate continue; 760*7c478bd9Sstevel@tonic-gate if (strcmp(instr + 1, (*be->getnamef)(args)) 761*7c478bd9Sstevel@tonic-gate != 0) 762*7c478bd9Sstevel@tonic-gate continue; 763*7c478bd9Sstevel@tonic-gate } 764*7c478bd9Sstevel@tonic-gate } /* end of case 3 */ 765*7c478bd9Sstevel@tonic-gate if (instr[0] == '-') { 766*7c478bd9Sstevel@tonic-gate /* no need to search for "-" entry */ 767*7c478bd9Sstevel@tonic-gate args->returnval = 0; 768*7c478bd9Sstevel@tonic-gate args->erange = 0; 769*7c478bd9Sstevel@tonic-gate res = NSS_NOTFOUND; 770*7c478bd9Sstevel@tonic-gate } else { 771*7c478bd9Sstevel@tonic-gate if (colon != 0) 772*7c478bd9Sstevel@tonic-gate *colon = ':'; /* restoration */ 773*7c478bd9Sstevel@tonic-gate res = do_merge(be, args, instr, linelen); 774*7c478bd9Sstevel@tonic-gate } 775*7c478bd9Sstevel@tonic-gate break; 776*7c478bd9Sstevel@tonic-gate } 777*7c478bd9Sstevel@tonic-gate 778*7c478bd9Sstevel@tonic-gate /* 779*7c478bd9Sstevel@tonic-gate * stayopen is set to 0 by default in order to close the opened 780*7c478bd9Sstevel@tonic-gate * file. Some applications may break if it is set to 1. 781*7c478bd9Sstevel@tonic-gate */ 782*7c478bd9Sstevel@tonic-gate if (!args->stayopen) { 783*7c478bd9Sstevel@tonic-gate (void) _nss_compat_endent(be, 0); 784*7c478bd9Sstevel@tonic-gate } 785*7c478bd9Sstevel@tonic-gate 786*7c478bd9Sstevel@tonic-gate return (res); 787*7c478bd9Sstevel@tonic-gate } 788*7c478bd9Sstevel@tonic-gate 789*7c478bd9Sstevel@tonic-gate nss_status_t 790*7c478bd9Sstevel@tonic-gate _nss_compat_getent(be, a) 791*7c478bd9Sstevel@tonic-gate compat_backend_ptr_t be; 792*7c478bd9Sstevel@tonic-gate void *a; 793*7c478bd9Sstevel@tonic-gate { 794*7c478bd9Sstevel@tonic-gate nss_XbyY_args_t *args = (nss_XbyY_args_t *)a; 795*7c478bd9Sstevel@tonic-gate nss_status_t res; 796*7c478bd9Sstevel@tonic-gate char *colon = 0; /* <=== need comment re lifetime */ 797*7c478bd9Sstevel@tonic-gate 798*7c478bd9Sstevel@tonic-gate if (be->f == 0) { 799*7c478bd9Sstevel@tonic-gate if ((res = _nss_compat_setent(be, 0)) != NSS_SUCCESS) { 800*7c478bd9Sstevel@tonic-gate return (res); 801*7c478bd9Sstevel@tonic-gate } 802*7c478bd9Sstevel@tonic-gate } 803*7c478bd9Sstevel@tonic-gate 804*7c478bd9Sstevel@tonic-gate if (be->buf == 0 && 805*7c478bd9Sstevel@tonic-gate (be->buf = malloc(be->minbuf)) == 0) { 806*7c478bd9Sstevel@tonic-gate return (NSS_UNAVAIL); /* really panic, malloc failed */ 807*7c478bd9Sstevel@tonic-gate } 808*7c478bd9Sstevel@tonic-gate 809*7c478bd9Sstevel@tonic-gate /*CONSTCOND*/ 810*7c478bd9Sstevel@tonic-gate while (1) { 811*7c478bd9Sstevel@tonic-gate char *instr = be->buf; 812*7c478bd9Sstevel@tonic-gate int linelen; 813*7c478bd9Sstevel@tonic-gate char *name; /* === Need more distinctive label */ 814*7c478bd9Sstevel@tonic-gate const char *savename; 815*7c478bd9Sstevel@tonic-gate 816*7c478bd9Sstevel@tonic-gate /* 817*7c478bd9Sstevel@tonic-gate * In the code below... 818*7c478bd9Sstevel@tonic-gate * break means "I found one, I think" (i.e. goto the 819*7c478bd9Sstevel@tonic-gate * code after the end of the switch statement), 820*7c478bd9Sstevel@tonic-gate * continue means "Next candidate" 821*7c478bd9Sstevel@tonic-gate * (i.e. loop around to the switch statement), 822*7c478bd9Sstevel@tonic-gate * return means "I'm quite sure" (either Yes or No). 823*7c478bd9Sstevel@tonic-gate */ 824*7c478bd9Sstevel@tonic-gate switch (be->state) { 825*7c478bd9Sstevel@tonic-gate 826*7c478bd9Sstevel@tonic-gate case GETENT_DONE: 827*7c478bd9Sstevel@tonic-gate args->returnval = 0; 828*7c478bd9Sstevel@tonic-gate args->erange = 0; 829*7c478bd9Sstevel@tonic-gate return (NSS_NOTFOUND); 830*7c478bd9Sstevel@tonic-gate 831*7c478bd9Sstevel@tonic-gate case GETENT_ATTRDB: 832*7c478bd9Sstevel@tonic-gate res = _attrdb_compat_XY_all(be, 833*7c478bd9Sstevel@tonic-gate args, 1, (compat_XY_check_func)NULL, 0); 834*7c478bd9Sstevel@tonic-gate return (res); 835*7c478bd9Sstevel@tonic-gate 836*7c478bd9Sstevel@tonic-gate case GETENT_FILE: 837*7c478bd9Sstevel@tonic-gate linelen = read_line(be->f, instr, be->minbuf); 838*7c478bd9Sstevel@tonic-gate if (linelen < 0) { 839*7c478bd9Sstevel@tonic-gate /* End of file */ 840*7c478bd9Sstevel@tonic-gate be->state = GETENT_DONE; 841*7c478bd9Sstevel@tonic-gate continue; 842*7c478bd9Sstevel@tonic-gate } 843*7c478bd9Sstevel@tonic-gate if ((colon = strchr(instr, ':')) != 0) { 844*7c478bd9Sstevel@tonic-gate *colon = '\0'; 845*7c478bd9Sstevel@tonic-gate } 846*7c478bd9Sstevel@tonic-gate if (instr[0] == '-') { 847*7c478bd9Sstevel@tonic-gate if (instr[1] != '@') { 848*7c478bd9Sstevel@tonic-gate strset_add(&be->minuses, instr + 1); 849*7c478bd9Sstevel@tonic-gate } else if (be->permit_netgroups) { 850*7c478bd9Sstevel@tonic-gate netgr_set(be, instr + 2); 851*7c478bd9Sstevel@tonic-gate while (netgr_next_u(be, &name)) { 852*7c478bd9Sstevel@tonic-gate strset_add(&be->minuses, 853*7c478bd9Sstevel@tonic-gate name); 854*7c478bd9Sstevel@tonic-gate } 855*7c478bd9Sstevel@tonic-gate netgr_end(be); 856*7c478bd9Sstevel@tonic-gate } /* Else (silently) ignore the entry */ 857*7c478bd9Sstevel@tonic-gate continue; 858*7c478bd9Sstevel@tonic-gate } else if (instr[0] != '+') { 859*7c478bd9Sstevel@tonic-gate int parsestat; 860*7c478bd9Sstevel@tonic-gate /* 861*7c478bd9Sstevel@tonic-gate * Normal entry, no +/- nonsense 862*7c478bd9Sstevel@tonic-gate */ 863*7c478bd9Sstevel@tonic-gate if (colon != 0) { 864*7c478bd9Sstevel@tonic-gate *colon = ':'; 865*7c478bd9Sstevel@tonic-gate } 866*7c478bd9Sstevel@tonic-gate args->returnval = 0; 867*7c478bd9Sstevel@tonic-gate parsestat = (*args->str2ent)(instr, linelen, 868*7c478bd9Sstevel@tonic-gate args->buf.result, 869*7c478bd9Sstevel@tonic-gate args->buf.buffer, 870*7c478bd9Sstevel@tonic-gate args->buf.buflen); 871*7c478bd9Sstevel@tonic-gate if (parsestat == NSS_STR_PARSE_SUCCESS) { 872*7c478bd9Sstevel@tonic-gate args->returnval = args->buf.result; 873*7c478bd9Sstevel@tonic-gate return (NSS_SUCCESS); 874*7c478bd9Sstevel@tonic-gate } 875*7c478bd9Sstevel@tonic-gate /* ==> ?? Treat ERANGE differently ?? */ 876*7c478bd9Sstevel@tonic-gate if (parsestat == NSS_STR_PARSE_ERANGE) { 877*7c478bd9Sstevel@tonic-gate args->returnval = 0; 878*7c478bd9Sstevel@tonic-gate args->erange = 1; 879*7c478bd9Sstevel@tonic-gate return (NSS_NOTFOUND); 880*7c478bd9Sstevel@tonic-gate } 881*7c478bd9Sstevel@tonic-gate /* Skip the offending entry, get next */ 882*7c478bd9Sstevel@tonic-gate continue; 883*7c478bd9Sstevel@tonic-gate } else if (instr[1] == '\0') { 884*7c478bd9Sstevel@tonic-gate /* Plain "+" */ 885*7c478bd9Sstevel@tonic-gate nss_setent(be->db_rootp, be->db_initf, 886*7c478bd9Sstevel@tonic-gate &be->db_context); 887*7c478bd9Sstevel@tonic-gate be->state = GETENT_ALL; 888*7c478bd9Sstevel@tonic-gate be->linelen = linelen; 889*7c478bd9Sstevel@tonic-gate continue; 890*7c478bd9Sstevel@tonic-gate } else if (instr[1] == '@') { 891*7c478bd9Sstevel@tonic-gate /* "+@netgroup" */ 892*7c478bd9Sstevel@tonic-gate netgr_set(be, instr + 2); 893*7c478bd9Sstevel@tonic-gate be->state = GETENT_NETGROUP; 894*7c478bd9Sstevel@tonic-gate be->linelen = linelen; 895*7c478bd9Sstevel@tonic-gate continue; 896*7c478bd9Sstevel@tonic-gate } else { 897*7c478bd9Sstevel@tonic-gate /* "+name" */ 898*7c478bd9Sstevel@tonic-gate name = instr + 1; 899*7c478bd9Sstevel@tonic-gate break; 900*7c478bd9Sstevel@tonic-gate } 901*7c478bd9Sstevel@tonic-gate /* NOTREACHED */ 902*7c478bd9Sstevel@tonic-gate 903*7c478bd9Sstevel@tonic-gate case GETENT_ALL: 904*7c478bd9Sstevel@tonic-gate linelen = be->linelen; 905*7c478bd9Sstevel@tonic-gate args->returnval = 0; 906*7c478bd9Sstevel@tonic-gate nss_getent(be->db_rootp, be->db_initf, 907*7c478bd9Sstevel@tonic-gate &be->db_context, args); 908*7c478bd9Sstevel@tonic-gate if (args->returnval == 0) { 909*7c478bd9Sstevel@tonic-gate /* ==> ?? Treat ERANGE differently ?? */ 910*7c478bd9Sstevel@tonic-gate nss_endent(be->db_rootp, be->db_initf, 911*7c478bd9Sstevel@tonic-gate &be->db_context); 912*7c478bd9Sstevel@tonic-gate be->state = GETENT_FILE; 913*7c478bd9Sstevel@tonic-gate continue; 914*7c478bd9Sstevel@tonic-gate } 915*7c478bd9Sstevel@tonic-gate if (strset_in(&be->minuses, (*be->getnamef)(args))) { 916*7c478bd9Sstevel@tonic-gate continue; 917*7c478bd9Sstevel@tonic-gate } 918*7c478bd9Sstevel@tonic-gate name = 0; /* tell code below we've done the lookup */ 919*7c478bd9Sstevel@tonic-gate break; 920*7c478bd9Sstevel@tonic-gate 921*7c478bd9Sstevel@tonic-gate case GETENT_NETGROUP: 922*7c478bd9Sstevel@tonic-gate linelen = be->linelen; 923*7c478bd9Sstevel@tonic-gate if (!netgr_next_u(be, &name)) { 924*7c478bd9Sstevel@tonic-gate netgr_end(be); 925*7c478bd9Sstevel@tonic-gate be->state = GETENT_FILE; 926*7c478bd9Sstevel@tonic-gate continue; 927*7c478bd9Sstevel@tonic-gate } 928*7c478bd9Sstevel@tonic-gate /* pass "name" variable to code below... */ 929*7c478bd9Sstevel@tonic-gate break; 930*7c478bd9Sstevel@tonic-gate } 931*7c478bd9Sstevel@tonic-gate 932*7c478bd9Sstevel@tonic-gate if (name != 0) { 933*7c478bd9Sstevel@tonic-gate if (strset_in(&be->minuses, name)) { 934*7c478bd9Sstevel@tonic-gate continue; 935*7c478bd9Sstevel@tonic-gate } 936*7c478bd9Sstevel@tonic-gate /* 937*7c478bd9Sstevel@tonic-gate * Do a getXXXnam(name). If we were being pure, 938*7c478bd9Sstevel@tonic-gate * we'd introduce yet another function-pointer 939*7c478bd9Sstevel@tonic-gate * that the database-specific code had to supply 940*7c478bd9Sstevel@tonic-gate * to us. Instead we'll be grotty and hard-code 941*7c478bd9Sstevel@tonic-gate * the knowledge that 942*7c478bd9Sstevel@tonic-gate * (a) The username is always passwd in key.name, 943*7c478bd9Sstevel@tonic-gate * (b) NSS_DBOP_PASSWD_BYNAME == 944*7c478bd9Sstevel@tonic-gate * NSS_DBOP_SHADOW_BYNAME == 945*7c478bd9Sstevel@tonic-gate * NSS_DBOP_next_iter. 946*7c478bd9Sstevel@tonic-gate */ 947*7c478bd9Sstevel@tonic-gate savename = args->key.name; 948*7c478bd9Sstevel@tonic-gate args->key.name = name; 949*7c478bd9Sstevel@tonic-gate args->returnval = 0; 950*7c478bd9Sstevel@tonic-gate nss_search(be->db_rootp, be->db_initf, 951*7c478bd9Sstevel@tonic-gate NSS_DBOP_next_iter, args); 952*7c478bd9Sstevel@tonic-gate args->key.name = savename; /* In case anyone cares */ 953*7c478bd9Sstevel@tonic-gate } 954*7c478bd9Sstevel@tonic-gate /* 955*7c478bd9Sstevel@tonic-gate * Found one via "+", "+name" or "@netgroup". 956*7c478bd9Sstevel@tonic-gate * Override some fields if the /etc file says to do so. 957*7c478bd9Sstevel@tonic-gate */ 958*7c478bd9Sstevel@tonic-gate if (args->returnval == 0) { 959*7c478bd9Sstevel@tonic-gate /* ==> ?? Should treat erange differently? */ 960*7c478bd9Sstevel@tonic-gate continue; 961*7c478bd9Sstevel@tonic-gate } 962*7c478bd9Sstevel@tonic-gate /* 'colon' was set umpteen iterations ago in GETENT_FILE */ 963*7c478bd9Sstevel@tonic-gate if (colon != 0) { 964*7c478bd9Sstevel@tonic-gate *colon = ':'; 965*7c478bd9Sstevel@tonic-gate colon = 0; 966*7c478bd9Sstevel@tonic-gate } 967*7c478bd9Sstevel@tonic-gate return (do_merge(be, args, instr, linelen)); 968*7c478bd9Sstevel@tonic-gate } 969*7c478bd9Sstevel@tonic-gate } 970*7c478bd9Sstevel@tonic-gate 971*7c478bd9Sstevel@tonic-gate /* We don't use this directly; we just copy the bits when we want to */ 972*7c478bd9Sstevel@tonic-gate /* initialize the variable (in the compat_backend struct) that we do use */ 973*7c478bd9Sstevel@tonic-gate static DEFINE_NSS_GETENT(context_initval); 974*7c478bd9Sstevel@tonic-gate 975*7c478bd9Sstevel@tonic-gate nss_backend_t * 976*7c478bd9Sstevel@tonic-gate _nss_compat_constr(ops, n_ops, filename, min_bufsize, rootp, initf, netgroups, 977*7c478bd9Sstevel@tonic-gate getname_func, merge_func) 978*7c478bd9Sstevel@tonic-gate compat_backend_op_t ops[]; 979*7c478bd9Sstevel@tonic-gate int n_ops; 980*7c478bd9Sstevel@tonic-gate const char *filename; 981*7c478bd9Sstevel@tonic-gate int min_bufsize; 982*7c478bd9Sstevel@tonic-gate nss_db_root_t *rootp; 983*7c478bd9Sstevel@tonic-gate nss_db_initf_t initf; 984*7c478bd9Sstevel@tonic-gate int netgroups; 985*7c478bd9Sstevel@tonic-gate compat_get_name getname_func; 986*7c478bd9Sstevel@tonic-gate compat_merge_func merge_func; 987*7c478bd9Sstevel@tonic-gate { 988*7c478bd9Sstevel@tonic-gate compat_backend_ptr_t be; 989*7c478bd9Sstevel@tonic-gate 990*7c478bd9Sstevel@tonic-gate if ((be = (compat_backend_ptr_t)malloc(sizeof (*be))) == 0) { 991*7c478bd9Sstevel@tonic-gate return (0); 992*7c478bd9Sstevel@tonic-gate } 993*7c478bd9Sstevel@tonic-gate be->ops = ops; 994*7c478bd9Sstevel@tonic-gate be->n_ops = n_ops; 995*7c478bd9Sstevel@tonic-gate be->filename = filename; 996*7c478bd9Sstevel@tonic-gate be->f = 0; 997*7c478bd9Sstevel@tonic-gate be->minbuf = min_bufsize; 998*7c478bd9Sstevel@tonic-gate be->buf = 0; 999*7c478bd9Sstevel@tonic-gate 1000*7c478bd9Sstevel@tonic-gate be->db_rootp = rootp; 1001*7c478bd9Sstevel@tonic-gate be->db_initf = initf; 1002*7c478bd9Sstevel@tonic-gate be->db_context = context_initval; 1003*7c478bd9Sstevel@tonic-gate 1004*7c478bd9Sstevel@tonic-gate be->getnamef = getname_func; 1005*7c478bd9Sstevel@tonic-gate be->mergef = merge_func; 1006*7c478bd9Sstevel@tonic-gate 1007*7c478bd9Sstevel@tonic-gate if ((strcmp(be->filename, USERATTR_FILENAME) == 0) || 1008*7c478bd9Sstevel@tonic-gate (strcmp(be->filename, AUDITUSER_FILENAME) == 0)) 1009*7c478bd9Sstevel@tonic-gate be->state = GETENT_ATTRDB; 1010*7c478bd9Sstevel@tonic-gate else 1011*7c478bd9Sstevel@tonic-gate be->state = GETENT_FILE; /* i.e. do Automatic setent(); */ 1012*7c478bd9Sstevel@tonic-gate 1013*7c478bd9Sstevel@tonic-gate be->minuses = 0; 1014*7c478bd9Sstevel@tonic-gate 1015*7c478bd9Sstevel@tonic-gate be->permit_netgroups = netgroups; 1016*7c478bd9Sstevel@tonic-gate be->yp_domain = 0; 1017*7c478bd9Sstevel@tonic-gate be->getnetgrent_backend = 0; 1018*7c478bd9Sstevel@tonic-gate be->netgr_buffer = 0; 1019*7c478bd9Sstevel@tonic-gate 1020*7c478bd9Sstevel@tonic-gate return ((nss_backend_t *)be); 1021*7c478bd9Sstevel@tonic-gate } 1022