D-Bus  1.12.16
dbus-credentials.c
1 /* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
2 /* dbus-credentials.c Credentials provable through authentication
3  *
4  * Copyright (C) 2007 Red Hat Inc.
5  *
6  * Licensed under the Academic Free License version 2.1
7  *
8  * This program is free software; you can redistribute it and/or modify
9  * it under the terms of the GNU General Public License as published by
10  * the Free Software Foundation; either version 2 of the License, or
11  * (at your option) any later version.
12  *
13  * This program is distributed in the hope that it will be useful,
14  * but WITHOUT ANY WARRANTY; without even the implied warranty of
15  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16  * GNU General Public License for more details.
17  *
18  * You should have received a copy of the GNU General Public License
19  * along with this program; if not, write to the Free Software
20  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21  *
22  */
23 #include <config.h>
24 #include <string.h>
25 #include "dbus-credentials.h"
26 #include "dbus-internals.h"
27 
49  int refcount;
50  dbus_uid_t unix_uid;
51  dbus_pid_t pid;
52  char *windows_sid;
53  char *linux_security_label;
54  void *adt_audit_data;
55  dbus_int32_t adt_audit_data_size;
56 };
57 
72 {
73  DBusCredentials *creds;
74 
75  creds = dbus_new (DBusCredentials, 1);
76  if (creds == NULL)
77  return NULL;
78 
79  creds->refcount = 1;
80  creds->unix_uid = DBUS_UID_UNSET;
81  creds->pid = DBUS_PID_UNSET;
82  creds->windows_sid = NULL;
83  creds->linux_security_label = NULL;
84  creds->adt_audit_data = NULL;
85  creds->adt_audit_data_size = 0;
86 
87  return creds;
88 }
89 
96 {
97  DBusCredentials *creds;
98 
99  creds = _dbus_credentials_new ();
100  if (creds == NULL)
101  return NULL;
102 
104  {
105  _dbus_credentials_unref (creds);
106  return NULL;
107  }
108 
109  return creds;
110 }
111 
117 void
119 {
120  _dbus_assert (credentials->refcount > 0);
121  credentials->refcount += 1;
122 }
123 
129 void
131 {
132  _dbus_assert (credentials->refcount > 0);
133 
134  credentials->refcount -= 1;
135  if (credentials->refcount == 0)
136  {
137  dbus_free (credentials->windows_sid);
138  dbus_free (credentials->linux_security_label);
139  dbus_free (credentials->adt_audit_data);
140  dbus_free (credentials);
141  }
142 }
143 
153  dbus_pid_t pid)
154 {
155  credentials->pid = pid;
156  return TRUE;
157 }
158 
168  dbus_uid_t uid)
169 {
170  credentials->unix_uid = uid;
171  return TRUE;
172 
173 }
174 
184  const char *windows_sid)
185 {
186  char *copy;
187 
188  copy = _dbus_strdup (windows_sid);
189  if (copy == NULL)
190  return FALSE;
191 
192  dbus_free (credentials->windows_sid);
193  credentials->windows_sid = copy;
194 
195  return TRUE;
196 }
197 
208  const char *label)
209 {
210  char *copy;
211 
212  copy = _dbus_strdup (label);
213  if (copy == NULL)
214  return FALSE;
215 
216  dbus_free (credentials->linux_security_label);
217  credentials->linux_security_label = copy;
218 
219  return TRUE;
220 }
221 
232  void *audit_data,
233  dbus_int32_t size)
234 {
235  void *copy;
236  copy = _dbus_memdup (audit_data, size);
237  if (copy == NULL)
238  return FALSE;
239 
240  dbus_free (credentials->adt_audit_data);
241  credentials->adt_audit_data = copy;
242  credentials->adt_audit_data_size = size;
243 
244  return TRUE;
245 }
246 
256  DBusCredentialType type)
257 {
258  switch (type)
259  {
260  case DBUS_CREDENTIAL_UNIX_PROCESS_ID:
261  return credentials->pid != DBUS_PID_UNSET;
262  case DBUS_CREDENTIAL_UNIX_USER_ID:
263  return credentials->unix_uid != DBUS_UID_UNSET;
264  case DBUS_CREDENTIAL_WINDOWS_SID:
265  return credentials->windows_sid != NULL;
266  case DBUS_CREDENTIAL_LINUX_SECURITY_LABEL:
267  return credentials->linux_security_label != NULL;
268  case DBUS_CREDENTIAL_ADT_AUDIT_DATA_ID:
269  return credentials->adt_audit_data != NULL;
270  default:
271  _dbus_assert_not_reached ("Unknown credential enum value");
272  return FALSE;
273  }
274 }
275 
285 {
286  return credentials->pid;
287 }
288 
298 {
299  return credentials->unix_uid;
300 }
301 
309 const char*
311 {
312  return credentials->windows_sid;
313 }
314 
322 const char *
324 {
325  return credentials->linux_security_label;
326 }
327 
335 void *
337 {
338  return credentials->adt_audit_data;
339 }
340 
350 {
351  return credentials->adt_audit_data_size;
352 }
353 
364  DBusCredentials *possible_subset)
365 {
366  return
367  (possible_subset->pid == DBUS_PID_UNSET ||
368  possible_subset->pid == credentials->pid) &&
369  (possible_subset->unix_uid == DBUS_UID_UNSET ||
370  possible_subset->unix_uid == credentials->unix_uid) &&
371  (possible_subset->windows_sid == NULL ||
372  (credentials->windows_sid && strcmp (possible_subset->windows_sid,
373  credentials->windows_sid) == 0)) &&
374  (possible_subset->linux_security_label == NULL ||
375  (credentials->linux_security_label != NULL &&
376  strcmp (possible_subset->linux_security_label,
377  credentials->linux_security_label) == 0)) &&
378  (possible_subset->adt_audit_data == NULL ||
379  (credentials->adt_audit_data && memcmp (possible_subset->adt_audit_data,
380  credentials->adt_audit_data,
381  credentials->adt_audit_data_size) == 0));
382 }
383 
392 {
393  return
394  credentials->pid == DBUS_PID_UNSET &&
395  credentials->unix_uid == DBUS_UID_UNSET &&
396  credentials->windows_sid == NULL &&
397  credentials->linux_security_label == NULL &&
398  credentials->adt_audit_data == NULL;
399 }
400 
409 {
410  return
411  credentials->unix_uid == DBUS_UID_UNSET &&
412  credentials->windows_sid == NULL;
413 }
414 
425  DBusCredentials *other_credentials)
426 {
427  return
429  DBUS_CREDENTIAL_UNIX_PROCESS_ID,
430  other_credentials) &&
432  DBUS_CREDENTIAL_UNIX_USER_ID,
433  other_credentials) &&
435  DBUS_CREDENTIAL_ADT_AUDIT_DATA_ID,
436  other_credentials) &&
438  DBUS_CREDENTIAL_LINUX_SECURITY_LABEL,
439  other_credentials) &&
441  DBUS_CREDENTIAL_WINDOWS_SID,
442  other_credentials);
443 }
444 
459  DBusCredentialType which,
460  DBusCredentials *other_credentials)
461 {
462  if (which == DBUS_CREDENTIAL_UNIX_PROCESS_ID &&
463  other_credentials->pid != DBUS_PID_UNSET)
464  {
465  if (!_dbus_credentials_add_pid (credentials, other_credentials->pid))
466  return FALSE;
467  }
468  else if (which == DBUS_CREDENTIAL_UNIX_USER_ID &&
469  other_credentials->unix_uid != DBUS_UID_UNSET)
470  {
471  if (!_dbus_credentials_add_unix_uid (credentials, other_credentials->unix_uid))
472  return FALSE;
473  }
474  else if (which == DBUS_CREDENTIAL_WINDOWS_SID &&
475  other_credentials->windows_sid != NULL)
476  {
477  if (!_dbus_credentials_add_windows_sid (credentials, other_credentials->windows_sid))
478  return FALSE;
479  }
480  else if (which == DBUS_CREDENTIAL_LINUX_SECURITY_LABEL &&
481  other_credentials->linux_security_label != NULL)
482  {
484  other_credentials->linux_security_label))
485  return FALSE;
486  }
487  else if (which == DBUS_CREDENTIAL_ADT_AUDIT_DATA_ID &&
488  other_credentials->adt_audit_data != NULL)
489  {
490  if (!_dbus_credentials_add_adt_audit_data (credentials, other_credentials->adt_audit_data, other_credentials->adt_audit_data_size))
491  return FALSE;
492  }
493 
494  return TRUE;
495 }
496 
502 void
504 {
505  credentials->pid = DBUS_PID_UNSET;
506  credentials->unix_uid = DBUS_UID_UNSET;
507  dbus_free (credentials->windows_sid);
508  credentials->windows_sid = NULL;
509  dbus_free (credentials->linux_security_label);
510  credentials->linux_security_label = NULL;
511  dbus_free (credentials->adt_audit_data);
512  credentials->adt_audit_data = NULL;
513  credentials->adt_audit_data_size = 0;
514 }
515 
524 {
525  DBusCredentials *copy;
526 
527  copy = _dbus_credentials_new ();
528  if (copy == NULL)
529  return NULL;
530 
531  if (!_dbus_credentials_add_credentials (copy, credentials))
532  {
534  return NULL;
535  }
536 
537  return copy;
538 }
539 
553  DBusCredentials *other_credentials)
554 {
555  /* both windows and unix user must be the same (though pretty much
556  * in all conceivable cases, one will be unset)
557  */
558  return credentials->unix_uid == other_credentials->unix_uid &&
559  ((!(credentials->windows_sid || other_credentials->windows_sid)) ||
560  (credentials->windows_sid && other_credentials->windows_sid &&
561  strcmp (credentials->windows_sid, other_credentials->windows_sid) == 0));
562 }
563 
574  DBusString *string)
575 {
576  dbus_bool_t join;
577 
578  join = FALSE;
579  if (credentials->unix_uid != DBUS_UID_UNSET)
580  {
581  if (!_dbus_string_append_printf (string, "uid=" DBUS_UID_FORMAT, credentials->unix_uid))
582  goto oom;
583  join = TRUE;
584  }
585  if (credentials->pid != DBUS_PID_UNSET)
586  {
587  if (!_dbus_string_append_printf (string, "%spid=" DBUS_PID_FORMAT, join ? " " : "", credentials->pid))
588  goto oom;
589  join = TRUE;
590  }
591  else
592  join = FALSE;
593  if (credentials->windows_sid != NULL)
594  {
595  if (!_dbus_string_append_printf (string, "%ssid=%s", join ? " " : "", credentials->windows_sid))
596  goto oom;
597  join = TRUE;
598  }
599  else
600  join = FALSE;
601 
602  if (credentials->linux_security_label != NULL)
603  {
604  if (!_dbus_string_append_printf (string, "%slsm='%s'",
605  join ? " " : "",
606  credentials->linux_security_label))
607  goto oom;
608  join = TRUE;
609  }
610 
611  return TRUE;
612 oom:
613  return FALSE;
614 }
615 
618 /* tests in dbus-credentials-util.c */