Esempio n. 1
0
/*
 * Simple memory allocator, allocates aligned physical memory.
 * Note that startup_kernel() only allocates memory, never frees.
 * Memory usage just grows in an upward direction.
 */
static void *
do_mem_alloc(uint32_t size, uint32_t align)
{
	uint_t i;
	uint64_t best;
	uint64_t start;
	uint64_t end;

	/*
	 * make sure size is a multiple of pagesize
	 */
	size = RNDUP(size, MMU_PAGESIZE);
	next_avail_addr = RNDUP(next_avail_addr, align);

	/*
	 * XXPV fixme joe
	 *
	 * a really large bootarchive that causes you to run out of memory
	 * may cause this to blow up
	 */
	/* LINTED E_UNEXPECTED_UINT_PROMOTION */
	best = (uint64_t)-size;
	for (i = 0; i < memlists_used; ++i) {
		start = memlists[i].addr;
#if defined(__xpv)
		start += mfn_base;
#endif
		end = start + memlists[i].size;

		/*
		 * did we find the desired address?
		 */
		if (start <= next_avail_addr && next_avail_addr + size <= end) {
			best = next_avail_addr;
			goto done;
		}

		/*
		 * if not is this address the best so far?
		 */
		if (start > next_avail_addr && start < best &&
		    RNDUP(start, align) + size <= end)
			best = RNDUP(start, align);
	}

	/*
	 * We didn't find exactly the address we wanted, due to going off the
	 * end of a memory region. Return the best found memory address.
	 */
done:
	next_avail_addr = best + size;
#if defined(__xpv)
	if (next_avail_addr > scratch_end)
		dboot_panic("Out of mem next_avail: 0x%lx, scratch_end: "
		    "0x%lx", (ulong_t)next_avail_addr,
		    (ulong_t)scratch_end);
#endif
	(void) memset((void *)(uintptr_t)best, 0, size);
	return ((void *)(uintptr_t)best);
}
Esempio n. 2
0
PPLLIST PLListListImport(PPLLIST pList, PPLLIST pImport, HNDPLLITEM hNode)
  {
  PPLLNODE pParent, pi;
  ULONG cb;
  INT i;
  char buffer[256];        // only for TRACE messages

  if ( !pList ) return NULL;
  // allocation needed for the current item
  cb = pImport->cbTot - sizeof(PLLIST);
  // if the current allocation size is not enough reallocate the list
  sprintf (buffer, "total (pList->cbTot): %ld, new item: %ld, pImport->cbTot: %ld sizeof(PLLIST): %ld", pList->cbTot, cb, pImport->cbTot, sizeof(PLLIST));
  TRACE1("%s", buffer);
  sprintf (buffer, "try to reallocate %ld (0x%X),cb: %ld", RNDUP(pList->cbTot + cb, pList->cbGrow), RNDUP(pList->cbTot + cb, pList->cbGrow), cb );
  TRACE1("%s", buffer);
  TRACE2("sizeof(pList) %d (0x%X)", sizeof(pList), sizeof(pList));
  TRACE2("pointer to pList before realloc: 0x%X, pImport: 0x%X", pList, pImport);
  if ( (RNDUP(pList->cbTot, pList->cbGrow) >= (pList->cbTot + cb)) ||
       (NULL != (pList =
                 realloc(pList, RNDUP(pList->cbTot + cb, pList->cbGrow)))) )
    {
    TRACE1("pList after realloc 0x%X", pList);
    pi = (PPLLNODE)((PBYTE)pList + pList->cbTot);
    // get the address of the parent node
    pParent = PNODEFROMHITEM(pList, hNode);
    TRACE1("pParent 0x%X", pParent);
    PREVITEM(pList, pParent)->offNext = pList->cbTot;
    pParent->offLast = pList->cbTot;
    // copy the data from the previous list to the current list
    memcpy(pi, (PBYTE)pImport + sizeof(PLLIST), cb);
    // update the offsets
    pParent->count += pImport->count;
    TRACE1("pParent->count %ld", pParent->count);
    for ( i = 0, cb = pList->cbTot - sizeof(PLLIST); i < pImport->count; ++i )
      {
      if ( pi->offNext )
        {
        pi->offNext += cb;
        }
      else
        {
        pParent->offLast = (HNDPLLITEM)((PBYTE)pi - (PBYTE)pList);
        } /* endif */
      // if the current item is a node
      if ( pi->isNode )
        {
        updateImpListOffsets((PPLLIST)((PBYTE)pList + cb), pi, cb);
        pi->offFirst += cb;
        pi->offLast  += cb;
        pi->offParent = hNode;
        } /* endif */
      pi = (PPLLNODE)NEXTITEM(pList, pi);
      } /* endfor */
    pList->cbTot += pImport->cbTot - sizeof(PLLIST);
    TRACE1("pList->cbTot %ld", pList->cbTot);
    } /* endif */
  TRACE1("pList after realloc 0x%X", pList);
  return pList;
  }
Esempio n. 3
0
static bool_t
svcauth_gss_validate(struct svc_req *rqst, struct svc_rpc_gss_data *gd, struct rpc_msg *msg)
{
	struct opaque_auth	*oa;
	gss_buffer_desc		 rpcbuf, checksum;
	OM_uint32		 maj_stat, min_stat, qop_state;
	u_char			 rpchdr[128];
	int32_t			*buf;

	log_debug("in svcauth_gss_validate()");

	memset(rpchdr, 0, sizeof(rpchdr));

	/* XXX - Reconstruct RPC header for signing (from xdr_callmsg). */
	oa = &msg->rm_call.cb_cred;
	if (oa->oa_length > MAX_AUTH_BYTES)
		return (FALSE);

	/* 8 XDR units from the IXDR macro calls. */
	if (sizeof(rpchdr) < (8 * BYTES_PER_XDR_UNIT +
			      RNDUP(oa->oa_length)))
		return (FALSE);

	buf = (int32_t *)(void *)rpchdr;
	IXDR_PUT_LONG(buf, msg->rm_xid);
	IXDR_PUT_ENUM(buf, msg->rm_direction);
	IXDR_PUT_LONG(buf, msg->rm_call.cb_rpcvers);
	IXDR_PUT_LONG(buf, msg->rm_call.cb_prog);
	IXDR_PUT_LONG(buf, msg->rm_call.cb_vers);
	IXDR_PUT_LONG(buf, msg->rm_call.cb_proc);
	IXDR_PUT_ENUM(buf, oa->oa_flavor);
	IXDR_PUT_LONG(buf, oa->oa_length);
	if (oa->oa_length) {
		memcpy((caddr_t)buf, oa->oa_base, oa->oa_length);
		buf += RNDUP(oa->oa_length) / sizeof(int32_t);
	}
	rpcbuf.value = rpchdr;
	rpcbuf.length = (u_char *)buf - rpchdr;

	checksum.value = msg->rm_call.cb_verf.oa_base;
	checksum.length = msg->rm_call.cb_verf.oa_length;

	maj_stat = gss_verify_mic(&min_stat, gd->ctx, &rpcbuf, &checksum,
				  &qop_state);

	if (maj_stat != GSS_S_COMPLETE) {
		log_status("gss_verify_mic", maj_stat, min_stat);
		if (log_badverf != NULL)
			(*log_badverf)(gd->client_name,
			       svcauth_gss_name,
			       rqst, msg, log_badverf_data);
		return (FALSE);
	}
	return (TRUE);
}
Esempio n. 4
0
PPLLIST PLListExport(PPLLIST pList, HNDPLLITEM hNode,
                     BOOL inclNode, ULONG cbGrow)
  {
  PPLLIST pnew, p;
  ULONG cbTot;
  PPLLNODE pnode, pn;
  // check the cbGrow parameter
  if ( !cbGrow ) cbGrow = pList->cbGrow;
  // if hNode is 0 just duplicate the list
  if ( !hNode )
    {
    if ( NULL != (pnew = malloc(RNDUP(pList->cbTot, cbGrow))) )
      {
      memcpy(pnew, pList, pList->cbTot);
      pnew->cbGrow = cbGrow;
      } /* endif */
    pnew;
    } /* endif */
  // calculate the size of the allocation needed for the new list
  cbTot = sizeof(PLLIST);
  pnode = PNODEFROMHITEM(pList, hNode);
  // size of the current node (if requested)
  if ( inclNode ) cbTot += pnode->offFirst - hNode;
  // total size of the node content
  for ( pn = pnode; !pn->offNext; pn = PNODEFROMHITEM(pList, pn->offParent) ) ;
  cbTot += pn->offNext - pnode->offFirst;
  // allocate the new list
  if ( NULL != (pnew = malloc(RNDUP(cbTot, cbGrow))) )
    {
    pnew->cbTot = cbTot;
    pnew->offFirst = sizeof(PLLIST);
    pnew->offParent = 0;
    pnew->cbGrow = cbGrow;
    if ( inclNode )
      {
      memcpy((PBYTE)pnew + sizeof(PLLIST), pnode, cbTot - sizeof(PLLIST));
      pnew->count = 1;
      pnew->offLast = pnew->offFirst;
      updateExpListOffsets(pnew, (PPLLNODE)pnew,
                           hNode - sizeof(PLLIST));
      }
    else
      {
      memcpy((PBYTE)pnew + sizeof(PLLIST), FIRSTITEM(pList, pnode),
             cbTot - sizeof(PLLIST));
      pnew->count = pnode->count;
      pnew->offLast = pnode->offLast - pnode->offFirst + sizeof(PLLIST);
      updateExpListOffsets(pnew, (PPLLNODE)pnew,
                           pnode->offFirst - sizeof(PLLIST));
      } /* endif */
    } /* endif */
  return pnew;
  }
