|
1 This patch provides the implementation of the smfproperty probe |
|
2 on solaris. |
|
3 This patch has not been contributed upstream but is planned to be contributed |
|
4 upstream. Hoping to have it accepted by 2016-Mar-15. |
|
5 --- openscap-1.2.1/configure.ac.~3~ 2015-04-22 16:20:53.433875799 -0700 |
|
6 +++ openscap-1.2.1/configure.ac 2015-04-22 16:25:56.053053597 -0700 |
|
7 @@ -257,6 +257,10 @@ |
|
8 probe_systemdunitdependency_req_deps_missing= |
|
9 probe_systemdunitdependency_opt_deps_ok=yes |
|
10 probe_systemdunitdependency_opt_deps_missing= |
|
11 +probe_smfproperty_req_deps_ok=yes |
|
12 +probe_smfproperty_req_deps_missing= |
|
13 +probe_smfproperty_opt_deps_ok=yes |
|
14 +probe_smfproperty_opt_deps_missing= |
|
15 |
|
16 # |
|
17 # env |
|
18 @@ -1325,6 +1329,8 @@ |
|
19 probe_systemdunitproperty_enabled=$probe_systemdunitproperty_req_deps_ok |
|
20 AM_CONDITIONAL([probe_systemdunitdependency_enabled], test "$probe_systemdunitdependency_req_deps_ok" = yes) |
|
21 probe_systemdunitdependency_enabled=$probe_systemdunitdependency_req_deps_ok |
|
22 +AM_CONDITIONAL([probe_smfproperty_enabled], test "$probe_smfproperty_req_deps_ok" = yes) |
|
23 +probe_smfproperty_enabled=$probe_smfproperty_req_deps_ok |
|
24 |
|
25 AM_CONDITIONAL([WANT_CCE], test "$cce" = yes) |
|
26 |
|
27 @@ -1736,6 +1742,12 @@ |
|
28 probe_systemdunitdependency_table_result="NO (missing: $probe_systemdunitdependency_req_deps_missing)" |
|
29 fi |
|
30 printf " %-28s %s\n" "systemdunitdependency:" "$probe_systemdunitdependency_table_result" |
|
31 +if test "$probe_smfproperty_req_deps_ok" = "yes"; then |
|
32 + probe_smfproperty_table_result="yes" |
|
33 +else |
|
34 + probe_smfproperty_table_result="NO (missing: $probe_smfproperty_req_deps_missing)" |
|
35 +fi |
|
36 +printf " %-28s %s\n" "smfproperty:" "$probe_smfproperty_table_result" |
|
37 echo |
|
38 echo " === configuration ===" |
|
39 echo " probe directory set to: $probe_dir" |
|
40 --- openscap-1.2.1/src/OVAL/oval_enumerations.c.~1~ 2015-04-22 16:40:36.569105567 -0700 |
|
41 +++ openscap-1.2.1/src/OVAL/oval_enumerations.c 2015-04-22 16:41:10.935676772 -0700 |
|
42 @@ -512,6 +512,7 @@ |
|
43 {OVAL_SOLARIS_SMF, "smf"}, |
|
44 {OVAL_SOLARIS_NDD, "ndd"}, |
|
45 {OVAL_SOLARIS_PACKAGECHECK, "packagecheck"}, |
|
46 + {OVAL_SOLARIS_SMFPROPERTY, "smfproperty"}, |
|
47 {OVAL_SUBTYPE_UNKNOWN, NULL} |
|
48 }; |
|
49 |
|
50 --- openscap-1.2.1/src/OVAL/probes/Makefile.am.~1~ 2015-04-22 16:43:21.761989228 -0700 |
|
51 +++ openscap-1.2.1/src/OVAL/probes/Makefile.am 2015-04-22 16:44:11.722065041 -0700 |
|
52 @@ -202,6 +202,11 @@ |
|
53 probe_smf_SOURCES= unix/solaris/smf.c |
|
54 endif |
|
55 |
|
56 +if probe_smfproperty_enabled |
|
57 +pkglibexec_PROGRAMS += probe_smfproperty |
|
58 +probe_smfproperty_SOURCES= unix/solaris/smfproperty.c |
|
59 +endif |
|
60 + |
|
61 endif |
|
62 |
|
63 # |
|
64 --- openscap-1.2.3/src/OVAL/probes/unix/solaris/smfproperty.c.~1~ 2015-06-02 21:28:41.068464123 -0700 |
|
65 +++ openscap-1.2.3/src/OVAL/probes/unix/solaris/smfproperty.c 2015-06-03 09:48:55.973035835 -0700 |
|
66 @@ -0,0 +1,385 @@ |
|
67 +/** |
|
68 + * @file smfproperty.c |
|
69 + * @brief smfproperty probe |
|
70 + * @author "Jacob Varughese" <[email protected]> |
|
71 + * |
|
72 + * This probe processes retrieves the properties of smf services. |
|
73 + */ |
|
74 + |
|
75 + |
|
76 +#include "probe-api.h" |
|
77 +#ifdef HAVE_CONFIG_H |
|
78 +#include <config.h> |
|
79 +#endif |
|
80 + |
|
81 +#if defined(__SVR4) && defined(__sun) |
|
82 +#include <stdlib.h> |
|
83 +#include <string.h> |
|
84 +#include <stdio.h> |
|
85 +#include <errno.h> |
|
86 +#include <sys/stat.h> |
|
87 +#include <ctype.h> |
|
88 +#include <sys/types.h> |
|
89 +#include <limits.h> |
|
90 +#include <unistd.h> |
|
91 +#include <libscf.h> |
|
92 +#include <libscf_priv.h> |
|
93 +#include "seap.h" |
|
94 +#include "probe/entcmp.h" |
|
95 +#include "alloc.h" |
|
96 +#include "common/debug_priv.h" |
|
97 + |
|
98 +#ifndef SCF_PG_START |
|
99 +#define SCF_PG_START "start" |
|
100 +#endif |
|
101 + |
|
102 +#ifndef SCF_SNAPSHOT_RUNNING |
|
103 +#define SCF_SNAPSHOT_RUNNING "running" |
|
104 +#endif |
|
105 + |
|
106 +#define MAX_SCF_VALUE_LENGTH 1024 |
|
107 +/* Convenience structure for the results being reported */ |
|
108 + |
|
109 +/* |
|
110 + * smfproperty probe: |
|
111 + * |
|
112 + * |
|
113 + * fmri |
|
114 + * service |
|
115 + * instance |
|
116 + * property |
|
117 + * value |
|
118 + */ |
|
119 + |
|
120 + |
|
121 +/* Convenience structure for the results being reported */ |
|
122 +struct result_info { |
|
123 + char *fmri; |
|
124 + char *service; |
|
125 + char *instance; |
|
126 + char *property; |
|
127 + char *value; |
|
128 +}; |
|
129 + |
|
130 + |
|
131 +static char * |
|
132 +strdup_check(char *p) |
|
133 +{ |
|
134 + char *ret; |
|
135 + |
|
136 + if ((ret = strdup(p)) == NULL) { |
|
137 + dE("Error: Out of Memory error.\n"); |
|
138 + exit(PROBE_ENOMEM); |
|
139 + } |
|
140 + return ret; |
|
141 +} |
|
142 + |
|
143 + |
|
144 + |
|
145 +static void |
|
146 +report_smfproperty(struct result_info *res, probe_ctx *ctx) |
|
147 +{ |
|
148 + SEXP_t *item; |
|
149 + |
|
150 + item = probe_item_create(OVAL_SOLARIS_SMFPROPERTY, NULL, |
|
151 + "fmri", OVAL_DATATYPE_STRING, res->fmri, |
|
152 + "service", OVAL_DATATYPE_STRING, res->service, |
|
153 + "instance", OVAL_DATATYPE_STRING, res->instance, |
|
154 + "property", OVAL_DATATYPE_STRING, res->property, |
|
155 + "value", OVAL_DATATYPE_STRING, |
|
156 + res->value, |
|
157 + NULL); |
|
158 + probe_item_collect(ctx, item); |
|
159 +} |
|
160 + |
|
161 + |
|
162 +static int |
|
163 +convert_prop(scf_handle_t *hdl, const scf_property_t *prop, |
|
164 + struct result_info *res, probe_ctx *ctx) |
|
165 +{ |
|
166 + char propname[256]; |
|
167 + scf_iter_t *iter = NULL; |
|
168 + scf_value_t *value = NULL; |
|
169 + ssize_t size = 0, len = 0, i = 0; |
|
170 + char *buffer; |
|
171 + int cur_size; |
|
172 + |
|
173 + if (prop == NULL) |
|
174 + return 0; |
|
175 + |
|
176 + if (scf_property_get_name(prop, propname, |
|
177 + sizeof(propname)) < 0) { |
|
178 + dE("Cannot get name of property\n"); |
|
179 + dE("Error: %s\n", scf_strerror(scf_error())); |
|
180 + return 1; |
|
181 + } |
|
182 + if ((value = scf_value_create(hdl)) == NULL) { |
|
183 + dE("Cannot create value from handle for prop:%s\n", |
|
184 + propname); |
|
185 + dE("Error: %s\n", scf_strerror(scf_error())); |
|
186 + return 1; |
|
187 + } |
|
188 + if ((iter = scf_iter_create(hdl)) == NULL) { |
|
189 + dE("Cannot create value iterator for prop:%s\n", |
|
190 + propname); |
|
191 + dE("Error: %s\n", scf_strerror(scf_error())); |
|
192 + return 1; |
|
193 + } |
|
194 + if (scf_iter_property_values(iter, prop) != 0) { |
|
195 + dE("Cannot iterate values for prop:%s\n", |
|
196 + propname); |
|
197 + dE("Error: %s\n", scf_strerror(scf_error())); |
|
198 + return 1; |
|
199 + } |
|
200 + buffer = malloc(MAX_SCF_VALUE_LENGTH); |
|
201 + if (buffer == NULL) { |
|
202 + dE("Out of Memory Error.\n"); |
|
203 + exit(PROBE_ENOMEM); |
|
204 + } |
|
205 + buffer[0] = '\0'; |
|
206 + cur_size = MAX_SCF_VALUE_LENGTH; |
|
207 + while ((scf_iter_next_value(iter, value)) > 0) { |
|
208 + char *tmp; |
|
209 + i++; |
|
210 + size = scf_value_get_as_string(value, NULL, 0) + 1; |
|
211 + if (size < 0) { |
|
212 + dE("Cannot get value for prop:%s size is" |
|
213 + " invalid\n", propname); |
|
214 + dE("Error: %s\n", scf_strerror(scf_error())); |
|
215 + return 1; |
|
216 + } |
|
217 + if ((size + len + 2) > cur_size) { |
|
218 + cur_size = cur_size * 2 + size; |
|
219 + buffer = realloc(buffer, cur_size); |
|
220 + if (buffer == NULL) { |
|
221 + dE("Out of Memory Error.\n"); |
|
222 + exit(PROBE_ENOMEM); |
|
223 + } |
|
224 + } |
|
225 + if (i > 1) { |
|
226 + buffer[len -1] = ' '; |
|
227 + buffer[len] = '\0'; |
|
228 + tmp = &buffer[len]; |
|
229 + } else { |
|
230 + tmp = &buffer[0]; |
|
231 + } |
|
232 + scf_value_get_as_string(value, tmp, size); |
|
233 + len += size; |
|
234 + } |
|
235 + res->value = buffer; |
|
236 + report_smfproperty(res, ctx); |
|
237 + dI("fmri=% service=%s instance=%s property=%s value=%s\n", |
|
238 + res->fmri, res->service, res->instance, res->property, res->value); |
|
239 + free(buffer); |
|
240 + return 0; |
|
241 +} |
|
242 + |
|
243 +static int |
|
244 +get_smf_prop(scf_handle_t *h, const scf_service_t *service, |
|
245 + const scf_instance_t *instance, const char *prop_grp_name, |
|
246 + const char *prop_name, struct result_info *res, probe_ctx *ctx) |
|
247 +{ |
|
248 + scf_propertygroup_t *pg = scf_pg_create(h); |
|
249 + scf_property_t *prop = scf_property_create(h); |
|
250 + int rc; |
|
251 + |
|
252 + if (pg == NULL) { |
|
253 + dE("Unable to create property group from handle.\n"); |
|
254 + dE("prop_grp_name=%s prop_name=%s.\n", |
|
255 + prop_grp_name, prop_name); |
|
256 + dE("Error: %s.\n", scf_strerror(scf_error())); |
|
257 + rc = 1; |
|
258 + goto cleanup; |
|
259 + } |
|
260 + if (prop == NULL) { |
|
261 + dE("Unable to create property from handle.\n"); |
|
262 + dE("prop_grp_name=%s prop_name=%s.\n", |
|
263 + prop_grp_name, prop_name); |
|
264 + dE("Error: %s.\n", scf_strerror(scf_error())); |
|
265 + rc = 1; |
|
266 + goto cleanup; |
|
267 + } |
|
268 + |
|
269 + if (instance == NULL) { |
|
270 + if (scf_service_get_pg(service, prop_grp_name, pg) == -1 || |
|
271 + scf_pg_get_property(pg, prop_name, prop) == -1) { |
|
272 + dE("Error: Could not read %s/%s from service.\n", |
|
273 + prop_grp_name, prop_name); |
|
274 + rc = 1; |
|
275 + goto cleanup; |
|
276 + } |
|
277 + } else { |
|
278 + scf_snapshot_t *snap; |
|
279 + if ((snap = scf_snapshot_create(h)) == NULL) { |
|
280 + dE("Unable to create snapshot from handle.\n"); |
|
281 + dE("fmri=%s \n", res->fmri); |
|
282 + dE("Error: %s.\n", scf_strerror(scf_error())); |
|
283 + rc = 1; |
|
284 + goto cleanup; |
|
285 + } |
|
286 + if (scf_instance_get_snapshot(instance, SCF_SNAPSHOT_RUNNING, |
|
287 + snap) == -1) { |
|
288 + dE("Unable to get running snapshot.\n"); |
|
289 + dE("for fmri=%s \n", res->fmri); |
|
290 + dE("Error: %s.\n", scf_strerror(scf_error())); |
|
291 + rc = 1; |
|
292 + goto cleanup; |
|
293 + } |
|
294 + if (scf_instance_get_pg_composed(instance, snap, |
|
295 + prop_grp_name, pg) == -1) { |
|
296 + dE("Error: Could not read " |
|
297 + " %s/%s property from snapshot for %s\n", |
|
298 + prop_grp_name, prop_name, res->fmri); |
|
299 + rc = 1; |
|
300 + scf_snapshot_destroy(snap); |
|
301 + goto cleanup; |
|
302 + } |
|
303 + scf_snapshot_destroy(snap); |
|
304 + } |
|
305 + if (scf_pg_get_property(pg, prop_name, prop) == -1) { |
|
306 + dE("Error: Could not read %s/%s property %s\n", |
|
307 + prop_grp_name, prop_name, res->fmri); |
|
308 + rc = 1; |
|
309 + goto cleanup; |
|
310 + } |
|
311 + rc = convert_prop(h, prop, res, ctx); |
|
312 +cleanup: |
|
313 + scf_property_destroy(prop); |
|
314 + scf_pg_destroy(pg); |
|
315 + return rc; |
|
316 +} |
|
317 + |
|
318 +static int |
|
319 +collect_smfprop_info(char *asvc, char *ainst, char *aprop, |
|
320 + probe_ctx *ctx) |
|
321 +{ |
|
322 + struct result_info r; |
|
323 + int rc = 0; |
|
324 + char *propgrp = NULL, *prop = NULL; |
|
325 + char *tmp = NULL; |
|
326 + scf_handle_t *scf_hdl; |
|
327 + scf_instance_t *inst = NULL; |
|
328 + scf_service_t *svc = NULL; |
|
329 + char *p = NULL; |
|
330 + |
|
331 + memset(&r, 0, sizeof(r)); |
|
332 + r.service = asvc; |
|
333 + |
|
334 + if (ainst == NULL) { |
|
335 + r.fmri = strdup_check(asvc); |
|
336 + } else { /* service name is service:instance */ |
|
337 + asprintf(&r.fmri, "%s:%s", asvc, ainst); |
|
338 + } |
|
339 + if (r.fmri == NULL) |
|
340 + _exit(1); |
|
341 + if ((scf_hdl = scf_handle_create(SCF_VERSION)) == NULL || |
|
342 + scf_handle_bind(scf_hdl) != 0 || |
|
343 + (svc = scf_service_create(scf_hdl)) == NULL || |
|
344 + (ainst != NULL && |
|
345 + (inst = scf_instance_create(scf_hdl)) == NULL)) { |
|
346 + rc = PROBE_EFATAL; |
|
347 + goto cleanup; |
|
348 + } |
|
349 + if (scf_handle_decode_fmri(scf_hdl, r.fmri, NULL, svc, |
|
350 + (ainst == NULL ? NULL : inst), NULL, NULL, |
|
351 + SCF_DECODE_FMRI_EXACT) != 0 || |
|
352 + scf_error() == SCF_ERROR_NOT_FOUND) { |
|
353 + dE("scf_handle_decode_fmri failed.\n"); |
|
354 + goto cleanup; |
|
355 + } |
|
356 + |
|
357 + tmp = strdup_check(aprop); |
|
358 + if ((p = strstr(tmp, SCF_FMRI_PROPERTY_PREFIX)) != NULL) { |
|
359 + *p = '\0'; |
|
360 + p++; |
|
361 + prop = p; |
|
362 + } |
|
363 + propgrp = tmp; |
|
364 + dI("r.service_name=%s\n", r.service); |
|
365 + dI("service:%s instance:%s propgrp:%s prop:%s\n", |
|
366 + STR(asvc), STR(ainst), STR(propgrp), STR(prop)); |
|
367 + r.instance = ainst; |
|
368 + r.property = aprop; |
|
369 + if (get_smf_prop(scf_hdl, svc, inst, propgrp, prop, &r, ctx) > 0) { |
|
370 + r.fmri = NULL; |
|
371 + dE("get_smf_prop failed.\n"); |
|
372 + } |
|
373 + dI("Service exists:%s\n", r.service); |
|
374 +cleanup: |
|
375 + free(tmp); |
|
376 + free(r.fmri); |
|
377 + scf_handle_destroy(scf_hdl); |
|
378 + scf_handle_unbind(scf_hdl); |
|
379 + scf_service_destroy(svc); |
|
380 + scf_instance_destroy(inst); |
|
381 + return rc; |
|
382 +} |
|
383 + |
|
384 +int |
|
385 +probe_main(probe_ctx *ctx, void *arg) |
|
386 +{ |
|
387 + SEXP_t *probe_in, *service = NULL, *instance = NULL, *property = NULL; |
|
388 + SEXP_t *service_val = NULL, *instance_val = NULL, *property_val = NULL; |
|
389 + char *service_str = NULL, *instance_str = NULL, *property_str = NULL; |
|
390 + int rc; |
|
391 + |
|
392 + probe_in = probe_ctx_getobject(ctx); |
|
393 + if (probe_in == NULL) { |
|
394 + return PROBE_ENOOBJ; |
|
395 + } |
|
396 + service = probe_obj_getent(probe_in, "service", 1); |
|
397 + if (service == NULL) { |
|
398 + dE("No service in context.\n"); |
|
399 + return PROBE_ENOENT; |
|
400 + } |
|
401 + instance = probe_obj_getent(probe_in, "instance", 1); |
|
402 + property = probe_obj_getent(probe_in, "property", 1); |
|
403 + if (property == NULL) { |
|
404 + dE("No property in context.\n"); |
|
405 + rc = PROBE_ENOENT; |
|
406 + goto error; |
|
407 + } |
|
408 + service_val = probe_ent_getval(service); |
|
409 + if (service_val == NULL) { |
|
410 + dE("Get service value failed.\n"); |
|
411 + rc = PROBE_ENOVAL; |
|
412 + goto error; |
|
413 + } |
|
414 + service_str = SEXP_string_cstr(service_val); |
|
415 + dI("service in context: %s.\n", service_str); |
|
416 + if (instance != NULL) { |
|
417 + instance_val = probe_ent_getval(instance); |
|
418 + instance_str = SEXP_string_cstr(instance_val); |
|
419 + } |
|
420 + if (instance_str != NULL && strcmp(instance_str, "") == 0) |
|
421 + instance_str = NULL; |
|
422 + dI("instance in context: %s.\n", instance_str); |
|
423 + property_val = probe_ent_getval(property); |
|
424 + if (property_val == NULL) { |
|
425 + dE("Get property value failed.\n"); |
|
426 + rc = PROBE_ENOVAL; |
|
427 + goto error; |
|
428 + } |
|
429 + property_str = SEXP_string_cstr(property_val); |
|
430 + dI("property in context: %s.\n", property_str); |
|
431 + rc = collect_smfprop_info(service_str, instance_str, property_str, ctx); |
|
432 +error: |
|
433 + free(service_str); |
|
434 + free(instance_str); |
|
435 + free(property_str); |
|
436 + SEXP_free(service); |
|
437 + SEXP_free(instance); |
|
438 + SEXP_free(property); |
|
439 + SEXP_free(service_val); |
|
440 + SEXP_free(instance_val); |
|
441 + SEXP_free(property_val); |
|
442 + return rc; |
|
443 +} |
|
444 +#else |
|
445 + |
|
446 +int |
|
447 +probe_main(probe_ctx *ctx, void *probe_arg) |
|
448 +{ |
|
449 + return PROBE_EOPNOTSUPP; |
|
450 +} |
|
451 +#endif |
|
452 --- openscap-1.2.3/src/OVAL/probes/unix/solaris/smfproperty.c.~2~ 2015-11-10 10:00:28.564892744 -0800 |
|
453 +++ openscap-1.2.3/src/OVAL/probes/unix/solaris/smfproperty.c 2015-11-10 10:03:34.496610180 -0800 |
|
454 @@ -38,6 +38,7 @@ |
|
455 #endif |
|
456 |
|
457 #define MAX_SCF_VALUE_LENGTH 1024 |
|
458 +#define STR(x) ((x == NULL) ? "" : x) |
|
459 /* Convenience structure for the results being reported */ |
|
460 |
|
461 /* |
|
462 --- openscap-1.2.6/src/OVAL/public/oval_types.h.~1~ 2016-01-28 10:36:10.169093685 -0800 |
|
463 +++ openscap-1.2.6/src/OVAL/public/oval_types.h 2016-01-28 10:36:55.766025827 -0800 |
|
464 @@ -238,7 +238,8 @@ |
|
465 OVAL_SOLARIS_SMF = OVAL_FAMILY_SOLARIS + 4, |
|
466 OVAL_SOLARIS_PATCH54 = OVAL_FAMILY_SOLARIS + 5, |
|
467 OVAL_SOLARIS_NDD = OVAL_FAMILY_SOLARIS + 6, |
|
468 - OVAL_SOLARIS_PACKAGECHECK = OVAL_FAMILY_SOLARIS + 7 |
|
469 + OVAL_SOLARIS_PACKAGECHECK = OVAL_FAMILY_SOLARIS + 7, |
|
470 + OVAL_SOLARIS_SMFPROPERTY = OVAL_FAMILY_SOLARIS + 8 |
|
471 } oval_solaris_subtype_t; |
|
472 |
|
473 /// Unix subtypes |