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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  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 unix_pid;
00052   char *windows_sid;
00053   void *adt_audit_data;
00054   dbus_int32_t adt_audit_data_size;
00055 };
00056 
00069 DBusCredentials*
00070 _dbus_credentials_new (void)
00071 {
00072   DBusCredentials *creds;
00073 
00074   creds = dbus_new (DBusCredentials, 1);
00075   if (creds == NULL)
00076     return NULL;
00077   
00078   creds->refcount = 1;
00079   creds->unix_uid = DBUS_UID_UNSET;
00080   creds->unix_pid = DBUS_PID_UNSET;
00081   creds->windows_sid = NULL;
00082   creds->adt_audit_data = NULL;
00083   creds->adt_audit_data_size = 0;
00084 
00085   return creds;
00086 }
00087 
00092 DBusCredentials*
00093 _dbus_credentials_new_from_current_process (void)
00094 {
00095   DBusCredentials *creds;
00096 
00097   creds = _dbus_credentials_new ();
00098   if (creds == NULL)
00099     return NULL;
00100 
00101   if (!_dbus_credentials_add_from_current_process (creds))
00102     {
00103       _dbus_credentials_unref (creds);
00104       return NULL;
00105     }
00106   
00107   return creds;
00108 }
00109 
00115 void
00116 _dbus_credentials_ref (DBusCredentials *credentials)
00117 {
00118   _dbus_assert (credentials->refcount > 0);
00119   credentials->refcount += 1;
00120 }
00121 
00127 void
00128 _dbus_credentials_unref (DBusCredentials    *credentials)
00129 {
00130   _dbus_assert (credentials->refcount > 0);
00131 
00132   credentials->refcount -= 1;
00133   if (credentials->refcount == 0)
00134     {
00135       dbus_free (credentials->windows_sid);
00136       dbus_free (credentials->adt_audit_data);
00137       dbus_free (credentials);
00138     }
00139 }
00140 
00148 dbus_bool_t
00149 _dbus_credentials_add_unix_pid (DBusCredentials    *credentials,
00150                                 dbus_pid_t          pid)
00151 {
00152   credentials->unix_pid = pid;
00153   return TRUE;
00154 }
00155 
00163 dbus_bool_t
00164 _dbus_credentials_add_unix_uid(DBusCredentials    *credentials,
00165                                dbus_uid_t          uid)
00166 {
00167   credentials->unix_uid = uid;
00168   return TRUE;
00169 
00170 }
00171 
00179 dbus_bool_t
00180 _dbus_credentials_add_windows_sid (DBusCredentials    *credentials,
00181                                    const char         *windows_sid)
00182 {
00183   char *copy;
00184 
00185   copy = _dbus_strdup (windows_sid);
00186   if (copy == NULL)
00187     return FALSE;
00188 
00189   dbus_free (credentials->windows_sid);
00190   credentials->windows_sid = copy;
00191 
00192   return TRUE;
00193 }
00194 
00203 dbus_bool_t
00204 _dbus_credentials_add_adt_audit_data (DBusCredentials    *credentials,
00205                                       void               *audit_data,
00206                                       dbus_int32_t        size)
00207 {
00208   void *copy;
00209   copy = _dbus_memdup (audit_data, size);
00210   if (copy == NULL)
00211     return FALSE;
00212 
00213   dbus_free (credentials->adt_audit_data);
00214   credentials->adt_audit_data = copy;
00215   credentials->adt_audit_data_size = size;
00216 
00217   return TRUE;
00218 }
00219 
00227 dbus_bool_t
00228 _dbus_credentials_include (DBusCredentials    *credentials,
00229                            DBusCredentialType  type)
00230 {
00231   switch (type)
00232     {
00233     case DBUS_CREDENTIAL_UNIX_PROCESS_ID:
00234       return credentials->unix_pid != DBUS_PID_UNSET;
00235     case DBUS_CREDENTIAL_UNIX_USER_ID:
00236       return credentials->unix_uid != DBUS_UID_UNSET;
00237     case DBUS_CREDENTIAL_WINDOWS_SID:
00238       return credentials->windows_sid != NULL;
00239     case DBUS_CREDENTIAL_ADT_AUDIT_DATA_ID:
00240       return credentials->adt_audit_data != NULL;
00241     }
00242 
00243   _dbus_assert_not_reached ("Unknown credential enum value");
00244   return FALSE;
00245 }
00246 
00254 dbus_pid_t
00255 _dbus_credentials_get_unix_pid (DBusCredentials    *credentials)
00256 {
00257   return credentials->unix_pid;
00258 }
00259 
00267 dbus_uid_t
00268 _dbus_credentials_get_unix_uid (DBusCredentials    *credentials)
00269 {
00270   return credentials->unix_uid;
00271 }
00272 
00280 const char*
00281 _dbus_credentials_get_windows_sid (DBusCredentials    *credentials)
00282 {
00283   return credentials->windows_sid;
00284 }
00285 
00293 void *
00294 _dbus_credentials_get_adt_audit_data (DBusCredentials    *credentials)
00295 {
00296   return credentials->adt_audit_data;
00297 }
00298 
00306 dbus_int32_t 
00307 _dbus_credentials_get_adt_audit_data_size (DBusCredentials    *credentials)
00308 {
00309   return credentials->adt_audit_data_size;
00310 }
00311 
00320 dbus_bool_t
00321 _dbus_credentials_are_superset (DBusCredentials    *credentials,
00322                                 DBusCredentials    *possible_subset)
00323 {
00324   return
00325     (possible_subset->unix_pid == DBUS_PID_UNSET ||
00326      possible_subset->unix_pid == credentials->unix_pid) &&
00327     (possible_subset->unix_uid == DBUS_UID_UNSET ||
00328      possible_subset->unix_uid == credentials->unix_uid) &&
00329     (possible_subset->windows_sid == NULL ||
00330      (credentials->windows_sid && strcmp (possible_subset->windows_sid,
00331                                           credentials->windows_sid) == 0)) &&
00332     (possible_subset->adt_audit_data == NULL ||
00333      (credentials->adt_audit_data && memcmp (possible_subset->adt_audit_data,
00334                                              credentials->adt_audit_data,
00335                                              credentials->adt_audit_data_size) == 0));
00336 }
00337 
00344 dbus_bool_t
00345 _dbus_credentials_are_empty (DBusCredentials    *credentials)
00346 {
00347   return
00348     credentials->unix_pid == DBUS_PID_UNSET &&
00349     credentials->unix_uid == DBUS_UID_UNSET &&
00350     credentials->windows_sid == NULL &&
00351     credentials->adt_audit_data == NULL;
00352 }
00353 
00360 dbus_bool_t
00361 _dbus_credentials_are_anonymous (DBusCredentials    *credentials)
00362 {
00363   return
00364     credentials->unix_uid == DBUS_UID_UNSET &&
00365     credentials->windows_sid == NULL;
00366 }
00367 
00376 dbus_bool_t
00377 _dbus_credentials_add_credentials (DBusCredentials    *credentials,
00378                                    DBusCredentials    *other_credentials)
00379 {
00380   return
00381     _dbus_credentials_add_credential (credentials,
00382                                       DBUS_CREDENTIAL_UNIX_PROCESS_ID,
00383                                       other_credentials) &&
00384     _dbus_credentials_add_credential (credentials,
00385                                       DBUS_CREDENTIAL_UNIX_USER_ID,
00386                                       other_credentials) &&
00387     _dbus_credentials_add_credential (credentials,
00388                                       DBUS_CREDENTIAL_ADT_AUDIT_DATA_ID,
00389                                       other_credentials) &&
00390     _dbus_credentials_add_credential (credentials,
00391                                       DBUS_CREDENTIAL_WINDOWS_SID,
00392                                       other_credentials);
00393 }
00394 
00407 dbus_bool_t
00408 _dbus_credentials_add_credential (DBusCredentials    *credentials,
00409                                   DBusCredentialType  which,
00410                                   DBusCredentials    *other_credentials)
00411 {
00412   if (which == DBUS_CREDENTIAL_UNIX_PROCESS_ID &&
00413       other_credentials->unix_pid != DBUS_PID_UNSET)
00414     {
00415       if (!_dbus_credentials_add_unix_pid (credentials, other_credentials->unix_pid))
00416         return FALSE;
00417     }
00418   else if (which == DBUS_CREDENTIAL_UNIX_USER_ID &&
00419            other_credentials->unix_uid != DBUS_UID_UNSET)
00420     {
00421       if (!_dbus_credentials_add_unix_uid (credentials, other_credentials->unix_uid))
00422         return FALSE;
00423     }
00424   else if (which == DBUS_CREDENTIAL_WINDOWS_SID &&
00425            other_credentials->windows_sid != NULL)
00426     {
00427       if (!_dbus_credentials_add_windows_sid (credentials, other_credentials->windows_sid))
00428         return FALSE;
00429     } 
00430   else if (which == DBUS_CREDENTIAL_ADT_AUDIT_DATA_ID &&
00431            other_credentials->adt_audit_data != NULL) 
00432     {
00433       if (!_dbus_credentials_add_adt_audit_data (credentials, other_credentials->adt_audit_data, other_credentials->adt_audit_data_size))
00434         return FALSE;
00435     }
00436 
00437   return TRUE;
00438 }
00439 
00445 void
00446 _dbus_credentials_clear (DBusCredentials    *credentials)
00447 {
00448   credentials->unix_pid = DBUS_PID_UNSET;
00449   credentials->unix_uid = DBUS_UID_UNSET;
00450   dbus_free (credentials->windows_sid);
00451   credentials->windows_sid = NULL;
00452   dbus_free (credentials->adt_audit_data);
00453   credentials->adt_audit_data = NULL;
00454   credentials->adt_audit_data_size = 0;
00455 }
00456 
00463 DBusCredentials*
00464 _dbus_credentials_copy (DBusCredentials    *credentials)
00465 {
00466   DBusCredentials *copy;
00467 
00468   copy = _dbus_credentials_new ();
00469   if (copy == NULL)
00470     return NULL;
00471 
00472   if (!_dbus_credentials_add_credentials (copy, credentials))
00473     {
00474       _dbus_credentials_unref (copy);
00475       return NULL;
00476     }
00477 
00478   return copy;
00479 }
00480 
00492 dbus_bool_t
00493 _dbus_credentials_same_user (DBusCredentials    *credentials,
00494                              DBusCredentials    *other_credentials)
00495 {
00496   /* both windows and unix user must be the same (though pretty much
00497    * in all conceivable cases, one will be unset)
00498    */
00499   return credentials->unix_uid == other_credentials->unix_uid &&
00500     ((!(credentials->windows_sid || other_credentials->windows_sid)) ||
00501      (credentials->windows_sid && other_credentials->windows_sid &&
00502       strcmp (credentials->windows_sid, other_credentials->windows_sid) == 0));
00503 }
00504 
00507 /* tests in dbus-credentials-util.c */

Generated on Tue Feb 24 16:40:39 2009 for D-Bus by  doxygen 1.5.1