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
3043883c
Commit
3043883c
authored
May 11, 2015
by
Henrik Kjölhede
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Added support for user groups in lxc-usernet
Signed-off-by:
Henrik Kjölhede
<
hkjolhede@gmail.com
>
parent
54c23a6a
Show whitespace changes
Inline
Side-by-side
Showing
1 changed file
with
182 additions
and
16 deletions
+182
-16
lxc_user_nic.c
src/lxc/lxc_user_nic.c
+182
-16
No files found.
src/lxc/lxc_user_nic.c
View file @
3043883c
...
@@ -23,6 +23,7 @@
...
@@ -23,6 +23,7 @@
#include <stdbool.h>
#include <stdbool.h>
#include <sys/types.h>
#include <sys/types.h>
#include <pwd.h>
#include <pwd.h>
#include <grp.h>
#include <unistd.h>
#include <unistd.h>
#include <fcntl.h>
#include <fcntl.h>
#include <sys/file.h>
#include <sys/file.h>
...
@@ -96,6 +97,116 @@ static char *get_username(void)
...
@@ -96,6 +97,116 @@ static char *get_username(void)
return
pwd
->
pw_name
;
return
pwd
->
pw_name
;
}
}
static
char
**
get_groupnames
(
void
)
{
int
ngroups
;
gid_t
*
group_ids
;
int
ret
,
i
,
j
;
char
**
group_names
;
struct
group
*
gr
;
ngroups
=
getgroups
(
0
,
NULL
);
group_ids
=
(
gid_t
*
)
malloc
(
sizeof
(
gid_t
)
*
ngroups
);
ret
=
getgroups
(
ngroups
,
group_ids
);
if
(
ret
<
0
)
{
free
(
group_ids
);
fprintf
(
stderr
,
"Failed to get process groups
\n
"
);
return
NULL
;
}
group_names
=
(
char
**
)
malloc
(
sizeof
(
char
*
)
*
(
ngroups
+
1
));
for
(
i
=
0
;
i
<
ngroups
;
i
++
)
{
gr
=
getgrgid
(
group_ids
[
i
]);
if
(
gr
==
NULL
)
{
fprintf
(
stderr
,
"Failed to get group name
\n
"
);
free
(
group_ids
);
for
(
j
=
0
;
j
<
i
;
j
++
)
{
free
(
group_names
[
j
]);
}
free
(
group_names
);
return
NULL
;
}
group_names
[
i
]
=
strdup
(
gr
->
gr_name
);
if
(
group_names
[
i
]
==
NULL
)
{
fprintf
(
stderr
,
"Failed to copy group name: %s"
,
gr
->
gr_name
);
free
(
group_ids
);
for
(
j
=
0
;
j
<
i
;
j
++
)
{
free
(
group_names
[
j
]);
}
free
(
group_names
);
return
NULL
;
}
}
group_names
[
ngroups
]
=
NULL
;
free
(
group_ids
);
return
group_names
;
}
struct
alloted_s
{
char
*
name
;
int
allowed
;
struct
alloted_s
*
next
;
};
static
struct
alloted_s
*
append_alloted
(
struct
alloted_s
**
head
,
char
*
name
,
int
n
)
{
struct
alloted_s
*
cur
,
*
al
;
if
(
head
==
NULL
||
name
==
NULL
)
{
// sanity check. parameters should not be null
return
NULL
;
}
al
=
(
struct
alloted_s
*
)
malloc
(
sizeof
(
struct
alloted_s
));
if
(
al
==
NULL
)
{
// unable to allocate memory to new struct
return
NULL
;
}
al
->
name
=
strdup
(
name
);
al
->
allowed
=
n
;
al
->
next
=
NULL
;
if
(
*
head
==
NULL
)
{
*
head
=
al
;
return
al
;
}
cur
=
*
head
;
while
(
cur
->
next
!=
NULL
)
cur
=
cur
->
next
;
cur
->
next
=
al
;
return
al
;
}
static
void
free_alloted
(
struct
alloted_s
**
head
)
{
struct
alloted_s
*
cur
;
if
(
head
==
NULL
)
{
return
;
}
cur
=
*
head
;
while
(
cur
!=
NULL
)
{
cur
=
cur
->
next
;
free
((
*
head
)
->
name
);
free
(
*
head
);
*
head
=
cur
;
}
}
/* The configuration file consists of lines of the form:
/* The configuration file consists of lines of the form:
*
*
* user type bridge count
* user type bridge count
...
@@ -103,13 +214,15 @@ static char *get_username(void)
...
@@ -103,13 +214,15 @@ static char *get_username(void)
* Return the count entry for the calling user if there is one. Else
* Return the count entry for the calling user if there is one. Else
* return -1.
* return -1.
*/
*/
static
int
get_alloted
(
char
*
me
,
char
*
intype
,
char
*
link
)
static
int
get_alloted
(
char
*
me
,
char
*
intype
,
char
*
link
,
struct
alloted_s
**
alloted
)
{
{
FILE
*
fin
=
fopen
(
LXC_USERNIC_CONF
,
"r"
);
FILE
*
fin
=
fopen
(
LXC_USERNIC_CONF
,
"r"
);
char
*
line
=
NULL
;
char
*
line
=
NULL
;
char
user
[
100
],
type
[
100
],
br
[
100
];
char
user
[
100
],
type
[
100
],
br
[
100
];
size_t
len
=
0
;
size_t
len
=
0
;
int
n
=
-
1
,
ret
;
int
n
,
ret
,
count
=
0
;
char
**
groups
;
char
**
g
;
if
(
!
fin
)
{
if
(
!
fin
)
{
fprintf
(
stderr
,
"Failed to open %s: %s
\n
"
,
LXC_USERNIC_CONF
,
fprintf
(
stderr
,
"Failed to open %s: %s
\n
"
,
LXC_USERNIC_CONF
,
...
@@ -128,13 +241,48 @@ static int get_alloted(char *me, char *intype, char *link)
...
@@ -128,13 +241,48 @@ static int get_alloted(char *me, char *intype, char *link)
continue
;
continue
;
if
(
strcmp
(
link
,
br
)
!=
0
)
if
(
strcmp
(
link
,
br
)
!=
0
)
continue
;
continue
;
free
(
line
);
fclose
(
fin
);
append_alloted
(
alloted
,
me
,
n
);
return
n
;
count
+=
n
;
break
;
// found the user with the appropriate settings, therefore finish the search.
// what to do if there are more than one applicable lines? not specified in the docs.
// since getline is implemented with realloc, we don't need to free line until exiting func.
}
}
// now parse any possible groups specified
groups
=
get_groupnames
();
if
(
groups
!=
NULL
)
{
fseek
(
fin
,
0
,
SEEK_SET
);
while
((
getline
(
&
line
,
&
len
,
fin
))
!=
-
1
)
{
ret
=
sscanf
(
line
,
"%99[^
\t
] %99[^
\t
] %99[^
\t
] %d"
,
user
,
type
,
br
,
&
n
);
if
(
ret
!=
4
)
continue
;
if
(
user
[
0
]
!=
'@'
)
continue
;
if
(
strcmp
(
type
,
intype
)
!=
0
)
continue
;
if
(
strcmp
(
link
,
br
)
!=
0
)
continue
;
for
(
g
=
groups
;
*
g
!=
NULL
;
g
++
)
{
if
(
strcmp
(
user
+
1
,
*
g
)
==
0
)
{
append_alloted
(
alloted
,
user
,
n
);
count
+=
n
;
break
;
}
}
}
for
(
g
=
groups
;
*
g
!=
NULL
;
g
++
)
free
(
*
g
);
free
(
groups
);
}
fclose
(
fin
);
fclose
(
fin
);
free
(
line
);
free
(
line
);
return
-
1
;
return
count
;
}
}
static
char
*
get_eol
(
char
*
s
,
char
*
e
)
static
char
*
get_eol
(
char
*
s
,
char
*
e
)
...
@@ -396,18 +544,23 @@ static int count_entries(char *buf, off_t len, char *me, char *t, char *br)
...
@@ -396,18 +544,23 @@ static int count_entries(char *buf, off_t len, char *me, char *t, char *br)
* The dbfile has lines of the format:
* The dbfile has lines of the format:
* user type bridge nicname
* user type bridge nicname
*/
*/
static
bool
get_nic_if_avail
(
int
fd
,
char
*
me
,
int
pid
,
char
*
intype
,
char
*
br
,
int
allowed
,
char
**
nicname
,
char
**
cnic
)
static
bool
get_nic_if_avail
(
int
fd
,
struct
alloted_s
*
names
,
int
pid
,
char
*
intype
,
char
*
br
,
int
allowed
,
char
**
nicname
,
char
**
cnic
)
{
{
off_t
len
,
slen
;
off_t
len
,
slen
;
struct
stat
sb
;
struct
stat
sb
;
char
*
buf
=
NULL
,
*
newline
;
char
*
buf
=
NULL
,
*
newline
;
int
ret
,
count
=
0
;
int
ret
,
count
=
0
;
char
*
owner
;
struct
alloted_s
*
n
;
cull_entries
(
fd
,
me
,
intype
,
br
);
for
(
n
=
names
;
n
!=
NULL
;
n
=
n
->
next
)
cull_entries
(
fd
,
n
->
name
,
intype
,
br
);
if
(
allowed
==
0
)
if
(
allowed
==
0
)
return
false
;
return
false
;
owner
=
names
->
name
;
if
(
fstat
(
fd
,
&
sb
)
<
0
)
{
if
(
fstat
(
fd
,
&
sb
)
<
0
)
{
fprintf
(
stderr
,
"Failed to fstat: %s
\n
"
,
strerror
(
errno
));
fprintf
(
stderr
,
"Failed to fstat: %s
\n
"
,
strerror
(
errno
));
return
false
;
return
false
;
...
@@ -420,17 +573,27 @@ static bool get_nic_if_avail(int fd, char *me, int pid, char *intype, char *br,
...
@@ -420,17 +573,27 @@ static bool get_nic_if_avail(int fd, char *me, int pid, char *intype, char *br,
return
false
;
return
false
;
}
}
count
=
count_entries
(
buf
,
len
,
me
,
intype
,
br
);
owner
=
NULL
;
if
(
count
>=
allowed
)
for
(
n
=
names
;
n
!=
NULL
;
n
=
n
->
next
)
{
return
false
;
count
=
count_entries
(
buf
,
len
,
n
->
name
,
intype
,
br
);
if
(
count
>=
n
->
allowed
)
continue
;
owner
=
n
->
name
;
break
;
}
}
}
if
(
owner
==
NULL
)
return
false
;
if
(
!
get_new_nicname
(
nicname
,
br
,
pid
,
cnic
))
if
(
!
get_new_nicname
(
nicname
,
br
,
pid
,
cnic
))
return
false
;
return
false
;
/*
me
' ' intype ' ' br ' ' *nicname + '\n' + '\0' */
/*
owner
' ' intype ' ' br ' ' *nicname + '\n' + '\0' */
slen
=
strlen
(
me
)
+
strlen
(
intype
)
+
strlen
(
br
)
+
strlen
(
*
nicname
)
+
5
;
slen
=
strlen
(
owner
)
+
strlen
(
intype
)
+
strlen
(
br
)
+
strlen
(
*
nicname
)
+
5
;
newline
=
alloca
(
slen
);
newline
=
alloca
(
slen
);
ret
=
snprintf
(
newline
,
slen
,
"%s %s %s %s
\n
"
,
me
,
intype
,
br
,
*
nicname
);
ret
=
snprintf
(
newline
,
slen
,
"%s %s %s %s
\n
"
,
owner
,
intype
,
br
,
*
nicname
);
if
(
ret
<
0
||
ret
>=
slen
)
{
if
(
ret
<
0
||
ret
>=
slen
)
{
if
(
lxc_netdev_delete_by_name
(
*
nicname
)
!=
0
)
if
(
lxc_netdev_delete_by_name
(
*
nicname
)
!=
0
)
fprintf
(
stderr
,
"Error unlinking %s!
\n
"
,
*
nicname
);
fprintf
(
stderr
,
"Error unlinking %s!
\n
"
,
*
nicname
);
...
@@ -592,6 +755,7 @@ int main(int argc, char *argv[])
...
@@ -592,6 +755,7 @@ int main(int argc, char *argv[])
char
*
cnic
=
NULL
;
// created nic name in container is returned here.
char
*
cnic
=
NULL
;
// created nic name in container is returned here.
char
*
vethname
=
NULL
;
char
*
vethname
=
NULL
;
int
pid
;
int
pid
;
struct
alloted_s
*
alloted
=
NULL
;
/* set a sane env, because we are setuid-root */
/* set a sane env, because we are setuid-root */
if
(
clearenv
()
<
0
)
{
if
(
clearenv
()
<
0
)
{
...
@@ -635,10 +799,12 @@ int main(int argc, char *argv[])
...
@@ -635,10 +799,12 @@ int main(int argc, char *argv[])
exit
(
1
);
exit
(
1
);
}
}
n
=
get_alloted
(
me
,
argv
[
2
],
argv
[
3
]);
n
=
get_alloted
(
me
,
argv
[
2
],
argv
[
3
]
,
&
alloted
);
if
(
n
>
0
)
if
(
n
>
0
)
gotone
=
get_nic_if_avail
(
fd
,
me
,
pid
,
argv
[
2
],
argv
[
3
],
n
,
&
nicname
,
&
cnic
);
gotone
=
get_nic_if_avail
(
fd
,
alloted
,
pid
,
argv
[
2
],
argv
[
3
],
n
,
&
nicname
,
&
cnic
);
close
(
fd
);
close
(
fd
);
free_alloted
(
&
alloted
);
if
(
!
gotone
)
{
if
(
!
gotone
)
{
fprintf
(
stderr
,
"Quota reached
\n
"
);
fprintf
(
stderr
,
"Quota reached
\n
"
);
exit
(
1
);
exit
(
1
);
...
...
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