librewolf: update to 134.0-1
[oi-userland.git] / components / x11 / xorg-server / srcs / os / osaudit.c
blobefd7f81c9d6ba07e33be386a365885ad356315c9
1 /*
2 * Copyright (c) 2011, 2015, Oracle and/or its affiliates. All rights reserved.
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
11 * The above copyright notice and this permission notice (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
13 * Software.
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21 * DEALINGS IN THE SOFTWARE.
24 #ifdef HAVE_DIX_CONFIG_H
25 #include <dix-config.h>
26 #endif
28 #define XSERV_t
29 #define TRANS_SERVER
30 #include <X11/Xtrans/Xtrans.h>
31 #include <X11/Xtrans/Xtransint.h>
33 #include "misc.h"
34 #include "osdep.h"
35 #include "dixstruct.h"
37 static DevPrivateKeyRec OSAuditPrivKeyRec;
38 #define OSAuditPrivKey (&OSAuditPrivKeyRec)
40 #define GetOSAuditClient(pClient) \
41 ((OSAuditClientPrivatePtr) dixLookupPrivate(&(pClient)->devPrivates, OSAuditPrivKey))
43 #ifdef HAVE_LIBBSM /* Solaris auditing implementation */
44 #include <ucred.h>
45 #include <bsm/adt.h>
46 #include <bsm/adt_event.h>
48 #ifdef ADT_xconnect
49 # define OS_AUDIT_IMPLEMENTED
51 typedef struct {
52 adt_session_data_t *ah; /* audit handle */
53 ClientState prevState;
54 } OSAuditClientPrivateRec, *OSAuditClientPrivatePtr;
56 static void
57 OSAuditClientInit (ClientPtr pClient)
59 adt_session_data_t *ah; /* audit handle */
60 ucred_t *uc = NULL; /* peer's ucred */
61 XtransConnInfo ci; /* peer's connection info */
62 int peer; /* peer's file descriptor */
63 int saveid;
65 OSAuditClientPrivatePtr priv = GetOSAuditClient(pClient);
67 saveid = geteuid();
68 if (saveid != 0) {
69 /* reset privs back to root */
70 if (seteuid(0) < 0) {
71 ErrorF("OSAuditClientInit: seteuid(0): %s\n", strerror(errno));
72 saveid = 0;
76 if (adt_start_session(&ah, NULL, 0) != 0) {
77 ErrorF("OSAuditClientInit: adt_start_session: %s\n", strerror(errno));
78 goto end;
81 if (pClient->osPrivate == NULL) {
82 ErrorF("OSAuditClientInit: NULL osPrivate: %s\n", strerror(errno));
83 goto end;
85 ci = ((OsCommPtr)pClient->osPrivate)->trans_conn;
86 peer = _XSERVTransGetConnectionNumber(ci);
87 if (getpeerucred(peer, &uc) == 0) {
88 if (adt_set_from_ucred(ah, uc, ADT_NEW) != 0) {
89 ErrorF("OSAuditClientInit: adt_set_from_ucred: %s\n",
90 strerror(errno));
92 ucred_free(uc);
93 } else {
94 if (adt_set_user(ah, ADT_NO_ATTRIB, ADT_NO_ATTRIB, ADT_NO_ATTRIB,
95 ADT_NO_ATTRIB, NULL, ADT_NEW) != 0) {
96 ErrorF("OSAuditClientInit: adt_set_user: %s\n", strerror(errno));
100 priv->ah = ah;
102 end:
103 if (saveid != 0) {
104 /* set privs back to user */
105 if (seteuid(saveid) < 0) {
106 ErrorF("OSAuditClientInit: seteuid(saveid): %s\n", strerror(errno));
112 static void
113 OSAudit (ClientPtr pClient, int event_id, int status, int reason)
115 adt_event_data_t *event; /* event handle */
116 XtransConnInfo ci; /* peer's connection info */
117 int peer; /* peer's file descriptor */
118 int saveid;
120 OSAuditClientPrivatePtr priv = GetOSAuditClient(pClient);
122 if (priv->ah == NULL) {
123 ErrorF("OSAudit: NULL adt_session_data: %s\n", strerror(errno));
124 return;
127 if ((event = adt_alloc_event(priv->ah, event_id)) == NULL) {
128 ErrorF("OSAudit: adt_set_from_ucred: %s\n", strerror(errno));
129 return;
132 /* fill in event */
133 switch (event_id) {
134 case ADT_xconnect:
135 if (pClient->osPrivate != NULL) {
136 ci = ((OsCommPtr)pClient->osPrivate)->trans_conn;
137 peer = _XSERVTransGetConnectionNumber(ci);
138 } else {
139 peer = -1;
141 event->adt_xconnect.client = pClient->index;
142 event->adt_xconnect.peer = peer;
143 break;
144 case ADT_xdisconnect:
145 event->adt_xdisconnect.client = pClient->index;
146 break;
147 default:
148 ErrorF("OSAudit: unknown event_id: %s\n", strerror(errno));
151 saveid = geteuid();
152 if (saveid != 0) {
153 /* reset privs back to root */
154 if (seteuid(0) < 0) {
155 ErrorF("OSAuditClientInit: seteuid(0): %s\n", strerror(errno));
156 saveid = 0;
160 if (adt_put_event(event, status, reason) != 0) {
161 ErrorF("OSAudit: adt_put_event: %s\n", strerror(errno));
164 if (saveid != 0) {
165 /* set privs back to user */
166 if (seteuid(saveid) < 0) {
167 ErrorF("OSAuditClientInit: seteuid(saveid): %s\n", strerror(errno));
171 adt_free_event(event);
174 /* Called when new client connects or existing client disconnects */
175 static void
176 OSAuditClientStateChange(CallbackListPtr *pcbl, void *nulldata, void *calldata)
178 NewClientInfoRec *pci = (NewClientInfoRec *)calldata;
179 ClientPtr pClient = pci->client;
180 OSAuditClientPrivatePtr priv = GetOSAuditClient(pClient);
182 switch (pClient->clientState) {
184 case ClientStateInitial: /* client attempting to connect */
185 OSAuditClientInit(pClient);
186 break;
188 case ClientStateRunning: /* connection accepted */
189 OSAudit (pClient, ADT_xconnect, ADT_SUCCESS, ADT_SUCCESS);
190 break;
192 case ClientStateGone: /* connection terminating */
193 if (priv->prevState == ClientStateInitial) /* was never accepted */
194 OSAudit (pClient, ADT_xconnect, ADT_FAILURE, EACCES);
195 else /* successful connection that ran for a while */
196 OSAudit (pClient, ADT_xdisconnect, ADT_SUCCESS, ADT_SUCCESS);
197 adt_end_session(priv->ah);
198 priv->ah = NULL;
199 break;
201 default:
202 return; /* skip over setting prevState to an unknown state */
205 priv->prevState = pClient->clientState;
207 #endif /* ADT_xconnect */
208 #endif /* HAVE_LIBBSM -- Solaris auditing implementation */
210 /* Generic code to initialize all OS auditing implementations */
211 void
212 OSAuditInit(void)
214 #ifdef OS_AUDIT_IMPLEMENTED
215 /* Reserve room in the client privates for the audit data */
216 if (!dixRegisterPrivateKey(&OSAuditPrivKeyRec, PRIVATE_CLIENT,
217 sizeof(OSAuditClientPrivateRec)))
218 FatalError("could not allocate OSAuditPrivKey\n");
220 /* Register callback to be called on every client connect & disconnect */
221 if (!AddCallback(&ClientStateCallback, OSAuditClientStateChange, NULL))
222 FatalError("could not register OSAuditClientStateChange callback\n");
223 #else
224 /* nothing implemented for this OS */
225 return;
226 #endif