version 1.2, 2015/04/20 18:10:10
|
version 1.3, 2015/04/20 18:19:50
|
|
|
**============================================================================== | **============================================================================== |
*/ | */ |
| |
|
#include <common.h> |
|
|
|
#include <pal/format.h> |
#include "user.h" | #include "user.h" |
#include "log.h" | #include "log.h" |
| |
|
|
#if defined(CONFIG_POSIX) | #if defined(CONFIG_POSIX) |
# include "credcache.h" | # include "credcache.h" |
# include <unistd.h> | # include <unistd.h> |
|
|
| |
#include "paths.h" | #include "paths.h" |
| |
#define USERNAME_SIZE 128 |
|
#define GROUPNAME_SIZE 128 | #define GROUPNAME_SIZE 128 |
| |
#if defined(CONFIG_POSIX) | #if defined(CONFIG_POSIX) |
static int s_ignoreAuthCalls; |
static int s_ignoreAuthCalls = 0; |
#endif | #endif |
| |
#if defined(CONFIG_OS_WINDOWS) | #if defined(CONFIG_OS_WINDOWS) |
|
|
Returns: | Returns: |
0 if operation was successful; -1 otherwise | 0 if operation was successful; -1 otherwise |
*/ | */ |
|
_Use_decl_annotations_ |
int CreateAuthFile( | int CreateAuthFile( |
uid_t uid, | uid_t uid, |
char* content, | char* content, |
size_t size, | size_t size, |
char path[MAX_PATH_SIZE]) |
char path[PAL_MAX_PATH_SIZE]) |
{ | { |
MI_UNUSED(uid); | MI_UNUSED(uid); |
MI_UNUSED(size); | MI_UNUSED(size); |
|
|
} | } |
| |
#elif defined(CONFIG_POSIX) | #elif defined(CONFIG_POSIX) |
static int GetUserName( |
|
uid_t uid, |
|
char name[USERNAME_SIZE]); |
|
| |
static int GetGroupName( | static int GetGroupName( |
gid_t gid, | gid_t gid, |
|
|
| |
static int _authCallback( | static int _authCallback( |
int numMessages, | int numMessages, |
#if defined(CONFIG_OS_LINUX) || defined(CONFIG_OS_DARWIN) |
#if defined(CONFIG_OS_LINUX) || defined(CONFIG_OS_DARWIN) || defined(CONFIG_OS_BSD) |
const struct pam_message** messages, | const struct pam_message** messages, |
#else | #else |
struct pam_message** messages, | struct pam_message** messages, |
|
|
| |
/* Allocate the responses */ | /* Allocate the responses */ |
| |
*response = (struct pam_response*)calloc( |
*response = (struct pam_response*)SystemCalloc( |
numMessages, | numMessages, |
sizeof(struct pam_response)); | sizeof(struct pam_response)); |
| |
|
|
{ | { |
if (PAM_PROMPT_ECHO_OFF == messages[i]->msg_style) | if (PAM_PROMPT_ECHO_OFF == messages[i]->msg_style) |
{ | { |
response[i]->resp = (char*)malloc(PAM_MAX_MSG_SIZE); |
response[i]->resp = (char*)SystemMalloc(PAM_MAX_MSG_SIZE); |
Strlcpy(response[i]->resp, password, PAM_MAX_MSG_SIZE); | Strlcpy(response[i]->resp, password, PAM_MAX_MSG_SIZE); |
response[i]->resp_retcode = 0; | response[i]->resp_retcode = 0; |
} | } |
|
|
/* create communication pipe */ | /* create communication pipe */ |
if(0 != socketpair(AF_UNIX, SOCK_STREAM, 0, s)) | if(0 != socketpair(AF_UNIX, SOCK_STREAM, 0, s)) |
{ | { |
LOGW_CHAR(("socketpair() failed\n")); |
trace_SocketPair_Failed(); |
return -1; | return -1; |
} | } |
| |
|
|
} | } |
| |
/* | /* |
|
Tests whether last error is EINTR |
|
*/ |
|
MI_INLINE int _TestEINTR() |
|
{ |
|
#if defined(CONFIG_OS_WINDOWS) |
|
return 0; |
|
#else |
|
return errno == EINTR; |
|
#endif |
|
} |
|
|
|
/* |
|
Reads data from file, retry if was interuptted |
|
Returns: |
|
'size of the data' readed from the file if success |
|
'-1' otherwise |
|
*/ |
|
int ReadFile(int fd, void* data, size_t size) |
|
{ |
|
int r; |
|
while ((r = read(fd, data, size)) == -1) |
|
{ |
|
if (!_TestEINTR()) break; |
|
} |
|
return r; |
|
} |
|
|
|
/* |
Validates user name and password; | Validates user name and password; |
Returns: | Returns: |
'0' if user account is valid and authorized to use CIM server | '0' if user account is valid and authorized to use CIM server |
|
|
return -1; | return -1; |
} | } |
| |
if (sizeof(int) != read(fd, &r, sizeof(int))) |
if (sizeof(int) != ReadFile(fd, &r, sizeof(int))) |
{ | { |
LOGE_CHAR(("failed to read result from child")); |
trace_UserAuth_FailedToRead( errno ); |
r = -1; | r = -1; |
goto done; | goto done; |
} | } |
|
|
s_ignoreAuthCalls = flag; | s_ignoreAuthCalls = flag; |
} | } |
| |
|
/* |
|
Get if authentication calls was ignored or not |
|
Return value: |
|
1 - ignored; 0 - not |
|
*/ |
|
int IsAuthCallsIgnored() |
|
{ |
|
return s_ignoreAuthCalls; |
|
} |
| |
/* | /* |
Looks for user's account and retrieves uid/gid. | Looks for user's account and retrieves uid/gid. |
|
|
if (0 != getpwnam_r(user, &pwd, buf, sizeof(buf), &ppwd) || | if (0 != getpwnam_r(user, &pwd, buf, sizeof(buf), &ppwd) || |
!ppwd) | !ppwd) |
{ | { |
LOGW_CHAR(("getpwnam_r filed, errno %d", errno)); |
trace_getpwnamr_Failed(errno); |
return -1; | return -1; |
} | } |
| |
|
|
| |
if (setgid(gid) != 0) | if (setgid(gid) != 0) |
{ | { |
LOGW_CHAR(("setgid failed: errno (%d)",errno)); |
trace_setgid_Failed(errno); |
|
return -1; |
|
} |
|
|
|
/* |
|
* Limit the groups that this user is in to the ones in /etc/groups. |
|
* Without this it includes the root group if root called Setuser() |
|
*/ |
|
{ |
|
struct passwd pwbuf; |
|
char buf[1024]; |
|
struct passwd* pw; |
|
|
|
if (getpwuid_r(uid, &pwbuf, buf, sizeof(buf), &pw) != 0 || !pw) |
|
{ |
|
trace_getpwuidr_Failed(errno); |
return -1; | return -1; |
} | } |
| |
|
if (initgroups(pw->pw_name, gid) != 0) |
|
{ |
|
trace_initgroups_Failed(errno); |
|
return -1; |
|
} |
|
} |
|
|
if (setuid(uid) != 0) | if (setuid(uid) != 0) |
{ | { |
LOGW_CHAR(("setuid failed: errno (%d)",errno)); |
trace_setuid_Failed(errno); |
return -1; | return -1; |
} | } |
| |
|
|
| |
int GetUIDByConnection(int fd, uid_t* uid, gid_t* gid) | int GetUIDByConnection(int fd, uid_t* uid, gid_t* gid) |
{ | { |
#if defined(CONFIG_OS_LINUX) |
#if defined(CONFIG_OS_LINUX) || defined(CONFIG_OS_BSD) |
struct ucred credentials; | struct ucred credentials; |
socklen_t ucred_size = (socklen_t)sizeof(credentials); | socklen_t ucred_size = (socklen_t)sizeof(credentials); |
| |
|
|
Returns: | Returns: |
0 if operation was successful; -1 otherwise | 0 if operation was successful; -1 otherwise |
*/ | */ |
int CreateAuthFile(uid_t uid, char* content, size_t size, char path[MAX_PATH_SIZE]) |
int CreateAuthFile(uid_t uid, char* content, size_t size, char path[PAL_MAX_PATH_SIZE]) |
{ | { |
static MI_Uint32 counter; | static MI_Uint32 counter; |
| |
|
|
if (0 != GetUserName(uid, name)) | if (0 != GetUserName(uid, name)) |
return -1; | return -1; |
| |
if (Strlcpy(path, GetPath(ID_AUTHDIR), MAX_PATH_SIZE) >= MAX_PATH_SIZE) |
if (Strlcpy(path, OMI_GetPath(ID_AUTHDIR), PAL_MAX_PATH_SIZE) >= PAL_MAX_PATH_SIZE) |
return -1; | return -1; |
| |
if (Strlcat(path, "/", MAX_PATH_SIZE) >= MAX_PATH_SIZE) |
if (Strlcat(path, "/", PAL_MAX_PATH_SIZE) >= PAL_MAX_PATH_SIZE) |
return -1; | return -1; |
| |
if (Strlcat(path, name, MAX_PATH_SIZE) >= MAX_PATH_SIZE) |
if (Strlcat(path, name, PAL_MAX_PATH_SIZE) >= PAL_MAX_PATH_SIZE) |
return -1; | return -1; |
| |
if (Strlcat(path, ".", MAX_PATH_SIZE) >= MAX_PATH_SIZE) |
if (Strlcat(path, ".", PAL_MAX_PATH_SIZE) >= PAL_MAX_PATH_SIZE) |
return -1; | return -1; |
| |
if (Strlcat(path, Uint32ToStr(numBuf, counter, &dummy), MAX_PATH_SIZE) >= MAX_PATH_SIZE) |
if (Strlcat(path, Uint32ToStr(numBuf, counter, &dummy), PAL_MAX_PATH_SIZE) >= PAL_MAX_PATH_SIZE) |
return -1; | return -1; |
} | } |
| |
|
|
fd = open(path, O_WRONLY|O_CREAT|O_TRUNC, S_IRUSR); | fd = open(path, O_WRONLY|O_CREAT|O_TRUNC, S_IRUSR); |
if (fd == -1) | if (fd == -1) |
{ | { |
LOGW_CHAR(("failed to create auth file %s", path)); |
trace_CreateAuthFile_Failed(scs(path)); |
return -1; | return -1; |
} | } |
if (write(fd, content, size) != (int)size) | if (write(fd, content, size) != (int)size) |
|
|
| |
if (0 != fchown(fd, uid, -1)) | if (0 != fchown(fd, uid, -1)) |
{ | { |
LOGW_CHAR(("failed to chown auth file %s", path)); |
trace_ChownAuthFile_Failed(scs(path)); |
close(fd); | close(fd); |
unlink(path); | unlink(path); |
return -1; | return -1; |
|
|
return 0; | return 0; |
} | } |
| |
static int GetUserName( |
/* |
|
Gets username by uid |
|
*/ |
|
int GetUserName( |
uid_t uid, | uid_t uid, |
char name[USERNAME_SIZE]) | char name[USERNAME_SIZE]) |
{ | { |
|
|
int FormatLogFileName( | int FormatLogFileName( |
uid_t uid, | uid_t uid, |
gid_t gid, | gid_t gid, |
char path[MAX_PATH_SIZE]) |
char path[PAL_MAX_PATH_SIZE]) |
{ | { |
char user[USERNAME_SIZE]; | char user[USERNAME_SIZE]; |
char group[GROUPNAME_SIZE]; | char group[GROUPNAME_SIZE]; |
| |
if (Strlcpy(path, GetPath(ID_LOGDIR), MAX_PATH_SIZE) >= MAX_PATH_SIZE) |
if (Strlcpy(path, OMI_GetPath(ID_LOGDIR), PAL_MAX_PATH_SIZE) >= PAL_MAX_PATH_SIZE) |
return -1; | return -1; |
| |
Strlcat(path, "/omiagent.", MAX_PATH_SIZE); |
Strlcat(path, "/omiagent.", PAL_MAX_PATH_SIZE); |
| |
/* Append user name */ | /* Append user name */ |
if (GetUserName(getuid(), user) == 0) | if (GetUserName(getuid(), user) == 0) |
{ | { |
Strlcat(path, user, MAX_PATH_SIZE); |
Strlcat(path, user, PAL_MAX_PATH_SIZE); |
} | } |
else | else |
{ | { |
char buf[11]; | char buf[11]; |
sprintf(buf, "%u", getuid()); | sprintf(buf, "%u", getuid()); |
Strlcat(path, buf, MAX_PATH_SIZE); |
Strlcat(path, buf, PAL_MAX_PATH_SIZE); |
} | } |
| |
/* Append group name */ | /* Append group name */ |
if (GetGroupName(getgid(), group) == 0) | if (GetGroupName(getgid(), group) == 0) |
{ | { |
Strlcat(path, ".", MAX_PATH_SIZE); |
Strlcat(path, ".", PAL_MAX_PATH_SIZE); |
Strlcat(path, group, MAX_PATH_SIZE); |
Strlcat(path, group, PAL_MAX_PATH_SIZE); |
} | } |
else | else |
{ | { |
char buf[11]; | char buf[11]; |
sprintf(buf, "%u", getgid()); | sprintf(buf, "%u", getgid()); |
Strlcat(path, ".", MAX_PATH_SIZE); |
Strlcat(path, ".", PAL_MAX_PATH_SIZE); |
Strlcat(path, buf, MAX_PATH_SIZE); |
Strlcat(path, buf, PAL_MAX_PATH_SIZE); |
} | } |
| |
Strlcat(path, ".log", MAX_PATH_SIZE); |
Strlcat(path, ".log", PAL_MAX_PATH_SIZE); |
| |
return 0; | return 0; |
} | } |