]> git.proxmox.com Git - mirror_lxc.git/blob - src/lxc/confile_utils.c
Merge pull request #1609 from brauner/2017-06-01/unit_test_idmap_parser
[mirror_lxc.git] / src / lxc / confile_utils.c
1 /* liblxcapi
2 *
3 * Copyright © 2017 Christian Brauner <christian.brauner@ubuntu.com>.
4 * Copyright © 2017 Canonical Ltd.
5 *
6 * This program is free software; you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License version 2, as
8 * published by the Free Software Foundation.
9 *
10 * This program is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 * GNU General Public License for more details.
14 *
15 * You should have received a copy of the GNU General Public License along
16 * with this program; if not, write to the Free Software Foundation, Inc.,
17 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
18 */
19
20 #include <stdio.h>
21 #include <string.h>
22
23 #include "utils.h"
24
25 int parse_idmaps(const char *idmap, char *type, unsigned long *nsid,
26 unsigned long *hostid, unsigned long *range)
27 {
28 int ret = -1;
29 unsigned long tmp_hostid, tmp_nsid, tmp_range;
30 char tmp_type;
31 char *window, *slide;
32 char *dup = NULL;
33
34 /* Duplicate string. */
35 dup = strdup(idmap);
36 if (!dup)
37 goto on_error;
38
39 /* A prototypical idmap entry would be: "u 1000 1000000 65536" */
40
41 /* align */
42 slide = window = dup;
43 /* skip whitespace */
44 slide += strspn(slide, " \t\r");
45 if (slide != window && *slide == '\0')
46 goto on_error;
47
48 /* Validate type. */
49 if (*slide != 'u' && *slide != 'g')
50 goto on_error;
51 /* Assign type. */
52 tmp_type = *slide;
53
54 /* move beyond type */
55 slide++;
56 /* align */
57 window = slide;
58 /* Validate that only whitespace follows. */
59 slide += strspn(slide, " \t\r");
60 /* There must be whitespace. */
61 if (slide == window)
62 goto on_error;
63
64 /* Mark beginning of nsuid. */
65 window = slide;
66 /* Validate that non-whitespace follows. */
67 slide += strcspn(slide, " \t\r");
68 /* There must be non-whitespace. */
69 if (slide == window || *slide == '\0')
70 goto on_error;
71 /* Mark end of nsuid. */
72 *slide = '\0';
73
74 /* Parse nsuid. */
75 if (lxc_safe_ulong(window, &tmp_nsid) < 0)
76 goto on_error;
77
78 /* Move beyond \0. */
79 slide++;
80 /* align */
81 window = slide;
82 /* Validate that only whitespace follows. */
83 slide += strspn(slide, " \t\r");
84 /* If there was only one whitespace then we whiped it with our \0 above.
85 * So only ensure that we're not at the end of the string.
86 */
87 if (*slide == '\0')
88 goto on_error;
89
90 /* Mark beginning of hostid. */
91 window = slide;
92 /* Validate that non-whitespace follows. */
93 slide += strcspn(slide, " \t\r");
94 /* There must be non-whitespace. */
95 if (slide == window || *slide == '\0')
96 goto on_error;
97 /* Mark end of nsuid. */
98 *slide = '\0';
99
100 /* Parse hostid. */
101 if (lxc_safe_ulong(window, &tmp_hostid) < 0)
102 goto on_error;
103
104 /* Move beyond \0. */
105 slide++;
106 /* align */
107 window = slide;
108 /* Validate that only whitespace follows. */
109 slide += strspn(slide, " \t\r");
110 /* If there was only one whitespace then we whiped it with our \0 above.
111 * So only ensure that we're not at the end of the string.
112 */
113 if (*slide == '\0')
114 goto on_error;
115
116 /* Mark beginning of range. */
117 window = slide;
118 /* Validate that non-whitespace follows. */
119 slide += strcspn(slide, " \t\r");
120 /* There must be non-whitespace. */
121 if (slide == window)
122 goto on_error;
123
124 /* The range is the last valid entry we expect. So make sure that there
125 * is not trailing garbage and if there is, error out.
126 */
127 if (*(slide + strspn(slide, " \t\r\n")) != '\0')
128 goto on_error;
129 /* Mark end of range. */
130 *slide = '\0';
131
132 /* Parse range. */
133 if (lxc_safe_ulong(window, &tmp_range) < 0)
134 goto on_error;
135
136 *type = tmp_type;
137 *nsid = tmp_nsid;
138 *hostid = tmp_hostid;
139 *range = tmp_range;
140
141 /* Yay, we survived. */
142 ret = 0;
143
144 on_error:
145 free(dup);
146
147 return ret;
148 }