Esempio n. 5
0
static u_int
fix_buf_size(u_int s)
{
	if (s < 100)
		s = 4000;
	return (RNDUP(s));
}
Esempio n. 6
0
static bool_t
xdrmblk_control(XDR *xdrs, int request, void *info)
{
	mblk_t *m;
	int32_t *int32p;
	int len;

	switch (request) {
	case XDR_PEEK:
		/*
		 * Return the next 4 byte unit in the XDR stream.
		 */
		if (xdrs->x_handy < sizeof (int32_t))
			return (FALSE);

		/* LINTED pointer alignment */
		m = (mblk_t *)xdrs->x_base;
		if (m == NULL)
			return (FALSE);

		/*
		 * If the pointer is not aligned, fail the peek
		 */
		if (!IS_P2ALIGNED(m->b_rptr, sizeof (int32_t)))
			return (FALSE);

		int32p = (int32_t *)info;
		/* LINTED pointer alignment */
		*int32p = ntohl(*((int32_t *)(m->b_rptr)));
		return (TRUE);

	case XDR_SKIPBYTES:
		/* LINTED pointer alignment */
		m = (mblk_t *)xdrs->x_base;
		if (m == NULL)
			return (FALSE);
		int32p = (int32_t *)info;
		len = RNDUP((int)(*int32p));
		if (len < 0)
			return (FALSE);
		while ((xdrs->x_handy -= len) < 0) {
			if ((xdrs->x_handy += len) > 0) {
				m->b_rptr += xdrs->x_handy;
				len -= xdrs->x_handy;
			}
			m = m->b_cont;
			xdrs->x_base = (caddr_t)m;
			if (m == NULL) {
				xdrs->x_handy = 0;
				return (FALSE);
			}
			xdrs->x_handy = (int)(m->b_wptr - m->b_rptr);
		}
		m->b_rptr += len;
		return (TRUE);

	default:
		return (FALSE);
	}
}
Esempio n. 7
0
/*
 * During memory allocation, find the highest address not used yet.
 */
static void
check_higher(paddr_t a)
{
	if (a < next_avail_addr)
		return;
	next_avail_addr = RNDUP(a + 1, MMU_PAGESIZE);
	DBG(next_avail_addr);
}
Esempio n. 8
0
static unsigned
fix_buf_size(
	register unsigned s)
{

	if (s < 100)
		s = 4000;
	return (RNDUP(s));
}
Esempio n. 9
0
static void* heapIncrease(Heap_t uhp, size_t* plen, int* pfl)
  {
  PVOID p = NULL;
  *plen = (size_t)RNDUP(*plen, CB_HEAPBLOCK);
  *pfl = !_BLOCK_CLEAN;
  logwrite("increaseHeap  -                    size : %8u\n", *plen, 0);
  if ( DosSubAllocMem(pbasemem, &p, *plen) )
    return NULL;
  return p;
  }
Esempio n. 10
0
PPLLIST PLListDup(PPLLIST pList, ULONG cb)
  {
  PPLLIST plist;
  if ( pList && !cb )
    cb = RNDUP(pList->cbTot, pList->cbGrow);
  TRACE1("allocate %d bytes", cb);
  if ( NULL != (plist = malloc(cb)) )
    {
    if ( pList ) memcpy(plist, pList, pList->cbTot);
    } /* endif */
  return plist;
  }
Esempio n. 11
0
/*
 * System (Unix) longhand authenticator
 */
enum auth_stat
__svcauth_sys(struct svc_req *rqst, struct rpc_msg *msg)
{
	struct authsys_parms *aup;
	int32_t *buf;
	struct authsys_area *area;
	uint_t auth_len;
	uint_t str_len, gid_len;
	int i;

	/* LINTED pointer cast */
	area = (struct authsys_area *)rqst->rq_clntcred;
	aup = &area->area_aup;
	aup->aup_machname = area->area_machname;
	aup->aup_gids = area->area_gids;
	auth_len = msg->rm_call.cb_cred.oa_length;
	if (auth_len == 0)
		return (AUTH_BADCRED);

	/* LINTED pointer cast */
	buf = (int32_t *)msg->rm_call.cb_cred.oa_base;

	aup->aup_time = IXDR_GET_INT32(buf);
	str_len = IXDR_GET_U_INT32(buf);
	if (str_len > MAX_MACHINE_NAME)
		return (AUTH_BADCRED);
	(void) memcpy(aup->aup_machname, buf, str_len);
	aup->aup_machname[str_len] = 0;
	str_len = RNDUP(str_len);
	buf += str_len / (int)sizeof (int32_t);
	aup->aup_uid = IXDR_GET_INT32(buf);
	aup->aup_gid = IXDR_GET_INT32(buf);
	gid_len = IXDR_GET_U_INT32(buf);
	if (gid_len > NGRPS)
		return (AUTH_BADCRED);
	aup->aup_len = gid_len;
	for (i = 0; i < gid_len; i++) {
		aup->aup_gids[i] = (gid_t)IXDR_GET_INT32(buf);
	}
	/*
	 * five is the smallest unix credentials structure -
	 * timestamp, hostname len (0), uid, gid, and gids len (0).
	 */
	if ((5 + gid_len) * BYTES_PER_XDR_UNIT + str_len > auth_len)
		return (AUTH_BADCRED);

	rqst->rq_xprt->xp_verf.oa_flavor = AUTH_NULL;
	rqst->rq_xprt->xp_verf.oa_length = 0;

	return (AUTH_OK);
}
Esempio n. 12
0
PPLLIST PLListNodeAdd(PPLLIST pList, HNDPLLITEM hNode, PHNDPLLITEM pNode,
                      PPLLISTADDITEM pFunc, PVOID pParm)
  {
  PPLLNODE pParent, pi;
  ULONG cbItem;
  size_t stSize;
  char buffer[128];

  if ( !pList || !pFunc ) return NULL;
  // allocation needed for the current item
  cbItem = pFunc(NULL, pParm) + sizeof(PLLNODE);
  // if the current allocation size is not enough reallocate the list
  stSize = RNDUP(pList->cbTot + cbItem, pList->cbGrow);
  sprintf (buffer, "new size to allocate %ld, total: %ld, item: %ld", stSize, pList->cbTot, cbItem);
  TRACE1("%s", buffer);
  if ( (RNDUP(pList->cbTot, pList->cbGrow) >= (pList->cbTot + cbItem)) ||
       (NULL != (pList =
                 realloc(pList, stSize ))) )
    {
    TRACE1("pList after realloc: 0x%X", pList);
    pi = (PPLLNODE)((PBYTE)pList + pList->cbTot);
    if ( pNode ) *pNode = pList->cbTot;
    // get the address of the parent node
    pParent = PNODEFROMHITEM(pList, hNode);
    PREVITEM(pList, pParent)->offNext = pList->cbTot;
    pParent->offLast = pList->cbTot;
    pi->offFirst = (pList->cbTot += cbItem);
    pi->offNext = 0;
    pi->isNode = 1;
    pi->offLast = 0;
    pi->offParent = (ULONG)hNode;
    pi->count = 0;
    // set the item data via the callback procedure
    pFunc(pi + 1, pParm);
    pParent->count++;             // update the items count
    } /* endif */
  return pList;
  }
Esempio n. 13
0
PPLLIST PLListItemAdd(PPLLIST pList, HNDPLLITEM hNode, PHNDPLLITEM phItem,
                      PPLLISTADDITEM pFunc, PVOID pParm)
  {
  PPLLNODE pParent;
  ULONG cbItem;
  PPLLITEM pi;
  if ( !pList || !pFunc ) return NULL;
  // allocation needed for the current item
  cbItem = pFunc(NULL, pParm) + sizeof(PLLITEM);
  // if the current allocation size is not enough reallocate the list
  if ( RNDUP(pList->cbTot, pList->cbGrow) < RNDUP(pList->cbTot + cbItem, pList->cbGrow) )
    {
    TRACE("reallocating");
    TRACE2("pList->cbTot: %ld, cbItem: %ld", pList->cbTot, cbItem);
    pList = realloc(pList, RNDUP(pList->cbTot + cbItem, pList->cbGrow));
    TRACE("reallocating OKAY");
    }
  if ( pList )
    {
    pi = (PPLLITEM)((PBYTE)pList + pList->cbTot);
    if ( phItem ) *phItem = pList->cbTot;
    // get the address of the parent node
    pParent = PNODEFROMHITEM(pList, hNode);
    PREVITEM(pList, pParent)->offNext = pList->cbTot;
    pParent->offLast = pList->cbTot;
    pList->cbTot += cbItem;
    pi->offNext = 0;
    pi->isNode = 0;
    // set the other item data via the callback procedure
    pFunc(pi + 1, pParm);
    pParent->count++;             // update the items count
    } /* endif */
  if ( pList == NULL )
    {
    TRACE("ERROR: reallocate");
    }
  return pList;
  }
