Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
L
lxc
Project
Overview
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
Chen Yisong
lxc
Commits
4e2e55dc
Unverified
Commit
4e2e55dc
authored
Aug 06, 2018
by
Christian Brauner
Committed by
GitHub
Aug 06, 2018
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #2511 from 2xsec/coverity
fix coverity issues
parents
3b6fd327
3a88eb8e
Hide whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
166 additions
and
86 deletions
+166
-86
pam_cgfs.c
src/lxc/pam/pam_cgfs.c
+166
-86
No files found.
src/lxc/pam/pam_cgfs.c
View file @
4e2e55dc
...
@@ -275,7 +275,7 @@ static bool mkdir_parent(const char *root, char *path)
...
@@ -275,7 +275,7 @@ static bool mkdir_parent(const char *root, char *path)
goto
next
;
goto
next
;
if
(
do_mkdir
(
path
,
0755
)
<
0
)
{
if
(
do_mkdir
(
path
,
0755
)
<
0
)
{
pam_cgfs_debug
(
"Failed to create %s: %s
.
\n
"
,
path
,
strerror
(
errno
));
pam_cgfs_debug
(
"Failed to create %s: %s
\n
"
,
path
,
strerror
(
errno
));
return
false
;
return
false
;
}
}
...
@@ -356,9 +356,8 @@ static int append_null_to_list(void ***list)
...
@@ -356,9 +356,8 @@ static int append_null_to_list(void ***list)
int
newentry
=
0
;
int
newentry
=
0
;
if
(
*
list
)
if
(
*
list
)
for
(;
(
*
list
)[
newentry
];
newentry
++
)
{
for
(;
(
*
list
)[
newentry
];
newentry
++
)
;
;
}
*
list
=
must_realloc
(
*
list
,
(
newentry
+
2
)
*
sizeof
(
void
**
));
*
list
=
must_realloc
(
*
list
,
(
newentry
+
2
)
*
sizeof
(
void
**
));
(
*
list
)[
newentry
+
1
]
=
NULL
;
(
*
list
)[
newentry
+
1
]
=
NULL
;
...
@@ -541,7 +540,7 @@ static int recursive_rmdir(char *dirname)
...
@@ -541,7 +540,7 @@ static int recursive_rmdir(char *dirname)
if
(
lstat
(
pathname
,
&
st
))
{
if
(
lstat
(
pathname
,
&
st
))
{
if
(
!
r
)
if
(
!
r
)
pam_cgfs_debug
(
"Failed to stat %s
.
\n
"
,
pathname
);
pam_cgfs_debug
(
"Failed to stat %s
\n
"
,
pathname
);
r
=
-
1
;
r
=
-
1
;
goto
next
;
goto
next
;
}
}
...
@@ -551,19 +550,20 @@ static int recursive_rmdir(char *dirname)
...
@@ -551,19 +550,20 @@ static int recursive_rmdir(char *dirname)
if
(
recursive_rmdir
(
pathname
)
<
0
)
if
(
recursive_rmdir
(
pathname
)
<
0
)
r
=
-
1
;
r
=
-
1
;
next:
next:
free
(
pathname
);
free
(
pathname
);
}
}
if
(
rmdir
(
dirname
)
<
0
)
{
if
(
rmdir
(
dirname
)
<
0
)
{
if
(
!
r
)
if
(
!
r
)
pam_cgfs_debug
(
"Failed to delete %s: %s
.
\n
"
,
dirname
,
strerror
(
errno
));
pam_cgfs_debug
(
"Failed to delete %s: %s
\n
"
,
dirname
,
strerror
(
errno
));
r
=
-
1
;
r
=
-
1
;
}
}
if
(
closedir
(
dir
)
<
0
)
{
if
(
closedir
(
dir
)
<
0
)
{
if
(
!
r
)
if
(
!
r
)
pam_cgfs_debug
(
"Failed to delete %s: %s
.
\n
"
,
dirname
,
strerror
(
errno
));
pam_cgfs_debug
(
"Failed to delete %s: %s
\n
"
,
dirname
,
strerror
(
errno
));
r
=
-
1
;
r
=
-
1
;
}
}
...
@@ -730,6 +730,7 @@ static bool cgv1_controller_list_is_dup(struct cgv1_hierarchy **hlist, char **cl
...
@@ -730,6 +730,7 @@ static bool cgv1_controller_list_is_dup(struct cgv1_hierarchy **hlist, char **cl
if
((
*
it
)
->
controllers
)
if
((
*
it
)
->
controllers
)
if
(
cgv1_controller_lists_intersect
((
*
it
)
->
controllers
,
clist
))
if
(
cgv1_controller_lists_intersect
((
*
it
)
->
controllers
,
clist
))
return
true
;
return
true
;
return
false
;
return
false
;
}
}
...
@@ -744,7 +745,7 @@ static void cgv1_mark_to_make_rw(char **clist)
...
@@ -744,7 +745,7 @@ static void cgv1_mark_to_make_rw(char **clist)
for
(
it
=
cgv1_hierarchies
;
it
&&
*
it
;
it
++
)
for
(
it
=
cgv1_hierarchies
;
it
&&
*
it
;
it
++
)
if
((
*
it
)
->
controllers
)
if
((
*
it
)
->
controllers
)
if
(
cgv1_controller_lists_intersect
((
*
it
)
->
controllers
,
clist
)
||
if
(
cgv1_controller_lists_intersect
((
*
it
)
->
controllers
,
clist
)
||
string_in_list
(
clist
,
"all"
))
string_in_list
(
clist
,
"all"
))
(
*
it
)
->
create_rw_cgroup
=
true
;
(
*
it
)
->
create_rw_cgroup
=
true
;
}
}
...
@@ -776,8 +777,10 @@ static char *cgv1_must_prefix_named(char *entry)
...
@@ -776,8 +777,10 @@ static char *cgv1_must_prefix_named(char *entry)
s
=
must_alloc
(
len
+
6
);
s
=
must_alloc
(
len
+
6
);
ret
=
snprintf
(
s
,
len
+
6
,
"name=%s"
,
entry
);
ret
=
snprintf
(
s
,
len
+
6
,
"name=%s"
,
entry
);
if
(
ret
<
0
||
(
size_t
)
ret
>=
(
len
+
6
))
if
(
ret
<
0
||
(
size_t
)
ret
>=
(
len
+
6
))
{
free
(
s
);
return
NULL
;
return
NULL
;
}
return
s
;
return
s
;
}
}
...
@@ -823,8 +826,6 @@ static char **cgv1_get_proc_mountinfo_controllers(char **klist, char **nlist, ch
...
@@ -823,8 +826,6 @@ static char **cgv1_get_proc_mountinfo_controllers(char **klist, char **nlist, ch
return
NULL
;
return
NULL
;
p
++
;
p
++
;
}
}
if
(
!
p
)
return
NULL
;
if
(
strncmp
(
p
,
"/sys/fs/cgroup/"
,
15
)
!=
0
)
if
(
strncmp
(
p
,
"/sys/fs/cgroup/"
,
15
)
!=
0
)
return
NULL
;
return
NULL
;
...
@@ -864,6 +865,7 @@ static bool cgv1_controller_in_clist(char *cgline, char *c)
...
@@ -864,6 +865,7 @@ static bool cgv1_controller_in_clist(char *cgline, char *c)
if
(
strcmp
(
tok
,
c
)
==
0
)
if
(
strcmp
(
tok
,
c
)
==
0
)
return
true
;
return
true
;
}
}
return
false
;
return
false
;
}
}
...
@@ -935,6 +937,7 @@ static void cgv1_add_controller(char **clist, char *mountpoint, char *base_cgrou
...
@@ -935,6 +937,7 @@ static void cgv1_add_controller(char **clist, char *mountpoint, char *base_cgrou
int
newentry
;
int
newentry
;
new
=
must_alloc
(
sizeof
(
*
new
));
new
=
must_alloc
(
sizeof
(
*
new
));
new
->
controllers
=
clist
;
new
->
controllers
=
clist
;
new
->
mountpoint
=
mountpoint
;
new
->
mountpoint
=
mountpoint
;
new
->
base_cgroup
=
base_cgroup
;
new
->
base_cgroup
=
base_cgroup
;
...
@@ -961,6 +964,7 @@ static void cgv2_add_controller(char **clist, char *mountpoint, char *base_cgrou
...
@@ -961,6 +964,7 @@ static void cgv2_add_controller(char **clist, char *mountpoint, char *base_cgrou
int
newentry
;
int
newentry
;
new
=
must_alloc
(
sizeof
(
*
new
));
new
=
must_alloc
(
sizeof
(
*
new
));
new
->
controllers
=
clist
;
new
->
controllers
=
clist
;
new
->
mountpoint
=
mountpoint
;
new
->
mountpoint
=
mountpoint
;
new
->
base_cgroup
=
base_cgroup
;
new
->
base_cgroup
=
base_cgroup
;
...
@@ -1002,6 +1006,7 @@ static bool cg_systemd_under_user_slice_1(const char *in, uid_t uid)
...
@@ -1002,6 +1006,7 @@ static bool cg_systemd_under_user_slice_1(const char *in, uid_t uid)
p
--
;
p
--
;
if
(
p
<
copy
)
if
(
p
<
copy
)
goto
cleanup
;
goto
cleanup
;
/* make sure it is something.session */
/* make sure it is something.session */
len
=
strlen
(
p
+
1
);
len
=
strlen
(
p
+
1
);
if
(
len
<
strlen
(
"1.session"
)
||
if
(
len
<
strlen
(
"1.session"
)
||
...
@@ -1012,6 +1017,7 @@ static bool cg_systemd_under_user_slice_1(const char *in, uid_t uid)
...
@@ -1012,6 +1017,7 @@ static bool cg_systemd_under_user_slice_1(const char *in, uid_t uid)
*
(
p
+
1
)
=
'\0'
;
*
(
p
+
1
)
=
'\0'
;
while
(
p
>=
copy
&&
*
(
--
p
)
!=
'/'
)
while
(
p
>=
copy
&&
*
(
--
p
)
!=
'/'
)
;
;
if
(
sscanf
(
p
+
1
,
"%d.user/"
,
&
id
)
!=
1
)
if
(
sscanf
(
p
+
1
,
"%d.user/"
,
&
id
)
!=
1
)
goto
cleanup
;
goto
cleanup
;
...
@@ -1121,6 +1127,7 @@ static bool cg_systemd_created_user_slice(const char *base_cgroup,
...
@@ -1121,6 +1127,7 @@ static bool cg_systemd_created_user_slice(const char *base_cgroup,
succeed:
succeed:
bret
=
true
;
bret
=
true
;
cleanup:
cleanup:
free
(
copy
);
free
(
copy
);
return
bret
;
return
bret
;
...
@@ -1142,9 +1149,9 @@ static bool cg_systemd_chown_existing_cgroup(const char *mountpoint,
...
@@ -1142,9 +1149,9 @@ static bool cg_systemd_chown_existing_cgroup(const char *mountpoint,
* need to chown it.
* need to chown it.
*/
*/
if
(
chown
(
path
,
uid
,
gid
)
<
0
)
if
(
chown
(
path
,
uid
,
gid
)
<
0
)
mysyslog
(
LOG_WARNING
,
"Failed to chown %s to %d:%d: %s
.
\n
"
,
mysyslog
(
LOG_WARNING
,
"Failed to chown %s to %d:%d: %s
\n
"
,
path
,
(
int
)
uid
,
(
int
)
gid
,
strerror
(
errno
),
NULL
);
path
,
(
int
)
uid
,
(
int
)
gid
,
strerror
(
errno
),
NULL
);
pam_cgfs_debug
(
"Chowned %s to %d:%d
.
\n
"
,
path
,
(
int
)
uid
,
(
int
)
gid
);
pam_cgfs_debug
(
"Chowned %s to %d:%d
\n
"
,
path
,
(
int
)
uid
,
(
int
)
gid
);
free
(
path
);
free
(
path
);
return
true
;
return
true
;
...
@@ -1183,8 +1190,7 @@ static bool cgv1_init(uid_t uid, gid_t gid)
...
@@ -1183,8 +1190,7 @@ static bool cgv1_init(uid_t uid, gid_t gid)
if
(
!
controller_list
)
if
(
!
controller_list
)
continue
;
continue
;
if
(
cgv1_controller_list_is_dup
(
cgv1_hierarchies
,
if
(
cgv1_controller_list_is_dup
(
cgv1_hierarchies
,
controller_list
))
{
controller_list
))
{
free
(
controller_list
);
free
(
controller_list
);
continue
;
continue
;
}
}
...
@@ -1201,13 +1207,14 @@ static bool cgv1_init(uid_t uid, gid_t gid)
...
@@ -1201,13 +1207,14 @@ static bool cgv1_init(uid_t uid, gid_t gid)
free
(
mountpoint
);
free
(
mountpoint
);
continue
;
continue
;
}
}
trim
(
base_cgroup
);
trim
(
base_cgroup
);
pam_cgfs_debug
(
"Detected cgroupfs v1 controller
\"
%s
\"
with "
pam_cgfs_debug
(
"Detected cgroupfs v1 controller
\"
%s
\"
with "
"mountpoint
\"
%s
\"
and cgroup
\"
%s
\"
.
\n
"
,
"mountpoint
\"
%s
\"
and cgroup
\"
%s
\"\n
"
,
controller_list
[
0
],
mountpoint
,
base_cgroup
);
controller_list
[
0
],
mountpoint
,
base_cgroup
);
cgv1_add_controller
(
controller_list
,
mountpoint
,
base_cgroup
,
cgv1_add_controller
(
controller_list
,
mountpoint
,
base_cgroup
,
NULL
);
NULL
);
}
}
free_string_list
(
klist
);
free_string_list
(
klist
);
free_string_list
(
nlist
);
free_string_list
(
nlist
);
free
(
basecginfo
);
free
(
basecginfo
);
...
@@ -1222,6 +1229,7 @@ static bool cgv1_init(uid_t uid, gid_t gid)
...
@@ -1222,6 +1229,7 @@ static bool cgv1_init(uid_t uid, gid_t gid)
for
(
it
=
cgv1_hierarchies
;
it
&&
*
it
;
it
++
)
{
for
(
it
=
cgv1_hierarchies
;
it
&&
*
it
;
it
++
)
{
if
((
*
it
)
->
controllers
)
{
if
((
*
it
)
->
controllers
)
{
char
*
init_cgroup
,
*
user_slice
;
char
*
init_cgroup
,
*
user_slice
;
/* We've already stored the controller and received its
/* We've already stored the controller and received its
* current cgroup. If we now fail to retrieve its init
* current cgroup. If we now fail to retrieve its init
* cgroup, we should probably fail.
* cgroup, we should probably fail.
...
@@ -1231,17 +1239,21 @@ static bool cgv1_init(uid_t uid, gid_t gid)
...
@@ -1231,17 +1239,21 @@ static bool cgv1_init(uid_t uid, gid_t gid)
free
(
basecginfo
);
free
(
basecginfo
);
return
false
;
return
false
;
}
}
cg_systemd_prune_init_scope
(
init_cgroup
);
cg_systemd_prune_init_scope
(
init_cgroup
);
(
*
it
)
->
init_cgroup
=
init_cgroup
;
(
*
it
)
->
init_cgroup
=
init_cgroup
;
pam_cgfs_debug
(
"cgroupfs v1 controller
\"
%s
\"
has init "
pam_cgfs_debug
(
"cgroupfs v1 controller
\"
%s
\"
has init "
"cgroup
\"
%s
\"
.
\n
"
,
"cgroup
\"
%s
\"\n
"
,
(
*
(
*
it
)
->
controllers
),
init_cgroup
);
(
*
(
*
it
)
->
controllers
),
init_cgroup
);
/* Check whether systemd has already created a cgroup
/* Check whether systemd has already created a cgroup
* for us.
* for us.
*/
*/
user_slice
=
must_make_path
((
*
it
)
->
mountpoint
,
(
*
it
)
->
base_cgroup
,
NULL
);
user_slice
=
must_make_path
((
*
it
)
->
mountpoint
,
(
*
it
)
->
base_cgroup
,
NULL
);
if
(
cg_systemd_created_user_slice
((
*
it
)
->
base_cgroup
,
(
*
it
)
->
init_cgroup
,
user_slice
,
uid
))
if
(
cg_systemd_created_user_slice
((
*
it
)
->
base_cgroup
,
(
*
it
)
->
init_cgroup
,
user_slice
,
uid
))
(
*
it
)
->
systemd_user_slice
=
true
;
(
*
it
)
->
systemd_user_slice
=
true
;
free
(
user_slice
);
}
}
}
}
free
(
basecginfo
);
free
(
basecginfo
);
...
@@ -1289,6 +1301,7 @@ static bool cgv2_init(uid_t uid, gid_t gid)
...
@@ -1289,6 +1301,7 @@ static bool cgv2_init(uid_t uid, gid_t gid)
*/
*/
goto
cleanup
;
goto
cleanup
;
}
}
cg_systemd_prune_init_scope
(
init_cgroup
);
cg_systemd_prune_init_scope
(
init_cgroup
);
/* Check if the v2 hierarchy is mounted at its standard location.
/* Check if the v2 hierarchy is mounted at its standard location.
...
@@ -1323,6 +1336,7 @@ static bool cgv2_init(uid_t uid, gid_t gid)
...
@@ -1323,6 +1336,7 @@ static bool cgv2_init(uid_t uid, gid_t gid)
while
(
getline
(
&
line
,
&
len
,
f
)
!=
-
1
)
{
while
(
getline
(
&
line
,
&
len
,
f
)
!=
-
1
)
{
char
*
user_slice
;
char
*
user_slice
;
bool
has_user_slice
=
false
;
bool
has_user_slice
=
false
;
if
(
!
is_cgv2
(
line
))
if
(
!
is_cgv2
(
line
))
continue
;
continue
;
...
@@ -1336,6 +1350,7 @@ static bool cgv2_init(uid_t uid, gid_t gid)
...
@@ -1336,6 +1350,7 @@ static bool cgv2_init(uid_t uid, gid_t gid)
free
(
user_slice
);
free
(
user_slice
);
cgv2_add_controller
(
NULL
,
mountpoint
,
current_cgroup
,
init_cgroup
,
has_user_slice
);
cgv2_add_controller
(
NULL
,
mountpoint
,
current_cgroup
,
init_cgroup
,
has_user_slice
);
/* Although the unified hierarchy can be mounted multiple times,
/* Although the unified hierarchy can be mounted multiple times,
* each of those mountpoints will expose identical information.
* each of those mountpoints will expose identical information.
* So let the first mountpoint we find, win.
* So let the first mountpoint we find, win.
...
@@ -1345,14 +1360,19 @@ static bool cgv2_init(uid_t uid, gid_t gid)
...
@@ -1345,14 +1360,19 @@ static bool cgv2_init(uid_t uid, gid_t gid)
}
}
pam_cgfs_debug
(
"Detected cgroupfs v2 hierarchy at mountpoint
\"
%s
\"
with "
pam_cgfs_debug
(
"Detected cgroupfs v2 hierarchy at mountpoint
\"
%s
\"
with "
"current cgroup
\"
%s
\"
and init cgroup
\"
%s
\"
.
\n
"
,
"current cgroup
\"
%s
\"
and init cgroup
\"
%s
\"
\n
"
,
mountpoint
,
current_cgroup
,
init_cgroup
);
mountpoint
,
current_cgroup
,
init_cgroup
);
cleanup:
cleanup:
if
(
f
)
if
(
f
)
fclose
(
f
);
fclose
(
f
);
free
(
line
);
free
(
line
);
if
(
!
ret
)
{
free
(
init_cgroup
);
free
(
current_cgroup
);
}
return
ret
;
return
ret
;
}
}
...
@@ -1373,16 +1393,16 @@ static bool cg_init(uid_t uid, gid_t gid)
...
@@ -1373,16 +1393,16 @@ static bool cg_init(uid_t uid, gid_t gid)
if
(
cgv1_hierarchies
&&
cgv2_hierarchies
)
{
if
(
cgv1_hierarchies
&&
cgv2_hierarchies
)
{
cg_mount_mode
=
CGROUP_MIXED
;
cg_mount_mode
=
CGROUP_MIXED
;
pam_cgfs_debug
(
"%s
\n
"
,
"Detected cgroupfs v1 and v2 hierarchies
.
"
);
pam_cgfs_debug
(
"%s
\n
"
,
"Detected cgroupfs v1 and v2 hierarchies"
);
}
else
if
(
cgv1_hierarchies
&&
!
cgv2_hierarchies
)
{
}
else
if
(
cgv1_hierarchies
&&
!
cgv2_hierarchies
)
{
cg_mount_mode
=
CGROUP_PURE_V1
;
cg_mount_mode
=
CGROUP_PURE_V1
;
pam_cgfs_debug
(
"%s
\n
"
,
"Detected cgroupfs v1 hierarchies
.
"
);
pam_cgfs_debug
(
"%s
\n
"
,
"Detected cgroupfs v1 hierarchies"
);
}
else
if
(
cgv2_hierarchies
&&
!
cgv1_hierarchies
)
{
}
else
if
(
cgv2_hierarchies
&&
!
cgv1_hierarchies
)
{
cg_mount_mode
=
CGROUP_PURE_V2
;
cg_mount_mode
=
CGROUP_PURE_V2
;
pam_cgfs_debug
(
"%s
\n
"
,
"Detected cgroupfs v2 hierarchies
.
"
);
pam_cgfs_debug
(
"%s
\n
"
,
"Detected cgroupfs v2 hierarchies"
);
}
else
{
}
else
{
cg_mount_mode
=
CGROUP_UNKNOWN
;
cg_mount_mode
=
CGROUP_UNKNOWN
;
mysyslog
(
LOG_ERR
,
"Could not detect cgroupfs hierarchy
.
\n
"
,
NULL
);
mysyslog
(
LOG_ERR
,
"Could not detect cgroupfs hierarchy
\n
"
,
NULL
);
}
}
if
(
cg_mount_mode
==
CGROUP_UNKNOWN
)
if
(
cg_mount_mode
==
CGROUP_UNKNOWN
)
...
@@ -1429,15 +1449,18 @@ static bool cgv1_enter(const char *cgroup)
...
@@ -1429,15 +1449,18 @@ static bool cgv1_enter(const char *cgroup)
"/tasks"
,
"/tasks"
,
NULL
);
NULL
);
}
}
pam_cgfs_debug
(
"Attempting to enter cgroupfs v1 hierarchy in
\"
%s
\"
cgroup.
\n
"
,
path
);
pam_cgfs_debug
(
"Attempting to enter cgroupfs v1 hierarchy in
\"
%s
\"
cgroup
\n
"
,
path
);
entered
=
write_int
(
path
,
(
int
)
getpid
());
entered
=
write_int
(
path
,
(
int
)
getpid
());
if
(
entered
)
{
if
(
entered
)
{
free
(
path
);
free
(
path
);
break
;
break
;
}
}
pam_cgfs_debug
(
"Failed to enter cgroupfs v1 hierarchy in
\"
%s
\"
cgroup.
\n
"
,
path
);
pam_cgfs_debug
(
"Failed to enter cgroupfs v1 hierarchy in
\"
%s
\"
cgroup
\n
"
,
path
);
free
(
path
);
free
(
path
);
}
}
if
(
!
entered
)
if
(
!
entered
)
return
false
;
return
false
;
}
}
...
@@ -1464,10 +1487,11 @@ static bool cgv2_enter(const char *cgroup)
...
@@ -1464,10 +1487,11 @@ static bool cgv2_enter(const char *cgroup)
return
true
;
return
true
;
path
=
must_make_path
(
v2
->
mountpoint
,
v2
->
base_cgroup
,
cgroup
,
"/cgroup.procs"
,
NULL
);
path
=
must_make_path
(
v2
->
mountpoint
,
v2
->
base_cgroup
,
cgroup
,
"/cgroup.procs"
,
NULL
);
pam_cgfs_debug
(
"Attempting to enter cgroupfs v2 hierarchy in cgroup
\"
%s
\"
.
\n
"
,
path
);
pam_cgfs_debug
(
"Attempting to enter cgroupfs v2 hierarchy in cgroup
\"
%s
\"\n
"
,
path
);
entered
=
write_int
(
path
,
(
int
)
getpid
());
entered
=
write_int
(
path
,
(
int
)
getpid
());
if
(
!
entered
)
{
if
(
!
entered
)
{
pam_cgfs_debug
(
"Failed to enter cgroupfs v2 hierarchy in cgroup
\"
%s
\"
.
\n
"
,
path
);
pam_cgfs_debug
(
"Failed to enter cgroupfs v2 hierarchy in cgroup
\"
%s
\"\n
"
,
path
);
free
(
path
);
free
(
path
);
return
false
;
return
false
;
}
}
...
@@ -1481,12 +1505,12 @@ static bool cgv2_enter(const char *cgroup)
...
@@ -1481,12 +1505,12 @@ static bool cgv2_enter(const char *cgroup)
static
bool
cg_enter
(
const
char
*
cgroup
)
static
bool
cg_enter
(
const
char
*
cgroup
)
{
{
if
(
!
cgv1_enter
(
cgroup
))
{
if
(
!
cgv1_enter
(
cgroup
))
{
mysyslog
(
LOG_WARNING
,
"cgroupfs v1: Failed to enter cgroups
.
\n
"
,
NULL
);
mysyslog
(
LOG_WARNING
,
"cgroupfs v1: Failed to enter cgroups
\n
"
,
NULL
);
return
false
;
return
false
;
}
}
if
(
!
cgv2_enter
(
cgroup
))
{
if
(
!
cgv2_enter
(
cgroup
))
{
mysyslog
(
LOG_WARNING
,
"cgroupfs v2: Failed to enter cgroups
.
\n
"
,
NULL
);
mysyslog
(
LOG_WARNING
,
"cgroupfs v2: Failed to enter cgroups
\n
"
,
NULL
);
return
false
;
return
false
;
}
}
...
@@ -1505,17 +1529,17 @@ static void cgv1_escape(void)
...
@@ -1505,17 +1529,17 @@ static void cgv1_escape(void)
*/
*/
for
(
it
=
cgv1_hierarchies
;
it
&&
*
it
;
it
++
)
for
(
it
=
cgv1_hierarchies
;
it
&&
*
it
;
it
++
)
if
(
!
cgv1_handle_root_cpuset_hierarchy
(
*
it
))
if
(
!
cgv1_handle_root_cpuset_hierarchy
(
*
it
))
mysyslog
(
LOG_WARNING
,
"cgroupfs v1: Failed to initialize cpuset
.
\n
"
,
NULL
);
mysyslog
(
LOG_WARNING
,
"cgroupfs v1: Failed to initialize cpuset
\n
"
,
NULL
);
if
(
!
cgv1_enter
(
"/"
))
if
(
!
cgv1_enter
(
"/"
))
mysyslog
(
LOG_WARNING
,
"cgroupfs v1: Failed to escape to init's cgroup
.
\n
"
,
NULL
);
mysyslog
(
LOG_WARNING
,
"cgroupfs v1: Failed to escape to init's cgroup
\n
"
,
NULL
);
}
}
/* Escape to root cgroup in the cgroupfs v2 hierarchy. */
/* Escape to root cgroup in the cgroupfs v2 hierarchy. */
static
void
cgv2_escape
(
void
)
static
void
cgv2_escape
(
void
)
{
{
if
(
!
cgv2_enter
(
"/"
))
if
(
!
cgv2_enter
(
"/"
))
mysyslog
(
LOG_WARNING
,
"cgroupfs v2: Failed to escape to init's cgroup
.
\n
"
,
NULL
);
mysyslog
(
LOG_WARNING
,
"cgroupfs v2: Failed to escape to init's cgroup
\n
"
,
NULL
);
}
}
/* Wrapper around cgv{1,2}_escape(). */
/* Wrapper around cgv{1,2}_escape(). */
...
@@ -1546,7 +1570,7 @@ static bool get_uid_gid(const char *user, uid_t *uid, gid_t *gid)
...
@@ -1546,7 +1570,7 @@ static bool get_uid_gid(const char *user, uid_t *uid, gid_t *gid)
if
(
!
pwentp
)
{
if
(
!
pwentp
)
{
if
(
ret
==
0
)
if
(
ret
==
0
)
mysyslog
(
LOG_ERR
,
mysyslog
(
LOG_ERR
,
"Could not find matched password record
\n
"
,
NULL
);
"Could not find matched password record
\n
"
,
NULL
);
free
(
buf
);
free
(
buf
);
return
false
;
return
false
;
...
@@ -1598,6 +1622,7 @@ static uint32_t *cg_cpumask(char *buf, size_t nbits)
...
@@ -1598,6 +1622,7 @@ static uint32_t *cg_cpumask(char *buf, size_t nbits)
char
*
range
=
strchr
(
token
,
'-'
);
char
*
range
=
strchr
(
token
,
'-'
);
if
(
range
)
if
(
range
)
end
=
strtoul
(
range
+
1
,
NULL
,
0
);
end
=
strtoul
(
range
+
1
,
NULL
,
0
);
if
(
!
(
start
<=
end
))
{
if
(
!
(
start
<=
end
))
{
free
(
bitarr
);
free
(
bitarr
);
return
NULL
;
return
NULL
;
...
@@ -1641,6 +1666,7 @@ static char *string_join(const char *sep, const char **parts, bool use_as_prefix
...
@@ -1641,6 +1666,7 @@ static char *string_join(const char *sep, const char **parts, bool use_as_prefix
for
(
p
=
(
char
**
)
parts
;
*
p
;
p
++
)
{
for
(
p
=
(
char
**
)
parts
;
*
p
;
p
++
)
{
if
(
p
>
(
char
**
)
parts
)
if
(
p
>
(
char
**
)
parts
)
(
void
)
strlcat
(
result
,
sep
,
buf_len
*
sizeof
(
char
));
(
void
)
strlcat
(
result
,
sep
,
buf_len
*
sizeof
(
char
));
(
void
)
strlcat
(
result
,
*
p
,
buf_len
*
sizeof
(
char
));
(
void
)
strlcat
(
result
,
*
p
,
buf_len
*
sizeof
(
char
));
}
}
...
@@ -1666,9 +1692,11 @@ static char *cg_cpumask_to_cpulist(uint32_t *bitarr, size_t nbits)
...
@@ -1666,9 +1692,11 @@ static char *cg_cpumask_to_cpulist(uint32_t *bitarr, size_t nbits)
free_string_list
(
cpulist
);
free_string_list
(
cpulist
);
return
NULL
;
return
NULL
;
}
}
must_append_string
(
&
cpulist
,
numstr
);
must_append_string
(
&
cpulist
,
numstr
);
}
}
}
}
return
string_join
(
","
,
(
const
char
**
)
cpulist
,
false
);
return
string_join
(
","
,
(
const
char
**
)
cpulist
,
false
);
}
}
...
@@ -1691,10 +1719,12 @@ static ssize_t cg_get_max_cpus(char *cpulist)
...
@@ -1691,10 +1719,12 @@ static ssize_t cg_get_max_cpus(char *cpulist)
else
if
(
c1
<
c2
)
else
if
(
c1
<
c2
)
c1
=
c2
;
c1
=
c2
;
if
(
!
c1
)
return
-
1
;
/* If the above logic is correct, c1 should always hold a valid string
/* If the above logic is correct, c1 should always hold a valid string
* here.
* here.
*/
*/
errno
=
0
;
errno
=
0
;
cpus
=
strtoul
(
c1
,
NULL
,
0
);
cpus
=
strtoul
(
c1
,
NULL
,
0
);
if
(
errno
!=
0
)
if
(
errno
!=
0
)
...
@@ -1706,10 +1736,12 @@ static ssize_t cg_get_max_cpus(char *cpulist)
...
@@ -1706,10 +1736,12 @@ static ssize_t cg_get_max_cpus(char *cpulist)
static
ssize_t
write_nointr
(
int
fd
,
const
void
*
buf
,
size_t
count
)
static
ssize_t
write_nointr
(
int
fd
,
const
void
*
buf
,
size_t
count
)
{
{
ssize_t
ret
;
ssize_t
ret
;
again:
again:
ret
=
write
(
fd
,
buf
,
count
);
ret
=
write
(
fd
,
buf
,
count
);
if
(
ret
<
0
&&
errno
==
EINTR
)
if
(
ret
<
0
&&
errno
==
EINTR
)
goto
again
;
goto
again
;
return
ret
;
return
ret
;
}
}
...
@@ -1721,16 +1753,19 @@ static int write_to_file(const char *filename, const void* buf, size_t count, bo
...
@@ -1721,16 +1753,19 @@ static int write_to_file(const char *filename, const void* buf, size_t count, bo
fd
=
open
(
filename
,
O_WRONLY
|
O_TRUNC
|
O_CREAT
|
O_CLOEXEC
,
0666
);
fd
=
open
(
filename
,
O_WRONLY
|
O_TRUNC
|
O_CREAT
|
O_CLOEXEC
,
0666
);
if
(
fd
<
0
)
if
(
fd
<
0
)
return
-
1
;
return
-
1
;
ret
=
write_nointr
(
fd
,
buf
,
count
);
ret
=
write_nointr
(
fd
,
buf
,
count
);
if
(
ret
<
0
)
if
(
ret
<
0
)
goto
out_error
;
goto
out_error
;
if
((
size_t
)
ret
!=
count
)
if
((
size_t
)
ret
!=
count
)
goto
out_error
;
goto
out_error
;
if
(
add_newline
)
{
if
(
add_newline
)
{
ret
=
write_nointr
(
fd
,
"
\n
"
,
1
);
ret
=
write_nointr
(
fd
,
"
\n
"
,
1
);
if
(
ret
!=
1
)
if
(
ret
!=
1
)
goto
out_error
;
goto
out_error
;
}
}
close
(
fd
);
close
(
fd
);
return
0
;
return
0
;
...
@@ -1755,15 +1790,17 @@ static bool cg_filter_and_set_cpus(char *path, bool am_initialized)
...
@@ -1755,15 +1790,17 @@ static bool cg_filter_and_set_cpus(char *path, bool am_initialized)
lastslash
=
strrchr
(
path
,
'/'
);
lastslash
=
strrchr
(
path
,
'/'
);
if
(
!
lastslash
)
{
// bug... this shouldn't be possible
if
(
!
lastslash
)
{
// bug... this shouldn't be possible
pam_cgfs_debug
(
"Invalid path: %s
.
\n
"
,
path
);
pam_cgfs_debug
(
"Invalid path: %s
\n
"
,
path
);
return
bret
;
return
bret
;
}
}
oldv
=
*
lastslash
;
oldv
=
*
lastslash
;
*
lastslash
=
'\0'
;
*
lastslash
=
'\0'
;
fpath
=
must_make_path
(
path
,
"cpuset.cpus"
,
NULL
);
fpath
=
must_make_path
(
path
,
"cpuset.cpus"
,
NULL
);
posscpus
=
read_file
(
fpath
);
posscpus
=
read_file
(
fpath
);
if
(
!
posscpus
)
{
if
(
!
posscpus
)
{
pam_cgfs_debug
(
"Could not read file: %s
.
\n
"
,
fpath
);
pam_cgfs_debug
(
"Could not read file: %s
\n
"
,
fpath
);
goto
on_error
;
goto
on_error
;
}
}
...
@@ -1774,16 +1811,18 @@ static bool cg_filter_and_set_cpus(char *path, bool am_initialized)
...
@@ -1774,16 +1811,18 @@ static bool cg_filter_and_set_cpus(char *path, bool am_initialized)
if
(
!
file_exists
(
__ISOL_CPUS
))
{
if
(
!
file_exists
(
__ISOL_CPUS
))
{
/* This system doesn't expose isolated cpus. */
/* This system doesn't expose isolated cpus. */
pam_cgfs_debug
(
"%s"
,
"Path: "
__ISOL_CPUS
" to read isolated cpus from does not exist
.
\n
"
);
pam_cgfs_debug
(
"%s"
,
"Path: "
__ISOL_CPUS
" to read isolated cpus from does not exist
\n
"
);
cpulist
=
posscpus
;
cpulist
=
posscpus
;
/* No isolated cpus but we weren't already initialized by
/* No isolated cpus but we weren't already initialized by
* someone. We should simply copy the parents cpuset.cpus
* someone. We should simply copy the parents cpuset.cpus
* values.
* values.
*/
*/
if
(
!
am_initialized
)
{
if
(
!
am_initialized
)
{
pam_cgfs_debug
(
"%s"
,
"Copying cpuset of parent cgroup
.
\n
"
);
pam_cgfs_debug
(
"%s"
,
"Copying cpuset of parent cgroup
\n
"
);
goto
copy_parent
;
goto
copy_parent
;
}
}
/* No isolated cpus but we were already initialized by someone.
/* No isolated cpus but we were already initialized by someone.
* Nothing more to do for us.
* Nothing more to do for us.
*/
*/
...
@@ -1795,17 +1834,20 @@ static bool cg_filter_and_set_cpus(char *path, bool am_initialized)
...
@@ -1795,17 +1834,20 @@ static bool cg_filter_and_set_cpus(char *path, bool am_initialized)
pam_cgfs_debug
(
"%s"
,
"Could not read file "
__ISOL_CPUS
"
\n
"
);
pam_cgfs_debug
(
"%s"
,
"Could not read file "
__ISOL_CPUS
"
\n
"
);
goto
on_error
;
goto
on_error
;
}
}
if
(
!
isdigit
(
isolcpus
[
0
]))
{
if
(
!
isdigit
(
isolcpus
[
0
]))
{
pam_cgfs_debug
(
"%s"
,
"No isolated cpus detected
.
\n
"
);
pam_cgfs_debug
(
"%s"
,
"No isolated cpus detected
\n
"
);
cpulist
=
posscpus
;
cpulist
=
posscpus
;
/* No isolated cpus but we weren't already initialized by
/* No isolated cpus but we weren't already initialized by
* someone. We should simply copy the parents cpuset.cpus
* someone. We should simply copy the parents cpuset.cpus
* values.
* values.
*/
*/
if
(
!
am_initialized
)
{
if
(
!
am_initialized
)
{
pam_cgfs_debug
(
"%s"
,
"Copying cpuset of parent cgroup
.
\n
"
);
pam_cgfs_debug
(
"%s"
,
"Copying cpuset of parent cgroup
\n
"
);
goto
copy_parent
;
goto
copy_parent
;
}
}
/* No isolated cpus but we were already initialized by someone.
/* No isolated cpus but we were already initialized by someone.
* Nothing more to do for us.
* Nothing more to do for us.
*/
*/
...
@@ -1823,13 +1865,13 @@ static bool cg_filter_and_set_cpus(char *path, bool am_initialized)
...
@@ -1823,13 +1865,13 @@ static bool cg_filter_and_set_cpus(char *path, bool am_initialized)
possmask
=
cg_cpumask
(
posscpus
,
maxposs
);
possmask
=
cg_cpumask
(
posscpus
,
maxposs
);
if
(
!
possmask
)
{
if
(
!
possmask
)
{
pam_cgfs_debug
(
"%s"
,
"Could not create cpumask for all possible cpus
.
\n
"
);
pam_cgfs_debug
(
"%s"
,
"Could not create cpumask for all possible cpus
\n
"
);
goto
on_error
;
goto
on_error
;
}
}
isolmask
=
cg_cpumask
(
isolcpus
,
maxposs
);
isolmask
=
cg_cpumask
(
isolcpus
,
maxposs
);
if
(
!
isolmask
)
{
if
(
!
isolmask
)
{
pam_cgfs_debug
(
"%s"
,
"Could not create cpumask for all isolated cpus
.
\n
"
);
pam_cgfs_debug
(
"%s"
,
"Could not create cpumask for all isolated cpus
\n
"
);
goto
on_error
;
goto
on_error
;
}
}
...
@@ -1841,23 +1883,27 @@ static bool cg_filter_and_set_cpus(char *path, bool am_initialized)
...
@@ -1841,23 +1883,27 @@ static bool cg_filter_and_set_cpus(char *path, bool am_initialized)
}
}
if
(
!
flipped_bit
)
{
if
(
!
flipped_bit
)
{
pam_cgfs_debug
(
"%s"
,
"No isolated cpus present in cpuset
.
\n
"
);
pam_cgfs_debug
(
"%s"
,
"No isolated cpus present in cpuset
\n
"
);
goto
on_success
;
goto
on_success
;
}
}
pam_cgfs_debug
(
"%s"
,
"Removed isolated cpus from cpuset
.
\n
"
);
pam_cgfs_debug
(
"%s"
,
"Removed isolated cpus from cpuset
\n
"
);
cpulist
=
cg_cpumask_to_cpulist
(
possmask
,
maxposs
);
cpulist
=
cg_cpumask_to_cpulist
(
possmask
,
maxposs
);
if
(
!
cpulist
)
{
if
(
!
cpulist
)
{
pam_cgfs_debug
(
"%s"
,
"Could not create cpu list
.
\n
"
);
pam_cgfs_debug
(
"%s"
,
"Could not create cpu list
\n
"
);
goto
on_error
;
goto
on_error
;
}
}
copy_parent:
copy_parent:
*
lastslash
=
oldv
;
*
lastslash
=
oldv
;
if
(
fpath
)
free
(
fpath
);
fpath
=
must_make_path
(
path
,
"cpuset.cpus"
,
NULL
);
fpath
=
must_make_path
(
path
,
"cpuset.cpus"
,
NULL
);
ret
=
write_to_file
(
fpath
,
cpulist
,
strlen
(
cpulist
),
false
);
ret
=
write_to_file
(
fpath
,
cpulist
,
strlen
(
cpulist
),
false
);
if
(
ret
<
0
)
{
if
(
ret
<
0
)
{
pam_cgfs_debug
(
"Could not write cpu list to: %s
.
\n
"
,
fpath
);
pam_cgfs_debug
(
"Could not write cpu list to: %s
\n
"
,
fpath
);
goto
on_error
;
goto
on_error
;
}
}
...
@@ -1865,8 +1911,9 @@ on_success:
...
@@ -1865,8 +1911,9 @@ on_success:
bret
=
true
;
bret
=
true
;
on_error:
on_error:
free
(
fpath
)
;
*
lastslash
=
oldv
;
free
(
fpath
);
free
(
isolcpus
);
free
(
isolcpus
);
free
(
isolmask
);
free
(
isolmask
);
...
@@ -1890,6 +1937,7 @@ int read_from_file(const char *filename, void* buf, size_t count)
...
@@ -1890,6 +1937,7 @@ int read_from_file(const char *filename, void* buf, size_t count)
if
(
!
buf
||
!
count
)
{
if
(
!
buf
||
!
count
)
{
char
buf2
[
100
];
char
buf2
[
100
];
size_t
count2
=
0
;
size_t
count2
=
0
;
while
((
ret
=
read
(
fd
,
buf2
,
100
))
>
0
)
while
((
ret
=
read
(
fd
,
buf2
,
100
))
>
0
)
count2
+=
ret
;
count2
+=
ret
;
if
(
ret
>=
0
)
if
(
ret
>=
0
)
...
@@ -1920,21 +1968,27 @@ static bool cg_copy_parent_file(char *path, char *file)
...
@@ -1920,21 +1968,27 @@ static bool cg_copy_parent_file(char *path, char *file)
pam_cgfs_debug
(
"cgfsng:copy_parent_file: bad path %s"
,
path
);
pam_cgfs_debug
(
"cgfsng:copy_parent_file: bad path %s"
,
path
);
return
false
;
return
false
;
}
}
oldv
=
*
lastslash
;
oldv
=
*
lastslash
;
*
lastslash
=
'\0'
;
*
lastslash
=
'\0'
;
fpath
=
must_make_path
(
path
,
file
,
NULL
);
fpath
=
must_make_path
(
path
,
file
,
NULL
);
len
=
read_from_file
(
fpath
,
NULL
,
0
);
len
=
read_from_file
(
fpath
,
NULL
,
0
);
if
(
len
<=
0
)
if
(
len
<=
0
)
goto
bad
;
goto
bad
;
value
=
must_alloc
(
len
+
1
);
value
=
must_alloc
(
len
+
1
);
if
(
read_from_file
(
fpath
,
value
,
len
)
!=
len
)
if
(
read_from_file
(
fpath
,
value
,
len
)
!=
len
)
goto
bad
;
goto
bad
;
free
(
fpath
);
free
(
fpath
);
*
lastslash
=
oldv
;
*
lastslash
=
oldv
;
fpath
=
must_make_path
(
path
,
file
,
NULL
);
fpath
=
must_make_path
(
path
,
file
,
NULL
);
ret
=
write_to_file
(
fpath
,
value
,
len
,
false
);
ret
=
write_to_file
(
fpath
,
value
,
len
,
false
);
if
(
ret
<
0
)
if
(
ret
<
0
)
pam_cgfs_debug
(
"Unable to write %s to %s"
,
value
,
fpath
);
pam_cgfs_debug
(
"Unable to write %s to %s"
,
value
,
fpath
);
free
(
fpath
);
free
(
fpath
);
free
(
value
);
free
(
value
);
return
ret
>=
0
;
return
ret
>=
0
;
...
@@ -1977,6 +2031,7 @@ static bool cgv1_handle_root_cpuset_hierarchy(struct cgv1_hierarchy *h)
...
@@ -1977,6 +2031,7 @@ static bool cgv1_handle_root_cpuset_hierarchy(struct cgv1_hierarchy *h)
free
(
clonechildrenpath
);
free
(
clonechildrenpath
);
return
false
;
return
false
;
}
}
free
(
clonechildrenpath
);
free
(
clonechildrenpath
);
return
true
;
return
true
;
}
}
...
@@ -2004,17 +2059,20 @@ static bool cgv1_handle_cpuset_hierarchy(struct cgv1_hierarchy *h,
...
@@ -2004,17 +2059,20 @@ static bool cgv1_handle_cpuset_hierarchy(struct cgv1_hierarchy *h,
cgpath
=
must_make_path
(
h
->
mountpoint
,
h
->
base_cgroup
,
cgroup
,
NULL
);
cgpath
=
must_make_path
(
h
->
mountpoint
,
h
->
base_cgroup
,
cgroup
,
NULL
);
if
(
slash
)
if
(
slash
)
*
slash
=
'/'
;
*
slash
=
'/'
;
if
(
do_mkdir
(
cgpath
,
0755
)
<
0
&&
errno
!=
EEXIST
)
{
if
(
do_mkdir
(
cgpath
,
0755
)
<
0
&&
errno
!=
EEXIST
)
{
pam_cgfs_debug
(
"Failed to create '%s'"
,
cgpath
);
pam_cgfs_debug
(
"Failed to create '%s'"
,
cgpath
);
free
(
cgpath
);
free
(
cgpath
);
return
false
;
return
false
;
}
}
clonechildrenpath
=
must_make_path
(
cgpath
,
"cgroup.clone_children"
,
NULL
);
clonechildrenpath
=
must_make_path
(
cgpath
,
"cgroup.clone_children"
,
NULL
);
if
(
!
file_exists
(
clonechildrenpath
))
{
/* unified hierarchy doesn't have clone_children */
if
(
!
file_exists
(
clonechildrenpath
))
{
/* unified hierarchy doesn't have clone_children */
free
(
clonechildrenpath
);
free
(
clonechildrenpath
);
free
(
cgpath
);
free
(
cgpath
);
return
true
;
return
true
;
}
}
if
(
read_from_file
(
clonechildrenpath
,
&
v
,
1
)
<
0
)
{
if
(
read_from_file
(
clonechildrenpath
,
&
v
,
1
)
<
0
)
{
pam_cgfs_debug
(
"Failed to read '%s'"
,
clonechildrenpath
);
pam_cgfs_debug
(
"Failed to read '%s'"
,
clonechildrenpath
);
free
(
clonechildrenpath
);
free
(
clonechildrenpath
);
...
@@ -2024,14 +2082,14 @@ static bool cgv1_handle_cpuset_hierarchy(struct cgv1_hierarchy *h,
...
@@ -2024,14 +2082,14 @@ static bool cgv1_handle_cpuset_hierarchy(struct cgv1_hierarchy *h,
/* Make sure any isolated cpus are removed from cpuset.cpus. */
/* Make sure any isolated cpus are removed from cpuset.cpus. */
if
(
!
cg_filter_and_set_cpus
(
cgpath
,
v
==
'1'
))
{
if
(
!
cg_filter_and_set_cpus
(
cgpath
,
v
==
'1'
))
{
pam_cgfs_debug
(
"%s"
,
"Failed to remove isolated cpus
.
\n
"
);
pam_cgfs_debug
(
"%s"
,
"Failed to remove isolated cpus
\n
"
);
free
(
clonechildrenpath
);
free
(
clonechildrenpath
);
free
(
cgpath
);
free
(
cgpath
);
return
false
;
return
false
;
}
}
if
(
v
==
'1'
)
{
/* already set for us by someone else */
if
(
v
==
'1'
)
{
/* already set for us by someone else */
pam_cgfs_debug
(
"%s"
,
"
\"
cgroup.clone_children
\"
was already set to
\"
1
\"
.
\n
"
);
pam_cgfs_debug
(
"%s"
,
"
\"
cgroup.clone_children
\"
was already set to
\"
1
\"\n
"
);
free
(
clonechildrenpath
);
free
(
clonechildrenpath
);
free
(
cgpath
);
free
(
cgpath
);
return
true
;
return
true
;
...
@@ -2039,7 +2097,7 @@ static bool cgv1_handle_cpuset_hierarchy(struct cgv1_hierarchy *h,
...
@@ -2039,7 +2097,7 @@ static bool cgv1_handle_cpuset_hierarchy(struct cgv1_hierarchy *h,
/* copy parent's settings */
/* copy parent's settings */
if
(
!
cg_copy_parent_file
(
cgpath
,
"cpuset.mems"
))
{
if
(
!
cg_copy_parent_file
(
cgpath
,
"cpuset.mems"
))
{
pam_cgfs_debug
(
"%s"
,
"Failed to copy
\"
cpuset.mems
\"
settings
.
\n
"
);
pam_cgfs_debug
(
"%s"
,
"Failed to copy
\"
cpuset.mems
\"
settings
\n
"
);
free
(
cgpath
);
free
(
cgpath
);
free
(
clonechildrenpath
);
free
(
clonechildrenpath
);
return
false
;
return
false
;
...
@@ -2072,6 +2130,7 @@ static bool cgv1_create_one(struct cgv1_hierarchy *h, const char *cgroup, uid_t
...
@@ -2072,6 +2130,7 @@ static bool cgv1_create_one(struct cgv1_hierarchy *h, const char *cgroup, uid_t
*
existed
=
false
;
*
existed
=
false
;
it
=
h
;
it
=
h
;
for
(
controller
=
it
->
controllers
;
controller
&&
*
controller
;
for
(
controller
=
it
->
controllers
;
controller
&&
*
controller
;
controller
++
)
{
controller
++
)
{
if
(
!
cgv1_handle_cpuset_hierarchy
(
it
,
cgroup
))
if
(
!
cgv1_handle_cpuset_hierarchy
(
it
,
cgroup
))
...
@@ -2082,9 +2141,8 @@ static bool cgv1_create_one(struct cgv1_hierarchy *h, const char *cgroup, uid_t
...
@@ -2082,9 +2141,8 @@ static bool cgv1_create_one(struct cgv1_hierarchy *h, const char *cgroup, uid_t
*/
*/
if
(
cg_systemd_chown_existing_cgroup
(
it
->
mountpoint
,
if
(
cg_systemd_chown_existing_cgroup
(
it
->
mountpoint
,
it
->
base_cgroup
,
uid
,
gid
,
it
->
base_cgroup
,
uid
,
gid
,
it
->
systemd_user_slice
))
{
it
->
systemd_user_slice
))
return
true
;
return
true
;
}
/* We need to make sure that we do not create an endless chain
/* We need to make sure that we do not create an endless chain
* of sub-cgroups. So we check if we have already logged in
* of sub-cgroups. So we check if we have already logged in
...
@@ -2106,27 +2164,34 @@ static bool cgv1_create_one(struct cgv1_hierarchy *h, const char *cgroup, uid_t
...
@@ -2106,27 +2164,34 @@ static bool cgv1_create_one(struct cgv1_hierarchy *h, const char *cgroup, uid_t
}
}
path
=
must_make_path
(
it
->
mountpoint
,
it
->
init_cgroup
,
cgroup
,
NULL
);
path
=
must_make_path
(
it
->
mountpoint
,
it
->
init_cgroup
,
cgroup
,
NULL
);
pam_cgfs_debug
(
"Constructing path: %s.
\n
"
,
path
);
pam_cgfs_debug
(
"Constructing path: %s
\n
"
,
path
);
if
(
file_exists
(
path
))
{
if
(
file_exists
(
path
))
{
bool
our_cg
=
cg_belongs_to_uid_gid
(
path
,
uid
,
gid
);
bool
our_cg
=
cg_belongs_to_uid_gid
(
path
,
uid
,
gid
);
pam_cgfs_debug
(
"%s existed and does %shave our uid: %d and gid: %d.
\n
"
,
path
,
our_cg
?
""
:
"not "
,
uid
,
gid
);
free
(
path
);
if
(
our_cg
)
if
(
our_cg
)
*
existed
=
false
;
*
existed
=
false
;
else
else
*
existed
=
true
;
*
existed
=
true
;
pam_cgfs_debug
(
"%s existed and does %shave our uid: %d and gid: %d
\n
"
,
path
,
our_cg
?
""
:
"not "
,
uid
,
gid
);
free
(
path
);
return
our_cg
;
return
our_cg
;
}
}
created
=
mkdir_parent
(
it
->
mountpoint
,
path
);
created
=
mkdir_parent
(
it
->
mountpoint
,
path
);
if
(
!
created
)
{
if
(
!
created
)
{
free
(
path
);
free
(
path
);
continue
;
continue
;
}
}
if
(
chown
(
path
,
uid
,
gid
)
<
0
)
if
(
chown
(
path
,
uid
,
gid
)
<
0
)
mysyslog
(
LOG_WARNING
,
mysyslog
(
LOG_WARNING
,
"Failed to chown %s to %d:%d: %s.
\n
"
,
path
,
"Failed to chown %s to %d:%d: %s
\n
"
,
path
,
(
int
)
uid
,
(
int
)
gid
,
strerror
(
errno
),
NULL
);
(
int
)
uid
,
(
int
)
gid
,
strerror
(
errno
),
NULL
);
pam_cgfs_debug
(
"Chowned %s to %d:%d.
\n
"
,
path
,
(
int
)
uid
,
(
int
)
gid
);
pam_cgfs_debug
(
"Chowned %s to %d:%d
\n
"
,
path
,
(
int
)
uid
,
(
int
)
gid
);
free
(
path
);
free
(
path
);
break
;
break
;
}
}
...
@@ -2255,12 +2320,12 @@ static bool cgv2_create(const char *cgroup, uid_t uid, gid_t gid, bool *existed)
...
@@ -2255,12 +2320,12 @@ static bool cgv2_create(const char *cgroup, uid_t uid, gid_t gid, bool *existed)
}
}
path
=
must_make_path
(
v2
->
mountpoint
,
v2
->
base_cgroup
,
cgroup
,
NULL
);
path
=
must_make_path
(
v2
->
mountpoint
,
v2
->
base_cgroup
,
cgroup
,
NULL
);
pam_cgfs_debug
(
"Constructing path
\"
%s
\"
.
\n
"
,
path
);
pam_cgfs_debug
(
"Constructing path
\"
%s
\"\n
"
,
path
);
if
(
file_exists
(
path
))
{
if
(
file_exists
(
path
))
{
our_cg
=
cg_belongs_to_uid_gid
(
path
,
uid
,
gid
);
our_cg
=
cg_belongs_to_uid_gid
(
path
,
uid
,
gid
);
pam_cgfs_debug
(
pam_cgfs_debug
(
"%s existed and does %shave our uid: %d and gid: %d
\n
"
,
"%s existed and does %shave our uid: %d and gid: %d.
\n
"
,
path
,
our_cg
?
""
:
"not "
,
uid
,
gid
);
path
,
our_cg
?
""
:
"not "
,
uid
,
gid
);
free
(
path
);
free
(
path
);
if
(
our_cg
)
{
if
(
our_cg
)
{
*
existed
=
false
;
*
existed
=
false
;
...
@@ -2279,10 +2344,10 @@ static bool cgv2_create(const char *cgroup, uid_t uid, gid_t gid, bool *existed)
...
@@ -2279,10 +2344,10 @@ static bool cgv2_create(const char *cgroup, uid_t uid, gid_t gid, bool *existed)
/* chown cgroup to user */
/* chown cgroup to user */
if
(
chown
(
path
,
uid
,
gid
)
<
0
)
if
(
chown
(
path
,
uid
,
gid
)
<
0
)
mysyslog
(
LOG_WARNING
,
"Failed to chown %s to %d:%d: %s
.
\n
"
,
mysyslog
(
LOG_WARNING
,
"Failed to chown %s to %d:%d: %s
\n
"
,
path
,
(
int
)
uid
,
(
int
)
gid
,
strerror
(
errno
),
NULL
);
path
,
(
int
)
uid
,
(
int
)
gid
,
strerror
(
errno
),
NULL
);
else
else
pam_cgfs_debug
(
"Chowned %s to %d:%d
.
\n
"
,
path
,
(
int
)
uid
,
(
int
)
gid
);
pam_cgfs_debug
(
"Chowned %s to %d:%d
\n
"
,
path
,
(
int
)
uid
,
(
int
)
gid
);
free
(
path
);
free
(
path
);
delegate_files:
delegate_files:
...
@@ -2293,12 +2358,13 @@ delegate_files:
...
@@ -2293,12 +2358,13 @@ delegate_files:
else
else
path
=
must_make_path
(
v2
->
mountpoint
,
v2
->
base_cgroup
,
cgroup
,
path
=
must_make_path
(
v2
->
mountpoint
,
v2
->
base_cgroup
,
cgroup
,
"/cgroup.procs"
,
NULL
);
"/cgroup.procs"
,
NULL
);
ret
=
chown
(
path
,
uid
,
gid
);
ret
=
chown
(
path
,
uid
,
gid
);
if
(
ret
<
0
)
if
(
ret
<
0
)
mysyslog
(
LOG_WARNING
,
"Failed to chown %s to %d:%d: %s
.
\n
"
,
mysyslog
(
LOG_WARNING
,
"Failed to chown %s to %d:%d: %s
\n
"
,
path
,
(
int
)
uid
,
(
int
)
gid
,
strerror
(
errno
),
NULL
);
path
,
(
int
)
uid
,
(
int
)
gid
,
strerror
(
errno
),
NULL
);
else
else
pam_cgfs_debug
(
"Chowned %s to %d:%d
.
\n
"
,
path
,
(
int
)
uid
,
(
int
)
gid
);
pam_cgfs_debug
(
"Chowned %s to %d:%d
\n
"
,
path
,
(
int
)
uid
,
(
int
)
gid
);
free
(
path
);
free
(
path
);
/* chown cgroup.subtree_control to user */
/* chown cgroup.subtree_control to user */
...
@@ -2308,9 +2374,10 @@ delegate_files:
...
@@ -2308,9 +2374,10 @@ delegate_files:
else
else
path
=
must_make_path
(
v2
->
mountpoint
,
v2
->
base_cgroup
,
cgroup
,
path
=
must_make_path
(
v2
->
mountpoint
,
v2
->
base_cgroup
,
cgroup
,
"/cgroup.subtree_control"
,
NULL
);
"/cgroup.subtree_control"
,
NULL
);
ret
=
chown
(
path
,
uid
,
gid
);
ret
=
chown
(
path
,
uid
,
gid
);
if
(
ret
<
0
)
if
(
ret
<
0
)
mysyslog
(
LOG_WARNING
,
"Failed to chown %s to %d:%d: %s
.
\n
"
,
mysyslog
(
LOG_WARNING
,
"Failed to chown %s to %d:%d: %s
\n
"
,
path
,
(
int
)
uid
,
(
int
)
gid
,
strerror
(
errno
),
NULL
);
path
,
(
int
)
uid
,
(
int
)
gid
,
strerror
(
errno
),
NULL
);
free
(
path
);
free
(
path
);
...
@@ -2323,7 +2390,7 @@ delegate_files:
...
@@ -2323,7 +2390,7 @@ delegate_files:
"/cgroup.threads"
,
NULL
);
"/cgroup.threads"
,
NULL
);
ret
=
chown
(
path
,
uid
,
gid
);
ret
=
chown
(
path
,
uid
,
gid
);
if
(
ret
<
0
&&
errno
!=
ENOENT
)
if
(
ret
<
0
&&
errno
!=
ENOENT
)
mysyslog
(
LOG_WARNING
,
"Failed to chown %s to %d:%d: %s
.
\n
"
,
mysyslog
(
LOG_WARNING
,
"Failed to chown %s to %d:%d: %s
\n
"
,
path
,
(
int
)
uid
,
(
int
)
gid
,
strerror
(
errno
),
NULL
);
path
,
(
int
)
uid
,
(
int
)
gid
,
strerror
(
errno
),
NULL
);
free
(
path
);
free
(
path
);
...
@@ -2344,7 +2411,7 @@ static int handle_login(const char *user, uid_t uid, gid_t gid)
...
@@ -2344,7 +2411,7 @@ static int handle_login(const char *user, uid_t uid, gid_t gid)
while
(
idx
>=
0
)
{
while
(
idx
>=
0
)
{
ret
=
snprintf
(
cg
,
MAXPATHLEN
,
"/user/%s/%d"
,
user
,
idx
);
ret
=
snprintf
(
cg
,
MAXPATHLEN
,
"/user/%s/%d"
,
user
,
idx
);
if
(
ret
<
0
||
ret
>=
MAXPATHLEN
)
{
if
(
ret
<
0
||
ret
>=
MAXPATHLEN
)
{
mysyslog
(
LOG_ERR
,
"Username too long
.
\n
"
,
NULL
);
mysyslog
(
LOG_ERR
,
"Username too long
\n
"
,
NULL
);
return
PAM_SESSION_ERR
;
return
PAM_SESSION_ERR
;
}
}
...
@@ -2355,7 +2422,8 @@ static int handle_login(const char *user, uid_t uid, gid_t gid)
...
@@ -2355,7 +2422,8 @@ static int handle_login(const char *user, uid_t uid, gid_t gid)
idx
++
;
idx
++
;
continue
;
continue
;
}
}
mysyslog
(
LOG_ERR
,
"Failed to create a cgroup for user %s.
\n
"
,
user
,
NULL
);
mysyslog
(
LOG_ERR
,
"Failed to create a cgroup for user %s
\n
"
,
user
,
NULL
);
return
PAM_SESSION_ERR
;
return
PAM_SESSION_ERR
;
}
}
...
@@ -2366,14 +2434,16 @@ static int handle_login(const char *user, uid_t uid, gid_t gid)
...
@@ -2366,14 +2434,16 @@ static int handle_login(const char *user, uid_t uid, gid_t gid)
idx
++
;
idx
++
;
continue
;
continue
;
}
}
mysyslog
(
LOG_ERR
,
"Failed to create a cgroup for user %s.
\n
"
,
user
,
NULL
);
mysyslog
(
LOG_ERR
,
"Failed to create a cgroup for user %s
\n
"
,
user
,
NULL
);
return
PAM_SESSION_ERR
;
return
PAM_SESSION_ERR
;
}
}
if
(
!
cg_enter
(
cg
))
{
if
(
!
cg_enter
(
cg
))
{
mysyslog
(
LOG_ERR
,
"Failed to enter user cgroup %s for user %s
.
\n
"
,
cg
,
user
,
NULL
);
mysyslog
(
LOG_ERR
,
"Failed to enter user cgroup %s for user %s
\n
"
,
cg
,
user
,
NULL
);
return
PAM_SESSION_ERR
;
return
PAM_SESSION_ERR
;
}
}
break
;
break
;
}
}
...
@@ -2403,7 +2473,8 @@ static bool cgv1_prune_empty_cgroups(const char *user)
...
@@ -2403,7 +2473,8 @@ static bool cgv1_prune_empty_cgroups(const char *user)
bool
path_base_rm
,
path_init_rm
;
bool
path_base_rm
,
path_init_rm
;
path_base
=
must_make_path
((
*
it
)
->
mountpoint
,
(
*
it
)
->
base_cgroup
,
"/user"
,
user
,
NULL
);
path_base
=
must_make_path
((
*
it
)
->
mountpoint
,
(
*
it
)
->
base_cgroup
,
"/user"
,
user
,
NULL
);
pam_cgfs_debug
(
"cgroupfs v1: Trying to prune
\"
%s
\"
.
\n
"
,
path_base
);
pam_cgfs_debug
(
"cgroupfs v1: Trying to prune
\"
%s
\"\n
"
,
path_base
);
ret
=
recursive_rmdir
(
path_base
);
ret
=
recursive_rmdir
(
path_base
);
if
(
ret
==
-
ENOENT
||
ret
>=
0
)
if
(
ret
==
-
ENOENT
||
ret
>=
0
)
path_base_rm
=
true
;
path_base_rm
=
true
;
...
@@ -2412,7 +2483,8 @@ static bool cgv1_prune_empty_cgroups(const char *user)
...
@@ -2412,7 +2483,8 @@ static bool cgv1_prune_empty_cgroups(const char *user)
free
(
path_base
);
free
(
path_base
);
path_init
=
must_make_path
((
*
it
)
->
mountpoint
,
(
*
it
)
->
init_cgroup
,
"/user"
,
user
,
NULL
);
path_init
=
must_make_path
((
*
it
)
->
mountpoint
,
(
*
it
)
->
init_cgroup
,
"/user"
,
user
,
NULL
);
pam_cgfs_debug
(
"cgroupfs v1: Trying to prune
\"
%s
\"
.
\n
"
,
path_init
);
pam_cgfs_debug
(
"cgroupfs v1: Trying to prune
\"
%s
\"\n
"
,
path_init
);
ret
=
recursive_rmdir
(
path_init
);
ret
=
recursive_rmdir
(
path_init
);
if
(
ret
==
-
ENOENT
||
ret
>=
0
)
if
(
ret
==
-
ENOENT
||
ret
>=
0
)
path_init_rm
=
true
;
path_init_rm
=
true
;
...
@@ -2428,6 +2500,7 @@ static bool cgv1_prune_empty_cgroups(const char *user)
...
@@ -2428,6 +2500,7 @@ static bool cgv1_prune_empty_cgroups(const char *user)
controller_removed
=
true
;
controller_removed
=
true
;
break
;
break
;
}
}
if
(
!
controller_removed
)
if
(
!
controller_removed
)
all_removed
=
false
;
all_removed
=
false
;
}
}
...
@@ -2451,7 +2524,8 @@ static bool cgv2_prune_empty_cgroups(const char *user)
...
@@ -2451,7 +2524,8 @@ static bool cgv2_prune_empty_cgroups(const char *user)
v2
=
*
cgv2_hierarchies
;
v2
=
*
cgv2_hierarchies
;
path_base
=
must_make_path
(
v2
->
mountpoint
,
v2
->
base_cgroup
,
"/user"
,
user
,
NULL
);
path_base
=
must_make_path
(
v2
->
mountpoint
,
v2
->
base_cgroup
,
"/user"
,
user
,
NULL
);
pam_cgfs_debug
(
"cgroupfs v2: Trying to prune
\"
%s
\"
.
\n
"
,
path_base
);
pam_cgfs_debug
(
"cgroupfs v2: Trying to prune
\"
%s
\"\n
"
,
path_base
);
ret
=
recursive_rmdir
(
path_base
);
ret
=
recursive_rmdir
(
path_base
);
if
(
ret
==
-
ENOENT
||
ret
>=
0
)
if
(
ret
==
-
ENOENT
||
ret
>=
0
)
path_base_rm
=
true
;
path_base_rm
=
true
;
...
@@ -2460,7 +2534,8 @@ static bool cgv2_prune_empty_cgroups(const char *user)
...
@@ -2460,7 +2534,8 @@ static bool cgv2_prune_empty_cgroups(const char *user)
free
(
path_base
);
free
(
path_base
);
path_init
=
must_make_path
(
v2
->
mountpoint
,
v2
->
init_cgroup
,
"/user"
,
user
,
NULL
);
path_init
=
must_make_path
(
v2
->
mountpoint
,
v2
->
init_cgroup
,
"/user"
,
user
,
NULL
);
pam_cgfs_debug
(
"cgroupfs v2: Trying to prune
\"
%s
\"
.
\n
"
,
path_init
);
pam_cgfs_debug
(
"cgroupfs v2: Trying to prune
\"
%s
\"\n
"
,
path_init
);
ret
=
recursive_rmdir
(
path_init
);
ret
=
recursive_rmdir
(
path_init
);
if
(
ret
==
-
ENOENT
||
ret
>=
0
)
if
(
ret
==
-
ENOENT
||
ret
>=
0
)
path_init_rm
=
true
;
path_init_rm
=
true
;
...
@@ -2497,11 +2572,13 @@ static void cgv1_free_hierarchies(void)
...
@@ -2497,11 +2572,13 @@ static void cgv1_free_hierarchies(void)
free
((
*
it
)
->
controllers
);
free
((
*
it
)
->
controllers
);
}
}
free
((
*
it
)
->
mountpoint
);
free
((
*
it
)
->
mountpoint
);
free
((
*
it
)
->
base_cgroup
);
free
((
*
it
)
->
base_cgroup
);
free
((
*
it
)
->
fullcgpath
);
free
((
*
it
)
->
fullcgpath
);
free
((
*
it
)
->
init_cgroup
);
free
((
*
it
)
->
init_cgroup
);
}
}
free
(
cgv1_hierarchies
);
free
(
cgv1_hierarchies
);
}
}
...
@@ -2516,16 +2593,19 @@ static void cgv2_free_hierarchies(void)
...
@@ -2516,16 +2593,19 @@ static void cgv2_free_hierarchies(void)
for
(
it
=
cgv2_hierarchies
;
it
&&
*
it
;
it
++
)
{
for
(
it
=
cgv2_hierarchies
;
it
&&
*
it
;
it
++
)
{
if
((
*
it
)
->
controllers
)
{
if
((
*
it
)
->
controllers
)
{
char
**
tmp
;
char
**
tmp
;
for
(
tmp
=
(
*
it
)
->
controllers
;
tmp
&&
*
tmp
;
tmp
++
)
for
(
tmp
=
(
*
it
)
->
controllers
;
tmp
&&
*
tmp
;
tmp
++
)
free
(
*
tmp
);
free
(
*
tmp
);
free
((
*
it
)
->
controllers
);
free
((
*
it
)
->
controllers
);
}
}
free
((
*
it
)
->
mountpoint
);
free
((
*
it
)
->
mountpoint
);
free
((
*
it
)
->
base_cgroup
);
free
((
*
it
)
->
base_cgroup
);
free
((
*
it
)
->
fullcgpath
);
free
((
*
it
)
->
fullcgpath
);
free
((
*
it
)
->
init_cgroup
);
free
((
*
it
)
->
init_cgroup
);
}
}
free
(
cgv2_hierarchies
);
free
(
cgv2_hierarchies
);
}
}
...
@@ -2551,7 +2631,7 @@ int pam_sm_open_session(pam_handle_t *pamh, int flags, int argc,
...
@@ -2551,7 +2631,7 @@ int pam_sm_open_session(pam_handle_t *pamh, int flags, int argc,
}
}
if
(
!
get_uid_gid
(
PAM_user
,
&
uid
,
&
gid
))
{
if
(
!
get_uid_gid
(
PAM_user
,
&
uid
,
&
gid
))
{
mysyslog
(
LOG_ERR
,
"Failed to get uid and gid for %s
.
\n
"
,
PAM_user
,
NULL
);
mysyslog
(
LOG_ERR
,
"Failed to get uid and gid for %s
\n
"
,
PAM_user
,
NULL
);
return
PAM_SESSION_ERR
;
return
PAM_SESSION_ERR
;
}
}
...
@@ -2576,7 +2656,7 @@ int pam_sm_open_session(pam_handle_t *pamh, int flags, int argc,
...
@@ -2576,7 +2656,7 @@ int pam_sm_open_session(pam_handle_t *pamh, int flags, int argc,
* that simply doesn't make any sense.
* that simply doesn't make any sense.
*/
*/
if
(
string_list_length
(
clist
)
>
1
&&
string_in_list
(
clist
,
"all"
))
{
if
(
string_list_length
(
clist
)
>
1
&&
string_in_list
(
clist
,
"all"
))
{
mysyslog
(
LOG_ERR
,
"Invalid -c option, cannot specify individual controllers alongside 'all'
.
\n
"
,
NULL
);
mysyslog
(
LOG_ERR
,
"Invalid -c option, cannot specify individual controllers alongside 'all'
\n
"
,
NULL
);
free_string_list
(
clist
);
free_string_list
(
clist
);
return
PAM_SESSION_ERR
;
return
PAM_SESSION_ERR
;
}
}
...
@@ -2603,7 +2683,7 @@ int pam_sm_close_session(pam_handle_t *pamh, int flags, int argc,
...
@@ -2603,7 +2683,7 @@ int pam_sm_close_session(pam_handle_t *pamh, int flags, int argc,
}
}
if
(
!
get_uid_gid
(
PAM_user
,
&
uid
,
&
gid
))
{
if
(
!
get_uid_gid
(
PAM_user
,
&
uid
,
&
gid
))
{
mysyslog
(
LOG_ERR
,
"Failed to get uid and gid for %s
.
\n
"
,
PAM_user
,
NULL
);
mysyslog
(
LOG_ERR
,
"Failed to get uid and gid for %s
\n
"
,
PAM_user
,
NULL
);
return
PAM_SESSION_ERR
;
return
PAM_SESSION_ERR
;
}
}
...
@@ -2619,7 +2699,7 @@ int pam_sm_close_session(pam_handle_t *pamh, int flags, int argc,
...
@@ -2619,7 +2699,7 @@ int pam_sm_close_session(pam_handle_t *pamh, int flags, int argc,
* that simply doesn't make any sense.
* that simply doesn't make any sense.
*/
*/
if
(
string_list_length
(
clist
)
>
1
&&
string_in_list
(
clist
,
"all"
))
{
if
(
string_list_length
(
clist
)
>
1
&&
string_in_list
(
clist
,
"all"
))
{
mysyslog
(
LOG_ERR
,
"Invalid -c option, cannot specify individual controllers alongside 'all'
.
\n
"
,
NULL
);
mysyslog
(
LOG_ERR
,
"Invalid -c option, cannot specify individual controllers alongside 'all'
\n
"
,
NULL
);
free_string_list
(
clist
);
free_string_list
(
clist
);
return
PAM_SESSION_ERR
;
return
PAM_SESSION_ERR
;
}
}
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment