|
1 --- openscap-0.8.1/src/OVAL/probes/unix/solaris/smf.c.~1~ 2011-09-21 04:46:46.000000000 -0700 |
|
2 +++ openscap-0.8.1/src/OVAL/probes/unix/solaris/smf.c 2013-01-28 15:39:59.601258629 -0800 |
|
3 @@ -28,10 +28,238 @@ |
|
4 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA |
|
5 */ |
|
6 |
|
7 +/* |
|
8 + * smf probe: |
|
9 + * |
|
10 + * fmri |
|
11 + * service_name |
|
12 + * service_state |
|
13 + * protocol |
|
14 + * server_executable |
|
15 + * server_arguements |
|
16 + * exec_as_user |
|
17 + */ |
|
18 + |
|
19 + |
|
20 +#include <stdlib.h> |
|
21 +#include <string.h> |
|
22 +#include <stdio.h> |
|
23 +#include <errno.h> |
|
24 +#include <sys/stat.h> |
|
25 +#include <ctype.h> |
|
26 +#include <sys/types.h> |
|
27 +#include <limits.h> |
|
28 +#include <unistd.h> |
|
29 +#include <libscf.h> |
|
30 +#include <libscf_priv.h> |
|
31 +#include "seap.h" |
|
32 #include "probe-api.h" |
|
33 +#include "probe/entcmp.h" |
|
34 +#include "alloc.h" |
|
35 +#include "common/debug_priv.h" |
|
36 + |
|
37 +#ifndef SCF_PG_START |
|
38 +#define SCF_PG_START "start" |
|
39 +#endif |
|
40 + |
|
41 +/* Convenience structure for the results being reported */ |
|
42 +struct result_info { |
|
43 + const char *fmri; |
|
44 + char *service_name; |
|
45 + char *service_state; |
|
46 + char *protocol; |
|
47 + char *server_executable; |
|
48 + char *server_arguments; |
|
49 + char *exec_as_user; |
|
50 +}; |
|
51 |
|
52 |
|
53 -int probe_main(probe_ctx *ctx, void *probe_arg) |
|
54 +static void |
|
55 +toUpperCase(char *str) |
|
56 +{ |
|
57 + int i = 0; |
|
58 + |
|
59 + if (str != NULL) { |
|
60 + while (str[i] != '\0') { |
|
61 + str[i] = toupper(str[i]); |
|
62 + i++; |
|
63 + } |
|
64 + } |
|
65 +} |
|
66 + |
|
67 +static char * |
|
68 +strdup_check(char *p) |
|
69 { |
|
70 - return(PROBE_EOPNOTSUPP); |
|
71 + char *ret; |
|
72 + |
|
73 + if ((ret = strdup(p)) == NULL) { |
|
74 + oscap_dlprintf(DBG_E, "Error: Out of Memory error.\n"); |
|
75 + exit(PROBE_ENOMEM); |
|
76 + } |
|
77 + return (ret); |
|
78 +} |
|
79 + |
|
80 +static int |
|
81 +get_smf_prop(scf_handle_t *h, const char *fmri, |
|
82 + const char *prop_grp_name, const char *prop_name, char **val) |
|
83 +{ |
|
84 + scf_simple_prop_t *prop; |
|
85 + char *state; |
|
86 + *val = NULL; |
|
87 + |
|
88 + if ((prop = scf_simple_prop_get(h, fmri, prop_grp_name, |
|
89 + prop_name)) == NULL) { |
|
90 + if (scf_error() == SCF_ERROR_NOT_FOUND) |
|
91 + oscap_dlprintf(DBG_E, "Error: Specified service " |
|
92 + " %s has no %s/%s property.\n", |
|
93 + fmri, prop_grp_name, prop_name); |
|
94 + if (scf_error() == SCF_ERROR_INVALID_ARGUMENT) { |
|
95 + oscap_dlprintf(DBG_E, "Error: %s is not a valid " |
|
96 + "service.\n", fmri); |
|
97 + (void) scf_handle_unbind(h); |
|
98 + scf_handle_destroy(h); |
|
99 + return (PROBE_EINVAL); |
|
100 + } |
|
101 + } else { |
|
102 + if ((state = |
|
103 + scf_simple_prop_next_astring(prop)) == NULL) { |
|
104 + oscap_dlprintf(DBG_E, |
|
105 + "Error: Could not read " |
|
106 + " %s/%s property of %s.\n", |
|
107 + prop_grp_name, |
|
108 + prop_name, |
|
109 + fmri); |
|
110 + } else if (state[0] != '\0') { |
|
111 + *val = strdup_check(state); |
|
112 + } |
|
113 + scf_simple_prop_free(prop); |
|
114 + } |
|
115 + return (0); |
|
116 +} |
|
117 + |
|
118 +static int |
|
119 +find_smf(struct result_info *res) |
|
120 +{ |
|
121 + scf_handle_t *scf_hdl; |
|
122 + int i; |
|
123 + |
|
124 + oscap_dlprintf(DBG_I, "In find_smf\n"); |
|
125 + if ((scf_hdl = scf_handle_create(SCF_VERSION)) == NULL) { |
|
126 + oscap_dlprintf(DBG_E, "Unexpected libscf error: %s. Exiting.\n", |
|
127 + scf_strerror(scf_error())); |
|
128 + return (PROBE_EFATAL); |
|
129 + } |
|
130 + if (scf_handle_bind(scf_hdl) == -1) { |
|
131 + oscap_dlprintf(DBG_E, "Error: Could not bind to" |
|
132 + " svc.configd.\n"); |
|
133 + scf_handle_destroy(scf_hdl); |
|
134 + return (PROBE_EFATAL); |
|
135 + } |
|
136 + if ((i = get_smf_prop(scf_hdl, res->fmri, SCF_PG_RESTARTER, |
|
137 + SCF_PROPERTY_STATE, &(res->service_state))) != 0) { |
|
138 + return (i); |
|
139 + } else { |
|
140 + toUpperCase(res->service_state); |
|
141 + } |
|
142 + if ((i = get_smf_prop(scf_hdl, res->fmri, SCF_PG_START, |
|
143 + SCF_PROPERTY_EXEC, &(res->server_executable))) != 0) |
|
144 + return (i); |
|
145 + if ((i = get_smf_prop(scf_hdl, res->fmri, SCF_PG_START, |
|
146 + SCF_PROPERTY_USER, &(res->exec_as_user))) != 0) |
|
147 + return (i); |
|
148 + (void) scf_handle_unbind(scf_hdl); |
|
149 + scf_handle_destroy(scf_hdl); |
|
150 + return (0); |
|
151 +} |
|
152 + |
|
153 +static void |
|
154 +report_finding(struct result_info *res, probe_ctx *ctx) |
|
155 +{ |
|
156 + SEXP_t *item; |
|
157 + |
|
158 + oscap_dlprintf(DBG_I, "In report_finding.\n"); |
|
159 + item = probe_item_create(OVAL_SOLARIS_SMF, NULL, |
|
160 + "fmri", OVAL_DATATYPE_STRING, res->fmri, |
|
161 + "service_name", OVAL_DATATYPE_STRING, res->service_name, |
|
162 + "service_state", OVAL_DATATYPE_STRING, res->service_state, |
|
163 + "protocol", OVAL_DATATYPE_STRING, res->protocol, |
|
164 + "server_executable", OVAL_DATATYPE_STRING, |
|
165 + res->server_executable, |
|
166 + "server_arguments", OVAL_DATATYPE_STRING, |
|
167 + res->server_arguments, |
|
168 + "exec_as_user", OVAL_DATATYPE_STRING, res->exec_as_user, |
|
169 + NULL); |
|
170 + probe_item_collect(ctx, item); |
|
171 +} |
|
172 + |
|
173 +static int |
|
174 +collect_smf_info(char *fmri, probe_ctx *ctx) |
|
175 +{ |
|
176 + struct result_info r; |
|
177 + int i, rc, type; |
|
178 + const char *service, *instance, *scope, *propgrp, *prop; |
|
179 + char *tmp; |
|
180 + |
|
181 + oscap_dlprintf(DBG_I, "In collect_smf_info.\n"); |
|
182 + memset(&r, 0, sizeof (r)); |
|
183 + r.service_name = strdup_check(fmri); |
|
184 + tmp = r.service_name; |
|
185 + scf_parse_fmri(r.service_name, &type, &scope, &service, |
|
186 + &instance, &propgrp, &prop); |
|
187 + if (scf_error() == SCF_ERROR_INVALID_ARGUMENT) { |
|
188 + oscap_dlprintf(DBG_E, "Error: Not a valid fmri:%s.\n", |
|
189 + fmri); |
|
190 + free(r.service_name); |
|
191 + return (PROBE_EINVAL); |
|
192 + } |
|
193 + if (instance == NULL) |
|
194 + r.service_name = strdup(service); |
|
195 + else /* service name is service:instance */ |
|
196 + asprintf(&r.service_name, "%s:%s", service, instance); |
|
197 + if (r.service_name == NULL) |
|
198 + exit(PROBE_ENOMEM); |
|
199 + free(tmp); |
|
200 + r.fmri = fmri; |
|
201 + if ((rc = find_smf(&r)) > 0) { |
|
202 + free(r.service_name); |
|
203 + return (rc); |
|
204 + } |
|
205 + oscap_dlprintf(DBG_I, "service params %s, %s, %s, %s, %s, %s, %s\n", |
|
206 + r.fmri, r.service_name, r.service_state, r.protocol, |
|
207 + r.server_executable, r.server_arguments, r.exec_as_user); |
|
208 + report_finding(&r, ctx); |
|
209 + free(r.protocol); |
|
210 + free(r.service_name); |
|
211 + free(r.service_state); |
|
212 + free(r.server_executable); |
|
213 + free(r.server_arguments); |
|
214 + free(r.exec_as_user); |
|
215 + return (0); |
|
216 +} |
|
217 + |
|
218 +int |
|
219 +probe_main(probe_ctx *ctx, void *arg) |
|
220 +{ |
|
221 + SEXP_t *fmri, *fmri_val, *probe_in; |
|
222 + char *fmri_str; |
|
223 + int rc; |
|
224 + |
|
225 + probe_in = probe_ctx_getobject(ctx); |
|
226 + if (probe_in == NULL) { |
|
227 + oscap_dlprintf(DBG_E, "No object in context.\n"); |
|
228 + return (PROBE_ENOVAL); |
|
229 + } |
|
230 + fmri = probe_obj_getent(probe_in, "fmri", 1); |
|
231 + if (fmri == NULL) { |
|
232 + oscap_dlprintf(DBG_E, "No fmri in context.\n"); |
|
233 + return (PROBE_ENOVAL); |
|
234 + } |
|
235 + fmri_val = probe_ent_getval(fmri); |
|
236 + fmri_str = SEXP_string_cstr(fmri_val); |
|
237 + oscap_dlprintf(DBG_I, "fmri in context: %s.\n", fmri_str); |
|
238 + rc = collect_smf_info(fmri_str, ctx); |
|
239 + free(fmri_str); |
|
240 + SEXP_free(fmri_val); |
|
241 + SEXP_free(fmri); |
|
242 + return (rc); |
|
243 } |