Esempio n. 14
0
static int
svcauth_gss_validate(struct svc_req *req,
		     struct svc_rpc_gss_data *gd,
		     struct rpc_msg *msg)
{
	struct opaque_auth *oa;
	gss_buffer_desc rpcbuf, checksum;
	OM_uint32 maj_stat, min_stat, qop_state;
	u_char rpchdr[RPCHDR_LEN];
	int32_t *buf;

	memset(rpchdr, 0, RPCHDR_LEN);

	/* XXX - Reconstruct RPC header for signing (from xdr_callmsg). */
	oa = &msg->rm_call.cb_cred;
	if (oa->oa_length > MAX_AUTH_BYTES)
		return GSS_S_CALL_BAD_STRUCTURE;
	/* XXX since MAX_AUTH_BYTES is 400, the following code trivially
	 * overruns (up to 431 per Coverity, but compare RPCHDR_LEN with
	 * what is marshalled below). */

	buf = (int32_t *) rpchdr;
	IXDR_PUT_LONG(buf, msg->rm_xid);
	IXDR_PUT_ENUM(buf, msg->rm_direction);
	IXDR_PUT_LONG(buf, msg->rm_call.cb_rpcvers);
	IXDR_PUT_LONG(buf, msg->rm_call.cb_prog);
	IXDR_PUT_LONG(buf, msg->rm_call.cb_vers);
	IXDR_PUT_LONG(buf, msg->rm_call.cb_proc);
	IXDR_PUT_ENUM(buf, oa->oa_flavor);
	IXDR_PUT_LONG(buf, oa->oa_length);
	if (oa->oa_length) {
		memcpy((caddr_t) buf, oa->oa_base, oa->oa_length);
		buf += RNDUP(oa->oa_length) / sizeof(int32_t);
	}
	rpcbuf.value = rpchdr;
	rpcbuf.length = (u_char *) buf - rpchdr;

	checksum.value = msg->rm_call.cb_verf.oa_base;
	checksum.length = msg->rm_call.cb_verf.oa_length;

	maj_stat =
	    gss_verify_mic(&min_stat, gd->ctx, &rpcbuf, &checksum, &qop_state);

	if (maj_stat != GSS_S_COMPLETE) {
		__warnx(TIRPC_DEBUG_FLAG_AUTH, "%s: %d %d", __func__, maj_stat,
			min_stat);
		return (maj_stat);
	}
	return GSS_S_COMPLETE;
}
Esempio n. 15
0
PPLLIST PLListNew(ULONG cbGrow)
  {
  PPLLIST pList;
  if ( !cbGrow ) cbGrow = SLPL_DEFCBGROW;
  if ( NULL != (pList = malloc(RNDUP(sizeof(PLLIST), cbGrow))) )
    {
    pList->isNode = 1;
    pList->offLast = pList->cbTot = pList->offFirst = sizeof(PLLIST);
    pList->offParent = pList->count = 0;
    pList->cbGrow = cbGrow;
    TRACE4("addr=0x%X, size requested=%d, actual size=%d, pList->count=%d", pList, cbGrow, RNDUP(sizeof(PLLIST), cbGrow), pList->count );
    return pList;
    } /* endif */
  return NULL;
  }
Esempio n. 16
0
bool_t
xdr_fastfhandle(XDR *xdrs, fhandle_t **fh)
{
	int32_t *ptr;

	if (xdrs->x_op != XDR_DECODE)
		return (FALSE);

	ptr = XDR_INLINE(xdrs, RNDUP(sizeof (fhandle_t)));
	if (ptr != NULL) {
		*fh = (fhandle_t *)ptr;
		return (TRUE);
	}

	return (FALSE);
}
Esempio n. 17
0
static bool_t
xdrmem_control(XDR *xdrs, int request, void *info)
{
	xdr_bytesrec *xptr;
	int32_t *l;
	int len;

	switch (request) {

	case XDR_GET_BYTES_AVAIL:
		xptr = (xdr_bytesrec *)info;
		xptr->xc_is_last_record = TRUE;
		xptr->xc_num_avail = xdrs->x_handy;
		return (TRUE);

	case XDR_PEEK:
		/*
		 * Return the next 4 byte unit in the XDR stream.
		 */
		if (xdrs->x_handy < sizeof (int32_t))
			return (FALSE);
		l = (int32_t *)info;
		*l = (int32_t)ntohl((uint32_t)
		    (*((int32_t *)(xdrs->x_private))));
		return (TRUE);

	case XDR_SKIPBYTES:
		/*
		 * Skip the next N bytes in the XDR stream.
		 */
		l = (int32_t *)info;
		len = RNDUP((int)(*l));
		if (xdrs->x_handy < len)
			return (FALSE);
		xdrs->x_handy -= len;
		xdrs->x_private = (char *)xdrs->x_private + len;
		return (TRUE);

	}
	return (FALSE);
}
Esempio n. 18
0
uint_t
calc_length(uint_t len)
{
	len = RNDUP(len);

	if (len <= 64 * 1024) {
		if (len > 32 * 1024) {
			len = 64 * 1024;
		} else {
			if (len > 16 * 1024) {
				len = 32 * 1024;
			} else {
				if (len > 8 * 1024) {
					len = 16 * 1024;
				} else {
					len = 8 * 1024;
				}
			}
		}
	}
	return (len);
}
Esempio n. 19
0
/*
 * File access handle
 * The fhandle struct is treated a opaque data on the wire
 */
bool_t
xdr_fhandle(XDR *xdrs, fhandle_t *fh)
{
	int32_t *ptr;
	int32_t *fhp;

	if (xdrs->x_op == XDR_FREE)
		return (TRUE);

	ptr = XDR_INLINE(xdrs, RNDUP(sizeof (fhandle_t)));
	if (ptr != NULL) {
		fhp = (int32_t *)fh;
		if (xdrs->x_op == XDR_DECODE) {
			*fhp++ = *ptr++;
			*fhp++ = *ptr++;
			*fhp++ = *ptr++;
			*fhp++ = *ptr++;
			*fhp++ = *ptr++;
			*fhp++ = *ptr++;
			*fhp++ = *ptr++;
			*fhp = *ptr;
		} else {
			*ptr++ = *fhp++;
			*ptr++ = *fhp++;
			*ptr++ = *fhp++;
			*ptr++ = *fhp++;
			*ptr++ = *fhp++;
			*ptr++ = *fhp++;
			*ptr++ = *fhp++;
			*ptr = *fhp;
		}
		return (TRUE);
	}

	return (xdr_opaque(xdrs, (caddr_t)fh, NFS_FHSIZE));
}
Esempio n. 20
0
/*
 * XDR a call message
 */
