/* Editor Settings: expandtabs and use 4 spaces for indentation
* ex: set softtabstop=4 tabstop=8 expandtab shiftwidth=4: *
* -*- mode: c, c-basic-offset: 4 -*- */
/*
* Copyright Likewise Software. All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or (at
* your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details. You should have received a copy of the GNU General
* Public License along with this program. If not, see
* .
*
* LIKEWISE SOFTWARE MAKES THIS SOFTWARE AVAILABLE UNDER OTHER LICENSING
* TERMS AS WELL. IF YOU HAVE ENTERED INTO A SEPARATE LICENSE AGREEMENT
* WITH LIKEWISE SOFTWARE, THEN YOU MAY ELECT TO USE THE SOFTWARE UNDER THE
* TERMS OF THAT SOFTWARE LICENSE AGREEMENT INSTEAD OF THE TERMS OF THE GNU
* GENERAL PUBLIC LICENSE, NOTWITHSTANDING THE ABOVE NOTICE. IF YOU
* HAVE QUESTIONS, OR WISH TO REQUEST A COPY OF THE ALTERNATE LICENSING
* TERMS OFFERED BY LIKEWISE SOFTWARE, PLEASE CONTACT LIKEWISE SOFTWARE AT
* license@likewisesoftware.com
*/
/*
* Copyright (C) Likewise Software. All rights reserved.
*
* Module Name:
*
* lwmapsecurity-test.c
*
* Abstract:
*
* Likewise Map Security - Test Program
*
* Authors: Danilo Almeida (dalmeida@likewise.com)
*/
#include
#include
#include "config.h"
#include
#include
#include
#include
#define LOG(Format, ...) \
printf(Format "\n", ## __VA_ARGS__)
#define ASSERT_NT_SUCCESS_STATUS(status) \
do { \
if (!NT_SUCCESS(status)) \
{ \
MapErrorCodes(status); \
exit(1); \
} \
} while (0)
VOID
MapErrorCodes(
NTSTATUS status
);
int
IsNumber(char* strNum);
void
ParseArgs(
int argc,
char* argv[]);
static
VOID
DumpTokenInfo(
IN PACCESS_TOKEN Token,
IN TOKEN_INFORMATION_CLASS TokenInformationClass
)
{
NTSTATUS status = STATUS_SUCCESS;
PBYTE tokenInfo = NULL;
ULONG size = 0;
ULONG savedSize = 0;
status = RtlQueryAccessTokenInformation(
Token,
TokenInformationClass,
tokenInfo,
size,
&size);
assert(STATUS_BUFFER_TOO_SMALL == status);
savedSize = size;
status = RTL_ALLOCATE(&tokenInfo, BYTE, size);
ASSERT_NT_SUCCESS_STATUS(status);
status = RtlQueryAccessTokenInformation(
Token,
TokenInformationClass,
tokenInfo,
size,
&size);
ASSERT_NT_SUCCESS_STATUS(status);
assert(size == savedSize);
switch (TokenInformationClass)
{
case TokenUser:
{
PTOKEN_USER tokenUser = (PTOKEN_USER) tokenInfo;
PSTR sidString = NULL;
status = RtlAllocateCStringFromSid(&sidString, tokenUser->User.Sid);
ASSERT_NT_SUCCESS_STATUS(status);
LOG("User = %s", sidString);
break;
}
case TokenGroups:
{
PTOKEN_GROUPS tokenGroups = (PTOKEN_GROUPS) tokenInfo;
ULONG i = 0;
PSTR sidString = NULL;
LOG("GroupCount = %u", tokenGroups->GroupCount);
for (i = 0; i < tokenGroups->GroupCount; i++)
{
status = RtlAllocateCStringFromSid(&sidString, tokenGroups->Groups[i].Sid);
ASSERT_NT_SUCCESS_STATUS(status);
LOG("Groups[%u] = (0x%08x, %s)", i, tokenGroups->Groups[i].Attributes, sidString);
}
break;
}
case TokenOwner:
{
PTOKEN_OWNER tokenOwner = (PTOKEN_OWNER) tokenInfo;
PSTR sidString = NULL;
status = RtlAllocateCStringFromSid(&sidString, tokenOwner->Owner);
ASSERT_NT_SUCCESS_STATUS(status);
LOG("Owner = %s", sidString);
break;
}
case TokenPrimaryGroup:
{
PTOKEN_PRIMARY_GROUP tokenPrimaryGroup = (PTOKEN_PRIMARY_GROUP) tokenInfo;
PSTR sidString = NULL;
status = RtlAllocateCStringFromSid(&sidString, tokenPrimaryGroup->PrimaryGroup);
ASSERT_NT_SUCCESS_STATUS(status);
LOG("PrimaryGroup = %s", sidString);
break;
}
case TokenDefaultDacl:
{
PTOKEN_DEFAULT_DACL tokenDefaultDacl = (PTOKEN_DEFAULT_DACL) tokenInfo;
LOG("Have DefaultdDacl = %c", tokenDefaultDacl->DefaultDacl ? 'Y' : 'N');
break;
}
}
}
static
VOID
DumpTokenUnixInfo(
IN PACCESS_TOKEN Token
)
{
NTSTATUS status = STATUS_SUCCESS;
TOKEN_UNIX tokenUnix = { 0 };
status = RtlQueryAccessTokenUnixInformation(
Token,
&tokenUnix);
ASSERT_NT_SUCCESS_STATUS(status);
LOG("Unix.Uid = %u", tokenUnix.Uid);
LOG("Unix.Gid = %u", tokenUnix.Gid);
LOG("Unix.Umask = 0%03o", tokenUnix.Umask);
}
static
VOID
DumpToken(
IN PACCESS_TOKEN Token
)
{
DumpTokenInfo(Token, TokenUser);
DumpTokenInfo(Token, TokenGroups);
DumpTokenInfo(Token, TokenOwner);
DumpTokenInfo(Token, TokenPrimaryGroup);
DumpTokenInfo(Token, TokenDefaultDacl);
DumpTokenUnixInfo(Token);
}
static
VOID
ShowUsage(
IN PCSTR pszProgramName
)
{
printf("Usage: %s \n"
" or: %s \n"
"\n"
" Test lwmapsecurity library.\n"
"\n",
pszProgramName,
pszProgramName);
}
void
ParseArgs(
int argc,
char* argv[])
{
if ( argc < 2 || (strcmp(argv[1], "--help") == 0) || (strcmp(argv[1], "-h") == 0))
{
ShowUsage(argv[0]);
exit(0);
}
else
{
if(argc == 2)
{
if( isalpha((int)*argv[1]) == 0)
{
fprintf(stdout, "Name should start with an alphabet\n\n");
ShowUsage(argv[0]);
exit(1);
}
}
else if (argc == 3)
{
if ( IsNumber(argv[1]) || IsNumber(argv[2]) )
{
fprintf(stdout, "uid and gid should be numbers\n\n");
ShowUsage(argv[0]);
exit(1);
}
}
else
{
fprintf(stdout, "Too many arguements\n\n");
ShowUsage(argv[0]);
exit(1);
}
}
}
int
main(
IN int argc,
IN char* argv[]
)
{
NTSTATUS status = 0;
PLW_MAP_SECURITY_CONTEXT context = NULL;
PACCESS_TOKEN accessToken = NULL;
ParseArgs(argc, argv);
status = LwMapSecurityCreateContext(&context);
ASSERT_NT_SUCCESS_STATUS(status);
if (argc == 2)
{
status = LwMapSecurityCreateAccessTokenFromCStringUsername(
context,
&accessToken,
argv[1]);
ASSERT_NT_SUCCESS_STATUS(status);
}
else if (argc == 3)
{
int uid = atoi(argv[1]);
int gid = atoi(argv[2]);
status = LwMapSecurityCreateAccessTokenFromUidGid(
context,
&accessToken,
(ULONG) uid,
(ULONG) gid);
ASSERT_NT_SUCCESS_STATUS(status);
}
DumpToken(accessToken);
RtlReleaseAccessToken(&accessToken);
LwMapSecurityFreeContext(&context);
return NT_SUCCESS(status) ? 0 : 1;
}
int
IsNumber(char* strNum)
{
int nLen = 0;
int nIndex = 0;
nLen = strlen(strNum);
for (nIndex = 0; nIndex < nLen; nIndex++)
{
if (isdigit((int)strNum[nIndex]) == 0)
return -1;
}
return 0;
}
VOID
MapErrorCodes(
NTSTATUS status
)
{
switch (status)
{
case LW_STATUS_NOT_FOUND:
fprintf(stderr,"User not found. Error code 0x%X\n", status);
break;
default:
fprintf(stderr,"Invalid operation. Error code 0x%X\n", status);
break;
}
}