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