1 /* Copyright (c) 1997, 1998 Free Software Foundation, Inc.
2 This file is part of the GNU C Library.
3 Contributed by Thorsten Kukuk <kukuk@vt.uni-paderborn.de>, 1997.
5 The GNU C Library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Library General Public License as
7 published by the Free Software Foundation; either version 2 of the
8 License, or (at your option) any later version.
10 The GNU C Library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Library General Public License for more details.
15 You should have received a copy of the GNU Library General Public
16 License along with the GNU C Library; see the file COPYING.LIB. If not,
17 write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18 Boston, MA 02111-1307, USA. */
21 #include <rpcsvc/nis.h>
22 #include "nis_intern.h"
25 splitname (const_nis_name name
, nis_name
*ibr_name
, int *srch_len
,
28 char *cptr
, *key
, *val
, *next
;
41 /* Not of "[key=value,key=value,...],foo.." format? */
48 *ibr_name
= strchr (cptr
, ']');
49 if (*ibr_name
== NULL
|| (*ibr_name
)[1] != ',')
58 *ibr_name
= strdup (*ibr_name
);
60 if (srch_len
== NULL
|| srch_val
== NULL
)
69 next
= strchr (key
, ',');
76 val
= strchr (key
, '=');
80 *srch_val
= malloc (sizeof (nis_attr
));
81 if (*srch_val
== NULL
)
88 (*srch_val
)[0].zattr_val
.zattr_val_len
= 0;
89 (*srch_val
)[0].zattr_val
.zattr_val_val
= NULL
;
96 if ((*srch_len
) + 1 >= size
)
100 *srch_val
= malloc (size
* sizeof (char *));
102 *srch_val
= realloc (val
, size
* sizeof (char *));
103 if (*srch_val
== NULL
)
112 (*srch_val
)[*srch_len
].zattr_ndx
= strdup (key
);
113 if (((*srch_val
)[*srch_len
].zattr_ndx
) == NULL
)
120 (*srch_val
)[*srch_len
].zattr_val
.zattr_val_len
= strlen (val
) + 1;
121 (*srch_val
)[*srch_len
].zattr_val
.zattr_val_val
= strdup (val
);
122 if ((*srch_val
)[*srch_len
].zattr_val
.zattr_val_val
== NULL
)
139 static struct ib_request
*
140 __create_ib_request (const_nis_name name
, struct ib_request
*ibreq
,
143 splitname (name
, &ibreq
->ibr_name
, &ibreq
->ibr_srch
.ibr_srch_len
,
144 &ibreq
->ibr_srch
.ibr_srch_val
);
145 if (ibreq
->ibr_name
== NULL
)
148 ibreq
->ibr_flags
= flags
;
149 ibreq
->ibr_obj
.ibr_obj_len
= 0;
150 ibreq
->ibr_obj
.ibr_obj_val
= NULL
;
151 ibreq
->ibr_cbhost
.ibr_cbhost_len
= 0;
152 ibreq
->ibr_cbhost
.ibr_cbhost_val
= NULL
;
153 ibreq
->ibr_bufsize
= 0;
154 ibreq
->ibr_cookie
.n_len
= 0;
155 ibreq
->ibr_cookie
.n_bytes
= NULL
;
161 nis_list (const_nis_name name
, u_long flags
,
162 int (*callback
) (const_nis_name name
,
163 const nis_object
*object
,
164 const void *userdata
),
165 const void *userdata
)
167 nis_result
*res
= NULL
;
168 ib_request
*ibreq
= calloc (1, sizeof (ib_request
));
170 int count_links
= 0; /* We will only follow NIS_MAXLINKS links! */
173 nis_name namebuf
[2] = {NULL
, NULL
};
177 res
= calloc (1, sizeof (nis_result
));
179 if (__create_ib_request (name
, ibreq
, flags
) == NULL
)
181 res
->status
= NIS_BADNAME
;
185 if (flags
& EXPAND_NAME
)
187 names
= nis_getnames (ibreq
->ibr_name
);
188 free (ibreq
->ibr_name
);
189 ibreq
->ibr_name
= NULL
;
192 res
->status
= NIS_BADNAME
;
195 ibreq
->ibr_name
= strdup (names
[name_nr
]);
200 names
[name_nr
] = ibreq
->ibr_name
;
205 if (flags
& FOLLOW_PATH
|| flags
& ALL_RESULTS
)
208 u_long newflags
= flags
& ~FOLLOW_PATH
& ~ALL_RESULTS
;
209 char table_path
[NIS_MAXPATH
+ 1];
211 u_long done
= 0, failures
= 0;
213 memset (res
, '\0', sizeof (nis_result
));
215 while (names
[name_nr
] != NULL
&& !done
)
217 lres
= nis_lookup (names
[name_nr
], newflags
);
218 if (lres
== NULL
|| lres
->status
!= NIS_SUCCESS
)
220 res
->status
= lres
->status
;
221 nis_freeresult (lres
);
226 /* nis_lookup handles FOLLOW_LINKS,
227 so we must have a table object. */
228 if (__type_of (NIS_RES_OBJECT (lres
)) != NIS_TABLE_OBJ
)
230 nis_freeresult (lres
);
231 res
->status
= NIS_INVALIDOBJ
;
235 /* Save the path, discard everything else. */
236 snprintf (table_path
, NIS_MAXPATH
, "%s:%s", names
[name_nr
],
237 NIS_RES_OBJECT (lres
)->TA_data
.ta_path
);
238 nis_freeresult (lres
);
244 while (((ntable
= strsep (&p
, ":")) != NULL
) && !done
)
249 nis_freeresult (res
);
251 /* Do the job recursive here! */
252 if ((c
= strchr(name
, ']')) != NULL
)
254 /* Have indexed name ! */
255 int index_len
= c
- name
+ 2;
256 char buf
[index_len
+ strlen (ntable
) + 1];
258 c
= __stpncpy (buf
, name
, index_len
);
260 res
= nis_list (buf
, newflags
, callback
,userdata
);
263 res
= nis_list (ntable
, newflags
, callback
, userdata
);
270 if (!(flags
& ALL_RESULTS
))
273 case NIS_PARTIAL
: /* The table is correct, we doesn't found
277 if (flags
& ALL_RESULTS
)
284 if (res
->status
== NIS_SUCCESS
&& failures
)
285 res
->status
= NIS_S_SUCCESS
;
286 if (res
->status
== NIS_NOTFOUND
&& failures
)
287 res
->status
= NIS_S_NOTFOUND
;
293 if (callback
!= NULL
)
295 cb
= __nis_create_callback (callback
, userdata
, flags
);
296 ibreq
->ibr_cbhost
.ibr_cbhost_len
= 1;
297 ibreq
->ibr_cbhost
.ibr_cbhost_val
= cb
->serv
;
302 memset (res
, '\0', sizeof (nis_result
));
304 status
= __do_niscall (ibreq
->ibr_name
, NIS_IBLIST
,
305 (xdrproc_t
) xdr_ib_request
,
306 (caddr_t
) ibreq
, (xdrproc_t
) xdr_nis_result
,
307 (caddr_t
) res
, flags
, cb
);
308 if (status
!= NIS_SUCCESS
)
309 res
->status
= status
;
316 if (__type_of (NIS_RES_OBJECT (res
)) == NIS_LINK_OBJ
&&
317 flags
& FOLLOW_LINKS
) /* We are following links. */
319 /* If we hit the link limit, bail. */
320 if (count_links
> NIS_MAXLINKS
)
322 res
->status
= NIS_LINKNAMEERROR
;
327 free (ibreq
->ibr_name
);
329 free (ibreq
->ibr_name
);
331 strdup (NIS_RES_OBJECT (res
)->LI_data
.li_name
);
332 if (NIS_RES_OBJECT (res
)->LI_data
.li_attrs
.li_attrs_len
)
333 if (ibreq
->ibr_srch
.ibr_srch_len
== 0)
335 ibreq
->ibr_srch
.ibr_srch_len
=
336 NIS_RES_OBJECT (res
)->LI_data
.li_attrs
.li_attrs_len
;
337 ibreq
->ibr_srch
.ibr_srch_val
=
338 NIS_RES_OBJECT (res
)->LI_data
.li_attrs
.li_attrs_val
;
340 nis_freeresult (res
);
341 res
= calloc (1, sizeof (nis_result
));
347 /* Calback is handled in nis_call.c (__do_niscall2). */
351 /* NIS+ is not installed, or all servers are down. */
355 /* Try the next domainname if we don't follow a link. */
358 free (ibreq
->ibr_name
);
359 res
->status
= NIS_LINKNAMEERROR
;
364 if (names
[name_nr
] == NULL
)
369 ibreq
->ibr_name
= names
[name_nr
];
373 } /* End of not FOLLOW_PATH. */
375 if (names
!= namebuf
)
376 nis_freenames (names
);
380 __nis_destroy_callback (cb
);
381 ibreq
->ibr_cbhost
.ibr_cbhost_len
= 0;
382 ibreq
->ibr_cbhost
.ibr_cbhost_val
= NULL
;
385 nis_free_request (ibreq
);
391 nis_add_entry (const_nis_name name
, const nis_object
*obj
,
396 ib_request
*ibreq
= calloc (1, sizeof (ib_request
));
397 char *p1
, *p2
, *p3
, *p4
;
398 char buf1
[strlen (name
) + 20];
399 char buf4
[strlen (name
) + 20];
401 res
= calloc (1, sizeof (nis_result
));
403 if (__create_ib_request (name
, ibreq
, flags
) == NULL
)
405 res
->status
= NIS_BADNAME
;
409 ibreq
->ibr_obj
.ibr_obj_val
= nis_clone_object (obj
, NULL
);
410 ibreq
->ibr_obj
.ibr_obj_len
= 1;
412 p1
= ibreq
->ibr_obj
.ibr_obj_val
->zo_name
;
413 if (p1
== NULL
|| strlen (p1
) == 0)
414 ibreq
->ibr_obj
.ibr_obj_val
->zo_name
=
415 nis_leaf_of_r (name
, buf1
, sizeof (buf1
));
417 p2
= ibreq
->ibr_obj
.ibr_obj_val
->zo_owner
;
418 if (p2
== NULL
|| strlen (p2
) == 0)
419 ibreq
->ibr_obj
.ibr_obj_val
->zo_owner
= nis_local_principal ();
421 p3
= ibreq
->ibr_obj
.ibr_obj_val
->zo_group
;
422 if (p3
== NULL
|| strlen (p3
) == 0)
423 ibreq
->ibr_obj
.ibr_obj_val
->zo_group
= nis_local_group ();
425 p4
= ibreq
->ibr_obj
.ibr_obj_val
->zo_domain
;
426 ibreq
->ibr_obj
.ibr_obj_val
->zo_domain
=
427 nis_domain_of_r (name
, buf4
, sizeof (buf4
));
429 if ((status
= __do_niscall (ibreq
->ibr_name
, NIS_IBADD
,
430 (xdrproc_t
) xdr_ib_request
,
432 (xdrproc_t
) xdr_nis_result
,
433 (caddr_t
) res
, 0, NULL
)) != NIS_SUCCESS
)
434 res
->status
= status
;
436 ibreq
->ibr_obj
.ibr_obj_val
->zo_name
= p1
;
437 ibreq
->ibr_obj
.ibr_obj_val
->zo_owner
= p2
;
438 ibreq
->ibr_obj
.ibr_obj_val
->zo_group
= p3
;
439 ibreq
->ibr_obj
.ibr_obj_val
->zo_domain
= p4
;
441 nis_free_request (ibreq
);
447 nis_modify_entry (const_nis_name name
, const nis_object
*obj
,
452 ib_request
*ibreq
= calloc (1, sizeof (ib_request
));
453 char *p1
, *p2
, *p3
, *p4
;
454 char buf1
[strlen (name
) + 20];
455 char buf4
[strlen (name
) + 20];
457 res
= calloc (1, sizeof (nis_result
));
459 if (__create_ib_request (name
, ibreq
, flags
) == NULL
)
461 res
->status
= NIS_BADNAME
;
465 ibreq
->ibr_obj
.ibr_obj_val
= nis_clone_object (obj
, NULL
);
466 ibreq
->ibr_obj
.ibr_obj_len
= 1;
468 p1
= ibreq
->ibr_obj
.ibr_obj_val
->zo_name
;
469 if (p1
== NULL
|| strlen (p1
) == 0)
470 ibreq
->ibr_obj
.ibr_obj_val
->zo_name
=
471 nis_leaf_of_r (name
, buf1
, sizeof (buf1
));
473 p2
= ibreq
->ibr_obj
.ibr_obj_val
->zo_owner
;
474 if (p2
== NULL
|| strlen (p2
) == 0)
475 ibreq
->ibr_obj
.ibr_obj_val
->zo_owner
= nis_local_principal ();
477 p3
= ibreq
->ibr_obj
.ibr_obj_val
->zo_group
;
478 if (p3
== NULL
|| strlen (p3
) == 0)
479 ibreq
->ibr_obj
.ibr_obj_val
->zo_group
= nis_local_group ();
481 p4
= ibreq
->ibr_obj
.ibr_obj_val
->zo_domain
;
482 ibreq
->ibr_obj
.ibr_obj_val
->zo_domain
=
483 nis_domain_of_r (name
, buf4
, sizeof (buf4
));
485 if ((status
= __do_niscall (ibreq
->ibr_name
, NIS_IBMODIFY
,
486 (xdrproc_t
) xdr_ib_request
,
487 (caddr_t
) ibreq
, (xdrproc_t
) xdr_nis_result
,
488 (caddr_t
) res
, 0, NULL
)) != NIS_SUCCESS
)
489 res
->status
= status
;
491 ibreq
->ibr_obj
.ibr_obj_val
->zo_name
= p1
;
492 ibreq
->ibr_obj
.ibr_obj_val
->zo_owner
= p2
;
493 ibreq
->ibr_obj
.ibr_obj_val
->zo_group
= p3
;
494 ibreq
->ibr_obj
.ibr_obj_val
->zo_domain
= p4
;
496 nis_free_request (ibreq
);
502 nis_remove_entry (const_nis_name name
, const nis_object
*obj
,
506 ib_request
*ibreq
= calloc (1, sizeof (ib_request
));
509 res
= calloc (1, sizeof (nis_result
));
511 if (__create_ib_request (name
, ibreq
, flags
) == NULL
)
513 res
->status
= NIS_BADNAME
;
519 ibreq
->ibr_obj
.ibr_obj_val
= nis_clone_object (obj
, NULL
);
520 ibreq
->ibr_obj
.ibr_obj_len
= 1;
523 if ((status
= __do_niscall (ibreq
->ibr_name
, NIS_IBREMOVE
,
524 (xdrproc_t
) xdr_ib_request
,
525 (caddr_t
) ibreq
, (xdrproc_t
) xdr_nis_result
,
526 (caddr_t
) res
, 0, NULL
)) != NIS_SUCCESS
)
527 res
->status
= status
;
529 nis_free_request (ibreq
);
535 nis_first_entry (const_nis_name name
)
538 ib_request
*ibreq
= calloc (1, sizeof (ib_request
));
541 res
= calloc (1, sizeof (nis_result
));
543 if (__create_ib_request (name
, ibreq
, 0) == NULL
)
545 res
->status
= NIS_BADNAME
;
549 if ((status
= __do_niscall (ibreq
->ibr_name
, NIS_IBFIRST
,
550 (xdrproc_t
) xdr_ib_request
,
551 (caddr_t
) ibreq
, (xdrproc_t
) xdr_nis_result
,
552 (caddr_t
) res
, 0, NULL
)) != NIS_SUCCESS
)
553 res
->status
= status
;
555 nis_free_request (ibreq
);
561 nis_next_entry (const_nis_name name
, const netobj
*cookie
)
564 ib_request
*ibreq
= calloc (1, sizeof (ib_request
));
567 res
= calloc (1, sizeof (nis_result
));
569 if (__create_ib_request (name
, ibreq
, 0) == NULL
)
571 res
->status
= NIS_BADNAME
;
577 ibreq
->ibr_cookie
.n_bytes
= malloc (cookie
->n_len
);
578 if (ibreq
->ibr_cookie
.n_bytes
== NULL
)
580 res
->status
= NIS_NOMEMORY
;
584 memcpy (ibreq
->ibr_cookie
.n_bytes
, cookie
->n_bytes
, cookie
->n_len
);
585 ibreq
->ibr_cookie
.n_len
= cookie
->n_len
;
588 if ((status
= __do_niscall (ibreq
->ibr_name
, NIS_IBNEXT
,
589 (xdrproc_t
) xdr_ib_request
,
590 (caddr_t
) ibreq
, (xdrproc_t
) xdr_nis_result
,
591 (caddr_t
) res
, 0, NULL
)) != NIS_SUCCESS
)
592 res
->status
= status
;
594 nis_free_request (ibreq
);