Skip to content
Navigation Menu
Toggle navigation
Sign in
In this repository
All GitHub Enterprise
↵
Jump to
↵
No suggested jump to results
In this repository
All GitHub Enterprise
↵
Jump to
↵
In this organization
All GitHub Enterprise
↵
Jump to
↵
In this repository
All GitHub Enterprise
↵
Jump to
↵
Sign in
Reseting focus
You signed in with another tab or window.
Reload
to refresh your session.
You signed out in another tab or window.
Reload
to refresh your session.
You switched accounts on another tab or window.
Reload
to refresh your session.
Dismiss alert
{{ message }}
git-mirror
/
glibc
Public
Notifications
You must be signed in to change notification settings
Fork
0
Star
0
Code
Pull requests
0
Actions
Projects
0
Security
Insights
Additional navigation options
Code
Pull requests
Actions
Projects
Security
Insights
Files
f2d5cf5
abilist
aout
argp
assert
bits
catgets
conf
conform
crypt
csu
ctype
debug
dirent
dlfcn
elf
gmon
gnulib
grp
hesiod
hurd
iconv
iconvdata
include
inet
intl
io
libidn
libio
locale
localedata
login
mach
malloc
manual
math
misc
nis
nss_compat
nss_nis
nss_nisplus
rpcsvc
Banner
Depend
Makefile
Versions
libnsl.h
nis_add.c
nis_addmember.c
nis_call.c
nis_callback.c
nis_checkpoint.c
nis_clone_dir.c
nis_clone_obj.c
nis_clone_res.c
nis_creategroup.c
nis_defaults.c
nis_destroygroup.c
nis_domain_of.c
nis_domain_of_r.c
nis_error.c
nis_file.c
nis_findserv.c
nis_free.c
nis_getservlist.c
nis_hash.c
nis_intern.h
nis_ismember.c
nis_local_names.c
nis_lookup.c
nis_mkdir.c
nis_modify.c
nis_ping.c
nis_print.c
nis_print_group_entry.c
nis_remove.c
nis_removemember.c
nis_rmdir.c
nis_server.c
nis_subr.c
nis_table.c
nis_util.c
nis_verifygroup.c
nis_xdr.c
nis_xdr.h
nisplus-parser.h
nss
nss-default.c
nss-nis.c
nss-nis.h
nss-nisplus.c
nss-nisplus.h
yp_xdr.c
ypclnt.c
ypupdate_xdr.c
nptl
nptl_db
nscd
nss
po
posix
pwd
resolv
resource
rt
scripts
setjmp
shadow
signal
socket
soft-fp
stdio-common
stdlib
streams
string
sunrpc
sysdeps
sysvipc
termios
time
timezone
wcsmbs
wctype
.cvsignore
BUGS
CANCEL-FCT-WAIVE
CANCEL-FILE-WAIVE
CONFORMANCE
COPYING
COPYING.LIB
ChangeLog
ChangeLog.1
ChangeLog.10
ChangeLog.11
ChangeLog.12
ChangeLog.13
ChangeLog.14
ChangeLog.15
ChangeLog.16
ChangeLog.2
ChangeLog.3
ChangeLog.4
ChangeLog.5
ChangeLog.6
ChangeLog.7
ChangeLog.8
ChangeLog.9
FAQ
FAQ.in
INSTALL
LICENSES
Makeconfig
Makefile
Makefile.in
Makerules
NAMESPACE
NEWS
NOTES
PROJECTS
README
README.libm
README.template
Rules
Versions.def
WUR-REPORT
abi-tags
aclocal.m4
config-name.in
config.h.in
config.make.in
configure
configure.in
cppflags-iterator.mk
extra-lib.mk
extra-modules.mk
o-iterator.mk
shlib-versions
test-skeleton.c
tls.make.c
version.h
Breadcrumbs
glibc
/
nis
/
nis_table.c
Blame
Blame
Latest commit
History
History
761 lines (659 loc) · 17.8 KB
Breadcrumbs
glibc
/
nis
/
nis_table.c
Top
File metadata and controls
Code
Blame
761 lines (659 loc) · 17.8 KB
Raw
/* Copyright (c) 1997-1999,2003,2004,2005,2006 Free Software Foundation, Inc. This file is part of the GNU C Library. Contributed by Thorsten Kukuk <kukuk@suse.de>, 1997. The GNU C Library is free software; you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation; either version 2.1 of the License, or (at your option) any later version. The GNU C Library is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with the GNU C Library; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA. */ #include <string.h> #include <rpcsvc/nis.h> #include "nis_xdr.h" #include "nis_intern.h" static struct ib_request * __create_ib_request (const_nis_name name, unsigned int flags) { struct ib_request *ibreq = calloc (1, sizeof (struct ib_request)); nis_attr *search_val = NULL; size_t search_len = 0; size_t size = 0; if (ibreq == NULL) return NULL; ibreq->ibr_flags = flags; char *cptr = strdupa (name); /* Not of "[key=value,key=value,...],foo.." format? */ if (cptr[0] != '[') { ibreq->ibr_name = strdup (cptr); if (ibreq->ibr_name == NULL) { free (ibreq); return NULL; } return ibreq; } /* "[key=value,...],foo" format */ ibreq->ibr_name = strchr (cptr, ']'); if (ibreq->ibr_name == NULL || ibreq->ibr_name[1] != ',') { /* The object has not really been built yet so we use free. */ free (ibreq); return NULL; } /* Check if we have an entry of "[key=value,],bar". If, remove the "," */ if (ibreq->ibr_name[-1] == ',') ibreq->ibr_name[-1] = '\0'; else ibreq->ibr_name[0] = '\0'; ibreq->ibr_name += 2; ibreq->ibr_name = strdup (ibreq->ibr_name); if (ibreq->ibr_name == NULL) { free_null: while (search_len-- > 0) { free (search_val[search_len].zattr_ndx); free (search_val[search_len].zattr_val.zattr_val_val); } free (search_val); nis_free_request (ibreq); return NULL; } ++cptr; /* Remove "[" */ while (cptr != NULL && cptr[0] != '\0') { char *key = cptr; char *val = strchr (cptr, '='); cptr = strchr (key, ','); if (cptr != NULL) *cptr++ = '\0'; if (!val) { nis_free_request (ibreq); return NULL; } *val++ = '\0'; if ((search_len + 1) >= size) { size += 1; nis_attr *newp = realloc (search_val, size * sizeof (nis_attr)); if (newp == NULL) goto free_null; search_val = newp; } search_val[search_len].zattr_ndx = strdup (key); if ((search_val[search_len].zattr_ndx) == NULL) goto free_null; search_val[search_len].zattr_val.zattr_val_len = strlen (val) + 1; search_val[search_len].zattr_val.zattr_val_val = strdup (val); if (search_val[search_len].zattr_val.zattr_val_val == NULL) { free (search_val[search_len].zattr_ndx); goto free_null; } ++search_len; } ibreq->ibr_srch.ibr_srch_val = search_val; ibreq->ibr_srch.ibr_srch_len = search_len; return ibreq; } static const struct timeval RPCTIMEOUT = {10, 0}; static char * get_tablepath (char *name, dir_binding *bptr) { enum clnt_stat result; nis_result res; struct ns_request req; memset (&res, '\0', sizeof (res)); req.ns_name = name; req.ns_object.ns_object_len = 0; req.ns_object.ns_object_val = NULL; result = clnt_call (bptr->clnt, NIS_LOOKUP, (xdrproc_t) _xdr_ns_request, (caddr_t) &req, (xdrproc_t) _xdr_nis_result, (caddr_t) &res, RPCTIMEOUT); const char *cptr; if (result == RPC_SUCCESS && NIS_RES_STATUS (&res) == NIS_SUCCESS && __type_of (NIS_RES_OBJECT (&res)) == NIS_TABLE_OBJ) cptr = NIS_RES_OBJECT (&res)->TA_data.ta_path; else cptr = ""; char *str = strdup (cptr); if (result == RPC_SUCCESS) xdr_free ((xdrproc_t) _xdr_nis_result, (char *) &res); return str; } nis_result * nis_list (const_nis_name name, unsigned int flags, int (*callback) (const_nis_name name, const nis_object *object, const void *userdata), const void *userdata) { nis_result *res = malloc (sizeof (nis_result)); ib_request *ibreq; int status; enum clnt_stat clnt_status; int count_links = 0; /* We will only follow NIS_MAXLINKS links! */ int done = 0; nis_name *names; nis_name namebuf[2] = {NULL, NULL}; int name_nr = 0; nis_cb *cb = NULL; char *tableptr; char *tablepath = NULL; int first_try = 0; /* Do we try the old binding at first ? */ int errcode; if (res == NULL) return NULL; if (name == NULL) { errcode = NIS_BADNAME; err_out: memset (res, '\0', sizeof (nis_result)); NIS_RES_STATUS (res) = NIS_BADNAME; return res; } if ((ibreq = __create_ib_request (name, flags)) == NULL) { errcode = NIS_BADNAME; goto err_out; } if ((flags & EXPAND_NAME) && ibreq->ibr_name[strlen (ibreq->ibr_name) - 1] != '.') { names = nis_getnames (ibreq->ibr_name); free (ibreq->ibr_name); ibreq->ibr_name = NULL; if (names == NULL) { nis_free_request (ibreq); errcode = NIS_BADNAME; goto err_out; } ibreq->ibr_name = strdup (names[name_nr]); if (ibreq->ibr_name == NULL) { nis_freenames (names); nis_free_request (ibreq); errcode = NIS_NOMEMORY; goto err_out; } } else { names = namebuf; names[name_nr] = ibreq->ibr_name; } cb = NULL; while (!done) { dir_binding bptr; directory_obj *dir = NULL; memset (res, '\0', sizeof (nis_result)); status = __nisfind_server (ibreq->ibr_name, &dir); if (status != NIS_SUCCESS) { NIS_RES_STATUS (res) = status; goto fail3; } status = __nisbind_create (&bptr, dir->do_servers.do_servers_val, dir->do_servers.do_servers_len, flags); if (status != NIS_SUCCESS) { NIS_RES_STATUS (res) = status; goto fail2; } while (__nisbind_connect (&bptr) != NIS_SUCCESS) if (__nisbind_next (&bptr) != NIS_SUCCESS) { NIS_RES_STATUS (res) = NIS_NAMEUNREACHABLE; goto fail; } if (callback != NULL) { cb = __nis_create_callback (callback, userdata, flags); ibreq->ibr_cbhost.ibr_cbhost_len = 1; ibreq->ibr_cbhost.ibr_cbhost_val = cb->serv; } again: clnt_status = clnt_call (bptr.clnt, NIS_IBLIST, (xdrproc_t) _xdr_ib_request, (caddr_t) ibreq, (xdrproc_t) _xdr_nis_result, (caddr_t) res, RPCTIMEOUT); if (clnt_status != RPC_SUCCESS) NIS_RES_STATUS (res) = NIS_RPCERROR; else switch (NIS_RES_STATUS (res)) { /* start switch */ case NIS_PARTIAL: case NIS_SUCCESS: case NIS_S_SUCCESS: if (__type_of (NIS_RES_OBJECT (res)) == NIS_LINK_OBJ && (flags & FOLLOW_LINKS)) /* We are following links. */ { free (ibreq->ibr_name); ibreq->ibr_name = NULL; /* If we hit the link limit, bail. */ if (count_links > NIS_MAXLINKS) { NIS_RES_STATUS (res) = NIS_LINKNAMEERROR; ++done; break; } ++count_links; ibreq->ibr_name = strdup (NIS_RES_OBJECT (res)->LI_data.li_name); if (ibreq->ibr_name == NULL) { NIS_RES_STATUS (res) = NIS_NOMEMORY; fail: __nisbind_destroy (&bptr); fail2: nis_free_directory (dir); fail3: free (tablepath); if (cb) { __nis_destroy_callback (cb); ibreq->ibr_cbhost.ibr_cbhost_len = 0; ibreq->ibr_cbhost.ibr_cbhost_val = NULL; } if (names != namebuf) nis_freenames (names); nis_free_request (ibreq); return res; } if (NIS_RES_OBJECT (res)->LI_data.li_attrs.li_attrs_len) if (ibreq->ibr_srch.ibr_srch_len == 0) { ibreq->ibr_srch.ibr_srch_len = NIS_RES_OBJECT (res)->LI_data.li_attrs.li_attrs_len; ibreq->ibr_srch.ibr_srch_val = NIS_RES_OBJECT (res)->LI_data.li_attrs.li_attrs_val; } /* The following is a non-obvious optimization. A nis_freeresult call would call xdr_free as the following code. But it also would unnecessarily free the result structure. We avoid this here along with the necessary tests. */ #if 1 xdr_free ((xdrproc_t) _xdr_nis_result, (char *)res); memset (res, '\0', sizeof (*res)); #else nis_freeresult (res); res = calloc (1, sizeof (nis_result)); if (res == NULL) goto fail; #endif first_try = 1; /* Try at first the old binding */ goto again; } else if ((flags & FOLLOW_PATH) && NIS_RES_STATUS (res) == NIS_PARTIAL) { if (tablepath == NULL) { tablepath = get_tablepath (ibreq->ibr_name, &bptr); tableptr = tablepath; } if (tableptr == NULL) { ++done; break; } free (ibreq->ibr_name); ibreq->ibr_name = strsep (&tableptr, ":"); if (ibreq->ibr_name == NULL || ibreq->ibr_name[0] == '\0') { ibreq->ibr_name = strdup (""); if (ibreq->ibr_name == NULL) { NIS_RES_STATUS (res) = NIS_NOMEMORY; goto fail; } ++done; } else { ibreq->ibr_name = strdup (ibreq->ibr_name); /* The following is a non-obvious optimization. A nis_freeresult call would call xdr_free as the following code. But it also would unnecessarily free the result structure. We avoid this here along with the necessary tests. */ #if 1 xdr_free ((xdrproc_t) _xdr_nis_result, (char *)res); memset (res, '\0', sizeof (*res)); if (ibreq->ibr_name == NULL) { NIS_RES_STATUS (res) = NIS_NOMEMORY; goto fail; } #else nis_freeresult (res); res = calloc (1, sizeof (nis_result)); if (res == NULL || ibreq->ibr_name == NULL) { free (res); res = NULL; goto fail; } #endif first_try = 1; goto again; } } else ++done; break; case NIS_CBRESULTS: if (cb != NULL) { __nis_do_callback (&bptr, &res->cookie, cb); NIS_RES_STATUS (res) = cb->result; if (!(flags & ALL_RESULTS)) ++done; else { if (tablepath == NULL) { tablepath = get_tablepath (ibreq->ibr_name, &bptr); tableptr = tablepath; } if (tableptr == NULL) { ++done; break; } free (ibreq->ibr_name); ibreq->ibr_name = strsep (&tableptr, ":"); if (ibreq->ibr_name == NULL || ibreq->ibr_name[0] == '\0') { ibreq->ibr_name = strdup (""); ++done; } else ibreq->ibr_name = strdup (ibreq->ibr_name); if (ibreq->ibr_name == NULL) { NIS_RES_STATUS (res) = NIS_NOMEMORY; goto fail; } } } break; case NIS_SYSTEMERROR: case NIS_NOSUCHNAME: case NIS_NOT_ME: /* If we had first tried the old binding, do nothing, but get a new binding */ if (!first_try) { if (__nisbind_next (&bptr) != NIS_SUCCESS) { ++done; break; /* No more servers to search */ } while (__nisbind_connect (&bptr) != NIS_SUCCESS) { if (__nisbind_next (&bptr) != NIS_SUCCESS) { ++done; break; /* No more servers to search */ } } goto again; } break; default: if (!first_try) { /* Try the next domainname if we don't follow a link. */ free (ibreq->ibr_name); ibreq->ibr_name = NULL; if (count_links) { NIS_RES_STATUS (res) = NIS_LINKNAMEERROR; ++done; break; } ++name_nr; if (names[name_nr] == NULL) { ++done; break; } ibreq->ibr_name = strdup (names[name_nr]); if (ibreq->ibr_name == NULL) { NIS_RES_STATUS (res) = NIS_NOMEMORY; goto fail; } first_try = 1; /* Try old binding at first */ goto again; } break; } first_try = 0; if (cb) { __nis_destroy_callback (cb); ibreq->ibr_cbhost.ibr_cbhost_len = 0; ibreq->ibr_cbhost.ibr_cbhost_val = NULL; cb = NULL; } __nisbind_destroy (&bptr); nis_free_directory (dir); } free (tablepath); if (names != namebuf) nis_freenames (names); nis_free_request (ibreq); return res; } libnsl_hidden_def (nis_list) nis_result * nis_add_entry (const_nis_name name, const nis_object *obj2, unsigned int flags) { nis_result *res = calloc (1, sizeof (nis_result)); if (res == NULL) return NULL; if (name == NULL) { NIS_RES_STATUS (res) = NIS_BADNAME; return res; } size_t namelen = strlen (name); char buf1[namelen + 20]; char buf4[namelen + 20]; ib_request *ibreq = __create_ib_request (name, flags); if (ibreq == NULL) { NIS_RES_STATUS (res) = NIS_BADNAME; return res; } nis_object obj; memcpy (&obj, obj2, sizeof (nis_object)); if (obj.zo_name == NULL || strlen (obj.zo_name) == 0) obj.zo_name = nis_leaf_of_r (name, buf1, sizeof (buf1)); if (obj.zo_owner == NULL || strlen (obj.zo_owner) == 0) obj.zo_owner = nis_local_principal (); if (obj.zo_group == NULL || strlen (obj.zo_group) == 0) obj.zo_group = nis_local_group (); obj.zo_domain = nis_domain_of_r (name, buf4, sizeof (buf4)); ibreq->ibr_obj.ibr_obj_val = nis_clone_object (&obj, NULL); if (ibreq->ibr_obj.ibr_obj_val == NULL) { nis_free_request (ibreq); NIS_RES_STATUS (res) = NIS_NOMEMORY; return res; } ibreq->ibr_obj.ibr_obj_len = 1; nis_error status = __do_niscall (ibreq->ibr_name, NIS_IBADD, (xdrproc_t) _xdr_ib_request, (caddr_t) ibreq, (xdrproc_t) _xdr_nis_result, (caddr_t) res, 0, NULL); if (status != NIS_SUCCESS) NIS_RES_STATUS (res) = status; nis_free_request (ibreq); return res; } nis_result * nis_modify_entry (const_nis_name name, const nis_object *obj2, unsigned int flags) { nis_object obj; nis_result *res; nis_error status; ib_request *ibreq; size_t namelen = strlen (name); char buf1[namelen + 20]; char buf4[namelen + 20]; res = calloc (1, sizeof (nis_result)); if (res == NULL) return NULL; if (( ibreq =__create_ib_request (name, flags)) == NULL) { NIS_RES_STATUS (res) = NIS_BADNAME; return res; } memcpy (&obj, obj2, sizeof (nis_object)); if (obj.zo_name == NULL || strlen (obj.zo_name) == 0) obj.zo_name = nis_leaf_of_r (name, buf1, sizeof (buf1)); if (obj.zo_owner == NULL || strlen (obj.zo_owner) == 0) obj.zo_owner = nis_local_principal (); if (obj.zo_group == NULL || strlen (obj.zo_group) == 0) obj.zo_group = nis_local_group (); obj.zo_domain = nis_domain_of_r (name, buf4, sizeof (buf4)); ibreq->ibr_obj.ibr_obj_val = nis_clone_object (&obj, NULL); if (ibreq->ibr_obj.ibr_obj_val == NULL) { nis_free_request (ibreq); NIS_RES_STATUS (res) = NIS_NOMEMORY; return res; } ibreq->ibr_obj.ibr_obj_len = 1; if ((status = __do_niscall (ibreq->ibr_name, NIS_IBMODIFY, (xdrproc_t) _xdr_ib_request, (caddr_t) ibreq, (xdrproc_t) _xdr_nis_result, (caddr_t) res, 0, NULL)) != NIS_SUCCESS) NIS_RES_STATUS (res) = status; nis_free_request (ibreq); return res; } nis_result * nis_remove_entry (const_nis_name name, const nis_object *obj, unsigned int flags) { nis_result *res; ib_request *ibreq; nis_error status; res = calloc (1, sizeof (nis_result)); if (res == NULL) return NULL; if (name == NULL) { NIS_RES_STATUS (res) = NIS_BADNAME; return res; } if ((ibreq =__create_ib_request (name, flags)) == NULL) { NIS_RES_STATUS (res) = NIS_BADNAME; return res; } if (obj != NULL) { ibreq->ibr_obj.ibr_obj_val = nis_clone_object (obj, NULL); if (ibreq->ibr_obj.ibr_obj_val == NULL) { nis_free_request (ibreq); NIS_RES_STATUS (res) = NIS_NOMEMORY; return res; } ibreq->ibr_obj.ibr_obj_len = 1; } if ((status = __do_niscall (ibreq->ibr_name, NIS_IBREMOVE, (xdrproc_t) _xdr_ib_request, (caddr_t) ibreq, (xdrproc_t) _xdr_nis_result, (caddr_t) res, 0, NULL)) != NIS_SUCCESS) NIS_RES_STATUS (res) = status; nis_free_request (ibreq); return res; } nis_result * nis_first_entry (const_nis_name name) { nis_result *res; ib_request *ibreq; nis_error status; res = calloc (1, sizeof (nis_result)); if (res == NULL) return NULL; if (name == NULL) { NIS_RES_STATUS (res) = NIS_BADNAME; return res; } ibreq = __create_ib_request (name, 0); if (ibreq == NULL) { NIS_RES_STATUS (res) = NIS_BADNAME; return res; } status = __do_niscall (ibreq->ibr_name, NIS_IBFIRST, (xdrproc_t) _xdr_ib_request, (caddr_t) ibreq, (xdrproc_t) _xdr_nis_result, (caddr_t) res, 0, NULL); if (status != NIS_SUCCESS) NIS_RES_STATUS (res) = status; nis_free_request (ibreq); return res; } nis_result * nis_next_entry (const_nis_name name, const netobj *cookie) { nis_result *res; ib_request *ibreq; nis_error status; res = calloc (1, sizeof (nis_result)); if (res == NULL) return NULL; if (name == NULL) { NIS_RES_STATUS (res) = NIS_BADNAME; return res; } ibreq = __create_ib_request (name, 0); if (ibreq == NULL) { NIS_RES_STATUS (res) = NIS_BADNAME; return res; } if (cookie != NULL) { ibreq->ibr_cookie.n_bytes = cookie->n_bytes; ibreq->ibr_cookie.n_len = cookie->n_len; } status = __do_niscall (ibreq->ibr_name, NIS_IBNEXT, (xdrproc_t) _xdr_ib_request, (caddr_t) ibreq, (xdrproc_t) _xdr_nis_result, (caddr_t) res, 0, NULL); if (status != NIS_SUCCESS) NIS_RES_STATUS (res) = status; if (cookie != NULL) { /* Don't give cookie free, it is not from us */ ibreq->ibr_cookie.n_bytes = NULL; ibreq->ibr_cookie.n_len = 0; } nis_free_request (ibreq); return res; }
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
You can’t perform that action at this time.