Skip to content
GitLab
Explore
Sign in
Primary navigation
Search or go to…
Project
S
Slurm
Manage
Activity
Members
Labels
Plan
Issues
Issue boards
Milestones
Code
Merge requests
Repository
Branches
Commits
Tags
Repository graph
Compare revisions
Snippets
Build
Pipelines
Jobs
Pipeline schedules
Artifacts
Deploy
Releases
Package Registry
Model registry
Operate
Environments
Terraform modules
Monitor
Incidents
Service Desk
Analyze
Value stream analytics
Contributor analytics
CI/CD analytics
Repository analytics
Model experiments
Help
Help
Support
GitLab documentation
Compare GitLab plans
Community forum
Contribute to GitLab
Provide feedback
Terms and privacy
Keyboard shortcuts
?
Snippets
Groups
Projects
Show more breadcrumbs
tud-zih-energy
Slurm
Commits
b70918a5
Commit
b70918a5
authored
17 years ago
by
Moe Jette
Browse files
Options
Downloads
Patches
Plain Diff
svn merge -r 12956:12968
https://eris.llnl.gov/svn/slurm/branches/slurm-1.2
parent
08e73a57
No related branches found
Branches containing commit
No related tags found
No related merge requests found
Changes
3
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
NEWS
+1
-0
1 addition, 0 deletions
NEWS
contribs/env_cache_builder.c
+125
-91
125 additions, 91 deletions
contribs/env_cache_builder.c
src/common/env.c
+65
-54
65 additions, 54 deletions
src/common/env.c
with
191 additions
and
145 deletions
NEWS
+
1
−
0
View file @
b70918a5
...
@@ -130,6 +130,7 @@ documents those changes that are of interest to users and admins.
...
@@ -130,6 +130,7 @@ documents those changes that are of interest to users and admins.
-- Avoid printing negative job run time in squeue due to clock skew.
-- Avoid printing negative job run time in squeue due to clock skew.
-- In sched/wiki and sched/wiki2, add support for wiki.conf option
-- In sched/wiki and sched/wiki2, add support for wiki.conf option
HidePartitionJobs (see man pages for details).
HidePartitionJobs (see man pages for details).
-- Update to srun/sbatch --get-user-env option logic (needed by Moab).
* Changes in SLURM 1.2.21
* Changes in SLURM 1.2.21
=========================
=========================
...
...
This diff is collapsed.
Click to expand it.
contribs/env_cache_builder.c
+
125
−
91
View file @
b70918a5
...
@@ -14,7 +14,7 @@
...
@@ -14,7 +14,7 @@
*
*
* This program must execute as user root.
* This program must execute as user root.
*****************************************************************************
*****************************************************************************
* Copyright (C) 2007 The Regents of the University of California.
* Copyright (C) 2007
-2008
The Regents of the University of California.
* Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER).
* Produced at Lawrence Livermore National Laboratory (cf, DISCLAIMER).
* Written by Morris Jette <jette1@llnl.gov>.
* Written by Morris Jette <jette1@llnl.gov>.
* UCRL-CODE-226842.
* UCRL-CODE-226842.
...
@@ -53,16 +53,18 @@
...
@@ -53,16 +53,18 @@
#include
<stdio.h>
#include
<stdio.h>
#include
<stdlib.h>
#include
<stdlib.h>
#include
<string.h>
#include
<string.h>
#include
<strings.h>
#include
<unistd.h>
#include
<unistd.h>
#include
<sys/stat.h>
#include
<sys/types.h>
#include
<sys/types.h>
#include
<sys/wait.h>
#include
<sys/wait.h>
#define DEBUG 0
#define
_
DEBUG 0
#define SU_WAIT_MSEC 8000
#define SU_WAIT_MSEC 8000
static
long
int
_build_cache
(
char
*
user_name
,
char
*
cache_dir
);
static
long
int
_build_cache
(
char
*
user_name
,
char
*
cache_dir
);
static
int
_get_cache_dir
(
char
*
buffer
,
int
buf_size
);
static
int
_get_cache_dir
(
char
*
buffer
,
int
buf_size
);
static
void
_parse_line
(
char
*
in_line
,
char
**
user_name
,
int
*
user_id
);
static
int
_parse_line
(
char
*
in_line
,
char
**
user_name
,
int
*
user_id
);
main
(
int
argc
,
char
**
argv
)
main
(
int
argc
,
char
**
argv
)
{
{
...
@@ -80,19 +82,17 @@ main (int argc, char **argv)
...
@@ -80,19 +82,17 @@ main (int argc, char **argv)
exit
(
1
);
exit
(
1
);
strncat
(
cache_dir
,
"/env_cache"
,
sizeof
(
cache_dir
));
strncat
(
cache_dir
,
"/env_cache"
,
sizeof
(
cache_dir
));
if
(
mkdir
(
cache_dir
,
0500
)
&&
(
errno
!=
EEXIST
))
{
if
(
mkdir
(
cache_dir
,
0500
)
&&
(
errno
!=
EEXIST
))
{
printf
(
"Could not create cache directory %s: %s"
,
cache_dir
,
printf
(
"Could not create cache directory %s: %s
\n
"
,
cache_dir
,
strerror
(
errno
));
strerror
(
errno
));
exit
(
1
);
exit
(
1
);
}
}
#if DEBUG
printf
(
"cache_dir=%s
\n
"
,
cache_dir
);
printf
(
"cache_dir=%s
\n
"
,
cache_dir
);
#endif
for
(
i
=
1
;
i
<
argc
;
i
++
)
{
for
(
i
=
1
;
i
<
argc
;
i
++
)
{
delta_t
=
_build_cache
(
argv
[
i
],
cache_dir
);
delta_t
=
_build_cache
(
argv
[
i
],
cache_dir
);
#
if
DEBUG
if
(
delta_t
<
((
SU_WAIT_MSEC
*
0
.
8
)
*
1000
))
printf
(
"user %-8s time %ld usec
\n
"
,
argv
[
i
],
delta_t
)
;
continue
;
#endif
printf
(
"WARNING: user %-8s time %ld usec
\n
"
,
argv
[
i
],
delta_t
);
}
}
if
(
i
>
1
)
if
(
i
>
1
)
exit
(
0
);
exit
(
0
);
...
@@ -104,52 +104,76 @@ main (int argc, char **argv)
...
@@ -104,52 +104,76 @@ main (int argc, char **argv)
}
}
while
(
fgets
(
in_line
,
sizeof
(
in_line
),
passwd_fd
))
{
while
(
fgets
(
in_line
,
sizeof
(
in_line
),
passwd_fd
))
{
_parse_line
(
in_line
,
&
user_name
,
&
user_id
);
if
(
_parse_line
(
in_line
,
&
user_name
,
&
user_id
)
<
0
)
continue
;
if
(
user_id
<=
100
)
if
(
user_id
<=
100
)
continue
;
continue
;
delta_t
=
_build_cache
(
user_name
,
cache_dir
);
delta_t
=
_build_cache
(
user_name
,
cache_dir
);
#if DEBUG
if
(
delta_t
<
((
SU_WAIT_MSEC
*
0
.
8
)
*
1000
))
if
(
delta_t
<
((
SU_WAIT_MSEC
*
0
.
8
)
*
1000
))
continue
;
continue
;
printf
(
"user %-8s time %ld usec
\n
"
,
user_name
,
delta_t
);
printf
(
"WARNING: user %-8s time %ld usec
\n
"
,
user_name
,
delta_t
);
#endif
}
}
fclose
(
passwd_fd
);
fclose
(
passwd_fd
);
}
}
/* Given a line from /etc/passwd, return the user_name and user_id */
/* Given a line from /etc/passwd, sets the user_name and user_id
static
void
_parse_line
(
char
*
in_line
,
char
**
user_name
,
int
*
user_id
)
* RET -1 if user can't login, 0 otherwise */
static
int
_parse_line
(
char
*
in_line
,
char
**
user_name
,
int
*
user_id
)
{
{
char
*
tok
;
char
*
tok
,
*
shell
;
/* user name */
*
user_name
=
strtok
(
in_line
,
":"
);
*
user_name
=
strtok
(
in_line
,
":"
);
(
void
)
strtok
(
NULL
,
":"
);
(
void
)
strtok
(
NULL
,
":"
);
/* uid */
tok
=
strtok
(
NULL
,
":"
);
tok
=
strtok
(
NULL
,
":"
);
if
(
tok
)
if
(
tok
)
*
user_id
=
atoi
(
tok
);
*
user_id
=
atoi
(
tok
);
else
{
else
{
printf
(
"
error
parsing /etc/passwd: %s
\n
"
,
in_line
);
printf
(
"
ERROR:
parsing /etc/passwd: %s
\n
"
,
in_line
);
*
user_id
=
0
;
*
user_id
=
0
;
}
}
(
void
)
strtok
(
NULL
,
":"
);
/* gid */
(
void
)
strtok
(
NULL
,
":"
);
/* name */
(
void
)
strtok
(
NULL
,
":"
);
/* home */
shell
=
strtok
(
NULL
,
":"
);
if
(
shell
)
{
tok
=
strchr
(
shell
,
'\n'
);
if
(
tok
)
tok
[
0
]
=
'\0'
;
if
((
strcmp
(
shell
,
"/sbin/nologin"
)
==
0
)
||
(
strcmp
(
shell
,
"/bin/false"
)
==
0
))
return
-
1
;
}
return
0
;
}
}
/* For a given user_name, get his environment variable by executing
/* For a given user_name, get his environment variable by executing
* "su - <user_name> -c env" and store the result in
* "su - <user_name> -c env" and store the result in
* cache_dir/env_<user_name>
* cache_dir/env_<user_name>
* Returns time to perform the operation in usec
* Returns time to perform the operation in usec
or -1 on error
*/
*/
static
long
int
_build_cache
(
char
*
user_name
,
char
*
cache_dir
)
static
long
int
_build_cache
(
char
*
user_name
,
char
*
cache_dir
)
{
{
FILE
*
su
,
*
cache
;
FILE
*
cache
;
char
line
[
BUFSIZ
],
name
[
BUFSIZ
],
value
[
BUFSIZ
],
out_file
[
BUFSIZ
];
char
*
line
,
*
last
,
out_file
[
BUFSIZ
],
buffer
[
64
*
1024
];
char
*
starttoken
=
"XXXXSLURMSTARTPARSINGHEREXXXX"
;
char
*
starttoken
=
"XXXXSLURMSTARTPARSINGHEREXXXX"
;
char
*
stoptoken
=
"XXXXSLURMSTOPPARSINGHEREXXXXX"
;
char
*
stoptoken
=
"XXXXSLURMSTOPPARSINGHEREXXXXX"
;
int
fildes
[
2
],
found
,
fval
,
len
,
rc
,
timeleft
;
int
fildes
[
2
],
found
,
fval
,
len
,
rc
,
timeleft
;
int
buf_read
,
buf_rem
;
pid_t
child
;
pid_t
child
;
struct
timeval
begin
,
now
;
struct
timeval
begin
,
now
;
struct
pollfd
ufds
;
struct
pollfd
ufds
;
long
int
delta_t
;
long
int
delta_t
;
gettimeofday
(
&
begin
,
NULL
);
if
(
pipe
(
fildes
)
<
0
)
{
if
(
pipe
(
fildes
)
<
0
)
{
perror
(
"pipe"
);
perror
(
"pipe"
);
return
-
1
;
return
-
1
;
...
@@ -166,13 +190,14 @@ static long int _build_cache(char *user_name, char *cache_dir)
...
@@ -166,13 +190,14 @@ static long int _build_cache(char *user_name, char *cache_dir)
dup2
(
fildes
[
1
],
1
);
dup2
(
fildes
[
1
],
1
);
close
(
2
);
close
(
2
);
open
(
"/dev/null"
,
O_WRONLY
);
open
(
"/dev/null"
,
O_WRONLY
);
snprintf
(
line
,
sizeof
(
line
),
snprintf
(
buffer
,
sizeof
(
buffer
),
"echo; echo; echo; echo %s; env; echo %s"
,
"/bin/echo; /bin/echo; /bin/echo; "
"/bin/echo %s; /bin/env; /bin/echo %s"
,
starttoken
,
stoptoken
);
starttoken
,
stoptoken
);
#ifdef LOAD_ENV_NO_LOGIN
#ifdef LOAD_ENV_NO_LOGIN
execl
(
"/bin/su"
,
"su"
,
user_name
,
"-c"
,
line
,
NULL
);
execl
(
"/bin/su"
,
"su"
,
user_name
,
"-c"
,
buffer
,
NULL
);
#else
#else
execl
(
"/bin/su"
,
"su"
,
"-"
,
user_name
,
"-c"
,
line
,
NULL
);
execl
(
"/bin/su"
,
"su"
,
"-"
,
user_name
,
"-c"
,
buffer
,
NULL
);
#endif
#endif
exit
(
1
);
exit
(
1
);
}
}
...
@@ -180,30 +205,30 @@ static long int _build_cache(char *user_name, char *cache_dir)
...
@@ -180,30 +205,30 @@ static long int _build_cache(char *user_name, char *cache_dir)
close
(
fildes
[
1
]);
close
(
fildes
[
1
]);
if
((
fval
=
fcntl
(
fildes
[
0
],
F_GETFL
,
0
))
>=
0
)
if
((
fval
=
fcntl
(
fildes
[
0
],
F_GETFL
,
0
))
>=
0
)
fcntl
(
fildes
[
0
],
F_SETFL
,
fval
|
O_NONBLOCK
);
fcntl
(
fildes
[
0
],
F_SETFL
,
fval
|
O_NONBLOCK
);
su
=
fdopen
(
fildes
[
0
],
"r"
);
gettimeofday
(
&
begin
,
NULL
);
ufds
.
fd
=
fildes
[
0
];
ufds
.
fd
=
fildes
[
0
];
ufds
.
events
=
POLLIN
;
ufds
.
events
=
POLLIN
;
ufds
.
revents
=
0
;
/* First look for the start token in the output */
/* Read all of the output from /bin/su into buffer */
len
=
strlen
(
starttoken
);
found
=
0
;
found
=
0
;
while
(
!
found
)
{
buf_read
=
0
;
bzero
(
buffer
,
sizeof
(
buffer
));
while
(
1
)
{
gettimeofday
(
&
now
,
NULL
);
gettimeofday
(
&
now
,
NULL
);
timeleft
=
SU_WAIT_MSEC
*
10
;
timeleft
=
SU_WAIT_MSEC
*
10
;
timeleft
-=
(
now
.
tv_sec
-
begin
.
tv_sec
)
*
1000
;
timeleft
-=
(
now
.
tv_sec
-
begin
.
tv_sec
)
*
1000
;
timeleft
-=
(
now
.
tv_usec
-
begin
.
tv_usec
)
/
1000
;
timeleft
-=
(
now
.
tv_usec
-
begin
.
tv_usec
)
/
1000
;
if
(
timeleft
<=
0
)
{
if
(
timeleft
<=
0
)
{
#if DEBUG
#if
_
DEBUG
printf
(
"timeout1
\n
"
);
printf
(
"timeout1
for %s
\n
"
,
user_name
);
#endif
#endif
break
;
break
;
}
}
if
((
rc
=
poll
(
&
ufds
,
1
,
timeleft
))
<=
0
)
{
if
((
rc
=
poll
(
&
ufds
,
1
,
timeleft
))
<=
0
)
{
if
(
rc
==
0
)
{
if
(
rc
==
0
)
{
#if DEBUG
#if
_
DEBUG
printf
(
"timeout2
\n
"
);
printf
(
"timeout2
for %s
\n
, user_name
"
);
#endif
#endif
break
;
break
;
}
}
...
@@ -213,88 +238,97 @@ static long int _build_cache(char *user_name, char *cache_dir)
...
@@ -213,88 +238,97 @@ static long int _build_cache(char *user_name, char *cache_dir)
break
;
break
;
}
}
if
(
!
(
ufds
.
revents
&
POLLIN
))
{
if
(
!
(
ufds
.
revents
&
POLLIN
))
{
perror
(
"POLLERR|POLLHUP"
);
if
(
ufds
.
revents
&
POLLHUP
)
{
/* EOF */
#if _DEBUG
printf
(
"POLLHUP for %s
\n
"
,
user_name
);
#endif
found
=
1
;
/* success */
}
else
if
(
ufds
.
revents
&
POLLERR
)
{
printf
(
"ERROR: POLLERR for %s
\n
"
,
user_name
);
}
else
{
printf
(
"ERROR: poll() revents=%d for %s
\n
"
,
ufds
.
revents
,
user_name
);
}
break
;
break
;
}
}
while
(
fgets
(
line
,
BUFSIZ
,
su
))
{
buf_rem
=
sizeof
(
buffer
)
-
buf_read
;
if
(
!
strncmp
(
line
,
starttoken
,
len
))
{
if
(
buf_rem
==
0
)
{
found
=
1
;
printf
(
"ERROR: buffer overflow for %s
\n
"
,
user_name
);
break
;
break
;
}
}
rc
=
read
(
fildes
[
0
],
&
buffer
[
buf_read
],
buf_rem
);
if
(
rc
>
0
)
buf_read
+=
rc
;
else
if
(
rc
==
0
)
{
/* EOF */
#if _DEBUG
printf
(
"EOF for %s
\n
"
,
user_name
);
#endif
found
=
1
;
/* success */
break
;
}
else
{
/* error */
perror
(
"read"
);
break
;
}
}
}
}
close
(
fildes
[
0
]);
if
(
!
found
)
{
if
(
!
found
)
{
printf
(
"Failed to get current user environment variables "
printf
(
"ERROR: Failed to load current user environment "
"for %s
\n
"
,
user_name
);
"variables for %s
\n
"
,
user_name
);
close
(
fildes
[
0
]);
return
-
1
;
gettimeofday
(
&
now
,
NULL
);
}
delta_t
=
now
.
tv_sec
-
begin
.
tv_sec
*
1000000
;
delta_t
+=
now
.
tv_usec
-
begin
.
tv_usec
;
/* First look for the start token in the output */
if
(
delta_t
<
(
SU_WAIT_MSEC
*
1000
))
len
=
strlen
(
starttoken
);
return
(
SU_WAIT_MSEC
*
1000
);
found
=
0
;
return
delta_t
;
line
=
strtok_r
(
buffer
,
"
\n
"
,
&
last
);
while
(
!
found
&&
line
)
{
if
(
!
strncmp
(
line
,
starttoken
,
len
))
{
found
=
1
;
break
;
}
line
=
strtok_r
(
NULL
,
"
\n
"
,
&
last
);
}
if
(
!
found
)
{
printf
(
"ERROR: Failed to get current user environment "
"variables for %s
\n
"
,
user_name
);
return
-
1
;
}
}
snprintf
(
out_file
,
sizeof
(
out_file
),
"%s/%s"
,
cache_dir
,
user_name
);
snprintf
(
out_file
,
sizeof
(
out_file
),
"%s/%s"
,
cache_dir
,
user_name
);
cache
=
fopen
(
out_file
,
"w"
);
cache
=
fopen
(
out_file
,
"w"
);
if
(
!
cache
)
{
if
(
!
cache
)
{
printf
(
"Could not create cache file %s: %s
\n
"
,
out_file
,
printf
(
"ERROR: Could not create cache file %s for %s: %s
\n
"
,
strerror
(
errno
));
out_file
,
user_name
,
strerror
(
errno
));
return
-
1
;
}
}
chmod
(
out_file
,
0600
);
/* Process environment variables until we find the stop token */
len
=
strlen
(
stoptoken
);
len
=
strlen
(
stoptoken
);
found
=
0
;
found
=
0
;
while
(
!
found
&&
cache
)
{
line
=
strtok_r
(
NULL
,
"
\n
"
,
&
last
);
gettimeofday
(
&
now
,
NULL
);
while
(
!
found
&&
line
)
{
timeleft
=
SU_WAIT_MSEC
*
10
;
if
(
!
strncmp
(
line
,
stoptoken
,
len
))
{
timeleft
-=
(
now
.
tv_sec
-
begin
.
tv_sec
)
*
1000
;
timeleft
-=
(
now
.
tv_usec
-
begin
.
tv_usec
)
/
1000
;
if
(
timeleft
<=
0
)
{
#if DEBUG
printf
(
"timeout3
\n
"
);
#endif
break
;
}
if
((
rc
=
poll
(
&
ufds
,
1
,
timeleft
))
<=
0
)
{
if
(
rc
==
0
)
{
#if DEBUG
printf
(
"timeout4
\n
"
);
#endif
break
;
}
if
((
errno
==
EINTR
)
||
(
errno
==
EAGAIN
))
continue
;
perror
(
"poll"
);
break
;
}
if
(
!
(
ufds
.
revents
&
POLLIN
))
{
perror
(
"POLLERR|POLLHUP"
);
break
;
}
/* stop at the line containing the stoptoken string */
if
((
fgets
(
line
,
BUFSIZ
,
su
)
==
0
)
||
(
!
strncmp
(
line
,
stoptoken
,
len
)))
{
found
=
1
;
found
=
1
;
break
;
break
;
}
}
if
(
fprintf
(
cache
,
"%s
\n
"
,
line
)
<
0
)
{
if
(
fputs
(
line
,
cache
)
==
EOF
)
{
printf
(
"ERROR: Could not write cache file %s "
printf
(
"Could not write cache file
%s: %s
\n
"
,
"for
%s: %s
\n
"
,
out_file
,
strerror
(
errno
));
out_file
,
user_name
,
strerror
(
errno
));
found
=
1
;
/* quit now */
found
=
1
;
/* quit now */
}
}
line
=
strtok_r
(
NULL
,
"
\n
"
,
&
last
);
}
}
close
(
fildes
[
0
]);
fclose
(
cache
);
if
(
cache
)
fclose
(
cache
);
waitpid
(
-
1
,
NULL
,
WNOHANG
);
waitpid
(
-
1
,
NULL
,
WNOHANG
);
gettimeofday
(
&
now
,
NULL
);
gettimeofday
(
&
now
,
NULL
);
delta_t
=
(
now
.
tv_sec
-
begin
.
tv_sec
)
*
1000000
;
delta_t
=
(
now
.
tv_sec
-
begin
.
tv_sec
)
*
1000000
;
delta_t
+=
now
.
tv_usec
-
begin
.
tv_usec
;
delta_t
+=
now
.
tv_usec
-
begin
.
tv_usec
;
if
(
!
found
)
{
if
(
!
found
)
{
printf
(
"Failed to
get current
user environment
variables
"
printf
(
"
ERROR:
Failed to
write all
user environment "
"for %s
\n
"
,
user_name
);
"
variables
for %s
\n
"
,
user_name
);
if
(
delta_t
<
(
SU_WAIT_MSEC
*
1000
))
if
(
delta_t
<
(
SU_WAIT_MSEC
*
1000
))
return
(
SU_WAIT_MSEC
*
1000
);
return
(
SU_WAIT_MSEC
*
1000
);
}
}
...
@@ -349,7 +383,7 @@ static int _get_cache_dir(char *buffer, int buf_size)
...
@@ -349,7 +383,7 @@ static int _get_cache_dir(char *buffer, int buf_size)
}
}
close
(
fildes
[
0
]);
close
(
fildes
[
0
]);
if
(
!
buffer
[
0
])
{
if
(
!
buffer
[
0
])
{
printf
(
"Failed to get StateSaveLocation
\n
"
);
printf
(
"
ERROR:
Failed to get StateSaveLocation
\n
"
);
close
(
fildes
[
0
]);
close
(
fildes
[
0
]);
return
-
1
;
return
-
1
;
}
}
...
...
This diff is collapsed.
Click to expand it.
src/common/env.c
+
65
−
54
View file @
b70918a5
...
@@ -1300,15 +1300,14 @@ char **_load_env_cache(const char *username)
...
@@ -1300,15 +1300,14 @@ char **_load_env_cache(const char *username)
*/
*/
char
**
env_array_user_default
(
const
char
*
username
,
int
timeout
,
int
mode
)
char
**
env_array_user_default
(
const
char
*
username
,
int
timeout
,
int
mode
)
{
{
FILE
*
su
;
char
*
line
,
*
last
,
name
[
128
],
value
[
ENV_BUFSIZE
];
char
line
[
ENV_BUFSIZE
];
char
buffer
[
ENV_BUFSIZE
];
char
name
[
128
];
char
value
[
ENV_BUFSIZE
];
char
**
env
=
NULL
;
char
**
env
=
NULL
;
char
*
starttoken
=
"XXXXSLURMSTARTPARSINGHEREXXXX"
;
char
*
starttoken
=
"XXXXSLURMSTARTPARSINGHEREXXXX"
;
char
*
stoptoken
=
"XXXXSLURMSTOPPARSINGHEREXXXXX"
;
char
*
stoptoken
=
"XXXXSLURMSTOPPARSINGHEREXXXXX"
;
char
cmdstr
[
256
];
char
cmdstr
[
256
];
int
fildes
[
2
],
found
,
fval
,
len
,
rc
,
timeleft
;
int
fildes
[
2
],
found
,
fval
,
len
,
rc
,
timeleft
;
int
buf_read
,
buf_rem
;
pid_t
child
;
pid_t
child
;
struct
timeval
begin
,
now
;
struct
timeval
begin
,
now
;
struct
pollfd
ufds
;
struct
pollfd
ufds
;
...
@@ -1335,7 +1334,8 @@ char **env_array_user_default(const char *username, int timeout, int mode)
...
@@ -1335,7 +1334,8 @@ char **env_array_user_default(const char *username, int timeout, int mode)
close
(
2
);
close
(
2
);
open
(
"/dev/null"
,
O_WRONLY
);
open
(
"/dev/null"
,
O_WRONLY
);
snprintf
(
cmdstr
,
sizeof
(
cmdstr
),
snprintf
(
cmdstr
,
sizeof
(
cmdstr
),
"/bin/echo; /bin/echo; /bin/echo; /bin/echo %s; /bin/env; /bin/echo %s"
,
"/bin/echo; /bin/echo; /bin/echo; "
"/bin/echo %s; /bin/env; /bin/echo %s"
,
starttoken
,
stoptoken
);
starttoken
,
stoptoken
);
if
(
mode
==
1
)
if
(
mode
==
1
)
execl
(
"/bin/su"
,
"su"
,
username
,
"-c"
,
cmdstr
,
NULL
);
execl
(
"/bin/su"
,
"su"
,
username
,
"-c"
,
cmdstr
,
NULL
);
...
@@ -1354,25 +1354,24 @@ char **env_array_user_default(const char *username, int timeout, int mode)
...
@@ -1354,25 +1354,24 @@ char **env_array_user_default(const char *username, int timeout, int mode)
close
(
fildes
[
1
]);
close
(
fildes
[
1
]);
if
((
fval
=
fcntl
(
fildes
[
0
],
F_GETFL
,
0
))
>=
0
)
if
((
fval
=
fcntl
(
fildes
[
0
],
F_GETFL
,
0
))
>=
0
)
fcntl
(
fildes
[
0
],
F_SETFL
,
fval
|
O_NONBLOCK
);
fcntl
(
fildes
[
0
],
F_SETFL
,
fval
|
O_NONBLOCK
);
su
=
fdopen
(
fildes
[
0
],
"r"
);
gettimeofday
(
&
begin
,
NULL
);
gettimeofday
(
&
begin
,
NULL
);
ufds
.
fd
=
fildes
[
0
];
ufds
.
fd
=
fildes
[
0
];
ufds
.
events
=
POLLIN
;
ufds
.
events
=
POLLIN
;
/* First look for the start token in the output */
/* Read all of the output from /bin/su into buffer */
len
=
strlen
(
starttoken
);
found
=
0
;
found
=
0
;
while
(
!
found
)
{
buf_read
=
0
;
bzero
(
buffer
,
sizeof
(
buffer
));
while
(
1
)
{
gettimeofday
(
&
now
,
NULL
);
gettimeofday
(
&
now
,
NULL
);
if
(
timeout
>
0
)
timeleft
=
SU_WAIT_MSEC
;
timeleft
=
timeout
*
1000
;
else
timeleft
=
SU_WAIT_MSEC
;
timeleft
-=
(
now
.
tv_sec
-
begin
.
tv_sec
)
*
1000
;
timeleft
-=
(
now
.
tv_sec
-
begin
.
tv_sec
)
*
1000
;
timeleft
-=
(
now
.
tv_usec
-
begin
.
tv_usec
)
/
1000
;
timeleft
-=
(
now
.
tv_usec
-
begin
.
tv_usec
)
/
1000
;
if
(
timeleft
<=
0
)
if
(
timeleft
<=
0
)
{
verbose
(
"timeout waiting for /bin/su to complete"
);
break
;
break
;
}
if
((
rc
=
poll
(
&
ufds
,
1
,
timeleft
))
<=
0
)
{
if
((
rc
=
poll
(
&
ufds
,
1
,
timeleft
))
<=
0
)
{
if
(
rc
==
0
)
{
if
(
rc
==
0
)
{
verbose
(
"timeout waiting for /bin/su to complete"
);
verbose
(
"timeout waiting for /bin/su to complete"
);
...
@@ -1380,64 +1379,76 @@ char **env_array_user_default(const char *username, int timeout, int mode)
...
@@ -1380,64 +1379,76 @@ char **env_array_user_default(const char *username, int timeout, int mode)
}
}
if
((
errno
==
EINTR
)
||
(
errno
==
EAGAIN
))
if
((
errno
==
EINTR
)
||
(
errno
==
EAGAIN
))
continue
;
continue
;
error
(
"poll: %m"
);
error
(
"poll
()
: %m"
);
break
;
break
;
}
}
if
(
!
(
ufds
.
revents
&
POLLIN
))
if
(
!
(
ufds
.
revents
&
POLLIN
))
{
break
;
if
(
ufds
.
revents
&
POLLHUP
)
{
/* EOF */
while
(
fgets
(
line
,
sizeof
(
line
),
su
))
{
found
=
1
;
/* success */
if
(
!
strncmp
(
line
,
starttoken
,
len
))
{
}
else
if
(
ufds
.
revents
&
POLLERR
)
{
found
=
1
;
error
(
"POLLERR"
);
break
;
}
else
{
error
(
"poll() revents=%d"
,
ufds
.
revents
);
}
}
break
;
}
buf_rem
=
sizeof
(
buffer
)
-
buf_read
;
if
(
buf_rem
==
0
)
{
error
(
"buffer overflow loading env vars"
);
break
;
}
rc
=
read
(
fildes
[
0
],
&
buffer
[
buf_read
],
buf_rem
);
if
(
rc
>
0
)
buf_read
+=
rc
;
else
if
(
rc
==
0
)
{
/* EOF */
found
=
1
;
/* success */
break
;
}
else
{
/* error */
error
(
"read(env pipe): %m"
);
break
;
}
}
close
(
fildes
[
0
]);
if
(
!
found
)
{
error
(
"Failed to load current user environment variables"
);
_load_env_cache
(
username
);
}
/* First look for the start token in the output */
len
=
strlen
(
starttoken
);
found
=
0
;
line
=
strtok_r
(
buffer
,
"
\n
"
,
&
last
);
while
(
!
found
&&
line
)
{
if
(
!
strncmp
(
line
,
starttoken
,
len
))
{
found
=
1
;
break
;
}
}
line
=
strtok_r
(
NULL
,
"
\n
"
,
&
last
);
}
}
if
(
!
found
)
{
if
(
!
found
)
{
error
(
"Failed to get current user environment variables"
);
error
(
"Failed to get current user environment variables"
);
close
(
fildes
[
0
]);
return
_load_env_cache
(
username
);
return
_load_env_cache
(
username
);
}
}
/* Now read in the environment variable strings. */
/* Process environment variables until we find the stop token */
env
=
env_array_create
();
len
=
strlen
(
stoptoken
);
len
=
strlen
(
stoptoken
);
found
=
0
;
found
=
0
;
while
(
!
found
)
{
env
=
env_array_create
();
gettimeofday
(
&
now
,
NULL
);
line
=
strtok_r
(
NULL
,
"
\n
"
,
&
last
);
if
(
timeout
>
0
)
while
(
!
found
&&
line
)
{
timeleft
=
timeout
*
1000
;
if
(
!
strncmp
(
line
,
stoptoken
,
len
))
{
else
timeleft
=
SU_WAIT_MSEC
;
timeleft
-=
(
now
.
tv_sec
-
begin
.
tv_sec
)
*
1000
;
timeleft
-=
(
now
.
tv_usec
-
begin
.
tv_usec
)
/
1000
;
if
(
timeleft
<=
0
)
break
;
if
((
rc
=
poll
(
&
ufds
,
1
,
timeleft
))
<=
0
)
{
if
(
rc
==
0
)
{
verbose
(
"timeout waiting for /bin/su to complete"
);
break
;
}
if
((
errno
==
EINTR
)
||
(
errno
==
EAGAIN
))
continue
;
error
(
"poll: %m"
);
break
;
}
/* stop at the line containing the stoptoken string */
if
(
!
(
ufds
.
revents
&
POLLIN
))
break
;
if
((
fgets
(
line
,
sizeof
(
line
),
su
)
==
0
)
||
(
!
strncmp
(
line
,
stoptoken
,
len
)))
{
found
=
1
;
found
=
1
;
break
;
break
;
}
}
if
(
_env_array_entry_splitter
(
line
,
name
,
sizeof
(
name
),
_strip_cr_nl
(
line
);
if
(
_env_array_entry_splitter
(
line
,
name
,
sizeof
(
name
),
value
,
sizeof
(
value
)))
value
,
sizeof
(
value
)))
env_array_overwrite
(
&
env
,
name
,
value
);
env_array_overwrite
(
&
env
,
name
,
value
);
line
=
strtok_r
(
NULL
,
"
\n
"
,
&
last
);
}
if
(
!
found
)
{
error
(
"Failed to get all user environment variables"
);
return
_load_env_cache
(
username
);
}
}
close
(
fildes
[
0
]);
return
env
;
return
env
;
}
}
This diff is collapsed.
Click to expand it.
Preview
0%
Loading
Try again
or
attach a new file
.
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Save comment
Cancel
Please
register
or
sign in
to comment