mirror of
https://github.com/pgbackrest/pgbackrest.git
synced 2024-12-12 10:04:14 +02:00
Add user module for managing system users/groups.
Centralize the management of users and groups. Also update Posix storage driver where users/groups were already in use.
This commit is contained in:
parent
d957acb36b
commit
1049632873
@ -87,6 +87,7 @@ my @stryCFile =
|
||||
'common/type/variant.c',
|
||||
'common/type/variantList.c',
|
||||
'common/type/xml.c',
|
||||
'common/user.c',
|
||||
'common/wait.c',
|
||||
'config/config.c',
|
||||
'config/define.c',
|
||||
|
@ -122,6 +122,7 @@ SRCS = \
|
||||
common/type/variant.c \
|
||||
common/type/variantList.c \
|
||||
common/type/xml.c \
|
||||
common/user.c \
|
||||
common/wait.c \
|
||||
config/config.c \
|
||||
config/define.c \
|
||||
@ -443,6 +444,9 @@ common/type/variantList.o: common/type/variantList.c build.auto.h common/assert.
|
||||
common/type/xml.o: common/type/xml.c build.auto.h common/assert.h common/debug.h common/error.auto.h common/error.h common/log.h common/logLevel.h common/macro.h common/memContext.h common/object.h common/stackTrace.h common/type/buffer.h common/type/convert.h common/type/list.h common/type/string.h common/type/xml.h
|
||||
$(CC) $(CPPFLAGS) $(CFLAGS) $(CMAKE) -c common/type/xml.c -o common/type/xml.o
|
||||
|
||||
common/user.o: common/user.c build.auto.h common/assert.h common/debug.h common/error.auto.h common/error.h common/logLevel.h common/memContext.h common/stackTrace.h common/type/buffer.h common/type/convert.h common/type/string.h common/user.h
|
||||
$(CC) $(CPPFLAGS) $(CFLAGS) $(CMAKE) -c common/user.c -o common/user.o
|
||||
|
||||
common/wait.o: common/wait.c build.auto.h common/assert.h common/debug.h common/error.auto.h common/error.h common/log.h common/logLevel.h common/macro.h common/memContext.h common/object.h common/stackTrace.h common/time.h common/type/convert.h common/wait.h
|
||||
$(CC) $(CPPFLAGS) $(CFLAGS) $(CMAKE) -c common/wait.c -o common/wait.o
|
||||
|
||||
@ -563,7 +567,7 @@ storage/helper.o: storage/helper.c build.auto.h common/assert.h common/debug.h c
|
||||
storage/posix/read.o: storage/posix/read.c build.auto.h common/assert.h common/debug.h common/error.auto.h common/error.h common/io/filter/filter.h common/io/filter/group.h common/io/read.h common/io/read.intern.h common/io/write.h common/io/write.intern.h common/log.h common/logLevel.h common/macro.h common/memContext.h common/object.h common/stackTrace.h common/time.h common/type/buffer.h common/type/convert.h common/type/keyValue.h common/type/string.h common/type/stringList.h common/type/variant.h common/type/variantList.h storage/info.h storage/posix/read.h storage/posix/storage.h storage/posix/storage.intern.h storage/read.h storage/read.intern.h storage/storage.h storage/storage.intern.h storage/write.h storage/write.intern.h version.h
|
||||
$(CC) $(CPPFLAGS) $(CFLAGS) $(CMAKE) -c storage/posix/read.c -o storage/posix/read.o
|
||||
|
||||
storage/posix/storage.o: storage/posix/storage.c build.auto.h common/assert.h common/debug.h common/error.auto.h common/error.h common/io/filter/filter.h common/io/filter/group.h common/io/read.h common/io/read.intern.h common/io/write.h common/io/write.intern.h common/log.h common/logLevel.h common/macro.h common/memContext.h common/object.h common/regExp.h common/stackTrace.h common/time.h common/type/buffer.h common/type/convert.h common/type/keyValue.h common/type/string.h common/type/stringList.h common/type/variant.h common/type/variantList.h storage/info.h storage/posix/read.h storage/posix/storage.h storage/posix/storage.intern.h storage/posix/write.h storage/read.h storage/read.intern.h storage/storage.h storage/storage.intern.h storage/write.h storage/write.intern.h version.h
|
||||
storage/posix/storage.o: storage/posix/storage.c build.auto.h common/assert.h common/debug.h common/error.auto.h common/error.h common/io/filter/filter.h common/io/filter/group.h common/io/read.h common/io/read.intern.h common/io/write.h common/io/write.intern.h common/log.h common/logLevel.h common/macro.h common/memContext.h common/object.h common/regExp.h common/stackTrace.h common/time.h common/type/buffer.h common/type/convert.h common/type/keyValue.h common/type/string.h common/type/stringList.h common/type/variant.h common/type/variantList.h common/user.h storage/info.h storage/posix/read.h storage/posix/storage.h storage/posix/storage.intern.h storage/posix/write.h storage/read.h storage/read.intern.h storage/storage.h storage/storage.intern.h storage/write.h storage/write.intern.h version.h
|
||||
$(CC) $(CPPFLAGS) $(CFLAGS) $(CMAKE) -c storage/posix/storage.c -o storage/posix/storage.o
|
||||
|
||||
storage/posix/write.o: storage/posix/write.c build.auto.h common/assert.h common/debug.h common/error.auto.h common/error.h common/io/filter/filter.h common/io/filter/group.h common/io/read.h common/io/read.intern.h common/io/write.h common/io/write.intern.h common/log.h common/logLevel.h common/macro.h common/memContext.h common/object.h common/stackTrace.h common/time.h common/type/buffer.h common/type/convert.h common/type/keyValue.h common/type/string.h common/type/stringList.h common/type/variant.h common/type/variantList.h storage/info.h storage/posix/storage.h storage/posix/storage.intern.h storage/posix/write.h storage/read.h storage/read.intern.h storage/storage.h storage/storage.intern.h storage/write.h storage/write.intern.h version.h
|
||||
|
136
src/common/user.c
Normal file
136
src/common/user.c
Normal file
@ -0,0 +1,136 @@
|
||||
/***********************************************************************************************************************************
|
||||
System User/Group Management
|
||||
***********************************************************************************************************************************/
|
||||
#include "build.auto.h"
|
||||
|
||||
#include <grp.h>
|
||||
#include <pwd.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "common/debug.h"
|
||||
#include "common/memContext.h"
|
||||
#include "common/user.h"
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
User group info
|
||||
***********************************************************************************************************************************/
|
||||
struct
|
||||
{
|
||||
MemContext *memContext; // Mem context to store data in this struct
|
||||
|
||||
uid_t userId; // Real user id of the calling process from getuid()
|
||||
bool userRoot; // Is this the root user?
|
||||
const String *userName; // User name if it exists
|
||||
|
||||
gid_t groupId; // Real group id of the calling process from getgid()
|
||||
const String *groupName; // Group name if it exists
|
||||
} userLocalData;
|
||||
|
||||
/***********************************************************************************************************************************/
|
||||
static void
|
||||
userInitInternal(void)
|
||||
{
|
||||
FUNCTION_TEST_VOID();
|
||||
|
||||
MEM_CONTEXT_BEGIN(memContextTop())
|
||||
{
|
||||
userLocalData.memContext = memContextNew("UserLocalData");
|
||||
}
|
||||
MEM_CONTEXT_END();
|
||||
|
||||
MEM_CONTEXT_BEGIN(userLocalData.memContext)
|
||||
{
|
||||
userLocalData.userId = getuid();
|
||||
userLocalData.userName = userNameFromId(userLocalData.userId);
|
||||
userLocalData.userRoot = userLocalData.userId == 0;
|
||||
|
||||
userLocalData.groupId = getgid();
|
||||
userLocalData.groupName = groupNameFromId(userLocalData.groupId);
|
||||
}
|
||||
MEM_CONTEXT_END();
|
||||
|
||||
FUNCTION_TEST_RETURN_VOID();
|
||||
}
|
||||
|
||||
void
|
||||
userInit(void)
|
||||
{
|
||||
FUNCTION_TEST_VOID();
|
||||
|
||||
if (!userLocalData.memContext)
|
||||
userInitInternal();
|
||||
|
||||
FUNCTION_TEST_RETURN_VOID();
|
||||
}
|
||||
|
||||
/**********************************************************************************************************************************/
|
||||
gid_t
|
||||
groupId(void)
|
||||
{
|
||||
FUNCTION_TEST_VOID();
|
||||
FUNCTION_TEST_RETURN(userLocalData.groupId);
|
||||
}
|
||||
|
||||
/**********************************************************************************************************************************/
|
||||
const String *
|
||||
groupName(void)
|
||||
{
|
||||
FUNCTION_TEST_VOID();
|
||||
FUNCTION_TEST_RETURN(userLocalData.groupName);
|
||||
}
|
||||
|
||||
/**********************************************************************************************************************************/
|
||||
String *
|
||||
groupNameFromId(gid_t groupId)
|
||||
{
|
||||
FUNCTION_TEST_BEGIN();
|
||||
FUNCTION_TEST_PARAM(UINT, groupId);
|
||||
FUNCTION_TEST_END();
|
||||
|
||||
struct group *groupData = getgrgid(groupId);
|
||||
|
||||
if (groupData != NULL)
|
||||
FUNCTION_TEST_RETURN(strNew(groupData->gr_name));
|
||||
|
||||
FUNCTION_TEST_RETURN(NULL);
|
||||
}
|
||||
|
||||
/**********************************************************************************************************************************/
|
||||
uid_t
|
||||
userId(void)
|
||||
{
|
||||
FUNCTION_TEST_VOID();
|
||||
FUNCTION_TEST_RETURN(userLocalData.userId);
|
||||
}
|
||||
|
||||
/**********************************************************************************************************************************/
|
||||
const String *
|
||||
userName(void)
|
||||
{
|
||||
FUNCTION_TEST_VOID();
|
||||
FUNCTION_TEST_RETURN(userLocalData.userName);
|
||||
}
|
||||
|
||||
/**********************************************************************************************************************************/
|
||||
String *
|
||||
userNameFromId(uid_t userId)
|
||||
{
|
||||
FUNCTION_TEST_BEGIN();
|
||||
FUNCTION_TEST_PARAM(UINT, userId);
|
||||
FUNCTION_TEST_END();
|
||||
|
||||
struct passwd *userData = getpwuid(userId);
|
||||
|
||||
if (userData != NULL)
|
||||
FUNCTION_TEST_RETURN(strNew(userData->pw_name));
|
||||
|
||||
FUNCTION_TEST_RETURN(NULL);
|
||||
}
|
||||
|
||||
/**********************************************************************************************************************************/
|
||||
bool
|
||||
userRoot(void)
|
||||
{
|
||||
FUNCTION_TEST_VOID();
|
||||
FUNCTION_TEST_RETURN(userLocalData.userRoot);
|
||||
}
|
36
src/common/user.h
Normal file
36
src/common/user.h
Normal file
@ -0,0 +1,36 @@
|
||||
/***********************************************************************************************************************************
|
||||
System User/Group Management
|
||||
***********************************************************************************************************************************/
|
||||
#ifndef COMMON_USER_H
|
||||
#define COMMON_USER_H
|
||||
|
||||
#include "common/type/string.h"
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Functions
|
||||
***********************************************************************************************************************************/
|
||||
// Call this initializer before using any of the functions below. Safe to call more than once.
|
||||
void userInit(void);
|
||||
|
||||
// Get the primary group id of the current user
|
||||
gid_t groupId(void);
|
||||
|
||||
// Get the primary group name of the current user. Returns NULL if there is no mapping.
|
||||
const String *groupName(void);
|
||||
|
||||
// Get the group name from a group id. Returns NULL if the group id is invalid or there is no mapping.
|
||||
String *groupNameFromId(gid_t groupId);
|
||||
|
||||
// Get the id of the current user
|
||||
uid_t userId(void);
|
||||
|
||||
// Get the name of the current user. Returns NULL if there is no mapping.
|
||||
const String *userName(void);
|
||||
|
||||
// Get the user name from a user id. Returns NULL if the user id is invalid or there is no mapping.
|
||||
String *userNameFromId(uid_t userId);
|
||||
|
||||
// Is the current user the root user?
|
||||
bool userRoot(void);
|
||||
|
||||
#endif
|
@ -6,9 +6,7 @@ Posix Storage
|
||||
#include <dirent.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <grp.h>
|
||||
#include <limits.h>
|
||||
#include <pwd.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <sys/stat.h>
|
||||
@ -18,6 +16,7 @@ Posix Storage
|
||||
#include "common/log.h"
|
||||
#include "common/memContext.h"
|
||||
#include "common/regExp.h"
|
||||
#include "common/user.h"
|
||||
#include "storage/posix/read.h"
|
||||
#include "storage/posix/storage.intern.h"
|
||||
#include "storage/posix/write.h"
|
||||
@ -109,21 +108,11 @@ storagePosixInfo(THIS_VOID, const String *file, bool followLink)
|
||||
{
|
||||
result.exists = true;
|
||||
result.groupId = statFile.st_gid;
|
||||
result.group = groupNameFromId(result.groupId);
|
||||
result.userId = statFile.st_uid;
|
||||
result.user = userNameFromId(result.userId);
|
||||
result.timeModified = statFile.st_mtime;
|
||||
|
||||
// Get user name if it exists
|
||||
struct passwd *userData = getpwuid(result.userId);
|
||||
|
||||
if (userData != NULL)
|
||||
result.user = strNew(userData->pw_name);
|
||||
|
||||
// Get group name if it exists
|
||||
struct group *groupData = getgrgid(result.groupId);
|
||||
|
||||
if (groupData != NULL)
|
||||
result.group = strNew(groupData->gr_name);
|
||||
|
||||
if (S_ISREG(statFile.st_mode))
|
||||
{
|
||||
result.type = storageTypeFile;
|
||||
@ -679,6 +668,9 @@ storagePosixNewInternal(
|
||||
ASSERT(modeFile != 0);
|
||||
ASSERT(modePath != 0);
|
||||
|
||||
// Initialze user module
|
||||
userInit();
|
||||
|
||||
// Create the object
|
||||
Storage *this = NULL;
|
||||
|
||||
|
@ -213,6 +213,13 @@ unit:
|
||||
coverage:
|
||||
common/type/xml: full
|
||||
|
||||
# ----------------------------------------------------------------------------------------------------------------------------
|
||||
- name: user
|
||||
total: 1
|
||||
|
||||
coverage:
|
||||
common/user: full
|
||||
|
||||
# ----------------------------------------------------------------------------------------------------------------------------
|
||||
- name: io
|
||||
total: 4
|
||||
|
30
test/src/module/common/userTest.c
Normal file
30
test/src/module/common/userTest.c
Normal file
@ -0,0 +1,30 @@
|
||||
/***********************************************************************************************************************************
|
||||
Test System User/Group Management
|
||||
***********************************************************************************************************************************/
|
||||
|
||||
/***********************************************************************************************************************************
|
||||
Test Run
|
||||
***********************************************************************************************************************************/
|
||||
void
|
||||
testRun(void)
|
||||
{
|
||||
FUNCTION_HARNESS_VOID();
|
||||
|
||||
// *****************************************************************************************************************************
|
||||
if (testBegin("all"))
|
||||
{
|
||||
TEST_RESULT_VOID(userInit(), "initialize info");
|
||||
TEST_RESULT_VOID(userInit(), "initialize info again");
|
||||
|
||||
TEST_RESULT_UINT(userId(), getuid(), "check user id");
|
||||
TEST_RESULT_STR_Z(userName(), testUser(), "check user name");
|
||||
TEST_RESULT_STR_Z(userNameFromId(77777), NULL, "invalid user name by id");
|
||||
TEST_RESULT_BOOL(userRoot(), false, "check user is root");
|
||||
|
||||
TEST_RESULT_UINT(groupId(), getgid(), "check group id");
|
||||
TEST_RESULT_STR_Z(groupName(), testGroup(), "check name name");
|
||||
TEST_RESULT_STR_Z(groupNameFromId(77777), NULL, "invalid group name by id");
|
||||
}
|
||||
|
||||
FUNCTION_HARNESS_RESULT_VOID();
|
||||
}
|
Loading…
Reference in New Issue
Block a user