components/openscap/patches/smfproperty.patch
author Rich Burridge <rich.burridge@oracle.com>
Tue, 02 May 2017 17:33:26 -0700
changeset 7964 d9801318ed3d
parent 7343 a6cfc180f5e8
permissions -rw-r--r--
25981468 Build ilmbase and openexr with the GNU compilers

This patch provides the implementation of the smfproperty probe
on solaris.
This patch has not been contributed upstream but is planned to be contributed
upstream.  Hoping to have it accepted by 2016-Dec-15.
--- openscap-1.2.1/configure.ac.~3~	2015-04-22 16:20:53.433875799 -0700
+++ openscap-1.2.1/configure.ac	2015-04-22 16:25:56.053053597 -0700
@@ -257,6 +257,10 @@
 probe_systemdunitdependency_req_deps_missing=
 probe_systemdunitdependency_opt_deps_ok=yes
 probe_systemdunitdependency_opt_deps_missing=
+probe_smfproperty_req_deps_ok=yes
+probe_smfproperty_req_deps_missing=
+probe_smfproperty_opt_deps_ok=yes
+probe_smfproperty_opt_deps_missing=
 
 #
 # env
@@ -1325,6 +1329,8 @@
 probe_systemdunitproperty_enabled=$probe_systemdunitproperty_req_deps_ok
 AM_CONDITIONAL([probe_systemdunitdependency_enabled], test "$probe_systemdunitdependency_req_deps_ok" = yes)
 probe_systemdunitdependency_enabled=$probe_systemdunitdependency_req_deps_ok
+AM_CONDITIONAL([probe_smfproperty_enabled], test "$probe_smfproperty_req_deps_ok" = yes)
+probe_smfproperty_enabled=$probe_smfproperty_req_deps_ok
 
 AM_CONDITIONAL([WANT_CCE],  test "$cce"  = yes)
 
@@ -1736,6 +1742,12 @@
   probe_systemdunitdependency_table_result="NO (missing: $probe_systemdunitdependency_req_deps_missing)"
 fi
 printf "  %-28s %s\n" "systemdunitdependency:" "$probe_systemdunitdependency_table_result"
+if test "$probe_smfproperty_req_deps_ok" = "yes"; then
+  probe_smfproperty_table_result="yes"
+else
+  probe_smfproperty_table_result="NO (missing: $probe_smfproperty_req_deps_missing)"
+fi
+printf "  %-28s %s\n" "smfproperty:" "$probe_smfproperty_table_result"
 echo
 echo "  === configuration ==="
 echo "  probe directory set to:      $probe_dir"
--- openscap-1.2.1/src/OVAL/oval_enumerations.c.~1~	2015-04-22 16:40:36.569105567 -0700
+++ openscap-1.2.1/src/OVAL/oval_enumerations.c	2015-04-22 16:41:10.935676772 -0700
@@ -512,6 +512,7 @@
 	{OVAL_SOLARIS_SMF, "smf"},
 	{OVAL_SOLARIS_NDD, "ndd"},
 	{OVAL_SOLARIS_PACKAGECHECK, "packagecheck"},
+	{OVAL_SOLARIS_SMFPROPERTY, "smfproperty"},
 	{OVAL_SUBTYPE_UNKNOWN, NULL}
 };
 
--- openscap-1.2.1/src/OVAL/probes/Makefile.am.~1~	2015-04-22 16:43:21.761989228 -0700
+++ openscap-1.2.1/src/OVAL/probes/Makefile.am	2015-04-22 16:44:11.722065041 -0700
@@ -202,6 +202,11 @@
 probe_smf_SOURCES= unix/solaris/smf.c
 endif
 
+if probe_smfproperty_enabled
+pkglibexec_PROGRAMS += probe_smfproperty
+probe_smfproperty_SOURCES= unix/solaris/smfproperty.c
+endif
+
 endif
 
 #
