4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21
22 /*
23 * Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved.
24 */
25
26 /*
27 * This is the client layer for svc.configd. All direct protocol interactions
28 * are handled here.
29 *
30 * Essentially, the job of this layer is to turn the idempotent protocol
31 * into a series of non-idempotent calls into the object layer, while
32 * also handling the necessary locking.
33 */
34
35 #include <alloca.h>
36 #include <assert.h>
37 #include <bsm/adt_event.h>
38 #include <door.h>
39 #include <errno.h>
40 #include <libintl.h>
41 #include <limits.h>
42 #include <pthread.h>
43 #include <stdio.h>
718 */
719 entity_cleanup(cp);
720 iter_cleanup(cp);
721
722 /*
723 * clean up notifications
724 */
725 rc_pg_notify_fini(&cp->rc_pg_notify);
726
727 /*
728 * clean up annotations
729 */
730 if (cp->rc_operation != NULL)
731 free((void *)cp->rc_operation);
732 if (cp->rc_file != NULL)
733 free((void *)cp->rc_file);
734
735 /*
736 * End audit session.
737 */
738 (void) adt_end_session(cp->rc_adt_session);
739
740 client_free(cp);
741 }
742
743 /*
744 * Fails with
745 * _TYPE_MISMATCH - the entity is already set up with a different type
746 * _NO_RESOURCES - out of memory
747 */
748 static int
749 entity_setup(repcache_client_t *cp, struct rep_protocol_entity_setup *rpr)
750 {
751 repcache_entity_t *ep;
752 uint32_t type;
753
754 client_start_insert(cp);
755
756 if ((ep = entity_find(cp, rpr->rpr_entityid)) != NULL) {
757 type = ep->re_type;
758 entity_release(ep);
1935 /* Buffer overflow, so do not generate event */
1936 rc = 0;
1937 }
1938 }
1939 }
1940 (void) pthread_mutex_unlock(&cp->rc_annotate_lock);
1941 return (rc);
1942 }
1943
1944 void
1945 client_annotation_finished()
1946 {
1947 thread_info_t *ti = thread_self();
1948 repcache_client_t *cp = ti->ti_active_client;
1949
1950 (void) pthread_mutex_lock(&cp->rc_annotate_lock);
1951 cp->rc_annotate = 0;
1952 (void) pthread_mutex_unlock(&cp->rc_annotate_lock);
1953 }
1954
1955 static void
1956 start_audit_session(repcache_client_t *cp)
1957 {
1958 ucred_t *cred = NULL;
1959 adt_session_data_t *session;
1960
1961 /*
1962 * A NULL session pointer value can legally be used in all
1963 * subsequent calls to adt_* functions.
1964 */
1965 cp->rc_adt_session = NULL;
1966
1967 if (!adt_audit_state(AUC_AUDITING))
1968 return;
1969
1970 if (door_ucred(&cred) != 0) {
1971 switch (errno) {
1972 case EAGAIN:
1973 case ENOMEM:
1974 syslog(LOG_ERR, gettext("start_audit_session(): cannot "
1991 syslog(LOG_ERR, gettext("start_audit_session(): could not "
1992 "start audit session.\n"));
1993 ucred_free(cred);
1994 return;
1995 }
1996 if (adt_set_from_ucred(session, cred, ADT_NEW) != 0) {
1997 syslog(LOG_ERR, gettext("start_audit_session(): cannot set "
1998 "audit session data from ucred\n"));
1999 /* Something went wrong. End the session. */
2000 (void) adt_end_session(session);
2001 ucred_free(cred);
2002 return;
2003 }
2004
2005 /* All went well. Save the session data and session ID */
2006 cp->rc_adt_session = session;
2007 adt_get_asid(session, &cp->rc_adt_sessionid);
2008
2009 ucred_free(cred);
2010 }
2011
2012 /*
2013 * Handle switch client request
2014 *
2015 * This routine can return:
2016 *
2017 * _PERMISSION_DENIED not enough privileges to do request.
2018 * _UNKNOWN file operation error (details written to
2019 * the console).
2020 * _SUCCESS switch operation is completed.
2021 * _BACKEND_ACCESS backend access fails.
2022 * _NO_RESOURCES out of memory.
2023 * _BACKEND_READONLY backend is not writable.
2024 */
2025 static rep_protocol_responseid_t
2026 repository_switch(repcache_client_t *cp,
2027 struct rep_protocol_switch_request *rpr)
2028 {
2029 rep_protocol_responseid_t result;
2030 ucred_t *uc = get_ucred();
2441
2442 struct door_info info;
2443
2444 int door_flags = DOOR_UNREF | DOOR_REFUSE_DESC;
2445 #ifdef DOOR_NO_CANCEL
2446 door_flags |= DOOR_NO_CANCEL;
2447 #endif
2448
2449 cp = client_alloc();
2450 if (cp == NULL)
2451 return (REPOSITORY_DOOR_FAIL_NO_RESOURCES);
2452
2453 (void) pthread_mutex_lock(&client_lock);
2454 cp->rc_id = ++client_maxid;
2455 (void) pthread_mutex_unlock(&client_lock);
2456
2457 cp->rc_all_auths = privileged;
2458 cp->rc_pid = pid;
2459 cp->rc_debug = debugflags;
2460
2461 start_audit_session(cp);
2462
2463 cp->rc_doorfd = door_create(client_switcher, (void *)cp->rc_id,
2464 door_flags);
2465
2466 if (cp->rc_doorfd < 0) {
2467 client_free(cp);
2468 return (REPOSITORY_DOOR_FAIL_NO_RESOURCES);
2469 }
2470 #ifdef DOOR_PARAM_DATA_MIN
2471 (void) door_setparam(cp->rc_doorfd, DOOR_PARAM_DATA_MIN,
2472 sizeof (enum rep_protocol_requestid));
2473 #endif
2474
2475 if ((fd = dup(cp->rc_doorfd)) < 0 ||
2476 door_info(cp->rc_doorfd, &info) < 0) {
2477 if (fd >= 0)
2478 (void) close(fd);
2479 (void) door_revoke(cp->rc_doorfd);
2480 cp->rc_doorfd = -1;
2481 client_free(cp);
|
4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License (the "License").
6 * You may not use this file except in compliance with the License.
7 *
8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9 * or http://www.opensolaris.org/os/licensing.
10 * See the License for the specific language governing permissions
11 * and limitations under the License.
12 *
13 * When distributing Covered Code, include this CDDL HEADER in each
14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15 * If applicable, add the following below this CDDL HEADER, with the
16 * fields enclosed by brackets "[]" replaced with your own identifying
17 * information: Portions Copyright [yyyy] [name of copyright owner]
18 *
19 * CDDL HEADER END
20 */
21
22 /*
23 * Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved.
24 * Copyright 2015 RackTop Systems.
25 */
26
27 /*
28 * This is the client layer for svc.configd. All direct protocol interactions
29 * are handled here.
30 *
31 * Essentially, the job of this layer is to turn the idempotent protocol
32 * into a series of non-idempotent calls into the object layer, while
33 * also handling the necessary locking.
34 */
35
36 #include <alloca.h>
37 #include <assert.h>
38 #include <bsm/adt_event.h>
39 #include <door.h>
40 #include <errno.h>
41 #include <libintl.h>
42 #include <limits.h>
43 #include <pthread.h>
44 #include <stdio.h>
719 */
720 entity_cleanup(cp);
721 iter_cleanup(cp);
722
723 /*
724 * clean up notifications
725 */
726 rc_pg_notify_fini(&cp->rc_pg_notify);
727
728 /*
729 * clean up annotations
730 */
731 if (cp->rc_operation != NULL)
732 free((void *)cp->rc_operation);
733 if (cp->rc_file != NULL)
734 free((void *)cp->rc_file);
735
736 /*
737 * End audit session.
738 */
739 #ifndef NATIVE_BUILD
740 (void) adt_end_session(cp->rc_adt_session);
741 #endif
742
743 client_free(cp);
744 }
745
746 /*
747 * Fails with
748 * _TYPE_MISMATCH - the entity is already set up with a different type
749 * _NO_RESOURCES - out of memory
750 */
751 static int
752 entity_setup(repcache_client_t *cp, struct rep_protocol_entity_setup *rpr)
753 {
754 repcache_entity_t *ep;
755 uint32_t type;
756
757 client_start_insert(cp);
758
759 if ((ep = entity_find(cp, rpr->rpr_entityid)) != NULL) {
760 type = ep->re_type;
761 entity_release(ep);
1938 /* Buffer overflow, so do not generate event */
1939 rc = 0;
1940 }
1941 }
1942 }
1943 (void) pthread_mutex_unlock(&cp->rc_annotate_lock);
1944 return (rc);
1945 }
1946
1947 void
1948 client_annotation_finished()
1949 {
1950 thread_info_t *ti = thread_self();
1951 repcache_client_t *cp = ti->ti_active_client;
1952
1953 (void) pthread_mutex_lock(&cp->rc_annotate_lock);
1954 cp->rc_annotate = 0;
1955 (void) pthread_mutex_unlock(&cp->rc_annotate_lock);
1956 }
1957
1958 #ifndef NATIVE_BUILD
1959 static void
1960 start_audit_session(repcache_client_t *cp)
1961 {
1962 ucred_t *cred = NULL;
1963 adt_session_data_t *session;
1964
1965 /*
1966 * A NULL session pointer value can legally be used in all
1967 * subsequent calls to adt_* functions.
1968 */
1969 cp->rc_adt_session = NULL;
1970
1971 if (!adt_audit_state(AUC_AUDITING))
1972 return;
1973
1974 if (door_ucred(&cred) != 0) {
1975 switch (errno) {
1976 case EAGAIN:
1977 case ENOMEM:
1978 syslog(LOG_ERR, gettext("start_audit_session(): cannot "
1995 syslog(LOG_ERR, gettext("start_audit_session(): could not "
1996 "start audit session.\n"));
1997 ucred_free(cred);
1998 return;
1999 }
2000 if (adt_set_from_ucred(session, cred, ADT_NEW) != 0) {
2001 syslog(LOG_ERR, gettext("start_audit_session(): cannot set "
2002 "audit session data from ucred\n"));
2003 /* Something went wrong. End the session. */
2004 (void) adt_end_session(session);
2005 ucred_free(cred);
2006 return;
2007 }
2008
2009 /* All went well. Save the session data and session ID */
2010 cp->rc_adt_session = session;
2011 adt_get_asid(session, &cp->rc_adt_sessionid);
2012
2013 ucred_free(cred);
2014 }
2015 #endif
2016
2017 /*
2018 * Handle switch client request
2019 *
2020 * This routine can return:
2021 *
2022 * _PERMISSION_DENIED not enough privileges to do request.
2023 * _UNKNOWN file operation error (details written to
2024 * the console).
2025 * _SUCCESS switch operation is completed.
2026 * _BACKEND_ACCESS backend access fails.
2027 * _NO_RESOURCES out of memory.
2028 * _BACKEND_READONLY backend is not writable.
2029 */
2030 static rep_protocol_responseid_t
2031 repository_switch(repcache_client_t *cp,
2032 struct rep_protocol_switch_request *rpr)
2033 {
2034 rep_protocol_responseid_t result;
2035 ucred_t *uc = get_ucred();
2446
2447 struct door_info info;
2448
2449 int door_flags = DOOR_UNREF | DOOR_REFUSE_DESC;
2450 #ifdef DOOR_NO_CANCEL
2451 door_flags |= DOOR_NO_CANCEL;
2452 #endif
2453
2454 cp = client_alloc();
2455 if (cp == NULL)
2456 return (REPOSITORY_DOOR_FAIL_NO_RESOURCES);
2457
2458 (void) pthread_mutex_lock(&client_lock);
2459 cp->rc_id = ++client_maxid;
2460 (void) pthread_mutex_unlock(&client_lock);
2461
2462 cp->rc_all_auths = privileged;
2463 cp->rc_pid = pid;
2464 cp->rc_debug = debugflags;
2465
2466 #ifndef NATIVE_BUILD
2467 start_audit_session(cp);
2468 #endif
2469
2470 cp->rc_doorfd = door_create(client_switcher, (void *)cp->rc_id,
2471 door_flags);
2472
2473 if (cp->rc_doorfd < 0) {
2474 client_free(cp);
2475 return (REPOSITORY_DOOR_FAIL_NO_RESOURCES);
2476 }
2477 #ifdef DOOR_PARAM_DATA_MIN
2478 (void) door_setparam(cp->rc_doorfd, DOOR_PARAM_DATA_MIN,
2479 sizeof (enum rep_protocol_requestid));
2480 #endif
2481
2482 if ((fd = dup(cp->rc_doorfd)) < 0 ||
2483 door_info(cp->rc_doorfd, &info) < 0) {
2484 if (fd >= 0)
2485 (void) close(fd);
2486 (void) door_revoke(cp->rc_doorfd);
2487 cp->rc_doorfd = -1;
2488 client_free(cp);
|