D-Bus  1.10.12
dbus-credentials.c
00001 /* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
00002 /* dbus-credentials.c Credentials provable through authentication
00003  *
00004  * Copyright (C) 2007 Red Hat Inc.
00005  *
00006  * Licensed under the Academic Free License version 2.1
00007  * 
00008  * This program is free software; you can redistribute it and/or modify
00009  * it under the terms of the GNU General Public License as published by
00010  * the Free Software Foundation; either version 2 of the License, or
00011  * (at your option) any later version.
00012  *
00013  * This program is distributed in the hope that it will be useful,
00014  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00015  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00016  * GNU General Public License for more details.
00017  * 
00018  * You should have received a copy of the GNU General Public License
00019  * along with this program; if not, write to the Free Software
00020  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
00021  *
00022  */
00023 #include <config.h>
00024 #include <string.h>
00025 #include "dbus-credentials.h"
00026 #include "dbus-internals.h"
00027 
00048 struct DBusCredentials {
00049   int refcount;
00050   dbus_uid_t unix_uid;
00051   dbus_pid_t pid;
00052   char *windows_sid;
00053   char *linux_security_label;
00054   void *adt_audit_data;
00055   dbus_int32_t adt_audit_data_size;
00056 };
00057 
00070 DBusCredentials*
00071 _dbus_credentials_new (void)
00072 {
00073   DBusCredentials *creds;
00074 
00075   creds = dbus_new (DBusCredentials, 1);
00076   if (creds == NULL)
00077     return NULL;
00078   
00079   creds->refcount = 1;
00080   creds->unix_uid = DBUS_UID_UNSET;
00081   creds->pid = DBUS_PID_UNSET;
00082   creds->windows_sid = NULL;
00083   creds->linux_security_label = NULL;
00084   creds->adt_audit_data = NULL;
00085   creds->adt_audit_data_size = 0;
00086 
00087   return creds;
00088 }
00089 
00094 DBusCredentials*
00095 _dbus_credentials_new_from_current_process (void)
00096 {
00097   DBusCredentials *creds;
00098 
00099   creds = _dbus_credentials_new ();
00100   if (creds == NULL)
00101     return NULL;
00102 
00103   if (!_dbus_credentials_add_from_current_process (creds))
00104     {
00105       _dbus_credentials_unref (creds);
00106       return NULL;
00107     }
00108   
00109   return creds;
00110 }
00111 
00117 void
00118 _dbus_credentials_ref (DBusCredentials *credentials)
00119 {
00120   _dbus_assert (credentials->refcount > 0);
00121   credentials->refcount += 1;
00122 }
00123 
00129 void
00130 _dbus_credentials_unref (DBusCredentials    *credentials)
00131 {
00132   _dbus_assert (credentials->refcount > 0);
00133 
00134   credentials->refcount -= 1;
00135   if (credentials->refcount == 0)
00136     {
00137       dbus_free (credentials->windows_sid);
00138       dbus_free (credentials->linux_security_label);
00139       dbus_free (credentials->adt_audit_data);
00140       dbus_free (credentials);
00141     }
00142 }
00143 
00151 dbus_bool_t
00152 _dbus_credentials_add_pid (DBusCredentials    *credentials,
00153                            dbus_pid_t          pid)
00154 {
00155   credentials->pid = pid;
00156   return TRUE;
00157 }
00158 
00166 dbus_bool_t
00167 _dbus_credentials_add_unix_uid(DBusCredentials    *credentials,
00168                                dbus_uid_t          uid)
00169 {
00170   credentials->unix_uid = uid;
00171   return TRUE;
00172 
00173 }
00174 
00182 dbus_bool_t
00183 _dbus_credentials_add_windows_sid (DBusCredentials    *credentials,
00184                                    const char         *windows_sid)
00185 {
00186   char *copy;
00187 
00188   copy = _dbus_strdup (windows_sid);
00189   if (copy == NULL)
00190     return FALSE;
00191 
00192   dbus_free (credentials->windows_sid);
00193   credentials->windows_sid = copy;
00194 
00195   return TRUE;
00196 }
00197 
00206 dbus_bool_t
00207 _dbus_credentials_add_linux_security_label (DBusCredentials    *credentials,
00208                                             const char         *label)
00209 {
00210   char *copy;
00211 
00212   copy = _dbus_strdup (label);
00213   if (copy == NULL)
00214     return FALSE;
00215 
00216   dbus_free (credentials->linux_security_label);
00217   credentials->linux_security_label = copy;
00218 
00219   return TRUE;
00220 }
00221 
00230 dbus_bool_t
00231 _dbus_credentials_add_adt_audit_data (DBusCredentials    *credentials,
00232                                       void               *audit_data,
00233                                       dbus_int32_t        size)
00234 {
00235   void *copy;
00236   copy = _dbus_memdup (audit_data, size);
00237   if (copy == NULL)
00238     return FALSE;
00239 
00240   dbus_free (credentials->adt_audit_data);
00241   credentials->adt_audit_data = copy;
00242   credentials->adt_audit_data_size = size;
00243 
00244   return TRUE;
00245 }
00246 
00254 dbus_bool_t
00255 _dbus_credentials_include (DBusCredentials    *credentials,
00256                            DBusCredentialType  type)
00257 {
00258   switch (type)
00259     {
00260     case DBUS_CREDENTIAL_UNIX_PROCESS_ID:
00261       return credentials->pid != DBUS_PID_UNSET;
00262     case DBUS_CREDENTIAL_UNIX_USER_ID:
00263       return credentials->unix_uid != DBUS_UID_UNSET;
00264     case DBUS_CREDENTIAL_WINDOWS_SID:
00265       return credentials->windows_sid != NULL;
00266     case DBUS_CREDENTIAL_LINUX_SECURITY_LABEL:
00267       return credentials->linux_security_label != NULL;
00268     case DBUS_CREDENTIAL_ADT_AUDIT_DATA_ID:
00269       return credentials->adt_audit_data != NULL;
00270     }
00271 
00272   _dbus_assert_not_reached ("Unknown credential enum value");
00273   return FALSE;
00274 }
00275 
00283 dbus_pid_t
00284 _dbus_credentials_get_pid (DBusCredentials    *credentials)
00285 {
00286   return credentials->pid;
00287 }
00288 
00296 dbus_uid_t
00297 _dbus_credentials_get_unix_uid (DBusCredentials    *credentials)
00298 {
00299   return credentials->unix_uid;
00300 }
00301 
00309 const char*
00310 _dbus_credentials_get_windows_sid (DBusCredentials    *credentials)
00311 {
00312   return credentials->windows_sid;
00313 }
00314 
00322 const char *
00323 _dbus_credentials_get_linux_security_label (DBusCredentials *credentials)
00324 {
00325   return credentials->linux_security_label;
00326 }
00327 
00335 void *
00336 _dbus_credentials_get_adt_audit_data (DBusCredentials    *credentials)
00337 {
00338   return credentials->adt_audit_data;
00339 }
00340 
00348 dbus_int32_t 
00349 _dbus_credentials_get_adt_audit_data_size (DBusCredentials    *credentials)
00350 {
00351   return credentials->adt_audit_data_size;
00352 }
00353 
00362 dbus_bool_t
00363 _dbus_credentials_are_superset (DBusCredentials    *credentials,
00364                                 DBusCredentials    *possible_subset)
00365 {
00366   return
00367     (possible_subset->pid == DBUS_PID_UNSET ||
00368      possible_subset->pid == credentials->pid) &&
00369     (possible_subset->unix_uid == DBUS_UID_UNSET ||
00370      possible_subset->unix_uid == credentials->unix_uid) &&
00371     (possible_subset->windows_sid == NULL ||
00372      (credentials->windows_sid && strcmp (possible_subset->windows_sid,
00373                                           credentials->windows_sid) == 0)) &&
00374     (possible_subset->linux_security_label == NULL ||
00375      (credentials->linux_security_label != NULL &&
00376       strcmp (possible_subset->linux_security_label,
00377               credentials->linux_security_label) == 0)) &&
00378     (possible_subset->adt_audit_data == NULL ||
00379      (credentials->adt_audit_data && memcmp (possible_subset->adt_audit_data,
00380                                              credentials->adt_audit_data,
00381                                              credentials->adt_audit_data_size) == 0));
00382 }
00383 
00390 dbus_bool_t
00391 _dbus_credentials_are_empty (DBusCredentials    *credentials)
00392 {
00393   return
00394     credentials->pid == DBUS_PID_UNSET &&
00395     credentials->unix_uid == DBUS_UID_UNSET &&
00396     credentials->windows_sid == NULL &&
00397     credentials->linux_security_label == NULL &&
00398     credentials->adt_audit_data == NULL;
00399 }
00400 
00407 dbus_bool_t
00408 _dbus_credentials_are_anonymous (DBusCredentials    *credentials)
00409 {
00410   return
00411     credentials->unix_uid == DBUS_UID_UNSET &&
00412     credentials->windows_sid == NULL;
00413 }
00414 
00423 dbus_bool_t
00424 _dbus_credentials_add_credentials (DBusCredentials    *credentials,
00425                                    DBusCredentials    *other_credentials)
00426 {
00427   return
00428     _dbus_credentials_add_credential (credentials,
00429                                       DBUS_CREDENTIAL_UNIX_PROCESS_ID,
00430                                       other_credentials) &&
00431     _dbus_credentials_add_credential (credentials,
00432                                       DBUS_CREDENTIAL_UNIX_USER_ID,
00433                                       other_credentials) &&
00434     _dbus_credentials_add_credential (credentials,
00435                                       DBUS_CREDENTIAL_ADT_AUDIT_DATA_ID,
00436                                       other_credentials) &&
00437     _dbus_credentials_add_credential (credentials,
00438                                       DBUS_CREDENTIAL_LINUX_SECURITY_LABEL,
00439                                       other_credentials) &&
00440     _dbus_credentials_add_credential (credentials,
00441                                       DBUS_CREDENTIAL_WINDOWS_SID,
00442                                       other_credentials);
00443 }
00444 
00457 dbus_bool_t
00458 _dbus_credentials_add_credential (DBusCredentials    *credentials,
00459                                   DBusCredentialType  which,
00460                                   DBusCredentials    *other_credentials)
00461 {
00462   if (which == DBUS_CREDENTIAL_UNIX_PROCESS_ID &&
00463       other_credentials->pid != DBUS_PID_UNSET)
00464     {
00465       if (!_dbus_credentials_add_pid (credentials, other_credentials->pid))
00466         return FALSE;
00467     }
00468   else if (which == DBUS_CREDENTIAL_UNIX_USER_ID &&
00469            other_credentials->unix_uid != DBUS_UID_UNSET)
00470     {
00471       if (!_dbus_credentials_add_unix_uid (credentials, other_credentials->unix_uid))
00472         return FALSE;
00473     }
00474   else if (which == DBUS_CREDENTIAL_WINDOWS_SID &&
00475            other_credentials->windows_sid != NULL)
00476     {
00477       if (!_dbus_credentials_add_windows_sid (credentials, other_credentials->windows_sid))
00478         return FALSE;
00479     } 
00480   else if (which == DBUS_CREDENTIAL_LINUX_SECURITY_LABEL &&
00481            other_credentials->linux_security_label != NULL)
00482     {
00483       if (!_dbus_credentials_add_linux_security_label (credentials,
00484             other_credentials->linux_security_label))
00485         return FALSE;
00486     }
00487   else if (which == DBUS_CREDENTIAL_ADT_AUDIT_DATA_ID &&
00488            other_credentials->adt_audit_data != NULL) 
00489     {
00490       if (!_dbus_credentials_add_adt_audit_data (credentials, other_credentials->adt_audit_data, other_credentials->adt_audit_data_size))
00491         return FALSE;
00492     }
00493 
00494   return TRUE;
00495 }
00496 
00502 void
00503 _dbus_credentials_clear (DBusCredentials    *credentials)
00504 {
00505   credentials->pid = DBUS_PID_UNSET;
00506   credentials->unix_uid = DBUS_UID_UNSET;
00507   dbus_free (credentials->windows_sid);
00508   credentials->windows_sid = NULL;
00509   dbus_free (credentials->linux_security_label);
00510   credentials->linux_security_label = NULL;
00511   dbus_free (credentials->adt_audit_data);
00512   credentials->adt_audit_data = NULL;
00513   credentials->adt_audit_data_size = 0;
00514 }
00515 
00522 DBusCredentials*
00523 _dbus_credentials_copy (DBusCredentials    *credentials)
00524 {
00525   DBusCredentials *copy;
00526 
00527   copy = _dbus_credentials_new ();
00528   if (copy == NULL)
00529     return NULL;
00530 
00531   if (!_dbus_credentials_add_credentials (copy, credentials))
00532     {
00533       _dbus_credentials_unref (copy);
00534       return NULL;
00535     }
00536 
00537   return copy;
00538 }
00539 
00551 dbus_bool_t
00552 _dbus_credentials_same_user (DBusCredentials    *credentials,
00553                              DBusCredentials    *other_credentials)
00554 {
00555   /* both windows and unix user must be the same (though pretty much
00556    * in all conceivable cases, one will be unset)
00557    */
00558   return credentials->unix_uid == other_credentials->unix_uid &&
00559     ((!(credentials->windows_sid || other_credentials->windows_sid)) ||
00560      (credentials->windows_sid && other_credentials->windows_sid &&
00561       strcmp (credentials->windows_sid, other_credentials->windows_sid) == 0));
00562 }
00563 
00572 dbus_bool_t
00573 _dbus_credentials_to_string_append (DBusCredentials    *credentials,
00574                                     DBusString         *string)
00575 {
00576   dbus_bool_t join;
00577 
00578   join = FALSE;
00579   if (credentials->unix_uid != DBUS_UID_UNSET)
00580     {
00581       if (!_dbus_string_append_printf (string, "uid=" DBUS_UID_FORMAT, credentials->unix_uid))
00582         goto oom;
00583       join = TRUE;
00584     }
00585   if (credentials->pid != DBUS_PID_UNSET)
00586     {
00587       if (!_dbus_string_append_printf (string, "%spid=" DBUS_PID_FORMAT, join ? " " : "", credentials->pid))
00588         goto oom;
00589       join = TRUE;
00590     }
00591   else
00592     join = FALSE;
00593   if (credentials->windows_sid != NULL)
00594     {
00595       if (!_dbus_string_append_printf (string, "%ssid=%s", join ? " " : "", credentials->windows_sid))
00596         goto oom;
00597       join = TRUE;
00598     }
00599   else
00600     join = FALSE;
00601 
00602   if (credentials->linux_security_label != NULL)
00603     {
00604       if (!_dbus_string_append_printf (string, "%slsm='%s'",
00605                                        join ? " " : "",
00606                                        credentials->linux_security_label))
00607         goto oom;
00608       join = TRUE;
00609     }
00610 
00611   return TRUE;
00612 oom:
00613   return FALSE;
00614 }
00615 
00618 /* tests in dbus-credentials-util.c */