nis_result *
nis_add_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 (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;
    }

  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_IBADD,
			      (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;
}
Esempio n. 2
0
static enum nss_status
internal_setgrent (int *errnop)
{
  enum nss_status status = NSS_STATUS_SUCCESS;

  if (grp_tablename_val == NULL)
    status = _nss_grp_create_tablename (errnop);

  if (status == NSS_STATUS_SUCCESS)
    {
      ibreq = __create_ib_request (grp_tablename_val, 0);
      if (ibreq == NULL)
	{
	  *errnop = errno;
	  return NSS_STATUS_TRYAGAIN;
	}

      nis_error retcode = __prepare_niscall (grp_tablename_val, &dir, &bptr, 0);
      if (retcode != NIS_SUCCESS)
	{
	  nis_free_request (ibreq);
	  ibreq = NULL;
	  status = niserr2nss (retcode);
	}
    }

  return status;
}
Esempio n. 3
0
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;
    }

    ibreq = __create_ib_request (name, flags);
    if (ibreq == 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;
}
Esempio n. 4
0
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;
}
Esempio n. 5
0
static void
internal_endgrent (void)
{
  __nisbind_destroy (&bptr);
  memset (&bptr, '\0', sizeof (bptr));

  nis_free_directory (dir);
  dir = NULL;

  nis_free_request (ibreq);
  ibreq = NULL;

  xdr_free ((xdrproc_t) xdr_netobj, (char *) &cursor);
  memset (&cursor, '\0', sizeof (cursor));

  free (tablepath);
  tableptr = tablepath = NULL;
}
Esempio n. 6
0
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;
}
Esempio n. 7
0
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 == NULL)
        {
            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;
}
Esempio n. 8
0
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 ? */
    nis_result *allres = NULL;

    if (res == NULL)
        return NULL;

    if (name == NULL)
    {
        status = NIS_BADNAME;
err_out:
        nis_freeresult (allres);
        memset (res, '\0', sizeof (nis_result));
        NIS_RES_STATUS (res) = status;
        return res;
    }

    ibreq = __create_ib_request (name, flags);
    if (ibreq == NULL)
    {
        status = 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);
            status = NIS_BADNAME;
            goto err_out;
        }
        ibreq->ibr_name = strdup (names[name_nr]);
        if (ibreq->ibr_name == NULL)
        {
            nis_freenames (names);
            nis_free_request (ibreq);
            status = 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,
                                   ibreq->ibr_srch.ibr_srch_val != NULL,
                                   &dir, &bptr, flags & ~MASTER_ONLY);
        if (status != NIS_SUCCESS)
        {
            NIS_RES_STATUS (res) = status;
            goto fail3;
        }

        while (__nisbind_connect (&bptr) != NIS_SUCCESS)
            if (__nisbind_next (&bptr) != NIS_SUCCESS)
            {
                NIS_RES_STATUS (res) = NIS_NAMEUNREACHABLE;
                goto fail;
            }

        if (callback != NULL)
        {
            assert (cb == 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);
                        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);
                        nis_freeresult (allres);
                        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.  */
                    xdr_free ((xdrproc_t) _xdr_nis_result, (char *)res);
                    memset (res, '\0', sizeof (*res));
                    first_try = 1; /* Try at first the old binding */
                    goto again;
                }
                else if ((flags & FOLLOW_PATH)
                         && NIS_RES_STATUS (res) == NIS_PARTIAL)
                {
                    enum nis_error err = __follow_path (&tablepath, &tableptr,
                                                        ibreq, &bptr);
                    if (err != NIS_SUCCESS)
                    {
                        if (err == NIS_NOMEMORY)
                            NIS_RES_STATUS (res) = err;
                        ++done;
                    }
                    else
                    {
                        /* 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.  */
                        xdr_free ((xdrproc_t) _xdr_nis_result, (char *) res);
                        memset (res, '\0', sizeof (*res));
                        first_try = 1;
                        goto again;
                    }
                }
                else if ((flags & (FOLLOW_PATH | ALL_RESULTS))
                         == (FOLLOW_PATH | ALL_RESULTS))
                {
                    if (allres == NULL)
                    {
                        allres = res;
                        res = malloc (sizeof (nis_result));
                        if (res == NULL)
                        {
                            res = allres;
                            allres = NULL;
                            NIS_RES_STATUS (res) = NIS_NOMEMORY;
                            goto fail;
                        }
                        NIS_RES_STATUS (res) = NIS_RES_STATUS (allres);
                    }
                    else
                    {
                        nis_object *objects_val
                            = realloc (NIS_RES_OBJECT (allres),
                                       (NIS_RES_NUMOBJ (allres)
                                        + NIS_RES_NUMOBJ (res))
                                       * sizeof (nis_object));
                        if (objects_val == NULL)
                        {
                            NIS_RES_STATUS (res) = NIS_NOMEMORY;
                            goto fail;
                        }
                        NIS_RES_OBJECT (allres) = objects_val;
                        memcpy (NIS_RES_OBJECT (allres) + NIS_RES_NUMOBJ (allres),
                                NIS_RES_OBJECT (res),
                                NIS_RES_NUMOBJ (res) * sizeof (nis_object));
                        NIS_RES_NUMOBJ (allres) += NIS_RES_NUMOBJ (res);
                        NIS_RES_NUMOBJ (res) = 0;
                        free (NIS_RES_OBJECT (res));
                        NIS_RES_OBJECT (res) = NULL;
                        NIS_RES_STATUS (allres) = NIS_RES_STATUS (res);
                        xdr_free ((xdrproc_t) _xdr_nis_result, (char *) res);
                    }
                    enum nis_error err = __follow_path (&tablepath, &tableptr,
                                                        ibreq, &bptr);
                    if (err != NIS_SUCCESS)
                    {
                        /* Prepare for the nis_freeresult call.  */
                        memset (res, '\0', sizeof (*res));

                        if (err == NIS_NOMEMORY)
                            NIS_RES_STATUS (allres) = err;
                        ++done;
                    }
                }
                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
                    {
                        enum nis_error err
                            = __follow_path (&tablepath, &tableptr, ibreq, &bptr);
                        if (err != NIS_SUCCESS)
                        {
                            if (err == NIS_NOMEMORY)
                                NIS_RES_STATUS (res) = err;
                            ++done;
                        }
                    }
                }
                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);

    if (allres)
    {
        nis_freeresult (res);
        return allres;
    }

    return res;
}