X-Git-Url: https://git.saurik.com/apple/syslog.git/blobdiff_plain/d7fa066074f8fd77fb237ffd8c1947e49f1e8837..5dd30d768c7cd795c2a3b974a6a1809dd8a3becf:/syslogd.tproj/asl_action.c diff --git a/syslogd.tproj/asl_action.c b/syslogd.tproj/asl_action.c index 92b7da1..699413f 100644 --- a/syslogd.tproj/asl_action.c +++ b/syslogd.tproj/asl_action.c @@ -3,21 +3,20 @@ * * @APPLE_LICENSE_HEADER_START@ * - * "Portions Copyright (c) 2004 Apple Computer, Inc. All Rights - * Reserved. This file contains Original Code and/or Modifications of - * Original Code as defined in and that are subject to the Apple Public - * Source License Version 1.0 (the 'License'). You may not use this file - * except in compliance with the License. Please obtain a copy of the - * License at http://www.apple.com/publicsource and read it before using - * this file. + * This file contains Original Code and/or Modifications of Original Code + * as defined in and that are subject to the Apple Public Source License + * Version 2.0 (the 'License'). You may not use this file except in + * compliance with the License. Please obtain a copy of the License at + * http://www.opensource.apple.com/apsl/ and read it before using this + * file. * * The Original Code and all software distributed under the License are * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, - * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the - * License for the specific language governing rights and limitations - * under the License." + * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. + * Please see the License for the specific language governing rights and + * limitations under the License. * * @APPLE_LICENSE_HEADER_END@ */ @@ -35,6 +34,7 @@ #include #include #include +#include #include "daemon.h" #define _PATH_ASL_CONF "/etc/asl.conf" @@ -44,6 +44,9 @@ #define IndexNull ((uint32_t)-1) #define forever for(;;) +#define ACT_STORE_FLAG_STAY_OPEN 0x00000001 +#define ACT_STORE_FLAG_EXCLUDE_ASLDB 0x00000002 + static asl_msg_t *query = NULL; static int reset = 0; @@ -52,9 +55,17 @@ struct action_rule asl_msg_t *query; char *action; char *options; + void *data; TAILQ_ENTRY(action_rule) entries; }; +struct store_data +{ + asl_store_t *store; + char *path; + uint32_t flags; +}; + static TAILQ_HEAD(cr, action_rule) asl_action_rule; int asl_action_close(); @@ -165,6 +176,68 @@ _parse_line(char *s) return 0; } +static char * +_next_word(char **s) +{ + char *a, *p, *e, *out; + int quote, len; + + if (s == NULL) return NULL; + if (*s == NULL) return NULL; + + quote = 0; + + p = *s; + a = p; + e = p; + + while (*p != '\0') + { + if (*p == '\\') + { + p++; + e = p; + + if (*p == '\0') + { + p--; + break; + } + + p++; + e = p; + continue; + } + + if (*p == '"') + { + if (quote == 0) quote = 1; + else quote = 0; + } + + if (((*p == ' ') || (*p == '\t')) && (quote == 0)) + { + e = p + 1; + break; + } + + p++; + e = p; + } + + *s = e; + + len = p - a; + if (len == 0) return NULL; + + out = malloc(len + 1); + if (out == NULL) return NULL; + + memcpy(out, a, len); + out[len] = '\0'; + return out; +} + static void _act_notify(struct action_rule *r) { @@ -173,12 +246,96 @@ _act_notify(struct action_rule *r) notify_post(r->options); } +static void +_act_access_control(struct action_rule *r, asl_msg_t *msg) +{ + int32_t ruid, rgid; + char *p; + + ruid = atoi(r->options); + rgid = -1; + p = strchr(r->options, ' '); + if (p == NULL) p = strchr(r->options, '\t'); + if (p != NULL) + { + *p = '\0'; + p++; + rgid = atoi(p); + } + + if (ruid != -1) asl_set((aslmsg)msg, ASL_KEY_READ_UID, r->options); + if (p != NULL) + { + if (rgid != -1) asl_set((aslmsg)msg, ASL_KEY_READ_GID, p); + p--; + *p = ' '; + } +} + +static void +_act_store(struct action_rule *r, asl_msg_t *msg) +{ + struct store_data *sd; + asl_store_t *s; + char *p, *opts; + uint32_t status; + uint64_t msgid; + + if (r == NULL) return; + if (r->options == NULL) return; + if (r->data == NULL) + { + /* Set up store data */ + sd = (struct store_data *)calloc(1, sizeof(struct store_data)); + if (sd == NULL) return; + + opts = r->options; + sd->store = NULL; + sd->path = _next_word(&opts); + if (sd->path == NULL) + { + free(sd); + return; + } + + sd->flags = 0; + while (NULL != (p = _next_word(&opts))) + { + if (!strcmp(p, "stayopen")) sd->flags |= ACT_STORE_FLAG_STAY_OPEN; + else if (!strcmp(p, "exclude_asldb")) sd->flags |= ACT_STORE_FLAG_EXCLUDE_ASLDB; + free(p); + p = NULL; + } + } + else + { + sd = (struct store_data *)r->data; + } + + if (sd->store == NULL) + { + s = NULL; + status = asl_store_open(sd->path, 0, &s); + if (status != ASL_STATUS_OK) return; + if (s == NULL) return; + sd->store = s; + } + + asl_store_save(sd->store, msg, -1, -1, &msgid); + if (!(sd->flags & ACT_STORE_FLAG_STAY_OPEN)) + { + asl_store_close(sd->store); + sd->store = NULL; + } + + if (sd->flags & ACT_STORE_FLAG_EXCLUDE_ASLDB) asl_set(msg, ASL_KEY_IGNORE, "Yes"); +} + int asl_action_sendmsg(asl_msg_t *msg, const char *outid) { struct action_rule *r; - if (reset != 0) { _do_reset(); @@ -192,7 +349,9 @@ asl_action_sendmsg(asl_msg_t *msg, const char *outid) if (asl_msg_cmp(r->query, msg) == 1) { if (r->action == NULL) continue; - if (!strcmp(r->action, "notify")) _act_notify(r); + else if (!strcmp(r->action, "access")) _act_access_control(r, msg); + else if (!strcmp(r->action, "notify")) _act_notify(r); + else if (!strcmp(r->action, "store")) _act_store(r, msg); } } @@ -245,12 +404,21 @@ int asl_action_close(void) { struct action_rule *r, *n; + struct store_data *sd; n = NULL; for (r = asl_action_rule.tqh_first; r != NULL; r = n) { n = r->entries.tqe_next; + if ((!strcmp(r->action, "store")) && (r->data != NULL)) + { + sd = (struct store_data *)r->data; + if (sd->store != NULL) asl_store_close(sd->store); + if (sd->path != NULL) free(sd->path); + free(r->data); + } + if (r->query != NULL) asl_free(r->query); if (r->action != NULL) free(r->action); if (r->options != NULL) free(r->options);