1 /* Copyright (c) 1997 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
)
208 u_long newflags
= flags
& ~FOLLOW_PATH
;
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
);
243 while (((ntable
= strsep (&p
, ":")) != NULL
) && !done
)
245 /* Do the job recursive here! */
246 res
= nis_list (name
, newflags
, callback
, userdata
);
253 if (!(flags
& ALL_RESULTS
))
257 if (flags
& ALL_RESULTS
)
264 if (res
->status
== NIS_SUCCESS
&& failures
)
265 res
->status
= NIS_S_SUCCESS
;
266 if (res
->status
== NIS_NOTFOUND
&& failures
)
267 res
->status
= NIS_S_NOTFOUND
;
273 if (callback
!= NULL
)
275 cb
= __nis_create_callback (callback
, userdata
, flags
);
276 ibreq
->ibr_cbhost
.ibr_cbhost_len
= 1;
277 ibreq
->ibr_cbhost
.ibr_cbhost_val
= cb
->serv
;
282 memset (res
, '\0', sizeof (nis_result
));
284 status
= __do_niscall (ibreq
->ibr_name
, NIS_IBLIST
,
285 (xdrproc_t
) xdr_ib_request
,
286 (caddr_t
) ibreq
, (xdrproc_t
) xdr_nis_result
,
287 (caddr_t
) res
, flags
, cb
);
288 if (status
!= NIS_SUCCESS
)
289 res
->status
= status
;
296 if (__type_of (NIS_RES_OBJECT (res
)) == NIS_LINK_OBJ
&&
297 flags
& FOLLOW_LINKS
) /* We are following links. */
299 /* If we hit the link limit, bail. */
300 if (count_links
> NIS_MAXLINKS
)
302 res
->status
= NIS_LINKNAMEERROR
;
307 free (ibreq
->ibr_name
);
309 free (ibreq
->ibr_name
);
311 strdup (NIS_RES_OBJECT (res
)->LI_data
.li_name
);
312 if (NIS_RES_OBJECT (res
)->LI_data
.li_attrs
.li_attrs_len
)
313 if (ibreq
->ibr_srch
.ibr_srch_len
== 0)
315 ibreq
->ibr_srch
.ibr_srch_len
=
316 NIS_RES_OBJECT (res
)->LI_data
.li_attrs
.li_attrs_len
;
317 ibreq
->ibr_srch
.ibr_srch_val
=
318 NIS_RES_OBJECT (res
)->LI_data
.li_attrs
.li_attrs_val
;
320 nis_freeresult (res
);
321 res
= calloc (1, sizeof (nis_result
));
327 /* Calback is handled in nis_call.c (__do_niscall2). */
331 /* NIS+ is not installed, or all servers are down. */
335 /* Try the next domainname if we don't follow a link. */
338 free (ibreq
->ibr_name
);
339 res
->status
= NIS_LINKNAMEERROR
;
344 if (names
[name_nr
] == NULL
)
349 ibreq
->ibr_name
= names
[name_nr
];
353 } /* End of not FOLLOW_PATH. */
355 if (names
!= namebuf
)
356 nis_freenames (names
);
360 __nis_destroy_callback (cb
);
361 ibreq
->ibr_cbhost
.ibr_cbhost_len
= 0;
362 ibreq
->ibr_cbhost
.ibr_cbhost_val
= NULL
;
365 nis_free_request (ibreq
);
371 nis_add_entry (const_nis_name name
, const nis_object
*obj
,
376 ib_request
*ibreq
= calloc (1, sizeof (ib_request
));
377 char *p1
, *p2
, *p3
, *p4
;
378 char buf1
[strlen (name
) + 20];
379 char buf4
[strlen (name
) + 20];
381 res
= calloc (1, sizeof (nis_result
));
383 if (__create_ib_request (name
, ibreq
, flags
) == NULL
)
385 res
->status
= NIS_BADNAME
;
389 ibreq
->ibr_obj
.ibr_obj_val
= nis_clone_object (obj
, NULL
);
390 ibreq
->ibr_obj
.ibr_obj_len
= 1;
392 p1
= ibreq
->ibr_obj
.ibr_obj_val
->zo_name
;
393 if (p1
== NULL
|| strlen (p1
) == 0)
394 ibreq
->ibr_obj
.ibr_obj_val
->zo_name
=
395 nis_leaf_of_r (name
, buf1
, sizeof (buf1
));
397 p2
= ibreq
->ibr_obj
.ibr_obj_val
->zo_owner
;
398 if (p2
== NULL
|| strlen (p2
) == 0)
399 ibreq
->ibr_obj
.ibr_obj_val
->zo_owner
= nis_local_principal ();
401 p3
= ibreq
->ibr_obj
.ibr_obj_val
->zo_group
;
402 if (p3
== NULL
|| strlen (p3
) == 0)
403 ibreq
->ibr_obj
.ibr_obj_val
->zo_group
= nis_local_group ();
405 p4
= ibreq
->ibr_obj
.ibr_obj_val
->zo_domain
;
406 ibreq
->ibr_obj
.ibr_obj_val
->zo_domain
=
407 nis_domain_of_r (name
, buf4
, sizeof (buf4
));
409 if ((status
= __do_niscall (ibreq
->ibr_name
, NIS_IBADD
,
410 (xdrproc_t
) xdr_ib_request
,
412 (xdrproc_t
) xdr_nis_result
,
413 (caddr_t
) res
, 0, NULL
)) != NIS_SUCCESS
)
414 res
->status
= status
;
416 ibreq
->ibr_obj
.ibr_obj_val
->zo_name
= p1
;
417 ibreq
->ibr_obj
.ibr_obj_val
->zo_owner
= p2
;
418 ibreq
->ibr_obj
.ibr_obj_val
->zo_group
= p3
;
419 ibreq
->ibr_obj
.ibr_obj_val
->zo_domain
= p4
;
421 nis_free_request (ibreq
);
427 nis_modify_entry (const_nis_name name
, const nis_object
*obj
,
432 ib_request
*ibreq
= calloc (1, sizeof (ib_request
));
433 char *p1
, *p2
, *p3
, *p4
;
434 char buf1
[strlen (name
) + 20];
435 char buf4
[strlen (name
) + 20];
437 res
= calloc (1, sizeof (nis_result
));
439 if (__create_ib_request (name
, ibreq
, flags
) == NULL
)
441 res
->status
= NIS_BADNAME
;
445 ibreq
->ibr_obj
.ibr_obj_val
= nis_clone_object (obj
, NULL
);
446 ibreq
->ibr_obj
.ibr_obj_len
= 1;
448 p1
= ibreq
->ibr_obj
.ibr_obj_val
->zo_name
;
449 if (p1
== NULL
|| strlen (p1
) == 0)
450 ibreq
->ibr_obj
.ibr_obj_val
->zo_name
=
451 nis_leaf_of_r (name
, buf1
, sizeof (buf1
));
453 p2
= ibreq
->ibr_obj
.ibr_obj_val
->zo_owner
;
454 if (p2
== NULL
|| strlen (p2
) == 0)
455 ibreq
->ibr_obj
.ibr_obj_val
->zo_owner
= nis_local_principal ();
457 p3
= ibreq
->ibr_obj
.ibr_obj_val
->zo_group
;
458 if (p3
== NULL
|| strlen (p3
) == 0)
459 ibreq
->ibr_obj
.ibr_obj_val
->zo_group
= nis_local_group ();
461 p4
= ibreq
->ibr_obj
.ibr_obj_val
->zo_domain
;
462 ibreq
->ibr_obj
.ibr_obj_val
->zo_domain
=
463 nis_domain_of_r (name
, buf4
, sizeof (buf4
));
465 if ((status
= __do_niscall (ibreq
->ibr_name
, NIS_IBMODIFY
,
466 (xdrproc_t
) xdr_ib_request
,
467 (caddr_t
) ibreq
, (xdrproc_t
) xdr_nis_result
,
468 (caddr_t
) res
, 0, NULL
)) != NIS_SUCCESS
)
469 res
->status
= status
;
471 ibreq
->ibr_obj
.ibr_obj_val
->zo_name
= p1
;
472 ibreq
->ibr_obj
.ibr_obj_val
->zo_owner
= p2
;
473 ibreq
->ibr_obj
.ibr_obj_val
->zo_group
= p3
;
474 ibreq
->ibr_obj
.ibr_obj_val
->zo_domain
= p4
;
476 nis_free_request (ibreq
);
482 nis_remove_entry (const_nis_name name
, const nis_object
*obj
,
486 ib_request
*ibreq
= calloc (1, sizeof (ib_request
));
489 res
= calloc (1, sizeof (nis_result
));
491 if (__create_ib_request (name
, ibreq
, flags
) == NULL
)
493 res
->status
= NIS_BADNAME
;
499 ibreq
->ibr_obj
.ibr_obj_val
= nis_clone_object (obj
, NULL
);
500 ibreq
->ibr_obj
.ibr_obj_len
= 1;
503 if ((status
= __do_niscall (ibreq
->ibr_name
, NIS_IBREMOVE
,
504 (xdrproc_t
) xdr_ib_request
,
505 (caddr_t
) ibreq
, (xdrproc_t
) xdr_nis_result
,
506 (caddr_t
) res
, 0, NULL
)) != NIS_SUCCESS
)
507 res
->status
= status
;
509 nis_free_request (ibreq
);
515 nis_first_entry (const_nis_name name
)
518 ib_request
*ibreq
= calloc (1, sizeof (ib_request
));
521 res
= calloc (1, sizeof (nis_result
));
523 if (__create_ib_request (name
, ibreq
, 0) == NULL
)
525 res
->status
= NIS_BADNAME
;
529 if ((status
= __do_niscall (ibreq
->ibr_name
, NIS_IBFIRST
,
530 (xdrproc_t
) xdr_ib_request
,
531 (caddr_t
) ibreq
, (xdrproc_t
) xdr_nis_result
,
532 (caddr_t
) res
, 0, NULL
)) != NIS_SUCCESS
)
533 res
->status
= status
;
535 nis_free_request (ibreq
);
541 nis_next_entry (const_nis_name name
, const netobj
*cookie
)
544 ib_request
*ibreq
= calloc (1, sizeof (ib_request
));
547 res
= calloc (1, sizeof (nis_result
));
549 if (__create_ib_request (name
, ibreq
, 0) == NULL
)
551 res
->status
= NIS_BADNAME
;
557 ibreq
->ibr_cookie
.n_bytes
= malloc (cookie
->n_len
);
558 if (ibreq
->ibr_cookie
.n_bytes
== NULL
)
560 res
->status
= NIS_NOMEMORY
;
564 memcpy (ibreq
->ibr_cookie
.n_bytes
, cookie
->n_bytes
, cookie
->n_len
);
565 ibreq
->ibr_cookie
.n_len
= cookie
->n_len
;
568 if ((status
= __do_niscall (ibreq
->ibr_name
, NIS_IBNEXT
,
569 (xdrproc_t
) xdr_ib_request
,
570 (caddr_t
) ibreq
, (xdrproc_t
) xdr_nis_result
,
571 (caddr_t
) res
, 0, NULL
)) != NIS_SUCCESS
)
572 res
->status
= status
;
574 nis_free_request (ibreq
);