bool_t
xdr_callmsg(XDR *xdrs, struct rpc_msg *cmsg)
{
	rpc_inline_t *buf;
	struct opaque_auth *oa;

	if (xdrs->x_op == XDR_ENCODE) {
		if (cmsg->rm_call.cb_cred.oa_length > MAX_AUTH_BYTES)
			return (FALSE);
		if (cmsg->rm_call.cb_verf.oa_length > MAX_AUTH_BYTES)
			return (FALSE);
		buf = XDR_INLINE(xdrs, 8 * BYTES_PER_XDR_UNIT
			+ RNDUP(cmsg->rm_call.cb_cred.oa_length)
			+ 2 * BYTES_PER_XDR_UNIT
			+ RNDUP(cmsg->rm_call.cb_verf.oa_length));
		if (buf != NULL) {
			IXDR_PUT_INT32(buf, cmsg->rm_xid);
			IXDR_PUT_ENUM(buf, cmsg->rm_direction);
			if (cmsg->rm_direction != CALL)
				return (FALSE);
			IXDR_PUT_INT32(buf, cmsg->rm_call.cb_rpcvers);
			if (cmsg->rm_call.cb_rpcvers != RPC_MSG_VERSION)
				return (FALSE);
			IXDR_PUT_INT32(buf, cmsg->rm_call.cb_prog);
			IXDR_PUT_INT32(buf, cmsg->rm_call.cb_vers);
			IXDR_PUT_INT32(buf, cmsg->rm_call.cb_proc);
			oa = &cmsg->rm_call.cb_cred;
			IXDR_PUT_ENUM(buf, oa->oa_flavor);
			IXDR_PUT_INT32(buf, oa->oa_length);
			if (oa->oa_length) {
				(void) memcpy(buf, oa->oa_base, oa->oa_length);
				buf += RNDUP(oa->oa_length) / sizeof (int32_t);
			}
			oa = &cmsg->rm_call.cb_verf;
			IXDR_PUT_ENUM(buf, oa->oa_flavor);
			IXDR_PUT_INT32(buf, oa->oa_length);
			if (oa->oa_length) {
				(void) memcpy(buf, oa->oa_base, oa->oa_length);
				/*
				 * no real need....
				 * buf += RNDUP(oa->oa_length) / sizeof
				 * (int32_t);
				 */
			}
			return (TRUE);
		}
	}
	if (xdrs->x_op == XDR_DECODE) {
		buf = XDR_INLINE(xdrs, 8 * BYTES_PER_XDR_UNIT);
		if (buf != NULL) {
			cmsg->rm_xid = IXDR_GET_INT32(buf);
			cmsg->rm_direction = IXDR_GET_ENUM(buf, enum msg_type);
			if (cmsg->rm_direction != CALL)
				return (FALSE);
			cmsg->rm_call.cb_rpcvers = IXDR_GET_INT32(buf);
			if (cmsg->rm_call.cb_rpcvers != RPC_MSG_VERSION)
				return (FALSE);
			cmsg->rm_call.cb_prog = IXDR_GET_INT32(buf);
			cmsg->rm_call.cb_vers = IXDR_GET_INT32(buf);
			cmsg->rm_call.cb_proc = IXDR_GET_INT32(buf);
			oa = &cmsg->rm_call.cb_cred;
			oa->oa_flavor = IXDR_GET_ENUM(buf, enum_t);
			oa->oa_length = IXDR_GET_INT32(buf);
			if (oa->oa_length) {
				if (oa->oa_length > MAX_AUTH_BYTES)
					return (FALSE);
				if (oa->oa_base == NULL) {
					oa->oa_base = malloc(oa->oa_length);
					if (oa->oa_base == NULL) {
						syslog(LOG_ERR,
							"xdr_callmsg : "
							"out of memory.");
						return (FALSE);
					}
				}
				buf = XDR_INLINE(xdrs, RNDUP(oa->oa_length));
				if (buf == NULL) {
					if (xdr_opaque(xdrs, oa->oa_base,
					    oa->oa_length) == FALSE)
						return (FALSE);
				} else {
					(void) memcpy(oa->oa_base,
					    buf, (size_t)oa->oa_length);
					/*
					 * no real need....
					 * buf += RNDUP(oa->oa_length) /
					 *	(int)sizeof (int32_t);
					 */
				}
			}
			oa = &cmsg->rm_call.cb_verf;
			buf = XDR_INLINE(xdrs, 2 * BYTES_PER_XDR_UNIT);
			if (buf == NULL) {
				if (xdr_enum(xdrs, &oa->oa_flavor) == FALSE ||
				    xdr_u_int(xdrs, &oa->oa_length) == FALSE)
					return (FALSE);
			} else {
				oa->oa_flavor = IXDR_GET_ENUM(buf, enum_t);
				oa->oa_length = IXDR_GET_INT32(buf);
			}
			if (oa->oa_length) {
				if (oa->oa_length > MAX_AUTH_BYTES)
					return (FALSE);
				if (oa->oa_base == NULL) {
					oa->oa_base = malloc(oa->oa_length);
					if (oa->oa_base == NULL) {
						syslog(LOG_ERR,
							"xdr_callmsg : "
							"out of memory.");
						return (FALSE);
					}
				}
				buf = XDR_INLINE(xdrs, RNDUP(oa->oa_length));
				if (buf == NULL) {
					if (xdr_opaque(xdrs, oa->oa_base,
					    oa->oa_length) == FALSE)
						return (FALSE);
				} else {
					(void) memcpy(oa->oa_base,
					    buf, (size_t)oa->oa_length);
					/*
					 * no real need...
					 * buf += RNDUP(oa->oa_length) /
					 *	(int)sizeof (int32_t);
					 */
				}
			}
			return (TRUE);
		}
Esempio n. 21
0
/*
 * XDR a call message
 */
bool_t
xdr_callmsg(
	register XDR *xdrs,
	register struct rpc_msg *cmsg)
{
	register uint32_t *buf;
	register struct opaque_auth *oa;

	if (xdrs->x_op == XDR_ENCODE) {
		if (cmsg->rm_call.cb_cred.oa_length > MAX_AUTH_BYTES) {
			return (FALSE);
		}
		if (cmsg->rm_call.cb_verf.oa_length > MAX_AUTH_BYTES) {
			return (FALSE);
		}
		buf = XDR_INLINE(xdrs, 8 * BYTES_PER_XDR_UNIT
			+ RNDUP(cmsg->rm_call.cb_cred.oa_length)
			+ 2 * BYTES_PER_XDR_UNIT
			+ RNDUP(cmsg->rm_call.cb_verf.oa_length));
		if (buf != NULL) {
			IXDR_PUT_LONG(buf, (uint32_t)cmsg->rm_xid);
			IXDR_PUT_ENUM(buf, (uint32_t)cmsg->rm_direction);
			if (cmsg->rm_direction != CALL) {
				return (FALSE);
			}
			IXDR_PUT_LONG(buf, (uint32_t)cmsg->rm_call.cb_rpcvers);
			if (cmsg->rm_call.cb_rpcvers != RPC_MSG_VERSION) {
				return (FALSE);
			}
			IXDR_PUT_LONG(buf, (uint32_t)cmsg->rm_call.cb_prog);
			IXDR_PUT_LONG(buf, (uint32_t)cmsg->rm_call.cb_vers);
			IXDR_PUT_LONG(buf, (uint32_t)cmsg->rm_call.cb_proc);
			oa = &cmsg->rm_call.cb_cred;
			IXDR_PUT_ENUM(buf, oa->oa_flavor);
			IXDR_PUT_LONG(buf, oa->oa_length);
			if (oa->oa_length) {
				bcopy(oa->oa_base, (char*)buf, oa->oa_length);
				buf += RNDUP(oa->oa_length) / sizeof (*buf);
			}
			oa = &cmsg->rm_call.cb_verf;
			IXDR_PUT_ENUM(buf, oa->oa_flavor);
			IXDR_PUT_LONG(buf, oa->oa_length);
			if (oa->oa_length) {
				bcopy(oa->oa_base, (char*)buf, oa->oa_length);
				/* no real need....
				buf += RNDUP(oa->oa_length) / sizeof (*buf);
				*/
			}
			return (TRUE);
		}
	}
	if (xdrs->x_op == XDR_DECODE) {
		buf = XDR_INLINE(xdrs, 8 * BYTES_PER_XDR_UNIT);
		if (buf != NULL) {
			cmsg->rm_xid = IXDR_GET_LONG(buf);
			cmsg->rm_direction = IXDR_GET_ENUM(buf, enum msg_type);
			if (cmsg->rm_direction != CALL) {
				return (FALSE);
			}
			cmsg->rm_call.cb_rpcvers = IXDR_GET_LONG(buf);
			if (cmsg->rm_call.cb_rpcvers != RPC_MSG_VERSION) {
				return (FALSE);
			}
			cmsg->rm_call.cb_prog = IXDR_GET_LONG(buf);
			cmsg->rm_call.cb_vers = IXDR_GET_LONG(buf);
			cmsg->rm_call.cb_proc = IXDR_GET_LONG(buf);
			oa = &cmsg->rm_call.cb_cred;
			oa->oa_flavor = IXDR_GET_ENUM(buf, enum_t);
			oa->oa_length = IXDR_GET_LONG(buf);
			if (oa->oa_length) {
				if (oa->oa_length > MAX_AUTH_BYTES) {
					return (FALSE);
				}
				if (oa->oa_base == NULL) {
					oa->oa_base = (char*)
						mem_alloc(oa->oa_length);
				}
				buf = XDR_INLINE(xdrs, RNDUP(oa->oa_length));
				if (buf == NULL) {
					if (xdr_opaque(xdrs, oa->oa_base,
					    oa->oa_length) == FALSE) {
						return (FALSE);
					}
				} else {
					bcopy((char*)buf, oa->oa_base,
					    oa->oa_length);
					/* no real need....
					buf += RNDUP(oa->oa_length) /
						sizeof (*buf);
					*/
				}
			}
			oa = &cmsg->rm_call.cb_verf;
			buf = XDR_INLINE(xdrs, 2 * BYTES_PER_XDR_UNIT);
			if (buf == NULL) {
				if (xdr_enum(xdrs, &oa->oa_flavor) == FALSE ||
				    xdr_u_int(xdrs, &oa->oa_length) == FALSE) {
					return (FALSE);
				}
			} else {
				oa->oa_flavor = IXDR_GET_ENUM(buf, enum_t);
				oa->oa_length = IXDR_GET_LONG(buf);
			}
			if (oa->oa_length) {
				if (oa->oa_length > MAX_AUTH_BYTES) {
					return (FALSE);
				}
				if (oa->oa_base == NULL) {
					oa->oa_base = (char*)
						mem_alloc(oa->oa_length);
				}
				buf = XDR_INLINE(xdrs, RNDUP(oa->oa_length));
				if (buf == NULL) {
					if (xdr_opaque(xdrs, oa->oa_base,
					    oa->oa_length) == FALSE) {
						return (FALSE);
					}
				} else {
					bcopy((char*)buf, oa->oa_base,
					    oa->oa_length);
					/* no real need...
					buf += RNDUP(oa->oa_length) /
						sizeof (*buf);
					*/
				}
			}
			return (TRUE);
		}
Esempio n. 22
0
/*
 * XXX - This is a shorter version of vattr_to_fattr4 which only takes care
 * of setattr args - size, mode, uid/gid, times. Eventually we should generalize
 * by using nfs4_ntov_map and the same functions used by the server.
 * Here we just hardcoded the setattr attributes. Note that the order is
 * important - it should follow the order of the bits in the mask.
 */
int
vattr_to_fattr4(vattr_t *vap, vsecattr_t *vsap, fattr4 *fattrp, int flags,
		enum nfs_opnum4 op, bitmap4 supp)
{
	int i, j;
	union nfs4_attr_u *na = NULL;
	int attrcnt;
	int uid_attr = -1;
	int gid_attr = -1;
	int acl_attr = -1;
	XDR xdr;
	ulong_t xdr_size;
	char *xdr_attrs;
	int error = 0;
	uint8_t amap[NFS4_MAXNUM_ATTRS];
	uint_t va_mask = vap->va_mask;
	bool_t (*attrfunc)();

#ifndef lint
	/*
	 * Make sure that maximum attribute number can be expressed as an
	 * 8 bit quantity.
	 */
	ASSERT(NFS4_MAXNUM_ATTRS <= (UINT8_MAX + 1));
#endif
	fattrp->attrmask = 0;
	fattrp->attrlist4_len = 0;
	fattrp->attrlist4 = NULL;
	na = kmem_zalloc(sizeof (union nfs4_attr_u) * nfs4_ntov_map_size,
			KM_SLEEP);

	if (op == OP_SETATTR || op == OP_CREATE || op == OP_OPEN) {
		/*
		 * Note we need to set the attrmask for set operations.
		 * In particular mtime and atime will be set to the
		 * servers time.
		 */
		nfs4_vmask_to_nmask_set(va_mask, &fattrp->attrmask);
		if (vsap != NULL)
			fattrp->attrmask |= FATTR4_ACL_MASK;
		attrfunc = nfs4_set_fattr4_attr;
	} else {	/* verify/nverify */
		/*
		 * Verfy/nverify use the "normal vmask_to_nmask
		 * this routine knows how to handle all vmask bits
		 */
		nfs4_vmask_to_nmask(va_mask, &fattrp->attrmask);
		/*
		 * XXX verify/nverify only works for a subset of attrs that
		 * directly map to vattr_t attrs.  So, verify/nverify is
		 * broken for servers that only support mandatory attrs.
		 * Mask out change attr for now and fix verify op to
		 * work with mandonly servers later.  nfs4_vmask_to_nmask
		 * sets change whenever it sees request for ctime/mtime,
		 * so we must turn off change because nfs4_ver_fattr4_attr
		 * will not generate args for change.  This is a bug
		 * that will be fixed later.
		 * XXX
		 */
		fattrp->attrmask &= ~FATTR4_CHANGE_MASK;
		attrfunc = nfs4_ver_fattr4_attr;
	}

	/* Mask out any rec attrs unsupported by server */
	fattrp->attrmask &= supp;

	attrcnt = 0;
	xdr_size = 0;
	for (i = 0; i < nfs4_ntov_map_size; i++) {
		/*
		 * In the case of FATTR4_ACL_MASK, the vbit will be 0 (zero)
		 * so we must also check if the fbit is FATTR4_ACL_MASK before
		 * skipping over this attribute.
		 */
		if (!(nfs4_ntov_map[i].vbit & vap->va_mask)) {
			if (nfs4_ntov_map[i].fbit != FATTR4_ACL_MASK)
				continue;
			if (vsap == NULL)
				continue;
		}

		if (attrfunc == nfs4_set_fattr4_attr) {
			if (!(*attrfunc)(vap, vsap, &nfs4_ntov_map[i],
			    &na[attrcnt], flags, &error))
				continue;
		} else if (attrfunc == nfs4_ver_fattr4_attr) {
			if (!(*attrfunc)(vap, &nfs4_ntov_map[i], &na[attrcnt],
			    flags, &error))
				continue;
		}

		if (error)
			goto done;	/* Exit! */

		/*
		 * Calculate XDR size
		 */
		if (nfs4_ntov_map[i].xdr_size != 0) {
			/*
			 * If we are setting attributes (attrfunc is
			 * nfs4_set_fattr4_attr) and are setting the
			 * mtime or atime, adjust the xdr size down by
			 * 3 words, since we are using the server's
			 * time as the current time.  Exception: if
			 * ATTR_UTIME is set, the client sends the
			 * time, so leave the xdr size alone.
			 */
			xdr_size += nfs4_ntov_map[i].xdr_size;
			if ((nfs4_ntov_map[i].nval == FATTR4_TIME_ACCESS_SET ||
			    nfs4_ntov_map[i].nval == FATTR4_TIME_MODIFY_SET) &&
				attrfunc == nfs4_set_fattr4_attr &&
				!(flags & ATTR_UTIME)) {
				xdr_size -= 3 * BYTES_PER_XDR_UNIT;
			}
		} else {
			/*
			 * The only zero xdr_sizes we should see
			 * are AT_UID, AT_GID and FATTR4_ACL_MASK
			 */
			ASSERT(nfs4_ntov_map[i].vbit == AT_UID ||
				nfs4_ntov_map[i].vbit == AT_GID ||
				nfs4_ntov_map[i].fbit == FATTR4_ACL_MASK);
			if (nfs4_ntov_map[i].vbit == AT_UID) {
				uid_attr = attrcnt;
				xdr_size += BYTES_PER_XDR_UNIT;	/* length */
				xdr_size +=
					RNDUP(na[attrcnt].owner.utf8string_len);
			} else if (nfs4_ntov_map[i].vbit == AT_GID) {
				gid_attr = attrcnt;
				xdr_size += BYTES_PER_XDR_UNIT;	/* length */
				xdr_size +=
				    RNDUP(
					na[attrcnt].owner_group.utf8string_len);
			} else if (nfs4_ntov_map[i].fbit == FATTR4_ACL_MASK) {
				nfsace4 *tmpacl = (nfsace4 *)vsap->vsa_aclentp;

				acl_attr = attrcnt;
				/* fattr4_acl_len */
				xdr_size += BYTES_PER_XDR_UNIT;
				/* fattr4_acl_val */
				xdr_size += RNDUP((vsap->vsa_aclcnt *
				    (sizeof (acetype4) + sizeof (aceflag4)
				    + sizeof (acemask4))));

				for (j = 0; j < vsap->vsa_aclcnt; j++) {
					/* who - utf8string_len */
					xdr_size += BYTES_PER_XDR_UNIT;
					/* who - utf8string_val */
					xdr_size +=
					    RNDUP(tmpacl[j].who.utf8string_len);
				}
			}
		}

		/*
		 * This attr is going otw
		 */
		amap[attrcnt] = (uint8_t)nfs4_ntov_map[i].nval;
		attrcnt++;

		/*
		 * Clear this bit from test mask so we stop
		 * as soon as all requested attrs are done.
		 */
		va_mask &= ~nfs4_ntov_map[i].vbit;
		if (va_mask == 0 &&
		    (vsap == NULL || (vsap != NULL && acl_attr != -1)))
			break;
	}

	if (attrcnt == 0) {
		goto done;
	}

	fattrp->attrlist4 = xdr_attrs = kmem_alloc(xdr_size, KM_SLEEP);
	fattrp->attrlist4_len = xdr_size;
	xdrmem_create(&xdr, xdr_attrs, xdr_size, XDR_ENCODE);
	for (i = 0; i < attrcnt; i++) {
		if ((*nfs4_ntov_map[amap[i]].xfunc)(&xdr, &na[i]) == FALSE) {
			cmn_err(CE_WARN, "vattr_to_fattr4: xdr encode of "
				"attribute failed\n");
			error = EINVAL;
			break;
		}
	}
done:
	/*
	 * Free any malloc'd attrs, can only be uid or gid
	 */
	if (uid_attr != -1 && na[uid_attr].owner.utf8string_val != NULL) {
		kmem_free(na[uid_attr].owner.utf8string_val,
				na[uid_attr].owner.utf8string_len);
	}
	if (gid_attr != -1 && na[gid_attr].owner_group.utf8string_val != NULL) {
		kmem_free(na[gid_attr].owner_group.utf8string_val,
				na[gid_attr].owner_group.utf8string_len);
	}

	/* xdrmem_destroy(&xdrs); */	/* NO-OP */
	kmem_free(na, sizeof (union nfs4_attr_u) * nfs4_ntov_map_size);
	if (error)
		nfs4_fattr4_free(fattrp);
	return (error);
}
Esempio n. 23
0
File: svc.c Progetto: vonwenm/pbft
enum auth_stat
svcbyz_auth_unix(struct svc_req *rqst, struct rpc_msg *msg) {
  register enum auth_stat stat;
  XDR xdrs;
  register struct authunix_parms *aup;
  register int *buf;
  struct area {
    struct authunix_parms area_aup;
    char area_machname[MAX_MACHINE_NAME+1];
    unsigned int area_gids[NGRPS]; // JC: changed to unsigned
  } *area;
  u_int auth_len;
  int str_len, gid_len;
  register int i;

  area = (struct area *) rqst->rq_clntcred;
  aup = &area->area_aup;
  aup->aup_machname = area->area_machname;
  aup->aup_gids = area->area_gids;
  auth_len = (unsigned int)msg->rm_call.cb_cred.oa_length;
  xdrmem_create(&xdrs, msg->rm_call.cb_cred.oa_base, auth_len,XDR_DECODE);
  buf = XDR_INLINE(&xdrs, auth_len);
  if (buf != NULL) {
    aup->aup_time = IXDR_GET_LONG(buf);
    str_len = IXDR_GET_U_LONG(buf);
    if (str_len > MAX_MACHINE_NAME) {
      stat = AUTH_BADCRED;
      goto done;
    }
    bcopy((caddr_t)buf, aup->aup_machname, (u_int)str_len);
    aup->aup_machname[str_len] = 0;
    str_len = RNDUP(str_len);
    buf += str_len / sizeof(int);
    aup->aup_uid = IXDR_GET_LONG(buf);
    aup->aup_gid = IXDR_GET_LONG(buf);
    gid_len = IXDR_GET_U_LONG(buf);
    if (gid_len > NGRPS) {
      stat = AUTH_BADCRED;
      goto done;
    }
    aup->aup_len = gid_len;
    for (i = 0; i < gid_len; i++) {
      aup->aup_gids[i] = IXDR_GET_LONG(buf);
    }
    /*
     * five is the smallest unix credentials structure -
     * timestamp, hostname len (0), uid, gid, and gids len (0).
     */
    if ((5 + gid_len) * BYTES_PER_XDR_UNIT + str_len > auth_len) {
      (void) printf("bad auth_len gid %d str %d auth %d\n",
		    gid_len, str_len, auth_len);
      stat = AUTH_BADCRED;
      goto done;
    }
  } else if (! xdr_authunix_parms(&xdrs, aup)) {
    xdrs.x_op = XDR_FREE;
    (void)xdr_authunix_parms(&xdrs, aup);
    stat = AUTH_BADCRED;
    goto done;
  }
  rqst->rq_xprt->xp_verf.oa_flavor = AUTH_NULL;
  rqst->rq_xprt->xp_verf.oa_length = 0;
  stat = AUTH_OK;
done:
  XDR_DESTROY(&xdrs);
  return (stat);
}
Esempio n. 24
0
/*
 * Unix longhand authenticator
 */
enum auth_stat
_svcauth_unix(struct svc_req *rqst, struct rpc_msg *msg)
{
	enum auth_stat stat;
	XDR xdrs;
	struct authunix_parms *aup;
	int32_t *buf;
	struct area {
		struct authunix_parms area_aup;
		char area_machname[MAX_MACHINE_NAME+1];
		int area_gids[NGRPS];
	} *area;
	u_int auth_len;
	size_t str_len, gid_len;
	u_int i;

	assert(rqst != NULL);
	assert(msg != NULL);

	area = (struct area *) rqst->rq_clntcred;
	aup = &area->area_aup;
	aup->aup_machname = area->area_machname;
	aup->aup_gids = area->area_gids;
	auth_len = (u_int)msg->rm_call.cb_cred.oa_length;
	xdrmem_create(&xdrs, msg->rm_call.cb_cred.oa_base, auth_len,XDR_DECODE);
	buf = XDR_INLINE(&xdrs, auth_len);
	if (buf != NULL) {
		aup->aup_time = IXDR_GET_INT32(buf);
		str_len = (size_t)IXDR_GET_U_INT32(buf);
		if (str_len > MAX_MACHINE_NAME) {
			stat = AUTH_BADCRED;
			goto done;
		}
		memmove(aup->aup_machname, buf, str_len);
		aup->aup_machname[str_len] = 0;
		str_len = RNDUP(str_len);
		buf += str_len / sizeof (int32_t);
		aup->aup_uid = (int)IXDR_GET_INT32(buf);
		aup->aup_gid = (int)IXDR_GET_INT32(buf);
		gid_len = (size_t)IXDR_GET_U_INT32(buf);
		if (gid_len > NGRPS) {
			stat = AUTH_BADCRED;
			goto done;
		}
		aup->aup_len = gid_len;
		for (i = 0; i < gid_len; i++) {
			aup->aup_gids[i] = (int)IXDR_GET_INT32(buf);
		}
		/*
		 * five is the smallest unix credentials structure -
		 * timestamp, hostname len (0), uid, gid, and gids len (0).
		 */
		if ((5 + gid_len) * BYTES_PER_XDR_UNIT + str_len > auth_len) {
			printf("bad auth_len gid %ld str %ld auth %u\n",
			    (long)gid_len, (long)str_len, auth_len);
			stat = AUTH_BADCRED;
			goto done;
		}
	} else if (! xdr_authunix_parms(&xdrs, aup)) {
		xdrs.x_op = XDR_FREE;
		xdr_authunix_parms(&xdrs, aup);
		stat = AUTH_BADCRED;
		goto done;
	}

       /* get the verifier */
	if ((u_int)msg->rm_call.cb_verf.oa_length) {
		rqst->rq_xprt->xp_verf.oa_flavor =
			msg->rm_call.cb_verf.oa_flavor;
		rqst->rq_xprt->xp_verf.oa_base =
			msg->rm_call.cb_verf.oa_base;
		rqst->rq_xprt->xp_verf.oa_length =
			msg->rm_call.cb_verf.oa_length;
	} else {
		rqst->rq_xprt->xp_verf.oa_flavor = AUTH_NULL;
		rqst->rq_xprt->xp_verf.oa_length = 0;
	}
	stat = AUTH_OK;
done:
	XDR_DESTROY(&xdrs);
	return (stat);
}
Esempio n. 25
0
static void
init_mem_alloc(void)
{
	int	local;	/* variables needed to find start region */
	paddr_t	scratch_start;
	xen_memory_map_t map;

	DBG_MSG("Entered init_mem_alloc()\n");

	/*
	 * Free memory follows the stack. There's at least 512KB of scratch
	 * space, rounded up to at least 2Mb alignment.  That should be enough
	 * for the page tables we'll need to build.  The nucleus memory is
	 * allocated last and will be outside the addressible range.  We'll
	 * switch to new page tables before we unpack the kernel
	 */
	scratch_start = RNDUP((paddr_t)(uintptr_t)&local, MMU_PAGESIZE);
	DBG(scratch_start);
	scratch_end = RNDUP((paddr_t)scratch_start + 512 * 1024, TWO_MEG);
	DBG(scratch_end);

	/*
	 * For paranoia, leave some space between hypervisor data and ours.
	 * Use 500 instead of 512.
	 */
	next_avail_addr = scratch_end - 500 * 1024;
	DBG(next_avail_addr);

	/*
	 * The domain builder gives us at most 1 module
	 */
	DBG(xen_info->mod_len);
	if (xen_info->mod_len > 0) {
		DBG(xen_info->mod_start);
		modules[0].bm_addr = xen_info->mod_start;
		modules[0].bm_size = xen_info->mod_len;
		bi->bi_module_cnt = 1;
		bi->bi_modules = (native_ptr_t)modules;
	} else {
		bi->bi_module_cnt = 0;
		bi->bi_modules = NULL;
	}
	DBG(bi->bi_module_cnt);
	DBG(bi->bi_modules);

	DBG(xen_info->mfn_list);
	DBG(xen_info->nr_pages);
	max_mem = (paddr_t)xen_info->nr_pages << MMU_PAGESHIFT;
	DBG(max_mem);

	/*
	 * Using pseudo-physical addresses, so only 1 memlist element
	 */
	memlists[0].addr = 0;
	DBG(memlists[0].addr);
	memlists[0].size = max_mem;
	DBG(memlists[0].size);
	memlists_used = 1;
	DBG(memlists_used);

	/*
	 * finish building physinstall list
	 */
	sort_physinstall();

	/*
	 * build bios reserved memlists
	 */
	build_rsvdmemlists();

	if (DOMAIN_IS_INITDOMAIN(xen_info)) {
		/*
		 * build PCI Memory list
		 */
		map.nr_entries = MAXMAPS;
		/*LINTED: constant in conditional context*/
		set_xen_guest_handle(map.buffer, map_buffer);
		if (HYPERVISOR_memory_op(XENMEM_machine_memory_map, &map) != 0)
			dboot_panic("getting XENMEM_machine_memory_map failed");
		build_pcimemlists(map_buffer, map.nr_entries);
	}
}
Esempio n. 26
0
/*
 * XDR for unix authentication parameters.
 */
bool_t
xdr_authunix_parms(XDR *xdrs, uint32_t *time, struct xucred *cred)
{
	uint32_t namelen;
	uint32_t ngroups, i;
	uint32_t junk;
	char hostbuf[MAXHOSTNAMELEN];

	if (xdrs->x_op == XDR_ENCODE) {
		/*
		 * Restrict name length to 255 according to RFC 1057.
		 */
		getcredhostname(NULL, hostbuf, sizeof(hostbuf));
		namelen = strlen(hostbuf);
		if (namelen > 255)
			namelen = 255;
	} else {
		namelen = 0;
	}
	junk = 0;

	if (!xdr_uint32_t(xdrs, time)
	    || !xdr_uint32_t(xdrs, &namelen))
		return (FALSE);

	/*
	 * Ignore the hostname on decode.
	 */
	if (xdrs->x_op == XDR_ENCODE) {
		if (!xdr_opaque(xdrs, hostbuf, namelen))
			return (FALSE);
	} else {
		xdr_setpos(xdrs, xdr_getpos(xdrs) + RNDUP(namelen));
	}

	if (!xdr_uint32_t(xdrs, &cred->cr_uid))
		return (FALSE);
	if (!xdr_uint32_t(xdrs, &cred->cr_groups[0]))
		return (FALSE);

	if (xdrs->x_op == XDR_ENCODE) {
		ngroups = cred->cr_ngroups - 1;
		if (ngroups > NGRPS)
			ngroups = NGRPS;
	}

	if (!xdr_uint32_t(xdrs, &ngroups))
		return (FALSE);
	for (i = 0; i < ngroups; i++) {
		if (i + 1 < ngroups_max + 1) {
			if (!xdr_uint32_t(xdrs, &cred->cr_groups[i + 1]))
				return (FALSE);
		} else {
			if (!xdr_uint32_t(xdrs, &junk))
				return (FALSE);
		}
	}

	if (xdrs->x_op == XDR_DECODE) {
		if (ngroups + 1 > ngroups_max + 1)
			cred->cr_ngroups = ngroups_max + 1;
		else
			cred->cr_ngroups = ngroups + 1;
	}

	return (TRUE);
}
Esempio n. 27
0
/*
 * Door IPC based client creation routine.
 *
 * NB: The rpch->cl_auth is initialized to null authentication.
 * 	Caller may wish to set this something more useful.
 *
 * sendsz is the maximum allowable packet size that can be sent.
 * 0 will cause default to be used.
 */
CLIENT *
clnt_door_create(const rpcprog_t program, const rpcvers_t version,
							const uint_t sendsz)
{
	CLIENT			*cl = NULL;	/* client handle */
	struct cu_data		*cu = NULL;	/* private data */
	struct rpc_msg		call_msg;
	char			rendezvous[64];
	int			did;
	struct door_info	info;
	XDR			xdrs;
	struct timeval		now;
	uint_t			ssz;

	(void) sprintf(rendezvous, RPC_DOOR_RENDEZVOUS, (int)program,
								(int)version);
	if ((did = open(rendezvous, O_RDONLY, 0)) < 0) {
		rpc_createerr.cf_stat = RPC_PROGNOTREGISTERED;
		rpc_createerr.cf_error.re_errno = errno;
		rpc_createerr.cf_error.re_terrno = 0;
		return (NULL);
	}

	if (door_info(did, &info) < 0 || (info.di_attributes & DOOR_REVOKED)) {
		(void) close(did);
		rpc_createerr.cf_stat = RPC_PROGNOTREGISTERED;
		rpc_createerr.cf_error.re_errno = errno;
		rpc_createerr.cf_error.re_terrno = 0;
		return (NULL);
	}

	/*
	 * Determine send size
	 */
	if (sendsz < __rpc_min_door_buf_size)
		ssz = __rpc_default_door_buf_size;
	else
		ssz = RNDUP(sendsz);

	if ((cl = malloc(sizeof (CLIENT))) == NULL ||
			(cu = malloc(sizeof (*cu))) == NULL) {
		rpc_createerr.cf_stat = RPC_SYSTEMERROR;
		rpc_createerr.cf_error.re_errno = errno;
		goto err;
	}

	/*
	 * Precreate RPC header for performance reasons.
	 */
	(void) gettimeofday(&now, NULL);
	call_msg.rm_xid = getpid() ^ now.tv_sec ^ now.tv_usec;
	call_msg.rm_call.cb_prog = program;
	call_msg.rm_call.cb_vers = version;
	xdrmem_create(&xdrs, cu->cu_header, sizeof (cu->cu_header), XDR_ENCODE);
	if (!xdr_callhdr(&xdrs, &call_msg)) {
		rpc_createerr.cf_stat = RPC_CANTENCODEARGS;
		rpc_createerr.cf_error.re_errno = 0;
		goto err;
	}
	cu->cu_xdrpos = XDR_GETPOS(&xdrs);

	cu->cu_sendsz = ssz;
	cu->cu_fd = did;
	cu->cu_closeit = TRUE;
	cl->cl_ops = clnt_door_ops();
	cl->cl_private = (caddr_t)cu;
	cl->cl_auth = authnone_create();
	cl->cl_tp = strdup(rendezvous);
	if (cl->cl_tp == NULL) {
		syslog(LOG_ERR, "clnt_door_create: strdup failed");
		rpc_createerr.cf_stat = RPC_SYSTEMERROR;
		rpc_createerr.cf_error.re_errno = errno;
		goto err;
	}
	cl->cl_netid = strdup("door");
	if (cl->cl_netid == NULL) {
		syslog(LOG_ERR, "clnt_door_create: strdup failed");
		if (cl->cl_tp)
			free(cl->cl_tp);
		rpc_createerr.cf_stat = RPC_SYSTEMERROR;
		rpc_createerr.cf_error.re_errno = errno;
		goto err;
	}
	return (cl);
err:
	rpc_createerr.cf_error.re_terrno = 0;
	if (cl) {
		free(cl);
		if (cu)
			free(cu);
	}
	(void) close(did);
	return (NULL);
}
Esempio n. 28
0
/*
 * Slightly modified version of authdessec_create which takes the public key
 * of the server principal as an argument. This spares us a call to
 * getpublickey() which in the nameserver context can cause a deadlock.
 */
AUTH *
authdes_pk_seccreate(const char *servername, netobj *pkey, u_int window,
	const char *timehost, const des_block *ckey, nis_server *srvr)
{
	AUTH *auth;
	struct ad_private *ad;
	char namebuf[MAXNETNAMELEN+1];

	/*
	 * Allocate everything now
	 */
	auth = ALLOC(AUTH);
	if (auth == NULL) {
		syslog(LOG_ERR, "authdes_pk_seccreate: out of memory");
		return (NULL);
	}
	ad = ALLOC(struct ad_private);
	if (ad == NULL) {
		syslog(LOG_ERR, "authdes_pk_seccreate: out of memory");
		goto failed;
	}
	ad->ad_fullname = ad->ad_servername = NULL; /* Sanity reasons */
	ad->ad_timehost = NULL;
	ad->ad_netid = NULL;
	ad->ad_uaddr = NULL;
	ad->ad_nis_srvr = NULL;
	ad->ad_timediff.tv_sec = 0;
	ad->ad_timediff.tv_usec = 0;
	memcpy(ad->ad_pkey, pkey->n_bytes, pkey->n_len);
	if (!getnetname(namebuf))
		goto failed;
	ad->ad_fullnamelen = RNDUP((u_int) strlen(namebuf));
	ad->ad_fullname = (char *)mem_alloc(ad->ad_fullnamelen + 1);
	ad->ad_servernamelen = strlen(servername);
	ad->ad_servername = (char *)mem_alloc(ad->ad_servernamelen + 1);

	if (ad->ad_fullname == NULL || ad->ad_servername == NULL) {
		syslog(LOG_ERR, "authdes_seccreate: out of memory");
		goto failed;
	}
	if (timehost != NULL) {
		ad->ad_timehost = (char *)mem_alloc(strlen(timehost) + 1);
		if (ad->ad_timehost == NULL) {
			syslog(LOG_ERR, "authdes_seccreate: out of memory");
			goto failed;
		}
		memcpy(ad->ad_timehost, timehost, strlen(timehost) + 1);
		ad->ad_dosync = TRUE;
	} else if (srvr != NULL) {
		ad->ad_nis_srvr = srvr;	/* transient */
		ad->ad_dosync = TRUE;
	} else {
		ad->ad_dosync = FALSE;
	}
	memcpy(ad->ad_fullname, namebuf, ad->ad_fullnamelen + 1);
	memcpy(ad->ad_servername, servername, ad->ad_servernamelen + 1);
	ad->ad_window = window;
	if (ckey == NULL) {
		if (key_gendes(&auth->ah_key) < 0) {
			syslog(LOG_ERR,
	    "authdes_seccreate: keyserv(1m) is unable to generate session key");
			goto failed;
		}
	} else {
		auth->ah_key = *ckey;
	}

	/*
	 * Set up auth handle
	 */
	auth->ah_cred.oa_flavor = AUTH_DES;
	auth->ah_verf.oa_flavor = AUTH_DES;
	auth->ah_ops = authdes_ops();
	auth->ah_private = (caddr_t)ad;

	if (!authdes_refresh(auth, NULL)) {
		goto failed;
	}
	ad->ad_nis_srvr = NULL; /* not needed any longer */
	return (auth);

failed:
	if (auth)
		FREE(auth, sizeof (AUTH));
	if (ad) {
		if (ad->ad_fullname)
			FREE(ad->ad_fullname, ad->ad_fullnamelen + 1);
		if (ad->ad_servername)
			FREE(ad->ad_servername, ad->ad_servernamelen + 1);
		if (ad->ad_timehost)
			FREE(ad->ad_timehost, strlen(ad->ad_timehost) + 1);
		if (ad->ad_netid)
			FREE(ad->ad_netid, strlen(ad->ad_netid) + 1);
		if (ad->ad_uaddr)
			FREE(ad->ad_uaddr, strlen(ad->ad_uaddr) + 1);
		FREE(ad, sizeof (struct ad_private));
	}
	return (NULL);
}
Esempio n. 29
0
/*
 * Arguments to remote write and writecache
 */
bool_t
xdr_writeargs(XDR *xdrs, struct nfswriteargs *wa)
{
	int32_t *ptr;
	int32_t *fhp;

	switch (xdrs->x_op) {
	case XDR_DECODE:
		wa->wa_args = &wa->wa_args_buf;
		ptr = XDR_INLINE(xdrs, RNDUP(sizeof (fhandle_t)) +
		    3 * BYTES_PER_XDR_UNIT);
		if (ptr != NULL) {
			fhp = (int32_t *)&wa->wa_fhandle;
			*fhp++ = *ptr++;
			*fhp++ = *ptr++;
			*fhp++ = *ptr++;
			*fhp++ = *ptr++;
			*fhp++ = *ptr++;
			*fhp++ = *ptr++;
			*fhp++ = *ptr++;
			*fhp = *ptr++;
			wa->wa_begoff = IXDR_GET_U_INT32(ptr);
			wa->wa_offset = IXDR_GET_U_INT32(ptr);
			wa->wa_totcount = IXDR_GET_U_INT32(ptr);
			wa->wa_mblk = NULL;
			wa->wa_data = NULL;
			wa->wa_rlist = NULL;
			wa->wa_conn = NULL;
			if (xdrs->x_ops == &xdrmblk_ops) {
				return (xdrmblk_getmblk(xdrs, &wa->wa_mblk,
				    &wa->wa_count));
			} else {
				if (xdrs->x_ops == &xdrrdmablk_ops) {
					if (xdrrdma_getrdmablk(xdrs,
					    &wa->wa_rlist,
					    &wa->wa_count,
					    &wa->wa_conn,
					    NFS_MAXDATA) == TRUE)
					return (xdrrdma_read_from_client(
					    wa->wa_rlist,
					    &wa->wa_conn,
					    wa->wa_count));

					wa->wa_rlist = NULL;
					wa->wa_conn = NULL;
				}
			}

			/*
			 * It is just as efficient to xdr_bytes
			 * an array of unknown length as to inline copy it.
			 */
			return (xdr_bytes(xdrs, &wa->wa_data,
			    &wa->wa_count, NFS_MAXDATA));
		}
		if (xdr_fhandle(xdrs, &wa->wa_fhandle) &&
		    xdr_u_int(xdrs, &wa->wa_begoff) &&
		    xdr_u_int(xdrs, &wa->wa_offset) &&
		    xdr_u_int(xdrs, &wa->wa_totcount)) {
			/* deal with the variety of data transfer types */

			wa->wa_mblk = NULL;
			wa->wa_data = NULL;
			wa->wa_rlist = NULL;
			wa->wa_conn = NULL;

			if (xdrs->x_ops == &xdrmblk_ops) {
				if (xdrmblk_getmblk(xdrs, &wa->wa_mblk,
				    &wa->wa_count) == TRUE)
					return (TRUE);
			} else {
				if (xdrs->x_ops == &xdrrdmablk_ops) {
					if (xdrrdma_getrdmablk(xdrs,
					    &wa->wa_rlist,
					    &wa->wa_count,
					    &wa->wa_conn,
					    NFS_MAXDATA) == TRUE)
					return (xdrrdma_read_from_client(
					    wa->wa_rlist,
					    &wa->wa_conn,
					    wa->wa_count));

					wa->wa_rlist = NULL;
					wa->wa_conn = NULL;
				}
			}
			return (xdr_bytes(xdrs, &wa->wa_data,
			    &wa->wa_count, NFS_MAXDATA));
		}
		return (FALSE);
	case XDR_ENCODE:
		ptr = XDR_INLINE(xdrs, RNDUP(sizeof (fhandle_t)) +
		    3 * BYTES_PER_XDR_UNIT);
		if (ptr != NULL) {
			fhp = (int32_t *)&wa->wa_fhandle;
			*ptr++ = *fhp++;
			*ptr++ = *fhp++;
			*ptr++ = *fhp++;
			*ptr++ = *fhp++;
			*ptr++ = *fhp++;
			*ptr++ = *fhp++;
			*ptr++ = *fhp++;
			*ptr++ = *fhp;
			IXDR_PUT_U_INT32(ptr, wa->wa_begoff);
			IXDR_PUT_U_INT32(ptr, wa->wa_offset);
			IXDR_PUT_U_INT32(ptr, wa->wa_totcount);
		} else {
			if (!(xdr_fhandle(xdrs, &wa->wa_fhandle) &&
			    xdr_u_int(xdrs, &wa->wa_begoff) &&
			    xdr_u_int(xdrs, &wa->wa_offset) &&
			    xdr_u_int(xdrs, &wa->wa_totcount)))
				return (FALSE);
		}

		return (xdr_bytes(xdrs, &wa->wa_data, &wa->wa_count,
		    NFS_MAXDATA));
	case XDR_FREE:
		if (wa->wa_rlist) {
			(void) xdrrdma_free_clist(wa->wa_conn, wa->wa_rlist);
			wa->wa_rlist = NULL;
		}

		if (wa->wa_data != NULL) {
			kmem_free(wa->wa_data, wa->wa_count);
			wa->wa_data = NULL;
		}
		return (TRUE);
	}
	return (FALSE);
}
Esempio n. 30
0
/*
 * Unix longhand authenticator
 */
enum auth_stat
_svcauth_unix(struct svc_req *rqst, struct rpc_msg *msg)
{
	enum auth_stat stat;
	XDR xdrs;
	int32_t *buf;
	uint32_t time;
	struct xucred *xcr;
	u_int auth_len;
	size_t str_len, gid_len;
	u_int i;

	xcr = rqst->rq_clntcred;
	auth_len = (u_int)msg->rm_call.cb_cred.oa_length;
	xdrmem_create(&xdrs, msg->rm_call.cb_cred.oa_base, auth_len,
	    XDR_DECODE);
	buf = XDR_INLINE(&xdrs, auth_len);
	if (buf != NULL) {
		time = IXDR_GET_UINT32(buf);
		str_len = (size_t)IXDR_GET_UINT32(buf);
		if (str_len > MAX_MACHINE_NAME) {
			stat = AUTH_BADCRED;
			goto done;
		}
		str_len = RNDUP(str_len);
		buf += str_len / sizeof (int32_t);
		xcr->cr_uid = IXDR_GET_UINT32(buf);
		xcr->cr_groups[0] = IXDR_GET_UINT32(buf);
		gid_len = (size_t)IXDR_GET_UINT32(buf);
		if (gid_len > NGRPS) {
			stat = AUTH_BADCRED;
			goto done;
		}
		for (i = 0; i < gid_len; i++) {
			if (i + 1 < XU_NGROUPS)
				xcr->cr_groups[i + 1] = IXDR_GET_INT32(buf);
			else
				buf++;
		}
		if (gid_len + 1 > XU_NGROUPS)
			xcr->cr_ngroups = XU_NGROUPS;
		else
			xcr->cr_ngroups = gid_len + 1;

		/*
		 * five is the smallest unix credentials structure -
		 * timestamp, hostname len (0), uid, gid, and gids len (0).
		 */
		if ((5 + gid_len) * BYTES_PER_XDR_UNIT + str_len > auth_len) {
			(void) printf("bad auth_len gid %ld str %ld auth %u\n",
			    (long)gid_len, (long)str_len, auth_len);
			stat = AUTH_BADCRED;
			goto done;
		}
	} else if (! xdr_authunix_parms(&xdrs, &time, xcr)) {
		stat = AUTH_BADCRED;
		goto done;
	}

	rqst->rq_verf = _null_auth;
	stat = AUTH_OK;
done:
	XDR_DESTROY(&xdrs);

	return (stat);
}