/*++
Copyright (c) 1992 Microsoft Corporation
Module Name:
sysdb.c
Abstract:
Client side of system database (password and group) access routines.
Author:
Matthew Bradburn (mattbr) 04-Mar-1992
Revision History:
--*/
#include <unistd.h>
#include <pwd.h>
#include <grp.h>
#include <stdio.h>
#include "psxdll.h"
extern PVOID PsxPortMemoryBase;
static char pwbuf[ARG_MAX];
static char grbuf[ARG_MAX];
struct passwd *
_CRTAPI1
getpwuid(uid_t uid)
{
PSX_API_MSG m;
PPSX_GETPWUID_MSG args;
NTSTATUS Status;
struct passwd *tmpbuf;
args = &m.u.GetPwUid;
PSX_FORMAT_API_MSG(m, PsxGetPwUidApi, sizeof(*args));
args->Uid = uid;
args->PwBuf = RtlAllocateHeap(PdxPortHeap, 0, ARG_MAX);
ASSERT(args->PwBuf != NULL);
args->PwBuf = (struct passwd *)((PCHAR)args->PwBuf +
PsxPortMemoryRemoteDelta);
Status = NtRequestWaitReplyPort(PsxPortHandle, (PPORT_MESSAGE)&m,
(PPORT_MESSAGE)&m);
args->PwBuf = (struct passwd *)((PCHAR)args->PwBuf -
PsxPortMemoryRemoteDelta);
if (0 != m.Error) {
RtlFreeHeap(PdxPortHeap, 0, args->PwBuf);
return NULL;
}
(void)memcpy(pwbuf, args->PwBuf, args->Length);
RtlFreeHeap(PdxPortHeap, 0, args->PwBuf);
tmpbuf = (struct passwd *)pwbuf;
tmpbuf->pw_name += (ULONG)tmpbuf;
tmpbuf->pw_dir += (ULONG)tmpbuf;
tmpbuf->pw_shell += (ULONG)tmpbuf;
return tmpbuf;
}
struct passwd *
_CRTAPI1
getpwnam(const char *name)
{
PSX_API_MSG m;
PPSX_GETPWNAM_MSG args;
NTSTATUS Status;
struct passwd *tmpbuf;
args = &m.u.GetPwNam;
PSX_FORMAT_API_MSG(m, PsxGetPwNamApi, sizeof(*args));
if ('\0' == *name) {
return NULL;
}
args->Name = (PCHAR)RtlAllocateHeap(PdxPortHeap, 0, ARG_MAX);
ASSERT(args->Name != NULL);
strcpy(args->Name,name);
args->Name += PsxPortMemoryRemoteDelta;
args->PwBuf = (struct passwd *)(args->Name + strlen(name) + 1);
//
// Make sure buffer is properly aligned.
//
while ((ULONG)args->PwBuf & 0x3)
args->PwBuf = (PVOID)((ULONG)args->PwBuf + 1);
Status = NtRequestWaitReplyPort(PsxPortHandle, (PPORT_MESSAGE)&m,
(PPORT_MESSAGE)&m);
args->Name = args->Name - PsxPortMemoryRemoteDelta;
args->PwBuf = (struct passwd *)((PCHAR)args->PwBuf -
PsxPortMemoryRemoteDelta);
if (0 != m.Error) {
RtlFreeHeap(PdxPortHeap, 0, args->Name);
return NULL;
}
(void)memcpy(pwbuf, args->PwBuf, args->Length);
RtlFreeHeap(PdxPortHeap, 0, args->Name);
tmpbuf = (struct passwd *)pwbuf;
tmpbuf->pw_name += (ULONG)tmpbuf;
tmpbuf->pw_dir += (ULONG)tmpbuf;
tmpbuf->pw_shell += (ULONG)tmpbuf;
return tmpbuf;
}
struct group *
_CRTAPI1
getgrgid(gid_t gid)
{
PSX_API_MSG m;
PPSX_GETGRGID_MSG args;
NTSTATUS Status;
struct group *tmpbuf;
char **ppch;
args = &m.u.GetGrGid;
PSX_FORMAT_API_MSG(m, PsxGetGrGidApi, sizeof(*args));
args->Gid = gid;
args->GrBuf = RtlAllocateHeap(PdxPortHeap, 0, ARG_MAX);
if (NULL == args->GrBuf) {
errno = ENOMEM;
return NULL;
}
args->GrBuf = (struct group *)((PCHAR)args->GrBuf +
PsxPortMemoryRemoteDelta);
Status = NtRequestWaitReplyPort(PsxPortHandle, (PPORT_MESSAGE)&m,
(PPORT_MESSAGE)&m);
args->GrBuf = (struct group *)((PCHAR)args->GrBuf -
PsxPortMemoryRemoteDelta);
if (0 != m.Error) {
RtlFreeHeap(PdxPortHeap, 0, args->GrBuf);
return NULL;
}
(void)memcpy(grbuf, args->GrBuf, args->Length);
RtlFreeHeap(PdxPortHeap, 0, args->GrBuf);
tmpbuf = (void *)grbuf;
tmpbuf->gr_name = (PCHAR)((ULONG)grbuf + (ULONG)tmpbuf->gr_name);
tmpbuf->gr_mem = (PCHAR *)((ULONG)grbuf + (ULONG)tmpbuf->gr_mem);
for (ppch = tmpbuf->gr_mem; NULL != *ppch; ++ppch) {
*ppch = (PCHAR)((ULONG)grbuf + (ULONG)*ppch);
}
return tmpbuf;
}
struct group *
_CRTAPI1
getgrnam(const char *name)
{
PSX_API_MSG m;
PPSX_GETGRNAM_MSG args;
NTSTATUS Status;
struct group *tmpbuf;
char **ppch;
args = &m.u.GetGrNam;
PSX_FORMAT_API_MSG(m, PsxGetGrNamApi, sizeof(*args));
if ('\0' == *name) {
//
// We need to take special care of this case, because
// SAM will find a match for the null name.
//
return NULL;
}
args->Name = (PCHAR)RtlAllocateHeap(PdxPortHeap, 0, ARG_MAX);
ASSERT(args->Name != NULL);
strcpy(args->Name,name);
args->Name += PsxPortMemoryRemoteDelta;
args->GrBuf = (struct group *)(args->Name + strlen(name) + 1);
//
// Make sure buffer is properly aligned.
//
while ((ULONG)args->GrBuf & 0x3)
args->GrBuf = (PVOID)((ULONG)args->GrBuf + 1);
Status = NtRequestWaitReplyPort(PsxPortHandle, (PPORT_MESSAGE)&m,
(PPORT_MESSAGE)&m);
args->Name = args->Name - PsxPortMemoryRemoteDelta;
args->GrBuf = (struct group *)((PCHAR)args->GrBuf -
PsxPortMemoryRemoteDelta);
if (0 != m.Error) {
RtlFreeHeap(PdxPortHeap, 0, args->Name);
return NULL;
}
(void)memcpy(grbuf, args->GrBuf, args->Length);
tmpbuf = (void *)grbuf;
tmpbuf->gr_name = (PCHAR)((ULONG)grbuf + (ULONG)tmpbuf->gr_name);
tmpbuf->gr_mem = (PCHAR *)((ULONG)grbuf + (ULONG)tmpbuf->gr_mem);
for (ppch = tmpbuf->gr_mem; NULL != *ppch; ++ppch) {
*ppch = (PCHAR)((ULONG)grbuf + (ULONG)*ppch);
}
RtlFreeHeap(PdxPortHeap, 0, (PVOID)args->Name);
return tmpbuf;
}
char *
_CRTAPI1
getlogin(void)
{
static char name[32];
PSX_API_MSG m;
PPSX_GETPWUID_MSG args;
NTSTATUS Status;
//
// We just do the equivalent of getpwuid(getuid()) and then
// throw away everything but the name.
//
//
// XXX.mjb: do I need to use a name outside the POSIX namespace
// for this? Like, what happens if the user has re-defined getuid()?
//
args = &m.u.GetPwUid;
PSX_FORMAT_API_MSG(m, PsxGetPwUidApi, sizeof(*args));
args->Uid = getuid();
args->PwBuf = (struct passwd *)RtlAllocateHeap(PdxPortHeap, 0, ARG_MAX);
ASSERT(args->PwBuf != NULL);
args->PwBuf = (struct passwd *)((PCHAR)args->PwBuf +
PsxPortMemoryRemoteDelta);
Status = NtRequestWaitReplyPort(PsxPortHandle, (PPORT_MESSAGE)&m,
(PPORT_MESSAGE)&m);
args->PwBuf = (struct passwd *)((PCHAR)args->PwBuf -
PsxPortMemoryRemoteDelta);
if (0 != m.Error) {
RtlFreeHeap(PdxPortHeap, 0, args->PwBuf);
return NULL;
}
strcpy(name, (PCHAR)((ULONG)(args->PwBuf->pw_name) + (ULONG)args->PwBuf));
RtlFreeHeap(PdxPortHeap, 0, args->PwBuf);
return name;
}
#ifndef L_cuserid
#define L_cuserid 32
#endif
char *
_CRTAPI1
cuserid(char *s)
{
static char ReturnSpace[ L_cuserid ];
struct passwd *PassWd;
char *Dest;
PassWd = getpwuid( getuid() );
if( PassWd == NULL ) {
*s = '\0';
return( ( s == NULL ) ? NULL : s );
} else {
Dest = ( ( s == NULL ) ? ReturnSpace : s );
strncpy( Dest, PassWd->pw_name, L_cuserid - 1 );
Dest[ L_cuserid - 1 ] = '\0';
}
}