D-Bus
1.10.12
|
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 */