1*0Sstevel@tonic-gate /* 2*0Sstevel@tonic-gate * CDDL HEADER START 3*0Sstevel@tonic-gate * 4*0Sstevel@tonic-gate * The contents of this file are subject to the terms of the 5*0Sstevel@tonic-gate * Common Development and Distribution License, Version 1.0 only 6*0Sstevel@tonic-gate * (the "License"). You may not use this file except in compliance 7*0Sstevel@tonic-gate * with the License. 8*0Sstevel@tonic-gate * 9*0Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10*0Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing. 11*0Sstevel@tonic-gate * See the License for the specific language governing permissions 12*0Sstevel@tonic-gate * and limitations under the License. 13*0Sstevel@tonic-gate * 14*0Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each 15*0Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16*0Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the 17*0Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying 18*0Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner] 19*0Sstevel@tonic-gate * 20*0Sstevel@tonic-gate * CDDL HEADER END 21*0Sstevel@tonic-gate */ 22*0Sstevel@tonic-gate /* 23*0Sstevel@tonic-gate * Copyright (c) 2001 by Sun Microsystems, Inc. 24*0Sstevel@tonic-gate * All rights reserved. 25*0Sstevel@tonic-gate */ 26*0Sstevel@tonic-gate 27*0Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI" 28*0Sstevel@tonic-gate 29*0Sstevel@tonic-gate #include <string.h> 30*0Sstevel@tonic-gate #include <sys/syslog.h> 31*0Sstevel@tonic-gate #include <sys/types.h> 32*0Sstevel@tonic-gate #include <rpc/types.h> 33*0Sstevel@tonic-gate #include <rpc/xdr.h> 34*0Sstevel@tonic-gate #include <rpcsvc/nis.h> 35*0Sstevel@tonic-gate 36*0Sstevel@tonic-gate #include "db_mindex_c.h" 37*0Sstevel@tonic-gate 38*0Sstevel@tonic-gate #include "ldap_xdr.h" 39*0Sstevel@tonic-gate #include "ldap_util.h" 40*0Sstevel@tonic-gate 41*0Sstevel@tonic-gate extern bool_t xdr_nis_object(); 42*0Sstevel@tonic-gate 43*0Sstevel@tonic-gate /* 44*0Sstevel@tonic-gate * In order not to change the on-disk NIS+ DB format, we need make sure 45*0Sstevel@tonic-gate * that XDR does nothing for the new structures added to various C++ 46*0Sstevel@tonic-gate * classes. 47*0Sstevel@tonic-gate */ 48*0Sstevel@tonic-gate 49*0Sstevel@tonic-gate bool_t 50*0Sstevel@tonic-gate xdr___nis_table_mapping_t(XDR *xdrs, void *t) { 51*0Sstevel@tonic-gate return (TRUE); 52*0Sstevel@tonic-gate } 53*0Sstevel@tonic-gate 54*0Sstevel@tonic-gate bool_t 55*0Sstevel@tonic-gate xdr___nisdb_ptr_t(XDR *xdrs, void *ptr) { 56*0Sstevel@tonic-gate return (TRUE); 57*0Sstevel@tonic-gate } 58*0Sstevel@tonic-gate 59*0Sstevel@tonic-gate bool_t 60*0Sstevel@tonic-gate xdr___nisdb_dictionary_defer_t(XDR *xdrs, void *defer) { 61*0Sstevel@tonic-gate return (TRUE); 62*0Sstevel@tonic-gate } 63*0Sstevel@tonic-gate 64*0Sstevel@tonic-gate bool_t 65*0Sstevel@tonic-gate xdr___nisdb_rwlock_t(XDR *xdrs, void *rw) { 66*0Sstevel@tonic-gate return (TRUE); 67*0Sstevel@tonic-gate } 68*0Sstevel@tonic-gate 69*0Sstevel@tonic-gate bool_t 70*0Sstevel@tonic-gate xdr___nisdb_flag_t(XDR *xdrs, void *flag) { 71*0Sstevel@tonic-gate return (TRUE); 72*0Sstevel@tonic-gate } 73*0Sstevel@tonic-gate 74*0Sstevel@tonic-gate /* 75*0Sstevel@tonic-gate * Imported from rpc.nisd/nis_db.c 76*0Sstevel@tonic-gate * 77*0Sstevel@tonic-gate * Special abbreviated XDR string which knows that the namep parameter (mainly 78*0Sstevel@tonic-gate * owner and group) has a trailing end which matches the last 'n' characters 79*0Sstevel@tonic-gate * in the domainname part. It makes use of those common characters to 80*0Sstevel@tonic-gate * encode/decode this information. We append an integer string to the 81*0Sstevel@tonic-gate * name to be encoded which denotes the place in the domainname from where the 82*0Sstevel@tonic-gate * common string starts. For example, if the name was "foo.my.domain." and the 83*0Sstevel@tonic-gate * domainname was "my.domain.", the name would be encoded as "foo.10" because 84*0Sstevel@tonic-gate * the length of the common part "my.domain." is 10. 85*0Sstevel@tonic-gate */ 86*0Sstevel@tonic-gate bool_t 87*0Sstevel@tonic-gate xdr_nis_name_abbrev( 88*0Sstevel@tonic-gate XDR *xdrs, 89*0Sstevel@tonic-gate nis_name *namep, 90*0Sstevel@tonic-gate nis_name domainname) /* domainname field from the table */ 91*0Sstevel@tonic-gate { 92*0Sstevel@tonic-gate size_t name_len, dom_len, min_len; 93*0Sstevel@tonic-gate char buf[NIS_MAXNAMELEN]; 94*0Sstevel@tonic-gate char *name; 95*0Sstevel@tonic-gate char *lenstr, *tmp; 96*0Sstevel@tonic-gate int i; 97*0Sstevel@tonic-gate 98*0Sstevel@tonic-gate switch (xdrs->x_op) { 99*0Sstevel@tonic-gate case XDR_ENCODE: 100*0Sstevel@tonic-gate /* Get the start of the common part */ 101*0Sstevel@tonic-gate name = *namep; 102*0Sstevel@tonic-gate name_len = strlen(name); 103*0Sstevel@tonic-gate if (name_len == 0) 104*0Sstevel@tonic-gate return (xdr_nis_name(xdrs, namep)); 105*0Sstevel@tonic-gate dom_len = strlen(domainname); 106*0Sstevel@tonic-gate min_len = (name_len < dom_len) ? name_len : dom_len; 107*0Sstevel@tonic-gate for (i = 1; i <= min_len; i++) { 108*0Sstevel@tonic-gate if (name[name_len - i] != domainname[dom_len - i]) 109*0Sstevel@tonic-gate break; 110*0Sstevel@tonic-gate } 111*0Sstevel@tonic-gate i--; 112*0Sstevel@tonic-gate memcpy(buf, name, name_len - i); 113*0Sstevel@tonic-gate sprintf(buf + name_len - i, ".%d", dom_len - i); 114*0Sstevel@tonic-gate tmp = buf; 115*0Sstevel@tonic-gate return (xdr_nis_name(xdrs, &tmp)); 116*0Sstevel@tonic-gate 117*0Sstevel@tonic-gate case XDR_DECODE: 118*0Sstevel@tonic-gate tmp = buf; 119*0Sstevel@tonic-gate if (!xdr_nis_name(xdrs, &tmp)) 120*0Sstevel@tonic-gate return (FALSE); 121*0Sstevel@tonic-gate if ((buf[0] == NULL) || buf[strlen(buf) - 1] == '.') { 122*0Sstevel@tonic-gate /* It is either a FQN or a NULL string */ 123*0Sstevel@tonic-gate if (*namep) { 124*0Sstevel@tonic-gate strcpy(*namep, buf); 125*0Sstevel@tonic-gate return (TRUE); 126*0Sstevel@tonic-gate } else { 127*0Sstevel@tonic-gate if ((*namep = strdup(buf)) == NULL) 128*0Sstevel@tonic-gate return (FALSE); 129*0Sstevel@tonic-gate else 130*0Sstevel@tonic-gate return (TRUE); 131*0Sstevel@tonic-gate } 132*0Sstevel@tonic-gate } 133*0Sstevel@tonic-gate /* Now concoct the new name */ 134*0Sstevel@tonic-gate if ((lenstr = strrchr(buf, '.')) == NULL) { 135*0Sstevel@tonic-gate /* something went wrong here */ 136*0Sstevel@tonic-gate syslog(LOG_ERR, 137*0Sstevel@tonic-gate "xdr_nis_name_abbrev: no dot found in %s", buf); 138*0Sstevel@tonic-gate return (FALSE); 139*0Sstevel@tonic-gate } 140*0Sstevel@tonic-gate i = atoi(lenstr + 1); 141*0Sstevel@tonic-gate strcpy(lenstr, domainname + i); 142*0Sstevel@tonic-gate if (*namep) { 143*0Sstevel@tonic-gate strcpy(*namep, buf); 144*0Sstevel@tonic-gate } else { 145*0Sstevel@tonic-gate if ((*namep = strdup(buf)) == NULL) 146*0Sstevel@tonic-gate return (FALSE); 147*0Sstevel@tonic-gate } 148*0Sstevel@tonic-gate return (TRUE); 149*0Sstevel@tonic-gate 150*0Sstevel@tonic-gate default: 151*0Sstevel@tonic-gate return (xdr_nis_name(xdrs, namep)); 152*0Sstevel@tonic-gate } 153*0Sstevel@tonic-gate } 154*0Sstevel@tonic-gate 155*0Sstevel@tonic-gate /* 156*0Sstevel@tonic-gate * Imported from rpc.nisd/nis_db.c 157*0Sstevel@tonic-gate * 158*0Sstevel@tonic-gate * special XDR for fetus object. We create the actual object from the 159*0Sstevel@tonic-gate * "forming" object plus the table object. We create this special object to 160*0Sstevel@tonic-gate * save the following components of the nis_object: 161*0Sstevel@tonic-gate * zo_name and zo_domain: replaced by just the length field of 0. We had 162*0Sstevel@tonic-gate * to keep the length field for backward compatibility. If we 163*0Sstevel@tonic-gate * ever change the object format, we should fix this. 164*0Sstevel@tonic-gate * zo_owner and zo_group: we condensed it by abbreviating the common part 165*0Sstevel@tonic-gate * shared between the table object and the entry object 166*0Sstevel@tonic-gate * en_type: Avoided altogether 167*0Sstevel@tonic-gate * zo_type and other en_data: Avoided altogether. 168*0Sstevel@tonic-gate * 169*0Sstevel@tonic-gate * XXX: If the definition of nis_object ever changes, this should be changed. 170*0Sstevel@tonic-gate */ 171*0Sstevel@tonic-gate bool_t 172*0Sstevel@tonic-gate xdr_nis_fetus_object( 173*0Sstevel@tonic-gate XDR *xdrs, 174*0Sstevel@tonic-gate nis_object *objp, /* Entry object */ 175*0Sstevel@tonic-gate nis_object *tobj) /* Table object */ 176*0Sstevel@tonic-gate { 177*0Sstevel@tonic-gate uint_t size; 178*0Sstevel@tonic-gate 179*0Sstevel@tonic-gate if (xdrs->x_op == XDR_FREE) 180*0Sstevel@tonic-gate return (xdr_nis_object(xdrs, objp)); 181*0Sstevel@tonic-gate if (!xdr_nis_oid(xdrs, &objp->zo_oid)) 182*0Sstevel@tonic-gate return (FALSE); 183*0Sstevel@tonic-gate 184*0Sstevel@tonic-gate /* 185*0Sstevel@tonic-gate * While encoding of zo_name, we put 0 in the length field, while for 186*0Sstevel@tonic-gate * decoding, we get the name from the table object. 187*0Sstevel@tonic-gate */ 188*0Sstevel@tonic-gate if (xdrs->x_op == XDR_ENCODE) { 189*0Sstevel@tonic-gate size = 0; 190*0Sstevel@tonic-gate if (!xdr_u_int(xdrs, &size)) 191*0Sstevel@tonic-gate return (FALSE); 192*0Sstevel@tonic-gate } else { 193*0Sstevel@tonic-gate if (!xdr_u_int(xdrs, &size)) 194*0Sstevel@tonic-gate return (FALSE); 195*0Sstevel@tonic-gate if (size == 0) { /* shrinked format */ 196*0Sstevel@tonic-gate /* get the name from the table object */ 197*0Sstevel@tonic-gate if ((objp->zo_name = strdup(tobj->zo_name)) == NULL) 198*0Sstevel@tonic-gate return (FALSE); 199*0Sstevel@tonic-gate } else { 200*0Sstevel@tonic-gate /* 201*0Sstevel@tonic-gate * We are opening up the xdr_string implementation here 202*0Sstevel@tonic-gate * because we called xdr_u_int() earlier. 203*0Sstevel@tonic-gate */ 204*0Sstevel@tonic-gate if ((objp->zo_name = (char *)malloc(size + 1)) == NULL) 205*0Sstevel@tonic-gate return (FALSE); 206*0Sstevel@tonic-gate if (!xdr_opaque(xdrs, objp->zo_name, size)) 207*0Sstevel@tonic-gate return (FALSE); 208*0Sstevel@tonic-gate } 209*0Sstevel@tonic-gate } 210*0Sstevel@tonic-gate 211*0Sstevel@tonic-gate /* 212*0Sstevel@tonic-gate * We use the xdr_nis_name_abbrev() function for both owner 213*0Sstevel@tonic-gate * and group which constructs the name from the domain name. 214*0Sstevel@tonic-gate */ 215*0Sstevel@tonic-gate if (!xdr_nis_name_abbrev(xdrs, &objp->zo_owner, tobj->zo_domain)) 216*0Sstevel@tonic-gate return (FALSE); 217*0Sstevel@tonic-gate if (!xdr_nis_name_abbrev(xdrs, &objp->zo_group, tobj->zo_domain)) 218*0Sstevel@tonic-gate return (FALSE); 219*0Sstevel@tonic-gate 220*0Sstevel@tonic-gate /* 221*0Sstevel@tonic-gate * While encoding of zo_domain, we put 0 in the length field, while for 222*0Sstevel@tonic-gate * decoding, we get the name from the table object. Same as above for 223*0Sstevel@tonic-gate * the name. Could have used a function instead. 224*0Sstevel@tonic-gate */ 225*0Sstevel@tonic-gate if (xdrs->x_op == XDR_ENCODE) { 226*0Sstevel@tonic-gate size = 0; 227*0Sstevel@tonic-gate if (!xdr_u_int(xdrs, &size)) 228*0Sstevel@tonic-gate return (FALSE); 229*0Sstevel@tonic-gate } else { 230*0Sstevel@tonic-gate if (!xdr_u_int(xdrs, &size)) 231*0Sstevel@tonic-gate return (FALSE); 232*0Sstevel@tonic-gate if (size == 0) { /* shrinked format */ 233*0Sstevel@tonic-gate /* get the name from the table object */ 234*0Sstevel@tonic-gate if ((objp->zo_domain = strdup(tobj->zo_domain)) == NULL) 235*0Sstevel@tonic-gate return (FALSE); 236*0Sstevel@tonic-gate } else { 237*0Sstevel@tonic-gate /* 238*0Sstevel@tonic-gate * We are opening up the xdr_string implementation here 239*0Sstevel@tonic-gate * because we called xdr_u_int() earlier. 240*0Sstevel@tonic-gate */ 241*0Sstevel@tonic-gate if ((objp->zo_domain = (char *)malloc(size + 1)) 242*0Sstevel@tonic-gate == NULL) 243*0Sstevel@tonic-gate return (FALSE); 244*0Sstevel@tonic-gate if (!xdr_opaque(xdrs, objp->zo_domain, size)) 245*0Sstevel@tonic-gate return (FALSE); 246*0Sstevel@tonic-gate } 247*0Sstevel@tonic-gate } 248*0Sstevel@tonic-gate 249*0Sstevel@tonic-gate if (!xdr_u_int(xdrs, &objp->zo_access)) 250*0Sstevel@tonic-gate return (FALSE); 251*0Sstevel@tonic-gate if (!xdr_u_int(xdrs, &objp->zo_ttl)) 252*0Sstevel@tonic-gate return (FALSE); 253*0Sstevel@tonic-gate 254*0Sstevel@tonic-gate /* 255*0Sstevel@tonic-gate * We know that this is an entry object, so we'll save all the entry_obj 256*0Sstevel@tonic-gate * space because we can recreate it later. 257*0Sstevel@tonic-gate */ 258*0Sstevel@tonic-gate if (xdrs->x_op == XDR_ENCODE) 259*0Sstevel@tonic-gate return (TRUE); 260*0Sstevel@tonic-gate /* Now for the DECODE case, just handcraft the entries and ignore XDR */ 261*0Sstevel@tonic-gate objp->zo_data.zo_type = NIS_ENTRY_OBJ; 262*0Sstevel@tonic-gate if ((objp->zo_data.objdata_u.en_data.en_type = 263*0Sstevel@tonic-gate strdup(tobj->zo_data.objdata_u.ta_data.ta_type)) == NULL) 264*0Sstevel@tonic-gate return (FALSE); 265*0Sstevel@tonic-gate objp->zo_data.objdata_u.en_data.en_cols.en_cols_val = NULL; 266*0Sstevel@tonic-gate objp->zo_data.objdata_u.en_data.en_cols.en_cols_len = 0; 267*0Sstevel@tonic-gate return (TRUE); 268*0Sstevel@tonic-gate } 269*0Sstevel@tonic-gate 270*0Sstevel@tonic-gate static const char *in_directory = "IN_DIRECTORY"; 271*0Sstevel@tonic-gate 272*0Sstevel@tonic-gate /* 273*0Sstevel@tonic-gate * Given an input NIS+ object, create the kind 274*0Sstevel@tonic-gate * of pseudo-entry_obj (with an XDR-encoded nis_object in the 275*0Sstevel@tonic-gate * first column) that's stored in the DB. Note that: 276*0Sstevel@tonic-gate * 277*0Sstevel@tonic-gate * If the input object is an entry, it's assumed to have the 278*0Sstevel@tonic-gate * columns moved up one step (col 0 in en_cols.en_cols_val[1], 279*0Sstevel@tonic-gate * etc.). en_cols.en_cols_val[0] will be overwritten. The 280*0Sstevel@tonic-gate * input object will be changed (some pointers set to zero, 281*0Sstevel@tonic-gate * etc.) on exit. 282*0Sstevel@tonic-gate * 283*0Sstevel@tonic-gate * 'eo' is assumed to be a pointer to an empty entry_obj (or, 284*0Sstevel@tonic-gate * at least, one that can be overwritten). It must not be a 285*0Sstevel@tonic-gate * pointer to the entry_obj in 'obj'. If the input object is 286*0Sstevel@tonic-gate * of a type other than entry, the 'eo' pointer must have 287*0Sstevel@tonic-gate * en_cols.en_cols_val appropriately initialized to an array of 288*0Sstevel@tonic-gate * (at least) length one. 289*0Sstevel@tonic-gate * 290*0Sstevel@tonic-gate * 'tobj' is a pointer to the table object for the table for 291*0Sstevel@tonic-gate * which the entry_obj is destined. It's needed for entry objects, 292*0Sstevel@tonic-gate * but unused for other object types. 293*0Sstevel@tonic-gate */ 294*0Sstevel@tonic-gate entry_obj * 295*0Sstevel@tonic-gate makePseudoEntryObj(nis_object *obj, entry_obj *eo, nis_object *tobj) { 296*0Sstevel@tonic-gate int bufsize; 297*0Sstevel@tonic-gate char *buf; 298*0Sstevel@tonic-gate XDR xdrs; 299*0Sstevel@tonic-gate bool_t xret; 300*0Sstevel@tonic-gate uint_t ecl; 301*0Sstevel@tonic-gate entry_col *ecv; 302*0Sstevel@tonic-gate char *myself = "makePseudoEntryObj"; 303*0Sstevel@tonic-gate 304*0Sstevel@tonic-gate if (obj == 0 || eo == 0) 305*0Sstevel@tonic-gate return (0); 306*0Sstevel@tonic-gate 307*0Sstevel@tonic-gate if (obj->zo_data.zo_type == NIS_ENTRY_OBJ) { 308*0Sstevel@tonic-gate *eo = obj->zo_data.objdata_u.en_data; 309*0Sstevel@tonic-gate eo->en_type = 0; 310*0Sstevel@tonic-gate 311*0Sstevel@tonic-gate /* 312*0Sstevel@tonic-gate * To prevent the XDR function from making a copy of 313*0Sstevel@tonic-gate * the entry columns, we set the columns structure to 314*0Sstevel@tonic-gate * 0 (ie no column data) 315*0Sstevel@tonic-gate */ 316*0Sstevel@tonic-gate ecl = obj->EN_data.en_cols.en_cols_len; 317*0Sstevel@tonic-gate ecv = obj->EN_data.en_cols.en_cols_val; 318*0Sstevel@tonic-gate obj->EN_data.en_cols.en_cols_len = 0; 319*0Sstevel@tonic-gate obj->EN_data.en_cols.en_cols_val = 0; 320*0Sstevel@tonic-gate } else { 321*0Sstevel@tonic-gate eo->en_type = (char *)in_directory; 322*0Sstevel@tonic-gate } 323*0Sstevel@tonic-gate 324*0Sstevel@tonic-gate bufsize = xdr_sizeof(xdr_nis_object, obj); 325*0Sstevel@tonic-gate buf = am(myself, bufsize); 326*0Sstevel@tonic-gate if (buf == 0) { 327*0Sstevel@tonic-gate if (obj->zo_data.zo_type == NIS_ENTRY_OBJ) { 328*0Sstevel@tonic-gate obj->EN_data.en_cols.en_cols_len = ecl; 329*0Sstevel@tonic-gate obj->EN_data.en_cols.en_cols_val = ecv; 330*0Sstevel@tonic-gate } 331*0Sstevel@tonic-gate return (0); 332*0Sstevel@tonic-gate } 333*0Sstevel@tonic-gate 334*0Sstevel@tonic-gate xdrmem_create(&xdrs, (char *)buf, bufsize, XDR_ENCODE); 335*0Sstevel@tonic-gate 336*0Sstevel@tonic-gate if (obj->zo_data.zo_type == NIS_ENTRY_OBJ) { 337*0Sstevel@tonic-gate xret = xdr_nis_fetus_object(&xdrs, obj, tobj); 338*0Sstevel@tonic-gate } else { 339*0Sstevel@tonic-gate xret = xdr_nis_object(&xdrs, obj); 340*0Sstevel@tonic-gate } 341*0Sstevel@tonic-gate 342*0Sstevel@tonic-gate /* Restore the 'obj' */ 343*0Sstevel@tonic-gate if (obj->zo_data.zo_type == NIS_ENTRY_OBJ) { 344*0Sstevel@tonic-gate obj->EN_data.en_cols.en_cols_len = ecl; 345*0Sstevel@tonic-gate obj->EN_data.en_cols.en_cols_val = ecv; 346*0Sstevel@tonic-gate } 347*0Sstevel@tonic-gate 348*0Sstevel@tonic-gate if (!xret) { 349*0Sstevel@tonic-gate logmsg(MSG_NOTIMECHECK, LOG_ERR, 350*0Sstevel@tonic-gate "%s: XDR encode failure", myself); 351*0Sstevel@tonic-gate sfree(buf); 352*0Sstevel@tonic-gate return (0); 353*0Sstevel@tonic-gate } 354*0Sstevel@tonic-gate 355*0Sstevel@tonic-gate eo->en_cols.en_cols_val[0].ec_value.ec_value_val = buf; 356*0Sstevel@tonic-gate eo->en_cols.en_cols_val[0].ec_value.ec_value_len = xdr_getpos(&xdrs); 357*0Sstevel@tonic-gate eo->en_cols.en_cols_val[0].ec_flags = EN_BINARY+EN_XDR; 358*0Sstevel@tonic-gate 359*0Sstevel@tonic-gate return (eo); 360*0Sstevel@tonic-gate } 361*0Sstevel@tonic-gate 362*0Sstevel@tonic-gate nis_object * 363*0Sstevel@tonic-gate unmakePseudoEntryObj(entry_obj *e, nis_object *tobj) { 364*0Sstevel@tonic-gate nis_object *o; 365*0Sstevel@tonic-gate XDR xdrs; 366*0Sstevel@tonic-gate bool_t stat; 367*0Sstevel@tonic-gate char *myself = "unmakePseudoEntryObj"; 368*0Sstevel@tonic-gate 369*0Sstevel@tonic-gate if (e == 0 || e->en_cols.en_cols_val == 0 || 370*0Sstevel@tonic-gate e->en_cols.en_cols_len == 0) 371*0Sstevel@tonic-gate return (0); 372*0Sstevel@tonic-gate 373*0Sstevel@tonic-gate o = am(myself, sizeof (*o)); 374*0Sstevel@tonic-gate if (o == 0) 375*0Sstevel@tonic-gate return (0); 376*0Sstevel@tonic-gate 377*0Sstevel@tonic-gate xdrmem_create(&xdrs, e->en_cols.en_cols_val[0].ec_value.ec_value_val, 378*0Sstevel@tonic-gate e->en_cols.en_cols_val[0].ec_value.ec_value_len, 379*0Sstevel@tonic-gate XDR_DECODE); 380*0Sstevel@tonic-gate 381*0Sstevel@tonic-gate if (tobj != 0 && (e->en_type == 0 || e->en_type[0] == '\0')) { 382*0Sstevel@tonic-gate stat = xdr_nis_fetus_object(&xdrs, o, tobj); 383*0Sstevel@tonic-gate } else { 384*0Sstevel@tonic-gate stat = xdr_nis_object(&xdrs, o); 385*0Sstevel@tonic-gate } 386*0Sstevel@tonic-gate 387*0Sstevel@tonic-gate if (!stat) { 388*0Sstevel@tonic-gate sfree(o); 389*0Sstevel@tonic-gate o = 0; 390*0Sstevel@tonic-gate } 391*0Sstevel@tonic-gate 392*0Sstevel@tonic-gate /* 393*0Sstevel@tonic-gate * If it's an entry object, construct the column information. 394*0Sstevel@tonic-gate * We make this a copy, so that 'o' can be freed using 395*0Sstevel@tonic-gate * nis_destroy_object(). 396*0Sstevel@tonic-gate */ 397*0Sstevel@tonic-gate if (o != 0 && o->zo_data.zo_type == NIS_ENTRY_OBJ && 398*0Sstevel@tonic-gate o->zo_data.objdata_u.en_data.en_cols.en_cols_val == 0 && 399*0Sstevel@tonic-gate e->en_cols.en_cols_len > 1) { 400*0Sstevel@tonic-gate entry_col *ec, *oec; 401*0Sstevel@tonic-gate uint_t i, *ocl; 402*0Sstevel@tonic-gate 403*0Sstevel@tonic-gate ec = am(myself, (e->en_cols.en_cols_len - 1) * sizeof (ec[0])); 404*0Sstevel@tonic-gate if (ec == 0) { 405*0Sstevel@tonic-gate nis_destroy_object(o); 406*0Sstevel@tonic-gate return (0); 407*0Sstevel@tonic-gate } 408*0Sstevel@tonic-gate 409*0Sstevel@tonic-gate o->zo_data.objdata_u.en_data.en_cols.en_cols_val = ec; 410*0Sstevel@tonic-gate o->zo_data.objdata_u.en_data.en_cols.en_cols_len = 0; 411*0Sstevel@tonic-gate ocl = &o->zo_data.objdata_u.en_data.en_cols.en_cols_len; 412*0Sstevel@tonic-gate oec = e->en_cols.en_cols_val; 413*0Sstevel@tonic-gate 414*0Sstevel@tonic-gate for (i = 1; i < e->en_cols.en_cols_len; i++) { 415*0Sstevel@tonic-gate uint_t len; 416*0Sstevel@tonic-gate 417*0Sstevel@tonic-gate if (oec[i].ec_value.ec_value_val != 0) { 418*0Sstevel@tonic-gate len = oec[i].ec_value.ec_value_len; 419*0Sstevel@tonic-gate if (len == 0) 420*0Sstevel@tonic-gate len++; 421*0Sstevel@tonic-gate ec[i-1].ec_value.ec_value_val = am(myself, len); 422*0Sstevel@tonic-gate if (ec[i-1].ec_value.ec_value_val == 0) { 423*0Sstevel@tonic-gate nis_destroy_object(o); 424*0Sstevel@tonic-gate return (0); 425*0Sstevel@tonic-gate } 426*0Sstevel@tonic-gate (void) memcpy(ec[i-1].ec_value.ec_value_val, 427*0Sstevel@tonic-gate oec[i].ec_value.ec_value_val, 428*0Sstevel@tonic-gate oec[i].ec_value.ec_value_len); 429*0Sstevel@tonic-gate ec[i-1].ec_value.ec_value_len = 430*0Sstevel@tonic-gate oec[i].ec_value.ec_value_len; 431*0Sstevel@tonic-gate } else { 432*0Sstevel@tonic-gate ec[i-1].ec_value.ec_value_val = 0; 433*0Sstevel@tonic-gate ec[i-1].ec_value.ec_value_len = 0; 434*0Sstevel@tonic-gate } 435*0Sstevel@tonic-gate *ocl += 1; 436*0Sstevel@tonic-gate } 437*0Sstevel@tonic-gate } 438*0Sstevel@tonic-gate 439*0Sstevel@tonic-gate /* 440*0Sstevel@tonic-gate * If it's an entry, and we have the table object, make sure 441*0Sstevel@tonic-gate * zo_name and en_type either already are set, or get them 442*0Sstevel@tonic-gate * from the table. 443*0Sstevel@tonic-gate */ 444*0Sstevel@tonic-gate if (o != 0 && o->zo_data.zo_type == NIS_ENTRY_OBJ && tobj != 0) { 445*0Sstevel@tonic-gate if (o->zo_name == 0) 446*0Sstevel@tonic-gate o->zo_name = sdup(myself, T, tobj->zo_name); 447*0Sstevel@tonic-gate if (o->zo_data.objdata_u.en_data.en_type == 0) 448*0Sstevel@tonic-gate o->zo_data.objdata_u.en_data.en_type = sdup(myself, T, 449*0Sstevel@tonic-gate tobj->zo_data.objdata_u.ta_data.ta_type); 450*0Sstevel@tonic-gate } 451*0Sstevel@tonic-gate 452*0Sstevel@tonic-gate return (o); 453*0Sstevel@tonic-gate } 454*0Sstevel@tonic-gate 455*0Sstevel@tonic-gate /* 456*0Sstevel@tonic-gate * Input: A (nis_object *), and (optionally) an (entry_obj *) array. 457*0Sstevel@tonic-gate * Output: Pointer to an XDR:ed version of an (xdr_nis_object_t). 458*0Sstevel@tonic-gate */ 459*0Sstevel@tonic-gate void * 460*0Sstevel@tonic-gate xdrNisObject(nis_object *obj, entry_obj **ea, int numEa, int *xdrLenP) { 461*0Sstevel@tonic-gate xdr_nis_object_t xno; 462*0Sstevel@tonic-gate void *buf; 463*0Sstevel@tonic-gate int xdrLen; 464*0Sstevel@tonic-gate XDR xdrs; 465*0Sstevel@tonic-gate bool_t xret; 466*0Sstevel@tonic-gate char *myself = "xdrNisObject"; 467*0Sstevel@tonic-gate 468*0Sstevel@tonic-gate if (obj == 0) 469*0Sstevel@tonic-gate return (0); 470*0Sstevel@tonic-gate 471*0Sstevel@tonic-gate /* 472*0Sstevel@tonic-gate * The version tells us what the XDR:ed buffer contains. 473*0Sstevel@tonic-gate * Should be incremented whenever xdr_nis_object_t changes 474*0Sstevel@tonic-gate * incompatibly. 475*0Sstevel@tonic-gate */ 476*0Sstevel@tonic-gate xno.xversion = 1; 477*0Sstevel@tonic-gate 478*0Sstevel@tonic-gate xno.obj = obj; 479*0Sstevel@tonic-gate 480*0Sstevel@tonic-gate if (obj->zo_data.zo_type == NIS_DIRECTORY_OBJ && 481*0Sstevel@tonic-gate ea != 0 && numEa > 0) { 482*0Sstevel@tonic-gate int i; 483*0Sstevel@tonic-gate 484*0Sstevel@tonic-gate /* 485*0Sstevel@tonic-gate * The ea[] array is expected to contain the kind of 486*0Sstevel@tonic-gate * pseudo-entry object stored in the nisdb incarnation 487*0Sstevel@tonic-gate * of a NIS+ directory. Column zero contains the XDR:ed 488*0Sstevel@tonic-gate * directory entry object (which we ignore), while column 489*0Sstevel@tonic-gate * one contains the name of said entry. It's the latter 490*0Sstevel@tonic-gate * that we borrow for use in the dirEntry[] list of the 491*0Sstevel@tonic-gate * xdr_nis_object_t. 492*0Sstevel@tonic-gate */ 493*0Sstevel@tonic-gate 494*0Sstevel@tonic-gate xno.dirEntry.dirEntry_len = 0; 495*0Sstevel@tonic-gate xno.dirEntry.dirEntry_val = am(myself, numEa * 496*0Sstevel@tonic-gate sizeof (xno.dirEntry.dirEntry_val[0])); 497*0Sstevel@tonic-gate if (xno.dirEntry.dirEntry_val == 0) 498*0Sstevel@tonic-gate return (0); 499*0Sstevel@tonic-gate 500*0Sstevel@tonic-gate for (i = 0; i < numEa; i++) { 501*0Sstevel@tonic-gate if (ea[i] == 0 || ea[i]->en_cols.en_cols_val == 0 || 502*0Sstevel@tonic-gate ea[i]->en_cols.en_cols_len != 2 || 503*0Sstevel@tonic-gate ea[i]->en_cols.en_cols_val[1]. 504*0Sstevel@tonic-gate ec_value.ec_value_len == 0) 505*0Sstevel@tonic-gate continue; 506*0Sstevel@tonic-gate /* 507*0Sstevel@tonic-gate * Yes, there's a NUL at the end of the dir entry 508*0Sstevel@tonic-gate * name. 509*0Sstevel@tonic-gate */ 510*0Sstevel@tonic-gate xno.dirEntry.dirEntry_val[xno.dirEntry.dirEntry_len] = 511*0Sstevel@tonic-gate ea[i]->en_cols.en_cols_val[1]. 512*0Sstevel@tonic-gate ec_value.ec_value_val; 513*0Sstevel@tonic-gate xno.dirEntry.dirEntry_len++; 514*0Sstevel@tonic-gate } 515*0Sstevel@tonic-gate } else { 516*0Sstevel@tonic-gate /* No directory entries */ 517*0Sstevel@tonic-gate xno.dirEntry.dirEntry_len = 0; 518*0Sstevel@tonic-gate xno.dirEntry.dirEntry_val = 0; 519*0Sstevel@tonic-gate } 520*0Sstevel@tonic-gate 521*0Sstevel@tonic-gate xdrLen = xdr_sizeof(xdr_xdr_nis_object_t, &xno); 522*0Sstevel@tonic-gate buf = am(myself, xdrLen); 523*0Sstevel@tonic-gate if (buf == 0) 524*0Sstevel@tonic-gate return (0); 525*0Sstevel@tonic-gate 526*0Sstevel@tonic-gate xdrmem_create(&xdrs, (char *)buf, xdrLen, XDR_ENCODE); 527*0Sstevel@tonic-gate 528*0Sstevel@tonic-gate xret = xdr_xdr_nis_object_t(&xdrs, &xno); 529*0Sstevel@tonic-gate 530*0Sstevel@tonic-gate sfree(xno.dirEntry.dirEntry_val); 531*0Sstevel@tonic-gate 532*0Sstevel@tonic-gate if (!xret) { 533*0Sstevel@tonic-gate sfree(buf); 534*0Sstevel@tonic-gate return (0); 535*0Sstevel@tonic-gate } 536*0Sstevel@tonic-gate 537*0Sstevel@tonic-gate if (xdrLenP != 0) 538*0Sstevel@tonic-gate *xdrLenP = xdrLen; 539*0Sstevel@tonic-gate 540*0Sstevel@tonic-gate return (buf); 541*0Sstevel@tonic-gate } 542*0Sstevel@tonic-gate 543*0Sstevel@tonic-gate /* 544*0Sstevel@tonic-gate * Input: Pointer to an XDR:ed version of an (xdr_nis_object_t). 545*0Sstevel@tonic-gate * Output: Pointer to a (nis_object *) and (if the object is a 546*0Sstevel@tonic-gate * directory) a pointer to an array of (entry_obj *). 547*0Sstevel@tonic-gate */ 548*0Sstevel@tonic-gate nis_object * 549*0Sstevel@tonic-gate unXdrNisObject(void *buf, int bufLen, entry_obj ***eaP, int *numEaP) { 550*0Sstevel@tonic-gate xdr_nis_object_t *xno; 551*0Sstevel@tonic-gate XDR xdrs; 552*0Sstevel@tonic-gate bool_t xret; 553*0Sstevel@tonic-gate entry_obj **ea; 554*0Sstevel@tonic-gate int numEa; 555*0Sstevel@tonic-gate nis_object *o; 556*0Sstevel@tonic-gate char *myself = "unXdrNisObject"; 557*0Sstevel@tonic-gate 558*0Sstevel@tonic-gate if (buf == 0 || bufLen <= 0) 559*0Sstevel@tonic-gate return (0); 560*0Sstevel@tonic-gate 561*0Sstevel@tonic-gate xno = am(myself, sizeof (*xno)); 562*0Sstevel@tonic-gate if (xno == 0) 563*0Sstevel@tonic-gate return (0); 564*0Sstevel@tonic-gate 565*0Sstevel@tonic-gate xdrmem_create(&xdrs, buf, bufLen, XDR_DECODE); 566*0Sstevel@tonic-gate xret = xdr_xdr_nis_object_t(&xdrs, xno); 567*0Sstevel@tonic-gate 568*0Sstevel@tonic-gate if (!xret) { 569*0Sstevel@tonic-gate sfree(xno); 570*0Sstevel@tonic-gate return (0); 571*0Sstevel@tonic-gate } 572*0Sstevel@tonic-gate 573*0Sstevel@tonic-gate switch (xno->xversion) { 574*0Sstevel@tonic-gate case 1: 575*0Sstevel@tonic-gate break; 576*0Sstevel@tonic-gate default: 577*0Sstevel@tonic-gate xdr_free(xdr_xdr_nis_object_t, (char *)xno); 578*0Sstevel@tonic-gate sfree(xno); 579*0Sstevel@tonic-gate logmsg(MSG_NOTIMECHECK, LOG_WARNING, 580*0Sstevel@tonic-gate "%s: Unknown xdr_nis_object_t version %d", 581*0Sstevel@tonic-gate myself, xno->xversion); 582*0Sstevel@tonic-gate return (0); 583*0Sstevel@tonic-gate } 584*0Sstevel@tonic-gate 585*0Sstevel@tonic-gate if (eaP != 0 && numEaP != 0 && xno->dirEntry.dirEntry_len > 0 && 586*0Sstevel@tonic-gate xno->dirEntry.dirEntry_val != 0) { 587*0Sstevel@tonic-gate ea = am(myself, xno->dirEntry.dirEntry_len * sizeof (ea[0])); 588*0Sstevel@tonic-gate if (ea == 0) { 589*0Sstevel@tonic-gate xdr_free(xdr_xdr_nis_object_t, (char *)xno); 590*0Sstevel@tonic-gate sfree(xno); 591*0Sstevel@tonic-gate return (0); 592*0Sstevel@tonic-gate } 593*0Sstevel@tonic-gate for (numEa = 0; numEa < xno->dirEntry.dirEntry_len; numEa++) { 594*0Sstevel@tonic-gate ea[numEa] = am(myself, sizeof (*ea[numEa])); 595*0Sstevel@tonic-gate if (ea[numEa] != 0) { 596*0Sstevel@tonic-gate ea[numEa]->en_cols.en_cols_len = 2; 597*0Sstevel@tonic-gate ea[numEa]->en_cols.en_cols_val = am(myself, 598*0Sstevel@tonic-gate ea[numEa]->en_cols.en_cols_len * 599*0Sstevel@tonic-gate sizeof (ea[numEa]->en_cols.en_cols_val[0])); 600*0Sstevel@tonic-gate } 601*0Sstevel@tonic-gate if (ea[numEa] == 0 || 602*0Sstevel@tonic-gate ea[numEa]->en_cols.en_cols_val == 0) { 603*0Sstevel@tonic-gate int i; 604*0Sstevel@tonic-gate for (i = 0; i < numEa; i++) { 605*0Sstevel@tonic-gate sfree(ea[i]->en_cols.en_cols_val); 606*0Sstevel@tonic-gate sfree(ea[i]); 607*0Sstevel@tonic-gate } 608*0Sstevel@tonic-gate sfree(ea); 609*0Sstevel@tonic-gate xdr_free(xdr_xdr_nis_object_t, (char *)xno); 610*0Sstevel@tonic-gate sfree(xno); 611*0Sstevel@tonic-gate return (0); 612*0Sstevel@tonic-gate } 613*0Sstevel@tonic-gate /* Leave column 0 (XDR:ed object) empty */ 614*0Sstevel@tonic-gate ea[numEa]->en_cols.en_cols_val[0]. 615*0Sstevel@tonic-gate ec_value.ec_value_len = 0; 616*0Sstevel@tonic-gate ea[numEa]->en_cols.en_cols_val[0]. 617*0Sstevel@tonic-gate ec_value.ec_value_val = 0; 618*0Sstevel@tonic-gate /* 619*0Sstevel@tonic-gate * Fill in name of dir entry. The DB counts the NUL 620*0Sstevel@tonic-gate * as part of the dir entry name; hence, add one 621*0Sstevel@tonic-gate * to the string length. 622*0Sstevel@tonic-gate */ 623*0Sstevel@tonic-gate ea[numEa]->en_cols.en_cols_val[1]. 624*0Sstevel@tonic-gate ec_value.ec_value_len = slen(xno->dirEntry. 625*0Sstevel@tonic-gate dirEntry_val[numEa]) + 1; 626*0Sstevel@tonic-gate ea[numEa]->en_cols.en_cols_val[1]. 627*0Sstevel@tonic-gate ec_value.ec_value_val = 628*0Sstevel@tonic-gate xno->dirEntry.dirEntry_val[numEa]; 629*0Sstevel@tonic-gate } 630*0Sstevel@tonic-gate *eaP = ea; 631*0Sstevel@tonic-gate *numEaP = numEa; 632*0Sstevel@tonic-gate /* 633*0Sstevel@tonic-gate * The xno->dirEntry.dirEntry_val[] pointers are duplicated 634*0Sstevel@tonic-gate * in 'ea'. Set the xno pointers to zero, so that the xdr_free 635*0Sstevel@tonic-gate * doesn't free the 'ea' data. 636*0Sstevel@tonic-gate */ 637*0Sstevel@tonic-gate if (numEa > 0) { 638*0Sstevel@tonic-gate int i; 639*0Sstevel@tonic-gate for (i = 0; i < numEa; i++) { 640*0Sstevel@tonic-gate xno->dirEntry.dirEntry_val[i] = 0; 641*0Sstevel@tonic-gate } 642*0Sstevel@tonic-gate } 643*0Sstevel@tonic-gate } else { 644*0Sstevel@tonic-gate if (eaP != 0) 645*0Sstevel@tonic-gate *eaP = 0; 646*0Sstevel@tonic-gate if (numEaP != 0) 647*0Sstevel@tonic-gate *numEaP = 0; 648*0Sstevel@tonic-gate } 649*0Sstevel@tonic-gate 650*0Sstevel@tonic-gate o = xno->obj; 651*0Sstevel@tonic-gate xno->obj = 0; 652*0Sstevel@tonic-gate xdr_free(xdr_xdr_nis_object_t, (char *)xno); 653*0Sstevel@tonic-gate sfree(xno); 654*0Sstevel@tonic-gate 655*0Sstevel@tonic-gate return (o); 656*0Sstevel@tonic-gate } 657*0Sstevel@tonic-gate 658*0Sstevel@tonic-gate void 659*0Sstevel@tonic-gate freeEntryObjArray(entry_obj **ea, int numEa) { 660*0Sstevel@tonic-gate int i; 661*0Sstevel@tonic-gate 662*0Sstevel@tonic-gate if (ea == 0) 663*0Sstevel@tonic-gate return; 664*0Sstevel@tonic-gate 665*0Sstevel@tonic-gate for (i = 0; i < numEa; i++) { 666*0Sstevel@tonic-gate int j; 667*0Sstevel@tonic-gate 668*0Sstevel@tonic-gate for (j = 0; j < ea[i]->en_cols.en_cols_len; j++) { 669*0Sstevel@tonic-gate sfree(ea[i]->en_cols.en_cols_val[j]. 670*0Sstevel@tonic-gate ec_value.ec_value_val); 671*0Sstevel@tonic-gate } 672*0Sstevel@tonic-gate 673*0Sstevel@tonic-gate sfree(ea[i]->en_cols.en_cols_val); 674*0Sstevel@tonic-gate } 675*0Sstevel@tonic-gate 676*0Sstevel@tonic-gate sfree(ea); 677*0Sstevel@tonic-gate } 678*0Sstevel@tonic-gate 679*0Sstevel@tonic-gate /* 680*0Sstevel@tonic-gate * Return TRUE if 'o1' and 'o2' are the same, FALSE otherwise. 681*0Sstevel@tonic-gate * We perform the comparison by XDR encoding the objects, and then 682*0Sstevel@tonic-gate * checking the XDR buffers for equality. However, we don't want to 683*0Sstevel@tonic-gate * include the zo_oid (i.e., ctime and mtime) in the comparison. 684*0Sstevel@tonic-gate */ 685*0Sstevel@tonic-gate bool_t 686*0Sstevel@tonic-gate sameNisPlusObj(nis_object *o1, nis_object *o2) { 687*0Sstevel@tonic-gate XDR x1, x2; 688*0Sstevel@tonic-gate void *b1, *b2; 689*0Sstevel@tonic-gate int l1, l2; 690*0Sstevel@tonic-gate bool_t ret; 691*0Sstevel@tonic-gate nis_object obj1, obj2; 692*0Sstevel@tonic-gate char *myself = "sameNisPlusObj"; 693*0Sstevel@tonic-gate 694*0Sstevel@tonic-gate if (o1 == o2) 695*0Sstevel@tonic-gate return (TRUE); 696*0Sstevel@tonic-gate else if (o1 == 0 || o2 == 0) 697*0Sstevel@tonic-gate return (FALSE); 698*0Sstevel@tonic-gate 699*0Sstevel@tonic-gate /* 700*0Sstevel@tonic-gate * We want to exclude the zo_oid from the comparison. In order 701*0Sstevel@tonic-gate * not to modify the objects (even very briefly), we do this by 702*0Sstevel@tonic-gate * making copies (nis_object itself only, not the underlying 703*0Sstevel@tonic-gate * structures accessed through pointers), and setting the zo_oid 704*0Sstevel@tonic-gate * to zero in the copies. 705*0Sstevel@tonic-gate */ 706*0Sstevel@tonic-gate obj1 = *o1; 707*0Sstevel@tonic-gate obj2 = *o2; 708*0Sstevel@tonic-gate obj1.zo_oid.ctime = obj1.zo_oid.mtime = 0; 709*0Sstevel@tonic-gate obj2.zo_oid.ctime = obj2.zo_oid.mtime = 0; 710*0Sstevel@tonic-gate 711*0Sstevel@tonic-gate l1 = xdr_sizeof(xdr_nis_object, &obj1); 712*0Sstevel@tonic-gate l2 = xdr_sizeof(xdr_nis_object, &obj2); 713*0Sstevel@tonic-gate if (l1 != l2) 714*0Sstevel@tonic-gate return (FALSE); 715*0Sstevel@tonic-gate 716*0Sstevel@tonic-gate b1 = am(myself, l1); 717*0Sstevel@tonic-gate b2 = am(myself, l2); 718*0Sstevel@tonic-gate if (b1 == 0 || b2 == 0) { 719*0Sstevel@tonic-gate sfree(b1); 720*0Sstevel@tonic-gate sfree(b2); 721*0Sstevel@tonic-gate return (FALSE); 722*0Sstevel@tonic-gate } 723*0Sstevel@tonic-gate 724*0Sstevel@tonic-gate xdrmem_create(&x1, (char *)b1, l1, XDR_ENCODE); 725*0Sstevel@tonic-gate xdrmem_create(&x2, (char *)b2, l2, XDR_ENCODE); 726*0Sstevel@tonic-gate 727*0Sstevel@tonic-gate if (xdr_nis_object(&x1, &obj1) && xdr_nis_object(&x2, &obj2)) { 728*0Sstevel@tonic-gate ret = (memcmp(b1, b2, l1) == 0); 729*0Sstevel@tonic-gate } else { 730*0Sstevel@tonic-gate logmsg(MSG_NOTIMECHECK, LOG_WARNING, 731*0Sstevel@tonic-gate "%s: xdr_nis_object() error", 732*0Sstevel@tonic-gate myself); 733*0Sstevel@tonic-gate ret = FALSE; 734*0Sstevel@tonic-gate } 735*0Sstevel@tonic-gate 736*0Sstevel@tonic-gate sfree(b1); 737*0Sstevel@tonic-gate sfree(b2); 738*0Sstevel@tonic-gate 739*0Sstevel@tonic-gate return (ret); 740*0Sstevel@tonic-gate } 741*0Sstevel@tonic-gate 742*0Sstevel@tonic-gate /* 743*0Sstevel@tonic-gate * A wrapper/convenience function for sameNisPlusObj() that extracts 744*0Sstevel@tonic-gate * the object in column zero of 'e2'. 745*0Sstevel@tonic-gate */ 746*0Sstevel@tonic-gate bool_t 747*0Sstevel@tonic-gate sameNisPlusPseudoObj(nis_object *o1, entry_obj *e2) { 748*0Sstevel@tonic-gate nis_object *o2; 749*0Sstevel@tonic-gate bool_t res; 750*0Sstevel@tonic-gate 751*0Sstevel@tonic-gate if (o1 == 0 && e2 == 0) 752*0Sstevel@tonic-gate return (TRUE); 753*0Sstevel@tonic-gate else if (e2 == 0) 754*0Sstevel@tonic-gate return (FALSE); 755*0Sstevel@tonic-gate 756*0Sstevel@tonic-gate o2 = unmakePseudoEntryObj(e2, 0); 757*0Sstevel@tonic-gate if (o2 == 0) 758*0Sstevel@tonic-gate return ((o1 == 0) ? TRUE : FALSE); 759*0Sstevel@tonic-gate 760*0Sstevel@tonic-gate res = sameNisPlusObj(o1, o2); 761*0Sstevel@tonic-gate 762*0Sstevel@tonic-gate nis_destroy_object(o2); 763*0Sstevel@tonic-gate 764*0Sstevel@tonic-gate return (res); 765*0Sstevel@tonic-gate } 766