--- openscap-1.2.9/src/OVAL/probes/unix/solaris/smfproperty.c.~1~	2016-11-09 09:54:40.194926041 +0000
+++ openscap-1.2.9/src/OVAL/probes/unix/solaris/smfproperty.c	2016-11-10 08:36:22.209408705 +0000
@@ -0,0 +1,468 @@
+/**
+ * @file smfproperty.c
+ * @brief smfproperty probe
+ * @author "Jacob Varughese" <[email protected]>
+ *
+ * This probe processes retrieves the properties of smf services.
+ */
+
+
+#include "probe-api.h"
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#if	defined(__SVR4) && defined(__sun)
+#include <stdlib.h>
+#include <string.h>
+#include <stdio.h>
+#include <errno.h>
+#include <sys/stat.h>
+#include <ctype.h>
+#include <sys/types.h>
+#include <limits.h>
+#include <unistd.h>
+#include <libscf.h>
+#include <libscf_priv.h>
+#include "seap.h"
+#include "probe/entcmp.h"
+#include "alloc.h"
+#include "common/debug_priv.h"
+
+#ifndef	SCF_PG_START
+#define	SCF_PG_START	"start"
+#endif
+
+#ifndef	SCF_SNAPSHOT_RUNNING
+#define	SCF_SNAPSHOT_RUNNING	"running"
+#endif
+
+#define	MAX_SCF_VALUE_LENGTH	1024
+#define	STR(x)	((x == NULL) ? "" : x)
+/* Convenience structure for the results being reported */
+
+/*
+ * smfproperty probe:
+ *
+ *
+ * fmri
+ * service
+ * instance
+ * property
+ * value
+ */
+
+
+/* Convenience structure for the results being reported */
+struct result_info {
+	char *fmri;
+	char *service;
+	char *instance;
+	char *property;
+	char *value;
+};
+
+
+static char *
+strdup_check(char *p)
+{
+	char *ret;
+
+	if ((ret = strdup(p)) == NULL) {
+		dE("Error: Out of Memory error.\n");
+		exit(PROBE_ENOMEM);
+	}
+	return ret;
+}
+
+
+
+static void
+report_smfproperty(struct result_info *res, probe_ctx *ctx)
+{
+	SEXP_t *item;
+
+	item = probe_item_create(OVAL_SOLARIS_SMFPROPERTY, NULL,
+	    "fmri", OVAL_DATATYPE_STRING, res->fmri,
+	    "service", OVAL_DATATYPE_STRING, res->service,
+	    "instance", OVAL_DATATYPE_STRING, res->instance,
+	    "property", OVAL_DATATYPE_STRING, res->property,
+	    "value", OVAL_DATATYPE_STRING,
+	    res->value,
+	    NULL);
+	probe_item_collect(ctx, item);
+}
+
+
+static int
+convert_prop(scf_handle_t *hdl, const scf_property_t *prop,
+    struct result_info *res)
+{
+	char propname[256];
+	scf_iter_t *iter = NULL;
+	scf_value_t *value = NULL;
+	ssize_t size = 0, len = 0, i = 0;
+	char *buffer;
+	int cur_size;
+
+	if (prop == NULL)
+		return 0;
+
+	if (scf_property_get_name(prop, propname,
+	    sizeof(propname)) < 0) {
+		dE("Cannot get name of property\n");
+		dE("Error: %s\n", scf_strerror(scf_error()));
+		return 1;
+	}
+	if ((value = scf_value_create(hdl)) == NULL) {
+		dE("Cannot create value from handle for prop:%s\n",
+		    propname);
+		dE("Error: %s\n", scf_strerror(scf_error()));
+		return 1;
+	}
+	if ((iter = scf_iter_create(hdl)) == NULL) {
+		dE("Cannot create value iterator for prop:%s\n",
+		    propname);
+		dE("Error: %s\n", scf_strerror(scf_error()));
+		return 1;
+	}
+	if (scf_iter_property_values(iter, prop) != 0) {
+		dE("Cannot iterate values  for prop:%s\n",
+		    propname);
+		dE("Error: %s\n", scf_strerror(scf_error()));
+		return 1;
+	}
+	buffer = malloc(MAX_SCF_VALUE_LENGTH);
+	if (buffer == NULL) {
+		dE("Out of Memory Error.\n");
+		exit(PROBE_ENOMEM);
+	}
+	buffer[0] = '\0';
+	cur_size = MAX_SCF_VALUE_LENGTH;
+	while ((scf_iter_next_value(iter, value)) > 0) {
+		char *tmp;
+		i++;
+		size = scf_value_get_as_string(value, NULL, 0) + 1;
+		if (size < 0) {
+			dE("Cannot get value for prop:%s size is"
+			    " invalid\n", propname);
+			dE("Error: %s\n", scf_strerror(scf_error()));
+			return 1;
+		}
+		if ((size + len + 2) > cur_size) {
+			cur_size = cur_size * 2 + size;
+			buffer = realloc(buffer, cur_size);
+			if (buffer == NULL) {
+				dE("Out of Memory Error.\n");
+				exit(PROBE_ENOMEM);
+			}
+		}
+		if (i > 1) {
+			buffer[len -1] = ' ';
+			buffer[len] = '\0';
+			tmp = &buffer[len];
+		} else {
+			tmp = &buffer[0];
+		}
+		scf_value_get_as_string(value, tmp, size);
+		len += size;
+	}
+	res->value = buffer;
+	return 0;
+}
+
+static int get_smf_nested_pg(scf_handle_t *h, scf_propertygroup_t *apg, char*aprop_name, scf_propertygroup_t **appg, char**app_prop)
+{
+        char *propgrp;
+        char *prop;
+        char props[2048];
+	 static int count = 0;
+
+        props[0] = '\0';
+        snprintf(props, sizeof(props), "%s", aprop_name); 
+	dI("In get_smf_nested_pg %s\n ", props);
+	if ((prop = strstr(props, SCF_FMRI_NESTED_PROPERTYGRP_PREFIX)) != NULL) {
+		scf_propertygroup_t *pg = scf_pg_create(h);
+		*prop = '\0';
+		prop += strlen(SCF_FMRI_NESTED_PROPERTYGRP_PREFIX);
+		propgrp = props;
+		dI("property-grp:%s\tproperty:%s\n", propgrp, prop);
+		if (scf_pg_get_pg(apg, propgrp, pg) == -1 ) {
+			dE("Error: Could not read %s/%s property group \n",
+			    propgrp, prop);
+                        scf_pg_destroy(pg);
+			count = 0;
+			return 1;
+		} else {
+			count++;
+			*appg = pg;
+			*app_prop = prop;
+			 if (count > 1)
+                            scf_pg_destroy(apg);
+			return get_smf_nested_pg(h, pg, prop, appg, app_prop);
+                }
+        } else {
+                *appg = apg;
+                *app_prop = aprop_name;
+		 count = 0;
+                return 0;
+        }
+}
+
+static int
+get_smf_prop_from_pg(scf_handle_t *h, scf_propertygroup_t *pg, char *prop_name, 
+ struct result_info *res)
+{
+	scf_propertygroup_t *apg = scf_pg_create(h);
+	scf_property_t *prop = scf_property_create(h);
+	int rc=0;
+	char *aprop;
+ 
+ 	if ((rc = get_smf_nested_pg(h, pg, prop_name, &apg, &aprop)) == 0) {
+		char grp[1024];
+		dI("prop_name:%s\n", aprop);
+		if (scf_pg_get_name(apg, grp, sizeof(grp)) > 0)
+			dI("prop_grp_name:%s\n", grp);
+		if (scf_pg_get_property(apg, aprop, prop) == -1 ) {
+			dE("Error: Could not read %s property %s\n",
+		                prop_name, res->fmri);
+			rc = 1;
+			goto cleanup;
+		} else {
+			rc = convert_prop(h, prop, res);
+                }
+	}
+cleanup:
+	scf_property_destroy(prop);
+	if (apg != pg)
+		scf_pg_destroy(apg);
+	return rc;
+}
+
+static int
+get_smf_prop(scf_handle_t *h, const scf_service_t *service,
+    const scf_instance_t *instance, const char *prop_grp_name,
+    const char *prop_name, struct result_info *res, probe_ctx *ctx)
+{
+	scf_propertygroup_t *pg = scf_pg_create(h);
+	scf_property_t *prop = scf_property_create(h);
+	int rc = 0;
+
+	if (pg == NULL) {
+		dE("Unable to create property group from handle.\n");
+		dE("prop_grp_name=%s prop_name=%s.\n",
+		    prop_grp_name, prop_name);
+		dE("Error: %s.\n", scf_strerror(scf_error()));
+		rc = 1;
+		goto cleanup;
+	}
+	if (prop == NULL) {
+		dE("Unable to create property from handle.\n");
+		dE("prop_grp_name=%s prop_name=%s.\n",
+		    prop_grp_name, prop_name);
+		dE("Error: %s.\n", scf_strerror(scf_error()));
+		rc = 1;
+		goto cleanup;
+	}
+
+	if (instance == NULL) {
+		if (scf_service_get_pg(service, prop_grp_name, pg) == -1 ||
+		    scf_pg_get_property(pg, prop_name, prop) == -1) {
+			dE("Error: Could not read %s/%s from service.\n",
+			    prop_grp_name, prop_name);
+			rc = 1;
+			goto cleanup;
+		}
+	} else {
+		scf_snapshot_t *snap;
+		if ((snap = scf_snapshot_create(h)) == NULL) {
+			dE("Unable to create snapshot from handle.\n");
+			dE("fmri=%s \n", res->fmri);
+			dE("Error: %s.\n", scf_strerror(scf_error()));
+			rc = 1;
+			goto cleanup;
+		}
+		if (scf_instance_get_snapshot(instance, SCF_SNAPSHOT_RUNNING,
+		    snap) == -1) {
+			dE("Unable to get running snapshot.\n");
+			dE("for fmri=%s \n", res->fmri);
+			dE("Error: %s.\n", scf_strerror(scf_error()));
+			rc = 1;
+			goto cleanup;
+		}
+		if (scf_instance_get_pg_composed(instance, snap,
+		    prop_grp_name, pg) == -1) {
+			dE("Error: Could not read "
+			    " %s/%s property from snapshot for %s\n",
+			    prop_grp_name, prop_name, res->fmri);
+			if (scf_instance_get_pg_composed(instance, NULL,
+                            prop_grp_name, pg) == -1) {
+                                dE( "Error: Could not read "
+                                    " %s/%s property for %s\n",
+                                    prop_grp_name, prop_name, res->fmri);
+                                goto cleanup;
+                        }
+
+		}
+		scf_snapshot_destroy(snap);
+	}
+ 	if ((rc = get_smf_prop_from_pg(h, pg, prop_name, res)) != 0) {
+		if (scf_instance_get_pg_composed(instance, NULL, prop_grp_name,
+		    pg) == -1) {
+			printf(
+			    "Error: Could not read "
+			    " %s/%s property for %s\n",
+			    prop_grp_name,
+			    prop_name, res->fmri);
+			rc = 1;
+			goto cleanup;
+		}
+		rc = get_smf_prop_from_pg(h, pg, prop_name, res);
+	}
+cleanup:
+	scf_property_destroy(prop);
+	scf_pg_destroy(pg);
+	return rc;
+}
+
+static int
+collect_smfprop_info(char *asvc, char *ainst, char *aprop,
+    probe_ctx *ctx)
+{
+	struct result_info r;
+	int rc = 0;
+	char *propgrp = NULL, *prop = NULL;
+	char *tmp = NULL;
+	scf_handle_t *scf_hdl;
+	scf_instance_t *inst = NULL;
+	scf_service_t *svc = NULL;
+	char *p = NULL;
+
+	memset(&r, 0, sizeof(r));
+	r.service = asvc;
+
+	if (ainst == NULL) {
+		r.fmri = strdup_check(asvc);
+	} else { /* service name is service:instance */
+		asprintf(&r.fmri, "%s:%s", asvc, ainst);
+	}
+	if (r.fmri == NULL)
+		_exit(1);
+	if ((scf_hdl = scf_handle_create(SCF_VERSION)) == NULL ||
+	    scf_handle_bind(scf_hdl) != 0 ||
+	    (svc = scf_service_create(scf_hdl)) == NULL ||
+	    (ainst != NULL &&
+	    (inst = scf_instance_create(scf_hdl)) == NULL)) {
+		rc = PROBE_EFATAL;
+		goto cleanup;
+	}
+	if (scf_handle_decode_fmri(scf_hdl, r.fmri, NULL, svc,
+	    (ainst == NULL ? NULL : inst), NULL, NULL,
+	    SCF_DECODE_FMRI_EXACT) != 0 ||
+	    scf_error() == SCF_ERROR_NOT_FOUND) {
+		dE("scf_handle_decode_fmri failed.\n");
+		goto cleanup;
+	}
+
+	tmp = strdup_check(aprop);
+	if ((p = strstr(tmp, SCF_FMRI_PROPERTY_PREFIX)) != NULL) {
+		*p = '\0';
+		p +=  strlen(SCF_FMRI_PROPERTY_PREFIX);
+		prop = p;
+	}
+	propgrp = tmp;
+	dI("r.service_name=%s\n", r.service);
+	dI("service:%s instance:%s propgrp:%s prop:%s\n",
+	    STR(asvc), STR(ainst), STR(propgrp), STR(prop));
+	r.instance = ainst;
+	r.property = aprop;
+	if (get_smf_prop(scf_hdl, svc, inst, propgrp, prop, &r, ctx) > 0) {
+		r.value = "";
+               probe_cobj_set_flag(probe_ctx_getresult(ctx), SYSCHAR_FLAG_NOT_APPLICABLE);
+		dE("get_smf_prop failed.\n");
+	}
+	report_smfproperty(&r, ctx);
+	dI("fmri=%s service=%s instance=%s property=%s value=%s\n",
+	    STR(r.fmri), STR(r.service), STR(r.instance), STR(r.property),
+	    STR(r.value));
+        if (r.value != NULL && strlen(r.value) > 0)
+	    free(r.value);
+	dI("Service exists:%s\n", r.service);
+cleanup:
+	free(tmp);
+	free(r.fmri);
+	scf_handle_unbind(scf_hdl);
+	scf_handle_destroy(scf_hdl);
+	scf_service_destroy(svc);
+	scf_instance_destroy(inst);
+	return rc;
+}
+
+int
+probe_main(probe_ctx *ctx, void *arg)
+{
+	SEXP_t *probe_in, *service = NULL, *instance = NULL, *property = NULL;
+	SEXP_t *service_val = NULL, *instance_val = NULL, *property_val = NULL;
+	char *service_str = NULL, *instance_str = NULL, *property_str = NULL;
+	int rc;
+
+	probe_in = probe_ctx_getobject(ctx);
+	if (probe_in == NULL) {
+		return PROBE_ENOOBJ;
+	}
+	service = probe_obj_getent(probe_in, "service", 1);
+	if (service == NULL) {
+		dE("No service in context.\n");
+		return PROBE_ENOENT;
+	}
+	instance = probe_obj_getent(probe_in, "instance", 1);
+	property = probe_obj_getent(probe_in, "property", 1);
+	if (property == NULL) {
+		dE("No property in context.\n");
+		rc = PROBE_ENOENT;
+		goto error;
+	}
+	service_val = probe_ent_getval(service);
+	if (service_val == NULL) {
+		dE("Get service value failed.\n");
+		rc = PROBE_ENOVAL;
+		goto error;
+	}
+	service_str = SEXP_string_cstr(service_val);
+	dI("service in context: %s.\n", service_str);
+	if (instance != NULL) {
+		instance_val = probe_ent_getval(instance);
+		instance_str = SEXP_string_cstr(instance_val);
+	}
+	if (instance_str != NULL && strcmp(instance_str, "") == 0)
+		instance_str = NULL;
+	dI("instance in context: %s.\n", instance_str);
+	property_val = probe_ent_getval(property);
+	if (property_val == NULL) {
+		dE("Get property value failed.\n");
+		rc = PROBE_ENOVAL;
+		goto error;
+	}
+	property_str = SEXP_string_cstr(property_val);
+	dI("property in context: %s.\n", property_str);
+	rc = collect_smfprop_info(service_str, instance_str, property_str, ctx);
+error:
+	free(service_str);
+	free(instance_str);
+	free(property_str);
+	SEXP_free(service);
+	SEXP_free(instance);
+	SEXP_free(property);
+	SEXP_free(service_val);
+	SEXP_free(instance_val);
+	SEXP_free(property_val);
+	return rc;
+}
+#else
+
+int
+probe_main(probe_ctx *ctx, void *probe_arg)
+{
+	return PROBE_EOPNOTSUPP;
+}
+#endif