Print this page
10127 coreadm is mis-using strcpy()
Split |
Close |
Expand all |
Collapse all |
--- old/usr/src/cmd/coreadm/coreadm.c
+++ new/usr/src/cmd/coreadm/coreadm.c
1 1 /*
2 2 * CDDL HEADER START
3 3 *
4 4 * The contents of this file are subject to the terms of the
5 5 * Common Development and Distribution License (the "License").
6 6 * You may not use this file except in compliance with the License.
7 7 *
8 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 9 * or http://www.opensolaris.org/os/licensing.
10 10 * See the License for the specific language governing permissions
11 11 * and limitations under the License.
12 12 *
13 13 * When distributing Covered Code, include this CDDL HEADER in each
↓ open down ↓ |
13 lines elided |
↑ open up ↑ |
14 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 15 * If applicable, add the following below this CDDL HEADER, with the
16 16 * fields enclosed by brackets "[]" replaced with your own identifying
17 17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 18 *
19 19 * CDDL HEADER END
20 20 */
21 21 /*
22 22 * Copyright 2008 Sun Microsystems, Inc. All rights reserved.
23 23 * Use is subject to license terms.
24 + * Copyright (c) 2018, Joyent, Inc.
24 25 */
25 26
26 27 #include <stdio.h>
27 28 #include <fcntl.h>
28 29 #include <ctype.h>
29 30 #include <string.h>
30 31 #include <stdlib.h>
31 32 #include <unistd.h>
32 33 #include <errno.h>
33 34 #include <limits.h>
34 35 #include <libintl.h>
35 36 #include <locale.h>
36 37 #include <sys/stat.h>
37 38 #include <sys/corectl.h>
38 39 #include <libproc.h>
39 40 #include <libscf.h>
40 41 #include <libscf_priv.h>
41 42 #include <assert.h>
42 43
43 44 #define E_SUCCESS 0 /* Exit status for success */
44 45 #define E_ERROR 1 /* Exit status for error */
45 46 #define E_USAGE 2 /* Exit status for usage error */
46 47
47 48 static const char PATH_CONFIG[] = "/etc/coreadm.conf";
48 49 static const char PATH_CONFIG_OLD[] = "/etc/coreadm.conf.old";
49 50
50 51 #define COREADM_INST_NAME "system/coreadm:default"
51 52 #define COREADM_INST_FMRI \
52 53 SCF_FMRI_SVC_PREFIX SCF_FMRI_SERVICE_PREFIX COREADM_INST_NAME
53 54
54 55 #define CONFIG_PARAMS "config_params"
55 56 #define GLOBAL_ENABLED "global_enabled"
56 57 #define PROCESS_ENABLED "process_enabled"
57 58 #define GLOBAL_SETID_ENABLED "global_setid_enabled"
58 59 #define PROCESS_SETID_ENABLED "process_setid_enabled"
59 60 #define GLOBAL_LOG_ENABLED "global_log_enabled"
60 61 #define GLOBAL_PATTERN "global_pattern"
61 62 #define GLOBAL_CONTENT "global_content"
62 63 #define INIT_PATTERN "init_pattern"
63 64 #define INIT_CONTENT "init_content"
64 65
65 66 static char *command;
66 67 static uint64_t options;
67 68 static int alloptions;
68 69 static char *glob_pattern;
69 70 static char gpattern[PATH_MAX];
70 71 static core_content_t glob_content = CC_CONTENT_INVALID;
71 72 static char *init_pattern;
72 73 static char ipattern[PATH_MAX];
73 74 static core_content_t init_content = CC_CONTENT_INVALID;
74 75 static char *proc_pattern;
75 76 static size_t proc_size;
76 77 static core_content_t proc_content = CC_CONTENT_INVALID;
77 78
78 79 static int report_settings(void);
79 80 static int do_processes(int, char **);
80 81 static int do_modify(boolean_t);
81 82 static int do_update(void);
82 83 static int do_legacy(void);
83 84
84 85 static scf_propvec_t prop_gpattern = { GLOBAL_PATTERN, NULL, SCF_TYPE_ASTRING };
85 86 static scf_propvec_t prop_gcontent = { GLOBAL_CONTENT, NULL, SCF_TYPE_ASTRING };
86 87 static scf_propvec_t prop_ipattern = { INIT_PATTERN, NULL, SCF_TYPE_ASTRING };
87 88 static scf_propvec_t prop_icontent = { INIT_CONTENT, NULL, SCF_TYPE_ASTRING };
88 89 static scf_propvec_t prop_option[] = {
89 90 { GLOBAL_ENABLED, NULL, SCF_TYPE_BOOLEAN, NULL, CC_GLOBAL_PATH },
90 91 { PROCESS_ENABLED, NULL, SCF_TYPE_BOOLEAN, NULL, CC_PROCESS_PATH },
91 92 { GLOBAL_SETID_ENABLED, NULL, SCF_TYPE_BOOLEAN, NULL, CC_GLOBAL_SETID },
92 93 { PROCESS_SETID_ENABLED, NULL, SCF_TYPE_BOOLEAN, NULL, CC_PROCESS_SETID },
93 94 { GLOBAL_LOG_ENABLED, NULL, SCF_TYPE_BOOLEAN, NULL, CC_GLOBAL_LOG },
94 95 { NULL }
95 96 };
96 97 #define MAX_PROPS (4 + (sizeof (prop_option) / sizeof (scf_propvec_t)))
97 98
98 99 static void
99 100 usage(void)
100 101 {
101 102 (void) fprintf(stderr, gettext(
102 103 "usage:\n"));
103 104 (void) fprintf(stderr, gettext(
104 105 " %s [ -g pattern ] [ -i pattern ] [ -G content ] [ -I content ]\n"),
105 106 command);
106 107 (void) fprintf(stderr, gettext(
107 108 " [ -e {global | process | global-setid | proc-setid | log} ]\n"));
108 109 (void) fprintf(stderr, gettext(
109 110 " [ -d {global | process | global-setid | proc-setid | log} ]\n"));
110 111 (void) fprintf(stderr, gettext(
111 112 " %s [ -p pattern ] [ -P content ] [ pid ... ]\n"), command);
112 113 exit(E_USAGE);
113 114 }
114 115
115 116 static int
116 117 perm(void)
117 118 {
118 119 (void) fprintf(stderr, gettext("%s: insufficient privileges to "
119 120 "exercise the -[GIgied] options\n"), command);
120 121 return (E_USAGE);
121 122 }
122 123
123 124 static int
124 125 parse_content(char *arg, core_content_t *content)
125 126 {
126 127 if (proc_str2content(arg, content) == 0)
127 128 return (0);
128 129 (void) fprintf(stderr, gettext("%s: invalid content string '%s'\n"),
129 130 command, arg);
130 131 return (1);
131 132 }
132 133
133 134 int
134 135 main(int argc, char **argv)
135 136 {
136 137 int flag;
137 138 int opt;
138 139 int modify;
139 140 int update = 0;
140 141 int legacy_update = 0;
141 142 int error = 0;
142 143 int npids;
143 144 char **pidlist;
144 145
145 146 char curpid[11];
146 147 char *curpid_ptr = &curpid[0];
147 148
148 149 (void) setlocale(LC_ALL, "");
149 150 (void) textdomain(TEXT_DOMAIN);
150 151
151 152 /* command name (e.g., "coreadm") */
152 153 if ((command = strrchr(argv[0], '/')) != NULL)
153 154 command++;
154 155 else
155 156 command = argv[0];
156 157
157 158 while ((opt = getopt(argc, argv, "g:G:i:I:p:P:e:d:uU?")) != EOF) {
158 159 switch (opt) {
159 160 case 'g':
160 161 glob_pattern = optarg;
161 162 break;
162 163 case 'i':
163 164 init_pattern = optarg;
164 165 break;
165 166 case 'p':
166 167 proc_pattern = optarg;
167 168 proc_size = strlen(proc_pattern) + 1;
168 169 break;
169 170 case 'G':
170 171 error |= parse_content(optarg, &glob_content);
171 172 break;
172 173 case 'I':
173 174 error |= parse_content(optarg, &init_content);
174 175 break;
175 176 case 'P':
176 177 error |= parse_content(optarg, &proc_content);
177 178 break;
178 179 case 'e':
179 180 case 'd':
180 181 if (strcmp(optarg, "global") == 0)
181 182 flag = CC_GLOBAL_PATH;
182 183 else if (strcmp(optarg, "process") == 0)
183 184 flag = CC_PROCESS_PATH;
184 185 else if (strcmp(optarg, "global-setid") == 0)
185 186 flag = CC_GLOBAL_SETID;
186 187 else if (strcmp(optarg, "proc-setid") == 0)
187 188 flag = CC_PROCESS_SETID;
188 189 else if (strcmp(optarg, "log") == 0)
189 190 flag = CC_GLOBAL_LOG;
190 191 else {
191 192 flag = 0;
192 193 error = 1;
193 194 }
194 195 if (opt == 'e')
195 196 options |= flag;
196 197 else
197 198 options &= ~flag;
198 199 alloptions |= flag;
199 200 break;
200 201 case 'U':
201 202 update = 1;
202 203 break;
203 204 case 'u':
204 205 legacy_update = 1;
205 206 break;
206 207 case '?':
207 208 default:
208 209 error = 1;
209 210 break;
210 211 }
211 212 }
212 213
213 214 npids = argc - optind;
214 215 pidlist = argv + optind;
215 216
216 217 if (error)
217 218 usage();
218 219
219 220 /*
220 221 * If 'modify' is true, we must modify the system settings
221 222 * and update the configuration file with the new parameters.
222 223 */
223 224 modify = glob_pattern != NULL || glob_content != CC_CONTENT_INVALID ||
224 225 init_pattern != NULL || init_content != CC_CONTENT_INVALID ||
225 226 alloptions != 0;
226 227
227 228 if ((update || legacy_update) && (modify || proc_pattern != NULL ||
228 229 proc_content != CC_CONTENT_INVALID || npids != 0)) {
229 230 (void) fprintf(stderr,
230 231 gettext("%s: the -u option must stand alone\n"), command);
231 232 usage();
232 233 }
233 234 if (modify &&
234 235 (proc_pattern != NULL || proc_content != CC_CONTENT_INVALID)) {
235 236 (void) fprintf(stderr, gettext(
236 237 "%s: -[GIgied] and -[Pp] options are mutually exclusive\n"),
237 238 command);
238 239 usage();
239 240 }
240 241 if (modify && npids != 0) {
241 242 (void) fprintf(stderr, gettext(
242 243 "%s: -[GIgied] options cannot have a process-id list\n"),
243 244 command);
244 245 usage();
245 246 }
246 247 if ((proc_pattern != NULL || proc_content != CC_CONTENT_INVALID) &&
247 248 npids == 0) {
248 249 (void) sprintf(curpid, "%u", (uint_t)getppid());
249 250 npids = 1;
250 251 pidlist = &curpid_ptr;
251 252 }
252 253
253 254 if (legacy_update)
254 255 return (do_legacy());
255 256 if (update)
256 257 return (do_update());
257 258 if (modify)
258 259 return (do_modify(B_FALSE));
259 260 if (npids != 0)
260 261 return (do_processes(npids, pidlist));
261 262
262 263 return (report_settings());
263 264 }
264 265
265 266 static int
266 267 report_settings(void)
267 268 {
268 269 char content_str[PRCONTENTBUFSZ];
269 270
270 271 if ((options = core_get_options()) == -1) {
271 272 perror("core_get_options()");
272 273 return (E_ERROR);
273 274 }
274 275 if (core_get_global_path(gpattern, sizeof (gpattern)) != 0) {
275 276 perror("core_get_global_path()");
276 277 return (E_ERROR);
277 278 }
278 279 if (core_get_default_path(ipattern, sizeof (ipattern)) != 0) {
279 280 perror("core_get_default_path()");
280 281 return (E_ERROR);
281 282 }
282 283 if (core_get_global_content(&glob_content) != 0) {
283 284 perror("core_get_global_content()");
284 285 return (E_ERROR);
285 286 }
286 287 if (core_get_default_content(&init_content) != 0) {
287 288 perror("core_get_default_content()");
288 289 return (E_ERROR);
289 290 }
290 291
291 292 (void) printf(gettext(" global core file pattern: %s\n"),
292 293 gpattern);
293 294 (void) proc_content2str(glob_content, content_str,
294 295 sizeof (content_str));
295 296 (void) printf(gettext(" global core file content: %s\n"),
296 297 content_str);
297 298 (void) printf(gettext(" init core file pattern: %s\n"),
298 299 ipattern);
299 300 (void) proc_content2str(init_content, content_str,
300 301 sizeof (content_str));
301 302 (void) printf(gettext(" init core file content: %s\n"),
302 303 content_str);
303 304 (void) printf(gettext(" global core dumps: %s\n"),
304 305 (options & CC_GLOBAL_PATH)? "enabled" : "disabled");
305 306 (void) printf(gettext(" per-process core dumps: %s\n"),
306 307 (options & CC_PROCESS_PATH)? "enabled" : "disabled");
307 308 (void) printf(gettext(" global setid core dumps: %s\n"),
308 309 (options & CC_GLOBAL_SETID)? "enabled" : "disabled");
309 310 (void) printf(gettext(" per-process setid core dumps: %s\n"),
310 311 (options & CC_PROCESS_SETID)? "enabled" : "disabled");
311 312 (void) printf(gettext(" global core dump logging: %s\n"),
312 313 (options & CC_GLOBAL_LOG)? "enabled" : "disabled");
313 314 return (E_SUCCESS);
314 315 }
315 316
316 317 static int
317 318 do_processes(int npids, char **pidlist)
318 319 {
319 320 char process_path[PATH_MAX];
320 321 core_content_t content;
321 322 pid_t pid;
322 323 char *next;
323 324 int rc = E_SUCCESS;
324 325 char content_str[PRCONTENTBUFSZ];
325 326
326 327 if (proc_pattern == NULL && proc_content == CC_CONTENT_INVALID) {
327 328 while (npids-- > 0) {
328 329 pid = strtol(*pidlist, &next, 10);
329 330 if (*next != '\0' || !isdigit(**pidlist)) {
330 331 (void) fprintf(stderr,
331 332 gettext("%s: invalid process-id\n"),
332 333 *pidlist);
333 334 rc = E_USAGE;
334 335 } else if (core_get_process_path(process_path,
335 336 sizeof (process_path), pid) != 0 ||
336 337 core_get_process_content(&content, pid) != 0) {
337 338 perror(*pidlist);
338 339 rc = E_USAGE;
339 340 } else {
340 341 (void) proc_content2str(content, content_str,
341 342 sizeof (content_str));
342 343 (void) printf(gettext("%s:\t%s\t%s\n"),
343 344 *pidlist, process_path, content_str);
344 345 }
345 346 pidlist++;
346 347 }
347 348 } else {
348 349 while (npids-- > 0) {
349 350 pid = strtol(*pidlist, &next, 10);
350 351 if (*next != '\0') {
351 352 (void) fprintf(stderr,
352 353 gettext("%s: invalid process-id\n"),
353 354 *pidlist);
354 355 rc = E_USAGE;
355 356 } else {
356 357 if (proc_pattern != NULL &&
357 358 core_set_process_path(proc_pattern,
358 359 proc_size, pid) != 0) {
359 360 perror(*pidlist);
360 361 rc = E_USAGE;
361 362 }
362 363
363 364 if (proc_content != CC_CONTENT_INVALID &&
364 365 core_set_process_content(
365 366 &proc_content, pid) != 0) {
366 367 perror(*pidlist);
367 368 rc = E_USAGE;
368 369 }
369 370 }
370 371 pidlist++;
371 372 }
372 373 }
373 374
374 375 return (rc);
375 376 }
376 377
377 378 static void
378 379 addprop(scf_propvec_t *props, int size, int count, scf_propvec_t *pv, void *ptr)
379 380 {
380 381 assert(count + 1 < size);
381 382 props[count] = *pv;
382 383 props[count].pv_ptr = ptr;
383 384 }
384 385
385 386 static boolean_t
386 387 is_online(const char *fmri)
387 388 {
388 389 char *state = smf_get_state(fmri);
389 390 boolean_t result = state != NULL &&
390 391 strcmp(state, SCF_STATE_STRING_ONLINE) == 0;
391 392
392 393 free(state);
393 394 return (result);
394 395 }
395 396
396 397 /*
397 398 * The user has specified the -g, -G, -i, -I, -d, or -e options to
398 399 * modify the given configuration parameter. Perform the modification
399 400 * in the smf repository and then perform a smf_refresh_instance which
400 401 * will cause a coreadm -u to occur which will transfer ALL coreadm
401 402 * configuration information from the repository to the kernel.
402 403 */
403 404 static int
404 405 do_modify(boolean_t method)
405 406 {
406 407 char gcontentstr[PRCONTENTBUFSZ];
407 408 char icontentstr[PRCONTENTBUFSZ];
408 409 scf_propvec_t *prop;
409 410 scf_propvec_t properties[MAX_PROPS + 1];
410 411 int count = 0;
411 412
412 413 if (!method && !is_online(COREADM_INST_FMRI)) {
413 414 (void) fprintf(stderr,
414 415 gettext("%s: coreadm service not online\n"), command);
415 416 return (E_ERROR);
416 417 }
417 418
418 419 if (glob_pattern != NULL)
419 420 addprop(properties, MAX_PROPS, count++, &prop_gpattern,
420 421 glob_pattern);
421 422
422 423 if (glob_content != CC_CONTENT_INVALID) {
423 424 (void) proc_content2str(glob_content, gcontentstr,
424 425 sizeof (gcontentstr));
425 426 addprop(properties, MAX_PROPS, count++, &prop_gcontent,
426 427 gcontentstr);
427 428 }
428 429
429 430 if (init_pattern != NULL)
430 431 addprop(properties, MAX_PROPS, count++, &prop_ipattern,
431 432 init_pattern);
432 433
433 434 if (init_content != CC_CONTENT_INVALID) {
434 435 (void) proc_content2str(init_content, icontentstr,
435 436 sizeof (icontentstr));
436 437 addprop(properties, MAX_PROPS, count++, &prop_icontent,
437 438 icontentstr);
438 439 }
439 440
440 441 for (prop = prop_option; prop->pv_prop != NULL; prop++)
441 442 if ((alloptions & prop->pv_aux) != 0)
442 443 addprop(properties, MAX_PROPS, count++, prop, &options);
443 444
444 445 properties[count].pv_prop = NULL;
445 446
446 447 prop = NULL;
447 448 if (scf_write_propvec(COREADM_INST_FMRI, CONFIG_PARAMS, properties,
448 449 &prop) == SCF_FAILED) {
449 450 if (prop != NULL) {
450 451 (void) fprintf(stderr, gettext(
451 452 "%s: Unable to write property '%s': %s"), command,
452 453 prop->pv_prop, scf_strerror(scf_error()));
453 454 } else {
454 455 (void) fprintf(stderr, gettext(
455 456 "%s: Unable to write configuration: %s\n"),
456 457 command, scf_strerror(scf_error()));
457 458 }
458 459 return (E_ERROR);
459 460 }
460 461
461 462 if (smf_refresh_instance(COREADM_INST_FMRI) != 0) {
462 463 (void) fprintf(stderr,
463 464 gettext("%s: Unable to refresh %s: %s\n"
464 465 "Configuration stored but not made active.\n"),
465 466 command, COREADM_INST_FMRI, scf_strerror(scf_error()));
466 467 return (E_ERROR);
467 468 }
468 469
469 470 return (E_SUCCESS);
470 471 }
471 472
472 473 static const char *
473 474 write_kernel(void)
474 475 {
475 476 if (core_set_global_path(glob_pattern, strlen(glob_pattern) + 1) != 0)
476 477 return ("core_set_global_path()");
477 478
478 479 if (core_set_global_content(&glob_content) != 0)
479 480 return ("core_set_global_content()");
480 481
481 482 if (core_set_default_path(init_pattern, strlen(init_pattern) + 1) != 0)
482 483 return ("core_set_default_path()");
483 484
484 485 if (core_set_default_content(&init_content) != 0)
485 486 return ("core_set_init_content()");
486 487
487 488 if (core_set_options((int)options) != 0)
488 489 return ("core_set_options()");
489 490
490 491 return (NULL);
491 492 }
492 493
493 494 /*
494 495 * BUFSIZE must be large enough to contain the longest path plus some more.
495 496 */
496 497 #define BUFSIZE (PATH_MAX + 80)
497 498
498 499 static int
499 500 yes(char *name, char *value, int line)
500 501 {
501 502 if (strcmp(value, "yes") == 0)
502 503 return (1);
503 504 if (strcmp(value, "no") == 0)
504 505 return (0);
505 506 (void) fprintf(stderr, gettext(
506 507 "\"%s\", line %d: warning: value must be yes or no: %s=%s\n"),
507 508 PATH_CONFIG, line, name, value);
508 509 return (0);
509 510 }
510 511
511 512 static int
512 513 read_legacy(void)
513 514 {
514 515 FILE *fp;
515 516 int line;
516 517 char buf[BUFSIZE];
517 518 char name[BUFSIZE], value[BUFSIZE];
518 519 int n, len;
519 520
520 521 /* defaults */
521 522 alloptions = CC_OPTIONS;
522 523 options = CC_PROCESS_PATH;
523 524 gpattern[0] = '\0';
524 525 (void) strcpy(ipattern, "core");
525 526 glob_content = init_content = CC_CONTENT_DEFAULT;
526 527
527 528 glob_pattern = gpattern;
528 529 init_pattern = ipattern;
529 530
530 531 if ((fp = fopen(PATH_CONFIG, "r")) == NULL)
531 532 return (0);
532 533
533 534 for (line = 1; fgets(buf, sizeof (buf), fp) != NULL; line++) {
534 535 /*
535 536 * Skip comment lines and empty lines.
536 537 */
537 538 if (buf[0] == '#' || buf[0] == '\n')
538 539 continue;
539 540 /*
↓ open down ↓ |
506 lines elided |
↑ open up ↑ |
540 541 * Look for "name=value", with optional whitespace on either
541 542 * side, terminated by a newline, and consuming the whole line.
542 543 */
543 544 /* LINTED - unbounded string specifier */
544 545 n = sscanf(buf, " %[^=]=%s \n%n", name, value, &len);
545 546 if (n >= 1 && name[0] != '\0' &&
546 547 (n == 1 || len == strlen(buf))) {
547 548 if (n == 1)
548 549 value[0] = '\0';
549 550 if (strcmp(name, "COREADM_GLOB_PATTERN") == 0) {
550 - (void) strcpy(gpattern, value);
551 + (void) strlcpy(gpattern, value,
552 + sizeof (gpattern));
551 553 continue;
552 554 }
553 555 if (strcmp(name, "COREADM_GLOB_CONTENT") == 0) {
554 556 (void) proc_str2content(value, &glob_content);
555 557 continue;
556 558 }
557 559 if (strcmp(name, "COREADM_INIT_PATTERN") == 0) {
558 - (void) strcpy(ipattern, value);
560 + (void) strlcpy(ipattern, value,
561 + sizeof (ipattern));
559 562 continue;
560 563 }
561 564 if (strcmp(name, "COREADM_INIT_CONTENT") == 0) {
562 565 (void) proc_str2content(value, &init_content);
563 566 continue;
564 567 }
565 568 if (strcmp(name, "COREADM_GLOB_ENABLED") == 0) {
566 569 if (yes(name, value, line))
567 570 options |= CC_GLOBAL_PATH;
568 571 continue;
569 572 }
570 573 if (strcmp(name, "COREADM_PROC_ENABLED") == 0) {
571 574 if (yes(name, value, line))
572 575 options |= CC_PROCESS_PATH;
573 576 else
574 577 options &= ~CC_PROCESS_PATH;
575 578 continue;
576 579 }
577 580 if (strcmp(name, "COREADM_GLOB_SETID_ENABLED") == 0) {
578 581 if (yes(name, value, line))
579 582 options |= CC_GLOBAL_SETID;
580 583 continue;
581 584 }
582 585 if (strcmp(name, "COREADM_PROC_SETID_ENABLED") == 0) {
583 586 if (yes(name, value, line))
584 587 options |= CC_PROCESS_SETID;
585 588 continue;
586 589 }
587 590 if (strcmp(name, "COREADM_GLOB_LOG_ENABLED") == 0) {
588 591 if (yes(name, value, line))
589 592 options |= CC_GLOBAL_LOG;
590 593 continue;
591 594 }
592 595 (void) fprintf(stderr, gettext(
593 596 "\"%s\", line %d: warning: invalid token: %s\n"),
594 597 PATH_CONFIG, line, name);
595 598 } else {
596 599 (void) fprintf(stderr,
597 600 gettext("\"%s\", line %d: syntax error\n"),
598 601 PATH_CONFIG, line);
599 602 }
600 603 }
601 604 (void) fclose(fp);
602 605
603 606 return (1);
604 607 }
605 608
606 609 /*
607 610 * Loads and applies the coreadm configuration stored in the default
608 611 * coreadm instance. As this option is (only) used from within an SMF
609 612 * service method, this function must return an SMF_EXIT_* exit status
610 613 * to its caller.
611 614 */
612 615 static int
613 616 do_update(void)
614 617 {
615 618 char *gcstr, *icstr;
616 619 scf_propvec_t properties[MAX_PROPS + 1];
617 620 scf_propvec_t *prop;
618 621 int count = 0;
619 622 const char *errstr;
620 623
621 624 if (read_legacy()) {
622 625 if ((errstr = write_kernel()) != NULL)
623 626 goto error;
624 627
625 628 if (do_modify(B_TRUE) != 0 ||
626 629 rename(PATH_CONFIG, PATH_CONFIG_OLD) != 0) {
627 630 (void) fprintf(stderr, gettext(
628 631 "%s: failed to import legacy configuration.\n"),
629 632 command);
630 633 return (SMF_EXIT_ERR_FATAL);
631 634 }
632 635 return (SMF_EXIT_OK);
633 636 }
634 637
635 638 addprop(properties, MAX_PROPS, count++, &prop_gpattern, &glob_pattern);
636 639 addprop(properties, MAX_PROPS, count++, &prop_gcontent, &gcstr);
637 640 addprop(properties, MAX_PROPS, count++, &prop_ipattern, &init_pattern);
638 641 addprop(properties, MAX_PROPS, count++, &prop_icontent, &icstr);
639 642 for (prop = prop_option; prop->pv_prop != NULL; prop++)
640 643 addprop(properties, MAX_PROPS, count++, prop, &options);
641 644 properties[count].pv_prop = NULL;
642 645
643 646 alloptions = CC_OPTIONS;
644 647 if (scf_read_propvec(COREADM_INST_FMRI, CONFIG_PARAMS, B_TRUE,
645 648 properties, &prop) == SCF_FAILED) {
646 649 if (prop != NULL) {
647 650 (void) fprintf(stderr, gettext(
648 651 "%s: configuration property '%s' not found.\n"),
649 652 command, prop->pv_prop);
650 653 } else {
651 654 (void) fprintf(stderr, gettext(
652 655 "%s: unable to read configuration: %s\n"),
653 656 command, scf_strerror(scf_error()));
654 657 }
655 658 return (SMF_EXIT_ERR_FATAL);
656 659 }
657 660
658 661 (void) proc_str2content(gcstr, &glob_content);
659 662 (void) proc_str2content(icstr, &init_content);
660 663
661 664 errstr = write_kernel();
662 665 scf_clean_propvec(properties);
663 666 if (errstr == NULL)
664 667 return (SMF_EXIT_OK);
665 668
666 669 error:
667 670 if (errno == EPERM) {
668 671 (void) perm();
669 672 return (SMF_EXIT_ERR_PERM);
670 673 }
671 674 perror(errstr);
672 675 return (SMF_EXIT_ERR_FATAL);
673 676 }
674 677
675 678 static int do_legacy()
676 679 {
677 680 const char *errstr;
678 681
679 682 if (read_legacy() && (errstr = write_kernel()) != NULL) {
680 683 if (errno == EPERM)
681 684 return (perm());
682 685 perror(errstr);
683 686 return (E_ERROR);
684 687 }
685 688
686 689 return (E_SUCCESS);
687 690 }
↓ open down ↓ |
119 lines elided |
↑ open up ↑ |
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX