summaryrefslogblamecommitdiffstats
path: root/private/posix/client/sysdb.c
blob: 84dbfc0786662eb5f3645639fb97bd8a579bf88c (plain) (tree)















































































































































































































































































































                                                                                  
/*++

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';
    }
}