aboutsummaryrefslogtreecommitdiff
path: root/nis
diff options
context:
space:
mode:
Diffstat (limited to 'nis')
-rw-r--r--nis/nis_call.c114
-rw-r--r--nis/nis_callback.c97
-rw-r--r--nis/nis_clone_obj.c4
-rw-r--r--nis/nis_creategroup.c11
-rw-r--r--nis/nis_findserv.c12
-rw-r--r--nis/nis_intern.h2
6 files changed, 179 insertions, 61 deletions
diff --git a/nis/nis_call.c b/nis/nis_call.c
index affae09..957399e 100644
--- a/nis/nis_call.c
+++ b/nis/nis_call.c
@@ -31,6 +31,9 @@
static struct timeval RPCTIMEOUT = {10, 0};
static struct timeval UDPTIMEOUT = {5, 0};
+extern u_short __pmap_getnisport (struct sockaddr_in *address, u_long program,
+ u_long version, u_int protocol);
+
unsigned long
inetstr2int (const char *str)
{
@@ -134,6 +137,11 @@ __bind_connect (dir_binding *dbp)
if (dbp->addr.sin_addr.s_addr == 0)
return NIS_FAIL;
+ /* Check, if the host is online and rpc.nisd is running. Much faster
+ then the clnt*_create functions: */
+ if (__pmap_getnisport (&dbp->addr, NIS_PROG, NIS_VERSION, IPPROTO_UDP) == 0)
+ return NIS_RPCERROR;
+
dbp->socket = RPC_ANYSOCK;
if (dbp->use_udp)
dbp->clnt = clntudp_create (&dbp->addr, NIS_PROG, NIS_VERSION,
@@ -152,7 +160,7 @@ __bind_connect (dir_binding *dbp)
if (dbp->use_auth)
{
- if (serv->key_type == NIS_PK_DH)
+ if (serv->key_type == NIS_PK_DH && key_secretkey_is_set ())
{
char netname[MAXNETNAMELEN+1];
char *p;
@@ -220,6 +228,7 @@ __bind_create (const nis_server *serv_val, u_int serv_len, u_long flags,
else
dbp->master_only = FALSE;
+ /* We try the first server */
dbp->trys = 1;
for (i = 0; i < serv_len; ++i)
@@ -317,7 +326,6 @@ __do_niscall2 (const nis_server *server, u_int server_len, u_long prog,
if (result != RPC_SUCCESS)
{
- clnt_perror (dbp->clnt, "__do_niscall2: clnt_call");
__bind_destroy (dbp);
retcode = NIS_RPCERROR;
}
@@ -424,31 +432,8 @@ rec_dirsearch (const_nis_name name, directory_obj *dir, u_long flags,
{
fd_result *fd_res;
XDR xdrs;
- char domain [strlen (name) + 3];
-
- nis_domain_of_r (name, domain, sizeof (domain));
- if (strncmp (domain, "org_dir.", 8) == 0)
- {
- char tmp[strlen (name) + 3];
-
- nis_domain_of_r (domain, tmp, sizeof (tmp));
- strcpy (domain, tmp);
- }
- else
- if (strncmp (domain, "groups_dir.", 11) == 0)
- {
- char tmp[strlen (name) + 3];
-
- nis_domain_of_r (domain, tmp, sizeof (tmp));
- strcpy (domain, tmp);
- }
- else
- {
- /* We have no grous_dir or org_dir, so try the complete name */
- strcpy (domain, name);
- }
- switch (nis_dir_cmp (domain, dir->do_name))
+ switch (nis_dir_cmp (name, dir->do_name))
{
case SAME_NAME:
*status = NIS_SUCCESS;
@@ -469,9 +454,9 @@ rec_dirsearch (const_nis_name name, directory_obj *dir, u_long flags,
*status = fd_res->status;
if (fd_res->status != NIS_SUCCESS)
{
- nis_free_directory (dir);
+ /* Try the current directory obj, maybe it works */
__free_fdresult (fd_res);
- return NULL;
+ return dir;
}
obj = calloc(1, sizeof(directory_obj));
xdrmem_create(&xdrs, fd_res->dir_data.dir_data_val,
@@ -498,8 +483,12 @@ rec_dirsearch (const_nis_name name, directory_obj *dir, u_long flags,
{
directory_obj *obj;
char leaf [strlen (name) + 3];
+ char domain [strlen (name) + 3];
char ndomain [strlen (name) + 3];
char *cp;
+ u_int run = 0;
+
+ strcpy (domain, name);
do
{
@@ -511,8 +500,16 @@ rec_dirsearch (const_nis_name name, directory_obj *dir, u_long flags,
nis_leaf_of_r (domain, leaf, sizeof (leaf));
nis_domain_of_r (domain, ndomain, sizeof (ndomain));
strcpy (domain, ndomain);
+ ++run;
}
while (nis_dir_cmp (domain, dir->do_name) != SAME_NAME);
+
+ if (run == 1)
+ {
+ /* We have found the directory above. Use it. */
+ return dir;
+ }
+
cp = strchr (leaf, '\0');
*cp++ = '.';
strcpy (cp, domain);
@@ -521,9 +518,9 @@ rec_dirsearch (const_nis_name name, directory_obj *dir, u_long flags,
*status = fd_res->status;
if (fd_res->status != NIS_SUCCESS)
{
- nis_free_directory (dir);
+ /* Try the current directory object, maybe it works */
__free_fdresult (fd_res);
- return NULL;
+ return dir;
}
obj = calloc(1, sizeof(directory_obj));
xdrmem_create(&xdrs, fd_res->dir_data.dir_data_val,
@@ -550,6 +547,46 @@ rec_dirsearch (const_nis_name name, directory_obj *dir, u_long flags,
return NULL;
}
+/* We try to query the current server for the searched object,
+ maybe he know about it ? */
+static directory_obj *
+first_shoot (const_nis_name name, directory_obj *dir, u_long flags)
+{
+ directory_obj *obj;
+ fd_result *fd_res;
+ XDR xdrs;
+ char domain [strlen (name) + 3];
+
+ if (nis_dir_cmp (name, dir->do_name) == SAME_NAME)
+ return dir;
+
+ nis_domain_of_r (name, domain, sizeof (domain));
+
+ if (nis_dir_cmp (domain, dir->do_name) == SAME_NAME)
+ return dir;
+
+ fd_res = __nis_finddirectory (dir, domain);
+ if (fd_res->status != NIS_SUCCESS)
+ {
+ __free_fdresult (fd_res);
+ return NULL;
+ }
+ obj = calloc(1, sizeof(directory_obj));
+ if (obj == NULL)
+ return NULL;
+ xdrmem_create(&xdrs, fd_res->dir_data.dir_data_val,
+ fd_res->dir_data.dir_data_len, XDR_DECODE);
+ xdr_directory_obj(&xdrs, obj);
+ xdr_destroy(&xdrs);
+ __free_fdresult (fd_res);
+ if (obj != NULL)
+ {
+ nis_free_directory (dir);
+ return obj;
+ }
+ return NULL;
+}
+
nis_error
__do_niscall (const_nis_name name, u_long prog, xdrproc_t xargs,
caddr_t req, xdrproc_t xres, caddr_t resp, u_long flags,
@@ -572,6 +609,8 @@ __do_niscall (const_nis_name name, u_long prog, xdrproc_t xargs,
if (dir == NULL)
{
nis_error status;
+ directory_obj *obj;
+
dir = readColdStartFile ();
if (dir == NULL) /* No /var/nis/NIS_COLD_START->no NIS+ installed */
{
@@ -579,12 +618,19 @@ __do_niscall (const_nis_name name, u_long prog, xdrproc_t xargs,
return NIS_UNAVAIL;
}
- dir = rec_dirsearch (name, dir, flags, &status);
- if (dir == NULL)
+ /* Try at first, if servers in "dir" know our object */
+ obj = first_shoot (name, dir, flags);
+ if (obj == NULL)
{
- __set_errno (saved_errno);
- return status;
+ dir = rec_dirsearch (name, dir, flags, &status);
+ if (dir == NULL)
+ {
+ __set_errno (saved_errno);
+ return status;
+ }
}
+ else
+ dir = obj;
}
if (flags & MASTER_ONLY)
diff --git a/nis/nis_callback.c b/nis/nis_callback.c
index 054b462..7dfab8f 100644
--- a/nis/nis_callback.c
+++ b/nis/nis_callback.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1997 Free Software Foundation, Inc.
+/* Copyright (C) 1997, 1998 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Thorsten Kukuk <kukuk@vt.uni-paderborn.de>, 1997.
@@ -29,13 +29,12 @@
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
+#include <rpc/key_prot.h>
#include <rpcsvc/nis.h>
#include <bits/libc-lock.h>
#include "nis_intern.h"
-extern void get_myaddress (struct sockaddr_in *addr);
-
/* Sorry, we are not able to make this threadsafe. Stupid. But some
functions doesn't send us a nis_result obj, so we don't have a
cookie. Maybe we could use keys for threads ? Have to learn more
@@ -64,6 +63,53 @@ static nis_cb *data;
__libc_lock_define_initialized (static, callback)
+
+static char *
+__nis_getpkey(const char *sname)
+{
+ char buf[(strlen (sname) + 1) * 2 + 40];
+ char pkey[HEXKEYBYTES + 1];
+ char *cp, *domain;
+ nis_result *res;
+ u_int len = 0;
+
+ domain = strchr (sname, '.');
+ if (domain == NULL)
+ return NULL;
+
+ /* Remove prefixing dot */
+ ++domain;
+
+ cp = stpcpy (buf, "[cname=");
+ cp = stpcpy (cp, sname);
+ cp = stpcpy (cp, ",auth_type=DES],cred.org_dir.");
+ cp = stpcpy (cp, domain);
+
+ res = nis_list (buf, USE_DGRAM|NO_AUTHINFO|FOLLOW_LINKS|FOLLOW_PATH,
+ NULL, NULL);
+
+ if (res == NULL)
+ return NULL;
+
+ if (res->status != NIS_SUCCESS)
+ {
+ nis_freeresult (res);
+ return NULL;
+ }
+
+ len = ENTRY_LEN(NIS_RES_OBJECT(res), 3);
+ strncpy (pkey, ENTRY_VAL(NIS_RES_OBJECT(res), 3), len);
+ pkey[len] = '\0';
+ cp = strchr (pkey, ':');
+ if (cp != NULL)
+ *cp = '\0';
+
+ nis_freeresult (res);
+
+ return strdup (pkey);
+}
+
+
static bool_t xdr_cback_data (XDR *, cback_data *);
static void
@@ -82,12 +128,11 @@ cb_prog_1 (struct svc_req *rqstp, SVCXPRT *transp)
switch (rqstp->rq_proc)
{
case NULLPROC:
- (void) svc_sendreply (transp, (xdrproc_t) xdr_void, (char *) NULL);
+ svc_sendreply (transp, (xdrproc_t) xdr_void, (char *) NULL);
return;
case CBPROC_RECEIVE:
{
- char name[NIS_MAXNAMELEN + 1];
u_long i;
xdr_argument = (xdrproc_t) xdr_cback_data;
@@ -101,13 +146,18 @@ cb_prog_1 (struct svc_req *rqstp, SVCXPRT *transp)
bool_result = FALSE;
for (i = 0; i < argument.cbproc_receive_1_arg.entries.entries_len; ++i)
{
- snprintf (name, NIS_MAXNAMELEN, "%s.%s",
- argument.cbproc_receive_1_arg.entries.entries_val[i]->zo_name,
- argument.cbproc_receive_1_arg.entries.entries_val[i]->zo_domain);
+#define cbproc_entry(a) argument.cbproc_receive_1_arg.entries.entries_val[a]
+ char name[strlen (cbproc_entry(i)->zo_name) +
+ strlen (cbproc_entry(i)->zo_domain) + 3];
+ char *cp;
+
+ cp = stpcpy (name, cbproc_entry(i)->zo_name);
+ *cp++ = '.';
+ cp = stpcpy (cp, cbproc_entry(i)->zo_domain);
- if ((data->callback)
- (name, argument.cbproc_receive_1_arg.entries.entries_val[i],
- data->userdata))
+ fprintf (stderr, "name=%s\n", name);
+
+ if ((data->callback) (name, cbproc_entry(i), data->userdata))
{
bool_result = TRUE;
data->nomore = 1;
@@ -273,17 +323,32 @@ __nis_create_callback (int (*callback) (const_nis_name, const nis_object *,
syslog (LOG_ERR, "NIS+: out of memory allocating callback");
return (NULL);
}
- cb->serv->name = strdup (nis_local_host ());
+ cb->serv->name = strdup (nis_local_principal ());
cb->serv->ep.ep_val = (endpoint *) calloc (2, sizeof (endpoint));
cb->serv->ep.ep_len = 1;
cb->serv->ep.ep_val[0].family = strdup ("inet");
cb->callback = callback;
cb->userdata = userdata;
- /* XXX Sometimes, we should add the public key of the user here ! */
- cb->serv->key_type = NIS_PK_NONE;
- cb->serv->pkey.n_bytes = NULL;
- cb->serv->pkey.n_len = 0;
+ if ((flags & NO_AUTHINFO) && key_secretkey_is_set ())
+ {
+ cb->serv->key_type = NIS_PK_NONE;
+ cb->serv->pkey.n_bytes = NULL;
+ cb->serv->pkey.n_len = 0;
+ }
+ else
+ {
+ if ((cb->serv->pkey.n_bytes = __nis_getpkey (cb->serv->name)) == NULL)
+ {
+ cb->serv->pkey.n_len = 0;
+ cb->serv->key_type = NIS_PK_NONE;
+ }
+ else
+ {
+ cb->serv->key_type = NIS_PK_DH;
+ cb->serv->pkey.n_len = strlen(cb->serv->pkey.n_bytes);
+ }
+ }
if (flags & USE_DGRAM)
{
diff --git a/nis/nis_clone_obj.c b/nis/nis_clone_obj.c
index 291148f..133c255 100644
--- a/nis/nis_clone_obj.c
+++ b/nis/nis_clone_obj.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 1997 Free Software Foundation, Inc.
+/* Copyright (c) 1997, 1998 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Thorsten Kukuk <kukuk@vt.uni-paderborn.de>, 1997.
@@ -25,7 +25,7 @@ nis_object *
nis_clone_object (const nis_object *src, nis_object *dest)
{
unsigned char *addr;
- unsigned int size;
+ unsigned long size;
XDR xdrs;
nis_object *res;
diff --git a/nis/nis_creategroup.c b/nis/nis_creategroup.c
index 2405731..a96d67d 100644
--- a/nis/nis_creategroup.c
+++ b/nis/nis_creategroup.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 1997 Free Software Foundation, Inc.
+/* Copyright (c) 1997, 1998 Free Software Foundation, Inc.
This file is part of the GNU C Library.
Contributed by Thorsten Kukuk <kukuk@vt.uni-paderborn.de>, 1997.
@@ -45,16 +45,23 @@ nis_creategroup (const_nis_name group, u_long flags)
return NIS_BADNAME;
obj = calloc (1, sizeof (nis_object));
+ if (obj == NULL)
+ return NIS_NOMEMORY;
+
+ obj->zo_name = strdup (leafbuf);
obj->zo_owner = strdup (__nis_default_owner (NULL));
obj->zo_group = strdup (__nis_default_group (NULL));
+ obj->zo_domain = strdup (domainbuf);
obj->zo_access = __nis_default_access (NULL, 0);
- obj->zo_ttl = __nis_default_ttl (0);
+ obj->zo_ttl = 60 * 60;
obj->zo_data.zo_type = NIS_GROUP_OBJ;
obj->zo_data.objdata_u.gr_data.gr_flags = flags;
obj->zo_data.objdata_u.gr_data.gr_members.gr_members_len = 0;
obj->zo_data.objdata_u.gr_data.gr_members.gr_members_val = NULL;
res = nis_add (buf, obj);
+ if (res == NULL)
+ return NIS_NOMEMORY;
status = res->status;
nis_freeresult (res);
nis_free_object (obj);
diff --git a/nis/nis_findserv.c b/nis/nis_findserv.c
index b6abff1..0e9f017 100644
--- a/nis/nis_findserv.c
+++ b/nis/nis_findserv.c
@@ -60,9 +60,9 @@ struct cu_data
* Calls the pmap service remotely to do the lookup.
* Returns 0 if no map exists.
*/
-static u_short
-__pmap_getport (struct sockaddr_in *address, u_long program,
- u_long version, u_int protocol)
+u_short
+__pmap_getnisport (struct sockaddr_in *address, u_long program,
+ u_long version, u_int protocol)
{
const struct timeval timeout = {1, 0};
const struct timeval tottimeout = {1, 0};
@@ -144,8 +144,9 @@ __nis_findfastest (dir_binding * bind)
inetstr2int (bind->server_val[i].ep.ep_val[j].uaddr);
if (sin.sin_addr.s_addr == 0)
continue;
- sin.sin_port = htons (__pmap_getport (&sin, NIS_PROG,
- NIS_VERSION, IPPROTO_UDP));
+ sin.sin_port = htons (__pmap_getnisport (&sin, NIS_PROG,
+ NIS_VERSION,
+ IPPROTO_UDP));
if (sin.sin_port == 0)
continue;
@@ -184,6 +185,7 @@ __nis_findfastest (dir_binding * bind)
free (pings);
return -1;
}
+ auth_destroy (clnt->cl_auth);
clnt->cl_auth = authunix_create_default ();
cu = (struct cu_data *) clnt->cl_private;
clnt_control (clnt, CLSET_TIMEOUT, (char *) &TIMEOUT00);
diff --git a/nis/nis_intern.h b/nis/nis_intern.h
index 22b753d..311555d 100644
--- a/nis/nis_intern.h
+++ b/nis/nis_intern.h
@@ -74,8 +74,6 @@ extern nis_error __do_niscall __P ((const_nis_name name, u_long prog,
xdrproc_t xargs, caddr_t req,
xdrproc_t xres, caddr_t resp,
u_long flags, nis_cb *cb));
-extern AUTH *authdes_pk_create __P ((const char *, const netobj *, u_int,
- struct sockaddr *, des_block *));
/* NIS+ callback */
extern nis_error __nis_do_callback __P ((struct dir_binding *bptr,